diff options
| author | Jan Djärv | 2009-11-21 15:28:59 +0000 |
|---|---|---|
| committer | Jan Djärv | 2009-11-21 15:28:59 +0000 |
| commit | 872870b29a846cc8e27d53d05147eb3e0beb7c50 (patch) | |
| tree | 5bf7121650264015843c2111e98a0d26ededc358 /src | |
| parent | 62a6e103dd7b9d940565639d6a47c8bdee3f24ce (diff) | |
| download | emacs-872870b29a846cc8e27d53d05147eb3e0beb7c50.tar.gz emacs-872870b29a846cc8e27d53d05147eb3e0beb7c50.zip | |
Use a select wrapper around the GLib event loop, thus taking into account GLib
timeouts and event sources. This simplifies Gtk+-code a lot, and is needed
for handling GConf death/restart.
* xterm.c: #include xgselect.h.
(x_initialize): Call xgselect_initialize.
* xsettings.c (something_changedCB): C++ comments => C comments.
(init_gconf): Do not deal with any GLib file descriptors, xg_select
does that now.
* gtkutil.c (xg_timer, xg_process_timeouts, xg_start_timer)
(xg_stop_timer, menu_grab_callback_cnt, menu_grab_callback)
(scroll_bar_button_cb): Remove.
(create_menus): C++ comments => C comments. Don't bind grab-notify
event.
(xg_create_scroll_bar): Don't bind button-press-event and
button-release-event.
* process.c: Include xgselect.h if defined (USE_GTK) ||
defined (HAVE_GCONF).
(wait_reading_process_output): Call xg_select for the same condition.
* xgselect.c (xg_select): New function to better integrate with
GLib/Gtk event handling. Needed if GConf daemon dies/restarts.
* xgselect.h: New file, declare xg_select, xgselect_initialize.
* Makefile.in (XOBJ): Add xgselect.o.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 28 | ||||
| -rw-r--r-- | src/Makefile.in | 2 | ||||
| -rw-r--r-- | src/gtkutil.c | 131 | ||||
| -rw-r--r-- | src/process.c | 8 | ||||
| -rw-r--r-- | src/xgselect.c | 157 | ||||
| -rw-r--r-- | src/xgselect.h | 35 | ||||
| -rw-r--r-- | src/xsettings.c | 39 | ||||
| -rw-r--r-- | src/xterm.c | 3 |
8 files changed, 236 insertions, 167 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 7f6891e0710..27c2b7246af 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,31 @@ | |||
| 1 | 2009-11-21 Jan Djärv <jan.h.d@swipnet.se> | ||
| 2 | |||
| 3 | * xterm.c: #include xgselect.h. | ||
| 4 | (x_initialize): Call xgselect_initialize. | ||
| 5 | |||
| 6 | * xsettings.c (something_changedCB): C++ comments => C comments. | ||
| 7 | (init_gconf): Do not deal with any GLib file descriptors, xg_select | ||
| 8 | does that now. | ||
| 9 | |||
| 10 | * gtkutil.c (xg_timer, xg_process_timeouts, xg_start_timer) | ||
| 11 | (xg_stop_timer, menu_grab_callback_cnt, menu_grab_callback) | ||
| 12 | (scroll_bar_button_cb): Remove. | ||
| 13 | (create_menus): C++ comments => C comments. Don't bind grab-notify | ||
| 14 | event. | ||
| 15 | (xg_create_scroll_bar): Don't bind button-press-event and | ||
| 16 | button-release-event. | ||
| 17 | |||
| 18 | * process.c: Include xgselect.h if defined (USE_GTK) || | ||
| 19 | defined (HAVE_GCONF). | ||
| 20 | (wait_reading_process_output): Call xg_select for the same condition. | ||
| 21 | |||
| 22 | * xgselect.c (xg_select): New function to better integrate with | ||
| 23 | GLib/Gtk event handling. Needed if GConf daemon dies/restarts. | ||
| 24 | |||
| 25 | * xgselect.h: New file, declare xg_select, xgselect_initialize. | ||
| 26 | |||
| 27 | * Makefile.in (XOBJ): Add xgselect.o. | ||
| 28 | |||
| 1 | 2009-11-21 Andreas Schwab <schwab@linux-m68k.org> | 29 | 2009-11-21 Andreas Schwab <schwab@linux-m68k.org> |
| 2 | 30 | ||
| 3 | * character.h (STRING_CHAR, STRING_CHAR_AND_LENGTH): Remove | 31 | * character.h (STRING_CHAR, STRING_CHAR_AND_LENGTH): Remove |
diff --git a/src/Makefile.in b/src/Makefile.in index 3d81cc1f2bc..aceecacb5c7 100644 --- a/src/Makefile.in +++ b/src/Makefile.in | |||
| @@ -292,7 +292,7 @@ ALL_OBJC_CFLAGS=$(ALL_CFLAGS) @GNU_OBJC_CFLAGS@ | |||
| 292 | #ifdef HAVE_X_WINDOWS | 292 | #ifdef HAVE_X_WINDOWS |
| 293 | XMENU_OBJ = xmenu.o | 293 | XMENU_OBJ = xmenu.o |
| 294 | XOBJ= xterm.o xfns.o xselect.o xrdb.o fontset.o xsmfns.o fringe.o image.o \ | 294 | XOBJ= xterm.o xfns.o xselect.o xrdb.o fontset.o xsmfns.o fringe.o image.o \ |
| 295 | xsettings.o | 295 | xsettings.o xgselect.o |
| 296 | 296 | ||
| 297 | #ifdef HAVE_MENUS | 297 | #ifdef HAVE_MENUS |
| 298 | 298 | ||
diff --git a/src/gtkutil.c b/src/gtkutil.c index 4a55e51b8b2..b1e238af55c 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c | |||
| @@ -29,7 +29,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 29 | #include "blockinput.h" | 29 | #include "blockinput.h" |
| 30 | #include "syssignal.h" | 30 | #include "syssignal.h" |
| 31 | #include "window.h" | 31 | #include "window.h" |
| 32 | #include "atimer.h" | ||
| 33 | #include "gtkutil.h" | 32 | #include "gtkutil.h" |
| 34 | #include "termhooks.h" | 33 | #include "termhooks.h" |
| 35 | #include "keyboard.h" | 34 | #include "keyboard.h" |
| @@ -181,11 +180,6 @@ xg_display_close (Display *dpy) | |||
| 181 | /*********************************************************************** | 180 | /*********************************************************************** |
| 182 | Utility functions | 181 | Utility functions |
| 183 | ***********************************************************************/ | 182 | ***********************************************************************/ |
| 184 | /* The timer for scroll bar repetition and menu bar timeouts. | ||
| 185 | NULL if no timer is started. */ | ||
| 186 | static struct atimer *xg_timer; | ||
| 187 | |||
| 188 | |||
| 189 | /* The next two variables and functions are taken from lwlib. */ | 183 | /* The next two variables and functions are taken from lwlib. */ |
| 190 | static widget_value *widget_value_free_list; | 184 | static widget_value *widget_value_free_list; |
| 191 | static int malloc_cpt; | 185 | static int malloc_cpt; |
| @@ -426,58 +420,6 @@ xg_set_cursor (w, cursor) | |||
| 426 | gdk_window_set_cursor (GDK_WINDOW (children->data), cursor); | 420 | gdk_window_set_cursor (GDK_WINDOW (children->data), cursor); |
| 427 | } | 421 | } |
| 428 | 422 | ||
| 429 | /* Timer function called when a timeout occurs for xg_timer. | ||
| 430 | This function processes all GTK events in a recursive event loop. | ||
| 431 | This is done because GTK timer events are not seen by Emacs event | ||
| 432 | detection, Emacs only looks for X events. When a scroll bar has the | ||
| 433 | pointer (detected by button press/release events below) an Emacs | ||
| 434 | timer is started, and this function can then check if the GTK timer | ||
| 435 | has expired by calling the GTK event loop. | ||
| 436 | Also, when a menu is active, it has a small timeout before it | ||
| 437 | pops down the sub menu under it. */ | ||
| 438 | |||
| 439 | static void | ||
| 440 | xg_process_timeouts (timer) | ||
| 441 | struct atimer *timer; | ||
| 442 | { | ||
| 443 | BLOCK_INPUT; | ||
| 444 | /* Ideally we would like to just handle timer events, like the Xt version | ||
| 445 | of this does in xterm.c, but there is no such feature in GTK. */ | ||
| 446 | while (gtk_events_pending ()) | ||
| 447 | gtk_main_iteration (); | ||
| 448 | UNBLOCK_INPUT; | ||
| 449 | } | ||
| 450 | |||
| 451 | /* Start the xg_timer with an interval of 0.1 seconds, if not already started. | ||
| 452 | xg_process_timeouts is called when the timer expires. The timer | ||
| 453 | started is continuous, i.e. runs until xg_stop_timer is called. */ | ||
| 454 | |||
| 455 | static void | ||
| 456 | xg_start_timer () | ||
| 457 | { | ||
| 458 | if (! xg_timer) | ||
| 459 | { | ||
| 460 | EMACS_TIME interval; | ||
| 461 | EMACS_SET_SECS_USECS (interval, 0, 100000); | ||
| 462 | xg_timer = start_atimer (ATIMER_CONTINUOUS, | ||
| 463 | interval, | ||
| 464 | xg_process_timeouts, | ||
| 465 | 0); | ||
| 466 | } | ||
| 467 | } | ||
| 468 | |||
| 469 | /* Stop the xg_timer if started. */ | ||
| 470 | |||
| 471 | static void | ||
| 472 | xg_stop_timer () | ||
| 473 | { | ||
| 474 | if (xg_timer) | ||
| 475 | { | ||
| 476 | cancel_atimer (xg_timer); | ||
| 477 | xg_timer = 0; | ||
| 478 | } | ||
| 479 | } | ||
| 480 | |||
| 481 | /* Insert NODE into linked LIST. */ | 423 | /* Insert NODE into linked LIST. */ |
| 482 | 424 | ||
| 483 | static void | 425 | static void |
| @@ -1895,29 +1837,6 @@ menu_destroy_callback (w, client_data) | |||
| 1895 | unref_cl_data ((xg_menu_cb_data*) client_data); | 1837 | unref_cl_data ((xg_menu_cb_data*) client_data); |
| 1896 | } | 1838 | } |
| 1897 | 1839 | ||
| 1898 | /* Callback called when a menu does a grab or ungrab. That means the | ||
| 1899 | menu has been activated or deactivated. | ||
| 1900 | Used to start a timer so the small timeout the menus in GTK uses before | ||
| 1901 | popping down a menu is seen by Emacs (see xg_process_timeouts above). | ||
| 1902 | W is the widget that does the grab (not used). | ||
| 1903 | UNGRAB_P is TRUE if this is an ungrab, FALSE if it is a grab. | ||
| 1904 | CLIENT_DATA is NULL (not used). */ | ||
| 1905 | |||
| 1906 | /* Keep track of total number of grabs. */ | ||
| 1907 | static int menu_grab_callback_cnt; | ||
| 1908 | |||
| 1909 | static void | ||
| 1910 | menu_grab_callback (GtkWidget *widget, | ||
| 1911 | gboolean ungrab_p, | ||
| 1912 | gpointer client_data) | ||
| 1913 | { | ||
| 1914 | if (ungrab_p) menu_grab_callback_cnt--; | ||
| 1915 | else menu_grab_callback_cnt++; | ||
| 1916 | |||
| 1917 | if (menu_grab_callback_cnt > 0 && ! xg_timer) xg_start_timer (); | ||
| 1918 | else if (menu_grab_callback_cnt == 0 && xg_timer) xg_stop_timer (); | ||
| 1919 | } | ||
| 1920 | |||
| 1921 | /* Make a GTK widget that contains both UTF8_LABEL and UTF8_KEY (both | 1840 | /* Make a GTK widget that contains both UTF8_LABEL and UTF8_KEY (both |
| 1922 | must be non-NULL) and can be inserted into a menu item. | 1841 | must be non-NULL) and can be inserted into a menu item. |
| 1923 | 1842 | ||
| @@ -2232,10 +2151,10 @@ create_menus (data, f, select_cb, deactivate_cb, highlight_cb, | |||
| 2232 | else | 2151 | else |
| 2233 | { | 2152 | { |
| 2234 | wmenu = gtk_menu_bar_new (); | 2153 | wmenu = gtk_menu_bar_new (); |
| 2235 | // Set width of menu bar to a small value so it doesn't enlarge | 2154 | /* Set width of menu bar to a small value so it doesn't enlarge |
| 2236 | // a small initial frame size. The width will be set to the | 2155 | a small initial frame size. The width will be set to the |
| 2237 | // width of the frame later on when it is added to a container. | 2156 | width of the frame later on when it is added to a container. |
| 2238 | // height -1: Natural height. | 2157 | height -1: Natural height. */ |
| 2239 | gtk_widget_set_size_request (wmenu, 1, -1); | 2158 | gtk_widget_set_size_request (wmenu, 1, -1); |
| 2240 | } | 2159 | } |
| 2241 | 2160 | ||
| @@ -2251,9 +2170,6 @@ create_menus (data, f, select_cb, deactivate_cb, highlight_cb, | |||
| 2251 | if (deactivate_cb) | 2170 | if (deactivate_cb) |
| 2252 | g_signal_connect (G_OBJECT (wmenu), | 2171 | g_signal_connect (G_OBJECT (wmenu), |
| 2253 | "selection-done", deactivate_cb, 0); | 2172 | "selection-done", deactivate_cb, 0); |
| 2254 | |||
| 2255 | g_signal_connect (G_OBJECT (wmenu), | ||
| 2256 | "grab-notify", G_CALLBACK (menu_grab_callback), 0); | ||
| 2257 | } | 2173 | } |
| 2258 | 2174 | ||
| 2259 | if (! menu_bar_p && add_tearoff_p) | 2175 | if (! menu_bar_p && add_tearoff_p) |
| @@ -3177,34 +3093,6 @@ xg_gtk_scroll_destroy (widget, data) | |||
| 3177 | xg_remove_widget_from_map (id); | 3093 | xg_remove_widget_from_map (id); |
| 3178 | } | 3094 | } |
| 3179 | 3095 | ||
| 3180 | /* Callback for button press/release events. Used to start timer so that | ||
| 3181 | the scroll bar repetition timer in GTK gets handled. | ||
| 3182 | Also, sets bar->dragging to Qnil when dragging (button release) is done. | ||
| 3183 | WIDGET is the scroll bar widget the event is for (not used). | ||
| 3184 | EVENT contains the event. | ||
| 3185 | USER_DATA points to the struct scrollbar structure. | ||
| 3186 | |||
| 3187 | Returns FALSE to tell GTK that it shall continue propagate the event | ||
| 3188 | to widgets. */ | ||
| 3189 | |||
| 3190 | static gboolean | ||
| 3191 | scroll_bar_button_cb (widget, event, user_data) | ||
| 3192 | GtkWidget *widget; | ||
| 3193 | GdkEventButton *event; | ||
| 3194 | gpointer user_data; | ||
| 3195 | { | ||
| 3196 | if (event->type == GDK_BUTTON_PRESS && ! xg_timer) | ||
| 3197 | xg_start_timer (); | ||
| 3198 | else if (event->type == GDK_BUTTON_RELEASE) | ||
| 3199 | { | ||
| 3200 | struct scroll_bar *bar = (struct scroll_bar *) user_data; | ||
| 3201 | if (xg_timer) xg_stop_timer (); | ||
| 3202 | bar->dragging = Qnil; | ||
| 3203 | } | ||
| 3204 | |||
| 3205 | return FALSE; | ||
| 3206 | } | ||
| 3207 | |||
| 3208 | /* Create a scroll bar widget for frame F. Store the scroll bar | 3096 | /* Create a scroll bar widget for frame F. Store the scroll bar |
| 3209 | in BAR. | 3097 | in BAR. |
| 3210 | SCROLL_CALLBACK is the callback to invoke when the value of the | 3098 | SCROLL_CALLBACK is the callback to invoke when the value of the |
| @@ -3246,17 +3134,6 @@ xg_create_scroll_bar (f, bar, scroll_callback, scroll_bar_name) | |||
| 3246 | G_CALLBACK (xg_gtk_scroll_destroy), | 3134 | G_CALLBACK (xg_gtk_scroll_destroy), |
| 3247 | (gpointer) (EMACS_INT) scroll_id); | 3135 | (gpointer) (EMACS_INT) scroll_id); |
| 3248 | 3136 | ||
| 3249 | /* Connect to button press and button release to detect if any scroll bar | ||
| 3250 | has the pointer. */ | ||
| 3251 | g_signal_connect (G_OBJECT (wscroll), | ||
| 3252 | "button-press-event", | ||
| 3253 | G_CALLBACK (scroll_bar_button_cb), | ||
| 3254 | (gpointer) bar); | ||
| 3255 | g_signal_connect (G_OBJECT (wscroll), | ||
| 3256 | "button-release-event", | ||
| 3257 | G_CALLBACK (scroll_bar_button_cb), | ||
| 3258 | (gpointer) bar); | ||
| 3259 | |||
| 3260 | /* The scroll bar widget does not draw on a window of its own. Instead | 3137 | /* The scroll bar widget does not draw on a window of its own. Instead |
| 3261 | it draws on the parent window, in this case the edit widget. So | 3138 | it draws on the parent window, in this case the edit widget. So |
| 3262 | whenever the edit widget is cleared, the scroll bar needs to redraw | 3139 | whenever the edit widget is cleared, the scroll bar needs to redraw |
diff --git a/src/process.c b/src/process.c index 5c6875520e6..90f2a9aa6bb 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -120,6 +120,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 120 | #include "composite.h" | 120 | #include "composite.h" |
| 121 | #include "atimer.h" | 121 | #include "atimer.h" |
| 122 | 122 | ||
| 123 | #if defined (USE_GTK) || defined (HAVE_GCONF) | ||
| 124 | #include "xgselect.h" | ||
| 125 | #endif /* defined (USE_GTK) || defined (HAVE_GCONF) */ | ||
| 126 | |||
| 123 | Lisp_Object Qprocessp; | 127 | Lisp_Object Qprocessp; |
| 124 | Lisp_Object Qrun, Qstop, Qsignal; | 128 | Lisp_Object Qrun, Qstop, Qsignal; |
| 125 | Lisp_Object Qopen, Qclosed, Qconnect, Qfailed, Qlisten; | 129 | Lisp_Object Qopen, Qclosed, Qconnect, Qfailed, Qlisten; |
| @@ -4922,7 +4926,9 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display, | |||
| 4922 | process_output_skip = 0; | 4926 | process_output_skip = 0; |
| 4923 | } | 4927 | } |
| 4924 | #endif | 4928 | #endif |
| 4925 | #ifdef HAVE_NS | 4929 | #if defined (USE_GTK) || defined (HAVE_GCONF) |
| 4930 | nfds = xg_select | ||
| 4931 | #elif defined (HAVE_NS) | ||
| 4926 | nfds = ns_select | 4932 | nfds = ns_select |
| 4927 | #else | 4933 | #else |
| 4928 | nfds = select | 4934 | nfds = select |
diff --git a/src/xgselect.c b/src/xgselect.c new file mode 100644 index 00000000000..3c5a99f8ed2 --- /dev/null +++ b/src/xgselect.c | |||
| @@ -0,0 +1,157 @@ | |||
| 1 | /* Function for handling the GLib event loop. | ||
| 2 | Copyright (C) 2009 | ||
| 3 | Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is part of GNU Emacs. | ||
| 6 | |||
| 7 | GNU Emacs is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU General Public License as published by | ||
| 9 | the Free Software Foundation, either version 3 of the License, or | ||
| 10 | (at your option) any later version. | ||
| 11 | |||
| 12 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU General Public License | ||
| 18 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | #include "config.h" | ||
| 21 | |||
| 22 | #if defined (USE_GTK) || defined (HAVE_GCONF) | ||
| 23 | #include <glib.h> | ||
| 24 | #include <errno.h> | ||
| 25 | #include <setjmp.h> | ||
| 26 | #include "xgselect.h" | ||
| 27 | |||
| 28 | static GPollFD *gfds; | ||
| 29 | static int gfds_size; | ||
| 30 | |||
| 31 | int | ||
| 32 | xg_select (max_fds, rfds, wfds, efds, timeout) | ||
| 33 | int max_fds; | ||
| 34 | SELECT_TYPE *rfds; | ||
| 35 | SELECT_TYPE *wfds; | ||
| 36 | SELECT_TYPE *efds; | ||
| 37 | EMACS_TIME *timeout; | ||
| 38 | { | ||
| 39 | SELECT_TYPE all_rfds, all_wfds; | ||
| 40 | EMACS_TIME tmo, *tmop = timeout; | ||
| 41 | |||
| 42 | GMainContext *context = g_main_context_default (); | ||
| 43 | int have_wfds = wfds != NULL; | ||
| 44 | int n_gfds = 0, our_tmo = 0, retval = 0, our_fds = 0; | ||
| 45 | int prio, i, nfds, tmo_in_millisec; | ||
| 46 | |||
| 47 | if (rfds) memcpy (&all_rfds, rfds, sizeof (all_rfds)); | ||
| 48 | else FD_ZERO (&all_rfds); | ||
| 49 | if (wfds) memcpy (&all_wfds, wfds, sizeof (all_rfds)); | ||
| 50 | else FD_ZERO (&all_wfds); | ||
| 51 | |||
| 52 | /* Update event sources in GLib. */ | ||
| 53 | g_main_context_pending (context); | ||
| 54 | |||
| 55 | do { | ||
| 56 | if (n_gfds > gfds_size) | ||
| 57 | { | ||
| 58 | while (n_gfds > gfds_size) | ||
| 59 | gfds_size *= 2; | ||
| 60 | xfree (gfds); | ||
| 61 | gfds = xmalloc (sizeof (*gfds) * gfds_size); | ||
| 62 | } | ||
| 63 | |||
| 64 | n_gfds = g_main_context_query (context, | ||
| 65 | G_PRIORITY_LOW, | ||
| 66 | &tmo_in_millisec, | ||
| 67 | gfds, | ||
| 68 | gfds_size); | ||
| 69 | } while (n_gfds > gfds_size); | ||
| 70 | |||
| 71 | for (i = 0; i < n_gfds; ++i) | ||
| 72 | { | ||
| 73 | if (gfds[i].events & G_IO_IN) | ||
| 74 | { | ||
| 75 | FD_SET (gfds[i].fd, &all_rfds); | ||
| 76 | if (gfds[i].fd > max_fds) max_fds = gfds[i].fd; | ||
| 77 | } | ||
| 78 | if (gfds[i].events & G_IO_OUT) | ||
| 79 | { | ||
| 80 | FD_SET (gfds[i].fd, &all_wfds); | ||
| 81 | if (gfds[i].fd > max_fds) max_fds = gfds[i].fd; | ||
| 82 | have_wfds = 1; | ||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | if (tmo_in_millisec >= 0) | ||
| 87 | { | ||
| 88 | EMACS_SET_SECS_USECS (tmo, tmo_in_millisec/1000, | ||
| 89 | 1000 * (tmo_in_millisec % 1000)); | ||
| 90 | if (!timeout) our_tmo = 1; | ||
| 91 | else | ||
| 92 | { | ||
| 93 | EMACS_TIME difference; | ||
| 94 | |||
| 95 | EMACS_SUB_TIME (difference, tmo, *timeout); | ||
| 96 | if (EMACS_TIME_NEG_P (difference)) our_tmo = 1; | ||
| 97 | } | ||
| 98 | |||
| 99 | if (our_tmo) tmop = &tmo; | ||
| 100 | } | ||
| 101 | |||
| 102 | nfds = select (max_fds+1, &all_rfds, have_wfds ? &all_wfds : NULL, | ||
| 103 | efds, tmop); | ||
| 104 | |||
| 105 | if (nfds < 0) | ||
| 106 | retval = nfds; | ||
| 107 | else if (nfds > 0) | ||
| 108 | { | ||
| 109 | for (i = 0; i < max_fds+1; ++i) | ||
| 110 | { | ||
| 111 | if (FD_ISSET (i, &all_rfds)) | ||
| 112 | { | ||
| 113 | if (rfds && FD_ISSET (i, rfds)) ++retval; | ||
| 114 | else ++our_fds; | ||
| 115 | } | ||
| 116 | if (have_wfds && FD_ISSET (i, &all_wfds)) | ||
| 117 | { | ||
| 118 | if (wfds && FD_ISSET (i, wfds)) ++retval; | ||
| 119 | else ++our_fds; | ||
| 120 | } | ||
| 121 | if (efds && FD_ISSET (i, efds)) | ||
| 122 | ++retval; | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | if (our_fds > 0 || (nfds == 0 && our_tmo)) | ||
| 127 | { | ||
| 128 | |||
| 129 | /* If Gtk+ is in use eventually gtk_main_iteration will be called, | ||
| 130 | unless retval is zero. */ | ||
| 131 | #ifdef USE_GTK | ||
| 132 | if (retval == 0) | ||
| 133 | #endif | ||
| 134 | while (g_main_context_pending (context)) | ||
| 135 | g_main_context_dispatch (context); | ||
| 136 | |||
| 137 | /* To not have to recalculate timeout, return like this. */ | ||
| 138 | if (retval == 0) | ||
| 139 | { | ||
| 140 | retval = -1; | ||
| 141 | errno = EINTR; | ||
| 142 | } | ||
| 143 | } | ||
| 144 | |||
| 145 | return retval; | ||
| 146 | } | ||
| 147 | #endif /* defined (USE_GTK) || defined (HAVE_GCONF) */ | ||
| 148 | |||
| 149 | void | ||
| 150 | xgselect_initialize () | ||
| 151 | { | ||
| 152 | #if defined (USE_GTK) || defined (HAVE_GCONF) | ||
| 153 | gfds_size = 128; | ||
| 154 | gfds = xmalloc (sizeof (*gfds)*gfds_size); | ||
| 155 | #endif /* defined (USE_GTK) || defined (HAVE_GCONF) */ | ||
| 156 | } | ||
| 157 | |||
diff --git a/src/xgselect.h b/src/xgselect.h new file mode 100644 index 00000000000..537f3471fb3 --- /dev/null +++ b/src/xgselect.h | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | /* Header for xg_select. | ||
| 2 | Copyright (C) 2009 | ||
| 3 | Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is part of GNU Emacs. | ||
| 6 | |||
| 7 | GNU Emacs is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU General Public License as published by | ||
| 9 | the Free Software Foundation, either version 3 of the License, or | ||
| 10 | (at your option) any later version. | ||
| 11 | |||
| 12 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU General Public License | ||
| 18 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | #ifndef XGSELECT_H | ||
| 21 | #define XGSELECT_H | ||
| 22 | |||
| 23 | #include "lisp.h" | ||
| 24 | #include "systime.h" | ||
| 25 | #include "sysselect.h" | ||
| 26 | |||
| 27 | extern int xg_select P_ ((int max_fds, | ||
| 28 | SELECT_TYPE *rfds, | ||
| 29 | SELECT_TYPE *wfds, | ||
| 30 | SELECT_TYPE *efds, | ||
| 31 | EMACS_TIME *timeout)); | ||
| 32 | |||
| 33 | extern void xgselect_initialize P_ ((void)); | ||
| 34 | |||
| 35 | #endif /* XGSELECT_H */ | ||
diff --git a/src/xsettings.c b/src/xsettings.c index 8ce24743260..0dabc060b9a 100644 --- a/src/xsettings.c +++ b/src/xsettings.c | |||
| @@ -82,7 +82,7 @@ something_changedCB (client, cnxn_id, entry, user_data) | |||
| 82 | const char *value = gconf_value_get_string (v); | 82 | const char *value = gconf_value_get_string (v); |
| 83 | int i; | 83 | int i; |
| 84 | if (current_mono_font != NULL && strcmp (value, current_mono_font) == 0) | 84 | if (current_mono_font != NULL && strcmp (value, current_mono_font) == 0) |
| 85 | return; // No change. | 85 | return; /* No change. */ |
| 86 | 86 | ||
| 87 | xfree (current_mono_font); | 87 | xfree (current_mono_font); |
| 88 | current_mono_font = xstrdup (value); | 88 | current_mono_font = xstrdup (value); |
| @@ -501,24 +501,6 @@ init_gconf () | |||
| 501 | #if defined (HAVE_GCONF) && defined (HAVE_XFT) | 501 | #if defined (HAVE_GCONF) && defined (HAVE_XFT) |
| 502 | int i; | 502 | int i; |
| 503 | char *s; | 503 | char *s; |
| 504 | /* Should be enough, this is called at startup */ | ||
| 505 | #define N_FDS 1024 | ||
| 506 | int fd_before[N_FDS], fd_before1[N_FDS]; | ||
| 507 | int dummy, n_fds; | ||
| 508 | GPollFD gfds[N_FDS]; | ||
| 509 | |||
| 510 | /* To find out which filedecriptors GConf uses, check before and after. | ||
| 511 | If we do not do this, GConf changes will only happen when Emacs gets | ||
| 512 | an X event. */ | ||
| 513 | memset (fd_before, 0, sizeof (fd_before)); | ||
| 514 | n_fds = g_main_context_query (g_main_context_default (), | ||
| 515 | G_PRIORITY_LOW, | ||
| 516 | &dummy, | ||
| 517 | gfds, | ||
| 518 | N_FDS); | ||
| 519 | for (i = 0; i < n_fds; ++i) | ||
| 520 | if (gfds[i].fd < N_FDS && gfds[i].fd > 0 && gfds[i].events > 0) | ||
| 521 | fd_before[gfds[i].fd] = 1; | ||
| 522 | 504 | ||
| 523 | g_type_init (); | 505 | g_type_init (); |
| 524 | gconf_client = gconf_client_get_default (); | 506 | gconf_client = gconf_client_get_default (); |
| @@ -537,25 +519,6 @@ init_gconf () | |||
| 537 | SYSTEM_MONO_FONT, | 519 | SYSTEM_MONO_FONT, |
| 538 | something_changedCB, | 520 | something_changedCB, |
| 539 | NULL, NULL, NULL); | 521 | NULL, NULL, NULL); |
| 540 | n_fds = g_main_context_query (g_main_context_default (), | ||
| 541 | G_PRIORITY_LOW, | ||
| 542 | &dummy, | ||
| 543 | gfds, | ||
| 544 | N_FDS); | ||
| 545 | |||
| 546 | for (i = 0; i < n_fds; ++i) | ||
| 547 | if (gfds[i].fd < N_FDS && gfds[i].fd > 0 && gfds[i].events > 0 | ||
| 548 | && !fd_before[gfds[i].fd]) | ||
| 549 | { | ||
| 550 | #ifdef F_SETOWN | ||
| 551 | fcntl (i, F_SETOWN, getpid ()); | ||
| 552 | #endif /* ! defined (F_SETOWN) */ | ||
| 553 | |||
| 554 | #ifdef SIGIO | ||
| 555 | if (interrupt_input) | ||
| 556 | init_sigio (i); | ||
| 557 | #endif /* ! defined (SIGIO) */ | ||
| 558 | } | ||
| 559 | #endif /* HAVE_GCONF && HAVE_XFT */ | 522 | #endif /* HAVE_GCONF && HAVE_XFT */ |
| 560 | } | 523 | } |
| 561 | 524 | ||
diff --git a/src/xterm.c b/src/xterm.c index f18b8105c02..aefa9d7217b 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -87,6 +87,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 87 | #include "font.h" | 87 | #include "font.h" |
| 88 | #include "fontset.h" | 88 | #include "fontset.h" |
| 89 | #include "xsettings.h" | 89 | #include "xsettings.h" |
| 90 | #include "xgselect.h" | ||
| 90 | #include "sysselect.h" | 91 | #include "sysselect.h" |
| 91 | 92 | ||
| 92 | #ifdef USE_X_TOOLKIT | 93 | #ifdef USE_X_TOOLKIT |
| @@ -10850,6 +10851,8 @@ x_initialize () | |||
| 10850 | XSetIOErrorHandler (x_io_error_quitter); | 10851 | XSetIOErrorHandler (x_io_error_quitter); |
| 10851 | 10852 | ||
| 10852 | signal (SIGPIPE, x_connection_signal); | 10853 | signal (SIGPIPE, x_connection_signal); |
| 10854 | |||
| 10855 | xgselect_initialize (); | ||
| 10853 | } | 10856 | } |
| 10854 | 10857 | ||
| 10855 | 10858 | ||