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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.7  
changed lines
  Added in v.31

  ViewVC Help
Powered by ViewVC 1.1.26