/[rdesktop]/sourceforge.net/trunk/rdesktop/xwin.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/trunk/rdesktop/xwin.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 28 by matty, Wed Jun 20 13:54:48 2001 UTC revision 42 by matthewc, Sun Apr 7 09:42:54 2002 UTC
# Line 1  Line 1 
1  /*  /*
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     User interface services - X-Windows     User interface services - X Window System
4     Copyright (C) Matthew Chapman 1999-2000     Copyright (C) Matthew Chapman 1999-2001
5        
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
# Line 21  Line 21 
21  #include <X11/Xlib.h>  #include <X11/Xlib.h>
22  #include <X11/Xutil.h>  #include <X11/Xutil.h>
23  #include <time.h>  #include <time.h>
24    #include <errno.h>
25  #include "rdesktop.h"  #include "rdesktop.h"
26    
27    extern char keymapname[16];
28    extern int keylayout;
29  extern int width;  extern int width;
30  extern int height;  extern int height;
31  extern BOOL motion;  extern BOOL sendmotion;
 extern BOOL grab_keyboard;  
32  extern BOOL fullscreen;  extern BOOL fullscreen;
 extern int private_colormap;  
33    
 static int bpp;  
 static int depth;  
34  static Display *display;  static Display *display;
35    static int x_socket;
36  static Window wnd;  static Window wnd;
37  static GC gc;  static GC gc;
38  static Visual *visual;  static Visual *visual;
39  static uint32 *colmap;  static int depth;
40    static int bpp;
 #define Ctrans(col) ( private_colormap ? col : colmap[col])  
41    
42  #define L_ENDIAN  /* endianness */
43  int screen_msbfirst = 0;  static BOOL host_be;
44    static BOOL xserver_be;
45    
46    /* software backing store */
47    static BOOL ownbackstore;
48    static Pixmap backstore;
49    
50    #define FILL_RECTANGLE(x,y,cx,cy)\
51    { \
52            XFillRectangle(display, wnd, gc, x, y, cx, cy); \
53            if (ownbackstore) \
54                    XFillRectangle(display, backstore, gc, x, y, cx, cy); \
55    }
56    
57    /* colour maps */
58    static BOOL owncolmap;
59    static Colormap xcolmap;
60    static uint32 white;
61    static uint32 *colmap;
62    
63  static uint8 *translate(int width, int height, uint8 *data);  #define TRANSLATE(col)          ( owncolmap ? col : translate_colour(colmap[col]) )
64    #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));
65    #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));
66    
67  static int rop2_map[] = {  static int rop2_map[] = {
68          GXclear,                /* 0 */          GXclear,                /* 0 */
# Line 64  static int rop2_map[] = { Line 83  static int rop2_map[] = {
83          GXset                   /* 1 */          GXset                   /* 1 */
84  };  };
85    
86    #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }
87    #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }
88    
89  static void  static void
90  xwin_set_function(uint8 rop2)  translate8(uint8 *data, uint8 *out, uint8 *end)
91  {  {
92          static uint8 last_rop2 = ROP2_COPY;          while (out < end)
93                    *(out++) = (uint8)colmap[*(data++)];
94    }
95    
96          if (last_rop2 != rop2)  static void
97    translate16(uint8 *data, uint16 *out, uint16 *end)
98    {
99            while (out < end)
100                    *(out++) = (uint16)colmap[*(data++)];
101    }
102    
103    /* little endian - conversion happens when colourmap is built */
104    static void
105    translate24(uint8 *data, uint8 *out, uint8 *end)
106    {
107            uint32 value;
108    
109            while (out < end)
110          {          {
111                  XSetFunction(display, gc, rop2_map[rop2]);                  value = colmap[*(data++)];
112                  last_rop2 = rop2;                  *(out++) = value;
113                    *(out++) = value >> 8;
114                    *(out++) = value >> 16;
115          }          }
116  }  }
117    
118  static void  static void
119  xwin_grab_keyboard()  translate32(uint8 *data, uint32 *out, uint32 *end)
120  {  {
121          XGrabKeyboard(display, wnd, True, GrabModeAsync, GrabModeAsync,          while (out < end)
122                        CurrentTime);                  *(out++) = colmap[*(data++)];
123  }  }
124    
125  static void  static uint8 *
126  xwin_ungrab_keyboard()  translate_image(int width, int height, uint8 *data)
127  {  {
128          XUngrabKeyboard(display, CurrentTime);          int size = width * height * bpp/8;
129            uint8 *out = xmalloc(size);
130            uint8 *end = out + size;
131    
132            switch (bpp)
133            {
134                    case 8:
135                            translate8(data, out, end);
136                            break;
137    
138                    case 16:
139                            translate16(data, (uint16 *)out, (uint16 *)end);
140                            break;
141    
142                    case 24:
143                            translate24(data, out, end);
144                            break;
145    
146                    case 32:
147                            translate32(data, (uint32 *)out, (uint32 *)end);
148                            break;
149            }
150    
151            return out;
152    }
153    
154    #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }
155    #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }
156    #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
157                            x = (x << 16) | (x >> 16); }
158    
159    static uint32
160    translate_colour(uint32 colour)
161    {
162            switch (bpp)
163            {
164                    case 16:
165                            if (host_be != xserver_be)
166                                    BSWAP16(colour);
167                            break;
168    
169                    case 24:
170                            if (xserver_be)
171                                    BSWAP24(colour);
172                            break;
173    
174                    case 32:
175                            if (host_be != xserver_be)
176                                    BSWAP32(colour);
177                            break;
178            }
179    
180            return colour;
181  }  }
182    
183  BOOL  BOOL
# Line 97  ui_create_window(char *title) Line 188  ui_create_window(char *title)
188          XSizeHints *sizehints;          XSizeHints *sizehints;
189          unsigned long input_mask;          unsigned long input_mask;
190          XPixmapFormatValues *pfm;          XPixmapFormatValues *pfm;
191          int count;          Screen *screen;
192            uint16 test;
193            int i;
194    
195          display = XOpenDisplay(NULL);          display = XOpenDisplay(NULL);
196          if (display == NULL)          if (display == NULL)
197          {          {
198                  ERROR("Failed to open display\n");                  error("Failed to open display\n");
199                  return False;                  return False;
200          }          }
201    
202          visual = DefaultVisual(display, DefaultScreen(display));          x_socket = ConnectionNumber(display);
203          depth = DefaultDepth(display, DefaultScreen(display));          screen = DefaultScreenOfDisplay(display);
204          pfm = XListPixmapFormats(display, &count);          visual = DefaultVisualOfScreen(screen);
205            depth = DefaultDepthOfScreen(screen);
206    
207            pfm = XListPixmapFormats(display, &i);
208          if (pfm != NULL)          if (pfm != NULL)
209          {          {
210                  while (count--)                  /* Use maximum bpp for this depth - this is generally
211                       desirable, e.g. 24 bits->32 bits. */
212                    while (i--)
213                  {                  {
214                          if ((pfm + count)->depth == depth                          if ((pfm[i].depth == depth)
215                              && (pfm + count)->bits_per_pixel > bpp)                              && (pfm[i].bits_per_pixel > bpp))
216                          {                          {
217                                  bpp = (pfm + count)->bits_per_pixel;                                  bpp = pfm[i].bits_per_pixel;
218                          }                          }
219                  }                  }
220                  XFree(pfm);                  XFree(pfm);
# Line 124  ui_create_window(char *title) Line 222  ui_create_window(char *title)
222    
223          if (bpp < 8)          if (bpp < 8)
224          {          {
225                  ERROR("Less than 8 bpp not currently supported.\n");                  error("Less than 8 bpp not currently supported.\n");
226                  XCloseDisplay(display);                  XCloseDisplay(display);
227                  return False;                  return False;
228          }          }
229    
230          width &= ~3; /* make width nicely divisible */          if (depth <= 8)
231                    owncolmap = True;
232            else
233                    xcolmap = DefaultColormapOfScreen(screen);
234    
235            test = 1;
236            host_be = !(BOOL)(*(uint8 *)(&test));
237            xserver_be = (ImageByteOrder(display) == MSBFirst);
238    
239            white = WhitePixelOfScreen(screen);
240            attribs.background_pixel = BlackPixelOfScreen(screen);
241            attribs.backing_store = DoesBackingStore(screen);
242    
243          attribs.background_pixel = BlackPixel(display, DefaultScreen(display));          if (attribs.backing_store == NotUseful)
244          attribs.backing_store = Always;                  ownbackstore = True;
245    
246          if (fullscreen)          if (fullscreen)
247          {          {
248                  attribs.override_redirect = True;                  attribs.override_redirect = True;
249                  width = WidthOfScreen(DefaultScreenOfDisplay(display));                  width = WidthOfScreen(screen);
250                  height = HeightOfScreen(DefaultScreenOfDisplay(display));                  height = HeightOfScreen(screen);
                 XSetInputFocus(display, PointerRoot, RevertToPointerRoot,  
                                CurrentTime);  
251          }          }
252          else          else
253          {          {
254                  attribs.override_redirect = False;                  attribs.override_redirect = False;
255          }          }
256    
257          wnd = XCreateWindow(display, DefaultRootWindow(display),          width = (width + 3) & ~3; /* make width a multiple of 32 bits */
258    
259            wnd = XCreateWindow(display, RootWindowOfScreen(screen),
260                              0, 0, width, height, 0, CopyFromParent,                              0, 0, width, height, 0, CopyFromParent,
261                              InputOutput, CopyFromParent,                              InputOutput, CopyFromParent,
262                              CWBackingStore | CWBackPixel | CWOverrideRedirect,                              CWBackingStore | CWBackPixel | CWOverrideRedirect,
# Line 157  ui_create_window(char *title) Line 266  ui_create_window(char *title)
266    
267          classhints = XAllocClassHint();          classhints = XAllocClassHint();
268          if (classhints != NULL)          if (classhints != NULL)
   
269          {          {
270                  classhints->res_name = "rdesktop";                  classhints->res_name = classhints->res_class = "rdesktop";
                 classhints->res_class = "rdesktop";  
271                  XSetClassHint(display, wnd, classhints);                  XSetClassHint(display, wnd, classhints);
272                  XFree(classhints);                  XFree(classhints);
273          }          }
# Line 168  ui_create_window(char *title) Line 275  ui_create_window(char *title)
275          sizehints = XAllocSizeHints();          sizehints = XAllocSizeHints();
276          if (sizehints)          if (sizehints)
277          {          {
278                  sizehints->flags =                  sizehints->flags = PMinSize | PMaxSize;
279                          PPosition | PSize | PMinSize | PMaxSize | PBaseSize;                  sizehints->min_width = sizehints->max_width = width;
280                  sizehints->min_width = width;                  sizehints->min_height = sizehints->max_height = height;
                 sizehints->max_width = width;  
                 sizehints->min_height = height;  
                 sizehints->max_height = height;  
                 sizehints->base_width = width;  
                 sizehints->base_height = height;  
281                  XSetWMNormalHints(display, wnd, sizehints);                  XSetWMNormalHints(display, wnd, sizehints);
282                  XFree(sizehints);                  XFree(sizehints);
283          }          }
284    
285          input_mask = KeyPressMask | KeyReleaseMask;          xkeymap_init(display);
286          input_mask |= ButtonPressMask | ButtonReleaseMask;  
287          if (motion)          input_mask = KeyPressMask | KeyReleaseMask
288                            | ButtonPressMask | ButtonReleaseMask
289                            | EnterWindowMask | LeaveWindowMask;
290    
291            if (sendmotion)
292                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
293          if (grab_keyboard)  
294                  input_mask |= EnterWindowMask | LeaveWindowMask;          if (ownbackstore)
295                    input_mask |= ExposureMask;
296    
297          XSelectInput(display, wnd, input_mask);          XSelectInput(display, wnd, input_mask);
298          gc = XCreateGC(display, wnd, 0, NULL);          gc = XCreateGC(display, wnd, 0, NULL);
299    
300            if (ownbackstore)
301                    backstore = XCreatePixmap(display, wnd, width, height, depth);
302    
303          XMapWindow(display, wnd);          XMapWindow(display, wnd);
304          return True;          return True;
305  }  }
# Line 197  ui_create_window(char *title) Line 307  ui_create_window(char *title)
307  void  void
308  ui_destroy_window()  ui_destroy_window()
309  {  {
310            if (ownbackstore)
311                    XFreePixmap(display, backstore);
312    
313          XFreeGC(display, gc);          XFreeGC(display, gc);
314          XDestroyWindow(display, wnd);          XDestroyWindow(display, wnd);
315          XCloseDisplay(display);          XCloseDisplay(display);
316          display = NULL;          display = NULL;
317  }  }
318    
319  static uint8  static void
320  xwin_translate_key(unsigned long key)  xwin_process_events()
 {  
         DEBUG("KEY(code=0x%lx)\n", key);  
   
         if ((key > 8) && (key <= 0x60))  
                 return (key - 8);  
   
         switch (key)  
         {  
                 case 0x61:      /* home */  
                         return 0x47 | 0x80;  
                 case 0x62:      /* up arrow */  
                         return 0x48 | 0x80;  
                 case 0x63:      /* page up */  
                         return 0x49 | 0x80;  
                 case 0x64:      /* left arrow */  
                         return 0x4b | 0x80;  
                 case 0x66:      /* right arrow */  
                         return 0x4d | 0x80;  
                 case 0x67:      /* end */  
                         return 0x4f | 0x80;  
                 case 0x68:      /* down arrow */  
                         return 0x50 | 0x80;  
                 case 0x69:      /* page down */  
                         return 0x51 | 0x80;  
                 case 0x6a:      /* insert */  
                         return 0x52 | 0x80;  
                 case 0x6b:      /* delete */  
                         return 0x53 | 0x80;  
                 case 0x6c:      /* keypad enter */  
                         return 0x1c | 0x80;  
                 case 0x6d:      /* right ctrl */  
                         return 0x1d | 0x80;  
                 case 0x6f:      /* ctrl - print screen */  
                         return 0x37 | 0x80;  
                 case 0x70:      /* keypad '/' */  
                         return 0x35 | 0x80;  
                 case 0x71:      /* right alt */  
                         return 0x38 | 0x80;  
                 case 0x72:      /* ctrl break */  
                         return 0x46 | 0x80;  
                 case 0x73:      /* left window key */  
                         return 0xff;    /* real scancode is 5b */  
                 case 0x74:      /* right window key */  
                         return 0xff;    /* real scancode is 5c */  
                 case 0x75:      /* menu key */  
                         return 0x5d | 0x80;  
         }  
   
         return 0;  
 }  
   
 static uint16  
 xwin_translate_mouse(unsigned long button)  
 {  
         switch (button)  
         {  
                 case Button1:   /* left */  
                         return MOUSE_FLAG_BUTTON1;  
                 case Button2:   /* middle */  
                         return MOUSE_FLAG_BUTTON3;  
                 case Button3:   /* right */  
                         return MOUSE_FLAG_BUTTON2;  
         }  
   
         return 0;  
 }  
   
 void  
 ui_process_events()  
321  {  {
322          XEvent event;          XEvent event;
323            KeySym keysym;
324          uint8 scancode;          uint8 scancode;
325          uint16 button;          uint16 button;
326          uint32 ev_time;          uint32 ev_time;
# Line 283  ui_process_events() Line 328  ui_process_events()
328          if (display == NULL)          if (display == NULL)
329                  return;                  return;
330    
331          while (XCheckWindowEvent(display, wnd, ~0, &event))          while (XCheckMaskEvent(display, ~0, &event))
332          {          {
333                  ev_time = time(NULL);                  ev_time = time(NULL);
334    
335                  switch (event.type)                  switch (event.type)
336                  {                  {
337                          case KeyPress:                          case KeyPress:
338                                  scancode = xwin_translate_key(event.xkey.keycode);                                  keysym = XKeycodeToKeysym(display, event.xkey.keycode, 0);
339                                    scancode = xkeymap_translate_key(keysym, event.xkey.keycode);
340                                  if (scancode == 0)                                  if (scancode == 0)
341                                          break;                                          break;
342    
# Line 299  ui_process_events() Line 345  ui_process_events()
345                                  break;                                  break;
346    
347                          case KeyRelease:                          case KeyRelease:
348                                  scancode = xwin_translate_key(event.xkey.keycode);                                  keysym = XKeycodeToKeysym(display, event.xkey.keycode, 0);
349                                    scancode = xkeymap_translate_key(keysym, event.xkey.keycode);
350                                  if (scancode == 0)                                  if (scancode == 0)
351                                          break;                                          break;
352    
# Line 309  ui_process_events() Line 356  ui_process_events()
356                                  break;                                  break;
357    
358                          case ButtonPress:                          case ButtonPress:
359                                  button = xwin_translate_mouse(event.xbutton.button);                                  button = xkeymap_translate_button(event.xbutton.button);
360                                  if (button == 0)                                  if (button == 0)
361                                          break;                                          break;
362    
# Line 320  ui_process_events() Line 367  ui_process_events()
367                                  break;                                  break;
368    
369                          case ButtonRelease:                          case ButtonRelease:
370                                  button = xwin_translate_mouse(event.xbutton.button);                                  button = xkeymap_translate_button(event.xbutton.button);
371                                  if (button == 0)                                  if (button == 0)
372                                          break;                                          break;
373    
# Line 338  ui_process_events() Line 385  ui_process_events()
385                                  break;                                  break;
386    
387                          case EnterNotify:                          case EnterNotify:
388                                  if (grab_keyboard)                                  XGrabKeyboard(display, wnd, True, GrabModeAsync,
389                                          xwin_grab_keyboard();                                                GrabModeAsync, CurrentTime);
390                                  break;                                  break;
391    
392                          case LeaveNotify:                          case LeaveNotify:
393                                  if (grab_keyboard)                                  XUngrabKeyboard(display, CurrentTime);
394                                          xwin_ungrab_keyboard();                                  break;
395    
396                            case Expose:
397                                    XCopyArea(display, backstore, wnd, gc,
398                                              event.xexpose.x, event.xexpose.y,
399                                              event.xexpose.width, event.xexpose.height,
400                                              event.xexpose.x, event.xexpose.y);
401                                  break;                                  break;
402                  }                  }
403          }          }
404  }  }
405    
406  void  void
407    ui_select(int rdp_socket)
408    {
409            int n = (rdp_socket > x_socket) ? rdp_socket+1 : x_socket+1;
410            fd_set rfds;
411    
412            XFlush(display);
413    
414            FD_ZERO(&rfds);
415    
416            while (True)
417            {
418                    FD_ZERO(&rfds);
419                    FD_SET(rdp_socket, &rfds);
420                    FD_SET(x_socket, &rfds);
421    
422                    switch (select(n, &rfds, NULL, NULL, NULL))
423                    {
424                            case -1:
425                                    error("select: %s\n", strerror(errno));
426    
427                            case 0:
428                                    continue;
429                    }
430    
431                    if (FD_ISSET(x_socket, &rfds))
432                            xwin_process_events();
433    
434                    if (FD_ISSET(rdp_socket, &rfds))
435                            return;
436            }
437    }
438    
439    void
440  ui_move_pointer(int x, int y)  ui_move_pointer(int x, int y)
441  {  {
442          XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);          XWarpPointer(display, wnd, wnd, 0, 0, 0, 0, x, y);
# Line 362  ui_create_bitmap(int width, int height, Line 448  ui_create_bitmap(int width, int height,
448          XImage *image;          XImage *image;
449          Pixmap bitmap;          Pixmap bitmap;
450          uint8 *tdata;          uint8 *tdata;
451          tdata = (private_colormap ? data : translate(width, height, data));  
452            tdata = (owncolmap ? data : translate_image(width, height, data));
453          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(display, wnd, width, height, depth);
454          image =          image = XCreateImage(display, visual, depth, ZPixmap,
455                  XCreateImage(display, visual,                               0, tdata, width, height, 8, 0);
                              depth, ZPixmap,  
                              0, tdata, width, height, BitmapPad(display), 0);  
456    
         xwin_set_function(ROP2_COPY);  
457          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
458    
459          XFree(image);          XFree(image);
460          if (!private_colormap)          if (!owncolmap)
461                  xfree(tdata);                  xfree(tdata);
462          return (HBITMAP) bitmap;          return (HBITMAP) bitmap;
463  }  }
# Line 383  ui_paint_bitmap(int x, int y, int cx, in Line 467  ui_paint_bitmap(int x, int y, int cx, in
467                  int width, int height, uint8 *data)                  int width, int height, uint8 *data)
468  {  {
469          XImage *image;          XImage *image;
470          uint8 *tdata =          uint8 *tdata;
                 (private_colormap ? data : translate(width, height, data));  
         image =  
                 XCreateImage(display, visual, depth, ZPixmap, 0, tdata, width,  
                              height, BitmapPad(display), 0);  
   
         xwin_set_function(ROP2_COPY);  
   
         /* Window */  
         XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);  
         XFree(image);  
         if (!private_colormap)  
                 xfree(tdata);  
 }  
   
 void  
 ui_destroy_bitmap(HBITMAP bmp)  
 {  
         XFreePixmap(display, (Pixmap) bmp);  
 }  
471    
472  HCURSOR          tdata = (owncolmap ? data : translate_image(width, height, data));
473  ui_create_cursor(unsigned int x, unsigned int y, int width,          image = XCreateImage(display, visual, depth, ZPixmap,
474                   int height, uint8 *mask, uint8 *data)                               0, tdata, width, height, 8, 0);
 {  
         XImage *imagecursor;  
         XImage *imagemask;  
         Pixmap maskbitmap, cursorbitmap;  
         Cursor cursor;  
         XColor bg, fg;  
         GC lgc;  
         int i, x1, y1, scanlinelen;  
         uint8 *cdata, *cmask;  
         uint8 c;  
         cdata = (uint8 *) malloc(sizeof(uint8) * width * height);  
         if (!cdata)  
                 return NULL;  
         scanlinelen = (width + 7) >> 3;  
         cmask = (uint8 *) malloc(sizeof(uint8) * scanlinelen * height);  
         if (!cmask)  
         {  
                 free(cdata);  
                 return NULL;  
         }  
         i = (height - 1) * scanlinelen;  
475    
476          if (!screen_msbfirst)          if (ownbackstore)
477          {          {
478                  while (i >= 0)                  XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
479                  {                  XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
                         for (x1 = 0; x1 < scanlinelen; x1++)  
                         {  
                                 c = *(mask++);  
                                 cmask[i + x1] =  
                                         ((c & 0x1) << 7) | ((c & 0x2) << 5) |  
                                         ((c & 0x4) << 3) | ((c & 0x8) << 1) |  
                                         ((c & 0x10) >> 1) | ((c & 0x20) >> 3)  
                                         | ((c & 0x40) >> 5) | ((c & 0x80) >>  
                                                                7);  
                         }  
                         i -= scanlinelen;  
                 }  
480          }          }
481          else          else
482          {          {
483                  while (i >= 0)                  XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
                 {  
                         for (x1 = 0; x1 < scanlinelen; x1++)  
                         {  
                                 cmask[i + x1] = *(mask++);  
                         }  
                         i -= scanlinelen;  
                 }  
484          }          }
485    
486            XFree(image);
487          fg.red = 0;          if (!owncolmap)
488          fg.blue = 0;                  xfree(tdata);
         fg.green = 0;  
         fg.flags = DoRed | DoBlue | DoGreen;  
         bg.red = 65535;  
         bg.blue = 65535;  
         bg.green = 65535;  
         bg.flags = DoRed | DoBlue | DoGreen;  
         maskbitmap = XCreatePixmap(display, wnd, width, height, 1);  
         cursorbitmap = XCreatePixmap(display, wnd, width, height, 1);  
         lgc = XCreateGC(display, maskbitmap, 0, NULL);  
         XSetFunction(display, lgc, GXcopy);  
         imagemask =  
                 XCreateImage(display, visual, 1, XYBitmap, 0, cmask, width,  
                              height, 8, 0);  
         imagecursor =  
                 XCreateImage(display, visual, 1, XYBitmap, 0, cdata, width,  
                              height, 8, 0);  
         for (y1 = height - 1; y1 >= 0; y1--)  
                 for (x1 = 0; x1 < width; x1++)  
                 {  
                         if (data[0] >= 0x80 || data[1] >= 0x80  
                             || data[2] >= 0x80)  
                                 if (XGetPixel(imagemask, x1, y1))  
   
                                 {  
                                         XPutPixel(imagecursor, x1, y1, 0);  
                                         XPutPixel(imagemask, x1, y1, 0);        /* mask is blank for text cursor! */  
                                 }  
   
                                 else  
                                         XPutPixel(imagecursor, x1, y1, 1);  
   
                         else  
                                 XPutPixel(imagecursor, x1, y1,  
                                           XGetPixel(imagemask, x1, y1));  
                         data += 3;  
                 }  
         XPutImage(display, maskbitmap, lgc, imagemask, 0, 0, 0, 0, width,  
                   height);  
         XPutImage(display, cursorbitmap, lgc, imagecursor, 0, 0, 0, 0, width,  
                   height); XFree(imagemask);  
         XFree(imagecursor);  
         free(cmask);  
         free(cdata);  
         XFreeGC(display, lgc);  
         cursor =  
                 XCreatePixmapCursor(display, cursorbitmap, maskbitmap, &fg,  
                                     &bg, x, y);  
         XFreePixmap(display, maskbitmap);  
         XFreePixmap(display, cursorbitmap);  
         return (HCURSOR) cursor;  
 }  
   
 void  
 ui_set_cursor(HCURSOR cursor)  
 {  
         XDefineCursor(display, wnd, (Cursor) cursor);  
489  }  }
490    
491  void  void
492  ui_destroy_cursor(HCURSOR cursor)  ui_destroy_bitmap(HBITMAP bmp)
493  {  {
494          XFreeCursor(display, (Cursor) cursor);          XFreePixmap(display, (Pixmap)bmp);
495  }  }
496    
497  HGLYPH  HGLYPH
# Line 544  ui_create_glyph(int width, int height, u Line 513  ui_create_glyph(int width, int height, u
513          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
514          XInitImage(image);          XInitImage(image);
515    
         XSetFunction(display, gc, GXcopy);  
516          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
517    
518          XFree(image);          XFree(image);
519          XFreeGC(display, gc);          XFreeGC(display, gc);
520            return (HGLYPH)bitmap;
         return (HGLYPH) bitmap;  
521  }  }
522    
523  void  void
524  ui_destroy_glyph(HGLYPH glyph)  ui_destroy_glyph(HGLYPH glyph)
525  {  {
526          XFreePixmap(display, (Pixmap) glyph);          XFreePixmap(display, (Pixmap)glyph);
527  }  }
528    
529  HCOLOURMAP  HCURSOR
530  ui_create_colourmap(COLOURMAP *colours)  ui_create_cursor(unsigned int x, unsigned int y, int width,
531                     int height, uint8 *andmask, uint8 *xormask)
532  {  {
533          if (!private_colormap)          HGLYPH maskglyph, cursorglyph;
534            XColor bg, fg;
535            Cursor xcursor;
536            uint8 *cursor, *pcursor;
537            uint8 *mask, *pmask;
538            uint8 nextbit;
539            int scanline, offset;
540            int i, j;
541    
542            scanline = (width + 7) / 8;
543            offset = scanline * height;
544    
545            cursor = xmalloc(offset);
546            memset(cursor, 0, offset);
547    
548            mask = xmalloc(offset);
549            memset(mask, 0, offset);
550    
551            /* approximate AND and XOR masks with a monochrome X pointer */
552            for (i = 0; i < height; i++)
553          {          {
554                  COLOURENTRY *entry;                  offset -= scanline;
555                  int i, ncolours = colours->ncolours;                  pcursor = &cursor[offset];
556                  uint32 *nc = xmalloc(sizeof(*colmap) * ncolours);                  pmask = &mask[offset];
557                  for (i = 0; i < ncolours; i++)  
558                    for (j = 0; j < scanline; j++)
559                  {                  {
560                          XColor xc;                          for (nextbit = 0x80; nextbit != 0; nextbit >>= 1)
561                          entry = &colours->colours[i];                          {
562                          xc.red = entry->red << 8;                                  if (xormask[0] || xormask[1] || xormask[2])
563                          xc.green = entry->green << 8;                                  {
564                          xc.blue = entry->blue << 8;                                          *pcursor |= (~(*andmask) & nextbit);
565                          XAllocColor(display,                                          *pmask |= nextbit;
566                                      DefaultColormap(display,                                  }
567                                                      DefaultScreen(display)),                                  else
568                                      &xc);                                  {
569                          /* XXX Check return value */                                          *pcursor |= ((*andmask) & nextbit);
570                          nc[i] = xc.pixel;                                          *pmask |= (~(*andmask) & nextbit);
571                                    }
572    
573                                    xormask += 3;
574                            }
575    
576                            andmask++;
577                            pcursor++;
578                            pmask++;
579                  }                  }
                 return nc;  
580          }          }
581          else  
582            fg.red = fg.blue = fg.green = 0xffff;
583            bg.red = bg.blue = bg.green = 0x0000;
584            fg.flags = bg.flags = DoRed | DoBlue | DoGreen;
585    
586            cursorglyph = ui_create_glyph(width, height, cursor);
587            maskglyph = ui_create_glyph(width, height, mask);
588            
589            xcursor = XCreatePixmapCursor(display, (Pixmap)cursorglyph,
590                                    (Pixmap)maskglyph, &fg, &bg, x, y);
591    
592            ui_destroy_glyph(maskglyph);
593            ui_destroy_glyph(cursorglyph);
594            xfree(mask);
595            xfree(cursor);
596            return (HCURSOR)xcursor;
597    }
598    
599    void
600    ui_set_cursor(HCURSOR cursor)
601    {
602            XDefineCursor(display, wnd, (Cursor)cursor);
603    }
604    
605    void
606    ui_destroy_cursor(HCURSOR cursor)
607    {
608            XFreeCursor(display, (Cursor)cursor);
609    }
610    
611    #define MAKE_XCOLOR(xc,c) \
612                    (xc)->red   = ((c)->red   << 8) | (c)->red; \
613                    (xc)->green = ((c)->green << 8) | (c)->green; \
614                    (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \
615                    (xc)->flags = DoRed | DoGreen | DoBlue;
616    
617    HCOLOURMAP
618    ui_create_colourmap(COLOURMAP *colours)
619    {
620            COLOURENTRY *entry;
621            int i, ncolours = colours->ncolours;
622    
623            if (owncolmap)
624          {          {
                 COLOURENTRY *entry;  
625                  XColor *xcolours, *xentry;                  XColor *xcolours, *xentry;
626                  Colormap map;                  Colormap map;
627                  int i, ncolours = colours->ncolours;  
628                  xcolours = xmalloc(sizeof(XColor) * ncolours);                  xcolours = xmalloc(sizeof(XColor) * ncolours);
629                  for (i = 0; i < ncolours; i++)                  for (i = 0; i < ncolours; i++)
630                  {                  {
631                          entry = &colours->colours[i];                          entry = &colours->colours[i];
632                          xentry = &xcolours[i];                          xentry = &xcolours[i];
   
633                          xentry->pixel = i;                          xentry->pixel = i;
634                          xentry->red = entry->red << 8;                          MAKE_XCOLOR(xentry, entry);
                         xentry->blue = entry->blue << 8;  
                         xentry->green = entry->green << 8;  
                         xentry->flags = DoRed | DoBlue | DoGreen;  
635                  }                  }
636    
637                  map = XCreateColormap(display, wnd, visual, AllocAll);                  map = XCreateColormap(display, wnd, visual, AllocAll);
638                  XStoreColors(display, map, xcolours, ncolours);                  XStoreColors(display, map, xcolours, ncolours);
639    
640                  xfree(xcolours);                  xfree(xcolours);
641                  return (HCOLOURMAP) map;                  return (HCOLOURMAP)map;
642            }
643            else
644            {
645                    uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
646                    XColor xentry;
647                    uint32 colour;
648    
649                    for (i = 0; i < ncolours; i++)
650                    {
651                            entry = &colours->colours[i];
652                            MAKE_XCOLOR(&xentry, entry);
653    
654                            if (XAllocColor(display, xcolmap, &xentry) != 0)
655                                    colour = xentry.pixel;
656                            else
657                                    colour = white;
658    
659                            /* byte swap here to make translate_image faster */
660                            map[i] = translate_colour(colour);
661                    }
662    
663                    return map;
664          }          }
665  }  }
666    
667  void  void
668  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
669  {  {
670          XFreeColormap(display, (Colormap) map);          if (owncolmap)
671                    XFreeColormap(display, (Colormap)map);
672            else
673                    xfree(map);
674  }  }
675    
676  void  void
677  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
678  {  {
679            if (owncolmap)
680          /* XXX, change values of all pixels on the screen if the new colmap                  XSetWindowColormap(display, wnd, (Colormap)map);
          * doesn't have the same values as the old one? */  
         if (!private_colormap)  
                 colmap = map;  
681          else          else
682          {                  colmap = map;
                 XSetWindowColormap(display, wnd, (Colormap) map);  
                 if (fullscreen)  
                         XInstallColormap(display, (Colormap) map);  
         }  
683  }  }
684    
685  void  void
# Line 665  void Line 716  void
716  ui_destblt(uint8 opcode,  ui_destblt(uint8 opcode,
717             /* dest */ int x, int y, int cx, int cy)             /* dest */ int x, int y, int cx, int cy)
718  {  {
719          xwin_set_function(opcode);          SET_FUNCTION(opcode);
720            FILL_RECTANGLE(x, y, cx, cy);
721          XFillRectangle(display, wnd, gc, x, y, cx, cy);          RESET_FUNCTION(opcode);
722  }  }
723    
724  void  void
# Line 675  ui_patblt(uint8 opcode, Line 726  ui_patblt(uint8 opcode,
726            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
727            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)
728  {  {
         Display *dpy = display;  
729          Pixmap fill;          Pixmap fill;
         uint8 i, ipattern[8];  
730    
731          xwin_set_function(opcode);          SET_FUNCTION(opcode);
732    
733          switch (brush->style)          switch (brush->style)
734          {          {
735                  case 0: /* Solid */                  case 0: /* Solid */
736                          XSetForeground(dpy, gc, Ctrans(fgcolour));                          SET_FOREGROUND(fgcolour);
737                          XFillRectangle(dpy, wnd, gc, x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
738                          break;                          break;
739    
740                  case 3: /* Pattern */                  case 3: /* Pattern */
741                          for (i = 0; i != 8; i++)                          fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);
                                 ipattern[i] = ~brush->pattern[i];  
                         fill = (Pixmap) ui_create_glyph(8, 8, ipattern);  
   
                         XSetForeground(dpy, gc, Ctrans(fgcolour));  
                         XSetBackground(dpy, gc, Ctrans(bgcolour));  
                         XSetFillStyle(dpy, gc, FillOpaqueStippled);  
                         XSetStipple(dpy, gc, fill);  
742    
743                          XFillRectangle(dpy, wnd, gc, x, y, cx, cy);                          SET_FOREGROUND(bgcolour);
744                            SET_BACKGROUND(fgcolour);
745                            XSetFillStyle(display, gc, FillOpaqueStippled);
746                            XSetStipple(display, gc, fill);
747                            XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);
748    
749                            FILL_RECTANGLE(x, y, cx, cy);
750    
751                          XSetFillStyle(dpy, gc, FillSolid);                          XSetFillStyle(display, gc, FillSolid);
752                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((HGLYPH)fill);
753                          break;                          break;
754    
755                  default:                  default:
756                          NOTIMP("brush %d\n", brush->style);                          unimpl("brush %d\n", brush->style);
757          }          }
758    
759            RESET_FUNCTION(opcode);
760  }  }
761    
762  void  void
# Line 714  ui_screenblt(uint8 opcode, Line 764  ui_screenblt(uint8 opcode,
764               /* dest */ int x, int y, int cx, int cy,               /* dest */ int x, int y, int cx, int cy,
765               /* src */ int srcx, int srcy)               /* src */ int srcx, int srcy)
766  {  {
767          xwin_set_function(opcode);          SET_FUNCTION(opcode);
   
768          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
769            if (ownbackstore)
770                    XCopyArea(display, backstore, backstore, gc, srcx, srcy,
771                              cx, cy, x, y);
772            RESET_FUNCTION(opcode);
773  }  }
774    
775  void  void
# Line 724  ui_memblt(uint8 opcode, Line 777  ui_memblt(uint8 opcode,
777            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
778            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ HBITMAP src, int srcx, int srcy)
779  {  {
780          xwin_set_function(opcode);          SET_FUNCTION(opcode);
781            XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);
782          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);          if (ownbackstore)
783                    XCopyArea(display, (Pixmap)src, backstore, gc, srcx, srcy,
784                              cx, cy, x, y);
785            RESET_FUNCTION(opcode);
786  }  }
787    
788  void  void
# Line 754  ui_triblt(uint8 opcode, Line 810  ui_triblt(uint8 opcode,
810                                    brush, bgcolour, fgcolour);                                    brush, bgcolour, fgcolour);
811                          break;                          break;
812    
813                  case 0xc0:                  case 0xc0:      /* PSa */
814                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
815                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,
816                                    fgcolour);                                    fgcolour);
817                          break;                          break;
818    
819                  default:                  default:
820                          NOTIMP("triblt 0x%x\n", opcode);                          unimpl("triblt 0x%x\n", opcode);
821                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
822          }          }
823  }  }
# Line 771  ui_line(uint8 opcode, Line 827  ui_line(uint8 opcode,
827          /* dest */ int startx, int starty, int endx, int endy,          /* dest */ int startx, int starty, int endx, int endy,
828          /* pen */ PEN *pen)          /* pen */ PEN *pen)
829  {  {
830          xwin_set_function(opcode);          SET_FUNCTION(opcode);
831            SET_FOREGROUND(pen->colour);
         XSetForeground(display, gc, Ctrans(pen->colour));  
832          XDrawLine(display, wnd, gc, startx, starty, endx, endy);          XDrawLine(display, wnd, gc, startx, starty, endx, endy);
833            if (ownbackstore)
834                    XDrawLine(display, backstore, gc, startx, starty, endx, endy);
835            RESET_FUNCTION(opcode);
836  }  }
837    
838  void  void
# Line 782  ui_rect( Line 840  ui_rect(
840                 /* dest */ int x, int y, int cx, int cy,                 /* dest */ int x, int y, int cx, int cy,
841                 /* brush */ int colour)                 /* brush */ int colour)
842  {  {
843          xwin_set_function(ROP2_COPY);          SET_FOREGROUND(colour);
844            FILL_RECTANGLE(x, y, cx, cy);
         XSetForeground(display, gc, Ctrans(colour));  
         XFillRectangle(display, wnd, gc, x, y, cx, cy);  
845  }  }
846    
847  void  void
# Line 794  ui_draw_glyph(int mixmode, Line 850  ui_draw_glyph(int mixmode,
850                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,
851                int fgcolour)                int fgcolour)
852  {  {
853          Pixmap pixmap = (Pixmap) glyph;          SET_FOREGROUND(fgcolour);
854            SET_BACKGROUND(bgcolour);
         xwin_set_function(ROP2_COPY);  
855    
856            XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)
857                          ? FillStippled : FillOpaqueStippled);
858            XSetStipple(display, gc, (Pixmap)glyph);
859            XSetTSOrigin(display, gc, x, y);
860    
861          XSetForeground(display, gc, Ctrans(fgcolour));          FILL_RECTANGLE(x, y, cx, cy);
         switch (mixmode)  
         {  
                 case MIX_TRANSPARENT:  
                         XSetStipple(display, gc, pixmap);  
                         XSetFillStyle(display, gc, FillStippled);  
                         XSetTSOrigin(display, gc, x, y);  
                         XFillRectangle(display, wnd, gc, x, y, cx, cy);  
                         XSetFillStyle(display, gc, FillSolid);  
                         break;  
   
                 case MIX_OPAQUE:  
                         XSetBackground(display, gc, Ctrans(bgcolour));  
 /*      XCopyPlane (display, pixmap, back_pixmap, back_gc, srcx, srcy, cx, cy, x, y, 1); */  
                         XSetStipple(display, gc, pixmap);  
                         XSetFillStyle(display, gc, FillOpaqueStippled);  
                         XSetTSOrigin(display, gc, x, y);  
                         XFillRectangle(display, wnd, gc, x, y, cx, cy);  
                         XSetFillStyle(display, gc, FillSolid);  
                         break;  
862    
863                  default:          XSetFillStyle(display, gc, FillSolid);
                         NOTIMP("mix %d\n", mixmode);  
         }  
864  }  }
865    
866  void  void
# Line 832  ui_draw_text(uint8 font, uint8 flags, in Line 870  ui_draw_text(uint8 font, uint8 flags, in
870               int bgcolour, int fgcolour, uint8 *text, uint8 length)               int bgcolour, int fgcolour, uint8 *text, uint8 length)
871  {  {
872          FONTGLYPH *glyph;          FONTGLYPH *glyph;
873          int i, xyoffset;          int i, offset;
874    
875          xwin_set_function(ROP2_COPY);          SET_FOREGROUND(bgcolour);
         XSetForeground(display, gc, Ctrans(bgcolour));  
876    
877          if (boxcx > 1)          if (boxcx > 1)
878                  XFillRectangle(display, wnd, gc, boxx, boxy, boxcx, boxcy);          {
879                    FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);
880            }
881          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
882                  XFillRectangle(display, wnd, gc, clipx, clipy, clipcx, clipcy);          {
883                    FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);
884            }
885    
886          /* Paint text, character by character */          /* Paint text, character by character */
887          for (i = 0; i < length; i++)          for (i = 0; i < length; i++)
# Line 848  ui_draw_text(uint8 font, uint8 flags, in Line 889  ui_draw_text(uint8 font, uint8 flags, in
889                  glyph = cache_get_font(font, text[i]);                  glyph = cache_get_font(font, text[i]);
890    
891                  if (!(flags & TEXT2_IMPLICIT_X))                  if (!(flags & TEXT2_IMPLICIT_X))
   
892                  {                  {
893                          xyoffset = text[++i];                          offset = text[++i];
894                          if ((xyoffset & 0x80))                          if (offset & 0x80)
895                          {                                  offset = ((offset & 0x7f) << 8) | text[++i];
                                 if (flags & 0x04)       /* vertical text */  
                                         y += text[++i] | (text[++i] << 8);  
                                 else  
                                         x += text[++i] | (text[++i] << 8);  
                         }  
                         else  
                         {  
                                 if (flags & 0x04)       /* vertical text */  
                                         y += xyoffset;  
                                 else  
                                         x += xyoffset;  
                         }  
896    
897                            if (flags & TEXT2_VERTICAL)
898                                    y += offset;
899                            else
900                                    x += offset;
901                  }                  }
902    
903                  if (glyph != NULL)                  if (glyph != NULL)
904                  {                  {
905                          ui_draw_glyph(mixmode, x + (short) glyph->offset,                          ui_draw_glyph(mixmode, x + (short) glyph->offset,
# Line 887  ui_desktop_save(uint32 offset, int x, in Line 920  ui_desktop_save(uint32 offset, int x, in
920          Pixmap pix;          Pixmap pix;
921          XImage *image;          XImage *image;
922    
923          pix = XCreatePixmap(display, wnd, cx, cy, depth);          if (ownbackstore)
924          xwin_set_function(ROP2_COPY);          {
925                    image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,
926          XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);                                    ZPixmap);
927          image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);          }
928            else
929            {
930                    pix = XCreatePixmap(display, wnd, cx, cy, depth);
931                    XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
932                    image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,
933                                      ZPixmap);
934                    XFreePixmap(display, pix);
935            }
936    
937          offset *= bpp/8;          offset *= bpp/8;
938          cache_put_desktop(offset, cx, cy, image->bytes_per_line,          cache_put_desktop(offset, cx, cy, image->bytes_per_line,
939                            bpp/8, image->data);                            bpp/8, (uint8 *)image->data);
940    
941          XDestroyImage(image);          XDestroyImage(image);
         XFreePixmap(display, pix);  
942  }  }
943    
944  void  void
# Line 911  ui_desktop_restore(uint32 offset, int x, Line 951  ui_desktop_restore(uint32 offset, int x,
951          data = cache_get_desktop(offset, cx, cy, bpp/8);          data = cache_get_desktop(offset, cx, cy, bpp/8);
952          if (data == NULL)          if (data == NULL)
953                  return;                  return;
954          image =  
955                  XCreateImage(display, visual,          image = XCreateImage(display, visual, depth, ZPixmap,
                              depth, ZPixmap,  
956                               0, data, cx, cy, BitmapPad(display),                               0, data, cx, cy, BitmapPad(display),
957                               cx * bpp/8);                               cx * bpp/8);
         xwin_set_function(ROP2_COPY);  
         XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);  
         XFree(image);  
 }  
   
 /* unroll defines, used to make the loops a bit more readable... */  
 #define unroll8Expr(uexp) uexp uexp uexp uexp uexp uexp uexp uexp  
 #define unroll8Lefts(uexp) case 7: uexp \  
         case 6: uexp \  
         case 5: uexp \  
         case 4: uexp \  
         case 3: uexp \  
         case 2: uexp \  
         case 1: uexp  
   
 static uint8 *  
 translate(int width, int height, uint8 *data)  
 {  
         uint32 i;  
         uint32 size = width * height;  
         uint8 *d2 = xmalloc(size * bpp/8);  
         uint8 *d3 = d2;  
         uint32 pix;  
         i = (size & ~0x7);  
   
         /* XXX: where are the bits swapped??? */  
 #ifdef L_ENDIAN                 /* little-endian */  
         /* big-endian screen */  
         if (screen_msbfirst)  
         {  
                 switch (bpp)  
                 {  
                         case 32:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix >> 24;  
                                                     *d3++ = pix >> 16;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix;) i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      24;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix;)}  
                                 break;  
                         case 24:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix >> 16;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix;) i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix;)}  
                                 break;  
                         case 16:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix;) i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix;)}  
                                 break;  
                         case 8:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;)}  
                                 break;  
                 }  
         }  
         else  
         {                       /* little-endian screen */  
                 switch (bpp)  
                 {  
                         case 32:  
                                 while (i)  
                                 {  
                                         unroll8Expr(*((uint32 *) d3) =  
                                                     colmap[*data++];  
                                                     d3 += sizeof(uint32);  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(*  
                                                                      ((uint32  
                                                                        *) d3)  
 = colmap[*data++];  
 d3 += sizeof(uint32);  
                                         )}  
                                 break;  
                         case 24:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix >> 16;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;)}  
                                 break;  
                         case 16:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                         )}  
                                 break;  
                         case 8:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;)}  
                 }  
         }  
958    
959  #else /* bigendian-compiled */          if (ownbackstore)
         if (screen_msbfirst)  
960          {          {
961                  /* big-endian screen */                  XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
962                  switch (bpp)                  XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
                 {  
                         case 32:  
                                 while (i)  
                                 {  
                                         unroll8Expr(*((uint32 *) d3) =  
                                                     colmap[*data++];  
                                                     d3 += sizeof(uint32);  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(*  
                                                                      ((uint32  
                                                                        *) d3)  
 = colmap[*data++];  
 d3 += sizeof(uint32);  
                                         )}  
                                 break;  
                         case 24:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix >> 16;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;)}  
                                 break;  
                         case 16:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                         )}  
                                 break;  
                         case 8:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;)}  
                 }  
963          }          }
964          else          else
965          {          {
966                  /* little-endian screen */                  XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
                 switch (bpp)  
                 {  
                         case 32:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix >> 16;  
                                                     *d3++ = pix >> 24;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      24;)}  
                                 break;  
                         case 24:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix >> 16;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;)}  
                                 break;  
                         case 16:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                         )}  
                                 break;  
                         case 8:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;)}  
                 }  
967          }          }
 #endif  
968    
969          return d2;          XFree(image);
970  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26