aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Third2018-06-23 15:26:26 +0100
committerAlan Third2020-03-22 15:31:45 +0000
commit3316e78c120f69aa3ac12ff7345a79dd09654c9a (patch)
tree95dab41336265e82d71bc45c621733bfdbe06a74 /src
parent41f54289058ec42829cd19f7c469b2e4e325b830 (diff)
downloademacs-scratch/ns/next.tar.gz
emacs-scratch/ns/next.zip
Run NSApp loop in its own threadscratch/ns/next
* src/emacs.c (main) [HAVE_NS]: Rename to emacs_main. * src/lisp.h (emacs_main) [HAVE_NS]: Define function. * src/nsfns.m (Fns_do_applescript): Remove runloop. (Fx_create_frame): Initialize the frame on the main thread. * src/nsterm.h ([EmacsApp initLispThread:withArgv:]): New method. ([EmacsApp fd_handler:]): ([EmacsApp timeout_handler:]): ([EmacsApp sendFromMainThread:]): Remove function definitions. ([EmacsApp initLispThread:]): New function. ([EmacsThread initWithArgc:Argv:]): ([EmacsThread sendEmacsEvent:NSEvent:frameOrWindow:]): New functions. * src/nsterm.m (EV_TRAILER): Reduce to a single function. (EV_TRAILER2): Remove. (ns_init_events): (ns_finish_events): (hold_event): (ns_send_appdefined): (ns_run_loop_break): ([EmacsApp timeout_handler:]): ([EmacsApp sendFromMainThread:]): ([EmacsApp fd_handler:]): Remove functions. (ns_check_menu_open): ([EmacsApp newFrame:]): ([EmacsApp openFile:]): ([EmacsApp terminate:]): ([EmacsApp fulfillService:withArg:]): ([EmacsView changeFont:]): ([EmacsView keyDown:]): ([EmacsView insertText:]): ([EmacsView setmarkedtext:selectedRange:]): ([EmacsView deleteWorkingText:]): ([EmacsView doCommandBySelector:]): ([EmacsView mouseDown:]): ([EmacsView mouseMoved:]): ([EmacsView windowShouldClose:]): ([EmacsView windowDidResize:]): ([EmacsView windowDidBecomeKey]): ([EmacsView windowDidResignKey:]): ([EmacsView windowDidMove:]): ([EmacsView windowDidDeminiaturize:]): ([EmacsView windowDidExpose:]): ([EmacsView windowDidMiniaturize:]): ([EmacsView menuDown:]): ([EmacsView toolbarClicked:]): ([EmacsView toggleToolbar:]): ([EmacsView performDragOperation:]): ([EmacsScroller sendScrollEventAtLoc:fromEvent:]): Change event handling. ([EmacsApp applicationDidFinishLaunching:]): ([EmacsApp applicationDidResignActive:]): Remove call to ns_send_appdefined. (ns_read_socket): Change event handling, use thread local runloop. (ns_select): Remove unused fd_handler and runloop related code. (ns_term_init): Move some NS initialisation code to new main function and remove fd_handler related code. ([EmacsApp sendEvent:]): Stop run loop from exiting. ([EmacsApp initLispThread:withArgv:]): New method. ([EmacsThread initWithArgc:Argv:]): ([EmacsThread processEmacsEvent:]): ([EmacsThread sendEmacsEvent:NSEvent:frameOrWindow:]): New functions. (main): New function to initialise NS stuff and run emacs_main in its own thread. * src/systhread.c (sys_cond_broadcast): Remove NS runloop related code.
Diffstat (limited to 'src')
-rw-r--r--src/emacs.c4
-rw-r--r--src/lisp.h4
-rw-r--r--src/nsfns.m13
-rw-r--r--src/nsterm.h14
-rw-r--r--src/nsterm.m909
-rw-r--r--src/systhread.c7
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
926int 926int
927#ifdef HAVE_NS
928emacs_main (int argc, char **argv)
929#else
927main (int argc, char **argv) 930main (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);
4717extern char *get_keysym_name (int); 4717extern char *get_keysym_name (int);
4718#endif /* HAVE_WINDOW_SYSTEM */ 4718#endif /* HAVE_WINDOW_SYSTEM */
4719 4719
4720#ifdef HAVE_NS
4721extern int emacs_main (int, char **);
4722#endif
4723
4720/* Defined in xml.c. */ 4724/* Defined in xml.c. */
4721extern void syms_of_xml (void); 4725extern 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
195EmacsThread *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 */
301static BOOL send_appdefined = YES;
302#define NO_APPDEFINED_DATA (-8)
303static int last_appdefined_event_data = NO_APPDEFINED_DATA;
304static NSTimer *timed_entry = 0;
305static NSTimer *scroll_repeat_entry = nil; 303static NSTimer *scroll_repeat_entry = nil;
306static fd_set select_readfds, select_writefds;
307enum { SELECT_HAVE_READ = 1, SELECT_HAVE_WRITE = 2, SELECT_HAVE_TMO = 4 };
308static int select_nfds = 0, select_valid = 0;
309static struct timespec select_timeout = { 0, 0 };
310static int selfds[2] = { -1, -1 };
311static pthread_mutex_t select_mutex;
312static NSAutoreleasePool *outerpool; 304static NSAutoreleasePool *outerpool;
313static struct input_event *emacs_event = NULL;
314static struct input_event *q_event_ptr = NULL; 305static struct input_event *q_event_ptr = NULL;
315static int n_emacs_events_pending = 0; 306static int n_emacs_events_pending = 0;
316static NSMutableArray *ns_pending_files, *ns_pending_service_names, 307static NSMutableArray *ns_pending_files, *ns_pending_service_names,
@@ -323,13 +314,6 @@ static BOOL ns_last_use_native_fullscreen;
323 314
324static BOOL any_help_event_p = NO; 315static BOOL any_help_event_p = NO;
325 316
326static 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
493void
494ns_init_events (struct input_event *ev)
495{
496 EVENT_INIT (*ev);
497 emacs_event = ev;
498}
499
500void
501ns_finish_events (void)
502{
503 emacs_event = NULL;
504}
505
506static void
507hold_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
523static Lisp_Object 458static Lisp_Object
524append2 (Lisp_Object list, Lisp_Object item) 459append2 (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
4185static void
4186ns_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
4257static void 4120static void
4258check_native_fs () 4121check_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
4579void
4580ns_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
9476int
9477main (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
9828void 9493void
9829syms_of_nsterm (void) 9494syms_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
187void 180void