X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/e8757f091a502b858912a4c267210e009227d6e6..8833692b29ba11c34413d6793cf6d222ccdd930b:/src/w32xfns.c diff --git a/src/w32xfns.c b/src/w32xfns.c index 018dd14cb8..b5b22c9aa5 100644 --- a/src/w32xfns.c +++ b/src/w32xfns.c @@ -1,12 +1,13 @@ /* Functions taken directly from X sources for use with the Microsoft Windows API. - Copyright (C) 1989, 1992-1995, 1999, 2001-2012 Free Software Foundation, Inc. + Copyright (C) 1989, 1992-1995, 1999, 2001-2016 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. +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 @@ -19,20 +20,22 @@ along with GNU Emacs. If not, see . */ #include #include #include +#include +#include + #include "lisp.h" -#include "keyboard.h" #include "frame.h" -#include "charset.h" -#include "fontset.h" -#include "blockinput.h" #include "w32term.h" -#include "windowsx.h" #define myalloc(cb) GlobalAllocPtr (GPTR, cb) #define myfree(lp) GlobalFreePtr (lp) CRITICAL_SECTION critsect; + +#ifdef WINDOWSNT extern HANDLE keyboard_handle; +#endif /* WINDOWSNT */ + HANDLE input_available = NULL; HANDLE interrupt_handle = NULL; @@ -43,7 +46,26 @@ init_crit (void) /* For safety, input_available should only be reset by get_next_msg when the input queue is empty, so make it a manual reset event. */ - keyboard_handle = input_available = CreateEvent (NULL, TRUE, FALSE, NULL); + input_available = CreateEvent (NULL, TRUE, FALSE, NULL); + +#if HAVE_W32NOTIFY + /* Initialize the linked list of notifications sets that will be + used to communicate between the watching worker threads and the + main thread. */ + notifications_set_head = malloc (sizeof(struct notifications_set)); + if (notifications_set_head) + { + memset (notifications_set_head, 0, sizeof(struct notifications_set)); + notifications_set_head->next + = notifications_set_head->prev = notifications_set_head; + } + else + DebPrint(("Out of memory: can't initialize notifications sets.")); +#endif + +#ifdef WINDOWSNT + keyboard_handle = input_available; +#endif /* WINDOWSNT */ /* interrupt_handle is signaled when quit (C-g) is detected, so that blocking system calls can be interrupted. We make it a manual @@ -69,6 +91,23 @@ delete_crit (void) CloseHandle (interrupt_handle); interrupt_handle = NULL; } + +#if HAVE_W32NOTIFY + if (notifications_set_head) + { + /* Free any remaining notifications set that could be left over. */ + while (notifications_set_head->next != notifications_set_head) + { + struct notifications_set *ns = notifications_set_head->next; + notifications_set_head->next = ns->next; + ns->next->prev = notifications_set_head; + if (ns->notifications) + free (ns->notifications); + free (ns); + } + } + free (notifications_set_head); +#endif } void @@ -80,9 +119,9 @@ signal_quit (void) } void -select_palette (FRAME_PTR f, HDC hdc) +select_palette (struct frame *f, HDC hdc) { - struct w32_display_info *display_info = FRAME_W32_DISPLAY_INFO (f); + struct w32_display_info *display_info = FRAME_DISPLAY_INFO (f); if (!display_info->has_palette) return; @@ -107,7 +146,7 @@ select_palette (FRAME_PTR f, HDC hdc) } void -deselect_palette (FRAME_PTR f, HDC hdc) +deselect_palette (struct frame *f, HDC hdc) { if (f->output_data.w32->old_palette) SelectPalette (hdc, f->output_data.w32->old_palette, FALSE); @@ -116,7 +155,7 @@ deselect_palette (FRAME_PTR f, HDC hdc) /* Get a DC for frame and select palette for drawing; force an update of all frames if palette's mapping changes. */ HDC -get_frame_dc (FRAME_PTR f) +get_frame_dc (struct frame *f) { HDC hdc; @@ -136,7 +175,7 @@ get_frame_dc (FRAME_PTR f) } int -release_frame_dc (FRAME_PTR f, HDC hdc) +release_frame_dc (struct frame *f, HDC hdc) { int ret; @@ -240,6 +279,22 @@ get_next_msg (W32Msg * lpmsg, BOOL bWait) return (bRet); } +extern char * w32_strerror (int error_no); + +/* Tell the main thread that we have input available; if the main + thread is blocked in select(), we wake it up here. */ +static void +notify_msg_ready (void) +{ + SetEvent (input_available); + +#ifdef CYGWIN + /* Wakes up the main thread, which is blocked select()ing for /dev/windows, + among other files. */ + (void) PostThreadMessage (dwMainThreadId, WM_EMACS_INPUT_READY, 0, 0); +#endif /* CYGWIN */ +} + BOOL post_msg (W32Msg * lpmsg) { @@ -263,8 +318,7 @@ post_msg (W32Msg * lpmsg) } lpTail = lpNew; - SetEvent (input_available); - + notify_msg_ready (); leave_crit (); return (TRUE); @@ -285,26 +339,26 @@ prepend_msg (W32Msg *lpmsg) nQueue++; lpNew->lpNext = lpHead; lpHead = lpNew; - + notify_msg_ready (); leave_crit (); return (TRUE); } -/* Process all messages in the current thread's queue. */ -void +/* Process all messages in the current thread's queue. Value is 1 if + one of these messages was WM_EMACS_FILENOTIFY, zero otherwise. */ +int drain_message_queue (void) { MSG msg; + int retval = 0; + while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) { + if (msg.message == WM_EMACS_FILENOTIFY) + retval = 1; TranslateMessage (&msg); DispatchMessage (&msg); } -} - -/* x_sync is a no-op on W32. */ -void -x_sync (struct frame *f) -{ + return retval; }