[Git]Ignore work files.
[synaesthesia.git] / xlib.c
blobdff2abb9490040adad02598c2cfe1ea595e47b6f
1 /*
2 * XaoS, a fast portable realtime fractal zoomer
3 * Copyright (C) 1996,1997 by
5 * Jan Hubicka (hubicka@paru.cas.cz)
6 * Thomas Marsh (tmarsh@austin.ibm.com)
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * Shamelessly ripped for use in xsynaesthesia
25 #include "config.h"
26 #ifndef X_DISPLAY_MISSING
28 #define X11_DRIVER
29 //#define MITSHM
31 #ifdef X11_DRIVER
32 #include <X11/Xlib.h>
33 #include <X11/Xutil.h>
34 #include <X11/cursorfont.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdint.h>
38 #include <string.h>
39 #ifndef __FreeBSD__
40 #include <malloc.h>
41 #else
42 #include <stdlib.h>
43 #endif
44 #include "xlib.h"
45 #ifdef AMIGA
46 #define XFlush(x) while(0)
47 #endif
49 #undef PIXMAP
51 #define chkalloc(n) if (!n) fprintf(stderr, "out of memory\n"), exit(-1)
53 int xupdate_size(xdisplay * d)
55 int tmp;
56 Window wtmp;
57 int width = d->width, height = d->height;
58 XGetGeometry(d->display, d->window, &wtmp, &tmp, &tmp, &d->width, &d->height, (unsigned int *) &tmp, (unsigned int *) &tmp);
59 if (d->width != width || d->height != height)
60 return 1;
61 return 0;
64 void xflip_buffers(xdisplay * d)
66 d->back = d->vbuffs[d->current];
67 d->current ^= 1;
68 d->vbuff = d->vbuffs[d->current];
71 void draw_screen(xdisplay * d)
73 switch (d->image[0]->bits_per_pixel) {
74 case 16:{
75 uint16_t *de;
76 unsigned char *s;
77 unsigned char *e;
78 for (s = (unsigned char *) d->vbuffs[d->current],
79 e = (unsigned char *) d->vbuffs[d->current] + (d->linewidth * d->height),
80 de = (unsigned short *) d->data[d->current]; s < e; s += 8, de += 8)
81 *de = d->pixels[*s],
82 *(de + 1) = d->pixels[*(s + 1)],
83 *(de + 2) = d->pixels[*(s + 2)],
84 *(de + 3) = d->pixels[*(s + 3)],
85 *(de + 4) = d->pixels[*(s + 4)],
86 *(de + 5) = d->pixels[*(s + 5)],
87 *(de + 6) = d->pixels[*(s + 6)],
88 *(de + 7) = d->pixels[*(s + 7)];
89 s -= 8;
90 de -= 8;
91 for (; s < e; s++, de++)
92 *de = d->pixels[*s];
93 break;
95 case 24:{
96 unsigned char *de;
97 unsigned char *s;
98 unsigned char *e;
99 for (s = (unsigned char *) d->vbuffs[d->current],
100 e = (unsigned char *) d->vbuffs[d->current] + (d->linewidth * d->height),
101 de = (unsigned char *) d->data[d->current]; s < e; s++, de+=3)
102 de[0] = d->pixels[*s],
103 de[1] = d->pixels[*s]>>8,
104 de[2] = d->pixels[*s]>>16;
106 break;
108 case 32:{
109 uint32_t *de;
110 unsigned char *s;
111 unsigned char *e;
112 for (s = (unsigned char *) d->vbuffs[d->current],
113 e = (unsigned char *) d->vbuffs[d->current] + (d->linewidth * d->height),
114 de = (uint32_t *) d->data[d->current]; s < e; s += 8, de += 8)
115 *de = d->pixels[*s],
116 *(de + 1) = d->pixels[*(s + 1)],
117 *(de + 2) = d->pixels[*(s + 2)],
118 *(de + 3) = d->pixels[*(s + 3)],
119 *(de + 4) = d->pixels[*(s + 4)],
120 *(de + 5) = d->pixels[*(s + 5)],
121 *(de + 6) = d->pixels[*(s + 6)],
122 *(de + 7) = d->pixels[*(s + 7)];
123 s -= 8;
124 de -= 8;
125 for (; s < e; s++, de++)
126 *de = d->pixels[*s];
127 break;
130 #ifdef MITSHM
131 if (d->SharedMemFlag) {
132 XShmPutImage(d->display, d->window, d->gc, d->image[d->current], 0, 0, 0,
133 0, d->width, d->height, True);
134 XFlush(d->display);
135 } else
136 #endif
138 XPutImage(d->display, d->window, d->gc, d->image[d->current], 0, 0, 0, 0, d->width, d->height);
139 XFlush(d->display);
141 d->screen_changed = 0;
144 #ifdef MITSHM
145 int alloc_shm_image(xdisplay * new)
147 register char *ptr;
148 int temp, size = 0, i;
149 ptr = DisplayString(new->display);
150 if (!ptr || (*ptr == ':') || !strncmp(ptr, "localhost:", 10) ||
151 !strncmp(ptr, "unix:", 5) || !strncmp(ptr, "local:", 6)) {
152 new->SharedMemOption = XQueryExtension(new->display, "MIT-SHM", &temp, &temp, &temp);
153 } else {
154 new->SharedMemOption = False;
155 return 0;
157 new->SharedMemFlag = False;
158 #if 0
159 new->SharedMemOption = True;
160 new->SharedMemFlag = False;
161 #endif
163 if (new->SharedMemFlag) {
164 XShmDetach(new->display, &new->xshminfo[0]);
165 XShmDetach(new->display, &new->xshminfo[1]);
166 new->image[0]->data = (char *) NULL;
167 new->image[1]->data = (char *) NULL;
168 shmdt(new->xshminfo[0].shmaddr);
169 shmdt(new->xshminfo[1].shmaddr);
171 for (i = 0; i < 2; i++) {
172 if (new->SharedMemOption) {
173 int mul;
174 if (new->depth == 8)
175 mul = 1;
176 else if (new->depth <= 24)
177 mul = 2;
178 else
179 mul = 4;
180 new->SharedMemFlag = False;
181 new->image[i] = XShmCreateImage(new->display, new->visual, new->depth, ZPixmap,
182 NULL, &new->xshminfo[i], new->width, new->height * mul);
183 if (new->image[i]) {
184 temp = new->image[i]->bytes_per_line * new->image[i]->height;
185 new->linewidth = new->image[i]->bytes_per_line * 8 / new->image[i]->bits_per_pixel;
186 if (temp > size)
187 size = temp;
188 new->xshminfo[i].shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | 0777);
189 if (new->xshminfo[i].shmid != -1) {
190 new->xshminfo[i].shmaddr = (char *) shmat(new->xshminfo[i].shmid, 0, 0);
191 if (new->xshminfo[i].shmaddr != (char *) -1) {
192 new->image[i]->data = new->xshminfo[i].shmaddr;
193 new->data[i] = new->vbuffs[i] = (char *) new->image[i]->data;
194 new->xshminfo[i].readOnly = True;
196 new->SharedMemFlag = XShmAttach(new->display, &new->xshminfo[i]);
197 XSync(new->display, False);
198 if (!new->SharedMemFlag) {
199 XDestroyImage(new->image[i]);
200 new->image[i] = (XImage *) NULL;
201 new->SharedMemFlag = 0;
202 return 0;
205 /* Always Destroy Shared Memory Ident */
206 shmctl(new->xshminfo[i].shmid, IPC_RMID, 0);
208 if (!new->SharedMemFlag) {
209 XDestroyImage(new->image[i]);
210 new->image[i] = (XImage *) NULL;
211 new->SharedMemFlag = 0;
212 return 0;
214 } else {
215 new->SharedMemFlag = 0;
216 return 0;
218 } else {
219 new->SharedMemFlag = 0;
220 return 0;
223 new->current = 0;
224 xflip_buffers(new);
225 return 1;
228 void free_shm_image(xdisplay * d)
230 if (d->SharedMemFlag) {
231 XDestroyImage(d->image[0]);
232 XDestroyImage(d->image[1]);
233 XShmDetach(d->display, &d->xshminfo[0]);
234 XShmDetach(d->display, &d->xshminfo[1]);
235 shmdt(d->xshminfo[0].shmaddr);
236 shmdt(d->xshminfo[1].shmaddr);
240 #endif
242 int alloc_image(xdisplay * d)
244 int i;
245 #ifdef MITSHM
246 if (!d->params->nomitshm && alloc_shm_image(d)) {
247 if (d->depth != 8) {
248 for (i = 0; i < 2; i++)
249 d->vbuffs[i] = malloc(d->linewidth * d->height);
251 return 1;
253 #endif
254 for (i = 0; i < 2; i++) {
255 d->image[i] = XCreateImage(d->display, d->visual, d->depth, ZPixmap, 0,
256 NULL, d->width, d->height, 8, 0);
257 if (d->image[i] == NULL) {
258 printf("Out of memory for image..exiting\n");
259 exit(-1);
261 //Add a little extra memory to catch overruns when dumping image to buffer in draw_screen
262 d->image[i]->data = malloc(d->image[i]->bytes_per_line * d->height + 32);
263 memset(d->image[i]->data,0,d->image[i]->bytes_per_line * d->height);
265 if (d->image[i]->data == NULL) {
266 printf("Out of memory for image buffers..exiting\n");
267 exit(-1);
269 d->data[i] = d->vbuffs[i] = (char *) d->image[i]->data;
270 d->linewidth = d->image[i]->bytes_per_line * 8 / d->image[i]->bits_per_pixel;
272 if (d->depth != 8) {
273 for (i = 0; i < 2; i++) {
274 //Add a little extra memory to catch overruns
275 //when dumping image to buffer in draw_screen
276 d->vbuffs[i] = malloc(d->linewidth * d->height + 32);
277 memset(d->vbuffs[i],0,d->linewidth * d->height);
279 if (d->vbuffs[i] == NULL) {
280 printf("Out of memory for image buffers2..exiting\n");
281 exit(-1);
285 xflip_buffers(d);
286 return 1;
289 void free_image(xdisplay * d)
291 if (d->depth != 8)
292 free(d->vbuffs[0]), free(d->vbuffs[1]);
293 #ifdef MITSHM
294 if (d->SharedMemFlag) {
295 free_shm_image(d);
296 return;
298 #endif
299 XDestroyImage(d->image[0]);
300 XDestroyImage(d->image[1]);
302 #define MAX(x,y) ((x)>(y)?(x):(y))
305 xdisplay *xalloc_display(char *s, int xHint, int yHint, int x, int y, xlibparam * params)
307 xdisplay *new;
308 Visual *defaultvisual;
309 XVisualInfo vis;
312 new = (xdisplay *) calloc(sizeof(xdisplay), 1);
313 chkalloc(new);
314 new->display = XOpenDisplay((char *) NULL);
315 if (!new->display) {
316 free((void *) new);
317 return NULL;
319 new->screen = DefaultScreen(new->display);
320 new->attributes = (XSetWindowAttributes *)
321 malloc(sizeof(XSetWindowAttributes));
322 chkalloc(new->attributes);
323 new->attributes->background_pixel = BlackPixel(new->display,
324 new->screen);
325 new->attributes->border_pixel = BlackPixel(new->display, new->screen);
326 new->attributes->event_mask = ButtonPressMask | StructureNotifyMask | ButtonReleaseMask | ButtonMotionMask | KeyPressMask | ExposureMask | KeyReleaseMask;
327 new->attributes->override_redirect = False;
328 new->attr_mask = CWBackPixel | CWBorderPixel | CWEventMask;
329 new->classX = InputOutput;
330 new->xcolor.n = 0;
331 new->parent_window = RootWindow(new->display, new->screen);
332 defaultvisual = DefaultVisual(new->display, new->screen);
333 new->params = params;
334 if (!params->usedefault) {
335 if (defaultvisual->class != PseudoColor || (!XMatchVisualInfo(new->display, new->screen, 8, PseudoColor, &vis) && vis.colormap_size > 128)) {
336 new->fixedcolormap = 1;
337 if (!XMatchVisualInfo(new->display, new->screen, 15, TrueColor, &vis)) {
338 if (!XMatchVisualInfo(new->display, new->screen, 16, TrueColor, &vis)) {
339 if (!XMatchVisualInfo(new->display, new->screen, 32, TrueColor, &vis) &&
340 !XMatchVisualInfo(new->display, new->screen, 24, TrueColor, &vis)) {
341 if (!XMatchVisualInfo(new->display, new->screen, 8, PseudoColor, &vis) &&
342 !XMatchVisualInfo(new->display, new->screen, 7, PseudoColor, &vis)) {
343 if (!XMatchVisualInfo(new->display, new->screen, 8, TrueColor, &vis) &&
344 !XMatchVisualInfo(new->display, new->screen, 8, StaticColor, &vis) &&
345 !XMatchVisualInfo(new->display, new->screen, 8, StaticGray, &vis)) {
346 printf("Display does not support PseudoColor depth 7,8,StaticColor depth 8, StaticGray depth 8, Truecolor depth 8,15,16,24 nor 32!\n");
347 return NULL;
348 } else
349 new->truecolor = 1;
350 } else
351 new->fixedcolormap = 0, new->truecolor = 0;
352 } else
353 new->truecolor = 1;
354 } else
355 new->truecolor = 1;
356 } else
357 new->truecolor = 1;
358 } else {
359 new->truecolor = 0;
361 new->depth = vis.depth;
362 new->visual = vis.visual;
363 } else { /*usedefault */
364 vis.depth = new->depth = DefaultDepth(new->display, new->screen);
365 new->visual = defaultvisual;
366 switch (defaultvisual->class) {
367 case PseudoColor:
368 if (new->depth <= 8) {
369 new->depth = 8;
370 new->truecolor = 0;
371 new->fixedcolormap = 0;
372 } else {
373 printf("Pseudocolor visual on unsuported depth\n");
374 return NULL;
376 break;
377 case TrueColor:
378 case StaticColor:
379 case StaticGray:
380 new->truecolor = 1;
381 new->fixedcolormap = 1;
382 if (new->depth <= 8)
383 new->depth = 8;
384 else if (new->depth <= 16)
385 new->depth = 16;
386 else if (new->depth <= 32)
387 new->depth = 32;
388 else {
389 printf("Truecolor visual on unsuported depth\n");
390 return NULL;
392 break;
393 default:
394 printf("Unusuported visual\n");
395 break;
398 /*new->visual->map_entries = 256; */
399 new->colormap = new->defaultcolormap = DefaultColormap(new->display, new->screen);
401 new->window_name = s;
402 new->height = y;
403 new->width = x;
404 new->border_width = 2;
405 new->lastx = 0;
406 new->lasty = 0;
407 new->font_struct = (XFontStruct *) NULL;
409 new->window = XCreateWindow(new->display, new->parent_window, xHint, yHint,
410 new->width, new->height, new->border_width,
411 vis.depth, new->classX, new->visual,
412 new->attr_mask, new->attributes);
413 if (!new->fixedcolormap && params->privatecolormap) {
414 unsigned long pixels[256];
415 int i;
416 new->colormap = XCreateColormap(new->display, new->window, new->visual, AllocNone);
417 XAllocColorCells(new->display, new->colormap, 1, 0, 0, pixels, MAX(new->visual->map_entries, 256));
418 for (i = 0; i < 16; i++) {
419 new->xcolor.c[i].pixel = pixels[i];
421 XQueryColors(new->display, new->defaultcolormap, new->xcolor.c, 16);
422 XStoreColors(new->display, new->colormap, new->xcolor.c, 16);
423 new->privatecolormap = 1;
425 if (!new->fixedcolormap)
426 XSetWindowColormap(new->display, new->window, new->colormap);
427 new->gc = XCreateGC(new->display, new->window, 0L, &(new->xgcvalues));
428 XSetBackground(new->display, new->gc,
429 BlackPixel(new->display, new->screen));
430 XSetForeground(new->display, new->gc,
431 WhitePixel(new->display, new->screen));
432 XStoreName(new->display, new->window, new->window_name);
433 XMapWindow(new->display, new->window);
434 #if 1
435 XSelectInput(new->display, new->window,
436 //ExposureMask |
437 KeyPress |
438 //KeyRelease |
439 //ConfigureRequest |
440 //FocusChangeMask |
441 StructureNotifyMask |
442 ButtonPressMask | ButtonReleaseMask);
443 #endif
444 #ifdef PIXAMP
445 new->pixmap = XCreatePixmap(new->display, new->window, new->width,
446 new->height, new->depth);
447 #endif
450 XColor c;
451 Pixmap p = XCreatePixmap(new->display, new->window, 1,1,1);
452 memset(&c,0,sizeof(c));
453 new->cursor = XCreatePixmapCursor(new->display, p,p,
454 &c,&c, 0,0);
455 XDefineCursor(new->display,new->window,new->cursor);
456 XFreePixmap(new->display, p);
459 return (new);
462 void xsetcolor(xdisplay * d, int col)
464 switch (col) {
465 case 0:
466 XSetForeground(d->display, d->gc,
467 BlackPixel(d->display, d->screen));
468 break;
469 case 1:
470 XSetForeground(d->display, d->gc,
471 WhitePixel(d->display, d->screen));
472 break;
473 default:
474 if ((col - 2) > d->xcolor.n) {
475 fprintf(stderr, "color error\n");
476 exit(-1);
478 XSetForeground(d->display, d->gc,
479 d->xcolor.c[col - 2].pixel);
480 break;
483 void xrotate_palette(xdisplay * d, int direction, unsigned char co[3][256], int ncolors)
485 int i, p;
487 if (d->privatecolormap) {
488 for (i = 0; i < d->xcolor.n; i++) {
489 p = d->xcolor.c[i].pixel;
490 d->xcolor.c[i].red = (int) co[0][p] * 256;
491 d->xcolor.c[i].green = (int) co[1][p] * 256;
492 d->xcolor.c[i].blue = (int) co[2][p] * 256;
494 XStoreColors(d->display, d->colormap, d->xcolor.c, d->xcolor.n);
496 if (d->truecolor) {
497 unsigned long oldpixels[256];
498 memcpy(oldpixels, d->pixels, sizeof(oldpixels));
499 p = (ncolors - 1 + direction) % (ncolors - 1) + 1;
500 for (i = 1; i < ncolors; i++) { /*this is ugly..I know */
501 d->pixels[i] = oldpixels[p];
502 p++;
503 if (p >= ncolors)
504 p = 1;
506 draw_screen(d);
509 int xalloc_color(xdisplay * d, int r, int g, int b, int readwrite)
511 d->xcolor.n++;
512 d->xcolor.c[d->xcolor.n - 1].flags = DoRed | DoGreen | DoBlue;
513 d->xcolor.c[d->xcolor.n - 1].red = r;
514 d->xcolor.c[d->xcolor.n - 1].green = g;
515 d->xcolor.c[d->xcolor.n - 1].blue = b;
516 d->xcolor.c[d->xcolor.n - 1].pixel = d->xcolor.n - 1;
517 if ((readwrite && !d->fixedcolormap) || d->privatecolormap) {
518 unsigned long cell;
519 if (d->privatecolormap) {
520 cell = d->xcolor.c[d->xcolor.n - 1].pixel += 16;
521 if (d->xcolor.c[d->xcolor.n - 1].pixel >= d->visual->map_entries) {
522 d->xcolor.n--;
523 return (-1);
525 } else {
526 if (!XAllocColorCells(d->display, d->colormap, 0, 0, 0, &cell, 1)) {
527 d->xcolor.n--;
528 if (d->xcolor.n <= 32)
529 printf("Colormap is too full! close some colorfull aplications or use -private\n");
530 return (-1);
532 d->xcolor.c[d->xcolor.n - 1].pixel = cell;
534 XStoreColor(d->display, d->colormap, &(d->xcolor.c[d->xcolor.n - 1]));
535 return (cell);
537 if (!XAllocColor(d->display, d->colormap, &(d->xcolor.c[d->xcolor.n - 1]))) {
538 d->xcolor.n--;
539 if (d->xcolor.n <= 32)
540 printf("Colormap is too full! close some colorfull aplications or use -private\n");
541 return (-1);
543 d->pixels[d->xcolor.n - 1] = d->xcolor.c[d->xcolor.n - 1].pixel;
544 return (d->depth != 8 ? d->xcolor.n - 1 : d->xcolor.c[d->xcolor.n - 1].pixel);
547 void xfree_colors(xdisplay * d)
549 unsigned long pixels[256];
550 int i;
551 for (i = 0; i < d->xcolor.n; i++)
552 pixels[i] = d->xcolor.c[i].pixel;
553 if (!d->privatecolormap)
554 XFreeColors(d->display, d->colormap, pixels, d->xcolor.n, 0);
555 d->xcolor.n = 0;
558 void xfree_display(xdisplay * d)
560 XSync(d->display, 0);
561 if (d->font_struct != (XFontStruct *) NULL) {
562 XFreeFont(d->display, d->font_struct);
564 XUnmapWindow(d->display, d->window);
565 #ifdef PIXMAP
566 XFreePixmap(d->display, d->pixmap);
567 #endif
568 XDestroyWindow(d->display, d->window);
569 XFreeCursor(d->display, d->cursor);
570 XCloseDisplay(d->display);
571 free((void *) d->attributes);
572 free((void *) d);
575 #ifdef PIXMAP
576 void xline(xdisplay * d, int x1, int y1, int x2, int y2)
578 XDrawLine(d->display, d->pixmap, d->gc, x1, y1, x2, y2);
579 d->lastx = x2, d->lasty = y2;
580 d->screen_changed = 1;
581 } void xlineto(xdisplay * d, int x, int y)
584 XDrawLine(d->display, d->pixmap, d->gc, d->lastx, d->lasty, x, y);
585 d->lastx = x, d->lasty = y;
586 d->screen_changed = 1;
587 } void xrect(xdisplay * d, int x1, int y1, int x2, int y2)
590 XDrawRectangle(d->display, d->pixmap, d->gc, x1, y1,
591 (x2 - x1), (y2 - y1));
592 d->lastx = x2, d->lasty = y2;
593 d->screen_changed = 1;
594 } void xfillrect(xdisplay * d, int x1, int y1, int x2, int y2)
597 XFillRectangle(d->display, d->pixmap, d->gc, x1, y1,
598 (x2 - x1), (y2 - y1));
599 d->lastx = x2, d->lasty = y2;
600 d->screen_changed = 1;
601 } void xpoint(xdisplay * d, int x, int y)
604 XDrawPoint(d->display, d->pixmap, d->gc, x, y);
605 d->lastx = x, d->lasty = y;
606 d->screen_changed = 1;
607 } void xflush(xdisplay * d)
610 draw_screen(d);
611 XFlush(d->display);
614 void xclear_screen(xdisplay * d)
616 xfillrect(d, 0, 0, d->width, d->height);
617 d->screen_changed = 1;
620 #endif
621 void xmoveto(xdisplay * d, int x, int y)
623 d->lastx = x, d->lasty = y;
624 } int xsetfont(xdisplay * d, char *font_name)
627 if (d->font_struct != (XFontStruct *) NULL) {
628 XFreeFont(d->display, d->font_struct);
630 d->font_struct = XLoadQueryFont(d->display, font_name);
631 if (!d->font_struct) {
632 fprintf(stderr, "could not load font: %s\n", font_name);
633 exit(-1);
635 return (d->font_struct->max_bounds.ascent + d->font_struct->max_bounds.descent);
638 void xouttext(xdisplay * d, char *string)
640 int sz;
642 sz = strlen(string);
643 XDrawImageString(d->display, d->window, d->gc, d->lastx, d->lasty,
644 string, sz);
645 #if 0
646 d->lastx += XTextWidth(d->font_struct, string, sz);
647 d->screen_changed = 1;
648 #endif
649 } void xresize(xdisplay * d, XEvent * ev)
652 #ifdef PIXMAP
653 XFreePixmap(d->display, d->pixmap);
654 #endif
655 d->width = ev->xconfigure.width;
656 d->height = ev->xconfigure.height;
657 #ifdef PIXMAP
658 d->pixmap = XCreatePixmap(d->display, d->window, d->width,
659 d->height, d->depth);
660 #endif
663 #ifdef PIXMAP
664 void xarc(xdisplay * d, int x, int y, unsigned int w,
665 unsigned int h, int a1, int a2)
667 XDrawArc(d->display, d->pixmap, d->gc, x, y, w, h, a1, a2);
668 } void xfillarc(xdisplay * d, int x, int y, unsigned int w,
669 unsigned int h, int a1, int a2)
671 XFillArc(d->display, d->pixmap, d->gc, x, y, w, h, a1, a2);
673 #endif
675 void xsize_set(xdisplay *d, int width, int height)
677 XResizeWindow(d->display, d->window, width, height);
680 int xmouse_x(xdisplay * d)
683 return d->mouse_x;
686 int xmouse_y(xdisplay * d)
688 return d->mouse_y;
691 void xmouse_update(xdisplay * d)
693 Window rootreturn, childreturn;
694 int rootx = 0, rooty = 0, buttons = 0;
696 XEvent event;
698 if (XCheckMaskEvent(d->display,ButtonPressMask | ButtonReleaseMask, &event)) {
699 if (event.type == ButtonPress)
700 d->mouse_buttons |= 1 << ((XButtonEvent*)(&event))->button;
701 else
702 d->mouse_buttons &= ~( 1 << ((XButtonEvent*)(&event))->button );
705 XQueryPointer(d->display, d->window, &rootreturn, &childreturn,
706 &rootx, &rooty, &(d->mouse_x), &(d->mouse_y),
707 &buttons);
710 char xkeyboard_query(xdisplay * d) {
711 XEvent event;
713 if (XCheckMaskEvent(d->display,KeyPressMask | KeyReleaseMask, &event)) {
714 char *str =
715 XKeysymToString(XLookupKeysym((XKeyPressedEvent*)(&event),0));
717 if ( ((XKeyPressedEvent*)(&event))->state &
718 (ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask) )
719 return 0;
721 if (str) {
722 char key;
724 if (strlen(str) == 1)
725 key = str[0];
726 else if (strcmp(str,"equal") == 0)
727 key = '=';
728 else if (strcmp(str,"minus") == 0)
729 key = '-';
730 else if (strcmp(str,"bracketleft") == 0)
731 key = '[';
732 else if (strcmp(str,"bracketright") == 0)
733 key = ']';
734 else if (strcmp(str,"comma") == 0)
735 key = ',';
736 else if (strcmp(str,"period") == 0)
737 key = '.';
738 else if (strcmp(str,"slash") == 0)
739 key = '/';
740 else return 0;
742 if ( ((XKeyPressedEvent*)(&event))->state & ShiftMask )
743 switch(key) {
744 case '=' : key = '+'; break;
745 case '[' : key = '{'; break;
746 case ']' : key = '}'; break;
747 case ',' : key = '<'; break;
748 case '/' : key = '?'; break;
749 default :
750 if (key >= 'a' && key <= 'z')
751 key = key+'A'-'a';
752 break;
754 return key;
758 return 0;
761 int xsize_update(xdisplay *d,int *width,int *height) {
762 XEvent event;
764 if (XCheckMaskEvent(d->display,StructureNotifyMask, &event)) {
765 if (event.type == ConfigureNotify) {
766 xupdate_size(d);
767 free_image(d);
768 alloc_image(d);
769 *width = d->linewidth;
770 *height = d->height;
771 return 1;
775 return 0;
778 unsigned int xmouse_buttons(xdisplay * d)
780 return d->mouse_buttons;
782 #endif
784 #endif