X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/dd118a073d7800973c5a7e3e74e541c6dc626392..2a205424e771703217ce8c6b4252d810d3310cd2:/src/w32xfns.c diff --git a/src/w32xfns.c b/src/w32xfns.c index e478bc2453..ba705d9498 100644 --- a/src/w32xfns.c +++ b/src/w32xfns.c @@ -1,5 +1,5 @@ -/* Functions taken directly from X sources - Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation. +/* Functions taken directly from X sources for use with the Microsoft W32 API. + Copyright (C) 1989, 1992, 1993, 1994, 1995, 1999 Free Software Foundation. This file is part of GNU Emacs. @@ -15,13 +15,17 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ -#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" @@ -31,41 +35,124 @@ Boston, MA 02111-1307, USA. */ CRITICAL_SECTION critsect; extern HANDLE keyboard_handle; -HANDLE hEvent = NULL; +HANDLE input_available = NULL; +HANDLE interrupt_handle = NULL; -void +void init_crit () { InitializeCriticalSection (&critsect); - keyboard_handle = hEvent = CreateEvent (NULL, FALSE, FALSE, NULL); + + /* 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); + + /* interrupt_handle is signalled when quit (C-g) is detected, so that + blocking system calls can be interrupted. We make it a manual + reset event, so that if we should ever have multiple threads + performing system calls, they will all be interrupted (I'm guessing + that would the right response). Note that we use PulseEvent to + signal this event, so that it never remains signalled. */ + interrupt_handle = CreateEvent (NULL, TRUE, FALSE, NULL); } -void -enter_crit () +void +delete_crit () { - EnterCriticalSection (&critsect); + DeleteCriticalSection (&critsect); + + if (input_available) + { + CloseHandle (input_available); + input_available = NULL; + } + if (interrupt_handle) + { + CloseHandle (interrupt_handle); + interrupt_handle = NULL; + } } -void -leave_crit () +void +signal_quit () { - LeaveCriticalSection (&critsect); + /* Make sure this event never remains signalled; if the main thread + isn't in a blocking call, then this should do nothing. */ + PulseEvent (interrupt_handle); } -void -delete_crit () +void +select_palette (FRAME_PTR f, HDC hdc) { - DeleteCriticalSection (&critsect); - if (hEvent) + struct w32_display_info *display_info = FRAME_W32_DISPLAY_INFO (f); + + if (!display_info->has_palette) + return; + + if (display_info->palette == 0) + return; + + if (!NILP (Vw32_enable_palette)) + f->output_data.w32->old_palette = + SelectPalette (hdc, display_info->palette, FALSE); + else + f->output_data.w32->old_palette = NULL; + + if (RealizePalette (hdc)) + { + Lisp_Object frame, framelist; + FOR_EACH_FRAME (framelist, frame) { - CloseHandle (hEvent); - hEvent = NULL; + SET_FRAME_GARBAGED (XFRAME (frame)); } + } +} + +void +deselect_palette (FRAME_PTR f, HDC hdc) +{ + if (f->output_data.w32->old_palette) + SelectPalette (hdc, f->output_data.w32->old_palette, FALSE); +} + +/* 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) +{ + HDC hdc; + + if (f->output_method != output_w32) + abort (); + + enter_crit (); + + hdc = GetDC (f->output_data.w32->window_desc); + + /* If this gets called during startup before the frame is valid, + there is a chance of corrupting random data or crashing. */ + if (hdc) + select_palette (f, hdc); + + return hdc; +} + +int +release_frame_dc (FRAME_PTR f, HDC hdc) +{ + int ret; + + deselect_palette (f, hdc); + ret = ReleaseDC (f->output_data.w32->window_desc, hdc); + + leave_crit (); + + return ret; } typedef struct int_msg { - Win32Msg w32msg; + W32Msg w32msg; struct int_msg *lpNext; } int_msg; @@ -73,33 +160,33 @@ int_msg *lpHead = NULL; int_msg *lpTail = NULL; int nQueue = 0; -BOOL +BOOL get_next_msg (lpmsg, bWait) - Win32Msg * lpmsg; + W32Msg * lpmsg; BOOL bWait; { BOOL bRet = FALSE; - + enter_crit (); - + /* The while loop takes care of multiple sets */ - + while (!nQueue && bWait) { leave_crit (); - WaitForSingleObject (hEvent, INFINITE); + WaitForSingleObject (input_available, INFINITE); enter_crit (); } - + if (nQueue) { - bcopy (&(lpHead->w32msg), lpmsg, sizeof (Win32Msg)); + bcopy (&(lpHead->w32msg), lpmsg, sizeof (W32Msg)); { int_msg * lpCur = lpHead; - + lpHead = lpHead->lpNext; - + myfree (lpCur); } @@ -107,21 +194,25 @@ get_next_msg (lpmsg, bWait) bRet = TRUE; } - + + if (nQueue == 0) + ResetEvent (input_available); + leave_crit (); - + return (bRet); } -BOOL +BOOL post_msg (lpmsg) - Win32Msg * lpmsg; + W32Msg * lpmsg; { int_msg * lpNew = (int_msg *) myalloc (sizeof (int_msg)); - if (!lpNew) return (FALSE); + if (!lpNew) + return (FALSE); - bcopy (lpmsg, &(lpNew->w32msg), sizeof (Win32Msg)); + bcopy (lpmsg, &(lpNew->w32msg), sizeof (W32Msg)); lpNew->lpNext = NULL; enter_crit (); @@ -130,19 +221,53 @@ post_msg (lpmsg) { lpTail->lpNext = lpNew; } - else + else { lpHead = lpNew; - SetEvent (hEvent); } lpTail = lpNew; - + SetEvent (input_available); + + leave_crit (); + + return (TRUE); +} + +BOOL +prepend_msg (W32Msg *lpmsg) +{ + int_msg * lpNew = (int_msg *) myalloc (sizeof (int_msg)); + + if (!lpNew) + return (FALSE); + + bcopy (lpmsg, &(lpNew->w32msg), sizeof (W32Msg)); + + enter_crit (); + + nQueue++; + lpNew->lpNext = lpHead; + lpHead = lpNew; + leave_crit (); return (TRUE); } +/* Process all messages in the current thread's queue. */ +void +drain_message_queue () +{ + MSG msg; + while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage (&msg); + DispatchMessage (&msg); + } +} + + /* * XParseGeometry parses strings of the form * "=x{+-}{+-}", where @@ -152,7 +277,7 @@ post_msg (lpmsg) * 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. + * not found, the corresponding argument is left unchanged. */ static int @@ -162,7 +287,7 @@ read_integer (string, NextString) { register int Result = 0; int Sign = 1; - + if (*string == '+') string++; else if (*string == '-') @@ -181,7 +306,7 @@ read_integer (string, NextString) return (-Result); } -int +int XParseGeometry (string, x, y, width, height) char *string; int *x, *y; @@ -192,23 +317,23 @@ XParseGeometry (string, x, y, width, height) 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') + if (*strind != '+' && *strind != '-' && *strind != 'x') { tempWidth = read_integer (strind, &nextCharacter); - if (strind == nextCharacter) + if (strind == nextCharacter) return (0); strind = nextCharacter; mask |= WidthValue; } - - if (*strind == 'x' || *strind == 'X') - { + + if (*strind == 'x' || *strind == 'X') + { strind++; tempHeight = read_integer (strind, &nextCharacter); if (strind == nextCharacter) @@ -216,10 +341,10 @@ XParseGeometry (string, x, y, width, height) strind = nextCharacter; mask |= HeightValue; } - - if ((*strind == '+') || (*strind == '-')) + + if ((*strind == '+') || (*strind == '-')) { - if (*strind == '-') + if (*strind == '-') { strind++; tempX = -read_integer (strind, &nextCharacter); @@ -230,7 +355,7 @@ XParseGeometry (string, x, y, width, height) } else - { + { strind++; tempX = read_integer (strind, &nextCharacter); if (strind == nextCharacter) @@ -238,9 +363,9 @@ XParseGeometry (string, x, y, width, height) strind = nextCharacter; } mask |= XValue; - if ((*strind == '+') || (*strind == '-')) + if ((*strind == '+') || (*strind == '-')) { - if (*strind == '-') + if (*strind == '-') { strind++; tempY = -read_integer (strind, &nextCharacter); @@ -261,12 +386,12 @@ XParseGeometry (string, x, y, width, height) mask |= YValue; } } - + /* If strind isn't at the end of the string the it's an invalid geometry specification. */ - + if (*strind != '\0') return (0); - + if (mask & XValue) *x = tempX; if (mask & YValue) @@ -278,17 +403,12 @@ XParseGeometry (string, x, y, width, height) return (mask); } -/* We can use mouse menus when we wish. */ -int -have_menus_p (void) -{ - return 1; -} - -/* x_sync is a no-op on Win32. */ +/* x_sync is a no-op on W32. */ void x_sync (f) void *f; { } +/* arch-tag: 4fab3695-4ad3-4cc6-a2b1-fd2c67dc46be + (do not change this comment) */