/[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 54 by n-ki, Fri Jun 7 07:49:59 2002 UTC revision 208 by matthewc, Fri Sep 27 01:04:34 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 Window System     User interface services - X Window System
4     Copyright (C) Matthew Chapman 1999-2001     Copyright (C) Matthew Chapman 1999-2002
5    
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
# Line 20  Line 20 
20    
21  #include <X11/Xlib.h>  #include <X11/Xlib.h>
22  #include <X11/Xutil.h>  #include <X11/Xutil.h>
 #include <X11/XKBlib.h>  
23  #include <time.h>  #include <time.h>
24  #include <errno.h>  #include <errno.h>
25  #include "rdesktop.h"  #include "rdesktop.h"
26    
 extern char keymapname[16];  
 extern int keylayout;  
27  extern int width;  extern int width;
28  extern int height;  extern int height;
29  extern BOOL sendmotion;  extern BOOL sendmotion;
30  extern BOOL fullscreen;  extern BOOL fullscreen;
31    extern BOOL grab_keyboard;
32    extern char title[];
33    BOOL enable_compose = False;
34    
35  Display *display;  Display *display;
 XkbDescPtr xkb;  
36  static int x_socket;  static int x_socket;
37    static Screen *screen;
38  static Window wnd;  static Window wnd;
39  static GC gc;  static GC gc;
40  static Visual *visual;  static Visual *visual;
41  static int depth;  static int depth;
42  static int bpp;  static int bpp;
43    static XIM IM;
44    static XIC IC;
45    static XModifierKeymap *mod_map;
46    static Cursor current_cursor;
47    
48  /* endianness */  /* endianness */
49  static BOOL host_be;  static BOOL host_be;
# Line 49  static BOOL xserver_be; Line 53  static BOOL xserver_be;
53  static BOOL ownbackstore;  static BOOL ownbackstore;
54  static Pixmap backstore;  static Pixmap backstore;
55    
 /* needed to keep track of the modifiers */  
 static unsigned int numlock_modifier_mask = 0;  
 static unsigned int key_down_state = 0;  
   
   
 #define DShift1Mask   (1<<0)  
 #define DLockMask     (1<<1)  
 #define DControl1Mask (1<<2)  
 #define DMod1Mask     (1<<3)  
 #define DMod2Mask     (1<<4)  
 #define DMod3Mask     (1<<5)  
 #define DMod4Mask     (1<<6)  
 #define DMod5Mask     (1<<7)  
 #define DShift2Mask   (1<<8)  
 #define DControl2Mask (1<<9)  
 #define DNumLockMask  (1<<10)  
   
56  #define FILL_RECTANGLE(x,y,cx,cy)\  #define FILL_RECTANGLE(x,y,cx,cy)\
57  { \  { \
58          XFillRectangle(display, wnd, gc, x, y, cx, cy); \          XFillRectangle(display, wnd, gc, x, y, cx, cy); \
# Line 74  static unsigned int key_down_state = 0; Line 61  static unsigned int key_down_state = 0;
61  }  }
62    
63  /* colour maps */  /* colour maps */
 static BOOL owncolmap;  
64  static Colormap xcolmap;  static Colormap xcolmap;
 static uint32 white;  
65  static uint32 *colmap;  static uint32 *colmap;
66    
67  #define TRANSLATE(col)          ( owncolmap ? col : translate_colour(colmap[col]) )  #define SET_FOREGROUND(col)     XSetForeground(display, gc, translate_colour(colmap[col]));
68  #define SET_FOREGROUND(col)     XSetForeground(display, gc, TRANSLATE(col));  #define SET_BACKGROUND(col)     XSetBackground(display, gc, translate_colour(colmap[col]));
 #define SET_BACKGROUND(col)     XSetBackground(display, gc, TRANSLATE(col));  
69    
70  static int rop2_map[] = {  static int rop2_map[] = {
71          GXclear,                /* 0 */          GXclear,                /* 0 */
# Line 105  static int rop2_map[] = { Line 89  static int rop2_map[] = {
89  #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }  #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(display, gc, rop2_map[rop2]); }
90  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(display, gc, GXcopy); }
91    
 void xwin_get_numlock_mask();  
 void xwin_mod_update(uint32 state, uint32 ev_time );  
 void xwin_mod_release(uint32 state, uint32 ev_time, uint32 scancode);  
 void xwin_mod_press(uint32 state, uint32 ev_time, uint32 scancode);  
   
92  static void  static void
93  translate8(uint8 *data, uint8 *out, uint8 *end)  translate8(uint8 * data, uint8 * out, uint8 * end)
94  {  {
95          while (out < end)          while (out < end)
96                  *(out++) = (uint8)colmap[*(data++)];                  *(out++) = (uint8) colmap[*(data++)];
97  }  }
98    
99  static void  static void
100  translate16(uint8 *data, uint16 *out, uint16 *end)  translate16(uint8 * data, uint16 * out, uint16 * end)
101  {  {
102          while (out < end)          while (out < end)
103                  *(out++) = (uint16)colmap[*(data++)];                  *(out++) = (uint16) colmap[*(data++)];
104  }  }
105    
106  /* little endian - conversion happens when colourmap is built */  /* little endian - conversion happens when colourmap is built */
107  static void  static void
108  translate24(uint8 *data, uint8 *out, uint8 *end)  translate24(uint8 * data, uint8 * out, uint8 * end)
109  {  {
110          uint32 value;          uint32 value;
111    
# Line 140  translate24(uint8 *data, uint8 *out, uin Line 119  translate24(uint8 *data, uint8 *out, uin
119  }  }
120    
121  static void  static void
122  translate32(uint8 *data, uint32 *out, uint32 *end)  translate32(uint8 * data, uint32 * out, uint32 * end)
123  {  {
124          while (out < end)          while (out < end)
125                  *(out++) = colmap[*(data++)];                  *(out++) = colmap[*(data++)];
126  }  }
127    
128  static uint8 *  static uint8 *
129  translate_image(int width, int height, uint8 *data)  translate_image(int width, int height, uint8 * data)
130  {  {
131          int size = width * height * bpp/8;          int size = width * height * bpp / 8;
132          uint8 *out = xmalloc(size);          uint8 *out = xmalloc(size);
133          uint8 *end = out + size;          uint8 *end = out + size;
134    
# Line 160  translate_image(int width, int height, u Line 139  translate_image(int width, int height, u
139                          break;                          break;
140    
141                  case 16:                  case 16:
142                          translate16(data, (uint16 *)out, (uint16 *)end);                          translate16(data, (uint16 *) out, (uint16 *) end);
143                          break;                          break;
144    
145                  case 24:                  case 24:
# Line 168  translate_image(int width, int height, u Line 147  translate_image(int width, int height, u
147                          break;                          break;
148    
149                  case 32:                  case 32:
150                          translate32(data, (uint32 *)out, (uint32 *)end);                          translate32(data, (uint32 *) out, (uint32 *) end);
151                          break;                          break;
152          }          }
153    
# Line 205  translate_colour(uint32 colour) Line 184  translate_colour(uint32 colour)
184  }  }
185    
186  BOOL  BOOL
187  ui_create_window(char *title)  get_key_state(uint32 keysym, unsigned int state)
188  {  {
189          XSetWindowAttributes attribs;          int modifierpos, key, keysymMask = 0;
190          XClassHint *classhints;          int offset;
         XSizeHints *sizehints;  
         unsigned long input_mask;  
         XPixmapFormatValues *pfm;  
         Screen *screen;  
         uint16 test;  
         int i;  
           
         int xkb_minor, xkb_major;  
         int xkb_event, xkb_error, xkb_reason;  
   
         /* compare compiletime libs with runtime libs. */  
         xkb_major = XkbMajorVersion;  
         xkb_minor = XkbMinorVersion;  
         if( XkbLibraryVersion( &xkb_major, &xkb_minor ) == False )  
         {  
                 error("please re-compile rdesktop\ncompile time version of xkb is not compatible with\nyour runtime version of the library\n");  
                 return False;  
         }  
191    
192            KeyCode keycode = XKeysymToKeycode(display, keysym);
193    
194          display = XkbOpenDisplay( NULL, &xkb_event, &xkb_error, &xkb_major, &xkb_minor, &xkb_reason );          if (keycode == NoSymbol)
195          switch(xkb_reason)                  return False;
196    
197            for (modifierpos = 0; modifierpos < 8; modifierpos++)
198          {          {
199                  case XkbOD_BadLibraryVersion:                  offset = mod_map->max_keypermod * modifierpos;
200                          error("XkbOD_BadLibraryVersion: XKB extensions in server and the library rdesktop is linked against aren't compatible with each other.\n");  
201                          break;                  for (key = 0; key < mod_map->max_keypermod; key++)
202                  case XkbOD_ConnectionRefused:                  {
203                          error("XkbOD_ConnectionRefused\n");                          if (mod_map->modifiermap[offset + key] == keycode)
204                          break;                                  keysymMask |= 1 << modifierpos;
205                  case XkbOD_BadServerVersion:                  }
                         error("XkbOD_BadServerVersion\n");  
                         break;  
                 case XkbOD_NonXkbServer:  
                         error("XkbOD_NonXkbServer: XKB extension not present in server\nupdate your X server.\n");  
                         break;  
                 case XkbOD_Success:  
                         DEBUG("XkbOD_Success: Connection established with display\n");  
                         break;  
206          }          }
207    
208            return (state & keysymMask) ? True : False;
209    }
210    
211    BOOL
212    ui_init(void)
213    {
214            XPixmapFormatValues *pfm;
215            uint16 test;
216            int i;
217    
218            display = XOpenDisplay(NULL);
219          if (display == NULL)          if (display == NULL)
220          {          {
221                  error("Failed to open display\n");                  error("Failed to open display\n");
# Line 259  ui_create_window(char *title) Line 226  ui_create_window(char *title)
226          screen = DefaultScreenOfDisplay(display);          screen = DefaultScreenOfDisplay(display);
227          visual = DefaultVisualOfScreen(screen);          visual = DefaultVisualOfScreen(screen);
228          depth = DefaultDepthOfScreen(screen);          depth = DefaultDepthOfScreen(screen);
229            
230          pfm = XListPixmapFormats(display, &i);          pfm = XListPixmapFormats(display, &i);
231          if (pfm != NULL)          if (pfm != NULL)
232          {          {
# Line 267  ui_create_window(char *title) Line 234  ui_create_window(char *title)
234                     desirable, e.g. 24 bits->32 bits. */                     desirable, e.g. 24 bits->32 bits. */
235                  while (i--)                  while (i--)
236                  {                  {
237                          if ((pfm[i].depth == depth)                          if ((pfm[i].depth == depth) && (pfm[i].bits_per_pixel > bpp))
                             && (pfm[i].bits_per_pixel > bpp))  
238                          {                          {
239                                  bpp = pfm[i].bits_per_pixel;                                  bpp = pfm[i].bits_per_pixel;
240                          }                          }
# Line 283  ui_create_window(char *title) Line 249  ui_create_window(char *title)
249                  return False;                  return False;
250          }          }
251    
252          if (depth <= 8)          xcolmap = DefaultColormapOfScreen(screen);
253                  owncolmap = True;          gc = XCreateGC(display, RootWindowOfScreen(screen), 0, NULL);
254          else  
255                  xcolmap = DefaultColormapOfScreen(screen);          if (DoesBackingStore(screen) != Always)
256                    ownbackstore = True;
257    
258          test = 1;          test = 1;
259          host_be = !(BOOL)(*(uint8 *)(&test));          host_be = !(BOOL) (*(uint8 *) (&test));
260          xserver_be = (ImageByteOrder(display) == MSBFirst);          xserver_be = (ImageByteOrder(display) == MSBFirst);
261    
         white = WhitePixelOfScreen(screen);  
         attribs.background_pixel = BlackPixelOfScreen(screen);  
         attribs.backing_store = DoesBackingStore(screen);  
   
         if (attribs.backing_store == NotUseful)  
                 ownbackstore = True;  
   
262          if (fullscreen)          if (fullscreen)
263          {          {
                 attribs.override_redirect = True;  
264                  width = WidthOfScreen(screen);                  width = WidthOfScreen(screen);
265                  height = HeightOfScreen(screen);                  height = HeightOfScreen(screen);
266          }          }
267          else  
268            /* make sure width is a multiple of 4 */
269            width = (width + 3) & ~3;
270    
271            if (ownbackstore)
272          {          {
273                  attribs.override_redirect = False;                  backstore =
274                            XCreatePixmap(display, RootWindowOfScreen(screen), width, height, depth);
275    
276                    /* clear to prevent rubbish being exposed at startup */
277                    XSetForeground(display, gc, BlackPixelOfScreen(screen));
278                    XFillRectangle(display, backstore, gc, 0, 0, width, height);
279          }          }
280    
281          width = (width + 3) & ~3; /* make width a multiple of 32 bits */          mod_map = XGetModifierMapping(display);
282    
283            if (enable_compose)
284                    IM = XOpenIM(display, NULL, NULL, NULL);
285    
286            xkeymap_init();
287            return True;
288    }
289    
290    void
291    ui_deinit(void)
292    {
293            if (IM != NULL)
294                    XCloseIM(IM);
295    
296            XFreeModifiermap(mod_map);
297    
298            if (ownbackstore)
299                    XFreePixmap(display, backstore);
300    
301            XFreeGC(display, gc);
302            XCloseDisplay(display);
303            display = NULL;
304    }
305    
306    BOOL
307    ui_create_window(void)
308    {
309            XSetWindowAttributes attribs;
310            XClassHint *classhints;
311            XSizeHints *sizehints;
312            int wndwidth, wndheight;
313            long input_mask, ic_input_mask;
314            XEvent xevent;
315    
316          wnd = XCreateWindow(display, RootWindowOfScreen(screen),          wndwidth = fullscreen ? WidthOfScreen(screen) : width;
317                              0, 0, width, height, 0, CopyFromParent,          wndheight = fullscreen ? HeightOfScreen(screen) : height;
318                              InputOutput, CopyFromParent,  
319                              CWBackingStore | CWBackPixel | CWOverrideRedirect,          attribs.background_pixel = BlackPixelOfScreen(screen);
320                              &attribs);          attribs.backing_store = ownbackstore ? NotUseful : Always;
321            attribs.override_redirect = fullscreen;
322    
323            wnd = XCreateWindow(display, RootWindowOfScreen(screen), 0, 0, wndwidth, wndheight,
324                                0, CopyFromParent, InputOutput, CopyFromParent,
325                                CWBackPixel | CWBackingStore | CWOverrideRedirect, &attribs);
326    
327          XStoreName(display, wnd, title);          XStoreName(display, wnd, title);
328    
# Line 338  ui_create_window(char *title) Line 344  ui_create_window(char *title)
344                  XFree(sizehints);                  XFree(sizehints);
345          }          }
346    
347          xkeymap_init();          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
348                    VisibilityChangeMask | FocusChangeMask;
349    
         input_mask = KeyPressMask | KeyReleaseMask |  
                          ButtonPressMask | ButtonReleaseMask |  
                          EnterWindowMask | LeaveWindowMask;  
350          if (sendmotion)          if (sendmotion)
351                  input_mask |= PointerMotionMask;                  input_mask |= PointerMotionMask;
   
352          if (ownbackstore)          if (ownbackstore)
353                  input_mask |= ExposureMask;                  input_mask |= ExposureMask;
354    
355          XSelectInput(display, wnd, input_mask);          if (IM != NULL)
356          gc = XCreateGC(display, wnd, 0, NULL);          {
357                    IC = XCreateIC(IM, XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
358                                   XNClientWindow, wnd, XNFocusWindow, wnd, NULL);
359    
360          if (ownbackstore)                  if ((IC != NULL)
361                  backstore = XCreatePixmap(display, wnd, width, height, depth);                      && (XGetICValues(IC, XNFilterEvents, &ic_input_mask, NULL) == NULL))
362                            input_mask |= ic_input_mask;
363            }
364    
365            XSelectInput(display, wnd, input_mask);
366          XMapWindow(display, wnd);          XMapWindow(display, wnd);
367    
368          /* TODO: error texts... make them friendly. */          /* wait for VisibilityNotify */
369          xkb = XkbGetKeyboard(display, XkbAllComponentsMask, XkbUseCoreKbd);          do
         if ((int)xkb == BadAlloc || xkb == NULL)  
         {  
                         error( "XkbGetKeyboard failed.\n");  
                         exit(0);  
         }  
   
         /* TODO: error texts... make them friendly. */  
         if( XkbSelectEvents(display, xkb->device_spec, XkbAllEventsMask, XkbAllEventsMask) == False )  
370          {          {
371                          error( "XkbSelectEvents failed.\n");                  XMaskEvent(display, VisibilityChangeMask, &xevent);
                         exit(0);  
372          }          }
373                    while (xevent.type != VisibilityNotify);
374          xwin_get_numlock_mask();  
375            if (fullscreen)
376                    XSetInputFocus(display, wnd, RevertToPointerRoot, CurrentTime);
377    
378          return True;          return True;
379  }  }
380    
381  void  void
382  xwin_get_numlock_mask()  ui_destroy_window(void)
383  {  {
384          KeyCode numlockcode;          if (IC != NULL)
385          KeyCode* keycode;                  XDestroyIC(IC);
         XModifierKeymap *modmap;  
         int i,j;  
   
         /* Find out if numlock is already defined as a modifier key, and if so where */  
         numlockcode = XKeysymToKeycode(display, 0xFF7F);        /* XF_Num_Lock = 0xFF7F */  
         if (numlockcode) {  
                 modmap = XGetModifierMapping(display);  
                 if (modmap) {  
                         keycode = modmap->modifiermap;  
                         for (i = 0; i < 8; i++)  
                                 for (j = modmap->max_keypermod; j--;) {  
                                         if (*keycode == numlockcode) {  
                                                 numlock_modifier_mask = (1 << i);  
                                                 i = 8;  
                                                 break;  
                                         }  
                                         keycode++;  
                                 }  
                 if (!numlock_modifier_mask) {  
                                 modmap->modifiermap[7 * modmap->max_keypermod] = numlockcode;  
                                 if (XSetModifierMapping(display, modmap) == MappingSuccess)  
                                         numlock_modifier_mask = (1 << 7);  
                                 else  
                                         printf("XSetModifierMapping failed!\n");  
                         }  
                         XFreeModifiermap(modmap);  
                 }  
         }  
386    
387          if (!numlock_modifier_mask)          XDestroyWindow(display, wnd);
                 printf("WARNING: Failed to get a numlock modifier mapping.\n");  
                   
388  }  }
389    
390  void  void
391  ui_destroy_window()  xwin_toggle_fullscreen(void)
392  {  {
393          if( xkb != NULL )          Pixmap contents = 0;
                 XkbFreeKeyboard(xkb, XkbAllControlsMask, True);  
394    
395          if (ownbackstore)          if (!ownbackstore)
396                  XFreePixmap(display, backstore);          {
397                    /* need to save contents of window */
398                    contents = XCreatePixmap(display, wnd, width, height, depth);
399                    XCopyArea(display, wnd, contents, gc, 0, 0, width, height, 0, 0);
400            }
401    
402          XFreeGC(display, gc);          ui_destroy_window();
403          XDestroyWindow(display, wnd);          fullscreen = !fullscreen;
404          XCloseDisplay(display);          ui_create_window();
405          display = NULL;  
406            XDefineCursor(display, wnd, current_cursor);
407    
408            if (!ownbackstore)
409            {
410                    XCopyArea(display, contents, wnd, gc, 0, 0, width, height, 0, 0);
411                    XFreePixmap(display, contents);
412            }
413  }  }
414    
415    /* Process all events in Xlib queue */
416  static void  static void
417  xwin_process_events()  xwin_process_events(void)
418  {  {
419          XEvent xevent;          XEvent xevent;
   
420          KeySym keysym;          KeySym keysym;
         uint8 scancode;  
421          uint16 button, flags;          uint16 button, flags;
422          uint32 ev_time;          uint32 ev_time;
423          uint32 tmpmods;          key_translation tr;
424            char str[256];
425            Status status;
426            unsigned int state;
427            Window wdummy;
428            int dummy;
429    
430          while (XCheckMaskEvent(display, ~0, &xevent))          while (XPending(display) > 0)
431          {          {
432                  ev_time = time(NULL);                  XNextEvent(display, &xevent);
433    
434                    if ((IC != NULL) && (XFilterEvent(&xevent, None) == True))
435                    {
436                            DEBUG_KBD(("Filtering event\n"));
437                            continue;
438                    }
439    
440                  flags = 0;                  flags = 0;
441    
442                  switch (xevent.type)                  switch (xevent.type)
443                  {                  {
                         case KeyRelease:  
                                 flags = KBD_FLAG_DOWN | KBD_FLAG_UP;  
                                 /* fall through */  
444                          case KeyPress:                          case KeyPress:
445                                  if( XkbTranslateKeyCode(xkb, xevent.xkey.keycode, xevent.xkey.state, &tmpmods, &keysym) == False )                                  if (IC != NULL)
446                                            /* Multi_key compatible version */
447                                    {
448                                            XmbLookupString(IC,
449                                                            (XKeyPressedEvent *) &
450                                                            xevent, str, sizeof(str), &keysym, &status);
451                                            if (!((status == XLookupKeySym) || (status == XLookupBoth)))
452                                            {
453                                                    error("XmbLookupString failed with status 0x%x\n",
454                                                          status);
455                                                    break;
456                                            }
457                                    }
458                                    else
459                                    {
460                                            /* Plain old XLookupString */
461                                            DEBUG_KBD(("\nNo input context, using XLookupString\n"));
462                                            XLookupString((XKeyEvent *) & xevent,
463                                                          str, sizeof(str), &keysym, NULL);
464                                    }
465    
466                                    DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym, get_ksname(keysym)));
467    
468                                    ev_time = time(NULL);
469                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
470                                          break;                                          break;
                                 scancode = xkeymap_translate_key(keysym, xevent.xkey.keycode, &flags);  
471    
472                                  if (scancode == 0 )                                  tr = xkeymap_translate_key(keysym,
473                                                               xevent.xkey.keycode, xevent.xkey.state);
474    
475                                    if (tr.scancode == 0)
476                                          break;                                          break;
477    
478                                  /* keep track of the modifiers -- needed for stickykeys... */                                  ensure_remote_modifiers(ev_time, tr);
                                 if( xevent.type == KeyPress )  
                                         xwin_mod_press( xevent.xkey.state, ev_time, scancode );  
479    
480                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, flags, scancode, 0);                                  rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
481                                    break;
482    
483                                  if( xevent.type == KeyRelease )                          case KeyRelease:
484                                          xwin_mod_release( xevent.xkey.state, ev_time, scancode );                                  XLookupString((XKeyEvent *) & xevent, str,
485                                                  sizeof(str), &keysym, NULL);
486    
487                                    DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,
488                                               get_ksname(keysym)));
489    
490                                    ev_time = time(NULL);
491                                    if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
492                                            break;
493    
494                                    tr = xkeymap_translate_key(keysym,
495                                                               xevent.xkey.keycode, xevent.xkey.state);
496    
497                                    if (tr.scancode == 0)
498                                            break;
499    
500                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);
501                                  break;                                  break;
502    
503                          case ButtonPress:                          case ButtonPress:
# Line 480  xwin_process_events() Line 509  xwin_process_events()
509                                  if (button == 0)                                  if (button == 0)
510                                          break;                                          break;
511    
512                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
513                                                 flags | button,                                                 flags | button, xevent.xbutton.x, xevent.xbutton.y);
                                                xevent.xbutton.x,  
                                                xevent.xbutton.y);  
514                                  break;                                  break;
515    
516                          case MotionNotify:                          case MotionNotify:
517                                  rdp_send_input(ev_time, RDP_INPUT_MOUSE,                                  rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
518                                                 MOUSE_FLAG_MOVE,                                                 MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
                                                xevent.xmotion.x,  
                                                xevent.xmotion.y);  
519                                  break;                                  break;
520    
521                          case EnterNotify:                          case FocusIn:
522                                  XGrabKeyboard(display, wnd, True, GrabModeAsync,                                  XQueryPointer(display, wnd, &wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state);
523                                                GrabModeAsync, CurrentTime);                                  reset_modifier_keys(state);
524                                    if (grab_keyboard)
525                                   xwin_mod_update( xevent.xcrossing.state, ev_time );                                          XGrabKeyboard(display, wnd, True,
526                                                          GrabModeAsync, GrabModeAsync, CurrentTime);
527                                  break;                                  break;
528    
529                          case LeaveNotify:                          case FocusOut:
530                                  XUngrabKeyboard(display, CurrentTime);                                  if (xevent.xfocus.mode == NotifyWhileGrabbed)
531                                            XUngrabKeyboard(display, CurrentTime);
532                                  break;                                  break;
533    
534                          case Expose:                          case Expose:
535                                  XCopyArea(display, backstore, wnd, gc,                                  XCopyArea(display, backstore, wnd, gc,
536                                            xevent.xexpose.x, xevent.xexpose.y,                                            xevent.xexpose.x, xevent.xexpose.y,
537                                            xevent.xexpose.width, xevent.xexpose.height,                                            xevent.xexpose.width,
538                                              xevent.xexpose.height,
539                                            xevent.xexpose.x, xevent.xexpose.y);                                            xevent.xexpose.x, xevent.xexpose.y);
540                                  break;                                  break;
                 }  
         }  
 }  
   
 void  
 xwin_mod_update(uint32 state, uint32 ev_time )  
 {  
         xwin_mod_press(state, ev_time, 0);  
         xwin_mod_release(state, ev_time, 0);  
 }  
   
 void  
 xwin_mod_release(uint32 state, uint32 ev_time, uint32 scancode)  
 {  
         switch (scancode) {  
         case 0x2a:  
                 key_down_state &= ~DShift1Mask;  
                 break;  
         case 0x36:  
                 key_down_state &= ~DShift2Mask;  
                 break;  
         case 0x1d:  
                 key_down_state &= ~DControl1Mask;  
                 break;  
         case 0x9d:  
                 key_down_state &= ~DControl2Mask;  
                 break;  
         case 0x38:  
                 key_down_state &= ~DMod1Mask;  
                 break;  
         case 0xb8:  
                 key_down_state &= ~DMod2Mask;  
                 break;  
         }  
   
         if( !(numlock_modifier_mask & state) && (key_down_state & DNumLockMask) )  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x45, 0);  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN | KBD_FLAG_UP, 0x45, 0);  
                 key_down_state &= ~DNumLockMask;  
         }  
   
         if( !(LockMask & state) && (key_down_state & DLockMask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x3a, 0);  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN | KBD_FLAG_UP, 0x3a, 0);  
                 key_down_state &= ~DLockMask;  
   
         }  
   
   
         if( !(ShiftMask & state) && (key_down_state & DShift1Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x2a, 0);  
                 key_down_state &= ~DShift1Mask;  
   
         }  
541    
542          if( !(ControlMask & state) && (key_down_state & DControl1Mask))                          case MappingNotify:
543          {                                  /* Refresh keyboard mapping if it has changed. This is important for
544                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x1d, 0);                                     Xvnc, since it allocates keycodes dynamically */
545                  key_down_state &= ~DControl1Mask;                                  if (xevent.xmapping.request == MappingKeyboard
546                                        || xevent.xmapping.request == MappingModifier)
547          }                                          XRefreshKeyboardMapping(&xevent.xmapping);
   
         if( !(Mod1Mask & state) && (key_down_state & DMod1Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0x38, 0);  
                 key_down_state &= ~DMod1Mask;  
   
         }  
   
         if( !(Mod2Mask & state) && (key_down_state & DMod2Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_UP, 0xb8, 0);  
                 key_down_state &= ~DMod2Mask;  
         }  
 }  
   
   
 void  
 xwin_mod_press(uint32 state, uint32 ev_time, uint32 scancode)  
 {  
   
         switch (scancode) {  
         case 0x2a:  
                 key_down_state |= DShift1Mask;  
                 break;  
         case 0x36:  
                 key_down_state |= DShift2Mask;  
                 break;  
         case 0x1d:  
                 key_down_state |= DControl1Mask;  
                 break;  
         case 0x9d:  
                 key_down_state |= DControl2Mask;  
                 break;  
         case 0x3a:  
                 key_down_state ^= DLockMask;  
                 break;  
         case 0x45:  
                 key_down_state ^= DNumLockMask;  
                 break;  
         case 0x38:  
                 key_down_state |= DMod1Mask;  
                 break;  
         case 0xb8:  
                 key_down_state |= DMod2Mask;  
                 break;  
         }  
   
         if( (numlock_modifier_mask && state) && !(key_down_state & DNumLockMask) )  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x45, 0);  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN | KBD_FLAG_UP, 0x45, 0);  
                 key_down_state |= DNumLockMask;  
         }  
   
         if( (LockMask & state) && !(key_down_state & DLockMask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, 0, 0x3a, 0);  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN | KBD_FLAG_UP, 0x3a, 0);  
                 key_down_state |= DLockMask;  
   
         }  
   
   
         if( (ShiftMask & state) && !((key_down_state & DShift1Mask) || (key_down_state & DShift2Mask)))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0x2a, 0);  
                 key_down_state |= DShift1Mask;  
   
         }  
548    
549          if( (ControlMask & state) && !((key_down_state & DControl1Mask) || (key_down_state & DControl2Mask)))                                  if (xevent.xmapping.request == MappingModifier)
550          {                                  {
551                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0x1d, 0);                                          XFreeModifiermap(mod_map);
552                  key_down_state |= DControl1Mask;                                          mod_map = XGetModifierMapping(display);
553                                    }
554          }                                  break;
   
         if( (Mod1Mask & state) && !(key_down_state & DMod1Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0x38, 0);  
                 key_down_state |= DMod1Mask;  
   
         }  
   
         if( (Mod2Mask & state) && !(key_down_state & DMod2Mask))  
         {  
                 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, KBD_FLAG_DOWN, 0xb8, 0);  
                 key_down_state |= DMod2Mask;  
555    
556                    }
557          }          }
558  }  }
559    
560  void  void
561  ui_select(int rdp_socket)  ui_select(int rdp_socket)
562  {  {
563          int n = (rdp_socket > x_socket) ? rdp_socket+1 : x_socket+1;          int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;
564          fd_set rfds;          fd_set rfds;
565    
566          FD_ZERO(&rfds);          FD_ZERO(&rfds);
567    
568          while (True)          while (True)
569          {          {
570                    /* Process any events already waiting */
571                    xwin_process_events();
572    
573                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
574                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
575                  if (display != NULL)                  FD_SET(x_socket, &rfds);
                 {  
                         FD_SET(x_socket, &rfds);  
                         XFlush(display);  
                 }  
576    
577                  switch (select(n, &rfds, NULL, NULL, NULL))                  switch (select(n, &rfds, NULL, NULL, NULL))
578                  {                  {
# Line 693  ui_select(int rdp_socket) Line 583  ui_select(int rdp_socket)
583                                  continue;                                  continue;
584                  }                  }
585    
                 if (FD_ISSET(x_socket, &rfds))  
                         xwin_process_events();  
   
586                  if (FD_ISSET(rdp_socket, &rfds))                  if (FD_ISSET(rdp_socket, &rfds))
587                          return;                          return;
588          }          }
# Line 708  ui_move_pointer(int x, int y) Line 595  ui_move_pointer(int x, int y)
595  }  }
596    
597  HBITMAP  HBITMAP
598  ui_create_bitmap(int width, int height, uint8 *data)  ui_create_bitmap(int width, int height, uint8 * data)
599  {  {
600          XImage *image;          XImage *image;
601          Pixmap bitmap;          Pixmap bitmap;
602          uint8 *tdata;          uint8 *tdata;
603    
604          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = translate_image(width, height, data);
605          bitmap = XCreatePixmap(display, wnd, width, height, depth);          bitmap = XCreatePixmap(display, wnd, width, height, depth);
606          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
607                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, 8, 0);
608    
609          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);          XPutImage(display, bitmap, gc, image, 0, 0, 0, 0, width, height);
610    
611          XFree(image);          XFree(image);
612          if (!owncolmap)          xfree(tdata);
                 xfree(tdata);  
613          return (HBITMAP) bitmap;          return (HBITMAP) bitmap;
614  }  }
615    
616  void  void
617  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)  
618  {  {
619          XImage *image;          XImage *image;
620          uint8 *tdata;          uint8 *tdata;
621    
622          tdata = (owncolmap ? data : translate_image(width, height, data));          tdata = translate_image(width, height, data);
623          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
624                               0, tdata, width, height, 8, 0);                               (char *) tdata, width, height, 8, 0);
625    
626          if (ownbackstore)          if (ownbackstore)
627          {          {
# Line 749  ui_paint_bitmap(int x, int y, int cx, in Line 634  ui_paint_bitmap(int x, int y, int cx, in
634          }          }
635    
636          XFree(image);          XFree(image);
637          if (!owncolmap)          xfree(tdata);
                 xfree(tdata);  
638  }  }
639    
640  void  void
641  ui_destroy_bitmap(HBITMAP bmp)  ui_destroy_bitmap(HBITMAP bmp)
642  {  {
643          XFreePixmap(display, (Pixmap)bmp);          XFreePixmap(display, (Pixmap) bmp);
644  }  }
645    
646  HGLYPH  HGLYPH
647  ui_create_glyph(int width, int height, uint8 *data)  ui_create_glyph(int width, int height, uint8 * data)
648  {  {
649          XImage *image;          XImage *image;
650          Pixmap bitmap;          Pixmap bitmap;
# Line 772  ui_create_glyph(int width, int height, u Line 656  ui_create_glyph(int width, int height, u
656          bitmap = XCreatePixmap(display, wnd, width, height, 1);          bitmap = XCreatePixmap(display, wnd, width, height, 1);
657          gc = XCreateGC(display, bitmap, 0, NULL);          gc = XCreateGC(display, bitmap, 0, NULL);
658    
659          image = XCreateImage(display, visual, 1, ZPixmap, 0,          image = XCreateImage(display, visual, 1, ZPixmap, 0, (char *) data,
660                               data, width, height, 8, scanline);                               width, height, 8, scanline);
661          image->byte_order = MSBFirst;          image->byte_order = MSBFirst;
662          image->bitmap_bit_order = MSBFirst;          image->bitmap_bit_order = MSBFirst;
663          XInitImage(image);          XInitImage(image);
# Line 782  ui_create_glyph(int width, int height, u Line 666  ui_create_glyph(int width, int height, u
666    
667          XFree(image);          XFree(image);
668          XFreeGC(display, gc);          XFreeGC(display, gc);
669          return (HGLYPH)bitmap;          return (HGLYPH) bitmap;
670  }  }
671    
672  void  void
673  ui_destroy_glyph(HGLYPH glyph)  ui_destroy_glyph(HGLYPH glyph)
674  {  {
675          XFreePixmap(display, (Pixmap)glyph);          XFreePixmap(display, (Pixmap) glyph);
676  }  }
677    
678  HCURSOR  HCURSOR
679  ui_create_cursor(unsigned int x, unsigned int y, int width,  ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
680                   int height, uint8 *andmask, uint8 *xormask)                   uint8 * andmask, uint8 * xormask)
681  {  {
682          HGLYPH maskglyph, cursorglyph;          HGLYPH maskglyph, cursorglyph;
683          XColor bg, fg;          XColor bg, fg;
# Line 850  ui_create_cursor(unsigned int x, unsigne Line 734  ui_create_cursor(unsigned int x, unsigne
734    
735          cursorglyph = ui_create_glyph(width, height, cursor);          cursorglyph = ui_create_glyph(width, height, cursor);
736          maskglyph = ui_create_glyph(width, height, mask);          maskglyph = ui_create_glyph(width, height, mask);
737            
738          xcursor = XCreatePixmapCursor(display, (Pixmap)cursorglyph,          xcursor =
739                                  (Pixmap)maskglyph, &fg, &bg, x, y);                  XCreatePixmapCursor(display, (Pixmap) cursorglyph,
740                                        (Pixmap) maskglyph, &fg, &bg, x, y);
741    
742          ui_destroy_glyph(maskglyph);          ui_destroy_glyph(maskglyph);
743          ui_destroy_glyph(cursorglyph);          ui_destroy_glyph(cursorglyph);
744          xfree(mask);          xfree(mask);
745          xfree(cursor);          xfree(cursor);
746          return (HCURSOR)xcursor;          return (HCURSOR) xcursor;
747  }  }
748    
749  void  void
750  ui_set_cursor(HCURSOR cursor)  ui_set_cursor(HCURSOR cursor)
751  {  {
752          XDefineCursor(display, wnd, (Cursor)cursor);          current_cursor = (Cursor) cursor;
753            XDefineCursor(display, wnd, current_cursor);
754  }  }
755    
756  void  void
757  ui_destroy_cursor(HCURSOR cursor)  ui_destroy_cursor(HCURSOR cursor)
758  {  {
759          XFreeCursor(display, (Cursor)cursor);          XFreeCursor(display, (Cursor) cursor);
760  }  }
761    
762  #define MAKE_XCOLOR(xc,c) \  #define MAKE_XCOLOR(xc,c) \
# Line 880  ui_destroy_cursor(HCURSOR cursor) Line 766  ui_destroy_cursor(HCURSOR cursor)
766                  (xc)->flags = DoRed | DoGreen | DoBlue;                  (xc)->flags = DoRed | DoGreen | DoBlue;
767    
768  HCOLOURMAP  HCOLOURMAP
769  ui_create_colourmap(COLOURMAP *colours)  ui_create_colourmap(COLOURMAP * colours)
770  {  {
771          COLOURENTRY *entry;          COLOURENTRY *entry;
772          int i, ncolours = colours->ncolours;          int i, ncolours = colours->ncolours;
773            uint32 *map = xmalloc(sizeof(*colmap) * ncolours);
774          if (owncolmap)          XColor xentry;
775            XColor xc_cache[256];
776            uint32 colour;
777            int colLookup = 256;
778            for (i = 0; i < ncolours; i++)
779          {          {
780                  XColor *xcolours, *xentry;                  entry = &colours->colours[i];
781                  Colormap map;                  MAKE_XCOLOR(&xentry, entry);
782    
783                  xcolours = xmalloc(sizeof(XColor) * ncolours);                  if (XAllocColor(display, xcolmap, &xentry) == 0)
                 for (i = 0; i < ncolours; i++)  
784                  {                  {
785                          entry = &colours->colours[i];                          /* Allocation failed, find closest match. */
786                          xentry = &xcolours[i];                          int j = 256;
787                          xentry->pixel = i;                          int nMinDist = 3 * 256 * 256;
788                          MAKE_XCOLOR(xentry, entry);                          long nDist = nMinDist;
                 }  
789    
790                  map = XCreateColormap(display, wnd, visual, AllocAll);                          /* only get the colors once */
791                  XStoreColors(display, map, xcolours, ncolours);                          while (colLookup--)
792                            {
793                                    xc_cache[colLookup].pixel = colLookup;
794                                    xc_cache[colLookup].red = xc_cache[colLookup].green =
795                                            xc_cache[colLookup].blue = 0;
796                                    xc_cache[colLookup].flags = 0;
797                                    XQueryColor(display,
798                                                DefaultColormap(display, DefaultScreen(display)),
799                                                &xc_cache[colLookup]);
800                            }
801                            colLookup = 0;
802    
803                  xfree(xcolours);                          /* approximate the pixel */
804                  return (HCOLOURMAP)map;                          while (j--)
805          }                          {
806          else                                  if (xc_cache[j].flags)
807          {                                  {
808                  uint32 *map = xmalloc(sizeof(*colmap) * ncolours);                                          nDist = ((long) (xc_cache[j].red >> 8) -
809                  XColor xentry;                                                   (long) (xentry.red >> 8)) *
810                  uint32 colour;                                                  ((long) (xc_cache[j].red >> 8) -
811                                                     (long) (xentry.red >> 8)) +
812                                                    ((long) (xc_cache[j].green >> 8) -
813                                                     (long) (xentry.green >> 8)) *
814                                                    ((long) (xc_cache[j].green >> 8) -
815                                                     (long) (xentry.green >> 8)) +
816                                                    ((long) (xc_cache[j].blue >> 8) -
817                                                     (long) (xentry.blue >> 8)) *
818                                                    ((long) (xc_cache[j].blue >> 8) -
819                                                     (long) (xentry.blue >> 8));
820                                    }
821                                    if (nDist < nMinDist)
822                                    {
823                                            nMinDist = nDist;
824                                            xentry.pixel = j;
825                                    }
826                            }
827                    }
828                    colour = xentry.pixel;
829    
830                  for (i = 0; i < ncolours; i++)                  /* update our cache */
831                    if (xentry.pixel < 256)
832                  {                  {
833                          entry = &colours->colours[i];                          xc_cache[xentry.pixel].red = xentry.red;
834                          MAKE_XCOLOR(&xentry, entry);                          xc_cache[xentry.pixel].green = xentry.green;
835                            xc_cache[xentry.pixel].blue = xentry.blue;
                         if (XAllocColor(display, xcolmap, &xentry) != 0)  
                                 colour = xentry.pixel;  
                         else  
                                 colour = white;  
836    
                         /* byte swap here to make translate_image faster */  
                         map[i] = translate_colour(colour);  
837                  }                  }
838    
839                  return map;  
840                    /* byte swap here to make translate_image faster */
841                    map[i] = translate_colour(colour);
842          }          }
843    
844            return map;
845  }  }
846    
847  void  void
848  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(HCOLOURMAP map)
849  {  {
850          if (owncolmap)          xfree(map);
                 XFreeColormap(display, (Colormap)map);  
         else  
                 xfree(map);  
851  }  }
852    
853  void  void
854  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(HCOLOURMAP map)
855  {  {
856          if (owncolmap)          colmap = map;
                 XSetWindowColormap(display, wnd, (Colormap)map);  
         else  
                 colmap = map;  
857  }  }
858    
859  void  void
# Line 960  ui_set_clip(int x, int y, int cx, int cy Line 869  ui_set_clip(int x, int y, int cx, int cy
869  }  }
870    
871  void  void
872  ui_reset_clip()  ui_reset_clip(void)
873  {  {
874          XRectangle rect;          XRectangle rect;
875    
# Line 972  ui_reset_clip() Line 881  ui_reset_clip()
881  }  }
882    
883  void  void
884  ui_bell()  ui_bell(void)
885  {  {
886          XBell(display, 0);          XBell(display, 0);
887  }  }
# Line 989  ui_destblt(uint8 opcode, Line 898  ui_destblt(uint8 opcode,
898  void  void
899  ui_patblt(uint8 opcode,  ui_patblt(uint8 opcode,
900            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
901            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
902  {  {
903          Pixmap fill;          Pixmap fill;
904            uint8 i, ipattern[8];
905    
906          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
907    
# Line 1003  ui_patblt(uint8 opcode, Line 913  ui_patblt(uint8 opcode,
913                          break;                          break;
914    
915                  case 3: /* Pattern */                  case 3: /* Pattern */
916                          fill = (Pixmap)ui_create_glyph(8, 8, brush->pattern);                          for (i = 0; i != 8; i++)
917                                    ipattern[7 - i] = brush->pattern[i];
918                            fill = (Pixmap) ui_create_glyph(8, 8, ipattern);
919    
920                          SET_FOREGROUND(bgcolour);                          SET_FOREGROUND(bgcolour);
921                          SET_BACKGROUND(fgcolour);                          SET_BACKGROUND(fgcolour);
# Line 1014  ui_patblt(uint8 opcode, Line 926  ui_patblt(uint8 opcode,
926                          FILL_RECTANGLE(x, y, cx, cy);                          FILL_RECTANGLE(x, y, cx, cy);
927    
928                          XSetFillStyle(display, gc, FillSolid);                          XSetFillStyle(display, gc, FillSolid);
929                          ui_destroy_glyph((HGLYPH)fill);                          XSetTSOrigin(display, gc, 0, 0);
930                            ui_destroy_glyph((HGLYPH) fill);
931                          break;                          break;
932    
933                  default:                  default:
# Line 1032  ui_screenblt(uint8 opcode, Line 945  ui_screenblt(uint8 opcode,
945          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
946          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, wnd, wnd, gc, srcx, srcy, cx, cy, x, y);
947          if (ownbackstore)          if (ownbackstore)
948                  XCopyArea(display, backstore, backstore, gc, srcx, srcy,                  XCopyArea(display, backstore, backstore, gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
949          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
950  }  }
951    
# Line 1043  ui_memblt(uint8 opcode, Line 955  ui_memblt(uint8 opcode,
955            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ HBITMAP src, int srcx, int srcy)
956  {  {
957          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
958          XCopyArea(display, (Pixmap)src, wnd, gc, srcx, srcy, cx, cy, x, y);          XCopyArea(display, (Pixmap) src, wnd, gc, srcx, srcy, cx, cy, x, y);
959          if (ownbackstore)          if (ownbackstore)
960                  XCopyArea(display, (Pixmap)src, backstore, gc, srcx, srcy,                  XCopyArea(display, (Pixmap) src, backstore, gc, srcx, srcy, cx, cy, x, y);
                           cx, cy, x, y);  
961          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
962  }  }
963    
# Line 1054  void Line 965  void
965  ui_triblt(uint8 opcode,  ui_triblt(uint8 opcode,
966            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
967            /* src */ HBITMAP src, int srcx, int srcy,            /* src */ HBITMAP src, int srcx, int srcy,
968            /* brush */ BRUSH *brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
969  {  {
970          /* This is potentially difficult to do in general. Until someone          /* This is potentially difficult to do in general. Until someone
971             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 1063  ui_triblt(uint8 opcode, Line 974  ui_triblt(uint8 opcode,
974          {          {
975                  case 0x69:      /* PDSxxn */                  case 0x69:      /* PDSxxn */
976                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_XOR, x, y, cx, cy, src, srcx, srcy);
977                          ui_patblt(ROP2_NXOR, x, y, cx, cy,                          ui_patblt(ROP2_NXOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
978                          break;                          break;
979    
980                  case 0xb8:      /* PSDPxax */                  case 0xb8:      /* PSDPxax */
981                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
982                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_AND, x, y, cx, cy, src, srcx, srcy);
983                          ui_patblt(ROP2_XOR, x, y, cx, cy,                          ui_patblt(ROP2_XOR, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   brush, bgcolour, fgcolour);  
984                          break;                          break;
985    
986                  case 0xc0:      /* PSa */                  case 0xc0:      /* PSa */
987                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);                          ui_memblt(ROP2_COPY, x, y, cx, cy, src, srcx, srcy);
988                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour,                          ui_patblt(ROP2_AND, x, y, cx, cy, brush, bgcolour, fgcolour);
                                   fgcolour);  
989                          break;                          break;
990    
991                  default:                  default:
# Line 1090  ui_triblt(uint8 opcode, Line 997  ui_triblt(uint8 opcode,
997  void  void
998  ui_line(uint8 opcode,  ui_line(uint8 opcode,
999          /* dest */ int startx, int starty, int endx, int endy,          /* dest */ int startx, int starty, int endx, int endy,
1000          /* pen */ PEN *pen)          /* pen */ PEN * pen)
1001  {  {
1002          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
1003          SET_FOREGROUND(pen->colour);          SET_FOREGROUND(pen->colour);
# Line 1112  ui_rect( Line 1019  ui_rect(
1019  void  void
1020  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
1021                /* dest */ int x, int y, int cx, int cy,                /* dest */ int x, int y, int cx, int cy,
1022                /* src */ HGLYPH glyph, int srcx, int srcy, int bgcolour,                /* src */ HGLYPH glyph, int srcx, int srcy,
1023                int fgcolour)                int bgcolour, int fgcolour)
1024  {  {
1025          SET_FOREGROUND(fgcolour);          SET_FOREGROUND(fgcolour);
1026          SET_BACKGROUND(bgcolour);          SET_BACKGROUND(bgcolour);
1027    
1028          XSetFillStyle(display, gc, (mixmode == MIX_TRANSPARENT)          XSetFillStyle(display, gc,
1029                        ? FillStippled : FillOpaqueStippled);                        (mixmode == MIX_TRANSPARENT) ? FillStippled : FillOpaqueStippled);
1030          XSetStipple(display, gc, (Pixmap)glyph);          XSetStipple(display, gc, (Pixmap) glyph);
1031          XSetTSOrigin(display, gc, x, y);          XSetTSOrigin(display, gc, x, y);
1032    
1033          FILL_RECTANGLE(x, y, cx, cy);          FILL_RECTANGLE(x, y, cx, cy);
# Line 1137  ui_draw_glyph(int mixmode, Line 1044  ui_draw_glyph(int mixmode,
1044        if ((xyoffset & 0x80))\        if ((xyoffset & 0x80))\
1045          {\          {\
1046            if (flags & TEXT2_VERTICAL) \            if (flags & TEXT2_VERTICAL) \
1047              y += ttext[++idx] | (ttext[++idx] << 8);\              y += ttext[idx+1] | (ttext[idx+2] << 8);\
1048            else\            else\
1049              x += ttext[++idx] | (ttext[++idx] << 8);\              x += ttext[idx+1] | (ttext[idx+2] << 8);\
1050              idx += 2;\
1051          }\          }\
1052        else\        else\
1053          {\          {\
# Line 1162  ui_draw_glyph(int mixmode, Line 1070  ui_draw_glyph(int mixmode,
1070    
1071  void  void
1072  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,
1073               int clipx, int clipy, int clipcx, int clipcy, int boxx,               int clipx, int clipy, int clipcx, int clipcy,
1074               int boxy, int boxcx, int boxcy, int bgcolour,               int boxx, int boxy, int boxcx, int boxcy, int bgcolour,
1075               int fgcolour, uint8 * text, uint8 length)               int fgcolour, uint8 * text, uint8 length)
1076  {  {
1077          FONTGLYPH *glyph;          FONTGLYPH *glyph;
# Line 1182  ui_draw_text(uint8 font, uint8 flags, in Line 1090  ui_draw_text(uint8 font, uint8 flags, in
1090          }          }
1091    
1092          /* Paint text, character by character */          /* Paint text, character by character */
1093          for (i = 0; i < length;) {          for (i = 0; i < length;)
1094                  switch (text[i]) {          {
1095                  case 0xff:                  switch (text[i])
1096                          if (i + 2 < length)                  {
1097                                  cache_put_text(text[i + 1], text, text[i + 2]);                          case 0xff:
1098                          else {                                  if (i + 2 < length)
1099                                  error("this shouldn't be happening\n");                                          cache_put_text(text[i + 1], text, text[i + 2]);
1100                                    else
1101                                    {
1102                                            error("this shouldn't be happening\n");
1103                                            break;
1104                                    }
1105                                    /* this will move pointer from start to first character after FF command */
1106                                    length -= i + 3;
1107                                    text = &(text[i + 3]);
1108                                    i = 0;
1109                                  break;                                  break;
                         }  
                         /* this will move pointer from start to first character after FF command */  
                         length -= i + 3;  
                         text = &(text[i + 3]);  
                         i = 0;  
                         break;  
1110    
1111                  case 0xfe:                          case 0xfe:
1112                          entry = cache_get_text(text[i + 1]);                                  entry = cache_get_text(text[i + 1]);
1113                          if (entry != NULL) {                                  if (entry != NULL)
1114                                  if ((((uint8 *) (entry->data))[1] == 0)                                  {
1115                                      && (!(flags & TEXT2_IMPLICIT_X))) {                                          if ((((uint8 *) (entry->data))[1] ==
1116                                          if (flags & TEXT2_VERTICAL)                                               0) && (!(flags & TEXT2_IMPLICIT_X)))
1117                                                  y += text[i + 2];                                          {
1118                                                    if (flags & TEXT2_VERTICAL)
1119                                                            y += text[i + 2];
1120                                                    else
1121                                                            x += text[i + 2];
1122                                            }
1123                                            if (i + 2 < length)
1124                                                    i += 3;
1125                                          else                                          else
1126                                                  x += text[i + 2];                                                  i += 2;
1127                                            length -= i;
1128                                            /* this will move pointer from start to first character after FE command */
1129                                            text = &(text[i]);
1130                                            i = 0;
1131                                            for (j = 0; j < entry->size; j++)
1132                                                    DO_GLYPH(((uint8 *) (entry->data)), j);
1133                                  }                                  }
1134                                  if (i + 2 < length)                                  break;
                                         i += 3;  
                                 else  
                                         i += 2;  
                                 length -= i;  
                                 /* this will move pointer from start to first character after FE command */  
                                 text = &(text[i]);  
                                 i = 0;  
                                 for (j = 0; j < entry->size; j++)  
                                         DO_GLYPH(((uint8 *) (entry->data)), j);  
                         }  
                         break;  
1135    
1136                  default:                          default:
1137                          DO_GLYPH(text, i);                                  DO_GLYPH(text, i);
1138                          i++;                                  i++;
1139                          break;                                  break;
1140                  }                  }
1141          }          }
1142    
# Line 1238  ui_desktop_save(uint32 offset, int x, in Line 1151  ui_desktop_save(uint32 offset, int x, in
1151    
1152          if (ownbackstore)          if (ownbackstore)
1153          {          {
1154                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes,                  image = XGetImage(display, backstore, x, y, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1155          }          }
1156          else          else
1157          {          {
1158                  pix = XCreatePixmap(display, wnd, cx, cy, depth);                  pix = XCreatePixmap(display, wnd, cx, cy, depth);
1159                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);                  XCopyArea(display, wnd, pix, gc, x, y, cx, cy, 0, 0);
1160                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes,                  image = XGetImage(display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
                                   ZPixmap);  
1161                  XFreePixmap(display, pix);                  XFreePixmap(display, pix);
1162          }          }
1163    
1164          offset *= bpp/8;          offset *= bpp / 8;
1165          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, (uint8 *)image->data);  
1166    
1167          XDestroyImage(image);          XDestroyImage(image);
1168  }  }
# Line 1263  ui_desktop_restore(uint32 offset, int x, Line 1173  ui_desktop_restore(uint32 offset, int x,
1173          XImage *image;          XImage *image;
1174          uint8 *data;          uint8 *data;
1175    
1176          offset *= bpp/8;          offset *= bpp / 8;
1177          data = cache_get_desktop(offset, cx, cy, bpp/8);          data = cache_get_desktop(offset, cx, cy, bpp / 8);
1178          if (data == NULL)          if (data == NULL)
1179                  return;                  return;
1180    
1181          image = XCreateImage(display, visual, depth, ZPixmap,          image = XCreateImage(display, visual, depth, ZPixmap, 0,
1182                               0, data, cx, cy, BitmapPad(display),                               (char *) data, cx, cy, BitmapPad(display), cx * bpp / 8);
                              cx * bpp/8);  
1183    
1184          if (ownbackstore)          if (ownbackstore)
1185          {          {

Legend:
Removed from v.54  
changed lines
  Added in v.208

  ViewVC Help
Powered by ViewVC 1.1.26