*** empty log message ***
[emacs.git] / src / w32xfns.c
blob689a2829eb37e251621ae1a5b17ff2f435fcd6c0
1 /* Functions taken directly from X sources for use with the Microsoft W32 API.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1999 Free Software Foundation.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 #include <config.h>
22 #include <signal.h>
23 #include <stdio.h>
24 #include "lisp.h"
25 #include "keyboard.h"
26 #include "frame.h"
27 #include "charset.h"
28 #include "fontset.h"
29 #include "blockinput.h"
30 #include "w32term.h"
31 #include "windowsx.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;
41 void
42 init_crit ()
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 signalled 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 signalled. */
56 interrupt_handle = CreateEvent (NULL, TRUE, FALSE, NULL);
59 void
60 delete_crit ()
62 DeleteCriticalSection (&critsect);
64 if (input_available)
66 CloseHandle (input_available);
67 input_available = NULL;
69 if (interrupt_handle)
71 CloseHandle (interrupt_handle);
72 interrupt_handle = NULL;
76 void
77 signal_quit ()
79 /* Make sure this event never remains signalled; if the main thread
80 isn't in a blocking call, then this should do nothing. */
81 PulseEvent (interrupt_handle);
84 void
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)
90 return;
92 if (display_info->palette == 0)
93 return;
95 if (!NILP (Vw32_enable_palette))
96 f->output_data.w32->old_palette =
97 SelectPalette (hdc, display_info->palette, FALSE);
98 else
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));
111 void
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)
123 HDC hdc;
125 if (f->output_method != output_w32)
126 abort ();
128 enter_crit ();
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. */
134 if (hdc)
135 select_palette (f, hdc);
137 return hdc;
141 release_frame_dc (FRAME_PTR f, HDC hdc)
143 int ret;
145 deselect_palette (f, hdc);
146 ret = ReleaseDC (f->output_data.w32->window_desc, hdc);
148 leave_crit ();
150 return ret;
153 typedef struct int_msg
155 W32Msg w32msg;
156 struct int_msg *lpNext;
157 } int_msg;
159 int_msg *lpHead = NULL;
160 int_msg *lpTail = NULL;
161 int nQueue = 0;
163 BOOL
164 get_next_msg (lpmsg, bWait)
165 W32Msg * lpmsg;
166 BOOL bWait;
168 BOOL bRet = FALSE;
170 enter_crit ();
172 /* The while loop takes care of multiple sets */
174 while (!nQueue && bWait)
176 leave_crit ();
177 WaitForSingleObject (input_available, INFINITE);
178 enter_crit ();
181 if (nQueue)
183 bcopy (&(lpHead->w32msg), lpmsg, sizeof (W32Msg));
186 int_msg * lpCur = lpHead;
188 lpHead = lpHead->lpNext;
190 myfree (lpCur);
193 nQueue--;
195 bRet = TRUE;
198 if (nQueue == 0)
199 ResetEvent (input_available);
201 leave_crit ();
203 return (bRet);
206 BOOL
207 post_msg (lpmsg)
208 W32Msg * lpmsg;
210 int_msg * lpNew = (int_msg *) myalloc (sizeof (int_msg));
212 if (!lpNew)
213 return (FALSE);
215 bcopy (lpmsg, &(lpNew->w32msg), sizeof (W32Msg));
216 lpNew->lpNext = NULL;
218 enter_crit ();
220 if (nQueue++)
222 lpTail->lpNext = lpNew;
224 else
226 lpHead = lpNew;
229 lpTail = lpNew;
230 SetEvent (input_available);
232 leave_crit ();
234 return (TRUE);
237 BOOL
238 prepend_msg (W32Msg *lpmsg)
240 int_msg * lpNew = (int_msg *) myalloc (sizeof (int_msg));
242 if (!lpNew)
243 return (FALSE);
245 bcopy (lpmsg, &(lpNew->w32msg), sizeof (W32Msg));
247 enter_crit ();
249 nQueue++;
250 lpNew->lpNext = lpHead;
251 lpHead = lpNew;
253 leave_crit ();
255 return (TRUE);
258 /* Process all messages in the current thread's queue. */
259 void
260 drain_message_queue ()
262 MSG msg;
263 while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
265 TranslateMessage (&msg);
266 DispatchMessage (&msg);
272 * XParseGeometry parses strings of the form
273 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
274 * width, height, xoffset, and yoffset are unsigned integers.
275 * Example: "=80x24+300-49"
276 * The equal sign is optional.
277 * It returns a bitmask that indicates which of the four values
278 * were actually found in the string. For each value found,
279 * the corresponding argument is updated; for each value
280 * not found, the corresponding argument is left unchanged.
283 static int
284 read_integer (string, NextString)
285 register char *string;
286 char **NextString;
288 register int Result = 0;
289 int Sign = 1;
291 if (*string == '+')
292 string++;
293 else if (*string == '-')
295 string++;
296 Sign = -1;
298 for (; (*string >= '0') && (*string <= '9'); string++)
300 Result = (Result * 10) + (*string - '0');
302 *NextString = string;
303 if (Sign >= 0)
304 return (Result);
305 else
306 return (-Result);
309 int
310 XParseGeometry (string, x, y, width, height)
311 char *string;
312 int *x, *y;
313 unsigned int *width, *height; /* RETURN */
315 int mask = NoValue;
316 register char *strind;
317 unsigned int tempWidth, tempHeight;
318 int tempX, tempY;
319 char *nextCharacter;
321 if ((string == NULL) || (*string == '\0')) return (mask);
322 if (*string == '=')
323 string++; /* ignore possible '=' at beg of geometry spec */
325 strind = (char *)string;
326 if (*strind != '+' && *strind != '-' && *strind != 'x')
328 tempWidth = read_integer (strind, &nextCharacter);
329 if (strind == nextCharacter)
330 return (0);
331 strind = nextCharacter;
332 mask |= WidthValue;
335 if (*strind == 'x' || *strind == 'X')
337 strind++;
338 tempHeight = read_integer (strind, &nextCharacter);
339 if (strind == nextCharacter)
340 return (0);
341 strind = nextCharacter;
342 mask |= HeightValue;
345 if ((*strind == '+') || (*strind == '-'))
347 if (*strind == '-')
349 strind++;
350 tempX = -read_integer (strind, &nextCharacter);
351 if (strind == nextCharacter)
352 return (0);
353 strind = nextCharacter;
354 mask |= XNegative;
357 else
359 strind++;
360 tempX = read_integer (strind, &nextCharacter);
361 if (strind == nextCharacter)
362 return (0);
363 strind = nextCharacter;
365 mask |= XValue;
366 if ((*strind == '+') || (*strind == '-'))
368 if (*strind == '-')
370 strind++;
371 tempY = -read_integer (strind, &nextCharacter);
372 if (strind == nextCharacter)
373 return (0);
374 strind = nextCharacter;
375 mask |= YNegative;
378 else
380 strind++;
381 tempY = read_integer (strind, &nextCharacter);
382 if (strind == nextCharacter)
383 return (0);
384 strind = nextCharacter;
386 mask |= YValue;
390 /* If strind isn't at the end of the string the it's an invalid
391 geometry specification. */
393 if (*strind != '\0') return (0);
395 if (mask & XValue)
396 *x = tempX;
397 if (mask & YValue)
398 *y = tempY;
399 if (mask & WidthValue)
400 *width = tempWidth;
401 if (mask & HeightValue)
402 *height = tempHeight;
403 return (mask);
406 /* x_sync is a no-op on W32. */
407 void
408 x_sync (f)
409 void *f;