X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/1399490e2bb58e1e7212d7a8469e1286ced9423a..bf6b4923f7eedea193dee2130bf7fa597a5932d4:/src/msdos.c diff --git a/src/msdos.c b/src/msdos.c index a2bcc06ac1..010a0a3746 100644 --- a/src/msdos.c +++ b/src/msdos.c @@ -1,6 +1,6 @@ /* MS-DOS specific C utilities. -*- coding: cp850 -*- -Copyright (C) 1993-1997, 1999-2013 Free Software Foundation, Inc. +Copyright (C) 1993-1997, 1999-2014 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -50,6 +50,8 @@ along with GNU Emacs. If not, see . */ #include /* for chdir, dup, dup2, etc. */ #include /* for getdisk */ #pragma pack(0) /* dir.h does a pack(4), which isn't GCC's default */ +#undef opendir +#include /* for opendir */ #include #include /* for setmode */ #include /* for __dpmi_xxx stuff */ @@ -298,7 +300,7 @@ mouse_button_depressed (int b, int *xp, int *yp) } void -mouse_get_pos (FRAME_PTR *f, int insist, Lisp_Object *bar_window, +mouse_get_pos (struct frame **f, int insist, Lisp_Object *bar_window, enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y, Time *time) { @@ -408,7 +410,7 @@ static int term_setup_done; static unsigned short outside_cursor; -/* Similar to the_only_frame. */ +/* The only display since MS-DOS does not support multiple ones. */ struct tty_display_info the_only_display_info; /* Support for DOS/V (allows Japanese characters to be displayed on @@ -602,11 +604,7 @@ dos_set_window_size (int *rows, int *cols) Lisp_Object window = hlinfo->mouse_face_window; if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f) - { - hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; - hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; - hlinfo->mouse_face_window = Qnil; - } + reset_mouse_highlight (hlinfo); } /* Enable bright background colors. */ @@ -950,9 +948,6 @@ IT_write_glyphs (struct frame *f, struct glyph *str, int str_len) Mouse Highlight (and friends..) ************************************************************************/ -/* Last window where we saw the mouse. Used by mouse-autoselect-window. */ -static Lisp_Object last_mouse_window; - static int mouse_preempted = 0; /* non-zero when XMenu gobbles mouse events */ int @@ -1158,7 +1153,7 @@ IT_display_cursor (int on) to put the cursor at the end of the text displayed there. */ static void -IT_cmgoto (FRAME_PTR f) +IT_cmgoto (struct frame *f) { /* Only set the cursor to where it should be if the display is already in sync with the window contents. */ @@ -1229,7 +1224,7 @@ IT_cmgoto (FRAME_PTR f) static void IT_update_begin (struct frame *f) { - struct tty_display_info *display_info = FRAME_X_DISPLAY_INFO (f); + struct tty_display_info *display_info = FRAME_DISPLAY_INFO (f); Mouse_HLInfo *hlinfo = &display_info->mouse_highlight; struct frame *mouse_face_frame = hlinfo->mouse_face_mouse_frame; @@ -1276,14 +1271,9 @@ IT_update_begin (struct frame *f) } } else if (mouse_face_frame && !FRAME_LIVE_P (mouse_face_frame)) - { - /* If the frame with mouse highlight was deleted, invalidate the - highlight info. */ - hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; - hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; - hlinfo->mouse_face_window = Qnil; - hlinfo->mouse_face_mouse_frame = NULL; - } + /* If the frame with mouse highlight was deleted, invalidate the + highlight info. */ + reset_mouse_highlight (hlinfo); unblock_input (); } @@ -1291,7 +1281,7 @@ IT_update_begin (struct frame *f) static void IT_update_end (struct frame *f) { - struct tty_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); + struct tty_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); if (dpyinfo->termscript) fprintf (dpyinfo->termscript, "\n= 0 && colors[1] < 16) FRAME_BACKGROUND_PIXEL (SELECTED_FRAME ()) = colors[1]; } - the_only_display_info.mouse_highlight.mouse_face_mouse_frame = NULL; - the_only_display_info.mouse_highlight.mouse_face_beg_row = - the_only_display_info.mouse_highlight.mouse_face_beg_col = -1; - the_only_display_info.mouse_highlight.mouse_face_end_row = - the_only_display_info.mouse_highlight.mouse_face_end_col = -1; - the_only_display_info.mouse_highlight.mouse_face_face_id = DEFAULT_FACE_ID; - the_only_display_info.mouse_highlight.mouse_face_window = Qnil; - the_only_display_info.mouse_highlight.mouse_face_mouse_x = - the_only_display_info.mouse_highlight.mouse_face_mouse_y = 0; - the_only_display_info.mouse_highlight.mouse_face_defer = 0; - the_only_display_info.mouse_highlight.mouse_face_hidden = 0; + + reset_mouse_highlight (&the_only_display_info.mouse_highlight); if (have_mouse) /* detected in dos_ttraw, which see */ { @@ -1889,7 +1858,7 @@ initialize_msdos_display (struct terminal *term) term->ring_bell_hook = IT_ring_bell; term->reset_terminal_modes_hook = IT_reset_terminal_modes; term->set_terminal_modes_hook = IT_set_terminal_modes; - term->set_terminal_window_hook = IT_set_terminal_window; + term->set_terminal_window_hook = NULL; term->update_begin_hook = IT_update_begin; term->update_end_hook = IT_update_end; term->frame_up_to_date_hook = IT_frame_up_to_date; @@ -1916,18 +1885,6 @@ dos_get_saved_screen (char **screen, int *rows, int *cols) #endif } -#ifndef HAVE_X_WINDOWS - -/* We are not X, but we can emulate it well enough for our needs... */ -void -check_window_system (void) -{ - if (! FRAME_MSDOS_P (SELECTED_FRAME ())) - error ("Not running under a window system"); -} - -#endif - /* ----------------------- Keyboard control ---------------------- * @@ -2691,10 +2648,10 @@ dos_rawgetc (void) /* Generate SELECT_WINDOW_EVENTs when needed. */ if (!NILP (Vmouse_autoselect_window)) { - mouse_window = window_from_coordinates (SELECTED_FRAME (), - mouse_last_x, - mouse_last_y, - 0, 0); + static Lisp_Object last_mouse_window; + + mouse_window = window_from_coordinates + (SELECTED_FRAME (), mouse_last_x, mouse_last_y, 0, 0); /* A window will be selected only when it is not selected now, and the last mouse movement event was not in it. A minibuffer window will be selected iff @@ -2709,10 +2666,9 @@ dos_rawgetc (void) event.timestamp = event_timestamp (); kbd_buffer_store_event (&event); } + /* Remember the last window where we saw the mouse. */ last_mouse_window = mouse_window; } - else - last_mouse_window = Qnil; previous_help_echo_string = help_echo_string; help_echo_string = help_echo_object = help_echo_window = Qnil; @@ -3320,18 +3276,6 @@ XMenuDestroy (Display *foo, XMenu *menu) xfree (menu); menu_help_message = prev_menu_help_message = NULL; } - -int -x_pixel_width (struct frame *f) -{ - return FRAME_COLS (f); -} - -int -x_pixel_height (struct frame *f) -{ - return FRAME_LINES (f); -} #endif /* !HAVE_X_WINDOWS */ /* ----------------------- DOS / UNIX conversion --------------------- */ @@ -3341,7 +3285,7 @@ void msdos_downcase_filename (unsigned char *); /* Destructively turn backslashes into slashes. */ void -dostounix_filename (char *p, int ignore) +dostounix_filename (char *p) { msdos_downcase_filename (p); @@ -3605,7 +3549,7 @@ init_environment (int argc, char **argv, int skip_args) if (!s) s = "c:/command.com"; t = alloca (strlen (s) + 1); strcpy (t, s); - dostounix_filename (t, 0); + dostounix_filename (t); setenv ("SHELL", t, 0); /* PATH is also downcased and backslashes mirrored. */ @@ -3615,7 +3559,7 @@ init_environment (int argc, char **argv, int skip_args) /* Current directory is always considered part of MsDos's path but it is not normally mentioned. Now it is. */ strcat (strcpy (t, ".;"), s); - dostounix_filename (t, 0); /* Not a single file name, but this should work. */ + dostounix_filename (t); /* Not a single file name, but this should work. */ setenv ("PATH", t, 1); /* In some sense all dos users have root privileges, so... */ @@ -3921,6 +3865,9 @@ int setpgid (int pid, int pgid) { return 0; } int setpriority (int x, int y, int z) { return 0; } pid_t setsid (void) { return 0; } + +/* Gnulib support and emulation. */ + #if __DJGPP__ == 2 && __DJGPP_MINOR__ < 4 ssize_t readlink (const char *name, char *dummy1, size_t dummy2) @@ -3932,6 +3879,38 @@ readlink (const char *name, char *dummy1, size_t dummy2) } #endif +/* dir_pathname is set by sys_opendir and used in readlinkat and in + fstatat, when they get a special FD of zero, which means use the + last directory opened by opendir. */ +static char dir_pathname[MAXPATHLEN]; +DIR * +sys_opendir (const char *dirname) +{ + _fixpath (dirname, dir_pathname); + return opendir (dirname); +} + +ssize_t +readlinkat (int fd, char const *name, char *buffer, size_t buffer_size) +{ + /* Rely on a hack: an open directory is modeled as file descriptor 0, + as in fstatat. FIXME: Add proper support for readlinkat. */ + char fullname[MAXPATHLEN]; + + if (fd != AT_FDCWD) + { + if (strlen (dir_pathname) + strlen (name) + 1 >= MAXPATHLEN) + { + errno = ENAMETOOLONG; + return -1; + } + sprintf (fullname, "%s/%s", dir_pathname, name); + name = fullname; + } + + return readlink (name, buffer, buffer_size); +} + char * careadlinkat (int fd, char const *filename, char *buffer, size_t buffer_size, @@ -3959,6 +3938,82 @@ careadlinkat (int fd, char const *filename, return buffer; } +/* Emulate faccessat(2). */ +int +faccessat (int dirfd, const char * path, int mode, int flags) +{ + /* We silently ignore FLAGS. */ + flags = flags; + + if (dirfd != AT_FDCWD + && !(IS_DIRECTORY_SEP (path[0]) + || IS_DEVICE_SEP (path[1]))) + { + errno = EBADF; + return -1; + } + + return access (path, mode); +} + +/* Emulate fstatat. */ +int +fstatat (int fd, char const *name, struct stat *st, int flags) +{ + /* Rely on a hack: an open directory is modeled as file descriptor 0. + This is good enough for the current usage in Emacs, but is fragile. + + FIXME: Add proper support for fdopendir, fstatat, readlinkat. + Gnulib does this and can serve as a model. */ + char fullname[MAXPATHLEN]; + + flags = flags; + + if (fd != AT_FDCWD) + { + char lastc = dir_pathname[strlen (dir_pathname) - 1]; + + if (strlen (dir_pathname) + strlen (name) + IS_DIRECTORY_SEP (lastc) + >= MAXPATHLEN) + { + errno = ENAMETOOLONG; + return -1; + } + + sprintf (fullname, "%s%s%s", + dir_pathname, IS_DIRECTORY_SEP (lastc) ? "" : "/", name); + name = fullname; + } + +#if __DJGPP__ > 2 || __DJGPP_MINOR__ > 3 + return (flags & AT_SYMLINK_NOFOLLOW) ? lstat (name, st) : stat (name, st); +#else + return stat (name, st); +#endif +} + +#if __DJGPP__ == 2 && __DJGPP_MINOR__ < 4 +/* Emulate the Posix unsetenv. DJGPP v2.04 has this in the library. */ +int +unsetenv (const char *name) +{ + char *var; + size_t name_len; + int retval; + + if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) + { + errno = EINVAL; + return -1; + } + + /* DJGPP's 'putenv' deletes the entry if it doesn't include '='. */ + putenv (name); + + return 0; +} +#endif + #if __DJGPP__ == 2 && __DJGPP_MINOR__ < 2 @@ -4084,8 +4139,8 @@ dos_yield_time_slice (void) /* We don't have to call timer_check here because wait_reading_process_output takes care of that. */ int -sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, - EMACS_TIME *timeout, void *ignored) +sys_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, + struct timespec *timeout, void *ignored) { int check_input; struct timespec t; @@ -4115,20 +4170,20 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, } else { - EMACS_TIME clnow, cllast, cldiff; + struct timespec clnow, cllast, cldiff; gettime (&t); - cllast = make_emacs_time (t.tv_sec, t.tv_nsec); + cllast = make_timespec (t.tv_sec, t.tv_nsec); while (!check_input || !detect_input_pending ()) { gettime (&t); - clnow = make_emacs_time (t.tv_sec, t.tv_nsec); - cldiff = sub_emacs_time (clnow, cllast); - *timeout = sub_emacs_time (*timeout, cldiff); + clnow = make_timespec (t.tv_sec, t.tv_nsec); + cldiff = timespec_sub (clnow, cllast); + *timeout = timespec_sub (*timeout, cldiff); /* Stop when timeout value crosses zero. */ - if (EMACS_TIME_SIGN (*timeout) <= 0) + if (timespec_sign (*timeout) <= 0) return 0; cllast = clnow; dos_yield_time_slice ();