/[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 28 by matty, Wed Jun 20 13:54:48 2001 UTC revision 34 by matty, Sat Sep 15 13:03:35 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 21  Line 21 
21  #include <X11/Xlib.h>  #include <X11/Xlib.h>
22  #include <X11/Xutil.h>  #include <X11/Xutil.h>
23  #include <time.h>  #include <time.h>
24    #include <errno.h>
25  #include "rdesktop.h"  #include "rdesktop.h"
26    
27  extern int width;  extern int width;
28  extern int height;  extern int height;
29  extern BOOL motion;  extern BOOL sendmotion;
 extern BOOL grab_keyboard;  
30  extern BOOL fullscreen;  extern BOOL fullscreen;
 extern int private_colormap;  
31    
 static int bpp;  
 static int depth;  
32  static Display *display;  static Display *display;
33    static int x_socket;
34  static Window wnd;  static Window wnd;
35  static GC gc;  static GC gc;
36  static Visual *visual;  static Visual *visual;
37  static uint32 *colmap;  static int depth;
38    static int bpp;
 #define Ctrans(col) ( private_colormap ? col : colmap[col])  
39    
40  #define L_ENDIAN  /* endianness */
41  int screen_msbfirst = 0;  static BOOL host_be;
42    static BOOL xserver_be;
43    
44    /* software backing store */
45    static BOOL ownbackstore;
46    static Pixmap backstore;
47    
48    #define FILL_RECTANGLE(x,y,cx,cy)\
49    { \
50            XFillRectangle(display, wnd, gc, x, y, cx, cy); \
51            if (ownbackstore) \
52                    XFillRectangle(display, backstore, gc, x, y, cx, cy); \
53    }
54    
55    /* colour maps */
56    static BOOL owncolmap;
57    static Colormap xcolmap;
58    static uint32 white;
59    static uint32 *colmap;
60    
61  static uint8 *translate(int width, int height, uint8 *data);  #define TRANSLATE(col)          ( owncolmap ? col : translate_colour(colmap[col]) )
62    #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));
63    #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));
64    
65  static int rop2_map[] = {  static int rop2_map[] = {
66          GXclear,                /* 0 */          GXclear,                /* 0 */
# Line 64  static int rop2_map[] = { Line 81  static int rop2_map[] = {
81          GXset                   /* 1 */          GXset                   /* 1 */
82  };  };
83    
84    #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }
85    #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }
86    
87    static void
88    translate8(uint8 *data, uint8 *out, uint8 *end)
89    {
90            while (out < end)
91                    *(out++) = (uint8)colmap[*(data++)];
92    }
93    
94  static void  static void
95  xwin_set_function(uint8 rop2)  translate16(uint8 *data, uint16 *out, uint16 *end)
96  {  {
97          static uint8 last_rop2 = ROP2_COPY;          while (out < end)
98                    *(out++) = (uint16)colmap[*(data++)];
99    }
100    
101          if (last_rop2 != rop2)  /* little endian - conversion happens when colourmap is built */
102    static void
103    translate24(uint8 *data, uint8 *out, uint8 *end)
104    {
105            uint32 value;
106    
107            while (out < end)
108          {          {
109                  XSetFunction(display, gc, rop2_map[rop2]);                  value = colmap[*(data++)];
110                  last_rop2 = rop2;                  *(out++) = value;
111                    *(out++) = value >> 8;
112                    *(out++) = value >> 16;
113          }          }
114  }  }
115    
116  static void  static void
117  xwin_grab_keyboard()  translate32(uint8 *data, uint32 *out, uint32 *end)
118  {  {
119          XGrabKeyboard(display, wnd, True, GrabModeAsync, GrabModeAsync,          while (out < end)
120                        CurrentTime);                  *(out++) = colmap[*(data++)];
121  }  }
122    
123  static void  static uint8 *
124  xwin_ungrab_keyboard()  translate_image(int width, int height, uint8 *data)
125  {  {
126          XUngrabKeyboard(display, CurrentTime);          int size = width * height * bpp/8;
127            uint8 *out = xmalloc(size);
128            uint8 *end = out + size;
129    
130            switch (bpp)
131            {
132                    case 8:
133                            translate8(data, out, end);
134                            break;
135    
136                    case 16:
137                            translate16(data, (uint16 *)out, (uint16 *)end);
138                            break;
139    
140                    case 24:
141                            translate24(data, out, end);
142                            break;
143    
144                    case 32:
145                            translate32(data, (uint32 *)out, (uint32 *)end);
146                            break;
147            }
148    
149            return out;
150    }
151    
152    #define BSWAP16(x) x = (((x & 0xff) << 8) | (x >> 8));
153    #define BSWAP24(x) x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00));
154    #define BSWAP32(x) x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
155                       x = (x << 16) | (x >> 16);
156    
157    static uint32
158    translate_colour(uint32 colour)
159    {
160            switch (bpp)
161            {
162                    case 16:
163                            if (host_be != xserver_be)
164                                    BSWAP16(colour);
165                            break;
166    
167                    case 24:
168                            if (xserver_be)
169                                    BSWAP24(colour);
170                            break;
171    
172                    case 32:
173                            if (host_be != xserver_be)
174                                    BSWAP32(colour);
175                            break;
176            }
177    
178            return colour;
179  }  }
180    
181  BOOL  BOOL
# Line 97  ui_create_window(char *title) Line 186  ui_create_window(char *title)
186          XSizeHints *sizehints;          XSizeHints *sizehints;
187          unsigned long input_mask;          unsigned long input_mask;
188          XPixmapFormatValues *pfm;          XPixmapFormatValues *pfm;
189          int count;          Screen *screen;
190            uint16 test;
191            int i;
192    
193          display = XOpenDisplay(NULL);          display = XOpenDisplay(NULL);
194          if (display == NULL)          if (display == NULL)
195          {          {
196                  ERROR("Failed to open display\n");                  error("Failed to open display\n");
197                  return False;                  return False;
198          }          }
199    
200          visual = DefaultVisual(display, DefaultScreen(display));          x_socket = ConnectionNumber(display);
201          depth = DefaultDepth(display, DefaultScreen(display));          screen = DefaultScreenOfDisplay(display);
202          pfm = XListPixmapFormats(display, &count);          visual = DefaultVisualOfScreen(screen);
203            depth = DefaultDepthOfScreen(screen);
204    
205            pfm = XListPixmapFormats(display, &i);
206          if (pfm != NULL)          if (pfm != NULL)
207          {          {
208                  while (count--)                  /* Use maximum bpp for this depth - this is generally
209                       desirable, e.g. 24 bits->32 bits. */
210                    while (i--)
211                  {                  {
212                          if ((pfm + count)->depth == depth                          if ((pfm[i].depth == depth)
213                              && (pfm + count)->bits_per_pixel > bpp)                              && (pfm[i].bits_per_pixel > bpp))
214                          {                          {
215                                  bpp = (pfm + count)->bits_per_pixel;                                  bpp = pfm[i].bits_per_pixel;
216                          }                          }
217                  }                  }
218                  XFree(pfm);                  XFree(pfm);
# Line 124  ui_create_window(char *title) Line 220  ui_create_window(char *title)
220    
221          if (bpp < 8)          if (bpp < 8)
222          {          {
223                  ERROR("Less than 8 bpp not currently supported.\n");                  error("Less than 8 bpp not currently supported.\n");
224                  XCloseDisplay(display);                  XCloseDisplay(display);
225                  return False;                  return False;
226          }          }
227    
228          width &= ~3; /* make width nicely divisible */          if (depth <= 8)
229                    owncolmap = True;
230            else
231                    xcolmap = DefaultColormapOfScreen(screen);
232    
233            test = 1;
234            host_be = !(BOOL)(*(uint8 *)(&test));
235            xserver_be = (ImageByteOrder(display) == MSBFirst);
236    
237            white = WhitePixelOfScreen(screen);
238            attribs.background_pixel = BlackPixelOfScreen(screen);
239            attribs.backing_store = DoesBackingStore(screen);
240    
241          attribs.background_pixel = BlackPixel(display, DefaultScreen(display));          if (attribs.backing_store == NotUseful)
242          attribs.backing_store = Always;                  ownbackstore = True;
243    
244          if (fullscreen)          if (fullscreen)
245          {          {
246                  attribs.override_redirect = True;                  attribs.override_redirect = True;
247                  width = WidthOfScreen(DefaultScreenOfDisplay(display));                  width = WidthOfScreen(screen);
248                  height = HeightOfScreen(DefaultScreenOfDisplay(display));                  height = HeightOfScreen(screen);
                 XSetInputFocus(display, PointerRoot, RevertToPointerRoot,  
                                CurrentTime);  
249          }          }
250          else          else
251          {          {
252                  attribs.override_redirect = False;                  attribs.override_redirect = False;
253          }          }
254    
255          wnd = XCreateWindow(display, DefaultRootWindow(display),          width = (width + 3) & ~3; /* make width a multiple of 32 bits */
256    
257            wnd = XCreateWindow(display, RootWindowOfScreen(screen),
258                              0, 0, width, height, 0, CopyFromParent,                              0, 0, width, height, 0, CopyFromParent,
259                              InputOutput, CopyFromParent,                              InputOutput, CopyFromParent,
260                              CWBackingStore | CWBackPixel | CWOverrideRedirect,                              CWBackingStore | CWBackPixel | CWOverrideRedirect,
# Line 157  ui_create_window(char *title) Line 264  ui_create_window(char *title)
264    
265          classhints = XAllocClassHint();          classhints = XAllocClassHint();
266          if (classhints != NULL)          if (classhints != NULL)
   
267          {          {
268                  classhints->res_name = "rdesktop";                  classhints->res_name = classhints->res_class = "rdesktop";
                 classhints->res_class = "rdesktop";  
269                  XSetClassHint(display, wnd, classhints);                  XSetClassHint(display, wnd, classhints);
270                  XFree(classhints);                  XFree(classhints);
271          }          }
# Line 168  ui_create_window(char *title) Line 273  ui_create_window(char *title)
273          sizehints = XAllocSizeHints();          sizehints = XAllocSizeHints();
274          if (sizehints)          if (sizehints)
275          {          {
276                  sizehints->flags =                  sizehints->flags = PMinSize | PMaxSize;
277                          PPosition | PSize | PMinSize | PMaxSize | PBaseSize;                  sizehints->min_width = sizehints->max_width = width;
278                  sizehints->min_width = width;                  sizehints->min_height = sizehints->max_height = height;
                 sizehints->max_width = width;  
                 sizehints->min_height = height;  
                 sizehints->max_height = height;  
                 sizehints->base_width = width;  
                 sizehints->base_height = height;  
279                  XSetWMNormalHints(display, wnd, sizehints);                  XSetWMNormalHints(display, wnd, sizehints);
280                  XFree(sizehints);                  XFree(sizehints);
281          }          }
282    
283          input_mask = KeyPressMask | KeyReleaseMask;          input_mask = KeyPressMask | KeyReleaseMask
284          input_mask |= ButtonPressMask | ButtonReleaseMask;                          | ButtonPressMask | ButtonReleaseMask
285          if (motion)                          | EnterWindowMask | LeaveWindowMask;
286    
287            if (sendmotion)
288                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
289          if (grab_keyboard)  
290                  input_mask |= EnterWindowMask | LeaveWindowMask;          if (ownbackstore)
291                    input_mask |= ExposureMask;
292    
293          XSelectInput(display, wnd, input_mask);          XSelectInput(display, wnd, input_mask);
294          gc = XCreateGC(display, wnd, 0, NULL);          gc = XCreateGC(display, wnd, 0, NULL);
295    
296            if (ownbackstore)
297                    backstore = XCreatePixmap(display, wnd, width, height, depth);
298    
299          XMapWindow(display, wnd);          XMapWindow(display, wnd);
300          return True;          return True;
301  }  }
# Line 197  ui_create_window(char *title) Line 303  ui_create_window(char *title)
303  void  void
304  ui_destroy_window()  ui_destroy_window()
305  {  {
306            if (ownbackstore)
307                    XFreePixmap(display, backstore);
308    
309          XFreeGC(display, gc);          XFreeGC(display, gc);
310          XDestroyWindow(display, wnd);          XDestroyWindow(display, wnd);
311          XCloseDisplay(display);          XCloseDisplay(display);
# Line 206  ui_destroy_window() Line 315  ui_destroy_window()
315  static uint8  static uint8
316  xwin_translate_key(unsigned long key)  xwin_translate_key(unsigned long key)
317  {  {
318          DEBUG("KEY(code=0x%lx)\n", key);          DEBUG(("KEY(code=0x%lx)\n", key));
319    
320          if ((key > 8) && (key <= 0x60))          if ((key > 8) && (key <= 0x60))
321                  return (key - 8);                  return (key - 8);
# Line 272  xwin_translate_mouse(unsigned long butto Line 381  xwin_translate_mouse(unsigned long butto
381          return 0;          return 0;
382  }  }
383    
384  void  static void
385  ui_process_events()  xwin_process_events()
386  {  {
387          XEvent event;          XEvent event;
388          uint8 scancode;          uint8 scancode;
# Line 338  ui_process_events() Line 447  ui_process_events()
447                                  break;                                  break;
448    
449                          case EnterNotify:                          case EnterNotify:
450                                  if (grab_keyboard)                                  XGrabKeyboard(display, wnd, True, GrabModeAsync,
451                                          xwin_grab_keyboard();                                                GrabModeAsync, CurrentTime);
452                                  break;                                  break;
453    
454                          case LeaveNotify:                          case LeaveNotify:
455                                  if (grab_keyboard)                                  XUngrabKeyboard(display, CurrentTime);
456                                          xwin_ungrab_keyboard();                                  break;
457    
458                            case Expose:
459                                    XCopyArea(display, backstore, wnd, gc,
460                                              event.xexpose.x, event.xexpose.y,
461                                              event.xexpose.width, event.xexpose.height,
462                                              event.xexpose.x, event.xexpose.y);
463                                  break;                                  break;
464                  }                  }
465          }          }
466  }  }
467    
468  void  void
469    ui_select(int rdp_socket)
470    {
471            int n = (rdp_socket > x_socket) ? rdp_socket+1 : x_socket+1;
472            fd_set rfds;
473    
474            XFlush(display);
475    
476            FD_ZERO(&rfds);
477    
478            while (True)
479            {
480                    FD_ZERO(&rfds);
481                    FD_SET(rdp_socket, &rfds);
482                    FD_SET(x_socket, &rfds);
483    
484                    switch (select(n, &rfds, NULL, NULL, NULL))
485                    {
486                            case -1:
487                                    error("select: %s\n", strerror(errno));
488    
489                            case 0:
490                                    continue;
491                    }
492    
493                    if (FD_ISSET(x_socket, &rfds))
494                            xwin_process_events();
495    
496                    if (FD_ISSET(rdp_socket, &rfds))
497                            return;
498            }
499    }
500    
501    void
502  ui_move_pointer(int x, int y)  ui_move_pointer(int x, int y)
503  {  {
504          XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);          XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);
# Line 362  ui_create_bitmap(int width, int height, Line 510  ui_create_bitmap(int width, int height,
510          XImage *image;          XImage *image;
511          Pixmap bitmap;          Pixmap bitmap;
512          uint8 *tdata;          uint8 *tdata;
513          tdata = (private_colormap ? data : translate(width, height, data));  
514            tdata = (owncolmap ? data : translate_image(width, height, data));
515          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(display, wnd, width, height, depth);
516          image =          image = XCreateImage(display, visual, depth, ZPixmap,
517                  XCreateImage(display, visual,                               0, tdata, width, height, 8, 0);
                              depth, ZPixmap,  
                              0, tdata, width, height, BitmapPad(display), 0);  
518    
         xwin_set_function(ROP2_COPY);  
519          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
520    
521          XFree(image);          XFree(image);
522          if (!private_colormap)          if (!owncolmap)
523                  xfree(tdata);                  xfree(tdata);
524          return (HBITMAP) bitmap;          return (HBITMAP) bitmap;
525  }  }
# Line 383  ui_paint_bitmap(int x, int y, int cx, in Line 529  ui_paint_bitmap(int x, int y, int cx, in
529                  int width, int height, uint8 *data)                  int width, int height, uint8 *data)
530  {  {
531          XImage *image;          XImage *image;
532          uint8 *tdata =          uint8 *tdata;
                 (private_colormap ? data : translate(width, height, data));  
         image =  
                 XCreateImage(display, visual, depth, ZPixmap, 0, tdata, width,  
                              height, BitmapPad(display), 0);  
   
         xwin_set_function(ROP2_COPY);  
   
         /* Window */  
         XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);  
         XFree(image);  
         if (!private_colormap)  
                 xfree(tdata);  
 }  
533    
534  void          tdata = (owncolmap ? data : translate_image(width, height, data));
535  ui_destroy_bitmap(HBITMAP bmp)          image = XCreateImage(display, visual, depth, ZPixmap,
536  {                               0, tdata, width, height, 8, 0);
         XFreePixmap(display, (Pixmap) bmp);  
 }  
537    
538  HCURSOR          if (ownbackstore)
 ui_create_cursor(unsigned int x, unsigned int y, int width,  
                  int height, uint8 *mask, uint8 *data)  
 {  
         XImage *imagecursor;  
         XImage *imagemask;  
         Pixmap maskbitmap, cursorbitmap;  
         Cursor cursor;  
         XColor bg, fg;  
         GC lgc;  
         int i, x1, y1, scanlinelen;  
         uint8 *cdata, *cmask;  
         uint8 c;  
         cdata = (uint8 *) malloc(sizeof(uint8) * width * height);  
         if (!cdata)  
                 return NULL;  
         scanlinelen = (width + 7) >> 3;  
         cmask = (uint8 *) malloc(sizeof(uint8) * scanlinelen * height);  
         if (!cmask)  
539          {          {
540                  free(cdata);                  XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
541                  return NULL;                  XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
         }  
         i = (height - 1) * scanlinelen;  
   
         if (!screen_msbfirst)  
         {  
                 while (i >= 0)  
                 {  
                         for (x1 = 0; x1 < scanlinelen; x1++)  
                         {  
                                 c = *(mask++);  
                                 cmask[i + x1] =  
                                         ((c & 0x1) << 7) | ((c & 0x2) << 5) |  
                                         ((c & 0x4) << 3) | ((c & 0x8) << 1) |  
                                         ((c & 0x10) >> 1) | ((c & 0x20) >> 3)  
                                         | ((c & 0x40) >> 5) | ((c & 0x80) >>  
                                                                7);  
                         }  
                         i -= scanlinelen;  
                 }  
542          }          }
543          else          else
544          {          {
545                  while (i >= 0)                  XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
                 {  
                         for (x1 = 0; x1 < scanlinelen; x1++)  
                         {  
                                 cmask[i + x1] = *(mask++);  
                         }  
                         i -= scanlinelen;  
                 }  
546          }          }
547    
548            XFree(image);
549          fg.red = 0;          if (!owncolmap)
550          fg.blue = 0;                  xfree(tdata);
         fg.green = 0;  
         fg.flags = DoRed | DoBlue | DoGreen;  
         bg.red = 65535;  
         bg.blue = 65535;  
         bg.green = 65535;  
         bg.flags = DoRed | DoBlue | DoGreen;  
         maskbitmap = XCreatePixmap(display, wnd, width, height, 1);  
         cursorbitmap = XCreatePixmap(display, wnd, width, height, 1);  
         lgc = XCreateGC(display, maskbitmap, 0, NULL);  
         XSetFunction(display, lgc, GXcopy);  
         imagemask =  
                 XCreateImage(display, visual, 1, XYBitmap, 0, cmask, width,  
                              height, 8, 0);  
         imagecursor =  
                 XCreateImage(display, visual, 1, XYBitmap, 0, cdata, width,  
                              height, 8, 0);  
         for (y1 = height - 1; y1 >= 0; y1--)  
                 for (x1 = 0; x1 < width; x1++)  
                 {  
                         if (data[0] >= 0x80 || data[1] >= 0x80  
                             || data[2] >= 0x80)  
                                 if (XGetPixel(imagemask, x1, y1))  
   
                                 {  
                                         XPutPixel(imagecursor, x1, y1, 0);  
                                         XPutPixel(imagemask, x1, y1, 0);        /* mask is blank for text cursor! */  
                                 }  
   
                                 else  
                                         XPutPixel(imagecursor, x1, y1, 1);  
   
                         else  
                                 XPutPixel(imagecursor, x1, y1,  
                                           XGetPixel(imagemask, x1, y1));  
                         data += 3;  
                 }  
         XPutImage(display, maskbitmap, lgc, imagemask, 0, 0, 0, 0, width,  
                   height);  
         XPutImage(display, cursorbitmap, lgc, imagecursor, 0, 0, 0, 0, width,  
                   height); XFree(imagemask);  
         XFree(imagecursor);  
         free(cmask);  
         free(cdata);  
         XFreeGC(display, lgc);  
         cursor =  
                 XCreatePixmapCursor(display, cursorbitmap, maskbitmap, &fg,  
                                     &bg, x, y);  
         XFreePixmap(display, maskbitmap);  
         XFreePixmap(display, cursorbitmap);  
         return (HCURSOR) cursor;  
 }  
   
 void  
 ui_set_cursor(HCURSOR cursor)  
 {  
         XDefineCursor(display, wnd, (Cursor) cursor);  
551  }  }
552    
553  void  void
554  ui_destroy_cursor(HCURSOR cursor)  ui_destroy_bitmap(HBITMAP bmp)
555  {  {
556          XFreeCursor(display, (Cursor) cursor);          XFreePixmap(display, (Pixmap)bmp);
557  }  }
558    
559  HGLYPH  HGLYPH
# Line 544  ui_create_glyph(int width, int height, u Line 575  ui_create_glyph(int width, int height, u
575          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
576          XInitImage(image);          XInitImage(image);
577    
         XSetFunction(display, gc, GXcopy);  
578          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
579    
580          XFree(image);          XFree(image);
581          XFreeGC(display, gc);          XFreeGC(display, gc);
582            return (HGLYPH)bitmap;
         return (HGLYPH) bitmap;  
583  }  }
584    
585  void  void
586  ui_destroy_glyph(HGLYPH glyph)  ui_destroy_glyph(HGLYPH glyph)
587  {  {
588          XFreePixmap(display, (Pixmap) glyph);          XFreePixmap(display, (Pixmap)glyph);
589  }  }
590    
591  HCOLOURMAP  HCURSOR
592  ui_create_colourmap(COLOURMAP *colours)  ui_create_cursor(unsigned int x, unsigned int y, int width,
593                     int height, uint8 *andmask, uint8 *xormask)
594  {  {
595          if (!private_colormap)          HGLYPH maskglyph, cursorglyph;
596            XColor bg, fg;
597            Cursor xcursor;
598            uint8 *cursor, *pcursor;
599            uint8 *mask, *pmask;
600            uint8 nextbit;
601            int scanline, offset;
602            int i, j;
603    
604            scanline = (width + 7) / 8;
605            offset = scanline * height;
606    
607            cursor = xmalloc(offset);
608            memset(cursor, 0, offset);
609    
610            mask = xmalloc(offset);
611            memset(mask, 0, offset);
612    
613            /* approximate AND and XOR masks with a monochrome X pointer */
614            for (i = 0; i < height; i++)
615          {          {
616                  COLOURENTRY *entry;                  offset -= scanline;
617                  int i, ncolours = colours->ncolours;                  pcursor = &cursor[offset];
618                  uint32 *nc = xmalloc(sizeof(*colmap) * ncolours);                  pmask = &mask[offset];
619                  for (i = 0; i < ncolours; i++)  
620                    for (j = 0; j < scanline; j++)
621                  {                  {
622                          XColor xc;                          for (nextbit = 0x80; nextbit != 0; nextbit >>= 1)
623                          entry = &colours->colours[i];                          {
624                          xc.red = entry->red << 8;                                  if (xormask[0] || xormask[1] || xormask[2])
625                          xc.green = entry->green << 8;                                  {
626                          xc.blue = entry->blue << 8;                                          *pcursor |= (~(*andmask) & nextbit);
627                          XAllocColor(display,                                          *pmask |= nextbit;
628                                      DefaultColormap(display,                                  }
629                                                      DefaultScreen(display)),                                  else
630                                      &xc);                                  {
631                          /* XXX Check return value */                                          *pcursor |= ((*andmask) & nextbit);
632                          nc[i] = xc.pixel;                                          *pmask |= (~(*andmask) & nextbit);
633                                    }
634    
635                                    xormask += 3;
636                            }
637    
638                            andmask++;
639                            pcursor++;
640                            pmask++;
641                  }                  }
                 return nc;  
642          }          }
643          else  
644            fg.red = fg.blue = fg.green = 0xffff;
645            bg.red = bg.blue = bg.green = 0x0000;
646            fg.flags = bg.flags = DoRed | DoBlue | DoGreen;
647    
648            cursorglyph = ui_create_glyph(width, height, cursor);
649            maskglyph = ui_create_glyph(width, height, mask);
650            
651            xcursor = XCreatePixmapCursor(display, (Pixmap)cursorglyph,
652                                    (Pixmap)maskglyph, &fg, &bg, x, y);
653    
654            ui_destroy_glyph(maskglyph);
655            ui_destroy_glyph(cursorglyph);
656            xfree(mask);
657            xfree(cursor);
658            return (HCURSOR)xcursor;
659    }
660    
661    void
662    ui_set_cursor(HCURSOR cursor)
663    {
664            XDefineCursor(display, wnd, (Cursor)cursor);
665    }
666    
667    void
668    ui_destroy_cursor(HCURSOR cursor)
669    {
670            XFreeCursor(display, (Cursor)cursor);
671    }
672    
673    #define MAKE_XCOLOR(xc,c) \
674                    (xc)->red   = ((c)->red   << 8) | (c)->red; \
675                    (xc)->green = ((c)->green << 8) | (c)->green; \
676                    (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \
677                    (xc)->flags = DoRed | DoGreen | DoBlue;
678    
679    HCOLOURMAP
680    ui_create_colourmap(COLOURMAP *colours)
681    {
682            COLOURENTRY *entry;
683            int i, ncolours = colours->ncolours;
684    
685            if (owncolmap)
686          {          {
                 COLOURENTRY *entry;  
687                  XColor *xcolours, *xentry;                  XColor *xcolours, *xentry;
688                  Colormap map;                  Colormap map;
689                  int i, ncolours = colours->ncolours;  
690                  xcolours = xmalloc(sizeof(XColor) * ncolours);                  xcolours = xmalloc(sizeof(XColor) * ncolours);
691                  for (i = 0; i < ncolours; i++)                  for (i = 0; i < ncolours; i++)
692                  {                  {
693                          entry = &colours->colours[i];                          entry = &colours->colours[i];
694                          xentry = &xcolours[i];                          xentry = &xcolours[i];
   
695                          xentry->pixel = i;                          xentry->pixel = i;
696                          xentry->red = entry->red << 8;                          MAKE_XCOLOR(xentry, entry);
                         xentry->blue = entry->blue << 8;  
                         xentry->green = entry->green << 8;  
                         xentry->flags = DoRed | DoBlue | DoGreen;  
697                  }                  }
698    
699                  map = XCreateColormap(display, wnd, visual, AllocAll);                  map = XCreateColormap(display, wnd, visual, AllocAll);
700                  XStoreColors(display, map, xcolours, ncolours);                  XStoreColors(display, map, xcolours, ncolours);
701    
702                  xfree(xcolours);                  xfree(xcolours);
703                  return (HCOLOURMAP) map;                  return (HCOLOURMAP)map;
704            }
705            else
706            {
707                    uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
708                    XColor xentry;
709                    uint32 colour;
710    
711                    for (i = 0; i < ncolours; i++)
712                    {
713                            entry = &colours->colours[i];
714                            MAKE_XCOLOR(&xentry, entry);
715    
716                            if (XAllocColor(display, xcolmap, &xentry) != 0)
717                                    colour = xentry.pixel;
718                            else
719                                    colour = white;
720    
721                            /* byte swap here to make translate_image faster */
722                            map[i] = translate_colour(colour);
723                    }
724    
725                    return map;
726          }          }
727  }  }
728    
729  void  void
730  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
731  {  {
732          XFreeColormap(display, (Colormap) map);          if (owncolmap)
733                    XFreeColormap(display, (Colormap)map);
734            else
735                    xfree(map);
736  }  }
737    
738  void  void
739  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
740  {  {
741            if (owncolmap)
742          /* XXX, change values of all pixels on the screen if the new colmap                  XSetWindowColormap(display, wnd, (Colormap)map);
          * doesn't have the same values as the old one? */  
         if (!private_colormap)  
                 colmap = map;  
743          else          else
744          {                  colmap = map;
                 XSetWindowColormap(display, wnd, (Colormap) map);  
                 if (fullscreen)  
                         XInstallColormap(display, (Colormap) map);  
         }  
745  }  }
746    
747  void  void
# Line 665  void Line 778  void
778  ui_destblt(uint8 opcode,  ui_destblt(uint8 opcode,
779             /* dest */ int x, int y, int cx, int cy)             /* dest */ int x, int y, int cx, int cy)
780  {  {
781          xwin_set_function(opcode);          SET_FUNCTION(opcode);
782            FILL_RECTANGLE(x, y, cx, cy);
783          XFillRectangle(display, wnd, gc, x, y, cx, cy);          RESET_FUNCTION(opcode);
784  }  }
785    
786  void  void
# Line 675  ui_patblt(uint8 opcode, Line 788  ui_patblt(uint8 opcode,
788            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
789            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
790  {  {
         Display *dpy = display;  
791          Pixmap fill;          Pixmap fill;
         uint8 i, ipattern[8];  
792    
793          xwin_set_function(opcode);          SET_FUNCTION(opcode);
794    
795          switch (brush->style)          switch (brush->style)
796          {          {
797                  case 0: /* Solid */                  case 0: /* Solid */
798                          XSetForeground(dpy, gc, Ctrans(fgcolour));                          SET_FOREGROUND(fgcolour);
799                          XFillRectangle(dpy, wnd, gc, x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
800                          break;                          break;
801    
802                  case 3: /* Pattern */                  case 3: /* Pattern */
803                          for (i = 0; i != 8; i++)                          fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);
                                 ipattern[i] = ~brush->pattern[i];  
                         fill = (Pixmap) ui_create_glyph(8, 8, ipattern);  
   
                         XSetForeground(dpy, gc, Ctrans(fgcolour));  
                         XSetBackground(dpy, gc, Ctrans(bgcolour));  
                         XSetFillStyle(dpy, gc, FillOpaqueStippled);  
                         XSetStipple(dpy, gc, fill);  
804    
805                          XFillRectangle(dpy, wnd, gc, x, y, cx, cy);                          SET_FOREGROUND(bgcolour);
806                            SET_BACKGROUND(fgcolour);
807                            XSetFillStyle(display, gc, FillOpaqueStippled);
808                            XSetStipple(display, gc, fill);
809                            XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);
810    
811                          XSetFillStyle(dpy, gc, FillSolid);                          FILL_RECTANGLE(x, y, cx, cy);
812                          ui_destroy_glyph((HGLYPH) fill);  
813                            XSetFillStyle(display, gc, FillSolid);
814                            ui_destroy_glyph((HGLYPH)fill);
815                          break;                          break;
816    
817                  default:                  default:
818                          NOTIMP("brush %d\n", brush->style);                          unimpl("brush %d\n", brush->style);
819          }          }
820    
821            RESET_FUNCTION(opcode);
822  }  }
823    
824  void  void
# Line 714  ui_screenblt(uint8 opcode, Line 826  ui_screenblt(uint8 opcode,
826               /* dest */ int x, int y, int cx, int cy,               /* dest */ int x, int y, int cx, int cy,
827               /* src */ int srcx, int srcy)               /* src */ int srcx, int srcy)
828  {  {
829          xwin_set_function(opcode);          SET_FUNCTION(opcode);
   
830          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
831            if (ownbackstore)
832                    XCopyArea(display, backstore, backstore, gc, srcx, srcy,
833                              cx, cy, x, y);
834            RESET_FUNCTION(opcode);
835  }  }
836    
837  void  void
# Line 724  ui_memblt(uint8 opcode, Line 839  ui_memblt(uint8 opcode,
839            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
840            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ HBITMAP src, int srcx, int srcy)
841  {  {
842          xwin_set_function(opcode);          SET_FUNCTION(opcode);
843            XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);
844          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);          if (ownbackstore)
845                    XCopyArea(display, (Pixmap)src, backstore, gc, srcx, srcy,
846                              cx, cy, x, y);
847            RESET_FUNCTION(opcode);
848  }  }
849    
850  void  void
# Line 754  ui_triblt(uint8 opcode, Line 872  ui_triblt(uint8 opcode,
872                                    brush, bgcolour, fgcolour);                                    brush, bgcolour, fgcolour);
873                          break;                          break;
874    
875                  case 0xc0:                  case 0xc0:      /* PSa */
876                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
877                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,
878                                    fgcolour);                                    fgcolour);
879                          break;                          break;
880    
881                  default:                  default:
882                          NOTIMP("triblt 0x%x\n", opcode);                          unimpl("triblt 0x%x\n", opcode);
883                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
884          }          }
885  }  }
# Line 771  ui_line(uint8 opcode, Line 889  ui_line(uint8 opcode,
889          /* dest */ int startx, int starty, int endx, int endy,          /* dest */ int startx, int starty, int endx, int endy,
890          /* pen */ PEN *pen)          /* pen */ PEN *pen)
891  {  {
892          xwin_set_function(opcode);          SET_FUNCTION(opcode);
893            SET_FOREGROUND(pen->colour);
         XSetForeground(display, gc, Ctrans(pen->colour));  
894          XDrawLine(display, wnd, gc, startx, starty, endx, endy);          XDrawLine(display, wnd, gc, startx, starty, endx, endy);
895            if (ownbackstore)
896                    XDrawLine(display, backstore, gc, startx, starty, endx, endy);
897            RESET_FUNCTION(opcode);
898  }  }
899    
900  void  void
# Line 782  ui_rect( Line 902  ui_rect(
902                 /* dest */ int x, int y, int cx, int cy,                 /* dest */ int x, int y, int cx, int cy,
903                 /* brush */ int colour)                 /* brush */ int colour)
904  {  {
905          xwin_set_function(ROP2_COPY);          SET_FOREGROUND(colour);
906            FILL_RECTANGLE(x, y, cx, cy);
         XSetForeground(display, gc, Ctrans(colour));  
         XFillRectangle(display, wnd, gc, x, y, cx, cy);  
907  }  }
908    
909  void  void
# Line 794  ui_draw_glyph(int mixmode, Line 912  ui_draw_glyph(int mixmode,
912                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,
913                int fgcolour)                int fgcolour)
914  {  {
915          Pixmap pixmap = (Pixmap) glyph;          SET_FOREGROUND(fgcolour);
916            SET_BACKGROUND(bgcolour);
         xwin_set_function(ROP2_COPY);  
917    
918            XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)
919                          ? FillStippled : FillOpaqueStippled);
920            XSetStipple(display, gc, (Pixmap)glyph);
921            XSetTSOrigin(display, gc, x, y);
922    
923          XSetForeground(display, gc, Ctrans(fgcolour));          FILL_RECTANGLE(x, y, cx, cy);
         switch (mixmode)  
         {  
                 case MIX_TRANSPARENT:  
                         XSetStipple(display, gc, pixmap);  
                         XSetFillStyle(display, gc, FillStippled);  
                         XSetTSOrigin(display, gc, x, y);  
                         XFillRectangle(display, wnd, gc, x, y, cx, cy);  
                         XSetFillStyle(display, gc, FillSolid);  
                         break;  
   
                 case MIX_OPAQUE:  
                         XSetBackground(display, gc, Ctrans(bgcolour));  
 /*      XCopyPlane (display, pixmap, back_pixmap, back_gc, srcx, srcy, cx, cy, x, y, 1); */  
                         XSetStipple(display, gc, pixmap);  
                         XSetFillStyle(display, gc, FillOpaqueStippled);  
                         XSetTSOrigin(display, gc, x, y);  
                         XFillRectangle(display, wnd, gc, x, y, cx, cy);  
                         XSetFillStyle(display, gc, FillSolid);  
                         break;  
924    
925                  default:          XSetFillStyle(display, gc, FillSolid);
                         NOTIMP("mix %d\n", mixmode);  
         }  
926  }  }
927    
928  void  void
# Line 832  ui_draw_text(uint8 font, uint8 flags, in Line 932  ui_draw_text(uint8 font, uint8 flags, in
932               int bgcolour, int fgcolour, uint8 *text, uint8 length)               int bgcolour, int fgcolour, uint8 *text, uint8 length)
933  {  {
934          FONTGLYPH *glyph;          FONTGLYPH *glyph;
935          int i, xyoffset;          int i, offset;
936    
937          xwin_set_function(ROP2_COPY);          SET_FOREGROUND(bgcolour);
         XSetForeground(display, gc, Ctrans(bgcolour));  
938    
939          if (boxcx > 1)          if (boxcx > 1)
940                  XFillRectangle(display, wnd, gc, boxx, boxy, boxcx, boxcy);          {
941                    FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);
942            }
943          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
944                  XFillRectangle(display, wnd, gc, clipx, clipy, clipcx, clipcy);          {
945                    FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);
946            }
947    
948          /* Paint text, character by character */          /* Paint text, character by character */
949          for (i = 0; i < length; i++)          for (i = 0; i < length; i++)
# Line 848  ui_draw_text(uint8 font, uint8 flags, in Line 951  ui_draw_text(uint8 font, uint8 flags, in
951                  glyph = cache_get_font(font, text[i]);                  glyph = cache_get_font(font, text[i]);
952    
953                  if (!(flags & TEXT2_IMPLICIT_X))                  if (!(flags & TEXT2_IMPLICIT_X))
   
954                  {                  {
955                          xyoffset = text[++i];                          offset = text[++i];
956                          if ((xyoffset & 0x80))                          if (offset & 0x80)
957                          {                                  offset = ((offset & 0x7f) << 8) | text[++i];
                                 if (flags & 0x04)       /* vertical text */  
                                         y += text[++i] | (text[++i] << 8);  
                                 else  
                                         x += text[++i] | (text[++i] << 8);  
                         }  
                         else  
                         {  
                                 if (flags & 0x04)       /* vertical text */  
                                         y += xyoffset;  
                                 else  
                                         x += xyoffset;  
                         }  
958    
959                            if (flags & TEXT2_VERTICAL)
960                                    y += offset;
961                            else
962                                    x += offset;
963                  }                  }
964    
965                  if (glyph != NULL)                  if (glyph != NULL)
966                  {                  {
967                          ui_draw_glyph(mixmode, x + (short) glyph->offset,                          ui_draw_glyph(mixmode, x + (short) glyph->offset,
# Line 887  ui_desktop_save(uint32 offset, int x, in Line 982  ui_desktop_save(uint32 offset, int x, in
982          Pixmap pix;          Pixmap pix;
983          XImage *image;          XImage *image;
984    
985          pix = XCreatePixmap(display, wnd, cx, cy, depth);          if (ownbackstore)
986          xwin_set_function(ROP2_COPY);          {
987                    image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,
988          XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);                                    ZPixmap);
989          image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);          }
990            else
991            {
992                    pix = XCreatePixmap(display, wnd, cx, cy, depth);
993                    XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
994                    image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,
995                                      ZPixmap);
996                    XFreePixmap(display, pix);
997            }
998    
999          offset *= bpp/8;          offset *= bpp/8;
1000          cache_put_desktop(offset, cx, cy, image->bytes_per_line,          cache_put_desktop(offset, cx, cy, image->bytes_per_line,
1001                            bpp/8, image->data);                            bpp/8, image->data);
1002    
1003          XDestroyImage(image);          XDestroyImage(image);
         XFreePixmap(display, pix);  
1004  }  }
1005    
1006  void  void
# Line 911  ui_desktop_restore(uint32 offset, int x, Line 1013  ui_desktop_restore(uint32 offset, int x,
1013          data = cache_get_desktop(offset, cx, cy, bpp/8);          data = cache_get_desktop(offset, cx, cy, bpp/8);
1014          if (data == NULL)          if (data == NULL)
1015                  return;                  return;
1016          image =  
1017                  XCreateImage(display, visual,          image = XCreateImage(display, visual, depth, ZPixmap,
                              depth, ZPixmap,  
1018                               0, data, cx, cy, BitmapPad(display),                               0, data, cx, cy, BitmapPad(display),
1019                               cx * bpp/8);                               cx * bpp/8);
         xwin_set_function(ROP2_COPY);  
         XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);  
         XFree(image);  
 }  
   
 /* unroll defines, used to make the loops a bit more readable... */  
 #define unroll8Expr(uexp) uexp uexp uexp uexp uexp uexp uexp uexp  
 #define unroll8Lefts(uexp) case 7: uexp \  
         case 6: uexp \  
         case 5: uexp \  
         case 4: uexp \  
         case 3: uexp \  
         case 2: uexp \  
         case 1: uexp  
   
 static uint8 *  
 translate(int width, int height, uint8 *data)  
 {  
         uint32 i;  
         uint32 size = width * height;  
         uint8 *d2 = xmalloc(size * bpp/8);  
         uint8 *d3 = d2;  
         uint32 pix;  
         i = (size & ~0x7);  
   
         /* XXX: where are the bits swapped??? */  
 #ifdef L_ENDIAN                 /* little-endian */  
         /* big-endian screen */  
         if (screen_msbfirst)  
         {  
                 switch (bpp)  
                 {  
                         case 32:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix >> 24;  
                                                     *d3++ = pix >> 16;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix;) i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      24;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix;)}  
                                 break;  
                         case 24:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix >> 16;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix;) i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix;)}  
                                 break;  
                         case 16:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix;) i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix;)}  
                                 break;  
                         case 8:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;)}  
                                 break;  
                 }  
         }  
         else  
         {                       /* little-endian screen */  
                 switch (bpp)  
                 {  
                         case 32:  
                                 while (i)  
                                 {  
                                         unroll8Expr(*((uint32 *) d3) =  
                                                     colmap[*data++];  
                                                     d3 += sizeof(uint32);  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(*  
                                                                      ((uint32  
                                                                        *) d3)  
 = colmap[*data++];  
 d3 += sizeof(uint32);  
                                         )}  
                                 break;  
                         case 24:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix >> 16;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;)}  
                                 break;  
                         case 16:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                         )}  
                                 break;  
                         case 8:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;)}  
                 }  
         }  
1020    
1021  #else /* bigendian-compiled */          if (ownbackstore)
         if (screen_msbfirst)  
1022          {          {
1023                  /* big-endian screen */                  XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
1024                  switch (bpp)                  XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
                 {  
                         case 32:  
                                 while (i)  
                                 {  
                                         unroll8Expr(*((uint32 *) d3) =  
                                                     colmap[*data++];  
                                                     d3 += sizeof(uint32);  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(*  
                                                                      ((uint32  
                                                                        *) d3)  
 = colmap[*data++];  
 d3 += sizeof(uint32);  
                                         )}  
                                 break;  
                         case 24:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix >> 16;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;)}  
                                 break;  
                         case 16:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                         )}  
                                 break;  
                         case 8:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;)}  
                 }  
1025          }          }
1026          else          else
1027          {          {
1028                  /* little-endian screen */                  XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
                 switch (bpp)  
                 {  
                         case 32:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix >> 16;  
                                                     *d3++ = pix >> 24;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      24;)}  
                                 break;  
                         case 24:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix >> 16;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;)}  
                                 break;  
                         case 16:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                         )}  
                                 break;  
                         case 8:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;)}  
                 }  
1029          }          }
 #endif  
1030    
1031          return d2;          XFree(image);
1032  }  }

Legend:
Removed from v.28  
changed lines
  Added in v.34

  ViewVC Help
Powered by ViewVC 1.1.26