From e2de64d6f1beb9e492daf5b886e19933c1fa41dd Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdemultimedia@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- kscd/kscdmagic/xlib.c | 781 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 781 insertions(+) create mode 100644 kscd/kscdmagic/xlib.c (limited to 'kscd/kscdmagic/xlib.c') diff --git a/kscd/kscdmagic/xlib.c b/kscd/kscdmagic/xlib.c new file mode 100644 index 00000000..2fb15c19 --- /dev/null +++ b/kscd/kscdmagic/xlib.c @@ -0,0 +1,781 @@ +/* + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * + * Shamelessly ripped for use in xsynaesthesia + */ +/*#include "aconfig.h"*/ +#define X11_DRIVER +/*#define MITSHM*/ + +#ifdef X11_DRIVER +#include +#include +#include +#include +#include +#include +#ifndef __FreeBSD__ +#include +#else +#include +#endif +#include "xlib.h" +#ifdef AMIGA +#define XFlush(x) while(0) +#endif + +#undef PIXMAP + +#define chkalloc(n) if (!n) fprintf(stderr, "out of memory\n"), exit(-1) + +int xupdate_size(xdisplay * d) +{ + int tmp; + Window wtmp; + int width = d->width, height = d->height; + XGetGeometry(d->display, d->window, &wtmp, &tmp, &tmp, &d->width, &d->height, (unsigned int *) &tmp, (unsigned int *) &tmp); + if ((int)d->width != width || (int)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) +{ + switch (d->image[0]->bits_per_pixel) { + case 16:{ + unsigned short *de; + unsigned char *s; + unsigned char *e; + for (s = (unsigned char *) d->vbuffs[d->current], + e = (unsigned char *) d->vbuffs[d->current] + (d->linewidth * d->height), + de = (unsigned short *) d->data[d->current]; s < e; s += 8, de += 8) + *de = d->pixels[*s], + *(de + 1) = d->pixels[*(s + 1)], + *(de + 2) = d->pixels[*(s + 2)], + *(de + 3) = d->pixels[*(s + 3)], + *(de + 4) = d->pixels[*(s + 4)], + *(de + 5) = d->pixels[*(s + 5)], + *(de + 6) = d->pixels[*(s + 6)], + *(de + 7) = d->pixels[*(s + 7)]; + s -= 8; + de -= 8; + for (; s < e; s++, de++) + *de = d->pixels[*s]; + break; + } + case 24:{ + unsigned char *de; + unsigned char *s; + unsigned char *e; + for (s = (unsigned char *) d->vbuffs[d->current], + e = (unsigned char *) d->vbuffs[d->current] + (d->linewidth * d->height), + de = (unsigned char *) d->data[d->current]; s < e; s++, de+=3) + de[0] = d->pixels[*s], + de[1] = d->pixels[*s]>>8, + de[2] = d->pixels[*s]>>16; + + break; + } + case 32:{ + unsigned long *de; + unsigned char *s; + unsigned char *e; + for (s = (unsigned char *) d->vbuffs[d->current], + e = (unsigned char *) d->vbuffs[d->current] + (d->linewidth * d->height), + de = (unsigned long *) d->data[d->current]; s < e; s += 8, de += 8) + *de = d->pixels[*s], + *(de + 1) = d->pixels[*(s + 1)], + *(de + 2) = d->pixels[*(s + 2)], + *(de + 3) = d->pixels[*(s + 3)], + *(de + 4) = d->pixels[*(s + 4)], + *(de + 5) = d->pixels[*(s + 5)], + *(de + 6) = d->pixels[*(s + 6)], + *(de + 7) = d->pixels[*(s + 7)]; + s -= 8; + de -= 8; + for (; s < e; s++, de++) + *de = d->pixels[*s]; + break; + } + } +#ifdef MITSHM + if (d->SharedMemFlag) { + XShmPutImage(d->display, d->window, d->gc, d->image[d->current], 0, 0, 0, + 0, d->width, d->height, True); + XFlush(d->display); + } else +#endif + { + XPutImage(d->display, d->window, d->gc, d->image[d->current], 0, 0, 0, 0, d->width, d->height); + XFlush(d->display); + } + 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 0 + new->SharedMemOption = True; + new->SharedMemFlag = False; +#endif + + 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) { + int mul; + if (new->depth == 8) + mul = 1; + else if (new->depth <= 24) + mul = 2; + else + mul = 4; + new->SharedMemFlag = False; + new->image[i] = XShmCreateImage(new->display, new->visual, new->depth, ZPixmap, + NULL, &new->xshminfo[i], new->width, new->height * mul); + if (new->image[i]) { + temp = new->image[i]->bytes_per_line * new->image[i]->height; + new->linewidth = new->image[i]->bytes_per_line * 8 / new->image[i]->bits_per_pixel; + if (temp > size) + size = temp; + new->xshminfo[i].shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | 0777); + if (new->xshminfo[i].shmid != -1) { + new->xshminfo[i].shmaddr = (char *) shmat(new->xshminfo[i].shmid, 0, 0); + if (new->xshminfo[i].shmaddr != (char *) -1) { + 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; +#ifdef MITSHM + if (!d->params->nomitshm && alloc_shm_image(d)) { + if (d->depth != 8) { + for (i = 0; i < 2; i++) + d->vbuffs[i] = malloc(d->linewidth * d->height); + } + return 1; + } +#endif + for (i = 0; i < 2; i++) { + d->image[i] = XCreateImage(d->display, d->visual, d->depth, ZPixmap, 0, + NULL, d->width, d->height, 8, 0); + if (d->image[i] == NULL) { + printf("Out of memory for image..exiting\n"); + exit(3); + } + /*Add a little extra memory to catch overruns when dumping image to buffer in draw_screen*/ + d->image[i]->data = malloc(d->image[i]->bytes_per_line * d->height + 32); + memset(d->image[i]->data,0,d->image[i]->bytes_per_line * d->height); + + if (d->image[i]->data == NULL) { + printf("Out of memory for image buffers..exiting\n"); + exit(3); + } + d->data[i] = d->vbuffs[i] = (char *) d->image[i]->data; + d->linewidth = d->image[i]->bytes_per_line * 8 / d->image[i]->bits_per_pixel; + } + if (d->depth != 8) { + for (i = 0; i < 2; i++) { + /* Add a little extra memory to catch overruns */ + /* when dumping image to buffer in draw_screen */ + d->vbuffs[i] = malloc(d->linewidth * d->height + 32); + memset(d->vbuffs[i],0,d->linewidth * d->height); + + if (d->vbuffs[i] == NULL) { + printf("Out of memory for image buffers2..exiting\n"); + exit(3); + } + } + } + xflip_buffers(d); + return 1; +} + +void free_image(xdisplay * d) +{ + if (d->depth != 8) + free(d->vbuffs[0]), free(d->vbuffs[1]); +#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 xHint, int yHint, int x, int y, xlibparam * params) +{ + xdisplay *xd; + Visual *defaultvisual; + XVisualInfo vis; + + + xd = (xdisplay *) calloc(sizeof(xdisplay), 1); + chkalloc(xd); + xd->display = XOpenDisplay((char *) NULL); + if (!xd->display) { + free((void *) xd); + return NULL; + } + xd->screen = DefaultScreen(xd->display); + xd->attributes = (XSetWindowAttributes *) + malloc(sizeof(XSetWindowAttributes)); + chkalloc(xd->attributes); + xd->attributes->background_pixel = BlackPixel(xd->display, + xd->screen); + xd->attributes->border_pixel = BlackPixel(xd->display, xd->screen); + xd->attributes->event_mask = ButtonPressMask | StructureNotifyMask | ButtonReleaseMask | ButtonMotionMask | KeyPressMask | ExposureMask | KeyReleaseMask; + xd->attributes->override_redirect = False; + xd->attr_mask = CWBackPixel | CWBorderPixel | CWEventMask; + xd->classX = InputOutput; + xd->xcolor.n = 0; + xd->parent_window = RootWindow(xd->display, xd->screen); + defaultvisual = DefaultVisual(xd->display, xd->screen); + xd->params = params; + if (!params->usedefault) { + if (defaultvisual->class != PseudoColor || (!XMatchVisualInfo(xd->display, xd->screen, 8, PseudoColor, &vis) && vis.colormap_size > 128)) { + xd->fixedcolormap = 1; + if (!XMatchVisualInfo(xd->display, xd->screen, 15, TrueColor, &vis)) { + if (!XMatchVisualInfo(xd->display, xd->screen, 16, TrueColor, &vis)) { + if (!XMatchVisualInfo(xd->display, xd->screen, 32, TrueColor, &vis) && + !XMatchVisualInfo(xd->display, xd->screen, 24, TrueColor, &vis)) { + if (!XMatchVisualInfo(xd->display, xd->screen, 8, PseudoColor, &vis) && + !XMatchVisualInfo(xd->display, xd->screen, 7, PseudoColor, &vis)) { + if (!XMatchVisualInfo(xd->display, xd->screen, 8, TrueColor, &vis) && + !XMatchVisualInfo(xd->display, xd->screen, 8, StaticColor, &vis) && + !XMatchVisualInfo(xd->display, xd->screen, 8, StaticGray, &vis)) { + printf("Display does not support PseudoColor depth 7,8,StaticColor depth 8, StaticGray depth 8, Truecolor depth 8,15,16,24 nor 32!\n"); + return NULL; + } else + xd->truecolor = 1; + } else + xd->fixedcolormap = 0, xd->truecolor = 0; + } else + xd->truecolor = 1; + } else + xd->truecolor = 1; + } else + xd->truecolor = 1; + } else { + xd->truecolor = 0; + } + xd->depth = vis.depth; + xd->visual = vis.visual; + } else { /*usedefault */ + vis.depth = xd->depth = DefaultDepth(xd->display, xd->screen); + xd->visual = defaultvisual; + switch (defaultvisual->class) { + case PseudoColor: + if (xd->depth <= 8) { + xd->depth = 8; + xd->truecolor = 0; + xd->fixedcolormap = 0; + } else { + printf("Pseudocolor visual on unsuported depth\n"); + return NULL; + } + break; + case TrueColor: + case StaticColor: + case StaticGray: + xd->truecolor = 1; + xd->fixedcolormap = 1; + if (xd->depth <= 8) + xd->depth = 8; + else if (xd->depth <= 16) + xd->depth = 16; + else if (xd->depth <= 32) + xd->depth = 32; + else { + printf("Truecolor visual on unsuported depth\n"); + return NULL; + } + break; + default: + printf("Unusuported visual\n"); + break; + } + } + /*xd->visual->map_entries = 256; */ + xd->colormap = xd->defaultcolormap = DefaultColormap(xd->display, xd->screen); + + xd->window_name = s; + xd->height = y; + xd->width = x; + xd->border_width = 2; + xd->lastx = 0; + xd->lasty = 0; + xd->font_struct = (XFontStruct *) NULL; + + xd->window = XCreateWindow(xd->display, xd->parent_window, xHint, yHint, + xd->width, xd->height, xd->border_width, + vis.depth, xd->classX, xd->visual, + xd->attr_mask, xd->attributes); + if (!xd->fixedcolormap && params->privatecolormap) { + unsigned long pixels[256]; + int i; + xd->colormap = XCreateColormap(xd->display, xd->window, xd->visual, AllocNone); + XAllocColorCells(xd->display, xd->colormap, 1, 0, 0, pixels, MAX(xd->visual->map_entries, 256)); + for (i = 0; i < 16; i++) { + xd->xcolor.c[i].pixel = pixels[i]; + } + XQueryColors(xd->display, xd->defaultcolormap, xd->xcolor.c, 16); + XStoreColors(xd->display, xd->colormap, xd->xcolor.c, 16); + xd->privatecolormap = 1; + } + if (!xd->fixedcolormap) + XSetWindowColormap(xd->display, xd->window, xd->colormap); + xd->gc = XCreateGC(xd->display, xd->window, 0L, &(xd->xgcvalues)); + XSetBackground(xd->display, xd->gc, + BlackPixel(xd->display, xd->screen)); + XSetForeground(xd->display, xd->gc, + WhitePixel(xd->display, xd->screen)); + XStoreName(xd->display, xd->window, xd->window_name); + XMapWindow(xd->display, xd->window); +#if 1 + XSelectInput(xd->display, xd->window, + /* ExposureMask | */ + KeyPress | + /* KeyRelease | */ + /* ConfigureRequest | */ + /* FocusChangeMask | */ + StructureNotifyMask | + ButtonPressMask | ButtonReleaseMask); +#endif +#ifdef PIXAMP + xd->pixmap = XCreatePixmap(xd->display, xd->window, xd->width, + xd->height, xd->depth); +#endif + + { + XColor c; + Pixmap p = XCreatePixmap(xd->display, xd->window, 1,1,1); + memset(&c,0,sizeof(c)); + xd->cursor = XCreatePixmapCursor(xd->display, p,p, + &c,&c, 0,0); + /* We don't need no fancy cursor + XDefineCursor(xd->display,xd->window,xd->cursor); + */ + XFreePixmap(xd->display, p); + } + + return (xd); +} + +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(3); + } + XSetForeground(d->display, d->gc, + d->xcolor.c[col - 2].pixel); + break; + } +} +void xrotate_palette(xdisplay * d, int direction, unsigned char co[3][256], int ncolors) +{ + int i, p; + + if (d->privatecolormap) { + for (i = 0; i < d->xcolor.n; i++) { + p = d->xcolor.c[i].pixel; + d->xcolor.c[i].red = (int) co[0][p] * 256; + d->xcolor.c[i].green = (int) co[1][p] * 256; + d->xcolor.c[i].blue = (int) co[2][p] * 256; + } + XStoreColors(d->display, d->colormap, d->xcolor.c, d->xcolor.n); + } + if (d->truecolor) { + unsigned long oldpixels[256]; + memcpy(oldpixels, d->pixels, sizeof(oldpixels)); + p = (ncolors - 1 + direction) % (ncolors - 1) + 1; + for (i = 1; i < ncolors; i++) { /*this is ugly..I know */ + d->pixels[i] = oldpixels[p]; + p++; + if (p >= ncolors) + p = 1; + } + draw_screen(d); + } +} +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 (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 aplications 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 (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 : 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); +#ifdef PIXMAP + XFreePixmap(d->display, d->pixmap); +#endif + XDestroyWindow(d->display, d->window); + XFreeCursor(d->display, d->cursor); + XCloseDisplay(d->display); + free((void *) d->attributes); + free((void *) d); +} + +#ifdef PIXMAP +void xline(xdisplay * d, int x1, int y1, int x2, int y2) +{ + XDrawLine(d->display, d->pixmap, d->gc, x1, y1, x2, y2); + d->lastx = x2, d->lasty = y2; + d->screen_changed = 1; +} void xlineto(xdisplay * d, int x, int y) +{ + + XDrawLine(d->display, d->pixmap, d->gc, d->lastx, d->lasty, x, y); + d->lastx = x, d->lasty = y; + d->screen_changed = 1; +} void xrect(xdisplay * d, int x1, int y1, int x2, int y2) +{ + + XDrawRectangle(d->display, d->pixmap, d->gc, x1, y1, + (x2 - x1), (y2 - y1)); + d->lastx = x2, d->lasty = y2; + d->screen_changed = 1; +} void xfillrect(xdisplay * d, int x1, int y1, int x2, int y2) +{ + + XFillRectangle(d->display, d->pixmap, d->gc, x1, y1, + (x2 - x1), (y2 - y1)); + d->lastx = x2, d->lasty = y2; + d->screen_changed = 1; +} void xpoint(xdisplay * d, int x, int y) +{ + + XDrawPoint(d->display, d->pixmap, d->gc, x, y); + d->lastx = x, d->lasty = y; + d->screen_changed = 1; +} void xflush(xdisplay * d) +{ + + draw_screen(d); + XFlush(d->display); +} + +void xclear_screen(xdisplay * d) +{ + xfillrect(d, 0, 0, d->width, d->height); + d->screen_changed = 1; +} + +#endif +void xmoveto(xdisplay * d, int x, int y) +{ + d->lastx = x, d->lasty = y; +} int xsetfont(xdisplay * d, char *font_name) +{ + + if (d->font_struct != (XFontStruct *) NULL) { + XFreeFont(d->display, d->font_struct); + } + d->font_struct = XLoadQueryFont(d->display, font_name); + if (!d->font_struct) { + fprintf(stderr, "could not load font: %s\n", font_name); + exit(3); + } + return (d->font_struct->max_bounds.ascent + d->font_struct->max_bounds.descent); +} + +void xouttext(xdisplay * d, char *string) +{ + int sz; + + sz = strlen(string); + XDrawImageString(d->display, d->window, d->gc, d->lastx, d->lasty, + string, sz); +#if 0 + d->lastx += XTextWidth(d->font_struct, string, sz); + d->screen_changed = 1; +#endif +} void xresize(xdisplay * d, XEvent * ev) +{ + +#ifdef PIXMAP + XFreePixmap(d->display, d->pixmap); +#endif + d->width = ev->xconfigure.width; + d->height = ev->xconfigure.height; +#ifdef PIXMAP + d->pixmap = XCreatePixmap(d->display, d->window, d->width, + d->height, d->depth); +#endif +} + +#ifdef PIXMAP +void xarc(xdisplay * d, int x, int y, unsigned int w, + unsigned int h, int a1, int a2) +{ + XDrawArc(d->display, d->pixmap, d->gc, x, y, w, h, a1, a2); +} void xfillarc(xdisplay * d, int x, int y, unsigned int w, + unsigned int h, int a1, int a2) +{ + XFillArc(d->display, d->pixmap, d->gc, x, y, w, h, a1, a2); +} +#endif + +void xsize_set(xdisplay *d, int width, int height) +{ + XResizeWindow(d->display, d->window, width, height); +} + +int xmouse_x(xdisplay * d) +{ + + return d->mouse_x; +} + +int xmouse_y(xdisplay * d) +{ + return d->mouse_y; +} + +void xmouse_update(xdisplay * d) +{ + Window rootreturn, childreturn; + int rootx = 0, rooty = 0, buttons = 0; + + XEvent event; + + if (XCheckMaskEvent(d->display,ButtonPressMask | ButtonReleaseMask, &event)) { + if (event.type == ButtonPress) + d->mouse_buttons |= 1 << ((XButtonEvent*)(&event))->button; + else + d->mouse_buttons &= ~( 1 << ((XButtonEvent*)(&event))->button ); + } + + XQueryPointer(d->display, d->window, &rootreturn, &childreturn, + &rootx, &rooty, &(d->mouse_x), &(d->mouse_y), + &buttons); +} + +char xkeyboard_query(xdisplay * d) { + XEvent event; + + if (XCheckMaskEvent(d->display,KeyPressMask | KeyReleaseMask, &event)) { + char *str = + XKeysymToString(XLookupKeysym((XKeyPressedEvent*)(&event),0)); + + if ( ((XKeyPressedEvent*)(&event))->state & + (ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask) ) + return 0; + + if (str) { + char key; + + if (strlen(str) == 1) + key = str[0]; + else if (strcmp(str,"equal") == 0) + key = '='; + else if (strcmp(str,"minus") == 0) + key = '-'; + else if (strcmp(str,"bracketleft") == 0) + key = '['; + else if (strcmp(str,"bracketright") == 0) + key = ']'; + else if (strcmp(str,"comma") == 0) + key = ','; + else if (strcmp(str,"period") == 0) + key = '.'; + else if (strcmp(str,"slash") == 0) + key = '/'; + else return 0; + + if ( ((XKeyPressedEvent*)(&event))->state & ShiftMask ) + switch(key) { + case '=' : key = '+'; break; + case '[' : key = '{'; break; + case ']' : key = '}'; break; + case ',' : key = '<'; break; + case '/' : key = '?'; break; + default : + if (key >= 'a' && key <= 'z') + key = key+'A'-'a'; + break; + } + return key; + } + } + + return 0; +} + +int xsize_update(xdisplay *d,int *width,int *height) { + XEvent event; + + if (XCheckMaskEvent(d->display,StructureNotifyMask, &event)) { + if (event.type == ConfigureNotify) { + xupdate_size(d); + free_image(d); + alloc_image(d); + *width = d->linewidth; + *height = d->height; + return 1; + } + } + + return 0; +} + +unsigned int xmouse_buttons(xdisplay * d) +{ + return d->mouse_buttons; +} +#endif -- cgit v1.2.1