/[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 12 by matty, Tue Aug 15 12:01:01 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 ui_destroy_bitmap(HBITMAP bmp)  void
517    ui_set_cursor(HCURSOR cursor)
518  {  {
519          XFreePixmap(display, (Pixmap)bmp);          XDefineCursor(display, wnd, (Cursor) cursor);
520  }  }
521    
522  HGLYPH ui_create_glyph(int width, int height, uint8 *data)  void
523    ui_destroy_cursor(HCURSOR cursor)
524    {
525            XFreeCursor(display, (Cursor) cursor);
526    }
527    
528    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                            xentry->pixel = i;
598                            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);                  map = XCreateColormap(display, wnd, visual, AllocAll);
605          XStoreColors(display, map, xcolours, ncolours);                  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 0xb8: /* PSDPxax */                  case 0x69:      /* PDSxxn */
744                            ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
745                            ui_patblt(ROP2_NXOR, x, y, cx, cy,
746                                      brush, bgcolour, fgcolour);
747                            break;
748    
749                    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,                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
                                         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:
764                          NOTIMP("triblt 0x%x\n", opcode);                          NOTIMP("triblt 0x%x\n", opcode);
765                          ui_memblt(ROP2_COPY, x, y, cx, cy,                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
                                         brush, bgcolour, fgcolour);  
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 487  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,  void
829                          int y, int boxx, int boxy, int boxcx, int boxcy,  ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
830                          int bgcolour, int fgcolour, uint8 *text, uint8 length)               int clipx, int clipy, int clipcx, int clipcy,
831                 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);
842                  ui_rect(boxx, boxy, boxcx, boxcy, bgcolour);          else if (mixmode == MIX_OPAQUE)
843          }                  XFillRectangle(display, wnd, gc, clipx, clipy, clipcx, clipcy);
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++)
847          {          {
848                  glyph = cache_get_font(font, text[i]);                  glyph = cache_get_font(font, text[i]);
849    
850                    if (!(flags & TEXT2_IMPLICIT_X))
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,                          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;
                         else  
                                 x += text[++i];  
880                  }                  }
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;
         int scanline;  
889    
890          scanline = (cx + 3) & ~3;          pix = XCreatePixmap(display, wnd, cx, cy, depth);
891          DEBUG("XGetImage(%p,%x,%d,%d,%d,%d,%x,%d)\n", display, wnd, x, y,          xwin_set_function(ROP2_COPY);
892                  cx, cy, 0xffffffff, ZPixmap);  
893          image = XGetImage(display, wnd, x, y, cx, cy, 0xffffffff, ZPixmap);          XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
894          cache_put_desktop(offset, scanline*cy, image->data);          image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
895          XFree(image->data);  
896          XFree(image);          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;
         int scanline;  
908          uint8 *data;          uint8 *data;
909    
910          scanline = (cx + 3) & ~3;          offset *= bpp/8;
911          data = cache_get_desktop(offset, scanline*cy);          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, scanline);                               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.12  
changed lines
  Added in v.28

  ViewVC Help
Powered by ViewVC 1.1.26