/[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 1132 by astrand, Wed Mar 15 12:58:50 2006 UTC revision 1170 by astrand, Mon Mar 20 15:43:15 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. */          int state;              /* normal/minimized/maximized. */
61          unsigned int desktop;          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 259  static int rop2_map[] = { Line 270  static int rop2_map[] = {
270  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(g_display, g_gc, GXcopy); }  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(g_display, g_gc, GXcopy); }
271    
272  static seamless_window *  static seamless_window *
273  seamless_get_window_by_id(unsigned long id)  sw_get_window_by_id(unsigned long id)
274  {  {
275          seamless_window *sw;          seamless_window *sw;
276          for (sw = g_seamless_windows; sw; sw = sw->next)          for (sw = g_seamless_windows; sw; sw = sw->next)
# Line 272  seamless_get_window_by_id(unsigned long Line 283  seamless_get_window_by_id(unsigned long
283    
284    
285  static seamless_window *  static seamless_window *
286  seamless_get_window_by_wnd(Window wnd)  sw_get_window_by_wnd(Window wnd)
287  {  {
288          seamless_window *sw;          seamless_window *sw;
289          for (sw = g_seamless_windows; sw; sw = sw->next)          for (sw = g_seamless_windows; sw; sw = sw->next)
# Line 285  seamless_get_window_by_wnd(Window wnd) Line 296  seamless_get_window_by_wnd(Window wnd)
296    
297    
298  static void  static void
299  seamless_remove_window(seamless_window * win)  sw_remove_window(seamless_window * win)
300  {  {
301          seamless_window *sw, **prevnext = &g_seamless_windows;          seamless_window *sw, **prevnext = &g_seamless_windows;
302          for (sw = g_seamless_windows; sw; sw = sw->next)          for (sw = g_seamless_windows; sw; sw = sw->next)
# Line 304  seamless_remove_window(seamless_window * Line 315  seamless_remove_window(seamless_window *
315    
316  /* Move all windows except wnd to new desktop */  /* Move all windows except wnd to new desktop */
317  static void  static void
318  seamless_all_to_desktop(Window wnd, unsigned int desktop)  sw_all_to_desktop(Window wnd, unsigned int desktop)
319  {  {
320          seamless_window *sw;          seamless_window *sw;
321          for (sw = g_seamless_windows; sw; sw = sw->next)          for (sw = g_seamless_windows; sw; sw = sw->next)
# Line 320  seamless_all_to_desktop(Window wnd, unsi Line 331  seamless_all_to_desktop(Window wnd, unsi
331  }  }
332    
333    
334    /* Send our position */
335    static void
336    sw_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    sw_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                            sw_update_position(sw);
373                    }
374            }
375    }
376    
377    
378    static void
379    sw_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
409    sw_handle_restack(seamless_window * sw)
410    {
411            Status status;
412            Window root, parent, *children;
413            unsigned int nchildren, i;
414            seamless_window *sw_below;
415    
416            status = XQueryTree(g_display, RootWindowOfScreen(g_screen),
417                                &root, &parent, &children, &nchildren);
418            if (!status || !nchildren)
419                    return;
420    
421            sw_below = NULL;
422    
423            i = 0;
424            while (children[i] != sw->wnd)
425            {
426                    i++;
427                    if (i >= nchildren)
428                            return;
429            }
430    
431            for (i++; i < nchildren; i++)
432            {
433                    sw_below = sw_get_window_by_wnd(children[i]);
434                    if (sw_below)
435                            break;
436            }
437    
438            if (!sw_below && !sw->behind)
439                    return;
440            if (sw_below && (sw_below->id == sw->behind))
441                    return;
442    
443            if (sw_below)
444            {
445                    seamless_send_zchange(sw->id, sw_below->id, 0);
446                    sw_restack_window(sw, sw_below->id);
447            }
448            else
449            {
450                    seamless_send_zchange(sw->id, 0, 0);
451                    sw_restack_window(sw, 0);
452            }
453    }
454    
455    
456  static void  static void
457  mwm_hide_decorations(Window wnd)  mwm_hide_decorations(Window wnd)
458  {  {
# Line 1564  ui_create_window(void) Line 1697  ui_create_window(void)
1697          }          }
1698    
1699          XSelectInput(g_display, g_wnd, input_mask);          XSelectInput(g_display, g_wnd, input_mask);
1700          if (!g_seamless_rdp)  
1701            XMapWindow(g_display, g_wnd);
1702            /* wait for VisibilityNotify */
1703            do
1704          {          {
1705                  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;  
1706          }          }
1707            while (xevent.type != VisibilityNotify);
1708            g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;
1709    
1710          g_focused = False;          g_focused = False;
1711          g_mouse_in_wnd = False;          g_mouse_in_wnd = False;
# Line 1638  xwin_toggle_fullscreen(void) Line 1769  xwin_toggle_fullscreen(void)
1769  {  {
1770          Pixmap contents = 0;          Pixmap contents = 0;
1771    
1772          if (g_seamless_rdp)          if (g_seamless_active)
1773                  /* Turn off SeamlessRDP mode */                  /* Turn off SeamlessRDP mode */
1774                  ui_seamless_toggle();                  ui_seamless_toggle();
1775    
# Line 1743  handle_button_event(XEvent xevent, BOOL Line 1874  handle_button_event(XEvent xevent, BOOL
1874          }          }
1875  }  }
1876    
1877    
1878  /* Process events in Xlib queue  /* Process events in Xlib queue
1879     Returns 0 after user quit, 1 otherwise */     Returns 0 after user quit, 1 otherwise */
1880  static int  static int
# Line 1875  xwin_process_events(void) Line 2007  xwin_process_events(void)
2007                                  if (g_grab_keyboard && g_mouse_in_wnd)                                  if (g_grab_keyboard && g_mouse_in_wnd)
2008                                          XGrabKeyboard(g_display, g_wnd, True,                                          XGrabKeyboard(g_display, g_wnd, True,
2009                                                        GrabModeAsync, GrabModeAsync, CurrentTime);                                                        GrabModeAsync, GrabModeAsync, CurrentTime);
2010    
2011                                    sw = sw_get_window_by_wnd(xevent.xfocus.window);
2012                                    if (!sw)
2013                                            break;
2014    
2015                                    if (sw->id != g_seamless_focused)
2016                                    {
2017                                            seamless_send_focus(sw->id, 0);
2018                                            g_seamless_focused = sw->id;
2019                                    }
2020                                  break;                                  break;
2021    
2022                          case FocusOut:                          case FocusOut:
# Line 1917  xwin_process_events(void) Line 2059  xwin_process_events(void)
2059                                  }                                  }
2060                                  else                                  else
2061                                  {                                  {
2062                                          sw = seamless_get_window_by_wnd(xevent.xexpose.window);                                          sw = sw_get_window_by_wnd(xevent.xexpose.window);
2063                                          if (sw)                                          if (sw)
2064                                                  XCopyArea(g_display, g_backstore,                                                  XCopyArea(g_display, g_backstore,
2065                                                            xevent.xexpose.window, g_gc,                                                            xevent.xexpose.window, g_gc,
# Line 1967  xwin_process_events(void) Line 2109  xwin_process_events(void)
2109                                          break;                                          break;
2110    
2111                                  /* seamless */                                  /* seamless */
2112                                  sw = seamless_get_window_by_wnd(xevent.xproperty.window);                                  sw = sw_get_window_by_wnd(xevent.xproperty.window);
2113                                  if (!sw)                                  if (!sw)
2114                                          break;                                          break;
2115    
# Line 1982  xwin_process_events(void) Line 2124  xwin_process_events(void)
2124                                      && (xevent.xproperty.state == PropertyNewValue))                                      && (xevent.xproperty.state == PropertyNewValue))
2125                                  {                                  {
2126                                          sw->desktop = ewmh_get_window_desktop(sw->wnd);                                          sw->desktop = ewmh_get_window_desktop(sw->wnd);
2127                                          seamless_all_to_desktop(sw->wnd, sw->desktop);                                          sw_all_to_desktop(sw->wnd, sw->desktop);
2128                                  }                                  }
2129    
2130                                  break;                                  break;
2131                          case MapNotify:                          case MapNotify:
2132                                  if (!g_seamless_rdp)                                  if (!g_seamless_active)
2133                                          rdp_send_client_window_status(1);                                          rdp_send_client_window_status(1);
2134                                  break;                                  break;
2135                          case UnmapNotify:                          case UnmapNotify:
2136                                  if (!g_seamless_rdp)                                  if (!g_seamless_active)
2137                                          rdp_send_client_window_status(0);                                          rdp_send_client_window_status(0);
2138                                  break;                                  break;
2139                            case ConfigureNotify:
2140                                    if (!g_seamless_active)
2141                                            break;
2142    
2143                                    sw = sw_get_window_by_wnd(xevent.xconfigure.window);
2144                                    if (!sw)
2145                                    {
2146                                            error("ConfigureNotify for unknown window 0x%lx\n",
2147                                                  xevent.xconfigure.window);
2148                                    }
2149    
2150                                    gettimeofday(sw->position_timer, NULL);
2151                                    if (sw->position_timer->tv_usec + SEAMLESSRDP_POSITION_TIMER >=
2152                                        1000000)
2153                                    {
2154                                            sw->position_timer->tv_usec +=
2155                                                    SEAMLESSRDP_POSITION_TIMER - 1000000;
2156                                            sw->position_timer->tv_sec += 1;
2157                                    }
2158                                    else
2159                                    {
2160                                            sw->position_timer->tv_usec += SEAMLESSRDP_POSITION_TIMER;
2161                                    }
2162    
2163                                    sw_handle_restack(sw);
2164                                    break;
2165                  }                  }
2166          }          }
2167          /* Keep going */          /* Keep going */
# Line 2017  ui_select(int rdp_socket) Line 2185  ui_select(int rdp_socket)
2185                          /* User quit */                          /* User quit */
2186                          return 0;                          return 0;
2187    
2188                    if (g_seamless_active)
2189                            sw_check_timers();
2190    
2191                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
2192                  FD_ZERO(&wfds);                  FD_ZERO(&wfds);
2193                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
# Line 2036  ui_select(int rdp_socket) Line 2207  ui_select(int rdp_socket)
2207    
2208                  /* add redirection handles */                  /* add redirection handles */
2209                  rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);                  rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);
2210                    seamless_select_timeout(&tv);
2211    
2212                  n++;                  n++;
2213    
# Line 3004  ui_end_update(void) Line 3176  ui_end_update(void)
3176  {  {
3177  }  }
3178    
3179    
3180    void
3181    ui_seamless_begin()
3182    {
3183            if (!g_seamless_rdp)
3184                    return;
3185    
3186            if (g_seamless_started)
3187                    return;
3188    
3189            g_seamless_started = True;
3190            ui_seamless_toggle();
3191    }
3192    
3193    
3194  void  void
3195  ui_seamless_toggle()  ui_seamless_toggle()
3196  {  {
3197          if (g_seamless_rdp)          if (!g_seamless_rdp)
3198                    return;
3199    
3200            if (!g_seamless_started)
3201                    return;
3202    
3203            if (g_seamless_active)
3204          {          {
3205                  /* Deactivate */                  /* Deactivate */
3206                  while (g_seamless_windows)                  while (g_seamless_windows)
3207                  {                  {
3208                          XDestroyWindow(g_display, g_seamless_windows->wnd);                          XDestroyWindow(g_display, g_seamless_windows->wnd);
3209                          seamless_remove_window(g_seamless_windows);                          sw_remove_window(g_seamless_windows);
3210                  }                  }
3211                  XMapWindow(g_display, g_wnd);                  XMapWindow(g_display, g_wnd);
3212          }          }
3213          else          else
3214          {          {
3215                  /* 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;  
                 }  
   
3216                  XUnmapWindow(g_display, g_wnd);                  XUnmapWindow(g_display, g_wnd);
3217                  seamless_send_sync();                  seamless_send_sync();
3218          }          }
3219    
3220          g_seamless_rdp = !g_seamless_rdp;          g_seamless_active = !g_seamless_active;
3221  }  }
3222    
3223    
3224  void  void
3225  ui_seamless_create_window(unsigned long id, unsigned long parent, unsigned long flags)  ui_seamless_create_window(unsigned long id, unsigned long parent, unsigned long flags)
3226  {  {
# Line 3048  ui_seamless_create_window(unsigned long Line 3231  ui_seamless_create_window(unsigned long
3231          long input_mask;          long input_mask;
3232          seamless_window *sw, *sw_parent;          seamless_window *sw, *sw_parent;
3233    
3234            if (!g_seamless_active)
3235                    return;
3236    
3237          /* Ignore CREATEs for existing windows */          /* Ignore CREATEs for existing windows */
3238          sw = seamless_get_window_by_id(id);          sw = sw_get_window_by_id(id);
3239          if (sw)          if (sw)
3240                  return;                  return;
3241    
# Line 3061  ui_seamless_create_window(unsigned long Line 3247  ui_seamless_create_window(unsigned long
3247                              CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |                              CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
3248                              CWBorderPixel, &attribs);                              CWBorderPixel, &attribs);
3249    
3250          XStoreName(g_display, wnd, "rdesktop-seamless");          XStoreName(g_display, wnd, "SeamlessRDP");
3251            ewmh_set_wm_name(wnd, "SeamlessRDP");
3252    
3253          mwm_hide_decorations(wnd);          mwm_hide_decorations(wnd);
3254    
3255          classhints = XAllocClassHint();          classhints = XAllocClassHint();
3256          if (classhints != NULL)          if (classhints != NULL)
3257          {          {
3258                  classhints->res_name = classhints->res_class = "rdesktop";                  classhints->res_name = "rdesktop";
3259                    classhints->res_class = "SeamlessRDP";
3260                  XSetClassHint(g_display, wnd, classhints);                  XSetClassHint(g_display, wnd, classhints);
3261                  XFree(classhints);                  XFree(classhints);
3262          }          }
# Line 3082  ui_seamless_create_window(unsigned long Line 3270  ui_seamless_create_window(unsigned long
3270                  XFree(sizehints);                  XFree(sizehints);
3271          }          }
3272    
3273            /* Handle popups without parents through some ewm hints */
3274            if (parent == 0xFFFFFFFF)
3275                    ewmh_set_window_popup(wnd);
3276          /* Set WM_TRANSIENT_FOR, if necessary */          /* Set WM_TRANSIENT_FOR, if necessary */
3277          if (parent)          else if (parent != 0x00000000)
3278          {          {
3279                  sw_parent = seamless_get_window_by_id(parent);                  sw_parent = sw_get_window_by_id(parent);
3280                  if (sw_parent)                  if (sw_parent)
3281                          XSetTransientForHint(g_display, wnd, sw_parent->wnd);                          XSetTransientForHint(g_display, wnd, sw_parent->wnd);
3282                  else                  else
3283                          warning("ui_seamless_create_window: No parent window 0x%lx\n", parent);                          warning("ui_seamless_create_window: No parent window 0x%lx\n", parent);
3284          }          }
3285    
3286    
3287          /* FIXME: Support for Input Context:s */          /* FIXME: Support for Input Context:s */
3288    
3289          get_input_mask(&input_mask);          get_input_mask(&input_mask);
# Line 3104  ui_seamless_create_window(unsigned long Line 3296  ui_seamless_create_window(unsigned long
3296             serverside, instead of terminating rdesktop */             serverside, instead of terminating rdesktop */
3297          XSetWMProtocols(g_display, wnd, &g_kill_atom, 1);          XSetWMProtocols(g_display, wnd, &g_kill_atom, 1);
3298    
3299          sw = malloc(sizeof(seamless_window));          sw = xmalloc(sizeof(seamless_window));
3300          sw->wnd = wnd;          sw->wnd = wnd;
3301          sw->id = id;          sw->id = id;
3302            sw->behind = 0;
3303          sw->xoffset = 0;          sw->xoffset = 0;
3304          sw->yoffset = 0;          sw->yoffset = 0;
3305          sw->width = 0;          sw->width = 0;
3306          sw->height = 0;          sw->height = 0;
3307          sw->state = SEAMLESSRDP_NOTYETMAPPED;          sw->state = SEAMLESSRDP_NOTYETMAPPED;
3308          sw->desktop = 0;          sw->desktop = 0;
3309            sw->position_timer = xmalloc(sizeof(struct timeval));
3310            timerclear(sw->position_timer);
3311            sw->outstanding_position = False;
3312          sw->next = g_seamless_windows;          sw->next = g_seamless_windows;
3313          g_seamless_windows = sw;          g_seamless_windows = sw;
3314  }  }
# Line 3123  ui_seamless_destroy_window(unsigned long Line 3319  ui_seamless_destroy_window(unsigned long
3319  {  {
3320          seamless_window *sw;          seamless_window *sw;
3321    
3322          sw = seamless_get_window_by_id(id);          if (!g_seamless_active)
3323                    return;
3324    
3325            sw = sw_get_window_by_id(id);
3326          if (!sw)          if (!sw)
3327          {          {
3328                  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 3131  ui_seamless_destroy_window(unsigned long Line 3330  ui_seamless_destroy_window(unsigned long
3330          }          }
3331    
3332          XDestroyWindow(g_display, sw->wnd);          XDestroyWindow(g_display, sw->wnd);
3333          seamless_remove_window(sw);          sw_remove_window(sw);
3334  }  }
3335    
3336    
# Line 3140  ui_seamless_move_window(unsigned long id Line 3339  ui_seamless_move_window(unsigned long id
3339  {  {
3340          seamless_window *sw;          seamless_window *sw;
3341    
3342          sw = seamless_get_window_by_id(id);          if (!g_seamless_active)
3343                    return;
3344    
3345            sw = sw_get_window_by_id(id);
3346          if (!sw)          if (!sw)
3347          {          {
3348                  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);
3349                  return;                  return;
3350          }          }
3351    
3352            /* We ignore server updates until it has handled our request. */
3353            if (sw->outstanding_position)
3354                    return;
3355    
3356          if (!width || !height)          if (!width || !height)
3357                  /* X11 windows must be at least 1x1 */                  /* X11 windows must be at least 1x1 */
3358                  return;                  return;
3359    
3360          /* About MAX and MIN: Windows allows moving a window outside          sw->xoffset = x;
3361             the desktop. This happens, for example, when maximizing an          sw->yoffset = y;
3362             application. In this case, the position is set to something          sw->width = width;
3363             like -4,-4,1288,1032. Many WMs does not allow windows          sw->height = height;
            outside the desktop, however. Therefore, clip the window  
            ourselves. */  
         sw->xoffset = MAX(0, x);  
         sw->yoffset = MAX(0, y);  
         sw->width = MIN(MIN(width, width + x), g_width - sw->xoffset);  
         sw->height = MIN(MIN(height, height + y), g_height - sw->yoffset);  
3364    
3365          /* If we move the window in a maximized state, then KDE won't          /* If we move the window in a maximized state, then KDE won't
3366             accept restoration */             accept restoration */
# Line 3177  ui_seamless_move_window(unsigned long id Line 3377  ui_seamless_move_window(unsigned long id
3377    
3378    
3379  void  void
3380    ui_seamless_restack_window(unsigned long id, unsigned long behind, unsigned long flags)
3381    {
3382            seamless_window *sw;
3383    
3384            if (!g_seamless_active)
3385                    return;
3386    
3387            sw = sw_get_window_by_id(id);
3388            if (!sw)
3389            {
3390                    warning("ui_seamless_restack_window: No information for window 0x%lx\n", id);
3391                    return;
3392            }
3393    
3394            if (behind)
3395            {
3396                    seamless_window *sw_behind;
3397                    Window wnds[2];
3398    
3399                    sw_behind = sw_get_window_by_id(behind);
3400                    if (!sw_behind)
3401                    {
3402                            warning("ui_seamless_restack_window: No information for window 0x%lx\n",
3403                                    behind);
3404                            return;
3405                    }
3406    
3407                    wnds[1] = sw_behind->wnd;
3408                    wnds[0] = sw->wnd;
3409    
3410                    XRestackWindows(g_display, wnds, 2);
3411            }
3412            else
3413            {
3414                    XRaiseWindow(g_display, sw->wnd);
3415            }
3416    
3417            sw_restack_window(sw, behind);
3418    }
3419    
3420    
3421    void
3422  ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags)  ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags)
3423  {  {
3424          seamless_window *sw;          seamless_window *sw;
3425    
3426          sw = seamless_get_window_by_id(id);          if (!g_seamless_active)
3427                    return;
3428    
3429            sw = sw_get_window_by_id(id);
3430          if (!sw)          if (!sw)
3431          {          {
3432                  warning("ui_seamless_settitle: No information for window 0x%lx\n", id);                  warning("ui_seamless_settitle: No information for window 0x%lx\n", id);
3433                  return;                  return;
3434          }          }
3435    
3436            /* FIXME: Might want to convert the name for non-EWMH WMs */
3437          XStoreName(g_display, sw->wnd, title);          XStoreName(g_display, sw->wnd, title);
3438            ewmh_set_wm_name(sw->wnd, title);
3439  }  }
3440    
3441    
# Line 3197  ui_seamless_setstate(unsigned long id, u Line 3444  ui_seamless_setstate(unsigned long id, u
3444  {  {
3445          seamless_window *sw;          seamless_window *sw;
3446    
3447          sw = seamless_get_window_by_id(id);          if (!g_seamless_active)
3448                    return;
3449    
3450            sw = sw_get_window_by_id(id);
3451          if (!sw)          if (!sw)
3452          {          {
3453                  warning("ui_seamless_setstate: No information for window 0x%lx\n", id);                  warning("ui_seamless_setstate: No information for window 0x%lx\n", id);
3454                  return;                  return;
3455          }          }
3456    
         if (sw->state == SEAMLESSRDP_NOTYETMAPPED)  
         {  
                 XMapWindow(g_display, sw->wnd);  
         }  
   
         sw->state = state;  
   
3457          switch (state)          switch (state)
3458          {          {
3459                  case SEAMLESSRDP_NORMAL:                  case SEAMLESSRDP_NORMAL:
3460                  case SEAMLESSRDP_MAXIMIZED:                  case SEAMLESSRDP_MAXIMIZED:
3461                          ewmh_change_state(sw->wnd, state);                          ewmh_change_state(sw->wnd, state);
3462                            XMapWindow(g_display, sw->wnd);
3463                          break;                          break;
3464                  case SEAMLESSRDP_MINIMIZED:                  case SEAMLESSRDP_MINIMIZED:
3465                          /* EWMH says: "if an Application asks to toggle _NET_WM_STATE_HIDDEN                          /* EWMH says: "if an Application asks to toggle _NET_WM_STATE_HIDDEN
# Line 3223  ui_seamless_setstate(unsigned long id, u Line 3467  ui_seamless_setstate(unsigned long id, u
3467                             _NET_WM_STATE_HIDDEN is a function of some other aspect of the window                             _NET_WM_STATE_HIDDEN is a function of some other aspect of the window
3468                             such as minimization, rather than an independent state." Besides,                             such as minimization, rather than an independent state." Besides,
3469                             XIconifyWindow is easier. */                             XIconifyWindow is easier. */
3470                          XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));                          if (sw->state == SEAMLESSRDP_NOTYETMAPPED)
3471                            {
3472                                    XWMHints *hints;
3473                                    hints = XAllocWMHints();
3474                                    hints->flags = StateHint;
3475                                    hints->initial_state = IconicState;
3476                                    XSetWMHints(g_display, sw->wnd, hints);
3477                                    XFree(hints);
3478                                    XMapWindow(g_display, sw->wnd);
3479                            }
3480                            else
3481                                    XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));
3482                          break;                          break;
3483                  default:                  default:
3484                          warning("SeamlessRDP: Invalid state %d\n", state);                          warning("SeamlessRDP: Invalid state %d\n", state);
3485                          break;                          break;
3486          }          }
3487    
3488            sw->state = state;
3489  }  }
3490    
3491    
3492  void  void
3493  ui_seamless_syncbegin(unsigned long flags)  ui_seamless_syncbegin(unsigned long flags)
3494  {  {
3495            if (!g_seamless_active)
3496                    return;
3497    
3498          /* Destroy all seamless windows */          /* Destroy all seamless windows */
3499          while (g_seamless_windows)          while (g_seamless_windows)
3500          {          {
3501                  XDestroyWindow(g_display, g_seamless_windows->wnd);                  XDestroyWindow(g_display, g_seamless_windows->wnd);
3502                  seamless_remove_window(g_seamless_windows);                  sw_remove_window(g_seamless_windows);
3503          }          }
3504  }  }
3505    
3506    
3507    void
3508    ui_seamless_ack(unsigned int serial)
3509    {
3510            seamless_window *sw;
3511            for (sw = g_seamless_windows; sw; sw = sw->next)
3512            {
3513                    if (sw->outpos_serial == serial)
3514                    {
3515                            sw->xoffset = sw->outpos_xoffset;
3516                            sw->yoffset = sw->outpos_yoffset;
3517                            sw->width = sw->outpos_width;
3518                            sw->height = sw->outpos_height;
3519                            sw->outstanding_position = False;
3520                            break;
3521                    }
3522            }
3523    
3524            return;
3525    }

Legend:
Removed from v.1132  
changed lines
  Added in v.1170

  ViewVC Help
Powered by ViewVC 1.1.26