]> code.delx.au - gnu-emacs/blobdiff - src/w32xfns.c
Merge from origin/emacs-25
[gnu-emacs] / src / w32xfns.c
index fbbf11bd65c574958840f5f7e1c79e1c5ea4b3f7..b5b22c9aa5207435d509e2219031a4b7c634ca0f 100644 (file)
@@ -1,12 +1,13 @@
-/* Functions taken directly from X sources for use with the Microsoft W32 API.
-   Copyright (C) 1989, 1992-1995, 1999, 2001-2011  Free Software Foundation, Inc.
+/* Functions taken directly from X sources for use with the Microsoft Windows API.
+   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,21 +20,22 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <config.h>
 #include <signal.h>
 #include <stdio.h>
-#include <setjmp.h>
+#include <windows.h>
+#include <windowsx.h>
+
 #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;
 
@@ -44,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
@@ -70,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
@@ -81,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;
@@ -108,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);
@@ -117,12 +155,12 @@ 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;
 
   if (f->output_method != output_w32)
-    abort ();
+    emacs_abort ();
 
   enter_crit ();
 
@@ -137,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;
 
@@ -188,7 +226,7 @@ get_next_msg (W32Msg * lpmsg, BOOL bWait)
       }
 
       nQueue--;
-      /* Consolidate WM_PAINT messages to optimise redrawing.  */
+      /* Consolidate WM_PAINT messages to optimize redrawing.  */
       if (lpmsg->msg.message == WM_PAINT && nQueue)
         {
           int_msg * lpCur = lpHead;
@@ -241,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)
 {
@@ -264,8 +318,7 @@ post_msg (W32Msg * lpmsg)
     }
 
   lpTail = lpNew;
-  SetEvent (input_available);
-
+  notify_msg_ready ();
   leave_crit ();
 
   return (TRUE);
@@ -286,159 +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);
     }
+  return retval;
 }
-
-
-/*
- *    XParseGeometry parses strings of the form
- *   "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
- *   width, height, xoffset, and yoffset are unsigned integers.
- *   Example:  "=80x24+300-49"
- *   The equal sign is optional.
- *   It returns a bitmask that indicates which of the four values
- *   were actually found in the string.  For each value found,
- *   the corresponding argument is updated;  for each value
- *   not found, the corresponding argument is left unchanged.
- */
-
-static int
-read_integer (register char *string, char **NextString)
-{
-  register int Result = 0;
-  int Sign = 1;
-
-  if (*string == '+')
-    string++;
-  else if (*string == '-')
-    {
-      string++;
-      Sign = -1;
-    }
-  for (; (*string >= '0') && (*string <= '9'); string++)
-    {
-      Result = (Result * 10) + (*string - '0');
-    }
-  *NextString = string;
-  if (Sign >= 0)
-    return (Result);
-  else
-    return (-Result);
-}
-
-int
-XParseGeometry (char *string,
-               int *x, int *y,
-               unsigned int *width, unsigned int *height)
-{
-  int mask = NoValue;
-  register char *strind;
-  unsigned int tempWidth, tempHeight;
-  int tempX, tempY;
-  char *nextCharacter;
-
-  if ((string == NULL) || (*string == '\0')) return (mask);
-  if (*string == '=')
-    string++;  /* ignore possible '=' at beg of geometry spec */
-
-  strind = (char *)string;
-  if (*strind != '+' && *strind != '-' && *strind != 'x')
-    {
-      tempWidth = read_integer (strind, &nextCharacter);
-      if (strind == nextCharacter)
-       return (0);
-      strind = nextCharacter;
-      mask |= WidthValue;
-    }
-
-  if (*strind == 'x' || *strind == 'X')
-    {
-      strind++;
-      tempHeight = read_integer (strind, &nextCharacter);
-      if (strind == nextCharacter)
-       return (0);
-      strind = nextCharacter;
-      mask |= HeightValue;
-    }
-
-  if ((*strind == '+') || (*strind == '-'))
-    {
-      if (*strind == '-')
-       {
-         strind++;
-         tempX = -read_integer (strind, &nextCharacter);
-         if (strind == nextCharacter)
-           return (0);
-         strind = nextCharacter;
-         mask |= XNegative;
-
-       }
-      else
-       {
-         strind++;
-         tempX = read_integer (strind, &nextCharacter);
-         if (strind == nextCharacter)
-           return (0);
-         strind = nextCharacter;
-       }
-      mask |= XValue;
-      if ((*strind == '+') || (*strind == '-'))
-       {
-         if (*strind == '-')
-           {
-             strind++;
-             tempY = -read_integer (strind, &nextCharacter);
-             if (strind == nextCharacter)
-               return (0);
-             strind = nextCharacter;
-             mask |= YNegative;
-           }
-         else
-           {
-             strind++;
-             tempY = read_integer (strind, &nextCharacter);
-             if (strind == nextCharacter)
-               return (0);
-             strind = nextCharacter;
-           }
-         mask |= YValue;
-       }
-    }
-
-  /* If strind isn't at the end of the string then it's an invalid
-     geometry specification. */
-
-  if (*strind != '\0') return (0);
-
-  if (mask & XValue)
-    *x = tempX;
-  if (mask & YValue)
-    *y = tempY;
-  if (mask & WidthValue)
-    *width = tempWidth;
-  if (mask & HeightValue)
-    *height = tempHeight;
-  return (mask);
-}
-
-/* x_sync is a no-op on W32.  */
-void
-x_sync (void *f)
-{
-}
-