/[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 29 - (hide annotations)
Fri Sep 14 03:38:39 2001 UTC (22 years, 8 months ago) by matty
File MIME type: text/plain
File size: 19070 byte(s)
Major cleanups, particularly in X code.

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

  ViewVC Help
Powered by ViewVC 1.1.26