aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog32
-rw-r--r--src/nsmenu.m43
-rw-r--r--src/nsterm.h4
-rw-r--r--src/nsterm.m322
4 files changed, 281 insertions, 120 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 04a0df774f9..6e49dd44fde 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,37 @@
12012-08-15 Jan Djärv <jan.h.d@swipnet.se> 12012-08-15 Jan Djärv <jan.h.d@swipnet.se>
2 2
3 * nsmenu.m (popupSession): Remove.
4 (pop_down_menu): Remove endModalSession.
5 (timeout_handler:): New method.
6 (runDialogAt:): Get next timeout. Start a NSTimer with that timeout.
7 Call runModalForWindow. Check timer_fired when it returns.
8 If not set, cancel timer and break out of loop.
9 Otherwise loop again, with a new timeout.
10
11 * nsterm.m: Include fcntl.h if present.
12 (fd_entry, t_readfds, inNsSelect): Remove.
13 (select_writefds, select_valid, select_timeout, selfds)
14 (select_mutex, apploopnr): Add.
15 (EV_TRAILER): Call kbd_buffer_store_event_hold only if q_event_ptr.
16 Otherwise call kbd_buffer_store_event.
17 (ns_send_appdefined): Remove release of fd_entry.
18 (ns_read_socket): Always send appdefined. Remove inNsSelect check.
19 Increment and decrement apploopnr.
20 (ns_select): If no file descriptors, just do a NSTimer.
21 Otherwise copy read/write masks and start select thread (fd_handler).
22 Start main loop and wait for application defined event.
23 Inform select thread to stop selecting after main loop is exited.
24 (ns_term_init): Create selfds pipe and set non-blocking.
25 Initialize select_mutex. Start the select thread (fd_handler).
26 (fd_handler:): Loop forever, wait for info from the main thread
27 to either start or stop selecting. When select returns, send
28 and appdefined event.
29 (sendScrollEventAtLoc:fromEvent:): Check if q_event_ptr is set.
30 If not call kbd_buffer_store_event.
31
32 * nsterm.h (EmacsApp): fd_handler takes id argument.
33 (EmacsDialogPanel): Add timer_fired and timeout_handler.
34
3 * gtkutil.c (xg_mark_data): Use FRAME_X_P. 35 * gtkutil.c (xg_mark_data): Use FRAME_X_P.
4 36
52012-08-15 Eli Zaretskii <eliz@gnu.org> 372012-08-15 Eli Zaretskii <eliz@gnu.org>
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 210f4530d7a..657b9306942 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -73,7 +73,6 @@ EmacsMenu *mainMenu, *svcsMenu, *dockMenu;
73 73
74/* Nonzero means a menu is currently active. */ 74/* Nonzero means a menu is currently active. */
75static int popup_activated_flag; 75static int popup_activated_flag;
76static NSModalSession popupSession;
77 76
78/* Nonzero means we are tracking and updating menus. */ 77/* Nonzero means we are tracking and updating menus. */
79static int trackingMenu; 78static int trackingMenu;
@@ -1365,8 +1364,6 @@ pop_down_menu (Lisp_Object arg)
1365 { 1364 {
1366 EmacsDialogPanel *panel = unwind_data->dialog; 1365 EmacsDialogPanel *panel = unwind_data->dialog;
1367 popup_activated_flag = 0; 1366 popup_activated_flag = 0;
1368 [NSApp endModalSession: popupSession];
1369
1370 [panel close]; 1367 [panel close];
1371 [unwind_data->pool release]; 1368 [unwind_data->pool release];
1372 [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow]; 1369 [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
@@ -1756,20 +1753,40 @@ void process_dialog (id window, Lisp_Object list)
1756} 1753}
1757 1754
1758 1755
1756
1757- (void)timeout_handler: (NSTimer *)timedEntry
1758{
1759 timer_fired = 1;
1760 [NSApp abortModal];
1761}
1762
1759- (Lisp_Object)runDialogAt: (NSPoint)p 1763- (Lisp_Object)runDialogAt: (NSPoint)p
1760{ 1764{
1761 NSInteger ret; 1765 NSInteger ret = 0;
1762 1766
1763 /* initiate a session that will be ended by pop_down_menu */ 1767 while (popup_activated_flag)
1764 popupSession = [NSApp beginModalSessionForWindow: self];
1765 while (popup_activated_flag
1766 && (ret = [NSApp runModalSession: popupSession])
1767 == NSRunContinuesResponse)
1768 { 1768 {
1769 /* Run this for timers.el, indep of atimers; might not return. 1769 NSTimer *tmo = nil;
1770 TODO: use return value to avoid calling every iteration. */ 1770 EMACS_TIME next_time = timer_check ();
1771 timer_check (); 1771
1772 [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.1]]; 1772 if (EMACS_TIME_VALID_P (next_time))
1773 {
1774 double time = EMACS_TIME_TO_DOUBLE (next_time);
1775 tmo = [NSTimer timerWithTimeInterval: time
1776 target: self
1777 selector: @selector (timeout_handler:)
1778 userInfo: 0
1779 repeats: NO];
1780 [[NSRunLoop currentRunLoop] addTimer: tmo
1781 forMode: NSModalPanelRunLoopMode];
1782 }
1783 timer_fired = 0;
1784 ret = [NSApp runModalForWindow: self];
1785 if (! timer_fired)
1786 {
1787 if (tmo != nil) [tmo invalidate]; /* Cancels timer */
1788 break;
1789 }
1773 } 1790 }
1774 1791
1775 { /* FIXME: BIG UGLY HACK!!! */ 1792 { /* FIXME: BIG UGLY HACK!!! */
diff --git a/src/nsterm.h b/src/nsterm.h
index de41929e3fd..94984b3d35e 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -56,7 +56,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
56- (void)sendEvent: (NSEvent *)theEvent; 56- (void)sendEvent: (NSEvent *)theEvent;
57- (void)showPreferencesWindow: (id)sender; 57- (void)showPreferencesWindow: (id)sender;
58- (BOOL) openFile: (NSString *)fileName; 58- (BOOL) openFile: (NSString *)fileName;
59- (void)fd_handler: (NSTimer *) fdEntry; 59- (void)fd_handler: (id)unused;
60- (void)timeout_handler: (NSTimer *)timedEntry; 60- (void)timeout_handler: (NSTimer *)timedEntry;
61- (BOOL)fulfillService: (NSString *)name withArg: (NSString *)arg; 61- (BOOL)fulfillService: (NSString *)name withArg: (NSString *)arg;
62@end 62@end
@@ -195,12 +195,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
195 NSTextField *title; 195 NSTextField *title;
196 NSMatrix *matrix; 196 NSMatrix *matrix;
197 int rows, cols; 197 int rows, cols;
198 int timer_fired;
198 } 199 }
199- initFromContents: (Lisp_Object)menu isQuestion: (BOOL)isQ; 200- initFromContents: (Lisp_Object)menu isQuestion: (BOOL)isQ;
200- addButton: (char *)str value: (Lisp_Object)val row: (int)row; 201- addButton: (char *)str value: (Lisp_Object)val row: (int)row;
201- addString: (char *)str row: (int)row; 202- addString: (char *)str row: (int)row;
202- addSplit; 203- addSplit;
203- (Lisp_Object)runDialogAt: (NSPoint)p; 204- (Lisp_Object)runDialogAt: (NSPoint)p;
205- (void)timeout_handler: (NSTimer *)timedEntry;
204@end 206@end
205 207
206#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 208#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
diff --git a/src/nsterm.m b/src/nsterm.m
index 5e3c3ac777f..76e6ee8fb40 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -39,6 +39,10 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
39#include <c-strcase.h> 39#include <c-strcase.h>
40#include <ftoastr.h> 40#include <ftoastr.h>
41 41
42#ifdef HAVE_FCNTL_H
43#include <fcntl.h>
44#endif
45
42#include "lisp.h" 46#include "lisp.h"
43#include "blockinput.h" 47#include "blockinput.h"
44#include "sysselect.h" 48#include "sysselect.h"
@@ -184,17 +188,20 @@ static BOOL ns_menu_bar_is_hidden = NO;
184static BOOL send_appdefined = YES; 188static BOOL send_appdefined = YES;
185static NSEvent *last_appdefined_event = 0; 189static NSEvent *last_appdefined_event = 0;
186static NSTimer *timed_entry = 0; 190static NSTimer *timed_entry = 0;
187static NSTimer *fd_entry = nil;
188static NSTimer *scroll_repeat_entry = nil; 191static NSTimer *scroll_repeat_entry = nil;
189static fd_set select_readfds, t_readfds; 192static fd_set select_readfds, select_writefds;
190static int select_nfds; 193enum { SELECT_HAVE_READ = 1, SELECT_HAVE_WRITE = 2, SELECT_HAVE_TMO = 4 };
194static int select_nfds = 0, select_valid = 0;
195static EMACS_TIME select_timeout = { 0, 0 };
196static int selfds[2] = { -1, -1 };
197static pthread_mutex_t select_mutex;
198static int apploopnr = 0;
191static NSAutoreleasePool *outerpool; 199static NSAutoreleasePool *outerpool;
192static struct input_event *emacs_event = NULL; 200static struct input_event *emacs_event = NULL;
193static struct input_event *q_event_ptr = NULL; 201static struct input_event *q_event_ptr = NULL;
194static int n_emacs_events_pending = 0; 202static int n_emacs_events_pending = 0;
195static NSMutableArray *ns_pending_files, *ns_pending_service_names, 203static NSMutableArray *ns_pending_files, *ns_pending_service_names,
196 *ns_pending_service_args; 204 *ns_pending_service_args;
197static BOOL inNsSelect = 0;
198static BOOL ns_do_open_file = NO; 205static BOOL ns_do_open_file = NO;
199 206
200/* Convert modifiers in a NeXTstep event to emacs style modifiers. */ 207/* Convert modifiers in a NeXTstep event to emacs style modifiers. */
@@ -252,15 +259,20 @@ static BOOL ns_do_open_file = NO;
252 259
253/* This is a piece of code which is common to all the event handling 260/* This is a piece of code which is common to all the event handling
254 methods. Maybe it should even be a function. */ 261 methods. Maybe it should even be a function. */
255#define EV_TRAILER(e) \ 262#define EV_TRAILER(e) \
256 { \ 263 { \
257 XSETFRAME (emacs_event->frame_or_window, emacsframe); \ 264 XSETFRAME (emacs_event->frame_or_window, emacsframe); \
258 if (e) emacs_event->timestamp = EV_TIMESTAMP (e); \ 265 if (e) emacs_event->timestamp = EV_TIMESTAMP (e); \
259 n_emacs_events_pending++; \ 266 if (q_event_ptr) \
260 kbd_buffer_store_event_hold (emacs_event, q_event_ptr); \ 267 { \
261 EVENT_INIT (*emacs_event); \ 268 n_emacs_events_pending++; \
262 ns_send_appdefined (-1); \ 269 kbd_buffer_store_event_hold (emacs_event, q_event_ptr); \
263 } 270 } \
271 else \
272 kbd_buffer_store_event (emacs_event); \
273 EVENT_INIT (*emacs_event); \
274 ns_send_appdefined (-1); \
275 }
264 276
265void x_set_cursor_type (struct frame *, Lisp_Object, Lisp_Object); 277void x_set_cursor_type (struct frame *, Lisp_Object, Lisp_Object);
266 278
@@ -3377,14 +3389,6 @@ ns_send_appdefined (int value)
3377 timed_entry = nil; 3389 timed_entry = nil;
3378 } 3390 }
3379 3391
3380 /* Ditto for file descriptor poller */
3381 if (fd_entry)
3382 {
3383 [fd_entry invalidate];
3384 [fd_entry release];
3385 fd_entry = nil;
3386 }
3387
3388 nxev = [NSEvent otherEventWithType: NSApplicationDefined 3392 nxev = [NSEvent otherEventWithType: NSApplicationDefined
3389 location: NSMakePoint (0, 0) 3393 location: NSMakePoint (0, 0)
3390 modifierFlags: 0 3394 modifierFlags: 0
@@ -3402,7 +3406,6 @@ ns_send_appdefined (int value)
3402 } 3406 }
3403} 3407}
3404 3408
3405
3406static int 3409static int
3407ns_read_socket (struct terminal *terminal, int expected, 3410ns_read_socket (struct terminal *terminal, int expected,
3408 struct input_event *hold_quit) 3411 struct input_event *hold_quit)
@@ -3466,24 +3469,14 @@ ns_read_socket (struct terminal *terminal, int expected,
3466 /* Run and wait for events. We must always send one NX_APPDEFINED event 3469 /* Run and wait for events. We must always send one NX_APPDEFINED event
3467 to ourself, otherwise [NXApp run] will never exit. */ 3470 to ourself, otherwise [NXApp run] will never exit. */
3468 send_appdefined = YES; 3471 send_appdefined = YES;
3472 ns_send_appdefined (-1);
3469 3473
3470 /* If called via ns_select, this is called once with expected=1, 3474 if (++apploopnr != 1)
3471 because we expect either the timeout or file descriptor activity.
3472 In this case the first event through will either be real input or
3473 one of these. read_avail_input() then calls once more with expected=0
3474 and in that case we need to return quickly if there is nothing.
3475 If we're being called outside of that, it's also OK to return quickly
3476 after one iteration through the event loop, since other terms do
3477 this and emacs expects it. */
3478 if (!(inNsSelect && expected))
3479 { 3475 {
3480 /* Post an application defined event on the event queue. When this is 3476 abort ();
3481 received the [NXApp run] will return, thus having processed all
3482 events which are currently queued, if any. */
3483 ns_send_appdefined (-1);
3484 } 3477 }
3485
3486 [NSApp run]; 3478 [NSApp run];
3479 --apploopnr;
3487 } 3480 }
3488 3481
3489 nevents = n_emacs_events_pending; 3482 nevents = n_emacs_events_pending;
@@ -3503,65 +3496,89 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds,
3503 -------------------------------------------------------------------------- */ 3496 -------------------------------------------------------------------------- */
3504{ 3497{
3505 int result; 3498 int result;
3506 double time;
3507 NSEvent *ev; 3499 NSEvent *ev;
3508 struct timespec select_timeout; 3500 int k, nr = 0;
3501 struct input_event event;
3502 char c;
3509 3503
3510/* NSTRACE (ns_select); */ 3504/* NSTRACE (ns_select); */
3511 3505
3512 if (NSApp == nil || inNsSelect == 1 /* || ([NSApp isActive] == NO && 3506 for (k = 0; readfds && k < nfds+1; k++)
3513 [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil 3507 if (FD_ISSET(k, readfds)) ++nr;
3514 inMode:NSDefaultRunLoopMode dequeue:NO] == nil) */) 3508
3509 if (NSApp == nil
3510 || (timeout && timeout->tv_sec == 0 && timeout->tv_nsec == 0))
3515 return pselect (nfds, readfds, writefds, exceptfds, timeout, sigmask); 3511 return pselect (nfds, readfds, writefds, exceptfds, timeout, sigmask);
3516 3512
3517 /* Save file descriptor set, which gets overwritten in calls to select () 3513 [outerpool release];
3518 Note, this is called from process.c, and only readfds is ever set */ 3514 outerpool = [[NSAutoreleasePool alloc] init];
3519 if (readfds) 3515
3516
3517 send_appdefined = YES;
3518 if (nr > 0)
3520 { 3519 {
3521 memcpy (&select_readfds, readfds, sizeof (fd_set)); 3520 pthread_mutex_lock (&select_mutex);
3522 select_nfds = nfds; 3521 select_nfds = nfds;
3522 select_valid = 0;
3523 if (readfds)
3524 {
3525 select_readfds = *readfds;
3526 select_valid += SELECT_HAVE_READ;
3527 }
3528 if (writefds)
3529 {
3530 select_writefds = *writefds;
3531 select_valid += SELECT_HAVE_WRITE;
3532 }
3533
3534 if (timeout)
3535 {
3536 select_timeout = *timeout;
3537 select_valid += SELECT_HAVE_TMO;
3538 }
3539
3540 pthread_mutex_unlock (&select_mutex);
3541
3542 /* Inform fd_handler that select should be called */
3543 c = 'g';
3544 write (selfds[1], &c, 1);
3523 } 3545 }
3524 else 3546 else if (nr == 0 && timeout)
3525 select_nfds = 0; 3547 {
3526 3548 /* No file descriptor, just a timeout, no need to wake fd_handler */
3527 /* Try an initial select for pending data on input files */ 3549 double time = EMACS_TIME_TO_DOUBLE (*timeout);
3528 select_timeout.tv_sec = select_timeout.tv_nsec = 0; 3550 timed_entry = [[NSTimer scheduledTimerWithTimeInterval: time
3529 result = pselect (nfds, readfds, writefds, exceptfds, 3551 target: NSApp
3530 &select_timeout, sigmask); 3552 selector:
3531 if (result) 3553 @selector (timeout_handler:)
3532 return result; 3554 userInfo: 0
3533 3555 repeats: NO]
3534 /* if (!timeout || timed_entry || fd_entry) 3556 retain];
3535 fprintf (stderr, "assertion failed: timeout null or timed_entry/fd_entry non-null in ns_select\n"); */ 3557 }
3536 3558 else /* No timeout and no file descriptors, can this happen? */
3537 /* set a timeout and run the main AppKit event loop while continuing 3559 {
3538 to monitor the files */ 3560 /* Send appdefined so we exit from the loop */
3539 time = EMACS_TIME_TO_DOUBLE (*timeout); 3561 ns_send_appdefined (-1);
3540 timed_entry = [[NSTimer scheduledTimerWithTimeInterval: time 3562 }
3541 target: NSApp 3563
3542 selector: @selector (timeout_handler:) 3564 EVENT_INIT (event);
3543 userInfo: 0 3565 BLOCK_INPUT;
3544 repeats: YES] /* for safe removal */ 3566 emacs_event = &event;
3545 retain]; 3567 if (++apploopnr != 1)
3546 3568 {
3547 /* set a periodic task to try the pselect () again */ 3569 abort();
3548 fd_entry = [[NSTimer scheduledTimerWithTimeInterval: 0.1 3570 }
3549 target: NSApp 3571 [NSApp run];
3550 selector: @selector (fd_handler:) 3572 --apploopnr;
3551 userInfo: 0 3573 emacs_event = NULL;
3552 repeats: YES] 3574 if (nr > 0 && readfds)
3553 retain]; 3575 {
3554 3576 c = 's';
3555 /* Let Application dispatch events until it receives an event of the type 3577 write (selfds[1], &c, 1);
3556 NX_APPDEFINED, which should only be sent by timeout_handler. 3578 }
3557 We tell read_avail_input() that input is "expected" because we do expect 3579 UNBLOCK_INPUT;
3558 either the timeout or fd handler to fire, and if they don't, the original 3580
3559 call from process.c that got us here expects us to wait until some input
3560 comes. */
3561 inNsSelect = 1;
3562 gobble_input (1);
3563 ev = last_appdefined_event; 3581 ev = last_appdefined_event;
3564 inNsSelect = 0;
3565 3582
3566 if (ev) 3583 if (ev)
3567 { 3584 {
@@ -3575,25 +3592,28 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds,
3575 if (t == -2) 3592 if (t == -2)
3576 { 3593 {
3577 /* The NX_APPDEFINED event we received was a timeout. */ 3594 /* The NX_APPDEFINED event we received was a timeout. */
3578 return 0; 3595 result = 0;
3579 } 3596 }
3580 else if (t == -1) 3597 else if (t == -1)
3581 { 3598 {
3582 /* The NX_APPDEFINED event we received was the result of 3599 /* The NX_APPDEFINED event we received was the result of
3583 at least one real input event arriving. */ 3600 at least one real input event arriving. */
3584 errno = EINTR; 3601 errno = EINTR;
3585 return -1; 3602 result = -1;
3586 } 3603 }
3587 else 3604 else
3588 { 3605 {
3589 /* Received back from pselect () in fd_handler; copy the results */ 3606 /* Received back from select () in fd_handler; copy the results */
3590 if (readfds) 3607 pthread_mutex_lock (&select_mutex);
3591 memcpy (readfds, &select_readfds, sizeof (fd_set)); 3608 if (readfds) *readfds = select_readfds;
3592 return t; 3609 if (writefds) *writefds = select_writefds;
3610 if (timeout) *timeout = select_timeout;
3611 pthread_mutex_unlock (&select_mutex);
3612 result = t;
3593 } 3613 }
3594 } 3614 }
3595 /* never reached, shut compiler up */ 3615
3596 return 0; 3616 return result;
3597} 3617}
3598 3618
3599 3619
@@ -4024,6 +4044,21 @@ ns_term_init (Lisp_Object display_name)
4024 { 4044 {
4025 baud_rate = 38400; 4045 baud_rate = 38400;
4026 Fset_input_interrupt_mode (Qnil); 4046 Fset_input_interrupt_mode (Qnil);
4047
4048 if (selfds[0] == -1)
4049 {
4050 if (pipe (selfds) == -1)
4051 {
4052 fprintf (stderr, "Failed to create pipe: %s\n",
4053 emacs_strerror (errno));
4054 abort ();
4055 }
4056
4057 fcntl (selfds[0], F_SETFL, O_NONBLOCK|fcntl (selfds[0], F_GETFL));
4058 FD_ZERO (&select_readfds);
4059 FD_ZERO (&select_writefds);
4060 pthread_mutex_init (&select_mutex, NULL);
4061 }
4027 ns_initialized = 1; 4062 ns_initialized = 1;
4028 } 4063 }
4029 4064
@@ -4039,6 +4074,11 @@ ns_term_init (Lisp_Object display_name)
4039 return NULL; 4074 return NULL;
4040 [NSApp setDelegate: NSApp]; 4075 [NSApp setDelegate: NSApp];
4041 4076
4077 /* Start the select thread. */
4078 [NSThread detachNewThreadSelector:@selector (fd_handler:)
4079 toTarget:NSApp
4080 withObject:nil];
4081
4042 /* debugging: log all notifications */ 4082 /* debugging: log all notifications */
4043 /* [[NSNotificationCenter defaultCenter] addObserver: NSApp 4083 /* [[NSNotificationCenter defaultCenter] addObserver: NSApp
4044 selector: @selector (logNotification:) 4084 selector: @selector (logNotification:)
@@ -4547,26 +4587,91 @@ not_in_argv (NSString *arg)
4547 ns_send_appdefined (-2); 4587 ns_send_appdefined (-2);
4548} 4588}
4549 4589
4550- (void)fd_handler: (NSTimer *) fdEntry 4590- (void)fd_handler:(id)unused
4551/* -------------------------------------------------------------------------- 4591/* --------------------------------------------------------------------------
4552 Check data waiting on file descriptors and terminate if so 4592 Check data waiting on file descriptors and terminate if so
4553 -------------------------------------------------------------------------- */ 4593 -------------------------------------------------------------------------- */
4554{ 4594{
4555 int result; 4595 int result;
4556 struct timespec select_timeout; 4596 int waiting = 1, nfds;
4557 /* NSTRACE (fd_handler); */ 4597 char c;
4558 4598
4559 if (select_nfds == 0) 4599 SELECT_TYPE readfds, writefds, *wfds;
4560 return; 4600 EMACS_TIME timeout, *tmo;
4561 4601
4562 memcpy (&t_readfds, &select_readfds, sizeof (fd_set)); 4602 /* NSTRACE (fd_handler); */
4563 4603
4564 select_timeout.tv_sec = select_timeout.tv_nsec = 0; 4604 for (;;)
4565 result = pselect (select_nfds, &t_readfds, NULL, NULL, &select_timeout, NULL);
4566 if (result)
4567 { 4605 {
4568 memcpy (&select_readfds, &t_readfds, sizeof (fd_set)); 4606 if (waiting)
4569 ns_send_appdefined (result); 4607 {
4608 SELECT_TYPE fds;
4609
4610 FD_SET (selfds[0], &fds);
4611 result = select (selfds[0]+1, &fds, NULL, NULL, NULL);
4612 if (result > 0)
4613 {
4614 read (selfds[0], &c, 1);
4615 if (c == 'g') waiting = 0;
4616 }
4617 }
4618 else
4619 {
4620 pthread_mutex_lock (&select_mutex);
4621 nfds = select_nfds;
4622
4623 if (select_valid & SELECT_HAVE_READ)
4624 readfds = select_readfds;
4625 else
4626 FD_ZERO (&readfds);
4627
4628 if (select_valid & SELECT_HAVE_WRITE)
4629 {
4630 writefds = select_writefds;
4631 wfds = &writefds;
4632 }
4633 else
4634 wfds = NULL;
4635 if (select_valid & SELECT_HAVE_TMO)
4636 {
4637 timeout = select_timeout;
4638 tmo = &timeout;
4639 }
4640 else
4641 tmo = NULL;
4642
4643 pthread_mutex_unlock (&select_mutex);
4644
4645 FD_SET (selfds[0], &readfds);
4646 if (selfds[0] >= nfds) nfds = selfds[0]+1;
4647
4648 result = pselect (nfds, &readfds, wfds, NULL, tmo, NULL);
4649
4650 if (result == 0)
4651 ns_send_appdefined (-2);
4652 else if (result > 0)
4653 {
4654 if (FD_ISSET (selfds[0], &readfds))
4655 {
4656 read (selfds[0], &c, 1);
4657 if (c == 's') waiting = 1;
4658 }
4659 else
4660 {
4661 pthread_mutex_lock (&select_mutex);
4662 if (select_valid & SELECT_HAVE_READ)
4663 select_readfds = readfds;
4664 if (select_valid & SELECT_HAVE_WRITE)
4665 select_writefds = writefds;
4666 if (select_valid & SELECT_HAVE_TMO)
4667 select_timeout = timeout;
4668 pthread_mutex_unlock (&select_mutex);
4669
4670 ns_send_appdefined (result);
4671 }
4672 }
4673 waiting = 1;
4674 }
4570 } 4675 }
4571} 4676}
4572 4677
@@ -6404,8 +6509,13 @@ not_in_argv (NSString *arg)
6404 XSETINT (emacs_event->x, loc * pixel_height); 6509 XSETINT (emacs_event->x, loc * pixel_height);
6405 XSETINT (emacs_event->y, pixel_height-20); 6510 XSETINT (emacs_event->y, pixel_height-20);
6406 6511
6407 n_emacs_events_pending++; 6512 if (q_event_ptr)
6408 kbd_buffer_store_event_hold (emacs_event, q_event_ptr); 6513 {
6514 n_emacs_events_pending++;
6515 kbd_buffer_store_event_hold (emacs_event, q_event_ptr);
6516 }
6517 else
6518 kbd_buffer_store_event (emacs_event);
6409 EVENT_INIT (*emacs_event); 6519 EVENT_INIT (*emacs_event);
6410 ns_send_appdefined (-1); 6520 ns_send_appdefined (-1);
6411} 6521}