/[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 1157 by astrand, Fri Mar 17 12:39:09 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 parent;
58            unsigned long behind;
59          int xoffset, yoffset;          int xoffset, yoffset;
60          int width, height;          int width, height;
61            int state;              /* normal/minimized/maximized. */
62            unsigned int desktop;
63            struct timeval *position_timer;
64          struct _seamless_window *next;          struct _seamless_window *next;
65  } seamless_window;  } seamless_window;
66  static seamless_window *g_seamless_windows = NULL;  static seamless_window *g_seamless_windows = NULL;
67    static unsigned long g_seamless_focused = 0;
68    static BOOL g_seamless_started = False; /* Server end is up and running */
69    static BOOL g_seamless_active = False;  /* We are currently in seamless mode */
70  extern BOOL g_seamless_rdp;  extern BOOL g_seamless_rdp;
71    
72  extern uint32 g_embed_wnd;  extern uint32 g_embed_wnd;
# Line 83  static XModifierKeymap *g_mod_map; Line 91  static XModifierKeymap *g_mod_map;
91  static Cursor g_current_cursor;  static Cursor g_current_cursor;
92  static HCURSOR g_null_cursor = NULL;  static HCURSOR g_null_cursor = NULL;
93  static Atom g_protocol_atom, g_kill_atom;  static Atom g_protocol_atom, g_kill_atom;
94    extern Atom g_net_wm_state_atom;
95    extern Atom g_net_wm_desktop_atom;
96  static BOOL g_focused;  static BOOL g_focused;
97  static BOOL g_mouse_in_wnd;  static BOOL g_mouse_in_wnd;
98  /* Indicates that:  /* Indicates that:
# Line 298  seamless_remove_window(seamless_window * Line 308  seamless_remove_window(seamless_window *
308  }  }
309    
310    
311    /* Move all windows except wnd to new desktop */
312    static void
313    seamless_all_to_desktop(Window wnd, unsigned int desktop)
314    {
315            seamless_window *sw;
316            for (sw = g_seamless_windows; sw; sw = sw->next)
317            {
318                    if (sw->wnd == wnd)
319                            continue;
320                    if (sw->desktop != desktop)
321                    {
322                            ewmh_move_to_desktop(sw->wnd, desktop);
323                            sw->desktop = desktop;
324                    }
325            }
326    }
327    
328    
329    /* Send our position */
330    static void
331    seamless_update_position(seamless_window * sw)
332    {
333            XWindowAttributes wa;
334            int x, y;
335            Window child_return;
336    
337            XGetWindowAttributes(g_display, sw->wnd, &wa);
338            XTranslateCoordinates(g_display, sw->wnd, wa.root,
339                                  -wa.border_width, -wa.border_width, &x, &y, &child_return);
340    
341            seamless_send_position(sw->id, x, y, wa.width, wa.height, 0);
342            sw->xoffset = x;
343            sw->yoffset = y;
344            sw->width = wa.width;
345            sw->height = wa.height;
346    }
347    
348    
349    /* Check if it's time to send our position */
350    static void
351    seamless_check_timers()
352    {
353            seamless_window *sw;
354            struct timeval now;
355    
356            gettimeofday(&now, NULL);
357            for (sw = g_seamless_windows; sw; sw = sw->next)
358            {
359                    if (timerisset(sw->position_timer) && timercmp(sw->position_timer, &now, <))
360                    {
361                            timerclear(sw->position_timer);
362                            seamless_update_position(sw);
363                    }
364            }
365    }
366    
367    
368    static void
369    seamless_restack_window(seamless_window * sw, unsigned long behind)
370    {
371            seamless_window *sw_above;
372    
373            /* Remove window from stack */
374            for (sw_above = g_seamless_windows; sw_above; sw_above = sw_above->next)
375            {
376                    if (sw_above->behind == sw->id)
377                            break;
378            }
379    
380            if (sw_above)
381                    sw_above->behind = sw->behind;
382    
383            /* And then add it at the new position */
384    
385            for (sw_above = g_seamless_windows; sw_above; sw_above = sw_above->next)
386            {
387                    if (sw_above->behind == behind)
388                            break;
389            }
390    
391            if (sw_above)
392                    sw_above->behind = sw->id;
393    
394            sw->behind = behind;
395    }
396    
397    
398  static void  static void
399  mwm_hide_decorations(Window wnd)  mwm_hide_decorations(Window wnd)
400  {  {
# Line 1396  ui_init(void) Line 1493  ui_init(void)
1493                  g_IM = XOpenIM(g_display, NULL, NULL, NULL);                  g_IM = XOpenIM(g_display, NULL, NULL, NULL);
1494    
1495          xclip_init();          xclip_init();
1496            ewmh_init();
1497          if (g_seamless_rdp)          if (g_seamless_rdp)
1498                  seamless_init();                  seamless_init();
1499    
# Line 1541  ui_create_window(void) Line 1639  ui_create_window(void)
1639          }          }
1640    
1641          XSelectInput(g_display, g_wnd, input_mask);          XSelectInput(g_display, g_wnd, input_mask);
1642          if (!g_seamless_rdp)  
1643            XMapWindow(g_display, g_wnd);
1644            /* wait for VisibilityNotify */
1645            do
1646          {          {
1647                  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;  
1648          }          }
1649            while (xevent.type != VisibilityNotify);
1650            g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;
1651    
1652          g_focused = False;          g_focused = False;
1653          g_mouse_in_wnd = False;          g_mouse_in_wnd = False;
# Line 1615  xwin_toggle_fullscreen(void) Line 1711  xwin_toggle_fullscreen(void)
1711  {  {
1712          Pixmap contents = 0;          Pixmap contents = 0;
1713    
1714          if (g_seamless_rdp)          if (g_seamless_active)
1715                  /* Turn off SeamlessRDP mode */                  /* Turn off SeamlessRDP mode */
1716                  ui_seamless_toggle();                  ui_seamless_toggle();
1717    
# Line 1720  handle_button_event(XEvent xevent, BOOL Line 1816  handle_button_event(XEvent xevent, BOOL
1816          }          }
1817  }  }
1818    
1819    static void
1820    ui_seamless_handle_restack(seamless_window * sw)
1821    {
1822            Status status;
1823            Window root, parent, *children;
1824            unsigned int nchildren, i;
1825            seamless_window *sw_below;
1826    
1827            status = XQueryTree(g_display, RootWindowOfScreen(g_screen),
1828                                &root, &parent, &children, &nchildren);
1829            if (!status || !nchildren)
1830                    return;
1831    
1832            sw_below = NULL;
1833    
1834            i = 0;
1835            while (children[i] != sw->wnd)
1836            {
1837                    i++;
1838                    if (i >= nchildren)
1839                            return;
1840            }
1841    
1842            for (i++; i < nchildren; i++)
1843            {
1844                    sw_below = seamless_get_window_by_wnd(children[i]);
1845                    if (sw_below)
1846                            break;
1847            }
1848    
1849            if (!sw_below && !sw->behind)
1850                    return;
1851            if (sw_below && (sw_below->id == sw->behind))
1852                    return;
1853    
1854            if (sw_below)
1855            {
1856                    seamless_send_zchange(sw->id, sw_below->id, 0);
1857                    seamless_restack_window(sw, sw_below->id);
1858            }
1859            else
1860            {
1861                    seamless_send_zchange(sw->id, 0, 0);
1862                    seamless_restack_window(sw, 0);
1863            }
1864    }
1865    
1866  /* Process events in Xlib queue  /* Process events in Xlib queue
1867     Returns 0 after user quit, 1 otherwise */     Returns 0 after user quit, 1 otherwise */
1868  static int  static int
# Line 1852  xwin_process_events(void) Line 1995  xwin_process_events(void)
1995                                  if (g_grab_keyboard && g_mouse_in_wnd)                                  if (g_grab_keyboard && g_mouse_in_wnd)
1996                                          XGrabKeyboard(g_display, g_wnd, True,                                          XGrabKeyboard(g_display, g_wnd, True,
1997                                                        GrabModeAsync, GrabModeAsync, CurrentTime);                                                        GrabModeAsync, GrabModeAsync, CurrentTime);
1998    
1999                                    sw = seamless_get_window_by_wnd(xevent.xfocus.window);
2000                                    if (!sw)
2001                                            break;
2002    
2003                                    if (sw->id != g_seamless_focused)
2004                                    {
2005                                            seamless_send_focus(sw->id, 0);
2006                                            g_seamless_focused = sw->id;
2007                                    }
2008                                  break;                                  break;
2009    
2010                          case FocusOut:                          case FocusOut:
# Line 1903  xwin_process_events(void) Line 2056  xwin_process_events(void)
2056                                                            xevent.xexpose.width,                                                            xevent.xexpose.width,
2057                                                            xevent.xexpose.height, xevent.xexpose.x,                                                            xevent.xexpose.height, xevent.xexpose.x,
2058                                                            xevent.xexpose.y);                                                            xevent.xexpose.y);
2059                                            else
2060                                            {
2061                                                    error("Expose for unknown window 0x%lx\n",
2062                                                          xevent.xexpose.window);
2063                                            }
2064                                  }                                  }
2065    
2066                                  break;                                  break;
# Line 1933  xwin_process_events(void) Line 2091  xwin_process_events(void)
2091                                  break;                                  break;
2092                          case PropertyNotify:                          case PropertyNotify:
2093                                  xclip_handle_PropertyNotify(&xevent.xproperty);                                  xclip_handle_PropertyNotify(&xevent.xproperty);
2094                                    if (xevent.xproperty.window == g_wnd)
2095                                            break;
2096                                    if (xevent.xproperty.window == DefaultRootWindow(g_display))
2097                                            break;
2098    
2099                                    /* seamless */
2100                                    sw = seamless_get_window_by_wnd(xevent.xproperty.window);
2101                                    if (!sw)
2102                                            break;
2103    
2104                                    if ((xevent.xproperty.atom == g_net_wm_state_atom)
2105                                        && (xevent.xproperty.state == PropertyNewValue))
2106                                    {
2107                                            sw->state = ewmh_get_window_state(sw->wnd);
2108                                            seamless_send_state(sw->id, sw->state, 0);
2109                                    }
2110    
2111                                    if ((xevent.xproperty.atom == g_net_wm_desktop_atom)
2112                                        && (xevent.xproperty.state == PropertyNewValue))
2113                                    {
2114                                            sw->desktop = ewmh_get_window_desktop(sw->wnd);
2115                                            seamless_all_to_desktop(sw->wnd, sw->desktop);
2116                                    }
2117    
2118                                  break;                                  break;
2119                          case MapNotify:                          case MapNotify:
2120                                  if (!g_seamless_rdp)                                  if (!g_seamless_active)
2121                                          rdp_send_client_window_status(1);                                          rdp_send_client_window_status(1);
2122                                  break;                                  break;
2123                          case UnmapNotify:                          case UnmapNotify:
2124                                  if (!g_seamless_rdp)                                  if (!g_seamless_active)
2125                                          rdp_send_client_window_status(0);                                          rdp_send_client_window_status(0);
2126                                  break;                                  break;
2127                            case ConfigureNotify:
2128                                    if (!g_seamless_active)
2129                                            break;
2130    
2131                                    sw = seamless_get_window_by_wnd(xevent.xconfigure.window);
2132                                    if (!sw)
2133                                    {
2134                                            error("ConfigureNotify for unknown window 0x%lx\n",
2135                                                  xevent.xconfigure.window);
2136                                    }
2137    
2138                                    gettimeofday(sw->position_timer, NULL);
2139                                    if (sw->position_timer->tv_usec + SEAMLESSRDP_POSITION_TIMER >=
2140                                        1000000)
2141                                    {
2142                                            sw->position_timer->tv_usec +=
2143                                                    SEAMLESSRDP_POSITION_TIMER - 1000000;
2144                                            sw->position_timer->tv_sec += 1;
2145                                    }
2146                                    else
2147                                    {
2148                                            sw->position_timer->tv_usec += SEAMLESSRDP_POSITION_TIMER;
2149                                    }
2150    
2151                                    ui_seamless_handle_restack(sw);
2152                                    break;
2153                  }                  }
2154          }          }
2155          /* Keep going */          /* Keep going */
# Line 1965  ui_select(int rdp_socket) Line 2173  ui_select(int rdp_socket)
2173                          /* User quit */                          /* User quit */
2174                          return 0;                          return 0;
2175    
2176                    if (g_seamless_active)
2177                            seamless_check_timers();
2178    
2179                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
2180                  FD_ZERO(&wfds);                  FD_ZERO(&wfds);
2181                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
# Line 1984  ui_select(int rdp_socket) Line 2195  ui_select(int rdp_socket)
2195    
2196                  /* add redirection handles */                  /* add redirection handles */
2197                  rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);                  rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);
2198                    seamless_select_timeout(&tv);
2199    
2200                  n++;                  n++;
2201    
# Line 2953  ui_end_update(void) Line 3165  ui_end_update(void)
3165  }  }
3166    
3167  void  void
3168    ui_seamless_begin()
3169    {
3170            if (!g_seamless_rdp)
3171                    return;
3172    
3173            if (g_seamless_started)
3174                    return;
3175    
3176            g_seamless_started = True;
3177    
3178            ui_seamless_toggle();
3179    }
3180    
3181    void
3182  ui_seamless_toggle()  ui_seamless_toggle()
3183  {  {
3184          if (g_seamless_rdp)          if (!g_seamless_rdp)
3185                    return;
3186    
3187            if (!g_seamless_started)
3188                    return;
3189    
3190            if (g_seamless_active)
3191          {          {
3192                  /* Deactivate */                  /* Deactivate */
3193                  while (g_seamless_windows)                  while (g_seamless_windows)
# Line 2968  ui_seamless_toggle() Line 3200  ui_seamless_toggle()
3200          else          else
3201          {          {
3202                  /* 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;  
                 }  
   
3203                  XUnmapWindow(g_display, g_wnd);                  XUnmapWindow(g_display, g_wnd);
3204                  seamless_send_sync();                  seamless_send_sync();
3205          }          }
3206    
3207          g_seamless_rdp = !g_seamless_rdp;          g_seamless_active = !g_seamless_active;
3208  }  }
3209    
3210  void  void
# Line 2992  ui_seamless_create_window(unsigned long Line 3213  ui_seamless_create_window(unsigned long
3213          Window wnd;          Window wnd;
3214          XSetWindowAttributes attribs;          XSetWindowAttributes attribs;
3215          XClassHint *classhints;          XClassHint *classhints;
3216            XSizeHints *sizehints;
3217          long input_mask;          long input_mask;
3218          seamless_window *sw;          seamless_window *sw, *sw_parent;
3219    
3220          get_window_attribs(&attribs);          if (!g_seamless_active)
3221                    return;
3222    
3223            /* Ignore CREATEs for existing windows */
3224            sw = seamless_get_window_by_id(id);
3225            if (sw)
3226                    return;
3227    
3228            get_window_attribs(&attribs);
3229          attribs.override_redirect = False;          attribs.override_redirect = False;
3230    
3231          /* 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,  
3232                              InputOutput, g_visual,                              InputOutput, g_visual,
3233                              CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |                              CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
3234                              CWBorderPixel, &attribs);                              CWBorderPixel, &attribs);
3235    
3236          XStoreName(g_display, wnd, "rdesktop-seamless");          XStoreName(g_display, wnd, "SeamlessRDP");
3237            ewmh_set_wm_name(wnd, "SeamlessRDP");
3238    
3239          mwm_hide_decorations(wnd);          mwm_hide_decorations(wnd);
3240    
3241          classhints = XAllocClassHint();          classhints = XAllocClassHint();
3242          if (classhints != NULL)          if (classhints != NULL)
3243          {          {
3244                  classhints->res_name = classhints->res_class = "rdesktop";                  classhints->res_name = "rdesktop";
3245                    classhints->res_class = "SeamlessRDP";
3246                  XSetClassHint(g_display, wnd, classhints);                  XSetClassHint(g_display, wnd, classhints);
3247                  XFree(classhints);                  XFree(classhints);
3248          }          }
3249    
3250            /* WM_NORMAL_HINTS */
3251            sizehints = XAllocSizeHints();
3252            if (sizehints != NULL)
3253            {
3254                    sizehints->flags = USPosition;
3255                    XSetWMNormalHints(g_display, wnd, sizehints);
3256                    XFree(sizehints);
3257            }
3258    
3259            /* Set WM_TRANSIENT_FOR, if necessary */
3260            if ((parent != 0x00000000) && (parent != 0xFFFFFFFF))
3261            {
3262                    sw_parent = seamless_get_window_by_id(parent);
3263                    if (sw_parent)
3264                            XSetTransientForHint(g_display, wnd, sw_parent->wnd);
3265                    else
3266                            warning("ui_seamless_create_window: No parent window 0x%lx\n", parent);
3267            }
3268    
3269    
3270          /* FIXME: Support for Input Context:s */          /* FIXME: Support for Input Context:s */
3271    
3272          get_input_mask(&input_mask);          get_input_mask(&input_mask);
3273            input_mask |= PropertyChangeMask;
3274    
3275          XSelectInput(g_display, wnd, input_mask);          XSelectInput(g_display, wnd, input_mask);
3276    
         XMapWindow(g_display, wnd);  
   
3277          /* handle the WM_DELETE_WINDOW protocol. FIXME: When killing a          /* handle the WM_DELETE_WINDOW protocol. FIXME: When killing a
3278             seamless window, we could try to close the window on the             seamless window, we could try to close the window on the
3279             serverside, instead of terminating rdesktop */             serverside, instead of terminating rdesktop */
3280          XSetWMProtocols(g_display, wnd, &g_kill_atom, 1);          XSetWMProtocols(g_display, wnd, &g_kill_atom, 1);
3281    
3282          sw = malloc(sizeof(seamless_window));          sw = xmalloc(sizeof(seamless_window));
3283          sw->wnd = wnd;          sw->wnd = wnd;
3284          sw->id = id;          sw->id = id;
3285            sw->parent = parent;
3286            sw->behind = 0;
3287          sw->xoffset = 0;          sw->xoffset = 0;
3288          sw->yoffset = 0;          sw->yoffset = 0;
3289          sw->width = 0;          sw->width = 0;
3290          sw->height = 0;          sw->height = 0;
3291            sw->state = SEAMLESSRDP_NOTYETMAPPED;
3292            sw->desktop = 0;
3293            sw->position_timer = xmalloc(sizeof(struct timeval));
3294            timerclear(sw->position_timer);
3295          sw->next = g_seamless_windows;          sw->next = g_seamless_windows;
3296          g_seamless_windows = sw;          g_seamless_windows = sw;
3297  }  }
# Line 3048  void Line 3301  void
3301  ui_seamless_destroy_window(unsigned long id, unsigned long flags)  ui_seamless_destroy_window(unsigned long id, unsigned long flags)
3302  {  {
3303          seamless_window *sw;          seamless_window *sw;
         sw = seamless_get_window_by_id(id);  
3304    
3305            if (!g_seamless_active)
3306                    return;
3307    
3308            sw = seamless_get_window_by_id(id);
3309          if (!sw)          if (!sw)
3310          {          {
3311                  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 3322  ui_seamless_move_window(unsigned long id
3322  {  {
3323          seamless_window *sw;          seamless_window *sw;
3324    
3325          sw = seamless_get_window_by_id(id);          if (!g_seamless_active)
3326                    return;
3327    
3328            sw = seamless_get_window_by_id(id);
3329          if (!sw)          if (!sw)
3330          {          {
3331                  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);
# Line 3078  ui_seamless_move_window(unsigned long id Line 3336  ui_seamless_move_window(unsigned long id
3336                  /* X11 windows must be at least 1x1 */                  /* X11 windows must be at least 1x1 */
3337                  return;                  return;
3338    
3339          /* About MAX and MIN: Windows allows moving a window outside          sw->xoffset = x;
3340             the desktop. This happens, for example, when maximizing an          sw->yoffset = y;
3341             application. In this case, the position is set to something          sw->width = width;
3342             like -4,-4,1288,1032. Many WMs does not allow windows          sw->height = height;
3343             outside the desktop, however. Therefore, clip the window  
3344             ourselves. */          /* If we move the window in a maximized state, then KDE won't
3345          sw->xoffset = MAX(0, x);             accept restoration */
3346          sw->yoffset = MAX(0, y);          switch (sw->state)
3347          sw->width = MIN(MIN(width, width + x), g_width - sw->xoffset);          {
3348          sw->height = MIN(MIN(height, height + y), g_height - sw->yoffset);                  case SEAMLESSRDP_MINIMIZED:
3349                    case SEAMLESSRDP_MAXIMIZED:
3350                            return;
3351            }
3352    
3353          /* FIXME: Perhaps use ewmh_net_moveresize_window instead */          /* FIXME: Perhaps use ewmh_net_moveresize_window instead */
3354          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);
3355  }  }
3356    
3357    void
3358    ui_seamless_restack_window(unsigned long id, unsigned long behind, unsigned long flags)
3359    {
3360            seamless_window *sw;
3361    
3362            if (!g_seamless_active)
3363                    return;
3364    
3365            sw = seamless_get_window_by_id(id);
3366            if (!sw)
3367            {
3368                    warning("ui_seamless_restack_window: No information for window 0x%lx\n", id);
3369                    return;
3370            }
3371    
3372            if (behind)
3373            {
3374                    seamless_window *sw_behind;
3375                    Window wnds[2];
3376    
3377                    sw_behind = seamless_get_window_by_id(behind);
3378                    if (!sw_behind)
3379                    {
3380                            warning("ui_seamless_restack_window: No information for window 0x%lx\n",
3381                                    behind);
3382                            return;
3383                    }
3384    
3385                    wnds[1] = sw_behind->wnd;
3386                    wnds[0] = sw->wnd;
3387    
3388                    XRestackWindows(g_display, wnds, 2);
3389            }
3390            else
3391            {
3392                    XRaiseWindow(g_display, sw->wnd);
3393            }
3394    
3395            seamless_restack_window(sw, behind);
3396    }
3397    
3398  void  void
3399  ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags)  ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags)
3400  {  {
3401          seamless_window *sw;          seamless_window *sw;
3402    
3403            if (!g_seamless_active)
3404                    return;
3405    
3406          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3407            if (!sw)
3408            {
3409                    warning("ui_seamless_settitle: No information for window 0x%lx\n", id);
3410                    return;
3411            }
3412    
3413            /* FIXME: Might want to convert the name for non-EWMH WMs */
3414          XStoreName(g_display, sw->wnd, title);          XStoreName(g_display, sw->wnd, title);
3415            ewmh_set_wm_name(sw->wnd, title);
3416  }  }
3417    
3418    
# Line 3110  ui_seamless_setstate(unsigned long id, u Line 3421  ui_seamless_setstate(unsigned long id, u
3421  {  {
3422          seamless_window *sw;          seamless_window *sw;
3423    
3424            if (!g_seamless_active)
3425                    return;
3426    
3427          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3428            if (!sw)
3429            {
3430                    warning("ui_seamless_setstate: No information for window 0x%lx\n", id);
3431                    return;
3432            }
3433    
3434          switch (state)          switch (state)
3435          {          {
3436                  case SEAMLESSRDP_NORMAL:                  case SEAMLESSRDP_NORMAL:
3437                  case SEAMLESSRDP_MAXIMIZED:                  case SEAMLESSRDP_MAXIMIZED:
3438                          /* FIXME */                          ewmh_change_state(sw->wnd, state);
3439                            XMapWindow(g_display, sw->wnd);
3440                          break;                          break;
3441                  case SEAMLESSRDP_MINIMIZED:                  case SEAMLESSRDP_MINIMIZED:
3442                          XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));                          /* EWMH says: "if an Application asks to toggle _NET_WM_STATE_HIDDEN
3443                               the Window Manager should probably just ignore the request, since
3444                               _NET_WM_STATE_HIDDEN is a function of some other aspect of the window
3445                               such as minimization, rather than an independent state." Besides,
3446                               XIconifyWindow is easier. */
3447                            if (sw->state == SEAMLESSRDP_NOTYETMAPPED)
3448                            {
3449                                    XWMHints *hints;
3450                                    hints = XAllocWMHints();
3451                                    hints->flags = StateHint;
3452                                    hints->initial_state = IconicState;
3453                                    XSetWMHints(g_display, sw->wnd, hints);
3454                                    XFree(hints);
3455                                    XMapWindow(g_display, sw->wnd);
3456                            }
3457                            else
3458                                    XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));
3459                          break;                          break;
3460                  default:                  default:
3461                          warning("SeamlessRDP: Invalid state %d\n", state);                          warning("SeamlessRDP: Invalid state %d\n", state);
3462                          break;                          break;
3463          }          }
3464    
3465            /* Handle popups without parents through some ewm hints */
3466            if ((sw->state == SEAMLESSRDP_NOTYETMAPPED) && (sw->parent == 0xFFFFFFFF))
3467                    ewmh_set_window_popup(sw->wnd);
3468    
3469            sw->state = state;
3470    }
3471    
3472    
3473    void
3474    ui_seamless_syncbegin(unsigned long flags)
3475    {
3476            if (!g_seamless_active)
3477                    return;
3478    
3479            /* Destroy all seamless windows */
3480            while (g_seamless_windows)
3481            {
3482                    XDestroyWindow(g_display, g_seamless_windows->wnd);
3483                    seamless_remove_window(g_seamless_windows);
3484            }
3485  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26