diff options
| author | Alan Third | 2016-12-31 10:31:19 +0000 |
|---|---|---|
| committer | Alan Third | 2016-12-31 16:55:30 +0000 |
| commit | e0e5b0f4a4ce1d19ee0240c514dedd873d4165dc (patch) | |
| tree | 0d629fd5b378ae23237d69ca670e36b582491b3f /src | |
| parent | 4bbd5424a2290ab4bd88c0af602b7aa7d53a407e (diff) | |
| download | emacs-e0e5b0f4a4ce1d19ee0240c514dedd873d4165dc.tar.gz emacs-e0e5b0f4a4ce1d19ee0240c514dedd873d4165dc.zip | |
Rework NS event handling (bug#25265)
* src/nsterm.m (unwind_apploopnr): Remove.
(ns_read_socket): Remove references to apploopnr. Make processing the
NS event loop conditional on being in the main thread.
(ns_select): Remove references to apploopnr. Remove all fd_handler
related stuff. Check if there are events waiting on the NS event
queue rather than running the event loop. Remove unused variables and
code.
(fd_handler): Remove.
(ns_term_init): Remove creation of fd_handler thread.
(hold_event, EmacsApp:sendEvent, EmacsView:mouseMoved,
EmacsView:windowDidExpose): Remove send_appdefined.
(ns_send_appdefined): Always check the event queue for
applicationDefined events rather than relying on send_appdefined var.
* src/nsterm.h: Remove reference to fd_handler method.
Diffstat (limited to 'src')
| -rw-r--r-- | src/nsterm.h | 1 | ||||
| -rw-r--r-- | src/nsterm.m | 380 |
2 files changed, 68 insertions, 313 deletions
diff --git a/src/nsterm.h b/src/nsterm.h index 35c6e1a4cbc..dc222a75e74 100644 --- a/src/nsterm.h +++ b/src/nsterm.h | |||
| @@ -392,7 +392,6 @@ char const * nstrace_fullscreen_type_name (int); | |||
| 392 | - (void)sendEvent: (NSEvent *)theEvent; | 392 | - (void)sendEvent: (NSEvent *)theEvent; |
| 393 | - (void)showPreferencesWindow: (id)sender; | 393 | - (void)showPreferencesWindow: (id)sender; |
| 394 | - (BOOL) openFile: (NSString *)fileName; | 394 | - (BOOL) openFile: (NSString *)fileName; |
| 395 | - (void)fd_handler: (id)unused; | ||
| 396 | - (void)timeout_handler: (NSTimer *)timedEntry; | 395 | - (void)timeout_handler: (NSTimer *)timedEntry; |
| 397 | - (BOOL)fulfillService: (NSString *)name withArg: (NSString *)arg; | 396 | - (BOOL)fulfillService: (NSString *)name withArg: (NSString *)arg; |
| 398 | #ifdef NS_IMPL_GNUSTEP | 397 | #ifdef NS_IMPL_GNUSTEP |
diff --git a/src/nsterm.m b/src/nsterm.m index 7e6ec85abf1..98fd8ab8558 100644 --- a/src/nsterm.m +++ b/src/nsterm.m | |||
| @@ -279,18 +279,10 @@ static BOOL ns_menu_bar_is_hidden = NO; | |||
| 279 | /*static int debug_lock = 0; */ | 279 | /*static int debug_lock = 0; */ |
| 280 | 280 | ||
| 281 | /* event loop */ | 281 | /* event loop */ |
| 282 | static BOOL send_appdefined = YES; | ||
| 283 | #define NO_APPDEFINED_DATA (-8) | 282 | #define NO_APPDEFINED_DATA (-8) |
| 284 | static int last_appdefined_event_data = NO_APPDEFINED_DATA; | 283 | static int last_appdefined_event_data = NO_APPDEFINED_DATA; |
| 285 | static NSTimer *timed_entry = 0; | 284 | static NSTimer *timed_entry = 0; |
| 286 | static NSTimer *scroll_repeat_entry = nil; | 285 | static NSTimer *scroll_repeat_entry = nil; |
| 287 | static fd_set select_readfds, select_writefds; | ||
| 288 | enum { SELECT_HAVE_READ = 1, SELECT_HAVE_WRITE = 2, SELECT_HAVE_TMO = 4 }; | ||
| 289 | static int select_nfds = 0, select_valid = 0; | ||
| 290 | static struct timespec select_timeout = { 0, 0 }; | ||
| 291 | static int selfds[2] = { -1, -1 }; | ||
| 292 | static pthread_mutex_t select_mutex; | ||
| 293 | static int apploopnr = 0; | ||
| 294 | static NSAutoreleasePool *outerpool; | 286 | static NSAutoreleasePool *outerpool; |
| 295 | static struct input_event *emacs_event = NULL; | 287 | static struct input_event *emacs_event = NULL; |
| 296 | static struct input_event *q_event_ptr = NULL; | 288 | static struct input_event *q_event_ptr = NULL; |
| @@ -457,7 +449,6 @@ hold_event (struct input_event *event) | |||
| 457 | hold_event_q.q[hold_event_q.nr++] = *event; | 449 | hold_event_q.q[hold_event_q.nr++] = *event; |
| 458 | /* Make sure ns_read_socket is called, i.e. we have input. */ | 450 | /* Make sure ns_read_socket is called, i.e. we have input. */ |
| 459 | raise (SIGIO); | 451 | raise (SIGIO); |
| 460 | send_appdefined = YES; | ||
| 461 | } | 452 | } |
| 462 | 453 | ||
| 463 | static Lisp_Object | 454 | static Lisp_Object |
| @@ -3872,31 +3863,17 @@ ns_send_appdefined (int value) | |||
| 3872 | return; | 3863 | return; |
| 3873 | } | 3864 | } |
| 3874 | 3865 | ||
| 3875 | /* Only post this event if we haven't already posted one. This will end | 3866 | /* Only post this event if we haven't already posted one. This will |
| 3876 | the [NXApp run] main loop after having processed all events queued at | 3867 | end the [NXApp run] main loop after having processed all events |
| 3877 | this moment. */ | 3868 | queued at this moment. */ |
| 3878 | 3869 | NSEvent *appev = [NSApp nextEventMatchingMask:NSEventMaskApplicationDefined | |
| 3879 | #ifdef NS_IMPL_COCOA | 3870 | untilDate:[NSDate distantPast] |
| 3880 | if (! send_appdefined) | 3871 | inMode:NSDefaultRunLoopMode |
| 3881 | { | 3872 | dequeue:NO]; |
| 3882 | /* OS X 10.10.1 swallows the AppDefined event we are sending ourselves | 3873 | if (! appev) |
| 3883 | in certain situations (rapid incoming events). | ||
| 3884 | So check if we have one, if not add one. */ | ||
| 3885 | NSEvent *appev = [NSApp nextEventMatchingMask:NSEventMaskApplicationDefined | ||
| 3886 | untilDate:[NSDate distantPast] | ||
| 3887 | inMode:NSDefaultRunLoopMode | ||
| 3888 | dequeue:NO]; | ||
| 3889 | if (! appev) send_appdefined = YES; | ||
| 3890 | } | ||
| 3891 | #endif | ||
| 3892 | |||
| 3893 | if (send_appdefined) | ||
| 3894 | { | 3874 | { |
| 3895 | NSEvent *nxev; | 3875 | NSEvent *nxev; |
| 3896 | 3876 | ||
| 3897 | /* We only need one NX_APPDEFINED event to stop NXApp from running. */ | ||
| 3898 | send_appdefined = NO; | ||
| 3899 | |||
| 3900 | /* Don't need wakeup timer any more */ | 3877 | /* Don't need wakeup timer any more */ |
| 3901 | if (timed_entry) | 3878 | if (timed_entry) |
| 3902 | { | 3879 | { |
| @@ -4011,14 +3988,6 @@ ns_check_pending_open_menu () | |||
| 4011 | } | 3988 | } |
| 4012 | #endif /* NS_IMPL_COCOA */ | 3989 | #endif /* NS_IMPL_COCOA */ |
| 4013 | 3990 | ||
| 4014 | static void | ||
| 4015 | unwind_apploopnr (Lisp_Object not_used) | ||
| 4016 | { | ||
| 4017 | --apploopnr; | ||
| 4018 | n_emacs_events_pending = 0; | ||
| 4019 | ns_finish_events (); | ||
| 4020 | q_event_ptr = NULL; | ||
| 4021 | } | ||
| 4022 | 3991 | ||
| 4023 | static int | 3992 | static int |
| 4024 | ns_read_socket (struct terminal *terminal, struct input_event *hold_quit) | 3993 | ns_read_socket (struct terminal *terminal, struct input_event *hold_quit) |
| @@ -4029,13 +3998,10 @@ ns_read_socket (struct terminal *terminal, struct input_event *hold_quit) | |||
| 4029 | -------------------------------------------------------------------------- */ | 3998 | -------------------------------------------------------------------------- */ |
| 4030 | { | 3999 | { |
| 4031 | struct input_event ev; | 4000 | struct input_event ev; |
| 4032 | int nevents; | 4001 | int nevents = 0; |
| 4033 | 4002 | ||
| 4034 | NSTRACE_WHEN (NSTRACE_GROUP_EVENTS, "ns_read_socket"); | 4003 | NSTRACE_WHEN (NSTRACE_GROUP_EVENTS, "ns_read_socket"); |
| 4035 | 4004 | ||
| 4036 | if (apploopnr > 0) | ||
| 4037 | return -1; /* Already within event loop. */ | ||
| 4038 | |||
| 4039 | #ifdef HAVE_NATIVE_FS | 4005 | #ifdef HAVE_NATIVE_FS |
| 4040 | check_native_fs (); | 4006 | check_native_fs (); |
| 4041 | #endif | 4007 | #endif |
| @@ -4052,54 +4018,49 @@ ns_read_socket (struct terminal *terminal, struct input_event *hold_quit) | |||
| 4052 | return i; | 4018 | return i; |
| 4053 | } | 4019 | } |
| 4054 | 4020 | ||
| 4055 | block_input (); | 4021 | if ([NSThread isMainThread]) |
| 4056 | n_emacs_events_pending = 0; | ||
| 4057 | ns_init_events (&ev); | ||
| 4058 | q_event_ptr = hold_quit; | ||
| 4059 | |||
| 4060 | /* we manage autorelease pools by allocate/reallocate each time around | ||
| 4061 | the loop; strict nesting is occasionally violated but seems not to | ||
| 4062 | matter.. earlier methods using full nesting caused major memory leaks */ | ||
| 4063 | [outerpool release]; | ||
| 4064 | outerpool = [[NSAutoreleasePool alloc] init]; | ||
| 4065 | |||
| 4066 | /* If have pending open-file requests, attend to the next one of those. */ | ||
| 4067 | if (ns_pending_files && [ns_pending_files count] != 0 | ||
| 4068 | && [(EmacsApp *)NSApp openFile: [ns_pending_files objectAtIndex: 0]]) | ||
| 4069 | { | 4022 | { |
| 4070 | [ns_pending_files removeObjectAtIndex: 0]; | 4023 | block_input (); |
| 4071 | } | 4024 | n_emacs_events_pending = 0; |
| 4072 | /* Deal with pending service requests. */ | 4025 | ns_init_events (&ev); |
| 4073 | else if (ns_pending_service_names && [ns_pending_service_names count] != 0 | 4026 | q_event_ptr = hold_quit; |
| 4074 | && [(EmacsApp *) | 4027 | |
| 4075 | NSApp fulfillService: [ns_pending_service_names objectAtIndex: 0] | 4028 | /* we manage autorelease pools by allocate/reallocate each time around |
| 4076 | withArg: [ns_pending_service_args objectAtIndex: 0]]) | 4029 | the loop; strict nesting is occasionally violated but seems not to |
| 4077 | { | 4030 | matter.. earlier methods using full nesting caused major memory leaks */ |
| 4078 | [ns_pending_service_names removeObjectAtIndex: 0]; | 4031 | [outerpool release]; |
| 4079 | [ns_pending_service_args removeObjectAtIndex: 0]; | 4032 | outerpool = [[NSAutoreleasePool alloc] init]; |
| 4080 | } | 4033 | |
| 4081 | else | 4034 | /* If have pending open-file requests, attend to the next one of those. */ |
| 4082 | { | 4035 | if (ns_pending_files && [ns_pending_files count] != 0 |
| 4083 | ptrdiff_t specpdl_count = SPECPDL_INDEX (); | 4036 | && [(EmacsApp *)NSApp openFile: [ns_pending_files objectAtIndex: 0]]) |
| 4084 | /* Run and wait for events. We must always send one NX_APPDEFINED event | ||
| 4085 | to ourself, otherwise [NXApp run] will never exit. */ | ||
| 4086 | send_appdefined = YES; | ||
| 4087 | ns_send_appdefined (-1); | ||
| 4088 | |||
| 4089 | if (++apploopnr != 1) | ||
| 4090 | { | 4037 | { |
| 4091 | emacs_abort (); | 4038 | [ns_pending_files removeObjectAtIndex: 0]; |
| 4092 | } | 4039 | } |
| 4093 | record_unwind_protect (unwind_apploopnr, Qt); | 4040 | /* Deal with pending service requests. */ |
| 4094 | [NSApp run]; | 4041 | else if (ns_pending_service_names && [ns_pending_service_names count] != 0 |
| 4095 | unbind_to (specpdl_count, Qnil); /* calls unwind_apploopnr */ | 4042 | && [(EmacsApp *) |
| 4096 | } | 4043 | NSApp fulfillService: [ns_pending_service_names objectAtIndex: 0] |
| 4044 | withArg: [ns_pending_service_args objectAtIndex: 0]]) | ||
| 4045 | { | ||
| 4046 | [ns_pending_service_names removeObjectAtIndex: 0]; | ||
| 4047 | [ns_pending_service_args removeObjectAtIndex: 0]; | ||
| 4048 | } | ||
| 4049 | else | ||
| 4050 | { | ||
| 4051 | /* Run and wait for events. We must always send one NX_APPDEFINED event | ||
| 4052 | to ourself, otherwise [NXApp run] will never exit. */ | ||
| 4053 | ns_send_appdefined (-1); | ||
| 4097 | 4054 | ||
| 4098 | nevents = n_emacs_events_pending; | 4055 | [NSApp run]; |
| 4099 | n_emacs_events_pending = 0; | 4056 | } |
| 4100 | ns_finish_events (); | 4057 | |
| 4101 | q_event_ptr = NULL; | 4058 | nevents = n_emacs_events_pending; |
| 4102 | unblock_input (); | 4059 | n_emacs_events_pending = 0; |
| 4060 | ns_finish_events (); | ||
| 4061 | q_event_ptr = NULL; | ||
| 4062 | unblock_input (); | ||
| 4063 | } | ||
| 4103 | 4064 | ||
| 4104 | return nevents; | 4065 | return nevents; |
| 4105 | } | 4066 | } |
| @@ -4114,15 +4075,11 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds, | |||
| 4114 | -------------------------------------------------------------------------- */ | 4075 | -------------------------------------------------------------------------- */ |
| 4115 | { | 4076 | { |
| 4116 | int result; | 4077 | int result; |
| 4117 | int t, k, nr = 0; | 4078 | NSDate *timeout_date = nil; |
| 4118 | struct input_event event; | 4079 | NSEvent *ns_event; |
| 4119 | char c; | ||
| 4120 | 4080 | ||
| 4121 | NSTRACE_WHEN (NSTRACE_GROUP_EVENTS, "ns_select"); | 4081 | NSTRACE_WHEN (NSTRACE_GROUP_EVENTS, "ns_select"); |
| 4122 | 4082 | ||
| 4123 | if (apploopnr > 0) | ||
| 4124 | return -1; /* Already within event loop. */ | ||
| 4125 | |||
| 4126 | #ifdef HAVE_NATIVE_FS | 4083 | #ifdef HAVE_NATIVE_FS |
| 4127 | check_native_fs (); | 4084 | check_native_fs (); |
| 4128 | #endif | 4085 | #endif |
| @@ -4135,121 +4092,34 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds, | |||
| 4135 | return -1; | 4092 | return -1; |
| 4136 | } | 4093 | } |
| 4137 | 4094 | ||
| 4138 | for (k = 0; k < nfds+1; k++) | ||
| 4139 | { | ||
| 4140 | if (readfds && FD_ISSET(k, readfds)) ++nr; | ||
| 4141 | if (writefds && FD_ISSET(k, writefds)) ++nr; | ||
| 4142 | } | ||
| 4143 | |||
| 4144 | if (NSApp == nil | 4095 | if (NSApp == nil |
| 4096 | || ![NSThread isMainThread] | ||
| 4145 | || (timeout && timeout->tv_sec == 0 && timeout->tv_nsec == 0)) | 4097 | || (timeout && timeout->tv_sec == 0 && timeout->tv_nsec == 0)) |
| 4146 | return pselect (nfds, readfds, writefds, exceptfds, timeout, sigmask); | 4098 | return pselect(nfds, readfds, writefds, |
| 4099 | exceptfds, timeout, sigmask); | ||
| 4100 | |||
| 4101 | result = pselect(nfds, readfds, writefds, exceptfds, | ||
| 4102 | &(struct timespec){.tv_sec = 0, .tv_nsec = 100}, | ||
| 4103 | sigmask); | ||
| 4147 | 4104 | ||
| 4148 | [outerpool release]; | 4105 | [outerpool release]; |
| 4149 | outerpool = [[NSAutoreleasePool alloc] init]; | 4106 | outerpool = [[NSAutoreleasePool alloc] init]; |
| 4150 | 4107 | ||
| 4151 | 4108 | if (timeout) | |
| 4152 | send_appdefined = YES; | ||
| 4153 | if (nr > 0) | ||
| 4154 | { | ||
| 4155 | pthread_mutex_lock (&select_mutex); | ||
| 4156 | select_nfds = nfds; | ||
| 4157 | select_valid = 0; | ||
| 4158 | if (readfds) | ||
| 4159 | { | ||
| 4160 | select_readfds = *readfds; | ||
| 4161 | select_valid += SELECT_HAVE_READ; | ||
| 4162 | } | ||
| 4163 | if (writefds) | ||
| 4164 | { | ||
| 4165 | select_writefds = *writefds; | ||
| 4166 | select_valid += SELECT_HAVE_WRITE; | ||
| 4167 | } | ||
| 4168 | |||
| 4169 | if (timeout) | ||
| 4170 | { | ||
| 4171 | select_timeout = *timeout; | ||
| 4172 | select_valid += SELECT_HAVE_TMO; | ||
| 4173 | } | ||
| 4174 | |||
| 4175 | pthread_mutex_unlock (&select_mutex); | ||
| 4176 | |||
| 4177 | /* Inform fd_handler that select should be called */ | ||
| 4178 | c = 'g'; | ||
| 4179 | emacs_write_sig (selfds[1], &c, 1); | ||
| 4180 | } | ||
| 4181 | else if (nr == 0 && timeout) | ||
| 4182 | { | 4109 | { |
| 4183 | /* No file descriptor, just a timeout, no need to wake fd_handler */ | ||
| 4184 | double time = timespectod (*timeout); | 4110 | double time = timespectod (*timeout); |
| 4185 | timed_entry = [[NSTimer scheduledTimerWithTimeInterval: time | 4111 | timeout_date = [NSDate dateWithTimeIntervalSinceNow:time]; |
| 4186 | target: NSApp | ||
| 4187 | selector: | ||
| 4188 | @selector (timeout_handler:) | ||
| 4189 | userInfo: 0 | ||
| 4190 | repeats: NO] | ||
| 4191 | retain]; | ||
| 4192 | } | ||
| 4193 | else /* No timeout and no file descriptors, can this happen? */ | ||
| 4194 | { | ||
| 4195 | /* Send appdefined so we exit from the loop */ | ||
| 4196 | ns_send_appdefined (-1); | ||
| 4197 | } | ||
| 4198 | |||
| 4199 | block_input (); | ||
| 4200 | ns_init_events (&event); | ||
| 4201 | if (++apploopnr != 1) | ||
| 4202 | { | ||
| 4203 | emacs_abort (); | ||
| 4204 | } | ||
| 4205 | |||
| 4206 | { | ||
| 4207 | ptrdiff_t specpdl_count = SPECPDL_INDEX (); | ||
| 4208 | record_unwind_protect (unwind_apploopnr, Qt); | ||
| 4209 | [NSApp run]; | ||
| 4210 | unbind_to (specpdl_count, Qnil); /* calls unwind_apploopnr */ | ||
| 4211 | } | ||
| 4212 | |||
| 4213 | ns_finish_events (); | ||
| 4214 | if (nr > 0 && readfds) | ||
| 4215 | { | ||
| 4216 | c = 's'; | ||
| 4217 | emacs_write_sig (selfds[1], &c, 1); | ||
| 4218 | } | 4112 | } |
| 4219 | unblock_input (); | ||
| 4220 | 4113 | ||
| 4221 | t = last_appdefined_event_data; | 4114 | /* Listen for a new NSEvent. */ |
| 4115 | ns_event = [NSApp nextEventMatchingMask:NSEventMaskAny | ||
| 4116 | untilDate:timeout_date | ||
| 4117 | inMode:NSDefaultRunLoopMode | ||
| 4118 | dequeue:NO]; | ||
| 4222 | 4119 | ||
| 4223 | if (t != NO_APPDEFINED_DATA) | 4120 | if (ns_event != nil) |
| 4224 | { | 4121 | { |
| 4225 | last_appdefined_event_data = NO_APPDEFINED_DATA; | 4122 | raise (SIGIO); |
| 4226 | |||
| 4227 | if (t == -2) | ||
| 4228 | { | ||
| 4229 | /* The NX_APPDEFINED event we received was a timeout. */ | ||
| 4230 | result = 0; | ||
| 4231 | } | ||
| 4232 | else if (t == -1) | ||
| 4233 | { | ||
| 4234 | /* The NX_APPDEFINED event we received was the result of | ||
| 4235 | at least one real input event arriving. */ | ||
| 4236 | errno = EINTR; | ||
| 4237 | result = -1; | ||
| 4238 | } | ||
| 4239 | else | ||
| 4240 | { | ||
| 4241 | /* Received back from select () in fd_handler; copy the results */ | ||
| 4242 | pthread_mutex_lock (&select_mutex); | ||
| 4243 | if (readfds) *readfds = select_readfds; | ||
| 4244 | if (writefds) *writefds = select_writefds; | ||
| 4245 | pthread_mutex_unlock (&select_mutex); | ||
| 4246 | result = t; | ||
| 4247 | } | ||
| 4248 | } | ||
| 4249 | else | ||
| 4250 | { | ||
| 4251 | errno = EINTR; | ||
| 4252 | result = -1; | ||
| 4253 | } | 4123 | } |
| 4254 | 4124 | ||
| 4255 | return result; | 4125 | return result; |
| @@ -4765,21 +4635,6 @@ ns_term_init (Lisp_Object display_name) | |||
| 4765 | baud_rate = 38400; | 4635 | baud_rate = 38400; |
| 4766 | Fset_input_interrupt_mode (Qnil); | 4636 | Fset_input_interrupt_mode (Qnil); |
| 4767 | 4637 | ||
| 4768 | if (selfds[0] == -1) | ||
| 4769 | { | ||
| 4770 | if (emacs_pipe (selfds) != 0) | ||
| 4771 | { | ||
| 4772 | fprintf (stderr, "Failed to create pipe: %s\n", | ||
| 4773 | emacs_strerror (errno)); | ||
| 4774 | emacs_abort (); | ||
| 4775 | } | ||
| 4776 | |||
| 4777 | fcntl (selfds[0], F_SETFL, O_NONBLOCK|fcntl (selfds[0], F_GETFL)); | ||
| 4778 | FD_ZERO (&select_readfds); | ||
| 4779 | FD_ZERO (&select_writefds); | ||
| 4780 | pthread_mutex_init (&select_mutex, NULL); | ||
| 4781 | } | ||
| 4782 | |||
| 4783 | ns_pending_files = [[NSMutableArray alloc] init]; | 4638 | ns_pending_files = [[NSMutableArray alloc] init]; |
| 4784 | ns_pending_service_names = [[NSMutableArray alloc] init]; | 4639 | ns_pending_service_names = [[NSMutableArray alloc] init]; |
| 4785 | ns_pending_service_args = [[NSMutableArray alloc] init]; | 4640 | ns_pending_service_args = [[NSMutableArray alloc] init]; |
| @@ -4792,11 +4647,6 @@ ns_term_init (Lisp_Object display_name) | |||
| 4792 | return NULL; | 4647 | return NULL; |
| 4793 | [NSApp setDelegate: NSApp]; | 4648 | [NSApp setDelegate: NSApp]; |
| 4794 | 4649 | ||
| 4795 | /* Start the select thread. */ | ||
| 4796 | [NSThread detachNewThreadSelector:@selector (fd_handler:) | ||
| 4797 | toTarget:NSApp | ||
| 4798 | withObject:nil]; | ||
| 4799 | |||
| 4800 | /* debugging: log all notifications */ | 4650 | /* debugging: log all notifications */ |
| 4801 | /* [[NSNotificationCenter defaultCenter] addObserver: NSApp | 4651 | /* [[NSNotificationCenter defaultCenter] addObserver: NSApp |
| 4802 | selector: @selector (logNotification:) | 4652 | selector: @selector (logNotification:) |
| @@ -5178,10 +5028,6 @@ ns_term_shutdown (int sig) | |||
| 5178 | last_appdefined_event_data = [theEvent data1]; | 5028 | last_appdefined_event_data = [theEvent data1]; |
| 5179 | [self stop: self]; | 5029 | [self stop: self]; |
| 5180 | } | 5030 | } |
| 5181 | else | ||
| 5182 | { | ||
| 5183 | send_appdefined = YES; | ||
| 5184 | } | ||
| 5185 | } | 5031 | } |
| 5186 | 5032 | ||
| 5187 | 5033 | ||
| @@ -5484,95 +5330,6 @@ not_in_argv (NSString *arg) | |||
| 5484 | ns_send_appdefined (nextappdefined); | 5330 | ns_send_appdefined (nextappdefined); |
| 5485 | } | 5331 | } |
| 5486 | 5332 | ||
| 5487 | - (void)fd_handler:(id)unused | ||
| 5488 | /* -------------------------------------------------------------------------- | ||
| 5489 | Check data waiting on file descriptors and terminate if so | ||
| 5490 | -------------------------------------------------------------------------- */ | ||
| 5491 | { | ||
| 5492 | int result; | ||
| 5493 | int waiting = 1, nfds; | ||
| 5494 | char c; | ||
| 5495 | |||
| 5496 | fd_set readfds, writefds, *wfds; | ||
| 5497 | struct timespec timeout, *tmo; | ||
| 5498 | NSAutoreleasePool *pool = nil; | ||
| 5499 | |||
| 5500 | /* NSTRACE ("fd_handler"); */ | ||
| 5501 | |||
| 5502 | for (;;) | ||
| 5503 | { | ||
| 5504 | [pool release]; | ||
| 5505 | pool = [[NSAutoreleasePool alloc] init]; | ||
| 5506 | |||
| 5507 | if (waiting) | ||
| 5508 | { | ||
| 5509 | fd_set fds; | ||
| 5510 | FD_ZERO (&fds); | ||
| 5511 | FD_SET (selfds[0], &fds); | ||
| 5512 | result = select (selfds[0]+1, &fds, NULL, NULL, NULL); | ||
| 5513 | if (result > 0 && read (selfds[0], &c, 1) == 1 && c == 'g') | ||
| 5514 | waiting = 0; | ||
| 5515 | } | ||
| 5516 | else | ||
| 5517 | { | ||
| 5518 | pthread_mutex_lock (&select_mutex); | ||
| 5519 | nfds = select_nfds; | ||
| 5520 | |||
| 5521 | if (select_valid & SELECT_HAVE_READ) | ||
| 5522 | readfds = select_readfds; | ||
| 5523 | else | ||
| 5524 | FD_ZERO (&readfds); | ||
| 5525 | |||
| 5526 | if (select_valid & SELECT_HAVE_WRITE) | ||
| 5527 | { | ||
| 5528 | writefds = select_writefds; | ||
| 5529 | wfds = &writefds; | ||
| 5530 | } | ||
| 5531 | else | ||
| 5532 | wfds = NULL; | ||
| 5533 | if (select_valid & SELECT_HAVE_TMO) | ||
| 5534 | { | ||
| 5535 | timeout = select_timeout; | ||
| 5536 | tmo = &timeout; | ||
| 5537 | } | ||
| 5538 | else | ||
| 5539 | tmo = NULL; | ||
| 5540 | |||
| 5541 | pthread_mutex_unlock (&select_mutex); | ||
| 5542 | |||
| 5543 | FD_SET (selfds[0], &readfds); | ||
| 5544 | if (selfds[0] >= nfds) nfds = selfds[0]+1; | ||
| 5545 | |||
| 5546 | result = pselect (nfds, &readfds, wfds, NULL, tmo, NULL); | ||
| 5547 | |||
| 5548 | if (result == 0) | ||
| 5549 | ns_send_appdefined (-2); | ||
| 5550 | else if (result > 0) | ||
| 5551 | { | ||
| 5552 | if (FD_ISSET (selfds[0], &readfds)) | ||
| 5553 | { | ||
| 5554 | if (read (selfds[0], &c, 1) == 1 && c == 's') | ||
| 5555 | waiting = 1; | ||
| 5556 | } | ||
| 5557 | else | ||
| 5558 | { | ||
| 5559 | pthread_mutex_lock (&select_mutex); | ||
| 5560 | if (select_valid & SELECT_HAVE_READ) | ||
| 5561 | select_readfds = readfds; | ||
| 5562 | if (select_valid & SELECT_HAVE_WRITE) | ||
| 5563 | select_writefds = writefds; | ||
| 5564 | if (select_valid & SELECT_HAVE_TMO) | ||
| 5565 | select_timeout = timeout; | ||
| 5566 | pthread_mutex_unlock (&select_mutex); | ||
| 5567 | |||
| 5568 | ns_send_appdefined (result); | ||
| 5569 | } | ||
| 5570 | } | ||
| 5571 | waiting = 1; | ||
| 5572 | } | ||
| 5573 | } | ||
| 5574 | } | ||
| 5575 | |||
| 5576 | 5333 | ||
| 5577 | 5334 | ||
| 5578 | /* ========================================================================== | 5335 | /* ========================================================================== |
| @@ -6361,7 +6118,7 @@ not_in_argv (NSString *arg) | |||
| 6361 | help_echo_object, help_echo_pos); | 6118 | help_echo_object, help_echo_pos); |
| 6362 | } | 6119 | } |
| 6363 | 6120 | ||
| 6364 | if (emacsframe->mouse_moved && send_appdefined) | 6121 | if (emacsframe->mouse_moved) |
| 6365 | ns_send_appdefined (-1); | 6122 | ns_send_appdefined (-1); |
| 6366 | } | 6123 | } |
| 6367 | 6124 | ||
| @@ -7058,8 +6815,7 @@ not_in_argv (NSString *arg) | |||
| 7058 | SET_FRAME_VISIBLE (emacsframe, 1); | 6815 | SET_FRAME_VISIBLE (emacsframe, 1); |
| 7059 | SET_FRAME_GARBAGED (emacsframe); | 6816 | SET_FRAME_GARBAGED (emacsframe); |
| 7060 | 6817 | ||
| 7061 | if (send_appdefined) | 6818 | ns_send_appdefined (-1); |
| 7062 | ns_send_appdefined (-1); | ||
| 7063 | } | 6819 | } |
| 7064 | 6820 | ||
| 7065 | 6821 | ||