/[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

Contents of /sourceforge.net/trunk/rdesktop/xwin.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 30 - (show annotations)
Fri Sep 14 13:51:38 2001 UTC (22 years, 8 months ago) by matty
File MIME type: text/plain
File size: 19085 byte(s)
Portability fixes, including elimination of variable argument macros.
Rudimentary configure script.
Miscellaneous cleanups.

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

  ViewVC Help
Powered by ViewVC 1.1.26