]> code.delx.au - gnu-emacs/blobdiff - src/nsterm.m
Fix bug #12878 with compilation failure with Visual C++ 11.0.
[gnu-emacs] / src / nsterm.m
index 1d935fc76de5dd854f001010e20393c004f5c265..9d52bd7f52b46718b09dc5cd83f3dc0b4581a0e3 100644 (file)
@@ -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
@@ -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);
 }