Change identifiers of the form win32* to w32*.
[bpt/emacs.git] / src / w32xfns.c
1 /* Functions taken directly from X sources for use with the Win32 API.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation.
3
4 This file is part of GNU Emacs.
5
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.
10
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.
15
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. */
20
21 #include <signal.h>
22 #include <config.h>
23 #include <stdio.h>
24 #include "lisp.h"
25 #include "frame.h"
26 #include "blockinput.h"
27 #include "w32term.h"
28 #include "windowsx.h"
29
30 #define myalloc(cb) GlobalAllocPtr (GPTR, cb)
31 #define myfree(lp) GlobalFreePtr (lp)
32
33 CRITICAL_SECTION critsect;
34 extern HANDLE keyboard_handle;
35 HANDLE input_available = NULL;
36
37 void
38 init_crit ()
39 {
40 InitializeCriticalSection (&critsect);
41
42 /* For safety, input_available should only be reset by get_next_msg
43 when the input queue is empty, so make it a manual reset event. */
44 keyboard_handle = input_available = CreateEvent (NULL, TRUE, FALSE, NULL);
45 }
46
47 void
48 delete_crit ()
49 {
50 DeleteCriticalSection (&critsect);
51
52 if (input_available)
53 {
54 CloseHandle (input_available);
55 input_available = NULL;
56 }
57 }
58
59 void
60 select_palette (FRAME_PTR f, HDC hdc)
61 {
62 if (!NILP (Vw32_enable_palette))
63 f->output_data.w32->old_palette =
64 SelectPalette (hdc, one_w32_display_info.palette, FALSE);
65 else
66 f->output_data.w32->old_palette = NULL;
67
68 if (RealizePalette (hdc))
69 {
70 Lisp_Object frame, framelist;
71 FOR_EACH_FRAME (framelist, frame)
72 {
73 SET_FRAME_GARBAGED (XFRAME (frame));
74 }
75 }
76 }
77
78 void
79 deselect_palette (FRAME_PTR f, HDC hdc)
80 {
81 if (f->output_data.w32->old_palette)
82 SelectPalette (hdc, f->output_data.w32->old_palette, FALSE);
83 }
84
85 /* Get a DC for frame and select palette for drawing; force an update of
86 all frames if palette's mapping changes. */
87 HDC
88 get_frame_dc (FRAME_PTR f)
89 {
90 HDC hdc;
91
92 enter_crit ();
93
94 hdc = GetDC (f->output_data.w32->window_desc);
95 select_palette (f, hdc);
96
97 return hdc;
98 }
99
100 int
101 release_frame_dc (FRAME_PTR f, HDC hdc)
102 {
103 int ret;
104
105 deselect_palette (f, hdc);
106 ret = ReleaseDC (f->output_data.w32->window_desc, hdc);
107
108 leave_crit ();
109
110 return ret;
111 }
112
113 typedef struct int_msg
114 {
115 W32Msg w32msg;
116 struct int_msg *lpNext;
117 } int_msg;
118
119 int_msg *lpHead = NULL;
120 int_msg *lpTail = NULL;
121 int nQueue = 0;
122
123 BOOL
124 get_next_msg (lpmsg, bWait)
125 W32Msg * lpmsg;
126 BOOL bWait;
127 {
128 BOOL bRet = FALSE;
129
130 enter_crit ();
131
132 /* The while loop takes care of multiple sets */
133
134 while (!nQueue && bWait)
135 {
136 leave_crit ();
137 WaitForSingleObject (input_available, INFINITE);
138 enter_crit ();
139 }
140
141 if (nQueue)
142 {
143 bcopy (&(lpHead->w32msg), lpmsg, sizeof (W32Msg));
144
145 {
146 int_msg * lpCur = lpHead;
147
148 lpHead = lpHead->lpNext;
149
150 myfree (lpCur);
151 }
152
153 nQueue--;
154
155 bRet = TRUE;
156 }
157
158 if (nQueue == 0)
159 ResetEvent (input_available);
160
161 leave_crit ();
162
163 return (bRet);
164 }
165
166 BOOL
167 post_msg (lpmsg)
168 W32Msg * lpmsg;
169 {
170 int_msg * lpNew = (int_msg *) myalloc (sizeof (int_msg));
171
172 if (!lpNew)
173 return (FALSE);
174
175 bcopy (lpmsg, &(lpNew->w32msg), sizeof (W32Msg));
176 lpNew->lpNext = NULL;
177
178 enter_crit ();
179
180 if (nQueue++)
181 {
182 lpTail->lpNext = lpNew;
183 }
184 else
185 {
186 lpHead = lpNew;
187 }
188
189 lpTail = lpNew;
190 SetEvent (input_available);
191
192 leave_crit ();
193
194 return (TRUE);
195 }
196
197 BOOL
198 prepend_msg (W32Msg *lpmsg)
199 {
200 int_msg * lpNew = (int_msg *) myalloc (sizeof (int_msg));
201
202 if (!lpNew)
203 return (FALSE);
204
205 bcopy (lpmsg, &(lpNew->w32msg), sizeof (W32Msg));
206
207 enter_crit ();
208
209 nQueue++;
210 lpNew->lpNext = lpHead;
211 lpHead = lpNew;
212
213 leave_crit ();
214
215 return (TRUE);
216 }
217
218 /*
219 * XParseGeometry parses strings of the form
220 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
221 * width, height, xoffset, and yoffset are unsigned integers.
222 * Example: "=80x24+300-49"
223 * The equal sign is optional.
224 * It returns a bitmask that indicates which of the four values
225 * were actually found in the string. For each value found,
226 * the corresponding argument is updated; for each value
227 * not found, the corresponding argument is left unchanged.
228 */
229
230 static int
231 read_integer (string, NextString)
232 register char *string;
233 char **NextString;
234 {
235 register int Result = 0;
236 int Sign = 1;
237
238 if (*string == '+')
239 string++;
240 else if (*string == '-')
241 {
242 string++;
243 Sign = -1;
244 }
245 for (; (*string >= '0') && (*string <= '9'); string++)
246 {
247 Result = (Result * 10) + (*string - '0');
248 }
249 *NextString = string;
250 if (Sign >= 0)
251 return (Result);
252 else
253 return (-Result);
254 }
255
256 int
257 XParseGeometry (string, x, y, width, height)
258 char *string;
259 int *x, *y;
260 unsigned int *width, *height; /* RETURN */
261 {
262 int mask = NoValue;
263 register char *strind;
264 unsigned int tempWidth, tempHeight;
265 int tempX, tempY;
266 char *nextCharacter;
267
268 if ((string == NULL) || (*string == '\0')) return (mask);
269 if (*string == '=')
270 string++; /* ignore possible '=' at beg of geometry spec */
271
272 strind = (char *)string;
273 if (*strind != '+' && *strind != '-' && *strind != 'x')
274 {
275 tempWidth = read_integer (strind, &nextCharacter);
276 if (strind == nextCharacter)
277 return (0);
278 strind = nextCharacter;
279 mask |= WidthValue;
280 }
281
282 if (*strind == 'x' || *strind == 'X')
283 {
284 strind++;
285 tempHeight = read_integer (strind, &nextCharacter);
286 if (strind == nextCharacter)
287 return (0);
288 strind = nextCharacter;
289 mask |= HeightValue;
290 }
291
292 if ((*strind == '+') || (*strind == '-'))
293 {
294 if (*strind == '-')
295 {
296 strind++;
297 tempX = -read_integer (strind, &nextCharacter);
298 if (strind == nextCharacter)
299 return (0);
300 strind = nextCharacter;
301 mask |= XNegative;
302
303 }
304 else
305 {
306 strind++;
307 tempX = read_integer (strind, &nextCharacter);
308 if (strind == nextCharacter)
309 return (0);
310 strind = nextCharacter;
311 }
312 mask |= XValue;
313 if ((*strind == '+') || (*strind == '-'))
314 {
315 if (*strind == '-')
316 {
317 strind++;
318 tempY = -read_integer (strind, &nextCharacter);
319 if (strind == nextCharacter)
320 return (0);
321 strind = nextCharacter;
322 mask |= YNegative;
323
324 }
325 else
326 {
327 strind++;
328 tempY = read_integer (strind, &nextCharacter);
329 if (strind == nextCharacter)
330 return (0);
331 strind = nextCharacter;
332 }
333 mask |= YValue;
334 }
335 }
336
337 /* If strind isn't at the end of the string the it's an invalid
338 geometry specification. */
339
340 if (*strind != '\0') return (0);
341
342 if (mask & XValue)
343 *x = tempX;
344 if (mask & YValue)
345 *y = tempY;
346 if (mask & WidthValue)
347 *width = tempWidth;
348 if (mask & HeightValue)
349 *height = tempHeight;
350 return (mask);
351 }
352
353 /* We can use mouse menus when we wish. */
354 int
355 have_menus_p (void)
356 {
357 return 1;
358 }
359
360 /* x_sync is a no-op on W32. */
361 void
362 x_sync (f)
363 void *f;
364 {
365 }
366