/[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 49 by mmihalik, Fri Apr 19 12:06:08 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            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          XUngrabKeyboard(display, CurrentTime);          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);
742                                  ipattern[i] = ~brush->pattern[i];  
743                          fill = (Pixmap) ui_create_glyph(8, 8, ipattern);                          SET_FOREGROUND(bgcolour);
744                            SET_BACKGROUND(fgcolour);
745                          XSetForeground(dpy, gc, Ctrans(fgcolour));                          XSetFillStyle(display, gc, FillOpaqueStippled);
746                          XSetBackground(dpy, gc, Ctrans(bgcolour));                          XSetStipple(display, gc, fill);
747                          XSetFillStyle(dpy, gc, FillOpaqueStippled);                          XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);
                         XSetStipple(dpy, gc, fill);  
748    
749                          XFillRectangle(dpy, wnd, gc, x, y, cx, cy);                          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);
855    
856          xwin_set_function(ROP2_COPY);          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)
857                          ? FillStippled : FillOpaqueStippled);
858            XSetStipple(display, gc, (Pixmap)glyph);
859          XSetForeground(display, gc, Ctrans(fgcolour));          XSetTSOrigin(display, gc, x, y);
860          switch (mixmode)  
861          {          FILL_RECTANGLE(x, y, cx, cy);
862                  case MIX_TRANSPARENT:  
863                          XSetStipple(display, gc, pixmap);          XSetFillStyle(display, gc, FillSolid);
864                          XSetFillStyle(display, gc, FillStippled);  }
865                          XSetTSOrigin(display, gc, x, y);  
866                          XFillRectangle(display, wnd, gc, x, y, cx, cy);  #define DO_GLYPH(ttext,idx) \
867                          XSetFillStyle(display, gc, FillSolid);  {\
868                          break;    glyph = cache_get_font (font, ttext[idx]);\
869      if (!(flags & TEXT2_IMPLICIT_X))\
870                  case MIX_OPAQUE:      {\
871                          XSetBackground(display, gc, Ctrans(bgcolour));        xyoffset = ttext[++idx];\
872  /*      XCopyPlane (display, pixmap, back_pixmap, back_gc, srcx, srcy, cx, cy, x, y, 1); */        if ((xyoffset & 0x80))\
873                          XSetStipple(display, gc, pixmap);          {\
874                          XSetFillStyle(display, gc, FillOpaqueStippled);            if (flags & TEXT2_VERTICAL) \
875                          XSetTSOrigin(display, gc, x, y);              y += ttext[++idx] | (ttext[++idx] << 8);\
876                          XFillRectangle(display, wnd, gc, x, y, cx, cy);            else\
877                          XSetFillStyle(display, gc, FillSolid);              x += ttext[++idx] | (ttext[++idx] << 8);\
878                          break;          }\
879          else\
880                  default:          {\
881                          NOTIMP("mix %d\n", mixmode);            if (flags & TEXT2_VERTICAL) \
882          }              y += xyoffset;\
883              else\
884                x += xyoffset;\
885            }\
886        }\
887      if (glyph != NULL)\
888        {\
889          ui_draw_glyph (mixmode, x + (short) glyph->offset,\
890                         y + (short) glyph->baseline,\
891                         glyph->width, glyph->height,\
892                         glyph->pixmap, 0, 0, bgcolour, fgcolour);\
893          if (flags & TEXT2_IMPLICIT_X)\
894            x += glyph->width;\
895        }\
896  }  }
897    
898  void  void
899  ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,  ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y,
900               int clipx, int clipy, int clipcx, int clipcy,               int clipx, int clipy, int clipcx, int clipcy, int boxx,
901               int boxx, int boxy, int boxcx, int boxcy,               int boxy, int boxcx, int boxcy, int bgcolour,
902               int bgcolour, int fgcolour, uint8 *text, uint8 length)               int fgcolour, uint8 * text, uint8 length)
903  {  {
904          FONTGLYPH *glyph;          FONTGLYPH *glyph;
905          int i, xyoffset;          int i, j, xyoffset;
906            DATABLOB *entry;
907    
908          xwin_set_function(ROP2_COPY);          SET_FOREGROUND(bgcolour);
         XSetForeground(display, gc, Ctrans(bgcolour));  
909    
910          if (boxcx > 1)          if (boxcx > 1)
911                  XFillRectangle(display, wnd, gc, boxx, boxy, boxcx, boxcy);          {
912                    FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);
913            }
914          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
                 XFillRectangle(display, wnd, gc, clipx, clipy, clipcx, clipcy);  
   
         /* Paint text, character by character */  
         for (i = 0; i < length; i++)  
915          {          {
916                  glyph = cache_get_font(font, text[i]);                  FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);
917            }
                 if (!(flags & TEXT2_IMPLICIT_X))  
918    
919                  {          /* Paint text, character by character */
920                          xyoffset = text[++i];          for (i = 0; i < length;) {
921                          if ((xyoffset & 0x80))                  switch (text[i]) {
922                          {                  case 0xff:
923                                  if (flags & 0x04)       /* vertical text */                          if (i + 2 < length)
924                                          y += text[++i] | (text[++i] << 8);                                  cache_put_text(text[i + 1], text, text[i + 2]);
925                                  else                          else {
926                                          x += text[++i] | (text[++i] << 8);                                  error("this shouldn't be happening\n");
927                                    break;
928                          }                          }
929                          else                          /* this will move pointer from start to first character after FF command */
930                          {                          length -= i + 3;
931                                  if (flags & 0x04)       /* vertical text */                          text = &(text[i + 3]);
932                                          y += xyoffset;                          i = 0;
933                            break;
934    
935                    case 0xfe:
936                            entry = cache_get_text(text[i + 1]);
937                            if (entry != NULL) {
938                                    if ((((uint8 *) (entry->data))[1] == 0)
939                                        && (!(flags & TEXT2_IMPLICIT_X))) {
940                                            if (flags & TEXT2_VERTICAL)      
941                                                    y += text[i + 2];
942                                            else
943                                                    x += text[i + 2];
944                                    }
945                                    if (i + 2 < length)
946                                            i += 3;
947                                  else                                  else
948                                          x += xyoffset;                                          i += 2;
949                                    length -= i;  
950                                    /* this will move pointer from start to first character after FE command */
951                                    text = &(text[i]);
952                                    i = 0;
953                                    for (j = 0; j < entry->size; j++)
954                                            DO_GLYPH(((uint8 *) (entry->data)), j);
955                          }                          }
956                            break;
957    
958                  }                  default:
959                  if (glyph != NULL)                          DO_GLYPH(text, i);
960                  {                          i++;
961                          ui_draw_glyph(mixmode, x + (short) glyph->offset,                          break;
                                       y + (short) glyph->baseline,  
                                       glyph->width, glyph->height,  
                                       glyph->pixmap, 0, 0,  
                                       bgcolour, fgcolour);  
   
                         if (flags & TEXT2_IMPLICIT_X)  
                                 x += glyph->width;  
962                  }                  }
963          }          }
964    
965    
966  }  }
967    
968  void  void
# Line 887  ui_desktop_save(uint32 offset, int x, in Line 971  ui_desktop_save(uint32 offset, int x, in
971          Pixmap pix;          Pixmap pix;
972          XImage *image;          XImage *image;
973    
974          pix = XCreatePixmap(display, wnd, cx, cy, depth);          if (ownbackstore)
975          xwin_set_function(ROP2_COPY);          {
976                    image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,
977          XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);                                    ZPixmap);
978          image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);          }
979            else
980            {
981                    pix = XCreatePixmap(display, wnd, cx, cy, depth);
982                    XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
983                    image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,
984                                      ZPixmap);
985                    XFreePixmap(display, pix);
986            }
987    
988          offset *= bpp/8;          offset *= bpp/8;
989          cache_put_desktop(offset, cx, cy, image->bytes_per_line,          cache_put_desktop(offset, cx, cy, image->bytes_per_line,
990                            bpp/8, image->data);                            bpp/8, (uint8 *)image->data);
991    
992          XDestroyImage(image);          XDestroyImage(image);
         XFreePixmap(display, pix);  
993  }  }
994    
995  void  void
# Line 911  ui_desktop_restore(uint32 offset, int x, Line 1002  ui_desktop_restore(uint32 offset, int x,
1002          data = cache_get_desktop(offset, cx, cy, bpp/8);          data = cache_get_desktop(offset, cx, cy, bpp/8);
1003          if (data == NULL)          if (data == NULL)
1004                  return;                  return;
1005          image =  
1006                  XCreateImage(display, visual,          image = XCreateImage(display, visual, depth, ZPixmap,
                              depth, ZPixmap,  
1007                               0, data, cx, cy, BitmapPad(display),                               0, data, cx, cy, BitmapPad(display),
1008                               cx * bpp/8);                               cx * bpp/8);
         xwin_set_function(ROP2_COPY);  
         XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);  
         XFree(image);  
 }  
1009    
1010  /* unroll defines, used to make the loops a bit more readable... */          if (ownbackstore)
 #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)  
1011          {          {
1012                  switch (bpp)                  XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
1013                  {                  XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
                         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;  
                 }  
1014          }          }
1015          else          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;)}  
                 }  
         }  
   
 #else /* bigendian-compiled */  
         if (screen_msbfirst)  
1016          {          {
1017                  /* big-endian screen */                  XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
                 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;)}  
                 }  
         }  
         else  
         {  
                 /* little-endian screen */  
                 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;)}  
                 }  
1018          }          }
 #endif  
1019    
1020          return d2;          XFree(image);
1021  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26