/[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 50 - (hide annotations)
Sat Apr 20 09:41:03 2002 UTC (22 years ago) by matthewc
File MIME type: text/plain
File size: 21312 byte(s)
There is an extended key flag that we should be setting for extended keys.
(Originally fixed by Ben McKeegan <Ben.McKeegan@fitz.cam.ac.uk>)

Ran make proto.

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 matthewc 50 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 50 xkeymap_init();
286 matthewc 38
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 matthewc 50 uint16 button, flags;
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 matthewc 50 flags = 0;
335 matty 10
336 matty 9 switch (event.type)
337     {
338 matthewc 50 case KeyRelease:
339     flags = KBD_FLAG_DOWN | KBD_FLAG_UP;
340     /* fall through */
341    
342 matty 9 case KeyPress:
343 matthewc 38 keysym = XKeycodeToKeysym(display, event.xkey.keycode, 0);
344 matthewc 50 scancode = xkeymap_translate_key(keysym, event.xkey.keycode, &flags);
345 matty 9 if (scancode == 0)
346     break;
347    
348 matthewc 50 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, flags, scancode, 0);
349 matty 9 break;
350    
351     case ButtonPress:
352 matthewc 50 flags = MOUSE_FLAG_DOWN;
353     /* fall through */
354 matty 9
355     case ButtonRelease:
356 matthewc 38 button = xkeymap_translate_button(event.xbutton.button);
357 matty 9 if (button == 0)
358     break;
359    
360 matty 10 rdp_send_input(ev_time, RDP_INPUT_MOUSE,
361 matthewc 50 flags | button,
362 matty 24 event.xbutton.x,
363     event.xbutton.y);
364 matty 10 break;
365    
366     case MotionNotify:
367     rdp_send_input(ev_time, RDP_INPUT_MOUSE,
368 matty 24 MOUSE_FLAG_MOVE,
369     event.xmotion.x,
370     event.xmotion.y);
371 matty 28 break;
372    
373     case EnterNotify:
374 matty 29 XGrabKeyboard(display, wnd, True, GrabModeAsync,
375     GrabModeAsync, CurrentTime);
376 matty 28 break;
377    
378     case LeaveNotify:
379 matty 29 XUngrabKeyboard(display, CurrentTime);
380 matty 28 break;
381 matty 31
382     case Expose:
383     XCopyArea(display, backstore, wnd, gc,
384     event.xexpose.x, event.xexpose.y,
385     event.xexpose.width, event.xexpose.height,
386     event.xexpose.x, event.xexpose.y);
387     break;
388 matty 9 }
389     }
390     }
391    
392 matty 25 void
393 matty 33 ui_select(int rdp_socket)
394     {
395     int n = (rdp_socket > x_socket) ? rdp_socket+1 : x_socket+1;
396     fd_set rfds;
397    
398     XFlush(display);
399    
400     FD_ZERO(&rfds);
401    
402     while (True)
403     {
404     FD_ZERO(&rfds);
405     FD_SET(rdp_socket, &rfds);
406     FD_SET(x_socket, &rfds);
407    
408     switch (select(n, &rfds, NULL, NULL, NULL))
409     {
410     case -1:
411     error("select: %s\n", strerror(errno));
412    
413     case 0:
414     continue;
415     }
416    
417     if (FD_ISSET(x_socket, &rfds))
418     xwin_process_events();
419    
420     if (FD_ISSET(rdp_socket, &rfds))
421     return;
422     }
423     }
424    
425     void
426 matty 25 ui_move_pointer(int x, int y)
427 matty 9 {
428 matty 10 XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);
429 matty 9 }
430    
431 matty 25 HBITMAP
432     ui_create_bitmap(int width, int height, uint8 *data)
433 matty 6 {
434     XImage *image;
435 matty 9 Pixmap bitmap;
436 matty 28 uint8 *tdata;
437 matty 29
438 matty 33 tdata = (owncolmap ? data : translate_image(width, height, data));
439 matty 28 bitmap = XCreatePixmap(display, wnd, width, height, depth);
440 matty 29 image = XCreateImage(display, visual, depth, ZPixmap,
441     0, tdata, width, height, 8, 0);
442 matty 6
443 matty 28 XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
444 matty 9
445     XFree(image);
446 matty 29 if (!owncolmap)
447 matty 28 xfree(tdata);
448 matty 24 return (HBITMAP) bitmap;
449 matty 6 }
450    
451 matty 25 void
452     ui_paint_bitmap(int x, int y, int cx, int cy,
453     int width, int height, uint8 *data)
454 matty 6 {
455 matty 10 XImage *image;
456 matty 29 uint8 *tdata;
457 matty 10
458 matty 33 tdata = (owncolmap ? data : translate_image(width, height, data));
459 matty 29 image = XCreateImage(display, visual, depth, ZPixmap,
460     0, tdata, width, height, 8, 0);
461 matty 28
462 matty 31 if (ownbackstore)
463     {
464     XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
465     XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
466     }
467     else
468     {
469     XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
470     }
471 matty 29
472 matty 24 XFree(image);
473 matty 29 if (!owncolmap)
474 matty 28 xfree(tdata);
475 matty 6 }
476    
477 matty 25 void
478     ui_destroy_bitmap(HBITMAP bmp)
479 matty 6 {
480 matty 29 XFreePixmap(display, (Pixmap)bmp);
481 matty 10 }
482    
483 matty 25 HGLYPH
484     ui_create_glyph(int width, int height, uint8 *data)
485 matty 10 {
486 matty 9 XImage *image;
487     Pixmap bitmap;
488     int scanline;
489     GC gc;
490 matty 6
491 matty 9 scanline = (width + 7) / 8;
492 matty 6
493 matty 10 bitmap = XCreatePixmap(display, wnd, width, height, 1);
494     gc = XCreateGC(display, bitmap, 0, NULL);
495 matty 9
496 matty 10 image = XCreateImage(display, visual, 1, ZPixmap, 0,
497 matty 24 data, width, height, 8, scanline);
498 matty 23 image->byte_order = MSBFirst;
499     image->bitmap_bit_order = MSBFirst;
500     XInitImage(image);
501    
502 matty 10 XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
503 matty 29
504 matty 9 XFree(image);
505 matty 10 XFreeGC(display, gc);
506 matty 29 return (HGLYPH)bitmap;
507 matty 6 }
508 matty 7
509 matty 25 void
510     ui_destroy_glyph(HGLYPH glyph)
511 matty 7 {
512 matty 29 XFreePixmap(display, (Pixmap)glyph);
513 matty 9 }
514    
515 matty 29 HCURSOR
516     ui_create_cursor(unsigned int x, unsigned int y, int width,
517     int height, uint8 *andmask, uint8 *xormask)
518 matty 9 {
519 matty 29 HGLYPH maskglyph, cursorglyph;
520     XColor bg, fg;
521     Cursor xcursor;
522     uint8 *cursor, *pcursor;
523     uint8 *mask, *pmask;
524     uint8 nextbit;
525     int scanline, offset;
526     int i, j;
527    
528     scanline = (width + 7) / 8;
529     offset = scanline * height;
530    
531     cursor = xmalloc(offset);
532     memset(cursor, 0, offset);
533    
534     mask = xmalloc(offset);
535     memset(mask, 0, offset);
536    
537     /* approximate AND and XOR masks with a monochrome X pointer */
538     for (i = 0; i < height; i++)
539 matty 7 {
540 matty 29 offset -= scanline;
541     pcursor = &cursor[offset];
542     pmask = &mask[offset];
543    
544     for (j = 0; j < scanline; j++)
545 matty 28 {
546 matty 29 for (nextbit = 0x80; nextbit != 0; nextbit >>= 1)
547     {
548     if (xormask[0] || xormask[1] || xormask[2])
549     {
550     *pcursor |= (~(*andmask) & nextbit);
551     *pmask |= nextbit;
552     }
553     else
554     {
555     *pcursor |= ((*andmask) & nextbit);
556     *pmask |= (~(*andmask) & nextbit);
557     }
558    
559     xormask += 3;
560     }
561    
562     andmask++;
563     pcursor++;
564     pmask++;
565 matty 28 }
566 matty 7 }
567 matty 29
568     fg.red = fg.blue = fg.green = 0xffff;
569     bg.red = bg.blue = bg.green = 0x0000;
570     fg.flags = bg.flags = DoRed | DoBlue | DoGreen;
571    
572     cursorglyph = ui_create_glyph(width, height, cursor);
573     maskglyph = ui_create_glyph(width, height, mask);
574    
575     xcursor = XCreatePixmapCursor(display, (Pixmap)cursorglyph,
576     (Pixmap)maskglyph, &fg, &bg, x, y);
577    
578     ui_destroy_glyph(maskglyph);
579     ui_destroy_glyph(cursorglyph);
580     xfree(mask);
581     xfree(cursor);
582     return (HCURSOR)xcursor;
583     }
584    
585     void
586     ui_set_cursor(HCURSOR cursor)
587     {
588     XDefineCursor(display, wnd, (Cursor)cursor);
589     }
590    
591     void
592     ui_destroy_cursor(HCURSOR cursor)
593     {
594     XFreeCursor(display, (Cursor)cursor);
595     }
596    
597     #define MAKE_XCOLOR(xc,c) \
598     (xc)->red = ((c)->red << 8) | (c)->red; \
599     (xc)->green = ((c)->green << 8) | (c)->green; \
600     (xc)->blue = ((c)->blue << 8) | (c)->blue; \
601     (xc)->flags = DoRed | DoGreen | DoBlue;
602    
603     HCOLOURMAP
604     ui_create_colourmap(COLOURMAP *colours)
605     {
606     COLOURENTRY *entry;
607     int i, ncolours = colours->ncolours;
608    
609     if (owncolmap)
610 matty 28 {
611     XColor *xcolours, *xentry;
612     Colormap map;
613 matty 29
614 matty 28 xcolours = xmalloc(sizeof(XColor) * ncolours);
615     for (i = 0; i < ncolours; i++)
616     {
617     entry = &colours->colours[i];
618     xentry = &xcolours[i];
619     xentry->pixel = i;
620 matty 29 MAKE_XCOLOR(xentry, entry);
621 matty 28 }
622 matty 7
623 matty 28 map = XCreateColormap(display, wnd, visual, AllocAll);
624     XStoreColors(display, map, xcolours, ncolours);
625    
626     xfree(xcolours);
627 matty 29 return (HCOLOURMAP)map;
628 matty 28 }
629 matty 29 else
630     {
631     uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
632     XColor xentry;
633 matty 33 uint32 colour;
634 matty 29
635     for (i = 0; i < ncolours; i++)
636     {
637     entry = &colours->colours[i];
638     MAKE_XCOLOR(&xentry, entry);
639    
640     if (XAllocColor(display, xcolmap, &xentry) != 0)
641 matty 34 colour = xentry.pixel;
642 matty 29 else
643 matty 34 colour = white;
644 matty 33
645     /* byte swap here to make translate_image faster */
646     map[i] = translate_colour(colour);
647 matty 29 }
648    
649     return map;
650     }
651 matty 7 }
652    
653 matty 25 void
654     ui_destroy_colourmap(HCOLOURMAP map)
655 matty 7 {
656 matty 29 if (owncolmap)
657     XFreeColormap(display, (Colormap)map);
658     else
659     xfree(map);
660 matty 7 }
661    
662 matty 25 void
663     ui_set_colourmap(HCOLOURMAP map)
664 matty 7 {
665 matty 29 if (owncolmap)
666     XSetWindowColormap(display, wnd, (Colormap)map);
667     else
668 matty 28 colmap = map;
669 matty 7 }
670    
671 matty 25 void
672     ui_set_clip(int x, int y, int cx, int cy)
673 matty 7 {
674 matty 9 XRectangle rect;
675 matty 7
676 matty 9 rect.x = x;
677     rect.y = y;
678     rect.width = cx;
679     rect.height = cy;
680 matty 10 XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
681 matty 9 }
682 matty 7
683 matty 25 void
684     ui_reset_clip()
685 matty 9 {
686     XRectangle rect;
687    
688     rect.x = 0;
689     rect.y = 0;
690 matty 10 rect.width = width;
691     rect.height = height;
692     XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
693 matty 7 }
694    
695 matty 25 void
696     ui_bell()
697 matty 10 {
698     XBell(display, 0);
699     }
700    
701 matty 25 void
702     ui_destblt(uint8 opcode,
703     /* dest */ int x, int y, int cx, int cy)
704 matty 9 {
705 matty 29 SET_FUNCTION(opcode);
706 matty 31 FILL_RECTANGLE(x, y, cx, cy);
707 matty 29 RESET_FUNCTION(opcode);
708 matty 9 }
709    
710 matty 25 void
711     ui_patblt(uint8 opcode,
712     /* dest */ int x, int y, int cx, int cy,
713     /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
714 matty 9 {
715     Pixmap fill;
716    
717 matty 29 SET_FUNCTION(opcode);
718 matty 9
719     switch (brush->style)
720     {
721 matty 24 case 0: /* Solid */
722 matty 29 SET_FOREGROUND(fgcolour);
723 matty 31 FILL_RECTANGLE(x, y, cx, cy);
724 matty 9 break;
725    
726 matty 24 case 3: /* Pattern */
727 matty 29 fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);
728 matty 9
729 matty 29 SET_FOREGROUND(bgcolour);
730     SET_BACKGROUND(fgcolour);
731     XSetFillStyle(display, gc, FillOpaqueStippled);
732     XSetStipple(display, gc, fill);
733     XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);
734 matty 9
735 matty 31 FILL_RECTANGLE(x, y, cx, cy);
736 matty 9
737 matty 29 XSetFillStyle(display, gc, FillSolid);
738     ui_destroy_glyph((HGLYPH)fill);
739 matty 9 break;
740    
741     default:
742 matty 30 unimpl("brush %d\n", brush->style);
743 matty 9 }
744 matty 29
745     RESET_FUNCTION(opcode);
746 matty 9 }
747    
748 matty 25 void
749     ui_screenblt(uint8 opcode,
750     /* dest */ int x, int y, int cx, int cy,
751     /* src */ int srcx, int srcy)
752 matty 9 {
753 matty 29 SET_FUNCTION(opcode);
754 matty 24 XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
755 matty 31 if (ownbackstore)
756     XCopyArea(display, backstore, backstore, gc, srcx, srcy,
757     cx, cy, x, y);
758 matty 29 RESET_FUNCTION(opcode);
759 matty 9 }
760    
761 matty 25 void
762     ui_memblt(uint8 opcode,
763     /* dest */ int x, int y, int cx, int cy,
764     /* src */ HBITMAP src, int srcx, int srcy)
765 matty 9 {
766 matty 29 SET_FUNCTION(opcode);
767     XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);
768 matty 31 if (ownbackstore)
769     XCopyArea(display, (Pixmap)src, backstore, gc, srcx, srcy,
770     cx, cy, x, y);
771 matty 29 RESET_FUNCTION(opcode);
772 matty 9 }
773    
774 matty 25 void
775     ui_triblt(uint8 opcode,
776     /* dest */ int x, int y, int cx, int cy,
777     /* src */ HBITMAP src, int srcx, int srcy,
778     /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
779 matty 9 {
780     /* This is potentially difficult to do in general. Until someone
781 matty 10 comes up with a more efficient way of doing it I am using cases. */
782 matty 9
783     switch (opcode)
784     {
785 matty 24 case 0x69: /* PDSxxn */
786 matty 16 ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
787     ui_patblt(ROP2_NXOR, x, y, cx, cy,
788 matty 24 brush, bgcolour, fgcolour);
789 matty 16 break;
790    
791 matty 24 case 0xb8: /* PSDPxax */
792 matty 10 ui_patblt(ROP2_XOR, x, y, cx, cy,
793 matty 24 brush, bgcolour, fgcolour);
794 matty 16 ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
795 matty 10 ui_patblt(ROP2_XOR, x, y, cx, cy,
796 matty 24 brush, bgcolour, fgcolour);
797 matty 9 break;
798    
799 matty 29 case 0xc0: /* PSa */
800 matty 28 ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
801     ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,
802     fgcolour);
803     break;
804    
805 matty 9 default:
806 matty 30 unimpl("triblt 0x%x\n", opcode);
807 matty 16 ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
808 matty 9 }
809     }
810    
811 matty 25 void
812     ui_line(uint8 opcode,
813     /* dest */ int startx, int starty, int endx, int endy,
814     /* pen */ PEN *pen)
815 matty 9 {
816 matty 29 SET_FUNCTION(opcode);
817     SET_FOREGROUND(pen->colour);
818 matty 10 XDrawLine(display, wnd, gc, startx, starty, endx, endy);
819 matty 31 if (ownbackstore)
820     XDrawLine(display, backstore, gc, startx, starty, endx, endy);
821 matty 29 RESET_FUNCTION(opcode);
822 matty 9 }
823    
824 matty 25 void
825     ui_rect(
826     /* dest */ int x, int y, int cx, int cy,
827     /* brush */ int colour)
828 matty 9 {
829 matty 29 SET_FOREGROUND(colour);
830 matty 31 FILL_RECTANGLE(x, y, cx, cy);
831 matty 9 }
832    
833 matty 25 void
834     ui_draw_glyph(int mixmode,
835     /* dest */ int x, int y, int cx, int cy,
836     /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,
837     int fgcolour)
838 matty 9 {
839 matty 29 SET_FOREGROUND(fgcolour);
840     SET_BACKGROUND(bgcolour);
841 matty 9
842 matty 29 XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)
843     ? FillStippled : FillOpaqueStippled);
844     XSetStipple(display, gc, (Pixmap)glyph);
845     XSetTSOrigin(display, gc, x, y);
846 matty 9
847 matty 31 FILL_RECTANGLE(x, y, cx, cy);
848 matty 9
849 matty 29 XSetFillStyle(display, gc, FillSolid);
850 matty 9 }
851    
852 mmihalik 49 #define DO_GLYPH(ttext,idx) \
853     {\
854     glyph = cache_get_font (font, ttext[idx]);\
855     if (!(flags & TEXT2_IMPLICIT_X))\
856     {\
857     xyoffset = ttext[++idx];\
858     if ((xyoffset & 0x80))\
859     {\
860     if (flags & TEXT2_VERTICAL) \
861     y += ttext[++idx] | (ttext[++idx] << 8);\
862     else\
863     x += ttext[++idx] | (ttext[++idx] << 8);\
864     }\
865     else\
866     {\
867     if (flags & TEXT2_VERTICAL) \
868     y += xyoffset;\
869     else\
870     x += xyoffset;\
871     }\
872     }\
873     if (glyph != NULL)\
874     {\
875     ui_draw_glyph (mixmode, x + (short) glyph->offset,\
876     y + (short) glyph->baseline,\
877     glyph->width, glyph->height,\
878     glyph->pixmap, 0, 0, bgcolour, fgcolour);\
879     if (flags & TEXT2_IMPLICIT_X)\
880     x += glyph->width;\
881     }\
882     }
883    
884 matty 25 void
885     ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
886 mmihalik 49 int clipx, int clipy, int clipcx, int clipcy, int boxx,
887     int boxy, int boxcx, int boxcy, int bgcolour,
888     int fgcolour, uint8 * text, uint8 length)
889 matty 9 {
890 matty 10 FONTGLYPH *glyph;
891 mmihalik 49 int i, j, xyoffset;
892     DATABLOB *entry;
893 matty 9
894 matty 29 SET_FOREGROUND(bgcolour);
895 matty 28
896 matty 9 if (boxcx > 1)
897 matty 31 {
898     FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);
899     }
900 matty 17 else if (mixmode == MIX_OPAQUE)
901 matty 31 {
902     FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);
903     }
904 matty 9
905     /* Paint text, character by character */
906 mmihalik 49 for (i = 0; i < length;) {
907     switch (text[i]) {
908     case 0xff:
909     if (i + 2 < length)
910     cache_put_text(text[i + 1], text, text[i + 2]);
911     else {
912     error("this shouldn't be happening\n");
913     break;
914     }
915     /* this will move pointer from start to first character after FF command */
916     length -= i + 3;
917     text = &(text[i + 3]);
918     i = 0;
919     break;
920 matty 9
921 mmihalik 49 case 0xfe:
922     entry = cache_get_text(text[i + 1]);
923     if (entry != NULL) {
924     if ((((uint8 *) (entry->data))[1] == 0)
925     && (!(flags & TEXT2_IMPLICIT_X))) {
926     if (flags & TEXT2_VERTICAL)
927     y += text[i + 2];
928     else
929     x += text[i + 2];
930 matthewc 44 }
931 mmihalik 49 if (i + 2 < length)
932     i += 3;
933 matthewc 44 else
934 mmihalik 49 i += 2;
935     length -= i;
936     /* this will move pointer from start to first character after FE command */
937     text = &(text[i]);
938     i = 0;
939     for (j = 0; j < entry->size; j++)
940     DO_GLYPH(((uint8 *) (entry->data)), j);
941 matthewc 44 }
942 mmihalik 49 break;
943 matty 17
944 mmihalik 49 default:
945     DO_GLYPH(text, i);
946     i++;
947     break;
948 matty 29 }
949 mmihalik 49 }
950 matty 28
951 matty 9
952     }
953    
954 matty 25 void
955     ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
956 matty 9 {
957 matty 28 Pixmap pix;
958 matty 9 XImage *image;
959    
960 matty 31 if (ownbackstore)
961     {
962     image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,
963     ZPixmap);
964     }
965     else
966     {
967     pix = XCreatePixmap(display, wnd, cx, cy, depth);
968     XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
969     image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,
970     ZPixmap);
971     XFreePixmap(display, pix);
972     }
973 matty 28
974     offset *= bpp/8;
975     cache_put_desktop(offset, cx, cy, image->bytes_per_line,
976 matty 36 bpp/8, (uint8 *)image->data);
977 matty 28
978     XDestroyImage(image);
979 matty 9 }
980    
981 matty 25 void
982     ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
983 matty 9 {
984     XImage *image;
985 matty 10 uint8 *data;
986 matty 9
987 matty 28 offset *= bpp/8;
988     data = cache_get_desktop(offset, cx, cy, bpp/8);
989 matty 10 if (data == NULL)
990     return;
991 matty 29
992     image = XCreateImage(display, visual, depth, ZPixmap,
993 matty 28 0, data, cx, cy, BitmapPad(display),
994     cx * bpp/8);
995 matty 29
996 matty 31 if (ownbackstore)
997     {
998     XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
999     XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
1000     }
1001     else
1002     {
1003     XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
1004     }
1005    
1006 matty 9 XFree(image);
1007     }

  ViewVC Help
Powered by ViewVC 1.1.26