GNOME Bugzilla – Bug 91683
G_WIN32_MSG_HANDLE can't be used on Cygwin
Last modified: 2004-12-22 21:47:04 UTC
G_WIN32_MSG_HANDLE isn't defined on Cygwin. Thus I'm using following patch to compile gdk for Cygwin. This code may be inefficient, but seems working anyway... --- gtk+-2.0.6.orig/gdk/win32/gdkevents-win32.c 2002-03-06 09:36:08.000000000 +0900 +++ gtk+-2.0.6/gdk/win32/gdkevents-win32.c 2002-08-24 00:38:16.000000000 +0900 @@ -126,7 +126,9 @@ NULL }; +#ifdef G_OS_WIN32 GPollFD event_poll_fd; +#endif static GdkWindow *current_window = NULL; static gint current_x, current_y; @@ -317,10 +319,12 @@ source = g_source_new (&event_funcs, sizeof (GSource)); g_source_set_priority (source, GDK_PRIORITY_EVENTS); +#ifdef G_OS_WIN32 event_poll_fd.fd = G_WIN32_MSG_HANDLE; event_poll_fd.events = G_IO_IN; g_source_add_poll (source, &event_poll_fd); +#endif g_source_set_can_recurse (source, TRUE); g_source_attach (source, NULL); @@ -3441,11 +3445,15 @@ GDK_THREADS_ENTER (); +#ifdef G_OS_WIN32 if (event_poll_fd.revents & G_IO_IN) +#endif retval = (_gdk_event_queue_find_first () != NULL) || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE); +#ifdef G_OS_WIN32 else retval = FALSE; +#endif GDK_THREADS_LEAVE ();
Hmm. I would like some more testing whether various GTK programs work on Cygwin with this fix before accepting this patch as such. As a comparison, how does the X11 backend behave if you don't g_source_add_poll() the X11 connection number? Wouldn't it be best to poll for Windows messages on Cygwin, too, but instead of using the magic G_WIN32_MSG_HANDLE "file descriptor" use a file descriptor resulting from opening /dev/windows? Can you call select() and read() on such? Or if polling for Windows messages really isn't necesary on Cygwin, is it necessary on native Win32?
According to cygwin-1.3.12-4/winsup/cygwin/fhandler_windows.cc we can call these functions on /dev/windows. | The following unix-style calls are supported: | | open ("/dev/windows", flags, mode=0) | - create a unix fd for message queue. | O_NONBLOCK flag controls the read() call behavior. | | read (fd, buf, len) | - return next message from queue. buf must point to MSG | structure, len must be >= sizeof (MSG). If read is set to | non-blocking and the queue is empty, read call returns -1 | immediately with errno set to EAGAIN, otherwise it blocks | untill the message will be received. | | write (fd, buf, len) | - send a message pointed by buf. len argument ignored. | | ioctl (fd, command, *param) | - control read()/write() behavior. | ioctl (fd, WINDOWS_POST, NULL): write() will PostMessage(); | ioctl (fd, WINDOWS_SEND, NULL): write() will SendMessage(); | ioctl (fd, WINDOWS_HWND, &hWnd): read() messages for | hWnd window. | | select () call marks read fd when any message posted to queue. Therefore I tried to use /dev/windows today. --- gtk+-2.0.6.orig/gdk/win32/gdkevents-win32.c 2002-03-06 09:36:08.000000000 +0900 +++ gtk+-2.0.6/gdk/win32/gdkevents-win32.c 2002-08-28 01:56:46.000000000 +0900 @@ -44,6 +44,11 @@ #include "gdkinput-win32.h" #include "gdkkeysyms.h" +#ifdef G_WITH_CYGWIN +#include <fcntl.h> +#include <errno.h> +#endif + #include <objbase.h> #if defined (__GNUC__) && defined (HAVE_DIMM_H) @@ -317,7 +322,13 @@ source = g_source_new (&event_funcs, sizeof (GSource)); g_source_set_priority (source, GDK_PRIORITY_EVENTS); +#ifdef G_WITH_CYGWIN + event_poll_fd.fd = open ("/dev/windows", O_RDONLY); + if (event_poll_fd.fd == -1) + g_error ("can't open \"/dev/windows\": %s", g_strerror (errno)); +#else event_poll_fd.fd = G_WIN32_MSG_HANDLE; +#endif event_poll_fd.events = G_IO_IN; g_source_add_poll (source, &event_poll_fd); I didn't replace PeekMessage() with read(), because - /dev/windows doesn't have its own buffer - I don't know how to translate PM_NOREMOVE This patch works much better than the previous patch. With the previous patch program sometimes hangs up. But with this patch it doesn't hang up in the same situation. And programs in gtk+-2.0.6/examples directory work fine with this patch.
Patch applied to HEAD and gtk-2-0.