*** empty log message ***
[emacs.git] / src / w32xfns.c
blob018aefdf35ed6714e36f59b3cc5f2d8ec9dc072d
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 if (!NILP (Vw32_enable_palette))
88 f->output_data.w32->old_palette =
89 SelectPalette (hdc, one_w32_display_info.palette, FALSE);
90 else
91 f->output_data.w32->old_palette = NULL;
93 if (RealizePalette (hdc))
95 Lisp_Object frame, framelist;
96 FOR_EACH_FRAME (framelist, frame)
98 SET_FRAME_GARBAGED (XFRAME (frame));
103 void
104 deselect_palette (FRAME_PTR f, HDC hdc)
106 if (f->output_data.w32->old_palette)
107 SelectPalette (hdc, f->output_data.w32->old_palette, FALSE);
110 /* Get a DC for frame and select palette for drawing; force an update of
111 all frames if palette's mapping changes. */
113 get_frame_dc (FRAME_PTR f)
115 HDC hdc;
117 enter_crit ();
119 hdc = GetDC (f->output_data.w32->window_desc);
121 /* If this gets called during startup before the frame is valid,
122 there is a chance of corrupting random data or crashing. */
123 if (hdc)
124 select_palette (f, hdc);
126 return hdc;
130 release_frame_dc (FRAME_PTR f, HDC hdc)
132 int ret;
134 deselect_palette (f, hdc);
135 ret = ReleaseDC (f->output_data.w32->window_desc, hdc);
137 leave_crit ();
139 return ret;
142 typedef struct int_msg
144 W32Msg w32msg;
145 struct int_msg *lpNext;
146 } int_msg;
148 int_msg *lpHead = NULL;
149 int_msg *lpTail = NULL;
150 int nQueue = 0;
152 BOOL
153 get_next_msg (lpmsg, bWait)
154 W32Msg * lpmsg;
155 BOOL bWait;
157 BOOL bRet = FALSE;
159 enter_crit ();
161 /* The while loop takes care of multiple sets */
163 while (!nQueue && bWait)
165 leave_crit ();
166 WaitForSingleObject (input_available, INFINITE);
167 enter_crit ();
170 if (nQueue)
172 bcopy (&(lpHead->w32msg), lpmsg, sizeof (W32Msg));
175 int_msg * lpCur = lpHead;
177 lpHead = lpHead->lpNext;
179 myfree (lpCur);
182 nQueue--;
184 bRet = TRUE;
187 if (nQueue == 0)
188 ResetEvent (input_available);
190 leave_crit ();
192 return (bRet);
195 BOOL
196 post_msg (lpmsg)
197 W32Msg * lpmsg;
199 int_msg * lpNew = (int_msg *) myalloc (sizeof (int_msg));
201 if (!lpNew)
202 return (FALSE);
204 bcopy (lpmsg, &(lpNew->w32msg), sizeof (W32Msg));
205 lpNew->lpNext = NULL;
207 enter_crit ();
209 if (nQueue++)
211 lpTail->lpNext = lpNew;
213 else
215 lpHead = lpNew;
218 lpTail = lpNew;
219 SetEvent (input_available);
221 leave_crit ();
223 return (TRUE);
226 BOOL
227 prepend_msg (W32Msg *lpmsg)
229 int_msg * lpNew = (int_msg *) myalloc (sizeof (int_msg));
231 if (!lpNew)
232 return (FALSE);
234 bcopy (lpmsg, &(lpNew->w32msg), sizeof (W32Msg));
236 enter_crit ();
238 nQueue++;
239 lpNew->lpNext = lpHead;
240 lpHead = lpNew;
242 leave_crit ();
244 return (TRUE);
247 /* Process all messages in the current thread's queue. */
248 void
249 drain_message_queue ()
251 MSG msg;
252 while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
254 TranslateMessage (&msg);
255 DispatchMessage (&msg);
261 * XParseGeometry parses strings of the form
262 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
263 * width, height, xoffset, and yoffset are unsigned integers.
264 * Example: "=80x24+300-49"
265 * The equal sign is optional.
266 * It returns a bitmask that indicates which of the four values
267 * were actually found in the string. For each value found,
268 * the corresponding argument is updated; for each value
269 * not found, the corresponding argument is left unchanged.
272 static int
273 read_integer (string, NextString)
274 register char *string;
275 char **NextString;
277 register int Result = 0;
278 int Sign = 1;
280 if (*string == '+')
281 string++;
282 else if (*string == '-')
284 string++;
285 Sign = -1;
287 for (; (*string >= '0') && (*string <= '9'); string++)
289 Result = (Result * 10) + (*string - '0');
291 *NextString = string;
292 if (Sign >= 0)
293 return (Result);
294 else
295 return (-Result);
298 int
299 XParseGeometry (string, x, y, width, height)
300 char *string;
301 int *x, *y;
302 unsigned int *width, *height; /* RETURN */
304 int mask = NoValue;
305 register char *strind;
306 unsigned int tempWidth, tempHeight;
307 int tempX, tempY;
308 char *nextCharacter;
310 if ((string == NULL) || (*string == '\0')) return (mask);
311 if (*string == '=')
312 string++; /* ignore possible '=' at beg of geometry spec */
314 strind = (char *)string;
315 if (*strind != '+' && *strind != '-' && *strind != 'x')
317 tempWidth = read_integer (strind, &nextCharacter);
318 if (strind == nextCharacter)
319 return (0);
320 strind = nextCharacter;
321 mask |= WidthValue;
324 if (*strind == 'x' || *strind == 'X')
326 strind++;
327 tempHeight = read_integer (strind, &nextCharacter);
328 if (strind == nextCharacter)
329 return (0);
330 strind = nextCharacter;
331 mask |= HeightValue;
334 if ((*strind == '+') || (*strind == '-'))
336 if (*strind == '-')
338 strind++;
339 tempX = -read_integer (strind, &nextCharacter);
340 if (strind == nextCharacter)
341 return (0);
342 strind = nextCharacter;
343 mask |= XNegative;
346 else
348 strind++;
349 tempX = read_integer (strind, &nextCharacter);
350 if (strind == nextCharacter)
351 return (0);
352 strind = nextCharacter;
354 mask |= XValue;
355 if ((*strind == '+') || (*strind == '-'))
357 if (*strind == '-')
359 strind++;
360 tempY = -read_integer (strind, &nextCharacter);
361 if (strind == nextCharacter)
362 return (0);
363 strind = nextCharacter;
364 mask |= YNegative;
367 else
369 strind++;
370 tempY = read_integer (strind, &nextCharacter);
371 if (strind == nextCharacter)
372 return (0);
373 strind = nextCharacter;
375 mask |= YValue;
379 /* If strind isn't at the end of the string the it's an invalid
380 geometry specification. */
382 if (*strind != '\0') return (0);
384 if (mask & XValue)
385 *x = tempX;
386 if (mask & YValue)
387 *y = tempY;
388 if (mask & WidthValue)
389 *width = tempWidth;
390 if (mask & HeightValue)
391 *height = tempHeight;
392 return (mask);
395 /* x_sync is a no-op on W32. */
396 void
397 x_sync (f)
398 void *f;