XEmacs 21.2.29 "Hestia".
[chise/xemacs-chise.git.1] / src / extw-Xt.c
1 /* Common code between client and shell widgets -- Xt only.
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 #ifdef emacs
24
25 #include <config.h>
26
27 #ifndef EXTERNAL_WIDGET
28 ERROR!  This ought not be getting compiled if EXTERNAL_WIDGET is undefined
29 #endif
30
31 void fatal (const char *fmt, ...);
32 #else /* not emacs */
33 static void fatal (char *msg);
34 #endif
35
36 #include <X11/Intrinsic.h>
37 #include <X11/IntrinsicP.h>
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include "extw-Xt.h"
41
42 /* Yeah, that's portable!
43
44    Why the hell didn't the Xt people just export this function
45    for real? */
46
47 #if (XT_REVISION > 5)
48 int _XtWaitForSomething(
49     XtAppContext app,
50     _XtBoolean ignoreEvents,
51     _XtBoolean ignoreTimers,
52     _XtBoolean ignoreInputs,
53     _XtBoolean ignoreSignals,
54     _XtBoolean block,
55 #ifdef XTHREADS
56     _XtBoolean drop_lock,
57 #endif
58     unsigned long *howlong);
59
60 # ifndef XTHREADS
61 #  define _XtwaitForSomething(timers,inputs,events,block,howlong,appCtx) \
62           _XtWaitForSomething(appCtx,events,timers,inputs,0,block,howlong)
63 # else
64 #  define _XtwaitForSomething(timers,inputs,events,block,howlong,appCtx) \
65           _XtWaitForSomething(appCtx,events,timers,inputs,0,block,1,howlong)
66 # endif
67 #else
68 int _XtwaitForSomething(
69         Boolean ignoreTimers,
70         Boolean ignoreInputs,
71         Boolean ignoreEvents,
72         Boolean block,
73         unsigned long *howlong,
74         XtAppContext app
75         );
76 #endif
77
78 #ifdef DEBUG_WIDGET
79
80 static int geom_masks[] = {
81   CWX, CWY, CWWidth, CWHeight, CWBorderWidth, CWSibling, CWStackMode,
82   XtCWQueryOnly };
83 static char *geom_mask_strings[] = {
84   "CWX", "CWY", "CWWidth", "CWHeight", "CWBorderWidth",
85   "CWSibling", "CWStackMode", "XtCWQueryOnly" };
86 static int stack_modes[] = {
87   Below, TopIf, BottomIf, Opposite, XtSMDontChange };
88 static char *stack_mode_strings[] = {
89   "Below", "TopIf", "BottomIf", "Opposite", "XtSMDontChange" };
90
91 static void
92 print_geometry_structure(XtWidgetGeometry *xwg)
93 {
94   int num = sizeof(geom_masks)/sizeof(int);
95   int i;
96   
97   printf ("  masks:");
98   for (i=0; i<num; i++)
99     if (xwg->request_mode & geom_masks[i])
100       printf (" %s", geom_mask_strings[i]);
101   printf ("\n");
102   printf ("  x:%d y:%d\n", xwg->x, xwg->y);
103   printf ("  width:%d height:%d border_width:%d\n", xwg->width,
104           xwg->height, xwg->border_width);
105   printf ("  sibling: %x\n", xwg->sibling);
106   printf ("  stack_mode: ");
107   for (i=0, num=sizeof(stack_modes)/sizeof(int); i<num; i++)
108     if (xwg->stack_mode == stack_modes[i]) {
109       printf ("%s", stack_mode_strings[i]);
110       break;
111     }
112   printf ("\n");
113 }
114
115 static void
116 print_geometry_result (XtGeometryResult res)
117 {
118   printf ("result: %s\n",
119           res == XtGeometryYes ? "XtGeometryYes" :
120           res == XtGeometryNo ? "XtGeometryNo" :
121           res == XtGeometryAlmost ? "XtGeometryAlmost" :
122           res == XtGeometryDone ? "XtGeometryDone" :
123           "unknown");
124 }
125
126 #endif
127
128 #ifndef emacs
129
130 static void
131 fatal (char *msg)
132 {
133   fprintf (stderr, "%s", msg);
134   exit (1);
135 }
136
137 #endif
138
139 /* put a geometry specification in the specified property on the window
140    of the specified widget, and send a notification message to tell the
141    client-side widget about this. */
142
143 void
144 extw_send_geometry_value(Display *display, Window win, Atom property,
145                          en_extw_notify type, XtWidgetGeometry *xwg,
146                          long data0)
147 {
148   if (xwg != NULL)
149     XChangeProperty(display, win, property,
150                     a_EXTW_WIDGET_GEOMETRY, 32, PropModeReplace,
151                     (unsigned char *) xwg, sizeof(*xwg)/sizeof(int));
152   extw_send_notify_3(display, win, type, data0, 0, 0);
153 }
154
155 /* get the geometry specification stored in the specified property of the
156    specified widget's window. */
157
158 void
159 extw_get_geometry_value(Display *display, Window win, Atom property,
160                         XtWidgetGeometry *xwg)
161 {
162   Atom dummy;
163   int format;
164   unsigned long nitems, bytes_after;
165   unsigned char *prop;
166   
167   if (XGetWindowProperty(display, win, property, 0,
168                          sizeof(*xwg)/4, False, a_EXTW_WIDGET_GEOMETRY,
169                          &dummy, &format, &nitems, &bytes_after,
170                          &prop) != Success)
171     goto error;
172   if (format != 8*sizeof(int) || bytes_after) {
173     XFree((char *) prop);
174     goto error;
175   }
176   *xwg = * (XtWidgetGeometry *) prop;
177   return;
178
179  error:
180   fatal("Unable to retrieve property for widget-geometry");
181 #if 0
182   XtAppErrorMsg(XtWidgetToApplicationContext((Widget)w),
183                 "invalidProperty","get_geometry_value",XtCXtToolkitError,
184                 "Unable to retrieve property for widget-geometry",
185                 (String *)NULL, (Cardinal *)NULL);
186 #endif
187 }
188
189 typedef struct {
190         Widget w;
191         unsigned long request_num;
192         en_extw_notify type;
193 } QueryStruct;
194
195 /* check if an event is of the sort we're looking for */
196
197 static Bool
198 isMine(Display *dpy, XEvent *event, char *arg)
199 {
200         QueryStruct *q = (QueryStruct *) arg;
201         Widget w = q->w;
202         
203         if ( (dpy != XtDisplay(w)) || (event->xany.window != XtWindow(w)) ) {
204             return FALSE;
205         }
206         if (event->xany.serial >= q->request_num) {
207           if (event->type == ClientMessage &&
208               event->xclient.message_type == a_EXTW_NOTIFY &&
209               event->xclient.data.l[0] == 1 - extw_which_side &&
210               event->xclient.data.l[1] == q->type)
211             return TRUE;
212         }
213         return FALSE;
214 }
215
216 /* wait for a ClientMessage of the specified type from the other widget, or
217    time-out.  isMine() determines whether an event matches.  Culled from
218    Shell.c. */
219
220 Bool
221 extw_wait_for_response(Widget w, XEvent *event, unsigned long request_num,
222                        en_extw_notify type, unsigned long timeout)
223 {
224         XtAppContext app = XtWidgetToApplicationContext(w);
225         QueryStruct q;
226
227         XFlush(XtDisplay(w));
228         q.w = w;
229         q.request_num = request_num;
230         q.type = type;
231         
232         for(;;) {
233             /*
234              * look for match event
235              */
236             if (XCheckIfEvent( XtDisplay(w), event, isMine, (char*)&q))
237                 return TRUE;
238             if (_XtwaitForSomething(TRUE, TRUE, FALSE, TRUE, &timeout, app)
239                 != -1) continue;
240             if (timeout == 0)
241                 return FALSE;
242         }
243 }