#include "lisp.h"
#include "buffer.h"
-
-#include "syssignal.h"
-#include "systime.h"
#include "syswindows.h"
typedef BOOL (WINAPI *pfSwitchToThread_t) (VOID);
/* Encode filename and current directory. */
Lisp_Object current_dir = Ffile_name_directory (document);
char* path = NULL;
-#ifdef CYGWIN
- char* fname1, *fname2;
- int pos, sz;
-#endif
char* doc = NULL;
+ Extbyte* f=0;
int ret;
struct gcpro gcpro1, gcpro2;
/* Use mule and cygwin-safe APIs top get at file data. */
if (STRINGP (current_dir))
{
- LOCAL_TO_WIN32_FILE_FORMAT (current_dir, path);
+ TO_EXTERNAL_FORMAT (LISP_STRING, current_dir,
+ C_STRING_ALLOCA, f,
+ Qfile_name);
+#ifdef CYGWIN
+ CYGWIN_WIN32_PATH (f, path);
+#else
+ path = f;
+#endif
}
if (STRINGP (document))
{
- doc = XSTRING_DATA (document);
+ TO_EXTERNAL_FORMAT (LISP_STRING, document,
+ C_STRING_ALLOCA, f,
+ Qfile_name);
#ifdef CYGWIN
- if ((fname1 = strchr (doc, ':')) != NULL
- && *++fname1 == '/' && *++fname1 == '/')
- {
- fname1++;
- pos = fname1 - doc;
- if (!(isalpha (fname1[0]) && (IS_DEVICE_SEP (fname1[1]))))
- {
- sz = cygwin_posix_to_win32_path_list_buf_size (fname1);
- fname2 = alloca (sz + pos);
- strncpy (fname2, doc, pos);
- doc = fname2;
- fname2 += pos;
- cygwin_posix_to_win32_path_list (fname1, fname2);
- }
- }
- else {
- LOCAL_TO_WIN32_FILE_FORMAT (document, doc);
- }
+ CYGWIN_WIN32_PATH (f, doc);
+#else
+ doc = f;
#endif
}
return Qnil;
}
-#ifdef CYGWIN
-DEFUN ("mswindows-cygwin-to-win32-path", Fmswindows_cygwin_to_win32_path, 1, 1, 0, /*
-Get the cygwin environment to convert the Unix PATH to win32 format.
-No expansion is performed, all conversion is done by the cygwin runtime.
-*/
- (path))
-{
- Extbyte* f;
- Bufbyte* p;
- CHECK_STRING (path);
-
- /* There appears to be a bug in the cygwin conversion routines in
- that they are not idempotent. */
- p = XSTRING_DATA (path);
- if (isalpha (p[0]) && (IS_DEVICE_SEP (p[1])))
- return path;
-
- /* Use mule and cygwin-safe APIs top get at file data. */
- LOCAL_TO_WIN32_FILE_FORMAT (path, f);
- return build_ext_string (f, Qnative);
-}
-#endif
-
-\f
-/*--------------------------------------------------------------------*/
-/* Async timers */
-/*--------------------------------------------------------------------*/
-
-/* setitimer() does not exist on native MS Windows, and appears broken
- on Cygwin (random lockups when BROKEN_SIGIO is defined), so we
- emulate in both cases by using multimedia timers. */
-
-/* We emulate two timers, one for SIGALRM, another for SIGPROF.
-
- itimerproc() function has an implementation limitation: it does
- not allow to set *both* interval and period. If an attempt is
- made to set both, and then they are unequal, the function
- asserts.
-
- Minimum timer resolution on Win32 systems varies, and is greater
- than or equal than 1 ms. The resolution is always wrapped not to
- attempt to get below the system defined limit.
- */
-
-/* Timer precision, denominator of one fraction: for 100 ms
- interval, request 10 ms precision
- */
-const int setitimer_helper_timer_prec = 10;
-
-/* Last itimervals, as set by calls to setitimer */
-static struct itimerval it_alarm;
-static struct itimerval it_prof;
-
-/* Timer IDs as returned by MM */
-MMRESULT tid_alarm = 0;
-MMRESULT tid_prof = 0;
-
-static void CALLBACK
-setitimer_helper_proc (UINT uID, UINT uMsg, DWORD dwUser,
- DWORD dw1, DWORD dw2)
-{
- /* Just raise the signal indicated by the dwUser parameter */
-#ifdef CYGWIN
- kill (getpid (), dwUser);
-#else
- mswindows_raise (dwUser);
-#endif
-}
-
-/* Divide time in ms specified by IT by DENOM. Return 1 ms
- if division results in zero */
-static UINT
-setitimer_helper_period (const struct itimerval* it, UINT denom)
-{
- static TIMECAPS time_caps;
-
- UINT res;
- const struct timeval* tv =
- (it->it_value.tv_sec == 0 && it->it_value.tv_usec == 0)
- ? &it->it_interval : &it->it_value;
-
- /* Zero means stop timer */
- if (tv->tv_sec == 0 && tv->tv_usec == 0)
- return 0;
-
- /* Convert to ms and divide by denom */
- res = (tv->tv_sec * 1000 + (tv->tv_usec + 500) / 1000) / denom;
-
- /* Converge to minimum timer resolution */
- if (time_caps.wPeriodMin == 0)
- timeGetDevCaps (&time_caps, sizeof(time_caps));
-
- if (res < time_caps.wPeriodMin)
- res = time_caps.wPeriodMin;
-
- return res;
-}
-
-static int
-setitimer_helper (const struct itimerval* itnew,
- struct itimerval* itold, struct itimerval* itcurrent,
- MMRESULT* tid, DWORD sigkind)
-{
- UINT delay, resolution, event_type;
-
- /* First stop the old timer */
- if (*tid)
- {
- timeKillEvent (*tid);
- timeEndPeriod (setitimer_helper_period (itcurrent,
- setitimer_helper_timer_prec));
- *tid = 0;
- }
-
- /* Return old itimerval if requested */
- if (itold)
- *itold = *itcurrent;
-
- *itcurrent = *itnew;
-
- /* Determine if to start new timer */
- delay = setitimer_helper_period (itnew, 1);
- if (delay)
- {
- resolution = setitimer_helper_period (itnew,
- setitimer_helper_timer_prec);
- event_type = (itnew->it_value.tv_sec == 0 &&
- itnew->it_value.tv_usec == 0)
- ? TIME_ONESHOT : TIME_PERIODIC;
- timeBeginPeriod (resolution);
- *tid = timeSetEvent (delay, resolution, setitimer_helper_proc, sigkind,
- event_type);
- }
-
- return !delay || *tid;
-}
-
-int
-mswindows_setitimer (int kind, const struct itimerval *itnew,
- struct itimerval *itold)
-{
- /* In this version, both interval and value are allowed
- only if they are equal. */
- assert ((itnew->it_value.tv_sec == 0 && itnew->it_value.tv_usec == 0)
- || (itnew->it_interval.tv_sec == 0 &&
- itnew->it_interval.tv_usec == 0)
- || (itnew->it_value.tv_sec == itnew->it_interval.tv_sec &&
- itnew->it_value.tv_usec == itnew->it_interval.tv_usec));
-
- if (kind == ITIMER_REAL)
- return setitimer_helper (itnew, itold, &it_alarm, &tid_alarm, SIGALRM);
- else if (kind == ITIMER_PROF)
- return setitimer_helper (itnew, itold, &it_prof, &tid_prof, SIGPROF);
- else
- return errno = EINVAL;
-}
-
-\f
void
syms_of_win32 (void)
{
DEFSUBR (Fmswindows_shell_execute);
-#ifdef CYGWIN
- DEFSUBR (Fmswindows_cygwin_to_win32_path);
-#endif
}
void