/[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

revision 1098 by astrand, Fri Mar 10 12:44:32 2006 UTC revision 1168 by ossman_, Mon Mar 20 14:39:00 2006 UTC
# Line 54  typedef struct _seamless_window Line 54  typedef struct _seamless_window
54  {  {
55          Window wnd;          Window wnd;
56          unsigned long id;          unsigned long id;
57            unsigned long behind;
58          int xoffset, yoffset;          int xoffset, yoffset;
59          int width, height;          int width, height;
60            int state;              /* normal/minimized/maximized. */
61            unsigned int desktop;
62            struct timeval *position_timer;
63    
64            BOOL outstanding_position;
65            unsigned int outpos_serial;
66            int outpos_xoffset, outpos_yoffset;
67            int outpos_width, outpos_height;
68    
69          struct _seamless_window *next;          struct _seamless_window *next;
70  } seamless_window;  } seamless_window;
71  static seamless_window *g_seamless_windows = NULL;  static seamless_window *g_seamless_windows = NULL;
72    static unsigned long g_seamless_focused = 0;
73    static BOOL g_seamless_started = False; /* Server end is up and running */
74    static BOOL g_seamless_active = False;  /* We are currently in seamless mode */
75  extern BOOL g_seamless_rdp;  extern BOOL g_seamless_rdp;
76    
77  extern uint32 g_embed_wnd;  extern uint32 g_embed_wnd;
# Line 83  static XModifierKeymap *g_mod_map; Line 96  static XModifierKeymap *g_mod_map;
96  static Cursor g_current_cursor;  static Cursor g_current_cursor;
97  static HCURSOR g_null_cursor = NULL;  static HCURSOR g_null_cursor = NULL;
98  static Atom g_protocol_atom, g_kill_atom;  static Atom g_protocol_atom, g_kill_atom;
99    extern Atom g_net_wm_state_atom;
100    extern Atom g_net_wm_desktop_atom;
101  static BOOL g_focused;  static BOOL g_focused;
102  static BOOL g_mouse_in_wnd;  static BOOL g_mouse_in_wnd;
103  /* Indicates that:  /* Indicates that:
# Line 298  seamless_remove_window(seamless_window * Line 313  seamless_remove_window(seamless_window *
313  }  }
314    
315    
316    /* Move all windows except wnd to new desktop */
317    static void
318    seamless_all_to_desktop(Window wnd, unsigned int desktop)
319    {
320            seamless_window *sw;
321            for (sw = g_seamless_windows; sw; sw = sw->next)
322            {
323                    if (sw->wnd == wnd)
324                            continue;
325                    if (sw->desktop != desktop)
326                    {
327                            ewmh_move_to_desktop(sw->wnd, desktop);
328                            sw->desktop = desktop;
329                    }
330            }
331    }
332    
333    
334    /* Send our position */
335    static void
336    seamless_update_position(seamless_window * sw)
337    {
338            XWindowAttributes wa;
339            int x, y;
340            Window child_return;
341            unsigned int serial;
342    
343            XGetWindowAttributes(g_display, sw->wnd, &wa);
344            XTranslateCoordinates(g_display, sw->wnd, wa.root,
345                                  -wa.border_width, -wa.border_width, &x, &y, &child_return);
346    
347            serial = seamless_send_position(sw->id, x, y, wa.width, wa.height, 0);
348    
349            sw->outstanding_position = True;
350            sw->outpos_serial = serial;
351    
352            sw->outpos_xoffset = x;
353            sw->outpos_yoffset = y;
354            sw->outpos_width = wa.width;
355            sw->outpos_height = wa.height;
356    }
357    
358    
359    /* Check if it's time to send our position */
360    static void
361    seamless_check_timers()
362    {
363            seamless_window *sw;
364            struct timeval now;
365    
366            gettimeofday(&now, NULL);
367            for (sw = g_seamless_windows; sw; sw = sw->next)
368            {
369                    if (timerisset(sw->position_timer) && timercmp(sw->position_timer, &now, <))
370                    {
371                            timerclear(sw->position_timer);
372                            seamless_update_position(sw);
373                    }
374            }
375    }
376    
377    
378    static void
379    seamless_restack_window(seamless_window * sw, unsigned long behind)
380    {
381            seamless_window *sw_above;
382    
383            /* Remove window from stack */
384            for (sw_above = g_seamless_windows; sw_above; sw_above = sw_above->next)
385            {
386                    if (sw_above->behind == sw->id)
387                            break;
388            }
389    
390            if (sw_above)
391                    sw_above->behind = sw->behind;
392    
393            /* And then add it at the new position */
394    
395            for (sw_above = g_seamless_windows; sw_above; sw_above = sw_above->next)
396            {
397                    if (sw_above->behind == behind)
398                            break;
399            }
400    
401            if (sw_above)
402                    sw_above->behind = sw->id;
403    
404            sw->behind = behind;
405    }
406    
407    
408  static void  static void
409  mwm_hide_decorations(Window wnd)  mwm_hide_decorations(Window wnd)
410  {  {
# Line 1396  ui_init(void) Line 1503  ui_init(void)
1503                  g_IM = XOpenIM(g_display, NULL, NULL, NULL);                  g_IM = XOpenIM(g_display, NULL, NULL, NULL);
1504    
1505          xclip_init();          xclip_init();
1506            ewmh_init();
1507          if (g_seamless_rdp)          if (g_seamless_rdp)
1508                  seamless_init();                  seamless_init();
1509    
# Line 1541  ui_create_window(void) Line 1649  ui_create_window(void)
1649          }          }
1650    
1651          XSelectInput(g_display, g_wnd, input_mask);          XSelectInput(g_display, g_wnd, input_mask);
1652          if (!g_seamless_rdp)  
1653            XMapWindow(g_display, g_wnd);
1654            /* wait for VisibilityNotify */
1655            do
1656          {          {
1657                  XMapWindow(g_display, g_wnd);                  XMaskEvent(g_display, VisibilityChangeMask, &xevent);
                 /* wait for VisibilityNotify */  
                 do  
                 {  
                         XMaskEvent(g_display, VisibilityChangeMask, &xevent);  
                 }  
                 while (xevent.type != VisibilityNotify);  
                 g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;  
1658          }          }
1659            while (xevent.type != VisibilityNotify);
1660            g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;
1661    
1662          g_focused = False;          g_focused = False;
1663          g_mouse_in_wnd = False;          g_mouse_in_wnd = False;
# Line 1615  xwin_toggle_fullscreen(void) Line 1721  xwin_toggle_fullscreen(void)
1721  {  {
1722          Pixmap contents = 0;          Pixmap contents = 0;
1723    
1724          if (g_seamless_rdp)          if (g_seamless_active)
1725                  /* Turn off SeamlessRDP mode */                  /* Turn off SeamlessRDP mode */
1726                  ui_seamless_toggle();                  ui_seamless_toggle();
1727    
# Line 1720  handle_button_event(XEvent xevent, BOOL Line 1826  handle_button_event(XEvent xevent, BOOL
1826          }          }
1827  }  }
1828    
1829    static void
1830    ui_seamless_handle_restack(seamless_window * sw)
1831    {
1832            Status status;
1833            Window root, parent, *children;
1834            unsigned int nchildren, i;
1835            seamless_window *sw_below;
1836    
1837            status = XQueryTree(g_display, RootWindowOfScreen(g_screen),
1838                                &root, &parent, &children, &nchildren);
1839            if (!status || !nchildren)
1840                    return;
1841    
1842            sw_below = NULL;
1843    
1844            i = 0;
1845            while (children[i] != sw->wnd)
1846            {
1847                    i++;
1848                    if (i >= nchildren)
1849                            return;
1850            }
1851    
1852            for (i++; i < nchildren; i++)
1853            {
1854                    sw_below = seamless_get_window_by_wnd(children[i]);
1855                    if (sw_below)
1856                            break;
1857            }
1858    
1859            if (!sw_below && !sw->behind)
1860                    return;
1861            if (sw_below && (sw_below->id == sw->behind))
1862                    return;
1863    
1864            if (sw_below)
1865            {
1866                    seamless_send_zchange(sw->id, sw_below->id, 0);
1867                    seamless_restack_window(sw, sw_below->id);
1868            }
1869            else
1870            {
1871                    seamless_send_zchange(sw->id, 0, 0);
1872                    seamless_restack_window(sw, 0);
1873            }
1874    }
1875    
1876  /* Process events in Xlib queue  /* Process events in Xlib queue
1877     Returns 0 after user quit, 1 otherwise */     Returns 0 after user quit, 1 otherwise */
1878  static int  static int
# Line 1852  xwin_process_events(void) Line 2005  xwin_process_events(void)
2005                                  if (g_grab_keyboard && g_mouse_in_wnd)                                  if (g_grab_keyboard && g_mouse_in_wnd)
2006                                          XGrabKeyboard(g_display, g_wnd, True,                                          XGrabKeyboard(g_display, g_wnd, True,
2007                                                        GrabModeAsync, GrabModeAsync, CurrentTime);                                                        GrabModeAsync, GrabModeAsync, CurrentTime);
2008    
2009                                    sw = seamless_get_window_by_wnd(xevent.xfocus.window);
2010                                    if (!sw)
2011                                            break;
2012    
2013                                    if (sw->id != g_seamless_focused)
2014                                    {
2015                                            seamless_send_focus(sw->id, 0);
2016                                            g_seamless_focused = sw->id;
2017                                    }
2018                                  break;                                  break;
2019    
2020                          case FocusOut:                          case FocusOut:
# Line 1903  xwin_process_events(void) Line 2066  xwin_process_events(void)
2066                                                            xevent.xexpose.width,                                                            xevent.xexpose.width,
2067                                                            xevent.xexpose.height, xevent.xexpose.x,                                                            xevent.xexpose.height, xevent.xexpose.x,
2068                                                            xevent.xexpose.y);                                                            xevent.xexpose.y);
2069                                            else
2070                                            {
2071                                                    error("Expose for unknown window 0x%lx\n",
2072                                                          xevent.xexpose.window);
2073                                            }
2074                                  }                                  }
2075    
2076                                  break;                                  break;
# Line 1933  xwin_process_events(void) Line 2101  xwin_process_events(void)
2101                                  break;                                  break;
2102                          case PropertyNotify:                          case PropertyNotify:
2103                                  xclip_handle_PropertyNotify(&xevent.xproperty);                                  xclip_handle_PropertyNotify(&xevent.xproperty);
2104                                    if (xevent.xproperty.window == g_wnd)
2105                                            break;
2106                                    if (xevent.xproperty.window == DefaultRootWindow(g_display))
2107                                            break;
2108    
2109                                    /* seamless */
2110                                    sw = seamless_get_window_by_wnd(xevent.xproperty.window);
2111                                    if (!sw)
2112                                            break;
2113    
2114                                    if ((xevent.xproperty.atom == g_net_wm_state_atom)
2115                                        && (xevent.xproperty.state == PropertyNewValue))
2116                                    {
2117                                            sw->state = ewmh_get_window_state(sw->wnd);
2118                                            seamless_send_state(sw->id, sw->state, 0);
2119                                    }
2120    
2121                                    if ((xevent.xproperty.atom == g_net_wm_desktop_atom)
2122                                        && (xevent.xproperty.state == PropertyNewValue))
2123                                    {
2124                                            sw->desktop = ewmh_get_window_desktop(sw->wnd);
2125                                            seamless_all_to_desktop(sw->wnd, sw->desktop);
2126                                    }
2127    
2128                                  break;                                  break;
2129                          case MapNotify:                          case MapNotify:
2130                                  if (!g_seamless_rdp)                                  if (!g_seamless_active)
2131                                          rdp_send_client_window_status(1);                                          rdp_send_client_window_status(1);
2132                                  break;                                  break;
2133                          case UnmapNotify:                          case UnmapNotify:
2134                                  if (!g_seamless_rdp)                                  if (!g_seamless_active)
2135                                          rdp_send_client_window_status(0);                                          rdp_send_client_window_status(0);
2136                                  break;                                  break;
2137                            case ConfigureNotify:
2138                                    if (!g_seamless_active)
2139                                            break;
2140    
2141                                    sw = seamless_get_window_by_wnd(xevent.xconfigure.window);
2142                                    if (!sw)
2143                                    {
2144                                            error("ConfigureNotify for unknown window 0x%lx\n",
2145                                                  xevent.xconfigure.window);
2146                                    }
2147    
2148                                    gettimeofday(sw->position_timer, NULL);
2149                                    if (sw->position_timer->tv_usec + SEAMLESSRDP_POSITION_TIMER >=
2150                                        1000000)
2151                                    {
2152                                            sw->position_timer->tv_usec +=
2153                                                    SEAMLESSRDP_POSITION_TIMER - 1000000;
2154                                            sw->position_timer->tv_sec += 1;
2155                                    }
2156                                    else
2157                                    {
2158                                            sw->position_timer->tv_usec += SEAMLESSRDP_POSITION_TIMER;
2159                                    }
2160    
2161                                    ui_seamless_handle_restack(sw);
2162                                    break;
2163                  }                  }
2164          }          }
2165          /* Keep going */          /* Keep going */
# Line 1965  ui_select(int rdp_socket) Line 2183  ui_select(int rdp_socket)
2183                          /* User quit */                          /* User quit */
2184                          return 0;                          return 0;
2185    
2186                    if (g_seamless_active)
2187                            seamless_check_timers();
2188    
2189                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
2190                  FD_ZERO(&wfds);                  FD_ZERO(&wfds);
2191                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
# Line 1984  ui_select(int rdp_socket) Line 2205  ui_select(int rdp_socket)
2205    
2206                  /* add redirection handles */                  /* add redirection handles */
2207                  rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);                  rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);
2208                    seamless_select_timeout(&tv);
2209    
2210                  n++;                  n++;
2211    
# Line 2953  ui_end_update(void) Line 3175  ui_end_update(void)
3175  }  }
3176    
3177  void  void
3178    ui_seamless_begin()
3179    {
3180            if (!g_seamless_rdp)
3181                    return;
3182    
3183            if (g_seamless_started)
3184                    return;
3185    
3186            g_seamless_started = True;
3187    
3188            ui_seamless_toggle();
3189    }
3190    
3191    void
3192  ui_seamless_toggle()  ui_seamless_toggle()
3193  {  {
3194          if (g_seamless_rdp)          if (!g_seamless_rdp)
3195                    return;
3196    
3197            if (!g_seamless_started)
3198                    return;
3199    
3200            if (g_seamless_active)
3201          {          {
3202                  /* Deactivate */                  /* Deactivate */
3203                  while (g_seamless_windows)                  while (g_seamless_windows)
# Line 2968  ui_seamless_toggle() Line 3210  ui_seamless_toggle()
3210          else          else
3211          {          {
3212                  /* Activate */                  /* Activate */
                 if (g_win_button_size)  
                 {  
                         error("SeamlessRDP mode cannot be activated when using single application mode\n");  
                         return;  
                 }  
                 if (!g_using_full_workarea)  
                 {  
                         error("SeamlessRDP mode requires a session that covers the whole screen");  
                         return;  
                 }  
   
3213                  XUnmapWindow(g_display, g_wnd);                  XUnmapWindow(g_display, g_wnd);
3214                  seamless_send_sync();                  seamless_send_sync();
3215          }          }
3216    
3217          g_seamless_rdp = !g_seamless_rdp;          g_seamless_active = !g_seamless_active;
3218  }  }
3219    
3220  void  void
# Line 2992  ui_seamless_create_window(unsigned long Line 3223  ui_seamless_create_window(unsigned long
3223          Window wnd;          Window wnd;
3224          XSetWindowAttributes attribs;          XSetWindowAttributes attribs;
3225          XClassHint *classhints;          XClassHint *classhints;
3226            XSizeHints *sizehints;
3227          long input_mask;          long input_mask;
3228          seamless_window *sw;          seamless_window *sw, *sw_parent;
3229    
3230          get_window_attribs(&attribs);          if (!g_seamless_active)
3231                    return;
3232    
3233            /* Ignore CREATEs for existing windows */
3234            sw = seamless_get_window_by_id(id);
3235            if (sw)
3236                    return;
3237    
3238            get_window_attribs(&attribs);
3239          attribs.override_redirect = False;          attribs.override_redirect = False;
3240    
3241          /* FIXME: Do not assume that -1, -1 is outside screen Consider          wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), -1, -1, 1, 1, 0, g_depth,
            wait with showing the window until STATE and others have  
            been recieved. */  
         wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), -1, -1, 1, 1, 0, 0,  
3242                              InputOutput, g_visual,                              InputOutput, g_visual,
3243                              CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |                              CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
3244                              CWBorderPixel, &attribs);                              CWBorderPixel, &attribs);
3245    
3246          XStoreName(g_display, wnd, "rdesktop-seamless");          XStoreName(g_display, wnd, "SeamlessRDP");
3247            ewmh_set_wm_name(wnd, "SeamlessRDP");
3248    
3249          mwm_hide_decorations(wnd);          mwm_hide_decorations(wnd);
3250    
3251          classhints = XAllocClassHint();          classhints = XAllocClassHint();
3252          if (classhints != NULL)          if (classhints != NULL)
3253          {          {
3254                  classhints->res_name = classhints->res_class = "rdesktop";                  classhints->res_name = "rdesktop";
3255                    classhints->res_class = "SeamlessRDP";
3256                  XSetClassHint(g_display, wnd, classhints);                  XSetClassHint(g_display, wnd, classhints);
3257                  XFree(classhints);                  XFree(classhints);
3258          }          }
3259    
3260            /* WM_NORMAL_HINTS */
3261            sizehints = XAllocSizeHints();
3262            if (sizehints != NULL)
3263            {
3264                    sizehints->flags = USPosition;
3265                    XSetWMNormalHints(g_display, wnd, sizehints);
3266                    XFree(sizehints);
3267            }
3268    
3269            /* Handle popups without parents through some ewm hints */
3270            if (parent == 0xFFFFFFFF)
3271                    ewmh_set_window_popup(wnd);
3272            /* Set WM_TRANSIENT_FOR, if necessary */
3273            else if (parent != 0x00000000)
3274            {
3275                    sw_parent = seamless_get_window_by_id(parent);
3276                    if (sw_parent)
3277                            XSetTransientForHint(g_display, wnd, sw_parent->wnd);
3278                    else
3279                            warning("ui_seamless_create_window: No parent window 0x%lx\n", parent);
3280            }
3281    
3282    
3283          /* FIXME: Support for Input Context:s */          /* FIXME: Support for Input Context:s */
3284    
3285          get_input_mask(&input_mask);          get_input_mask(&input_mask);
3286            input_mask |= PropertyChangeMask;
3287    
3288          XSelectInput(g_display, wnd, input_mask);          XSelectInput(g_display, wnd, input_mask);
3289    
         XMapWindow(g_display, wnd);  
   
3290          /* handle the WM_DELETE_WINDOW protocol. FIXME: When killing a          /* handle the WM_DELETE_WINDOW protocol. FIXME: When killing a
3291             seamless window, we could try to close the window on the             seamless window, we could try to close the window on the
3292             serverside, instead of terminating rdesktop */             serverside, instead of terminating rdesktop */
3293          XSetWMProtocols(g_display, wnd, &g_kill_atom, 1);          XSetWMProtocols(g_display, wnd, &g_kill_atom, 1);
3294    
3295          sw = malloc(sizeof(seamless_window));          sw = xmalloc(sizeof(seamless_window));
3296          sw->wnd = wnd;          sw->wnd = wnd;
3297          sw->id = id;          sw->id = id;
3298            sw->behind = 0;
3299          sw->xoffset = 0;          sw->xoffset = 0;
3300          sw->yoffset = 0;          sw->yoffset = 0;
3301          sw->width = 0;          sw->width = 0;
3302          sw->height = 0;          sw->height = 0;
3303            sw->state = SEAMLESSRDP_NOTYETMAPPED;
3304            sw->desktop = 0;
3305            sw->position_timer = xmalloc(sizeof(struct timeval));
3306            timerclear(sw->position_timer);
3307            sw->outstanding_position = False;
3308          sw->next = g_seamless_windows;          sw->next = g_seamless_windows;
3309          g_seamless_windows = sw;          g_seamless_windows = sw;
3310  }  }
# Line 3048  void Line 3314  void
3314  ui_seamless_destroy_window(unsigned long id, unsigned long flags)  ui_seamless_destroy_window(unsigned long id, unsigned long flags)
3315  {  {
3316          seamless_window *sw;          seamless_window *sw;
         sw = seamless_get_window_by_id(id);  
3317    
3318            if (!g_seamless_active)
3319                    return;
3320    
3321            sw = seamless_get_window_by_id(id);
3322          if (!sw)          if (!sw)
3323          {          {
3324                  warning("ui_seamless_destroy_window: No information for window 0x%lx\n", id);                  warning("ui_seamless_destroy_window: No information for window 0x%lx\n", id);
# Line 3066  ui_seamless_move_window(unsigned long id Line 3335  ui_seamless_move_window(unsigned long id
3335  {  {
3336          seamless_window *sw;          seamless_window *sw;
3337    
3338          sw = seamless_get_window_by_id(id);          if (!g_seamless_active)
3339                    return;
3340    
3341            sw = seamless_get_window_by_id(id);
3342          if (!sw)          if (!sw)
3343          {          {
3344                  warning("ui_seamless_move_window: No information for window 0x%lx\n", id);                  warning("ui_seamless_move_window: No information for window 0x%lx\n", id);
3345                  return;                  return;
3346          }          }
3347    
3348            /* We ignore server updates until it has handled our request. */
3349            if (sw->outstanding_position)
3350                    return;
3351    
3352          if (!width || !height)          if (!width || !height)
3353                  /* X11 windows must be at least 1x1 */                  /* X11 windows must be at least 1x1 */
3354                  return;                  return;
3355    
3356          /* About MAX and MIN: Windows allows moving a window outside          sw->xoffset = x;
3357             the desktop. This happens, for example, when maximizing an          sw->yoffset = y;
3358             application. In this case, the position is set to something          sw->width = width;
3359             like -4,-4,1288,1032. Many WMs does not allow windows          sw->height = height;
3360             outside the desktop, however. Therefore, clip the window  
3361             ourselves. */          /* If we move the window in a maximized state, then KDE won't
3362          sw->xoffset = MAX(0, x);             accept restoration */
3363          sw->yoffset = MAX(0, y);          switch (sw->state)
3364          sw->width = MIN(MIN(width, width + x), g_width - sw->xoffset);          {
3365          sw->height = MIN(MIN(height, height + y), g_height - sw->yoffset);                  case SEAMLESSRDP_MINIMIZED:
3366                    case SEAMLESSRDP_MAXIMIZED:
3367                            return;
3368            }
3369    
3370          /* FIXME: Perhaps use ewmh_net_moveresize_window instead */          /* FIXME: Perhaps use ewmh_net_moveresize_window instead */
3371          XMoveResizeWindow(g_display, sw->wnd, sw->xoffset, sw->yoffset, sw->width, sw->height);          XMoveResizeWindow(g_display, sw->wnd, sw->xoffset, sw->yoffset, sw->width, sw->height);
3372  }  }
3373    
3374    void
3375    ui_seamless_restack_window(unsigned long id, unsigned long behind, unsigned long flags)
3376    {
3377            seamless_window *sw;
3378    
3379            if (!g_seamless_active)
3380                    return;
3381    
3382            sw = seamless_get_window_by_id(id);
3383            if (!sw)
3384            {
3385                    warning("ui_seamless_restack_window: No information for window 0x%lx\n", id);
3386                    return;
3387            }
3388    
3389            if (behind)
3390            {
3391                    seamless_window *sw_behind;
3392                    Window wnds[2];
3393    
3394                    sw_behind = seamless_get_window_by_id(behind);
3395                    if (!sw_behind)
3396                    {
3397                            warning("ui_seamless_restack_window: No information for window 0x%lx\n",
3398                                    behind);
3399                            return;
3400                    }
3401    
3402                    wnds[1] = sw_behind->wnd;
3403                    wnds[0] = sw->wnd;
3404    
3405                    XRestackWindows(g_display, wnds, 2);
3406            }
3407            else
3408            {
3409                    XRaiseWindow(g_display, sw->wnd);
3410            }
3411    
3412            seamless_restack_window(sw, behind);
3413    }
3414    
3415  void  void
3416  ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags)  ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags)
3417  {  {
3418          seamless_window *sw;          seamless_window *sw;
3419    
3420            if (!g_seamless_active)
3421                    return;
3422    
3423          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3424            if (!sw)
3425            {
3426                    warning("ui_seamless_settitle: No information for window 0x%lx\n", id);
3427                    return;
3428            }
3429    
3430            /* FIXME: Might want to convert the name for non-EWMH WMs */
3431          XStoreName(g_display, sw->wnd, title);          XStoreName(g_display, sw->wnd, title);
3432            ewmh_set_wm_name(sw->wnd, title);
3433  }  }
3434    
3435    
# Line 3110  ui_seamless_setstate(unsigned long id, u Line 3438  ui_seamless_setstate(unsigned long id, u
3438  {  {
3439          seamless_window *sw;          seamless_window *sw;
3440    
3441            if (!g_seamless_active)
3442                    return;
3443    
3444          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3445            if (!sw)
3446            {
3447                    warning("ui_seamless_setstate: No information for window 0x%lx\n", id);
3448                    return;
3449            }
3450    
3451          switch (state)          switch (state)
3452          {          {
3453                  case SEAMLESSRDP_NORMAL:                  case SEAMLESSRDP_NORMAL:
3454                  case SEAMLESSRDP_MAXIMIZED:                  case SEAMLESSRDP_MAXIMIZED:
3455                          /* FIXME */                          ewmh_change_state(sw->wnd, state);
3456                            XMapWindow(g_display, sw->wnd);
3457                          break;                          break;
3458                  case SEAMLESSRDP_MINIMIZED:                  case SEAMLESSRDP_MINIMIZED:
3459                          XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));                          /* EWMH says: "if an Application asks to toggle _NET_WM_STATE_HIDDEN
3460                               the Window Manager should probably just ignore the request, since
3461                               _NET_WM_STATE_HIDDEN is a function of some other aspect of the window
3462                               such as minimization, rather than an independent state." Besides,
3463                               XIconifyWindow is easier. */
3464                            if (sw->state == SEAMLESSRDP_NOTYETMAPPED)
3465                            {
3466                                    XWMHints *hints;
3467                                    hints = XAllocWMHints();
3468                                    hints->flags = StateHint;
3469                                    hints->initial_state = IconicState;
3470                                    XSetWMHints(g_display, sw->wnd, hints);
3471                                    XFree(hints);
3472                                    XMapWindow(g_display, sw->wnd);
3473                            }
3474                            else
3475                                    XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));
3476                          break;                          break;
3477                  default:                  default:
3478                          warning("SeamlessRDP: Invalid state %d\n", state);                          warning("SeamlessRDP: Invalid state %d\n", state);
3479                          break;                          break;
3480          }          }
3481    
3482            sw->state = state;
3483    }
3484    
3485    
3486    void
3487    ui_seamless_syncbegin(unsigned long flags)
3488    {
3489            if (!g_seamless_active)
3490                    return;
3491    
3492            /* Destroy all seamless windows */
3493            while (g_seamless_windows)
3494            {
3495                    XDestroyWindow(g_display, g_seamless_windows->wnd);
3496                    seamless_remove_window(g_seamless_windows);
3497            }
3498    }
3499    
3500    void
3501    ui_seamless_ack(unsigned int serial)
3502    {
3503            seamless_window *sw;
3504            for (sw = g_seamless_windows; sw; sw = sw->next)
3505            {
3506                    if (sw->outpos_serial == serial)
3507                    {
3508                            sw->xoffset = sw->outpos_xoffset;
3509                            sw->yoffset = sw->outpos_yoffset;
3510                            sw->width = sw->outpos_width;
3511                            sw->height = sw->outpos_height;
3512    
3513                            sw->outstanding_position = False;
3514    
3515                            break;
3516                    }
3517            }
3518    
3519            return;
3520  }  }

Legend:
Removed from v.1098  
changed lines
  Added in v.1168

  ViewVC Help
Powered by ViewVC 1.1.26