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

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

  ViewVC Help
Powered by ViewVC 1.1.26