summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGlenn Morris <rgm@gnu.org>2014-09-14 17:20:21 -0700
committerGlenn Morris <rgm@gnu.org>2014-09-14 17:20:21 -0700
commit11af46027d22daa11d0df7d5032e6925c990dad1 (patch)
tree4d0d528afaf7449dba3cb73af0745980306c57d0 /src
parent5ce52d05c93e0c006bbd145b938aa9fab7dfcb8d (diff)
parentd4dc0e1691a15efd1ea0a8793cf889e683a37933 (diff)
downloademacs-11af46027d22daa11d0df7d5032e6925c990dad1.tar.gz
Merge from emacs-24; up to 2014-07-09T02:04:12Z!rgm@gnu.org
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog37
-rw-r--r--src/nsterm.m17
-rw-r--r--src/sound.c17
-rw-r--r--src/w32.c56
-rw-r--r--src/window.c4
-rw-r--r--src/xdisp.c17
6 files changed, 117 insertions, 31 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 015ed3618cf..5f1dfbfe785 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,40 @@
+2014-09-15 Eli Zaretskii <eliz@gnu.org>
+
+ * w32.c (fcntl): Support O_NONBLOCK fcntl on the write side of pipes.
+ (sys_write): When a write to a non-blocking pipe returns ENOSPC,
+ set errno to EAGAIN instead, to allow the caller to retry the
+ write after some waiting. Fixes deadlocks when Emacs exchanges a
+ lot of data through the pipe. (Bug#18420)
+
+ * sound.c (Fplay_sound_internal): Encode the sound file name in
+ the ANSI codepage. Expand it against data-directory, as per docs,
+ not against the current directory. No need to make a local copy
+ of the file name; pass the encoded file name directly to
+ do_play_sound. (Bug#18463)
+
+ * w32.c (ansi_encode_filename): If w32_get_short_filename returns
+ NULL, and the file name is not encodable in ANSI codepage, return
+ the string with "?" replacement characters, which will fail the
+ caller. This avoids returning a random value in that case.
+
+2014-09-15 Martin Rudalics <rudalics@gmx.at>
+
+ * window.c (Fresize_mini_window_internal): Set w->total_lines
+ from w->pixel_height (Bug#18422).
+
+2014-09-15 Jan Djärv <jan.h.d@swipnet.se>
+
+ * nsterm.m (updateFrameSize:, initFrameFromEmacs:)
+ (toggleFullScreen:): Take frame_resize_pixelwise into account when
+ setting resize increments (Bug#18435).
+
+2014-09-15 Eli Zaretskii <eliz@gnu.org>
+
+ * xdisp.c (pos_visible_p): Properly save and restore the iterator
+ state around the call to line_bottom, since it can move the
+ iterator to another screen line. This fixes off-by-one errors in
+ the reported row in some rare cases.
+
2014-09-14 Jan Djärv <jan.h.d@swipnet.se>
* callproc.c (init_callproc): Fix bug introduced at
diff --git a/src/nsterm.m b/src/nsterm.m
index dc775fc417a..5f86369a8c4 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -5849,10 +5849,13 @@ not_in_argv (NSString *arg)
// Did resize increments change because of a font change?
if (sz.width != FRAME_COLUMN_WIDTH (emacsframe) ||
- sz.height != FRAME_LINE_HEIGHT (emacsframe))
+ sz.height != FRAME_LINE_HEIGHT (emacsframe) ||
+ (frame_resize_pixelwise && sz.width != 1))
{
- sz.width = FRAME_COLUMN_WIDTH (emacsframe);
- sz.height = FRAME_LINE_HEIGHT (emacsframe);
+ sz.width = frame_resize_pixelwise
+ ? 1 : FRAME_COLUMN_WIDTH (emacsframe);
+ sz.height = frame_resize_pixelwise
+ ? 1 : FRAME_LINE_HEIGHT (emacsframe);
[win setResizeIncrements: sz];
NSTRACE_SIZE ("New size", NSMakeSize (neww, newh));
@@ -6122,8 +6125,8 @@ if (cols > 0 && rows > 0)
[win setDelegate: self];
[win useOptimizedDrawing: YES];
- sz.width = FRAME_COLUMN_WIDTH (f);
- sz.height = FRAME_LINE_HEIGHT (f);
+ sz.width = frame_resize_pixelwise ? 1 : FRAME_COLUMN_WIDTH (f);
+ sz.height = frame_resize_pixelwise ? 1 : FRAME_LINE_HEIGHT (f);
[win setResizeIncrements: sz];
[[win contentView] addSubview: self];
@@ -6470,8 +6473,8 @@ if (cols > 0 && rows > 0)
(FRAME_DEFAULT_FACE (f)),
f);
- sz.width = FRAME_COLUMN_WIDTH (f);
- sz.height = FRAME_LINE_HEIGHT (f);
+ sz.width = frame_resize_pixelwise ? 1 : FRAME_COLUMN_WIDTH (f);
+ sz.height = frame_resize_pixelwise ? 1 : FRAME_LINE_HEIGHT (f);
if (fs_state != FULLSCREEN_BOTH)
{
diff --git a/src/sound.c b/src/sound.c
index 9351097138d..7ba14b36f33 100644
--- a/src/sound.c
+++ b/src/sound.c
@@ -88,6 +88,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <limits.h>
#include <windows.h>
#include <mmsystem.h>
+
+#include "coding.h"
+#include "w32.h"
/* END: Windows Specific Includes */
#endif /* WINDOWSNT */
@@ -1310,8 +1313,7 @@ Internal use only, use `play-sound' instead. */)
struct gcpro gcpro1, gcpro2;
Lisp_Object args[2];
#else /* WINDOWSNT */
- Lisp_Object lo_file = {0};
- char * psz_file = NULL;
+ Lisp_Object lo_file;
unsigned long ui_volume_tmp = UINT_MAX;
unsigned long ui_volume = UINT_MAX;
#endif /* WINDOWSNT */
@@ -1384,10 +1386,11 @@ Internal use only, use `play-sound' instead. */)
#else /* WINDOWSNT */
- lo_file = Fexpand_file_name (attrs[SOUND_FILE], Qnil);
- len = XSTRING (lo_file)->size;
- psz_file = alloca (len + 1);
- strcpy (psz_file, XSTRING (lo_file)->data);
+ lo_file = Fexpand_file_name (attrs[SOUND_FILE], Vdata_directory);
+ lo_file = ENCODE_FILE (lo_file);
+ /* Since UNICOWS.DLL includes only a stub for mciSendStringW, we
+ need to encode the file in the ANSI codepage. */
+ lo_file = ansi_encode_filename (lo_file);
if (INTEGERP (attrs[SOUND_VOLUME]))
{
ui_volume_tmp = XFASTINT (attrs[SOUND_VOLUME]);
@@ -1409,7 +1412,7 @@ Internal use only, use `play-sound' instead. */)
{
ui_volume = ui_volume_tmp * (UINT_MAX / 100);
}
- do_play_sound (psz_file, ui_volume);
+ do_play_sound (SDATA (lo_file), ui_volume);
#endif /* WINDOWSNT */
diff --git a/src/w32.c b/src/w32.c
index cc0d0af3445..95e6d394ee0 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -2391,6 +2391,8 @@ ansi_encode_filename (Lisp_Object filename)
dostounix_filename (shortname);
encoded_filename = build_string (shortname);
}
+ else
+ encoded_filename = build_unibyte_string (fname);
}
else
encoded_filename = build_unibyte_string (fname);
@@ -7720,15 +7722,15 @@ fcntl (int s, int cmd, int options)
if (cmd == F_DUPFD_CLOEXEC)
return sys_dup (s);
- if (winsock_lib == NULL)
- {
- errno = ENETDOWN;
- return -1;
- }
-
check_errno ();
if (fd_info[s].flags & FILE_SOCKET)
{
+ if (winsock_lib == NULL)
+ {
+ errno = ENETDOWN;
+ return -1;
+ }
+
if (cmd == F_SETFL && options == O_NONBLOCK)
{
unsigned long nblock = 1;
@@ -7745,13 +7747,36 @@ fcntl (int s, int cmd, int options)
return SOCKET_ERROR;
}
}
+ else if ((fd_info[s].flags & (FILE_PIPE | FILE_WRITE))
+ == (FILE_PIPE | FILE_WRITE))
+ {
+ /* Force our writes to pipes be non-blocking. */
+ if (cmd == F_SETFL && options == O_NONBLOCK)
+ {
+ HANDLE h = (HANDLE)_get_osfhandle (s);
+ DWORD pipe_mode = PIPE_NOWAIT;
+
+ if (!SetNamedPipeHandleState (h, &pipe_mode, NULL, NULL))
+ {
+ DebPrint (("SetNamedPipeHandleState: %lu\n", GetLastError ()));
+ return SOCKET_ERROR;
+ }
+ fd_info[s].flags |= FILE_NDELAY;
+ return 0;
+ }
+ else
+ {
+ errno = EINVAL;
+ return SOCKET_ERROR;
+ }
+ }
errno = ENOTSOCK;
return SOCKET_ERROR;
}
/* Shadow main io functions: we need to handle pipes and sockets more
- intelligently, and implement non-blocking mode as well. */
+ intelligently. */
int
sys_close (int fd)
@@ -8236,7 +8261,6 @@ sys_read (int fd, char * buffer, unsigned int count)
/* From w32xfns.c */
extern HANDLE interrupt_handle;
-/* For now, don't bother with a non-blocking mode */
int
sys_write (int fd, const void * buffer, unsigned int count)
{
@@ -8388,6 +8412,22 @@ sys_write (int fd, const void * buffer, unsigned int count)
nchars += n;
if (n < 0)
{
+ /* When there's no buffer space in a pipe that is in the
+ non-blocking mode, _write returns ENOSPC. We return
+ EAGAIN instead, which should trigger the logic in
+ send_process that enters waiting loop and calls
+ wait_reading_process_output to allow process input to
+ be accepted during the wait. Those calls to
+ wait_reading_process_output allow sys_select to
+ notice when process input becomes available, thus
+ avoiding deadlock whereby each side of the pipe is
+ blocked on write, waiting for the other party to read
+ its end of the pipe. */
+ if (errno == ENOSPC
+ && fd < MAXDESC
+ && ((fd_info[fd].flags & (FILE_PIPE | FILE_NDELAY))
+ == (FILE_PIPE | FILE_NDELAY)))
+ errno = EAGAIN;
nchars = n;
break;
}
diff --git a/src/window.c b/src/window.c
index 8736fe13c3b..ce651abdda9 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4796,10 +4796,10 @@ DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini
block_input ();
window_resize_apply (r, 0);
- w->total_lines = XFASTINT (w->new_total);
- w->top_line = r->top_line + r->total_lines;
w->pixel_height = XFASTINT (w->new_pixel);
+ w->total_lines = w->pixel_height / FRAME_LINE_HEIGHT (f);
w->pixel_top = r->pixel_top + r->pixel_height;
+ w->top_line = r->top_line + r->total_lines;
fset_redisplay (f);
FRAME_WINDOW_SIZES_CHANGED (f) = 1;
diff --git a/src/xdisp.c b/src/xdisp.c
index d02caba5c19..1c6362d0345 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -1455,15 +1455,19 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
glyph. */
int top_x = it.current_x;
int top_y = it.current_y;
- /* Calling line_bottom_y may change it.method, it.position, etc. */
- enum it_method it_method = it.method;
- int bottom_y = (last_height = 0, line_bottom_y (&it));
int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
+ int bottom_y;
+ struct it save_it;
+ void *save_it_data = NULL;
+ /* Calling line_bottom_y may change it.method, it.position, etc. */
+ SAVE_IT (save_it, it, save_it_data);
+ last_height = 0;
+ bottom_y = line_bottom_y (&it);
if (top_y < window_top_y)
visible_p = bottom_y > window_top_y;
else if (top_y < it.last_visible_y)
- visible_p = true;
+ visible_p = 1;
if (bottom_y >= it.last_visible_y
&& it.bidi_p && it.bidi_it.scan_dir == -1
&& IT_CHARPOS (it) < charpos)
@@ -1476,7 +1480,6 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
move_it_to again with a slightly larger vertical limit,
and see if it actually moved vertically; if it did, we
didn't really reach CHARPOS, which is beyond window end. */
- struct it save_it = it;
/* Why 10? because we don't know how many canonical lines
will the height of the next line(s) be. So we guess. */
int ten_more_lines = 10 * default_line_pixel_height (w);
@@ -1486,11 +1489,11 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
if (it.current_y > top_y)
visible_p = 0;
- it = save_it;
}
+ RESTORE_IT (&it, &save_it, save_it_data);
if (visible_p)
{
- if (it_method == GET_FROM_DISPLAY_VECTOR)
+ if (it.method == GET_FROM_DISPLAY_VECTOR)
{
/* We stopped on the last glyph of a display vector.
Try and recompute. Hack alert! */