Mercurial > hg > xemacs-beta
annotate src/ExternalClient.c @ 5602:c9e5612f5424
Support the MP library on recent FreeBSD, have it pass relevant tests.
src/ChangeLog addition:
2011-11-26 Aidan Kehoe <kehoea@parhasard.net>
* number-mp.c (bignum_to_string):
Don't overwrite the accumulator we've just set up for this
function.
* number-mp.c (BIGNUM_TO_TYPE):
mp_itom() doesn't necessarily do what this code used to think with
negative numbers, it can treat them as unsigned ints. Subtract
numbers from bignum_zero instead of multiplying them by -1 to
convert them to their negative equivalents.
* number-mp.c (bignum_to_int):
* number-mp.c (bignum_to_uint):
* number-mp.c (bignum_to_long):
* number-mp.c (bignum_to_ulong):
* number-mp.c (bignum_to_double):
Use the changed BIGNUM_TO_TYPE() in these functions.
* number-mp.c (bignum_ceil):
* number-mp.c (bignum_floor):
In these functions, be more careful about rounding to positive and
negative infinity, respectively. Don't use the sign of QUOTIENT
when working out out whether to add or subtract one, rather use
the sign QUOTIENT would have if arbitrary-precision division were
done.
* number-mp.h:
* number-mp.h (MP_GCD):
Wrap #include <mp.h> in BEGIN_C_DECLS/END_C_DECLS.
* number.c (Fbigfloat_get_precision):
* number.c (Fbigfloat_set_precision):
Don't attempt to call XBIGFLOAT_GET_PREC if this build doesn't
support big floats.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Sat, 26 Nov 2011 17:59:14 +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 } |