/[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 28 - (hide annotations)
Wed Jun 20 13:54:48 2001 UTC (22 years, 10 months ago) by matty
File MIME type: text/plain
File size: 27484 byte(s)
Merges from pl19-6-5.

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     extern BOOL motion;
29 matty 28 extern BOOL grab_keyboard;
30     extern BOOL fullscreen;
31     extern int private_colormap;
32 matty 10
33 matty 28 static int bpp;
34     static int depth;
35 matty 10 static Display *display;
36     static Window wnd;
37     static GC gc;
38     static Visual *visual;
39 matty 28 static uint32 *colmap;
40 matty 10
41 matty 28 #define Ctrans(col) ( private_colormap ? col : colmap[col])
42    
43     #define L_ENDIAN
44     int screen_msbfirst = 0;
45    
46     static uint8 *translate(int width, int height, uint8 *data);
47    
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     static void
68     xwin_set_function(uint8 rop2)
69     {
70     static uint8 last_rop2 = ROP2_COPY;
71    
72     if (last_rop2 != rop2)
73     {
74     XSetFunction(display, gc, rop2_map[rop2]);
75     last_rop2 = rop2;
76     }
77     }
78    
79     static void
80     xwin_grab_keyboard()
81     {
82     XGrabKeyboard(display, wnd, True, GrabModeAsync, GrabModeAsync,
83     CurrentTime);
84     }
85    
86     static void
87     xwin_ungrab_keyboard()
88     {
89     XUngrabKeyboard(display, CurrentTime);
90     }
91    
92 matty 25 BOOL
93     ui_create_window(char *title)
94 matty 6 {
95 matty 9 XSetWindowAttributes attribs;
96 matty 28 XClassHint *classhints;
97     XSizeHints *sizehints;
98 matty 10 unsigned long input_mask;
99 matty 28 XPixmapFormatValues *pfm;
100     int count;
101 matty 6
102     display = XOpenDisplay(NULL);
103     if (display == NULL)
104 matty 21 {
105     ERROR("Failed to open display\n");
106 matty 10 return False;
107 matty 21 }
108 matty 6
109 matty 28 visual = DefaultVisual(display, DefaultScreen(display));
110     depth = DefaultDepth(display, DefaultScreen(display));
111     pfm = XListPixmapFormats(display, &count);
112     if (pfm != NULL)
113     {
114     while (count--)
115     {
116     if ((pfm + count)->depth == depth
117     && (pfm + count)->bits_per_pixel > bpp)
118     {
119     bpp = (pfm + count)->bits_per_pixel;
120     }
121     }
122     XFree(pfm);
123     }
124 matty 10
125 matty 28 if (bpp < 8)
126 matty 10 {
127 matty 28 ERROR("Less than 8 bpp not currently supported.\n");
128 matty 10 XCloseDisplay(display);
129     return False;
130     }
131    
132 matty 28 width &= ~3; /* make width nicely divisible */
133 matty 6
134 matty 28 attribs.background_pixel = BlackPixel(display, DefaultScreen(display));
135 matty 9 attribs.backing_store = Always;
136 matty 28
137     if (fullscreen)
138     {
139     attribs.override_redirect = True;
140     width = WidthOfScreen(DefaultScreenOfDisplay(display));
141     height = HeightOfScreen(DefaultScreenOfDisplay(display));
142     XSetInputFocus(display, PointerRoot, RevertToPointerRoot,
143     CurrentTime);
144     }
145     else
146     {
147     attribs.override_redirect = False;
148     }
149    
150 matty 10 wnd = XCreateWindow(display, DefaultRootWindow(display),
151 matty 28 0, 0, width, height, 0, CopyFromParent,
152     InputOutput, CopyFromParent,
153     CWBackingStore | CWBackPixel | CWOverrideRedirect,
154     &attribs);
155 matty 9
156 matty 10 XStoreName(display, wnd, title);
157 matty 6
158 matty 28 classhints = XAllocClassHint();
159     if (classhints != NULL)
160    
161     {
162     classhints->res_name = "rdesktop";
163     classhints->res_class = "rdesktop";
164     XSetClassHint(display, wnd, classhints);
165     XFree(classhints);
166     }
167    
168     sizehints = XAllocSizeHints();
169     if (sizehints)
170     {
171     sizehints->flags =
172     PPosition | PSize | PMinSize | PMaxSize | PBaseSize;
173     sizehints->min_width = width;
174     sizehints->max_width = width;
175     sizehints->min_height = height;
176     sizehints->max_height = height;
177     sizehints->base_width = width;
178     sizehints->base_height = height;
179     XSetWMNormalHints(display, wnd, sizehints);
180     XFree(sizehints);
181     }
182    
183 matty 24 input_mask = KeyPressMask | KeyReleaseMask;
184 matty 10 input_mask |= ButtonPressMask | ButtonReleaseMask;
185     if (motion)
186     input_mask |= PointerMotionMask;
187 matty 28 if (grab_keyboard)
188     input_mask |= EnterWindowMask | LeaveWindowMask;
189 matty 6
190 matty 10 XSelectInput(display, wnd, input_mask);
191     gc = XCreateGC(display, wnd, 0, NULL);
192 matty 7
193 matty 28 XMapWindow(display, wnd);
194 matty 10 return True;
195 matty 6 }
196    
197 matty 25 void
198     ui_destroy_window()
199 matty 6 {
200 matty 10 XFreeGC(display, gc);
201     XDestroyWindow(display, wnd);
202     XCloseDisplay(display);
203 matty 28 display = NULL;
204 matty 6 }
205    
206 matty 25 static uint8
207     xwin_translate_key(unsigned long key)
208 matty 9 {
209     DEBUG("KEY(code=0x%lx)\n", key);
210    
211     if ((key > 8) && (key <= 0x60))
212     return (key - 8);
213    
214     switch (key)
215     {
216 matty 28 case 0x61: /* home */
217     return 0x47 | 0x80;
218     case 0x62: /* up arrow */
219     return 0x48 | 0x80;
220     case 0x63: /* page up */
221     return 0x49 | 0x80;
222     case 0x64: /* left arrow */
223     return 0x4b | 0x80;
224     case 0x66: /* right arrow */
225     return 0x4d | 0x80;
226     case 0x67: /* end */
227     return 0x4f | 0x80;
228     case 0x68: /* down arrow */
229     return 0x50 | 0x80;
230     case 0x69: /* page down */
231     return 0x51 | 0x80;
232     case 0x6a: /* insert */
233     return 0x52 | 0x80;
234     case 0x6b: /* delete */
235     return 0x53 | 0x80;
236     case 0x6c: /* keypad enter */
237     return 0x1c | 0x80;
238     case 0x6d: /* right ctrl */
239     return 0x1d | 0x80;
240     case 0x6f: /* ctrl - print screen */
241     return 0x37 | 0x80;
242     case 0x70: /* keypad '/' */
243     return 0x35 | 0x80;
244     case 0x71: /* right alt */
245     return 0x38 | 0x80;
246     case 0x72: /* ctrl break */
247     return 0x46 | 0x80;
248     case 0x73: /* left window key */
249     return 0xff; /* real scancode is 5b */
250     case 0x74: /* right window key */
251     return 0xff; /* real scancode is 5c */
252     case 0x75: /* menu key */
253     return 0x5d | 0x80;
254 matty 9 }
255    
256     return 0;
257     }
258    
259 matty 25 static uint16
260     xwin_translate_mouse(unsigned long button)
261 matty 9 {
262     switch (button)
263     {
264 matty 24 case Button1: /* left */
265 matty 9 return MOUSE_FLAG_BUTTON1;
266 matty 24 case Button2: /* middle */
267 matty 9 return MOUSE_FLAG_BUTTON3;
268 matty 24 case Button3: /* right */
269 matty 9 return MOUSE_FLAG_BUTTON2;
270     }
271    
272     return 0;
273     }
274    
275 matty 25 void
276     ui_process_events()
277 matty 9 {
278     XEvent event;
279     uint8 scancode;
280     uint16 button;
281 matty 10 uint32 ev_time;
282 matty 9
283 matty 10 if (display == NULL)
284 matty 9 return;
285    
286 matty 28 while (XCheckWindowEvent(display, wnd, ~0, &event))
287 matty 9 {
288 matty 10 ev_time = time(NULL);
289    
290 matty 9 switch (event.type)
291     {
292     case KeyPress:
293 matty 28 scancode = xwin_translate_key(event.xkey.keycode);
294 matty 9 if (scancode == 0)
295     break;
296    
297 matty 10 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,
298 matty 24 scancode, 0);
299 matty 9 break;
300    
301     case KeyRelease:
302 matty 28 scancode = xwin_translate_key(event.xkey.keycode);
303 matty 9 if (scancode == 0)
304     break;
305    
306 matty 10 rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
307 matty 24 KBD_FLAG_DOWN | KBD_FLAG_UP,
308     scancode, 0);
309 matty 9 break;
310    
311     case ButtonPress:
312 matty 28 button = xwin_translate_mouse(event.xbutton.button);
313 matty 9 if (button == 0)
314     break;
315    
316 matty 10 rdp_send_input(ev_time, RDP_INPUT_MOUSE,
317 matty 24 button | MOUSE_FLAG_DOWN,
318     event.xbutton.x,
319     event.xbutton.y);
320 matty 9 break;
321    
322     case ButtonRelease:
323 matty 28 button = xwin_translate_mouse(event.xbutton.button);
324 matty 9 if (button == 0)
325     break;
326    
327 matty 10 rdp_send_input(ev_time, RDP_INPUT_MOUSE,
328 matty 24 button,
329     event.xbutton.x,
330     event.xbutton.y);
331 matty 10 break;
332    
333     case MotionNotify:
334     rdp_send_input(ev_time, RDP_INPUT_MOUSE,
335 matty 24 MOUSE_FLAG_MOVE,
336     event.xmotion.x,
337     event.xmotion.y);
338 matty 28 break;
339    
340     case EnterNotify:
341     if (grab_keyboard)
342     xwin_grab_keyboard();
343     break;
344    
345     case LeaveNotify:
346     if (grab_keyboard)
347     xwin_ungrab_keyboard();
348     break;
349 matty 9 }
350     }
351     }
352    
353 matty 25 void
354     ui_move_pointer(int x, int y)
355 matty 9 {
356 matty 10 XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);
357 matty 9 }
358    
359 matty 25 HBITMAP
360     ui_create_bitmap(int width, int height, uint8 *data)
361 matty 6 {
362     XImage *image;
363 matty 9 Pixmap bitmap;
364 matty 28 uint8 *tdata;
365     tdata = (private_colormap ? data : translate(width, height, data));
366     bitmap = XCreatePixmap(display, wnd, width, height, depth);
367     image =
368     XCreateImage(display, visual,
369     depth, ZPixmap,
370     0, tdata, width, height, BitmapPad(display), 0);
371 matty 6
372 matty 28 xwin_set_function(ROP2_COPY);
373     XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
374 matty 9
375     XFree(image);
376 matty 28 if (!private_colormap)
377     xfree(tdata);
378 matty 24 return (HBITMAP) bitmap;
379 matty 6 }
380    
381 matty 25 void
382     ui_paint_bitmap(int x, int y, int cx, int cy,
383     int width, int height, uint8 *data)
384 matty 6 {
385 matty 10 XImage *image;
386 matty 28 uint8 *tdata =
387     (private_colormap ? data : translate(width, height, data));
388     image =
389     XCreateImage(display, visual, depth, ZPixmap, 0, tdata, width,
390     height, BitmapPad(display), 0);
391 matty 10
392 matty 28 xwin_set_function(ROP2_COPY);
393    
394     /* Window */
395 matty 10 XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
396 matty 24 XFree(image);
397 matty 28 if (!private_colormap)
398     xfree(tdata);
399 matty 6 }
400    
401 matty 25 void
402     ui_destroy_bitmap(HBITMAP bmp)
403 matty 6 {
404 matty 24 XFreePixmap(display, (Pixmap) bmp);
405 matty 10 }
406    
407 matty 28 HCURSOR
408     ui_create_cursor(unsigned int x, unsigned int y, int width,
409     int height, uint8 *mask, uint8 *data)
410     {
411     XImage *imagecursor;
412     XImage *imagemask;
413     Pixmap maskbitmap, cursorbitmap;
414     Cursor cursor;
415     XColor bg, fg;
416     GC lgc;
417     int i, x1, y1, scanlinelen;
418     uint8 *cdata, *cmask;
419     uint8 c;
420     cdata = (uint8 *) malloc(sizeof(uint8) * width * height);
421     if (!cdata)
422     return NULL;
423     scanlinelen = (width + 7) >> 3;
424     cmask = (uint8 *) malloc(sizeof(uint8) * scanlinelen * height);
425     if (!cmask)
426     {
427     free(cdata);
428     return NULL;
429     }
430     i = (height - 1) * scanlinelen;
431    
432     if (!screen_msbfirst)
433     {
434     while (i >= 0)
435     {
436     for (x1 = 0; x1 < scanlinelen; x1++)
437     {
438     c = *(mask++);
439     cmask[i + x1] =
440     ((c & 0x1) << 7) | ((c & 0x2) << 5) |
441     ((c & 0x4) << 3) | ((c & 0x8) << 1) |
442     ((c & 0x10) >> 1) | ((c & 0x20) >> 3)
443     | ((c & 0x40) >> 5) | ((c & 0x80) >>
444     7);
445     }
446     i -= scanlinelen;
447     }
448     }
449     else
450     {
451     while (i >= 0)
452     {
453     for (x1 = 0; x1 < scanlinelen; x1++)
454     {
455     cmask[i + x1] = *(mask++);
456     }
457     i -= scanlinelen;
458     }
459     }
460    
461    
462     fg.red = 0;
463     fg.blue = 0;
464     fg.green = 0;
465     fg.flags = DoRed | DoBlue | DoGreen;
466     bg.red = 65535;
467     bg.blue = 65535;
468     bg.green = 65535;
469     bg.flags = DoRed | DoBlue | DoGreen;
470     maskbitmap = XCreatePixmap(display, wnd, width, height, 1);
471     cursorbitmap = XCreatePixmap(display, wnd, width, height, 1);
472     lgc = XCreateGC(display, maskbitmap, 0, NULL);
473     XSetFunction(display, lgc, GXcopy);
474     imagemask =
475     XCreateImage(display, visual, 1, XYBitmap, 0, cmask, width,
476     height, 8, 0);
477     imagecursor =
478     XCreateImage(display, visual, 1, XYBitmap, 0, cdata, width,
479     height, 8, 0);
480     for (y1 = height - 1; y1 >= 0; y1--)
481     for (x1 = 0; x1 < width; x1++)
482     {
483     if (data[0] >= 0x80 || data[1] >= 0x80
484     || data[2] >= 0x80)
485     if (XGetPixel(imagemask, x1, y1))
486    
487     {
488     XPutPixel(imagecursor, x1, y1, 0);
489     XPutPixel(imagemask, x1, y1, 0); /* mask is blank for text cursor! */
490     }
491    
492     else
493     XPutPixel(imagecursor, x1, y1, 1);
494    
495     else
496     XPutPixel(imagecursor, x1, y1,
497     XGetPixel(imagemask, x1, y1));
498     data += 3;
499     }
500     XPutImage(display, maskbitmap, lgc, imagemask, 0, 0, 0, 0, width,
501     height);
502     XPutImage(display, cursorbitmap, lgc, imagecursor, 0, 0, 0, 0, width,
503     height); XFree(imagemask);
504     XFree(imagecursor);
505     free(cmask);
506     free(cdata);
507     XFreeGC(display, lgc);
508     cursor =
509     XCreatePixmapCursor(display, cursorbitmap, maskbitmap, &fg,
510     &bg, x, y);
511     XFreePixmap(display, maskbitmap);
512     XFreePixmap(display, cursorbitmap);
513     return (HCURSOR) cursor;
514     }
515    
516     void
517     ui_set_cursor(HCURSOR cursor)
518     {
519     XDefineCursor(display, wnd, (Cursor) cursor);
520     }
521    
522     void
523     ui_destroy_cursor(HCURSOR cursor)
524     {
525     XFreeCursor(display, (Cursor) cursor);
526     }
527    
528 matty 25 HGLYPH
529     ui_create_glyph(int width, int height, uint8 *data)
530 matty 10 {
531 matty 9 XImage *image;
532     Pixmap bitmap;
533     int scanline;
534     GC gc;
535 matty 6
536 matty 9 scanline = (width + 7) / 8;
537 matty 6
538 matty 10 bitmap = XCreatePixmap(display, wnd, width, height, 1);
539     gc = XCreateGC(display, bitmap, 0, NULL);
540 matty 9
541 matty 10 image = XCreateImage(display, visual, 1, ZPixmap, 0,
542 matty 24 data, width, height, 8, scanline);
543 matty 23 image->byte_order = MSBFirst;
544     image->bitmap_bit_order = MSBFirst;
545     XInitImage(image);
546    
547 matty 10 XSetFunction(display, gc, GXcopy);
548     XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
549 matty 9 XFree(image);
550 matty 10 XFreeGC(display, gc);
551 matty 24
552     return (HGLYPH) bitmap;
553 matty 6 }
554 matty 7
555 matty 25 void
556     ui_destroy_glyph(HGLYPH glyph)
557 matty 7 {
558 matty 24 XFreePixmap(display, (Pixmap) glyph);
559 matty 9 }
560    
561 matty 25 HCOLOURMAP
562     ui_create_colourmap(COLOURMAP *colours)
563 matty 9 {
564 matty 28 if (!private_colormap)
565 matty 7 {
566 matty 28 COLOURENTRY *entry;
567     int i, ncolours = colours->ncolours;
568     uint32 *nc = xmalloc(sizeof(*colmap) * ncolours);
569     for (i = 0; i < ncolours; i++)
570     {
571     XColor xc;
572     entry = &colours->colours[i];
573     xc.red = entry->red << 8;
574     xc.green = entry->green << 8;
575     xc.blue = entry->blue << 8;
576     XAllocColor(display,
577     DefaultColormap(display,
578     DefaultScreen(display)),
579     &xc);
580     /* XXX Check return value */
581     nc[i] = xc.pixel;
582     }
583     return nc;
584 matty 7 }
585 matty 28 else
586     {
587     COLOURENTRY *entry;
588     XColor *xcolours, *xentry;
589     Colormap map;
590     int i, ncolours = colours->ncolours;
591     xcolours = xmalloc(sizeof(XColor) * ncolours);
592     for (i = 0; i < ncolours; i++)
593     {
594     entry = &colours->colours[i];
595     xentry = &xcolours[i];
596 matty 7
597 matty 28 xentry->pixel = i;
598     xentry->red = entry->red << 8;
599     xentry->blue = entry->blue << 8;
600     xentry->green = entry->green << 8;
601     xentry->flags = DoRed | DoBlue | DoGreen;
602     }
603 matty 7
604 matty 28 map = XCreateColormap(display, wnd, visual, AllocAll);
605     XStoreColors(display, map, xcolours, ncolours);
606    
607     xfree(xcolours);
608     return (HCOLOURMAP) map;
609     }
610 matty 7 }
611    
612 matty 25 void
613     ui_destroy_colourmap(HCOLOURMAP map)
614 matty 7 {
615 matty 24 XFreeColormap(display, (Colormap) map);
616 matty 7 }
617    
618 matty 25 void
619     ui_set_colourmap(HCOLOURMAP map)
620 matty 7 {
621 matty 28
622     /* XXX, change values of all pixels on the screen if the new colmap
623     * doesn't have the same values as the old one? */
624     if (!private_colormap)
625     colmap = map;
626     else
627     {
628     XSetWindowColormap(display, wnd, (Colormap) map);
629     if (fullscreen)
630     XInstallColormap(display, (Colormap) map);
631     }
632 matty 7 }
633    
634 matty 25 void
635     ui_set_clip(int x, int y, int cx, int cy)
636 matty 7 {
637 matty 9 XRectangle rect;
638 matty 7
639 matty 9 rect.x = x;
640     rect.y = y;
641     rect.width = cx;
642     rect.height = cy;
643 matty 10 XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
644 matty 9 }
645 matty 7
646 matty 25 void
647     ui_reset_clip()
648 matty 9 {
649     XRectangle rect;
650    
651     rect.x = 0;
652     rect.y = 0;
653 matty 10 rect.width = width;
654     rect.height = height;
655     XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
656 matty 7 }
657    
658 matty 25 void
659     ui_bell()
660 matty 10 {
661     XBell(display, 0);
662     }
663    
664 matty 25 void
665     ui_destblt(uint8 opcode,
666     /* dest */ int x, int y, int cx, int cy)
667 matty 9 {
668 matty 10 xwin_set_function(opcode);
669 matty 9
670 matty 10 XFillRectangle(display, wnd, gc, x, y, cx, cy);
671 matty 9 }
672    
673 matty 25 void
674     ui_patblt(uint8 opcode,
675     /* dest */ int x, int y, int cx, int cy,
676     /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
677 matty 9 {
678 matty 10 Display *dpy = display;
679 matty 9 Pixmap fill;
680 matty 28 uint8 i, ipattern[8];
681 matty 9
682 matty 10 xwin_set_function(opcode);
683 matty 9
684     switch (brush->style)
685     {
686 matty 24 case 0: /* Solid */
687 matty 28 XSetForeground(dpy, gc, Ctrans(fgcolour));
688 matty 10 XFillRectangle(dpy, wnd, gc, x, y, cx, cy);
689 matty 9 break;
690    
691 matty 24 case 3: /* Pattern */
692 matty 28 for (i = 0; i != 8; i++)
693     ipattern[i] = ~brush->pattern[i];
694     fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
695 matty 9
696 matty 28 XSetForeground(dpy, gc, Ctrans(fgcolour));
697     XSetBackground(dpy, gc, Ctrans(bgcolour));
698 matty 9 XSetFillStyle(dpy, gc, FillOpaqueStippled);
699     XSetStipple(dpy, gc, fill);
700    
701 matty 10 XFillRectangle(dpy, wnd, gc, x, y, cx, cy);
702 matty 9
703     XSetFillStyle(dpy, gc, FillSolid);
704 matty 24 ui_destroy_glyph((HGLYPH) fill);
705 matty 9 break;
706    
707     default:
708 matty 10 NOTIMP("brush %d\n", brush->style);
709 matty 9 }
710     }
711    
712 matty 25 void
713     ui_screenblt(uint8 opcode,
714     /* dest */ int x, int y, int cx, int cy,
715     /* src */ int srcx, int srcy)
716 matty 9 {
717 matty 10 xwin_set_function(opcode);
718 matty 9
719 matty 24 XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
720 matty 9 }
721    
722 matty 25 void
723     ui_memblt(uint8 opcode,
724     /* dest */ int x, int y, int cx, int cy,
725     /* src */ HBITMAP src, int srcx, int srcy)
726 matty 9 {
727 matty 10 xwin_set_function(opcode);
728 matty 9
729 matty 24 XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
730 matty 9 }
731    
732 matty 25 void
733     ui_triblt(uint8 opcode,
734     /* dest */ int x, int y, int cx, int cy,
735     /* src */ HBITMAP src, int srcx, int srcy,
736     /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
737 matty 9 {
738     /* This is potentially difficult to do in general. Until someone
739 matty 10 comes up with a more efficient way of doing it I am using cases. */
740 matty 9
741     switch (opcode)
742     {
743 matty 24 case 0x69: /* PDSxxn */
744 matty 16 ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
745     ui_patblt(ROP2_NXOR, x, y, cx, cy,
746 matty 24 brush, bgcolour, fgcolour);
747 matty 16 break;
748    
749 matty 24 case 0xb8: /* PSDPxax */
750 matty 10 ui_patblt(ROP2_XOR, x, y, cx, cy,
751 matty 24 brush, bgcolour, fgcolour);
752 matty 16 ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
753 matty 10 ui_patblt(ROP2_XOR, x, y, cx, cy,
754 matty 24 brush, bgcolour, fgcolour);
755 matty 9 break;
756    
757 matty 28 case 0xc0:
758     ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
759     ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,
760     fgcolour);
761     break;
762    
763 matty 9 default:
764 matty 10 NOTIMP("triblt 0x%x\n", opcode);
765 matty 16 ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
766 matty 9 }
767     }
768    
769 matty 25 void
770     ui_line(uint8 opcode,
771     /* dest */ int startx, int starty, int endx, int endy,
772     /* pen */ PEN *pen)
773 matty 9 {
774 matty 10 xwin_set_function(opcode);
775 matty 9
776 matty 28 XSetForeground(display, gc, Ctrans(pen->colour));
777 matty 10 XDrawLine(display, wnd, gc, startx, starty, endx, endy);
778 matty 9 }
779    
780 matty 25 void
781     ui_rect(
782     /* dest */ int x, int y, int cx, int cy,
783     /* brush */ int colour)
784 matty 9 {
785 matty 10 xwin_set_function(ROP2_COPY);
786 matty 9
787 matty 28 XSetForeground(display, gc, Ctrans(colour));
788 matty 10 XFillRectangle(display, wnd, gc, x, y, cx, cy);
789 matty 9 }
790    
791 matty 25 void
792     ui_draw_glyph(int mixmode,
793     /* dest */ int x, int y, int cx, int cy,
794     /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,
795     int fgcolour)
796 matty 9 {
797 matty 24 Pixmap pixmap = (Pixmap) glyph;
798 matty 9
799 matty 10 xwin_set_function(ROP2_COPY);
800 matty 9
801    
802 matty 28 XSetForeground(display, gc, Ctrans(fgcolour));
803 matty 9 switch (mixmode)
804     {
805     case MIX_TRANSPARENT:
806 matty 10 XSetStipple(display, gc, pixmap);
807     XSetFillStyle(display, gc, FillStippled);
808     XSetTSOrigin(display, gc, x, y);
809 matty 24 XFillRectangle(display, wnd, gc, x, y, cx, cy);
810 matty 10 XSetFillStyle(display, gc, FillSolid);
811 matty 9 break;
812    
813     case MIX_OPAQUE:
814 matty 28 XSetBackground(display, gc, Ctrans(bgcolour));
815     /* XCopyPlane (display, pixmap, back_pixmap, back_gc, srcx, srcy, cx, cy, x, y, 1); */
816     XSetStipple(display, gc, pixmap);
817     XSetFillStyle(display, gc, FillOpaqueStippled);
818     XSetTSOrigin(display, gc, x, y);
819     XFillRectangle(display, wnd, gc, x, y, cx, cy);
820     XSetFillStyle(display, gc, FillSolid);
821 matty 9 break;
822    
823     default:
824 matty 10 NOTIMP("mix %d\n", mixmode);
825 matty 9 }
826     }
827    
828 matty 25 void
829     ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
830     int clipx, int clipy, int clipcx, int clipcy,
831     int boxx, int boxy, int boxcx, int boxcy,
832     int bgcolour, int fgcolour, uint8 *text, uint8 length)
833 matty 9 {
834 matty 10 FONTGLYPH *glyph;
835 matty 28 int i, xyoffset;
836 matty 9
837 matty 28 xwin_set_function(ROP2_COPY);
838     XSetForeground(display, gc, Ctrans(bgcolour));
839    
840 matty 9 if (boxcx > 1)
841 matty 28 XFillRectangle(display, wnd, gc, boxx, boxy, boxcx, boxcy);
842 matty 17 else if (mixmode == MIX_OPAQUE)
843 matty 28 XFillRectangle(display, wnd, gc, clipx, clipy, clipcx, clipcy);
844 matty 9
845     /* Paint text, character by character */
846     for (i = 0; i < length; i++)
847     {
848 matty 10 glyph = cache_get_font(font, text[i]);
849 matty 9
850 matty 17 if (!(flags & TEXT2_IMPLICIT_X))
851    
852 matty 28 {
853     xyoffset = text[++i];
854     if ((xyoffset & 0x80))
855     {
856     if (flags & 0x04) /* vertical text */
857     y += text[++i] | (text[++i] << 8);
858     else
859     x += text[++i] | (text[++i] << 8);
860     }
861     else
862     {
863     if (flags & 0x04) /* vertical text */
864     y += xyoffset;
865     else
866     x += xyoffset;
867     }
868    
869     }
870 matty 9 if (glyph != NULL)
871     {
872 matty 24 ui_draw_glyph(mixmode, x + (short) glyph->offset,
873     y + (short) glyph->baseline,
874     glyph->width, glyph->height,
875     glyph->pixmap, 0, 0,
876     bgcolour, fgcolour);
877 matty 9
878     if (flags & TEXT2_IMPLICIT_X)
879     x += glyph->width;
880     }
881     }
882     }
883    
884 matty 25 void
885     ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
886 matty 9 {
887 matty 28 Pixmap pix;
888 matty 9 XImage *image;
889    
890 matty 28 pix = XCreatePixmap(display, wnd, cx, cy, depth);
891     xwin_set_function(ROP2_COPY);
892    
893     XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
894     image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
895    
896     offset *= bpp/8;
897     cache_put_desktop(offset, cx, cy, image->bytes_per_line,
898     bpp/8, image->data);
899    
900     XDestroyImage(image);
901     XFreePixmap(display, pix);
902 matty 9 }
903    
904 matty 25 void
905     ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
906 matty 9 {
907     XImage *image;
908 matty 10 uint8 *data;
909 matty 9
910 matty 28 offset *= bpp/8;
911     data = cache_get_desktop(offset, cx, cy, bpp/8);
912 matty 10 if (data == NULL)
913     return;
914 matty 28 image =
915     XCreateImage(display, visual,
916     depth, ZPixmap,
917     0, data, cx, cy, BitmapPad(display),
918     cx * bpp/8);
919     xwin_set_function(ROP2_COPY);
920 matty 10 XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
921 matty 9 XFree(image);
922     }
923 matty 28
924     /* unroll defines, used to make the loops a bit more readable... */
925     #define unroll8Expr(uexp) uexp uexp uexp uexp uexp uexp uexp uexp
926     #define unroll8Lefts(uexp) case 7: uexp \
927     case 6: uexp \
928     case 5: uexp \
929     case 4: uexp \
930     case 3: uexp \
931     case 2: uexp \
932     case 1: uexp
933    
934     static uint8 *
935     translate(int width, int height, uint8 *data)
936     {
937     uint32 i;
938     uint32 size = width * height;
939     uint8 *d2 = xmalloc(size * bpp/8);
940     uint8 *d3 = d2;
941     uint32 pix;
942     i = (size & ~0x7);
943    
944     /* XXX: where are the bits swapped??? */
945     #ifdef L_ENDIAN /* little-endian */
946     /* big-endian screen */
947     if (screen_msbfirst)
948     {
949     switch (bpp)
950     {
951     case 32:
952     while (i)
953     {
954     unroll8Expr(pix = colmap[*data++];
955     *d3++ = pix >> 24;
956     *d3++ = pix >> 16;
957     *d3++ = pix >> 8;
958     *d3++ = pix;) i -= 8;
959     }
960     i = (size & 0x7);
961     if (i != 0)
962     switch (i)
963     {
964     unroll8Lefts(pix =
965     colmap
966     [*data++];
967     *d3++ =
968     pix >>
969     24;
970     *d3++ =
971     pix >>
972     16;
973     *d3++ =
974     pix >> 8;
975     *d3++ =
976     pix;)}
977     break;
978     case 24:
979     while (i)
980     {
981     unroll8Expr(pix = colmap[*data++];
982     *d3++ = pix >> 16;
983     *d3++ = pix >> 8;
984     *d3++ = pix;) i -= 8;
985     }
986     i = (size & 0x7);
987     if (i != 0)
988     switch (i)
989     {
990     unroll8Lefts(pix =
991     colmap
992     [*data++];
993     *d3++ =
994     pix >>
995     16;
996     *d3++ =
997     pix >> 8;
998     *d3++ =
999     pix;)}
1000     break;
1001     case 16:
1002     while (i)
1003     {
1004     unroll8Expr(pix = colmap[*data++];
1005     *d3++ = pix >> 8;
1006     *d3++ = pix;) i -= 8;
1007     }
1008     i = (size & 0x7);
1009     if (i != 0)
1010     switch (i)
1011     {
1012     unroll8Lefts(pix =
1013     colmap
1014     [*data++];
1015     *d3++ =
1016     pix >> 8;
1017     *d3++ =
1018     pix;)}
1019     break;
1020     case 8:
1021     while (i)
1022     {
1023     unroll8Expr(pix = colmap[*data++];
1024     *d3++ = pix;
1025     )i -= 8;
1026     }
1027     i = (size & 0x7);
1028     if (i != 0)
1029     switch (i)
1030     {
1031     unroll8Lefts(pix =
1032     colmap
1033     [*data++];
1034     *d3++ =
1035     pix;)}
1036     break;
1037     }
1038     }
1039     else
1040     { /* little-endian screen */
1041     switch (bpp)
1042     {
1043     case 32:
1044     while (i)
1045     {
1046     unroll8Expr(*((uint32 *) d3) =
1047     colmap[*data++];
1048     d3 += sizeof(uint32);
1049     )i -= 8;
1050     }
1051     i = (size & 0x7);
1052     if (i != 0)
1053     switch (i)
1054     {
1055     unroll8Lefts(*
1056     ((uint32
1057     *) d3)
1058     = colmap[*data++];
1059     d3 += sizeof(uint32);
1060     )}
1061     break;
1062     case 24:
1063     while (i)
1064     {
1065     unroll8Expr(pix = colmap[*data++];
1066     *d3++ = pix;
1067     *d3++ = pix >> 8;
1068     *d3++ = pix >> 16;
1069     )i -= 8;
1070     }
1071     i = (size & 0x7);
1072     if (i != 0)
1073     switch (i)
1074     {
1075     unroll8Lefts(pix =
1076     colmap
1077     [*data++];
1078     *d3++ =
1079     pix;
1080     *d3++ =
1081     pix >> 8;
1082     *d3++ =
1083     pix >>
1084     16;)}
1085     break;
1086     case 16:
1087     while (i)
1088     {
1089     unroll8Expr(pix = colmap[*data++];
1090     *d3++ = pix;
1091     *d3++ = pix >> 8;
1092     )i -= 8;
1093     }
1094     i = (size & 0x7);
1095     if (i != 0)
1096     switch (i)
1097     {
1098     unroll8Lefts(pix =
1099     colmap
1100     [*data++];
1101     *d3++ =
1102     pix;
1103     *d3++ =
1104     pix >> 8;
1105     )}
1106     break;
1107     case 8:
1108     while (i)
1109     {
1110     unroll8Expr(pix = colmap[*data++];
1111     *d3++ = pix;
1112     )i -= 8;
1113     }
1114     i = (size & 0x7);
1115     if (i != 0)
1116     switch (i)
1117     {
1118     unroll8Lefts(pix =
1119     colmap
1120     [*data++];
1121     *d3++ =
1122     pix;)}
1123     }
1124     }
1125    
1126     #else /* bigendian-compiled */
1127     if (screen_msbfirst)
1128     {
1129     /* big-endian screen */
1130     switch (bpp)
1131     {
1132     case 32:
1133     while (i)
1134     {
1135     unroll8Expr(*((uint32 *) d3) =
1136     colmap[*data++];
1137     d3 += sizeof(uint32);
1138     )i -= 8;
1139     }
1140     i = (size & 0x7);
1141     if (i != 0)
1142     switch (i)
1143     {
1144     unroll8Lefts(*
1145     ((uint32
1146     *) d3)
1147     = colmap[*data++];
1148     d3 += sizeof(uint32);
1149     )}
1150     break;
1151     case 24:
1152     while (i)
1153     {
1154     unroll8Expr(pix = colmap[*data++];
1155     *d3++ = pix;
1156     *d3++ = pix >> 8;
1157     *d3++ = pix >> 16;
1158     )i -= 8;
1159     }
1160     i = (size & 0x7);
1161     if (i != 0)
1162     switch (i)
1163     {
1164     unroll8Lefts(pix =
1165     colmap
1166     [*data++];
1167     *d3++ =
1168     pix;
1169     *d3++ =
1170     pix >> 8;
1171     *d3++ =
1172     pix >>
1173     16;)}
1174     break;
1175     case 16:
1176     while (i)
1177     {
1178     unroll8Expr(pix = colmap[*data++];
1179     *d3++ = pix;
1180     *d3++ = pix >> 8;
1181     )i -= 8;
1182     }
1183     i = (size & 0x7);
1184     if (i != 0)
1185     switch (i)
1186     {
1187     unroll8Lefts(pix =
1188     colmap
1189     [*data++];
1190     *d3++ =
1191     pix;
1192     *d3++ =
1193     pix >> 8;
1194     )}
1195     break;
1196     case 8:
1197     while (i)
1198     {
1199     unroll8Expr(pix = colmap[*data++];
1200     *d3++ = pix;
1201     )i -= 8;
1202     }
1203     i = (size & 0x7);
1204     if (i != 0)
1205     switch (i)
1206     {
1207     unroll8Lefts(pix =
1208     colmap
1209     [*data++];
1210     *d3++ =
1211     pix;)}
1212     }
1213     }
1214     else
1215     {
1216     /* little-endian screen */
1217     switch (bpp)
1218     {
1219     case 32:
1220     while (i)
1221     {
1222     unroll8Expr(pix = colmap[*data++];
1223     *d3++ = pix;
1224     *d3++ = pix >> 8;
1225     *d3++ = pix >> 16;
1226     *d3++ = pix >> 24;
1227     )i -= 8;
1228     }
1229     i = (size & 0x7);
1230     if (i != 0)
1231     switch (i)
1232     {
1233     unroll8Lefts(pix =
1234     colmap
1235     [*data++];
1236     *d3++ =
1237     pix;
1238     *d3++ =
1239     pix >> 8;
1240     *d3++ =
1241     pix >>
1242     16;
1243     *d3++ =
1244     pix >>
1245     24;)}
1246     break;
1247     case 24:
1248     while (i)
1249     {
1250     unroll8Expr(pix = colmap[*data++];
1251     *d3++ = pix;
1252     *d3++ = pix >> 8;
1253     *d3++ = pix >> 16;
1254     )i -= 8;
1255     }
1256     i = (size & 0x7);
1257     if (i != 0)
1258     switch (i)
1259     {
1260     unroll8Lefts(pix =
1261     colmap
1262     [*data++];
1263     *d3++ =
1264     pix;
1265     *d3++ =
1266     pix >> 8;
1267     *d3++ =
1268     pix >>
1269     16;)}
1270     break;
1271     case 16:
1272     while (i)
1273     {
1274     unroll8Expr(pix = colmap[*data++];
1275     *d3++ = pix;
1276     *d3++ = pix >> 8;
1277     )i -= 8;
1278     }
1279     i = (size & 0x7);
1280     if (i != 0)
1281     switch (i)
1282     {
1283     unroll8Lefts(pix =
1284     colmap
1285     [*data++];
1286     *d3++ =
1287     pix;
1288     *d3++ =
1289     pix >> 8;
1290     )}
1291     break;
1292     case 8:
1293     while (i)
1294     {
1295     unroll8Expr(pix = colmap[*data++];
1296     *d3++ = pix;
1297     )i -= 8;
1298     }
1299     i = (size & 0x7);
1300     if (i != 0)
1301     switch (i)
1302     {
1303     unroll8Lefts(pix =
1304     colmap
1305     [*data++];
1306     *d3++ =
1307     pix;)}
1308     }
1309     }
1310     #endif
1311    
1312     return d2;
1313     }

  ViewVC Help
Powered by ViewVC 1.1.26