/[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 9 by matty, Tue Jul 25 12:34:29 2000 UTC revision 28 by matty, Wed Jun 20 13:54:48 2001 UTC
# Line 18  Line 18 
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */  */
20    
21  #include "includes.h"  #include <X11/Xlib.h>
22    #include <X11/Xutil.h>
23    #include <time.h>
24    #include "rdesktop.h"
25    
26    extern int width;
27    extern int height;
28    extern BOOL 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;
36    static Window wnd;
37    static GC gc;
38    static Visual *visual;
39    static uint32 *colmap;
40    
41  HWINDOW ui_create_window(HCONN conn, int width, int height)  #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  {  {
         struct window *wnd;  
95          XSetWindowAttributes attribs;          XSetWindowAttributes attribs;
96          Display *display;          XClassHint *classhints;
97          Visual *visual;          XSizeHints *sizehints;
98          Window window;          unsigned long input_mask;
99          int black;          XPixmapFormatValues *pfm;
100          GC gc;          int count;
101    
102          display = XOpenDisplay(NULL);          display = XOpenDisplay(NULL);
103          if (display == NULL)          if (display == NULL)
104                  return NULL;          {
105                    ERROR("Failed to open display\n");
106                    return False;
107            }
108    
109          visual = DefaultVisual(display, DefaultScreen(display));          visual = DefaultVisual(display, DefaultScreen(display));
110          black = BlackPixel(display, DefaultScreen(display));          depth = DefaultDepth(display, DefaultScreen(display));
111            pfm = XListPixmapFormats(display, &count);
112            if (pfm != NULL)
113            {
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 (bpp < 8)
126            {
127                    ERROR("Less than 8 bpp not currently supported.\n");
128                    XCloseDisplay(display);
129                    return False;
130            }
131    
132            width &= ~3; /* make width nicely divisible */
133    
134          attribs.background_pixel = black;          attribs.background_pixel = BlackPixel(display, DefaultScreen(display));
135          attribs.backing_store = Always;          attribs.backing_store = Always;
         window = XCreateWindow(display, DefaultRootWindow(display), 0, 0,  
                         width, height, 0, 8, InputOutput, visual,  
                         CWBackingStore | CWBackPixel, &attribs);  
136    
137          XStoreName(display, window, "rdesktop");          if (fullscreen)
138          XMapWindow(display, window);          {
139          XSelectInput(display, window, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask);                  attribs.override_redirect = True;
140          XSync(display, True);                  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),
151                                0, 0, width, height, 0, CopyFromParent,
152                                InputOutput, CopyFromParent,
153                                CWBackingStore | CWBackPixel | CWOverrideRedirect,
154                                &attribs);
155    
156            XStoreName(display, wnd, title);
157    
158            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          gc = XCreateGC(display, window, 0, NULL);          input_mask = KeyPressMask | KeyReleaseMask;
184            input_mask |= ButtonPressMask | ButtonReleaseMask;
185            if (motion)
186                    input_mask |= PointerMotionMask;
187            if (grab_keyboard)
188                    input_mask |= EnterWindowMask | LeaveWindowMask;
189    
190          wnd = xmalloc(sizeof(struct window));          XSelectInput(display, wnd, input_mask);
191          wnd->conn = conn;          gc = XCreateGC(display, wnd, 0, NULL);
         wnd->width = width;  
         wnd->height = height;  
         wnd->display = display;  
         wnd->wnd = window;  
         wnd->gc = gc;  
         wnd->visual = visual;  
192    
193          return wnd;          XMapWindow(display, wnd);
194            return True;
195  }  }
196    
197  void ui_destroy_window(HWINDOW wnd)  void
198    ui_destroy_window()
199  {  {
200          XFreeGC(wnd->display, wnd->gc);          XFreeGC(display, gc);
201          XDestroyWindow(wnd->display, wnd->wnd);          XDestroyWindow(display, wnd);
202          XCloseDisplay(wnd->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 78  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(HWINDOW wnd, HCONN conn)  void
276    ui_process_events()
277  {  {
278          XEvent event;          XEvent event;
279          uint8 scancode;          uint8 scancode;
280          uint16 button;          uint16 button;
281            uint32 ev_time;
282    
283          if (wnd == NULL)          if (display == NULL)
284                  return;                  return;
285    
286          while (XCheckWindowEvent(wnd->display, wnd->wnd, 0xffffffff, &event))          while (XCheckWindowEvent(display, wnd, ~0, &event))
287          {          {
288                    ev_time = time(NULL);
289    
290                  switch (event.type)                  switch (event.type)
291                  {                  {
292                          case KeyPress:                          case KeyPress:
# Line 126  void ui_process_events(HWINDOW wnd, HCON Line 294  void ui_process_events(HWINDOW wnd, HCON
294                                  if (scancode == 0)                                  if (scancode == 0)
295                                          break;                                          break;
296    
297                                  rdp_send_input(conn, 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 135  void ui_process_events(HWINDOW wnd, HCON Line 303  void ui_process_events(HWINDOW wnd, HCON
303                                  if (scancode == 0)                                  if (scancode == 0)
304                                          break;                                          break;
305    
306                                  rdp_send_input(conn, 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(conn, 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 157  void ui_process_events(HWINDOW wnd, HCON Line 324  void ui_process_events(HWINDOW wnd, HCON
324                                  if (button == 0)                                  if (button == 0)
325                                          break;                                          break;
326    
327                                  rdp_send_input(conn, 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;
332    
333                            case MotionNotify:
334                                    rdp_send_input(ev_time, RDP_INPUT_MOUSE,
335                                                   MOUSE_FLAG_MOVE,
336                                                   event.xmotion.x,
337                                                   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(HWINDOW wnd, int x, int y)  void
354    ui_move_pointer(int x, int y)
355  {  {
356          XWarpPointer(wnd->display, wnd->wnd, 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(HWINDOW wnd, 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(wnd->display, wnd->wnd, width, height, 8);          xwin_set_function(ROP2_COPY);
373            XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
374    
         image = XCreateImage(wnd->display, wnd->visual, 8, ZPixmap, 0,  
                                 data, width, height, 8, width);  
         XSetFunction(wnd->display, wnd->gc, GXcopy);  
         XPutImage(wnd->display, bitmap, wnd->gc, image, 0, 0, 0, 0,  
                         width, height);  
375          XFree(image);          XFree(image);
376                    if (!private_colormap)
377          return (HBITMAP)bitmap;                  xfree(tdata);
378            return (HBITMAP) bitmap;
379    }
380    
381    void
382    ui_paint_bitmap(int x, int y, int cx, int cy,
383                    int width, int height, uint8 *data)
384    {
385            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            xwin_set_function(ROP2_COPY);
393    
394            /* Window */
395            XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
396            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(HWINDOW wnd, HBITMAP bmp)  void
523    ui_destroy_cursor(HCURSOR cursor)
524  {  {
525          XFreePixmap(wnd->display, (Pixmap)bmp);          XFreeCursor(display, (Cursor) cursor);
526  }  }
527    
528  HGLYPH ui_create_glyph(HWINDOW wnd, 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 201  HGLYPH ui_create_glyph(HWINDOW wnd, int Line 535  HGLYPH ui_create_glyph(HWINDOW wnd, int
535    
536          scanline = (width + 7) / 8;          scanline = (width + 7) / 8;
537    
538          bitmap = XCreatePixmap(wnd->display, wnd->wnd, width, height, 1);          bitmap = XCreatePixmap(display, wnd, width, height, 1);
539          gc = XCreateGC(wnd->display, bitmap, 0, NULL);          gc = XCreateGC(display, bitmap, 0, NULL);
540    
541          image = XCreateImage(wnd->display, wnd->visual, 1, ZPixmap, 0,          image = XCreateImage(display, visual, 1, ZPixmap, 0,
542                                  data, width, height, 8, scanline);                               data, width, height, 8, scanline);
543          XSetFunction(wnd->display, wnd->gc, GXcopy);          image->byte_order = MSBFirst;
544          XPutImage(wnd->display, bitmap, gc, image, 0, 0, 0, 0, width, height);          image->bitmap_bit_order = MSBFirst;
545            XInitImage(image);
546    
547            XSetFunction(display, gc, GXcopy);
548            XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
549          XFree(image);          XFree(image);
550          XFreeGC(wnd->display, gc);          XFreeGC(display, gc);
551            
552          return (HGLYPH)bitmap;          return (HGLYPH) bitmap;
553  }  }
554    
555  void ui_destroy_glyph(HWINDOW wnd, HGLYPH glyph)  void
556    ui_destroy_glyph(HGLYPH glyph)
557  {  {
558          XFreePixmap(wnd->display, (Pixmap)glyph);          XFreePixmap(display, (Pixmap) glyph);
559  }  }
560    
561  HCOLOURMAP ui_create_colourmap(HWINDOW wnd, 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 = malloc(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(wnd->display, wnd->wnd, wnd->visual, AllocAll);                  map = XCreateColormap(display, wnd, visual, AllocAll);
605          XStoreColors(wnd->display, map, xcolours, ncolours);                  XStoreColors(display, map, xcolours, ncolours);
606    
607          free(xcolours);                  xfree(xcolours);
608          return (HCOLOURMAP)map;                  return (HCOLOURMAP) map;
609            }
610  }  }
611    
612  void ui_destroy_colourmap(HWINDOW wnd, HCOLOURMAP map)  void
613    ui_destroy_colourmap(HCOLOURMAP map)
614  {  {
615          XFreeColormap(wnd->display, (Colormap)map);          XFreeColormap(display, (Colormap) map);
616  }  }
617    
618  void ui_set_colourmap(HWINDOW wnd, HCOLOURMAP map)  void
619    ui_set_colourmap(HCOLOURMAP map)
620  {  {
621          XSetWindowColormap(wnd->display, wnd->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(HWINDOW wnd, 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 264  void ui_set_clip(HWINDOW wnd, int x, int Line 640  void ui_set_clip(HWINDOW wnd, int x, int
640          rect.y = y;          rect.y = y;
641          rect.width = cx;          rect.width = cx;
642          rect.height = cy;          rect.height = cy;
643          XSetClipRectangles(wnd->display, wnd->gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
644  }  }
645    
646  void ui_reset_clip(HWINDOW wnd)  void
647    ui_reset_clip()
648  {  {
649          XRectangle rect;          XRectangle rect;
650    
651          rect.x = 0;          rect.x = 0;
652          rect.y = 0;          rect.y = 0;
653          rect.width = wnd->width;          rect.width = width;
654          rect.height = wnd->height;          rect.height = height;
655          XSetClipRectangles(wnd->display, wnd->gc, 0, 0, &rect, 1, YXBanded);          XSetClipRectangles(display, gc, 0, 0, &rect, 1, YXBanded);
656  }  }
657    
658  static int rop2_map[] = {  void
659          GXclear,        /* 0 */  ui_bell()
         GXnor,          /* DPon */  
         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(HWINDOW wnd, uint8 rop2)  
660  {  {
661          XSetFunction(wnd->display, wnd->gc, rop2_map[rop2]);          XBell(display, 0);
662  }  }
663    
664  void ui_destblt(HWINDOW wnd, uint8 opcode,  void
665          /* dest */  int x, int y, int cx, int cy)  ui_destblt(uint8 opcode,
666               /* dest */ int x, int y, int cx, int cy)
667  {  {
668          xwin_set_function(wnd, opcode);          xwin_set_function(opcode);
669    
670          XFillRectangle(wnd->display, wnd->wnd, wnd->gc, x, y, cx, cy);          XFillRectangle(display, wnd, gc, x, y, cx, cy);
671  }  }
672    
673  void ui_patblt(HWINDOW wnd, 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 = wnd->display;          Display *dpy = display;
         GC gc = wnd->gc;  
679          Pixmap fill;          Pixmap fill;
680            uint8 i, ipattern[8];
681    
682          xwin_set_function(wnd, 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->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(wnd, 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->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(wnd, (HGLYPH)fill);                          ui_destroy_glyph((HGLYPH) fill);
705                          break;                          break;
706    
707                  default:                  default:
708                          NOTIMP("brush style %d\n", brush->style);                          NOTIMP("brush %d\n", brush->style);
709          }          }
710  }  }
711    
712  void ui_screenblt(HWINDOW wnd, 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(wnd, opcode);          xwin_set_function(opcode);
718    
719          XCopyArea(wnd->display, wnd->wnd, wnd->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(HWINDOW wnd, 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(wnd, opcode);          xwin_set_function(opcode);
728    
729          XCopyArea(wnd->display, (Pixmap)src, wnd->wnd, 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(HWINDOW wnd, 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 an efficient way of doing that 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_patblt(wnd, ROP2_XOR, x, y, cx, cy,                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
745                                          brush, bgcolour, fgcolour);                          ui_patblt(ROP2_NXOR, x, y, cx, cy,
746                          ui_memblt(wnd, ROP2_AND, x, y, cx, cy,                                    brush, bgcolour, fgcolour);
747                                          src, srcx, srcy);                          break;
748                          ui_patblt(wnd, ROP2_XOR, x, y, cx, cy,  
749                                          brush, bgcolour, fgcolour);                  case 0xb8:      /* PSDPxax */
750                            ui_patblt(ROP2_XOR, x, y, cx, cy,
751                                      brush, bgcolour, fgcolour);
752                            ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
753                            ui_patblt(ROP2_XOR, x, y, cx, cy,
754                                      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 opcode 0x%x\n", opcode);                          NOTIMP("triblt 0x%x\n", opcode);
765                          ui_memblt(wnd, 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(HWINDOW wnd, 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(wnd, opcode);          xwin_set_function(opcode);
775    
776          XSetForeground(wnd->display, wnd->gc, pen->colour);          XSetForeground(display, gc, Ctrans(pen->colour));
777          XDrawLine(wnd->display, wnd->wnd, wnd->gc, startx, starty, endx, endy);          XDrawLine(display, wnd, gc, startx, starty, endx, endy);
778  }  }
779    
780  void ui_rect(HWINDOW wnd,  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(wnd, ROP2_COPY);          xwin_set_function(ROP2_COPY);
786    
787          XSetForeground(wnd->display, wnd->gc, colour);          XSetForeground(display, gc, Ctrans(colour));
788          XFillRectangle(wnd->display, wnd->wnd, wnd->gc, x, y, cx, cy);          XFillRectangle(display, wnd, gc, x, y, cx, cy);
789  }  }
790    
791  void ui_draw_glyph(HWINDOW wnd, 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(wnd, ROP2_COPY);          xwin_set_function(ROP2_COPY);
800    
         XSetForeground(wnd->display, wnd->gc, fgcolour);  
801    
802            XSetForeground(display, gc, Ctrans(fgcolour));
803          switch (mixmode)          switch (mixmode)
804          {          {
805                  case MIX_TRANSPARENT:                  case MIX_TRANSPARENT:
806                          XSetStipple(wnd->display, wnd->gc, pixmap);                          XSetStipple(display, gc, pixmap);
807                          XSetFillStyle(wnd->display, wnd->gc, FillStippled);                          XSetFillStyle(display, gc, FillStippled);
808                          XSetTSOrigin(wnd->display, wnd->gc, x, y);                          XSetTSOrigin(display, gc, x, y);
809                          XFillRectangle(wnd->display, wnd->wnd, wnd->gc,                          XFillRectangle(display, wnd, gc, x, y, cx, cy);
810                                          x, y, cx, cy);                          XSetFillStyle(display, gc, FillSolid);
                         XSetFillStyle(wnd->display, wnd->gc, FillSolid);  
811                          break;                          break;
812    
813                  case MIX_OPAQUE:                  case MIX_OPAQUE:
814                          XSetBackground(wnd->display, wnd->gc, bgcolour);                          XSetBackground(display, gc, Ctrans(bgcolour));
815                          XCopyPlane(wnd->display, pixmap, wnd->wnd, 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:
824                          NOTIMP("mix mode %d\n", mixmode);                          NOTIMP("mix %d\n", mixmode);
825          }          }
826  }  }
827    
828  void ui_draw_text(HWINDOW wnd, 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          FONT_GLYPH *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(wnd, 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(wnd->conn, 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(wnd, 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(HWINDOW wnd, uint8 *data, 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          image = XGetImage(wnd->display, wnd->wnd, x, y, cx, cy,          xwin_set_function(ROP2_COPY);
892                                  0xffffffff, ZPixmap);  
893          memcpy(data, image->data, scanline*cy);          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);          XDestroyImage(image);
901            XFreePixmap(display, pix);
902  }  }
903    
904  void ui_desktop_restore(HWINDOW wnd, uint8 *data, 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          int scanline;          uint8 *data;
909    
910          scanline = (cx + 3) & ~3;          offset *= bpp/8;
911          image = XCreateImage(wnd->display, wnd->visual, 8, ZPixmap, 0,          data = cache_get_desktop(offset, cx, cy, bpp/8);
912                                  data, cx, cy, 32, scanline);          if (data == NULL)
913          XSetFunction(wnd->display, wnd->gc, GXcopy);                  return;
914          XPutImage(wnd->display, wnd->wnd, wnd->gc, image, 0, 0, x, y, cx, cy);          image =
915                    XCreateImage(display, visual,
916                                 depth, ZPixmap,
917                                 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);
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.9  
changed lines
  Added in v.28

  ViewVC Help
Powered by ViewVC 1.1.26