display-private.h

Go to the documentation of this file.
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
00002 
00003 /* Metacity X display handler */
00004 
00005 /* 
00006  * Copyright (C) 2001 Havoc Pennington
00007  * Copyright (C) 2002 Red Hat, Inc.
00008  * Copyright (C) 2003 Rob Adams
00009  * Copyright (C) 2004-2006 Elijah Newren
00010  * 
00011  * This program is free software; you can redistribute it and/or
00012  * modify it under the terms of the GNU General Public License as
00013  * published by the Free Software Foundation; either version 2 of the
00014  * License, or (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful, but
00017  * WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019  * General Public License for more details.
00020  * 
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software
00023  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00024  * 02111-1307, USA.
00025  */
00026 
00027 #ifndef META_DISPLAY_PRIVATE_H
00028 #define META_DISPLAY_PRIVATE_H
00029 
00030 #ifndef PACKAGE
00031 #error "config.h not included"
00032 #endif
00033 
00034 #include <glib.h>
00035 #include <X11/Xlib.h>
00036 #include "eventqueue.h"
00037 #include "common.h"
00038 #include "boxes.h"
00039 #include "display.h"
00040 
00041 #ifdef HAVE_STARTUP_NOTIFICATION
00042 #include <libsn/sn.h>
00043 #endif
00044 
00045 #ifdef HAVE_XSYNC
00046 #include <X11/extensions/sync.h>
00047 #endif
00048 
00049 typedef struct _MetaKeyBinding MetaKeyBinding;
00050 typedef struct _MetaStack      MetaStack;
00051 typedef struct _MetaUISlave    MetaUISlave;
00052 typedef struct _MetaWorkspace  MetaWorkspace;
00053 
00054 typedef struct _MetaWindowPropHooks MetaWindowPropHooks;
00055 typedef struct _MetaGroupPropHooks  MetaGroupPropHooks;
00056 
00057 typedef struct MetaEdgeResistanceData MetaEdgeResistanceData;
00058 
00059 typedef void (* MetaWindowPingFunc) (MetaDisplay *display,
00060                                      Window       xwindow,
00061                                      guint32      timestamp,
00062                                      gpointer     user_data);
00063 
00064 
00065 #define _NET_WM_STATE_REMOVE        0    /* remove/unset property */
00066 #define _NET_WM_STATE_ADD           1    /* add/set property */
00067 #define _NET_WM_STATE_TOGGLE        2    /* toggle property  */
00068 
00069 /* This is basically a bogus number, just has to be large enough
00070  * to handle the expected case of the alt+tab operation, where
00071  * we want to ignore serials from UnmapNotify on the tab popup,
00072  * and the LeaveNotify/EnterNotify from the pointer ungrab
00073  */
00074 #define N_IGNORED_SERIALS           4
00075 
00076 struct _MetaDisplay
00077 {
00078   char *name;
00079   Display *xdisplay;
00080 
00081   Window leader_window;
00082   Window timestamp_pinging_window;
00083   
00084   /* Pull in all the names of atoms as fields; we will intern them when the
00085    * class is constructed.
00086    */
00087 #define item(x)  Atom atom_##x;
00088 #include "atomnames.h"
00089 #undef item
00090 
00091   /* This is the actual window from focus events,
00092    * not the one we last set
00093    */
00094   MetaWindow *focus_window;
00095 
00096   /* window we are expecting a FocusIn event for or the current focus
00097    * window if we are not expecting any FocusIn/FocusOut events; not
00098    * perfect because applications can call XSetInputFocus directly.
00099    * (It could also be messed up if a timestamp later than current
00100    * time is sent to meta_display_set_input_focus_window, though that
00101    * would be a programming error).  See bug 154598 for more info.
00102    */
00103   MetaWindow *expected_focus_window;
00104 
00105   /* last timestamp passed to XSetInputFocus */
00106   guint32 last_focus_time;
00107 
00108   /* last user interaction time in any app */
00109   guint32 last_user_time;
00110 
00111   /* whether we're using mousenav (only relevant for sloppy&mouse focus modes;
00112    * !mouse_mode means "keynav mode")
00113    */
00114   guint mouse_mode : 1;
00115 
00116   /* Helper var used when focus_new_windows setting is 'strict'; only
00117    * relevant in 'strict' mode and if the focus window is a terminal.
00118    * In that case, we don't allow new windows to take focus away from
00119    * a terminal, but if the user explicitly did something that should
00120    * allow a different window to gain focus (e.g. global keybinding or
00121    * clicking on a dock), then we will allow the transfer.
00122    */
00123   guint allow_terminal_deactivation : 1;
00124 
00125   guint static_gravity_works : 1;
00126   
00127   /*< private-ish >*/
00128   guint error_trap_synced_at_last_pop : 1;
00129   MetaEventQueue *events;
00130   GSList *screens;
00131   MetaScreen *active_screen;
00132   GHashTable *window_ids;
00133   int error_traps;
00134   int (* error_trap_handler) (Display     *display,
00135                               XErrorEvent *error);  
00136   int server_grab_count;
00137 
00138   /* serials of leave/unmap events that may
00139    * correspond to an enter event we should
00140    * ignore
00141    */
00142   unsigned long ignored_serials[N_IGNORED_SERIALS];
00143   Window ungrab_should_not_cause_focus_window;
00144   
00145   guint32 current_time;
00146 
00147   /* Pings which we're waiting for a reply from */
00148   GSList     *pending_pings;
00149 
00150   /* Pending autoraise */
00151   guint       autoraise_timeout_id;
00152   MetaWindow* autoraise_window;
00153 
00154   /* Alt+click button grabs */
00155   unsigned int window_grab_modifiers;
00156   
00157   /* current window operation */
00158   MetaGrabOp  grab_op;
00159   MetaScreen *grab_screen;
00160   MetaWindow *grab_window;
00161   Window      grab_xwindow;
00162   int         grab_button;
00163   int         grab_anchor_root_x;
00164   int         grab_anchor_root_y;
00165   MetaRectangle grab_anchor_window_pos;
00166   int         grab_latest_motion_x;
00167   int         grab_latest_motion_y;
00168   gulong      grab_mask;
00169   guint       grab_have_pointer : 1;
00170   guint       grab_have_keyboard : 1;
00171   guint       grab_wireframe_active : 1;
00172   guint       grab_was_cancelled : 1;    /* Only used in wireframe mode */
00173   guint       grab_frame_action : 1;
00174   MetaRectangle grab_wireframe_rect;
00175   MetaRectangle grab_wireframe_last_xor_rect;
00176   MetaRectangle grab_initial_window_pos;
00177   int         grab_initial_x, grab_initial_y;  /* These are only relevant for */
00178   gboolean    grab_threshold_movement_reached; /* raise_on_click == FALSE.    */
00179   MetaResizePopup *grab_resize_popup;
00180   GTimeVal    grab_last_moveresize_time;
00181   guint32     grab_motion_notify_time;
00182   int         grab_wireframe_last_display_width;
00183   int         grab_wireframe_last_display_height;
00184   GList*      grab_old_window_stacking;
00185   MetaEdgeResistanceData *grab_edge_resistance_data;
00186   unsigned int grab_last_user_action_was_snap;
00187 
00188   /* we use property updates as sentinels for certain window focus events
00189    * to avoid some race conditions on EnterNotify events
00190    */
00191   int         sentinel_counter;
00192 
00193 #ifdef HAVE_XKB
00194   int         xkb_base_event_type;
00195   guint32     last_bell_time;
00196 #endif
00197 #ifdef HAVE_XSYNC
00198   /* alarm monitoring client's _NET_WM_SYNC_REQUEST_COUNTER */
00199   XSyncAlarm  grab_sync_request_alarm;
00200 #endif
00201   int         grab_resize_timeout_id;
00202 
00203   /* Keybindings stuff */
00204   MetaKeyBinding *screen_bindings;
00205   int             n_screen_bindings;
00206   MetaKeyBinding *window_bindings;
00207   int             n_window_bindings;
00208   int             min_keycode;
00209   int             max_keycode;
00210   KeySym *keymap;
00211   int keysyms_per_keycode;
00212   XModifierKeymap *modmap;
00213   unsigned int ignored_modifier_mask;
00214   unsigned int num_lock_mask;
00215   unsigned int scroll_lock_mask;
00216   unsigned int hyper_mask;
00217   unsigned int super_mask;
00218   unsigned int meta_mask;
00219   
00220   /* Xinerama cache */
00221   unsigned int xinerama_cache_invalidated : 1;
00222 
00223   /* Opening the display */
00224   unsigned int display_opening : 1;
00225 
00226   /* Closing down the display */
00227   int closing;
00228 
00229   /* Managed by group.c */
00230   GHashTable *groups_by_leader;
00231 
00232   /* currently-active window menu if any */
00233   MetaWindowMenu *window_menu;
00234   MetaWindow *window_with_menu;
00235 
00236   /* Managed by window-props.c */
00237   MetaWindowPropHooks *prop_hooks;
00238 
00239   /* Managed by group-props.c */
00240   MetaGroupPropHooks *group_prop_hooks;
00241 
00242   /* Managed by compositor.c */
00243   MetaCompositor *compositor;
00244   
00245 #ifdef HAVE_STARTUP_NOTIFICATION
00246   SnDisplay *sn_display;
00247 #endif
00248 #ifdef HAVE_XSYNC
00249   int xsync_event_base;
00250   int xsync_error_base;
00251 #endif
00252 #ifdef HAVE_SHAPE
00253   int shape_event_base;
00254   int shape_error_base;
00255 #endif
00256 #ifdef HAVE_RENDER
00257   int render_event_base;
00258   int render_error_base;
00259 #endif
00260 #ifdef HAVE_COMPOSITE_EXTENSIONS
00261   int composite_event_base;
00262   int composite_error_base;
00263   int composite_major_version;
00264   int composite_minor_version;
00265   int damage_event_base;
00266   int damage_error_base;
00267   int xfixes_event_base;
00268   int xfixes_error_base;
00269 #endif
00270 #ifdef HAVE_XSYNC
00271   unsigned int have_xsync : 1;
00272 #define META_DISPLAY_HAS_XSYNC(display) ((display)->have_xsync)
00273 #else
00274 #define META_DISPLAY_HAS_XSYNC(display) FALSE
00275 #endif
00276 #ifdef HAVE_SHAPE
00277   unsigned int have_shape : 1;
00278 #define META_DISPLAY_HAS_SHAPE(display) ((display)->have_shape)
00279 #else
00280 #define META_DISPLAY_HAS_SHAPE(display) FALSE
00281 #endif
00282 #ifdef HAVE_RENDER
00283   unsigned int have_render : 1;
00284 #define META_DISPLAY_HAS_RENDER(display) ((display)->have_render)
00285 #else
00286 #define META_DISPLAY_HAS_RENDER(display) FALSE
00287 #endif
00288 #ifdef HAVE_COMPOSITE_EXTENSIONS
00289   unsigned int have_composite : 1;
00290   unsigned int have_damage : 1;
00291   unsigned int have_xfixes : 1;
00292 #define META_DISPLAY_HAS_COMPOSITE(display) ((display)->have_composite)
00293 #define META_DISPLAY_HAS_DAMAGE(display) ((display)->have_damage)
00294 #define META_DISPLAY_HAS_XFIXES(display) ((display)->have_xfixes)
00295 #else
00296 #define META_DISPLAY_HAS_COMPOSITE(display) FALSE
00297 #define META_DISPLAY_HAS_DAMAGE(display) FALSE
00298 #define META_DISPLAY_HAS_XFIXES(display) FALSE
00299 #endif
00300 };
00301 
00302 /* Xserver time can wraparound, thus comparing two timestamps needs to take
00303  * this into account.  Here's a little macro to help out.  If no wraparound
00304  * has occurred, this is equivalent to
00305  *   time1 < time2
00306  * Of course, the rest of the ugliness of this macro comes from accounting
00307  * for the fact that wraparound can occur and the fact that a timestamp of
00308  * 0 must be special-cased since it means older than anything else. 
00309  *
00310  * Note that this is NOT an equivalent for time1 <= time2; if that's what
00311  * you need then you'll need to swap the order of the arguments and negate
00312  * the result.
00313  */
00314 #define XSERVER_TIME_IS_BEFORE_ASSUMING_REAL_TIMESTAMPS(time1, time2) \
00315   ( (( (time1) < (time2) ) && ( (time2) - (time1) < ((guint32)-1)/2 )) ||     \
00316     (( (time1) > (time2) ) && ( (time1) - (time2) > ((guint32)-1)/2 ))        \
00317   )
00318 #define XSERVER_TIME_IS_BEFORE(time1, time2)                          \
00319   ( (time1) == 0 ||                                                     \
00320     (XSERVER_TIME_IS_BEFORE_ASSUMING_REAL_TIMESTAMPS(time1, time2) && \
00321      (time2) != 0)                                                      \
00322   )
00323 
00324 gboolean      meta_display_open                (void);
00325 void          meta_display_close               (MetaDisplay *display,
00326                                                 guint32      timestamp);
00327 MetaScreen*   meta_display_screen_for_x_screen (MetaDisplay *display,
00328                                                 Screen      *screen);
00329 MetaScreen*   meta_display_screen_for_xwindow  (MetaDisplay *display,
00330                                                 Window       xindow);
00331 void          meta_display_grab                (MetaDisplay *display);
00332 void          meta_display_ungrab              (MetaDisplay *display);
00333 
00334 void          meta_display_unmanage_screen     (MetaDisplay *display,
00335                                                 MetaScreen  *screen,
00336                                                 guint32      timestamp);
00337 
00338 void          meta_display_unmanage_windows_for_screen (MetaDisplay *display,
00339                                                         MetaScreen  *screen,
00340                                                         guint32      timestamp);
00341 
00342 /* Utility function to compare the stacking of two windows */
00343 int           meta_display_stack_cmp           (const void *a,
00344                                                 const void *b);
00345 
00346 /* A given MetaWindow may have various X windows that "belong"
00347  * to it, such as the frame window.
00348  */
00349 MetaWindow* meta_display_lookup_x_window     (MetaDisplay *display,
00350                                               Window       xwindow);
00351 void        meta_display_register_x_window   (MetaDisplay *display,
00352                                               Window      *xwindowp,
00353                                               MetaWindow  *window);
00354 void        meta_display_unregister_x_window (MetaDisplay *display,
00355                                               Window       xwindow);
00356 /* Return whether the xwindow is a no focus window for any of the screens */
00357 gboolean    meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display,
00358                                                        Window xwindow);
00359 
00360 GSList*     meta_display_list_windows        (MetaDisplay *display);
00361 
00362 MetaDisplay* meta_display_for_x_display  (Display     *xdisplay);
00363 MetaDisplay* meta_get_display            (void);
00364 
00365 Cursor         meta_display_create_x_cursor (MetaDisplay *display,
00366                                              MetaCursor   cursor);
00367 
00368 void     meta_display_set_grab_op_cursor (MetaDisplay *display,
00369                                           MetaScreen  *screen,
00370                                           MetaGrabOp   op,
00371                                           gboolean     change_pointer,
00372                                           Window       grab_xwindow,
00373                                           guint32      timestamp);
00374 
00375 gboolean meta_display_begin_grab_op (MetaDisplay *display,
00376                                      MetaScreen  *screen,
00377                                      MetaWindow  *window,
00378                                      MetaGrabOp   op,
00379                                      gboolean     pointer_already_grabbed,
00380                                      gboolean     frame_action,
00381                                      int          button,
00382                                      gulong       modmask,
00383                                      guint32      timestamp,
00384                                      int          root_x,
00385                                      int          root_y);
00386 void     meta_display_end_grab_op   (MetaDisplay *display,
00387                                      guint32      timestamp);
00388 
00389 void    meta_display_check_threshold_reached (MetaDisplay *display,
00390                                               int          x,
00391                                               int          y);
00392 void     meta_display_grab_window_buttons    (MetaDisplay *display,
00393                                               Window       xwindow);
00394 void     meta_display_ungrab_window_buttons  (MetaDisplay *display,
00395                                               Window       xwindow);
00396 
00397 void meta_display_grab_focus_window_button   (MetaDisplay *display,
00398                                               MetaWindow  *window);
00399 void meta_display_ungrab_focus_window_button (MetaDisplay *display,
00400                                               MetaWindow  *window);
00401 
00402 /* Next two functions are defined in edge-resistance.c */
00403 void meta_display_compute_resistance_and_snapping_edges (MetaDisplay *display);
00404 void meta_display_cleanup_edges                         (MetaDisplay *display);
00405 
00406 /* make a request to ensure the event serial has changed */
00407 void     meta_display_increment_event_serial (MetaDisplay *display);
00408 
00409 void     meta_display_update_active_window_hint (MetaDisplay *display);
00410 
00411 guint32  meta_display_get_current_time           (MetaDisplay *display);
00412 guint32  meta_display_get_current_time_roundtrip (MetaDisplay *display);
00413 
00414 /* utility goo */
00415 const char* meta_event_mode_to_string   (int m);
00416 const char* meta_event_detail_to_string (int d);
00417 
00418 void meta_display_queue_retheme_all_windows (MetaDisplay *display);
00419 void meta_display_retheme_all (void);
00420 
00421 void meta_display_set_cursor_theme (const char *theme, 
00422                                     int         size);
00423 
00424 void meta_display_ping_window      (MetaDisplay        *display,
00425                                     MetaWindow         *window,
00426                                     guint32             timestamp,
00427                                     MetaWindowPingFunc  ping_reply_func,
00428                                     MetaWindowPingFunc  ping_timeout_func,
00429                                     void               *user_data);
00430 gboolean meta_display_window_has_pending_pings (MetaDisplay        *display,
00431                                                 MetaWindow         *window);
00432 
00433 typedef enum
00434 {
00435   META_TAB_LIST_NORMAL,
00436   META_TAB_LIST_DOCKS,
00437   META_TAB_LIST_GROUP
00438 } MetaTabList;
00439 
00440 typedef enum
00441 {
00442   META_TAB_SHOW_ICON,      /* Alt-Tab mode */
00443   META_TAB_SHOW_INSTANTLY  /* Alt-Esc mode */
00444 } MetaTabShowType;
00445 
00446 GList* meta_display_get_tab_list (MetaDisplay   *display,
00447                                   MetaTabList    type,
00448                                   MetaScreen    *screen,
00449                                   MetaWorkspace *workspace);
00450 
00451 MetaWindow* meta_display_get_tab_next (MetaDisplay   *display,
00452                                        MetaTabList    type,
00453                                        MetaScreen    *screen,
00454                                        MetaWorkspace *workspace,
00455                                        MetaWindow    *window,
00456                                        gboolean       backward);
00457 
00458 MetaWindow* meta_display_get_tab_current (MetaDisplay   *display,
00459                                           MetaTabList    type,
00460                                           MetaScreen    *screen,
00461                                           MetaWorkspace *workspace);
00462 
00463 int meta_resize_gravity_from_grab_op (MetaGrabOp op);
00464 
00465 gboolean meta_grab_op_is_moving   (MetaGrabOp op);
00466 gboolean meta_grab_op_is_resizing (MetaGrabOp op);
00467 
00468 void meta_display_devirtualize_modifiers (MetaDisplay        *display,
00469                                           MetaVirtualModifier modifiers,
00470                                           unsigned int       *mask);
00471 
00472 void meta_display_increment_focus_sentinel (MetaDisplay *display);
00473 void meta_display_decrement_focus_sentinel (MetaDisplay *display);
00474 gboolean meta_display_focus_sentinel_clear (MetaDisplay *display);
00475 
00476 /* meta_display_set_input_focus_window is like XSetInputFocus, except
00477  * that (a) it can't detect timestamps later than the current time,
00478  * since Metacity isn't part of the XServer, and thus gives erroneous
00479  * behavior in this circumstance (so don't do it), (b) it uses
00480  * display->last_focus_time since we don't have access to the true
00481  * Xserver one, (c) it makes use of display->user_time since checking
00482  * whether a window should be allowed to be focused should depend
00483  * on user_time events (see bug 167358, comment 15 in particular)
00484  */
00485 void meta_display_set_input_focus_window   (MetaDisplay *display, 
00486                                             MetaWindow  *window,
00487                                             gboolean     focus_frame,
00488                                             guint32      timestamp);
00489 
00490 /* meta_display_focus_the_no_focus_window is called when the
00491  * designated no_focus_window should be focused, but is otherwise the
00492  * same as meta_display_set_input_focus_window
00493  */
00494 void meta_display_focus_the_no_focus_window (MetaDisplay *display, 
00495                                              MetaScreen  *screen,
00496                                              guint32      timestamp);
00497 
00498 void meta_display_queue_autoraise_callback  (MetaDisplay *display,
00499                                              MetaWindow  *window);
00500 void meta_display_remove_autoraise_callback (MetaDisplay *display);
00501 
00502 #endif

Generated on Sat Aug 23 22:04:16 2008 for metacity by  doxygen 1.5.5