Blame lib/Xm/Xm.c

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