/[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 1140 by ossman_, Wed Mar 15 15:27:24 2006 UTC revision 1155 by ossman_, Fri Mar 17 10:48:11 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. */          int state;              /* normal/minimized/maximized. */
# Line 61  typedef struct _seamless_window Line 63  typedef struct _seamless_window
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 321  seamless_all_to_desktop(Window wnd, unsi Line 326  seamless_all_to_desktop(Window wnd, unsi
326    
327    
328  static void  static void
329    seamless_restack_window(seamless_window * sw, unsigned long behind)
330    {
331            seamless_window *sw_above;
332    
333            /* Remove window from stack */
334            for (sw_above = g_seamless_windows; sw_above; sw_above = sw_above->next)
335            {
336                    if (sw_above->behind == sw->id)
337                            break;
338            }
339    
340            if (sw_above)
341                    sw_above->behind = sw->behind;
342    
343            /* And then add it at the new position */
344    
345            for (sw_above = g_seamless_windows; sw_above; sw_above = sw_above->next)
346            {
347                    if (sw_above->behind == behind)
348                            break;
349            }
350    
351            if (sw_above)
352                    sw_above->behind = sw->id;
353    
354            sw->behind = behind;
355    }
356    
357    
358    static void
359  mwm_hide_decorations(Window wnd)  mwm_hide_decorations(Window wnd)
360  {  {
361          PropMotifWmHints motif_hints;          PropMotifWmHints motif_hints;
# Line 1564  ui_create_window(void) Line 1599  ui_create_window(void)
1599          }          }
1600    
1601          XSelectInput(g_display, g_wnd, input_mask);          XSelectInput(g_display, g_wnd, input_mask);
1602          if (!g_seamless_rdp)  
1603            XMapWindow(g_display, g_wnd);
1604            /* wait for VisibilityNotify */
1605            do
1606          {          {
1607                  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;  
1608          }          }
1609            while (xevent.type != VisibilityNotify);
1610            g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;
1611    
1612          g_focused = False;          g_focused = False;
1613          g_mouse_in_wnd = False;          g_mouse_in_wnd = False;
# Line 1638  xwin_toggle_fullscreen(void) Line 1671  xwin_toggle_fullscreen(void)
1671  {  {
1672          Pixmap contents = 0;          Pixmap contents = 0;
1673    
1674          if (g_seamless_rdp)          if (g_seamless_active)
1675                  /* Turn off SeamlessRDP mode */                  /* Turn off SeamlessRDP mode */
1676                  ui_seamless_toggle();                  ui_seamless_toggle();
1677    
# Line 1743  handle_button_event(XEvent xevent, BOOL Line 1776  handle_button_event(XEvent xevent, BOOL
1776          }          }
1777  }  }
1778    
1779    static void
1780    ui_seamless_handle_restack(seamless_window * sw)
1781    {
1782            Status status;
1783            Window root, parent, *children;
1784            unsigned int nchildren, i;
1785            seamless_window *sw_below;
1786    
1787            status = XQueryTree(g_display, RootWindowOfScreen(g_screen),
1788                                &root, &parent, &children, &nchildren);
1789            if (!status || !nchildren)
1790                    return;
1791    
1792            sw_below = NULL;
1793    
1794            i = 0;
1795            while (children[i] != sw->wnd)
1796            {
1797                    i++;
1798                    if (i >= nchildren)
1799                            return;
1800            }
1801    
1802            for (i++; i < nchildren; i++)
1803            {
1804                    sw_below = seamless_get_window_by_wnd(children[i]);
1805                    if (sw_below)
1806                            break;
1807            }
1808    
1809            if (!sw_below && !sw->behind)
1810                    return;
1811            if (sw_below && (sw_below->id == sw->behind))
1812                    return;
1813    
1814            if (sw_below)
1815            {
1816                    seamless_send_zchange(sw->id, sw_below->id, 0);
1817                    seamless_restack_window(sw, sw_below->id);
1818            }
1819            else
1820            {
1821                    seamless_send_zchange(sw->id, 0, 0);
1822                    seamless_restack_window(sw, 0);
1823            }
1824    }
1825    
1826  /* Process events in Xlib queue  /* Process events in Xlib queue
1827     Returns 0 after user quit, 1 otherwise */     Returns 0 after user quit, 1 otherwise */
1828  static int  static int
# Line 1875  xwin_process_events(void) Line 1955  xwin_process_events(void)
1955                                  if (g_grab_keyboard && g_mouse_in_wnd)                                  if (g_grab_keyboard && g_mouse_in_wnd)
1956                                          XGrabKeyboard(g_display, g_wnd, True,                                          XGrabKeyboard(g_display, g_wnd, True,
1957                                                        GrabModeAsync, GrabModeAsync, CurrentTime);                                                        GrabModeAsync, GrabModeAsync, CurrentTime);
1958    
1959                                    sw = seamless_get_window_by_wnd(xevent.xfocus.window);
1960                                    if (!sw)
1961                                            break;
1962    
1963                                    if (sw->id != g_seamless_focused)
1964                                    {
1965                                            seamless_send_focus(sw->id, 0);
1966                                            g_seamless_focused = sw->id;
1967                                    }
1968                                  break;                                  break;
1969    
1970                          case FocusOut:                          case FocusOut:
# Line 1987  xwin_process_events(void) Line 2077  xwin_process_events(void)
2077    
2078                                  break;                                  break;
2079                          case MapNotify:                          case MapNotify:
2080                                  if (!g_seamless_rdp)                                  if (!g_seamless_active)
2081                                          rdp_send_client_window_status(1);                                          rdp_send_client_window_status(1);
2082                                  break;                                  break;
2083                          case UnmapNotify:                          case UnmapNotify:
2084                                  if (!g_seamless_rdp)                                  if (!g_seamless_active)
2085                                          rdp_send_client_window_status(0);                                          rdp_send_client_window_status(0);
2086                                  break;                                  break;
2087                            case ConfigureNotify:
2088                                    /* seamless */
2089                                    sw = seamless_get_window_by_wnd(xevent.xconfigure.window);
2090                                    if (!sw)
2091                                            break;
2092    
2093                                    ui_seamless_handle_restack(sw);
2094                  }                  }
2095          }          }
2096          /* Keep going */          /* Keep going */
# Line 3005  ui_end_update(void) Line 3102  ui_end_update(void)
3102  }  }
3103    
3104  void  void
3105    ui_seamless_begin()
3106    {
3107            if (!g_seamless_rdp)
3108                    return;
3109    
3110            if (g_seamless_started)
3111                    return;
3112    
3113            g_seamless_started = True;
3114    
3115            ui_seamless_toggle();
3116    }
3117    
3118    void
3119  ui_seamless_toggle()  ui_seamless_toggle()
3120  {  {
3121          if (g_seamless_rdp)          if (!g_seamless_rdp)
3122                    return;
3123    
3124            if (!g_seamless_started)
3125                    return;
3126    
3127            if (g_seamless_active)
3128          {          {
3129                  /* Deactivate */                  /* Deactivate */
3130                  while (g_seamless_windows)                  while (g_seamless_windows)
# Line 3020  ui_seamless_toggle() Line 3137  ui_seamless_toggle()
3137          else          else
3138          {          {
3139                  /* 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;  
                 }  
   
3140                  XUnmapWindow(g_display, g_wnd);                  XUnmapWindow(g_display, g_wnd);
3141                  seamless_send_sync();                  seamless_send_sync();
3142          }          }
3143    
3144          g_seamless_rdp = !g_seamless_rdp;          g_seamless_active = !g_seamless_active;
3145  }  }
3146    
3147  void  void
# Line 3048  ui_seamless_create_window(unsigned long Line 3154  ui_seamless_create_window(unsigned long
3154          long input_mask;          long input_mask;
3155          seamless_window *sw, *sw_parent;          seamless_window *sw, *sw_parent;
3156    
3157            if (!g_seamless_active)
3158                    return;
3159    
3160          /* Ignore CREATEs for existing windows */          /* Ignore CREATEs for existing windows */
3161          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3162          if (sw)          if (sw)
# Line 3084  ui_seamless_create_window(unsigned long Line 3193  ui_seamless_create_window(unsigned long
3193                  XFree(sizehints);                  XFree(sizehints);
3194          }          }
3195    
         /* Handle popups without parents through some ewm hints */  
         if (parent == 0xFFFFFFFF)  
                 ewmh_set_window_popup(wnd);  
3196          /* Set WM_TRANSIENT_FOR, if necessary */          /* Set WM_TRANSIENT_FOR, if necessary */
3197          else if (parent != 0x00000000)          if ((parent != 0x00000000) && (parent != 0xFFFFFFFF))
3198          {          {
3199                  sw_parent = seamless_get_window_by_id(parent);                  sw_parent = seamless_get_window_by_id(parent);
3200                  if (sw_parent)                  if (sw_parent)
# Line 3113  ui_seamless_create_window(unsigned long Line 3219  ui_seamless_create_window(unsigned long
3219          sw = malloc(sizeof(seamless_window));          sw = malloc(sizeof(seamless_window));
3220          sw->wnd = wnd;          sw->wnd = wnd;
3221          sw->id = id;          sw->id = id;
3222            sw->parent = parent;
3223            sw->behind = 0;
3224          sw->xoffset = 0;          sw->xoffset = 0;
3225          sw->yoffset = 0;          sw->yoffset = 0;
3226          sw->width = 0;          sw->width = 0;
# Line 3129  ui_seamless_destroy_window(unsigned long Line 3237  ui_seamless_destroy_window(unsigned long
3237  {  {
3238          seamless_window *sw;          seamless_window *sw;
3239    
3240            if (!g_seamless_active)
3241                    return;
3242    
3243          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3244          if (!sw)          if (!sw)
3245          {          {
# Line 3146  ui_seamless_move_window(unsigned long id Line 3257  ui_seamless_move_window(unsigned long id
3257  {  {
3258          seamless_window *sw;          seamless_window *sw;
3259    
3260            if (!g_seamless_active)
3261                    return;
3262    
3263          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3264          if (!sw)          if (!sw)
3265          {          {
# Line 3181  ui_seamless_move_window(unsigned long id Line 3295  ui_seamless_move_window(unsigned long id
3295          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);
3296  }  }
3297    
3298    void
3299    ui_seamless_restack_window(unsigned long id, unsigned long behind, unsigned long flags)
3300    {
3301            seamless_window *sw;
3302    
3303            if (!g_seamless_active)
3304                    return;
3305    
3306            sw = seamless_get_window_by_id(id);
3307            if (!sw)
3308            {
3309                    warning("ui_seamless_restack_window: No information for window 0x%lx\n", id);
3310                    return;
3311            }
3312    
3313            if (behind)
3314            {
3315                    seamless_window *sw_behind;
3316                    Window wnds[2];
3317    
3318                    sw_behind = seamless_get_window_by_id(behind);
3319                    if (!sw_behind)
3320                    {
3321                            warning("ui_seamless_restack_window: No information for window 0x%lx\n",
3322                                    behind);
3323                            return;
3324                    }
3325    
3326                    wnds[1] = sw_behind->wnd;
3327                    wnds[0] = sw->wnd;
3328    
3329                    XRestackWindows(g_display, wnds, 2);
3330            }
3331            else
3332            {
3333                    XRaiseWindow(g_display, sw->wnd);
3334            }
3335    
3336            seamless_restack_window(sw, behind);
3337    }
3338    
3339  void  void
3340  ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags)  ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags)
3341  {  {
3342          seamless_window *sw;          seamless_window *sw;
3343    
3344            if (!g_seamless_active)
3345                    return;
3346    
3347          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3348          if (!sw)          if (!sw)
3349          {          {
# Line 3205  ui_seamless_setstate(unsigned long id, u Line 3362  ui_seamless_setstate(unsigned long id, u
3362  {  {
3363          seamless_window *sw;          seamless_window *sw;
3364    
3365            if (!g_seamless_active)
3366                    return;
3367    
3368          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3369          if (!sw)          if (!sw)
3370          {          {
# Line 3212  ui_seamless_setstate(unsigned long id, u Line 3372  ui_seamless_setstate(unsigned long id, u
3372                  return;                  return;
3373          }          }
3374    
         if (sw->state == SEAMLESSRDP_NOTYETMAPPED)  
         {  
                 XMapWindow(g_display, sw->wnd);  
         }  
   
         sw->state = state;  
   
3375          switch (state)          switch (state)
3376          {          {
3377                  case SEAMLESSRDP_NORMAL:                  case SEAMLESSRDP_NORMAL:
3378                  case SEAMLESSRDP_MAXIMIZED:                  case SEAMLESSRDP_MAXIMIZED:
3379                          ewmh_change_state(sw->wnd, state);                          ewmh_change_state(sw->wnd, state);
3380                            XMapWindow(g_display, sw->wnd);
3381                          break;                          break;
3382                  case SEAMLESSRDP_MINIMIZED:                  case SEAMLESSRDP_MINIMIZED:
3383                          /* 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 3231  ui_seamless_setstate(unsigned long id, u Line 3385  ui_seamless_setstate(unsigned long id, u
3385                             _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
3386                             such as minimization, rather than an independent state." Besides,                             such as minimization, rather than an independent state." Besides,
3387                             XIconifyWindow is easier. */                             XIconifyWindow is easier. */
3388                          XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));                          if (sw->state == SEAMLESSRDP_NOTYETMAPPED)
3389                            {
3390                                    XWMHints *hints;
3391                                    hints = XAllocWMHints();
3392                                    hints->flags = StateHint;
3393                                    hints->initial_state = IconicState;
3394                                    XSetWMHints(g_display, sw->wnd, hints);
3395                                    XFree(hints);
3396                                    XMapWindow(g_display, sw->wnd);
3397                            }
3398                            else
3399                                    XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));
3400                          break;                          break;
3401                  default:                  default:
3402                          warning("SeamlessRDP: Invalid state %d\n", state);                          warning("SeamlessRDP: Invalid state %d\n", state);
3403                          break;                          break;
3404          }          }
3405    
3406            /* Handle popups without parents through some ewm hints */
3407            if ((sw->state == SEAMLESSRDP_NOTYETMAPPED) && (sw->parent == 0xFFFFFFFF))
3408                    ewmh_set_window_popup(sw->wnd);
3409    
3410            sw->state = state;
3411  }  }
3412    
3413    
3414  void  void
3415  ui_seamless_syncbegin(unsigned long flags)  ui_seamless_syncbegin(unsigned long flags)
3416  {  {
3417            if (!g_seamless_active)
3418                    return;
3419    
3420          /* Destroy all seamless windows */          /* Destroy all seamless windows */
3421          while (g_seamless_windows)          while (g_seamless_windows)
3422          {          {

Legend:
Removed from v.1140  
changed lines
  Added in v.1155

  ViewVC Help
Powered by ViewVC 1.1.26