/[rdesktop]/sourceforge.net/branches/seamlessrdp-branch/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/branches/seamlessrdp-branch/rdesktop/xwin.c

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

sourceforge.net/trunk/rdesktop/xwin.c revision 1049 by astrand, Wed Mar 1 13:54:19 2006 UTC sourceforge.net/branches/seamlessrdp-branch/rdesktop/xwin.c revision 1103 by astrand, Fri Mar 10 13:32:18 2006 UTC
# Line 48  Time g_last_gesturetime; Line 48  Time g_last_gesturetime;
48  static int g_x_socket;  static int g_x_socket;
49  static Screen *g_screen;  static Screen *g_screen;
50  Window g_wnd;  Window g_wnd;
51    
52    /* SeamlessRDP support */
53    typedef struct _seamless_window
54    {
55            Window wnd;
56            unsigned long id;
57            int xoffset, yoffset;
58            int width, height;
59            struct _seamless_window *next;
60    } seamless_window;
61    static seamless_window *g_seamless_windows = NULL;
62    extern BOOL g_seamless_rdp;
63    
64  extern uint32 g_embed_wnd;  extern uint32 g_embed_wnd;
65  BOOL g_enable_compose = False;  BOOL g_enable_compose = False;
66  BOOL g_Unobscured;              /* used for screenblt */  BOOL g_Unobscured;              /* used for screenblt */
67  static GC g_gc = NULL;  static GC g_gc = NULL;
68  static GC g_create_bitmap_gc = NULL;  static GC g_create_bitmap_gc = NULL;
69  static GC g_create_glyph_gc = NULL;  static GC g_create_glyph_gc = NULL;
70    static XRectangle g_clip_rectangle;
71  static Visual *g_visual;  static Visual *g_visual;
72  /* Color depth of the X11 visual of our window (e.g. 24 for True Color R8G8B visual).  /* Color depth of the X11 visual of our window (e.g. 24 for True Color R8G8B visual).
73     This may be 32 for R8G8B8 visuals, and then the rest of the bits are undefined     This may be 32 for R8G8B8 visuals, and then the rest of the bits are undefined
# Line 133  typedef struct Line 147  typedef struct
147  }  }
148  PixelColour;  PixelColour;
149    
150    #define ON_ALL_SEAMLESS_WINDOWS(func, args) \
151            do { \
152                    seamless_window *sw; \
153                    XRectangle rect; \
154                    for (sw = g_seamless_windows; sw; sw = sw->next) { \
155                        rect.x = g_clip_rectangle.x - sw->xoffset; \
156                        rect.y = g_clip_rectangle.y - sw->yoffset; \
157                        rect.width = g_clip_rectangle.width; \
158                        rect.height = g_clip_rectangle.height; \
159                        XSetClipRectangles(g_display, g_gc, 0, 0, &rect, 1, YXBanded); \
160                        func args; \
161                    } \
162                    XSetClipRectangles(g_display, g_gc, 0, 0, &g_clip_rectangle, 1, YXBanded); \
163            } while (0)
164    
165    static void
166    seamless_XFillPolygon(Drawable d, XPoint * points, int npoints, int xoffset, int yoffset)
167    {
168            points[0].x -= xoffset;
169            points[0].y -= yoffset;
170            XFillPolygon(g_display, d, g_gc, points, npoints, Complex, CoordModePrevious);
171            points[0].x += xoffset;
172            points[0].y += yoffset;
173    }
174    
175    static void
176    seamless_XDrawLines(Drawable d, XPoint * points, int npoints, int xoffset, int yoffset)
177    {
178            points[0].x -= xoffset;
179            points[0].y -= yoffset;
180            XDrawLines(g_display, d, g_gc, points, npoints, CoordModePrevious);
181            points[0].x += xoffset;
182            points[0].y += yoffset;
183    }
184    
185  #define FILL_RECTANGLE(x,y,cx,cy)\  #define FILL_RECTANGLE(x,y,cx,cy)\
186  { \  { \
187          XFillRectangle(g_display, g_wnd, g_gc, x, y, cx, cy); \          XFillRectangle(g_display, g_wnd, g_gc, x, y, cx, cy); \
188            ON_ALL_SEAMLESS_WINDOWS(XFillRectangle, (g_display, sw->wnd, g_gc, x-sw->xoffset, y-sw->yoffset, cx, cy)); \
189          if (g_ownbackstore) \          if (g_ownbackstore) \
190                  XFillRectangle(g_display, g_backstore, g_gc, x, y, cx, cy); \                  XFillRectangle(g_display, g_backstore, g_gc, x, y, cx, cy); \
191  }  }
# Line 151  PixelColour; Line 200  PixelColour;
200          XFillPolygon(g_display, g_wnd, g_gc, p, np, Complex, CoordModePrevious); \          XFillPolygon(g_display, g_wnd, g_gc, p, np, Complex, CoordModePrevious); \
201          if (g_ownbackstore) \          if (g_ownbackstore) \
202                  XFillPolygon(g_display, g_backstore, g_gc, p, np, Complex, CoordModePrevious); \                  XFillPolygon(g_display, g_backstore, g_gc, p, np, Complex, CoordModePrevious); \
203            ON_ALL_SEAMLESS_WINDOWS(seamless_XFillPolygon, (sw->wnd, p, np, sw->xoffset, sw->yoffset)); \
204  }  }
205    
206  #define DRAW_ELLIPSE(x,y,cx,cy,m)\  #define DRAW_ELLIPSE(x,y,cx,cy,m)\
# Line 159  PixelColour; Line 209  PixelColour;
209          { \          { \
210                  case 0: /* Outline */ \                  case 0: /* Outline */ \
211                          XDrawArc(g_display, g_wnd, g_gc, x, y, cx, cy, 0, 360*64); \                          XDrawArc(g_display, g_wnd, g_gc, x, y, cx, cy, 0, 360*64); \
212                            ON_ALL_SEAMLESS_WINDOWS(XDrawArc, (g_display, sw->wnd, g_gc, x-sw->xoffset, y-sw->yoffset, cx, cy, 0, 360*64)); \
213                          if (g_ownbackstore) \                          if (g_ownbackstore) \
214                                  XDrawArc(g_display, g_backstore, g_gc, x, y, cx, cy, 0, 360*64); \                                  XDrawArc(g_display, g_backstore, g_gc, x, y, cx, cy, 0, 360*64); \
215                          break; \                          break; \
216                  case 1: /* Filled */ \                  case 1: /* Filled */ \
217                          XFillArc(g_display, g_wnd, g_gc, x, y, cx, cy, 0, 360*64); \                          XFillArc(g_display, g_wnd, g_gc, x, y, \
218                                     cx, cy, 0, 360*64); \
219                            ON_ALL_SEAMLESS_WINDOWS(XCopyArea, (g_display, g_ownbackstore ? g_backstore : g_wnd, sw->wnd, g_gc, x, y, cx, cy, x-sw->xoffset, y-sw->yoffset)); \
220                          if (g_ownbackstore) \                          if (g_ownbackstore) \
221                                  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); \
222                          break; \                          break; \
# Line 201  static int rop2_map[] = { Line 254  static int rop2_map[] = {
254  #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(g_display, g_gc, rop2_map[rop2]); }  #define SET_FUNCTION(rop2)      { if (rop2 != ROP2_COPY) XSetFunction(g_display, g_gc, rop2_map[rop2]); }
255  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(g_display, g_gc, GXcopy); }  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(g_display, g_gc, GXcopy); }
256    
257    static seamless_window *
258    seamless_get_window_by_id(unsigned long id)
259    {
260            seamless_window *sw;
261            for (sw = g_seamless_windows; sw; sw = sw->next)
262            {
263                    if (sw->id == id)
264                            return sw;
265            }
266            return NULL;
267    }
268    
269    
270    static seamless_window *
271    seamless_get_window_by_wnd(Window wnd)
272    {
273            seamless_window *sw;
274            for (sw = g_seamless_windows; sw; sw = sw->next)
275            {
276                    if (sw->wnd == wnd)
277                            return sw;
278            }
279            return NULL;
280    }
281    
282    
283    static void
284    seamless_remove_window(seamless_window * win)
285    {
286            seamless_window *sw, **prevnext = &g_seamless_windows;
287            for (sw = g_seamless_windows; sw; sw = sw->next)
288            {
289                    if (sw == win)
290                    {
291                            *prevnext = sw->next;
292                            xfree(sw);
293                            return;
294                    }
295                    prevnext = &sw->next;
296            }
297            return;
298    }
299    
300    
301  static void  static void
302  mwm_hide_decorations(void)  mwm_hide_decorations(Window wnd)
303  {  {
304          PropMotifWmHints motif_hints;          PropMotifWmHints motif_hints;
305          Atom hintsatom;          Atom hintsatom;
# Line 219  mwm_hide_decorations(void) Line 316  mwm_hide_decorations(void)
316                  return;                  return;
317          }          }
318    
319          XChangeProperty(g_display, g_wnd, hintsatom, hintsatom, 32, PropModeReplace,          XChangeProperty(g_display, wnd, hintsatom, hintsatom, 32, PropModeReplace,
320                          (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);                          (unsigned char *) &motif_hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
321    
322  }  }
323    
324  #define SPLITCOLOUR15(colour, rv) \  #define SPLITCOLOUR15(colour, rv) \
# Line 1259  ui_init(void) Line 1357  ui_init(void)
1357          {          {
1358                  g_width = WidthOfScreen(g_screen);                  g_width = WidthOfScreen(g_screen);
1359                  g_height = HeightOfScreen(g_screen);                  g_height = HeightOfScreen(g_screen);
1360                    g_using_full_workarea = True;
1361          }          }
1362          else if (g_width < 0)          else if (g_width < 0)
1363          {          {
# Line 1272  ui_init(void) Line 1371  ui_init(void)
1371          {          {
1372                  /* Fetch geometry from _NET_WORKAREA */                  /* Fetch geometry from _NET_WORKAREA */
1373                  uint32 x, y, cx, cy;                  uint32 x, y, cx, cy;
                 g_using_full_workarea = True;  
   
1374                  if (get_current_workarea(&x, &y, &cx, &cy) == 0)                  if (get_current_workarea(&x, &y, &cx, &cy) == 0)
1375                  {                  {
1376                          g_width = cx;                          g_width = cx;
1377                          g_height = cy;                          g_height = cy;
1378                            g_using_full_workarea = True;
1379                  }                  }
1380                  else                  else
1381                  {                  {
1382                          warning("Failed to get workarea: probably your window manager does not support extended hints\n");                          warning("Failed to get workarea: probably your window manager does not support extended hints\n");
1383                          g_width = 800;                          g_width = WidthOfScreen(g_screen);
1384                          g_height = 600;                          g_height = HeightOfScreen(g_screen);
1385                  }                  }
1386          }          }
1387    
# Line 1298  ui_init(void) Line 1396  ui_init(void)
1396                  g_IM = XOpenIM(g_display, NULL, NULL, NULL);                  g_IM = XOpenIM(g_display, NULL, NULL, NULL);
1397    
1398          xclip_init();          xclip_init();
1399            if (g_seamless_rdp)
1400                    seamless_init();
1401    
1402          DEBUG_RDP5(("server bpp %d client bpp %d depth %d\n", g_server_depth, g_bpp, g_depth));          DEBUG_RDP5(("server bpp %d client bpp %d depth %d\n", g_server_depth, g_bpp, g_depth));
1403    
# Line 1323  ui_deinit(void) Line 1423  ui_deinit(void)
1423          g_display = NULL;          g_display = NULL;
1424  }  }
1425    
1426    
1427    static void
1428    get_window_attribs(XSetWindowAttributes * attribs)
1429    {
1430            attribs->background_pixel = BlackPixelOfScreen(g_screen);
1431            attribs->background_pixel = WhitePixelOfScreen(g_screen);
1432            attribs->border_pixel = WhitePixelOfScreen(g_screen);
1433            attribs->backing_store = g_ownbackstore ? NotUseful : Always;
1434            attribs->override_redirect = g_fullscreen;
1435            attribs->colormap = g_xcolmap;
1436    }
1437    
1438    static void
1439    get_input_mask(long *input_mask)
1440    {
1441            *input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
1442                    VisibilityChangeMask | FocusChangeMask | StructureNotifyMask;
1443    
1444            if (g_sendmotion)
1445                    *input_mask |= PointerMotionMask;
1446            if (g_ownbackstore)
1447                    *input_mask |= ExposureMask;
1448            if (g_fullscreen || g_grab_keyboard)
1449                    *input_mask |= EnterWindowMask;
1450            if (g_grab_keyboard)
1451                    *input_mask |= LeaveWindowMask;
1452    }
1453    
1454  BOOL  BOOL
1455  ui_create_window(void)  ui_create_window(void)
1456  {  {
# Line 1345  ui_create_window(void) Line 1473  ui_create_window(void)
1473          if (g_ypos < 0 || (g_ypos == 0 && (g_pos & 4)))          if (g_ypos < 0 || (g_ypos == 0 && (g_pos & 4)))
1474                  g_ypos = HeightOfScreen(g_screen) + g_ypos - g_height;                  g_ypos = HeightOfScreen(g_screen) + g_ypos - g_height;
1475    
1476          attribs.background_pixel = BlackPixelOfScreen(g_screen);          get_window_attribs(&attribs);
         attribs.border_pixel = WhitePixelOfScreen(g_screen);  
         attribs.backing_store = g_ownbackstore ? NotUseful : Always;  
         attribs.override_redirect = g_fullscreen;  
         attribs.colormap = g_xcolmap;  
1477    
1478          g_wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), g_xpos, g_ypos, wndwidth,          g_wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), g_xpos, g_ypos, wndwidth,
1479                                wndheight, 0, g_depth, InputOutput, g_visual,                                wndheight, 0, g_depth, InputOutput, g_visual,
# Line 1357  ui_create_window(void) Line 1481  ui_create_window(void)
1481                                CWBorderPixel, &attribs);                                CWBorderPixel, &attribs);
1482    
1483          if (g_gc == NULL)          if (g_gc == NULL)
1484            {
1485                  g_gc = XCreateGC(g_display, g_wnd, 0, NULL);                  g_gc = XCreateGC(g_display, g_wnd, 0, NULL);
1486                    ui_reset_clip();
1487            }
1488    
1489          if (g_create_bitmap_gc == NULL)          if (g_create_bitmap_gc == NULL)
1490                  g_create_bitmap_gc = XCreateGC(g_display, g_wnd, 0, NULL);                  g_create_bitmap_gc = XCreateGC(g_display, g_wnd, 0, NULL);
# Line 1374  ui_create_window(void) Line 1501  ui_create_window(void)
1501          XStoreName(g_display, g_wnd, g_title);          XStoreName(g_display, g_wnd, g_title);
1502    
1503          if (g_hide_decorations)          if (g_hide_decorations)
1504                  mwm_hide_decorations();                  mwm_hide_decorations(g_wnd);
1505    
1506          classhints = XAllocClassHint();          classhints = XAllocClassHint();
1507          if (classhints != NULL)          if (classhints != NULL)
# Line 1401  ui_create_window(void) Line 1528  ui_create_window(void)
1528                  XReparentWindow(g_display, g_wnd, (Window) g_embed_wnd, 0, 0);                  XReparentWindow(g_display, g_wnd, (Window) g_embed_wnd, 0, 0);
1529          }          }
1530    
1531          input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |          get_input_mask(&input_mask);
                 VisibilityChangeMask | FocusChangeMask | StructureNotifyMask;  
   
         if (g_sendmotion)  
                 input_mask |= PointerMotionMask;  
         if (g_ownbackstore)  
                 input_mask |= ExposureMask;  
         if (g_fullscreen || g_grab_keyboard)  
                 input_mask |= EnterWindowMask;  
         if (g_grab_keyboard)  
                 input_mask |= LeaveWindowMask;  
1532    
1533          if (g_IM != NULL)          if (g_IM != NULL)
1534          {          {
# Line 1424  ui_create_window(void) Line 1541  ui_create_window(void)
1541          }          }
1542    
1543          XSelectInput(g_display, g_wnd, input_mask);          XSelectInput(g_display, g_wnd, input_mask);
1544          XMapWindow(g_display, g_wnd);          if (!g_seamless_rdp)
   
         /* wait for VisibilityNotify */  
         do  
1545          {          {
1546                  XMaskEvent(g_display, VisibilityChangeMask, &xevent);                  XMapWindow(g_display, g_wnd);
1547                    /* wait for VisibilityNotify */
1548                    do
1549                    {
1550                            XMaskEvent(g_display, VisibilityChangeMask, &xevent);
1551                    }
1552                    while (xevent.type != VisibilityNotify);
1553                    g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;
1554          }          }
         while (xevent.type != VisibilityNotify);  
         g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;  
1555    
1556          g_focused = False;          g_focused = False;
1557          g_mouse_in_wnd = False;          g_mouse_in_wnd = False;
# Line 1496  xwin_toggle_fullscreen(void) Line 1615  xwin_toggle_fullscreen(void)
1615  {  {
1616          Pixmap contents = 0;          Pixmap contents = 0;
1617    
1618            if (g_seamless_rdp)
1619                    /* Turn off SeamlessRDP mode */
1620                    ui_seamless_toggle();
1621    
1622          if (!g_ownbackstore)          if (!g_ownbackstore)
1623          {          {
1624                  /* need to save contents of window */                  /* need to save contents of window */
# Line 1584  handle_button_event(XEvent xevent, BOOL Line 1707  handle_button_event(XEvent xevent, BOOL
1707                  }                  }
1708          }          }
1709    
1710          rdp_send_input(time(NULL), RDP_INPUT_MOUSE,          if (xevent.xmotion.window == g_wnd)
1711                         flags | button, xevent.xbutton.x, xevent.xbutton.y);          {
1712                    rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
1713                                   flags | button, xevent.xbutton.x, xevent.xbutton.y);
1714            }
1715            else
1716            {
1717                    /* SeamlessRDP */
1718                    rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
1719                                   flags | button, xevent.xbutton.x_root, xevent.xbutton.y_root);
1720            }
1721  }  }
1722    
1723  /* Process events in Xlib queue  /* Process events in Xlib queue
# Line 1599  xwin_process_events(void) Line 1731  xwin_process_events(void)
1731          char str[256];          char str[256];
1732          Status status;          Status status;
1733          int events = 0;          int events = 0;
1734            seamless_window *sw;
1735    
1736          while ((XPending(g_display) > 0) && events++ < 20)          while ((XPending(g_display) > 0) && events++ < 20)
1737          {          {
# Line 1613  xwin_process_events(void) Line 1746  xwin_process_events(void)
1746                  switch (xevent.type)                  switch (xevent.type)
1747                  {                  {
1748                          case VisibilityNotify:                          case VisibilityNotify:
1749                                  g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;                                  if (xevent.xvisibility.window == g_wnd)
1750                                            g_Unobscured =
1751                                                    xevent.xvisibility.state == VisibilityUnobscured;
1752    
1753                                  break;                                  break;
1754                          case ClientMessage:                          case ClientMessage:
1755                                  /* the window manager told us to quit */                                  /* the window manager told us to quit */
# Line 1693  xwin_process_events(void) Line 1829  xwin_process_events(void)
1829                                  if (g_fullscreen && !g_focused)                                  if (g_fullscreen && !g_focused)
1830                                          XSetInputFocus(g_display, g_wnd, RevertToPointerRoot,                                          XSetInputFocus(g_display, g_wnd, RevertToPointerRoot,
1831                                                         CurrentTime);                                                         CurrentTime);
1832                                  rdp_send_input(time(NULL), RDP_INPUT_MOUSE,  
1833                                                 MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);                                  if (xevent.xmotion.window == g_wnd)
1834                                    {
1835                                            rdp_send_input(time(NULL), RDP_INPUT_MOUSE, MOUSE_FLAG_MOVE,
1836                                                           xevent.xmotion.x, xevent.xmotion.y);
1837                                    }
1838                                    else
1839                                    {
1840                                            /* SeamlessRDP */
1841                                            rdp_send_input(time(NULL), RDP_INPUT_MOUSE, MOUSE_FLAG_MOVE,
1842                                                           xevent.xmotion.x_root,
1843                                                           xevent.xmotion.y_root);
1844                                    }
1845                                  break;                                  break;
1846    
1847                          case FocusIn:                          case FocusIn:
# Line 1737  xwin_process_events(void) Line 1884  xwin_process_events(void)
1884                                  break;                                  break;
1885    
1886                          case Expose:                          case Expose:
1887                                  XCopyArea(g_display, g_backstore, g_wnd, g_gc,                                  if (xevent.xexpose.window == g_wnd)
1888                                            xevent.xexpose.x, xevent.xexpose.y,                                  {
1889                                            xevent.xexpose.width,                                          XCopyArea(g_display, g_backstore, xevent.xexpose.window,
1890                                            xevent.xexpose.height,                                                    g_gc,
1891                                            xevent.xexpose.x, xevent.xexpose.y);                                                    xevent.xexpose.x, xevent.xexpose.y,
1892                                                      xevent.xexpose.width, xevent.xexpose.height,
1893                                                      xevent.xexpose.x, xevent.xexpose.y);
1894                                    }
1895                                    else
1896                                    {
1897                                            sw = seamless_get_window_by_wnd(xevent.xexpose.window);
1898                                            if (sw)
1899                                                    XCopyArea(g_display, g_backstore,
1900                                                              xevent.xexpose.window, g_gc,
1901                                                              xevent.xexpose.x + sw->xoffset,
1902                                                              xevent.xexpose.y + sw->yoffset,
1903                                                              xevent.xexpose.width,
1904                                                              xevent.xexpose.height, xevent.xexpose.x,
1905                                                              xevent.xexpose.y);
1906                                    }
1907    
1908                                  break;                                  break;
1909    
1910                          case MappingNotify:                          case MappingNotify:
# Line 1772  xwin_process_events(void) Line 1935  xwin_process_events(void)
1935                                  xclip_handle_PropertyNotify(&xevent.xproperty);                                  xclip_handle_PropertyNotify(&xevent.xproperty);
1936                                  break;                                  break;
1937                          case MapNotify:                          case MapNotify:
1938                                  rdp_send_client_window_status(1);                                  if (!g_seamless_rdp)
1939                                            rdp_send_client_window_status(1);
1940                                  break;                                  break;
1941                          case UnmapNotify:                          case UnmapNotify:
1942                                  rdp_send_client_window_status(0);                                  if (!g_seamless_rdp)
1943                                            rdp_send_client_window_status(0);
1944                                  break;                                  break;
1945                  }                  }
1946          }          }
# Line 1912  ui_paint_bitmap(int x, int y, int cx, in Line 2077  ui_paint_bitmap(int x, int y, int cx, in
2077          {          {
2078                  XPutImage(g_display, g_backstore, g_gc, image, 0, 0, x, y, cx, cy);                  XPutImage(g_display, g_backstore, g_gc, image, 0, 0, x, y, cx, cy);
2079                  XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);                  XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);
2080                    ON_ALL_SEAMLESS_WINDOWS(XCopyArea,
2081                                            (g_display, g_backstore, sw->wnd, g_gc, x, y, cx, cy,
2082                                             x - sw->xoffset, y - sw->yoffset));
2083          }          }
2084          else          else
2085          {          {
2086                  XPutImage(g_display, g_wnd, g_gc, image, 0, 0, x, y, cx, cy);                  XPutImage(g_display, g_wnd, g_gc, image, 0, 0, x, y, cx, cy);
2087                    ON_ALL_SEAMLESS_WINDOWS(XCopyArea,
2088                                            (g_display, g_wnd, sw->wnd, g_gc, x, y, cx, cy,
2089                                             x - sw->xoffset, y - sw->yoffset));
2090          }          }
2091    
2092          XFree(image);          XFree(image);
# Line 2036  ui_set_cursor(HCURSOR cursor) Line 2207  ui_set_cursor(HCURSOR cursor)
2207  {  {
2208          g_current_cursor = (Cursor) cursor;          g_current_cursor = (Cursor) cursor;
2209          XDefineCursor(g_display, g_wnd, g_current_cursor);          XDefineCursor(g_display, g_wnd, g_current_cursor);
2210            ON_ALL_SEAMLESS_WINDOWS(XDefineCursor, (g_display, sw->wnd, g_current_cursor));
2211  }  }
2212    
2213  void  void
# Line 2177  ui_set_colourmap(HCOLOURMAP map) Line 2349  ui_set_colourmap(HCOLOURMAP map)
2349                  g_colmap = (uint32 *) map;                  g_colmap = (uint32 *) map;
2350          }          }
2351          else          else
2352            {
2353                  XSetWindowColormap(g_display, g_wnd, (Colormap) map);                  XSetWindowColormap(g_display, g_wnd, (Colormap) map);
2354                    ON_ALL_SEAMLESS_WINDOWS(XSetWindowColormap, (g_display, sw->wnd, (Colormap) map));
2355            }
2356  }  }
2357    
2358  void  void
2359  ui_set_clip(int x, int y, int cx, int cy)  ui_set_clip(int x, int y, int cx, int cy)
2360  {  {
2361          XRectangle rect;          g_clip_rectangle.x = x;
2362            g_clip_rectangle.y = y;
2363          rect.x = x;          g_clip_rectangle.width = cx;
2364          rect.y = y;          g_clip_rectangle.height = cy;
2365          rect.width = cx;          XSetClipRectangles(g_display, g_gc, 0, 0, &g_clip_rectangle, 1, YXBanded);
         rect.height = cy;  
         XSetClipRectangles(g_display, g_gc, 0, 0, &rect, 1, YXBanded);  
2366  }  }
2367    
2368  void  void
2369  ui_reset_clip(void)  ui_reset_clip(void)
2370  {  {
2371          XRectangle rect;          g_clip_rectangle.x = 0;
2372            g_clip_rectangle.y = 0;
2373          rect.x = 0;          g_clip_rectangle.width = g_width;
2374          rect.y = 0;          g_clip_rectangle.height = g_height;
2375          rect.width = g_width;          XSetClipRectangles(g_display, g_gc, 0, 0, &g_clip_rectangle, 1, YXBanded);
         rect.height = g_height;  
         XSetClipRectangles(g_display, g_gc, 0, 0, &rect, 1, YXBanded);  
2376  }  }
2377    
2378  void  void
# Line 2282  ui_patblt(uint8 opcode, Line 2453  ui_patblt(uint8 opcode,
2453    
2454          if (g_ownbackstore)          if (g_ownbackstore)
2455                  XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);                  XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);
2456            ON_ALL_SEAMLESS_WINDOWS(XCopyArea,
2457                                    (g_display, g_ownbackstore ? g_backstore : g_wnd, sw->wnd, g_gc,
2458                                     x, y, cx, cy, x - sw->xoffset, y - sw->yoffset));
2459  }  }
2460    
2461  void  void
# Line 2292  ui_screenblt(uint8 opcode, Line 2466  ui_screenblt(uint8 opcode,
2466          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
2467          if (g_ownbackstore)          if (g_ownbackstore)
2468          {          {
2469                  if (g_Unobscured)                  XCopyArea(g_display, g_Unobscured ? g_wnd : g_backstore,
2470                  {                            g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
2471                          XCopyArea(g_display, g_wnd, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);                  XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x, y);
                         XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x,  
                                   y);  
                 }  
                 else  
                 {  
                         XCopyArea(g_display, g_backstore, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);  
                         XCopyArea(g_display, g_backstore, g_backstore, g_gc, srcx, srcy, cx, cy, x,  
                                   y);  
                 }  
2472          }          }
2473          else          else
2474          {          {
2475                  XCopyArea(g_display, g_wnd, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);                  XCopyArea(g_display, g_wnd, g_wnd, g_gc, srcx, srcy, cx, cy, x, y);
2476          }          }
2477    
2478            ON_ALL_SEAMLESS_WINDOWS(XCopyArea,
2479                                    (g_display, g_ownbackstore ? g_backstore : g_wnd,
2480                                     sw->wnd, g_gc, x, y, cx, cy, x - sw->xoffset, y - sw->yoffset));
2481    
2482          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
2483  }  }
2484    
# Line 2319  ui_memblt(uint8 opcode, Line 2489  ui_memblt(uint8 opcode,
2489  {  {
2490          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
2491          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);
2492            ON_ALL_SEAMLESS_WINDOWS(XCopyArea,
2493                                    (g_display, (Pixmap) src, sw->wnd, g_gc,
2494                                     srcx, srcy, cx, cy, x - sw->xoffset, y - sw->yoffset));
2495          if (g_ownbackstore)          if (g_ownbackstore)
2496                  XCopyArea(g_display, (Pixmap) src, g_backstore, g_gc, srcx, srcy, cx, cy, x, y);                  XCopyArea(g_display, (Pixmap) src, g_backstore, g_gc, srcx, srcy, cx, cy, x, y);
2497          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
# Line 2365  ui_line(uint8 opcode, Line 2538  ui_line(uint8 opcode,
2538          SET_FUNCTION(opcode);          SET_FUNCTION(opcode);
2539          SET_FOREGROUND(pen->colour);          SET_FOREGROUND(pen->colour);
2540          XDrawLine(g_display, g_wnd, g_gc, startx, starty, endx, endy);          XDrawLine(g_display, g_wnd, g_gc, startx, starty, endx, endy);
2541            ON_ALL_SEAMLESS_WINDOWS(XDrawLine, (g_display, sw->wnd, g_gc,
2542                                                startx - sw->xoffset, starty - sw->yoffset,
2543                                                endx - sw->xoffset, endy - sw->yoffset));
2544          if (g_ownbackstore)          if (g_ownbackstore)
2545                  XDrawLine(g_display, g_backstore, g_gc, startx, starty, endx, endy);                  XDrawLine(g_display, g_backstore, g_gc, startx, starty, endx, endy);
2546          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
# Line 2462  ui_polyline(uint8 opcode, Line 2638  ui_polyline(uint8 opcode,
2638          if (g_ownbackstore)          if (g_ownbackstore)
2639                  XDrawLines(g_display, g_backstore, g_gc, (XPoint *) points, npoints,                  XDrawLines(g_display, g_backstore, g_gc, (XPoint *) points, npoints,
2640                             CoordModePrevious);                             CoordModePrevious);
2641    
2642            ON_ALL_SEAMLESS_WINDOWS(seamless_XDrawLines,
2643                                    (sw->wnd, (XPoint *) points, npoints, sw->xoffset, sw->yoffset));
2644    
2645          RESET_FUNCTION(opcode);          RESET_FUNCTION(opcode);
2646  }  }
2647    
# Line 2682  ui_draw_text(uint8 font, uint8 flags, ui Line 2862  ui_draw_text(uint8 font, uint8 flags, ui
2862          if (g_ownbackstore)          if (g_ownbackstore)
2863          {          {
2864                  if (boxcx > 1)                  if (boxcx > 1)
2865                    {
2866                          XCopyArea(g_display, g_backstore, g_wnd, g_gc, boxx,                          XCopyArea(g_display, g_backstore, g_wnd, g_gc, boxx,
2867                                    boxy, boxcx, boxcy, boxx, boxy);                                    boxy, boxcx, boxcy, boxx, boxy);
2868                            ON_ALL_SEAMLESS_WINDOWS(XCopyArea,
2869                                                    (g_display, g_backstore, sw->wnd, g_gc,
2870                                                     boxx, boxy,
2871                                                     boxcx, boxcy,
2872                                                     boxx - sw->xoffset, boxy - sw->yoffset));
2873                    }
2874                  else                  else
2875                    {
2876                          XCopyArea(g_display, g_backstore, g_wnd, g_gc, clipx,                          XCopyArea(g_display, g_backstore, g_wnd, g_gc, clipx,
2877                                    clipy, clipcx, clipcy, clipx, clipy);                                    clipy, clipcx, clipcy, clipx, clipy);
2878                            ON_ALL_SEAMLESS_WINDOWS(XCopyArea,
2879                                                    (g_display, g_backstore, sw->wnd, g_gc,
2880                                                     clipx, clipy,
2881                                                     clipcx, clipcy, clipx - sw->xoffset,
2882                                                     clipy - sw->yoffset));
2883                    }
2884          }          }
2885  }  }
2886    
# Line 2732  ui_desktop_restore(uint32 offset, int x, Line 2926  ui_desktop_restore(uint32 offset, int x,
2926          {          {
2927                  XPutImage(g_display, g_backstore, g_gc, image, 0, 0, x, y, cx, cy);                  XPutImage(g_display, g_backstore, g_gc, image, 0, 0, x, y, cx, cy);
2928                  XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);                  XCopyArea(g_display, g_backstore, g_wnd, g_gc, x, y, cx, cy, x, y);
2929                    ON_ALL_SEAMLESS_WINDOWS(XCopyArea,
2930                                            (g_display, g_backstore, sw->wnd, g_gc,
2931                                             x, y, cx, cy, x - sw->xoffset, y - sw->yoffset));
2932          }          }
2933          else          else
2934          {          {
2935                  XPutImage(g_display, g_wnd, g_gc, image, 0, 0, x, y, cx, cy);                  XPutImage(g_display, g_wnd, g_gc, image, 0, 0, x, y, cx, cy);
2936                    ON_ALL_SEAMLESS_WINDOWS(XCopyArea,
2937                                            (g_display, g_wnd, sw->wnd, g_gc, x, y, cx, cy,
2938                                             x - sw->xoffset, y - sw->yoffset));
2939          }          }
2940    
2941          XFree(image);          XFree(image);
# Line 2751  void Line 2951  void
2951  ui_end_update(void)  ui_end_update(void)
2952  {  {
2953  }  }
2954    
2955    void
2956    ui_seamless_toggle()
2957    {
2958            if (g_seamless_rdp)
2959            {
2960                    /* Deactivate */
2961                    while (g_seamless_windows)
2962                    {
2963                            XDestroyWindow(g_display, g_seamless_windows->wnd);
2964                            seamless_remove_window(g_seamless_windows);
2965                    }
2966                    XMapWindow(g_display, g_wnd);
2967            }
2968            else
2969            {
2970                    /* Activate */
2971                    if (g_win_button_size)
2972                    {
2973                            error("SeamlessRDP mode cannot be activated when using single application mode\n");
2974                            return;
2975                    }
2976                    if (!g_using_full_workarea)
2977                    {
2978                            error("SeamlessRDP mode requires a session that covers the whole screen");
2979                            return;
2980                    }
2981    
2982                    XUnmapWindow(g_display, g_wnd);
2983                    seamless_send_sync();
2984            }
2985    
2986            g_seamless_rdp = !g_seamless_rdp;
2987    }
2988    
2989    void
2990    ui_seamless_create_window(unsigned long id, unsigned long parent, unsigned long flags)
2991    {
2992            Window wnd;
2993            XSetWindowAttributes attribs;
2994            XClassHint *classhints;
2995            long input_mask;
2996            seamless_window *sw, *sw_parent;
2997    
2998            get_window_attribs(&attribs);
2999    
3000            attribs.override_redirect = False;
3001    
3002            /* FIXME: Do not assume that -1, -1 is outside screen Consider
3003               wait with showing the window until STATE and others have
3004               been recieved. */
3005            wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), -1, -1, 1, 1, 0, 0,
3006                                InputOutput, g_visual,
3007                                CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
3008                                CWBorderPixel, &attribs);
3009    
3010            XStoreName(g_display, wnd, "rdesktop-seamless");
3011    
3012            mwm_hide_decorations(wnd);
3013    
3014            classhints = XAllocClassHint();
3015            if (classhints != NULL)
3016            {
3017                    classhints->res_name = classhints->res_class = "rdesktop";
3018                    XSetClassHint(g_display, wnd, classhints);
3019                    XFree(classhints);
3020            }
3021    
3022            /* Set WM_TRANSIENT_FOR, if necessary */
3023            if (parent)
3024            {
3025                    sw_parent = seamless_get_window_by_id(parent);
3026                    if (sw_parent)
3027                            XSetTransientForHint(g_display, wnd, sw_parent->wnd);
3028                    else
3029                            warning("ui_seamless_create_window: No parent window 0x%lx\n", parent);
3030            }
3031    
3032            /* FIXME: Support for Input Context:s */
3033    
3034            get_input_mask(&input_mask);
3035    
3036            XSelectInput(g_display, wnd, input_mask);
3037    
3038            XMapWindow(g_display, wnd);
3039    
3040            /* handle the WM_DELETE_WINDOW protocol. FIXME: When killing a
3041               seamless window, we could try to close the window on the
3042               serverside, instead of terminating rdesktop */
3043            XSetWMProtocols(g_display, wnd, &g_kill_atom, 1);
3044    
3045            sw = malloc(sizeof(seamless_window));
3046            sw->wnd = wnd;
3047            sw->id = id;
3048            sw->xoffset = 0;
3049            sw->yoffset = 0;
3050            sw->width = 0;
3051            sw->height = 0;
3052            sw->next = g_seamless_windows;
3053            g_seamless_windows = sw;
3054    }
3055    
3056    
3057    void
3058    ui_seamless_destroy_window(unsigned long id, unsigned long flags)
3059    {
3060            seamless_window *sw;
3061            sw = seamless_get_window_by_id(id);
3062    
3063            if (!sw)
3064            {
3065                    warning("ui_seamless_destroy_window: No information for window 0x%lx\n", id);
3066                    return;
3067            }
3068    
3069            XDestroyWindow(g_display, sw->wnd);
3070            seamless_remove_window(sw);
3071    }
3072    
3073    
3074    void
3075    ui_seamless_move_window(unsigned long id, int x, int y, int width, int height, unsigned long flags)
3076    {
3077            seamless_window *sw;
3078    
3079            sw = seamless_get_window_by_id(id);
3080    
3081            if (!sw)
3082            {
3083                    warning("ui_seamless_move_window: No information for window 0x%lx\n", id);
3084                    return;
3085            }
3086    
3087            if (!width || !height)
3088                    /* X11 windows must be at least 1x1 */
3089                    return;
3090    
3091            /* About MAX and MIN: Windows allows moving a window outside
3092               the desktop. This happens, for example, when maximizing an
3093               application. In this case, the position is set to something
3094               like -4,-4,1288,1032. Many WMs does not allow windows
3095               outside the desktop, however. Therefore, clip the window
3096               ourselves. */
3097            sw->xoffset = MAX(0, x);
3098            sw->yoffset = MAX(0, y);
3099            sw->width = MIN(MIN(width, width + x), g_width - sw->xoffset);
3100            sw->height = MIN(MIN(height, height + y), g_height - sw->yoffset);
3101    
3102            /* FIXME: Perhaps use ewmh_net_moveresize_window instead */
3103            XMoveResizeWindow(g_display, sw->wnd, sw->xoffset, sw->yoffset, sw->width, sw->height);
3104    }
3105    
3106    
3107    void
3108    ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags)
3109    {
3110            seamless_window *sw;
3111    
3112            sw = seamless_get_window_by_id(id);
3113    
3114            XStoreName(g_display, sw->wnd, title);
3115    }
3116    
3117    
3118    void
3119    ui_seamless_setstate(unsigned long id, unsigned int state, unsigned long flags)
3120    {
3121            seamless_window *sw;
3122    
3123            sw = seamless_get_window_by_id(id);
3124    
3125            switch (state)
3126            {
3127                    case SEAMLESSRDP_NORMAL:
3128                    case SEAMLESSRDP_MAXIMIZED:
3129                            /* FIXME */
3130                            break;
3131                    case SEAMLESSRDP_MINIMIZED:
3132                            XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));
3133                            break;
3134                    default:
3135                            warning("SeamlessRDP: Invalid state %d\n", state);
3136                            break;
3137            }
3138    }

Legend:
Removed from v.1049  
changed lines
  Added in v.1103

  ViewVC Help
Powered by ViewVC 1.1.26