/[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 31 - (hide annotations)
Sat Sep 15 03:16:05 2001 UTC (22 years, 8 months ago) by matty
File MIME type: text/plain
File size: 20304 byte(s)
Software backing store support.

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

  ViewVC Help
Powered by ViewVC 1.1.26