diff options
Diffstat (limited to 'src/ui/ui-drv/x11')
-rw-r--r-- | src/ui/ui-drv/x11/Makefile.in | 40 | ||||
-rw-r--r-- | src/ui/ui-drv/x11/ui_x11.c | 597 | ||||
-rw-r--r-- | src/ui/ui-drv/x11/xlib.c | 663 | ||||
-rw-r--r-- | src/ui/ui-drv/x11/xlib.h | 139 |
4 files changed, 1439 insertions, 0 deletions
diff --git a/src/ui/ui-drv/x11/Makefile.in b/src/ui/ui-drv/x11/Makefile.in new file mode 100644 index 0000000..c4ac33c --- /dev/null +++ b/src/ui/ui-drv/x11/Makefile.in @@ -0,0 +1,40 @@ +CC = @CC@ +CFLAGS = @CFLAGS@ +LIBS = @LIBS@ -lm +LFLAGS = @LDFLAGS@ +AR = @AR@ +RANLIB = @RANLIB@ + +SRCS = xlib.c \ + ui_x11.c + +OBJS = $(SRCS:.c=.o) + +TLIB = @LIBPATH@/libuix11.a + + +all: $(TLIB) + +$(TLIB):$(OBJS) + rm -f $@ + $(AR) rc $@ $(OBJS) + $(RANLIB) $@ + +clean: + rm -f $(TLIB) + rm -f *.[oas] + rm -f *~ + rm -f core + +distclean:clean + rm Makefile + +#dep: +# rm -f .depend +# make .depend +# +#.depend: +# echo '# Program dependencies' >.depend +# gcc -I svgalib $(DEFINES) -MM $(patsubst %.o,%.c,$(OBJS)) >>.depend +# +#include .depend diff --git a/src/ui/ui-drv/x11/ui_x11.c b/src/ui/ui-drv/x11/ui_x11.c new file mode 100644 index 0000000..9b5daa3 --- /dev/null +++ b/src/ui/ui-drv/x11/ui_x11.c @@ -0,0 +1,597 @@ +/* + * XaoS, a fast portable realtime fractal zoomer + * Copyright (C) 1996,1997 by + * + * Jan Hubicka (hubicka@paru.cas.cz) + * Thomas Marsh (tmarsh@austin.ibm.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include "aconfig.h" +#ifdef X11_DRIVER +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <signal.h> +#include <string.h> +#include <X11/Xlib.h> +#include <X11/cursorfont.h> +#include "xlib.h" +#ifdef MITSHM +#include <sys/ipc.h> +#include <sys/shm.h> +#include <X11/extensions/XShm.h> +#endif +#include <fconfig.h> +#include <ui.h> +xlibparam xparams = { 0, 0, 0, 0, NULL, -1 }; + +static int allocated; +Cursor normal, xwait, replay; + +struct ui_driver x11_driver; +static xdisplay *d; +static char *size; +static int Xsync; +static int busy; +static int sharedcolormap; +#if 0 +static char *selection; +#endif +#ifdef MITSHM +static int Completion; +#endif +#ifdef AMIGA +#define XFlush(x) while(0) +#endif + +static void x11_setpaletterange(ui_palette p, int s, int e) +{ + xsetpaletterange(d, p, s, e); +} + +static int x11_set_color(int r, int g, int b, int init) +{ + if (init) + xfree_colors(d); + return (xalloc_color(d, r * 256, g * 256, b * 256, init)); +} + +static void x11_print(int x, int y, CONST char *text) +{ + xmoveto(d, x, y + x11_driver.textheight - 2); + xouttext(d, text); + +} + +static void x11_flush(void) +{ + XFlush(d->display); +} + +static int display; +static int flipped = 0; +static void x11_display(void) +{ + XFlush(d->display); +#ifdef MITSHM + if (d->SharedMemFlag) { + if (busy) { + display = 1; + return; + } + busy++; + display = 0; + } +#endif + if (Xsync) + XSync(d->display, 0); + if (flipped) + xflip_buffers(d), flipped = 0; + draw_screen(d); +#ifdef MITSHM + if (d->SharedMemFlag) { + XSync(d->display, 0); + } +#endif +} + +static void x11_flip_buffers(void) +{ + flipped ^= 1; +} + +static void x11_free_buffers(char *b1, char *b2) +{ + if (allocated) { + XSync(d->display, 0); + allocated = 0; + free_image(d); + } +} + +static int x11_alloc_buffers(char **b1, char **b2) +{ + if (!allocated) { + XSync(d->display, 0); + allocated = 1; + if (!alloc_image(d)) { + return (0); + } + xflip_buffers(d); + } + *b1 = d->vbuff; + *b2 = d->back; + flipped = 0; +#if 0 + if (d->SharedMemFlag) { + x11_driver.flags |= UI_KEEP_BUFFER; + } +#endif + return (d->linewidth); +} + +static void x11_getsize(int *w, int *h) +{ + XSync(d->display, 0); + xupdate_size(d); + *w = d->width; + *h = d->height; +} + +static void x11_processevents(int wait, int *mx, int *my, int *mb, int *k) +{ + static int mousex = 100, mousey = 0; + static int iflag = 0; + static unsigned int mousebuttons = 0; + static int resized; + XEvent ev; + + + if (XPending(d->display) || busy >= 2 || wait) { + do { + XNextEvent(d->display, &ev); + switch (ev.type) { + case ClientMessage: + if ((int) ev.xclient.format == 32 + && ev.xclient.data.l[0] == wmDeleteWindow) + ui_quit(); + break; + case ButtonRelease: + mousex = ev.xbutton.x; + mousey = ev.xbutton.y; + switch (ev.xbutton.button) { + case 1: + mousebuttons &= ~BUTTON1; + break; + case 2: + mousebuttons &= ~BUTTON2; + break; + case 3: + mousebuttons &= ~BUTTON3; + break; + } + break; + case ButtonPress: + mousex = ev.xbutton.x; + mousey = ev.xbutton.y; + if (! + (mousex < 0 || mousey < 0 || mousex > (int) d->width + || mousey > (int) d->height)) { + switch (ev.xbutton.button) { + case 1: + mousebuttons |= BUTTON1; + break; + case 2: + mousebuttons |= BUTTON2; + break; + case 3: + mousebuttons |= BUTTON3; + break; + } + } + break; + case MotionNotify: + mousex = ev.xmotion.x; + mousey = ev.xmotion.y; + mousebuttons = + ev.xmotion.state & (BUTTON1 | BUTTON2 | BUTTON3); + break; + case Expose: + if (resized) + break; + x11_display(); + break; + case ResizeRequest: + XResizeWindow(d->display, d->window, + ev.xresizerequest.width, + ev.xresizerequest.height); + XResizeWindow(d->display, d->parent_window, + ev.xresizerequest.width, + ev.xresizerequest.height); + XSync(d->display, 0); + resized = 2; + ui_resize(); + resized = 0; + break; + + case ConfigureNotify: + { + int oldw = d->width, oldh = d->height; + XSync(d->display, 0); + xupdate_size(d); + if ((int) d->width != oldw || (int) d->height != oldh) { + resized = 2; + ui_resize(); + resized = 0; + } + } + break; + case KeyRelease: + { + switch (XLookupKeysym(&ev.xkey, 0)) { + case XK_Left: + iflag &= ~1; + break; + case XK_Right: + iflag &= ~2; + break; + case XK_Up: + iflag &= ~4; + break; + case XK_Down: + iflag &= ~8; + break; + } + } + break; + case KeyPress: + { + KeySym ksym; + switch (ksym = XLookupKeysym(&ev.xkey, 0)) { + case XK_Left: + iflag |= 1; + ui_key(UIKEY_LEFT); + break; + case XK_Right: + iflag |= 2; + ui_key(UIKEY_RIGHT); + break; + case XK_Up: + iflag |= 4; + ui_key(UIKEY_UP); + break; + case XK_Down: + iflag |= 8; + ui_key(UIKEY_DOWN); + break; +#ifdef XK_Page_Up + case XK_Page_Up: + iflag |= 4; + ui_key(UIKEY_PGUP); + break; + case XK_Page_Down: + iflag |= 8; + ui_key(UIKEY_PGDOWN); + break; +#endif + case XK_Escape: + ui_key(UIKEY_ESC); + case XK_BackSpace: + ui_key(UIKEY_BACKSPACE); + break; /* This statement was missing. + I'm not sure if this is needed + because new X drivers handle + UIKEY_BACKSPACE better or + double backspaces were problems + in earlier versions of XaoS, too. + -- Zoltan, 2004-10-30 */ + default: + { + CONST char *name; + char buff[256]; + if (ksym == XK_F1) + name = "h"; + else { + name = buff; + buff[XLookupString + (&ev.xkey, buff, 256, &ksym, NULL)] = + 0; + } + if (strlen(name) == 1) { + if (ui_key(*name) == 2) { + return; + } + } + } + } + } + break; + default: +#ifdef MITSHM + if (ev.xany.type == Completion) { + busy--; + if (display) + x11_display(); + } +#endif + break; + } + } + while (busy >= 2 || /*XEventsQueued (d->display, QueuedAlready) */ + XPending(d->display)); + } + *mx = mousex; + *my = mousey; + *mb = mousebuttons; + *k = iflag; +} + +/*static int defined; */ +static void x11_cursor(int mode) +{ + /*if(defined) + XUndefineCursor(d->display,d->window),defined=0; */ + switch (mode) { + case NORMALMOUSE: + XDefineCursor(d->display, d->window, normal); + /*defined=1; */ + break; + case WAITMOUSE: + XDefineCursor(d->display, d->window, xwait); + /*defined=1; */ + break; + case REPLAYMOUSE: + XDefineCursor(d->display, d->window, replay); + /*defined=1; */ + break; + } + XFlush(d->display); +} + +#if 0 +static Atom atom; +void x11_copy() +{ + if (slection) + free(selection), selection = NULL; + selection = ui_getpos(); + atom = XInternAtom(d->display, "image/x-xaos.position", False); + printf("%i\n", atom); + XSetSelectionOwner(d->display, atom, d->window, CurrentTime); +} +#endif +static int x11_init(void) +{ + if (xparams.windowid != -1) + xparams.rootwindow = xparams.fullscreen = 0; + if (xparams.fullscreen || xparams.rootwindow) + sharedcolormap = 1; /*private colormap is broken in fullscreen + mode (at least at my X) */ + xparams.privatecolormap = !sharedcolormap; + if (xparams.display == NULL) { /*solaris stuff */ + xparams.display = getenv("DISPLAY"); + } + if (size != NULL) { + int x, y; + sscanf(size, "%ix%i", &x, &y); + if (x < 0) + x = XSIZE; + if (y < 0) + y = YSIZE; + d = xalloc_display("XaoS", x, y, &xparams); + } else + d = xalloc_display("XaoS", XSIZE, YSIZE, &xparams); + if (d == NULL) + return 0; + /*normal=XCreateFontCursor(d->display,XC_arrow); */ + normal = XCreateFontCursor(d->display, XC_left_ptr); + xwait = XCreateFontCursor(d->display, XC_watch); + replay = XCreateFontCursor(d->display, XC_dot); + if (d->truecolor || d->privatecolormap) + x11_driver.flags &= ~RANDOM_PALETTE_SIZE; + if (!alloc_image(d)) { + xfree_display(d); + return (0); + } + allocated = 1; + switch (d->visual->class) { + case StaticGray: + if (d->depth == 1) { + if (BitmapBitOrder(d->display) == LSBFirst) + if (WhitePixel(d->display, d->screen)) + x11_driver.imagetype = UI_LBITMAP; + else + x11_driver.imagetype = UI_LIBITMAP; + else if (WhitePixel(d->display, d->screen)) + x11_driver.imagetype = UI_MBITMAP; + else + x11_driver.imagetype = UI_MIBITMAP; + } else { + /*Warning! this is untested. I believe it works */ + /*x11_driver.set_color = x11_set_color; */ + x11_driver.palettestart = 0; + x11_driver.paletteend = 256; + x11_driver.maxentries = 256; + x11_driver.imagetype = UI_GRAYSCALE; + } + break; + case StaticColor: + smallcolor: + { + int end = 256; + int start = 0; + int entries = d->visual->map_entries; + if (d->visual->class == TrueColor) { + entries = (int) (d->image[0]->red_mask | + d->image[0]->green_mask | + d->image[0]->blue_mask); + } + x11_driver.imagetype = UI_FIXEDCOLOR; + if (end > entries) + end = entries; + if (end < 64) + start = 0; + x11_driver.set_range = x11_setpaletterange; + x11_driver.palettestart = start; + x11_driver.paletteend = end; + x11_driver.maxentries = end - start; + } + break; + case PseudoColor: + case GrayScale: + if (d->privatecolormap) { + int end = 256; + int start = 16; + if (end > d->visual->map_entries) + end = d->visual->map_entries; + if (end < 64) + start = 0; + x11_driver.set_range = x11_setpaletterange; + x11_driver.palettestart = start; + x11_driver.paletteend = end; + x11_driver.maxentries = end - start; + } else { + int end = 256; + if (end > d->visual->map_entries) + end = d->visual->map_entries; + x11_driver.set_color = x11_set_color, x11_driver.flags |= + RANDOM_PALETTE_SIZE; + x11_driver.palettestart = 0; + x11_driver.paletteend = end; + x11_driver.maxentries = end; + } + break; + case TrueColor: + x11_driver.rmask = d->image[0]->red_mask; + x11_driver.gmask = d->image[0]->green_mask; + x11_driver.bmask = d->image[0]->blue_mask; + { + unsigned char c[4]; + int order = MSBFirst; + *(unsigned short *) c = 0xff; + if (c[0] == (unsigned char) 0xff) + order = LSBFirst; + if (order != d->image[0]->byte_order) { + int shift = 32 - d->image[0]->bits_per_pixel; +#define SWAPE(c) (((c&0xffU)<<24)|((c&0xff00U)<<8)|((c&0xff0000U)>>8)|((c&0xff000000U)>>24)) + x11_driver.rmask = SWAPE(x11_driver.rmask) >> shift; + x11_driver.gmask = SWAPE(x11_driver.gmask) >> shift; + x11_driver.bmask = SWAPE(x11_driver.bmask) >> shift; + } + } + switch (d->image[0]->bits_per_pixel) { + case 8: + goto smallcolor; + case 16: + x11_driver.imagetype = UI_TRUECOLOR16; + break; + case 24: + x11_driver.imagetype = UI_TRUECOLOR24; + break; + case 32: + x11_driver.imagetype = UI_TRUECOLOR; + break; + default: + printf("Fatal error:unsupported bits per pixel!\n"); + } + } + x11_driver.maxwidth = XDisplayWidth(d->display, d->screen); + x11_driver.maxheight = XDisplayHeight(d->display, d->screen); + x11_driver.width = + ((double) ((unsigned int) XDisplayWidthMM(d->display, d->screen))) + / x11_driver.maxwidth / 10.0; + x11_driver.height = + ((double) ((unsigned int) XDisplayHeightMM(d->display, d->screen))) + / x11_driver.maxheight / 10.0; + x11_driver.textheight = xsetfont(d, "fixed"); + x11_driver.textwidth = + d->font_struct->max_bounds.rbearing - + d->font_struct->min_bounds.lbearing; +#ifdef MITSHM + Completion = XShmGetEventBase(d->display) + ShmCompletion; +#endif + if (d->privatecolormap) { + x11_driver.flags |= PALETTE_ROTATION | ROTATE_INSIDE_CALCULATION; + } + return (1); +} + +static void x11_uninitialise(void) +{ +#if 0 + if (selection) + free(selection), selection = NULL; +#endif + xfree_colors(d); + xfree_display(d); +} + +static void x11_getmouse(int *x, int *y, int *b) +{ + int rootx, rooty; + Window rootreturn, childreturn; + XQueryPointer(d->display, d->window, + &rootreturn, &childreturn, + &rootx, &rooty, x, y, (unsigned int *) b); +} + +static CONST struct params params[] = { + {"", P_HELP, NULL, "X11 driver options:"}, + {"-display", P_STRING, &xparams.display, "Select display"}, + {"-size", P_STRING, &size, "Select size of window (WIDTHxHEIGHT)."}, + {"-sync", P_SWITCH, &Xsync, + "Generate sync signals before looking for events. This\n\t\t\thelps on old and buggy HP-UX X servers."}, + {"-shared", P_SWITCH, &sharedcolormap, + "Use shared colormap on pseudocolor display."}, + {"-usedefault", P_SWITCH, &xparams.usedefault, + "Use default visual if autodetection causes troubles."}, + {"-nomitshm", P_SWITCH, &xparams.nomitshm, + "Disable MITSHM extension."}, + {"-fullscreen", P_SWITCH, &xparams.fullscreen, + "Enable fullscreen mode."}, + {"-windowid", P_NUMBER, &xparams.windowid, "Use selected window."}, + {"-window-id", P_NUMBER, &xparams.windowid, "Use selected window."}, + {"-root", P_SWITCH, &xparams.rootwindow, "Use root window."}, + {NULL, 0, NULL, NULL} +}; + +struct ui_driver x11_driver = { + "X11", + x11_init, + x11_getsize, + x11_processevents, + x11_getmouse, + x11_uninitialise, + NULL, + NULL, + x11_print, + x11_display, + x11_alloc_buffers, + x11_free_buffers, + x11_flip_buffers, + x11_cursor, + x11_flush, + 8, + 8, + params, + RESOLUTION | PIXELSIZE | NOFLUSHDISPLAY /*| UPDATE_AFTER_RESIZE */ , + 0.0, 0.0, + 0, 0, + UI_C256, + 16, 254, 254 - 16 +}; + +#endif diff --git a/src/ui/ui-drv/x11/xlib.c b/src/ui/ui-drv/x11/xlib.c new file mode 100644 index 0000000..87308b8 --- /dev/null +++ b/src/ui/ui-drv/x11/xlib.c @@ -0,0 +1,663 @@ +/* + * XaoS, a fast portable realtime fractal zoomer + * Copyright (C) 1996,1997 by + * + * Jan Hubicka (hubicka@paru.cas.cz) + * Thomas Marsh (tmarsh@austin.ibm.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include "aconfig.h" +#ifdef X11_DRIVER +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <config.h> +#ifndef NO_MALLOC_H +#include <malloc.h> +#endif +#include "xlib.h" +#ifdef AMIGA +#define XFlush(x) while(0) +#endif + +#define chkalloc(n) if (!n) fprintf(stderr, "out of memory\n"), exit(-1) + +extern int prog_argc; +extern char **prog_argv; +Atom wmDeleteWindow; + +int xupdate_size(xdisplay * d) +{ + int tmp; + Window wtmp; + unsigned int width = d->width, height = d->height; + XSync(d->display, False); + XGetGeometry(d->display, d->window, &wtmp, &tmp, &tmp, &d->width, + &d->height, (unsigned int *) &tmp, (unsigned int *) &tmp); + if (d->width != width || d->height != height) + return 1; + return 0; +} + +void xflip_buffers(xdisplay * d) +{ + d->back = d->vbuffs[d->current]; + d->current ^= 1; + d->vbuff = d->vbuffs[d->current]; +} + + +void draw_screen(xdisplay * d) +{ +#ifdef MITSHM + if (d->SharedMemFlag) { + XShmPutImage(d->display, d->window, d->gc, d->image[d->current], 0, + 0, 0, 0, d->bwidth, d->bheight, True); + } else +#endif + XPutImage(d->display, d->window, d->gc, d->image[d->current], 0, 0, + 0, 0, d->bwidth, d->bheight); + /*XFlush(d->display); *//*gives small rest to X but degrades perofrmance + too much */ + d->screen_changed = 0; +} + +#ifdef MITSHM +int alloc_shm_image(xdisplay * new) +{ + register char *ptr; + int temp, size = 0, i; + ptr = DisplayString(new->display); + if (!ptr || (*ptr == ':') || !strncmp(ptr, "localhost:", 10) || + !strncmp(ptr, "unix:", 5) || !strncmp(ptr, "local:", 6)) { + new->SharedMemOption = + XQueryExtension(new->display, "MIT-SHM", &temp, &temp, &temp); + } else { + new->SharedMemOption = False; + return 0; + } + new->SharedMemFlag = False; + + if (new->SharedMemFlag) { + XShmDetach(new->display, &new->xshminfo[0]); + XShmDetach(new->display, &new->xshminfo[1]); + new->image[0]->data = (char *) NULL; + new->image[1]->data = (char *) NULL; + shmdt(new->xshminfo[0].shmaddr); + shmdt(new->xshminfo[1].shmaddr); + } + for (i = 0; i < 2; i++) { + if (new->SharedMemOption) { + new->SharedMemFlag = False; + new->image[i] = + XShmCreateImage(new->display, new->visual, new->depth, + new->depth == 1 ? XYBitmap : ZPixmap, NULL, + &new->xshminfo[i], new->width, + new->height); + if (new->image[i]) { + temp = + new->image[i]->bytes_per_line * + (new->image[i]->height + 150); + new->linewidth = new->image[i]->bytes_per_line; + if (temp > size) + size = temp; + new->xshminfo[i].shmid = + shmget(IPC_PRIVATE, size, IPC_CREAT | 0777); + if (new->xshminfo[i].shmid != -1) { + errno = 0; + new->xshminfo[i].shmaddr = + (char *) shmat(new->xshminfo[i].shmid, 0, 0); + if (!errno) { + new->image[i]->data = new->xshminfo[i].shmaddr; + new->data[i] = new->vbuffs[i] = + (char *) new->image[i]->data; + new->xshminfo[i].readOnly = True; + + new->SharedMemFlag = + XShmAttach(new->display, &new->xshminfo[i]); + XSync(new->display, False); + if (!new->SharedMemFlag) { + XDestroyImage(new->image[i]); + new->image[i] = (XImage *) NULL; + new->SharedMemFlag = 0; + return 0; + } + } + /* Always Destroy Shared Memory Ident */ + shmctl(new->xshminfo[i].shmid, IPC_RMID, 0); + } + if (!new->SharedMemFlag) { + XDestroyImage(new->image[i]); + new->image[i] = (XImage *) NULL; + new->SharedMemFlag = 0; + return 0; + } + } else { + new->SharedMemFlag = 0; + return 0; + } + } else { + new->SharedMemFlag = 0; + return 0; + } + } + new->current = 0; + xflip_buffers(new); + return 1; +} + +void free_shm_image(xdisplay * d) +{ + if (d->SharedMemFlag) { + XDestroyImage(d->image[0]); + XDestroyImage(d->image[1]); + XShmDetach(d->display, &d->xshminfo[0]); + XShmDetach(d->display, &d->xshminfo[1]); + shmdt(d->xshminfo[0].shmaddr); + shmdt(d->xshminfo[1].shmaddr); + } +} + +#endif + +int alloc_image(xdisplay * d) +{ + int i; + d->bwidth = d->width; + d->bheight = d->height; +#ifdef MITSHM + if (!d->params->nomitshm && d->depth != 1 && alloc_shm_image(d)) { + return 1; + } +#endif + for (i = 0; i < 2; i++) { + + d->image[i] = + XCreateImage(d->display, d->visual, d->depth, + d->depth == 1 ? XYBitmap : ZPixmap, 0, NULL, + d->width, d->height, 32, 0); + if (d->image[i] == NULL) { + printf("Out of memory for image..exiting\n"); + exit(-1); + } + d->image[i]->data = + malloc(d->image[i]->bytes_per_line * d->height); + if (d->image[i]->data == NULL) { + printf("Out of memory for image buffers..exiting\n"); + exit(-1); + } + { + unsigned char c[4]; + int byteexact = 0; + *(unsigned short *) c = 0xff; + if ((!(d->image[i]->red_mask & ~0xffU) + || !(d->image[i]->red_mask & ~0xff00U) + || !(d->image[i]->red_mask & ~0xff0000U) + || !(d->image[i]->red_mask & ~0xff000000U)) + && (!(d->image[i]->green_mask & ~0xffU) + || !(d->image[i]->green_mask & ~0xff00U) + || !(d->image[i]->green_mask & ~0xff0000U) + || !(d->image[i]->green_mask & ~0xff000000U)) + && (!(d->image[i]->blue_mask & ~0xffU) + || !(d->image[i]->blue_mask & ~0xff00U) + || !(d->image[i]->blue_mask & ~0xff0000U) + || !(d->image[i]->blue_mask & ~0xff000000U))) + byteexact = 1; + if (!byteexact) { + /*Make endianity correct */ + if (c[0] == (unsigned char) 0xff) { + if (d->image[i]->byte_order != LSBFirst) { + d->image[i]->byte_order = LSBFirst; + /*XInitImage(d->image[i]); */ + } + } else { + if (d->image[i]->byte_order != MSBFirst) { + d->image[i]->byte_order = MSBFirst; + /*XInitImage(d->image[i]); */ + } + } + } + } + d->data[i] = d->vbuffs[i] = (char *) d->image[i]->data; + d->linewidth = d->image[i]->bytes_per_line; + } + xflip_buffers(d); + return 1; +} + +void free_image(xdisplay * d) +{ +#ifdef MITSHM + if (d->SharedMemFlag) { + free_shm_image(d); + return; + } +#endif + XDestroyImage(d->image[0]); + XDestroyImage(d->image[1]); +} + +#define MAX(x,y) ((x)>(y)?(x):(y)) + + +xdisplay *xalloc_display(CONST char *s, int x, int y, xlibparam * params) +{ + xdisplay *new; + Visual *defaultvisual; + XVisualInfo vis; + int found; + int i; + + XClassHint classHint; + XWMHints *hints; + char **faked_argv; + + new = (xdisplay *) calloc(sizeof(xdisplay), 1); + chkalloc(new); + new->display = XOpenDisplay(params->display); + if (!new->display) { + free((void *) new); + return NULL; + } + new->screen = DefaultScreen(new->display); + + new->attributes = + (XSetWindowAttributes *) malloc(sizeof(XSetWindowAttributes)); + chkalloc(new->attributes); + new->attributes->background_pixel = + BlackPixel(new->display, new->screen); + new->attributes->border_pixel = BlackPixel(new->display, new->screen); + new->attributes->event_mask = ButtonPressMask | StructureNotifyMask | + ButtonReleaseMask | PointerMotionMask | KeyPressMask | + ExposureMask | KeyReleaseMask; + + + new->attr_mask = CWBackPixel | CWEventMask; + if (params->fullscreen || params->rootwindow) { + new->attributes->override_redirect = True; + new->attr_mask |= CWOverrideRedirect; + } else + new->attr_mask |= CWBorderPixel; + new->class = InputOutput; + new->xcolor.n = 0; + new->parent_window = RootWindow(new->display, new->screen); + defaultvisual = DefaultVisual(new->display, new->screen); + new->params = params; + + found = 0; + for (i = 31; i > 13 && !found; i--) + if (XMatchVisualInfo + (new->display, new->screen, i, TrueColor, &vis)) { + found = 1; + } + if (defaultvisual->class != StaticGray + && defaultvisual->class != GrayScale) { + for (i = 8; i && !found; i--) + if (XMatchVisualInfo + (new->display, new->screen, i, PseudoColor, &vis)) { + found = 1; + } + for (i = 8; i && !found; i--) + if (XMatchVisualInfo + (new->display, new->screen, i, StaticColor, &vis)) { + found = 1; + } + for (i = 8; i && !found; i--) + if (XMatchVisualInfo + (new->display, new->screen, i, TrueColor, &vis)) { + found = 1; + } + } + if (!found + && XMatchVisualInfo(new->display, new->screen, 8, StaticGray, + &vis)) { + found = 1; + } + for (i = 8; i && !found; i--) + if (XMatchVisualInfo + (new->display, new->screen, i, GrayScale, &vis)) { + found = 1; + } + if (!found + && XMatchVisualInfo(new->display, new->screen, 1, StaticGray, + &vis)) { + found = 8; + } + if (!found || params->fullscreen || params->rootwindow) { + new->visual = defaultvisual; + new->depth = DefaultDepth(new->display, new->screen); + } else { + new->visual = vis.visual; + new->depth = vis.depth; + } + + switch (new->visual->class) { + case StaticColor: + case StaticGray: + smallcolor: + new->truecolor = 0; + new->fixedcolormap = 1; + break; + case PseudoColor: + case GrayScale: + if (new->depth <= 8) { + new->truecolor = 0; + new->fixedcolormap = 0; + } else { + goto visuals; + } + break; + case TrueColor: + new->truecolor = 1; + new->fixedcolormap = 1; + if (new->depth <= 8) + goto smallcolor; + if (new->depth > 32) { + goto visuals; + } + break; + default: + visuals: + printf + ("Unusuported visual. Please contact authors. Maybe it will be supported in next release:)\n"); + return (NULL); + } + new->privatecolormap = params->privatecolormap; + new->attributes->colormap = new->defaultcolormap = + DefaultColormap(new->display, new->screen); + if (new->visual->visualid != defaultvisual->visualid) { + new->privatecolormap = 1; + } + if ( /*!new->fixedcolormap && */ new->privatecolormap) { + unsigned long pixels[256]; + int i; + new->attributes->colormap = + XCreateColormap(new->display, + RootWindow(new->display, new->screen), + new->visual, AllocNone); + if (new->visual->visualid == defaultvisual->visualid + && new->visual->class == PseudoColor) { + XAllocColorCells(new->display, new->attributes->colormap, 1, 0, + 0, pixels, MAX(new->visual->map_entries, + 256)); + for (i = 0; i < 16; i++) { + new->xcolor.c[i].pixel = pixels[i]; + } + XQueryColors(new->display, new->defaultcolormap, new->xcolor.c, + 16); + XStoreColors(new->display, new->attributes->colormap, + new->xcolor.c, 16); + } + } + new->colormap = new->attributes->colormap; + new->attr_mask |= CWColormap; + + new->window_name = (char *) s; + new->height = y; + new->width = x; + new->border_width = 2; + new->lastx = 0; + new->lasty = 0; + new->font_struct = (XFontStruct *) NULL; + + if (params->fullscreen || params->rootwindow) { + Window wtmp; + int tmp; + /* Get size of the root window */ + XGetGeometry(new->display, RootWindow(new->display, new->screen), &wtmp, &tmp, &tmp, &new->width, &new->height, (unsigned int *) &tmp, /* border width */ + (unsigned int *) &tmp); /* depth */ + new->border_width = 0; + } + + if (params->windowid != -1) { + Window wtmp; + int tmp; + + new->parent_window = params->windowid; + XGetGeometry(new->display, new->parent_window, &wtmp, &tmp, &tmp, &new->width, &new->height, (unsigned int *) &tmp, /* border width */ + (unsigned int *) &tmp); /* depth */ + XSelectInput(new->display, new->parent_window, ResizeRedirectMask); + } + if (params->rootwindow) + new->window = RootWindow(new->display, new->screen); + else + new->window = XCreateWindow(new->display, new->parent_window, 0, 0, + new->width, new->height, + new->border_width, new->depth, + new->class, new->visual, + new->attr_mask, new->attributes); + + classHint.res_name = (char *) "xaos"; + classHint.res_class = (char *) "XaoS"; + hints = XAllocWMHints(); + hints->initial_state = NormalState; + hints->window_group = new->window; + hints->flags = (WindowGroupHint | StateHint); + + { + int fake = 0; + + if (prog_argc < 2) + fake = 1; + + if (fake == 0) + if (strcmp(prog_argv[prog_argc - 2], "-driver") && + strcmp(prog_argv[prog_argc - 1], "x11")) + fake = 1; + + if (fake) { + int i; + faked_argv = + (char **) malloc((prog_argc + 2) * sizeof(char *)); + for (i = 0; i < prog_argc; i++) + faked_argv[i] = prog_argv[i]; + faked_argv[prog_argc] = (char *) "-driver"; + faked_argv[prog_argc + 1] = (char *) "x11"; + + XSetWMProperties(new->display, new->window, NULL, NULL, + faked_argv, prog_argc + 2, NULL, hints, + &classHint); + + free(faked_argv); + } else + XSetWMProperties(new->display, new->window, NULL, NULL, + prog_argv, prog_argc, NULL, hints, + &classHint); + } + XSetIconName(new->display, new->window, "xaos"); + + wmDeleteWindow = XInternAtom(new->display, "WM_DELETE_WINDOW", False); + XSetWMProtocols(new->display, new->window, &wmDeleteWindow, 1); + + new->gc = XCreateGC(new->display, new->window, 0L, &(new->xgcvalues)); + XSetBackground(new->display, new->gc, + BlackPixel(new->display, new->screen)); + XSetForeground(new->display, new->gc, + WhitePixel(new->display, new->screen)); + XStoreName(new->display, new->window, new->window_name); + XMapWindow(new->display, new->window); + if (params->fullscreen || params->rootwindow) + XSetInputFocus(new->display, new->window, RevertToNone, + CurrentTime); + + return (new); +} + +void xsetcolor(xdisplay * d, int col) +{ + switch (col) { + case 0: + XSetForeground(d->display, d->gc, + BlackPixel(d->display, d->screen)); + break; + case 1: + XSetForeground(d->display, d->gc, + WhitePixel(d->display, d->screen)); + break; + default: + if ((col - 2) > d->xcolor.n) { + fprintf(stderr, "color error\n"); + exit(-1); + } + XSetForeground(d->display, d->gc, d->xcolor.c[col - 2].pixel); + break; + } +} + +void xsetpaletterange(xdisplay * d, ui_palette c, int start, int end) +{ + int i; + if (d->visual->class == StaticColor || d->visual->class == TrueColor) { + for (i = start; i < end; i++) + d->xcolor.c[i].pixel = i; + XQueryColors(d->display, d->colormap, d->xcolor.c + start, + end - start); + for (i = start; i < end; i++) { + c[i - start][0] = d->xcolor.c[i].red / 256; + c[i - start][1] = d->xcolor.c[i].green / 256; + c[i - start][2] = d->xcolor.c[i].blue / 256; + } + + } else { + for (i = start; i < end; i++) { + d->xcolor.c[i].pixel = i; + d->xcolor.c[i].flags = DoRed | DoGreen | DoBlue; + d->xcolor.c[i].red = c[i - start][0] * 256; + d->xcolor.c[i].green = c[i - start][1] * 256; + d->xcolor.c[i].blue = c[i - start][2] * 256; + } + XStoreColors(d->display, d->colormap, d->xcolor.c + start, + end - start); + } +} + +int xalloc_color(xdisplay * d, int r, int g, int b, int readwrite) +{ + d->xcolor.n++; + d->xcolor.c[d->xcolor.n - 1].flags = DoRed | DoGreen | DoBlue; + d->xcolor.c[d->xcolor.n - 1].red = r; + d->xcolor.c[d->xcolor.n - 1].green = g; + d->xcolor.c[d->xcolor.n - 1].blue = b; + d->xcolor.c[d->xcolor.n - 1].pixel = d->xcolor.n - 1; + if ((readwrite && !d->fixedcolormap) || d->privatecolormap) { + unsigned long cell; + if (d->privatecolormap) { + cell = d->xcolor.c[d->xcolor.n - 1].pixel += 16; + if ((int) d->xcolor.c[d->xcolor.n - 1].pixel >= + d->visual->map_entries) { + d->xcolor.n--; + return (-1); + } + } else { + if (!XAllocColorCells + (d->display, d->colormap, 0, 0, 0, &cell, 1)) { + d->xcolor.n--; + if (d->xcolor.n <= 32) + printf + ("Colormap is too full! close some colorfull applications or use -private\n"); + return (-1); + } + d->xcolor.c[d->xcolor.n - 1].pixel = cell; + } + XStoreColor(d->display, d->colormap, + &(d->xcolor.c[d->xcolor.n - 1])); + return ((int) cell); + } + if (!XAllocColor + (d->display, d->colormap, &(d->xcolor.c[d->xcolor.n - 1]))) { + d->xcolor.n--; + if (d->xcolor.n <= 32) + printf + ("Colormap is too full! close some colorfull aplications or use -private\n"); + return (-1); + } + d->pixels[d->xcolor.n - 1] = d->xcolor.c[d->xcolor.n - 1].pixel; + return (d->depth != + 8 ? d->xcolor.n - 1 : (int) d->xcolor.c[d->xcolor.n - + 1].pixel); +} + +void xfree_colors(xdisplay * d) +{ + unsigned long pixels[256]; + int i; + for (i = 0; i < d->xcolor.n; i++) + pixels[i] = d->xcolor.c[i].pixel; + if (!d->privatecolormap) + XFreeColors(d->display, d->colormap, pixels, d->xcolor.n, 0); + d->xcolor.n = 0; +} + +void xfree_display(xdisplay * d) +{ + XSync(d->display, 0); + if (d->font_struct != (XFontStruct *) NULL) { + XFreeFont(d->display, d->font_struct); + } + XUnmapWindow(d->display, d->window); + XDestroyWindow(d->display, d->window); + XCloseDisplay(d->display); + free((void *) d->attributes); + free((void *) d); +} + +void xclear_screen(xdisplay * d) +{ + XClearWindow(d->display, d->window); + d->screen_changed = 1; +} + +void xmoveto(xdisplay * d, int x, int y) +{ + d->lastx = x, d->lasty = y; +} + +int xsetfont(xdisplay * d, CONST char *font_name) +{ + + if (d->font_struct != (XFontStruct *) NULL) { + XFreeFont(d->display, d->font_struct); + } + d->font_struct = XLoadQueryFont(d->display, font_name); + XSetFont(d->display, d->gc, d->font_struct->fid); + if (!d->font_struct) { + fprintf(stderr, "could not load font: %s\n", font_name); + exit(-1); + } + return (d->font_struct->max_bounds.ascent + + d->font_struct->max_bounds.descent); +} + +void xouttext(xdisplay * d, CONST char *string) +{ + int sz; + + sz = (int) strlen(string); + XDrawImageString(d->display, d->window, d->gc, d->lastx, d->lasty, + string, sz); +} + +void xresize(xdisplay * d, XEvent * ev) +{ + XSync(d->display, False); + d->width = ev->xconfigure.width; + d->height = ev->xconfigure.height; +} + +#endif diff --git a/src/ui/ui-drv/x11/xlib.h b/src/ui/ui-drv/x11/xlib.h new file mode 100644 index 0000000..485a032 --- /dev/null +++ b/src/ui/ui-drv/x11/xlib.h @@ -0,0 +1,139 @@ +/* + * XaoS, a fast portable realtime fractal zoomer + * Copyright (C) 1996,1997 by + * + * Jan Hubicka (hubicka@paru.cas.cz) + * Thomas Marsh (tmarsh@austin.ibm.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef XAOS_X11_H +#define XAOS_X11_H + +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/keysym.h> +#include <X11/keysymdef.h> +#include "config.h" +#include "ui.h" +#ifdef MITSHM +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <X11/extensions/XShm.h> +#endif /* MITSHM */ + +typedef struct { + int n; + XColor c[256]; +} xcol_t; + +typedef struct { + int privatecolormap; + int usedefault; + int nomitshm; + int fullscreen; + char *display; + int windowid; + int rootwindow; +} xlibparam; + +typedef struct { + Colormap colormap; + Colormap defaultcolormap; + int fixedcolormap; + int privatecolormap; + xlibparam *params; + Display *display; + Window parent_window; + Window window; + unsigned int width, height; + unsigned int bwidth, bheight; + unsigned int border_width; + unsigned long background; + int depth; + unsigned int class; + Visual *visual; + unsigned long valuemask; + XSetWindowAttributes *attributes; + unsigned long attr_mask; + XSizeHints sizehints; + int screen; + char *window_name; + int status; + GC gc; + XGCValues xgcvalues; + xcol_t xcolor; + Pixmap pixmap; + XFontStruct *font_struct; + int screen_changed; + int lastx, lasty; + int mouse_x, mouse_y; + unsigned int mouse_buttons; + int current; + XImage *image[2]; +#ifdef MITSHM + XShmSegmentInfo xshminfo[2]; + int SharedMemOption; + int SharedMemFlag; +#endif /* MITSHM */ + unsigned long pixels[256]; + char *vbuffs[2]; + char *data[2]; + char *vbuff; + char *back; + int truecolor; + int linewidth; +} xdisplay; + +void xsetpaletterange(xdisplay * d, ui_palette c, int start, int end); +extern int alloc_shm_image(xdisplay * d); +extern void free_shm_image(xdisplay * d); +extern int alloc_image(xdisplay * d); +extern void free_image(xdisplay * d); +extern int xupdate_size(xdisplay * d); +extern void xflip_buffers(xdisplay * d); +extern xdisplay *xalloc_display(CONST char *n, int x, int y, + xlibparam * p); +extern void xfree_display(xdisplay * d); +extern void xsetcolor(xdisplay * d, int col); +extern int xsetfont(xdisplay * d, CONST char *font_name); +extern int xalloc_color(xdisplay * d, int r, int g, int b, int readwrite); +extern void xfree_colors(xdisplay * d); +extern void xline(xdisplay * d, int x1, int y1, int x2, int y2); +extern void xmoveto(xdisplay * d, int x, int y); +extern void xlineto(xdisplay * d, int x, int y); +extern void xrect(xdisplay * d, int x1, int y1, int x2, int y2); +extern void xfillrect(xdisplay * d, int x1, int y1, int x2, int y2); +extern void xarc(xdisplay * d, int x, int y, unsigned int w, + unsigned int h, int a1, int a2); +extern void xfillarc(xdisplay * d, int x, int y, unsigned int w, + unsigned int h, int a1, int a2); +extern void xpoint(xdisplay * d, int x, int y); +extern void xflush(xdisplay * d); +extern void xclear_screen(xdisplay * d); +extern void xrotate_palette(xdisplay * d, int direction, + unsigned char c[3][256], int ncolors); +extern void draw_screen(xdisplay * d); +extern void xouttext(xdisplay * d, CONST char *string); +extern void xresize(xdisplay * d, XEvent * ev); +extern int xmouse_x(xdisplay * d); +extern int xmouse_y(xdisplay * d); +extern void xmouse_update(xdisplay * d); +extern unsigned int xmouse_buttons(xdisplay * d); + +extern Atom wmDeleteWindow; + +#endif /* XAOS_X11_H */ |