1 /* Functions taken directly from X sources for use with the Microsoft W32 API.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1999, 2001, 2002, 2003,
3 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
29 #include "blockinput.h"
33 #define myalloc(cb) GlobalAllocPtr (GPTR, cb)
34 #define myfree(lp) GlobalFreePtr (lp)
36 CRITICAL_SECTION critsect
;
37 extern HANDLE keyboard_handle
;
38 HANDLE input_available
= NULL
;
39 HANDLE interrupt_handle
= NULL
;
44 InitializeCriticalSection (&critsect
);
46 /* For safety, input_available should only be reset by get_next_msg
47 when the input queue is empty, so make it a manual reset event. */
48 keyboard_handle
= input_available
= CreateEvent (NULL
, TRUE
, FALSE
, NULL
);
50 /* interrupt_handle is signaled when quit (C-g) is detected, so that
51 blocking system calls can be interrupted. We make it a manual
52 reset event, so that if we should ever have multiple threads
53 performing system calls, they will all be interrupted (I'm guessing
54 that would the right response). Note that we use PulseEvent to
55 signal this event, so that it never remains signaled. */
56 interrupt_handle
= CreateEvent (NULL
, TRUE
, FALSE
, NULL
);
62 DeleteCriticalSection (&critsect
);
66 CloseHandle (input_available
);
67 input_available
= NULL
;
71 CloseHandle (interrupt_handle
);
72 interrupt_handle
= NULL
;
79 /* Make sure this event never remains signaled; if the main thread
80 isn't in a blocking call, then this should do nothing. */
81 PulseEvent (interrupt_handle
);
85 select_palette (FRAME_PTR f
, HDC hdc
)
87 struct w32_display_info
*display_info
= FRAME_W32_DISPLAY_INFO (f
);
89 if (!display_info
->has_palette
)
92 if (display_info
->palette
== 0)
95 if (!NILP (Vw32_enable_palette
))
96 f
->output_data
.w32
->old_palette
=
97 SelectPalette (hdc
, display_info
->palette
, FALSE
);
99 f
->output_data
.w32
->old_palette
= NULL
;
101 if (RealizePalette (hdc
))
103 Lisp_Object frame
, framelist
;
104 FOR_EACH_FRAME (framelist
, frame
)
106 SET_FRAME_GARBAGED (XFRAME (frame
));
112 deselect_palette (FRAME_PTR f
, HDC hdc
)
114 if (f
->output_data
.w32
->old_palette
)
115 SelectPalette (hdc
, f
->output_data
.w32
->old_palette
, FALSE
);
118 /* Get a DC for frame and select palette for drawing; force an update of
119 all frames if palette's mapping changes. */
121 get_frame_dc (FRAME_PTR f
)
125 if (f
->output_method
!= output_w32
)
130 hdc
= GetDC (f
->output_data
.w32
->window_desc
);
132 /* If this gets called during startup before the frame is valid,
133 there is a chance of corrupting random data or crashing. */
135 select_palette (f
, hdc
);
141 release_frame_dc (FRAME_PTR f
, HDC hdc
)
145 deselect_palette (f
, hdc
);
146 ret
= ReleaseDC (f
->output_data
.w32
->window_desc
, hdc
);
153 typedef struct int_msg
156 struct int_msg
*lpNext
;
159 int_msg
*lpHead
= NULL
;
160 int_msg
*lpTail
= NULL
;
164 get_next_msg (lpmsg
, bWait
)
172 /* The while loop takes care of multiple sets */
174 while (!nQueue
&& bWait
)
177 WaitForSingleObject (input_available
, INFINITE
);
183 bcopy (&(lpHead
->w32msg
), lpmsg
, sizeof (W32Msg
));
186 int_msg
* lpCur
= lpHead
;
188 lpHead
= lpHead
->lpNext
;
194 /* Consolidate WM_PAINT messages to optimise redrawing. */
195 if (lpmsg
->msg
.message
== WM_PAINT
&& nQueue
)
197 int_msg
* lpCur
= lpHead
;
198 int_msg
* lpPrev
= NULL
;
199 int_msg
* lpNext
= NULL
;
201 while (lpCur
&& nQueue
)
203 lpNext
= lpCur
->lpNext
;
204 if (lpCur
->w32msg
.msg
.message
== WM_PAINT
)
206 /* Remove this message from the queue. */
208 lpPrev
->lpNext
= lpNext
;
215 /* Adjust clip rectangle to cover both. */
216 if (!UnionRect (&(lpmsg
->rect
), &(lpmsg
->rect
),
217 &(lpCur
->w32msg
.rect
)))
219 SetRectEmpty(&(lpmsg
->rect
));
240 ResetEvent (input_available
);
251 int_msg
* lpNew
= (int_msg
*) myalloc (sizeof (int_msg
));
256 bcopy (lpmsg
, &(lpNew
->w32msg
), sizeof (W32Msg
));
257 lpNew
->lpNext
= NULL
;
263 lpTail
->lpNext
= lpNew
;
271 SetEvent (input_available
);
279 prepend_msg (W32Msg
*lpmsg
)
281 int_msg
* lpNew
= (int_msg
*) myalloc (sizeof (int_msg
));
286 bcopy (lpmsg
, &(lpNew
->w32msg
), sizeof (W32Msg
));
291 lpNew
->lpNext
= lpHead
;
299 /* Process all messages in the current thread's queue. */
301 drain_message_queue ()
304 while (PeekMessage (&msg
, NULL
, 0, 0, PM_REMOVE
))
306 TranslateMessage (&msg
);
307 DispatchMessage (&msg
);
313 * XParseGeometry parses strings of the form
314 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
315 * width, height, xoffset, and yoffset are unsigned integers.
316 * Example: "=80x24+300-49"
317 * The equal sign is optional.
318 * It returns a bitmask that indicates which of the four values
319 * were actually found in the string. For each value found,
320 * the corresponding argument is updated; for each value
321 * not found, the corresponding argument is left unchanged.
325 read_integer (string
, NextString
)
326 register char *string
;
329 register int Result
= 0;
334 else if (*string
== '-')
339 for (; (*string
>= '0') && (*string
<= '9'); string
++)
341 Result
= (Result
* 10) + (*string
- '0');
343 *NextString
= string
;
351 XParseGeometry (string
, x
, y
, width
, height
)
354 unsigned int *width
, *height
; /* RETURN */
357 register char *strind
;
358 unsigned int tempWidth
, tempHeight
;
362 if ((string
== NULL
) || (*string
== '\0')) return (mask
);
364 string
++; /* ignore possible '=' at beg of geometry spec */
366 strind
= (char *)string
;
367 if (*strind
!= '+' && *strind
!= '-' && *strind
!= 'x')
369 tempWidth
= read_integer (strind
, &nextCharacter
);
370 if (strind
== nextCharacter
)
372 strind
= nextCharacter
;
376 if (*strind
== 'x' || *strind
== 'X')
379 tempHeight
= read_integer (strind
, &nextCharacter
);
380 if (strind
== nextCharacter
)
382 strind
= nextCharacter
;
386 if ((*strind
== '+') || (*strind
== '-'))
391 tempX
= -read_integer (strind
, &nextCharacter
);
392 if (strind
== nextCharacter
)
394 strind
= nextCharacter
;
401 tempX
= read_integer (strind
, &nextCharacter
);
402 if (strind
== nextCharacter
)
404 strind
= nextCharacter
;
407 if ((*strind
== '+') || (*strind
== '-'))
412 tempY
= -read_integer (strind
, &nextCharacter
);
413 if (strind
== nextCharacter
)
415 strind
= nextCharacter
;
422 tempY
= read_integer (strind
, &nextCharacter
);
423 if (strind
== nextCharacter
)
425 strind
= nextCharacter
;
431 /* If strind isn't at the end of the string the it's an invalid
432 geometry specification. */
434 if (*strind
!= '\0') return (0);
440 if (mask
& WidthValue
)
442 if (mask
& HeightValue
)
443 *height
= tempHeight
;
447 /* x_sync is a no-op on W32. */
454 /* arch-tag: 4fab3695-4ad3-4cc6-a2b1-fd2c67dc46be
455 (do not change this comment) */