/[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 101 by astrand, Mon Aug 26 17:12:43 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  static void
104  xwin_set_function(uint8 rop2)  translate8(uint8 * data, uint8 * out, uint8 * end)
105  {  {
106          static uint8 last_rop2 = ROP2_COPY;          while (out < end)
107                    *(out++) = (uint8) colmap[*(data++)];
108    }
109    
110          if (last_rop2 != rop2)  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
119    translate24(uint8 * data, uint8 * out, uint8 * end)
120    {
121            uint32 value;
122    
123            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            while (out < end)
136                    *(out++) = colmap[*(data++)];
137    }
138    
139    static uint8 *
140    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          XGrabKeyboard(display, wnd, True, GrabModeAsync, GrabModeAsync,          switch (bpp)
177                        CurrentTime);          {
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    static unsigned long
198    init_inputmethod(void)
199    {
200            unsigned long filtered_events = 0;
201    
202            IM = XOpenIM(display, NULL, NULL, NULL);
203            if (IM == NULL)
204            {
205                    error("Failed to open input method\n");
206            }
207    
208            if (IM != NULL)
209            {
210                    /* 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                            error("Failed to create input context\n");
218                            XCloseIM(IM);
219                            IM = NULL;
220                    }
221            }
222    
223            /* For correct Multi_key/Compose processing, I guess.
224               It seems to work alright anyway, though. */
225            if (IC != NULL)
226            {
227                    if (XGetICValues(IC, XNFilterEvents, &filtered_events, NULL) != NULL)
228                    {
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  static void
237  xwin_ungrab_keyboard()  close_inputmethod(void)
238  {  {
239          XUngrabKeyboard(display, CurrentTime);          if (IC != NULL)
240            {
241                    XDestroyIC(IC);
242                    if (IM != NULL)
243                    {
244                            XCloseIM(IM);
245                            IM = NULL;
246                    }
247            }
248  }  }
249    
250  BOOL  BOOL
251  ui_create_window(char *title)  ui_init()
252  {  {
253          XSetWindowAttributes attribs;          Screen *screen;
         XClassHint *classhints;  
         XSizeHints *sizehints;  
         unsigned long input_mask;  
         XPixmapFormatValues *pfm;  
         int count;  
   
254          display = XOpenDisplay(NULL);          display = XOpenDisplay(NULL);
255          if (display == NULL)          if (display == NULL)
256          {          {
257                  ERROR("Failed to open display\n");                  error("Failed to open display\n");
258                  return False;                  return False;
259          }          }
260            if (fullscreen)
261            {
262                    screen = DefaultScreenOfDisplay(display);
263                    width = WidthOfScreen(screen);
264                    height = HeightOfScreen(screen);
265            }
266            return True;
267    }
268    
269    BOOL
270    ui_create_window_obj(int xpos, int ypos, int width, int height, int valuemask)
271    {
272            XClassHint *classhints;
273            XSizeHints *sizehints;
274            XEvent xevent;
275            Screen *screen;
276    
277            screen = DefaultScreenOfDisplay(display);
278    
279            wnd = XCreateWindow(display, RootWindowOfScreen(screen), xpos,
280                                ypos, width, height, 0, CopyFromParent,
281                                InputOutput, CopyFromParent, valuemask, &attribs);
282    
283    
284            XStoreName(display, wnd, title);
285    
286            classhints = XAllocClassHint();
287            if (classhints != NULL)
288            {
289                    classhints->res_name = classhints->res_class = "rdesktop";
290                    XSetClassHint(display, wnd, classhints);
291                    XFree(classhints);
292            }
293    
294            sizehints = XAllocSizeHints();
295            if (sizehints)
296            {
297                    sizehints->flags = PMinSize | PMaxSize;
298                    sizehints->min_width = sizehints->max_width = width;
299                    sizehints->min_height = sizehints->max_height = height;
300                    XSetWMNormalHints(display, wnd, sizehints);
301                    XFree(sizehints);
302            }
303    
304            if (enable_compose)
305                    input_mask |= init_inputmethod();
306    
307          visual = DefaultVisual(display, DefaultScreen(display));          XSelectInput(display, wnd, input_mask);
308          depth = DefaultDepth(display, DefaultScreen(display));  
309          pfm = XListPixmapFormats(display, &count);          gc = XCreateGC(display, wnd, 0, NULL);
310    
311            XMapWindow(display, wnd);
312    
313            /* Wait for VisibilityNotify Event */
314            for (;;)
315            {
316                    XNextEvent(display, &xevent);
317                    if (xevent.type == VisibilityNotify)
318                            break;
319            }
320    
321            if (ownbackstore)
322                    backstore = XCreatePixmap(display, wnd, width, height, depth);
323    
324            /* clear the window so that cached data is not viewed upon start... */
325            XSetBackground(display, gc, 0);
326            XSetForeground(display, gc, 0);
327            FILL_RECTANGLE(0, 0, width, height);
328            /* make sure the window is focused */
329            XSetInputFocus(display, wnd, RevertToPointerRoot, CurrentTime);
330    }
331    
332    BOOL
333    ui_create_window()
334    {
335            XPixmapFormatValues *pfm;
336            Screen *screen;
337            uint16 test;
338            int i;
339    
340            x_socket = ConnectionNumber(display);
341            screen = DefaultScreenOfDisplay(display);
342            visual = DefaultVisualOfScreen(screen);
343            depth = DefaultDepthOfScreen(screen);
344    
345            pfm = XListPixmapFormats(display, &i);
346          if (pfm != NULL)          if (pfm != NULL)
347          {          {
348                  while (count--)                  /* Use maximum bpp for this depth - this is generally
349                       desirable, e.g. 24 bits->32 bits. */
350                    while (i--)
351                  {                  {
352                          if ((pfm + count)->depth == depth                          if ((pfm[i].depth == depth) && (pfm[i].bits_per_pixel > bpp))
                             && (pfm + count)->bits_per_pixel > bpp)  
353                          {                          {
354                                  bpp = (pfm + count)->bits_per_pixel;                                  bpp = pfm[i].bits_per_pixel;
355                          }                          }
356                  }                  }
357                  XFree(pfm);                  XFree(pfm);
# Line 124  ui_create_window(char *title) Line 359  ui_create_window(char *title)
359    
360          if (bpp < 8)          if (bpp < 8)
361          {          {
362                  ERROR("Less than 8 bpp not currently supported.\n");                  error("Less than 8 bpp not currently supported.\n");
363                  XCloseDisplay(display);                  XCloseDisplay(display);
364                  return False;                  return False;
365          }          }
366    
367          width &= ~3; /* make width nicely divisible */          if (depth <= 8)
368                    owncolmap = True;
369            else
370                    xcolmap = DefaultColormapOfScreen(screen);
371    
372            test = 1;
373            host_be = !(BOOL) (*(uint8 *) (&test));
374            xserver_be = (ImageByteOrder(display) == MSBFirst);
375    
376            white = WhitePixelOfScreen(screen);
377            attribs.background_pixel = BlackPixelOfScreen(screen);
378            attribs.backing_store = DoesBackingStore(screen);
379    
380          attribs.background_pixel = BlackPixel(display, DefaultScreen(display));          if (attribs.backing_store == NotUseful)
381          attribs.backing_store = Always;                  ownbackstore = True;
382    
383            dpy_width = WidthOfScreen(screen);
384            dpy_height = HeightOfScreen(screen);
385    
386          if (fullscreen)          if (fullscreen)
387          {          {
388                  attribs.override_redirect = True;                  attribs.override_redirect = True;
389                  width = WidthOfScreen(DefaultScreenOfDisplay(display));                  width = dpy_width;
390                  height = HeightOfScreen(DefaultScreenOfDisplay(display));                  height = dpy_height;
                 XSetInputFocus(display, PointerRoot, RevertToPointerRoot,  
                                CurrentTime);  
391          }          }
392          else          else
393          {          {
394                  attribs.override_redirect = False;                  attribs.override_redirect = False;
395          }          }
396    
397          wnd = XCreateWindow(display, DefaultRootWindow(display),          width = (width + 3) & ~3;       /* make width a multiple of 32 bits */
                             0, 0, width, height, 0, CopyFromParent,  
                             InputOutput, CopyFromParent,  
                             CWBackingStore | CWBackPixel | CWOverrideRedirect,  
                             &attribs);  
398    
         XStoreName(display, wnd, title);  
399    
400          classhints = XAllocClassHint();          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
401          if (classhints != NULL)                  VisibilityChangeMask | FocusChangeMask;
   
         {  
                 classhints->res_name = "rdesktop";  
                 classhints->res_class = "rdesktop";  
                 XSetClassHint(display, wnd, classhints);  
                 XFree(classhints);  
         }  
402    
         sizehints = XAllocSizeHints();  
         if (sizehints)  
         {  
                 sizehints->flags =  
                         PPosition | PSize | PMinSize | PMaxSize | PBaseSize;  
                 sizehints->min_width = width;  
                 sizehints->max_width = width;  
                 sizehints->min_height = height;  
                 sizehints->max_height = height;  
                 sizehints->base_width = width;  
                 sizehints->base_height = height;  
                 XSetWMNormalHints(display, wnd, sizehints);  
                 XFree(sizehints);  
         }  
   
         input_mask = KeyPressMask | KeyReleaseMask;  
         input_mask |= ButtonPressMask | ButtonReleaseMask;  
         if (motion)  
                 input_mask |= PointerMotionMask;  
403          if (grab_keyboard)          if (grab_keyboard)
404                  input_mask |= EnterWindowMask | LeaveWindowMask;                  input_mask |= EnterWindowMask | LeaveWindowMask;
405            if (sendmotion)
406                    input_mask |= PointerMotionMask;
407    
408          XSelectInput(display, wnd, input_mask);          if (ownbackstore)
409          gc = XCreateGC(display, wnd, 0, NULL);                  input_mask |= ExposureMask;
410    
411            if (fullscreen)
412                    ui_create_window_obj(0, 0, width, height,
413                                         CWBackingStore | CWBackPixel | CWOverrideRedirect);
414            else
415                    ui_create_window_obj(0, 0, width, height, CWBackingStore | CWBackPixel);
416    
417            xkeymap_init2();
418    
         XMapWindow(display, wnd);  
419          return True;          return True;
420  }  }
421    
422  void  void
423  ui_destroy_window()  ui_destroy_window()
424  {  {
425            if (ownbackstore)
426                    XFreePixmap(display, backstore);
427    
428          XFreeGC(display, gc);          XFreeGC(display, gc);
429    
430            close_inputmethod();
431    
432          XDestroyWindow(display, wnd);          XDestroyWindow(display, wnd);
433          XCloseDisplay(display);          XCloseDisplay(display);
434          display = NULL;          display = NULL;
435  }  }
436    
437  static uint8  void
438  xwin_translate_key(unsigned long key)  reset_keys()
439  {  {
440          DEBUG("KEY(code=0x%lx)\n", key);          /* reset keys */
441            uint32 ev_time;
442            ev_time = time(NULL);
443            rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
444            rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LALT);
445            rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
446            rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RCTRL);
447            rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
448            rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
449    }
450    
451          if ((key > 8) && (key <= 0x60))  void
452                  return (key - 8);  toggle_fullscreen()
453    {
454            /* save window contents */
455            Pixmap pixmap;
456            pixmap = XCreatePixmap(display, wnd, width, height, depth);
457            if (ownbackstore)
458                    XCopyArea(display, backstore, pixmap, gc, 0, 0, width, height, 0, 0);
459            else
460                    XCopyArea(display, wnd, pixmap, gc, 0, 0, width, height, 0, 0);
461            fullscreen = fullscreen ? False : True;
462            close_inputmethod();
463            if (ownbackstore)
464                    XFreePixmap(display, backstore);
465            XFreeGC(display, gc);
466            XDestroyWindow(display, wnd);
467            if (fullscreen)
468            {
469                    attribs.override_redirect = True;
470                    ui_create_window_obj(0, 0, dpy_width, dpy_height,
471                                         CWBackingStore | CWBackPixel | CWOverrideRedirect);
472            }
473            else
474            {
475                    attribs.override_redirect = False;
476                    ui_create_window_obj(0, 0, width, height, CWBackingStore | CWBackPixel);
477            }
478            ui_set_cursor(cache_get_cursor(0));
479            ui_move_pointer(width / 2, height / 2);
480            reset_keys();
481            /* restore window contents */
482            if (ownbackstore)
483                    XCopyArea(display, pixmap, backstore, gc, 0, 0, width, height, 0, 0);
484            XCopyArea(display, pixmap, wnd, gc, 0, 0, width, height, 0, 0);
485            XFreePixmap(display, pixmap);
486    }
487    
488    static void
489    xwin_process_events()
490    {
491            XEvent xevent;
492    
493          switch (key)          KeySym keysym;
494          {          uint16 button, flags;
                 case 0x61:      /* home */  
                         return 0x47 | 0x80;  
                 case 0x62:      /* up arrow */  
                         return 0x48 | 0x80;  
                 case 0x63:      /* page up */  
                         return 0x49 | 0x80;  
                 case 0x64:      /* left arrow */  
                         return 0x4b | 0x80;  
                 case 0x66:      /* right arrow */  
                         return 0x4d | 0x80;  
                 case 0x67:      /* end */  
                         return 0x4f | 0x80;  
                 case 0x68:      /* down arrow */  
                         return 0x50 | 0x80;  
                 case 0x69:      /* page down */  
                         return 0x51 | 0x80;  
                 case 0x6a:      /* insert */  
                         return 0x52 | 0x80;  
                 case 0x6b:      /* delete */  
                         return 0x53 | 0x80;  
                 case 0x6c:      /* keypad enter */  
                         return 0x1c | 0x80;  
                 case 0x6d:      /* right ctrl */  
                         return 0x1d | 0x80;  
                 case 0x6f:      /* ctrl - print screen */  
                         return 0x37 | 0x80;  
                 case 0x70:      /* keypad '/' */  
                         return 0x35 | 0x80;  
                 case 0x71:      /* right alt */  
                         return 0x38 | 0x80;  
                 case 0x72:      /* ctrl break */  
                         return 0x46 | 0x80;  
                 case 0x73:      /* left window key */  
                         return 0xff;    /* real scancode is 5b */  
                 case 0x74:      /* right window key */  
                         return 0xff;    /* real scancode is 5c */  
                 case 0x75:      /* menu key */  
                         return 0x5d | 0x80;  
         }  
   
         return 0;  
 }  
   
 static uint16  
 xwin_translate_mouse(unsigned long button)  
 {  
         switch (button)  
         {  
                 case Button1:   /* left */  
                         return MOUSE_FLAG_BUTTON1;  
                 case Button2:   /* middle */  
                         return MOUSE_FLAG_BUTTON3;  
                 case Button3:   /* right */  
                         return MOUSE_FLAG_BUTTON2;  
         }  
   
         return 0;  
 }  
   
 void  
 ui_process_events()  
 {  
         XEvent event;  
         uint8 scancode;  
         uint16 button;  
495          uint32 ev_time;          uint32 ev_time;
496            key_translation tr;
497            char *ksname = NULL;
498            char str[256];
499            Status status;
500    
501          if (display == NULL)          /* Refresh keyboard mapping if it has changed. This is important for
502                  return;             Xvnc, since it allocates keycodes dynamically */
503            if (XCheckTypedEvent(display, MappingNotify, &xevent))
504            {
505                    if (xevent.xmapping.request == MappingKeyboard
506                        || xevent.xmapping.request == MappingModifier)
507                            XRefreshKeyboardMapping(&xevent.xmapping);
508            }
509    
510          while (XCheckWindowEvent(display, wnd, ~0, &event))          while (XCheckMaskEvent(display, ~0, &xevent))
511          {          {
512                    if (enable_compose && (XFilterEvent(&xevent, None) == True))
513                    {
514                            DEBUG_KBD(("Filtering event\n"));
515                            continue;
516                    }
517    
518                  ev_time = time(NULL);                  ev_time = time(NULL);
519                    flags = 0;
520    
521                  switch (event.type)                  switch (xevent.type)
522                  {                  {
523                          case KeyPress:                          case KeyPress:
524                                  scancode = xwin_translate_key(event.xkey.keycode);                                  if (IC != NULL)
525                                  if (scancode == 0)                                          /* Multi_key compatible version */
526                                    {
527                                            XmbLookupString(IC,
528                                                            (XKeyPressedEvent *) &
529                                                            xevent, str, sizeof(str), &keysym, &status);
530                                            if (!((status == XLookupKeySym) || (status == XLookupBoth)))
531                                            {
532                                                    error("XmbLookupString failed with status 0x%x\n",
533                                                          status);
534                                                    break;
535                                            }
536                                    }
537                                    else
538                                    {
539                                            /* Plain old XLookupString */
540                                            DEBUG_KBD(("No input context, using XLookupString\n"));
541                                            XLookupString((XKeyEvent *) & xevent,
542                                                          str, sizeof(str), &keysym, NULL);
543                                    }
544    
545                                    /* FIXME needs alt modifier */
546                                    if (keysym == XK_Break) /* toggle full screen */
547                                    {
548                                            toggle_fullscreen();
549                                          break;                                          break;
550                                    }
551                                    ksname = get_ksname(keysym);
552                                    DEBUG_KBD(("\nKeyPress for (keysym 0x%lx, %s)\n", keysym, ksname));
553    
554                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0,                                  if (inhibit_key(keysym))
555                                                 scancode, 0);                                  {
556                                  break;                                          DEBUG_KBD(("Inhibiting key\n"));
557                                            break;
558                                    }
559    
560                          case KeyRelease:                                  tr = xkeymap_translate_key(keysym,
561                                  scancode = xwin_translate_key(event.xkey.keycode);                                                             xevent.xkey.keycode, xevent.xkey.state);
562                                  if (scancode == 0)  
563                                    ensure_remote_modifiers(ev_time, tr);
564    
565                                    if (tr.scancode == 0)
566                                          break;                                          break;
567    
568                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE,                                  rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
                                                KBD_FLAG_DOWN | KBD_FLAG_UP,  
                                                scancode, 0);  
569                                  break;                                  break;
570                            case KeyRelease:
571                                    XLookupString((XKeyEvent *) & xevent, str,
572                                                  sizeof(str), &keysym, NULL);
573    
574                          case ButtonPress:                                  ksname = get_ksname(keysym);
575                                  button = xwin_translate_mouse(event.xbutton.button);                                  DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,
576                                  if (button == 0)                                             ksname));
577    
578                                    if (inhibit_key(keysym))
579                                          break;                                          break;
580    
581                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  tr = xkeymap_translate_key(keysym,
582                                                 button | MOUSE_FLAG_DOWN,                                                             xevent.xkey.keycode, xevent.xkey.state);
583                                                 event.xbutton.x,  
584                                                 event.xbutton.y);                                  if (tr.scancode == 0)
585                                            break;
586    
587                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);
588                                  break;                                  break;
589    
590                            case ButtonPress:
591                                    flags = MOUSE_FLAG_DOWN;
592                                    /* fall through */
593    
594                          case ButtonRelease:                          case ButtonRelease:
595                                  button = xwin_translate_mouse(event.xbutton.button);                                  button = xkeymap_translate_button(xevent.xbutton.button);
596                                  if (button == 0)                                  if (button == 0)
597                                          break;                                          break;
598    
599                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,
600                                                 button,                                                 flags | button, xevent.xbutton.x, xevent.xbutton.y);
                                                event.xbutton.x,  
                                                event.xbutton.y);  
601                                  break;                                  break;
602    
603                          case MotionNotify:                          case MotionNotify:
604                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,
605                                                 MOUSE_FLAG_MOVE,                                                 MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
                                                event.xmotion.x,  
                                                event.xmotion.y);  
606                                  break;                                  break;
607    
608                            case FocusIn:
609                                    /* fall through */
610                          case EnterNotify:                          case EnterNotify:
611                                  if (grab_keyboard)                                  if (grab_keyboard)
612                                          xwin_grab_keyboard();                                          XGrabKeyboard(display, wnd, True,
613                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
614                                  break;                                  break;
615    
616                            case FocusOut:
617                                    reset_keys();
618                                    /* fall through */
619                          case LeaveNotify:                          case LeaveNotify:
620                                  if (grab_keyboard)                                  if (grab_keyboard)
621                                          xwin_ungrab_keyboard();                                          XUngrabKeyboard(display, CurrentTime);
622                                  break;                                  break;
623    
624                            case Expose:
625                                    XCopyArea(display, backstore, wnd, gc,
626                                              xevent.xexpose.x, xevent.xexpose.y,
627                                              xevent.xexpose.width,
628                                              xevent.xexpose.height,
629                                              xevent.xexpose.x, xevent.xexpose.y);
630                                    break;
631                    }
632            }
633    }
634    
635    void
636    ui_select(int rdp_socket)
637    {
638            int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;
639            fd_set rfds;
640    
641            FD_ZERO(&rfds);
642    
643            while (True)
644            {
645                    FD_ZERO(&rfds);
646                    FD_SET(rdp_socket, &rfds);
647                    if (display != NULL)
648                    {
649                            FD_SET(x_socket, &rfds);
650                            XFlush(display);
651                    }
652    
653                    switch (select(n, &rfds, NULL, NULL, NULL))
654                    {
655                            case -1:
656                                    error("select: %s\n", strerror(errno));
657    
658                            case 0:
659                                    continue;
660                  }                  }
661    
662                    if (FD_ISSET(x_socket, &rfds))
663                            xwin_process_events();
664    
665                    if (FD_ISSET(rdp_socket, &rfds))
666                            return;
667          }          }
668  }  }
669    
# Line 357  ui_move_pointer(int x, int y) Line 674  ui_move_pointer(int x, int y)
674  }  }
675    
676  HBITMAP  HBITMAP
677  ui_create_bitmap(int width, int height, uint8 *data)  ui_create_bitmap(int width, int height, uint8 * data)
678  {  {
679          XImage *image;          XImage *image;
680          Pixmap bitmap;          Pixmap bitmap;
681          uint8 *tdata;          uint8 *tdata;
682          tdata = (private_colormap ? data : translate(width, height, data));  
683            tdata = (owncolmap ? data : translate_image(width, height, data));
684          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(display, wnd, width, height, depth);
685          image =          image = XCreateImage(display, visual, depth, ZPixmap, 0,
686                  XCreateImage(display, visual,                               (char *) tdata, width, height, 8, 0);
                              depth, ZPixmap,  
                              0, tdata, width, height, BitmapPad(display), 0);  
687    
         xwin_set_function(ROP2_COPY);  
688          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
689    
690          XFree(image);          XFree(image);
691          if (!private_colormap)          if (!owncolmap)
692                  xfree(tdata);                  xfree(tdata);
693          return (HBITMAP) bitmap;          return (HBITMAP) bitmap;
694  }  }
695    
696  void  void
697  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)  
698  {  {
699          XImage *image;          XImage *image;
700          uint8 *tdata =          uint8 *tdata;
                 (private_colormap ? data : translate(width, height, data));  
         image =  
                 XCreateImage(display, visual, depth, ZPixmap, 0, tdata, width,  
                              height, BitmapPad(display), 0);  
   
         xwin_set_function(ROP2_COPY);  
   
         /* Window */  
         XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);  
         XFree(image);  
         if (!private_colormap)  
                 xfree(tdata);  
 }  
   
 void  
 ui_destroy_bitmap(HBITMAP bmp)  
 {  
         XFreePixmap(display, (Pixmap) bmp);  
 }  
701    
702  HCURSOR          tdata = (owncolmap ? data : translate_image(width, height, data));
703  ui_create_cursor(unsigned int x, unsigned int y, int width,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
704                   int height, uint8 *mask, uint8 *data)                               (char *) tdata, width, height, 8, 0);
 {  
         XImage *imagecursor;  
         XImage *imagemask;  
         Pixmap maskbitmap, cursorbitmap;  
         Cursor cursor;  
         XColor bg, fg;  
         GC lgc;  
         int i, x1, y1, scanlinelen;  
         uint8 *cdata, *cmask;  
         uint8 c;  
         cdata = (uint8 *) malloc(sizeof(uint8) * width * height);  
         if (!cdata)  
                 return NULL;  
         scanlinelen = (width + 7) >> 3;  
         cmask = (uint8 *) malloc(sizeof(uint8) * scanlinelen * height);  
         if (!cmask)  
         {  
                 free(cdata);  
                 return NULL;  
         }  
         i = (height - 1) * scanlinelen;  
705    
706          if (!screen_msbfirst)          if (ownbackstore)
707          {          {
708                  while (i >= 0)                  XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
709                  {                  XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
                         for (x1 = 0; x1 < scanlinelen; x1++)  
                         {  
                                 c = *(mask++);  
                                 cmask[i + x1] =  
                                         ((c & 0x1) << 7) | ((c & 0x2) << 5) |  
                                         ((c & 0x4) << 3) | ((c & 0x8) << 1) |  
                                         ((c & 0x10) >> 1) | ((c & 0x20) >> 3)  
                                         | ((c & 0x40) >> 5) | ((c & 0x80) >>  
                                                                7);  
                         }  
                         i -= scanlinelen;  
                 }  
710          }          }
711          else          else
712          {          {
713                  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;  
                 }  
714          }          }
715    
716            XFree(image);
717          fg.red = 0;          if (!owncolmap)
718          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);  
719  }  }
720    
721  void  void
722  ui_destroy_cursor(HCURSOR cursor)  ui_destroy_bitmap(HBITMAP bmp)
723  {  {
724          XFreeCursor(display, (Cursor) cursor);          XFreePixmap(display, (Pixmap) bmp);
725  }  }
726    
727  HGLYPH  HGLYPH
728  ui_create_glyph(int width, int height, uint8 *data)  ui_create_glyph(int width, int height, uint8 * data)
729  {  {
730          XImage *image;          XImage *image;
731          Pixmap bitmap;          Pixmap bitmap;
# Line 538  ui_create_glyph(int width, int height, u Line 737  ui_create_glyph(int width, int height, u
737          bitmap = XCreatePixmap(display, wnd, width, height, 1);          bitmap = XCreatePixmap(display, wnd, width, height, 1);
738          gc = XCreateGC(display, bitmap, 0, NULL);          gc = XCreateGC(display, bitmap, 0, NULL);
739    
740          image = XCreateImage(display, visual, 1, ZPixmap, 0,          image = XCreateImage(display, visual, 1, ZPixmap, 0, (char *) data,
741                               data, width, height, 8, scanline);                               width, height, 8, scanline);
742          image->byte_order = MSBFirst;          image->byte_order = MSBFirst;
743          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
744          XInitImage(image);          XInitImage(image);
745    
         XSetFunction(display, gc, GXcopy);  
746          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
747    
748          XFree(image);          XFree(image);
749          XFreeGC(display, gc);          XFreeGC(display, gc);
   
750          return (HGLYPH) bitmap;          return (HGLYPH) bitmap;
751  }  }
752    
# Line 558  ui_destroy_glyph(HGLYPH glyph) Line 756  ui_destroy_glyph(HGLYPH glyph)
756          XFreePixmap(display, (Pixmap) glyph);          XFreePixmap(display, (Pixmap) glyph);
757  }  }
758    
759  HCOLOURMAP  HCURSOR
760  ui_create_colourmap(COLOURMAP *colours)  ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
761                     uint8 * andmask, uint8 * xormask)
762  {  {
763          if (!private_colormap)          HGLYPH maskglyph, cursorglyph;
764            XColor bg, fg;
765            Cursor xcursor;
766            uint8 *cursor, *pcursor;
767            uint8 *mask, *pmask;
768            uint8 nextbit;
769            int scanline, offset;
770            int i, j;
771    
772            scanline = (width + 7) / 8;
773            offset = scanline * height;
774    
775            cursor = xmalloc(offset);
776            memset(cursor, 0, offset);
777    
778            mask = xmalloc(offset);
779            memset(mask, 0, offset);
780    
781            /* approximate AND and XOR masks with a monochrome X pointer */
782            for (i = 0; i < height; i++)
783          {          {
784                  COLOURENTRY *entry;                  offset -= scanline;
785                  int i, ncolours = colours->ncolours;                  pcursor = &cursor[offset];
786                  uint32 *nc = xmalloc(sizeof(*colmap) * ncolours);                  pmask = &mask[offset];
787                  for (i = 0; i < ncolours; i++)  
788                    for (j = 0; j < scanline; j++)
789                  {                  {
790                          XColor xc;                          for (nextbit = 0x80; nextbit != 0; nextbit >>= 1)
791                          entry = &colours->colours[i];                          {
792                          xc.red = entry->red << 8;                                  if (xormask[0] || xormask[1] || xormask[2])
793                          xc.green = entry->green << 8;                                  {
794                          xc.blue = entry->blue << 8;                                          *pcursor |= (~(*andmask) & nextbit);
795                          XAllocColor(display,                                          *pmask |= nextbit;
796                                      DefaultColormap(display,                                  }
797                                                      DefaultScreen(display)),                                  else
798                                      &xc);                                  {
799                          /* XXX Check return value */                                          *pcursor |= ((*andmask) & nextbit);
800                          nc[i] = xc.pixel;                                          *pmask |= (~(*andmask) & nextbit);
801                                    }
802    
803                                    xormask += 3;
804                            }
805    
806                            andmask++;
807                            pcursor++;
808                            pmask++;
809                  }                  }
                 return nc;  
810          }          }
811          else  
812            fg.red = fg.blue = fg.green = 0xffff;
813            bg.red = bg.blue = bg.green = 0x0000;
814            fg.flags = bg.flags = DoRed | DoBlue | DoGreen;
815    
816            cursorglyph = ui_create_glyph(width, height, cursor);
817            maskglyph = ui_create_glyph(width, height, mask);
818    
819            xcursor =
820                    XCreatePixmapCursor(display, (Pixmap) cursorglyph,
821                                        (Pixmap) maskglyph, &fg, &bg, x, y);
822    
823            ui_destroy_glyph(maskglyph);
824            ui_destroy_glyph(cursorglyph);
825            xfree(mask);
826            xfree(cursor);
827            return (HCURSOR) xcursor;
828    }
829    
830    void
831    ui_set_cursor(HCURSOR cursor)
832    {
833            XDefineCursor(display, wnd, (Cursor) cursor);
834    }
835    
836    void
837    ui_destroy_cursor(HCURSOR cursor)
838    {
839            XFreeCursor(display, (Cursor) cursor);
840    }
841    
842    #define MAKE_XCOLOR(xc,c) \
843                    (xc)->red   = ((c)->red   << 8) | (c)->red; \
844                    (xc)->green = ((c)->green << 8) | (c)->green; \
845                    (xc)->blue  = ((c)->blue  << 8) | (c)->blue; \
846                    (xc)->flags = DoRed | DoGreen | DoBlue;
847    
848    HCOLOURMAP
849    ui_create_colourmap(COLOURMAP * colours)
850    {
851            COLOURENTRY *entry;
852            int i, ncolours = colours->ncolours;
853    
854            if (owncolmap)
855          {          {
                 COLOURENTRY *entry;  
856                  XColor *xcolours, *xentry;                  XColor *xcolours, *xentry;
857                  Colormap map;                  Colormap map;
858                  int i, ncolours = colours->ncolours;  
859                  xcolours = xmalloc(sizeof(XColor) * ncolours);                  xcolours = xmalloc(sizeof(XColor) * ncolours);
860                  for (i = 0; i < ncolours; i++)                  for (i = 0; i < ncolours; i++)
861                  {                  {
862                          entry = &colours->colours[i];                          entry = &colours->colours[i];
863                          xentry = &xcolours[i];                          xentry = &xcolours[i];
   
864                          xentry->pixel = i;                          xentry->pixel = i;
865                          xentry->red = entry->red << 8;                          MAKE_XCOLOR(xentry, entry);
                         xentry->blue = entry->blue << 8;  
                         xentry->green = entry->green << 8;  
                         xentry->flags = DoRed | DoBlue | DoGreen;  
866                  }                  }
867    
868                  map = XCreateColormap(display, wnd, visual, AllocAll);                  map = XCreateColormap(display, wnd, visual, AllocAll);
# Line 607  ui_create_colourmap(COLOURMAP *colours) Line 871  ui_create_colourmap(COLOURMAP *colours)
871                  xfree(xcolours);                  xfree(xcolours);
872                  return (HCOLOURMAP) map;                  return (HCOLOURMAP) map;
873          }          }
874            else
875            {
876                    uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
877                    XColor xentry;
878                    uint32 colour;
879    
880                    for (i = 0; i < ncolours; i++)
881                    {
882                            entry = &colours->colours[i];
883                            MAKE_XCOLOR(&xentry, entry);
884    
885                            if (XAllocColor(display, xcolmap, &xentry) != 0)
886                                    colour = xentry.pixel;
887                            else
888                                    colour = white;
889    
890                            /* byte swap here to make translate_image faster */
891                            map[i] = translate_colour(colour);
892                    }
893    
894                    return map;
895            }
896  }  }
897    
898  void  void
899  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
900  {  {
901          XFreeColormap(display, (Colormap) map);          if (owncolmap)
902                    XFreeColormap(display, (Colormap) map);
903            else
904                    xfree(map);
905  }  }
906    
907  void  void
908  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
909  {  {
910            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  
         {  
911                  XSetWindowColormap(display, wnd, (Colormap) map);                  XSetWindowColormap(display, wnd, (Colormap) map);
912                  if (fullscreen)          else
913                          XInstallColormap(display, (Colormap) map);                  colmap = map;
         }  
914  }  }
915    
916  void  void
# Line 665  void Line 947  void
947  ui_destblt(uint8 opcode,  ui_destblt(uint8 opcode,
948             /* dest */ int x, int y, int cx, int cy)             /* dest */ int x, int y, int cx, int cy)
949  {  {
950          xwin_set_function(opcode);          SET_FUNCTION(opcode);
951            FILL_RECTANGLE(x, y, cx, cy);
952          XFillRectangle(display, wnd, gc, x, y, cx, cy);          RESET_FUNCTION(opcode);
953  }  }
954    
955  void  void
956  ui_patblt(uint8 opcode,  ui_patblt(uint8 opcode,
957            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
958            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
959  {  {
         Display *dpy = display;  
960          Pixmap fill;          Pixmap fill;
961          uint8 i, ipattern[8];          uint8 i, ipattern[8];
962    
963          xwin_set_function(opcode);          SET_FUNCTION(opcode);
964    
965          switch (brush->style)          switch (brush->style)
966          {          {
967                  case 0: /* Solid */                  case 0: /* Solid */
968                          XSetForeground(dpy, gc, Ctrans(fgcolour));                          SET_FOREGROUND(fgcolour);
969                          XFillRectangle(dpy, wnd, gc, x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
970                          break;                          break;
971    
972                  case 3: /* Pattern */                  case 3: /* Pattern */
973                          for (i = 0; i != 8; i++)                          for (i = 0; i != 8; i++)
974                                  ipattern[i] = ~brush->pattern[i];                                  ipattern[7 - i] = brush->pattern[i];
975                          fill = (Pixmap) ui_create_glyph(8, 8, ipattern);                          fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
976    
977                          XSetForeground(dpy, gc, Ctrans(fgcolour));                          SET_FOREGROUND(bgcolour);
978                          XSetBackground(dpy, gc, Ctrans(bgcolour));                          SET_BACKGROUND(fgcolour);
979                          XSetFillStyle(dpy, gc, FillOpaqueStippled);                          XSetFillStyle(display, gc, FillOpaqueStippled);
980                          XSetStipple(dpy, gc, fill);                          XSetStipple(display, gc, fill);
981                            XSetTSOrigin(display, gc, brush->xorigin, brush->yorigin);
982    
983                          XFillRectangle(dpy, wnd, gc, x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
984    
985                          XSetFillStyle(dpy, gc, FillSolid);                          XSetFillStyle(display, gc, FillSolid);
986                            XSetTSOrigin(display, gc, 0, 0);
987                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((HGLYPH) fill);
988                          break;                          break;
989    
990                  default:                  default:
991                          NOTIMP("brush %d\n", brush->style);                          unimpl("brush %d\n", brush->style);
992          }          }
993    
994            RESET_FUNCTION(opcode);
995  }  }
996    
997  void  void
# Line 714  ui_screenblt(uint8 opcode, Line 999  ui_screenblt(uint8 opcode,
999               /* dest */ int x, int y, int cx, int cy,               /* dest */ int x, int y, int cx, int cy,
1000               /* src */ int srcx, int srcy)               /* src */ int srcx, int srcy)
1001  {  {
1002          xwin_set_function(opcode);          SET_FUNCTION(opcode);
   
1003          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
1004            if (ownbackstore)
1005                    XCopyArea(display, backstore, backstore, gc, srcx, srcy, cx, cy, x, y);
1006            RESET_FUNCTION(opcode);
1007  }  }
1008    
1009  void  void
# Line 724  ui_memblt(uint8 opcode, Line 1011  ui_memblt(uint8 opcode,
1011            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1012            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ HBITMAP src, int srcx, int srcy)
1013  {  {
1014          xwin_set_function(opcode);          SET_FUNCTION(opcode);
   
1015          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
1016            if (ownbackstore)
1017                    XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy, cx, cy, x, y);
1018            RESET_FUNCTION(opcode);
1019  }  }
1020    
1021  void  void
1022  ui_triblt(uint8 opcode,  ui_triblt(uint8 opcode,
1023            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
1024            /* src */ HBITMAP src, int srcx, int srcy,            /* src */ HBITMAP src, int srcx, int srcy,
1025            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
1026  {  {
1027          /* This is potentially difficult to do in general. Until someone          /* This is potentially difficult to do in general. Until someone
1028             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 1031  ui_triblt(uint8 opcode,
1031          {          {
1032                  case 0x69:      /* PDSxxn */                  case 0x69:      /* PDSxxn */
1033                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
1034                          ui_patblt(ROP2_NXOR, x, y, cx, cy,                          ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1035                          break;                          break;
1036    
1037                  case 0xb8:      /* PSDPxax */                  case 0xb8:      /* PSDPxax */
1038                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1039                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
1040                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
1041                          break;                          break;
1042    
1043                  case 0xc0:                  case 0xc0:      /* PSa */
1044                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1045                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   fgcolour);  
1046                          break;                          break;
1047    
1048                  default:                  default:
1049                          NOTIMP("triblt 0x%x\n", opcode);                          unimpl("triblt 0x%x\n", opcode);
1050                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
1051          }          }
1052  }  }
# Line 769  ui_triblt(uint8 opcode, Line 1054  ui_triblt(uint8 opcode,
1054  void  void
1055  ui_line(uint8 opcode,  ui_line(uint8 opcode,
1056          /* dest */ int startx, int starty, int endx, int endy,          /* dest */ int startx, int starty, int endx, int endy,
1057          /* pen */ PEN *pen)          /* pen */ PEN * pen)
1058  {  {
1059          xwin_set_function(opcode);          SET_FUNCTION(opcode);
1060            SET_FOREGROUND(pen->colour);
         XSetForeground(display, gc, Ctrans(pen->colour));  
1061          XDrawLine(display, wnd, gc, startx, starty, endx, endy);          XDrawLine(display, wnd, gc, startx, starty, endx, endy);
1062            if (ownbackstore)
1063                    XDrawLine(display, backstore, gc, startx, starty, endx, endy);
1064            RESET_FUNCTION(opcode);
1065  }  }
1066    
1067  void  void
# Line 782  ui_rect( Line 1069  ui_rect(
1069                 /* dest */ int x, int y, int cx, int cy,                 /* dest */ int x, int y, int cx, int cy,
1070                 /* brush */ int colour)                 /* brush */ int colour)
1071  {  {
1072          xwin_set_function(ROP2_COPY);          SET_FOREGROUND(colour);
1073            FILL_RECTANGLE(x, y, cx, cy);
         XSetForeground(display, gc, Ctrans(colour));  
         XFillRectangle(display, wnd, gc, x, y, cx, cy);  
1074  }  }
1075    
1076  void  void
1077  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
1078                /* dest */ int x, int y, int cx, int cy,                /* dest */ int x, int y, int cx, int cy,
1079                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy,
1080                int fgcolour)                int bgcolour, int fgcolour)
1081  {  {
1082          Pixmap pixmap = (Pixmap) glyph;          SET_FOREGROUND(fgcolour);
1083            SET_BACKGROUND(bgcolour);
1084    
1085          xwin_set_function(ROP2_COPY);          XSetFillStyle(display, gc,
1086                          (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
1087            XSetStipple(display, gc, (Pixmap) glyph);
1088          XSetForeground(display, gc, Ctrans(fgcolour));          XSetTSOrigin(display, gc, x, y);
1089          switch (mixmode)  
1090          {          FILL_RECTANGLE(x, y, cx, cy);
1091                  case MIX_TRANSPARENT:  
1092                          XSetStipple(display, gc, pixmap);          XSetFillStyle(display, gc, FillSolid);
1093                          XSetFillStyle(display, gc, FillStippled);  }
1094                          XSetTSOrigin(display, gc, x, y);  
1095                          XFillRectangle(display, wnd, gc, x, y, cx, cy);  #define DO_GLYPH(ttext,idx) \
1096                          XSetFillStyle(display, gc, FillSolid);  {\
1097                          break;    glyph = cache_get_font (font, ttext[idx]);\
1098      if (!(flags & TEXT2_IMPLICIT_X))\
1099                  case MIX_OPAQUE:      {\
1100                          XSetBackground(display, gc, Ctrans(bgcolour));        xyoffset = ttext[++idx];\
1101  /*      XCopyPlane (display, pixmap, back_pixmap, back_gc, srcx, srcy, cx, cy, x, y, 1); */        if ((xyoffset & 0x80))\
1102                          XSetStipple(display, gc, pixmap);          {\
1103                          XSetFillStyle(display, gc, FillOpaqueStippled);            if (flags & TEXT2_VERTICAL) \
1104                          XSetTSOrigin(display, gc, x, y);              y += ttext[idx+1] | (ttext[idx+2] << 8);\
1105                          XFillRectangle(display, wnd, gc, x, y, cx, cy);            else\
1106                          XSetFillStyle(display, gc, FillSolid);              x += ttext[idx+1] | (ttext[idx+2] << 8);\
1107                          break;            idx += 2;\
1108            }\
1109                  default:        else\
1110                          NOTIMP("mix %d\n", mixmode);          {\
1111          }            if (flags & TEXT2_VERTICAL) \
1112                y += xyoffset;\
1113              else\
1114                x += xyoffset;\
1115            }\
1116        }\
1117      if (glyph != NULL)\
1118        {\
1119          ui_draw_glyph (mixmode, x + (short) glyph->offset,\
1120                         y + (short) glyph->baseline,\
1121                         glyph->width, glyph->height,\
1122                         glyph->pixmap, 0, 0, bgcolour, fgcolour);\
1123          if (flags & TEXT2_IMPLICIT_X)\
1124            x += glyph->width;\
1125        }\
1126  }  }
1127    
1128  void  void
1129  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,
1130               int clipx, int clipy, int clipcx, int clipcy,               int clipx, int clipy, int clipcx, int clipcy,
1131               int boxx, int boxy, int boxcx, int boxcy,               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,
1132               int bgcolour, int fgcolour, uint8 *text, uint8 length)               int fgcolour, uint8 * text, uint8 length)
1133  {  {
1134          FONTGLYPH *glyph;          FONTGLYPH *glyph;
1135          int i, xyoffset;          int i, j, xyoffset;
1136            DATABLOB *entry;
1137    
1138          xwin_set_function(ROP2_COPY);          SET_FOREGROUND(bgcolour);
         XSetForeground(display, gc, Ctrans(bgcolour));  
1139    
1140          if (boxcx > 1)          if (boxcx > 1)
1141                  XFillRectangle(display, wnd, gc, boxx, boxy, boxcx, boxcy);          {
1142                    FILL_RECTANGLE(boxx, boxy, boxcx, boxcy);
1143            }
1144          else if (mixmode == MIX_OPAQUE)          else if (mixmode == MIX_OPAQUE)
1145                  XFillRectangle(display, wnd, gc, clipx, clipy, clipcx, clipcy);          {
1146                    FILL_RECTANGLE(clipx, clipy, clipcx, clipcy);
1147            }
1148    
1149          /* Paint text, character by character */          /* Paint text, character by character */
1150          for (i = 0; i < length; i++)          for (i = 0; i < length;)
1151          {          {
1152                  glyph = cache_get_font(font, text[i]);                  switch (text[i])
   
                 if (!(flags & TEXT2_IMPLICIT_X))  
   
1153                  {                  {
1154                          xyoffset = text[++i];                          case 0xff:
1155                          if ((xyoffset & 0x80))                                  if (i + 2 < length)
1156                          {                                          cache_put_text(text[i + 1], text, text[i + 2]);
                                 if (flags & 0x04)       /* vertical text */  
                                         y += text[++i] | (text[++i] << 8);  
1157                                  else                                  else
1158                                          x += text[++i] | (text[++i] << 8);                                  {
1159                          }                                          error("this shouldn't be happening\n");
1160                          else                                          break;
1161                          {                                  }
1162                                  if (flags & 0x04)       /* vertical text */                                  /* this will move pointer from start to first character after FF command */
1163                                          y += xyoffset;                                  length -= i + 3;
1164                                  else                                  text = &(text[i + 3]);
1165                                          x += xyoffset;                                  i = 0;
1166                          }                                  break;
1167    
1168                  }                          case 0xfe:
1169                  if (glyph != NULL)                                  entry = cache_get_text(text[i + 1]);
1170                  {                                  if (entry != NULL)
1171                          ui_draw_glyph(mixmode, x + (short) glyph->offset,                                  {
1172                                        y + (short) glyph->baseline,                                          if ((((uint8 *) (entry->data))[1] ==
1173                                        glyph->width, glyph->height,                                               0) && (!(flags & TEXT2_IMPLICIT_X)))
1174                                        glyph->pixmap, 0, 0,                                          {
1175                                        bgcolour, fgcolour);                                                  if (flags & TEXT2_VERTICAL)
1176                                                            y += text[i + 2];
1177                                                    else
1178                                                            x += text[i + 2];
1179                                            }
1180                                            if (i + 2 < length)
1181                                                    i += 3;
1182                                            else
1183                                                    i += 2;
1184                                            length -= i;
1185                                            /* this will move pointer from start to first character after FE command */
1186                                            text = &(text[i]);
1187                                            i = 0;
1188                                            for (j = 0; j < entry->size; j++)
1189                                                    DO_GLYPH(((uint8 *) (entry->data)), j);
1190                                    }
1191                                    break;
1192    
1193                          if (flags & TEXT2_IMPLICIT_X)                          default:
1194                                  x += glyph->width;                                  DO_GLYPH(text, i);
1195                                    i++;
1196                                    break;
1197                  }                  }
1198          }          }
1199    
1200    
1201  }  }
1202    
1203  void  void
# Line 887  ui_desktop_save(uint32 offset, int x, in Line 1206  ui_desktop_save(uint32 offset, int x, in
1206          Pixmap pix;          Pixmap pix;
1207          XImage *image;          XImage *image;
1208    
1209          pix = XCreatePixmap(display, wnd, cx, cy, depth);          if (ownbackstore)
1210          xwin_set_function(ROP2_COPY);          {
1211                    image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes, ZPixmap);
1212          XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);          }
1213          image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);          else
1214            {
1215                    pix = XCreatePixmap(display, wnd, cx, cy, depth);
1216                    XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
1217                    image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
1218                    XFreePixmap(display, pix);
1219            }
1220    
1221          offset *= bpp/8;          offset *= bpp / 8;
1222          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);  
1223    
1224          XDestroyImage(image);          XDestroyImage(image);
         XFreePixmap(display, pix);  
1225  }  }
1226    
1227  void  void
# Line 907  ui_desktop_restore(uint32 offset, int x, Line 1230  ui_desktop_restore(uint32 offset, int x,
1230          XImage *image;          XImage *image;
1231          uint8 *data;          uint8 *data;
1232    
1233          offset *= bpp/8;          offset *= bpp / 8;
1234          data = cache_get_desktop(offset, cx, cy, bpp/8);          data = cache_get_desktop(offset, cx, cy, bpp / 8);
1235          if (data == NULL)          if (data == NULL)
1236                  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);  
 }  
1237    
1238  /* unroll defines, used to make the loops a bit more readable... */          image = XCreateImage(display, visual, depth, ZPixmap, 0,
1239  #define unroll8Expr(uexp) uexp uexp uexp uexp uexp uexp uexp uexp                               (char *) data, cx, cy, BitmapPad(display), cx * bpp / 8);
 #define unroll8Lefts(uexp) case 7: uexp \  
         case 6: uexp \  
         case 5: uexp \  
         case 4: uexp \  
         case 3: uexp \  
         case 2: uexp \  
         case 1: uexp  
1240    
1241  static uint8 *          if (ownbackstore)
 translate(int width, int height, uint8 *data)  
 {  
         uint32 i;  
         uint32 size = width * height;  
         uint8 *d2 = xmalloc(size * bpp/8);  
         uint8 *d3 = d2;  
         uint32 pix;  
         i = (size & ~0x7);  
   
         /* XXX: where are the bits swapped??? */  
 #ifdef L_ENDIAN                 /* little-endian */  
         /* big-endian screen */  
         if (screen_msbfirst)  
1242          {          {
1243                  switch (bpp)                  XPutImage(display, backstore, gc, image, 0, 0, x, y, cx, cy);
1244                  {                  XCopyArea(display, backstore, wnd, gc, x, y, cx, cy, x, y);
                         case 32:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix >> 24;  
                                                     *d3++ = pix >> 16;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix;) i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      24;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix;)}  
                                 break;  
                         case 24:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix >> 16;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix;) i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix;)}  
                                 break;  
                         case 16:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix;) i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix;)}  
                                 break;  
                         case 8:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;)}  
                                 break;  
                 }  
1245          }          }
1246          else          else
         {                       /* little-endian screen */  
                 switch (bpp)  
                 {  
                         case 32:  
                                 while (i)  
                                 {  
                                         unroll8Expr(*((uint32 *) d3) =  
                                                     colmap[*data++];  
                                                     d3 += sizeof(uint32);  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(*  
                                                                      ((uint32  
                                                                        *) d3)  
 = colmap[*data++];  
 d3 += sizeof(uint32);  
                                         )}  
                                 break;  
                         case 24:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix >> 16;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;)}  
                                 break;  
                         case 16:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                         )}  
                                 break;  
                         case 8:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;)}  
                 }  
         }  
   
 #else /* bigendian-compiled */  
         if (screen_msbfirst)  
1247          {          {
1248                  /* big-endian screen */                  XPutImage(display, wnd, gc, image, 0, 0, x, y, cx, cy);
                 switch (bpp)  
                 {  
                         case 32:  
                                 while (i)  
                                 {  
                                         unroll8Expr(*((uint32 *) d3) =  
                                                     colmap[*data++];  
                                                     d3 += sizeof(uint32);  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(*  
                                                                      ((uint32  
                                                                        *) d3)  
 = colmap[*data++];  
 d3 += sizeof(uint32);  
                                         )}  
                                 break;  
                         case 24:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix >> 16;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;)}  
                                 break;  
                         case 16:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                         )}  
                                 break;  
                         case 8:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;)}  
                 }  
         }  
         else  
         {  
                 /* little-endian screen */  
                 switch (bpp)  
                 {  
                         case 32:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix >> 16;  
                                                     *d3++ = pix >> 24;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      24;)}  
                                 break;  
                         case 24:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                     *d3++ = pix >> 16;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                                                      *d3++ =  
                                                                      pix >>  
                                                                      16;)}  
                                 break;  
                         case 16:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                     *d3++ = pix >> 8;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;  
                                                                      *d3++ =  
                                                                      pix >> 8;  
                                         )}  
                                 break;  
                         case 8:  
                                 while (i)  
                                 {  
                                         unroll8Expr(pix = colmap[*data++];  
                                                     *d3++ = pix;  
                                                 )i -= 8;  
                                 }  
                                 i = (size & 0x7);  
                                 if (i != 0)  
                                         switch (i)  
                                         {  
                                                         unroll8Lefts(pix =  
                                                                      colmap  
                                                                      [*data++];  
                                                                      *d3++ =  
                                                                      pix;)}  
                 }  
1249          }          }
 #endif  
1250    
1251          return d2;          XFree(image);
1252  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26