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

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

  ViewVC Help
Powered by ViewVC 1.1.26