/* $XConsortium: Xm.c /main/6 1995/10/25 20:28:03 cde-sun $ */
/*
* Motif
*
* Copyright (c) 1987-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these librararies and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/*
* HISTORY
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "XmI.h"
#include "MessagesI.h"
#include <Xm/PrimitiveP.h>
#include <Xm/ManagerP.h>
#include <Xm/GadgetP.h>
#include <Xm/IconGP.h>
#include <Xm/LabelGP.h>
#ifdef FIX_345
#include <X11/keysym.h>
#endif
/**************************************************************************
* This is Xm.c
* It contains global API that:
* - it's not widget specific
* - it's already used by various widgets (you don't get useless
* code by linking with this module: all the functions
* are useful and used.
* For example, TrackingLocate or ResolvePartOffset do not belong
* here because they are not used by everybody.
*************************************************************************/
#ifdef FIX_345
Boolean _init_modifiers = TRUE;
unsigned int NumLockMask = 0;
unsigned int ScrollLockMask = 0;
/*************************************<->*************************************
*
* _XmInitModifiers (void)
*
* Description:
* -----------
* Sets the appropriate mask for NumLock and ScrollLock
*
*
* Inputs:
* ------
* None
*
* Outputs:
* -------
* None
*
* Procedures Called
* -----------------
* None
*
*************************************<->***********************************/
void
_XmInitModifiers (void)
{
XModifierKeymap *modmap;
Display *dpy;
KeySym *keymap;
unsigned int keycode;
int min_keycode;
int max_keycode;
int keysyms_per_keycode;
int i;
dpy = _XmGetDefaultDisplay();
NumLockMask = 0;
ScrollLockMask = 0;
keysyms_per_keycode = 0;
min_keycode = 0;
max_keycode = 0;
XDisplayKeycodes (dpy, &min_keycode, &max_keycode);
modmap = XGetModifierMapping (dpy);
keymap = XGetKeyboardMapping (dpy, min_keycode, max_keycode - min_keycode + 1, &keysyms_per_keycode);
if (modmap && keymap) {
for (i = 3 * modmap->max_keypermod; i < 8 * modmap->max_keypermod; i++) {
keycode = modmap->modifiermap[i];
if ((keycode >= min_keycode) && (keycode <= max_keycode)) {
int j;
KeySym *syms = keymap + (keycode - min_keycode) * keysyms_per_keycode;
for (j = 0; j < keysyms_per_keycode; j++)
if (!NumLockMask && (syms[j] == XK_Num_Lock))
NumLockMask = (1 << (i / modmap->max_keypermod));
else if (!ScrollLockMask && (syms[j] == XK_Scroll_Lock))
ScrollLockMask = (1 << (i / modmap->max_keypermod));
}
}
}
/* Cleanup memory */
if (modmap)
XFreeModifiermap (modmap);
if (keymap)
XFree (keymap);
}
#endif
/**************************************************************************
* *
* _XmSocorro - Help dispatch function. Start at the widget help was *
* invoked on, find the first non-null help callback list, and call it. *
* -- Called by various widgets across Xm *
* *
*************************************************************************/
/* ARGSUSED */
void
_XmSocorro(
Widget w,
XEvent *event,
String *params, /* unused */
Cardinal *num_params ) /* unused */
{
XmAnyCallbackStruct cb;
if (w == NULL) return;
cb.reason = XmCR_HELP;
cb.event = event;
do {
if ((XtHasCallbacks(w, XmNhelpCallback) == XtCallbackHasSome))
{
XtCallCallbacks (w, XmNhelpCallback, &cb);
return;
}
else
w = XtParent(w);
}
while (w != NULL);
}
/****************************************************************
*
* _XmParentProcess
* This is the entry point for parent processing.
* -- Called by various widgets across Xm
*
****************************************************************/
Boolean
_XmParentProcess(
Widget widget,
XmParentProcessData data )
{
XmManagerWidgetClass manClass ;
manClass = (XmManagerWidgetClass) widget->core.widget_class ;
if( XmIsManager( widget)
&& manClass->manager_class.parent_process ) {
return( (*manClass->manager_class.parent_process)( widget, data)) ;
}
return( FALSE) ;
}
/************************************************************************
*
* _XmDestroyParentCallback
* Destroy parent. Used by various dialog subclasses
*
************************************************************************/
/* ARGSUSED */
void
_XmDestroyParentCallback(
Widget w,
XtPointer client_data, /* unused */
XtPointer call_data ) /* unused */
{
XtDestroyWidget (XtParent (w));
}
/************************************************************************
*
* _XmClearShadowType
* Clear the right and bottom border area and save
* the old width, height and shadow type.
* Used by various subclasses for resize larger situation, where the
* inside shadow is not exposed.
* Maybe that should be moved in Draw.c, maybe not, since it's a widget API
*
************************************************************************/
void
_XmClearShadowType(
Widget w,
#if NeedWidePrototypes
int old_width,
int old_height,
int old_shadow_thickness,
int old_highlight_thickness )
#else
Dimension old_width,
Dimension old_height,
Dimension old_shadow_thickness,
Dimension old_highlight_thickness )
#endif /* NeedWidePrototypes */
{
if (old_shadow_thickness == 0) return;
if (XtIsRealized(w)) {
if (old_width <= w->core.width)
XClearArea (XtDisplay (w), XtWindow (w),
old_width - old_shadow_thickness -
old_highlight_thickness, 0,
old_shadow_thickness, old_height -
old_highlight_thickness,
False);
if (old_height <= w->core.height)
XClearArea (XtDisplay (w), XtWindow (w),
0, old_height - old_shadow_thickness -
old_highlight_thickness,
old_width - old_highlight_thickness,
old_shadow_thickness,
False);
}
}
/**********************************************************************
*
* _XmReOrderResourceList
* This procedure moves the given resource right after the
* insert_after name in this class resource list.
* (+ insert_after NULL means insert in front)
*
* ----Replace by a call to an Xt function in R6.-----
**********************************************************************/
void
_XmReOrderResourceList(
WidgetClass widget_class,
String res_name,
String insert_after)
{
XrmResource **list;
int len;
XrmQuark res_nameQ = XrmPermStringToQuark(res_name);
XrmResource *tmp ;
int n ;
_XmProcessLock();
list = (XrmResource **) widget_class->core_class.resources ;
len = widget_class->core_class.num_resources;
/* look for the named resource slot */
n = 0;
while ((n < len) && (list[n]->xrm_name != res_nameQ))
n++;
if (n < len) {
int m, i;
XrmQuark insert_afterQ ;
if (insert_after) {
insert_afterQ = XrmPermStringToQuark(insert_after) ;
/* now look for the insert_after resource slot */
m = 0;
while ((m < len) && (list[m]->xrm_name != insert_afterQ))
m++;
} else m = len ;
if (m == len) m = -1 ;
/* now do the insertion/packing, both cases */
tmp = list[n] ;
if (n > m) {
for (i = n; i > m+1; i--)
list[i] = list[i-1];
list[m+1] = tmp;
} else {
for (i = n; i < m; i++)
list[i] = list[i+1];
list[m] = tmp;
}
}
_XmProcessUnlock();
}
/************************************************************************
*
* _XmWarningMsg
* Add XME_WARNING to Message list so MotifWarningHandler will
* add Name: & Class:
*
************************************************************************/
void
_XmWarningMsg(Widget w,
char *type,
char *message,
char **params,
Cardinal num_params)
{
Display * dpy;
char *new_params[11];
Cardinal num_new_params = num_params + 1;
int i;
if (num_new_params > 11) num_new_params = 11;
for (i = 0; i < num_new_params-1; i++)
new_params[i] = params[i];
new_params[num_new_params-1] = XME_WARNING;
if (w != NULL) {
XtAppWarningMsg (XtWidgetToApplicationContext(w),
XrmQuarkToString (w->core.xrm_name),
type,
w->core.widget_class->core_class.class_name,
message, new_params, &num_new_params);
} else
XtWarning(message);
}
/* ARGSUSED */
Boolean
_XmIsISO10646(Display *dpy, XFontStruct *font)
{
Boolean ok;
int i;
char *regname;
Atom registry;
XFontProp *xfp;
ok = False;
registry = XInternAtom(dpy, "CHARSET_REGISTRY", False);
for (i = 0, xfp = font->properties;
ok == False && i < font->n_properties; xfp++, i++) {
if (xfp->name == registry) {
regname = XGetAtomName(dpy, (Atom) xfp->card32);
if (strcmp(regname, "ISO10646") == 0 ||
strcmp(regname, "iso10646") == 0)
ok = True;
XFree(regname);
}
}
return ok;
}
XChar2b*
_XmUtf8ToUcs2(char *draw_text, size_t seg_len, size_t *ret_str_len)
{
char *ep;
unsigned short codepoint;
XChar2b *ptr;
XChar2b *buf2b;
/*
* Convert to UCS2 string on the fly.
*/
buf2b = (XChar2b *)XtMalloc(seg_len * sizeof(XChar2b));
ep = draw_text + seg_len;
for (ptr = buf2b; draw_text < ep; ptr++) {
if((draw_text[0]&0x80)==0) {
codepoint=draw_text[0];
draw_text++;
} else if((draw_text[0]&0x20)==0) {
codepoint = (draw_text[0]&0x1F)<<6 | (draw_text[1]&0x3F);
draw_text+=2;
} else if((draw_text[0]&0x10)==0) {
codepoint = (draw_text[0]&0x0F)<<12
| (draw_text[1]&0x3F)<<6
| (draw_text[2]&0x3F);
draw_text+=3;
} else { /* wrong UTF-8 */
codepoint=(unsigned)'?';
draw_text++;
}
ptr->byte1 = (codepoint >> 8) & 0xff;;
ptr->byte2 = codepoint & 0xff;
}
*ret_str_len = ptr - buf2b;
return buf2b;
}
/***************************************/
/********---- PUBLIC API ----**********/
/*************************************/
/************************************************************************
*
* XmeWarning
* Build up a warning message and call Xt to get it displayed.
*
************************************************************************/
void
XmeWarning(Widget w,
char *message )
{
char *params[1];
Cardinal num_params = 0;
Display * dpy;
if (w != NULL) {
/* the MotifWarningHandler installed in VendorS.c knows about
this convention */
params[0] = XME_WARNING;
num_params++;
XtAppWarningMsg (XtWidgetToApplicationContext(w),
XrmQuarkToString (w->core.xrm_name),
"XmeWarning",
w->core.widget_class->core_class.class_name,
message, params, &num_params);
} else
XtWarning(message);
}
/************************************************************************
*
* XmObjectAtPoint
* new implementation that ask a manager class method
* -- Called by various widgets across Xm
*
************************************************************************/
Widget
XmObjectAtPoint(
Widget wid,
Position x,
Position y )
{
XmManagerWidgetClass mw = (XmManagerWidgetClass) XtClass(wid);
XmManagerClassExt *mext ;
Widget return_wid = NULL;
_XmWidgetToAppContext(wid);
_XmAppLock(app);
if (!XmIsManager(wid)) {
_XmAppUnlock(app);
return NULL;
}
mext = (XmManagerClassExt *)
_XmGetClassExtensionPtr( (XmGenericClassExt *)
&(mw->manager_class.extension), NULLQUARK) ;
if (!*mext) {
_XmAppUnlock(app);
return NULL;
}
if ((*mext)->object_at_point)
return_wid = ((*mext)->object_at_point)(wid, x, y);
_XmAppUnlock(app);
return return_wid;
}
#ifdef FIX_1381
/************************************************************************
*
* _XmAssignInsensitiveColor
* Allocate the Gray color for display widget like insensitive.
*
*
************************************************************************/
Pixel
_XmAssignInsensitiveColor(Widget w)
{
Pixel p;
if (XmIsPrimitive(w)) {
XmPrimitiveWidget pw = (XmPrimitiveWidget) w;
p = pw->primitive.bottom_shadow_color;
}
else if (XmIsGadget(w)) {
if (XmIsLabelGadget(w)) {
XmLabelGadget lg = (XmLabelGadget) w;
p = LabG_BottomShadowColor(lg);
}
if (XmIsIconGadget(w)) {
XmIconGadget ig = (XmIconGadget) w;
p = IG_BottomShadowColor(ig);
}
}
else {
p = 0;
}
return p;
}
#endif