/[rdesktop]/sourceforge.net/trunk/rdesktop/xwin.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /sourceforge.net/trunk/rdesktop/xwin.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 42 - (hide annotations)
Sun Apr 7 09:42:54 2002 UTC (22 years, 1 month ago) by matthewc
File MIME type: text/plain
File size: 20567 byte(s)
Fix for rdesktop hanging when it loses the X server connection.
(reported by Per Kristian Hove <Per.Hove@math.ntnu.no>)

1 matty 6 /*
2     rdesktop: A Remote Desktop Protocol client.
3 matthewc 38 User interface services - X Window System
4 matty 30 Copyright (C) Matthew Chapman 1999-2001
5 matty 6
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10    
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     GNU General Public License for more details.
15    
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19     */
20    
21 matty 10 #include <X11/Xlib.h>
22 matty 28 #include <X11/Xutil.h>
23 matty 10 #include <time.h>
24 matty 33 #include <errno.h>
25 matty 10 #include "rdesktop.h"
26 matty 6
27 matthewc 38 extern char keymapname[16];
28     extern int keylayout;
29 matty 10 extern int width;
30     extern int height;
31 matty 29 extern BOOL sendmotion;
32 matty 28 extern BOOL fullscreen;
33 matty 10
34     static Display *display;
35 matty 33 static int x_socket;
36 matty 10 static Window wnd;
37     static GC gc;
38     static Visual *visual;
39 matty 29 static int depth;
40     static int bpp;
41    
42 matty 33 /* endianness */
43     static BOOL host_be;
44     static BOOL xserver_be;
45    
46     /* software backing store */
47 matty 31 static BOOL ownbackstore;
48     static Pixmap backstore;
49    
50     #define FILL_RECTANGLE(x,y,cx,cy)\
51     { \
52     XFillRectangle(display, wnd, gc, x, y, cx, cy); \
53     if (ownbackstore) \
54     XFillRectangle(display, backstore, gc, x, y, cx, cy); \
55     }
56    
57 matty 33 /* colour maps */
58 matty 29 static BOOL owncolmap;
59     static Colormap xcolmap;
60     static uint32 white;
61 matty 28 static uint32 *colmap;
62 matty 10
63 matty 33 #define TRANSLATE(col) ( owncolmap ? col : translate_colour(colmap[col]) )
64 matty 29 #define SET_FOREGROUND(col) XSetForeground(display, gc, TRANSLATE(col));
65     #define SET_BACKGROUND(col) XSetBackground(display, gc, TRANSLATE(col));
66 matty 28
67     static int rop2_map[] = {
68     GXclear, /* 0 */
69     GXnor, /* DPon */
70     GXandInverted, /* DPna */
71     GXcopyInverted, /* Pn */
72     GXandReverse, /* PDna */
73     GXinvert, /* Dn */
74     GXxor, /* DPx */
75     GXnand, /* DPan */
76     GXand, /* DPa */
77     GXequiv, /* DPxn */
78     GXnoop, /* D */
79     GXorInverted, /* DPno */
80     GXcopy, /* P */
81     GXorReverse, /* PDno */
82     GXor, /* DPo */
83     GXset /* 1 */
84     };
85    
86 matty 29 #define SET_FUNCTION(rop2) { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }
87     #define RESET_FUNCTION(rop2) { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }
88    
89 matty 28 static void
90 matty 29 translate8(uint8 *data, uint8 *out, uint8 *end)
91 matty 28 {
92 matty 29 while (out < end)
93     *(out++) = (uint8)colmap[*(data++)];
94     }
95 matty 28
96 matty 29 static void
97     translate16(uint8 *data, uint16 *out, uint16 *end)
98     {
99     while (out < end)
100     *(out++) = (uint16)colmap[*(data++)];
101     }
102    
103 matty 33 /* little endian - conversion happens when colourmap is built */
104 matty 29 static void
105     translate24(uint8 *data, uint8 *out, uint8 *end)
106     {
107     uint32 value;
108    
109     while (out < end)
110 matty 28 {
111 matty 29 value = colmap[*(data++)];
112     *(out++) = value;
113     *(out++) = value >> 8;
114     *(out++) = value >> 16;
115 matty 28 }
116     }
117    
118     static void
119 matty 29 translate32(uint8 *data, uint32 *out, uint32 *end)
120 matty 28 {
121 matty 29 while (out < end)
122     *(out++) = colmap[*(data++)];
123 matty 28 }
124    
125 matty 29 static uint8 *
126 matty 33 translate_image(int width, int height, uint8 *data)
127 matty 28 {
128 matty 29 int size = width * height * bpp/8;
129     uint8 *out = xmalloc(size);
130     uint8 *end = out + size;
131    
132     switch (bpp)
133     {
134     case 8:
135     translate8(data, out, end);
136     break;
137    
138     case 16:
139     translate16(data, (uint16 *)out, (uint16 *)end);
140     break;
141    
142     case 24:
143     translate24(data, out, end);
144     break;
145    
146     case 32:
147     translate32(data, (uint32 *)out, (uint32 *)end);
148     break;
149     }
150    
151     return out;
152 matty 28 }
153    
154 matty 35 #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }
155     #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }
156     #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
157     x = (x << 16) | (x >> 16); }
158 matty 29
159 matty 33 static uint32
160     translate_colour(uint32 colour)
161     {
162     switch (bpp)
163     {
164     case 16:
165     if (host_be != xserver_be)
166     BSWAP16(colour);
167     break;
168 matty 29
169 matty 33 case 24:
170     if (xserver_be)
171     BSWAP24(colour);
172     break;
173    
174     case 32:
175     if (host_be != xserver_be)
176     BSWAP32(colour);
177     break;
178     }
179    
180     return colour;
181     }
182    
183 matty 25 BOOL
184     ui_create_window(char *title)
185 matty 6 {
186 matty 9 XSetWindowAttributes attribs;
187 matty 28 XClassHint *classhints;
188     XSizeHints *sizehints;
189 matty 10 unsigned long input_mask;
190 matty 28 XPixmapFormatValues *pfm;
191 matty 29 Screen *screen;
192 matty 33 uint16 test;
193 matty 29 int i;
194 matty 6
195     display = XOpenDisplay(NULL);
196     if (display == NULL)
197 matty 21 {
198 matty 30 error("Failed to open display\n");
199 matty 10 return False;
200 matty 21 }
201 matty 6
202 matty 33 x_socket = ConnectionNumber(display);
203 matty 29 screen = DefaultScreenOfDisplay(display);
204     visual = DefaultVisualOfScreen(screen);
205     depth = DefaultDepthOfScreen(screen);
206    
207     pfm = XListPixmapFormats(display, &i);
208 matty 28 if (pfm != NULL)
209     {
210 matty 29 /* Use maximum bpp for this depth - this is generally
211     desirable, e.g. 24 bits->32 bits. */
212     while (i--)
213 matty 28 {
214 matty 29 if ((pfm[i].depth == depth)
215     && (pfm[i].bits_per_pixel > bpp))
216 matty 28 {
217 matty 29 bpp = pfm[i].bits_per_pixel;
218 matty 28 }
219     }
220     XFree(pfm);
221     }
222 matty 10
223 matty 28 if (bpp < 8)
224 matty 10 {
225 matty 30 error("Less than 8 bpp not currently supported.\n");
226 matty 10 XCloseDisplay(display);
227     return False;
228     }
229    
230 matty 29 if (depth <= 8)
231     owncolmap = True;
232     else
233     xcolmap = DefaultColormapOfScreen(screen);
234 matty 6
235 matty 33 test = 1;
236     host_be = !(BOOL)(*(uint8 *)(&test));
237     xserver_be = (ImageByteOrder(display) == MSBFirst);
238    
239 matty 29 white = WhitePixelOfScreen(screen);
240     attribs.background_pixel = BlackPixelOfScreen(screen);
241     attribs.backing_store = DoesBackingStore(screen);
242 matty 28
243 matty 29 if (attribs.backing_store == NotUseful)
244 matty 31 ownbackstore = True;
245 matty 29
246 matty 28 if (fullscreen)
247     {
248     attribs.override_redirect = True;
249 matty 29 width = WidthOfScreen(screen);
250     height = HeightOfScreen(screen);
251 matty 28 }
252     else
253     {
254     attribs.override_redirect = False;
255     }
256    
257 matty 30 width = (width + 3) & ~3; /* make width a multiple of 32 bits */
258 matty 29
259     wnd = XCreateWindow(display, RootWindowOfScreen(screen),
260 matty 28 0, 0, width, height, 0, CopyFromParent,
261     InputOutput, CopyFromParent,
262     CWBackingStore | CWBackPixel | CWOverrideRedirect,
263     &attribs);
264 matty 9
265 matty 10 XStoreName(display, wnd, title);
266 matty 6
267 matty 28 classhints = XAllocClassHint();
268     if (classhints != NULL)
269     {
270 matty 29 classhints->res_name = classhints->res_class = "rdesktop";
271 matty 28 XSetClassHint(display, wnd, classhints);
272     XFree(classhints);
273     }
274    
275     sizehints = XAllocSizeHints();
276     if (sizehints)
277     {
278 matty 29 sizehints->flags = PMinSize | PMaxSize;
279     sizehints->min_width = sizehints->max_width = width;
280     sizehints->min_height = sizehints->max_height = height;
281 matty 28 XSetWMNormalHints(display, wnd, sizehints);
282     XFree(sizehints);
283     }
284    
285 matthewc 38 xkeymap_init(display);
286    
287 matty 29 input_mask = KeyPressMask | KeyReleaseMask
288     | ButtonPressMask | ButtonReleaseMask
289     | EnterWindowMask | LeaveWindowMask;
290    
291     if (sendmotion)
292 matty 10 input_mask |= PointerMotionMask;
293 matty 6
294 matty 31 if (ownbackstore)
295     input_mask |= ExposureMask;
296    
297 matty 10 XSelectInput(display, wnd, input_mask);
298     gc = XCreateGC(display, wnd, 0, NULL);
299 matty 7
300 matty 31 if (ownbackstore)
301     backstore = XCreatePixmap(display, wnd, width, height, depth);
302    
303 matty 28 XMapWindow(display, wnd);
304 matty 10 return True;
305 matty 6 }
306    
307 matty 25 void
308     ui_destroy_window()
309 matty 6 {
310 matty 31 if (ownbackstore)
311     XFreePixmap(display, backstore);
312    
313 matty 10 XFreeGC(display, gc);
314     XDestroyWindow(display, wnd);
315     XCloseDisplay(display);
316 matty 28 display = NULL;
317 matty 6 }
318    
319 matty 33 static void
320     xwin_process_events()
321 matty 9 {
322     XEvent event;
323 matthewc 38 KeySym keysym;
324 matty 9 uint8 scancode;
325     uint16 button;
326 matty 10 uint32 ev_time;
327 matty 9
328 matty 10 if (display == NULL)
329 matty 9 return;
330    
331 matthewc 42 while (XCheckMaskEvent(display, ~0, &event))
332 matty 9 {
333 matty 10 ev_time = time(NULL);
334    
335 matty 9 switch (event.type)
336     {
337     case KeyPress:
338 matthewc 38 keysym = XKeycodeToKeysym(display, event.xkey.keycode, 0);
339     scancode = xkeymap_translate_key(keysym, event.xkey.keycode);
340 matty 9 if (scancode == 0)
341     break;
342    
343 matty 10 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,
344 matty 24 scancode, 0);
345 matty 9 break;
346    
347     case KeyRelease:
348 matthewc 38 keysym = XKeycodeToKeysym(display, event.xkey.keycode, 0);
349     scancode = xkeymap_translate_key(keysym, event.xkey.keycode);
350 matty 9 if (scancode == 0)
351     break;
352    
353 matty 10 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
354 matty 24 KBD_FLAG_DOWN | KBD_FLAG_UP,
355     scancode, 0);
356 matty 9 break;
357    
358     case ButtonPress:
359 matthewc 38 button = xkeymap_translate_button(event.xbutton.button);
360 matty 9 if (button == 0)
361     break;
362    
363 matty 10 rdp_send_input(ev_time, RDP_INPUT_MOUSE,
364 matty 24 button | MOUSE_FLAG_DOWN,
365     event.xbutton.x,
366     event.xbutton.y);
367 matty 9 break;
368    
369     case ButtonRelease:
370 matthewc 38 button = xkeymap_translate_button(event.xbutton.button);
371 matty 9 if (button == 0)
372     break;
373    
374 matty 10 rdp_send_input(ev_time, RDP_INPUT_MOUSE,
375 matty 24 button,
376     event.xbutton.x,
377     event.xbutton.y);
378 matty 10 break;
379    
380     case MotionNotify:
381     rdp_send_input(ev_time, RDP_INPUT_MOUSE,
382 matty 24 MOUSE_FLAG_MOVE,
383     event.xmotion.x,
384     event.xmotion.y);
385 matty 28 break;
386    
387     case EnterNotify:
388 matty 29 XGrabKeyboard(display, wnd, True, GrabModeAsync,
389     GrabModeAsync, CurrentTime);
390 matty 28 break;
391    
392     case LeaveNotify:
393 matty 29 XUngrabKeyboard(display, CurrentTime);
394 matty 28 break;
395 matty 31
396     case Expose:
397     XCopyArea(display, backstore, wnd, gc,
398     event.xexpose.x, event.xexpose.y,
399     event.xexpose.width, event.xexpose.height,
400     event.xexpose.x, event.xexpose.y);
401     break;
402 matty 9 }
403     }
404     }
405    
406 matty 25 void
407 matty 33 ui_select(int rdp_socket)
408     {
409     int n = (rdp_socket > x_socket) ? rdp_socket+1 : x_socket+1;
410     fd_set rfds;
411    
412     XFlush(display);
413    
414     FD_ZERO(&rfds);
415    
416     while (True)
417     {
418     FD_ZERO(&rfds);
419     FD_SET(rdp_socket, &rfds);
420     FD_SET(x_socket, &rfds);
421    
422     switch (select(n, &rfds, NULL, NULL, NULL))
423     {
424     case -1:
425     error("select: %s\n", strerror(errno));
426    
427     case 0:
428     continue;
429     }
430    
431     if (FD_ISSET(x_socket, &rfds))
432     xwin_process_events();
433    
434     if (FD_ISSET(rdp_socket, &rfds))
435     return;
436     }
437     }
438    
439     void
440 matty 25 ui_move_pointer(int x, int y)
441 matty 9 {
442 matty 10 XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);
443 matty 9 }
444    
445 matty 25 HBITMAP
446     ui_create_bitmap(int width, int height, uint8 *data)
447 matty 6 {
448     XImage *image;
449 matty 9 Pixmap bitmap;
450 matty 28 uint8 *tdata;
451 matty 29
452 matty 33 tdata = (owncolmap ? data : translate_image(width, height, data));
453 matty 28 bitmap = XCreatePixmap(display, wnd, width, height, depth);
454 matty 29 image = XCreateImage(display, visual, depth, ZPixmap,
455     0, tdata, width, height, 8, 0);
456 matty 6
457 matty 28 XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
458 matty 9
459     XFree(image);
460 matty 29 if (!owncolmap)
461 matty 28 xfree(tdata);
462 matty 24 return (HBITMAP) bitmap;
463 matty 6 }
464    
465 matty 25 void
466     ui_paint_bitmap(int x, int y, int cx, int cy,
467     int width, int height, uint8 *data)
468 matty 6 {
469 matty 10 XImage *image;
470 matty 29 uint8 *tdata;
471 matty 10
472 matty 33 tdata = (owncolmap ? data : translate_image(width, height, data));
473 matty 29 image = XCreateImage(display, visual, depth, ZPixmap,
474     0, tdata, width, height, 8, 0);
475 matty 28
476 matty 31 if (ownbackstore)
477     {
478     XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
479     XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
480     }
481     else
482     {
483     XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
484     }
485 matty 29
486 matty 24 XFree(image);
487 matty 29 if (!owncolmap)
488 matty 28 xfree(tdata);
489 matty 6 }
490    
491 matty 25 void
492     ui_destroy_bitmap(HBITMAP bmp)
493 matty 6 {
494 matty 29 XFreePixmap(display, (Pixmap)bmp);
495 matty 10 }
496    
497 matty 25 HGLYPH
498     ui_create_glyph(int width, int height, uint8 *data)
499 matty 10 {
500 matty 9 XImage *image;
501     Pixmap bitmap;
502     int scanline;
503     GC gc;
504 matty 6
505 matty 9 scanline = (width + 7) / 8;
506 matty 6
507 matty 10 bitmap = XCreatePixmap(display, wnd, width, height, 1);
508     gc = XCreateGC(display, bitmap, 0, NULL);
509 matty 9
510 matty 10 image = XCreateImage(display, visual, 1, ZPixmap, 0,
511 matty 24 data, width, height, 8, scanline);
512 matty 23 image->byte_order = MSBFirst;
513     image->bitmap_bit_order = MSBFirst;
514     XInitImage(image);
515    
516 matty 10 XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
517 matty 29
518 matty 9 XFree(image);
519 matty 10 XFreeGC(display, gc);
520 matty 29 return (HGLYPH)bitmap;
521 matty 6 }
522 matty 7
523 matty 25 void
524     ui_destroy_glyph(HGLYPH glyph)
525 matty 7 {
526 matty 29 XFreePixmap(display, (Pixmap)glyph);
527 matty 9 }
528    
529 matty 29 HCURSOR
530     ui_create_cursor(unsigned int x, unsigned int y, int width,
531     int height, uint8 *andmask, uint8 *xormask)
532 matty 9 {
533 matty 29 HGLYPH maskglyph, cursorglyph;
534     XColor bg, fg;
535     Cursor xcursor;
536     uint8 *cursor, *pcursor;
537     uint8 *mask, *pmask;
538     uint8 nextbit;
539     int scanline, offset;
540     int i, j;
541    
542     scanline = (width + 7) / 8;
543     offset = scanline * height;
544    
545     cursor = xmalloc(offset);
546     memset(cursor, 0, offset);
547    
548     mask = xmalloc(offset);
549     memset(mask, 0, offset);
550    
551     /* approximate AND and XOR masks with a monochrome X pointer */
552     for (i = 0; i < height; i++)
553 matty 7 {
554 matty 29 offset -= scanline;
555     pcursor = &cursor[offset];
556     pmask = &mask[offset];
557    
558     for (j = 0; j < scanline; j++)
559 matty 28 {
560 matty 29 for (nextbit = 0x80; nextbit != 0; nextbit >>= 1)
561     {
562     if (xormask[0] || xormask[1] || xormask[2])
563     {
564     *pcursor |= (~(*andmask) & nextbit);
565     *pmask |= nextbit;
566     }
567     else
568     {
569     *pcursor |= ((*andmask) & nextbit);
570     *pmask |= (~(*andmask) & nextbit);
571     }
572    
573     xormask += 3;
574     }
575    
576     andmask++;
577     pcursor++;
578     pmask++;
579 matty 28 }
580 matty 7 }
581 matty 29
582     fg.red = fg.blue = fg.green = 0xffff;
583     bg.red = bg.blue = bg.green = 0x0000;
584     fg.flags = bg.flags = DoRed | DoBlue | DoGreen;
585    
586     cursorglyph = ui_create_glyph(width, height, cursor);
587     maskglyph = ui_create_glyph(width, height, mask);
588    
589     xcursor = XCreatePixmapCursor(display, (Pixmap)cursorglyph,
590     (Pixmap)maskglyph, &fg, &bg, x, y);
591    
592     ui_destroy_glyph(maskglyph);
593     ui_destroy_glyph(cursorglyph);
594     xfree(mask);
595     xfree(cursor);
596     return (HCURSOR)xcursor;
597     }
598    
599     void
600     ui_set_cursor(HCURSOR cursor)
601     {
602     XDefineCursor(display, wnd, (Cursor)cursor);
603     }
604    
605     void
606     ui_destroy_cursor(HCURSOR cursor)
607     {
608     XFreeCursor(display, (Cursor)cursor);
609     }
610    
611     #define MAKE_XCOLOR(xc,c) \
612     (xc)->red = ((c)->red << 8) | (c)->red; \
613     (xc)->green = ((c)->green << 8) | (c)->green; \
614     (xc)->blue = ((c)->blue << 8) | (c)->blue; \
615     (xc)->flags = DoRed | DoGreen | DoBlue;
616    
617     HCOLOURMAP
618     ui_create_colourmap(COLOURMAP *colours)
619     {
620     COLOURENTRY *entry;
621     int i, ncolours = colours->ncolours;
622    
623     if (owncolmap)
624 matty 28 {
625     XColor *xcolours, *xentry;
626     Colormap map;
627 matty 29
628 matty 28 xcolours = xmalloc(sizeof(XColor) * ncolours);
629     for (i = 0; i < ncolours; i++)
630     {
631     entry = &colours->colours[i];
632     xentry = &xcolours[i];
633     xentry->pixel = i;
634 matty 29 MAKE_XCOLOR(xentry, entry);
635 matty 28 }
636 matty 7
637 matty 28 map = XCreateColormap(display, wnd, visual, AllocAll);
638     XStoreColors(display, map, xcolours, ncolours);
639    
640     xfree(xcolours);
641 matty 29 return (HCOLOURMAP)map;
642 matty 28 }
643 matty 29 else
644     {
645     uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
646     XColor xentry;
647 matty 33 uint32 colour;
648 matty 29
649     for (i = 0; i < ncolours; i++)
650     {
651     entry = &colours->colours[i];
652     MAKE_XCOLOR(&xentry, entry);
653    
654     if (XAllocColor(display, xcolmap, &xentry) != 0)
655 matty 34 colour = xentry.pixel;
656 matty 29 else
657 matty 34 colour = white;
658 matty 33
659     /* byte swap here to make translate_image faster */
660     map[i] = translate_colour(colour);
661 matty 29 }
662    
663     return map;
664     }
665 matty 7 }
666    
667 matty 25 void
668     ui_destroy_colourmap(HCOLOURMAP map)
669 matty 7 {
670 matty 29 if (owncolmap)
671     XFreeColormap(display, (Colormap)map);
672     else
673     xfree(map);
674 matty 7 }
675    
676 matty 25 void
677     ui_set_colourmap(HCOLOURMAP map)
678 matty 7 {
679 matty 29 if (owncolmap)
680     XSetWindowColormap(display, wnd, (Colormap)map);
681     else
682 matty 28 colmap = map;
683 matty 7 }
684    
685 matty 25 void
686     ui_set_clip(int x, int y, int cx, int cy)
687 matty 7 {
688 matty 9 XRectangle rect;
689 matty 7
690 matty 9 rect.x = x;
691     rect.y = y;
692     rect.width = cx;
693     rect.height = cy;
694 matty 10 XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
695 matty 9 }
696 matty 7
697 matty 25 void
698     ui_reset_clip()
699 matty 9 {
700     XRectangle rect;
701    
702     rect.x = 0;
703     rect.y = 0;
704 matty 10 rect.width = width;
705     rect.height = height;
706     XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
707 matty 7 }
708    
709 matty 25 void
710     ui_bell()
711 matty 10 {
712     XBell(display, 0);
713     }
714    
715 matty 25 void
716     ui_destblt(uint8 opcode,
717     /* dest */ int x, int y, int cx, int cy)
718 matty 9 {
719 matty 29 SET_FUNCTION(opcode);
720 matty 31 FILL_RECTANGLE(x, y, cx, cy);
721 matty 29 RESET_FUNCTION(opcode);
722 matty 9 }
723    
724 matty 25 void
725     ui_patblt(uint8 opcode,
726     /* dest */ int x, int y, int cx, int cy,
727     /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
728 matty 9 {
729     Pixmap fill;
730    
731 matty 29 SET_FUNCTION(opcode);
732 matty 9
733     switch (brush->style)
734     {
735 matty 24 case 0: /* Solid */
736 matty 29 SET_FOREGROUND(fgcolour);
737 matty 31 FILL_RECTANGLE(x, y, cx, cy);
738 matty 9 break;
739    
740 matty 24 case 3: /* Pattern */
741 matty 29 fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);
742 matty 9
743 matty 29 SET_FOREGROUND(bgcolour);
744     SET_BACKGROUND(fgcolour);
745     XSetFillStyle(display, gc, FillOpaqueStippled);
746     XSetStipple(display, gc, fill);
747     XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);
748 matty 9
749 matty 31 FILL_RECTANGLE(x, y, cx, cy);
750 matty 9
751 matty 29 XSetFillStyle(display, gc, FillSolid);
752     ui_destroy_glyph((HGLYPH)fill);
753 matty 9 break;
754    
755     default:
756 matty 30 unimpl("brush %d\n", brush->style);
757 matty 9 }
758 matty 29
759     RESET_FUNCTION(opcode);
760 matty 9 }
761    
762 matty 25 void
763     ui_screenblt(uint8 opcode,
764     /* dest */ int x, int y, int cx, int cy,
765     /* src */ int srcx, int srcy)
766 matty 9 {
767 matty 29 SET_FUNCTION(opcode);
768 matty 24 XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
769 matty 31 if (ownbackstore)
770     XCopyArea(display, backstore, backstore, gc, srcx, srcy,
771     cx, cy, x, y);
772 matty 29 RESET_FUNCTION(opcode);
773 matty 9 }
774    
775 matty 25 void
776     ui_memblt(uint8 opcode,
777     /* dest */ int x, int y, int cx, int cy,
778     /* src */ HBITMAP src, int srcx, int srcy)
779 matty 9 {
780 matty 29 SET_FUNCTION(opcode);
781     XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);
782 matty 31 if (ownbackstore)
783     XCopyArea(display, (Pixmap)src, backstore, gc, srcx, srcy,
784     cx, cy, x, y);
785 matty 29 RESET_FUNCTION(opcode);
786 matty 9 }
787    
788 matty 25 void
789     ui_triblt(uint8 opcode,
790     /* dest */ int x, int y, int cx, int cy,
791     /* src */ HBITMAP src, int srcx, int srcy,
792     /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
793 matty 9 {
794     /* This is potentially difficult to do in general. Until someone
795 matty 10 comes up with a more efficient way of doing it I am using cases. */
796 matty 9
797     switch (opcode)
798     {
799 matty 24 case 0x69: /* PDSxxn */
800 matty 16 ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
801     ui_patblt(ROP2_NXOR, x, y, cx, cy,
802 matty 24 brush, bgcolour, fgcolour);
803 matty 16 break;
804    
805 matty 24 case 0xb8: /* PSDPxax */
806 matty 10 ui_patblt(ROP2_XOR, x, y, cx, cy,
807 matty 24 brush, bgcolour, fgcolour);
808 matty 16 ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
809 matty 10 ui_patblt(ROP2_XOR, x, y, cx, cy,
810 matty 24 brush, bgcolour, fgcolour);
811 matty 9 break;
812    
813 matty 29 case 0xc0: /* PSa */
814 matty 28 ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
815     ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,
816     fgcolour);
817     break;
818    
819 matty 9 default:
820 matty 30 unimpl("triblt 0x%x\n", opcode);
821 matty 16 ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
822 matty 9 }
823     }
824    
825 matty 25 void
826     ui_line(uint8 opcode,
827     /* dest */ int startx, int starty, int endx, int endy,
828     /* pen */ PEN *pen)
829 matty 9 {
830 matty 29 SET_FUNCTION(opcode);
831     SET_FOREGROUND(pen->colour);
832 matty 10 XDrawLine(display, wnd, gc, startx, starty, endx, endy);
833 matty 31 if (ownbackstore)
834     XDrawLine(display, backstore, gc, startx, starty, endx, endy);
835 matty 29 RESET_FUNCTION(opcode);
836 matty 9 }
837    
838 matty 25 void
839     ui_rect(
840     /* dest */ int x, int y, int cx, int cy,
841     /* brush */ int colour)
842 matty 9 {
843 matty 29 SET_FOREGROUND(colour);
844 matty 31 FILL_RECTANGLE(x, y, cx, cy);
845 matty 9 }
846    
847 matty 25 void
848     ui_draw_glyph(int mixmode,
849     /* dest */ int x, int y, int cx, int cy,
850     /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,
851     int fgcolour)
852 matty 9 {
853 matty 29 SET_FOREGROUND(fgcolour);
854     SET_BACKGROUND(bgcolour);
855 matty 9
856 matty 29 XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)
857     ? FillStippled : FillOpaqueStippled);
858     XSetStipple(display, gc, (Pixmap)glyph);
859     XSetTSOrigin(display, gc, x, y);
860 matty 9
861 matty 31 FILL_RECTANGLE(x, y, cx, cy);
862 matty 9
863 matty 29 XSetFillStyle(display, gc, FillSolid);
864 matty 9 }
865    
866 matty 25 void
867     ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
868     int clipx, int clipy, int clipcx, int clipcy,
869     int boxx, int boxy, int boxcx, int boxcy,
870     int bgcolour, int fgcolour, uint8 *text, uint8 length)
871 matty 9 {
872 matty 10 FONTGLYPH *glyph;
873 matty 29 int i, offset;
874 matty 9
875 matty 29 SET_FOREGROUND(bgcolour);
876 matty 28
877 matty 9 if (boxcx > 1)
878 matty 31 {
879     FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);
880     }
881 matty 17 else if (mixmode == MIX_OPAQUE)
882 matty 31 {
883     FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);
884     }
885 matty 9
886     /* Paint text, character by character */
887     for (i = 0; i < length; i++)
888     {
889 matty 10 glyph = cache_get_font(font, text[i]);
890 matty 9
891 matty 17 if (!(flags & TEXT2_IMPLICIT_X))
892 matty 29 {
893     offset = text[++i];
894     if (offset & 0x80)
895     offset = ((offset & 0x7f) << 8) | text[++i];
896 matty 17
897 matty 29 if (flags & TEXT2_VERTICAL)
898     y += offset;
899 matty 28 else
900 matty 29 x += offset;
901     }
902 matty 28
903 matty 9 if (glyph != NULL)
904     {
905 matty 24 ui_draw_glyph(mixmode, x + (short) glyph->offset,
906     y + (short) glyph->baseline,
907     glyph->width, glyph->height,
908     glyph->pixmap, 0, 0,
909     bgcolour, fgcolour);
910 matty 9
911     if (flags & TEXT2_IMPLICIT_X)
912     x += glyph->width;
913     }
914     }
915     }
916    
917 matty 25 void
918     ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
919 matty 9 {
920 matty 28 Pixmap pix;
921 matty 9 XImage *image;
922    
923 matty 31 if (ownbackstore)
924     {
925     image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,
926     ZPixmap);
927     }
928     else
929     {
930     pix = XCreatePixmap(display, wnd, cx, cy, depth);
931     XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
932     image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,
933     ZPixmap);
934     XFreePixmap(display, pix);
935     }
936 matty 28
937     offset *= bpp/8;
938     cache_put_desktop(offset, cx, cy, image->bytes_per_line,
939 matty 36 bpp/8, (uint8 *)image->data);
940 matty 28
941     XDestroyImage(image);
942 matty 9 }
943    
944 matty 25 void
945     ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
946 matty 9 {
947     XImage *image;
948 matty 10 uint8 *data;
949 matty 9
950 matty 28 offset *= bpp/8;
951     data = cache_get_desktop(offset, cx, cy, bpp/8);
952 matty 10 if (data == NULL)
953     return;
954 matty 29
955     image = XCreateImage(display, visual, depth, ZPixmap,
956 matty 28 0, data, cx, cy, BitmapPad(display),
957     cx * bpp/8);
958 matty 29
959 matty 31 if (ownbackstore)
960     {
961     XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
962     XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
963     }
964     else
965     {
966     XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
967     }
968    
969 matty 9 XFree(image);
970     }

  ViewVC Help
Powered by ViewVC 1.1.26