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

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

  ViewVC Help
Powered by ViewVC 1.1.26