/[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 1103 by astrand, Fri Mar 10 13:32:18 2006 UTC revision 1143 by ossman_, Thu Mar 16 08:41:53 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            XWMHints *hints;
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 _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;
# Line 83  static XModifierKeymap *g_mod_map; Line 87  static XModifierKeymap *g_mod_map;
87  static Cursor g_current_cursor;  static Cursor g_current_cursor;
88  static HCURSOR g_null_cursor = NULL;  static HCURSOR g_null_cursor = NULL;
89  static Atom g_protocol_atom, g_kill_atom;  static Atom g_protocol_atom, g_kill_atom;
90    extern Atom g_net_wm_state_atom;
91    extern Atom g_net_wm_desktop_atom;
92  static BOOL g_focused;  static BOOL g_focused;
93  static BOOL g_mouse_in_wnd;  static BOOL g_mouse_in_wnd;
94  /* Indicates that:  /* Indicates that:
# Line 289  seamless_remove_window(seamless_window * Line 295  seamless_remove_window(seamless_window *
295                  if (sw == win)                  if (sw == win)
296                  {                  {
297                          *prevnext = sw->next;                          *prevnext = sw->next;
298                            XFree(sw->hints);
299                          xfree(sw);                          xfree(sw);
300                          return;                          return;
301                  }                  }
# Line 298  seamless_remove_window(seamless_window * Line 305  seamless_remove_window(seamless_window *
305  }  }
306    
307    
308    /* Move all windows except wnd to new desktop */
309    static void
310    seamless_all_to_desktop(Window wnd, unsigned int desktop)
311    {
312            seamless_window *sw;
313            for (sw = g_seamless_windows; sw; sw = sw->next)
314            {
315                    if (sw->wnd == wnd)
316                            continue;
317                    if (sw->desktop != desktop)
318                    {
319                            ewmh_move_to_desktop(sw->wnd, desktop);
320                            sw->desktop = desktop;
321                    }
322            }
323    }
324    
325    
326  static void  static void
327  mwm_hide_decorations(Window wnd)  mwm_hide_decorations(Window wnd)
328  {  {
# Line 1396  ui_init(void) Line 1421  ui_init(void)
1421                  g_IM = XOpenIM(g_display, NULL, NULL, NULL);                  g_IM = XOpenIM(g_display, NULL, NULL, NULL);
1422    
1423          xclip_init();          xclip_init();
1424            ewmh_init();
1425          if (g_seamless_rdp)          if (g_seamless_rdp)
1426                  seamless_init();                  seamless_init();
1427    
# Line 1903  xwin_process_events(void) Line 1929  xwin_process_events(void)
1929                                                            xevent.xexpose.width,                                                            xevent.xexpose.width,
1930                                                            xevent.xexpose.height, xevent.xexpose.x,                                                            xevent.xexpose.height, xevent.xexpose.x,
1931                                                            xevent.xexpose.y);                                                            xevent.xexpose.y);
1932                                            else
1933                                            {
1934                                                    error("Expose for unknown window 0x%lx\n",
1935                                                          xevent.xexpose.window);
1936                                            }
1937                                  }                                  }
1938    
1939                                  break;                                  break;
# Line 1933  xwin_process_events(void) Line 1964  xwin_process_events(void)
1964                                  break;                                  break;
1965                          case PropertyNotify:                          case PropertyNotify:
1966                                  xclip_handle_PropertyNotify(&xevent.xproperty);                                  xclip_handle_PropertyNotify(&xevent.xproperty);
1967                                    if (xevent.xproperty.window == g_wnd)
1968                                            break;
1969                                    if (xevent.xproperty.window == DefaultRootWindow(g_display))
1970                                            break;
1971    
1972                                    /* seamless */
1973                                    sw = seamless_get_window_by_wnd(xevent.xproperty.window);
1974                                    if (!sw)
1975                                            break;
1976    
1977                                    if ((xevent.xproperty.atom == g_net_wm_state_atom)
1978                                        && (xevent.xproperty.state == PropertyNewValue))
1979                                    {
1980                                            sw->state = ewmh_get_window_state(sw->wnd);
1981                                            seamless_send_state(sw->id, sw->state, 0);
1982                                    }
1983    
1984                                    if ((xevent.xproperty.atom == g_net_wm_desktop_atom)
1985                                        && (xevent.xproperty.state == PropertyNewValue))
1986                                    {
1987                                            sw->desktop = ewmh_get_window_desktop(sw->wnd);
1988                                            seamless_all_to_desktop(sw->wnd, sw->desktop);
1989                                    }
1990    
1991                                  break;                                  break;
1992                          case MapNotify:                          case MapNotify:
1993                                  if (!g_seamless_rdp)                                  if (!g_seamless_rdp)
# Line 2992  ui_seamless_create_window(unsigned long Line 3047  ui_seamless_create_window(unsigned long
3047          Window wnd;          Window wnd;
3048          XSetWindowAttributes attribs;          XSetWindowAttributes attribs;
3049          XClassHint *classhints;          XClassHint *classhints;
3050            XSizeHints *sizehints;
3051          long input_mask;          long input_mask;
3052          seamless_window *sw, *sw_parent;          seamless_window *sw, *sw_parent;
3053    
3054          get_window_attribs(&attribs);          /* Ignore CREATEs for existing windows */
3055            sw = seamless_get_window_by_id(id);
3056            if (sw)
3057                    return;
3058    
3059            get_window_attribs(&attribs);
3060          attribs.override_redirect = False;          attribs.override_redirect = False;
3061    
3062          /* 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,  
3063                              InputOutput, g_visual,                              InputOutput, g_visual,
3064                              CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |                              CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
3065                              CWBorderPixel, &attribs);                              CWBorderPixel, &attribs);
3066    
3067          XStoreName(g_display, wnd, "rdesktop-seamless");          XStoreName(g_display, wnd, "SeamlessRDP");
3068            ewmh_set_wm_name(wnd, "SeamlessRDP");
3069    
3070          mwm_hide_decorations(wnd);          mwm_hide_decorations(wnd);
3071    
3072          classhints = XAllocClassHint();          classhints = XAllocClassHint();
3073          if (classhints != NULL)          if (classhints != NULL)
3074          {          {
3075                  classhints->res_name = classhints->res_class = "rdesktop";                  classhints->res_name = "rdesktop";
3076                    classhints->res_class = "SeamlessRDP";
3077                  XSetClassHint(g_display, wnd, classhints);                  XSetClassHint(g_display, wnd, classhints);
3078                  XFree(classhints);                  XFree(classhints);
3079          }          }
3080    
3081            /* WM_NORMAL_HINTS */
3082            sizehints = XAllocSizeHints();
3083            if (sizehints != NULL)
3084            {
3085                    sizehints->flags = USPosition;
3086                    XSetWMNormalHints(g_display, wnd, sizehints);
3087                    XFree(sizehints);
3088            }
3089    
3090          /* Set WM_TRANSIENT_FOR, if necessary */          /* Set WM_TRANSIENT_FOR, if necessary */
3091          if (parent)          if ((parent != 0x00000000) && (parent != 0xFFFFFFFF))
3092          {          {
3093                  sw_parent = seamless_get_window_by_id(parent);                  sw_parent = seamless_get_window_by_id(parent);
3094                  if (sw_parent)                  if (sw_parent)
# Line 3029  ui_seamless_create_window(unsigned long Line 3097  ui_seamless_create_window(unsigned long
3097                          warning("ui_seamless_create_window: No parent window 0x%lx\n", parent);                          warning("ui_seamless_create_window: No parent window 0x%lx\n", parent);
3098          }          }
3099    
3100    
3101          /* FIXME: Support for Input Context:s */          /* FIXME: Support for Input Context:s */
3102    
3103          get_input_mask(&input_mask);          get_input_mask(&input_mask);
3104            input_mask |= PropertyChangeMask;
3105    
3106          XSelectInput(g_display, wnd, input_mask);          XSelectInput(g_display, wnd, input_mask);
3107    
         XMapWindow(g_display, wnd);  
   
3108          /* handle the WM_DELETE_WINDOW protocol. FIXME: When killing a          /* handle the WM_DELETE_WINDOW protocol. FIXME: When killing a
3109             seamless window, we could try to close the window on the             seamless window, we could try to close the window on the
3110             serverside, instead of terminating rdesktop */             serverside, instead of terminating rdesktop */
# Line 3045  ui_seamless_create_window(unsigned long Line 3113  ui_seamless_create_window(unsigned long
3113          sw = malloc(sizeof(seamless_window));          sw = malloc(sizeof(seamless_window));
3114          sw->wnd = wnd;          sw->wnd = wnd;
3115          sw->id = id;          sw->id = id;
3116            sw->parent = parent;
3117            sw->hints = XAllocWMHints();
3118            sw->hints->flags = 0;
3119          sw->xoffset = 0;          sw->xoffset = 0;
3120          sw->yoffset = 0;          sw->yoffset = 0;
3121          sw->width = 0;          sw->width = 0;
3122          sw->height = 0;          sw->height = 0;
3123            sw->state = SEAMLESSRDP_NOTYETMAPPED;
3124            sw->desktop = 0;
3125          sw->next = g_seamless_windows;          sw->next = g_seamless_windows;
3126          g_seamless_windows = sw;          g_seamless_windows = sw;
3127  }  }
# Line 3058  void Line 3131  void
3131  ui_seamless_destroy_window(unsigned long id, unsigned long flags)  ui_seamless_destroy_window(unsigned long id, unsigned long flags)
3132  {  {
3133          seamless_window *sw;          seamless_window *sw;
         sw = seamless_get_window_by_id(id);  
3134    
3135            sw = seamless_get_window_by_id(id);
3136          if (!sw)          if (!sw)
3137          {          {
3138                  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 3077  ui_seamless_move_window(unsigned long id Line 3150  ui_seamless_move_window(unsigned long id
3150          seamless_window *sw;          seamless_window *sw;
3151    
3152          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
   
3153          if (!sw)          if (!sw)
3154          {          {
3155                  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 3099  ui_seamless_move_window(unsigned long id Line 3171  ui_seamless_move_window(unsigned long id
3171          sw->width = MIN(MIN(width, width + x), g_width - sw->xoffset);          sw->width = MIN(MIN(width, width + x), g_width - sw->xoffset);
3172          sw->height = MIN(MIN(height, height + y), g_height - sw->yoffset);          sw->height = MIN(MIN(height, height + y), g_height - sw->yoffset);
3173    
3174            /* If we move the window in a maximized state, then KDE won't
3175               accept restoration */
3176            switch (sw->state)
3177            {
3178                    case SEAMLESSRDP_MINIMIZED:
3179                    case SEAMLESSRDP_MAXIMIZED:
3180                            return;
3181            }
3182    
3183          /* FIXME: Perhaps use ewmh_net_moveresize_window instead */          /* FIXME: Perhaps use ewmh_net_moveresize_window instead */
3184          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);
3185  }  }
# Line 3110  ui_seamless_settitle(unsigned long id, c Line 3191  ui_seamless_settitle(unsigned long id, c
3191          seamless_window *sw;          seamless_window *sw;
3192    
3193          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3194            if (!sw)
3195            {
3196                    warning("ui_seamless_settitle: No information for window 0x%lx\n", id);
3197                    return;
3198            }
3199    
3200            /* FIXME: Might want to convert the name for non-EWMH WMs */
3201          XStoreName(g_display, sw->wnd, title);          XStoreName(g_display, sw->wnd, title);
3202            ewmh_set_wm_name(sw->wnd, title);
3203  }  }
3204    
3205    
# Line 3121  ui_seamless_setstate(unsigned long id, u Line 3209  ui_seamless_setstate(unsigned long id, u
3209          seamless_window *sw;          seamless_window *sw;
3210    
3211          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3212            if (!sw)
3213            {
3214                    warning("ui_seamless_setstate: No information for window 0x%lx\n", id);
3215                    return;
3216            }
3217    
3218          switch (state)          switch (state)
3219          {          {
3220                  case SEAMLESSRDP_NORMAL:                  case SEAMLESSRDP_NORMAL:
3221                  case SEAMLESSRDP_MAXIMIZED:                  case SEAMLESSRDP_MAXIMIZED:
3222                          /* FIXME */                          ewmh_change_state(sw->wnd, state);
3223                            XMapWindow(g_display, sw->wnd);
3224                          break;                          break;
3225                  case SEAMLESSRDP_MINIMIZED:                  case SEAMLESSRDP_MINIMIZED:
3226                          XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));                          /* EWMH says: "if an Application asks to toggle _NET_WM_STATE_HIDDEN
3227                               the Window Manager should probably just ignore the request, since
3228                               _NET_WM_STATE_HIDDEN is a function of some other aspect of the window
3229                               such as minimization, rather than an independent state." Besides,
3230                               XIconifyWindow is easier. */
3231                            if (sw->state == SEAMLESSRDP_NOTYETMAPPED)
3232                            {
3233                                    sw->hints->flags |= StateHint;
3234                                    sw->hints->initial_state = IconicState;
3235                                    XSetWMHints(g_display, sw->wnd, sw->hints);
3236                                    XMapWindow(g_display, sw->wnd);
3237                            }
3238                            else
3239                                    XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));
3240                          break;                          break;
3241                  default:                  default:
3242                          warning("SeamlessRDP: Invalid state %d\n", state);                          warning("SeamlessRDP: Invalid state %d\n", state);
3243                          break;                          break;
3244          }          }
3245    
3246            /* Handle popups without parents through some ewm hints */
3247            if ((sw->state == SEAMLESSRDP_NOTYETMAPPED) && (sw->parent == 0xFFFFFFFF))
3248                    ewmh_set_window_popup(sw->wnd);
3249    
3250            sw->state = state;
3251    }
3252    
3253    
3254    void
3255    ui_seamless_syncbegin(unsigned long flags)
3256    {
3257            /* Destroy all seamless windows */
3258            while (g_seamless_windows)
3259            {
3260                    XDestroyWindow(g_display, g_seamless_windows->wnd);
3261                    seamless_remove_window(g_seamless_windows);
3262            }
3263  }  }

Legend:
Removed from v.1103  
changed lines
  Added in v.1143

  ViewVC Help
Powered by ViewVC 1.1.26