/[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 36 - (hide annotations)
Sat Sep 15 14:30:46 2001 UTC (22 years, 8 months ago) by matty
File MIME type: text/plain
File size: 21809 byte(s)
OSF1/Alpha build fixes.

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

  ViewVC Help
Powered by ViewVC 1.1.26