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