/[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 262 by astrand, Mon Nov 18 15:37:20 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-2002
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
8     the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.     (at your option) any later version.
10      
11     This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.     GNU General Public License for more details.
15      
16     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# 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 int width;  extern int width;
28  extern int height;  extern int height;
29  extern BOOL motion;  extern BOOL sendmotion;
 extern BOOL grab_keyboard;  
30  extern BOOL fullscreen;  extern BOOL fullscreen;
31  extern int private_colormap;  extern BOOL grab_keyboard;
32    extern BOOL hide_decorations;
33  static int bpp;  extern char title[];
34  static int depth;  BOOL enable_compose = False;
35  static Display *display;  BOOL focused;
36    BOOL mouse_in_wnd;
37    
38    Display *display;
39    static int x_socket;
40    static Screen *screen;
41  static Window wnd;  static Window wnd;
42  static GC gc;  static GC gc;
43  static Visual *visual;  static Visual *visual;
44  static uint32 *colmap;  static int depth;
45    static int bpp;
46  #define Ctrans(col) ( private_colormap ? col : colmap[col])  static XIM IM;
47    static XIC IC;
48    static XModifierKeymap *mod_map;
49    static Cursor current_cursor;
50    
51    /* endianness */
52    static BOOL host_be;
53    static BOOL xserver_be;
54    
55    /* software backing store */
56    static BOOL ownbackstore;
57    static Pixmap backstore;
58    
59    /* MWM decorations */
60    #define MWM_HINTS_DECORATIONS   (1L << 1)
61    #define PROP_MOTIF_WM_HINTS_ELEMENTS    5
62    typedef struct
63    {
64            unsigned long flags;
65            unsigned long functions;
66            unsigned long decorations;
67            long inputMode;
68            unsigned long status;
69    }
70    PropMotifWmHints;
71    
72    
73    #define FILL_RECTANGLE(x,y,cx,cy)\
74    { \
75            XFillRectangle(display, wnd, gc, x, y, cx, cy); \
76            if (ownbackstore) \
77                    XFillRectangle(display, backstore, gc, x, y, cx, cy); \
78    }
79    
80  #define L_ENDIAN  /* colour maps */
81  int screen_msbfirst = 0;  static Colormap xcolmap;
82    static uint32 *colmap;
83    
84  static uint8 *translate(int width, int height, uint8 *data);  #define SET_FOREGROUND(col)     XSetForeground(display, gc, translate_colour(colmap[col]));
85    #define SET_BACKGROUND(col)     XSetBackground(display, gc, translate_colour(colmap[col]));
86    
87  static int rop2_map[] = {  static int rop2_map[] = {
88          GXclear,                /* 0 */          GXclear,                /* 0 */
# Line 64  static int rop2_map[] = { Line 103  static int rop2_map[] = {
103          GXset                   /* 1 */          GXset                   /* 1 */
104  };  };
105    
106  static void  #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }
107  xwin_set_function(uint8 rop2)  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }
108    
109    void
110    mwm_hide_decorations(void)
111  {  {
112          static uint8 last_rop2 = ROP2_COPY;          PropMotifWmHints motif_hints;
113            Atom hintsatom;
114    
115          if (last_rop2 != rop2)          /* setup the property */
116            motif_hints.flags = MWM_HINTS_DECORATIONS;
117            motif_hints.decorations = 0;
118    
119            /* get the atom for the property */
120            hintsatom = XInternAtom(display, "_MOTIF_WM_HINTS", False);
121            if (!hintsatom)
122          {          {
123                  XSetFunction(display, gc, rop2_map[rop2]);                  error("Failed to get atom _MOTIF_WM_HINTS\n");
124                  last_rop2 = rop2;                  return;
125          }          }
126    
127            XChangeProperty(display, wnd, hintsatom, hintsatom, 32, PropModeReplace,
128                            (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
129    }
130    
131    static void
132    translate8(uint8 * data, uint8 * out, uint8 * end)
133    {
134            while (out < end)
135                    *(out++) = (uint8) colmap[*(data++)];
136    }
137    
138    static void
139    translate16(uint8 * data, uint16 * out, uint16 * end)
140    {
141            while (out < end)
142                    *(out++) = (uint16) colmap[*(data++)];
143  }  }
144    
145    /* little endian - conversion happens when colourmap is built */
146  static void  static void
147  xwin_grab_keyboard()  translate24(uint8 * data, uint8 * out, uint8 * end)
148  {  {
149          XGrabKeyboard(display, wnd, True, GrabModeAsync, GrabModeAsync,          uint32 value;
150                        CurrentTime);  
151            while (out < end)
152            {
153                    value = colmap[*(data++)];
154                    *(out++) = value;
155                    *(out++) = value >> 8;
156                    *(out++) = value >> 16;
157            }
158  }  }
159    
160  static void  static void
161  xwin_ungrab_keyboard()  translate32(uint8 * data, uint32 * out, uint32 * end)
162    {
163            while (out < end)
164                    *(out++) = colmap[*(data++)];
165    }
166    
167    static uint8 *
168    translate_image(int width, int height, uint8 * data)
169    {
170            int size = width * height * bpp / 8;
171            uint8 *out = xmalloc(size);
172            uint8 *end = out + size;
173    
174            switch (bpp)
175            {
176                    case 8:
177                            translate8(data, out, end);
178                            break;
179    
180                    case 16:
181                            translate16(data, (uint16 *) out, (uint16 *) end);
182                            break;
183    
184                    case 24:
185                            translate24(data, out, end);
186                            break;
187    
188                    case 32:
189                            translate32(data, (uint32 *) out, (uint32 *) end);
190                            break;
191            }
192    
193            return out;
194    }
195    
196    #define BSWAP16(x) { x = (((x & 0xff) << 8) | (x >> 8)); }
197    #define BSWAP24(x) { x = (((x & 0xff) << 16) | (x >> 16) | ((x >> 8) & 0xff00)); }
198    #define BSWAP32(x) { x = (((x & 0xff00ff) << 8) | ((x >> 8) & 0xff00ff)); \
199                            x = (x << 16) | (x >> 16); }
200    
201    static uint32
202    translate_colour(uint32 colour)
203    {
204            switch (bpp)
205            {
206                    case 16:
207                            if (host_be != xserver_be)
208                                    BSWAP16(colour);
209                            break;
210    
211                    case 24:
212                            if (xserver_be)
213                                    BSWAP24(colour);
214                            break;
215    
216                    case 32:
217                            if (host_be != xserver_be)
218                                    BSWAP32(colour);
219                            break;
220            }
221    
222            return colour;
223    }
224    
225    BOOL
226    get_key_state(unsigned int state, uint32 keysym)
227  {  {
228          XUngrabKeyboard(display, CurrentTime);          int modifierpos, key, keysymMask = 0;
229            int offset;
230    
231            KeyCode keycode = XKeysymToKeycode(display, keysym);
232    
233            if (keycode == NoSymbol)
234                    return False;
235    
236            for (modifierpos = 0; modifierpos < 8; modifierpos++)
237            {
238                    offset = mod_map->max_keypermod * modifierpos;
239    
240                    for (key = 0; key < mod_map->max_keypermod; key++)
241                    {
242                            if (mod_map->modifiermap[offset + key] == keycode)
243                                    keysymMask |= 1 << modifierpos;
244                    }
245            }
246    
247            return (state & keysymMask) ? True : False;
248  }  }
249    
250  BOOL  BOOL
251  ui_create_window(char *title)  ui_init(void)
252  {  {
         XSetWindowAttributes attribs;  
         XClassHint *classhints;  
         XSizeHints *sizehints;  
         unsigned long input_mask;  
253          XPixmapFormatValues *pfm;          XPixmapFormatValues *pfm;
254          int count;          uint16 test;
255            int i;
256    
257          display = XOpenDisplay(NULL);          display = XOpenDisplay(NULL);
258          if (display == NULL)          if (display == NULL)
259          {          {
260                  ERROR("Failed to open display\n");                  error("Failed to open display: %s\n", XDisplayName(NULL));
261                  return False;                  return False;
262          }          }
263    
264          visual = DefaultVisual(display, DefaultScreen(display));          x_socket = ConnectionNumber(display);
265          depth = DefaultDepth(display, DefaultScreen(display));          screen = DefaultScreenOfDisplay(display);
266          pfm = XListPixmapFormats(display, &count);          visual = DefaultVisualOfScreen(screen);
267            depth = DefaultDepthOfScreen(screen);
268    
269            pfm = XListPixmapFormats(display, &i);
270          if (pfm != NULL)          if (pfm != NULL)
271          {          {
272                  while (count--)                  /* Use maximum bpp for this depth - this is generally
273                       desirable, e.g. 24 bits->32 bits. */
274                    while (i--)
275                  {                  {
276                          if ((pfm + count)->depth == depth                          if ((pfm[i].depth == depth) && (pfm[i].bits_per_pixel > bpp))
                             && (pfm + count)->bits_per_pixel > bpp)  
277                          {                          {
278                                  bpp = (pfm + count)->bits_per_pixel;                                  bpp = pfm[i].bits_per_pixel;
279                          }                          }
280                  }                  }
281                  XFree(pfm);                  XFree(pfm);
# Line 124  ui_create_window(char *title) Line 283  ui_create_window(char *title)
283    
284          if (bpp < 8)          if (bpp < 8)
285          {          {
286                  ERROR("Less than 8 bpp not currently supported.\n");                  error("Less than 8 bpp not currently supported.\n");
287                  XCloseDisplay(display);                  XCloseDisplay(display);
288                  return False;                  return False;
289          }          }
290    
291          width &= ~3; /* make width nicely divisible */          xcolmap = DefaultColormapOfScreen(screen);
292            gc = XCreateGC(display, RootWindowOfScreen(screen), 0, NULL);
293    
294            if (DoesBackingStore(screen) != Always)
295                    ownbackstore = True;
296    
297          attribs.background_pixel = BlackPixel(display, DefaultScreen(display));          test = 1;
298          attribs.backing_store = Always;          host_be = !(BOOL) (*(uint8 *) (&test));
299            xserver_be = (ImageByteOrder(display) == MSBFirst);
300    
301          if (fullscreen)          if (fullscreen)
302          {          {
303                  attribs.override_redirect = True;                  width = WidthOfScreen(screen);
304                  width = WidthOfScreen(DefaultScreenOfDisplay(display));                  height = HeightOfScreen(screen);
                 height = HeightOfScreen(DefaultScreenOfDisplay(display));  
                 XSetInputFocus(display, PointerRoot, RevertToPointerRoot,  
                                CurrentTime);  
305          }          }
306          else  
307            /* make sure width is a multiple of 4 */
308            width = (width + 3) & ~3;
309    
310            if (ownbackstore)
311          {          {
312                  attribs.override_redirect = False;                  backstore =
313                            XCreatePixmap(display, RootWindowOfScreen(screen), width, height, depth);
314    
315                    /* clear to prevent rubbish being exposed at startup */
316                    XSetForeground(display, gc, BlackPixelOfScreen(screen));
317                    XFillRectangle(display, backstore, gc, 0, 0, width, height);
318          }          }
319    
320          wnd = XCreateWindow(display, DefaultRootWindow(display),          mod_map = XGetModifierMapping(display);
321                              0, 0, width, height, 0, CopyFromParent,  
322                              InputOutput, CopyFromParent,          if (enable_compose)
323                              CWBackingStore | CWBackPixel | CWOverrideRedirect,                  IM = XOpenIM(display, NULL, NULL, NULL);
324                              &attribs);  
325            xkeymap_init();
326            return True;
327    }
328    
329    void
330    ui_deinit(void)
331    {
332            if (IM != NULL)
333                    XCloseIM(IM);
334    
335            XFreeModifiermap(mod_map);
336    
337            if (ownbackstore)
338                    XFreePixmap(display, backstore);
339    
340            XFreeGC(display, gc);
341            XCloseDisplay(display);
342            display = NULL;
343    }
344    
345    BOOL
346    ui_create_window(void)
347    {
348            XSetWindowAttributes attribs;
349            XClassHint *classhints;
350            XSizeHints *sizehints;
351            int wndwidth, wndheight;
352            long input_mask, ic_input_mask;
353            XEvent xevent;
354    
355            wndwidth = fullscreen ? WidthOfScreen(screen) : width;
356            wndheight = fullscreen ? HeightOfScreen(screen) : height;
357    
358            attribs.background_pixel = BlackPixelOfScreen(screen);
359            attribs.backing_store = ownbackstore ? NotUseful : Always;
360            attribs.override_redirect = fullscreen;
361    
362            wnd = XCreateWindow(display, RootWindowOfScreen(screen), 0, 0, wndwidth, wndheight,
363                                0, CopyFromParent, InputOutput, CopyFromParent,
364                                CWBackPixel | CWBackingStore | CWOverrideRedirect, &attribs);
365    
366          XStoreName(display, wnd, title);          XStoreName(display, wnd, title);
367    
368            if (hide_decorations)
369                    mwm_hide_decorations();
370    
371          classhints = XAllocClassHint();          classhints = XAllocClassHint();
372          if (classhints != NULL)          if (classhints != NULL)
   
373          {          {
374                  classhints->res_name = "rdesktop";                  classhints->res_name = classhints->res_class = "rdesktop";
                 classhints->res_class = "rdesktop";  
375                  XSetClassHint(display, wnd, classhints);                  XSetClassHint(display, wnd, classhints);
376                  XFree(classhints);                  XFree(classhints);
377          }          }
# Line 168  ui_create_window(char *title) Line 379  ui_create_window(char *title)
379          sizehints = XAllocSizeHints();          sizehints = XAllocSizeHints();
380          if (sizehints)          if (sizehints)
381          {          {
382                  sizehints->flags =                  sizehints->flags = PMinSize | PMaxSize;
383                          PPosition | PSize | PMinSize | PMaxSize | PBaseSize;                  sizehints->min_width = sizehints->max_width = width;
384                  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;  
385                  XSetWMNormalHints(display, wnd, sizehints);                  XSetWMNormalHints(display, wnd, sizehints);
386                  XFree(sizehints);                  XFree(sizehints);
387          }          }
388    
389          input_mask = KeyPressMask | KeyReleaseMask;          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
390          input_mask |= ButtonPressMask | ButtonReleaseMask;                  VisibilityChangeMask | FocusChangeMask;
391          if (motion)  
392            if (sendmotion)
393                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
394            if (ownbackstore)
395                    input_mask |= ExposureMask;
396            if (fullscreen || grab_keyboard)
397                    input_mask |= EnterWindowMask;
398          if (grab_keyboard)          if (grab_keyboard)
399                  input_mask |= EnterWindowMask | LeaveWindowMask;                  input_mask |= LeaveWindowMask;
400    
401          XSelectInput(display, wnd, input_mask);          if (IM != NULL)
402          gc = XCreateGC(display, wnd, 0, NULL);          {
403                    IC = XCreateIC(IM, XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
404                                   XNClientWindow, wnd, XNFocusWindow, wnd, NULL);
405    
406                    if ((IC != NULL)
407                        && (XGetICValues(IC, XNFilterEvents, &ic_input_mask, NULL) == NULL))
408                            input_mask |= ic_input_mask;
409            }
410    
411            XSelectInput(display, wnd, input_mask);
412          XMapWindow(display, wnd);          XMapWindow(display, wnd);
413    
414            /* wait for VisibilityNotify */
415            do
416            {
417                    XMaskEvent(display, VisibilityChangeMask, &xevent);
418            }
419            while (xevent.type != VisibilityNotify);
420    
421            focused = False;
422            mouse_in_wnd = False;
423    
424          return True;          return True;
425  }  }
426    
427  void  void
428  ui_destroy_window()  ui_destroy_window(void)
429  {  {
430          XFreeGC(display, gc);          if (IC != NULL)
431                    XDestroyIC(IC);
432    
433          XDestroyWindow(display, wnd);          XDestroyWindow(display, wnd);
         XCloseDisplay(display);  
         display = NULL;  
434  }  }
435    
436  static uint8  void
437  xwin_translate_key(unsigned long key)  xwin_toggle_fullscreen(void)
438  {  {
439          DEBUG("KEY(code=0x%lx)\n", key);          Pixmap contents = 0;
440    
441          if ((key > 8) && (key <= 0x60))          if (!ownbackstore)
442                  return (key - 8);          {
443                    /* need to save contents of window */
444                    contents = XCreatePixmap(display, wnd, width, height, depth);
445                    XCopyArea(display, wnd, contents, gc, 0, 0, width, height, 0, 0);
446            }
447    
448          switch (key)          ui_destroy_window();
449          {          fullscreen = !fullscreen;
450                  case 0x61:      /* home */          ui_create_window();
                         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()  
 {  
         XEvent event;  
         uint8 scancode;  
         uint16 button;  
         uint32 ev_time;  
451    
452          if (display == NULL)          XDefineCursor(display, wnd, current_cursor);
453                  return;  
454            if (!ownbackstore)
455            {
456                    XCopyArea(display, contents, wnd, gc, 0, 0, width, height, 0, 0);
457                    XFreePixmap(display, contents);
458            }
459    }
460    
461    /* Process all events in Xlib queue */
462    static void
463    xwin_process_events(void)
464    {
465            XEvent xevent;
466            KeySym keysym;
467            uint16 button, flags;
468            uint32 ev_time;
469            key_translation tr;
470            char str[256];
471            Status status;
472            unsigned int state;
473            Window wdummy;
474            int dummy;
475    
476          while (XCheckWindowEvent(display, wnd, ~0, &event))          while (XPending(display) > 0)
477          {          {
478                  ev_time = time(NULL);                  XNextEvent(display, &xevent);
479    
480                  switch (event.type)                  if ((IC != NULL) && (XFilterEvent(&xevent, None) == True))
481                    {
482                            DEBUG_KBD(("Filtering event\n"));
483                            continue;
484                    }
485    
486                    flags = 0;
487    
488                    switch (xevent.type)
489                  {                  {
490                          case KeyPress:                          case KeyPress:
491                                  scancode = xwin_translate_key(event.xkey.keycode);                                  if (IC != NULL)
492                                  if (scancode == 0)                                          /* Multi_key compatible version */
493                                    {
494                                            XmbLookupString(IC,
495                                                            (XKeyPressedEvent *) &
496                                                            xevent, str, sizeof(str), &keysym, &status);
497                                            if (!((status == XLookupKeySym) || (status == XLookupBoth)))
498                                            {
499                                                    error("XmbLookupString failed with status 0x%x\n",
500                                                          status);
501                                                    break;
502                                            }
503                                    }
504                                    else
505                                    {
506                                            /* Plain old XLookupString */
507                                            DEBUG_KBD(("\nNo input context, using XLookupString\n"));
508                                            XLookupString((XKeyEvent *) & xevent,
509                                                          str, sizeof(str), &keysym, NULL);
510                                    }
511    
512                                    DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym,
513                                               get_ksname(keysym)));
514    
515                                    ev_time = time(NULL);
516                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
517                                            break;
518    
519                                    tr = xkeymap_translate_key(keysym,
520                                                               xevent.xkey.keycode, xevent.xkey.state);
521    
522                                    if (tr.scancode == 0)
523                                          break;                                          break;
524    
525                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,                                  ensure_remote_modifiers(ev_time, tr);
526                                                 scancode, 0);  
527                                    rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
528                                  break;                                  break;
529    
530                          case KeyRelease:                          case KeyRelease:
531                                  scancode = xwin_translate_key(event.xkey.keycode);                                  XLookupString((XKeyEvent *) & xevent, str,
532                                  if (scancode == 0)                                                sizeof(str), &keysym, NULL);
533    
534                                    DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,
535                                               get_ksname(keysym)));
536    
537                                    ev_time = time(NULL);
538                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
539                                          break;                                          break;
540    
541                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE,                                  tr = xkeymap_translate_key(keysym,
542                                                 KBD_FLAG_DOWN | KBD_FLAG_UP,                                                             xevent.xkey.keycode, xevent.xkey.state);
                                                scancode, 0);  
                                 break;  
543    
544                          case ButtonPress:                                  if (tr.scancode == 0)
                                 button = xwin_translate_mouse(event.xbutton.button);  
                                 if (button == 0)  
545                                          break;                                          break;
546    
547                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);
                                                button | MOUSE_FLAG_DOWN,  
                                                event.xbutton.x,  
                                                event.xbutton.y);  
548                                  break;                                  break;
549    
550                            case ButtonPress:
551                                    flags = MOUSE_FLAG_DOWN;
552                                    /* fall through */
553    
554                          case ButtonRelease:                          case ButtonRelease:
555                                  button = xwin_translate_mouse(event.xbutton.button);                                  button = xkeymap_translate_button(xevent.xbutton.button);
556                                  if (button == 0)                                  if (button == 0)
557                                          break;                                          break;
558    
559                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
560                                                 button,                                                 flags | button, xevent.xbutton.x, xevent.xbutton.y);
                                                event.xbutton.x,  
                                                event.xbutton.y);  
561                                  break;                                  break;
562    
563                          case MotionNotify:                          case MotionNotify:
564                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
565                                                 MOUSE_FLAG_MOVE,                                                 MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
566                                                 event.xmotion.x,                                  break;
567                                                 event.xmotion.y);  
568                            case FocusIn:
569                                    if (xevent.xfocus.mode == NotifyGrab)
570                                            break;
571                                    focused = True;
572                                    XQueryPointer(display, wnd, &wdummy, &wdummy, &dummy, &dummy,
573                                                  &dummy, &dummy, &state);
574                                    reset_modifier_keys(state);
575                                    if (grab_keyboard && mouse_in_wnd)
576                                            XGrabKeyboard(display, wnd, True,
577                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
578                                    break;
579    
580                            case FocusOut:
581                                    if (xevent.xfocus.mode == NotifyUngrab)
582                                            break;
583                                    focused = False;
584                                    if (xevent.xfocus.mode == NotifyWhileGrabbed)
585                                            XUngrabKeyboard(display, CurrentTime);
586                                  break;                                  break;
587    
588                          case EnterNotify:                          case EnterNotify:
589                                  if (grab_keyboard)                                  /* we only register for this event when in fullscreen mode */
590                                          xwin_grab_keyboard();                                  /* or grab_keyboard */
591                                    mouse_in_wnd = True;
592                                    if (fullscreen)
593                                    {
594                                            XSetInputFocus(display, wnd, RevertToPointerRoot,
595                                                           CurrentTime);
596                                            break;
597                                    }
598                                    if (focused)
599                                            XGrabKeyboard(display, wnd, True,
600                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
601                                  break;                                  break;
602    
603                          case LeaveNotify:                          case LeaveNotify:
604                                  if (grab_keyboard)                                  /* we only register for this event when grab_keyboard */
605                                          xwin_ungrab_keyboard();                                  mouse_in_wnd = False;
606                                    XUngrabKeyboard(display, CurrentTime);
607                                    break;
608    
609                            case Expose:
610                                    XCopyArea(display, backstore, wnd, gc,
611                                              xevent.xexpose.x, xevent.xexpose.y,
612                                              xevent.xexpose.width,
613                                              xevent.xexpose.height,
614                                              xevent.xexpose.x, xevent.xexpose.y);
615                                    break;
616    
617                            case MappingNotify:
618                                    /* Refresh keyboard mapping if it has changed. This is important for
619                                       Xvnc, since it allocates keycodes dynamically */
620                                    if (xevent.xmapping.request == MappingKeyboard
621                                        || xevent.xmapping.request == MappingModifier)
622                                            XRefreshKeyboardMapping(&xevent.xmapping);
623    
624                                    if (xevent.xmapping.request == MappingModifier)
625                                    {
626                                            XFreeModifiermap(mod_map);
627                                            mod_map = XGetModifierMapping(display);
628                                    }
629                                  break;                                  break;
630    
631                    }
632            }
633    }
634    
635    void
636    ui_select(int rdp_socket)
637    {
638            int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;
639            fd_set rfds;
640    
641            FD_ZERO(&rfds);
642    
643            while (True)
644            {
645                    /* Process any events already waiting */
646                    xwin_process_events();
647    
648                    FD_ZERO(&rfds);
649                    FD_SET(rdp_socket, &rfds);
650                    FD_SET(x_socket, &rfds);
651    
652                    switch (select(n, &rfds, NULL, NULL, NULL))
653                    {
654                            case -1:
655                                    error("select: %s\n", strerror(errno));
656    
657                            case 0:
658                                    continue;
659                  }                  }
660    
661                    if (FD_ISSET(rdp_socket, &rfds))
662                            return;
663          }          }
664  }  }
665    
# Line 357  ui_move_pointer(int x, int y) Line 670  ui_move_pointer(int x, int y)
670  }  }
671    
672  HBITMAP  HBITMAP
673  ui_create_bitmap(int width, int height, uint8 *data)  ui_create_bitmap(int width, int height, uint8 * data)
674  {  {
675          XImage *image;          XImage *image;
676          Pixmap bitmap;          Pixmap bitmap;
677          uint8 *tdata;          uint8 *tdata;
678          tdata = (private_colormap ? data : translate(width, height, data));  
679            tdata = translate_image(width, height, data);
680          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(display, wnd, width, height, depth);
681          image =          image = XCreateImage(display, visual, depth, ZPixmap, 0,
682                  XCreateImage(display, visual,                               (char *) tdata, width, height, 8, 0);
                              depth, ZPixmap,  
                              0, tdata, width, height, BitmapPad(display), 0);  
683    
         xwin_set_function(ROP2_COPY);  
684          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
685    
686          XFree(image);          XFree(image);
687          if (!private_colormap)          xfree(tdata);
                 xfree(tdata);  
688          return (HBITMAP) bitmap;          return (HBITMAP) bitmap;
689  }  }
690    
691  void  void
692  ui_paint_bitmap(int x, int y, int cx, int cy,  ui_paint_bitmap(int x, int y, int cx, int cy, int width, int height, uint8 * data)
                 int width, int height, uint8 *data)  
693  {  {
694          XImage *image;          XImage *image;
695          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);  
 }  
696    
697  HCURSOR          tdata = translate_image(width, height, data);
698  ui_create_cursor(unsigned int x, unsigned int y, int width,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
699                   int height, uint8 *mask, uint8 *data)                               (char *) 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;  
700    
701          if (!screen_msbfirst)          if (ownbackstore)
702          {          {
703                  while (i >= 0)                  XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
704                  {                  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;  
                 }  
705          }          }
706          else          else
707          {          {
708                  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;  
                 }  
709          }          }
710    
711            XFree(image);
712          fg.red = 0;          xfree(tdata);
         fg.blue = 0;  
         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);  
713  }  }
714    
715  void  void
716  ui_destroy_cursor(HCURSOR cursor)  ui_destroy_bitmap(HBITMAP bmp)
717  {  {
718          XFreeCursor(display, (Cursor) cursor);          XFreePixmap(display, (Pixmap) bmp);
719  }  }
720    
721  HGLYPH  HGLYPH
722  ui_create_glyph(int width, int height, uint8 *data)  ui_create_glyph(int width, int height, uint8 * data)
723  {  {
724          XImage *image;          XImage *image;
725          Pixmap bitmap;          Pixmap bitmap;
# Line 538  ui_create_glyph(int width, int height, u Line 731  ui_create_glyph(int width, int height, u
731          bitmap = XCreatePixmap(display, wnd, width, height, 1);          bitmap = XCreatePixmap(display, wnd, width, height, 1);
732          gc = XCreateGC(display, bitmap, 0, NULL);          gc = XCreateGC(display, bitmap, 0, NULL);
733    
734          image = XCreateImage(display, visual, 1, ZPixmap, 0,          image = XCreateImage(display, visual, 1, ZPixmap, 0, (char *) data,
735                               data, width, height, 8, scanline);                               width, height, 8, scanline);
736          image->byte_order = MSBFirst;          image->byte_order = MSBFirst;
737          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
738          XInitImage(image);          XInitImage(image);
739    
         XSetFunction(display, gc, GXcopy);  
740          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
741    
742          XFree(image);          XFree(image);
743          XFreeGC(display, gc);          XFreeGC(display, gc);
   
744          return (HGLYPH) bitmap;          return (HGLYPH) bitmap;
745  }  }
746    
# Line 558  ui_destroy_glyph(HGLYPH glyph) Line 750  ui_destroy_glyph(HGLYPH glyph)
750          XFreePixmap(display, (Pixmap) glyph);          XFreePixmap(display, (Pixmap) glyph);
751  }  }
752    
753  HCOLOURMAP  HCURSOR
754  ui_create_colourmap(COLOURMAP *colours)  ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
755                     uint8 * andmask, uint8 * xormask)
756  {  {
757          if (!private_colormap)          HGLYPH maskglyph, cursorglyph;
758            XColor bg, fg;
759            Cursor xcursor;
760            uint8 *cursor, *pcursor;
761            uint8 *mask, *pmask;
762            uint8 nextbit;
763            int scanline, offset;
764            int i, j;
765    
766            scanline = (width + 7) / 8;
767            offset = scanline * height;
768    
769            cursor = xmalloc(offset);
770            memset(cursor, 0, offset);
771    
772            mask = xmalloc(offset);
773            memset(mask, 0, offset);
774    
775            /* approximate AND and XOR masks with a monochrome X pointer */
776            for (i = 0; i < height; i++)
777          {          {
778                  COLOURENTRY *entry;                  offset -= scanline;
779                  int i, ncolours = colours->ncolours;                  pcursor = &cursor[offset];
780                  uint32 *nc = xmalloc(sizeof(*colmap) * ncolours);                  pmask = &mask[offset];
781                  for (i = 0; i < ncolours; i++)  
782                    for (j = 0; j < scanline; j++)
783                  {                  {
784                          XColor xc;                          for (nextbit = 0x80; nextbit != 0; nextbit >>= 1)
785                          entry = &colours->colours[i];                          {
786                          xc.red = entry->red << 8;                                  if (xormask[0] || xormask[1] || xormask[2])
787                          xc.green = entry->green << 8;                                  {
788                          xc.blue = entry->blue << 8;                                          *pcursor |= (~(*andmask) & nextbit);
789                          XAllocColor(display,                                          *pmask |= nextbit;
790                                      DefaultColormap(display,                                  }
791                                                      DefaultScreen(display)),                                  else
792                                      &xc);                                  {
793                          /* XXX Check return value */                                          *pcursor |= ((*andmask) & nextbit);
794                          nc[i] = xc.pixel;                                          *pmask |= (~(*andmask) & nextbit);
795                                    }
796    
797                                    xormask += 3;
798                            }
799    
800                            andmask++;
801                            pcursor++;
802                            pmask++;
803                  }                  }
                 return nc;  
804          }          }
805          else  
806            fg.red = fg.blue = fg.green = 0xffff;
807            bg.red = bg.blue = bg.green = 0x0000;
808            fg.flags = bg.flags = DoRed | DoBlue | DoGreen;
809    
810            cursorglyph = ui_create_glyph(width, height, cursor);
811            maskglyph = ui_create_glyph(width, height, mask);
812    
813            xcursor =
814                    XCreatePixmapCursor(display, (Pixmap) cursorglyph,
815                                        (Pixmap) maskglyph, &fg, &bg, x, y);
816    
817            ui_destroy_glyph(maskglyph);
818            ui_destroy_glyph(cursorglyph);
819            xfree(mask);
820            xfree(cursor);
821            return (HCURSOR) xcursor;
822    }
823    
824    void
825    ui_set_cursor(HCURSOR cursor)
826    {
827            current_cursor = (Cursor) cursor;
828            XDefineCursor(display, wnd, current_cursor);
829    }
830    
831    void
832    ui_destroy_cursor(HCURSOR cursor)
833    {
834            XFreeCursor(display, (Cursor) cursor);
835    }
836    
837    #define MAKE_XCOLOR(xc,c) \
838                    (xc)->red   = ((c)->red   << 8) | (c)->red; \
839                    (xc)->green = ((c)->green << 8) | (c)->green; \
840                    (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \
841                    (xc)->flags = DoRed | DoGreen | DoBlue;
842    
843    HCOLOURMAP
844    ui_create_colourmap(COLOURMAP * colours)
845    {
846            COLOURENTRY *entry;
847            int i, ncolours = colours->ncolours;
848            uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
849            XColor xentry;
850            XColor xc_cache[256];
851            uint32 colour;
852            int colLookup = 256;
853            for (i = 0; i < ncolours; i++)
854          {          {
855                  COLOURENTRY *entry;                  entry = &colours->colours[i];
856                  XColor *xcolours, *xentry;                  MAKE_XCOLOR(&xentry, entry);
857                  Colormap map;  
858                  int i, ncolours = colours->ncolours;                  if (XAllocColor(display, xcolmap, &xentry) == 0)
859                  xcolours = xmalloc(sizeof(XColor) * ncolours);                  {
860                  for (i = 0; i < ncolours; i++)                          /* Allocation failed, find closest match. */
861                            int j = 256;
862                            int nMinDist = 3 * 256 * 256;
863                            long nDist = nMinDist;
864    
865                            /* only get the colors once */
866                            while (colLookup--)
867                            {
868                                    xc_cache[colLookup].pixel = colLookup;
869                                    xc_cache[colLookup].red = xc_cache[colLookup].green =
870                                            xc_cache[colLookup].blue = 0;
871                                    xc_cache[colLookup].flags = 0;
872                                    XQueryColor(display,
873                                                DefaultColormap(display, DefaultScreen(display)),
874                                                &xc_cache[colLookup]);
875                            }
876                            colLookup = 0;
877    
878                            /* approximate the pixel */
879                            while (j--)
880                            {
881                                    if (xc_cache[j].flags)
882                                    {
883                                            nDist = ((long) (xc_cache[j].red >> 8) -
884                                                     (long) (xentry.red >> 8)) *
885                                                    ((long) (xc_cache[j].red >> 8) -
886                                                     (long) (xentry.red >> 8)) +
887                                                    ((long) (xc_cache[j].green >> 8) -
888                                                     (long) (xentry.green >> 8)) *
889                                                    ((long) (xc_cache[j].green >> 8) -
890                                                     (long) (xentry.green >> 8)) +
891                                                    ((long) (xc_cache[j].blue >> 8) -
892                                                     (long) (xentry.blue >> 8)) *
893                                                    ((long) (xc_cache[j].blue >> 8) -
894                                                     (long) (xentry.blue >> 8));
895                                    }
896                                    if (nDist < nMinDist)
897                                    {
898                                            nMinDist = nDist;
899                                            xentry.pixel = j;
900                                    }
901                            }
902                    }
903                    colour = xentry.pixel;
904    
905                    /* update our cache */
906                    if (xentry.pixel < 256)
907                  {                  {
908                          entry = &colours->colours[i];                          xc_cache[xentry.pixel].red = xentry.red;
909                          xentry = &xcolours[i];                          xc_cache[xentry.pixel].green = xentry.green;
910                            xc_cache[xentry.pixel].blue = xentry.blue;
911    
                         xentry->pixel = i;  
                         xentry->red = entry->red << 8;  
                         xentry->blue = entry->blue << 8;  
                         xentry->green = entry->green << 8;  
                         xentry->flags = DoRed | DoBlue | DoGreen;  
912                  }                  }
913    
                 map = XCreateColormap(display, wnd, visual, AllocAll);  
                 XStoreColors(display, map, xcolours, ncolours);  
914    
915                  xfree(xcolours);                  /* byte swap here to make translate_image faster */
916                  return (HCOLOURMAP) map;                  map[i] = translate_colour(colour);
917          }          }
918    
919            return map;
920  }  }
921    
922  void  void
923  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
924  {  {
925          XFreeColormap(display, (Colormap) map);          xfree(map);
926  }  }
927    
928  void  void
929  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
930  {  {
931            colmap = map;
         /* XXX, change values of all pixels on the screen if the new colmap  
          * doesn't have the same values as the old one? */  
         if (!private_colormap)  
                 colmap = map;  
         else  
         {  
                 XSetWindowColormap(display, wnd, (Colormap) map);  
                 if (fullscreen)  
                         XInstallColormap(display, (Colormap) map);  
         }  
932  }  }
933    
934  void  void
# Line 644  ui_set_clip(int x, int y, int cx, int cy Line 944  ui_set_clip(int x, int y, int cx, int cy
944  }  }
945    
946  void  void
947  ui_reset_clip()  ui_reset_clip(void)
948  {  {
949          XRectangle rect;          XRectangle rect;
950    
# Line 656  ui_reset_clip() Line 956  ui_reset_clip()
956  }  }
957    
958  void  void
959  ui_bell()  ui_bell(void)
960  {  {
961          XBell(display, 0);          XBell(display, 0);
962  }  }
# Line 665  void Line 965  void
965  ui_destblt(uint8 opcode,  ui_destblt(uint8 opcode,
966             /* dest */ int x, int y, int cx, int cy)             /* dest */ int x, int y, int cx, int cy)
967  {  {
968          xwin_set_function(opcode);          SET_FUNCTION(opcode);
969            FILL_RECTANGLE(x, y, cx, cy);
970          XFillRectangle(display, wnd, gc, x, y, cx, cy);          RESET_FUNCTION(opcode);
971  }  }
972    
973  void  void
974  ui_patblt(uint8 opcode,  ui_patblt(uint8 opcode,
975            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
976            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
977  {  {
         Display *dpy = display;  
978          Pixmap fill;          Pixmap fill;
979          uint8 i, ipattern[8];          uint8 i, ipattern[8];
980    
981          xwin_set_function(opcode);          SET_FUNCTION(opcode);
982    
983          switch (brush->style)          switch (brush->style)
984          {          {
985                  case 0: /* Solid */                  case 0: /* Solid */
986                          XSetForeground(dpy, gc, Ctrans(fgcolour));                          SET_FOREGROUND(fgcolour);
987                          XFillRectangle(dpy, wnd, gc, x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
988                          break;                          break;
989    
990                  case 3: /* Pattern */                  case 3: /* Pattern */
991                          for (i = 0; i != 8; i++)                          for (i = 0; i != 8; i++)
992                                  ipattern[i] = ~brush->pattern[i];                                  ipattern[7 - i] = brush->pattern[i];
993                          fill = (Pixmap) ui_create_glyph(8, 8, ipattern);                          fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
994    
995                          XSetForeground(dpy, gc, Ctrans(fgcolour));                          SET_FOREGROUND(bgcolour);
996                          XSetBackground(dpy, gc, Ctrans(bgcolour));                          SET_BACKGROUND(fgcolour);
997                          XSetFillStyle(dpy, gc, FillOpaqueStippled);                          XSetFillStyle(display, gc, FillOpaqueStippled);
998                          XSetStipple(dpy, gc, fill);                          XSetStipple(display, gc, fill);
999                            XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);
1000    
1001                          XFillRectangle(dpy, wnd, gc, x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
1002    
1003                          XSetFillStyle(dpy, gc, FillSolid);                          XSetFillStyle(display, gc, FillSolid);
1004                            XSetTSOrigin(display, gc, 0, 0);
1005                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((HGLYPH) fill);
1006                          break;                          break;
1007    
1008                  default:                  default:
1009                          NOTIMP("brush %d\n", brush->style);                          unimpl("brush %d\n", brush->style);
1010          }          }
1011    
1012            RESET_FUNCTION(opcode);
1013  }  }
1014    
1015  void  void
# Line 714  ui_screenblt(uint8 opcode, Line 1017  ui_screenblt(uint8 opcode,
1017               /* dest */ int x, int y, int cx, int cy,               /* dest */ int x, int y, int cx, int cy,
1018               /* src */ int srcx, int srcy)               /* src */ int srcx, int srcy)
1019  {  {
1020          xwin_set_function(opcode);          SET_FUNCTION(opcode);
   
1021          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
1022            if (ownbackstore)
1023                    XCopyArea(display, backstore, backstore, gc, srcx, srcy, cx, cy, x, y);
1024            RESET_FUNCTION(opcode);
1025  }  }
1026    
1027  void  void
# Line 724  ui_memblt(uint8 opcode, Line 1029  ui_memblt(uint8 opcode,
1029            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1030            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ HBITMAP src, int srcx, int srcy)
1031  {  {
1032          xwin_set_function(opcode);          SET_FUNCTION(opcode);
   
1033          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
1034            if (ownbackstore)
1035                    XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy, cx, cy, x, y);
1036            RESET_FUNCTION(opcode);
1037  }  }
1038    
1039  void  void
1040  ui_triblt(uint8 opcode,  ui_triblt(uint8 opcode,
1041            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1042            /* src */ HBITMAP src, int srcx, int srcy,            /* src */ HBITMAP src, int srcx, int srcy,
1043            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1044  {  {
1045          /* This is potentially difficult to do in general. Until someone          /* This is potentially difficult to do in general. Until someone
1046             comes up with a more efficient way of doing it I am using cases. */             comes up with a more efficient way of doing it I am using cases. */
# Line 742  ui_triblt(uint8 opcode, Line 1049  ui_triblt(uint8 opcode,
1049          {          {
1050                  case 0x69:      /* PDSxxn */                  case 0x69:      /* PDSxxn */
1051                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
1052                          ui_patblt(ROP2_NXOR, x, y, cx, cy,                          ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1053                          break;                          break;
1054    
1055                  case 0xb8:      /* PSDPxax */                  case 0xb8:      /* PSDPxax */
1056                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1057                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
1058                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1059                          break;                          break;
1060    
1061                  case 0xc0:                  case 0xc0:      /* PSa */
1062                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1063                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   fgcolour);  
1064                          break;                          break;
1065    
1066                  default:                  default:
1067                          NOTIMP("triblt 0x%x\n", opcode);                          unimpl("triblt 0x%x\n", opcode);
1068                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1069          }          }
1070  }  }
# Line 769  ui_triblt(uint8 opcode, Line 1072  ui_triblt(uint8 opcode,
1072  void  void
1073  ui_line(uint8 opcode,  ui_line(uint8 opcode,
1074          /* dest */ int startx, int starty, int endx, int endy,          /* dest */ int startx, int starty, int endx, int endy,
1075          /* pen */ PEN *pen)          /* pen */ PEN * pen)
1076  {  {
1077          xwin_set_function(opcode);          SET_FUNCTION(opcode);
1078            SET_FOREGROUND(pen->colour);
         XSetForeground(display, gc, Ctrans(pen->colour));  
1079          XDrawLine(display, wnd, gc, startx, starty, endx, endy);          XDrawLine(display, wnd, gc, startx, starty, endx, endy);
1080            if (ownbackstore)
1081                    XDrawLine(display, backstore, gc, startx, starty, endx, endy);
1082            RESET_FUNCTION(opcode);
1083  }  }
1084    
1085  void  void
# Line 782  ui_rect( Line 1087  ui_rect(
1087                 /* dest */ int x, int y, int cx, int cy,                 /* dest */ int x, int y, int cx, int cy,
1088                 /* brush */ int colour)                 /* brush */ int colour)
1089  {  {
1090          xwin_set_function(ROP2_COPY);          SET_FOREGROUND(colour);
1091            FILL_RECTANGLE(x, y, cx, cy);
         XSetForeground(display, gc, Ctrans(colour));  
         XFillRectangle(display, wnd, gc, x, y, cx, cy);  
1092  }  }
1093    
1094  void  void
1095  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
1096                /* dest */ int x, int y, int cx, int cy,                /* dest */ int x, int y, int cx, int cy,
1097                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy,
1098                int fgcolour)                int bgcolour, int fgcolour)
1099  {  {
1100          Pixmap pixmap = (Pixmap) glyph;          SET_FOREGROUND(fgcolour);
1101            SET_BACKGROUND(bgcolour);
         xwin_set_function(ROP2_COPY);  
   
   
         XSetForeground(display, gc, Ctrans(fgcolour));  
         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;  
1102    
1103                  case MIX_OPAQUE:          XSetFillStyle(display, gc,
1104                          XSetBackground(display, gc, Ctrans(bgcolour));                        (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
1105  /*      XCopyPlane (display, pixmap, back_pixmap, back_gc, srcx, srcy, cx, cy, x, y, 1); */          XSetStipple(display, gc, (Pixmap) glyph);
1106                          XSetStipple(display, gc, pixmap);          XSetTSOrigin(display, gc, x, y);
1107                          XSetFillStyle(display, gc, FillOpaqueStippled);  
1108                          XSetTSOrigin(display, gc, x, y);          FILL_RECTANGLE(x, y, cx, cy);
1109                          XFillRectangle(display, wnd, gc, x, y, cx, cy);  
1110                          XSetFillStyle(display, gc, FillSolid);          XSetFillStyle(display, gc, FillSolid);
1111                          break;  }
1112    
1113                  default:  #define DO_GLYPH(ttext,idx) \
1114                          NOTIMP("mix %d\n", mixmode);  {\
1115          }    glyph = cache_get_font (font, ttext[idx]);\
1116      if (!(flags & TEXT2_IMPLICIT_X))\
1117        {\
1118          xyoffset = ttext[++idx];\
1119          if ((xyoffset & 0x80))\
1120            {\
1121              if (flags & TEXT2_VERTICAL) \
1122                y += ttext[idx+1] | (ttext[idx+2] << 8);\
1123              else\
1124                x += ttext[idx+1] | (ttext[idx+2] << 8);\
1125              idx += 2;\
1126            }\
1127          else\
1128            {\
1129              if (flags & TEXT2_VERTICAL) \
1130                y += xyoffset;\
1131              else\
1132                x += xyoffset;\
1133            }\
1134        }\
1135      if (glyph != NULL)\
1136        {\
1137          ui_draw_glyph (mixmode, x + (short) glyph->offset,\
1138                         y + (short) glyph->baseline,\
1139                         glyph->width, glyph->height,\
1140                         glyph->pixmap, 0, 0, bgcolour, fgcolour);\
1141          if (flags & TEXT2_IMPLICIT_X)\
1142            x += glyph->width;\
1143        }\
1144  }  }
1145    
1146  void  void
1147  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,
1148               int clipx, int clipy, int clipcx, int clipcy,               int clipx, int clipy, int clipcx, int clipcy,
1149               int boxx, int boxy, int boxcx, int boxcy,               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,
1150               int bgcolour, int fgcolour, uint8 *text, uint8 length)               int fgcolour, uint8 * text, uint8 length)
1151  {  {
1152          FONTGLYPH *glyph;          FONTGLYPH *glyph;
1153          int i, xyoffset;          int i, j, xyoffset;
1154            DATABLOB *entry;
1155    
1156          xwin_set_function(ROP2_COPY);          SET_FOREGROUND(bgcolour);
         XSetForeground(display, gc, Ctrans(bgcolour));  
1157    
1158          if (boxcx > 1)          if (boxcx > 1)
1159                  XFillRectangle(display, wnd, gc, boxx, boxy, boxcx, boxcy);          {
1160                    FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);
1161            }
1162          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
1163                  XFillRectangle(display, wnd, gc, clipx, clipy, clipcx, clipcy);          {
1164                    FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);
1165            }
1166    
1167          /* Paint text, character by character */          /* Paint text, character by character */
1168          for (i = 0; i < length; i++)          for (i = 0; i < length;)
1169          {          {
1170                  glyph = cache_get_font(font, text[i]);                  switch (text[i])
   
                 if (!(flags & TEXT2_IMPLICIT_X))  
   
1171                  {                  {
1172                          xyoffset = text[++i];                          case 0xff:
1173                          if ((xyoffset & 0x80))                                  if (i + 2 < length)
1174                          {                                          cache_put_text(text[i + 1], text, text[i + 2]);
                                 if (flags & 0x04)       /* vertical text */  
                                         y += text[++i] | (text[++i] << 8);  
1175                                  else                                  else
1176                                          x += text[++i] | (text[++i] << 8);                                  {
1177                          }                                          error("this shouldn't be happening\n");
1178                          else                                          break;
1179                          {                                  }
1180                                  if (flags & 0x04)       /* vertical text */                                  /* this will move pointer from start to first character after FF command */
1181                                          y += xyoffset;                                  length -= i + 3;
1182                                  else                                  text = &(text[i + 3]);
1183                                          x += xyoffset;                                  i = 0;
1184                          }                                  break;
1185    
1186                  }                          case 0xfe:
1187                  if (glyph != NULL)                                  entry = cache_get_text(text[i + 1]);
1188                  {                                  if (entry != NULL)
1189                          ui_draw_glyph(mixmode, x + (short) glyph->offset,                                  {
1190                                        y + (short) glyph->baseline,                                          if ((((uint8 *) (entry->data))[1] ==
1191                                        glyph->width, glyph->height,                                               0) && (!(flags & TEXT2_IMPLICIT_X)))
1192                                        glyph->pixmap, 0, 0,                                          {
1193                                        bgcolour, fgcolour);                                                  if (flags & TEXT2_VERTICAL)
1194                                                            y += text[i + 2];
1195                                                    else
1196                                                            x += text[i + 2];
1197                                            }
1198                                            if (i + 2 < length)
1199                                                    i += 3;
1200                                            else
1201                                                    i += 2;
1202                                            length -= i;
1203                                            /* this will move pointer from start to first character after FE command */
1204                                            text = &(text[i]);
1205                                            i = 0;
1206                                            for (j = 0; j < entry->size; j++)
1207                                                    DO_GLYPH(((uint8 *) (entry->data)), j);
1208                                    }
1209                                    break;
1210    
1211                          if (flags & TEXT2_IMPLICIT_X)                          default:
1212                                  x += glyph->width;                                  DO_GLYPH(text, i);
1213                                    i++;
1214                                    break;
1215                  }                  }
1216          }          }
1217    
1218    
1219  }  }
1220    
1221  void  void
# Line 887  ui_desktop_save(uint32 offset, int x, in Line 1224  ui_desktop_save(uint32 offset, int x, in
1224          Pixmap pix;          Pixmap pix;
1225          XImage *image;          XImage *image;
1226    
1227          pix = XCreatePixmap(display, wnd, cx, cy, depth);          if (ownbackstore)
1228          xwin_set_function(ROP2_COPY);          {
1229                    image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes, ZPixmap);
1230          XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);          }
1231          image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);          else
1232            {
1233                    pix = XCreatePixmap(display, wnd, cx, cy, depth);
1234                    XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
1235                    image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
1236                    XFreePixmap(display, pix);
1237            }
1238    
1239          offset *= bpp/8;          offset *= bpp / 8;
1240          cache_put_desktop(offset, cx, cy, image->bytes_per_line,          cache_put_desktop(offset, cx, cy, image->bytes_per_line, bpp / 8, (uint8 *) image->data);
                           bpp/8, image->data);  
1241    
1242          XDestroyImage(image);          XDestroyImage(image);
         XFreePixmap(display, pix);  
1243  }  }
1244    
1245  void  void
# Line 907  ui_desktop_restore(uint32 offset, int x, Line 1248  ui_desktop_restore(uint32 offset, int x,
1248          XImage *image;          XImage *image;
1249          uint8 *data;          uint8 *data;
1250    
1251          offset *= bpp/8;          offset *= bpp / 8;
1252          data = cache_get_desktop(offset, cx, cy, bpp/8);          data = cache_get_desktop(offset, cx, cy, bpp / 8);
1253          if (data == NULL)          if (data == NULL)
1254                  return;                  return;
         image =  
                 XCreateImage(display, visual,  
                              depth, ZPixmap,  
                              0, data, cx, cy, BitmapPad(display),  
                              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  
1255    
1256  static uint8 *          image = XCreateImage(display, visual, depth, ZPixmap, 0,
1257  translate(int width, int height, uint8 *data)                               (char *) data, cx, cy, BitmapPad(display), cx * bpp / 8);
 {  
         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;)}  
                 }  
         }  
1258    
1259  #else /* bigendian-compiled */          if (ownbackstore)
         if (screen_msbfirst)  
1260          {          {
1261                  /* big-endian screen */                  XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
1262                  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;)}  
                 }  
1263          }          }
1264          else          else
1265          {          {
1266                  /* 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;)}  
                 }  
1267          }          }
 #endif  
1268    
1269          return d2;          XFree(image);
1270  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26