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

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

  ViewVC Help
Powered by ViewVC 1.1.26