comparison src/ExternalShell.c @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children 966663fcf606
comparison
equal deleted inserted replaced
-1:000000000000 0:376386a54a3c
1 /* External shell widget.
2 Copyright (C) 1993, 1994 Sun Microsystems, Inc.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public
15 License along with this library; if not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
18
19 /* Synched up with: Not in FSF. */
20
21 /* Written by Ben Wing, September 1993. */
22
23 /* This is a special Shell that is designed to use an externally-
24 provided window created by someone else (possibly another process).
25 That other window should have an associated widget of class
26 ExternalClient. The two widgets communicate with each other using
27 ClientMessage events and properties on the external window.
28
29 Ideally this feature should be independent of Emacs. Unfortunately
30 there are lots and lots of specifics that need to be dealt with
31 for this to work properly, and some of them can't conveniently
32 be handled within the widget's methods. Some day the code may
33 be rewritten so that the embedded-widget feature can be used by
34 any application, with appropriate entry points that are called
35 at specific points within the application.
36
37 This feature is similar to the OLE (Object Linking & Embedding)
38 feature provided by MS Windows.
39 */
40
41 #ifdef emacs
42
43 #include <config.h>
44
45 #ifndef EXTERNAL_WIDGET
46 ERROR! This ought not be getting compiled if EXTERNAL_WIDGET is undefined
47 #endif
48
49 #endif /* emacs */
50
51 #include <stdio.h>
52 #include <string.h>
53 #include <X11/StringDefs.h>
54 #include "xintrinsicp.h"
55 #include <X11/Shell.h>
56 #include <X11/ShellP.h>
57 #include <X11/Vendor.h>
58 #include <X11/VendorP.h>
59 #include "ExternalShellP.h"
60 #include "extw-Xt.h"
61
62 #ifdef emacs
63 extern void emacs_Xt_handle_focus_event (XEvent *event);
64 #endif
65
66 /* Communication between this shell and the client widget:
67
68 Communication is through ClientMessage events with message_type
69 EXTW_NOTIFY and format 32. Both the shell and the client widget
70 communicate with each other by sending the message to the same
71 window (the "external window" below), and the data.l[0] value is
72 used to determine who sent the message.
73
74 The data is formatted as follows:
75
76 data.l[0] = who sent this message: external_shell_send (0) or
77 external_client_send (1)
78 data.l[1] = message type (see enum en_extw_notify below)
79 data.l[2-4] = data associated with this message
80
81 EventHandler() handles messages from the other side.
82
83 extw_send_notify_3() sends a message to the other side.
84
85 extw_send_geometry_value() is used when an XtWidgetGeometry structure
86 needs to be sent. This is too much data to fit into a
87 ClientMessage, so the data is stored in a property and then
88 extw_send_notify_3() is called.
89
90 extw_get_geometry_value() receives an XtWidgetGeometry structure from a
91 property.
92
93 extw_wait_for_response() is used when a response to a sent message
94 is expected. It looks for a matching event within a
95 particular timeout.
96
97 The particular message types are as follows:
98
99 1) extw_notify_init (event_window, event_mask)
100
101 This is sent from the shell to the client after the shell realizes
102 its EmacsFrame widget on the client's "external window". This
103 tells the client that it should start passing along events of the
104 types specified in event_mask. event_window specifies the window
105 of the EmacsFrame widget, which is a child of the client's
106 external window.
107
108 extw_notify_init (client_type)
109
110 When the client receives an extw_notify_init message from the
111 shell, it sends back a message of the same sort specifying the type
112 of the toolkit used by the client (Motif, generic Xt, or Xlib).
113
114 2) extw_notify_end ()
115
116 This is sent from the shell to the client when the shell's
117 EmacsFrame widget is destroyed, and tells the client to stop
118 passing events along.
119
120 3) extw_notify_qg (result)
121
122 This is sent from the client to the shell when a QueryGeometry
123 request is received on the client. The XtWidgetGeometry structure
124 specified in the QueryGeometry request is passed on in the
125 EXTW_QUERY_GEOMETRY property (of type EXTW_WIDGET_GEOMETRY) on the
126 external window. result is unused.
127
128 In response, the shell passes the QueryGeometry request down the
129 widget tree, and when a response is received, sends a message of
130 type extw_notify_qg back to the client, with result specifying the
131 GeometryResult value. If this value is XtGeometryAlmost, the
132 returned XtWidgetGeometry structure is stored into the same property
133 as above. [BPW is there a possible race condition here?]
134
135 4) extw_notify_gm (result)
136
137 A very similar procedure to that for extw_notify_qg is followed
138 when the shell's RootGeometryManager method is called, indicating
139 that a child widget wishes to change the shell's geometry. The
140 XtWidgetGeometry structure is stored in the EXTW_GEOMETRY_MANAGER
141 property.
142
143 5) extw_notify_focus_in (), extw_notify_focus_out ()
144
145 These are sent from the client to the shell when the client gains
146 or loses the keyboard focus. It is done this way because Xt
147 maintains its own concept of keyboard focus and only the client
148 knows this information.
149 */
150
151 #define NOTIFY(w, type, l0, l1, l2) \
152 extw_send_notify_3(XtDisplay((Widget)(w)),\
153 (w)->externalShell.external_window, type, l0, l1, l2)
154
155 static void ExternalShellInitialize (Widget req, Widget new, ArgList args,
156 Cardinal *num_args);
157 static void ExternalShellRealize (Widget wid, Mask *vmask, XSetWindowAttributes
158 *attr);
159 static void ExternalShellDestroy (Widget w);
160 static void ChangeManaged (Widget wid);
161 static XtGeometryResult ExternalShellRootGeometryManager (Widget gw,
162 XtWidgetGeometry *request, XtWidgetGeometry *reply);
163 static void EventHandler (Widget wid, XtPointer closure, XEvent *event,
164 Boolean *continue_to_dispatch);
165
166 #ifndef DEFAULT_WM_TIMEOUT
167 # define DEFAULT_WM_TIMEOUT 5000
168 #endif
169
170 void ExternalShellUnrealize (Widget w);
171
172 static XtResource resources[] = {
173 #define offset(field) XtOffset(ExternalShellWidget, externalShell.field)
174 { XtNwindow, XtCWindow, XtRWindow, sizeof (Window),
175 offset (external_window), XtRImmediate, (XtPointer)0},
176 { XtNclientTimeout, XtCClientTimeout, XtRInt, sizeof(int),
177 offset(client_timeout), XtRImmediate,(XtPointer)DEFAULT_WM_TIMEOUT},
178 { XtNdeadClient, XtCDeadClient, XtRBoolean, sizeof(Boolean),
179 offset(dead_client), XtRImmediate, (XtPointer)False},
180 };
181
182 static CompositeClassExtensionRec compositeClassExtRec = {
183 NULL,
184 NULLQUARK,
185 XtCompositeExtensionVersion,
186 sizeof(CompositeClassExtensionRec),
187 TRUE,
188 };
189
190 static ShellClassExtensionRec shellClassExtRec = {
191 NULL,
192 NULLQUARK,
193 XtShellExtensionVersion,
194 sizeof(ShellClassExtensionRec),
195 ExternalShellRootGeometryManager
196 };
197
198 ExternalShellClassRec externalShellClassRec = {
199 { /*
200 * core_class fields
201 */
202 /* superclass */ (WidgetClass) &shellClassRec,
203 /* class_name */ "ExternalShell",
204 /* size */ sizeof(ExternalShellRec),
205 /* Class Initializer */ NULL,
206 /* class_part_initialize*/ NULL, /* XtInheritClassPartInitialize, */
207 /* Class init'ed ? */ FALSE,
208 /* initialize */ ExternalShellInitialize,
209 /* initialize_notify */ NULL,
210 /* realize */ ExternalShellRealize,
211 /* actions */ NULL,
212 /* num_actions */ 0,
213 /* resources */ resources,
214 /* resource_count */ XtNumber (resources),
215 /* xrm_class */ NULLQUARK,
216 /* compress_motion */ FALSE,
217 /* compress_exposure */ TRUE,
218 /* compress_enterleave*/ FALSE,
219 /* visible_interest */ TRUE,
220 /* destroy */ ExternalShellDestroy, /* XtInheritDestroy, */
221 /* resize */ XtInheritResize,
222 /* expose */ NULL,
223 /* set_values */ NULL, /* XtInheritSetValues, */
224 /* set_values_hook */ NULL,
225 /* set_values_almost */ XtInheritSetValuesAlmost,
226 /* get_values_hook */ NULL,
227 /* accept_focus */ NULL,
228 /* intrinsics version */ XtVersion,
229 /* callback offsets */ NULL,
230 /* tm_table */ NULL,
231 /* query_geometry */ NULL,
232 /* display_accelerator*/ NULL,
233 /* extension */ NULL
234 },{ /* Composite */
235 /* geometry_manager */ XtInheritGeometryManager,
236 /* change_managed */ ChangeManaged, /* XtInheritChangeManaged */
237 /* insert_child */ XtInheritInsertChild,
238 /* delete_child */ XtInheritDeleteChild,
239 /* extension */ (XtPointer)&compositeClassExtRec
240 },{ /* Shell */
241 /* extension */ (XtPointer)&shellClassExtRec
242 },{ /* ExternalShell */
243 0
244 }
245 };
246
247 WidgetClass externalShellWidgetClass = (WidgetClass) &externalShellClassRec;
248
249 static void
250 ExternalShellInitialize (Widget req, Widget new, ArgList args,
251 Cardinal *num_args)
252 {
253 XtAddEventHandler(new, 0,
254 TRUE, EventHandler, (XtPointer) NULL);
255 extw_initialize_atoms(XtDisplay(req));
256 extw_which_side = extw_shell_send;
257 }
258
259 static Widget
260 find_managed_child (CompositeWidget w)
261 {
262 int i;
263 Widget *childP = w->composite.children;
264
265 for (i = w->composite.num_children; i; i--, childP++)
266 if (XtIsWidget(*childP) && XtIsManaged(*childP))
267 return *childP;
268 return NULL;
269 }
270
271 #ifndef XtCXtToolkitError
272 # define XtCXtToolkitError "XtToolkitError"
273 #endif
274
275 static void EventHandler(wid, closure, event, continue_to_dispatch)
276 Widget wid;
277 XtPointer closure; /* unused */
278 XEvent *event;
279 Boolean *continue_to_dispatch; /* unused */
280 {
281 ExternalShellWidget w = (ExternalShellWidget) wid;
282
283 if(w->core.window != event->xany.window) {
284 XtAppErrorMsg(XtWidgetToApplicationContext(wid),
285 "invalidWindow","eventHandler",XtCXtToolkitError,
286 "Event with wrong window",
287 (String *)NULL, (Cardinal *)NULL);
288 return;
289 }
290
291 if (event->type == ClientMessage &&
292 event->xclient.data.l[0] == extw_client_send &&
293 event->xclient.message_type == a_EXTW_NOTIFY)
294 switch (event->xclient.data.l[1]) {
295
296 case extw_notify_gm:
297 /* client is alive again. */
298 w->externalShell.dead_client = False;
299 break;
300
301 case extw_notify_qg: {
302 XtWidgetGeometry xwg, xwg_return;
303 XtGeometryResult result;
304 Widget child = find_managed_child((CompositeWidget) w);
305
306 if (child) {
307 extw_get_geometry_value(XtDisplay(wid), XtWindow(wid),
308 a_EXTW_QUERY_GEOMETRY, &xwg);
309 result = XtQueryGeometry(child, &xwg, &xwg_return);
310 } else
311 result = XtGeometryYes;
312
313 extw_send_geometry_value(XtDisplay(wid), XtWindow(wid),
314 a_EXTW_QUERY_GEOMETRY, extw_notify_qg,
315 result == XtGeometryAlmost ? &xwg_return :
316 NULL, result);
317 break;
318 }
319
320 case extw_notify_focus_in: {
321 XFocusChangeEvent evnt;
322
323 evnt.type = FocusIn;
324 evnt.serial = LastKnownRequestProcessed (XtDisplay (wid));
325 evnt.send_event = True;
326 evnt.display = XtDisplay (wid);
327 evnt.window = XtWindow (wid);
328 evnt.mode = NotifyNormal;
329 evnt.detail = NotifyAncestor;
330 #ifdef emacs
331 emacs_Xt_handle_focus_event ((XEvent *) &evnt);
332 #else
333 XtDispatchEvent ((XEvent *) &evnt);
334 #endif
335 break;
336 }
337
338 case extw_notify_focus_out: {
339 XFocusChangeEvent evnt;
340
341 evnt.type = FocusOut;
342 evnt.serial = LastKnownRequestProcessed (XtDisplay (wid));
343 evnt.send_event = True;
344 evnt.display = XtDisplay (wid);
345 evnt.window = XtWindow (wid);
346 evnt.mode = NotifyNormal;
347 evnt.detail = NotifyAncestor;
348 #ifdef emacs
349 emacs_Xt_handle_focus_event ((XEvent *) &evnt);
350 #else
351 XtDispatchEvent ((XEvent *) &evnt);
352 #endif
353 break;
354 }
355
356 case extw_notify_end:
357 /* frame should be destroyed. */
358 break;
359 }
360 }
361
362 /* Lifted almost entirely from GetGeometry() in Shell.c
363 */
364 static void
365 GetGeometry (Widget W, Widget child)
366 {
367 ExternalShellWidget w = (ExternalShellWidget)W;
368 int x, y, win_gravity = -1, flag;
369 XSizeHints hints;
370 Window win = w->externalShell.external_window;
371
372 {
373 Window dummy_root;
374 unsigned int dummy_bd_width, dummy_depth, width, height;
375
376 /* determine the existing size of the window. */
377 XGetGeometry(XtDisplay(W), win, &dummy_root, &x, &y, &width,
378 &height, &dummy_bd_width, &dummy_depth);
379 w->core.width = width;
380 w->core.height = height;
381 }
382
383 if(w->shell.geometry != NULL) {
384 char def_geom[64];
385 int width, height;
386
387 x = w->core.x;
388 y = w->core.y;
389 width = w->core.width;
390 height = w->core.height;
391 hints.flags = 0;
392
393 sprintf( def_geom, "%dx%d+%d+%d", width, height, x, y );
394 flag = XWMGeometry( XtDisplay(W),
395 XScreenNumberOfScreen(XtScreen(W)),
396 w->shell.geometry, def_geom,
397 (unsigned int)w->core.border_width,
398 &hints, &x, &y, &width, &height,
399 &win_gravity
400 );
401 if (flag) {
402 if (flag & XValue) w->core.x = (Position)x;
403 if (flag & YValue) w->core.y = (Position)y;
404 if (flag & WidthValue) w->core.width = (Dimension)width;
405 if (flag & HeightValue) w->core.height = (Dimension)height;
406 }
407 else {
408 String params[2];
409 Cardinal num_params = 2;
410 params[0] = XtName(W);
411 params[1] = w->shell.geometry;
412 XtAppWarningMsg(XtWidgetToApplicationContext(W),
413 "badGeometry", "shellRealize", XtCXtToolkitError,
414 "Shell widget \"%s\" has an invalid geometry specification: \"%s\"",
415 params, &num_params);
416 }
417 }
418 else
419 flag = 0;
420
421 w->shell.client_specified |= _XtShellGeometryParsed;
422 }
423
424 /* Lifted almost entirely from Realize() in Shell.c
425 */
426 static void ExternalShellRealize (Widget wid, Mask *vmask,
427 XSetWindowAttributes *attr)
428 {
429 ExternalShellWidget w = (ExternalShellWidget) wid;
430 Mask mask = *vmask;
431 Window win = w->externalShell.external_window;
432
433 if (!win) {
434 Cardinal count = 1;
435 XtErrorMsg("invalidWindow","shellRealize", XtCXtToolkitError,
436 "No external window specified for ExternalShell widget %s",
437 &wid->core.name, &count);
438 }
439
440 if (! (w->shell.client_specified & _XtShellGeometryParsed)) {
441 /* we'll get here only if there was no child the first
442 time we were realized. If the shell was Unrealized
443 and then re-Realized, we probably don't want to
444 re-evaluate the defaults anyway.
445 */
446 GetGeometry(wid, (Widget)NULL);
447 }
448 else if (w->core.background_pixmap == XtUnspecifiedPixmap) {
449 /* I attempt to inherit my child's background to avoid screen flash
450 * if there is latency between when I get resized and when my child
451 * is resized. Background=None is not satisfactory, as I want the
452 * user to get immediate feedback on the new dimensions (most
453 * particularly in the case of a non-reparenting wm). It is
454 * especially important to have the server clear any old cruft
455 * from the display when I am resized larger.
456 */
457 Widget *childP = w->composite.children;
458 int i;
459 for (i = w->composite.num_children; i; i--, childP++) {
460 if (XtIsWidget(*childP) && XtIsManaged(*childP)) {
461 if ((*childP)->core.background_pixmap
462 != XtUnspecifiedPixmap) {
463 mask &= ~(CWBackPixel);
464 mask |= CWBackPixmap;
465 attr->background_pixmap =
466 w->core.background_pixmap =
467 (*childP)->core.background_pixmap;
468 } else {
469 attr->background_pixel =
470 w->core.background_pixel =
471 (*childP)->core.background_pixel;
472 }
473 break;
474 }
475 }
476 }
477
478 if(w->shell.save_under) {
479 mask |= CWSaveUnder;
480 attr->save_under = TRUE;
481 }
482 if(w->shell.override_redirect) {
483 mask |= CWOverrideRedirect;
484 attr->override_redirect = TRUE;
485 }
486 if (wid->core.width == 0 || wid->core.height == 0) {
487 Cardinal count = 1;
488 XtErrorMsg("invalidDimension", "shellRealize", XtCXtToolkitError,
489 "Shell widget %s has zero width and/or height",
490 &wid->core.name, &count);
491 }
492 wid->core.window = win;
493 XChangeWindowAttributes(XtDisplay(wid), wid->core.window,
494 mask, attr);
495
496 }
497
498 static void ExternalShellDestroy(wid)
499 Widget wid;
500 {
501 ExternalShellWidget w = (ExternalShellWidget)wid;
502
503 if (XtIsRealized(wid))
504 ExternalShellUnrealize(wid);
505
506 NOTIFY(w, extw_notify_end, 0, 0, 0);
507 }
508
509 /* Invoke matching routine from superclass, but first override its
510 geometry opinions with our own routine */
511
512 static void ChangeManaged(wid)
513 Widget wid;
514 {
515 if (!XtIsRealized (wid))
516 GetGeometry(wid, (Widget)NULL);
517 (*((ShellClassRec*)externalShellClassRec.core_class.superclass)->
518 composite_class.change_managed)(wid);
519 }
520
521 /* Based on RootGeometryManager() in Shell.c */
522
523 static XtGeometryResult ExternalShellRootGeometryManager(gw, request, reply)
524 Widget gw;
525 XtWidgetGeometry *request, *reply;
526 {
527 ExternalShellWidget w = (ExternalShellWidget)gw;
528 unsigned int mask = request->request_mode;
529 XEvent event;
530 int oldx, oldy, oldwidth, oldheight, oldborder_width;
531 unsigned long request_num;
532 XtWidgetGeometry req = *request; /* don't modify caller's structure */
533
534 oldx = w->core.x;
535 oldy = w->core.y;
536 oldwidth = w->core.width;
537 oldheight = w->core.height;
538 oldborder_width = w->core.border_width;
539
540 #define PutBackGeometry() \
541 { w->core.x = oldx; \
542 w->core.y = oldy; \
543 w->core.width = oldwidth; \
544 w->core.height = oldheight; \
545 w->core.border_width = oldborder_width; }
546
547 if (mask & CWX) {
548 if (w->core.x == request->x) mask &= ~CWX;
549 else
550 w->core.x = request->x;
551 }
552 if (mask & CWY) {
553 if (w->core.y == request->y) mask &= ~CWY;
554 else w->core.y = request->y;
555 }
556 if (mask & CWBorderWidth) {
557 if (w->core.border_width == request->border_width)
558 mask &= ~CWBorderWidth;
559 else w->core.border_width = request->border_width;
560 }
561 if (mask & CWWidth) {
562 if (w->core.width == request->width) mask &= ~CWWidth;
563 else w->core.width = request->width;
564 }
565 if (mask & CWHeight) {
566 if (w->core.height == request->height) mask &= ~CWHeight;
567 else w->core.height = request->height;
568 }
569
570 if (!XtIsRealized((Widget)w)) return XtGeometryYes;
571
572 req.sibling = None;
573 req.request_mode = mask & ~CWSibling;
574 request_num = NextRequest(XtDisplay(w));
575 extw_send_geometry_value(XtDisplay(w), XtWindow(w),
576 a_EXTW_GEOMETRY_MANAGER,
577 extw_notify_gm, &req, 0);
578
579 if (w->externalShell.dead_client == TRUE) {
580 /* The client is sick. Refuse the request.
581 * If the client recovers and decides to honor the
582 * request, it will be handled by Shell's EventHandler().
583 */
584 PutBackGeometry();
585 return XtGeometryNo;
586 }
587
588 if (extw_wait_for_response(gw, &event, request_num, extw_notify_gm,
589 w->externalShell.client_timeout)) {
590 XtGeometryResult result = (XtGeometryResult) event.xclient.data.l[2];
591
592 if (result != XtGeometryYes)
593 PutBackGeometry();
594 if (result == XtGeometryAlmost) {
595 extw_get_geometry_value(XtDisplay(w), XtWindow(w),
596 a_EXTW_GEOMETRY_MANAGER, reply);
597 }
598 return result;
599 } else {
600 w->externalShell.dead_client = TRUE; /* timed out; must be broken */
601 PutBackGeometry();
602 return XtGeometryNo;
603 }
604 #undef PutBackGeometry
605 }
606
607 static void
608 hack_event_masks_1 (Display *display, Window w, int this_window_propagate)
609 {
610 Window root, parent, *children;
611 unsigned int nchildren;
612 int i;
613
614 if (!XQueryTree (display, w, &root, &parent, &children, &nchildren))
615 return;
616 for (i=0; i<nchildren; i++)
617 hack_event_masks_1 (display, children[i], 1);
618 if (children)
619 XFree (children);
620 {
621 XWindowAttributes xwa;
622 XSetWindowAttributes xswa;
623 if (XGetWindowAttributes (display, w, &xwa)) {
624 xswa.event_mask = xwa.your_event_mask & ~KeyPressMask;
625 if (this_window_propagate)
626 xswa.do_not_propagate_mask = xwa.do_not_propagate_mask & ~KeyPressMask;
627 XChangeWindowAttributes (display, w, CWEventMask, &xswa);
628 }
629 }
630 }
631
632 /* fix all event masks on all subwindows of the specified window so that
633 all key presses in any subwindow filter up to the specified window.
634
635 We have to do this cruftiness with external widgets so that we don't
636 step on Motif's concept of keyboard focus. (Due to the nature of
637 Xt and Motif, X's idea of who gets the keyboard events may not jive
638 with Xt's idea of same, and Xt redirects the events to the proper
639 window. This occurs on the client side and we have no knowledge
640 of it, so we have to rely on a SendEvent from the client side to
641 receive our keyboard events.)
642 */
643
644 static void
645 hack_event_masks (Display *display, Window w)
646 {
647 hack_event_masks_1 (display, w, 0);
648 }
649
650 /* external entry points */
651
652 Bool
653 ExternalShellReady (Widget w, Window win, long event_mask)
654 {
655 ExternalShellWidget ew = (ExternalShellWidget) w;
656 XEvent event;
657 unsigned long request_num;
658
659 request_num = NextRequest(XtDisplay(w));
660 NOTIFY(ew, extw_notify_init, (long) win, event_mask, 0);
661 if (extw_wait_for_response(w, &event, request_num, extw_notify_init,
662 ew->externalShell.client_timeout))
663 {
664 /* Xt/Xm extw's have more elaborate focus needs than mere
665 Xlib ones.
666
667 Rather independently, they *don't* need the
668 ConfigureNotify event, having fixed up the window size in
669 ChangeManaged, above, but Xlib extw's do need this.
670 */
671 ew->externalShell.client_type = event.xclient.data.l[2];
672 if (ew->externalShell.client_type != EXTW_TYPE_XLIB)
673 {
674 hack_event_masks (XtDisplay (w), XtWindow (w));
675 }
676 else
677 {
678 XConfigureEvent ev;
679 XWindowAttributes xwa;
680 ev.type = ConfigureNotify;
681 ev.display = XtDisplay (w);
682 ev.event = ev.window = XtWindow (w);
683 XGetWindowAttributes (ev.display, ev.window, &xwa);
684 ev.x = xwa.x; ev.y = xwa.y;
685 ev.width = xwa.width; ev.height = xwa.height;
686 ev.border_width = xwa.border_width;
687 ev.above = None;
688 ev.override_redirect = xwa.override_redirect;
689 XtDispatchEvent ((XEvent *) &ev);
690 }
691 return TRUE;
692 }
693 else
694 return FALSE;
695 }
696
697 void
698 ExternalShellSetFocus (Widget wid)
699 {
700 ExternalShellWidget w = (ExternalShellWidget) wid;
701
702 NOTIFY(w, extw_notify_set_focus, 0, 0, 0);
703 }
704
705 extern void _XtUnregisterWindow (Window, Widget);
706
707 void
708 ExternalShellUnrealize (Widget w)
709 {
710 #if (XT_REVISION > 5)
711 XtUnregisterDrawable (XtDisplay (w), w->core.window);
712 #else
713 extern void _XtUnregisterWindow (Window, Widget);
714 _XtUnregisterWindow (w->core.window, w);
715 #endif
716 w->core.window = 0;
717 }