1 /* $XConsortium: Xm.c /main/6 1995/10/25 20:28:03 cde-sun $ */
2 /*
3 * Motif
4 *
5 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
6 *
7 * These libraries and programs are free software; you can
8 * redistribute them and/or modify them under the terms of the GNU
9 * Lesser General Public License as published by the Free Software
10 * Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * These libraries and programs are distributed in the hope that
14 * they will be useful, but WITHOUT ANY WARRANTY; without even the
15 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU Lesser General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with these librararies and programs; if not, write
21 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
22 * Floor, Boston, MA 02110-1301 USA
23 */
24 /*
25 * HISTORY
26 */
27
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31
32
33 #include "XmI.h"
34 #include "MessagesI.h"
35 #include <Xm/PrimitiveP.h>
36 #include <Xm/ManagerP.h>
37 #include <Xm/GadgetP.h>
38 #include <Xm/IconGP.h>
39 #include <Xm/LabelGP.h>
40 #ifdef FIX_345
41 #include <X11/keysym.h>
42 #endif
43
44
45 /**************************************************************************
46 * This is Xm.c
47 * It contains global API that:
48 * - it's not widget specific
49 * - it's already used by various widgets (you don't get useless
50 * code by linking with this module: all the functions
51 * are useful and used.
52 * For example, TrackingLocate or ResolvePartOffset do not belong
53 * here because they are not used by everybody.
54 *************************************************************************/
55
56 #ifdef FIX_345
57 Boolean _init_modifiers = TRUE;
58 unsigned int NumLockMask = 0;
59 unsigned int ScrollLockMask = 0;
60
61
62 /*************************************<->*************************************
63 *
64 * _XmInitModifiers (void)
65 *
66 * Description:
67 * -----------
68 * Sets the appropriate mask for NumLock and ScrollLock
69 *
70 *
71 * Inputs:
72 * ------
73 * None
74 *
75 * Outputs:
76 * -------
77 * None
78 *
79 * Procedures Called
80 * -----------------
81 * None
82 *
83 *************************************<->***********************************/
84 void
_XmInitModifiers(void)85 _XmInitModifiers (void)
86 {
87 XModifierKeymap *modmap;
88 Display *dpy;
89 KeySym *keymap;
90 unsigned int keycode;
91 int min_keycode;
92 int max_keycode;
93 int keysyms_per_keycode;
94 int i;
95
96 dpy = _XmGetDefaultDisplay();
97 NumLockMask = 0;
98 ScrollLockMask = 0;
99 keysyms_per_keycode = 0;
100 min_keycode = 0;
101 max_keycode = 0;
102
103 XDisplayKeycodes (dpy, &min_keycode, &max_keycode);
104 modmap = XGetModifierMapping (dpy);
105 keymap = XGetKeyboardMapping (dpy, min_keycode, max_keycode - min_keycode + 1, &keysyms_per_keycode);
106
107 if (modmap && keymap) {
108 for (i = 3 * modmap->max_keypermod; i < 8 * modmap->max_keypermod; i++) {
109 keycode = modmap->modifiermap[i];
110 if ((keycode >= min_keycode) && (keycode <= max_keycode)) {
111 int j;
112 KeySym *syms = keymap + (keycode - min_keycode) * keysyms_per_keycode;
113
114 for (j = 0; j < keysyms_per_keycode; j++)
115 if (!NumLockMask && (syms[j] == XK_Num_Lock))
116 NumLockMask = (1 << (i / modmap->max_keypermod));
117 else if (!ScrollLockMask && (syms[j] == XK_Scroll_Lock))
118 ScrollLockMask = (1 << (i / modmap->max_keypermod));
119 }
120 }
121 }
122
123 /* Cleanup memory */
124 if (modmap)
125 XFreeModifiermap (modmap);
126
127 if (keymap)
128 XFree (keymap);
129 }
130 #endif
131
132
133 /**************************************************************************
134 * *
135 * _XmSocorro - Help dispatch function. Start at the widget help was *
136 * invoked on, find the first non-null help callback list, and call it. *
137 * -- Called by various widgets across Xm *
138 * *
139 *************************************************************************/
140 /* ARGSUSED */
141 void
_XmSocorro(Widget w,XEvent * event,String * params,Cardinal * num_params)142 _XmSocorro(
143 Widget w,
144 XEvent *event,
145 String *params, /* unused */
146 Cardinal *num_params ) /* unused */
147 {
148 XmAnyCallbackStruct cb;
149
150 if (w == NULL) return;
151
152 cb.reason = XmCR_HELP;
153 cb.event = event;
154
155 do {
156 if ((XtHasCallbacks(w, XmNhelpCallback) == XtCallbackHasSome))
157 {
158 XtCallCallbacks (w, XmNhelpCallback, &cb);
159 return;
160 }
161 else
162 w = XtParent(w);
163 }
164 while (w != NULL);
165 }
166
167
168 /****************************************************************
169 *
170 * _XmParentProcess
171 * This is the entry point for parent processing.
172 * -- Called by various widgets across Xm
173 *
174 ****************************************************************/
175 Boolean
_XmParentProcess(Widget widget,XmParentProcessData data)176 _XmParentProcess(
177 Widget widget,
178 XmParentProcessData data )
179 {
180 XmManagerWidgetClass manClass ;
181
182 manClass = (XmManagerWidgetClass) widget->core.widget_class ;
183
184 if( XmIsManager( widget)
185 && manClass->manager_class.parent_process ) {
186 return( (*manClass->manager_class.parent_process)( widget, data)) ;
187 }
188
189 return( FALSE) ;
190 }
191
192
193
194 /************************************************************************
195 *
196 * _XmDestroyParentCallback
197 * Destroy parent. Used by various dialog subclasses
198 *
199 ************************************************************************/
200 /* ARGSUSED */
201 void
_XmDestroyParentCallback(Widget w,XtPointer client_data,XtPointer call_data)202 _XmDestroyParentCallback(
203 Widget w,
204 XtPointer client_data, /* unused */
205 XtPointer call_data ) /* unused */
206 {
207 XtDestroyWidget (XtParent (w));
208 }
209
210
211
212 /************************************************************************
213 *
214 * _XmClearShadowType
215 * Clear the right and bottom border area and save
216 * the old width, height and shadow type.
217 * Used by various subclasses for resize larger situation, where the
218 * inside shadow is not exposed.
219 * Maybe that should be moved in Draw.c, maybe not, since it's a widget API
220 *
221 ************************************************************************/
222 void
_XmClearShadowType(Widget w,int old_width,int old_height,int old_shadow_thickness,int old_highlight_thickness)223 _XmClearShadowType(
224 Widget w,
225 #if NeedWidePrototypes
226 int old_width,
227 int old_height,
228 int old_shadow_thickness,
229 int old_highlight_thickness )
230 #else
231 Dimension old_width,
232 Dimension old_height,
233 Dimension old_shadow_thickness,
234 Dimension old_highlight_thickness )
235 #endif /* NeedWidePrototypes */
236 {
237
238 if (old_shadow_thickness == 0) return;
239
240 if (XtIsRealized(w)) {
241 if (old_width <= w->core.width)
242 XClearArea (XtDisplay (w), XtWindow (w),
243 old_width - old_shadow_thickness -
244 old_highlight_thickness, 0,
245 old_shadow_thickness, old_height -
246 old_highlight_thickness,
247 False);
248
249 if (old_height <= w->core.height)
250 XClearArea (XtDisplay (w), XtWindow (w),
251 0, old_height - old_shadow_thickness -
252 old_highlight_thickness,
253 old_width - old_highlight_thickness,
254 old_shadow_thickness,
255 False);
256 }
257 }
258
259
260
261 /**********************************************************************
262 *
263 * _XmReOrderResourceList
264 * This procedure moves the given resource right after the
265 * insert_after name in this class resource list.
266 * (+ insert_after NULL means insert in front)
267 *
268 * ----Replace by a call to an Xt function in R6.-----
269 **********************************************************************/
270 void
_XmReOrderResourceList(WidgetClass widget_class,String res_name,String insert_after)271 _XmReOrderResourceList(
272 WidgetClass widget_class,
273 String res_name,
274 String insert_after)
275 {
276 XrmResource **list;
277 int len;
278 XrmQuark res_nameQ = XrmPermStringToQuark(res_name);
279 XrmResource *tmp ;
280 int n ;
281
282 _XmProcessLock();
283 list = (XrmResource **) widget_class->core_class.resources ;
284 len = widget_class->core_class.num_resources;
285
286 /* look for the named resource slot */
287 n = 0;
288 while ((n < len) && (list[n]->xrm_name != res_nameQ))
289 n++;
290
291 if (n < len) {
292 int m, i;
293 XrmQuark insert_afterQ ;
294
295 if (insert_after) {
296 insert_afterQ = XrmPermStringToQuark(insert_after) ;
297 /* now look for the insert_after resource slot */
298 m = 0;
299 while ((m < len) && (list[m]->xrm_name != insert_afterQ))
300 m++;
301 } else m = len ;
302 if (m == len) m = -1 ;
303
304 /* now do the insertion/packing, both cases */
305 tmp = list[n] ;
306
307 if (n > m) {
308 for (i = n; i > m+1; i--)
309 list[i] = list[i-1];
310 list[m+1] = tmp;
311 } else {
312 for (i = n; i < m; i++)
313 list[i] = list[i+1];
314 list[m] = tmp;
315 }
316 }
317 _XmProcessUnlock();
318 }
319
320
321
322 /************************************************************************
323 *
324 * _XmWarningMsg
325 * Add XME_WARNING to Message list so MotifWarningHandler will
326 * add Name: & Class:
327 *
328 ************************************************************************/
329 void
_XmWarningMsg(Widget w,char * type,char * message,char ** params,Cardinal num_params)330 _XmWarningMsg(Widget w,
331 char *type,
332 char *message,
333 char **params,
334 Cardinal num_params)
335 {
336 Display * dpy;
337 char *new_params[11];
338 Cardinal num_new_params = num_params + 1;
339 int i;
340
341 if (num_new_params > 11) num_new_params = 11;
342 for (i = 0; i < num_new_params-1; i++)
343 new_params[i] = params[i];
344 new_params[num_new_params-1] = XME_WARNING;
345
346 if (w != NULL) {
347 XtAppWarningMsg (XtWidgetToApplicationContext(w),
348 XrmQuarkToString (w->core.xrm_name),
349 type,
350 w->core.widget_class->core_class.class_name,
351 message, new_params, &num_new_params);
352 } else
353 XtWarning(message);
354 }
355
356 /* ARGSUSED */
357 Boolean
_XmIsISO10646(Display * dpy,XFontStruct * font)358 _XmIsISO10646(Display *dpy, XFontStruct *font)
359 {
360 Boolean ok;
361 int i;
362 char *regname;
363 Atom registry;
364 XFontProp *xfp;
365
366 ok = False;
367 registry = XInternAtom(dpy, "CHARSET_REGISTRY", False);
368
369 for (i = 0, xfp = font->properties;
370 ok == False && i < font->n_properties; xfp++, i++) {
371 if (xfp->name == registry) {
372 regname = XGetAtomName(dpy, (Atom) xfp->card32);
373 if (strcmp(regname, "ISO10646") == 0 ||
374 strcmp(regname, "iso10646") == 0)
375 ok = True;
376 XFree(regname);
377 }
378 }
379 return ok;
380 }
381
382 XChar2b*
_XmUtf8ToUcs2(char * draw_text,size_t seg_len,size_t * ret_str_len)383 _XmUtf8ToUcs2(char *draw_text, size_t seg_len, size_t *ret_str_len)
384 {
385 char *ep;
386 unsigned short codepoint;
387 XChar2b *ptr;
388 XChar2b *buf2b;
389
390 /*
391 * Convert to UCS2 string on the fly.
392 */
393
394 buf2b = (XChar2b *)XtMalloc(seg_len * sizeof(XChar2b));
395
396 ep = draw_text + seg_len;
397 for (ptr = buf2b; draw_text < ep; ptr++) {
398 if((draw_text[0]&0x80)==0) {
399 codepoint=draw_text[0];
400 draw_text++;
401 } else if((draw_text[0]&0x20)==0) {
402 codepoint = (draw_text[0]&0x1F)<<6 | (draw_text[1]&0x3F);
403 draw_text+=2;
404 } else if((draw_text[0]&0x10)==0) {
405 codepoint = (draw_text[0]&0x0F)<<12
406 | (draw_text[1]&0x3F)<<6
407 | (draw_text[2]&0x3F);
408 draw_text+=3;
409 } else { /* wrong UTF-8 */
410 codepoint=(unsigned)'?';
411 draw_text++;
412 }
413 ptr->byte1 = (codepoint >> 8) & 0xff;;
414 ptr->byte2 = codepoint & 0xff;
415 }
416 *ret_str_len = ptr - buf2b;
417 return buf2b;
418 }
419
420
421 /***************************************/
422 /********---- PUBLIC API ----**********/
423 /*************************************/
424
425
426
427
428 /************************************************************************
429 *
430 * XmeWarning
431 * Build up a warning message and call Xt to get it displayed.
432 *
433 ************************************************************************/
434 void
XmeWarning(Widget w,char * message)435 XmeWarning(Widget w,
436 char *message )
437 {
438 char *params[1];
439 Cardinal num_params = 0;
440 Display * dpy;
441
442 if (w != NULL) {
443 /* the MotifWarningHandler installed in VendorS.c knows about
444 this convention */
445 params[0] = XME_WARNING;
446 num_params++;
447
448 XtAppWarningMsg (XtWidgetToApplicationContext(w),
449 XrmQuarkToString (w->core.xrm_name),
450 "XmeWarning",
451 w->core.widget_class->core_class.class_name,
452 message, params, &num_params);
453 } else
454 XtWarning(message);
455 }
456
457
458 /************************************************************************
459 *
460 * XmObjectAtPoint
461 * new implementation that ask a manager class method
462 * -- Called by various widgets across Xm
463 *
464 ************************************************************************/
465 Widget
XmObjectAtPoint(Widget wid,Position x,Position y)466 XmObjectAtPoint(
467 Widget wid,
468 Position x,
469 Position y )
470 {
471 XmManagerWidgetClass mw = (XmManagerWidgetClass) XtClass(wid);
472 XmManagerClassExt *mext ;
473 Widget return_wid = NULL;
474 _XmWidgetToAppContext(wid);
475
476 _XmAppLock(app);
477
478 if (!XmIsManager(wid)) {
479 _XmAppUnlock(app);
480 return NULL;
481 }
482
483 mext = (XmManagerClassExt *)
484 _XmGetClassExtensionPtr( (XmGenericClassExt *)
485 &(mw->manager_class.extension), NULLQUARK) ;
486 if (!*mext) {
487 _XmAppUnlock(app);
488 return NULL;
489 }
490
491 if ((*mext)->object_at_point)
492 return_wid = ((*mext)->object_at_point)(wid, x, y);
493
494 _XmAppUnlock(app);
495 return return_wid;
496 }
497
498 #ifdef FIX_1381
499 /************************************************************************
500 *
501 * _XmAssignInsensitiveColor
502 * Allocate the Gray color for display widget like insensitive.
503 *
504 *
505 ************************************************************************/
506
507 Pixel
_XmAssignInsensitiveColor(Widget w)508 _XmAssignInsensitiveColor(Widget w)
509 {
510 Pixel p = 0;
511
512 if (XmIsPrimitive(w)) {
513 XmPrimitiveWidget pw = (XmPrimitiveWidget) w;
514 p = pw->primitive.bottom_shadow_color;
515 }
516 else if (XmIsGadget(w)) {
517 if (XmIsLabelGadget(w)) {
518 XmLabelGadget lg = (XmLabelGadget) w;
519 p = LabG_BottomShadowColor(lg);
520 }
521 if (XmIsIconGadget(w)) {
522 XmIconGadget ig = (XmIconGadget) w;
523 p = IG_BottomShadowColor(ig);
524 }
525 }
526 else {
527 p = 0;
528 }
529
530 return p;
531 }
532 #endif
533
534