Blame tests/lib/Geometry/geoSetValues.c

Packit b099d7
/* $XConsortium: geoSetValues.c /main/4 1995/07/15 21:13:32 drk $ */
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
#include "IntrinsicI.h"
Packit b099d7
#include "StringDefs.h"
Packit b099d7
  
Packit b099d7
#include "geoTattler.h"
Packit b099d7
Packit b099d7
/*
Packit b099d7
 *	XtSetValues(), XtSetSubvalues()
Packit b099d7
 */
Packit b099d7
Packit b099d7
Packit b099d7
extern void _XtCopyFromArg();
Packit b099d7
extern XrmResourceList* _XtCreateIndirectionTable();
Packit b099d7
Packit b099d7
static void SetValues(base, res, num_resources, args, num_args)
Packit b099d7
  char*			base;		/* Base address to write values to   */
Packit b099d7
  XrmResourceList*	res;		/* The current resource values.      */
Packit b099d7
  register Cardinal	num_resources;	/* number of items in resources      */
Packit b099d7
  ArgList 		args;		/* The resource values to set        */
Packit b099d7
  Cardinal		num_args;	/* number of items in arg list       */
Packit b099d7
{
Packit b099d7
    register ArgList		arg;
Packit b099d7
    register int 	        i;
Packit b099d7
    register XrmName		argName;
Packit b099d7
    register XrmResourceList*   xrmres;
Packit b099d7
Packit b099d7
    /* Resource lists are assumed to be in compiled form already via the
Packit b099d7
       initial XtGetResources, XtGetSubresources calls */
Packit b099d7
Packit b099d7
    for (arg = args ; num_args != 0; num_args--, arg++) {
Packit b099d7
	argName = StringToName(arg->name);
Packit b099d7
	for (xrmres = res, i = 0; i < num_resources; i++, xrmres++) {
Packit b099d7
	    if (argName == (*xrmres)->xrm_name) {
Packit b099d7
		_XtCopyFromArg(arg->value,
Packit b099d7
		    base - (*xrmres)->xrm_offset - 1,
Packit b099d7
		    (*xrmres)->xrm_size);
Packit b099d7
		break;
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
} /* SetValues */
Packit b099d7
Packit b099d7
static Boolean CallSetValues (class, current, request, new, args, num_args)
Packit b099d7
    WidgetClass class;
Packit b099d7
    Widget      current, request, new;
Packit b099d7
    ArgList     args;
Packit b099d7
    Cardinal    num_args;
Packit b099d7
{
Packit b099d7
    Boolean redisplay = FALSE;
Packit b099d7
Packit b099d7
    if (class->core_class.superclass != NULL)
Packit b099d7
        redisplay = CallSetValues(
Packit b099d7
	  class->core_class.superclass, current, request, new, args, num_args);
Packit b099d7
    if (class->core_class.set_values != NULL)
Packit b099d7
        redisplay |= (*class->core_class.
Packit b099d7
		      set_values) (current, request, new, args, &num_args);
Packit b099d7
    if (class->core_class.set_values_hook != NULL)
Packit b099d7
	redisplay |=
Packit b099d7
	    (*class->core_class.set_values_hook) (new, args, &num_args);
Packit b099d7
    return (redisplay);
Packit b099d7
}
Packit b099d7
Packit b099d7
static Boolean
Packit b099d7
CallConstraintSetValues (class, current, request, new, args, num_args)
Packit b099d7
    ConstraintWidgetClass class;
Packit b099d7
    Widget      current, request, new;
Packit b099d7
    ArgList     args;
Packit b099d7
    Cardinal    num_args;
Packit b099d7
{
Packit b099d7
    Boolean redisplay = FALSE;
Packit b099d7
Packit b099d7
    if ((WidgetClass)class != constraintWidgetClass) {
Packit b099d7
	if (class == NULL)
Packit b099d7
	    XtAppErrorMsg(XtWidgetToApplicationContext(current),
Packit b099d7
		    "invalidClass","constraintSetValue",XtCXtToolkitError,
Packit b099d7
                 "Subclass of Constraint required in CallConstraintSetValues",
Packit b099d7
                  (String *)NULL, (Cardinal *)NULL);
Packit b099d7
	redisplay = CallConstraintSetValues(
Packit b099d7
	    (ConstraintWidgetClass) (class->core_class.superclass),
Packit b099d7
	    current, request, new, args, num_args);
Packit b099d7
    }
Packit b099d7
    if (class->constraint_class.set_values != NULL)
Packit b099d7
        redisplay |= (*class->constraint_class.
Packit b099d7
		      set_values) (current, request, new, args, &num_args);
Packit b099d7
    return (redisplay);
Packit b099d7
}
Packit b099d7
Packit b099d7
void XtSetSubvalues(base, resources, num_resources, args, num_args)
Packit b099d7
  XtPointer             base;           /* Base address to write values to   */
Packit b099d7
  register XtResourceList resources;    /* The current resource values.      */
Packit b099d7
  register Cardinal     num_resources;  /* number of items in resources      */
Packit b099d7
  ArgList               args;           /* The resource values to set        */
Packit b099d7
  Cardinal              num_args;       /* number of items in arg list       */
Packit b099d7
{
Packit b099d7
      register XrmResourceList*   xrmres;
Packit b099d7
      xrmres = _XtCreateIndirectionTable (resources, num_resources);
Packit b099d7
      SetValues((char*)base,xrmres,num_resources, args, num_args);
Packit b099d7
      XtFree((char *)xrmres);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
void XtSetValues(w, args, num_args)
Packit b099d7
    register Widget   w;
Packit b099d7
	     ArgList  args;
Packit b099d7
	     Cardinal num_args;
Packit b099d7
{
Packit b099d7
    register Widget oldw, reqw;
Packit b099d7
    /* need to use strictest alignment rules possible in next two decls. */
Packit b099d7
    double	    oldwCache[100], reqwCache[100];
Packit b099d7
    double	    oldcCache[20], reqcCache[20];
Packit b099d7
    Cardinal	    widgetSize, constraintSize;
Packit b099d7
    Boolean	    redisplay, cleared_rect_obj = False;
Packit b099d7
    XtGeometryResult result;
Packit b099d7
    XtWidgetGeometry geoReq, geoReply;
Packit b099d7
    WidgetClass     wc = XtClass(w);
Packit b099d7
    ConstraintWidgetClass cwc;
Packit b099d7
    Boolean	    hasConstraints;
Packit b099d7
    Cardinal i ;
Packit b099d7
Packit b099d7
    /* Editres hack: 
Packit b099d7
       editres uses XtGetResourceList to get the resource list of a widget,
Packit b099d7
       and geoTattler can't be in the list, so we use "traversalOn", which
Packit b099d7
       is in all Motif subclasses. 
Packit b099d7
    
Packit b099d7
    for (i = 0 ; i < num_args ; i++) {
Packit b099d7
	if (strcmp(args[i].name, "traversalOn") == 0) {
Packit b099d7
	    _GeoChangeCache(w, (Boolean)args[i].value);
Packit b099d7
	    return ;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
    remove that code, scale turns in on by default */
Packit b099d7
Packit b099d7
Packit b099d7
    if ((args == NULL) && (num_args != 0)) {
Packit b099d7
        XtAppErrorMsg(XtWidgetToApplicationContext(w),
Packit b099d7
		"invalidArgCount","xtSetValues",XtCXtToolkitError,
Packit b099d7
                "Argument count > 0 on NULL argument list in XtSetValues",
Packit b099d7
                 (String *)NULL, (Cardinal *)NULL);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* Allocate and copy current widget into old widget */
Packit b099d7
Packit b099d7
    widgetSize = wc->core_class.widget_size;
Packit b099d7
    oldw = (Widget) XtStackAlloc(widgetSize, oldwCache);
Packit b099d7
    reqw = (Widget) XtStackAlloc (widgetSize, reqwCache);
Packit b099d7
    bcopy((char *) w, (char *) oldw, (int) widgetSize);
Packit b099d7
Packit b099d7
    /* Set resource values */
Packit b099d7
Packit b099d7
    SetValues((char*)w, (XrmResourceList *) wc->core_class.resources,
Packit b099d7
	wc->core_class.num_resources, args, num_args);
Packit b099d7
Packit b099d7
    bcopy ((char *) w, (char *) reqw, (int) widgetSize);
Packit b099d7
Packit b099d7
    /* assert: !XtIsShell(w) => (XtParent(w) != NULL) */
Packit b099d7
    hasConstraints = (!XtIsShell(w) && XtIsConstraint(XtParent(w)));
Packit b099d7
Packit b099d7
    /* Some widget sets apparently do ugly things by freeing the
Packit b099d7
     * constraints on some children, thus the extra test here */
Packit b099d7
    if (hasConstraints) {
Packit b099d7
	cwc = (ConstraintWidgetClass) XtClass(w->core.parent);
Packit b099d7
	if (w->core.constraints)
Packit b099d7
	    constraintSize = cwc->constraint_class.constraint_size;
Packit b099d7
	else constraintSize = 0;
Packit b099d7
    } else constraintSize = 0;
Packit b099d7
	
Packit b099d7
    if (constraintSize) {
Packit b099d7
	/* Allocate and copy current constraints into oldw */
Packit b099d7
	oldw->core.constraints = XtStackAlloc(constraintSize, oldcCache);
Packit b099d7
	reqw->core.constraints = XtStackAlloc(constraintSize, reqcCache);
Packit b099d7
	bcopy((char *) w->core.constraints, 
Packit b099d7
		(char *) oldw->core.constraints, (int) constraintSize);
Packit b099d7
Packit b099d7
	/* Set constraint values */
Packit b099d7
	SetValues((char*)w->core.constraints,
Packit b099d7
	    (XrmResourceList *)(cwc->constraint_class.resources),
Packit b099d7
	    cwc->constraint_class.num_resources, args, num_args);
Packit b099d7
	bcopy((char *) w->core.constraints,
Packit b099d7
	      (char *) reqw->core.constraints, (int) constraintSize);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* Inform widget of changes, then inform parent of changes */
Packit b099d7
    redisplay = CallSetValues (wc, oldw, reqw, w, args, num_args);
Packit b099d7
    if (hasConstraints) {
Packit b099d7
	redisplay |= CallConstraintSetValues(cwc, oldw, reqw, w, args, num_args);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (XtIsRectObj(w)) {
Packit b099d7
	/* Now perform geometry request if needed */
Packit b099d7
	geoReq.request_mode = 0;
Packit b099d7
	if (oldw->core.x	!= w->core.x) {
Packit b099d7
	    geoReq.x		= w->core.x;
Packit b099d7
	    w->core.x		= oldw->core.x;
Packit b099d7
	    geoReq.request_mode |= CWX;
Packit b099d7
	}
Packit b099d7
	if (oldw->core.y	!= w->core.y) {
Packit b099d7
	    geoReq.y		= w->core.y;
Packit b099d7
	    w->core.y		= oldw->core.y;
Packit b099d7
	    geoReq.request_mode |= CWY;
Packit b099d7
	}
Packit b099d7
	if (oldw->core.width	!= w->core.width) {
Packit b099d7
	    geoReq.width	= w->core.width;
Packit b099d7
	    w->core.width	= oldw->core.width;
Packit b099d7
	    geoReq.request_mode |= CWWidth;
Packit b099d7
	}
Packit b099d7
	if (oldw->core.height	!= w->core.height) {
Packit b099d7
	    geoReq.height	= w->core.height;
Packit b099d7
	    w->core.height	= oldw->core.height;
Packit b099d7
	    geoReq.request_mode |= CWHeight;
Packit b099d7
	}
Packit b099d7
	if (oldw->core.border_width != w->core.border_width) {
Packit b099d7
	    geoReq.border_width	    = w->core.border_width;
Packit b099d7
	    w->core.border_width    = oldw->core.border_width;
Packit b099d7
	    geoReq.request_mode	    |= CWBorderWidth;
Packit b099d7
	}
Packit b099d7
    
Packit b099d7
	if (geoReq.request_mode != 0) {
Packit b099d7
 	    /* Pass on any requests for unchanged geometry values */
Packit b099d7
 	    if (geoReq.request_mode !=
Packit b099d7
 		(CWX | CWY | CWWidth | CWHeight | CWBorderWidth)) {
Packit b099d7
 		for ( ; num_args != 0; num_args--, args++) {
Packit b099d7
 		    if (! (geoReq.request_mode & CWX) &&
Packit b099d7
 			strcmp(XtNx, args->name) == 0) {
Packit b099d7
 			geoReq.x = w->core.x;
Packit b099d7
 			geoReq.request_mode |= CWX;
Packit b099d7
 		    } else if (! (geoReq.request_mode & CWY) &&
Packit b099d7
 			       strcmp(XtNy, args->name) == 0) {
Packit b099d7
 			geoReq.y = w->core.y;
Packit b099d7
 			geoReq.request_mode |= CWY;
Packit b099d7
 		    } else if (! (geoReq.request_mode & CWWidth) &&
Packit b099d7
 			       strcmp(XtNwidth, args->name) == 0) {
Packit b099d7
 			geoReq.width = w->core.width;
Packit b099d7
 			geoReq.request_mode |= CWWidth;
Packit b099d7
 		    } else if (! (geoReq.request_mode & CWHeight) &&
Packit b099d7
 			       strcmp(XtNheight, args->name) == 0) {
Packit b099d7
 			geoReq.height = w->core.height;
Packit b099d7
 			geoReq.request_mode |= CWHeight;
Packit b099d7
 		    } else if (! (geoReq.request_mode & CWBorderWidth) &&
Packit b099d7
 			       strcmp(XtNborderWidth, args->name) == 0) {
Packit b099d7
 			geoReq.border_width = w->core.border_width;
Packit b099d7
 			geoReq.request_mode |= CWBorderWidth;
Packit b099d7
 		    }
Packit b099d7
 		}
Packit b099d7
 	    }
Packit b099d7
Packit b099d7
	    _GeoPrintTab();  /* newline */
Packit b099d7
	    _GeoPrintTrace(w,"XtSetValues sees some geometry changes for \"%s\".\n", XtName(w));
Packit b099d7
	    _GeoTabTrace();
Packit b099d7
Packit b099d7
	    do {
Packit b099d7
		result = _XtMakeGeometryRequest(w, &geoReq, &geoReply, 
Packit b099d7
						&cleared_rect_obj);
Packit b099d7
		if (result == XtGeometryYes || result == XtGeometryDone)
Packit b099d7
		    break;
Packit b099d7
Packit b099d7
		/* An Almost or No reply.  Call widget and let it munge
Packit b099d7
		   request, reply */
Packit b099d7
		if (wc->core_class.set_values_almost == NULL) {
Packit b099d7
		    XtAppWarningMsg(XtWidgetToApplicationContext(w),
Packit b099d7
			    "invalidProcedure","set_values_almost",
Packit b099d7
			  XtCXtToolkitError,
Packit b099d7
			  "set_values_almost procedure shouldn't be NULL",
Packit b099d7
			  (String *)NULL, (Cardinal *)NULL);
Packit b099d7
		    break;
Packit b099d7
		}
Packit b099d7
		if (result == XtGeometryNo) geoReply.request_mode = 0;
Packit b099d7
Packit b099d7
		_GeoPrintTrace(w,"calling SetValuesAlmost.\n");
Packit b099d7
	    
Packit b099d7
		(*(wc->core_class.set_values_almost))
Packit b099d7
		    (oldw, w, &geoReq, &geoReply);
Packit b099d7
	    } while (geoReq.request_mode != 0);
Packit b099d7
Packit b099d7
	    /* call resize proc if we changed size and parent
Packit b099d7
	     * didn't already invoke resize */
Packit b099d7
	    if (((w->core.width != oldw->core.width ||
Packit b099d7
		 w->core.height != oldw->core.height)
Packit b099d7
		&& result != XtGeometryDone))  {
Packit b099d7
Packit b099d7
		_GeoPrintTrace(w,"XtSetValues calls \"%s\"'s resize proc.\n",
Packit b099d7
			    XtName(w));
Packit b099d7
		
Packit b099d7
		if (wc->core_class.resize) (*(wc->core_class.resize))(w);
Packit b099d7
	    }
Packit b099d7
Packit b099d7
	    _GeoUnTabTrace();
Packit b099d7
	}
Packit b099d7
Packit b099d7
	/* Redisplay if needed.  No point in clearing if the window is
Packit b099d7
	 * about to disappear, as the Expose event will just go straight
Packit b099d7
	 * to the bit bucket. */
Packit b099d7
        if (XtIsWidget(w)) {
Packit b099d7
            /* widgets can distinguish between redisplay and resize, since
Packit b099d7
             the server will cause an expose on resize */
Packit b099d7
            if (redisplay && XtIsRealized(w) && !w->core.being_destroyed) {
Packit b099d7
Packit b099d7
		_GeoPrintTrace(w,"XtSetValues calls ClearArea on \"%s\".\n",XtName(w));
Packit b099d7
		
Packit b099d7
                XClearArea (XtDisplay(w), XtWindow(w), 0, 0, 0, 0, TRUE);
Packit b099d7
	    }
Packit b099d7
        } else { /*non-window object */
Packit b099d7
	  if (redisplay && ! cleared_rect_obj ) {
Packit b099d7
	      Widget pw = _XtWindowedAncestor(w);
Packit b099d7
	      if (XtIsRealized(pw) && !pw->core.being_destroyed) {
Packit b099d7
		  RectObj r = (RectObj)w;
Packit b099d7
		  int bw2 = r->rectangle.border_width << 1;
Packit b099d7
Packit b099d7
		  _GeoPrintTrace(w,"XtSetValues calls ClearArea on \"%s\"'s parent \"%s\".\n",
Packit b099d7
			      XtName(w),XtName(pw));
Packit b099d7
		
Packit b099d7
		  XClearArea (XtDisplay (pw), XtWindow (pw),
Packit b099d7
		      r->rectangle.x, r->rectangle.y,
Packit b099d7
		      r->rectangle.width + bw2,r->rectangle.height + bw2,TRUE);
Packit b099d7
	      }
Packit b099d7
	  }
Packit b099d7
        }
Packit b099d7
    }
Packit b099d7
Packit b099d7
Packit b099d7
    /* Free dynamic storage */
Packit b099d7
    if (constraintSize) {
Packit b099d7
        XtStackFree(oldw->core.constraints, oldcCache);
Packit b099d7
        XtStackFree(reqw->core.constraints, reqcCache);
Packit b099d7
    }
Packit b099d7
    XtStackFree((XtPointer)oldw, oldwCache);
Packit b099d7
    XtStackFree((XtPointer)reqw, reqwCache);
Packit b099d7
Packit b099d7
} /* XtSetValues */