Commit | Line | Data |
---|---|---|
872870b2 | 1 | /* Function for handling the GLib event loop. |
95df8112 | 2 | |
ab422c4d | 3 | Copyright (C) 2009-2013 Free Software Foundation, Inc. |
872870b2 JD |
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 | |
0949d2b6 | 18 | along with GNU Emacs. If not, see <http§://www.gnu.org/licenses/>. */ |
872870b2 | 19 | |
08a494a3 | 20 | #include <config.h> |
872870b2 | 21 | |
aefd87e1 PE |
22 | #include "xgselect.h" |
23 | ||
0949d2b6 | 24 | #if defined (USE_GTK) || defined (HAVE_GCONF) || defined (HAVE_GSETTINGS) |
aefd87e1 | 25 | |
872870b2 JD |
26 | #include <glib.h> |
27 | #include <errno.h> | |
b2f4d39f | 28 | #include "xterm.h" |
872870b2 | 29 | |
872870b2 | 30 | int |
ff23cd9f | 31 | xg_select (int fds_lim, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, |
d35af63c | 32 | EMACS_TIME *timeout, sigset_t *sigmask) |
872870b2 JD |
33 | { |
34 | SELECT_TYPE all_rfds, all_wfds; | |
35 | EMACS_TIME tmo, *tmop = timeout; | |
36 | ||
b0572523 | 37 | GMainContext *context; |
872870b2 | 38 | int have_wfds = wfds != NULL; |
0f46bc75 PE |
39 | GPollFD gfds_buf[128]; |
40 | GPollFD *gfds = gfds_buf; | |
41 | int gfds_size = sizeof gfds_buf / sizeof *gfds_buf; | |
42 | int n_gfds, retval = 0, our_fds = 0, max_fds = fds_lim - 1; | |
ff23cd9f | 43 | int i, nfds, tmo_in_millisec; |
0f46bc75 | 44 | USE_SAFE_ALLOCA; |
872870b2 | 45 | |
0f46bc75 PE |
46 | if (! (x_in_use |
47 | && g_main_context_pending (context = g_main_context_default ()))) | |
48 | return pselect (fds_lim, rfds, wfds, efds, timeout, sigmask); | |
b0572523 | 49 | |
ae1d87e2 | 50 | if (rfds) all_rfds = *rfds; |
872870b2 | 51 | else FD_ZERO (&all_rfds); |
ae1d87e2 | 52 | if (wfds) all_wfds = *wfds; |
872870b2 JD |
53 | else FD_ZERO (&all_wfds); |
54 | ||
0f46bc75 PE |
55 | n_gfds = g_main_context_query (context, G_PRIORITY_LOW, &tmo_in_millisec, |
56 | gfds, gfds_size); | |
57 | if (gfds_size < n_gfds) | |
58 | { | |
59 | SAFE_NALLOCA (gfds, sizeof *gfds, n_gfds); | |
60 | gfds_size = n_gfds; | |
61 | n_gfds = g_main_context_query (context, G_PRIORITY_LOW, &tmo_in_millisec, | |
62 | gfds, gfds_size); | |
63 | } | |
872870b2 | 64 | |
41729b81 | 65 | for (i = 0; i < n_gfds; ++i) |
872870b2 JD |
66 | { |
67 | if (gfds[i].events & G_IO_IN) | |
68 | { | |
69 | FD_SET (gfds[i].fd, &all_rfds); | |
70 | if (gfds[i].fd > max_fds) max_fds = gfds[i].fd; | |
71 | } | |
72 | if (gfds[i].events & G_IO_OUT) | |
73 | { | |
74 | FD_SET (gfds[i].fd, &all_wfds); | |
75 | if (gfds[i].fd > max_fds) max_fds = gfds[i].fd; | |
76 | have_wfds = 1; | |
77 | } | |
78 | } | |
79 | ||
0f46bc75 PE |
80 | SAFE_FREE (); |
81 | ||
872870b2 JD |
82 | if (tmo_in_millisec >= 0) |
83 | { | |
e9a9ae03 PE |
84 | tmo = make_emacs_time (tmo_in_millisec / 1000, |
85 | 1000 * 1000 * (tmo_in_millisec % 1000)); | |
d35af63c PE |
86 | if (!timeout || EMACS_TIME_LT (tmo, *timeout)) |
87 | tmop = &tmo; | |
872870b2 JD |
88 | } |
89 | ||
97107e2e | 90 | fds_lim = max_fds + 1; |
d35af63c PE |
91 | nfds = pselect (fds_lim, &all_rfds, have_wfds ? &all_wfds : NULL, |
92 | efds, tmop, sigmask); | |
872870b2 JD |
93 | |
94 | if (nfds < 0) | |
95 | retval = nfds; | |
41729b81 | 96 | else if (nfds > 0) |
872870b2 | 97 | { |
97107e2e | 98 | for (i = 0; i < fds_lim; ++i) |
872870b2 JD |
99 | { |
100 | if (FD_ISSET (i, &all_rfds)) | |
101 | { | |
102 | if (rfds && FD_ISSET (i, rfds)) ++retval; | |
103 | else ++our_fds; | |
104 | } | |
42d3022b J |
105 | else if (rfds) |
106 | FD_CLR (i, rfds); | |
107 | ||
872870b2 JD |
108 | if (have_wfds && FD_ISSET (i, &all_wfds)) |
109 | { | |
110 | if (wfds && FD_ISSET (i, wfds)) ++retval; | |
111 | else ++our_fds; | |
112 | } | |
42d3022b J |
113 | else if (wfds) |
114 | FD_CLR (i, wfds); | |
115 | ||
872870b2 JD |
116 | if (efds && FD_ISSET (i, efds)) |
117 | ++retval; | |
118 | } | |
119 | } | |
120 | ||
d35af63c | 121 | if (our_fds > 0 || (nfds == 0 && tmop == &tmo)) |
872870b2 | 122 | { |
41729b81 | 123 | |
872870b2 JD |
124 | /* If Gtk+ is in use eventually gtk_main_iteration will be called, |
125 | unless retval is zero. */ | |
126 | #ifdef USE_GTK | |
127 | if (retval == 0) | |
128 | #endif | |
129 | while (g_main_context_pending (context)) | |
130 | g_main_context_dispatch (context); | |
131 | ||
132 | /* To not have to recalculate timeout, return like this. */ | |
41729b81 | 133 | if (retval == 0) |
872870b2 JD |
134 | { |
135 | retval = -1; | |
136 | errno = EINTR; | |
137 | } | |
138 | } | |
139 | ||
140 | return retval; | |
141 | } | |
0949d2b6 | 142 | #endif /* USE_GTK || HAVE_GCONF || HAVE_GSETTINGS */ |