/[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 20 by matty, Mon Oct 16 07:37:52 2000 UTC revision 28 by matty, Wed Jun 20 13:54:48 2001 UTC
# Line 19  Line 19 
19  */  */
20    
21  #include <X11/Xlib.h>  #include <X11/Xlib.h>
22    #include <X11/Xutil.h>
23  #include <time.h>  #include <time.h>
24  #include "rdesktop.h"  #include "rdesktop.h"
25    
26  extern int width;  extern int width;
27  extern int height;  extern int height;
28  extern BOOL motion;  extern BOOL motion;
29    extern BOOL grab_keyboard;
30    extern BOOL fullscreen;
31    extern int private_colormap;
32    
33    static int bpp;
34    static int depth;
35  static Display *display;  static Display *display;
36  static Window wnd;  static Window wnd;
37  static GC gc;  static GC gc;
38  static Visual *visual;  static Visual *visual;
39  static XIM IM;  static uint32 *colmap;
40    
41  BOOL ui_create_window(char *title)  #define Ctrans(col) ( private_colormap ? col : colmap[col])
42    
43    #define L_ENDIAN
44    int screen_msbfirst = 0;
45    
46    static uint8 *translate(int width, int height, uint8 *data);
47    
48    static int rop2_map[] = {
49            GXclear,                /* 0 */
50            GXnor,                  /* DPon */
51            GXandInverted,          /* DPna */
52            GXcopyInverted,         /* Pn */
53            GXandReverse,           /* PDna */
54            GXinvert,               /* Dn */
55            GXxor,                  /* DPx */
56            GXnand,                 /* DPan */
57            GXand,                  /* DPa */
58            GXequiv,                /* DPxn */
59            GXnoop,                 /* D */
60            GXorInverted,           /* DPno */
61            GXcopy,                 /* P */
62            GXorReverse,            /* PDno */
63            GXor,                   /* DPo */
64            GXset                   /* 1 */
65    };
66    
67    static void
68    xwin_set_function(uint8 rop2)
69    {
70            static uint8 last_rop2 = ROP2_COPY;
71    
72            if (last_rop2 != rop2)
73            {
74                    XSetFunction(display, gc, rop2_map[rop2]);
75                    last_rop2 = rop2;
76            }
77    }
78    
79    static void
80    xwin_grab_keyboard()
81    {
82            XGrabKeyboard(display, wnd, True, GrabModeAsync, GrabModeAsync,
83                          CurrentTime);
84    }
85    
86    static void
87    xwin_ungrab_keyboard()
88    {
89            XUngrabKeyboard(display, CurrentTime);
90    }
91    
92    BOOL
93    ui_create_window(char *title)
94  {  {
         Screen *screen;  
95          XSetWindowAttributes attribs;          XSetWindowAttributes attribs;
96            XClassHint *classhints;
97            XSizeHints *sizehints;
98          unsigned long input_mask;          unsigned long input_mask;
99          int i;          XPixmapFormatValues *pfm;
100            int count;
101    
102          display = XOpenDisplay(NULL);          display = XOpenDisplay(NULL);
103          if (display == NULL)          if (display == NULL)
104            {
105                    ERROR("Failed to open display\n");
106                  return False;                  return False;
107            }
108    
109          /* Check the screen supports 8-bit depth. */          visual = DefaultVisual(display, DefaultScreen(display));
110          screen = DefaultScreenOfDisplay(display);          depth = DefaultDepth(display, DefaultScreen(display));
111          for (i = 0; i < screen->ndepths; i++)          pfm = XListPixmapFormats(display, &count);
112                  if (screen->depths[i].depth == 8)          if (pfm != NULL)
113                          break;          {
114                    while (count--)
115                    {
116                            if ((pfm + count)->depth == depth
117                                && (pfm + count)->bits_per_pixel > bpp)
118                            {
119                                    bpp = (pfm + count)->bits_per_pixel;
120                            }
121                    }
122                    XFree(pfm);
123            }
124    
125          if (i >= screen->ndepths)          if (bpp < 8)
126          {          {
127                  ERROR("8-bit depth required (in this version).\n");                  ERROR("Less than 8 bpp not currently supported.\n");
128                  XCloseDisplay(display);                  XCloseDisplay(display);
129                  return False;                  return False;
130          }          }
131    
132          visual = DefaultVisual(display, DefaultScreen(display));          width &= ~3; /* make width nicely divisible */
133    
134          attribs.background_pixel = BlackPixel(display, DefaultScreen(display));          attribs.background_pixel = BlackPixel(display, DefaultScreen(display));
135          attribs.backing_store = Always;          attribs.backing_store = Always;
136    
137            if (fullscreen)
138            {
139                    attribs.override_redirect = True;
140                    width = WidthOfScreen(DefaultScreenOfDisplay(display));
141                    height = HeightOfScreen(DefaultScreenOfDisplay(display));
142                    XSetInputFocus(display, PointerRoot, RevertToPointerRoot,
143                                   CurrentTime);
144            }
145            else
146            {
147                    attribs.override_redirect = False;
148            }
149    
150          wnd = XCreateWindow(display, DefaultRootWindow(display),          wnd = XCreateWindow(display, DefaultRootWindow(display),
151                          0, 0, width, height, 0, 8, InputOutput, visual,                              0, 0, width, height, 0, CopyFromParent,
152                          CWBackingStore | CWBackPixel, &attribs);                              InputOutput, CopyFromParent,
153                                CWBackingStore | CWBackPixel | CWOverrideRedirect,
154                                &attribs);
155    
156          XStoreName(display, wnd, title);          XStoreName(display, wnd, title);
         XMapWindow(display, wnd);  
157    
158          input_mask  = KeyPressMask | KeyReleaseMask;          classhints = XAllocClassHint();
159            if (classhints != NULL)
160    
161            {
162                    classhints->res_name = "rdesktop";
163                    classhints->res_class = "rdesktop";
164                    XSetClassHint(display, wnd, classhints);
165                    XFree(classhints);
166            }
167    
168            sizehints = XAllocSizeHints();
169            if (sizehints)
170            {
171                    sizehints->flags =
172                            PPosition | PSize | PMinSize | PMaxSize | PBaseSize;
173                    sizehints->min_width = width;
174                    sizehints->max_width = width;
175                    sizehints->min_height = height;
176                    sizehints->max_height = height;
177                    sizehints->base_width = width;
178                    sizehints->base_height = height;
179                    XSetWMNormalHints(display, wnd, sizehints);
180                    XFree(sizehints);
181            }
182    
183            input_mask = KeyPressMask | KeyReleaseMask;
184          input_mask |= ButtonPressMask | ButtonReleaseMask;          input_mask |= ButtonPressMask | ButtonReleaseMask;
185          if (motion)          if (motion)
186                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
187            if (grab_keyboard)
188                    input_mask |= EnterWindowMask | LeaveWindowMask;
189    
190          XSelectInput(display, wnd, input_mask);          XSelectInput(display, wnd, input_mask);
191          gc = XCreateGC(display, wnd, 0, NULL);          gc = XCreateGC(display, wnd, 0, NULL);
192    
193          IM = XOpenIM(display, NULL, NULL, NULL);          XMapWindow(display, wnd);
194          return True;          return True;
195  }  }
196    
197  void ui_destroy_window()  void
198    ui_destroy_window()
199  {  {
         XCloseIM(IM);  
200          XFreeGC(display, gc);          XFreeGC(display, gc);
201          XDestroyWindow(display, wnd);          XDestroyWindow(display, wnd);
202          XCloseDisplay(display);          XCloseDisplay(display);
203            display = NULL;
204  }  }
205    
206  static uint8 xwin_translate_key(unsigned long key)  static uint8
207    xwin_translate_key(unsigned long key)
208  {  {
209          DEBUG("KEY(code=0x%lx)\n", key);          DEBUG("KEY(code=0x%lx)\n", key);
210    
# Line 96  static uint8 xwin_translate_key(unsigned Line 213  static uint8 xwin_translate_key(unsigned
213    
214          switch (key)          switch (key)
215          {          {
216                  case 0x62: /* left arrow */                  case 0x61:      /* home */
217                          return 0x48;                          return 0x47 | 0x80;
218                  case 0x64: /* up arrow */                  case 0x62:      /* up arrow */
219                          return 0x4b;                          return 0x48 | 0x80;
220                  case 0x66: /* down arrow */                  case 0x63:      /* page up */
221                          return 0x4d;                          return 0x49 | 0x80;
222                  case 0x68: /* right arrow */                  case 0x64:      /* left arrow */
223                          return 0x50;                          return 0x4b | 0x80;
224                  case 0x73: /* Windows key */                  case 0x66:      /* right arrow */
225                          DEBUG("CHECKPOINT\n");                          return 0x4d | 0x80;
226                    case 0x67:      /* end */
227                            return 0x4f | 0x80;
228                    case 0x68:      /* down arrow */
229                            return 0x50 | 0x80;
230                    case 0x69:      /* page down */
231                            return 0x51 | 0x80;
232                    case 0x6a:      /* insert */
233                            return 0x52 | 0x80;
234                    case 0x6b:      /* delete */
235                            return 0x53 | 0x80;
236                    case 0x6c:      /* keypad enter */
237                            return 0x1c | 0x80;
238                    case 0x6d:      /* right ctrl */
239                            return 0x1d | 0x80;
240                    case 0x6f:      /* ctrl - print screen */
241                            return 0x37 | 0x80;
242                    case 0x70:      /* keypad '/' */
243                            return 0x35 | 0x80;
244                    case 0x71:      /* right alt */
245                            return 0x38 | 0x80;
246                    case 0x72:      /* ctrl break */
247                            return 0x46 | 0x80;
248                    case 0x73:      /* left window key */
249                            return 0xff;    /* real scancode is 5b */
250                    case 0x74:      /* right window key */
251                            return 0xff;    /* real scancode is 5c */
252                    case 0x75:      /* menu key */
253                            return 0x5d | 0x80;
254          }          }
255    
256          return 0;          return 0;
257  }  }
258    
259  static uint16 xwin_translate_mouse(unsigned long button)  static uint16
260    xwin_translate_mouse(unsigned long button)
261  {  {
262          switch (button)          switch (button)
263          {          {
264                  case Button1: /* left */                  case Button1:   /* left */
265                          return MOUSE_FLAG_BUTTON1;                          return MOUSE_FLAG_BUTTON1;
266                  case Button2: /* middle */                  case Button2:   /* middle */
267                          return MOUSE_FLAG_BUTTON3;                          return MOUSE_FLAG_BUTTON3;
268                  case Button3: /* right */                  case Button3:   /* right */
269                          return MOUSE_FLAG_BUTTON2;                          return MOUSE_FLAG_BUTTON2;
270          }          }
271    
272          return 0;          return 0;
273  }  }
274    
275  void ui_process_events()  void
276    ui_process_events()
277  {  {
278          XEvent event;          XEvent event;
279          uint8 scancode;          uint8 scancode;
# Line 136  void ui_process_events() Line 283  void ui_process_events()
283          if (display == NULL)          if (display == NULL)
284                  return;                  return;
285    
286          while (XCheckWindowEvent(display, wnd, 0xffffffff, &event))          while (XCheckWindowEvent(display, wnd, ~0, &event))
287          {          {
288                  ev_time = time(NULL);                  ev_time = time(NULL);
289    
# Line 148  void ui_process_events() Line 295  void ui_process_events()
295                                          break;                                          break;
296    
297                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,
298                                                  scancode, 0);                                                 scancode, 0);
299                                  break;                                  break;
300    
301                          case KeyRelease:                          case KeyRelease:
# Line 157  void ui_process_events() Line 304  void ui_process_events()
304                                          break;                                          break;
305    
306                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE,                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE,
307                                                  KBD_FLAG_DOWN | KBD_FLAG_UP,                                                 KBD_FLAG_DOWN | KBD_FLAG_UP,
308                                                  scancode, 0);                                                 scancode, 0);
309                                  break;                                  break;
310    
311                          case ButtonPress:                          case ButtonPress:
312                                  button = xwin_translate_mouse(event.xbutton.button);                                  button = xwin_translate_mouse(event.xbutton.button);
   
313                                  if (button == 0)                                  if (button == 0)
314                                          break;                                          break;
315    
316                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,
317                                                  button | MOUSE_FLAG_DOWN,                                                 button | MOUSE_FLAG_DOWN,
318                                                  event.xbutton.x,                                                 event.xbutton.x,
319                                                  event.xbutton.y);                                                 event.xbutton.y);
320                                  break;                                  break;
321    
322                          case ButtonRelease:                          case ButtonRelease:
# Line 179  void ui_process_events() Line 325  void ui_process_events()
325                                          break;                                          break;
326    
327                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,
328                                                  button,                                                 button,
329                                                  event.xbutton.x,                                                 event.xbutton.x,
330                                                  event.xbutton.y);                                                 event.xbutton.y);
331                                  break;                                  break;
332    
333                          case MotionNotify:                          case MotionNotify:
334                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,
335                                                  MOUSE_FLAG_MOVE,                                                 MOUSE_FLAG_MOVE,
336                                                  event.xmotion.x,                                                 event.xmotion.x,
337                                                  event.xmotion.y);                                                 event.xmotion.y);
338                                    break;
339    
340                            case EnterNotify:
341                                    if (grab_keyboard)
342                                            xwin_grab_keyboard();
343                                    break;
344    
345                            case LeaveNotify:
346                                    if (grab_keyboard)
347                                            xwin_ungrab_keyboard();
348                                    break;
349                  }                  }
350          }          }
351  }  }
352    
353  void ui_move_pointer(int x, int y)  void
354    ui_move_pointer(int x, int y)
355  {  {
356          XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);          XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);
357  }  }
358    
359  HBITMAP ui_create_bitmap(int width, int height, uint8 *data)  HBITMAP
360    ui_create_bitmap(int width, int height, uint8 *data)
361  {  {
362          XImage *image;          XImage *image;
363          Pixmap bitmap;          Pixmap bitmap;
364            uint8 *tdata;
365            tdata = (private_colormap ? data : translate(width, height, data));
366            bitmap = XCreatePixmap(display, wnd, width, height, depth);
367            image =
368                    XCreateImage(display, visual,
369                                 depth, ZPixmap,
370                                 0, tdata, width, height, BitmapPad(display), 0);
371    
372          bitmap = XCreatePixmap(display, wnd, width, height, 8);          xwin_set_function(ROP2_COPY);
   
         image = XCreateImage(display, visual, 8, ZPixmap, 0,  
                                 data, width, height, 8, width);  
         XSetFunction(display, gc, GXcopy);  
373          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
374    
375          XFree(image);          XFree(image);
376                    if (!private_colormap)
377          return (HBITMAP)bitmap;                  xfree(tdata);
378            return (HBITMAP) bitmap;
379  }  }
380    
381  void ui_paint_bitmap(int x, int y, int cx, int cy,  void
382                          int width, int height, uint8 *data)  ui_paint_bitmap(int x, int y, int cx, int cy,
383                    int width, int height, uint8 *data)
384  {  {
385          XImage *image;          XImage *image;
386            uint8 *tdata =
387                    (private_colormap ? data : translate(width, height, data));
388            image =
389                    XCreateImage(display, visual, depth, ZPixmap, 0, tdata, width,
390                                 height, BitmapPad(display), 0);
391    
392          image = XCreateImage(display, visual, 8, ZPixmap, 0,          xwin_set_function(ROP2_COPY);
393                                  data, width, height, 8, width);  
394          XSetFunction(display, gc, GXcopy);          /* Window */
395          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
396          XFree(image);          XFree(image);
397            if (!private_colormap)
398                    xfree(tdata);
399    }
400    
401    void
402    ui_destroy_bitmap(HBITMAP bmp)
403    {
404            XFreePixmap(display, (Pixmap) bmp);
405    }
406    
407    HCURSOR
408    ui_create_cursor(unsigned int x, unsigned int y, int width,
409                     int height, uint8 *mask, uint8 *data)
410    {
411            XImage *imagecursor;
412            XImage *imagemask;
413            Pixmap maskbitmap, cursorbitmap;
414            Cursor cursor;
415            XColor bg, fg;
416            GC lgc;
417            int i, x1, y1, scanlinelen;
418            uint8 *cdata, *cmask;
419            uint8 c;
420            cdata = (uint8 *) malloc(sizeof(uint8) * width * height);
421            if (!cdata)
422                    return NULL;
423            scanlinelen = (width + 7) >> 3;
424            cmask = (uint8 *) malloc(sizeof(uint8) * scanlinelen * height);
425            if (!cmask)
426            {
427                    free(cdata);
428                    return NULL;
429            }
430            i = (height - 1) * scanlinelen;
431    
432            if (!screen_msbfirst)
433            {
434                    while (i >= 0)
435                    {
436                            for (x1 = 0; x1 < scanlinelen; x1++)
437                            {
438                                    c = *(mask++);
439                                    cmask[i + x1] =
440                                            ((c & 0x1) << 7) | ((c & 0x2) << 5) |
441                                            ((c & 0x4) << 3) | ((c & 0x8) << 1) |
442                                            ((c & 0x10) >> 1) | ((c & 0x20) >> 3)
443                                            | ((c & 0x40) >> 5) | ((c & 0x80) >>
444                                                                   7);
445                            }
446                            i -= scanlinelen;
447                    }
448            }
449            else
450            {
451                    while (i >= 0)
452                    {
453                            for (x1 = 0; x1 < scanlinelen; x1++)
454                            {
455                                    cmask[i + x1] = *(mask++);
456                            }
457                            i -= scanlinelen;
458                    }
459            }
460    
461    
462            fg.red = 0;
463            fg.blue = 0;
464            fg.green = 0;
465            fg.flags = DoRed | DoBlue | DoGreen;
466            bg.red = 65535;
467            bg.blue = 65535;
468            bg.green = 65535;
469            bg.flags = DoRed | DoBlue | DoGreen;
470            maskbitmap = XCreatePixmap(display, wnd, width, height, 1);
471            cursorbitmap = XCreatePixmap(display, wnd, width, height, 1);
472            lgc = XCreateGC(display, maskbitmap, 0, NULL);
473            XSetFunction(display, lgc, GXcopy);
474            imagemask =
475                    XCreateImage(display, visual, 1, XYBitmap, 0, cmask, width,
476                                 height, 8, 0);
477            imagecursor =
478                    XCreateImage(display, visual, 1, XYBitmap, 0, cdata, width,
479                                 height, 8, 0);
480            for (y1 = height - 1; y1 >= 0; y1--)
481                    for (x1 = 0; x1 < width; x1++)
482                    {
483                            if (data[0] >= 0x80 || data[1] >= 0x80
484                                || data[2] >= 0x80)
485                                    if (XGetPixel(imagemask, x1, y1))
486    
487                                    {
488                                            XPutPixel(imagecursor, x1, y1, 0);
489                                            XPutPixel(imagemask, x1, y1, 0);        /* mask is blank for text cursor! */
490                                    }
491    
492                                    else
493                                            XPutPixel(imagecursor, x1, y1, 1);
494    
495                            else
496                                    XPutPixel(imagecursor, x1, y1,
497                                              XGetPixel(imagemask, x1, y1));
498                            data += 3;
499                    }
500            XPutImage(display, maskbitmap, lgc, imagemask, 0, 0, 0, 0, width,
501                      height);
502            XPutImage(display, cursorbitmap, lgc, imagecursor, 0, 0, 0, 0, width,
503                      height); XFree(imagemask);
504            XFree(imagecursor);
505            free(cmask);
506            free(cdata);
507            XFreeGC(display, lgc);
508            cursor =
509                    XCreatePixmapCursor(display, cursorbitmap, maskbitmap, &fg,
510                                        &bg, x, y);
511            XFreePixmap(display, maskbitmap);
512            XFreePixmap(display, cursorbitmap);
513            return (HCURSOR) cursor;
514    }
515    
516    void
517    ui_set_cursor(HCURSOR cursor)
518    {
519            XDefineCursor(display, wnd, (Cursor) cursor);
520  }  }
521    
522  void ui_destroy_bitmap(HBITMAP bmp)  void
523    ui_destroy_cursor(HCURSOR cursor)
524  {  {
525          XFreePixmap(display, (Pixmap)bmp);          XFreeCursor(display, (Cursor) cursor);
526  }  }
527    
528  HGLYPH ui_create_glyph(int width, int height, uint8 *data)  HGLYPH
529    ui_create_glyph(int width, int height, uint8 *data)
530  {  {
531          XImage *image;          XImage *image;
532          Pixmap bitmap;          Pixmap bitmap;
# Line 244  HGLYPH ui_create_glyph(int width, int he Line 539  HGLYPH ui_create_glyph(int width, int he
539          gc = XCreateGC(display, bitmap, 0, NULL);          gc = XCreateGC(display, bitmap, 0, NULL);
540    
541          image = XCreateImage(display, visual, 1, ZPixmap, 0,          image = XCreateImage(display, visual, 1, ZPixmap, 0,
542                                  data, width, height, 8, scanline);                               data, width, height, 8, scanline);
543            image->byte_order = MSBFirst;
544            image->bitmap_bit_order = MSBFirst;
545            XInitImage(image);
546    
547          XSetFunction(display, gc, GXcopy);          XSetFunction(display, gc, GXcopy);
548          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
549          XFree(image);          XFree(image);
550          XFreeGC(display, gc);          XFreeGC(display, gc);
551            
552          return (HGLYPH)bitmap;          return (HGLYPH) bitmap;
553  }  }
554    
555  void ui_destroy_glyph(HGLYPH glyph)  void
556    ui_destroy_glyph(HGLYPH glyph)
557  {  {
558          XFreePixmap(display, (Pixmap)glyph);          XFreePixmap(display, (Pixmap) glyph);
559  }  }
560    
561  HCOLOURMAP ui_create_colourmap(COLOURMAP *colours)  HCOLOURMAP
562    ui_create_colourmap(COLOURMAP *colours)
563  {  {
564          COLOURENTRY *entry;          if (!private_colormap)
         XColor *xcolours, *xentry;  
         Colormap map;  
         int i, ncolours = colours->ncolours;  
   
         xcolours = xmalloc(sizeof(XColor) * ncolours);  
         for (i = 0; i < ncolours; i++)  
565          {          {
566                  entry = &colours->colours[i];                  COLOURENTRY *entry;
567                  xentry = &xcolours[i];                  int i, ncolours = colours->ncolours;
568                    uint32 *nc = xmalloc(sizeof(*colmap) * ncolours);
569                  xentry->pixel = i;                  for (i = 0; i < ncolours; i++)
570                  xentry->red = entry->red << 8;                  {
571                  xentry->blue = entry->blue << 8;                          XColor xc;
572                  xentry->green = entry->green << 8;                          entry = &colours->colours[i];
573                  xentry->flags = DoRed | DoBlue | DoGreen;                          xc.red = entry->red << 8;
574                            xc.green = entry->green << 8;
575                            xc.blue = entry->blue << 8;
576                            XAllocColor(display,
577                                        DefaultColormap(display,
578                                                        DefaultScreen(display)),
579                                        &xc);
580                            /* XXX Check return value */
581                            nc[i] = xc.pixel;
582                    }
583                    return nc;
584          }          }
585            else
586            {
587                    COLOURENTRY *entry;
588                    XColor *xcolours, *xentry;
589                    Colormap map;
590                    int i, ncolours = colours->ncolours;
591                    xcolours = xmalloc(sizeof(XColor) * ncolours);
592                    for (i = 0; i < ncolours; i++)
593                    {
594                            entry = &colours->colours[i];
595                            xentry = &xcolours[i];
596    
597          map = XCreateColormap(display, wnd, visual, AllocAll);                          xentry->pixel = i;
598          XStoreColors(display, map, xcolours, ncolours);                          xentry->red = entry->red << 8;
599                            xentry->blue = entry->blue << 8;
600                            xentry->green = entry->green << 8;
601                            xentry->flags = DoRed | DoBlue | DoGreen;
602                    }
603    
604                    map = XCreateColormap(display, wnd, visual, AllocAll);
605                    XStoreColors(display, map, xcolours, ncolours);
606    
607          xfree(xcolours);                  xfree(xcolours);
608          return (HCOLOURMAP)map;                  return (HCOLOURMAP) map;
609            }
610  }  }
611    
612  void ui_destroy_colourmap(HCOLOURMAP map)  void
613    ui_destroy_colourmap(HCOLOURMAP map)
614  {  {
615          XFreeColormap(display, (Colormap)map);          XFreeColormap(display, (Colormap) map);
616  }  }
617    
618  void ui_set_colourmap(HCOLOURMAP map)  void
619    ui_set_colourmap(HCOLOURMAP map)
620  {  {
621          XSetWindowColormap(display, wnd, (Colormap)map);  
622            /* XXX, change values of all pixels on the screen if the new colmap
623             * doesn't have the same values as the old one? */
624            if (!private_colormap)
625                    colmap = map;
626            else
627            {
628                    XSetWindowColormap(display, wnd, (Colormap) map);
629                    if (fullscreen)
630                            XInstallColormap(display, (Colormap) map);
631            }
632  }  }
633    
634  void ui_set_clip(int x, int y, int cx, int cy)  void
635    ui_set_clip(int x, int y, int cx, int cy)
636  {  {
637          XRectangle rect;          XRectangle rect;
638    
# Line 306  void ui_set_clip(int x, int y, int cx, i Line 643  void ui_set_clip(int x, int y, int cx, i
643          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
644  }  }
645    
646  void ui_reset_clip()  void
647    ui_reset_clip()
648  {  {
649          XRectangle rect;          XRectangle rect;
650    
# Line 317  void ui_reset_clip() Line 655  void ui_reset_clip()
655          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
656  }  }
657    
658  void ui_bell()  void
659    ui_bell()
660  {  {
661          XBell(display, 0);          XBell(display, 0);
662  }  }
663    
664  static int rop2_map[] = {  void
665          GXclear,        /* 0 */  ui_destblt(uint8 opcode,
666          GXnor,          /* DPon */             /* dest */ int x, int y, int cx, int cy)
         GXandInverted,  /* DPna */  
         GXcopyInverted, /* Pn */  
         GXandReverse,   /* PDna */  
         GXinvert,       /* Dn */  
         GXxor,          /* DPx */  
         GXnand,         /* DPan */  
         GXand,          /* DPa */  
         GXequiv,        /* DPxn */  
         GXnoop,         /* D */  
         GXorInverted,   /* DPno */  
         GXcopy,         /* P */  
         GXorReverse,    /* PDno */  
         GXor,           /* DPo */  
         GXset           /* 1 */  
 };  
   
 static void xwin_set_function(uint8 rop2)  
 {  
         XSetFunction(display, gc, rop2_map[rop2]);  
 }  
   
 void ui_destblt(uint8 opcode,  
         /* dest */  int x, int y, int cx, int cy)  
667  {  {
668          xwin_set_function(opcode);          xwin_set_function(opcode);
669    
670          XFillRectangle(display, wnd, gc, x, y, cx, cy);          XFillRectangle(display, wnd, gc, x, y, cx, cy);
671  }  }
672    
673  void ui_patblt(uint8 opcode,  void
674          /* dest */  int x, int y, int cx, int cy,  ui_patblt(uint8 opcode,
675          /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* dest */ int x, int y, int cx, int cy,
676              /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
677  {  {
678          Display *dpy = display;          Display *dpy = display;
679          Pixmap fill;          Pixmap fill;
680            uint8 i, ipattern[8];
681    
682          xwin_set_function(opcode);          xwin_set_function(opcode);
683    
684          switch (brush->style)          switch (brush->style)
685          {          {
686                  case 0: /* Solid */                  case 0: /* Solid */
687                          XSetForeground(dpy, gc, fgcolour);                          XSetForeground(dpy, gc, Ctrans(fgcolour));
688                          XFillRectangle(dpy, wnd, gc, x, y, cx, cy);                          XFillRectangle(dpy, wnd, gc, x, y, cx, cy);
689                          break;                          break;
690    
691                  case 3: /* Pattern */                  case 3: /* Pattern */
692                          fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);                          for (i = 0; i != 8; i++)
693                                    ipattern[i] = ~brush->pattern[i];
694                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
695    
696                          XSetForeground(dpy, gc, fgcolour);                          XSetForeground(dpy, gc, Ctrans(fgcolour));
697                          XSetBackground(dpy, gc, bgcolour);                          XSetBackground(dpy, gc, Ctrans(bgcolour));
698                          XSetFillStyle(dpy, gc, FillOpaqueStippled);                          XSetFillStyle(dpy, gc, FillOpaqueStippled);
699                          XSetStipple(dpy, gc, fill);                          XSetStipple(dpy, gc, fill);
700    
701                          XFillRectangle(dpy, wnd, gc, x, y, cx, cy);                          XFillRectangle(dpy, wnd, gc, x, y, cx, cy);
702    
703                          XSetFillStyle(dpy, gc, FillSolid);                          XSetFillStyle(dpy, gc, FillSolid);
704                          ui_destroy_glyph((HGLYPH)fill);                          ui_destroy_glyph((HGLYPH) fill);
705                          break;                          break;
706    
707                  default:                  default:
# Line 389  void ui_patblt(uint8 opcode, Line 709  void ui_patblt(uint8 opcode,
709          }          }
710  }  }
711    
712  void ui_screenblt(uint8 opcode,  void
713                  /* dest */ int x, int y, int cx, int cy,  ui_screenblt(uint8 opcode,
714                  /* src */  int srcx, int srcy)               /* dest */ int x, int y, int cx, int cy,
715                 /* src */ int srcx, int srcy)
716  {  {
717          xwin_set_function(opcode);          xwin_set_function(opcode);
718    
719          XCopyArea(display, wnd, wnd, gc, srcx, srcy,          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
                         cx, cy, x, y);  
720  }  }
721    
722  void ui_memblt(uint8 opcode,  void
723          /* dest */  int x, int y, int cx, int cy,  ui_memblt(uint8 opcode,
724          /* src */   HBITMAP src, int srcx, int srcy)            /* dest */ int x, int y, int cx, int cy,
725              /* src */ HBITMAP src, int srcx, int srcy)
726  {  {
727          xwin_set_function(opcode);          xwin_set_function(opcode);
728    
729          XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy,          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
                         cx, cy, x, y);  
730  }  }
731    
732  void ui_triblt(uint8 opcode,  void
733          /* dest */  int x, int y, int cx, int cy,  ui_triblt(uint8 opcode,
734          /* src */   HBITMAP src, int srcx, int srcy,            /* dest */ int x, int y, int cx, int cy,
735          /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* src */ HBITMAP src, int srcx, int srcy,
736              /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
737  {  {
738          /* This is potentially difficult to do in general. Until someone          /* This is potentially difficult to do in general. Until someone
739             comes up with a more efficient way of doing it I am using cases. */             comes up with a more efficient way of doing it I am using cases. */
740    
741          switch (opcode)          switch (opcode)
742          {          {
743                  case 0x69: /* PDSxxn */                  case 0x69:      /* PDSxxn */
744                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
745                          ui_patblt(ROP2_NXOR, x, y, cx, cy,                          ui_patblt(ROP2_NXOR, x, y, cx, cy,
746                                          brush, bgcolour, fgcolour);                                    brush, bgcolour, fgcolour);
747                          break;                          break;
748    
749                  case 0xb8: /* PSDPxax */                  case 0xb8:      /* PSDPxax */
750                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy,
751                                          brush, bgcolour, fgcolour);                                    brush, bgcolour, fgcolour);
752                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
753                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy,
754                                          brush, bgcolour, fgcolour);                                    brush, bgcolour, fgcolour);
755                            break;
756    
757                    case 0xc0:
758                            ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
759                            ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,
760                                      fgcolour);
761                          break;                          break;
762    
763                  default:                  default:
# Line 439  void ui_triblt(uint8 opcode, Line 766  void ui_triblt(uint8 opcode,
766          }          }
767  }  }
768    
769  void ui_line(uint8 opcode,  void
770          /* dest */  int startx, int starty, int endx, int endy,  ui_line(uint8 opcode,
771          /* pen */   PEN *pen)          /* dest */ int startx, int starty, int endx, int endy,
772            /* pen */ PEN *pen)
773  {  {
774          xwin_set_function(opcode);          xwin_set_function(opcode);
775    
776          XSetForeground(display, gc, pen->colour);          XSetForeground(display, gc, Ctrans(pen->colour));
777          XDrawLine(display, wnd, gc, startx, starty, endx, endy);          XDrawLine(display, wnd, gc, startx, starty, endx, endy);
778  }  }
779    
780  void ui_rect(  void
781          /* dest */  int x, int y, int cx, int cy,  ui_rect(
782          /* brush */ int colour)                 /* dest */ int x, int y, int cx, int cy,
783                   /* brush */ int colour)
784  {  {
785          xwin_set_function(ROP2_COPY);          xwin_set_function(ROP2_COPY);
786    
787          XSetForeground(display, gc, colour);          XSetForeground(display, gc, Ctrans(colour));
788          XFillRectangle(display, wnd, gc, x, y, cx, cy);          XFillRectangle(display, wnd, gc, x, y, cx, cy);
789  }  }
790    
791  void ui_draw_glyph(int mixmode,  void
792          /* dest */ int x, int y, int cx, int cy,  ui_draw_glyph(int mixmode,
793          /* src */  HGLYPH glyph, int srcx, int srcy, int bgcolour, int fgcolour)                /* dest */ int x, int y, int cx, int cy,
794                  /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,
795                  int fgcolour)
796  {  {
797          Pixmap pixmap = (Pixmap)glyph;          Pixmap pixmap = (Pixmap) glyph;
798    
799          xwin_set_function(ROP2_COPY);          xwin_set_function(ROP2_COPY);
800    
         XSetForeground(display, gc, fgcolour);  
801    
802            XSetForeground(display, gc, Ctrans(fgcolour));
803          switch (mixmode)          switch (mixmode)
804          {          {
805                  case MIX_TRANSPARENT:                  case MIX_TRANSPARENT:
806                          XSetStipple(display, gc, pixmap);                          XSetStipple(display, gc, pixmap);
807                          XSetFillStyle(display, gc, FillStippled);                          XSetFillStyle(display, gc, FillStippled);
808                          XSetTSOrigin(display, gc, x, y);                          XSetTSOrigin(display, gc, x, y);
809                          XFillRectangle(display, wnd, gc,                          XFillRectangle(display, wnd, gc, x, y, cx, cy);
                                         x, y, cx, cy);  
810                          XSetFillStyle(display, gc, FillSolid);                          XSetFillStyle(display, gc, FillSolid);
811                          break;                          break;
812    
813                  case MIX_OPAQUE:                  case MIX_OPAQUE:
814                          XSetBackground(display, gc, bgcolour);                          XSetBackground(display, gc, Ctrans(bgcolour));
815                          XCopyPlane(display, pixmap, wnd, gc,  /*      XCopyPlane (display, pixmap, back_pixmap, back_gc, srcx, srcy, cx, cy, x, y, 1); */
816                                          srcx, srcy, cx, cy, x, y, 1);                          XSetStipple(display, gc, pixmap);
817                            XSetFillStyle(display, gc, FillOpaqueStippled);
818                            XSetTSOrigin(display, gc, x, y);
819                            XFillRectangle(display, wnd, gc, x, y, cx, cy);
820                            XSetFillStyle(display, gc, FillSolid);
821                          break;                          break;
822    
823                  default:                  default:
# Line 491  void ui_draw_glyph(int mixmode, Line 825  void ui_draw_glyph(int mixmode,
825          }          }
826  }  }
827    
828  void ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,  void
829                          int clipx, int clipy, int clipcx, int clipcy,  ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
830                          int boxx, int boxy, int boxcx, int boxcy,               int clipx, int clipy, int clipcx, int clipcy,
831                          int bgcolour, int fgcolour, uint8 *text, uint8 length)               int boxx, int boxy, int boxcx, int boxcy,
832                 int bgcolour, int fgcolour, uint8 *text, uint8 length)
833  {  {
834          FONTGLYPH *glyph;          FONTGLYPH *glyph;
835          int i;          int i, xyoffset;
836    
837            xwin_set_function(ROP2_COPY);
838            XSetForeground(display, gc, Ctrans(bgcolour));
839    
840          if (boxcx > 1)          if (boxcx > 1)
841          {                  XFillRectangle(display, wnd, gc, boxx, boxy, boxcx, boxcy);
                 ui_rect(boxx, boxy, boxcx, boxcy, bgcolour);  
         }  
842          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
843          {                  XFillRectangle(display, wnd, gc, clipx, clipy, clipcx, clipcy);
                 ui_rect(clipx, clipy, clipcx, clipcy, bgcolour);  
         }  
844    
845          /* Paint text, character by character */          /* Paint text, character by character */
846          for (i = 0; i < length; i++)          for (i = 0; i < length; i++)
# Line 514  void ui_draw_text(uint8 font, uint8 flag Line 848  void ui_draw_text(uint8 font, uint8 flag
848                  glyph = cache_get_font(font, text[i]);                  glyph = cache_get_font(font, text[i]);
849    
850                  if (!(flags & TEXT2_IMPLICIT_X))                  if (!(flags & TEXT2_IMPLICIT_X))
                         x += text[++i];  
851    
852                    {
853                            xyoffset = text[++i];
854                            if ((xyoffset & 0x80))
855                            {
856                                    if (flags & 0x04)       /* vertical text */
857                                            y += text[++i] | (text[++i] << 8);
858                                    else
859                                            x += text[++i] | (text[++i] << 8);
860                            }
861                            else
862                            {
863                                    if (flags & 0x04)       /* vertical text */
864                                            y += xyoffset;
865                                    else
866                                            x += xyoffset;
867                            }
868    
869                    }
870                  if (glyph != NULL)                  if (glyph != NULL)
871                  {                  {
872                          ui_draw_glyph(mixmode, x + (short)glyph->offset,                          ui_draw_glyph(mixmode, x + (short) glyph->offset,
873                                          y + (short)glyph->baseline,                                        y + (short) glyph->baseline,
874                                          glyph->width, glyph->height,                                        glyph->width, glyph->height,
875                                          glyph->pixmap, 0, 0,                                        glyph->pixmap, 0, 0,
876                                          bgcolour, fgcolour);                                        bgcolour, fgcolour);
877    
878                          if (flags & TEXT2_IMPLICIT_X)                          if (flags & TEXT2_IMPLICIT_X)
879                                  x += glyph->width;                                  x += glyph->width;
# Line 530  void ui_draw_text(uint8 font, uint8 flag Line 881  void ui_draw_text(uint8 font, uint8 flag
881          }          }
882  }  }
883    
884  void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)  void
885    ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
886  {  {
887            Pixmap pix;
888          XImage *image;          XImage *image;
889    
890          image = XGetImage(display, wnd, x, y, cx, cy, 0xffffffff, ZPixmap);          pix = XCreatePixmap(display, wnd, cx, cy, depth);
891          cache_put_desktop(offset, cx, cy, image->bytes_per_line, image->data);          xwin_set_function(ROP2_COPY);
892          XFree(image->data);  
893          XFree(image);          XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
894            image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
895    
896            offset *= bpp/8;
897            cache_put_desktop(offset, cx, cy, image->bytes_per_line,
898                              bpp/8, image->data);
899    
900            XDestroyImage(image);
901            XFreePixmap(display, pix);
902  }  }
903    
904  void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)  void
905    ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
906  {  {
907          XImage *image;          XImage *image;
908          uint8 *data;          uint8 *data;
909    
910          data = cache_get_desktop(offset, cx, cy);          offset *= bpp/8;
911            data = cache_get_desktop(offset, cx, cy, bpp/8);
912          if (data == NULL)          if (data == NULL)
913                  return;                  return;
914            image =
915          image = XCreateImage(display, visual, 8, ZPixmap, 0,                  XCreateImage(display, visual,
916                                  data, cx, cy, 32, cx);                               depth, ZPixmap,
917          XSetFunction(display, gc, GXcopy);                               0, data, cx, cy, BitmapPad(display),
918                                 cx * bpp/8);
919            xwin_set_function(ROP2_COPY);
920          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);          XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
921          XFree(image);          XFree(image);
922  }  }
923    
924    /* unroll defines, used to make the loops a bit more readable... */
925    #define unroll8Expr(uexp) uexp uexp uexp uexp uexp uexp uexp uexp
926    #define unroll8Lefts(uexp) case 7: uexp \
927            case 6: uexp \
928            case 5: uexp \
929            case 4: uexp \
930            case 3: uexp \
931            case 2: uexp \
932            case 1: uexp
933    
934    static uint8 *
935    translate(int width, int height, uint8 *data)
936    {
937            uint32 i;
938            uint32 size = width * height;
939            uint8 *d2 = xmalloc(size * bpp/8);
940            uint8 *d3 = d2;
941            uint32 pix;
942            i = (size & ~0x7);
943    
944            /* XXX: where are the bits swapped??? */
945    #ifdef L_ENDIAN                 /* little-endian */
946            /* big-endian screen */
947            if (screen_msbfirst)
948            {
949                    switch (bpp)
950                    {
951                            case 32:
952                                    while (i)
953                                    {
954                                            unroll8Expr(pix = colmap[*data++];
955                                                        *d3++ = pix >> 24;
956                                                        *d3++ = pix >> 16;
957                                                        *d3++ = pix >> 8;
958                                                        *d3++ = pix;) i -= 8;
959                                    }
960                                    i = (size & 0x7);
961                                    if (i != 0)
962                                            switch (i)
963                                            {
964                                                            unroll8Lefts(pix =
965                                                                         colmap
966                                                                         [*data++];
967                                                                         *d3++ =
968                                                                         pix >>
969                                                                         24;
970                                                                         *d3++ =
971                                                                         pix >>
972                                                                         16;
973                                                                         *d3++ =
974                                                                         pix >> 8;
975                                                                         *d3++ =
976                                                                         pix;)}
977                                    break;
978                            case 24:
979                                    while (i)
980                                    {
981                                            unroll8Expr(pix = colmap[*data++];
982                                                        *d3++ = pix >> 16;
983                                                        *d3++ = pix >> 8;
984                                                        *d3++ = pix;) i -= 8;
985                                    }
986                                    i = (size & 0x7);
987                                    if (i != 0)
988                                            switch (i)
989                                            {
990                                                            unroll8Lefts(pix =
991                                                                         colmap
992                                                                         [*data++];
993                                                                         *d3++ =
994                                                                         pix >>
995                                                                         16;
996                                                                         *d3++ =
997                                                                         pix >> 8;
998                                                                         *d3++ =
999                                                                         pix;)}
1000                                    break;
1001                            case 16:
1002                                    while (i)
1003                                    {
1004                                            unroll8Expr(pix = colmap[*data++];
1005                                                        *d3++ = pix >> 8;
1006                                                        *d3++ = pix;) i -= 8;
1007                                    }
1008                                    i = (size & 0x7);
1009                                    if (i != 0)
1010                                            switch (i)
1011                                            {
1012                                                            unroll8Lefts(pix =
1013                                                                         colmap
1014                                                                         [*data++];
1015                                                                         *d3++ =
1016                                                                         pix >> 8;
1017                                                                         *d3++ =
1018                                                                         pix;)}
1019                                    break;
1020                            case 8:
1021                                    while (i)
1022                                    {
1023                                            unroll8Expr(pix = colmap[*data++];
1024                                                        *d3++ = pix;
1025                                                    )i -= 8;
1026                                    }
1027                                    i = (size & 0x7);
1028                                    if (i != 0)
1029                                            switch (i)
1030                                            {
1031                                                            unroll8Lefts(pix =
1032                                                                         colmap
1033                                                                         [*data++];
1034                                                                         *d3++ =
1035                                                                         pix;)}
1036                                    break;
1037                    }
1038            }
1039            else
1040            {                       /* little-endian screen */
1041                    switch (bpp)
1042                    {
1043                            case 32:
1044                                    while (i)
1045                                    {
1046                                            unroll8Expr(*((uint32 *) d3) =
1047                                                        colmap[*data++];
1048                                                        d3 += sizeof(uint32);
1049                                                    )i -= 8;
1050                                    }
1051                                    i = (size & 0x7);
1052                                    if (i != 0)
1053                                            switch (i)
1054                                            {
1055                                                            unroll8Lefts(*
1056                                                                         ((uint32
1057                                                                           *) d3)
1058    = colmap[*data++];
1059    d3 += sizeof(uint32);
1060                                            )}
1061                                    break;
1062                            case 24:
1063                                    while (i)
1064                                    {
1065                                            unroll8Expr(pix = colmap[*data++];
1066                                                        *d3++ = pix;
1067                                                        *d3++ = pix >> 8;
1068                                                        *d3++ = pix >> 16;
1069                                                    )i -= 8;
1070                                    }
1071                                    i = (size & 0x7);
1072                                    if (i != 0)
1073                                            switch (i)
1074                                            {
1075                                                            unroll8Lefts(pix =
1076                                                                         colmap
1077                                                                         [*data++];
1078                                                                         *d3++ =
1079                                                                         pix;
1080                                                                         *d3++ =
1081                                                                         pix >> 8;
1082                                                                         *d3++ =
1083                                                                         pix >>
1084                                                                         16;)}
1085                                    break;
1086                            case 16:
1087                                    while (i)
1088                                    {
1089                                            unroll8Expr(pix = colmap[*data++];
1090                                                        *d3++ = pix;
1091                                                        *d3++ = pix >> 8;
1092                                                    )i -= 8;
1093                                    }
1094                                    i = (size & 0x7);
1095                                    if (i != 0)
1096                                            switch (i)
1097                                            {
1098                                                            unroll8Lefts(pix =
1099                                                                         colmap
1100                                                                         [*data++];
1101                                                                         *d3++ =
1102                                                                         pix;
1103                                                                         *d3++ =
1104                                                                         pix >> 8;
1105                                            )}
1106                                    break;
1107                            case 8:
1108                                    while (i)
1109                                    {
1110                                            unroll8Expr(pix = colmap[*data++];
1111                                                        *d3++ = pix;
1112                                                    )i -= 8;
1113                                    }
1114                                    i = (size & 0x7);
1115                                    if (i != 0)
1116                                            switch (i)
1117                                            {
1118                                                            unroll8Lefts(pix =
1119                                                                         colmap
1120                                                                         [*data++];
1121                                                                         *d3++ =
1122                                                                         pix;)}
1123                    }
1124            }
1125    
1126    #else /* bigendian-compiled */
1127            if (screen_msbfirst)
1128            {
1129                    /* big-endian screen */
1130                    switch (bpp)
1131                    {
1132                            case 32:
1133                                    while (i)
1134                                    {
1135                                            unroll8Expr(*((uint32 *) d3) =
1136                                                        colmap[*data++];
1137                                                        d3 += sizeof(uint32);
1138                                                    )i -= 8;
1139                                    }
1140                                    i = (size & 0x7);
1141                                    if (i != 0)
1142                                            switch (i)
1143                                            {
1144                                                            unroll8Lefts(*
1145                                                                         ((uint32
1146                                                                           *) d3)
1147    = colmap[*data++];
1148    d3 += sizeof(uint32);
1149                                            )}
1150                                    break;
1151                            case 24:
1152                                    while (i)
1153                                    {
1154                                            unroll8Expr(pix = colmap[*data++];
1155                                                        *d3++ = pix;
1156                                                        *d3++ = pix >> 8;
1157                                                        *d3++ = pix >> 16;
1158                                                    )i -= 8;
1159                                    }
1160                                    i = (size & 0x7);
1161                                    if (i != 0)
1162                                            switch (i)
1163                                            {
1164                                                            unroll8Lefts(pix =
1165                                                                         colmap
1166                                                                         [*data++];
1167                                                                         *d3++ =
1168                                                                         pix;
1169                                                                         *d3++ =
1170                                                                         pix >> 8;
1171                                                                         *d3++ =
1172                                                                         pix >>
1173                                                                         16;)}
1174                                    break;
1175                            case 16:
1176                                    while (i)
1177                                    {
1178                                            unroll8Expr(pix = colmap[*data++];
1179                                                        *d3++ = pix;
1180                                                        *d3++ = pix >> 8;
1181                                                    )i -= 8;
1182                                    }
1183                                    i = (size & 0x7);
1184                                    if (i != 0)
1185                                            switch (i)
1186                                            {
1187                                                            unroll8Lefts(pix =
1188                                                                         colmap
1189                                                                         [*data++];
1190                                                                         *d3++ =
1191                                                                         pix;
1192                                                                         *d3++ =
1193                                                                         pix >> 8;
1194                                            )}
1195                                    break;
1196                            case 8:
1197                                    while (i)
1198                                    {
1199                                            unroll8Expr(pix = colmap[*data++];
1200                                                        *d3++ = pix;
1201                                                    )i -= 8;
1202                                    }
1203                                    i = (size & 0x7);
1204                                    if (i != 0)
1205                                            switch (i)
1206                                            {
1207                                                            unroll8Lefts(pix =
1208                                                                         colmap
1209                                                                         [*data++];
1210                                                                         *d3++ =
1211                                                                         pix;)}
1212                    }
1213            }
1214            else
1215            {
1216                    /* little-endian screen */
1217                    switch (bpp)
1218                    {
1219                            case 32:
1220                                    while (i)
1221                                    {
1222                                            unroll8Expr(pix = colmap[*data++];
1223                                                        *d3++ = pix;
1224                                                        *d3++ = pix >> 8;
1225                                                        *d3++ = pix >> 16;
1226                                                        *d3++ = pix >> 24;
1227                                                    )i -= 8;
1228                                    }
1229                                    i = (size & 0x7);
1230                                    if (i != 0)
1231                                            switch (i)
1232                                            {
1233                                                            unroll8Lefts(pix =
1234                                                                         colmap
1235                                                                         [*data++];
1236                                                                         *d3++ =
1237                                                                         pix;
1238                                                                         *d3++ =
1239                                                                         pix >> 8;
1240                                                                         *d3++ =
1241                                                                         pix >>
1242                                                                         16;
1243                                                                         *d3++ =
1244                                                                         pix >>
1245                                                                         24;)}
1246                                    break;
1247                            case 24:
1248                                    while (i)
1249                                    {
1250                                            unroll8Expr(pix = colmap[*data++];
1251                                                        *d3++ = pix;
1252                                                        *d3++ = pix >> 8;
1253                                                        *d3++ = pix >> 16;
1254                                                    )i -= 8;
1255                                    }
1256                                    i = (size & 0x7);
1257                                    if (i != 0)
1258                                            switch (i)
1259                                            {
1260                                                            unroll8Lefts(pix =
1261                                                                         colmap
1262                                                                         [*data++];
1263                                                                         *d3++ =
1264                                                                         pix;
1265                                                                         *d3++ =
1266                                                                         pix >> 8;
1267                                                                         *d3++ =
1268                                                                         pix >>
1269                                                                         16;)}
1270                                    break;
1271                            case 16:
1272                                    while (i)
1273                                    {
1274                                            unroll8Expr(pix = colmap[*data++];
1275                                                        *d3++ = pix;
1276                                                        *d3++ = pix >> 8;
1277                                                    )i -= 8;
1278                                    }
1279                                    i = (size & 0x7);
1280                                    if (i != 0)
1281                                            switch (i)
1282                                            {
1283                                                            unroll8Lefts(pix =
1284                                                                         colmap
1285                                                                         [*data++];
1286                                                                         *d3++ =
1287                                                                         pix;
1288                                                                         *d3++ =
1289                                                                         pix >> 8;
1290                                            )}
1291                                    break;
1292                            case 8:
1293                                    while (i)
1294                                    {
1295                                            unroll8Expr(pix = colmap[*data++];
1296                                                        *d3++ = pix;
1297                                                    )i -= 8;
1298                                    }
1299                                    i = (size & 0x7);
1300                                    if (i != 0)
1301                                            switch (i)
1302                                            {
1303                                                            unroll8Lefts(pix =
1304                                                                         colmap
1305                                                                         [*data++];
1306                                                                         *d3++ =
1307                                                                         pix;)}
1308                    }
1309            }
1310    #endif
1311    
1312            return d2;
1313    }

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

  ViewVC Help
Powered by ViewVC 1.1.26