Mercurial > hg > xemacs-beta
annotate src/ExternalClient.c @ 5936:574f0cded429 cygwin
try to replace all nnnL or nnnUL constants with EMACS_[U]INT
author | Henry Thompson <ht@markup.co.uk> |
---|---|
date | Sun, 13 Dec 2015 13:22:58 +0000 |
parents | 2aa9cd456ae7 |
children |
rev | line source |
---|---|
428 | 1 /* External client widget. |
2 Copyright (C) 1993, 1994 Sun Microsystems, Inc. | |
3 | |
5405
2aa9cd456ae7
Move src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
3025
diff
changeset
|
4 This library is free software: you can redistribute it and/or modify it |
2aa9cd456ae7
Move src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
3025
diff
changeset
|
5 under the terms of the GNU General Public License as published by the |
2aa9cd456ae7
Move src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
3025
diff
changeset
|
6 Free Software Foundation, either version 3 of the License, or (at your |
2aa9cd456ae7
Move src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
3025
diff
changeset
|
7 option) any later version. |
428 | 8 |
5405
2aa9cd456ae7
Move src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
3025
diff
changeset
|
9 This library is distributed in the hope that it will be useful, but WITHOUT |
2aa9cd456ae7
Move src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
3025
diff
changeset
|
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
2aa9cd456ae7
Move src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
3025
diff
changeset
|
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
2aa9cd456ae7
Move src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
3025
diff
changeset
|
12 for more details. |
428 | 13 |
5405
2aa9cd456ae7
Move src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
3025
diff
changeset
|
14 You should have received a copy of the GNU General Public License |
2aa9cd456ae7
Move src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
3025
diff
changeset
|
15 along with this library. If not, see <http://www.gnu.org/licenses/>. */ |
428 | 16 |
17 /* Synched up with: Not in FSF. */ | |
18 | |
19 /* Written by Ben Wing, September 1993. */ | |
20 | |
21 #ifdef emacs | |
22 | |
23 #include <config.h> | |
24 | |
25 #ifndef EXTERNAL_WIDGET | |
26 ERROR! This ought not be getting compiled if EXTERNAL_WIDGET is undefined | |
27 #endif | |
28 | |
29 #endif /* emacs */ | |
30 | |
31 #include <stdio.h> | |
32 #include <string.h> | |
33 #include <stdlib.h> | |
34 #ifdef EXTW_USES_MOTIF | |
35 # include <Xm/XmP.h> | |
36 # include <Xm/PrimitiveP.h> | |
37 # include <X11/keysym.h> | |
38 #else | |
39 # include "xintrinsicp.h" | |
40 # include <X11/StringDefs.h> | |
41 #endif | |
42 | |
2299 | 43 #include "compiler.h" |
428 | 44 #include "ExternalClientP.h" |
45 #include "extw-Xt.h" | |
46 | |
47 #ifdef TOOLTALK | |
442 | 48 #include TT_C_H_FILE |
428 | 49 #endif |
50 | |
51 /* This is the client widget, used to communicate with an ExternalShell | |
52 widget. */ | |
53 | |
54 #define NOTIFY(w, type, l0, l1, l2) \ | |
55 extw_send_notify_3(XtDisplay((Widget)(w)), XtWindow((Widget)(w)),\ | |
56 type, l0, l1, l2) | |
57 | |
3025 | 58 static void externalClientInitialize (Widget req, Widget new_, ArgList args, |
428 | 59 Cardinal *num_args); |
60 static void externalClientRealize (Widget widget, XtValueMask *mask, | |
61 XSetWindowAttributes *attrs); | |
62 static void Destroy (Widget w); | |
63 static void EventHandler (Widget wid, XtPointer closure, XEvent *event, | |
64 Boolean *continue_to_dispatch); | |
65 static void MaskableEventHandler (Widget wid, XtPointer closure, XEvent *event, | |
66 Boolean *continue_to_dispatch); | |
67 static XtGeometryResult QueryGeometry(Widget, XtWidgetGeometry *, | |
68 XtWidgetGeometry *); | |
69 static void ExternalClientFocusIn (Widget, XEvent *, String *, Cardinal *); | |
70 static void ExternalClientFocusOut (Widget, XEvent *, String *, Cardinal *); | |
71 static void ExternalClientEnter (Widget, XEvent *, String *, Cardinal *); | |
72 static void ExternalClientLeave (Widget, XEvent *, String *, Cardinal *); | |
73 | |
74 static int my_error_handler(Display *display, XErrorEvent *xev); | |
75 static int (*error_old_handler)(Display *, XErrorEvent *); | |
76 | |
77 static XtResource resources[] = { | |
78 #define offset(field) XtOffset(ExternalClientWidget, externalClient.field) | |
440 | 79 { XtNshellTimeout, XtCShellTimeout, |
80 XtRInt, sizeof (int), | |
81 offset(shell_timeout), XtRImmediate,(XtPointer)DEFAULT_WM_TIMEOUT }, | |
82 { XtNdeadShell, XtCDeadShell, | |
83 XtRBoolean, sizeof (Boolean), | |
84 offset(dead_shell), XtRImmediate, (XtPointer)False }, | |
428 | 85 #ifdef EXTW_USES_MOTIF |
440 | 86 { XmNnavigationType, XmCNavigationType, |
87 XmRNavigationType, sizeof (XmNavigationType), | |
88 XtOffset (ExternalClientWidget, primitive.navigation_type), | |
89 XtRImmediate, (XtPointer)XmTAB_GROUP }, | |
428 | 90 #endif |
440 | 91 { XtNemacsProcID, XtCEmacsProcID, |
92 XtRString, sizeof (String), | |
93 offset(emacs_procid), XtRImmediate, (XtPointer)NULL }, | |
94 { XtNshellReadyCallback, XtCCallback, | |
95 XtRCallback, sizeof (XtCallbackList), | |
96 offset(shell_ready_callback), XtRImmediate, (XtPointer)NULL }, | |
97 { XtNshellName, XtCShellName, | |
98 XtRString, sizeof (String), | |
99 offset(shell_name), XtRImmediate, (XtPointer)NULL }, | |
100 { XtNuseToolTalk, XtCUseToolTalk, | |
101 XtRBoolean, sizeof (Boolean), | |
102 offset(use_tooltalk), XtRImmediate, (XtPointer)False } | |
428 | 103 }; |
104 | |
105 static XtActionsRec actions[] = { | |
106 {"focusIn", ExternalClientFocusIn}, | |
107 {"focusOut", ExternalClientFocusOut}, | |
108 {"enter", ExternalClientEnter}, | |
109 {"leave", ExternalClientLeave}, | |
110 }; | |
111 | |
112 ExternalClientClassRec externalClientClassRec = { | |
113 { /* | |
114 * core_class fields | |
115 */ | |
116 #ifdef EXTW_USES_MOTIF | |
117 /* superclass */ (WidgetClass) &xmPrimitiveClassRec, | |
118 #else | |
119 /* superclass */ (WidgetClass) &coreClassRec, | |
120 #endif | |
121 /* class_name */ "ExternalClient", | |
440 | 122 /* size */ sizeof (ExternalClientRec), |
428 | 123 /* Class Initializer */ NULL, |
124 /* class_part_initialize*/ NULL, /* XtInheritClassPartInitialize, */ | |
125 /* Class init'ed ? */ FALSE, | |
126 /* initialize */ externalClientInitialize, | |
127 /* initialize_notify */ NULL, | |
440 | 128 /* realize */ externalClientRealize, |
428 | 129 /* actions */ actions, |
130 /* num_actions */ XtNumber (actions), | |
131 /* resources */ resources, | |
132 /* resource_count */ XtNumber (resources), | |
133 /* xrm_class */ NULLQUARK, | |
134 /* compress_motion */ FALSE, | |
135 /* compress_exposure */ TRUE, | |
136 /* compress_enterleave*/ FALSE, | |
137 /* visible_interest */ TRUE, | |
138 /* destroy */ Destroy, /* XtInheritDestroy, */ | |
139 /* resize */ XtInheritResize, | |
140 /* expose */ NULL, | |
141 /* set_values */ NULL, /* XtInheritSetValues, */ | |
440 | 142 /* set_values_hook */ NULL, |
143 /* set_values_almost */ XtInheritSetValuesAlmost, | |
144 /* get_values_hook */ NULL, | |
428 | 145 /* accept_focus */ NULL, |
146 /* intrinsics version */ XtVersion, | |
147 /* callback offsets */ NULL, | |
148 /* tm_table */ "", /* MUST NOT BE NULL or | |
149 XtInheritTranslations in Motif!!!!! | |
150 Otherwise keyboard focus translations | |
151 will not work. */ | |
152 /* query_geometry */ QueryGeometry, | |
153 /* display_accelerator*/ NULL, | |
154 /* extension */ NULL | |
155 }, | |
156 #ifdef EXTW_USES_MOTIF | |
157 { | |
158 XmInheritBorderHighlight,/* Primitive border_highlight */ | |
159 XmInheritBorderHighlight,/* Primitive border_unhighlight */ | |
160 XtInheritTranslations, /* translations */ | |
161 NULL, /* arm_and_activate */ | |
162 NULL, /* get resources */ | |
163 0, /* num get_resources */ | |
164 NULL, /* extension */ | |
165 }, | |
166 #endif | |
167 { | |
168 0 | |
169 } | |
170 }; | |
171 | |
172 WidgetClass externalClientWidgetClass = (WidgetClass) &externalClientClassRec; | |
173 | |
174 static void | |
3025 | 175 externalClientInitialize (Widget UNUSED (req), Widget new_, |
2286 | 176 ArgList UNUSED (args), Cardinal *UNUSED (num_args)) |
428 | 177 { |
3025 | 178 ExternalClientWidget ecw = (ExternalClientWidget) new_; |
428 | 179 static int error_handler_added = 0; |
180 | |
3025 | 181 extw_initialize_atoms (XtDisplay (new_)); |
428 | 182 extw_which_side = extw_client_send; |
183 | |
184 #ifdef EXTW_USES_MOTIF | |
185 | |
186 /* yes I know this is horrible. However, the XmPrimitive class adds | |
187 the Tab translation in its initialization routine, so we have to | |
188 override it here. This is all the fault of Xt, which doesn't | |
189 provide a proper inheritance mechanism for translations. | |
190 | |
191 -- BPW | |
192 | |
193 */ | |
440 | 194 |
3025 | 195 XtOverrideTranslations (new_, |
428 | 196 XtParseTranslationTable ("None<Key>Tab:\n" |
197 "<FocusIn>:focusIn()\n" | |
198 "<FocusOut>:focusOut()\n" | |
199 "<Enter>:enter()\n" | |
200 "<Leave>:leave()\n")); | |
201 | |
202 #endif | |
440 | 203 |
3025 | 204 XtAddEventHandler (new_, 0, TRUE, EventHandler, (XtPointer) NULL); |
428 | 205 |
206 ecw->externalClient.shell_ready = False; | |
207 ecw->externalClient.has_focus = False; | |
208 | |
209 if (!error_handler_added) | |
210 { | |
211 error_handler_added = 1; | |
212 error_old_handler = XSetErrorHandler (my_error_handler); | |
213 } | |
214 } | |
215 | |
216 | |
217 #ifdef TOOLTALK | |
218 static Tt_callback_action | |
2286 | 219 tt_callback(Tt_message m, Tt_pattern UNUSED (p)) |
428 | 220 { |
221 ExternalClientWidget ecw = (ExternalClientWidget)tt_message_user (m, 0); | |
440 | 222 |
428 | 223 switch (tt_message_state(m)) |
224 { | |
225 case TT_FAILED: | |
226 /* handle errors here */ | |
227 break; | |
228 case TT_HANDLED: | |
229 ecw->externalClient.shell_name = tt_message_arg_val (m, 2); | |
230 XtCallCallbackList ((Widget) ecw, | |
231 ecw->externalClient.shell_ready_callback, NULL); | |
232 break; | |
233 } | |
440 | 234 |
428 | 235 tt_message_destroy (m); |
236 return TT_CALLBACK_PROCESSED; | |
237 } | |
238 | |
239 static void | |
240 send_tooltalk_handshake (ExternalClientWidget ecw, Window win, char *name) | |
241 { | |
242 Tt_message m = tt_message_create (); | |
243 | |
244 tt_message_op_set (m, "emacs-make-client-screen"); | |
245 tt_message_scope_set (m, TT_SESSION); | |
246 tt_message_class_set (m, TT_REQUEST); | |
247 tt_message_arg_add (m, TT_IN, "string", name); | |
248 tt_message_iarg_add (m, TT_IN, "int", win); | |
440 | 249 tt_message_arg_add (m, TT_OUT, "string", NULL); |
428 | 250 tt_message_user_set (m, 0, (void *)ecw); |
251 tt_message_callback_add (m, tt_callback); | |
252 if (ecw->externalClient.emacs_procid) | |
253 { | |
254 tt_message_address_set (m, TT_HANDLER); | |
255 tt_message_handler_set (m, ecw->externalClient.emacs_procid); | |
256 } | |
257 else | |
258 tt_message_address_set (m, TT_PROCEDURE); | |
259 tt_message_send (m); | |
260 } | |
261 | |
262 #endif | |
263 | |
264 | |
265 static void | |
266 externalClientRealize (Widget w, XtValueMask *vm, XSetWindowAttributes *attrs) | |
267 { | |
1094 | 268 #ifdef TOOLTALK |
428 | 269 ExternalClientWidget ecw = (ExternalClientWidget)w; |
1094 | 270 #endif |
440 | 271 |
272 #ifdef EXTW_USES_MOTIF | |
428 | 273 (*xmPrimitiveWidgetClass->core_class.realize) (w, vm, attrs); |
274 #else | |
275 (*coreWidgetClass->core_class.realize) (w, vm, attrs); | |
276 #endif | |
277 | |
278 #ifdef TOOLTALK | |
279 /* Make sure that the server actually knows about this window id before | |
280 * telling Emacs about it. | |
281 */ | |
282 if (ecw->externalClient.use_tooltalk) | |
283 { | |
284 XSync (XtDisplay (w), False); | |
285 send_tooltalk_handshake (ecw, XtWindow (w), XtName (w)); | |
286 } | |
440 | 287 #endif |
428 | 288 } |
289 | |
290 | |
291 /***********************************************************************/ | |
292 | |
293 /* window-to-widget list. */ | |
294 | |
295 struct ww_list | |
296 { | |
297 Window win; | |
298 Widget wid; | |
299 struct ww_list *next; | |
300 }; | |
301 | |
302 struct ww_list ww_list[1]; | |
303 | |
304 static int | |
305 add_ww (Window win, Widget wid) | |
306 { | |
307 struct ww_list *ww = (struct ww_list *) malloc (sizeof (struct | |
308 ww_list)); | |
309 if (!ww) | |
310 return 0; | |
311 ww->win = win; | |
312 ww->wid = wid; | |
313 ww->next = ww_list->next; | |
314 ww_list->next = ww; | |
315 return 1; | |
316 } | |
317 | |
318 static Widget | |
319 remove_ww (Window win) | |
320 { | |
321 struct ww_list *w1, *w2; | |
322 Widget wid = 0; | |
440 | 323 |
428 | 324 for (w1=ww_list, w2=w1->next; w2; w1=w2, w2=w2->next) |
325 if (w2->win == win) | |
326 { | |
327 w1->next = w2->next; | |
328 wid = w2->wid; | |
329 free (w2); | |
330 break; | |
331 } | |
332 return wid; | |
333 } | |
334 | |
335 /***********************************************************************/ | |
336 | |
337 /* stolen outright from Intrinsic.c */ | |
338 | |
2108 | 339 static void |
340 ComputeWindowAttributes (Widget widget, XtValueMask *value_mask, | |
341 XSetWindowAttributes *values) | |
428 | 342 { |
343 *value_mask = CWEventMask | CWColormap; | |
344 (*values).event_mask = XtBuildEventMask(widget); | |
345 (*values).colormap = widget->core.colormap; | |
346 if (widget->core.background_pixmap != XtUnspecifiedPixmap) { | |
347 *value_mask |= CWBackPixmap; | |
348 (*values).background_pixmap = widget->core.background_pixmap; | |
349 } else { | |
350 *value_mask |= CWBackPixel; | |
351 (*values).background_pixel = widget->core.background_pixel; | |
352 } | |
353 if (widget->core.border_pixmap != XtUnspecifiedPixmap) { | |
354 *value_mask |= CWBorderPixmap; | |
355 (*values).border_pixmap = widget->core.border_pixmap; | |
356 } else { | |
357 *value_mask |= CWBorderPixel; | |
358 (*values).border_pixel = widget->core.border_pixel; | |
359 } | |
360 if (widget->core.widget_class->core_class.expose == (XtExposeProc) NULL) { | |
361 /* Try to avoid redisplay upon resize by making bit_gravity the same | |
362 as the default win_gravity */ | |
363 *value_mask |= CWBitGravity; | |
364 (*values).bit_gravity = NorthWestGravity; | |
365 } | |
366 } /* ComputeWindowAttributes */ | |
367 | |
368 static void | |
369 end_connection (ExternalClientWidget w) | |
370 { | |
371 XSetWindowAttributes xswa; | |
372 XtValueMask mask; | |
373 Widget wid = (Widget) w; | |
440 | 374 |
428 | 375 w->externalClient.shell_ready = False; |
376 XtRemoveEventHandler (wid, w->externalClient.event_mask, | |
377 FALSE, MaskableEventHandler, (XtPointer) NULL); | |
378 ComputeWindowAttributes (wid, &mask, &xswa); | |
379 XChangeWindowAttributes (XtDisplay (wid), XtWindow (wid), mask, &xswa); | |
380 XClearArea (XtDisplay (wid), XtWindow (wid), 0, 0, 0, 0, True); | |
381 } | |
382 | |
383 static int | |
384 my_error_handler (Display *display, XErrorEvent *xev) | |
385 { | |
386 Widget wid; | |
440 | 387 |
428 | 388 if (xev->error_code != BadWindow) |
389 goto call_old; | |
390 wid = remove_ww (xev->resourceid); | |
391 if (wid) | |
392 { | |
393 end_connection ((ExternalClientWidget) wid); | |
394 return 0; | |
395 } | |
440 | 396 |
428 | 397 call_old: |
398 return error_old_handler (display, xev); | |
399 } | |
400 | |
401 static void | |
2286 | 402 MaskableEventHandler (Widget wid, XtPointer UNUSED (closure), XEvent *event, |
403 Boolean *UNUSED (continue_to_dispatch)) | |
428 | 404 { |
405 ExternalClientWidget w = (ExternalClientWidget) wid; | |
440 | 406 |
428 | 407 if (w->externalClient.shell_ready) |
408 { | |
409 if (event->type == KeyPress || event->type == KeyRelease || | |
410 event->type == ButtonPress || event->type == ButtonRelease || | |
411 event->type == MotionNotify) | |
412 event->xkey.subwindow = 0; | |
413 #ifdef EXTW_USES_MOTIF | |
414 /* hackkkkkkkkkkkkkk! Suppress CTRL-TAB, SHIFT-TAB, etc. so that | |
415 Emacs doesn't attempt to interpret focus-change keystrokes. */ | |
416 if (event->type == KeyPress && | |
417 XLookupKeysym ((XKeyEvent *) event, 0) == XK_Tab && | |
418 (event->xkey.state & ControlMask || | |
419 event->xkey.state & ShiftMask)) | |
420 return; | |
421 #endif | |
422 event->xany.window = w->core.window; | |
423 XSendEvent (XtDisplay (wid), w->externalClient.event_window, FALSE, 0, | |
424 event); | |
425 XSync (XtDisplay (wid), 0); /* make sure that any BadWindow errors | |
426 (meaning the server died) get handled | |
427 before XSendEvent is called again. */ | |
440 | 428 |
428 | 429 } |
430 } | |
431 | |
432 static void | |
2286 | 433 EventHandler (Widget wid, XtPointer UNUSED (closure), XEvent *event, |
434 Boolean *UNUSED (continue_to_dispatch)) | |
428 | 435 { |
436 ExternalClientWidget w = (ExternalClientWidget) wid; | |
440 | 437 |
428 | 438 if (w->core.window != event->xany.window) |
439 { | |
440 XtAppErrorMsg (XtWidgetToApplicationContext (wid), | |
441 "invalidWindow","eventHandler",XtCXtToolkitError, | |
442 "Event with wrong window", | |
443 (String *)NULL, (Cardinal *)NULL); | |
444 return; | |
445 } | |
440 | 446 |
428 | 447 if (event->type == ClientMessage && |
448 event->xclient.message_type == a_EXTW_NOTIFY && | |
449 event->xclient.data.l[0] == extw_shell_send) | |
450 switch (event->xclient.data.l[1]) | |
451 { | |
440 | 452 |
428 | 453 case extw_notify_qg: |
454 /* shell is alive again. */ | |
440 | 455 |
428 | 456 w->externalClient.dead_shell = False; |
457 break; | |
440 | 458 |
428 | 459 case extw_notify_gm: |
460 { | |
461 XtWidgetGeometry xwg, xwg_return; | |
462 XtGeometryResult result; | |
440 | 463 |
428 | 464 extw_get_geometry_value (XtDisplay (wid), XtWindow (wid), |
465 a_EXTW_GEOMETRY_MANAGER, &xwg); | |
466 result = XtMakeGeometryRequest (wid, &xwg, &xwg_return); | |
440 | 467 |
428 | 468 extw_send_geometry_value (XtDisplay (wid), XtWindow (wid), |
469 a_EXTW_GEOMETRY_MANAGER, extw_notify_gm, | |
470 result == XtGeometryAlmost ? &xwg_return : | |
471 NULL, result); | |
472 break; | |
473 } | |
440 | 474 |
428 | 475 case extw_notify_init: |
476 w->externalClient.shell_ready = True; | |
477 w->externalClient.event_window = event->xclient.data.l[2]; | |
478 w->externalClient.event_mask = event->xclient.data.l[3]; | |
479 add_ww (w->externalClient.event_window, (Widget) w); | |
440 | 480 |
428 | 481 XtAddEventHandler (wid, w->externalClient.event_mask, |
482 FALSE, MaskableEventHandler, (XtPointer) NULL); | |
483 #ifdef EXTW_USES_MOTIF | |
484 NOTIFY (w, extw_notify_init, | |
485 EXTW_TYPE_MOTIF, | |
486 0, 0); | |
487 #else | |
488 NOTIFY (w, extw_notify_init, | |
489 EXTW_TYPE_XT, | |
490 0, 0); | |
491 #endif | |
492 break; | |
440 | 493 |
428 | 494 case extw_notify_end: |
495 end_connection (w); | |
496 remove_ww (w->externalClient.event_window); | |
497 break; | |
440 | 498 |
428 | 499 case extw_notify_set_focus: |
500 #ifdef EXTW_USES_MOTIF | |
501 XmProcessTraversal (wid, XmTRAVERSE_CURRENT); | |
502 #else | |
503 XtSetKeyboardFocus (wid, None); | |
504 #endif | |
505 break; | |
440 | 506 |
428 | 507 } |
508 } | |
509 | |
2108 | 510 static void Destroy (Widget wid) |
428 | 511 { |
512 ExternalClientWidget w = (ExternalClientWidget)wid; | |
440 | 513 |
428 | 514 NOTIFY(w, extw_notify_end, 0, 0, 0); |
515 } | |
516 | |
2108 | 517 static XtGeometryResult |
518 QueryGeometry (Widget gw, XtWidgetGeometry *request, XtWidgetGeometry *reply) | |
428 | 519 { |
2108 | 520 ExternalClientWidget w = (ExternalClientWidget) gw; |
428 | 521 XEvent event; |
522 unsigned long request_num; | |
523 Display *display = XtDisplay(gw); | |
524 XtWidgetGeometry req = *request; /* don't modify caller's structure */ | |
440 | 525 |
428 | 526 if (!XtIsRealized((Widget)w) || !w->externalClient.shell_ready) |
527 return XtGeometryYes; | |
440 | 528 |
428 | 529 if (w->externalClient.dead_shell == TRUE) |
530 /* The shell is sick. */ | |
531 return XtGeometryNo; | |
440 | 532 |
428 | 533 req.sibling = None; |
534 req.request_mode &= ~CWSibling; | |
535 request_num = NextRequest(display); | |
536 extw_send_geometry_value(XtDisplay(gw), XtWindow(gw), a_EXTW_QUERY_GEOMETRY, | |
537 extw_notify_qg, &req, 0); | |
538 | |
539 if (extw_wait_for_response(gw, &event, request_num, extw_notify_qg, | |
540 w->externalClient.shell_timeout)) { | |
541 XtGeometryResult result = (XtGeometryResult) event.xclient.data.l[0]; | |
542 | |
543 if (result == XtGeometryAlmost) { | |
544 extw_get_geometry_value(XtDisplay(gw), XtWindow(gw), | |
545 a_EXTW_QUERY_GEOMETRY, reply); | |
546 } | |
547 return result; | |
548 } else { | |
549 w->externalClient.dead_shell = TRUE; /* timed out; must be broken */ | |
550 return XtGeometryNo; | |
551 } | |
552 } | |
553 | |
2286 | 554 #ifdef EXTW_USES_MOTIF |
555 # define USED_IF_MOTIF(decl) decl | |
556 #else | |
557 # define USED_IF_MOTIF(decl) UNUSED (decl) | |
558 #endif | |
559 | |
560 static void ExternalClientFocusIn (Widget w, XEvent *event, | |
561 String *USED_IF_MOTIF (params), | |
562 Cardinal *USED_IF_MOTIF (num_params)) | |
428 | 563 { |
564 ExternalClientWidget ecw = (ExternalClientWidget) w; | |
440 | 565 |
428 | 566 if (event->xfocus.send_event && !ecw->externalClient.has_focus) { |
567 ecw->externalClient.has_focus = True; | |
568 NOTIFY(ecw, extw_notify_focus_in, 0, 0, 0); | |
569 } | |
570 #ifdef EXTW_USES_MOTIF | |
571 _XmPrimitiveFocusIn (w, event, params, num_params); | |
572 #endif | |
573 } | |
574 | |
2286 | 575 static void ExternalClientFocusOut (Widget w, XEvent *event, |
576 String *USED_IF_MOTIF (params), | |
577 Cardinal *USED_IF_MOTIF (num_params)) | |
428 | 578 { |
579 ExternalClientWidget ecw = (ExternalClientWidget) w; | |
440 | 580 |
428 | 581 if (event->xfocus.send_event && ecw->externalClient.has_focus) { |
582 ecw->externalClient.has_focus = False; | |
583 NOTIFY(ecw, extw_notify_focus_out, 0, 0, 0); | |
584 } | |
585 #ifdef EXTW_USES_MOTIF | |
586 _XmPrimitiveFocusOut(w, event, params, num_params); | |
587 #endif | |
588 } | |
589 | |
2286 | 590 static void ExternalClientEnter (Widget w, XEvent *event, |
591 String *USED_IF_MOTIF (params), | |
592 Cardinal *USED_IF_MOTIF (num_params)) | |
428 | 593 { |
594 ExternalClientWidget ecw = (ExternalClientWidget) w; | |
440 | 595 |
428 | 596 if ( |
597 #ifdef EXTW_USES_MOTIF | |
598 _XmGetFocusPolicy (w) != XmEXPLICIT && | |
599 #endif | |
600 !ecw->externalClient.has_focus && | |
601 event->xcrossing.focus && event->xcrossing.detail != NotifyInferior) { | |
602 ecw->externalClient.has_focus = True; | |
603 NOTIFY(ecw, extw_notify_focus_in, 0, 0, 0); | |
604 } | |
605 #ifdef EXTW_USES_MOTIF | |
606 _XmPrimitiveEnter (w, event, params, num_params); | |
607 #endif | |
608 } | |
609 | |
2286 | 610 static void ExternalClientLeave (Widget w, XEvent *event, |
611 String *USED_IF_MOTIF (params), | |
612 Cardinal *USED_IF_MOTIF (num_params)) | |
428 | 613 { |
614 ExternalClientWidget ecw = (ExternalClientWidget) w; | |
440 | 615 |
428 | 616 if ( |
617 #ifdef EXTW_USES_MOTIF | |
618 _XmGetFocusPolicy (w) != XmEXPLICIT && | |
619 #endif | |
620 ecw->externalClient.has_focus && | |
621 event->xcrossing.focus && event->xcrossing.detail != NotifyInferior) { | |
622 ecw->externalClient.has_focus = False; | |
623 NOTIFY(ecw, extw_notify_focus_out, 0, 0, 0); | |
624 } | |
625 #ifdef EXTW_USES_MOTIF | |
626 _XmPrimitiveLeave (w, event, params, num_params); | |
627 #endif | |
628 } |