X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/d3e4228575e9ba9e99dc4a7dae788280ffcc4566..ab422c4d6899b1442cb6954c1829c1fb656b006c:/src/nsterm.m diff --git a/src/nsterm.m b/src/nsterm.m index 1d935fc76d..d9ebf714a9 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -1,7 +1,7 @@ /* NeXT/Open/GNUstep / MacOSX communication module. -Copyright (C) 1989, 1993-1994, 2005-2006, 2008-2012 - Free Software Foundation, Inc. +Copyright (C) 1989, 1993-1994, 2005-2006, 2008-2013 Free Software +Foundation, Inc. This file is part of GNU Emacs. @@ -190,7 +190,8 @@ static BOOL ns_menu_bar_is_hidden = NO; /* event loop */ static BOOL send_appdefined = YES; -static NSEvent *last_appdefined_event = 0; +#define NO_APPDEFINED_DATA (-8) +static int last_appdefined_event_data = NO_APPDEFINED_DATA; static NSTimer *timed_entry = 0; static NSTimer *scroll_repeat_entry = nil; static fd_set select_readfds, select_writefds; @@ -208,6 +209,13 @@ static NSMutableArray *ns_pending_files, *ns_pending_service_names, *ns_pending_service_args; static BOOL ns_do_open_file = NO; +static struct { + struct input_event *q; + int nr, cap; +} hold_event_q = { + NULL, 0, 0 +}; + /* Convert modifiers in a NeXTstep event to emacs style modifiers. */ #define NS_FUNCTION_KEY_MASK 0x800000 #define NSLeftControlKeyMask (0x000001 | NSControlKeyMask) @@ -273,7 +281,7 @@ static BOOL ns_do_open_file = NO; kbd_buffer_store_event_hold (emacs_event, q_event_ptr); \ } \ else \ - kbd_buffer_store_event (emacs_event); \ + hold_event (emacs_event); \ EVENT_INIT (*emacs_event); \ ns_send_appdefined (-1); \ } @@ -292,6 +300,22 @@ void x_set_frame_alpha (struct frame *f); ========================================================================== */ +static void +hold_event (struct input_event *event) +{ + if (hold_event_q.nr == hold_event_q.cap) + { + if (hold_event_q.cap == 0) hold_event_q.cap = 10; + else hold_event_q.cap *= 2; + hold_event_q.q = (struct input_event *) + xrealloc (hold_event_q.q, hold_event_q.cap * sizeof (*hold_event_q.q)); + } + + hold_event_q.q[hold_event_q.nr++] = *event; + /* Make sure ns_read_socket is called, i.e. we have input. */ + kill (0, SIGIO); + send_appdefined = YES; +} static Lisp_Object append2 (Lisp_Object list, Lisp_Object item) @@ -3348,6 +3372,15 @@ ns_read_socket (struct terminal *terminal, struct input_event *hold_quit) if ([NSApp modalWindow] != nil) return -1; + if (hold_event_q.nr > 0) + { + int i; + for (i = 0; i < hold_event_q.nr; ++i) + kbd_buffer_store_event_hold (&hold_event_q.q[i], hold_quit); + hold_event_q.nr = 0; + return i; + } + block_input (); n_emacs_events_pending = 0; EVENT_INIT (ev); @@ -3407,15 +3440,25 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds, -------------------------------------------------------------------------- */ { int result; - NSEvent *ev; - int k, nr = 0; + int t, k, nr = 0; struct input_event event; char c; /* NSTRACE (ns_select); */ - for (k = 0; readfds && k < nfds+1; k++) - if (FD_ISSET(k, readfds)) ++nr; + if (hold_event_q.nr > 0) + { + /* We already have events pending. */ + kill (0, SIGIO); + errno = EINTR; + return -1; + } + + for (k = 0; k < nfds+1; k++) + { + if (readfds && FD_ISSET(k, readfds)) ++nr; + if (writefds && FD_ISSET(k, writefds)) ++nr; + } if (NSApp == nil || (timeout && timeout->tv_sec == 0 && timeout->tv_nsec == 0)) @@ -3489,16 +3532,11 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds, } unblock_input (); - ev = last_appdefined_event; + t = last_appdefined_event_data; - if (ev) + if (t != NO_APPDEFINED_DATA) { - int t; - if ([ev type] != NSApplicationDefined) - emacs_abort (); - - t = [ev data1]; - last_appdefined_event = 0; + last_appdefined_event_data = NO_APPDEFINED_DATA; if (t == -2) { @@ -4275,7 +4313,7 @@ ns_term_shutdown (int sig) modal loop. Just defer it until later. */ if ([NSApp modalWindow] == nil) { - last_appdefined_event = theEvent; + last_appdefined_event_data = [theEvent data1]; [self stop: self]; } else @@ -4528,7 +4566,7 @@ not_in_argv (NSString *arg) if (waiting) { SELECT_TYPE fds; - + FD_ZERO (&fds); FD_SET (selfds[0], &fds); result = select (selfds[0]+1, &fds, NULL, NULL, NULL); if (result > 0) @@ -6645,6 +6683,12 @@ not_in_argv (NSString *arg) [self setFloatValue: pos knobProportion: por]; #endif } + + /* Events may come here even if the event loop is not running. + If we don't enter the event loop, the scroll bar will not update. + So send SIGIO to ourselves. */ + if (apploopnr == 0) kill (0, SIGIO); + return self; } @@ -6685,7 +6729,7 @@ not_in_argv (NSString *arg) kbd_buffer_store_event_hold (emacs_event, q_event_ptr); } else - kbd_buffer_store_event (emacs_event); + hold_event (emacs_event); EVENT_INIT (*emacs_event); ns_send_appdefined (-1); }