ui.c

Go to the documentation of this file.
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
00002 
00003 /* Metacity interface for talking to GTK+ UI module */
00004 
00005 /* 
00006  * Copyright (C) 2002 Havoc Pennington
00007  * stock icon code Copyright (C) 2002 Jorn Baayen <jorn@nl.linux.org>
00008  * 
00009  * This program is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU General Public License as
00011  * published by the Free Software Foundation; either version 2 of the
00012  * License, or (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful, but
00015  * WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * General Public License for more details.
00018  * 
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00022  * 02111-1307, USA.
00023  */
00024 
00025 #include "prefs.h"
00026 #include "ui.h"
00027 #include "frames.h"
00028 #include "util.h"
00029 #include "menu.h"
00030 #include "core.h"
00031 #include "theme.h"
00032 
00033 #include "inlinepixbufs.h"
00034 
00035 #include <string.h>
00036 #include <stdlib.h>
00037 
00038 static void meta_stock_icons_init (void);
00039 static void meta_ui_accelerator_parse (const char      *accel,
00040                                        guint           *keysym,
00041                                        guint           *keycode,
00042                                        GdkModifierType *keymask);
00043 
00044 struct _MetaUI
00045 {
00046   Display *xdisplay;
00047   Screen *xscreen;
00048   MetaFrames *frames;
00049 };
00050 
00051 void
00052 meta_ui_init (int *argc, char ***argv)
00053 {
00054   if (!gtk_init_check (argc, argv))
00055     meta_fatal ("Unable to open X display %s\n", XDisplayName (NULL));
00056 
00057   meta_stock_icons_init ();
00058 }
00059 
00060 Display*
00061 meta_ui_get_display (void)
00062 {
00063   return gdk_display;
00064 }
00065 
00066 typedef struct _EventFunc EventFunc;
00067 
00068 struct _EventFunc
00069 {
00070   MetaEventFunc func;
00071   gpointer data;
00072 };
00073 
00074 static EventFunc *ef = NULL;
00075 
00076 static GdkFilterReturn
00077 filter_func (GdkXEvent *xevent,
00078              GdkEvent *event,
00079              gpointer data)
00080 {
00081   g_return_val_if_fail (ef != NULL, GDK_FILTER_CONTINUE);
00082 
00083   if ((* ef->func) (xevent, ef->data))
00084     return GDK_FILTER_REMOVE;
00085   else
00086     return GDK_FILTER_CONTINUE;
00087 }
00088 
00089 void
00090 meta_ui_add_event_func (Display       *xdisplay,
00091                         MetaEventFunc  func,
00092                         gpointer       data)
00093 {
00094   g_return_if_fail (ef == NULL);
00095 
00096   ef = g_new (EventFunc, 1);
00097   ef->func = func;
00098   ef->data = data;
00099 
00100   gdk_window_add_filter (NULL, filter_func, ef);
00101 }
00102 
00103 /* removal is by data due to proxy function */
00104 void
00105 meta_ui_remove_event_func (Display       *xdisplay,
00106                            MetaEventFunc  func,
00107                            gpointer       data)
00108 {
00109   g_return_if_fail (ef != NULL);
00110   
00111   gdk_window_remove_filter (NULL, filter_func, ef);
00112 
00113   g_free (ef);
00114   ef = NULL;
00115 }
00116 
00117 MetaUI*
00118 meta_ui_new (Display *xdisplay,
00119              Screen  *screen)
00120 {
00121   MetaUI *ui;
00122 
00123   ui = g_new (MetaUI, 1);
00124   ui->xdisplay = xdisplay;
00125   ui->xscreen = screen;
00126 
00127   g_assert (xdisplay == gdk_display);
00128   ui->frames = meta_frames_new (XScreenNumberOfScreen (screen));
00129   gtk_widget_realize (GTK_WIDGET (ui->frames));
00130   
00131   return ui;
00132 }
00133 
00134 void
00135 meta_ui_free (MetaUI *ui)
00136 {
00137   gtk_widget_destroy (GTK_WIDGET (ui->frames));
00138 
00139   g_free (ui);
00140 }
00141 
00142 void
00143 meta_ui_get_frame_geometry (MetaUI *ui,
00144                             Window frame_xwindow,
00145                             int *top_height, int *bottom_height,
00146                             int *left_width, int *right_width)
00147 {
00148   meta_frames_get_geometry (ui->frames, frame_xwindow,
00149                             top_height, bottom_height,
00150                             left_width, right_width);
00151 }
00152 
00153 Window
00154 meta_ui_create_frame_window (MetaUI *ui,
00155                              Display *xdisplay,
00156                              Visual *xvisual,
00157                              gint x,
00158                              gint y,
00159                              gint width,
00160                              gint height,
00161                              gint screen_no)
00162 {
00163   GdkDisplay *display = gdk_x11_lookup_xdisplay (xdisplay);
00164   GdkScreen *screen = gdk_display_get_screen (display, screen_no);
00165   GdkWindowAttr attrs;
00166   gint attributes_mask;
00167   GdkWindow *window;
00168   GdkVisual *visual;
00169   GdkColormap *cmap = gdk_screen_get_default_colormap (screen);
00170   
00171   /* Default depth/visual handles clients with weird visuals; they can
00172    * always be children of the root depth/visual obviously, but
00173    * e.g. DRI games can't be children of a parent that has the same
00174    * visual as the client.
00175    */
00176   if (!xvisual)
00177     visual = gdk_screen_get_system_visual (screen);
00178   else
00179     {
00180       visual = gdk_x11_screen_lookup_visual (screen,
00181                                              XVisualIDFromVisual (xvisual));
00182       cmap = gdk_colormap_new (visual, FALSE);
00183     }
00184 
00185   attrs.title = NULL;
00186 
00187   /* frame.c is going to replace the event mask immediately, but
00188    * we still have to set it here to let GDK know what it is.
00189    */
00190   attrs.event_mask =
00191     GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
00192     GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK |
00193     GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK;
00194   attrs.x = x;
00195   attrs.y = y;
00196   attrs.wclass = GDK_INPUT_OUTPUT;
00197   attrs.visual = visual;
00198   attrs.colormap = cmap;
00199   attrs.window_type = GDK_WINDOW_CHILD;
00200   attrs.cursor = NULL;
00201   attrs.wmclass_name = NULL;
00202   attrs.wmclass_class = NULL;
00203   attrs.override_redirect = FALSE;
00204 
00205   attrs.width  = width;
00206   attrs.height = height;
00207 
00208   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
00209 
00210   window =
00211     gdk_window_new (gdk_screen_get_root_window(screen),
00212                     &attrs, attributes_mask);
00213 
00214   gdk_window_resize (window, width, height);
00215   
00216   meta_frames_manage_window (ui->frames, GDK_WINDOW_XID (window), window);
00217 
00218   return GDK_WINDOW_XID (window);
00219 }
00220 
00221 void
00222 meta_ui_destroy_frame_window (MetaUI *ui,
00223                               Window  xwindow)
00224 {
00225   meta_frames_unmanage_window (ui->frames, xwindow);
00226 }
00227 
00228 void
00229 meta_ui_move_resize_frame (MetaUI *ui,
00230                            Window frame,
00231                            int x,
00232                            int y,
00233                            int width,
00234                            int height)
00235 {
00236   meta_frames_move_resize_frame (ui->frames, frame, x, y, width, height);
00237 }
00238 
00239 void
00240 meta_ui_map_frame   (MetaUI *ui,
00241                      Window  xwindow)
00242 {
00243   GdkWindow *window;
00244 
00245   window = gdk_xid_table_lookup (xwindow);
00246 
00247   if (window)
00248     gdk_window_show_unraised (window);
00249 }
00250 
00251 void
00252 meta_ui_unmap_frame (MetaUI *ui,
00253                      Window  xwindow)
00254 {
00255   GdkWindow *window;
00256 
00257   window = gdk_xid_table_lookup (xwindow);
00258 
00259   if (window)
00260     gdk_window_hide (window);
00261 }
00262 
00263 void
00264 meta_ui_unflicker_frame_bg (MetaUI *ui,
00265                             Window  xwindow,
00266                             int     target_width,
00267                             int     target_height)
00268 {
00269   meta_frames_unflicker_bg (ui->frames, xwindow,
00270                             target_width, target_height);
00271 }
00272 
00273 void
00274 meta_ui_repaint_frame (MetaUI *ui,
00275                        Window xwindow)
00276 {
00277   meta_frames_repaint_frame (ui->frames, xwindow);
00278 }
00279 
00280 void
00281 meta_ui_reset_frame_bg (MetaUI *ui,
00282                         Window xwindow)
00283 {
00284   meta_frames_reset_bg (ui->frames, xwindow);
00285 }
00286 
00287 void
00288 meta_ui_apply_frame_shape  (MetaUI  *ui,
00289                             Window   xwindow,
00290                             int      new_window_width,
00291                             int      new_window_height,
00292                             gboolean window_has_shape)
00293 {
00294   meta_frames_apply_shapes (ui->frames, xwindow,
00295                             new_window_width, new_window_height,
00296                             window_has_shape);
00297 }
00298 
00299 void
00300 meta_ui_queue_frame_draw (MetaUI *ui,
00301                           Window xwindow)
00302 {
00303   meta_frames_queue_draw (ui->frames, xwindow);
00304 }
00305 
00306 
00307 void
00308 meta_ui_set_frame_title (MetaUI     *ui,
00309                          Window      xwindow,
00310                          const char *title)
00311 {
00312   meta_frames_set_title (ui->frames, xwindow, title);
00313 }
00314 
00315 MetaWindowMenu*
00316 meta_ui_window_menu_new  (MetaUI             *ui,
00317                           Window              client_xwindow,
00318                           MetaMenuOp          ops,
00319                           MetaMenuOp          insensitive,
00320                           unsigned long       active_workspace,
00321                           int                 n_workspaces,
00322                           MetaWindowMenuFunc  func,
00323                           gpointer            data)
00324 {
00325   return meta_window_menu_new (ui->frames,
00326                                ops, insensitive,
00327                                client_xwindow,
00328                                active_workspace,
00329                                n_workspaces,
00330                                func, data);
00331 }
00332 
00333 void
00334 meta_ui_window_menu_popup (MetaWindowMenu     *menu,
00335                            int                 root_x,
00336                            int                 root_y,
00337                            int                 button,
00338                            guint32             timestamp)
00339 {
00340   meta_window_menu_popup (menu, root_x, root_y, button, timestamp);
00341 }
00342 
00343 void
00344 meta_ui_window_menu_free (MetaWindowMenu *menu)
00345 {
00346   meta_window_menu_free (menu);
00347 }
00348 
00349 struct _MetaImageWindow
00350 {
00351   GtkWidget *window;
00352   GdkPixmap *pixmap;
00353 };
00354 
00355 MetaImageWindow*
00356 meta_image_window_new (Display *xdisplay,
00357                        int      screen_number,
00358                        int      max_width,
00359                        int      max_height)
00360 {
00361   MetaImageWindow *iw;
00362   GdkDisplay *gdisplay;
00363   GdkScreen *gscreen;
00364     
00365   iw = g_new (MetaImageWindow, 1);
00366   iw->window = gtk_window_new (GTK_WINDOW_POPUP);
00367     
00368   gdisplay = gdk_x11_lookup_xdisplay (xdisplay);
00369   gscreen = gdk_display_get_screen (gdisplay, screen_number);
00370   
00371   gtk_window_set_screen (GTK_WINDOW (iw->window), gscreen);
00372  
00373   gtk_widget_realize (iw->window);
00374   iw->pixmap = gdk_pixmap_new (iw->window->window,
00375                                max_width, max_height,
00376                                -1);
00377   
00378   gtk_widget_set_size_request (iw->window, 1, 1);
00379   gtk_widget_set_double_buffered (iw->window, FALSE);
00380   gtk_widget_set_app_paintable (iw->window, TRUE);
00381   
00382   return iw;
00383 }
00384 
00385 void
00386 meta_image_window_free (MetaImageWindow *iw)
00387 {
00388   gtk_widget_destroy (iw->window);
00389   g_object_unref (G_OBJECT (iw->pixmap));
00390   g_free (iw);
00391 }
00392 
00393 void
00394 meta_image_window_set_showing  (MetaImageWindow *iw,
00395                                 gboolean         showing)
00396 {
00397   if (showing)
00398     gtk_widget_show_all (iw->window);
00399   else
00400     {
00401       gtk_widget_hide (iw->window);
00402       meta_core_increment_event_serial (gdk_display);
00403     }
00404 }
00405 
00406 void
00407 meta_image_window_set (MetaImageWindow *iw,
00408                        GdkPixbuf       *pixbuf,
00409                        int              x,
00410                        int              y)
00411 {
00412   /* We use a back pixmap to avoid having to handle exposes, because
00413    * it's really too slow for large clients being minimized, etc.
00414    * and this way flicker is genuinely zero.
00415    */
00416 
00417   gdk_draw_pixbuf (iw->pixmap,
00418                    iw->window->style->black_gc,
00419                    pixbuf,
00420                    0, 0,
00421                    0, 0,
00422                    gdk_pixbuf_get_width (pixbuf),
00423                    gdk_pixbuf_get_height (pixbuf),
00424                    GDK_RGB_DITHER_NORMAL,
00425                    0, 0);
00426 
00427   gdk_window_set_back_pixmap (iw->window->window,
00428                               iw->pixmap,
00429                               FALSE);
00430   
00431   gdk_window_move_resize (iw->window->window,
00432                           x, y,
00433                           gdk_pixbuf_get_width (pixbuf),
00434                           gdk_pixbuf_get_height (pixbuf));
00435 
00436   gdk_window_clear (iw->window->window);
00437 }
00438 
00439 static GdkColormap*
00440 get_cmap (GdkPixmap *pixmap)
00441 {
00442   GdkColormap *cmap;
00443 
00444   cmap = gdk_drawable_get_colormap (pixmap);
00445   if (cmap)
00446     g_object_ref (G_OBJECT (cmap));
00447 
00448   if (cmap == NULL)
00449     {
00450       if (gdk_drawable_get_depth (pixmap) == 1)
00451         {
00452           meta_verbose ("Using NULL colormap for snapshotting bitmap\n");
00453           cmap = NULL;
00454         }
00455       else
00456         {
00457           meta_verbose ("Using system cmap to snapshot pixmap\n");
00458           cmap = gdk_screen_get_system_colormap (gdk_drawable_get_screen (pixmap));
00459 
00460           g_object_ref (G_OBJECT (cmap));
00461         }
00462     }
00463 
00464   /* Be sure we aren't going to blow up due to visual mismatch */
00465   if (cmap &&
00466       (gdk_colormap_get_visual (cmap)->depth !=
00467        gdk_drawable_get_depth (pixmap)))
00468     {
00469       cmap = NULL;
00470       meta_verbose ("Switching back to NULL cmap because of depth mismatch\n");
00471     }
00472   
00473   return cmap;
00474 }
00475 
00476 GdkPixbuf*
00477 meta_gdk_pixbuf_get_from_window (GdkPixbuf   *dest,
00478                                  Window       xwindow,
00479                                  int          src_x,
00480                                  int          src_y,
00481                                  int          dest_x,
00482                                  int          dest_y,
00483                                  int          width,
00484                                  int          height)
00485 {
00486   GdkDrawable *drawable;
00487   GdkPixbuf *retval;
00488   GdkColormap *cmap;
00489   
00490   retval = NULL;
00491   
00492   drawable = gdk_xid_table_lookup (xwindow);
00493 
00494   if (drawable)
00495     g_object_ref (G_OBJECT (drawable));
00496   else
00497     drawable = gdk_window_foreign_new (xwindow);
00498 
00499   cmap = get_cmap (drawable);
00500   
00501   retval = gdk_pixbuf_get_from_drawable (dest,
00502                                          drawable,
00503                                          cmap,
00504                                          src_x, src_y,
00505                                          dest_x, dest_y,
00506                                          width, height);
00507 
00508   if (cmap)
00509     g_object_unref (G_OBJECT (cmap));
00510   g_object_unref (G_OBJECT (drawable));
00511 
00512   return retval;
00513 }
00514 
00515 GdkPixbuf*
00516 meta_gdk_pixbuf_get_from_pixmap (GdkPixbuf   *dest,
00517                                  Pixmap       xpixmap,
00518                                  int          src_x,
00519                                  int          src_y,
00520                                  int          dest_x,
00521                                  int          dest_y,
00522                                  int          width,
00523                                  int          height)
00524 {
00525   GdkDrawable *drawable;
00526   GdkPixbuf *retval;
00527   GdkColormap *cmap;
00528   
00529   retval = NULL;
00530   cmap = NULL;
00531   
00532   drawable = gdk_xid_table_lookup (xpixmap);
00533 
00534   if (drawable)
00535     g_object_ref (G_OBJECT (drawable));
00536   else
00537     drawable = gdk_pixmap_foreign_new (xpixmap);
00538 
00539   if (drawable)
00540     {
00541       cmap = get_cmap (drawable);
00542   
00543       retval = gdk_pixbuf_get_from_drawable (dest,
00544                                              drawable,
00545                                              cmap,
00546                                              src_x, src_y,
00547                                              dest_x, dest_y,
00548                                              width, height);
00549     }
00550   if (cmap)
00551     g_object_unref (G_OBJECT (cmap));
00552   if (drawable)
00553     g_object_unref (G_OBJECT (drawable));
00554 
00555   return retval;
00556 }
00557 
00558 void
00559 meta_ui_push_delay_exposes (MetaUI *ui)
00560 {
00561   meta_frames_push_delay_exposes (ui->frames);
00562 }
00563 
00564 void
00565 meta_ui_pop_delay_exposes  (MetaUI *ui)
00566 {
00567   meta_frames_pop_delay_exposes (ui->frames);
00568 }
00569 
00570 GdkPixbuf*
00571 meta_ui_get_default_window_icon (MetaUI *ui)
00572 {
00573   static GdkPixbuf *default_icon = NULL;
00574 
00575   if (default_icon == NULL)
00576     {
00577       GtkIconTheme *theme;
00578       gboolean icon_exists;
00579 
00580       theme = gtk_icon_theme_get_default ();
00581 
00582       icon_exists = gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME);
00583 
00584       if (icon_exists)
00585           default_icon = gtk_icon_theme_load_icon (theme,
00586                                                    META_DEFAULT_ICON_NAME,
00587                                                    META_ICON_WIDTH,
00588                                                    0,
00589                                                    NULL);
00590       else
00591           default_icon = gtk_icon_theme_load_icon (theme,
00592                                                    "gtk-missing-image",
00593                                                    META_ICON_WIDTH,
00594                                                    0,
00595                                                    NULL);
00596 
00597       g_assert (default_icon);
00598     }
00599 
00600   g_object_ref (G_OBJECT (default_icon));
00601   
00602   return default_icon;
00603 }
00604 
00605 GdkPixbuf*
00606 meta_ui_get_default_mini_icon (MetaUI *ui)
00607 {
00608   static GdkPixbuf *default_icon = NULL;
00609 
00610   if (default_icon == NULL)
00611     {
00612       GtkIconTheme *theme;
00613       gboolean icon_exists;
00614 
00615       theme = gtk_icon_theme_get_default ();
00616 
00617       icon_exists = gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME);
00618 
00619       if (icon_exists)
00620           default_icon = gtk_icon_theme_load_icon (theme,
00621                                                    META_DEFAULT_ICON_NAME,
00622                                                    META_MINI_ICON_WIDTH,
00623                                                    0,
00624                                                    NULL);
00625       else
00626           default_icon = gtk_icon_theme_load_icon (theme,
00627                                                    "gtk-missing-image",
00628                                                    META_MINI_ICON_WIDTH,
00629                                                    0,
00630                                                    NULL);
00631 
00632       g_assert (default_icon);
00633     }
00634 
00635   g_object_ref (G_OBJECT (default_icon));
00636   
00637   return default_icon;
00638 }
00639 
00640 gboolean
00641 meta_ui_window_should_not_cause_focus (Display *xdisplay,
00642                                        Window   xwindow)
00643 {
00644   GdkWindow *window;
00645 
00646   window = gdk_xid_table_lookup (xwindow);
00647 
00648   /* we shouldn't cause focus if we're an override redirect
00649    * toplevel which is not foreign
00650    */
00651   if (window && gdk_window_get_type (window) == GDK_WINDOW_TEMP)
00652     return TRUE;
00653   else
00654     return FALSE;
00655 }
00656 
00657 char*
00658 meta_text_property_to_utf8 (Display             *xdisplay,
00659                             const XTextProperty *prop)
00660 {
00661   char **list;
00662   int count;
00663   char *retval;
00664   
00665   list = NULL;
00666 
00667   count = gdk_text_property_to_utf8_list (gdk_x11_xatom_to_atom (prop->encoding),
00668                                           prop->format,
00669                                           prop->value,
00670                                           prop->nitems,
00671                                           &list);
00672 
00673   if (count == 0)
00674     return NULL;
00675 
00676   retval = list[0];
00677   list[0] = g_strdup (""); /* something to free */
00678   
00679   g_strfreev (list);
00680 
00681   return retval;
00682 }
00683 
00684 void
00685 meta_ui_theme_get_frame_borders (MetaUI *ui,
00686                                  MetaFrameType      type,
00687                                  MetaFrameFlags     flags,
00688                                  int               *top_height,
00689                                  int               *bottom_height,
00690                                  int               *left_width,
00691                                  int               *right_width)
00692 {
00693   int text_height;
00694   PangoContext *context;
00695   const PangoFontDescription *font_desc;
00696   GtkStyle *default_style;
00697 
00698   if (meta_ui_have_a_theme ())
00699     {
00700       context = gtk_widget_get_pango_context (GTK_WIDGET (ui->frames));
00701       font_desc = meta_prefs_get_titlebar_font ();
00702 
00703       if (!font_desc)
00704         {
00705           default_style = gtk_widget_get_default_style ();
00706           font_desc = default_style->font_desc;
00707         }
00708 
00709       text_height = meta_pango_font_desc_get_text_height (font_desc, context);
00710 
00711       meta_theme_get_frame_borders (meta_theme_get_current (),
00712                                     type, text_height, flags,
00713                                     top_height, bottom_height,
00714                                     left_width, right_width);
00715     }
00716   else
00717     {
00718       *top_height = *bottom_height = *left_width = *right_width = 0;
00719     }
00720 }
00721 
00722 void
00723 meta_ui_set_current_theme (const char *name,
00724                            gboolean    force_reload)
00725 {
00726   meta_theme_set_current (name, force_reload);
00727   meta_invalidate_default_icons ();
00728 }
00729 
00730 gboolean
00731 meta_ui_have_a_theme (void)
00732 {
00733   return meta_theme_get_current () != NULL;
00734 }
00735 
00736 static void
00737 meta_ui_accelerator_parse (const char      *accel,
00738                            guint           *keysym,
00739                            guint           *keycode,
00740                            GdkModifierType *keymask)
00741 {
00742   if (accel[0] == '0' && accel[1] == 'x')
00743     {
00744       *keysym = 0;
00745       *keycode = (guint) strtoul (accel, NULL, 16);
00746       *keymask = 0;
00747     }
00748   else
00749     gtk_accelerator_parse (accel, keysym, keymask);
00750 }
00751 
00752 gboolean
00753 meta_ui_parse_accelerator (const char          *accel,
00754                            unsigned int        *keysym,
00755                            unsigned int        *keycode,
00756                            MetaVirtualModifier *mask)
00757 {
00758   GdkModifierType gdk_mask = 0;
00759   guint gdk_sym = 0;
00760   guint gdk_code = 0;
00761   
00762   *keysym = 0;
00763   *keycode = 0;
00764   *mask = 0;
00765 
00766   if (strcmp (accel, "disabled") == 0)
00767     return TRUE;
00768   
00769   meta_ui_accelerator_parse (accel, &gdk_sym, &gdk_code, &gdk_mask);
00770   if (gdk_mask == 0 && gdk_sym == 0 && gdk_code == 0)
00771     return FALSE;
00772 
00773   if (gdk_sym == None && gdk_code == 0)
00774     return FALSE;
00775   
00776   if (gdk_mask & GDK_RELEASE_MASK) /* we don't allow this */
00777     return FALSE;
00778   
00779   *keysym = gdk_sym;
00780   *keycode = gdk_code;
00781 
00782   if (gdk_mask & GDK_SHIFT_MASK)
00783     *mask |= META_VIRTUAL_SHIFT_MASK;
00784   if (gdk_mask & GDK_CONTROL_MASK)
00785     *mask |= META_VIRTUAL_CONTROL_MASK;
00786   if (gdk_mask & GDK_MOD1_MASK)
00787     *mask |= META_VIRTUAL_ALT_MASK;
00788   if (gdk_mask & GDK_MOD2_MASK)
00789     *mask |= META_VIRTUAL_MOD2_MASK;
00790   if (gdk_mask & GDK_MOD3_MASK)
00791     *mask |= META_VIRTUAL_MOD3_MASK;
00792   if (gdk_mask & GDK_MOD4_MASK)
00793     *mask |= META_VIRTUAL_MOD4_MASK;
00794   if (gdk_mask & GDK_MOD5_MASK)
00795     *mask |= META_VIRTUAL_MOD5_MASK;
00796   if (gdk_mask & GDK_SUPER_MASK)
00797     *mask |= META_VIRTUAL_SUPER_MASK;
00798   if (gdk_mask & GDK_HYPER_MASK)
00799     *mask |= META_VIRTUAL_HYPER_MASK;
00800   if (gdk_mask & GDK_META_MASK)
00801     *mask |= META_VIRTUAL_META_MASK;
00802   
00803   return TRUE;
00804 }
00805 
00806 /* Caller responsible for freeing return string of meta_ui_accelerator_name! */
00807 gchar*
00808 meta_ui_accelerator_name  (unsigned int        keysym,
00809                            MetaVirtualModifier mask)
00810 {
00811   GdkModifierType mods = 0;
00812         
00813   if (keysym == 0 && mask == 0)
00814     {
00815       return g_strdup ("disabled");
00816     }
00817 
00818   if (mask & META_VIRTUAL_SHIFT_MASK)
00819     mods |= GDK_SHIFT_MASK;
00820   if (mask & META_VIRTUAL_CONTROL_MASK)
00821     mods |= GDK_CONTROL_MASK;
00822   if (mask & META_VIRTUAL_ALT_MASK)
00823     mods |= GDK_MOD1_MASK;
00824   if (mask & META_VIRTUAL_MOD2_MASK)
00825     mods |= GDK_MOD2_MASK;
00826   if (mask & META_VIRTUAL_MOD3_MASK)
00827     mods |= GDK_MOD3_MASK;
00828   if (mask & META_VIRTUAL_MOD4_MASK)
00829     mods |= GDK_MOD4_MASK;
00830   if (mask & META_VIRTUAL_MOD5_MASK)
00831     mods |= GDK_MOD5_MASK;
00832   if (mask & META_VIRTUAL_SUPER_MASK)
00833     mods |= GDK_SUPER_MASK;
00834   if (mask & META_VIRTUAL_HYPER_MASK)
00835     mods |= GDK_HYPER_MASK;
00836   if (mask & META_VIRTUAL_META_MASK)
00837     mods |= GDK_META_MASK;
00838 
00839   return gtk_accelerator_name (keysym, mods);
00840 
00841 }
00842 
00843 gboolean
00844 meta_ui_parse_modifier (const char          *accel,
00845                         MetaVirtualModifier *mask)
00846 {
00847   GdkModifierType gdk_mask = 0;
00848   guint gdk_sym = 0;
00849   guint gdk_code = 0;
00850   
00851   *mask = 0;
00852 
00853   if (strcmp (accel, "disabled") == 0)
00854     return TRUE;
00855   
00856   meta_ui_accelerator_parse (accel, &gdk_sym, &gdk_code, &gdk_mask);
00857   if (gdk_mask == 0 && gdk_sym == 0 && gdk_code == 0)
00858     return FALSE;
00859 
00860   if (gdk_sym != None || gdk_code != 0)
00861     return FALSE;
00862   
00863   if (gdk_mask & GDK_RELEASE_MASK) /* we don't allow this */
00864     return FALSE;
00865 
00866   if (gdk_mask & GDK_SHIFT_MASK)
00867     *mask |= META_VIRTUAL_SHIFT_MASK;
00868   if (gdk_mask & GDK_CONTROL_MASK)
00869     *mask |= META_VIRTUAL_CONTROL_MASK;
00870   if (gdk_mask & GDK_MOD1_MASK)
00871     *mask |= META_VIRTUAL_ALT_MASK;
00872   if (gdk_mask & GDK_MOD2_MASK)
00873     *mask |= META_VIRTUAL_MOD2_MASK;
00874   if (gdk_mask & GDK_MOD3_MASK)
00875     *mask |= META_VIRTUAL_MOD3_MASK;
00876   if (gdk_mask & GDK_MOD4_MASK)
00877     *mask |= META_VIRTUAL_MOD4_MASK;
00878   if (gdk_mask & GDK_MOD5_MASK)
00879     *mask |= META_VIRTUAL_MOD5_MASK;
00880   if (gdk_mask & GDK_SUPER_MASK)
00881     *mask |= META_VIRTUAL_SUPER_MASK;
00882   if (gdk_mask & GDK_HYPER_MASK)
00883     *mask |= META_VIRTUAL_HYPER_MASK;
00884   if (gdk_mask & GDK_META_MASK)
00885     *mask |= META_VIRTUAL_META_MASK;
00886   
00887   return TRUE;
00888 }
00889 
00890 gboolean
00891 meta_ui_window_is_widget (MetaUI *ui,
00892                           Window  xwindow)
00893 {
00894   GdkWindow *window;
00895 
00896   window = gdk_xid_table_lookup (xwindow);
00897 
00898   if (window)
00899     {
00900       void *user_data = NULL;
00901       gdk_window_get_user_data (window, &user_data);
00902       return user_data != NULL && user_data != ui->frames;
00903     }
00904   else
00905     return FALSE;
00906 }
00907 
00908 /* stock icon code Copyright (C) 2002 Jorn Baayen <jorn@nl.linux.org> */
00909 typedef struct
00910 {
00911   char *stock_id;
00912   const guint8 *icon_data;
00913 } MetaStockIcon;
00914 
00915 static void
00916 meta_stock_icons_init (void)
00917 {
00918   GtkIconFactory *factory;
00919   int i;
00920 
00921   MetaStockIcon items[] =
00922   {
00923     { METACITY_STOCK_DELETE,   stock_delete_data   },
00924     { METACITY_STOCK_MINIMIZE, stock_minimize_data },
00925     { METACITY_STOCK_MAXIMIZE, stock_maximize_data }
00926   };
00927 
00928   factory = gtk_icon_factory_new ();
00929   gtk_icon_factory_add_default (factory);
00930 
00931   for (i = 0; i < (gint) G_N_ELEMENTS (items); i++)
00932     {
00933       GtkIconSet *icon_set;
00934       GdkPixbuf *pixbuf;
00935 
00936       pixbuf = gdk_pixbuf_new_from_inline (-1, items[i].icon_data,
00937                                            FALSE,
00938                                            NULL);
00939 
00940       icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
00941       gtk_icon_factory_add (factory, items[i].stock_id, icon_set);
00942       gtk_icon_set_unref (icon_set);
00943       
00944       g_object_unref (G_OBJECT (pixbuf));
00945     }
00946 
00947   g_object_unref (G_OBJECT (factory));
00948 }
00949 
00950 int
00951 meta_ui_get_drag_threshold (MetaUI *ui)
00952 {
00953   GtkSettings *settings;
00954   int threshold;
00955 
00956   settings = gtk_widget_get_settings (GTK_WIDGET (ui->frames));
00957 
00958   threshold = 8;
00959   g_object_get (G_OBJECT (settings), "gtk-dnd-drag-threshold", &threshold, NULL);
00960 
00961   return threshold;
00962 }
00963 
00964 MetaUIDirection
00965 meta_ui_get_direction (void)
00966 {
00967   if (gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL)
00968     return META_UI_DIRECTION_RTL;
00969 
00970   return META_UI_DIRECTION_LTR;
00971 }
00972 
00973 GdkPixbuf *
00974 meta_ui_get_pixbuf_from_pixmap (Pixmap   pmap)
00975 {
00976   GdkPixmap *gpmap;
00977   GdkScreen *screen;
00978   GdkPixbuf *pixbuf;
00979   GdkColormap *cmap;
00980   int width, height, depth;
00981 
00982   gpmap = gdk_pixmap_foreign_new (pmap);
00983   screen = gdk_drawable_get_screen (gpmap);
00984 
00985   gdk_drawable_get_size (GDK_DRAWABLE (gpmap), &width, &height);
00986   
00987   depth = gdk_drawable_get_depth (GDK_DRAWABLE (gpmap));
00988   if (depth <= 24)
00989     cmap = gdk_screen_get_rgb_colormap (screen);
00990   else
00991     cmap = gdk_screen_get_rgba_colormap (screen);
00992   
00993   pixbuf = gdk_pixbuf_get_from_drawable (NULL, gpmap, cmap, 0, 0, 0, 0,
00994                                          width, height);
00995 
00996   g_object_unref (gpmap);
00997 
00998   return pixbuf;
00999 }
01000   
01001 void
01002 meta_ui_get_fallback_icons (GdkPixbuf **fallback_icon_p,
01003                             GdkPixbuf **fallback_mini_icon_p)
01004 {
01005   MetaTheme *theme = meta_theme_get_current ();
01006 
01007   if (fallback_icon_p)
01008     *fallback_icon_p = theme->fallback_icon;
01009 
01010   if (fallback_mini_icon_p)
01011     *fallback_mini_icon_p = theme->fallback_mini_icon;  
01012 }

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