comparison src/win32.c @ 611:38db05db9cb5

[xemacs-hg @ 2001-06-08 12:21:09 by ben] ------ gc-in-window-procedure fixes ------ alloc.c: Create "post-gc actions", to avoid those dreaded "GC during window procedure" problems. event-msw.c: Abort, clean and simple, when GC in window procedure. We want to flush these puppies out. glyphs-msw.c: Use a post-gc action when destroying subwindows. lisp.h: Declare register_post_gc_action(). scrollbar-msw.c: Use a post-gc action when unshowing scrollbar windows, if in gc. redisplay.c: Add comment about the utter evilness of what's going down here. ------ cygwin setitimer fixes ------ Makefile.in.in: Compile profile.c only when HAVE_SETITIMER. nt.c: Style fixes. nt.c: Move setitimer() emulation to win32.c, because Cygwin needs it too. profile.c: Make sure we don't compile if no setitimer(). Use qxe_setitimer() instead of just plain setitimer(). signal.c: Define qxe_setitimer() as an encapsulation around setitimer() -- call setitimer() directly unless Cygwin or MS Win, in which case we use our simulated version in win32.c. systime.h: Prototype mswindows_setitimer() and qxe_setitimer(). Long comment about "qxe" and the policy regarding encapsulation. win32.c: Move setitimer() emulation here, so Cygwin can use it. Rename a couple of functions and variables to be longer and more descriptive. In setitimer_helper_proc(), send the signal using either mswindows_raise() or (on Cygwin) kill(). If for some reason we are still getting lockups, we'll change the kill() to directly invoke the signal handlers. ------ windows shell fixes ------ callproc.c, ntproc.c: Comments about how these two files must die. callproc.c: On MS Windows, init shell-file-name from SHELL, then COMSPEC, not just COMSPEC. (more correct and closer to FSF.) Don't force a value for SHELL into the environment. (Comments added to explain why not.) nt.c: Don't shove a fabricated SHELL into the environment. See above. ------ misc fixes ------ glyphs-shared.c: Style correction. xemacs-faq.texi: Merge in the rest of Hrvoje's Windows FAQ. Redo section 7 to update current reality and add condensed versions of new changes for 21.1 and 21.4. (Not quite done for 21.4.) Lots more Windows updates. process.el: Need to quote a null argument, too. From Dan Holmsand. startup.el: startup.el: Call MS Windows init function. win32-native.el: Correct comments at top. Correctly handle passing arguments to Cygwin programs and to bash. Fix quoting of zero-length arguments (from Dan Holmsand). Set shell-command-switch based on shell-file-name, which in turn comes from env var SHELL.
author ben
date Fri, 08 Jun 2001 12:21:27 +0000
parents 5fd7ba8b56e7
children 023b83f4e54b
comparison
equal deleted inserted replaced
610:45ba69404a1f 611:38db05db9cb5
20 20
21 #include <config.h> 21 #include <config.h>
22 #include "lisp.h" 22 #include "lisp.h"
23 23
24 #include "buffer.h" 24 #include "buffer.h"
25
26 #include "syssignal.h"
27 #include "systime.h"
25 #include "syswindows.h" 28 #include "syswindows.h"
26 29
27 typedef BOOL (WINAPI *pfSwitchToThread_t) (VOID); 30 typedef BOOL (WINAPI *pfSwitchToThread_t) (VOID);
28 pfSwitchToThread_t xSwitchToThread; 31 pfSwitchToThread_t xSwitchToThread;
29 32
244 signal_error (Qinternal_error, "internal error", Qunbound); 247 signal_error (Qinternal_error, "internal error", Qunbound);
245 248
246 return Qnil; 249 return Qnil;
247 } 250 }
248 251
252
253 /*--------------------------------------------------------------------*/
254 /* Async timers */
255 /*--------------------------------------------------------------------*/
256
257 /* setitimer() does not exist on native MS Windows, and appears broken
258 on Cygwin (random lockups when BROKEN_SIGIO is defined), so we
259 emulate in both cases by using multimedia timers. */
260
261 /* We emulate two timers, one for SIGALRM, another for SIGPROF.
262
263 itimerproc() function has an implementation limitation: it does
264 not allow to set *both* interval and period. If an attempt is
265 made to set both, and then they are unequal, the function
266 asserts.
267
268 Minimum timer resolution on Win32 systems varies, and is greater
269 than or equal than 1 ms. The resolution is always wrapped not to
270 attempt to get below the system defined limit.
271 */
272
273 /* Timer precision, denominator of one fraction: for 100 ms
274 interval, request 10 ms precision
275 */
276 const int setitimer_helper_timer_prec = 10;
277
278 /* Last itimervals, as set by calls to setitimer */
279 static struct itimerval it_alarm;
280 static struct itimerval it_prof;
281
282 /* Timer IDs as returned by MM */
283 MMRESULT tid_alarm = 0;
284 MMRESULT tid_prof = 0;
285
286 static void CALLBACK
287 setitimer_helper_proc (UINT uID, UINT uMsg, DWORD dwUser,
288 DWORD dw1, DWORD dw2)
289 {
290 /* Just raise the signal indicated by the dwUser parameter */
291 #ifdef CYGWIN
292 kill (getpid (), dwUser);
293 #else
294 mswindows_raise (dwUser);
295 #endif
296 }
297
298 /* Divide time in ms specified by IT by DENOM. Return 1 ms
299 if division results in zero */
300 static UINT
301 setitimer_helper_period (const struct itimerval* it, UINT denom)
302 {
303 static TIMECAPS time_caps;
304
305 UINT res;
306 const struct timeval* tv =
307 (it->it_value.tv_sec == 0 && it->it_value.tv_usec == 0)
308 ? &it->it_interval : &it->it_value;
309
310 /* Zero means stop timer */
311 if (tv->tv_sec == 0 && tv->tv_usec == 0)
312 return 0;
313
314 /* Convert to ms and divide by denom */
315 res = (tv->tv_sec * 1000 + (tv->tv_usec + 500) / 1000) / denom;
316
317 /* Converge to minimum timer resolution */
318 if (time_caps.wPeriodMin == 0)
319 timeGetDevCaps (&time_caps, sizeof(time_caps));
320
321 if (res < time_caps.wPeriodMin)
322 res = time_caps.wPeriodMin;
323
324 return res;
325 }
326
327 static int
328 setitimer_helper (const struct itimerval* itnew,
329 struct itimerval* itold, struct itimerval* itcurrent,
330 MMRESULT* tid, DWORD sigkind)
331 {
332 UINT delay, resolution, event_type;
333
334 /* First stop the old timer */
335 if (*tid)
336 {
337 timeKillEvent (*tid);
338 timeEndPeriod (setitimer_helper_period (itcurrent,
339 setitimer_helper_timer_prec));
340 *tid = 0;
341 }
342
343 /* Return old itimerval if requested */
344 if (itold)
345 *itold = *itcurrent;
346
347 *itcurrent = *itnew;
348
349 /* Determine if to start new timer */
350 delay = setitimer_helper_period (itnew, 1);
351 if (delay)
352 {
353 resolution = setitimer_helper_period (itnew,
354 setitimer_helper_timer_prec);
355 event_type = (itnew->it_value.tv_sec == 0 &&
356 itnew->it_value.tv_usec == 0)
357 ? TIME_ONESHOT : TIME_PERIODIC;
358 timeBeginPeriod (resolution);
359 *tid = timeSetEvent (delay, resolution, setitimer_helper_proc, sigkind,
360 event_type);
361 }
362
363 return !delay || *tid;
364 }
365
366 int
367 mswindows_setitimer (int kind, const struct itimerval *itnew,
368 struct itimerval *itold)
369 {
370 /* In this version, both interval and value are allowed
371 only if they are equal. */
372 assert ((itnew->it_value.tv_sec == 0 && itnew->it_value.tv_usec == 0)
373 || (itnew->it_interval.tv_sec == 0 &&
374 itnew->it_interval.tv_usec == 0)
375 || (itnew->it_value.tv_sec == itnew->it_interval.tv_sec &&
376 itnew->it_value.tv_usec == itnew->it_interval.tv_usec));
377
378 if (kind == ITIMER_REAL)
379 return setitimer_helper (itnew, itold, &it_alarm, &tid_alarm, SIGALRM);
380 else if (kind == ITIMER_PROF)
381 return setitimer_helper (itnew, itold, &it_prof, &tid_prof, SIGPROF);
382 else
383 return errno = EINVAL;
384 }
385
386
249 void 387 void
250 syms_of_win32 (void) 388 syms_of_win32 (void)
251 { 389 {
252 DEFSUBR (Fmswindows_shell_execute); 390 DEFSUBR (Fmswindows_shell_execute);
253 } 391 }