Mercurial > hg > xemacs-beta
comparison src/nt.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 | 47823c2cf014 |
children | 023b83f4e54b |
comparison
equal
deleted
inserted
replaced
610:45ba69404a1f | 611:38db05db9cb5 |
---|---|
1 /* Utility and Unix shadow routines for XEmacs on Windows NT. | 1 /* Utility and Unix shadow routines for XEmacs on MS Windows. |
2 Copyright (C) 1994, 1995 Free Software Foundation, Inc. | 2 Copyright (C) 1994, 1995 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of XEmacs. | 4 This file is part of XEmacs. |
5 | 5 |
6 XEmacs is free software; you can redistribute it and/or modify it | 6 XEmacs is free software; you can redistribute it and/or modify it |
246 * With XEmacs, setting $HOME is deprecated. | 246 * With XEmacs, setting $HOME is deprecated. |
247 */ | 247 */ |
248 if (getenv ("HOME") == NULL) | 248 if (getenv ("HOME") == NULL) |
249 putenv ("HOME=c:/"); | 249 putenv ("HOME=c:/"); |
250 #endif | 250 #endif |
251 if (getenv ("SHELL") == NULL) | 251 |
252 putenv ((GetVersion () & 0x80000000) ? "SHELL=command" : "SHELL=cmd"); | 252 /* Set dir from environment variables. */ |
253 | |
254 /* Set dir and shell from environment variables. */ | |
255 strcpy (the_passwd.pw_dir, (char *)get_home_directory()); | 253 strcpy (the_passwd.pw_dir, (char *)get_home_directory()); |
256 strcpy (the_passwd.pw_shell, getenv ("SHELL")); | 254 /* We used to set pw_shell here, but the order is wrong (SHELL gets |
255 init in callproc.c, called later in the init process) and pw_shell | |
256 is not used anywhere. */ | |
257 } | 257 } |
258 | 258 |
259 /* Normalize filename by converting all path separators to | 259 /* Normalize filename by converting all path separators to |
260 the specified separator. Also conditionally convert upper | 260 the specified separator. Also conditionally convert upper |
261 case path name components to lower case. */ | 261 case path name components to lower case. */ |
1825 unsigned signal_block_mask = 0; | 1825 unsigned signal_block_mask = 0; |
1826 | 1826 |
1827 /* Signal pending mask: bit set to 1 means sig is pending */ | 1827 /* Signal pending mask: bit set to 1 means sig is pending */ |
1828 unsigned signal_pending_mask = 0; | 1828 unsigned signal_pending_mask = 0; |
1829 | 1829 |
1830 mswindows_sighandler mswindows_sigset (int nsig, mswindows_sighandler handler) | 1830 mswindows_sighandler |
1831 mswindows_sigset (int nsig, mswindows_sighandler handler) | |
1831 { | 1832 { |
1832 /* We delegate some signals to the system function */ | 1833 /* We delegate some signals to the system function */ |
1833 if (nsig == SIGFPE || nsig == SIGABRT || nsig == SIGINT) | 1834 if (nsig == SIGFPE || nsig == SIGABRT || nsig == SIGINT) |
1834 return signal (nsig, handler); | 1835 return signal (nsig, handler); |
1835 | 1836 |
1845 signal_handlers[nsig] = handler; | 1846 signal_handlers[nsig] = handler; |
1846 return old_handler; | 1847 return old_handler; |
1847 } | 1848 } |
1848 } | 1849 } |
1849 | 1850 |
1850 int mswindows_sighold (int nsig) | 1851 int |
1852 mswindows_sighold (int nsig) | |
1851 { | 1853 { |
1852 if (nsig < 0 || nsig > SIG_MAX) | 1854 if (nsig < 0 || nsig > SIG_MAX) |
1853 return errno = EINVAL; | 1855 return errno = EINVAL; |
1854 | 1856 |
1855 signal_block_mask |= sigmask(nsig); | 1857 signal_block_mask |= sigmask (nsig); |
1856 return 0; | 1858 return 0; |
1857 } | 1859 } |
1858 | 1860 |
1859 int mswindows_sigrelse (int nsig) | 1861 int |
1862 mswindows_sigrelse (int nsig) | |
1860 { | 1863 { |
1861 if (nsig < 0 || nsig > SIG_MAX) | 1864 if (nsig < 0 || nsig > SIG_MAX) |
1862 return errno = EINVAL; | 1865 return errno = EINVAL; |
1863 | 1866 |
1864 signal_block_mask &= ~sigmask(nsig); | 1867 signal_block_mask &= ~sigmask (nsig); |
1865 | 1868 |
1866 if (signal_pending_mask & sigmask(nsig)) | 1869 if (signal_pending_mask & sigmask (nsig)) |
1867 mswindows_raise (nsig); | 1870 mswindows_raise (nsig); |
1868 | 1871 |
1869 return 0; | 1872 return 0; |
1870 } | 1873 } |
1871 | 1874 |
1872 int mswindows_sigpause (int nsig) | 1875 int |
1873 { | 1876 mswindows_sigpause (int nsig) |
1874 /* This is currently not called, because the only | 1877 { |
1875 call to sigpause inside XEmacs is with SIGCHLD | 1878 /* This is currently not called, because the only call to sigpause |
1876 parameter. Just in case, we put an assert here, | 1879 inside XEmacs is with SIGCHLD parameter. Just in case, we put an |
1877 so anyone who will add a call to sigpause will | 1880 assert here, so anyone adds a call to sigpause will be surprised |
1878 be surprised (or surprise someone else...) */ | 1881 (or surprise someone else...) */ |
1879 assert (0); | 1882 assert (0); |
1880 return 0; | 1883 return 0; |
1881 } | 1884 } |
1882 | 1885 |
1883 int mswindows_raise (int nsig) | 1886 int |
1887 mswindows_raise (int nsig) | |
1884 { | 1888 { |
1885 /* We delegate some raises to the system routine */ | 1889 /* We delegate some raises to the system routine */ |
1886 if (nsig == SIGFPE || nsig == SIGABRT || nsig == SIGINT) | 1890 if (nsig == SIGFPE || nsig == SIGABRT || nsig == SIGINT) |
1887 return raise (nsig); | 1891 return raise (nsig); |
1888 | 1892 |
1889 if (nsig < 0 || nsig > SIG_MAX) | 1893 if (nsig < 0 || nsig > SIG_MAX) |
1890 return errno = EINVAL; | 1894 return errno = EINVAL; |
1891 | 1895 |
1892 /* If the signal is blocked, remember to issue later */ | 1896 /* If the signal is blocked, remember to issue later */ |
1893 if (signal_block_mask & sigmask(nsig)) | 1897 if (signal_block_mask & sigmask (nsig)) |
1894 { | 1898 { |
1895 signal_pending_mask |= sigmask(nsig); | 1899 signal_pending_mask |= sigmask (nsig); |
1896 return 0; | 1900 return 0; |
1897 } | 1901 } |
1898 | 1902 |
1899 if (signal_handlers[nsig] == SIG_IGN) | 1903 if (signal_handlers[nsig] == SIG_IGN) |
1900 return 0; | 1904 return 0; |
1901 | 1905 |
1902 if (signal_handlers[nsig] != SIG_DFL) | 1906 if (signal_handlers[nsig] != SIG_DFL) |
1903 { | 1907 { |
1904 (*signal_handlers[nsig])(nsig); | 1908 (*signal_handlers[nsig]) (nsig); |
1905 return 0; | 1909 return 0; |
1906 } | 1910 } |
1907 | 1911 |
1908 /* Default signal actions */ | 1912 /* Default signal actions */ |
1909 if (nsig == SIGALRM || nsig == SIGPROF) | 1913 if (nsig == SIGALRM || nsig == SIGPROF) |
1910 exit (3); | 1914 exit (3); |
1911 | 1915 |
1912 /* Other signals are ignored by default */ | 1916 /* Other signals are ignored by default */ |
1913 return 0; | 1917 return 0; |
1914 } | |
1915 | |
1916 /*--------------------------------------------------------------------*/ | |
1917 /* Async timers */ | |
1918 /*--------------------------------------------------------------------*/ | |
1919 | |
1920 /* We emulate two timers, one for SIGALRM, another for SIGPROF. | |
1921 | |
1922 itimerproc() function has an implementation limitation: it does | |
1923 not allow to set *both* interval and period. If an attempt is | |
1924 made to set both, and then they are unequal, the function | |
1925 asserts. | |
1926 | |
1927 Minimum timer resolution on Win32 systems varies, and is greater | |
1928 than or equal than 1 ms. The resolution is always wrapped not to | |
1929 attempt to get below the system defined limit. | |
1930 */ | |
1931 | |
1932 /* Timer precision, denominator of one fraction: for 100 ms | |
1933 interval, request 10 ms precision | |
1934 */ | |
1935 const int timer_prec = 10; | |
1936 | |
1937 /* Last itimervals, as set by calls to setitimer */ | |
1938 static struct itimerval it_alarm; | |
1939 static struct itimerval it_prof; | |
1940 | |
1941 /* Timer IDs as returned by MM */ | |
1942 MMRESULT tid_alarm = 0; | |
1943 MMRESULT tid_prof = 0; | |
1944 | |
1945 static void CALLBACK timer_proc (UINT uID, UINT uMsg, DWORD dwUser, | |
1946 DWORD dw1, DWORD dw2) | |
1947 { | |
1948 /* Just raise a signal indicated by dwUser parameter */ | |
1949 mswindows_raise (dwUser); | |
1950 } | |
1951 | |
1952 /* Divide time in ms specified by IT by DENOM. Return 1 ms | |
1953 if division results in zero */ | |
1954 static UINT period (const struct itimerval* it, UINT denom) | |
1955 { | |
1956 static TIMECAPS time_caps; | |
1957 | |
1958 UINT res; | |
1959 const struct timeval* tv = | |
1960 (it->it_value.tv_sec == 0 && it->it_value.tv_usec == 0) | |
1961 ? &it->it_interval : &it->it_value; | |
1962 | |
1963 /* Zero means stop timer */ | |
1964 if (tv->tv_sec == 0 && tv->tv_usec == 0) | |
1965 return 0; | |
1966 | |
1967 /* Convert to ms and divide by denom */ | |
1968 res = (tv->tv_sec * 1000 + (tv->tv_usec + 500) / 1000) / denom; | |
1969 | |
1970 /* Converge to minimum timer resolution */ | |
1971 if (time_caps.wPeriodMin == 0) | |
1972 timeGetDevCaps (&time_caps, sizeof(time_caps)); | |
1973 | |
1974 if (res < time_caps.wPeriodMin) | |
1975 res = time_caps.wPeriodMin; | |
1976 | |
1977 return res; | |
1978 } | |
1979 | |
1980 static int setitimer_helper (const struct itimerval* itnew, | |
1981 struct itimerval* itold, struct itimerval* itcurrent, | |
1982 MMRESULT* tid, DWORD sigkind) | |
1983 { | |
1984 UINT delay, resolution, event_type; | |
1985 | |
1986 /* First stop the old timer */ | |
1987 if (*tid) | |
1988 { | |
1989 timeKillEvent (*tid); | |
1990 timeEndPeriod (period (itcurrent, timer_prec)); | |
1991 *tid = 0; | |
1992 } | |
1993 | |
1994 /* Return old itimerval if requested */ | |
1995 if (itold) | |
1996 *itold = *itcurrent; | |
1997 | |
1998 *itcurrent = *itnew; | |
1999 | |
2000 /* Determine if to start new timer */ | |
2001 delay = period (itnew, 1); | |
2002 if (delay) | |
2003 { | |
2004 resolution = period (itnew, timer_prec); | |
2005 event_type = (itnew->it_value.tv_sec == 0 && itnew->it_value.tv_usec == 0) | |
2006 ? TIME_ONESHOT : TIME_PERIODIC; | |
2007 timeBeginPeriod (resolution); | |
2008 *tid = timeSetEvent (delay, resolution, timer_proc, sigkind, event_type); | |
2009 } | |
2010 | |
2011 return !delay || *tid; | |
2012 } | |
2013 | |
2014 int setitimer (int kind, const struct itimerval* itnew, | |
2015 struct itimerval* itold) | |
2016 { | |
2017 /* In this version, both interval and value are allowed | |
2018 only if they are equal. */ | |
2019 assert ((itnew->it_value.tv_sec == 0 && itnew->it_value.tv_usec == 0) | |
2020 || (itnew->it_interval.tv_sec == 0 && itnew->it_interval.tv_usec == 0) | |
2021 || (itnew->it_value.tv_sec == itnew->it_interval.tv_sec && | |
2022 itnew->it_value.tv_usec == itnew->it_interval.tv_usec)); | |
2023 | |
2024 if (kind == ITIMER_REAL) | |
2025 return setitimer_helper (itnew, itold, &it_alarm, &tid_alarm, SIGALRM); | |
2026 else if (kind == ITIMER_PROF) | |
2027 return setitimer_helper (itnew, itold, &it_prof, &tid_prof, SIGPROF); | |
2028 else | |
2029 return errno = EINVAL; | |
2030 } | 1918 } |
2031 | 1919 |
2032 | 1920 |
2033 /*--------------------------------------------------------------------*/ | 1921 /*--------------------------------------------------------------------*/ |
2034 /* Memory-mapped files */ | 1922 /* Memory-mapped files */ |
2319 | 2207 |
2320 /* Close the system structures associated with the given file. */ | 2208 /* Close the system structures associated with the given file. */ |
2321 void | 2209 void |
2322 close_file_data (file_data *p_file) | 2210 close_file_data (file_data *p_file) |
2323 { | 2211 { |
2324 UnmapViewOfFile (p_file->file_base); | 2212 UnmapViewOfFile (p_file->file_base); |
2325 CloseHandle (p_file->file_mapping); | 2213 CloseHandle (p_file->file_mapping); |
2326 CloseHandle (p_file->file); | 2214 CloseHandle (p_file->file); |
2327 } | 2215 } |
2328 | 2216 |
2329 void | 2217 void |
2330 vars_of_nt (void) | 2218 vars_of_nt (void) |
2331 { | 2219 { |