diff options
| -rw-r--r-- | src/emacs.c | 4 | ||||
| -rw-r--r-- | src/lisp.h | 4 | ||||
| -rw-r--r-- | src/nsfns.m | 13 | ||||
| -rw-r--r-- | src/nsterm.h | 14 | ||||
| -rw-r--r-- | src/nsterm.m | 909 | ||||
| -rw-r--r-- | src/systhread.c | 7 |
6 files changed, 308 insertions, 643 deletions
diff --git a/src/emacs.c b/src/emacs.c index ea9c4cd79dc..ad64ffa08f2 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -924,7 +924,11 @@ load_pdump (int argc, char **argv) | |||
| 924 | #endif /* HAVE_PDUMPER */ | 924 | #endif /* HAVE_PDUMPER */ |
| 925 | 925 | ||
| 926 | int | 926 | int |
| 927 | #ifdef HAVE_NS | ||
| 928 | emacs_main (int argc, char **argv) | ||
| 929 | #else | ||
| 927 | main (int argc, char **argv) | 930 | main (int argc, char **argv) |
| 931 | #endif | ||
| 928 | { | 932 | { |
| 929 | /* Variable near the bottom of the stack, and aligned appropriately | 933 | /* Variable near the bottom of the stack, and aligned appropriately |
| 930 | for pointers. */ | 934 | for pointers. */ |
diff --git a/src/lisp.h b/src/lisp.h index a379977d353..34d97a8efc9 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -4717,6 +4717,10 @@ extern void syms_of_xterm (void); | |||
| 4717 | extern char *get_keysym_name (int); | 4717 | extern char *get_keysym_name (int); |
| 4718 | #endif /* HAVE_WINDOW_SYSTEM */ | 4718 | #endif /* HAVE_WINDOW_SYSTEM */ |
| 4719 | 4719 | ||
| 4720 | #ifdef HAVE_NS | ||
| 4721 | extern int emacs_main (int, char **); | ||
| 4722 | #endif | ||
| 4723 | |||
| 4720 | /* Defined in xml.c. */ | 4724 | /* Defined in xml.c. */ |
| 4721 | extern void syms_of_xml (void); | 4725 | extern void syms_of_xml (void); |
| 4722 | #ifdef HAVE_LIBXML2 | 4726 | #ifdef HAVE_LIBXML2 |
diff --git a/src/nsfns.m b/src/nsfns.m index dea51bdba00..d693873d422 100644 --- a/src/nsfns.m +++ b/src/nsfns.m | |||
| @@ -1310,7 +1310,10 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, | |||
| 1310 | 1310 | ||
| 1311 | f->output_data.ns->in_animation = NO; | 1311 | f->output_data.ns->in_animation = NO; |
| 1312 | 1312 | ||
| 1313 | f->output_data.ns->frame = [[EmacsFrame alloc] initWithEmacsframe:f]; | 1313 | f->output_data.ns->frame = |
| 1314 | [(EmacsFrame *)[[[MainThreadProxy alloc] initWithObject:[EmacsFrame alloc] | ||
| 1315 | waitUntilDone:YES] autorelease] | ||
| 1316 | initWithEmacsframe:f]; | ||
| 1314 | 1317 | ||
| 1315 | ns_icon (f, parms); | 1318 | ns_icon (f, parms); |
| 1316 | 1319 | ||
| @@ -2141,7 +2144,6 @@ In case the execution fails, an error is signaled. */) | |||
| 2141 | Lisp_Object result; | 2144 | Lisp_Object result; |
| 2142 | int status; | 2145 | int status; |
| 2143 | NSEvent *nxev; | 2146 | NSEvent *nxev; |
| 2144 | struct input_event ev; | ||
| 2145 | 2147 | ||
| 2146 | CHECK_STRING (script); | 2148 | CHECK_STRING (script); |
| 2147 | check_window_system (NULL); | 2149 | check_window_system (NULL); |
| @@ -2167,13 +2169,6 @@ In case the execution fails, an error is signaled. */) | |||
| 2167 | 2169 | ||
| 2168 | [NSApp postEvent: nxev atStart: NO]; | 2170 | [NSApp postEvent: nxev atStart: NO]; |
| 2169 | 2171 | ||
| 2170 | /* If there are other events, the event loop may exit. Keep running | ||
| 2171 | until the script has been handled. */ | ||
| 2172 | ns_init_events (&ev); | ||
| 2173 | while (! NILP (as_script)) | ||
| 2174 | [NSApp run]; | ||
| 2175 | ns_finish_events (); | ||
| 2176 | |||
| 2177 | status = as_status; | 2172 | status = as_status; |
| 2178 | as_status = 0; | 2173 | as_status = 0; |
| 2179 | as_result = 0; | 2174 | as_result = 0; |
diff --git a/src/nsterm.h b/src/nsterm.h index 1aff5ad1c96..1eb5ac92a70 100644 --- a/src/nsterm.h +++ b/src/nsterm.h | |||
| @@ -391,12 +391,8 @@ typedef id instancetype; | |||
| 391 | - (void)sendEvent: (NSEvent *)theEvent; | 391 | - (void)sendEvent: (NSEvent *)theEvent; |
| 392 | - (void)showPreferencesWindow: (id)sender; | 392 | - (void)showPreferencesWindow: (id)sender; |
| 393 | - (BOOL) openFile: (NSString *)fileName; | 393 | - (BOOL) openFile: (NSString *)fileName; |
| 394 | - (void)fd_handler: (id)unused; | ||
| 395 | - (void)timeout_handler: (NSTimer *)timedEntry; | ||
| 396 | - (BOOL)fulfillService: (NSString *)name withArg: (NSString *)arg; | 394 | - (BOOL)fulfillService: (NSString *)name withArg: (NSString *)arg; |
| 397 | #ifdef NS_IMPL_GNUSTEP | 395 | - (void)initLispThread: (int)argc withArgv: (char **)argv; |
| 398 | - (void)sendFromMainThread:(id)unused; | ||
| 399 | #endif | ||
| 400 | @end | 396 | @end |
| 401 | 397 | ||
| 402 | #ifdef NS_IMPL_GNUSTEP | 398 | #ifdef NS_IMPL_GNUSTEP |
| @@ -758,6 +754,14 @@ typedef id instancetype; | |||
| 758 | + (CGFloat)scrollerWidth; | 754 | + (CGFloat)scrollerWidth; |
| 759 | @end | 755 | @end |
| 760 | 756 | ||
| 757 | @interface EmacsThread: NSThread | ||
| 758 | { | ||
| 759 | } | ||
| 760 | - (instancetype) initWithArgc: (int)argc Argv: (char **)argv; | ||
| 761 | - (void) sendEmacsEvent: (struct input_event *)emacs_event | ||
| 762 | NSEvent: (NSEvent *)e | ||
| 763 | frameOrWindow: (void *)frame_or_window; | ||
| 764 | @end | ||
| 761 | 765 | ||
| 762 | /* ========================================================================== | 766 | /* ========================================================================== |
| 763 | 767 | ||
diff --git a/src/nsterm.m b/src/nsterm.m index 37163cef1e4..f1ec60fbc15 100644 --- a/src/nsterm.m +++ b/src/nsterm.m | |||
| @@ -192,6 +192,8 @@ char const * nstrace_fullscreen_type_name (int fs_type) | |||
| 192 | 192 | ||
| 193 | ========================================================================== */ | 193 | ========================================================================== */ |
| 194 | 194 | ||
| 195 | EmacsThread *emacsMainThread; | ||
| 196 | |||
| 195 | /* Convert a symbol indexed with an NSxxx value to a value as defined | 197 | /* Convert a symbol indexed with an NSxxx value to a value as defined |
| 196 | in keyboard.c (lispy_function_key). I hope this is a correct way | 198 | in keyboard.c (lispy_function_key). I hope this is a correct way |
| 197 | of doing things... */ | 199 | of doing things... */ |
| @@ -298,19 +300,8 @@ static BOOL ns_menu_bar_is_hidden = NO; | |||
| 298 | /* static int debug_lock = 0; */ | 300 | /* static int debug_lock = 0; */ |
| 299 | 301 | ||
| 300 | /* event loop */ | 302 | /* event loop */ |
| 301 | static BOOL send_appdefined = YES; | ||
| 302 | #define NO_APPDEFINED_DATA (-8) | ||
| 303 | static int last_appdefined_event_data = NO_APPDEFINED_DATA; | ||
| 304 | static NSTimer *timed_entry = 0; | ||
| 305 | static NSTimer *scroll_repeat_entry = nil; | 303 | static NSTimer *scroll_repeat_entry = nil; |
| 306 | static fd_set select_readfds, select_writefds; | ||
| 307 | enum { SELECT_HAVE_READ = 1, SELECT_HAVE_WRITE = 2, SELECT_HAVE_TMO = 4 }; | ||
| 308 | static int select_nfds = 0, select_valid = 0; | ||
| 309 | static struct timespec select_timeout = { 0, 0 }; | ||
| 310 | static int selfds[2] = { -1, -1 }; | ||
| 311 | static pthread_mutex_t select_mutex; | ||
| 312 | static NSAutoreleasePool *outerpool; | 304 | static NSAutoreleasePool *outerpool; |
| 313 | static struct input_event *emacs_event = NULL; | ||
| 314 | static struct input_event *q_event_ptr = NULL; | 305 | static struct input_event *q_event_ptr = NULL; |
| 315 | static int n_emacs_events_pending = 0; | 306 | static int n_emacs_events_pending = 0; |
| 316 | static NSMutableArray *ns_pending_files, *ns_pending_service_names, | 307 | static NSMutableArray *ns_pending_files, *ns_pending_service_names, |
| @@ -323,13 +314,6 @@ static BOOL ns_last_use_native_fullscreen; | |||
| 323 | 314 | ||
| 324 | static BOOL any_help_event_p = NO; | 315 | static BOOL any_help_event_p = NO; |
| 325 | 316 | ||
| 326 | static struct { | ||
| 327 | struct input_event *q; | ||
| 328 | int nr, cap; | ||
| 329 | } hold_event_q = { | ||
| 330 | NULL, 0, 0 | ||
| 331 | }; | ||
| 332 | |||
| 333 | #ifdef NS_IMPL_COCOA | 317 | #ifdef NS_IMPL_COCOA |
| 334 | /* | 318 | /* |
| 335 | * State for pending menu activation: | 319 | * State for pending menu activation: |
| @@ -448,28 +432,9 @@ ev_modifiers_helper (unsigned int flags, unsigned int left_mask, | |||
| 448 | /* This is a piece of code which is common to all the event handling | 432 | /* This is a piece of code which is common to all the event handling |
| 449 | methods. Maybe it should even be a function. */ | 433 | methods. Maybe it should even be a function. */ |
| 450 | #define EV_TRAILER(e) \ | 434 | #define EV_TRAILER(e) \ |
| 451 | { \ | 435 | [emacsMainThread sendEmacsEvent:&emacs_event \ |
| 452 | XSETFRAME (emacs_event->frame_or_window, emacsframe); \ | 436 | NSEvent:e \ |
| 453 | EV_TRAILER2 (e); \ | 437 | frameOrWindow:emacsframe]; |
| 454 | } | ||
| 455 | |||
| 456 | #define EV_TRAILER2(e) \ | ||
| 457 | { \ | ||
| 458 | if (e) emacs_event->timestamp = EV_TIMESTAMP (e); \ | ||
| 459 | if (q_event_ptr) \ | ||
| 460 | { \ | ||
| 461 | Lisp_Object tem = Vinhibit_quit; \ | ||
| 462 | Vinhibit_quit = Qt; \ | ||
| 463 | n_emacs_events_pending++; \ | ||
| 464 | kbd_buffer_store_event_hold (emacs_event, q_event_ptr); \ | ||
| 465 | Vinhibit_quit = tem; \ | ||
| 466 | } \ | ||
| 467 | else \ | ||
| 468 | hold_event (emacs_event); \ | ||
| 469 | EVENT_INIT (*emacs_event); \ | ||
| 470 | ns_send_appdefined (-1); \ | ||
| 471 | } | ||
| 472 | |||
| 473 | 438 | ||
| 474 | /* These flags will be OR'd or XOR'd with the NSWindow's styleMask | 439 | /* These flags will be OR'd or XOR'd with the NSWindow's styleMask |
| 475 | property depending on what we're doing. */ | 440 | property depending on what we're doing. */ |
| @@ -490,36 +455,6 @@ static void ns_judge_scroll_bars (struct frame *f); | |||
| 490 | 455 | ||
| 491 | ========================================================================== */ | 456 | ========================================================================== */ |
| 492 | 457 | ||
| 493 | void | ||
| 494 | ns_init_events (struct input_event *ev) | ||
| 495 | { | ||
| 496 | EVENT_INIT (*ev); | ||
| 497 | emacs_event = ev; | ||
| 498 | } | ||
| 499 | |||
| 500 | void | ||
| 501 | ns_finish_events (void) | ||
| 502 | { | ||
| 503 | emacs_event = NULL; | ||
| 504 | } | ||
| 505 | |||
| 506 | static void | ||
| 507 | hold_event (struct input_event *event) | ||
| 508 | { | ||
| 509 | if (hold_event_q.nr == hold_event_q.cap) | ||
| 510 | { | ||
| 511 | if (hold_event_q.cap == 0) hold_event_q.cap = 10; | ||
| 512 | else hold_event_q.cap *= 2; | ||
| 513 | hold_event_q.q = | ||
| 514 | xrealloc (hold_event_q.q, hold_event_q.cap * sizeof *hold_event_q.q); | ||
| 515 | } | ||
| 516 | |||
| 517 | hold_event_q.q[hold_event_q.nr++] = *event; | ||
| 518 | /* Make sure ns_read_socket is called, i.e. we have input. */ | ||
| 519 | raise (SIGIO); | ||
| 520 | send_appdefined = YES; | ||
| 521 | } | ||
| 522 | |||
| 523 | static Lisp_Object | 458 | static Lisp_Object |
| 524 | append2 (Lisp_Object list, Lisp_Object item) | 459 | append2 (Lisp_Object list, Lisp_Object item) |
| 525 | /* -------------------------------------------------------------------------- | 460 | /* -------------------------------------------------------------------------- |
| @@ -4181,78 +4116,6 @@ ns_draw_glyph_string (struct glyph_string *s) | |||
| 4181 | 4116 | ||
| 4182 | ========================================================================== */ | 4117 | ========================================================================== */ |
| 4183 | 4118 | ||
| 4184 | |||
| 4185 | static void | ||
| 4186 | ns_send_appdefined (int value) | ||
| 4187 | /* -------------------------------------------------------------------------- | ||
| 4188 | Internal: post an appdefined event which EmacsApp-sendEvent will | ||
| 4189 | recognize and take as a command to halt the event loop. | ||
| 4190 | -------------------------------------------------------------------------- */ | ||
| 4191 | { | ||
| 4192 | NSTRACE_WHEN (NSTRACE_GROUP_EVENTS, "ns_send_appdefined(%d)", value); | ||
| 4193 | |||
| 4194 | // GNUstep needs postEvent to happen on the main thread. | ||
| 4195 | // Cocoa needs nextEventMatchingMask to happen on the main thread too. | ||
| 4196 | if (! [[NSThread currentThread] isMainThread]) | ||
| 4197 | { | ||
| 4198 | EmacsApp *app = (EmacsApp *)NSApp; | ||
| 4199 | app->nextappdefined = value; | ||
| 4200 | [app performSelectorOnMainThread:@selector (sendFromMainThread:) | ||
| 4201 | withObject:nil | ||
| 4202 | waitUntilDone:NO]; | ||
| 4203 | return; | ||
| 4204 | } | ||
| 4205 | |||
| 4206 | /* Only post this event if we haven't already posted one. This will end | ||
| 4207 | the [NXApp run] main loop after having processed all events queued at | ||
| 4208 | this moment. */ | ||
| 4209 | |||
| 4210 | #ifdef NS_IMPL_COCOA | ||
| 4211 | if (! send_appdefined) | ||
| 4212 | { | ||
| 4213 | /* OS X 10.10.1 swallows the AppDefined event we are sending ourselves | ||
| 4214 | in certain situations (rapid incoming events). | ||
| 4215 | So check if we have one, if not add one. */ | ||
| 4216 | NSEvent *appev = [NSApp nextEventMatchingMask:NSEventMaskApplicationDefined | ||
| 4217 | untilDate:[NSDate distantPast] | ||
| 4218 | inMode:NSDefaultRunLoopMode | ||
| 4219 | dequeue:NO]; | ||
| 4220 | if (! appev) send_appdefined = YES; | ||
| 4221 | } | ||
| 4222 | #endif | ||
| 4223 | |||
| 4224 | if (send_appdefined) | ||
| 4225 | { | ||
| 4226 | NSEvent *nxev; | ||
| 4227 | |||
| 4228 | /* We only need one NX_APPDEFINED event to stop NXApp from running. */ | ||
| 4229 | send_appdefined = NO; | ||
| 4230 | |||
| 4231 | /* Don't need wakeup timer any more. */ | ||
| 4232 | if (timed_entry) | ||
| 4233 | { | ||
| 4234 | [timed_entry invalidate]; | ||
| 4235 | [timed_entry release]; | ||
| 4236 | timed_entry = nil; | ||
| 4237 | } | ||
| 4238 | |||
| 4239 | nxev = [NSEvent otherEventWithType: NSEventTypeApplicationDefined | ||
| 4240 | location: NSMakePoint (0, 0) | ||
| 4241 | modifierFlags: 0 | ||
| 4242 | timestamp: 0 | ||
| 4243 | windowNumber: [[NSApp mainWindow] windowNumber] | ||
| 4244 | context: [NSApp context] | ||
| 4245 | subtype: 0 | ||
| 4246 | data1: value | ||
| 4247 | data2: 0]; | ||
| 4248 | |||
| 4249 | /* Post an application defined event on the event queue. When this is | ||
| 4250 | received the [NXApp run] will return, thus having processed all | ||
| 4251 | events which are currently queued. */ | ||
| 4252 | [NSApp postEvent: nxev atStart: NO]; | ||
| 4253 | } | ||
| 4254 | } | ||
| 4255 | |||
| 4256 | #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 | 4119 | #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 |
| 4257 | static void | 4120 | static void |
| 4258 | check_native_fs () | 4121 | check_native_fs () |
| @@ -4298,10 +4161,13 @@ ns_check_menu_open (NSMenu *menu) | |||
| 4298 | found = menu == [[a objectAtIndex:i] submenu]; | 4161 | found = menu == [[a objectAtIndex:i] submenu]; |
| 4299 | if (found) | 4162 | if (found) |
| 4300 | { | 4163 | { |
| 4301 | if (menu_will_open_state == MENU_NONE && emacs_event) | 4164 | if (menu_will_open_state == MENU_NONE) |
| 4302 | { | 4165 | { |
| 4303 | NSEvent *theEvent = [NSApp currentEvent]; | 4166 | NSEvent *theEvent = [NSApp currentEvent]; |
| 4304 | struct frame *emacsframe = SELECTED_FRAME (); | 4167 | struct frame *emacsframe = SELECTED_FRAME (); |
| 4168 | struct input_event emacs_event; | ||
| 4169 | |||
| 4170 | EVENT_INIT (emacs_event); | ||
| 4305 | 4171 | ||
| 4306 | /* On macOS, the following can cause an event loop when the | 4172 | /* On macOS, the following can cause an event loop when the |
| 4307 | Spotlight for Help search field is populated. Avoid this by | 4173 | Spotlight for Help search field is populated. Avoid this by |
| @@ -4312,7 +4178,7 @@ ns_check_menu_open (NSMenu *menu) | |||
| 4312 | { | 4178 | { |
| 4313 | [menu cancelTracking]; | 4179 | [menu cancelTracking]; |
| 4314 | menu_will_open_state = MENU_PENDING; | 4180 | menu_will_open_state = MENU_PENDING; |
| 4315 | emacs_event->kind = MENU_BAR_ACTIVATE_EVENT; | 4181 | emacs_event.kind = MENU_BAR_ACTIVATE_EVENT; |
| 4316 | EV_TRAILER (theEvent); | 4182 | EV_TRAILER (theEvent); |
| 4317 | 4183 | ||
| 4318 | CGEventRef ourEvent = CGEventCreate (NULL); | 4184 | CGEventRef ourEvent = CGEventCreate (NULL); |
| @@ -4358,7 +4224,6 @@ ns_read_socket (struct terminal *terminal, struct input_event *hold_quit) | |||
| 4358 | From 21+ we have to manage the event buffer ourselves. | 4224 | From 21+ we have to manage the event buffer ourselves. |
| 4359 | -------------------------------------------------------------------------- */ | 4225 | -------------------------------------------------------------------------- */ |
| 4360 | { | 4226 | { |
| 4361 | struct input_event ev; | ||
| 4362 | int nevents; | 4227 | int nevents; |
| 4363 | 4228 | ||
| 4364 | NSTRACE_WHEN (NSTRACE_GROUP_EVENTS, "ns_read_socket"); | 4229 | NSTRACE_WHEN (NSTRACE_GROUP_EVENTS, "ns_read_socket"); |
| @@ -4370,20 +4235,10 @@ ns_read_socket (struct terminal *terminal, struct input_event *hold_quit) | |||
| 4370 | if ([NSApp modalWindow] != nil) | 4235 | if ([NSApp modalWindow] != nil) |
| 4371 | return -1; | 4236 | return -1; |
| 4372 | 4237 | ||
| 4373 | if (hold_event_q.nr > 0) | 4238 | if ([NSThread currentThread] == emacsMainThread) |
| 4374 | { | ||
| 4375 | int i; | ||
| 4376 | for (i = 0; i < hold_event_q.nr; ++i) | ||
| 4377 | kbd_buffer_store_event_hold (&hold_event_q.q[i], hold_quit); | ||
| 4378 | hold_event_q.nr = 0; | ||
| 4379 | return i; | ||
| 4380 | } | ||
| 4381 | |||
| 4382 | if ([NSThread isMainThread]) | ||
| 4383 | { | 4239 | { |
| 4384 | block_input (); | 4240 | block_input (); |
| 4385 | n_emacs_events_pending = 0; | 4241 | n_emacs_events_pending = 0; |
| 4386 | ns_init_events (&ev); | ||
| 4387 | q_event_ptr = hold_quit; | 4242 | q_event_ptr = hold_quit; |
| 4388 | 4243 | ||
| 4389 | /* We manage autorelease pools by allocate/reallocate each time around | 4244 | /* We manage autorelease pools by allocate/reallocate each time around |
| @@ -4409,17 +4264,19 @@ ns_read_socket (struct terminal *terminal, struct input_event *hold_quit) | |||
| 4409 | } | 4264 | } |
| 4410 | else | 4265 | else |
| 4411 | { | 4266 | { |
| 4412 | /* Run and wait for events. We must always send one NX_APPDEFINED event | 4267 | /* Run this thread's RunLoop. This will process all events |
| 4413 | to ourself, otherwise [NXApp run] will never exit. */ | 4268 | sent by the NS GUI thread. |
| 4414 | send_appdefined = YES; | 4269 | |
| 4415 | ns_send_appdefined (-1); | 4270 | We use CFRunLoop instead of NSRunLoop as it allows us to |
| 4416 | 4271 | run once and check why it returned. If it processed an | |
| 4417 | [NSApp run]; | 4272 | event we want it to try again, if it "times out" then |
| 4273 | there was nothing more to process and we finish up. */ | ||
| 4274 | while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, YES) | ||
| 4275 | == kCFRunLoopRunHandledSource); | ||
| 4418 | } | 4276 | } |
| 4419 | 4277 | ||
| 4420 | nevents = n_emacs_events_pending; | 4278 | nevents = n_emacs_events_pending; |
| 4421 | n_emacs_events_pending = 0; | 4279 | n_emacs_events_pending = 0; |
| 4422 | ns_finish_events (); | ||
| 4423 | q_event_ptr = NULL; | 4280 | q_event_ptr = NULL; |
| 4424 | unblock_input (); | 4281 | unblock_input (); |
| 4425 | } | 4282 | } |
| @@ -4438,156 +4295,16 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds, | |||
| 4438 | Replacement for select, checking for events | 4295 | Replacement for select, checking for events |
| 4439 | -------------------------------------------------------------------------- */ | 4296 | -------------------------------------------------------------------------- */ |
| 4440 | { | 4297 | { |
| 4441 | int result; | ||
| 4442 | int t, k, nr = 0; | ||
| 4443 | struct input_event event; | ||
| 4444 | char c; | ||
| 4445 | |||
| 4446 | NSTRACE_WHEN (NSTRACE_GROUP_EVENTS, "ns_select"); | 4298 | NSTRACE_WHEN (NSTRACE_GROUP_EVENTS, "ns_select"); |
| 4447 | 4299 | ||
| 4448 | #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 | 4300 | #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 |
| 4449 | check_native_fs (); | 4301 | check_native_fs (); |
| 4450 | #endif | 4302 | #endif |
| 4451 | 4303 | ||
| 4452 | if (hold_event_q.nr > 0) | 4304 | return thread_select(pselect, nfds, readfds, writefds, |
| 4453 | { | ||
| 4454 | /* We already have events pending. */ | ||
| 4455 | raise (SIGIO); | ||
| 4456 | errno = EINTR; | ||
| 4457 | return -1; | ||
| 4458 | } | ||
| 4459 | |||
| 4460 | for (k = 0; k < nfds+1; k++) | ||
| 4461 | { | ||
| 4462 | if (readfds && FD_ISSET(k, readfds)) ++nr; | ||
| 4463 | if (writefds && FD_ISSET(k, writefds)) ++nr; | ||
| 4464 | } | ||
| 4465 | |||
| 4466 | if (NSApp == nil | ||
| 4467 | || ![NSThread isMainThread] | ||
| 4468 | || (timeout && timeout->tv_sec == 0 && timeout->tv_nsec == 0)) | ||
| 4469 | return thread_select(pselect, nfds, readfds, writefds, | ||
| 4470 | exceptfds, timeout, sigmask); | 4305 | exceptfds, timeout, sigmask); |
| 4471 | else | ||
| 4472 | { | ||
| 4473 | struct timespec t = {0, 0}; | ||
| 4474 | thread_select(pselect, 0, NULL, NULL, NULL, &t, sigmask); | ||
| 4475 | } | ||
| 4476 | |||
| 4477 | [outerpool release]; | ||
| 4478 | outerpool = [[NSAutoreleasePool alloc] init]; | ||
| 4479 | |||
| 4480 | |||
| 4481 | send_appdefined = YES; | ||
| 4482 | if (nr > 0) | ||
| 4483 | { | ||
| 4484 | pthread_mutex_lock (&select_mutex); | ||
| 4485 | select_nfds = nfds; | ||
| 4486 | select_valid = 0; | ||
| 4487 | if (readfds) | ||
| 4488 | { | ||
| 4489 | select_readfds = *readfds; | ||
| 4490 | select_valid += SELECT_HAVE_READ; | ||
| 4491 | } | ||
| 4492 | if (writefds) | ||
| 4493 | { | ||
| 4494 | select_writefds = *writefds; | ||
| 4495 | select_valid += SELECT_HAVE_WRITE; | ||
| 4496 | } | ||
| 4497 | |||
| 4498 | if (timeout) | ||
| 4499 | { | ||
| 4500 | select_timeout = *timeout; | ||
| 4501 | select_valid += SELECT_HAVE_TMO; | ||
| 4502 | } | ||
| 4503 | |||
| 4504 | pthread_mutex_unlock (&select_mutex); | ||
| 4505 | |||
| 4506 | /* Inform fd_handler that select should be called. */ | ||
| 4507 | c = 'g'; | ||
| 4508 | emacs_write_sig (selfds[1], &c, 1); | ||
| 4509 | } | ||
| 4510 | else if (nr == 0 && timeout) | ||
| 4511 | { | ||
| 4512 | /* No file descriptor, just a timeout, no need to wake fd_handler. */ | ||
| 4513 | double time = timespectod (*timeout); | ||
| 4514 | timed_entry = [[NSTimer scheduledTimerWithTimeInterval: time | ||
| 4515 | target: NSApp | ||
| 4516 | selector: | ||
| 4517 | @selector (timeout_handler:) | ||
| 4518 | userInfo: 0 | ||
| 4519 | repeats: NO] | ||
| 4520 | retain]; | ||
| 4521 | } | ||
| 4522 | else /* No timeout and no file descriptors, can this happen? */ | ||
| 4523 | { | ||
| 4524 | /* Send appdefined so we exit from the loop. */ | ||
| 4525 | ns_send_appdefined (-1); | ||
| 4526 | } | ||
| 4527 | |||
| 4528 | block_input (); | ||
| 4529 | ns_init_events (&event); | ||
| 4530 | |||
| 4531 | [NSApp run]; | ||
| 4532 | |||
| 4533 | ns_finish_events (); | ||
| 4534 | if (nr > 0 && readfds) | ||
| 4535 | { | ||
| 4536 | c = 's'; | ||
| 4537 | emacs_write_sig (selfds[1], &c, 1); | ||
| 4538 | } | ||
| 4539 | unblock_input (); | ||
| 4540 | |||
| 4541 | t = last_appdefined_event_data; | ||
| 4542 | |||
| 4543 | if (t != NO_APPDEFINED_DATA) | ||
| 4544 | { | ||
| 4545 | last_appdefined_event_data = NO_APPDEFINED_DATA; | ||
| 4546 | |||
| 4547 | if (t == -2) | ||
| 4548 | { | ||
| 4549 | /* The NX_APPDEFINED event we received was a timeout. */ | ||
| 4550 | result = 0; | ||
| 4551 | } | ||
| 4552 | else if (t == -1) | ||
| 4553 | { | ||
| 4554 | /* The NX_APPDEFINED event we received was the result of | ||
| 4555 | at least one real input event arriving. */ | ||
| 4556 | errno = EINTR; | ||
| 4557 | result = -1; | ||
| 4558 | } | ||
| 4559 | else | ||
| 4560 | { | ||
| 4561 | /* Received back from select () in fd_handler; copy the results. */ | ||
| 4562 | pthread_mutex_lock (&select_mutex); | ||
| 4563 | if (readfds) *readfds = select_readfds; | ||
| 4564 | if (writefds) *writefds = select_writefds; | ||
| 4565 | pthread_mutex_unlock (&select_mutex); | ||
| 4566 | result = t; | ||
| 4567 | } | ||
| 4568 | } | ||
| 4569 | else | ||
| 4570 | { | ||
| 4571 | errno = EINTR; | ||
| 4572 | result = -1; | ||
| 4573 | } | ||
| 4574 | |||
| 4575 | return result; | ||
| 4576 | } | 4306 | } |
| 4577 | 4307 | ||
| 4578 | #ifdef HAVE_PTHREAD | ||
| 4579 | void | ||
| 4580 | ns_run_loop_break () | ||
| 4581 | /* Break out of the NS run loop in ns_select or ns_read_socket. */ | ||
| 4582 | { | ||
| 4583 | NSTRACE_WHEN (NSTRACE_GROUP_EVENTS, "ns_run_loop_break"); | ||
| 4584 | |||
| 4585 | /* If we don't have a GUI, don't send the event. */ | ||
| 4586 | if (NSApp != NULL) | ||
| 4587 | ns_send_appdefined(-1); | ||
| 4588 | } | ||
| 4589 | #endif | ||
| 4590 | |||
| 4591 | 4308 | ||
| 4592 | /* ========================================================================== | 4309 | /* ========================================================================== |
| 4593 | 4310 | ||
| @@ -5118,9 +4835,6 @@ ns_term_init (Lisp_Object display_name) | |||
| 5118 | 4835 | ||
| 5119 | NSTRACE ("ns_term_init"); | 4836 | NSTRACE ("ns_term_init"); |
| 5120 | 4837 | ||
| 5121 | [outerpool release]; | ||
| 5122 | outerpool = [[NSAutoreleasePool alloc] init]; | ||
| 5123 | |||
| 5124 | /* count object allocs (About, click icon); on macOS use ObjectAlloc tool */ | 4838 | /* count object allocs (About, click icon); on macOS use ObjectAlloc tool */ |
| 5125 | /*GSDebugAllocationActive (YES); */ | 4839 | /*GSDebugAllocationActive (YES); */ |
| 5126 | block_input (); | 4840 | block_input (); |
| @@ -5128,38 +4842,10 @@ ns_term_init (Lisp_Object display_name) | |||
| 5128 | baud_rate = 38400; | 4842 | baud_rate = 38400; |
| 5129 | Fset_input_interrupt_mode (Qnil); | 4843 | Fset_input_interrupt_mode (Qnil); |
| 5130 | 4844 | ||
| 5131 | if (selfds[0] == -1) | ||
| 5132 | { | ||
| 5133 | if (emacs_pipe (selfds) != 0) | ||
| 5134 | { | ||
| 5135 | fprintf (stderr, "Failed to create pipe: %s\n", | ||
| 5136 | emacs_strerror (errno)); | ||
| 5137 | emacs_abort (); | ||
| 5138 | } | ||
| 5139 | |||
| 5140 | fcntl (selfds[0], F_SETFL, O_NONBLOCK|fcntl (selfds[0], F_GETFL)); | ||
| 5141 | FD_ZERO (&select_readfds); | ||
| 5142 | FD_ZERO (&select_writefds); | ||
| 5143 | pthread_mutex_init (&select_mutex, NULL); | ||
| 5144 | } | ||
| 5145 | |||
| 5146 | ns_pending_files = [[NSMutableArray alloc] init]; | 4845 | ns_pending_files = [[NSMutableArray alloc] init]; |
| 5147 | ns_pending_service_names = [[NSMutableArray alloc] init]; | 4846 | ns_pending_service_names = [[NSMutableArray alloc] init]; |
| 5148 | ns_pending_service_args = [[NSMutableArray alloc] init]; | 4847 | ns_pending_service_args = [[NSMutableArray alloc] init]; |
| 5149 | 4848 | ||
| 5150 | /* Start app and create the main menu, window, view. | ||
| 5151 | Needs to be here because ns_initialize_display_info () uses AppKit classes. | ||
| 5152 | The view will then ask the NSApp to stop and return to Emacs. */ | ||
| 5153 | [EmacsApp sharedApplication]; | ||
| 5154 | if (NSApp == nil) | ||
| 5155 | return NULL; | ||
| 5156 | [NSApp setDelegate: NSApp]; | ||
| 5157 | |||
| 5158 | /* Start the select thread. */ | ||
| 5159 | [NSThread detachNewThreadSelector:@selector (fd_handler:) | ||
| 5160 | toTarget:NSApp | ||
| 5161 | withObject:nil]; | ||
| 5162 | |||
| 5163 | /* debugging: log all notifications */ | 4849 | /* debugging: log all notifications */ |
| 5164 | /* [[NSNotificationCenter defaultCenter] addObserver: NSApp | 4850 | /* [[NSNotificationCenter defaultCenter] addObserver: NSApp |
| 5165 | selector: @selector (logNotification:) | 4851 | selector: @selector (logNotification:) |
| @@ -5356,9 +5042,9 @@ ns_term_init (Lisp_Object display_name) | |||
| 5356 | right for fullscreen windows, so set this. */ | 5042 | right for fullscreen windows, so set this. */ |
| 5357 | [NSApp activateIgnoringOtherApps:YES]; | 5043 | [NSApp activateIgnoringOtherApps:YES]; |
| 5358 | 5044 | ||
| 5359 | NSTRACE_MSG ("Call NSApp run"); | 5045 | // NSTRACE_MSG ("Call NSApp run"); |
| 5360 | 5046 | ||
| 5361 | [NSApp run]; | 5047 | // [NSApp run]; |
| 5362 | ns_do_open_file = YES; | 5048 | ns_do_open_file = YES; |
| 5363 | 5049 | ||
| 5364 | #ifdef NS_IMPL_GNUSTEP | 5050 | #ifdef NS_IMPL_GNUSTEP |
| @@ -5968,12 +5654,10 @@ ns_term_shutdown (int sig) | |||
| 5968 | #ifdef NS_IMPL_COCOA | 5654 | #ifdef NS_IMPL_COCOA |
| 5969 | case NSAPP_DATA2_RUNASSCRIPT: | 5655 | case NSAPP_DATA2_RUNASSCRIPT: |
| 5970 | ns_run_ascript (); | 5656 | ns_run_ascript (); |
| 5971 | [self stop: self]; | ||
| 5972 | return; | 5657 | return; |
| 5973 | #endif | 5658 | #endif |
| 5974 | case NSAPP_DATA2_RUNFILEDIALOG: | 5659 | case NSAPP_DATA2_RUNFILEDIALOG: |
| 5975 | ns_run_file_dialog (); | 5660 | ns_run_file_dialog (); |
| 5976 | [self stop: self]; | ||
| 5977 | return; | 5661 | return; |
| 5978 | } | 5662 | } |
| 5979 | } | 5663 | } |
| @@ -5984,24 +5668,6 @@ ns_term_shutdown (int sig) | |||
| 5984 | return; | 5668 | return; |
| 5985 | } | 5669 | } |
| 5986 | 5670 | ||
| 5987 | if (type == NSEventTypeApplicationDefined) | ||
| 5988 | { | ||
| 5989 | /* Events posted by ns_send_appdefined interrupt the run loop here. | ||
| 5990 | But, if a modal window is up, an appdefined can still come through, | ||
| 5991 | (e.g., from a makeKeyWindow event) but stopping self also stops the | ||
| 5992 | modal loop. Just defer it until later. */ | ||
| 5993 | if ([NSApp modalWindow] == nil) | ||
| 5994 | { | ||
| 5995 | last_appdefined_event_data = [theEvent data1]; | ||
| 5996 | [self stop: self]; | ||
| 5997 | } | ||
| 5998 | else | ||
| 5999 | { | ||
| 6000 | send_appdefined = YES; | ||
| 6001 | } | ||
| 6002 | } | ||
| 6003 | |||
| 6004 | |||
| 6005 | #ifdef NS_IMPL_COCOA | 5671 | #ifdef NS_IMPL_COCOA |
| 6006 | /* If no dialog and none of our frames have focus and it is a move, skip it. | 5672 | /* If no dialog and none of our frames have focus and it is a move, skip it. |
| 6007 | It is a mouse move in an auxiliary menu, i.e. on the top right on macOS, | 5673 | It is a mouse move in an auxiliary menu, i.e. on the top right on macOS, |
| @@ -6028,12 +5694,13 @@ ns_term_shutdown (int sig) | |||
| 6028 | { | 5694 | { |
| 6029 | struct frame *emacsframe = SELECTED_FRAME (); | 5695 | struct frame *emacsframe = SELECTED_FRAME (); |
| 6030 | NSEvent *theEvent = [NSApp currentEvent]; | 5696 | NSEvent *theEvent = [NSApp currentEvent]; |
| 5697 | struct input_event emacs_event; | ||
| 6031 | 5698 | ||
| 6032 | if (!emacs_event) | 5699 | EVENT_INIT (emacs_event); |
| 6033 | return; | 5700 | |
| 6034 | emacs_event->kind = NS_NONKEY_EVENT; | 5701 | emacs_event.kind = NS_NONKEY_EVENT; |
| 6035 | emacs_event->code = KEY_NS_SHOW_PREFS; | 5702 | emacs_event.code = KEY_NS_SHOW_PREFS; |
| 6036 | emacs_event->modifiers = 0; | 5703 | emacs_event.modifiers = 0; |
| 6037 | EV_TRAILER (theEvent); | 5704 | EV_TRAILER (theEvent); |
| 6038 | } | 5705 | } |
| 6039 | 5706 | ||
| @@ -6044,12 +5711,13 @@ ns_term_shutdown (int sig) | |||
| 6044 | 5711 | ||
| 6045 | struct frame *emacsframe = SELECTED_FRAME (); | 5712 | struct frame *emacsframe = SELECTED_FRAME (); |
| 6046 | NSEvent *theEvent = [NSApp currentEvent]; | 5713 | NSEvent *theEvent = [NSApp currentEvent]; |
| 5714 | struct input_event emacs_event; | ||
| 6047 | 5715 | ||
| 6048 | if (!emacs_event) | 5716 | EVENT_INIT (emacs_event); |
| 6049 | return; | 5717 | |
| 6050 | emacs_event->kind = NS_NONKEY_EVENT; | 5718 | emacs_event.kind = NS_NONKEY_EVENT; |
| 6051 | emacs_event->code = KEY_NS_NEW_FRAME; | 5719 | emacs_event.code = KEY_NS_NEW_FRAME; |
| 6052 | emacs_event->modifiers = 0; | 5720 | emacs_event.modifiers = 0; |
| 6053 | EV_TRAILER (theEvent); | 5721 | EV_TRAILER (theEvent); |
| 6054 | } | 5722 | } |
| 6055 | 5723 | ||
| @@ -6061,15 +5729,15 @@ ns_term_shutdown (int sig) | |||
| 6061 | 5729 | ||
| 6062 | struct frame *emacsframe = SELECTED_FRAME (); | 5730 | struct frame *emacsframe = SELECTED_FRAME (); |
| 6063 | NSEvent *theEvent = [NSApp currentEvent]; | 5731 | NSEvent *theEvent = [NSApp currentEvent]; |
| 5732 | struct input_event emacs_event; | ||
| 6064 | 5733 | ||
| 6065 | if (!emacs_event) | 5734 | EVENT_INIT (emacs_event); |
| 6066 | return NO; | ||
| 6067 | 5735 | ||
| 6068 | emacs_event->kind = NS_NONKEY_EVENT; | 5736 | emacs_event.kind = NS_NONKEY_EVENT; |
| 6069 | emacs_event->code = KEY_NS_OPEN_FILE_LINE; | 5737 | emacs_event.code = KEY_NS_OPEN_FILE_LINE; |
| 6070 | ns_input_file = append2 (ns_input_file, build_string ([fileName UTF8String])); | 5738 | ns_input_file = append2 (ns_input_file, build_string ([fileName UTF8String])); |
| 6071 | ns_input_line = Qnil; /* can be start or cons start,end */ | 5739 | ns_input_line = Qnil; /* can be start or cons start,end */ |
| 6072 | emacs_event->modifiers =0; | 5740 | emacs_event.modifiers = 0; |
| 6073 | EV_TRAILER (theEvent); | 5741 | EV_TRAILER (theEvent); |
| 6074 | 5742 | ||
| 6075 | return YES; | 5743 | return YES; |
| @@ -6115,8 +5783,6 @@ ns_term_shutdown (int sig) | |||
| 6115 | build_string("icons/hicolor/128x128/apps/emacs.png")]]; | 5783 | build_string("icons/hicolor/128x128/apps/emacs.png")]]; |
| 6116 | } | 5784 | } |
| 6117 | #endif | 5785 | #endif |
| 6118 | |||
| 6119 | ns_send_appdefined (-2); | ||
| 6120 | } | 5786 | } |
| 6121 | 5787 | ||
| 6122 | - (void)antialiasThresholdDidChange:(NSNotification *)notification | 5788 | - (void)antialiasThresholdDidChange:(NSNotification *)notification |
| @@ -6153,13 +5819,13 @@ ns_term_shutdown (int sig) | |||
| 6153 | NSTRACE ("[EmacsApp terminate:]"); | 5819 | NSTRACE ("[EmacsApp terminate:]"); |
| 6154 | 5820 | ||
| 6155 | struct frame *emacsframe = SELECTED_FRAME (); | 5821 | struct frame *emacsframe = SELECTED_FRAME (); |
| 5822 | struct input_event emacs_event; | ||
| 6156 | 5823 | ||
| 6157 | if (!emacs_event) | 5824 | EVENT_INIT (emacs_event); |
| 6158 | return; | ||
| 6159 | 5825 | ||
| 6160 | emacs_event->kind = NS_NONKEY_EVENT; | 5826 | emacs_event.kind = NS_NONKEY_EVENT; |
| 6161 | emacs_event->code = KEY_NS_POWER_OFF; | 5827 | emacs_event.code = KEY_NS_POWER_OFF; |
| 6162 | emacs_event->arg = Qt; /* mark as non-key event */ | 5828 | emacs_event.arg = Qt; /* mark as non-key event */ |
| 6163 | EV_TRAILER ((id)nil); | 5829 | EV_TRAILER ((id)nil); |
| 6164 | } | 5830 | } |
| 6165 | 5831 | ||
| @@ -6287,123 +5953,9 @@ not_in_argv (NSString *arg) | |||
| 6287 | NSTRACE ("[EmacsApp applicationDidResignActive:]"); | 5953 | NSTRACE ("[EmacsApp applicationDidResignActive:]"); |
| 6288 | 5954 | ||
| 6289 | // ns_app_active=NO; | 5955 | // ns_app_active=NO; |
| 6290 | ns_send_appdefined (-1); | ||
| 6291 | } | 5956 | } |
| 6292 | 5957 | ||
| 6293 | 5958 | ||
| 6294 | |||
| 6295 | /* ========================================================================== | ||
| 6296 | |||
| 6297 | EmacsApp aux handlers for managing event loop | ||
| 6298 | |||
| 6299 | ========================================================================== */ | ||
| 6300 | |||
| 6301 | |||
| 6302 | - (void)timeout_handler: (NSTimer *)timedEntry | ||
| 6303 | /* -------------------------------------------------------------------------- | ||
| 6304 | The timeout specified to ns_select has passed. | ||
| 6305 | -------------------------------------------------------------------------- */ | ||
| 6306 | { | ||
| 6307 | /* NSTRACE ("timeout_handler"); */ | ||
| 6308 | ns_send_appdefined (-2); | ||
| 6309 | } | ||
| 6310 | |||
| 6311 | - (void)sendFromMainThread:(id)unused | ||
| 6312 | { | ||
| 6313 | ns_send_appdefined (nextappdefined); | ||
| 6314 | } | ||
| 6315 | |||
| 6316 | - (void)fd_handler:(id)unused | ||
| 6317 | /* -------------------------------------------------------------------------- | ||
| 6318 | Check data waiting on file descriptors and terminate if so. | ||
| 6319 | -------------------------------------------------------------------------- */ | ||
| 6320 | { | ||
| 6321 | int result; | ||
| 6322 | int waiting = 1, nfds; | ||
| 6323 | char c; | ||
| 6324 | |||
| 6325 | fd_set readfds, writefds, *wfds; | ||
| 6326 | struct timespec timeout, *tmo; | ||
| 6327 | NSAutoreleasePool *pool = nil; | ||
| 6328 | |||
| 6329 | /* NSTRACE ("fd_handler"); */ | ||
| 6330 | |||
| 6331 | for (;;) | ||
| 6332 | { | ||
| 6333 | [pool release]; | ||
| 6334 | pool = [[NSAutoreleasePool alloc] init]; | ||
| 6335 | |||
| 6336 | if (waiting) | ||
| 6337 | { | ||
| 6338 | fd_set fds; | ||
| 6339 | FD_ZERO (&fds); | ||
| 6340 | FD_SET (selfds[0], &fds); | ||
| 6341 | result = select (selfds[0]+1, &fds, NULL, NULL, NULL); | ||
| 6342 | if (result > 0 && read (selfds[0], &c, 1) == 1 && c == 'g') | ||
| 6343 | waiting = 0; | ||
| 6344 | } | ||
| 6345 | else | ||
| 6346 | { | ||
| 6347 | pthread_mutex_lock (&select_mutex); | ||
| 6348 | nfds = select_nfds; | ||
| 6349 | |||
| 6350 | if (select_valid & SELECT_HAVE_READ) | ||
| 6351 | readfds = select_readfds; | ||
| 6352 | else | ||
| 6353 | FD_ZERO (&readfds); | ||
| 6354 | |||
| 6355 | if (select_valid & SELECT_HAVE_WRITE) | ||
| 6356 | { | ||
| 6357 | writefds = select_writefds; | ||
| 6358 | wfds = &writefds; | ||
| 6359 | } | ||
| 6360 | else | ||
| 6361 | wfds = NULL; | ||
| 6362 | if (select_valid & SELECT_HAVE_TMO) | ||
| 6363 | { | ||
| 6364 | timeout = select_timeout; | ||
| 6365 | tmo = &timeout; | ||
| 6366 | } | ||
| 6367 | else | ||
| 6368 | tmo = NULL; | ||
| 6369 | |||
| 6370 | pthread_mutex_unlock (&select_mutex); | ||
| 6371 | |||
| 6372 | FD_SET (selfds[0], &readfds); | ||
| 6373 | if (selfds[0] >= nfds) nfds = selfds[0]+1; | ||
| 6374 | |||
| 6375 | result = pselect (nfds, &readfds, wfds, NULL, tmo, NULL); | ||
| 6376 | |||
| 6377 | if (result == 0) | ||
| 6378 | ns_send_appdefined (-2); | ||
| 6379 | else if (result > 0) | ||
| 6380 | { | ||
| 6381 | if (FD_ISSET (selfds[0], &readfds)) | ||
| 6382 | { | ||
| 6383 | if (read (selfds[0], &c, 1) == 1 && c == 's') | ||
| 6384 | waiting = 1; | ||
| 6385 | } | ||
| 6386 | else | ||
| 6387 | { | ||
| 6388 | pthread_mutex_lock (&select_mutex); | ||
| 6389 | if (select_valid & SELECT_HAVE_READ) | ||
| 6390 | select_readfds = readfds; | ||
| 6391 | if (select_valid & SELECT_HAVE_WRITE) | ||
| 6392 | select_writefds = writefds; | ||
| 6393 | if (select_valid & SELECT_HAVE_TMO) | ||
| 6394 | select_timeout = timeout; | ||
| 6395 | pthread_mutex_unlock (&select_mutex); | ||
| 6396 | |||
| 6397 | ns_send_appdefined (result); | ||
| 6398 | } | ||
| 6399 | } | ||
| 6400 | waiting = 1; | ||
| 6401 | } | ||
| 6402 | } | ||
| 6403 | } | ||
| 6404 | |||
| 6405 | |||
| 6406 | |||
| 6407 | /* ========================================================================== | 5959 | /* ========================================================================== |
| 6408 | 5960 | ||
| 6409 | Service provision | 5961 | Service provision |
| @@ -6426,22 +5978,30 @@ not_in_argv (NSString *arg) | |||
| 6426 | { | 5978 | { |
| 6427 | struct frame *emacsframe = SELECTED_FRAME (); | 5979 | struct frame *emacsframe = SELECTED_FRAME (); |
| 6428 | NSEvent *theEvent = [NSApp currentEvent]; | 5980 | NSEvent *theEvent = [NSApp currentEvent]; |
| 5981 | struct input_event emacs_event; | ||
| 6429 | 5982 | ||
| 6430 | NSTRACE ("[EmacsApp fulfillService:withArg:]"); | 5983 | NSTRACE ("[EmacsApp fulfillService:withArg:]"); |
| 6431 | 5984 | ||
| 6432 | if (!emacs_event) | 5985 | EVENT_INIT (emacs_event); |
| 6433 | return NO; | ||
| 6434 | 5986 | ||
| 6435 | emacs_event->kind = NS_NONKEY_EVENT; | 5987 | emacs_event.kind = NS_NONKEY_EVENT; |
| 6436 | emacs_event->code = KEY_NS_SPI_SERVICE_CALL; | 5988 | emacs_event.code = KEY_NS_SPI_SERVICE_CALL; |
| 6437 | ns_input_spi_name = build_string ([name UTF8String]); | 5989 | ns_input_spi_name = build_string ([name UTF8String]); |
| 6438 | ns_input_spi_arg = build_string ([arg UTF8String]); | 5990 | ns_input_spi_arg = build_string ([arg UTF8String]); |
| 6439 | emacs_event->modifiers = EV_MODIFIERS (theEvent); | 5991 | emacs_event.modifiers = EV_MODIFIERS (theEvent); |
| 6440 | EV_TRAILER (theEvent); | 5992 | EV_TRAILER (theEvent); |
| 6441 | 5993 | ||
| 6442 | return YES; | 5994 | return YES; |
| 6443 | } | 5995 | } |
| 6444 | 5996 | ||
| 5997 | -(void) initLispThread:(int)argc withArgv:(char **)argv | ||
| 5998 | { | ||
| 5999 | [outerpool release]; | ||
| 6000 | outerpool = [[NSAutoreleasePool alloc] init]; | ||
| 6001 | |||
| 6002 | emacs_main (argc, argv); | ||
| 6003 | } | ||
| 6004 | |||
| 6445 | 6005 | ||
| 6446 | @end /* EmacsApp */ | 6006 | @end /* EmacsApp */ |
| 6447 | 6007 | ||
| @@ -6483,11 +6043,11 @@ not_in_argv (NSString *arg) | |||
| 6483 | id newFont; | 6043 | id newFont; |
| 6484 | CGFloat size; | 6044 | CGFloat size; |
| 6485 | NSFont *nsfont; | 6045 | NSFont *nsfont; |
| 6046 | struct input_event emacs_event; | ||
| 6486 | 6047 | ||
| 6487 | NSTRACE ("[EmacsView changeFont:]"); | 6048 | NSTRACE ("[EmacsView changeFont:]"); |
| 6488 | 6049 | ||
| 6489 | if (!emacs_event) | 6050 | EVENT_INIT (emacs_event); |
| 6490 | return; | ||
| 6491 | 6051 | ||
| 6492 | #ifdef NS_IMPL_GNUSTEP | 6052 | #ifdef NS_IMPL_GNUSTEP |
| 6493 | nsfont = ((struct nsfont_info *)font)->nsfont; | 6053 | nsfont = ((struct nsfont_info *)font)->nsfont; |
| @@ -6500,9 +6060,9 @@ not_in_argv (NSString *arg) | |||
| 6500 | { | 6060 | { |
| 6501 | SET_FRAME_GARBAGED (emacsframe); /* now needed as of 2008/10 */ | 6061 | SET_FRAME_GARBAGED (emacsframe); /* now needed as of 2008/10 */ |
| 6502 | 6062 | ||
| 6503 | emacs_event->kind = NS_NONKEY_EVENT; | 6063 | emacs_event.kind = NS_NONKEY_EVENT; |
| 6504 | emacs_event->modifiers = 0; | 6064 | emacs_event.modifiers = 0; |
| 6505 | emacs_event->code = KEY_NS_CHANGE_FONT; | 6065 | emacs_event.code = KEY_NS_CHANGE_FONT; |
| 6506 | 6066 | ||
| 6507 | size = [newFont pointSize]; | 6067 | size = [newFont pointSize]; |
| 6508 | ns_input_fontsize = make_fixnum (lrint (size)); | 6068 | ns_input_fontsize = make_fixnum (lrint (size)); |
| @@ -6552,6 +6112,7 @@ not_in_argv (NSString *arg) | |||
| 6552 | unsigned fnKeysym = 0; | 6112 | unsigned fnKeysym = 0; |
| 6553 | static NSMutableArray *nsEvArray; | 6113 | static NSMutableArray *nsEvArray; |
| 6554 | unsigned int flags = [theEvent modifierFlags]; | 6114 | unsigned int flags = [theEvent modifierFlags]; |
| 6115 | struct input_event emacs_event; | ||
| 6555 | 6116 | ||
| 6556 | NSTRACE ("[EmacsView keyDown:]"); | 6117 | NSTRACE ("[EmacsView keyDown:]"); |
| 6557 | 6118 | ||
| @@ -6561,8 +6122,7 @@ not_in_argv (NSString *arg) | |||
| 6561 | else if ([theEvent type] != NSEventTypeKeyDown) | 6122 | else if ([theEvent type] != NSEventTypeKeyDown) |
| 6562 | return; | 6123 | return; |
| 6563 | 6124 | ||
| 6564 | if (!emacs_event) | 6125 | EVENT_INIT (emacs_event); |
| 6565 | return; | ||
| 6566 | 6126 | ||
| 6567 | if (![[self window] isKeyWindow] | 6127 | if (![[self window] isKeyWindow] |
| 6568 | && [[theEvent window] isKindOfClass: [EmacsWindow class]] | 6128 | && [[theEvent window] isKindOfClass: [EmacsWindow class]] |
| @@ -6644,7 +6204,7 @@ not_in_argv (NSString *arg) | |||
| 6644 | Therefore its return value is the set of control-like | 6204 | Therefore its return value is the set of control-like |
| 6645 | modifiers. */ | 6205 | modifiers. */ |
| 6646 | Lisp_Object kind = fnKeysym ? QCfunction : QCordinary; | 6206 | Lisp_Object kind = fnKeysym ? QCfunction : QCordinary; |
| 6647 | emacs_event->modifiers = EV_MODIFIERS2 (flags, kind); | 6207 | emacs_event.modifiers = EV_MODIFIERS2 (flags, kind); |
| 6648 | 6208 | ||
| 6649 | /* Function keys (such as the F-keys, arrow keys, etc.) set | 6209 | /* Function keys (such as the F-keys, arrow keys, etc.) set |
| 6650 | modifiers as though the fn key has been pressed when it | 6210 | modifiers as though the fn key has been pressed when it |
| @@ -6653,21 +6213,21 @@ not_in_argv (NSString *arg) | |||
| 6653 | <home>). We need to unset the fn modifier in these cases. | 6213 | <home>). We need to unset the fn modifier in these cases. |
| 6654 | FIXME: Can we avoid setting it in the first place? */ | 6214 | FIXME: Can we avoid setting it in the first place? */ |
| 6655 | if (fnKeysym && (flags & NS_FUNCTION_KEY_MASK)) | 6215 | if (fnKeysym && (flags & NS_FUNCTION_KEY_MASK)) |
| 6656 | emacs_event->modifiers | 6216 | emacs_event.modifiers |
| 6657 | ^= parse_solitary_modifier (mod_of_kind (ns_function_modifier, | 6217 | ^= parse_solitary_modifier (mod_of_kind (ns_function_modifier, |
| 6658 | QCfunction)); | 6218 | QCfunction)); |
| 6659 | 6219 | ||
| 6660 | if (NS_KEYLOG) | 6220 | if (NS_KEYLOG) |
| 6661 | fprintf (stderr, "keyDown: code =%x\tfnKey =%x\tflags = %x\tmods = %x\n", | 6221 | fprintf (stderr, "keyDown: code =%x\tfnKey =%x\tflags = %x\tmods = %x\n", |
| 6662 | code, fnKeysym, flags, emacs_event->modifiers); | 6222 | code, fnKeysym, flags, emacs_event.modifiers); |
| 6663 | 6223 | ||
| 6664 | /* If it was a function key or had control-like modifiers, pass | 6224 | /* If it was a function key or had control-like modifiers, pass |
| 6665 | it directly to Emacs. */ | 6225 | it directly to Emacs. */ |
| 6666 | if (fnKeysym || (emacs_event->modifiers | 6226 | if (fnKeysym || (emacs_event.modifiers |
| 6667 | && (emacs_event->modifiers != shift_modifier) | 6227 | && (emacs_event.modifiers != shift_modifier) |
| 6668 | && [[theEvent charactersIgnoringModifiers] length] > 0)) | 6228 | && [[theEvent charactersIgnoringModifiers] length] > 0)) |
| 6669 | { | 6229 | { |
| 6670 | emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT; | 6230 | emacs_event.kind = NON_ASCII_KEYSTROKE_EVENT; |
| 6671 | /* FIXME: What are the next four lines supposed to do? */ | 6231 | /* FIXME: What are the next four lines supposed to do? */ |
| 6672 | if (code < 0x20) | 6232 | if (code < 0x20) |
| 6673 | code |= (1<<28)|(3<<16); | 6233 | code |= (1<<28)|(3<<16); |
| @@ -6686,12 +6246,14 @@ not_in_argv (NSString *arg) | |||
| 6686 | [0x80, 0xFF] are not ASCII characters. Can’t we just | 6246 | [0x80, 0xFF] are not ASCII characters. Can’t we just |
| 6687 | use MULTIBYTE_CHAR_KEYSTROKE_EVENT here for all kinds | 6247 | use MULTIBYTE_CHAR_KEYSTROKE_EVENT here for all kinds |
| 6688 | of characters? */ | 6248 | of characters? */ |
| 6689 | emacs_event->kind = code > 0xFF | 6249 | emacs_event.kind = code > 0xFF |
| 6690 | ? MULTIBYTE_CHAR_KEYSTROKE_EVENT : ASCII_KEYSTROKE_EVENT; | 6250 | ? MULTIBYTE_CHAR_KEYSTROKE_EVENT : ASCII_KEYSTROKE_EVENT; |
| 6691 | } | 6251 | } |
| 6692 | 6252 | ||
| 6693 | emacs_event->code = code; | 6253 | emacs_event.code = code; |
| 6254 | |||
| 6694 | EV_TRAILER (theEvent); | 6255 | EV_TRAILER (theEvent); |
| 6256 | |||
| 6695 | processingCompose = NO; | 6257 | processingCompose = NO; |
| 6696 | return; | 6258 | return; |
| 6697 | } | 6259 | } |
| @@ -6739,6 +6301,7 @@ not_in_argv (NSString *arg) | |||
| 6739 | { | 6301 | { |
| 6740 | NSString *s; | 6302 | NSString *s; |
| 6741 | NSUInteger len; | 6303 | NSUInteger len; |
| 6304 | struct input_event emacs_event; | ||
| 6742 | 6305 | ||
| 6743 | NSTRACE ("[EmacsView insertText:]"); | 6306 | NSTRACE ("[EmacsView insertText:]"); |
| 6744 | 6307 | ||
| @@ -6753,8 +6316,7 @@ not_in_argv (NSString *arg) | |||
| 6753 | NSLog (@"insertText '%@'\tlen = %lu", aString, (unsigned long) len); | 6316 | NSLog (@"insertText '%@'\tlen = %lu", aString, (unsigned long) len); |
| 6754 | processingCompose = NO; | 6317 | processingCompose = NO; |
| 6755 | 6318 | ||
| 6756 | if (!emacs_event) | 6319 | EVENT_INIT(emacs_event); |
| 6757 | return; | ||
| 6758 | 6320 | ||
| 6759 | /* First, clear any working text. */ | 6321 | /* First, clear any working text. */ |
| 6760 | if (workingText != nil) | 6322 | if (workingText != nil) |
| @@ -6782,10 +6344,10 @@ not_in_argv (NSString *arg) | |||
| 6782 | if (code == 0x2DC) | 6344 | if (code == 0x2DC) |
| 6783 | code = '~'; /* 0x7E */ | 6345 | code = '~'; /* 0x7E */ |
| 6784 | if (code != 32) /* Space */ | 6346 | if (code != 32) /* Space */ |
| 6785 | emacs_event->modifiers = 0; | 6347 | emacs_event.modifiers = 0; |
| 6786 | emacs_event->kind | 6348 | emacs_event.kind |
| 6787 | = code > 0xFF ? MULTIBYTE_CHAR_KEYSTROKE_EVENT : ASCII_KEYSTROKE_EVENT; | 6349 | = code > 0xFF ? MULTIBYTE_CHAR_KEYSTROKE_EVENT : ASCII_KEYSTROKE_EVENT; |
| 6788 | emacs_event->code = code; | 6350 | emacs_event.code = code; |
| 6789 | EV_TRAILER ((id)nil); | 6351 | EV_TRAILER ((id)nil); |
| 6790 | } | 6352 | } |
| 6791 | } | 6353 | } |
| @@ -6796,6 +6358,7 @@ not_in_argv (NSString *arg) | |||
| 6796 | { | 6358 | { |
| 6797 | NSString *str = [aString respondsToSelector: @selector (string)] ? | 6359 | NSString *str = [aString respondsToSelector: @selector (string)] ? |
| 6798 | [aString string] : aString; | 6360 | [aString string] : aString; |
| 6361 | struct input_event emacs_event; | ||
| 6799 | 6362 | ||
| 6800 | NSTRACE ("[EmacsView setMarkedText:selectedRange:]"); | 6363 | NSTRACE ("[EmacsView setMarkedText:selectedRange:]"); |
| 6801 | 6364 | ||
| @@ -6811,16 +6374,15 @@ not_in_argv (NSString *arg) | |||
| 6811 | return; | 6374 | return; |
| 6812 | } | 6375 | } |
| 6813 | 6376 | ||
| 6814 | if (!emacs_event) | 6377 | EVENT_INIT (emacs_event); |
| 6815 | return; | ||
| 6816 | 6378 | ||
| 6817 | processingCompose = YES; | 6379 | processingCompose = YES; |
| 6818 | [workingText release]; | 6380 | [workingText release]; |
| 6819 | workingText = [str copy]; | 6381 | workingText = [str copy]; |
| 6820 | ns_working_text = build_string ([workingText UTF8String]); | 6382 | ns_working_text = build_string ([workingText UTF8String]); |
| 6821 | 6383 | ||
| 6822 | emacs_event->kind = NS_TEXT_EVENT; | 6384 | emacs_event.kind = NS_TEXT_EVENT; |
| 6823 | emacs_event->code = KEY_NS_PUT_WORKING_TEXT; | 6385 | emacs_event.code = KEY_NS_PUT_WORKING_TEXT; |
| 6824 | EV_TRAILER ((id)nil); | 6386 | EV_TRAILER ((id)nil); |
| 6825 | } | 6387 | } |
| 6826 | 6388 | ||
| @@ -6828,6 +6390,8 @@ not_in_argv (NSString *arg) | |||
| 6828 | /* Delete display of composing characters [not in <NSTextInput>]. */ | 6390 | /* Delete display of composing characters [not in <NSTextInput>]. */ |
| 6829 | - (void)deleteWorkingText | 6391 | - (void)deleteWorkingText |
| 6830 | { | 6392 | { |
| 6393 | struct input_event emacs_event; | ||
| 6394 | |||
| 6831 | NSTRACE ("[EmacsView deleteWorkingText]"); | 6395 | NSTRACE ("[EmacsView deleteWorkingText]"); |
| 6832 | 6396 | ||
| 6833 | if (workingText == nil) | 6397 | if (workingText == nil) |
| @@ -6838,11 +6402,10 @@ not_in_argv (NSString *arg) | |||
| 6838 | workingText = nil; | 6402 | workingText = nil; |
| 6839 | processingCompose = NO; | 6403 | processingCompose = NO; |
| 6840 | 6404 | ||
| 6841 | if (!emacs_event) | 6405 | EVENT_INIT (emacs_event); |
| 6842 | return; | ||
| 6843 | 6406 | ||
| 6844 | emacs_event->kind = NS_TEXT_EVENT; | 6407 | emacs_event.kind = NS_TEXT_EVENT; |
| 6845 | emacs_event->code = KEY_NS_UNPUT_WORKING_TEXT; | 6408 | emacs_event.code = KEY_NS_UNPUT_WORKING_TEXT; |
| 6846 | EV_TRAILER ((id)nil); | 6409 | EV_TRAILER ((id)nil); |
| 6847 | } | 6410 | } |
| 6848 | 6411 | ||
| @@ -6943,12 +6506,12 @@ not_in_argv (NSString *arg) | |||
| 6943 | processingCompose = NO; | 6506 | processingCompose = NO; |
| 6944 | if (aSelector == @selector (deleteBackward:)) | 6507 | if (aSelector == @selector (deleteBackward:)) |
| 6945 | { | 6508 | { |
| 6946 | /* Happens when user backspaces over an ongoing composition: | 6509 | struct input_event emacs_event; |
| 6510 | /* Happens when user backspaces over an ongoing composition: | ||
| 6947 | throw a 'delete' into the event queue. */ | 6511 | throw a 'delete' into the event queue. */ |
| 6948 | if (!emacs_event) | 6512 | EVENT_INIT (emacs_event); |
| 6949 | return; | 6513 | emacs_event.kind = NON_ASCII_KEYSTROKE_EVENT; |
| 6950 | emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT; | 6514 | emacs_event.code = 0xFF08; |
| 6951 | emacs_event->code = 0xFF08; | ||
| 6952 | EV_TRAILER ((id)nil); | 6515 | EV_TRAILER ((id)nil); |
| 6953 | } | 6516 | } |
| 6954 | } | 6517 | } |
| @@ -6998,11 +6561,11 @@ not_in_argv (NSString *arg) | |||
| 6998 | { | 6561 | { |
| 6999 | struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe); | 6562 | struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe); |
| 7000 | NSPoint p = [self convertPoint: [theEvent locationInWindow] fromView: nil]; | 6563 | NSPoint p = [self convertPoint: [theEvent locationInWindow] fromView: nil]; |
| 6564 | struct input_event emacs_event; | ||
| 7001 | 6565 | ||
| 7002 | NSTRACE ("[EmacsView mouseDown:]"); | 6566 | NSTRACE ("[EmacsView mouseDown:]"); |
| 7003 | 6567 | ||
| 7004 | if (!emacs_event) | 6568 | EVENT_INIT (emacs_event); |
| 7005 | return; | ||
| 7006 | 6569 | ||
| 7007 | dpyinfo->last_mouse_frame = emacsframe; | 6570 | dpyinfo->last_mouse_frame = emacsframe; |
| 7008 | /* Appears to be needed to prevent spurious movement events generated on | 6571 | /* Appears to be needed to prevent spurious movement events generated on |
| @@ -7111,11 +6674,11 @@ not_in_argv (NSString *arg) | |||
| 7111 | if (lines == 0) | 6674 | if (lines == 0) |
| 7112 | return; | 6675 | return; |
| 7113 | 6676 | ||
| 7114 | emacs_event->kind = horizontal ? HORIZ_WHEEL_EVENT : WHEEL_EVENT; | 6677 | emacs_event.kind = horizontal ? HORIZ_WHEEL_EVENT : WHEEL_EVENT; |
| 7115 | emacs_event->arg = (make_fixnum (lines)); | 6678 | emacs_event.arg = (make_fixnum (lines)); |
| 7116 | 6679 | ||
| 7117 | emacs_event->code = 0; | 6680 | emacs_event.code = 0; |
| 7118 | emacs_event->modifiers = EV_MODIFIERS (theEvent) | | 6681 | emacs_event.modifiers = EV_MODIFIERS (theEvent) | |
| 7119 | (scrollUp ? up_modifier : down_modifier); | 6682 | (scrollUp ? up_modifier : down_modifier); |
| 7120 | #if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 | 6683 | #if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 |
| 7121 | } | 6684 | } |
| @@ -7135,27 +6698,27 @@ not_in_argv (NSString *arg) | |||
| 7135 | NSTRACE_MSG ("deltaIsZero"); | 6698 | NSTRACE_MSG ("deltaIsZero"); |
| 7136 | return; | 6699 | return; |
| 7137 | } | 6700 | } |
| 7138 | emacs_event->kind = HORIZ_WHEEL_EVENT; | 6701 | emacs_event.kind = HORIZ_WHEEL_EVENT; |
| 7139 | } | 6702 | } |
| 7140 | else | 6703 | else |
| 7141 | emacs_event->kind = WHEEL_EVENT; | 6704 | emacs_event.kind = WHEEL_EVENT; |
| 7142 | 6705 | ||
| 7143 | emacs_event->code = 0; | 6706 | emacs_event.code = 0; |
| 7144 | emacs_event->modifiers = EV_MODIFIERS (theEvent) | | 6707 | emacs_event.modifiers = EV_MODIFIERS (theEvent) | |
| 7145 | ((delta > 0) ? up_modifier : down_modifier); | 6708 | ((delta > 0) ? up_modifier : down_modifier); |
| 7146 | } | 6709 | } |
| 7147 | #endif | 6710 | #endif |
| 7148 | } | 6711 | } |
| 7149 | else | 6712 | else |
| 7150 | { | 6713 | { |
| 7151 | emacs_event->kind = MOUSE_CLICK_EVENT; | 6714 | emacs_event.kind = MOUSE_CLICK_EVENT; |
| 7152 | emacs_event->code = EV_BUTTON (theEvent); | 6715 | emacs_event.code = EV_BUTTON (theEvent); |
| 7153 | emacs_event->modifiers = EV_MODIFIERS (theEvent) | 6716 | emacs_event.modifiers = EV_MODIFIERS (theEvent) |
| 7154 | | EV_UDMODIFIERS (theEvent); | 6717 | | EV_UDMODIFIERS (theEvent); |
| 7155 | } | 6718 | } |
| 7156 | 6719 | ||
| 7157 | XSETINT (emacs_event->x, lrint (p.x)); | 6720 | XSETINT (emacs_event.x, lrint (p.x)); |
| 7158 | XSETINT (emacs_event->y, lrint (p.y)); | 6721 | XSETINT (emacs_event.y, lrint (p.y)); |
| 7159 | EV_TRAILER (theEvent); | 6722 | EV_TRAILER (theEvent); |
| 7160 | return; | 6723 | return; |
| 7161 | } | 6724 | } |
| @@ -7243,10 +6806,14 @@ not_in_argv (NSString *arg) | |||
| 7243 | || (EQ (XWINDOW (window)->frame, | 6806 | || (EQ (XWINDOW (window)->frame, |
| 7244 | XWINDOW (selected_window)->frame)))) | 6807 | XWINDOW (selected_window)->frame)))) |
| 7245 | { | 6808 | { |
| 6809 | struct input_event emacs_event; | ||
| 6810 | |||
| 7246 | NSTRACE_MSG ("in_window"); | 6811 | NSTRACE_MSG ("in_window"); |
| 7247 | emacs_event->kind = SELECT_WINDOW_EVENT; | 6812 | EVENT_INIT (emacs_event); |
| 7248 | emacs_event->frame_or_window = window; | 6813 | |
| 7249 | EV_TRAILER2 (e); | 6814 | emacs_event.kind = SELECT_WINDOW_EVENT; |
| 6815 | emacs_event.frame_or_window = window; | ||
| 6816 | EV_TRAILER (e); | ||
| 7250 | } | 6817 | } |
| 7251 | /* Remember the last window where we saw the mouse. */ | 6818 | /* Remember the last window where we saw the mouse. */ |
| 7252 | last_mouse_window = window; | 6819 | last_mouse_window = window; |
| @@ -7266,8 +6833,8 @@ not_in_argv (NSString *arg) | |||
| 7266 | help_echo_object, help_echo_pos); | 6833 | help_echo_object, help_echo_pos); |
| 7267 | } | 6834 | } |
| 7268 | 6835 | ||
| 7269 | if (emacsframe->mouse_moved && send_appdefined) | 6836 | if (emacsframe->mouse_moved) |
| 7270 | ns_send_appdefined (-1); | 6837 | raise (SIGIO); |
| 7271 | } | 6838 | } |
| 7272 | 6839 | ||
| 7273 | 6840 | ||
| @@ -7295,14 +6862,14 @@ not_in_argv (NSString *arg) | |||
| 7295 | - (BOOL)windowShouldClose: (id)sender | 6862 | - (BOOL)windowShouldClose: (id)sender |
| 7296 | { | 6863 | { |
| 7297 | NSEvent *e =[[self window] currentEvent]; | 6864 | NSEvent *e =[[self window] currentEvent]; |
| 6865 | struct input_event emacs_event; | ||
| 7298 | 6866 | ||
| 7299 | NSTRACE ("[EmacsView windowShouldClose:]"); | 6867 | NSTRACE ("[EmacsView windowShouldClose:]"); |
| 7300 | windowClosing = YES; | 6868 | windowClosing = YES; |
| 7301 | if (!emacs_event) | 6869 | EVENT_INIT (emacs_event); |
| 7302 | return NO; | 6870 | emacs_event.kind = DELETE_WINDOW_EVENT; |
| 7303 | emacs_event->kind = DELETE_WINDOW_EVENT; | 6871 | emacs_event.modifiers = 0; |
| 7304 | emacs_event->modifiers = 0; | 6872 | emacs_event.code = 0; |
| 7305 | emacs_event->code = 0; | ||
| 7306 | EV_TRAILER (e); | 6873 | EV_TRAILER (e); |
| 7307 | /* Don't close this window, let this be done from lisp code. */ | 6874 | /* Don't close this window, let this be done from lisp code. */ |
| 7308 | return NO; | 6875 | return NO; |
| @@ -7550,8 +7117,6 @@ not_in_argv (NSString *arg) | |||
| 7550 | { | 7117 | { |
| 7551 | [self updateFrameSize: YES]; | 7118 | [self updateFrameSize: YES]; |
| 7552 | } | 7119 | } |
| 7553 | |||
| 7554 | ns_send_appdefined (-1); | ||
| 7555 | } | 7120 | } |
| 7556 | 7121 | ||
| 7557 | #ifdef NS_IMPL_COCOA | 7122 | #ifdef NS_IMPL_COCOA |
| @@ -7582,19 +7147,19 @@ not_in_argv (NSString *arg) | |||
| 7582 | { | 7147 | { |
| 7583 | struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe); | 7148 | struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe); |
| 7584 | struct frame *old_focus = dpyinfo->ns_focus_frame; | 7149 | struct frame *old_focus = dpyinfo->ns_focus_frame; |
| 7150 | struct input_event emacs_event; | ||
| 7585 | 7151 | ||
| 7586 | NSTRACE ("[EmacsView windowDidBecomeKey]"); | 7152 | NSTRACE ("[EmacsView windowDidBecomeKey]"); |
| 7587 | 7153 | ||
| 7154 | EVENT_INIT (emacs_event); | ||
| 7155 | |||
| 7588 | if (emacsframe != old_focus) | 7156 | if (emacsframe != old_focus) |
| 7589 | dpyinfo->ns_focus_frame = emacsframe; | 7157 | dpyinfo->ns_focus_frame = emacsframe; |
| 7590 | 7158 | ||
| 7591 | ns_frame_rehighlight (emacsframe); | 7159 | ns_frame_rehighlight (emacsframe); |
| 7592 | 7160 | ||
| 7593 | if (emacs_event) | 7161 | emacs_event.kind = FOCUS_IN_EVENT; |
| 7594 | { | 7162 | EV_TRAILER ((id)nil); |
| 7595 | emacs_event->kind = FOCUS_IN_EVENT; | ||
| 7596 | EV_TRAILER ((id)nil); | ||
| 7597 | } | ||
| 7598 | } | 7163 | } |
| 7599 | 7164 | ||
| 7600 | 7165 | ||
| @@ -7603,6 +7168,8 @@ not_in_argv (NSString *arg) | |||
| 7603 | { | 7168 | { |
| 7604 | struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe); | 7169 | struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe); |
| 7605 | BOOL is_focus_frame = dpyinfo->ns_focus_frame == emacsframe; | 7170 | BOOL is_focus_frame = dpyinfo->ns_focus_frame == emacsframe; |
| 7171 | struct input_event emacs_event; | ||
| 7172 | |||
| 7606 | NSTRACE ("[EmacsView windowDidResignKey:]"); | 7173 | NSTRACE ("[EmacsView windowDidResignKey:]"); |
| 7607 | 7174 | ||
| 7608 | if (is_focus_frame) | 7175 | if (is_focus_frame) |
| @@ -7627,9 +7194,10 @@ not_in_argv (NSString *arg) | |||
| 7627 | gen_help_event (Qnil, frame, Qnil, Qnil, 0); | 7194 | gen_help_event (Qnil, frame, Qnil, Qnil, 0); |
| 7628 | } | 7195 | } |
| 7629 | 7196 | ||
| 7630 | if (emacs_event && is_focus_frame) | 7197 | if (is_focus_frame) |
| 7631 | { | 7198 | { |
| 7632 | emacs_event->kind = FOCUS_OUT_EVENT; | 7199 | EVENT_INIT (emacs_event); |
| 7200 | emacs_event.kind = FOCUS_OUT_EVENT; | ||
| 7633 | EV_TRAILER ((id)nil); | 7201 | EV_TRAILER ((id)nil); |
| 7634 | } | 7202 | } |
| 7635 | } | 7203 | } |
| @@ -7858,6 +7426,7 @@ not_in_argv (NSString *arg) | |||
| 7858 | NSRect r = [win frame]; | 7426 | NSRect r = [win frame]; |
| 7859 | NSArray *screens = [NSScreen screens]; | 7427 | NSArray *screens = [NSScreen screens]; |
| 7860 | NSScreen *screen = [screens objectAtIndex: 0]; | 7428 | NSScreen *screen = [screens objectAtIndex: 0]; |
| 7429 | struct input_event emacs_event; | ||
| 7861 | 7430 | ||
| 7862 | NSTRACE ("[EmacsView windowDidMove:]"); | 7431 | NSTRACE ("[EmacsView windowDidMove:]"); |
| 7863 | 7432 | ||
| @@ -7865,6 +7434,8 @@ not_in_argv (NSString *arg) | |||
| 7865 | return; | 7434 | return; |
| 7866 | if (screen != nil) | 7435 | if (screen != nil) |
| 7867 | { | 7436 | { |
| 7437 | EVENT_INIT (emacs_event); | ||
| 7438 | |||
| 7868 | emacsframe->left_pos = r.origin.x - NS_PARENT_WINDOW_LEFT_POS (emacsframe); | 7439 | emacsframe->left_pos = r.origin.x - NS_PARENT_WINDOW_LEFT_POS (emacsframe); |
| 7869 | emacsframe->top_pos = | 7440 | emacsframe->top_pos = |
| 7870 | NS_PARENT_WINDOW_TOP_POS (emacsframe) - (r.origin.y + r.size.height); | 7441 | NS_PARENT_WINDOW_TOP_POS (emacsframe) - (r.origin.y + r.size.height); |
| @@ -7872,7 +7443,7 @@ not_in_argv (NSString *arg) | |||
| 7872 | // FIXME: after event part below didExitFullScreen is not received | 7443 | // FIXME: after event part below didExitFullScreen is not received |
| 7873 | // if (emacs_event) | 7444 | // if (emacs_event) |
| 7874 | // { | 7445 | // { |
| 7875 | // emacs_event->kind = MOVE_FRAME_EVENT; | 7446 | // emacs_event.kind = MOVE_FRAME_EVENT; |
| 7876 | // EV_TRAILER ((id)nil); | 7447 | // EV_TRAILER ((id)nil); |
| 7877 | // } | 7448 | // } |
| 7878 | } | 7449 | } |
| @@ -8016,7 +7587,12 @@ not_in_argv (NSString *arg) | |||
| 8016 | 7587 | ||
| 8017 | - (void)windowDidDeminiaturize: sender | 7588 | - (void)windowDidDeminiaturize: sender |
| 8018 | { | 7589 | { |
| 7590 | struct input_event emacs_event; | ||
| 7591 | |||
| 8019 | NSTRACE ("[EmacsView windowDidDeminiaturize:]"); | 7592 | NSTRACE ("[EmacsView windowDidDeminiaturize:]"); |
| 7593 | |||
| 7594 | EVENT_INIT (emacs_event); | ||
| 7595 | |||
| 8020 | if (!emacsframe->output_data.ns) | 7596 | if (!emacsframe->output_data.ns) |
| 8021 | return; | 7597 | return; |
| 8022 | 7598 | ||
| @@ -8024,11 +7600,8 @@ not_in_argv (NSString *arg) | |||
| 8024 | SET_FRAME_VISIBLE (emacsframe, 1); | 7600 | SET_FRAME_VISIBLE (emacsframe, 1); |
| 8025 | windows_or_buffers_changed = 63; | 7601 | windows_or_buffers_changed = 63; |
| 8026 | 7602 | ||
| 8027 | if (emacs_event) | 7603 | emacs_event.kind = DEICONIFY_EVENT; |
| 8028 | { | 7604 | EV_TRAILER ((id)nil); |
| 8029 | emacs_event->kind = DEICONIFY_EVENT; | ||
| 8030 | EV_TRAILER ((id)nil); | ||
| 8031 | } | ||
| 8032 | } | 7605 | } |
| 8033 | 7606 | ||
| 8034 | 7607 | ||
| @@ -8040,26 +7613,25 @@ not_in_argv (NSString *arg) | |||
| 8040 | 7613 | ||
| 8041 | SET_FRAME_VISIBLE (emacsframe, 1); | 7614 | SET_FRAME_VISIBLE (emacsframe, 1); |
| 8042 | SET_FRAME_GARBAGED (emacsframe); | 7615 | SET_FRAME_GARBAGED (emacsframe); |
| 8043 | |||
| 8044 | if (send_appdefined) | ||
| 8045 | ns_send_appdefined (-1); | ||
| 8046 | } | 7616 | } |
| 8047 | 7617 | ||
| 8048 | 7618 | ||
| 8049 | - (void)windowDidMiniaturize: sender | 7619 | - (void)windowDidMiniaturize: sender |
| 8050 | { | 7620 | { |
| 7621 | struct input_event emacs_event; | ||
| 7622 | |||
| 8051 | NSTRACE ("[EmacsView windowDidMiniaturize:]"); | 7623 | NSTRACE ("[EmacsView windowDidMiniaturize:]"); |
| 7624 | |||
| 7625 | EVENT_INIT (emacs_event); | ||
| 7626 | |||
| 8052 | if (!emacsframe->output_data.ns) | 7627 | if (!emacsframe->output_data.ns) |
| 8053 | return; | 7628 | return; |
| 8054 | 7629 | ||
| 8055 | SET_FRAME_ICONIFIED (emacsframe, 1); | 7630 | SET_FRAME_ICONIFIED (emacsframe, 1); |
| 8056 | SET_FRAME_VISIBLE (emacsframe, 0); | 7631 | SET_FRAME_VISIBLE (emacsframe, 0); |
| 8057 | 7632 | ||
| 8058 | if (emacs_event) | 7633 | emacs_event.kind = ICONIFY_EVENT; |
| 8059 | { | 7634 | EV_TRAILER ((id)nil); |
| 8060 | emacs_event->kind = ICONIFY_EVENT; | ||
| 8061 | EV_TRAILER ((id)nil); | ||
| 8062 | } | ||
| 8063 | } | 7635 | } |
| 8064 | 7636 | ||
| 8065 | #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 | 7637 | #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 |
| @@ -8505,7 +8077,6 @@ not_in_argv (NSString *arg) | |||
| 8505 | (void *)tag); | 8077 | (void *)tag); |
| 8506 | } | 8078 | } |
| 8507 | 8079 | ||
| 8508 | ns_send_appdefined (-1); | ||
| 8509 | return self; | 8080 | return self; |
| 8510 | } | 8081 | } |
| 8511 | 8082 | ||
| @@ -8521,18 +8092,22 @@ not_in_argv (NSString *arg) | |||
| 8521 | { | 8092 | { |
| 8522 | NSEvent *theEvent; | 8093 | NSEvent *theEvent; |
| 8523 | int idx = [item tag] * TOOL_BAR_ITEM_NSLOTS; | 8094 | int idx = [item tag] * TOOL_BAR_ITEM_NSLOTS; |
| 8095 | struct input_event emacs_event; | ||
| 8524 | 8096 | ||
| 8525 | NSTRACE ("[EmacsView toolbarClicked:]"); | 8097 | NSTRACE ("[EmacsView toolbarClicked:]"); |
| 8526 | 8098 | ||
| 8527 | if (!emacs_event) | 8099 | EVENT_INIT (emacs_event); |
| 8528 | return self; | ||
| 8529 | 8100 | ||
| 8530 | theEvent = [[self window] currentEvent]; | 8101 | theEvent = [[self window] currentEvent]; |
| 8531 | emacs_event->kind = TOOL_BAR_EVENT; | 8102 | emacs_event.kind = TOOL_BAR_EVENT; |
| 8103 | XSETFRAME (emacs_event.arg, emacsframe); | ||
| 8104 | EV_TRAILER (theEvent); | ||
| 8105 | |||
| 8106 | emacs_event.kind = TOOL_BAR_EVENT; | ||
| 8532 | /* XSETINT (emacs_event->code, 0); */ | 8107 | /* XSETINT (emacs_event->code, 0); */ |
| 8533 | emacs_event->arg = AREF (emacsframe->tool_bar_items, | 8108 | emacs_event.arg = AREF (emacsframe->tool_bar_items, |
| 8534 | idx + TOOL_BAR_ITEM_KEY); | 8109 | idx + TOOL_BAR_ITEM_KEY); |
| 8535 | emacs_event->modifiers = EV_MODIFIERS (theEvent); | 8110 | emacs_event.modifiers = EV_MODIFIERS (theEvent); |
| 8536 | EV_TRAILER (theEvent); | 8111 | EV_TRAILER (theEvent); |
| 8537 | return self; | 8112 | return self; |
| 8538 | } | 8113 | } |
| @@ -8540,13 +8115,14 @@ not_in_argv (NSString *arg) | |||
| 8540 | 8115 | ||
| 8541 | - (instancetype)toggleToolbar: (id)sender | 8116 | - (instancetype)toggleToolbar: (id)sender |
| 8542 | { | 8117 | { |
| 8118 | struct input_event emacs_event; | ||
| 8119 | |||
| 8543 | NSTRACE ("[EmacsView toggleToolbar:]"); | 8120 | NSTRACE ("[EmacsView toggleToolbar:]"); |
| 8544 | 8121 | ||
| 8545 | if (!emacs_event) | 8122 | EVENT_INIT (emacs_event); |
| 8546 | return self; | ||
| 8547 | 8123 | ||
| 8548 | emacs_event->kind = NS_NONKEY_EVENT; | 8124 | emacs_event.kind = NS_NONKEY_EVENT; |
| 8549 | emacs_event->code = KEY_NS_TOGGLE_TOOLBAR; | 8125 | emacs_event.code = KEY_NS_TOGGLE_TOOLBAR; |
| 8550 | EV_TRAILER ((id)nil); | 8126 | EV_TRAILER ((id)nil); |
| 8551 | return self; | 8127 | return self; |
| 8552 | } | 8128 | } |
| @@ -8722,11 +8298,12 @@ not_in_argv (NSString *arg) | |||
| 8722 | Lisp_Object operations = Qnil; | 8298 | Lisp_Object operations = Qnil; |
| 8723 | Lisp_Object strings = Qnil; | 8299 | Lisp_Object strings = Qnil; |
| 8724 | Lisp_Object type_sym; | 8300 | Lisp_Object type_sym; |
| 8301 | int modifiers = 0; | ||
| 8302 | struct input_event emacs_event; | ||
| 8725 | 8303 | ||
| 8726 | NSTRACE ("[EmacsView performDragOperation:]"); | 8304 | NSTRACE ("[EmacsView performDragOperation:]"); |
| 8727 | 8305 | ||
| 8728 | if (!emacs_event) | 8306 | EVENT_INIT (emacs_event); |
| 8729 | return NO; | ||
| 8730 | 8307 | ||
| 8731 | position = [self convertPoint: [sender draggingLocation] fromView: nil]; | 8308 | position = [self convertPoint: [sender draggingLocation] fromView: nil]; |
| 8732 | x = lrint (position.x); y = lrint (position.y); | 8309 | x = lrint (position.x); y = lrint (position.y); |
| @@ -8794,14 +8371,14 @@ not_in_argv (NSString *arg) | |||
| 8794 | return NO; | 8371 | return NO; |
| 8795 | } | 8372 | } |
| 8796 | 8373 | ||
| 8797 | emacs_event->kind = DRAG_N_DROP_EVENT; | 8374 | emacs_event.kind = DRAG_N_DROP_EVENT; |
| 8798 | XSETINT (emacs_event->x, x); | 8375 | XSETINT (emacs_event.x, x); |
| 8799 | XSETINT (emacs_event->y, y); | 8376 | XSETINT (emacs_event.y, y); |
| 8800 | emacs_event->modifiers = 0; | 8377 | emacs_event.modifiers = 0; |
| 8801 | 8378 | ||
| 8802 | emacs_event->arg = Fcons (type_sym, | 8379 | emacs_event.arg = Fcons (type_sym, |
| 8803 | Fcons (operations, | 8380 | Fcons (operations, |
| 8804 | strings)); | 8381 | strings)); |
| 8805 | EV_TRAILER (theEvent); | 8382 | EV_TRAILER (theEvent); |
| 8806 | 8383 | ||
| 8807 | return YES; | 8384 | return YES; |
| @@ -9427,46 +9004,38 @@ not_in_argv (NSString *arg) | |||
| 9427 | return self; | 9004 | return self; |
| 9428 | } | 9005 | } |
| 9429 | 9006 | ||
| 9430 | /* Set up emacs_event. */ | ||
| 9431 | - (void) sendScrollEventAtLoc: (float)loc fromEvent: (NSEvent *)e | 9007 | - (void) sendScrollEventAtLoc: (float)loc fromEvent: (NSEvent *)e |
| 9432 | { | 9008 | { |
| 9433 | Lisp_Object win; | 9009 | Lisp_Object win; |
| 9010 | struct input_event emacs_event; | ||
| 9434 | 9011 | ||
| 9435 | NSTRACE ("[EmacsScroller sendScrollEventAtLoc:fromEvent:]"); | 9012 | NSTRACE ("[EmacsScroller sendScrollEventAtLoc:fromEvent:]"); |
| 9436 | 9013 | ||
| 9437 | if (!emacs_event) | 9014 | EVENT_INIT (emacs_event); |
| 9438 | return; | ||
| 9439 | 9015 | ||
| 9440 | emacs_event->part = last_hit_part; | 9016 | emacs_event.part = last_hit_part; |
| 9441 | emacs_event->code = 0; | 9017 | emacs_event.code = 0; |
| 9442 | emacs_event->modifiers = EV_MODIFIERS (e) | down_modifier; | 9018 | emacs_event.modifiers = EV_MODIFIERS (e) | down_modifier; |
| 9443 | XSETWINDOW (win, window); | 9019 | XSETWINDOW (win, window); |
| 9444 | emacs_event->frame_or_window = win; | 9020 | emacs_event.arg = Qnil; |
| 9445 | emacs_event->timestamp = EV_TIMESTAMP (e); | ||
| 9446 | emacs_event->arg = Qnil; | ||
| 9447 | 9021 | ||
| 9448 | if (horizontal) | 9022 | if (horizontal) |
| 9449 | { | 9023 | { |
| 9450 | emacs_event->kind = HORIZONTAL_SCROLL_BAR_CLICK_EVENT; | 9024 | emacs_event.kind = HORIZONTAL_SCROLL_BAR_CLICK_EVENT; |
| 9451 | XSETINT (emacs_event->x, em_whole * loc / pixel_length); | 9025 | XSETINT (emacs_event.x, em_whole * loc / pixel_length); |
| 9452 | XSETINT (emacs_event->y, em_whole); | 9026 | XSETINT (emacs_event.y, em_whole); |
| 9453 | } | 9027 | } |
| 9454 | else | 9028 | else |
| 9455 | { | 9029 | { |
| 9456 | emacs_event->kind = SCROLL_BAR_CLICK_EVENT; | 9030 | emacs_event.kind = SCROLL_BAR_CLICK_EVENT; |
| 9457 | XSETINT (emacs_event->x, loc); | 9031 | XSETINT (emacs_event.x, loc); |
| 9458 | XSETINT (emacs_event->y, pixel_length-20); | 9032 | XSETINT (emacs_event.y, pixel_length-20); |
| 9459 | } | 9033 | } |
| 9460 | 9034 | ||
| 9461 | if (q_event_ptr) | 9035 | [emacsMainThread sendEmacsEvent:&emacs_event |
| 9462 | { | 9036 | NSEvent:e |
| 9463 | n_emacs_events_pending++; | 9037 | frameOrWindow:win]; |
| 9464 | kbd_buffer_store_event_hold (emacs_event, q_event_ptr); | 9038 | |
| 9465 | } | ||
| 9466 | else | ||
| 9467 | hold_event (emacs_event); | ||
| 9468 | EVENT_INIT (*emacs_event); | ||
| 9469 | ns_send_appdefined (-1); | ||
| 9470 | } | 9039 | } |
| 9471 | 9040 | ||
| 9472 | 9041 | ||
| @@ -9698,6 +9267,85 @@ not_in_argv (NSString *arg) | |||
| 9698 | @end /* EmacsScroller */ | 9267 | @end /* EmacsScroller */ |
| 9699 | 9268 | ||
| 9700 | 9269 | ||
| 9270 | /* ========================================================================== | ||
| 9271 | |||
| 9272 | EmacsThread implementation | ||
| 9273 | |||
| 9274 | ========================================================================== */ | ||
| 9275 | |||
| 9276 | /* EmacsThread extends NSThread and provides a few convenience methods | ||
| 9277 | for passing events and such like. */ | ||
| 9278 | |||
| 9279 | @implementation EmacsThread | ||
| 9280 | |||
| 9281 | - (instancetype) initWithArgc: (int)argc Argv: (char **)argv | ||
| 9282 | { | ||
| 9283 | NSMethodSignature *lispSignature; | ||
| 9284 | NSInvocation *lispInvocation; | ||
| 9285 | |||
| 9286 | lispSignature = [NSApp methodSignatureForSelector:@selector(initLispThread:withArgv:)]; | ||
| 9287 | lispInvocation = [NSInvocation invocationWithMethodSignature:lispSignature]; | ||
| 9288 | [lispInvocation setTarget:NSApp]; | ||
| 9289 | [lispInvocation setSelector:@selector(initLispThread:withArgv:)]; | ||
| 9290 | [lispInvocation setArgument:&argc atIndex:2]; | ||
| 9291 | [lispInvocation setArgument:&argv atIndex:3]; | ||
| 9292 | |||
| 9293 | return [self initWithTarget:lispInvocation | ||
| 9294 | selector:@selector (invoke) | ||
| 9295 | object:nil]; | ||
| 9296 | } | ||
| 9297 | |||
| 9298 | |||
| 9299 | /* Put the input_event held in data into the emacs event queue. | ||
| 9300 | |||
| 9301 | This method should be run in the Emacs Main Lisp thread, so never | ||
| 9302 | call it directly, only from sendEmacsEvent. */ | ||
| 9303 | - (void) processEmacsEvent: (NSData *)data | ||
| 9304 | { | ||
| 9305 | struct input_event *event; | ||
| 9306 | Lisp_Object tem = Vinhibit_quit; | ||
| 9307 | |||
| 9308 | NSTRACE ("[EmacsThread processEmacsEvent:]"); | ||
| 9309 | |||
| 9310 | event = (struct input_event *)[data bytes]; | ||
| 9311 | |||
| 9312 | Vinhibit_quit = Qt; | ||
| 9313 | n_emacs_events_pending++; | ||
| 9314 | kbd_buffer_store_event_hold (event, q_event_ptr); | ||
| 9315 | Vinhibit_quit = tem; | ||
| 9316 | } | ||
| 9317 | |||
| 9318 | /* Send an input_event to the Emacs main thread. */ | ||
| 9319 | - (void) sendEmacsEvent: (struct input_event *)emacs_event | ||
| 9320 | NSEvent: (NSEvent *)e | ||
| 9321 | frameOrWindow: (void *)frame_or_window | ||
| 9322 | { | ||
| 9323 | NSData *event; | ||
| 9324 | |||
| 9325 | NSTRACE ("[EmacsThread sendEmacsEvent:]"); | ||
| 9326 | |||
| 9327 | XSETFRAME (emacs_event->frame_or_window, frame_or_window); | ||
| 9328 | |||
| 9329 | if (e) | ||
| 9330 | emacs_event->timestamp = EV_TIMESTAMP (e); | ||
| 9331 | |||
| 9332 | /* Package the input_event inside an NSData object so we can pass it | ||
| 9333 | to the lisp thread using performSelector. performSelector | ||
| 9334 | doesn't handle complex C types. Even using an NSInvocation to | ||
| 9335 | package it up fails. */ | ||
| 9336 | event = [NSData dataWithBytes:emacs_event | ||
| 9337 | length:sizeof(struct input_event)]; | ||
| 9338 | |||
| 9339 | [emacsMainThread performSelector:@selector(processEmacsEvent:) | ||
| 9340 | onThread:emacsMainThread | ||
| 9341 | withObject:event | ||
| 9342 | waitUntilDone:NO]; | ||
| 9343 | |||
| 9344 | raise (SIGIO); | ||
| 9345 | } | ||
| 9346 | |||
| 9347 | @end /* EmacsThread */ | ||
| 9348 | |||
| 9701 | #ifdef NS_IMPL_GNUSTEP | 9349 | #ifdef NS_IMPL_GNUSTEP |
| 9702 | /* Dummy class to get rid of startup warnings. */ | 9350 | /* Dummy class to get rid of startup warnings. */ |
| 9703 | @implementation EmacsDocument | 9351 | @implementation EmacsDocument |
| @@ -9825,6 +9473,23 @@ ns_xlfd_to_fontname (const char *xlfd) | |||
| 9825 | } | 9473 | } |
| 9826 | 9474 | ||
| 9827 | 9475 | ||
| 9476 | int | ||
| 9477 | main (int argc, char **argv) | ||
| 9478 | { | ||
| 9479 | // if (! initialized) | ||
| 9480 | // return emacs_main(argc, argv); | ||
| 9481 | |||
| 9482 | [EmacsApp sharedApplication]; | ||
| 9483 | [NSApp setDelegate: NSApp]; | ||
| 9484 | |||
| 9485 | /* Start the Lisp thread. */ | ||
| 9486 | emacsMainThread = [[EmacsThread alloc] initWithArgc:argc Argv:argv]; | ||
| 9487 | [emacsMainThread start]; | ||
| 9488 | |||
| 9489 | [NSApp run]; | ||
| 9490 | } | ||
| 9491 | |||
| 9492 | |||
| 9828 | void | 9493 | void |
| 9829 | syms_of_nsterm (void) | 9494 | syms_of_nsterm (void) |
| 9830 | { | 9495 | { |
diff --git a/src/systhread.c b/src/systhread.c index 0d600d6895e..ff2b43dc92b 100644 --- a/src/systhread.c +++ b/src/systhread.c | |||
| @@ -175,13 +175,6 @@ sys_cond_broadcast (sys_cond_t *cond) | |||
| 175 | { | 175 | { |
| 176 | int error = pthread_cond_broadcast (cond); | 176 | int error = pthread_cond_broadcast (cond); |
| 177 | eassert (error == 0); | 177 | eassert (error == 0); |
| 178 | #ifdef HAVE_NS | ||
| 179 | /* Send an app defined event to break out of the NS run loop. | ||
| 180 | It seems that if ns_select is running the NS run loop, this | ||
| 181 | broadcast has no effect until the loop is done, breaking a couple | ||
| 182 | of tests in thread-tests.el. */ | ||
| 183 | ns_run_loop_break (); | ||
| 184 | #endif | ||
| 185 | } | 178 | } |
| 186 | 179 | ||
| 187 | void | 180 | void |