/[rdesktop]/jpeg/rdesktop/trunk/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 /jpeg/rdesktop/trunk/xwin.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1246 by stargo, Tue Jul 11 17:22:24 2006 UTC revision 1453 by astrand, Fri Mar 14 07:39:38 2008 UTC
# Line 1  Line 1 
1  /* -*- c-basic-offset: 8 -*-  /* -*- c-basic-offset: 8 -*-
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-2005     Copyright (C) Matthew Chapman 1999-2007
5       Copyright 2007 Pierre Ossman <ossman@cendio.se> for Cendio AB
6    
7     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
8     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 21 
21    
22  #include <X11/Xlib.h>  #include <X11/Xlib.h>
23  #include <X11/Xutil.h>  #include <X11/Xutil.h>
24    #include <X11/Xproto.h>
25  #include <unistd.h>  #include <unistd.h>
26  #include <sys/time.h>  #include <sys/time.h>
27  #include <time.h>  #include <time.h>
# Line 28  Line 30 
30  #include "rdesktop.h"  #include "rdesktop.h"
31  #include "xproto.h"  #include "xproto.h"
32    
 /* We can't include Xproto.h because of conflicting defines for BOOL */  
 #define X_ConfigureWindow              12  
   
33  extern int g_width;  extern int g_width;
34  extern int g_height;  extern int g_height;
35  extern int g_xpos;  extern int g_xpos;
36  extern int g_ypos;  extern int g_ypos;
37  extern int g_pos;  extern int g_pos;
38  extern BOOL g_sendmotion;  extern RD_BOOL g_sendmotion;
39  extern BOOL g_fullscreen;  extern RD_BOOL g_fullscreen;
40  extern BOOL g_grab_keyboard;  extern RD_BOOL g_grab_keyboard;
41  extern BOOL g_hide_decorations;  extern RD_BOOL g_hide_decorations;
42  extern char g_title[];  extern char g_title[];
43  /* Color depth of the RDP session.  /* Color depth of the RDP session.
44     As of RDP 5.1, it may be 8, 15, 16 or 24. */     As of RDP 5.1, it may be 8, 15, 16 or 24. */
# Line 71  typedef struct _seamless_window Line 70  typedef struct _seamless_window
70          unsigned int desktop;          unsigned int desktop;
71          struct timeval *position_timer;          struct timeval *position_timer;
72    
73          BOOL outstanding_position;          RD_BOOL outstanding_position;
74          unsigned int outpos_serial;          unsigned int outpos_serial;
75          int outpos_xoffset, outpos_yoffset;          int outpos_xoffset, outpos_yoffset;
76          int outpos_width, outpos_height;          int outpos_width, outpos_height;
77    
78            unsigned int icon_size;
79            unsigned int icon_offset;
80            char icon_buffer[32 * 32 * 4];
81    
82          struct _seamless_window *next;          struct _seamless_window *next;
83  } seamless_window;  } seamless_window;
84  static seamless_window *g_seamless_windows = NULL;  static seamless_window *g_seamless_windows = NULL;
85  static unsigned long g_seamless_focused = 0;  static unsigned long g_seamless_focused = 0;
86  static BOOL g_seamless_started = False; /* Server end is up and running */  static RD_BOOL g_seamless_started = False;      /* Server end is up and running */
87  static BOOL g_seamless_active = False;  /* We are currently in seamless mode */  static RD_BOOL g_seamless_active = False;       /* We are currently in seamless mode */
88  static BOOL g_seamless_hidden = False;  /* Desktop is hidden on server */  static RD_BOOL g_seamless_hidden = False;       /* Desktop is hidden on server */
89  extern BOOL g_seamless_rdp;  extern RD_BOOL g_seamless_rdp;
90    
91  extern uint32 g_embed_wnd;  extern uint32 g_embed_wnd;
92  BOOL g_enable_compose = False;  RD_BOOL g_enable_compose = False;
93  BOOL g_Unobscured;              /* used for screenblt */  RD_BOOL g_Unobscured;           /* used for screenblt */
94  static GC g_gc = NULL;  static GC g_gc = NULL;
95  static GC g_create_bitmap_gc = NULL;  static GC g_create_bitmap_gc = NULL;
96  static GC g_create_glyph_gc = NULL;  static GC g_create_glyph_gc = NULL;
# Line 104  static int g_bpp; Line 107  static int g_bpp;
107  static XIM g_IM;  static XIM g_IM;
108  static XIC g_IC;  static XIC g_IC;
109  static XModifierKeymap *g_mod_map;  static XModifierKeymap *g_mod_map;
110    /* Maps logical (xmodmap -pp) pointing device buttons (0-based) back
111       to physical (1-based) indices. */
112    static unsigned char g_pointer_log_to_phys_map[16];
113  static Cursor g_current_cursor;  static Cursor g_current_cursor;
114  static HCURSOR g_null_cursor = NULL;  static RD_HCURSOR g_null_cursor = NULL;
115  static Atom g_protocol_atom, g_kill_atom;  static Atom g_protocol_atom, g_kill_atom;
116  extern Atom g_net_wm_state_atom;  extern Atom g_net_wm_state_atom;
117  extern Atom g_net_wm_desktop_atom;  extern Atom g_net_wm_desktop_atom;
118  static BOOL g_focused;  static RD_BOOL g_focused;
119  static BOOL g_mouse_in_wnd;  static RD_BOOL g_mouse_in_wnd;
120  /* Indicates that:  /* Indicates that:
121     1) visual has 15, 16 or 24 depth and the same color channel masks     1) visual has 15, 16 or 24 depth and the same color channel masks
122        as its RDP equivalent (implies X server is LE),        as its RDP equivalent (implies X server is LE),
123     2) host is LE     2) host is LE
124     This will trigger an optimization whose real value is questionable.     This will trigger an optimization whose real value is questionable.
125  */  */
126  static BOOL g_compatible_arch;  static RD_BOOL g_compatible_arch;
127  /* Indicates whether RDP's bitmaps and our XImages have the same  /* Indicates whether RDP's bitmaps and our XImages have the same
128     binary format. If so, we can avoid an expensive translation.     binary format. If so, we can avoid an expensive translation.
129     Note that this can be true when g_compatible_arch is false,     Note that this can be true when g_compatible_arch is false,
# Line 128  static BOOL g_compatible_arch; Line 134  static BOOL g_compatible_arch;
134     ('host' is the machine running rdesktop; the host simply memcpy's     ('host' is the machine running rdesktop; the host simply memcpy's
135      so its endianess doesn't matter)      so its endianess doesn't matter)
136   */   */
137  static BOOL g_no_translate_image = False;  static RD_BOOL g_no_translate_image = False;
138    
139  /* endianness */  /* endianness */
140  static BOOL g_host_be;  static RD_BOOL g_host_be;
141  static BOOL g_xserver_be;  static RD_BOOL g_xserver_be;
142  static int g_red_shift_r, g_blue_shift_r, g_green_shift_r;  static int g_red_shift_r, g_blue_shift_r, g_green_shift_r;
143  static int g_red_shift_l, g_blue_shift_l, g_green_shift_l;  static int g_red_shift_l, g_blue_shift_l, g_green_shift_l;
144    
145  /* software backing store */  /* software backing store */
146  extern BOOL g_ownbackstore;  extern RD_BOOL g_ownbackstore;
147  static Pixmap g_backstore = 0;  static Pixmap g_backstore = 0;
148    
149  /* Moving in single app mode */  /* Moving in single app mode */
150  static BOOL g_moving_wnd;  static RD_BOOL g_moving_wnd;
151  static int g_move_x_offset = 0;  static int g_move_x_offset = 0;
152  static int g_move_y_offset = 0;  static int g_move_y_offset = 0;
153  static BOOL g_using_full_workarea = False;  static RD_BOOL g_using_full_workarea = False;
154    
155  #ifdef WITH_RDPSND  #ifdef WITH_RDPSND
156  extern int g_dsp_fd;  extern RD_BOOL g_rdpsnd;
 extern BOOL g_dsp_busy;  
 extern BOOL g_rdpsnd;  
157  #endif  #endif
158    
159  /* MWM decorations */  /* MWM decorations */
# Line 242  seamless_XDrawLines(Drawable d, XPoint * Line 246  seamless_XDrawLines(Drawable d, XPoint *
246                          break; \                          break; \
247                  case 1: /* Filled */ \                  case 1: /* Filled */ \
248                          XFillArc(g_display, g_wnd, g_gc, x, y, cx, cy, 0, 360*64); \                          XFillArc(g_display, g_wnd, g_gc, x, y, cx, cy, 0, 360*64); \
249                          ON_ALL_SEAMLESS_WINDOWS(XCopyArea, (g_display, g_ownbackstore ? g_backstore : g_wnd, sw->wnd, g_gc, \                          ON_ALL_SEAMLESS_WINDOWS(XFillArc, (g_display, sw->wnd, g_gc, x-sw->xoffset, y-sw->yoffset, cx, cy, 0, 360*64)); \
                                                             x, y, cx, cy, x-sw->xoffset, y-sw->yoffset)); \  
250                          if (g_ownbackstore) \                          if (g_ownbackstore) \
251                                  XFillArc(g_display, g_backstore, g_gc, x, y, cx, cy, 0, 360*64); \                                  XFillArc(g_display, g_backstore, g_gc, x, y, cx, cy, 0, 360*64); \
252                          break; \                          break; \
# Line 251  seamless_XDrawLines(Drawable d, XPoint * Line 254  seamless_XDrawLines(Drawable d, XPoint *
254  }  }
255    
256  /* colour maps */  /* colour maps */
257  extern BOOL g_owncolmap;  extern RD_BOOL g_owncolmap;
258  static Colormap g_xcolmap;  static Colormap g_xcolmap;
259  static uint32 *g_colmap = NULL;  static uint32 *g_colmap = NULL;
260    
# Line 475  sw_handle_restack(seamless_window * sw) Line 478  sw_handle_restack(seamless_window * sw)
478    
479    
480  static seamless_group *  static seamless_group *
481  sw_find_group(unsigned long id, BOOL dont_create)  sw_find_group(unsigned long id, RD_BOOL dont_create)
482  {  {
483          seamless_window *sw;          seamless_window *sw;
484          seamless_group *sg;          seamless_group *sg;
# Line 580  translate_colour(uint32 colour) Line 583  translate_colour(uint32 colour)
583                          SPLITCOLOUR16(colour, pc);                          SPLITCOLOUR16(colour, pc);
584                          break;                          break;
585                  case 24:                  case 24:
586                    case 32:
587                          SPLITCOLOUR24(colour, pc);                          SPLITCOLOUR24(colour, pc);
588                          break;                          break;
589                  default:                  default:
# Line 1188  translate_image(int width, int height, u Line 1192  translate_image(int width, int height, u
1192             is only set for compatible depths, but the RDP depth might've             is only set for compatible depths, but the RDP depth might've
1193             changed during connection negotiations.             changed during connection negotiations.
1194           */           */
1195    
1196            /* todo */
1197            if (g_server_depth == 32 && g_depth == 24)
1198            {
1199                    return data;
1200            }
1201    
1202          if (g_no_translate_image)          if (g_no_translate_image)
1203          {          {
1204                  if ((g_depth == 15 && g_server_depth == 15) ||                  if ((g_depth == 15 && g_server_depth == 15) ||
# Line 1265  translate_image(int width, int height, u Line 1276  translate_image(int width, int height, u
1276          return out;          return out;
1277  }  }
1278    
1279  BOOL  static void
1280    xwin_refresh_pointer_map(void)
1281    {
1282            unsigned char phys_to_log_map[sizeof(g_pointer_log_to_phys_map)];
1283            int i, pointer_buttons;
1284    
1285            pointer_buttons = XGetPointerMapping(g_display, phys_to_log_map, sizeof(phys_to_log_map));
1286            for (i = 0; i < pointer_buttons; ++i)
1287            {
1288                    /* This might produce multiple logical buttons mapping
1289                       to a single physical one, but hey, that's
1290                       life... */
1291                    g_pointer_log_to_phys_map[phys_to_log_map[i] - 1] = i + 1;
1292            }
1293    }
1294    
1295    RD_BOOL
1296  get_key_state(unsigned int state, uint32 keysym)  get_key_state(unsigned int state, uint32 keysym)
1297  {  {
1298          int modifierpos, key, keysymMask = 0;          int modifierpos, key, keysymMask = 0;
# Line 1313  calculate_mask_weight(uint32 mask) Line 1340  calculate_mask_weight(uint32 mask)
1340          return weight;          return weight;
1341  }  }
1342    
1343  static BOOL  static RD_BOOL
1344  select_visual(int screen_num)  select_visual(int screen_num)
1345  {  {
1346          XPixmapFormatValues *pfm;          XPixmapFormatValues *pfm;
# Line 1341  select_visual(int screen_num) Line 1368  select_visual(int screen_num)
1368          /* Search for best TrueColor visual */          /* Search for best TrueColor visual */
1369          template.class = TrueColor;          template.class = TrueColor;
1370          template.screen = screen_num;          template.screen = screen_num;
1371          vmatches = XGetVisualInfo(g_display, VisualClassMask | VisualScreenMask, &template, &visuals_count);          vmatches =
1372                    XGetVisualInfo(g_display, VisualClassMask | VisualScreenMask, &template,
1373                                   &visuals_count);
1374          g_visual = NULL;          g_visual = NULL;
1375          g_no_translate_image = False;          g_no_translate_image = False;
1376          g_compatible_arch = False;          g_compatible_arch = False;
# Line 1350  select_visual(int screen_num) Line 1379  select_visual(int screen_num)
1379                  for (i = 0; i < visuals_count; ++i)                  for (i = 0; i < visuals_count; ++i)
1380                  {                  {
1381                          XVisualInfo *visual_info = &vmatches[i];                          XVisualInfo *visual_info = &vmatches[i];
1382                          BOOL can_translate_to_bpp = False;                          RD_BOOL can_translate_to_bpp = False;
1383                          int j;                          int j;
1384    
1385                          /* Try to find a no-translation visual that'll                          /* Try to find a no-translation visual that'll
# Line 1522  error_handler(Display * dpy, XErrorEvent Line 1551  error_handler(Display * dpy, XErrorEvent
1551          return g_old_error_handler(dpy, eev);          return g_old_error_handler(dpy, eev);
1552  }  }
1553    
1554  BOOL  RD_BOOL
1555  ui_init(void)  ui_init(void)
1556  {  {
1557          int screen_num;          int screen_num;
# Line 1536  ui_init(void) Line 1565  ui_init(void)
1565    
1566          {          {
1567                  uint16 endianess_test = 1;                  uint16 endianess_test = 1;
1568                  g_host_be = !(BOOL) (*(uint8 *) (&endianess_test));                  g_host_be = !(RD_BOOL) (*(uint8 *) (&endianess_test));
1569          }          }
1570    
1571          g_old_error_handler = XSetErrorHandler(error_handler);          g_old_error_handler = XSetErrorHandler(error_handler);
# Line 1617  ui_init(void) Line 1646  ui_init(void)
1646          g_width = (g_width + 3) & ~3;          g_width = (g_width + 3) & ~3;
1647    
1648          g_mod_map = XGetModifierMapping(g_display);          g_mod_map = XGetModifierMapping(g_display);
1649            xwin_refresh_pointer_map();
1650    
1651          xkeymap_init();          xkeymap_init();
1652    
# Line 1688  get_input_mask(long *input_mask) Line 1718  get_input_mask(long *input_mask)
1718                  *input_mask |= LeaveWindowMask;                  *input_mask |= LeaveWindowMask;
1719  }  }
1720    
1721  BOOL  RD_BOOL
1722  ui_create_window(void)  ui_create_window(void)
1723  {  {
1724          uint8 null_pointer_mask[1] = { 0x80 };          uint8 null_pointer_mask[1] = { 0x80 };
# Line 1736  ui_create_window(void) Line 1766  ui_create_window(void)
1766          }          }
1767    
1768          XStoreName(g_display, g_wnd, g_title);          XStoreName(g_display, g_wnd, g_title);
1769            ewmh_set_wm_name(g_wnd, g_title);
1770    
1771          if (g_hide_decorations)          if (g_hide_decorations)
1772                  mwm_hide_decorations(g_wnd);                  mwm_hide_decorations(g_wnd);
# Line 1875  xwin_toggle_fullscreen(void) Line 1906  xwin_toggle_fullscreen(void)
1906  }  }
1907    
1908  static void  static void
1909  handle_button_event(XEvent xevent, BOOL down)  handle_button_event(XEvent xevent, RD_BOOL down)
1910  {  {
1911          uint16 button, flags = 0;          uint16 button, flags = 0;
1912          g_last_gesturetime = xevent.xbutton.time;          g_last_gesturetime = xevent.xbutton.time;
1913            /* Reverse the pointer button mapping, e.g. in the case of
1914               "left-handed mouse mode"; the RDP session expects to
1915               receive physical buttons (true in mstsc as well) and
1916               logical button behavior depends on the remote desktop's own
1917               mouse settings */
1918            xevent.xbutton.button = g_pointer_log_to_phys_map[xevent.xbutton.button - 1];
1919          button = xkeymap_translate_button(xevent.xbutton.button);          button = xkeymap_translate_button(xevent.xbutton.button);
1920          if (button == 0)          if (button == 0)
1921                  return;                  return;
# Line 1991  xwin_process_events(void) Line 2028  xwin_process_events(void)
2028                                  /* the window manager told us to quit */                                  /* the window manager told us to quit */
2029                                  if ((xevent.xclient.message_type == g_protocol_atom)                                  if ((xevent.xclient.message_type == g_protocol_atom)
2030                                      && ((Atom) xevent.xclient.data.l[0] == g_kill_atom))                                      && ((Atom) xevent.xclient.data.l[0] == g_kill_atom))
2031                                          /* Quit */                                  {
2032                                          return 0;                                          /* When killing a seamless window, close the window on the
2033                                               serverside instead of terminating rdesktop */
2034                                            sw = sw_get_window_by_wnd(xevent.xclient.window);
2035                                            if (!sw)
2036                                                    /* Otherwise, quit */
2037                                                    return 0;
2038                                            /* send seamless destroy process message */
2039                                            seamless_send_destroy(sw->id);
2040                                    }
2041                                  break;                                  break;
2042    
2043                          case KeyPress:                          case KeyPress:
# Line 2166  xwin_process_events(void) Line 2211  xwin_process_events(void)
2211                                          XFreeModifiermap(g_mod_map);                                          XFreeModifiermap(g_mod_map);
2212                                          g_mod_map = XGetModifierMapping(g_display);                                          g_mod_map = XGetModifierMapping(g_display);
2213                                  }                                  }
2214    
2215                                    if (xevent.xmapping.request == MappingPointer)
2216                                    {
2217                                            xwin_refresh_pointer_map();
2218                                    }
2219    
2220                                  break;                                  break;
2221    
2222                                  /* clipboard stuff */                                  /* clipboard stuff */
# Line 2249  ui_select(int rdp_socket) Line 2300  ui_select(int rdp_socket)
2300          int n;          int n;
2301          fd_set rfds, wfds;          fd_set rfds, wfds;
2302          struct timeval tv;          struct timeval tv;
2303          BOOL s_timeout = False;          RD_BOOL s_timeout = False;
2304    
2305          while (True)          while (True)
2306          {          {
# Line 2267  ui_select(int rdp_socket) Line 2318  ui_select(int rdp_socket)
2318                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
2319                  FD_SET(g_x_socket, &rfds);                  FD_SET(g_x_socket, &rfds);
2320    
 #ifdef WITH_RDPSND  
                 /* FIXME: there should be an API for registering fds */  
                 if (g_dsp_busy)  
                 {  
                         FD_SET(g_dsp_fd, &wfds);  
                         n = (g_dsp_fd > n) ? g_dsp_fd : n;  
                 }  
 #endif  
2321                  /* default timeout */                  /* default timeout */
2322                  tv.tv_sec = 60;                  tv.tv_sec = 60;
2323                  tv.tv_usec = 0;                  tv.tv_usec = 0;
2324    
2325    #ifdef WITH_RDPSND
2326                    rdpsnd_add_fds(&n, &rfds, &wfds, &tv);
2327    #endif
2328    
2329                  /* add redirection handles */                  /* add redirection handles */
2330                  rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);                  rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);
2331                  seamless_select_timeout(&tv);                  seamless_select_timeout(&tv);
# Line 2291  ui_select(int rdp_socket) Line 2338  ui_select(int rdp_socket)
2338                                  error("select: %s\n", strerror(errno));                                  error("select: %s\n", strerror(errno));
2339    
2340                          case 0:                          case 0:
2341    #ifdef WITH_RDPSND
2342                                    rdpsnd_check_fds(&rfds, &wfds);
2343    #endif
2344    
2345                                  /* Abort serial read calls */                                  /* Abort serial read calls */
2346                                  if (s_timeout)                                  if (s_timeout)
2347                                          rdpdr_check_fds(&rfds, &wfds, (BOOL) True);                                          rdpdr_check_fds(&rfds, &wfds, (RD_BOOL) True);
2348                                  continue;                                  continue;
2349                  }                  }
2350    
2351                  rdpdr_check_fds(&rfds, &wfds, (BOOL) False);  #ifdef WITH_RDPSND
2352                    rdpsnd_check_fds(&rfds, &wfds);
2353    #endif
2354    
2355                    rdpdr_check_fds(&rfds, &wfds, (RD_BOOL) False);
2356    
2357                  if (FD_ISSET(rdp_socket, &rfds))                  if (FD_ISSET(rdp_socket, &rfds))
2358                          return 1;                          return 1;
2359    
 #ifdef WITH_RDPSND  
                 if (g_dsp_busy && FD_ISSET(g_dsp_fd, &wfds))  
                         wave_out_play();  
 #endif  
2360          }          }
2361  }  }
2362    
# Line 2315  ui_move_pointer(int x, int y) Line 2366  ui_move_pointer(int x, int y)
2366          XWarpPointer(g_display, g_wnd, g_wnd, 0, 0, 0, 0, x, y);          XWarpPointer(g_display, g_wnd, g_wnd, 0, 0, 0, 0, x, y);
2367  }  }
2368    
2369  HBITMAP  RD_HBITMAP
2370  ui_create_bitmap(int width, int height, uint8 * data)  ui_create_bitmap(int width, int height, uint8 * data)
2371  {  {
2372          XImage *image;          XImage *image;
# Line 2345  ui_create_bitmap(int width, int height, Line 2396  ui_create_bitmap(int width, int height,
2396          XFree(image);          XFree(image);
2397          if (tdata != data)          if (tdata != data)
2398                  xfree(tdata);                  xfree(tdata);
2399          return (HBITMAP) bitmap;          return (RD_HBITMAP) bitmap;
2400  }  }
2401    
2402  void  void
# Line 2393  ui_paint_bitmap(int x, int y, int cx, in Line 2444  ui_paint_bitmap(int x, int y, int cx, in
2444  }  }
2445    
2446  void  void
2447  ui_destroy_bitmap(HBITMAP bmp)  ui_destroy_bitmap(RD_HBITMAP bmp)
2448  {  {
2449          XFreePixmap(g_display, (Pixmap) bmp);          XFreePixmap(g_display, (Pixmap) bmp);
2450  }  }
2451    
2452  HGLYPH  RD_HGLYPH
2453  ui_create_glyph(int width, int height, uint8 * data)  ui_create_glyph(int width, int height, uint8 * data)
2454  {  {
2455          XImage *image;          XImage *image;
# Line 2420  ui_create_glyph(int width, int height, u Line 2471  ui_create_glyph(int width, int height, u
2471          XPutImage(g_display, bitmap, g_create_glyph_gc, image, 0, 0, 0, 0, width, height);          XPutImage(g_display, bitmap, g_create_glyph_gc, image, 0, 0, 0, 0, width, height);
2472    
2473          XFree(image);          XFree(image);
2474          return (HGLYPH) bitmap;          return (RD_HGLYPH) bitmap;
2475  }  }
2476    
2477  void  void
2478  ui_destroy_glyph(HGLYPH glyph)  ui_destroy_glyph(RD_HGLYPH glyph)
2479  {  {
2480          XFreePixmap(g_display, (Pixmap) glyph);          XFreePixmap(g_display, (Pixmap) glyph);
2481  }  }
2482    
2483  HCURSOR  RD_HCURSOR
2484  ui_create_cursor(unsigned int x, unsigned int y, int width, int height,  ui_create_cursor(unsigned int x, unsigned int y, int width, int height,
2485                   uint8 * andmask, uint8 * xormask)                   uint8 * andmask, uint8 * xormask)
2486  {  {
2487          HGLYPH maskglyph, cursorglyph;          RD_HGLYPH maskglyph, cursorglyph;
2488          XColor bg, fg;          XColor bg, fg;
2489          Cursor xcursor;          Cursor xcursor;
2490          uint8 *cursor, *pcursor;          uint8 *cursor, *pcursor;
# Line 2497  ui_create_cursor(unsigned int x, unsigne Line 2548  ui_create_cursor(unsigned int x, unsigne
2548          ui_destroy_glyph(cursorglyph);          ui_destroy_glyph(cursorglyph);
2549          xfree(mask);          xfree(mask);
2550          xfree(cursor);          xfree(cursor);
2551          return (HCURSOR) xcursor;          return (RD_HCURSOR) xcursor;
2552  }  }
2553    
2554  void  void
2555  ui_set_cursor(HCURSOR cursor)  ui_set_cursor(RD_HCURSOR cursor)
2556  {  {
2557          g_current_cursor = (Cursor) cursor;          g_current_cursor = (Cursor) cursor;
2558          XDefineCursor(g_display, g_wnd, g_current_cursor);          XDefineCursor(g_display, g_wnd, g_current_cursor);
# Line 2509  ui_set_cursor(HCURSOR cursor) Line 2560  ui_set_cursor(HCURSOR cursor)
2560  }  }
2561    
2562  void  void
2563  ui_destroy_cursor(HCURSOR cursor)  ui_destroy_cursor(RD_HCURSOR cursor)
2564  {  {
2565          XFreeCursor(g_display, (Cursor) cursor);          XFreeCursor(g_display, (Cursor) cursor);
2566  }  }
# Line 2527  ui_set_null_cursor(void) Line 2578  ui_set_null_cursor(void)
2578                  (xc)->flags = DoRed | DoGreen | DoBlue;                  (xc)->flags = DoRed | DoGreen | DoBlue;
2579    
2580    
2581  HCOLOURMAP  RD_HCOLOURMAP
2582  ui_create_colourmap(COLOURMAP * colours)  ui_create_colourmap(COLOURMAP * colours)
2583  {  {
2584          COLOURENTRY *entry;          COLOURENTRY *entry;
# Line 2623  ui_create_colourmap(COLOURMAP * colours) Line 2674  ui_create_colourmap(COLOURMAP * colours)
2674                  XStoreColors(g_display, map, xcolours, ncolours);                  XStoreColors(g_display, map, xcolours, ncolours);
2675    
2676                  xfree(xcolours);                  xfree(xcolours);
2677                  return (HCOLOURMAP) map;                  return (RD_HCOLOURMAP) map;
2678          }          }
2679  }  }
2680    
2681  void  void
2682  ui_destroy_colourmap(HCOLOURMAP map)  ui_destroy_colourmap(RD_HCOLOURMAP map)
2683  {  {
2684          if (!g_owncolmap)          if (!g_owncolmap)
2685                  xfree(map);                  xfree(map);
# Line 2637  ui_destroy_colourmap(HCOLOURMAP map) Line 2688  ui_destroy_colourmap(HCOLOURMAP map)
2688  }  }
2689    
2690  void  void
2691  ui_set_colourmap(HCOLOURMAP map)  ui_set_colourmap(RD_HCOLOURMAP map)
2692  {  {
2693          if (!g_owncolmap)          if (!g_owncolmap)
2694          {          {
# Line 2725  ui_patblt(uint8 opcode, Line 2776  ui_patblt(uint8 opcode,
2776                          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);                          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
2777                          XSetFillStyle(g_display, g_gc, FillSolid);                          XSetFillStyle(g_display, g_gc, FillSolid);
2778                          XSetTSOrigin(g_display, g_gc, 0, 0);                          XSetTSOrigin(g_display, g_gc, 0, 0);
2779                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((RD_HGLYPH) fill);
2780                          break;                          break;
2781    
2782                  case 3: /* Pattern */                  case 3: /* Pattern */
# Line 2740  ui_patblt(uint8 opcode, Line 2791  ui_patblt(uint8 opcode,
2791                          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);                          FILL_RECTANGLE_BACKSTORE(x, y, cx, cy);
2792                          XSetFillStyle(g_display, g_gc, FillSolid);                          XSetFillStyle(g_display, g_gc, FillSolid);
2793                          XSetTSOrigin(g_display, g_gc, 0, 0);                          XSetTSOrigin(g_display, g_gc, 0, 0);
2794                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((RD_HGLYPH) fill);
2795                          break;                          break;
2796    
2797                  default:                  default:
# Line 2783  ui_screenblt(uint8 opcode, Line 2834  ui_screenblt(uint8 opcode,
2834  void  void
2835  ui_memblt(uint8 opcode,  ui_memblt(uint8 opcode,
2836            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
2837            /* src */ HBITMAP src, int srcx, int srcy)            /* src */ RD_HBITMAP src, int srcx, int srcy)
2838  {  {
2839          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
2840          XCopyArea(g_display, (Pixmap) src, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);          XCopyArea(g_display, (Pixmap) src, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
# Line 2798  ui_memblt(uint8 opcode, Line 2849  ui_memblt(uint8 opcode,
2849  void  void
2850  ui_triblt(uint8 opcode,  ui_triblt(uint8 opcode,
2851            /* dest */ int x, int y, int cx, int cy,            /* dest */ int x, int y, int cx, int cy,
2852            /* src */ HBITMAP src, int srcx, int srcy,            /* src */ RD_HBITMAP src, int srcx, int srcy,
2853            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)            /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2854  {  {
2855          /* This is potentially difficult to do in general. Until someone          /* This is potentially difficult to do in general. Until someone
# Line 2856  ui_rect( Line 2907  ui_rect(
2907  void  void
2908  ui_polygon(uint8 opcode,  ui_polygon(uint8 opcode,
2909             /* mode */ uint8 fillmode,             /* mode */ uint8 fillmode,
2910             /* dest */ POINT * point, int npoints,             /* dest */ RD_POINT * point, int npoints,
2911             /* brush */ BRUSH * brush, int bgcolour, int fgcolour)             /* brush */ BRUSH * brush, int bgcolour, int fgcolour)
2912  {  {
2913          uint8 style, i, ipattern[8];          uint8 style, i, ipattern[8];
# Line 2899  ui_polygon(uint8 opcode, Line 2950  ui_polygon(uint8 opcode,
2950                          FILL_POLYGON((XPoint *) point, npoints);                          FILL_POLYGON((XPoint *) point, npoints);
2951                          XSetFillStyle(g_display, g_gc, FillSolid);                          XSetFillStyle(g_display, g_gc, FillSolid);
2952                          XSetTSOrigin(g_display, g_gc, 0, 0);                          XSetTSOrigin(g_display, g_gc, 0, 0);
2953                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((RD_HGLYPH) fill);
2954                          break;                          break;
2955    
2956                  case 3: /* Pattern */                  case 3: /* Pattern */
# Line 2914  ui_polygon(uint8 opcode, Line 2965  ui_polygon(uint8 opcode,
2965                          FILL_POLYGON((XPoint *) point, npoints);                          FILL_POLYGON((XPoint *) point, npoints);
2966                          XSetFillStyle(g_display, g_gc, FillSolid);                          XSetFillStyle(g_display, g_gc, FillSolid);
2967                          XSetTSOrigin(g_display, g_gc, 0, 0);                          XSetTSOrigin(g_display, g_gc, 0, 0);
2968                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((RD_HGLYPH) fill);
2969                          break;                          break;
2970    
2971                  default:                  default:
# Line 2926  ui_polygon(uint8 opcode, Line 2977  ui_polygon(uint8 opcode,
2977    
2978  void  void
2979  ui_polyline(uint8 opcode,  ui_polyline(uint8 opcode,
2980              /* dest */ POINT * points, int npoints,              /* dest */ RD_POINT * points, int npoints,
2981              /* pen */ PEN * pen)              /* pen */ PEN * pen)
2982  {  {
2983          /* TODO: set join style */          /* TODO: set join style */
# Line 2977  ui_ellipse(uint8 opcode, Line 3028  ui_ellipse(uint8 opcode,
3028                          DRAW_ELLIPSE(x, y, cx, cy, fillmode);                          DRAW_ELLIPSE(x, y, cx, cy, fillmode);
3029                          XSetFillStyle(g_display, g_gc, FillSolid);                          XSetFillStyle(g_display, g_gc, FillSolid);
3030                          XSetTSOrigin(g_display, g_gc, 0, 0);                          XSetTSOrigin(g_display, g_gc, 0, 0);
3031                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((RD_HGLYPH) fill);
3032                          break;                          break;
3033    
3034                  case 3: /* Pattern */                  case 3: /* Pattern */
# Line 2992  ui_ellipse(uint8 opcode, Line 3043  ui_ellipse(uint8 opcode,
3043                          DRAW_ELLIPSE(x, y, cx, cy, fillmode);                          DRAW_ELLIPSE(x, y, cx, cy, fillmode);
3044                          XSetFillStyle(g_display, g_gc, FillSolid);                          XSetFillStyle(g_display, g_gc, FillSolid);
3045                          XSetTSOrigin(g_display, g_gc, 0, 0);                          XSetTSOrigin(g_display, g_gc, 0, 0);
3046                          ui_destroy_glyph((HGLYPH) fill);                          ui_destroy_glyph((RD_HGLYPH) fill);
3047                          break;                          break;
3048    
3049                  default:                  default:
# Line 3006  ui_ellipse(uint8 opcode, Line 3057  ui_ellipse(uint8 opcode,
3057  void  void
3058  ui_draw_glyph(int mixmode,  ui_draw_glyph(int mixmode,
3059                /* dest */ int x, int y, int cx, int cy,                /* dest */ int x, int y, int cx, int cy,
3060                /* src */ HGLYPH glyph, int srcx, int srcy,                /* src */ RD_HGLYPH glyph, int srcx, int srcy,
3061                int bgcolour, int fgcolour)                int bgcolour, int fgcolour)
3062  {  {
3063          SET_FOREGROUND(fgcolour);          SET_FOREGROUND(fgcolour);
# Line 3191  ui_desktop_save(uint32 offset, int x, in Line 3242  ui_desktop_save(uint32 offset, int x, in
3242          if (g_ownbackstore)          if (g_ownbackstore)
3243          {          {
3244                  image = XGetImage(g_display, g_backstore, x, y, cx, cy, AllPlanes, ZPixmap);                  image = XGetImage(g_display, g_backstore, x, y, cx, cy, AllPlanes, ZPixmap);
3245                    exit_if_null(image);
3246          }          }
3247          else          else
3248          {          {
3249                  pix = XCreatePixmap(g_display, g_wnd, cx, cy, g_depth);                  pix = XCreatePixmap(g_display, g_wnd, cx, cy, g_depth);
3250                  XCopyArea(g_display, g_wnd, pix, g_gc, x, y, cx, cy, 0, 0);                  XCopyArea(g_display, g_wnd, pix, g_gc, x, y, cx, cy, 0, 0);
3251                  image = XGetImage(g_display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);                  image = XGetImage(g_display, pix, 0, 0, cx, cy, AllPlanes, ZPixmap);
3252                    exit_if_null(image);
3253                  XFreePixmap(g_display, pix);                  XFreePixmap(g_display, pix);
3254          }          }
3255    
# Line 3218  ui_desktop_restore(uint32 offset, int x, Line 3271  ui_desktop_restore(uint32 offset, int x,
3271                  return;                  return;
3272    
3273          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,          image = XCreateImage(g_display, g_visual, g_depth, ZPixmap, 0,
3274                               (char *) data, cx, cy, BitmapPad(g_display), cx * g_bpp / 8);                               (char *) data, cx, cy, g_bpp, 0);
3275    
3276          if (g_ownbackstore)          if (g_ownbackstore)
3277          {          {
# Line 3252  ui_end_update(void) Line 3305  ui_end_update(void)
3305    
3306    
3307  void  void
3308  ui_seamless_begin(BOOL hidden)  ui_seamless_begin(RD_BOOL hidden)
3309  {  {
3310          if (!g_seamless_rdp)          if (!g_seamless_rdp)
3311                  return;                  return;
# Line 3407  ui_seamless_create_window(unsigned long Line 3460  ui_seamless_create_window(unsigned long
3460                  ewmh_set_window_modal(wnd);                  ewmh_set_window_modal(wnd);
3461          }          }
3462    
3463            if (flags & SEAMLESSRDP_CREATE_TOPMOST)
3464            {
3465                    /* Make window always-on-top */
3466                    ewmh_set_window_above(wnd);
3467            }
3468    
3469          /* FIXME: Support for Input Context:s */          /* FIXME: Support for Input Context:s */
3470    
3471          get_input_mask(&input_mask);          get_input_mask(&input_mask);
# Line 3414  ui_seamless_create_window(unsigned long Line 3473  ui_seamless_create_window(unsigned long
3473    
3474          XSelectInput(g_display, wnd, input_mask);          XSelectInput(g_display, wnd, input_mask);
3475    
3476          /* handle the WM_DELETE_WINDOW protocol. FIXME: When killing a          /* handle the WM_DELETE_WINDOW protocol. */
            seamless window, we could try to close the window on the  
            serverside, instead of terminating rdesktop */  
3477          XSetWMProtocols(g_display, wnd, &g_kill_atom, 1);          XSetWMProtocols(g_display, wnd, &g_kill_atom, 1);
3478    
3479          sw = xmalloc(sizeof(seamless_window));          sw = xmalloc(sizeof(seamless_window));
3480    
3481            memset(sw, 0, sizeof(seamless_window));
3482    
3483          sw->wnd = wnd;          sw->wnd = wnd;
3484          sw->id = id;          sw->id = id;
         sw->behind = 0;  
3485          sw->group = sw_find_group(group, False);          sw->group = sw_find_group(group, False);
3486          sw->group->refcnt++;          sw->group->refcnt++;
         sw->xoffset = 0;  
         sw->yoffset = 0;  
         sw->width = 0;  
         sw->height = 0;  
3487          sw->state = SEAMLESSRDP_NOTYETMAPPED;          sw->state = SEAMLESSRDP_NOTYETMAPPED;
3488          sw->desktop = 0;          sw->desktop = 0;
3489          sw->position_timer = xmalloc(sizeof(struct timeval));          sw->position_timer = xmalloc(sizeof(struct timeval));
# Line 3496  ui_seamless_destroy_group(unsigned long Line 3551  ui_seamless_destroy_group(unsigned long
3551    
3552    
3553  void  void
3554    ui_seamless_seticon(unsigned long id, const char *format, int width, int height, int chunk,
3555                        const char *data, int chunk_len)
3556    {
3557            seamless_window *sw;
3558    
3559            if (!g_seamless_active)
3560                    return;
3561    
3562            sw = sw_get_window_by_id(id);
3563            if (!sw)
3564            {
3565                    warning("ui_seamless_seticon: No information for window 0x%lx\n", id);
3566                    return;
3567            }
3568    
3569            if (chunk == 0)
3570            {
3571                    if (sw->icon_size)
3572                            warning("ui_seamless_seticon: New icon started before previous completed\n");
3573    
3574                    if (strcmp(format, "RGBA") != 0)
3575                    {
3576                            warning("ui_seamless_seticon: Uknown icon format \"%s\"\n", format);
3577                            return;
3578                    }
3579    
3580                    sw->icon_size = width * height * 4;
3581                    if (sw->icon_size > 32 * 32 * 4)
3582                    {
3583                            warning("ui_seamless_seticon: Icon too large (%d bytes)\n", sw->icon_size);
3584                            sw->icon_size = 0;
3585                            return;
3586                    }
3587    
3588                    sw->icon_offset = 0;
3589            }
3590            else
3591            {
3592                    if (!sw->icon_size)
3593                            return;
3594            }
3595    
3596            if (chunk_len > (sw->icon_size - sw->icon_offset))
3597            {
3598                    warning("ui_seamless_seticon: Too large chunk received (%d bytes > %d bytes)\n",
3599                            chunk_len, sw->icon_size - sw->icon_offset);
3600                    sw->icon_size = 0;
3601                    return;
3602            }
3603    
3604            memcpy(sw->icon_buffer + sw->icon_offset, data, chunk_len);
3605            sw->icon_offset += chunk_len;
3606    
3607            if (sw->icon_offset == sw->icon_size)
3608            {
3609                    ewmh_set_icon(sw->wnd, width, height, sw->icon_buffer);
3610                    sw->icon_size = 0;
3611            }
3612    }
3613    
3614    
3615    void
3616    ui_seamless_delicon(unsigned long id, const char *format, int width, int height)
3617    {
3618            seamless_window *sw;
3619    
3620            if (!g_seamless_active)
3621                    return;
3622    
3623            sw = sw_get_window_by_id(id);
3624            if (!sw)
3625            {
3626                    warning("ui_seamless_seticon: No information for window 0x%lx\n", id);
3627                    return;
3628            }
3629    
3630            if (strcmp(format, "RGBA") != 0)
3631            {
3632                    warning("ui_seamless_seticon: Uknown icon format \"%s\"\n", format);
3633                    return;
3634            }
3635    
3636            ewmh_del_icon(sw->wnd, width, height);
3637    }
3638    
3639    
3640    void
3641  ui_seamless_move_window(unsigned long id, int x, int y, int width, int height, unsigned long flags)  ui_seamless_move_window(unsigned long id, int x, int y, int width, int height, unsigned long flags)
3642  {  {
3643          seamless_window *sw;          seamless_window *sw;
# Line 3560  ui_seamless_restack_window(unsigned long Line 3702  ui_seamless_restack_window(unsigned long
3702                  sw_behind = sw_get_window_by_id(behind);                  sw_behind = sw_get_window_by_id(behind);
3703                  if (!sw_behind)                  if (!sw_behind)
3704                  {                  {
3705                          warning("ui_seamless_restack_window: No information for window 0x%lx\n",                          warning("ui_seamless_restack_window: No information for behind window 0x%lx\n", behind);
                                 behind);  
3706                          return;                          return;
3707                  }                  }
3708    
3709                  wnds[1] = sw_behind->wnd;                  wnds[1] = sw->wnd;
3710                  wnds[0] = sw->wnd;                  wnds[0] = sw_behind->wnd;
3711    
3712                  XRestackWindows(g_display, wnds, 2);                  XRestackWindows(g_display, wnds, 2);
3713          }          }
# Line 3576  ui_seamless_restack_window(unsigned long Line 3717  ui_seamless_restack_window(unsigned long
3717          }          }
3718    
3719          sw_restack_window(sw, behind);          sw_restack_window(sw, behind);
3720    
3721            if (flags & SEAMLESSRDP_CREATE_TOPMOST)
3722            {
3723                    /* Make window always-on-top */
3724                    ewmh_set_window_above(sw->wnd);
3725            }
3726  }  }
3727    
3728    

Legend:
Removed from v.1246  
changed lines
  Added in v.1453

  ViewVC Help
Powered by ViewVC 1.1.26