/[emacs]/emacs/src/gtkutil.c
ViewVC logotype

Diff of /emacs/src/gtkutil.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.35 by jhd, Sun Nov 2 16:47:32 2003 UTC revision 1.36 by jhd, Sun Nov 16 16:05:24 2003 UTC
# Line 36  Boston, MA 02111-1307, USA.  */ Line 36  Boston, MA 02111-1307, USA.  */
36  #include "coding.h"  #include "coding.h"
37  #include <gdk/gdkkeysyms.h>  #include <gdk/gdkkeysyms.h>
38    
39    
40  #define FRAME_TOTAL_PIXEL_HEIGHT(f) \  #define FRAME_TOTAL_PIXEL_HEIGHT(f) \
41    (FRAME_PIXEL_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f))    (FRAME_PIXEL_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f))
42    
43    
44    /***********************************************************************
45                          Display handling functions
46     ***********************************************************************/
47    
48    #ifdef HAVE_GTK_MULTIDISPLAY
49    
50    /* Return the GdkDisplay that corresponds to the X display DPY.  */
51    static GdkDisplay *
52    xg_get_gdk_display (dpy)
53         Display *dpy;
54    {
55      return gdk_x11_lookup_xdisplay (dpy);
56    }
57    
58    /* When the GTK widget W is to be created on a display for F that
59       is not the default display, set the display for W.
60       W can be a GtkMenu or a GtkWindow widget.  */
61    static void
62    xg_set_screen (w, f)
63         GtkWidget *w;
64         FRAME_PTR f;
65    {
66      if (FRAME_X_DISPLAY (f) != GDK_DISPLAY ())
67        {
68          GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f));
69          GdkScreen *gscreen = gdk_display_get_default_screen (gdpy);
70    
71          if (GTK_IS_MENU (w))
72            gtk_menu_set_screen (GTK_MENU (w), gscreen);
73          else
74            gtk_window_set_screen (GTK_WINDOW (w), gscreen);
75        }
76    }
77    
78    
79    #else /* not HAVE_GTK_MULTIDISPLAY */
80    
81    /* Make some defines so we can use the GTK 2.2 functions when
82       compiling with GTK 2.0.  */
83    #define xg_set_screen(w, f)
84    #define gdk_xid_table_lookup_for_display(dpy, w)    gdk_xid_table_lookup (w)
85    #define gdk_pixmap_foreign_new_for_display(dpy, p)  gdk_pixmap_foreign_new (p)
86    #define gdk_cursor_new_for_display(dpy, c)          gdk_cursor_new (c)
87    #define gdk_x11_lookup_xdisplay(dpy)                0
88    #define GdkDisplay                                  void
89    
90    #endif /* not HAVE_GTK_MULTIDISPLAY */
91    
92    /* Open a display named by DISPLAY_NAME.  The display is returned in *DPY.
93       *DPY is set to NULL if the display can't be opened.
94    
95       Returns non-zero if display could be opened, zero if display could not
96       be opened, and less than zero if the GTK version doesn't support
97       multipe displays.  */
98    int
99    xg_display_open (display_name, dpy)
100         char *display_name;
101         Display **dpy;
102    {
103    #ifdef HAVE_GTK_MULTIDISPLAY
104      GdkDisplay *gdpy;
105    
106      gdpy = gdk_display_open (display_name);
107      *dpy = gdpy ? GDK_DISPLAY_XDISPLAY (gdpy) : NULL;
108    
109      return gdpy != NULL;
110    
111    #else /* not HAVE_GTK_MULTIDISPLAY */
112    
113      return -1;
114    #endif /* not HAVE_GTK_MULTIDISPLAY */
115    }
116    
117    
118    void
119    xg_display_close (Display *dpy)
120    {
121    #ifdef HAVE_GTK_MULTIDISPLAY
122      GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (dpy);
123    
124      /* GTK 2.2 has a bug that makes gdk_display_close crash (bug
125         http://bugzilla.gnome.org/show_bug.cgi?id=85715).  This way
126         we can continue running, but there will be memory leaks.  */
127    
128    #if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 4
129    
130      /* If this is the default display, we must change it before calling
131         dispose, otherwise it will crash.  */
132      if (gdk_display_get_default () == gdpy)
133        {
134          struct x_display_info *dpyinfo;
135          Display *new_dpy = 0;
136          GdkDisplay *gdpy_new;
137    
138          /* Find another display.  */
139          for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
140            if (dpyinfo->display != dpy)
141              {
142                new_dpy = dpyinfo->display;
143                break;
144              }
145    
146          if (! new_dpy) return; /* Emacs will exit anyway.  */
147    
148          gdpy_new = gdk_x11_lookup_xdisplay (new_dpy);
149          gdk_display_manager_set_default_display (gdk_display_manager_get (),
150                                                   gdpy_new);
151        }
152    
153      g_object_run_dispose (G_OBJECT (gdpy));
154    
155    #else
156      /* I hope this will be fixed in GTK 2.4.  It is what bug 85715 says.  */
157      gdk_display_close (gdpy);
158    #endif
159    #endif /* HAVE_GTK_MULTIDISPLAY */
160    }
161    
162    
163  /***********************************************************************  /***********************************************************************
# Line 48  Boston, MA 02111-1307, USA.  */ Line 167  Boston, MA 02111-1307, USA.  */
167     NULL if no timer is started.  */     NULL if no timer is started.  */
168  static struct atimer *xg_timer;  static struct atimer *xg_timer;
169    
 /* The cursor used for scroll bars and popup menus.  
    We only have one cursor for all scroll bars and all popup menus.  */  
 static GdkCursor *xg_left_ptr_cursor;  
   
170    
171  /* The next two variables and functions are taken from lwlib.  */  /* The next two variables and functions are taken from lwlib.  */
172  static widget_value *widget_value_free_list;  static widget_value *widget_value_free_list;
# Line 103  free_widget_value (wv) Line 218  free_widget_value (wv)
218      }      }
219  }  }
220    
 /* Set *CURSOR on W and all widgets W contain.  We must do like this  
    for scroll bars and menu because they create widgets internally,  
    and it is those widgets that are visible.  
221    
222     If *CURSOR is NULL, create a GDK_LEFT_PTR cursor and set *CURSOR to  /* Create and return the cursor to be used for popup menus and
223     the created cursor.  */     scroll bars on display DPY.  */
224  void  GdkCursor *
225    xg_create_default_cursor (dpy)
226         Display *dpy;
227    {
228      GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (dpy);
229      return gdk_cursor_new_for_display (gdpy, GDK_LEFT_PTR);
230    }
231    
232    /* For the image defined in IMG, make and return a GdkPixmap for
233       the pixmap in *GPIX, and a GdkBitmap for the mask in *GMASK.
234       If IMG has no mask, *GMASK is set to NULL.
235       The image is defined on the display where frame F is.  */
236    static void
237    xg_get_gdk_pixmap_and_mask (f, img, gpix, gmask)
238         FRAME_PTR f;
239         struct image *img;
240         GdkPixmap **gpix;
241         GdkBitmap **gmask;
242    {
243      GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f));
244    
245      *gpix = gdk_pixmap_foreign_new_for_display (gdpy, img->pixmap);
246      *gmask = img->mask ?
247        (GdkBitmap*) gdk_pixmap_foreign_new_for_display (gdpy, img->mask)
248        : 0;
249    }
250    
251    
252    /* Set CURSOR on W and all widgets W contain.  We must do like this
253       for scroll bars and menu because they create widgets internally,
254       and it is those widgets that are visible.  */
255    static void
256  xg_set_cursor (w, cursor)  xg_set_cursor (w, cursor)
257       GtkWidget *w;       GtkWidget *w;
258       GdkCursor **cursor;       GdkCursor *cursor;
259  {  {
260    GList *children = gdk_window_peek_children (w->window);    GList *children = gdk_window_peek_children (w->window);
261    
262    /* Create the cursor unless already created.  */    gdk_window_set_cursor (w->window, cursor);
   if (! *cursor)  
     *cursor = gdk_cursor_new (GDK_LEFT_PTR);  
   
   gdk_window_set_cursor (w->window, *cursor);  
263    
264    /* The scroll bar widget has more than one GDK window (had to look at    /* The scroll bar widget has more than one GDK window (had to look at
265       the source to figure this out), and there is no way to set cursor       the source to figure this out), and there is no way to set cursor
# Line 128  xg_set_cursor (w, cursor) Line 267  xg_set_cursor (w, cursor)
267       Ditto for menus.  */       Ditto for menus.  */
268    
269    for ( ; children; children = g_list_next (children))    for ( ; children; children = g_list_next (children))
270      gdk_window_set_cursor (GDK_WINDOW (children->data), *cursor);      gdk_window_set_cursor (GDK_WINDOW (children->data), cursor);
271  }  }
272    
273  /*  Timer function called when a timeout occurs for xg_timer.  /*  Timer function called when a timeout occurs for xg_timer.
# Line 381  xg_frame_set_char_size (f, cols, rows) Line 520  xg_frame_set_char_size (f, cols, rows)
520    cancel_mouse_face (f);    cancel_mouse_face (f);
521  }  }
522    
523  /* Convert an X Window WSESC to its corresponding GtkWidget.  /* Convert an X Window WSESC on display DPY to its corresponding GtkWidget.
524     Must be done like this, because GtkWidget:s can have "hidden"     Must be done like this, because GtkWidget:s can have "hidden"
525     X Window that aren't accessible.     X Window that aren't accessible.
526    
527     Return 0 if no widget match WDESC.  */     Return 0 if no widget match WDESC.  */
528  GtkWidget *  GtkWidget *
529  xg_win_to_widget (wdesc)  xg_win_to_widget (dpy, wdesc)
530         Display *dpy;
531       Window wdesc;       Window wdesc;
532  {  {
533    gpointer gdkwin;    gpointer gdkwin;
534    GtkWidget *gwdesc = 0;    GtkWidget *gwdesc = 0;
535    
536    BLOCK_INPUT;    BLOCK_INPUT;
537    gdkwin = gdk_xid_table_lookup (wdesc);  
538      gdkwin = gdk_xid_table_lookup_for_display (gdk_x11_lookup_xdisplay (dpy),
539                                                 wdesc);
540    if (gdkwin)    if (gdkwin)
541      {      {
542        GdkEvent event;        GdkEvent event;
# Line 429  xg_pix_to_gcolor (w, pixel, c) Line 571  xg_pix_to_gcolor (w, pixel, c)
571     Return TRUE to tell GTK that this expose event has been fully handeled     Return TRUE to tell GTK that this expose event has been fully handeled
572     and that GTK shall do nothing more with it.  */     and that GTK shall do nothing more with it.  */
573  static gboolean  static gboolean
574  xg_fixed_handle_expose(GtkWidget *widget,  xg_fixed_handle_expose (GtkWidget *widget,
575                         GdkEventExpose *event,                          GdkEventExpose *event,
576                         gpointer user_data)                          gpointer user_data)
577  {  {
578    GList *iter;    GList *iter;
579    
# Line 483  xg_create_frame_widgets (f) Line 625  xg_create_frame_widgets (f)
625    BLOCK_INPUT;    BLOCK_INPUT;
626    
627    wtop = gtk_window_new (GTK_WINDOW_TOPLEVEL);    wtop = gtk_window_new (GTK_WINDOW_TOPLEVEL);
628      xg_set_screen (wtop, f);
629    
630    wvbox = gtk_vbox_new (FALSE, 0);    wvbox = gtk_vbox_new (FALSE, 0);
631    wfixed = gtk_fixed_new ();  /* Must have this to place scroll bars  */    wfixed = gtk_fixed_new ();  /* Must have this to place scroll bars  */
632    
# Line 512  xg_create_frame_widgets (f) Line 656  xg_create_frame_widgets (f)
656    
657    gtk_fixed_set_has_window (GTK_FIXED (wfixed), TRUE);    gtk_fixed_set_has_window (GTK_FIXED (wfixed), TRUE);
658    
659    gtk_widget_set_size_request (wfixed, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));    gtk_widget_set_size_request (wfixed, FRAME_PIXEL_WIDTH (f),
660                                   FRAME_PIXEL_HEIGHT (f));
661    
662    gtk_container_add (GTK_CONTAINER (wtop), wvbox);    gtk_container_add (GTK_CONTAINER (wtop), wvbox);
663    gtk_box_pack_end (GTK_BOX (wvbox), wfixed, TRUE, TRUE, 0);    gtk_box_pack_end (GTK_BOX (wvbox), wfixed, TRUE, TRUE, 0);
# Line 963  xg_get_file_name (f, prompt, default_fil Line 1108  xg_get_file_name (f, prompt, default_fil
1108    filewin = gtk_file_selection_new (prompt);    filewin = gtk_file_selection_new (prompt);
1109    filesel = GTK_FILE_SELECTION (filewin);    filesel = GTK_FILE_SELECTION (filewin);
1110    
1111      xg_set_screen (filewin, f);
1112    
1113    gtk_widget_set_name (filewin, "emacs-filedialog");    gtk_widget_set_name (filewin, "emacs-filedialog");
1114    
1115    gtk_window_set_transient_for (GTK_WINDOW (filewin),    gtk_window_set_transient_for (GTK_WINDOW (filewin),
# Line 1500  create_menus (data, f, select_cb, deacti Line 1647  create_menus (data, f, select_cb, deacti
1647    
1648    if (! topmenu)    if (! topmenu)
1649      {      {
1650        if (! menu_bar_p) wmenu = gtk_menu_new ();        if (! menu_bar_p)
1651          {
1652            wmenu = gtk_menu_new ();
1653            xg_set_screen (wmenu, f);
1654          }
1655        else wmenu = gtk_menu_bar_new ();        else wmenu = gtk_menu_bar_new ();
1656    
1657        /* Put cl_data on the top menu for easier access.  */        /* Put cl_data on the top menu for easier access.  */
# Line 1618  xg_create_widget (type, name, f, val, Line 1769  xg_create_widget (type, name, f, val,
1769    if (strcmp (type, "dialog") == 0)    if (strcmp (type, "dialog") == 0)
1770      {      {
1771        w = create_dialog (val, select_cb, deactivate_cb);        w = create_dialog (val, select_cb, deactivate_cb);
1772          xg_set_screen (w, f);
1773        gtk_window_set_transient_for (GTK_WINDOW (w),        gtk_window_set_transient_for (GTK_WINDOW (w),
1774                                      GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));                                      GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
1775        gtk_window_set_destroy_with_parent (GTK_WINDOW (w), TRUE);        gtk_window_set_destroy_with_parent (GTK_WINDOW (w), TRUE);
1776          gtk_widget_set_name (w, "emacs-dialog");
       if (w)  
         gtk_widget_set_name (w, "emacs-dialog");  
1777      }      }
1778    else if (menu_bar_p || pop_up_p)    else if (menu_bar_p || pop_up_p)
1779      {      {
# Line 1645  xg_create_widget (type, name, f, val, Line 1795  xg_create_widget (type, name, f, val,
1795          {          {
1796            /* Must realize so the GdkWindow inside the widget is created.  */            /* Must realize so the GdkWindow inside the widget is created.  */
1797            gtk_widget_realize (w);            gtk_widget_realize (w);
1798            xg_set_cursor (w, &xg_left_ptr_cursor);            xg_set_cursor (w, FRAME_X_DISPLAY_INFO (f)->xg_cursor);
1799          }          }
1800      }      }
1801    else    else
# Line 2261  xg_modify_menubar_widgets (menubar, f, v Line 2411  xg_modify_menubar_widgets (menubar, f, v
2411               a new menu bar item, it has no sub menu yet.  So we set the               a new menu bar item, it has no sub menu yet.  So we set the
2412               newly created sub menu under witem.  */               newly created sub menu under witem.  */
2413            if (newsub != sub)            if (newsub != sub)
2414              gtk_menu_item_set_submenu (witem, newsub);              {
2415                  xg_set_screen (newsub, f);
2416                  gtk_menu_item_set_submenu (witem, newsub);
2417                }
2418          }          }
2419      }      }
2420    
# Line 2417  xg_get_widget_from_map (idx) Line 2570  xg_get_widget_from_map (idx)
2570    return 0;    return 0;
2571  }  }
2572    
2573  /* Return the scrollbar id for X Window WID.  /* Return the scrollbar id for X Window WID on display DPY.
2574     Return -1 if WID not in id_to_widget.  */     Return -1 if WID not in id_to_widget.  */
2575  int  int
2576  xg_get_scroll_id_for_window (wid)  xg_get_scroll_id_for_window (dpy, wid)
2577         Display *dpy;
2578       Window wid;       Window wid;
2579  {  {
2580    int idx;    int idx;
2581    GtkWidget *w;    GtkWidget *w;
2582    
2583    w = xg_win_to_widget (wid);    w = xg_win_to_widget (dpy, wid);
2584    
2585    if (w)    if (w)
2586      {      {
# Line 2533  xg_create_scroll_bar (f, bar, scroll_cal Line 2687  xg_create_scroll_bar (f, bar, scroll_cal
2687                   wscroll, -1, -1);                   wscroll, -1, -1);
2688    
2689    /* Set the cursor to an arrow.  */    /* Set the cursor to an arrow.  */
2690    xg_set_cursor (wscroll, &xg_left_ptr_cursor);    xg_set_cursor (wscroll, FRAME_X_DISPLAY_INFO (f)->xg_cursor);
2691    
2692    SET_SCROLL_BAR_X_WINDOW (bar, scroll_id);    SET_SCROLL_BAR_X_WINDOW (bar, scroll_id);
2693  }  }
# Line 2952  xg_tool_bar_item_expose_callback (w, eve Line 3106  xg_tool_bar_item_expose_callback (w, eve
3106    event->area.x -= width > event->area.width ? width-event->area.width : 0;    event->area.x -= width > event->area.width ? width-event->area.width : 0;
3107    event->area.y -= height > event->area.height ? height-event->area.height : 0;    event->area.y -= height > event->area.height ? height-event->area.height : 0;
3108    
3109    event->area.x = max(0, event->area.x);    event->area.x = max (0, event->area.x);
3110    event->area.y = max(0, event->area.y);    event->area.y = max (0, event->area.y);
3111        
3112    event->area.width = max (width, event->area.width);    event->area.width = max (width, event->area.width);
3113    event->area.height = max (height, event->area.height);    event->area.height = max (height, event->area.height);
# Line 2975  xg_tool_bar_expose_callback (w, event, c Line 3129  xg_tool_bar_expose_callback (w, event, c
3129       GdkEventExpose *event;       GdkEventExpose *event;
3130       gpointer client_data;       gpointer client_data;
3131  {  {
3132    update_frame_tool_bar((FRAME_PTR)client_data);    update_frame_tool_bar ((FRAME_PTR) client_data);
3133    return FALSE;    return FALSE;
3134  }  }
3135    
# Line 3108  update_frame_tool_bar (f) Line 3262  update_frame_tool_bar (f)
3262    
3263        if (! wicon)        if (! wicon)
3264          {          {
3265            GdkPixmap *gpix = gdk_pixmap_foreign_new (img->pixmap);            GdkPixmap *gpix;
3266            GdkBitmap *gmask = img->mask ?            GdkBitmap *gmask;
3267              (GdkBitmap*) gdk_pixmap_foreign_new (img->mask) : 0;            GtkWidget *w;
3268    
3269            GtkWidget *w = gtk_image_new_from_pixmap (gpix, gmask);            xg_get_gdk_pixmap_and_mask (f, img, &gpix, &gmask);
3270              w = gtk_image_new_from_pixmap (gpix, gmask);
3271            gtk_toolbar_append_item (GTK_TOOLBAR (x->toolbar_widget),            gtk_toolbar_append_item (GTK_TOOLBAR (x->toolbar_widget),
3272                                     0, 0, 0,                                     0, 0, 0,
3273                                     w,                                     w,
# Line 3170  update_frame_tool_bar (f) Line 3325  update_frame_tool_bar (f)
3325    
3326            if (old_img != img->pixmap)            if (old_img != img->pixmap)
3327              {              {
3328                GdkPixmap *gpix = gdk_pixmap_foreign_new (img->pixmap);                GdkPixmap *gpix;
3329                GdkBitmap *gmask = img->mask ?                GdkBitmap *gmask;
                 (GdkBitmap*) gdk_pixmap_foreign_new (img->mask) : 0;  
3330    
3331                  xg_get_gdk_pixmap_and_mask (f, img, &gpix, &gmask);
3332                gtk_image_set_from_pixmap (wimage, gpix, gmask);                gtk_image_set_from_pixmap (wimage, gpix, gmask);
3333              }              }
3334    
# Line 3241  void Line 3396  void
3396  xg_initialize ()  xg_initialize ()
3397  {  {
3398    xg_ignore_gtk_scrollbar = 0;    xg_ignore_gtk_scrollbar = 0;
   xg_left_ptr_cursor = 0;  
3399    xg_detached_menus = 0;    xg_detached_menus = 0;
3400    xg_menu_cb_list.prev = xg_menu_cb_list.next =    xg_menu_cb_list.prev = xg_menu_cb_list.next =
3401      xg_menu_item_cb_list.prev = xg_menu_item_cb_list.next = 0;      xg_menu_item_cb_list.prev = xg_menu_item_cb_list.next = 0;

Legend:
Removed from v.1.35  
changed lines
  Added in v.1.36

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26