1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-29 08:31:35 -08:00
emacs/src/xgselect.c
Paul Eggert 63cfb75f3a Include-file cleanup for src directory
Omit ‘#include "foo.h"’ unless the file needs foo.h (Bug#21707).
In a few cases, add ‘#include "foo.h"’ if the file needs foo.h
but does not include it directly.  As a general rule, a source
file should include foo.h if it needs the interfaces that foo.h
defines.
* src/alloc.c: Don’t include process.h.  Include dispextern.h,
systime.h.
* src/atimer.c: Don’t include blockinput.h.
* src/buffer.c: Include coding.h, systime.h.  Don’t include
keyboard.h, coding.h.
* src/callint.c: Don’t include commands.h, keymap.h.
* src/callproc.c: Don’t include character.h, ccl.h, composite.h,
systty.h, termhooks.h.
* src/casetab.c: Don’t include character.h.
* src/category.c: Don’t include charset.h, keymap.h.
* src/ccl.h: Don’t include character.h.
* src/character.c: Don’t include charset.h.
* src/charset.c: Don’t include disptab.h.
* src/chartab.c: Don’t include ccl.h.
* src/cm.c: Don’t include frame.h, termhooks.h.
* src/cmds.c: Don’t include window.h, dispextern.h.
* src/coding.c: Don’t include window.h, frame.h.
* src/composite.c: Include composite.h.  Don’t include window.h,
font.h.
* src/data.c: Don’t include syssignal.h, termhooks.h, font.h.
* src/dbusbind.c: Don’t include frame.h.
* src/decompress.c: Don’t include character.h.
* src/dired.c: Don’t include character.h, commands.h, charset.h.
* src/dispnew.c: Don’t include character.h, indent.h, intervals.h,
process.h, timespec.h.  Include systime.h.
* src/doc.c: Include coding.h.  Don’t include keyboard.h.
* src/editfns.c: Include composite.h.  Don’t include frame.h.
* src/emacs.c: Include fcntl.h, coding.h.  Don’t include
commands.h, systty.h..
* src/fileio.c: Don’t include intervals.h, dispextern.h.
Include composite.h.
* src/filelock.c: Don’t include character.h, systime.h.
* src/fns.c: Don’t include time.h, commands.h, keyboard.h,
keymap.h, frame.h, blockinput.h, xterm.h.  Include composite.h.
* src/font.c: Include termhooks.h.
* src/font.h: Don’t include ccl.h, frame.h.  Add forward decls of
struct composition_it, struct face, struct glyph_string.
* src/fontset.c: Don’t include buffer.h, ccl.h, keyboard.h,
intervals.h, window.h, termhooks.h.
* src/frame.c: Don’t include character.h, commands.h, font.h.
* src/frame.h: Don’t include dispextern.h.
* src/fringe.c: Don’t include character.h.
* src/ftcrfont.c: Don’t include dispextern.h, frame.h,
character.h, charset.h, fontset.h.
* src/ftfont.c: Don’t include frame.h, blockinput.h, coding.h,
fontset.h.
* src/ftxfont.c: Don’t include dispextern.h, character.h,
charset.h, fontset.h.
* src/gfilenotify.c: Don’t include frame.h, process.h.
* src/gtkutil.c: Include dispextern.h, frame.h, systime.h.
Don’t include syssignal.h, buffer.h, charset.h, font.h.
* src/gtkutil.h: Don’t include frame.h.
* src/image.c: Include fcntl.h and stdio.h instead of sysstdio.h.
Don’t include character.h.
* src/indent.c: Don’t include keyboard.h, termchar.h.
* src/inotify.c: Don’t include character.h, frame.h.
* src/insdel.c: Include composite.h.  Don’t include blockinput.h.
* src/intervals.c: Don’t include character.h, keyboard.h.
* src/intervals.h: Don’t include dispextern.h, composite.h.
* src/keyboard.c: Don’t include sysstdio.h, disptab.h, puresize.h.
Include coding.h.
* src/keyboard.h: Don’t incldue systime.h.
* src/keymap.c: Don’t include charset.h, frame.h.
* src/lread.c: Include dispextern.h and systime.h.
Don’t include frame.h.  Include systime.h.
* src/macros.c: Don’t include commands.h, character.h, buffer.h.
* src/menu.c: Include character.h, coding.h.  Don’t include
dispextern.h.
* src/menu.h: Don’t include systime.h.
* src/minibuf.c: Don’t include commands.h, dispextern.h, syntax.h,
intervals.h, termhooks.h.
* src/print.c: Include coding.h.  Don’t include keyboard.h,
window.h, dispextern.h, termchar.h, termhooks.h, font.h.
Add forward decl of struct terminal.
* src/process.c: Don’t include termhooks.h, commands.h,
dispextern.h, composite.h.
* src/region-cache.c: Don’t include character.h.
* src/scroll.c: Don’t include keyboard.h, window.h.
* src/search.c: Don’t include category.h, commands.h.
* src/sound.c: Don’t include dispextern.h.
* src/syntax.c: Don’t include command.h, keymap.h.
* src/sysdep.c: Don’t include window.h, dispextern.h.
* src/systime.h: Use ‘#ifdef emacs’, not ‘#ifdef EMACS_LISP_H’,
* src/term.c: Don’t include systty.h, intervals.h, xterm.h.
* src/terminal.c: Include character.h.
Don’t include charset.h, coding.h.
* src/textprop.c: Don’t include character.h.
* src/undo.c: Don’t include character.h, commands.h, window.h.
* src/unexsol.c: Don’t include character.h, charset.h.
* src/widget.c: Include widget.h.  Don’t include keyboard.h,
window.h, dispextern.h, blockinput.h, character.h, font.h.
* src/widgetprv.h: Don’t include widget.h.
* src/window.c: Don’t include character.h, menu.h, intervals.h.
* src/xdisp.c: Include composite.h, systime.h.  Don’t include
macros.h, process.h.
* src/xfaces.c: Don’t include charset.h, keyboard.h, termhooks.h,
intervals.h.
* src/xfns.c: Don’t include menu.h, character.h, intervals.h,
epaths.h, fontset.h, systime.h, atimer.h, termchar.h.
* src/xfont.c: Don’t include dispextern.h, fontset.h, ccl.h.
* src/xftfont.c: Don’t include dispextern.h, character.h, fontset.h.
* src/xgselect.c: Don’t include timespec.h, frame.h.
Include systime.h.
* src/xgselect.h: Don’t include time.h.
Use a forward decl to struct timespec instead.
* src/xmenu.c: Don’t include keymap.h, character.h, charset.h,
dispextern.h.  Include systime.h.
* src/xml.c: Don’t include character.h.
* src/xrdb.c [USE_MOTIF]: Don’t include keyboard.h.
* src/xselect.c: Don’t include dispextern.h, character.h,
buffer.h, process.h.
* src/xsmfns.c: Don’t include systime.h, sysselect.h.
* src/xterm.c: Don’t include syssignal.h, charset.h, disptab.h,
intervals.h process.h, keymap.h, xgselect.h.  Include composite.h.
2015-10-20 18:35:53 -07:00

175 lines
5.1 KiB
C

/* Function for handling the GLib event loop.
Copyright (C) 2009-2015 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include "xgselect.h"
#ifdef HAVE_GLIB
#include <glib.h>
#include <errno.h>
#include <stdbool.h>
#include "blockinput.h"
#include "systime.h"
/* `xg_select' is a `pselect' replacement. Why do we need a separate function?
1. Timeouts. Glib and Gtk rely on timer events. If we did pselect
with a greater timeout then the one scheduled by Glib, we would
not allow Glib to process its timer events. We want Glib to
work smoothly, so we need to reduce our timeout to match Glib.
2. Descriptors. Glib may listen to more file descriptors than we do.
So we add Glib descriptors to our pselect pool, but we don't change
the value returned by the function. The return value matches only
the descriptors passed as arguments, making it compatible with
plain pselect. */
int
xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds,
struct timespec const *timeout, sigset_t const *sigmask)
{
fd_set all_rfds, all_wfds;
struct timespec tmo;
struct timespec const *tmop = timeout;
GMainContext *context;
bool have_wfds = wfds != NULL;
GPollFD gfds_buf[128];
GPollFD *gfds = gfds_buf;
int gfds_size = ARRAYELTS (gfds_buf);
int n_gfds, retval = 0, our_fds = 0, max_fds = fds_lim - 1;
bool context_acquired = false;
int i, nfds, tmo_in_millisec;
bool need_to_dispatch;
USE_SAFE_ALLOCA;
context = g_main_context_default ();
context_acquired = g_main_context_acquire (context);
/* FIXME: If we couldn't acquire the context, we just silently proceed
because this function handles more than just glib file descriptors.
Note that, as implemented, this failure is completely silent: there is
no feedback to the caller. */
if (rfds) all_rfds = *rfds;
else FD_ZERO (&all_rfds);
if (wfds) all_wfds = *wfds;
else FD_ZERO (&all_wfds);
n_gfds = (context_acquired
? g_main_context_query (context, G_PRIORITY_LOW, &tmo_in_millisec,
gfds, gfds_size)
: -1);
if (gfds_size < n_gfds)
{
SAFE_NALLOCA (gfds, sizeof *gfds, n_gfds);
gfds_size = n_gfds;
n_gfds = g_main_context_query (context, G_PRIORITY_LOW, &tmo_in_millisec,
gfds, gfds_size);
}
for (i = 0; i < n_gfds; ++i)
{
if (gfds[i].events & G_IO_IN)
{
FD_SET (gfds[i].fd, &all_rfds);
if (gfds[i].fd > max_fds) max_fds = gfds[i].fd;
}
if (gfds[i].events & G_IO_OUT)
{
FD_SET (gfds[i].fd, &all_wfds);
if (gfds[i].fd > max_fds) max_fds = gfds[i].fd;
have_wfds = true;
}
}
SAFE_FREE ();
if (n_gfds >= 0 && tmo_in_millisec >= 0)
{
tmo = make_timespec (tmo_in_millisec / 1000,
1000 * 1000 * (tmo_in_millisec % 1000));
if (!timeout || timespec_cmp (tmo, *timeout) < 0)
tmop = &tmo;
}
fds_lim = max_fds + 1;
nfds = pselect (fds_lim, &all_rfds, have_wfds ? &all_wfds : NULL,
efds, tmop, sigmask);
if (nfds < 0)
retval = nfds;
else if (nfds > 0)
{
for (i = 0; i < fds_lim; ++i)
{
if (FD_ISSET (i, &all_rfds))
{
if (rfds && FD_ISSET (i, rfds)) ++retval;
else ++our_fds;
}
else if (rfds)
FD_CLR (i, rfds);
if (have_wfds && FD_ISSET (i, &all_wfds))
{
if (wfds && FD_ISSET (i, wfds)) ++retval;
else ++our_fds;
}
else if (wfds)
FD_CLR (i, wfds);
if (efds && FD_ISSET (i, efds))
++retval;
}
}
/* If Gtk+ is in use eventually gtk_main_iteration will be called,
unless retval is zero. */
#ifdef USE_GTK
need_to_dispatch = retval == 0;
#else
need_to_dispatch = true;
#endif
if (need_to_dispatch)
{
int pselect_errno = errno;
/* Prevent g_main_dispatch recursion, that would occur without
block_input wrapper, because event handlers call
unblock_input. Event loop recursion was causing Bug#15801. */
block_input ();
while (g_main_context_pending (context))
g_main_context_dispatch (context);
unblock_input ();
errno = pselect_errno;
}
if (context_acquired)
g_main_context_release (context);
/* To not have to recalculate timeout, return like this. */
if ((our_fds > 0 || (nfds == 0 && tmop == &tmo)) && (retval == 0))
{
retval = -1;
errno = EINTR;
}
return retval;
}
#endif /* HAVE_GLIB */