зеркало из https://github.com/mozilla/pjs.git
1741 строка
46 KiB
C
1741 строка
46 KiB
C
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
* for the specific language governing rights and limitations under the
|
|
* NPL.
|
|
*
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
* Reserved.
|
|
*/
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* Name: <Xfe/Primitive.c> */
|
|
/* Description: XfePrimitive widget source. */
|
|
/* Author: Ramiro Estrugo <ramiro@netscape.com> */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <Xfe/PrimitiveP.h>
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* Warnings and messages */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
#define MESSAGE0 "XfePrimitive is an abstract class and cannot be instanciated."
|
|
#define MESSAGE1 "Widget is not XfePrimitive."
|
|
#define MESSAGE2 "XmNpreferredHeight is a read-only resource."
|
|
#define MESSAGE3 "XmNpreferredWidth is a read-only resource."
|
|
#define MESSAGE4 "XmNpointerInside is a read-only resource."
|
|
#define MESSAGE5 "XmNnumPopupChildren is a read-only resource."
|
|
#define MESSAGE6 "XmNpopupChildren is a read-only resource."
|
|
#define MESSAGE7 "Cannot change XmNbufferType after initialization."
|
|
#define MESSAGE8 "Widget's width must be greater than 0."
|
|
#define MESSAGE9 "Widget's height must be greater than 0."
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* Core Class Methods */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static void ClassInitialize ();
|
|
static void ClassPartInit (WidgetClass);
|
|
static void Initialize (Widget,Widget,ArgList,Cardinal *);
|
|
static void Destroy (Widget);
|
|
static void Redisplay (Widget,XEvent *,Region);
|
|
static void Realize (Widget,XtValueMask *,
|
|
XSetWindowAttributes *);
|
|
static void Resize (Widget);
|
|
static Boolean SetValues (Widget,Widget,Widget,ArgList,
|
|
Cardinal *);
|
|
static XtGeometryResult QueryGeometry (Widget,XtWidgetGeometry *,
|
|
XtWidgetGeometry *);
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XmPrimitive Extension Methods */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static Boolean WidgetDisplayRect (Widget,XRectangle *);
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfePrimitive Class Methods */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static void InitializePostHook (Widget,Widget);
|
|
static Boolean SetValuesPostHook (Widget,Widget,Widget);
|
|
static void PreferredGeometry (Widget,Dimension *,Dimension *);
|
|
static void UpdateBoundary (Widget);
|
|
static void DrawShadow (Widget,XEvent *,Region,XRectangle *);
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfePrimitive Buffer Pixmap functions */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static void BufferAllocate (Widget);
|
|
static void BufferFree (Widget);
|
|
static void BufferUpdate (Widget);
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* Misc XfePrimitive functions */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static Dimension GetWidth (Widget);
|
|
static Dimension GetHeight (Widget);
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* Rep type registration functions */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static void PrimitiveRegisterRepTypes (void);
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfePrimitive Resources */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static XtResource resources[] =
|
|
{
|
|
/* Callback resources */
|
|
{
|
|
XmNenterCallback,
|
|
XmCCallback,
|
|
XmRCallback,
|
|
sizeof(XtCallbackList),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . enter_callback),
|
|
XmRImmediate,
|
|
(XtPointer) NULL,
|
|
},
|
|
{
|
|
XmNfocusCallback,
|
|
XmCCallback,
|
|
XmRCallback,
|
|
sizeof(XtCallbackList),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . focus_callback),
|
|
XmRImmediate,
|
|
(XtPointer) NULL,
|
|
},
|
|
{
|
|
XmNleaveCallback,
|
|
XmCCallback,
|
|
XmRCallback,
|
|
sizeof(XtCallbackList),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . leave_callback),
|
|
XmRImmediate,
|
|
(XtPointer) NULL,
|
|
},
|
|
{
|
|
XmNrealizeCallback,
|
|
XmCCallback,
|
|
XmRCallback,
|
|
sizeof(XtCallbackList),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . realize_callback),
|
|
XmRImmediate,
|
|
(XtPointer) NULL,
|
|
},
|
|
{
|
|
XmNresizeCallback,
|
|
XmCCallback,
|
|
XmRCallback,
|
|
sizeof(XtCallbackList),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . resize_callback),
|
|
XmRImmediate,
|
|
(XtPointer) NULL,
|
|
},
|
|
|
|
/* Cursor resources */
|
|
{
|
|
XmNcursor,
|
|
XmCCursor,
|
|
XmRCursor,
|
|
sizeof(Cursor),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . cursor),
|
|
XmRImmediate,
|
|
(XtPointer) None
|
|
},
|
|
|
|
/* Appearance resources */
|
|
{
|
|
XmNshadowType,
|
|
XmCShadowType,
|
|
XmRShadowType,
|
|
sizeof(unsigned char),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . shadow_type),
|
|
XmRImmediate,
|
|
(XtPointer) XmSHADOW_OUT
|
|
},
|
|
{
|
|
XmNbufferType,
|
|
XmCBufferType,
|
|
XmRBufferType,
|
|
sizeof(unsigned char),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . buffer_type),
|
|
XmRImmediate,
|
|
(XtPointer) XmBUFFER_NONE
|
|
},
|
|
/*
|
|
* I just realized this resource is misnamed. It should be
|
|
* XmNpretendInsensitive and default to False.
|
|
*/
|
|
{
|
|
XmNpretendSensitive,
|
|
XmCPretendSensitive,
|
|
XmRBoolean,
|
|
sizeof(Boolean),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . pretend_sensitive),
|
|
XmRImmediate,
|
|
(XtPointer) True
|
|
},
|
|
|
|
/* Geometry resources */
|
|
{
|
|
XmNusePreferredHeight,
|
|
XmCUsePreferredHeight,
|
|
XmRBoolean,
|
|
sizeof(Boolean),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . use_preferred_height),
|
|
XmRImmediate,
|
|
(XtPointer) True
|
|
},
|
|
{
|
|
XmNusePreferredWidth,
|
|
XmCUsePreferredWidth,
|
|
XmRBoolean,
|
|
sizeof(Boolean),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . use_preferred_width),
|
|
XmRImmediate,
|
|
(XtPointer) True
|
|
},
|
|
{
|
|
XmNmarginBottom,
|
|
XmCMarginBottom,
|
|
XmRVerticalDimension,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . margin_bottom),
|
|
XmRImmediate,
|
|
(XtPointer) 2
|
|
},
|
|
{
|
|
XmNmarginLeft,
|
|
XmCMarginLeft,
|
|
XmRHorizontalDimension,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . margin_left),
|
|
XmRImmediate,
|
|
(XtPointer) 2
|
|
},
|
|
{
|
|
XmNmarginRight,
|
|
XmCMarginRight,
|
|
XmRHorizontalDimension,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . margin_right),
|
|
XmRImmediate,
|
|
(XtPointer) 2
|
|
},
|
|
{
|
|
XmNmarginTop,
|
|
XmCMarginTop,
|
|
XmRVerticalDimension,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . margin_top),
|
|
XmRImmediate,
|
|
(XtPointer) 2
|
|
},
|
|
|
|
/* For c++ usage */
|
|
{
|
|
XmNinstancePointer,
|
|
XmCInstancePointer,
|
|
XmRPointer,
|
|
sizeof(XtPointer),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . instance_pointer),
|
|
XmRImmediate,
|
|
(XtPointer) NULL
|
|
},
|
|
|
|
|
|
/* Read-only resources */
|
|
{
|
|
XmNpointerInside,
|
|
XmCReadOnly,
|
|
XmRBoolean,
|
|
sizeof(Boolean),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . pointer_inside),
|
|
XmRImmediate,
|
|
(XtPointer) False
|
|
},
|
|
{
|
|
XmNpreferredHeight,
|
|
XmCReadOnly,
|
|
XmRVerticalDimension,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . preferred_height),
|
|
XmRImmediate,
|
|
(XtPointer) True
|
|
},
|
|
{
|
|
XmNpreferredWidth,
|
|
XmCReadOnly,
|
|
XmRHorizontalDimension,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . preferred_width),
|
|
XmRImmediate,
|
|
(XtPointer) True
|
|
},
|
|
|
|
#ifdef DEBUG
|
|
/* Debug resources */
|
|
{
|
|
"debugTrace",
|
|
"DebugTrace",
|
|
XmRBoolean,
|
|
sizeof(Boolean),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . debug_trace),
|
|
XmRImmediate,
|
|
(XtPointer) False
|
|
},
|
|
#endif
|
|
|
|
/* Core popup resources */
|
|
{
|
|
XmNnumPopupChildren,
|
|
XmCReadOnly,
|
|
XmRCardinal,
|
|
sizeof(Cardinal),
|
|
XtOffsetOf(XfePrimitiveRec , core . num_popups),
|
|
XmRImmediate,
|
|
(XtPointer) 0,
|
|
},
|
|
{
|
|
XmNpopupChildren,
|
|
XmCReadOnly,
|
|
XmRWidgetList,
|
|
sizeof(WidgetList),
|
|
XtOffsetOf(XfePrimitiveRec , core . popup_list),
|
|
XmRImmediate,
|
|
(XtPointer) NULL,
|
|
},
|
|
|
|
/* Force a default shadow thickness */
|
|
{
|
|
XmNshadowThickness,
|
|
XmCShadowThickness,
|
|
XmRHorizontalDimension,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfePrimitiveRec , primitive . shadow_thickness),
|
|
XmRImmediate,
|
|
(XtPointer) 1
|
|
},
|
|
|
|
/* Force the width and height to the preffered values */
|
|
{
|
|
XmNwidth,
|
|
XmCWidth,
|
|
XmRHorizontalDimension,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfePrimitiveRec , core . width),
|
|
XmRImmediate,
|
|
(XtPointer) XfeDEFAULT_PREFERRED_WIDTH
|
|
},
|
|
{
|
|
XmNheight,
|
|
XmCHeight,
|
|
XmRVerticalDimension,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfePrimitiveRec , core . height),
|
|
XmRImmediate,
|
|
(XtPointer) XfeDEFAULT_PREFERRED_HEIGHT
|
|
},
|
|
};
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfePrimitive Synthetic Resources */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static XmSyntheticResource syn_resources[] =
|
|
{
|
|
{
|
|
XmNmarginBottom,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . margin_bottom),
|
|
_XmFromVerticalPixels,
|
|
_XmToVerticalPixels
|
|
},
|
|
{
|
|
XmNmarginLeft,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . margin_left),
|
|
_XmFromHorizontalPixels,
|
|
_XmToHorizontalPixels
|
|
},
|
|
{
|
|
XmNmarginRight,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . margin_right),
|
|
_XmFromHorizontalPixels,
|
|
_XmToHorizontalPixels
|
|
},
|
|
{
|
|
XmNmarginTop,
|
|
sizeof(Dimension),
|
|
XtOffsetOf(XfePrimitiveRec , xfe_primitive . margin_top),
|
|
_XmFromVerticalPixels,
|
|
_XmToVerticalPixels
|
|
},
|
|
};
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfePrimitive Actions */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static XtActionsRec actions[] =
|
|
{
|
|
{ "Focus", _XfePrimitiveFocus },
|
|
{ "Enter", _XfePrimitiveEnter },
|
|
{ "Leave", _XfePrimitiveLeave },
|
|
};
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XmPrimitive extension record initialization */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static XmPrimitiveClassExtRec primClassExtRec =
|
|
{
|
|
NULL, /* next_extension */
|
|
NULLQUARK, /* record_type */
|
|
XmPrimitiveClassExtVersion, /* version */
|
|
sizeof(XmPrimitiveClassExtRec), /* record_size */
|
|
NULL, /* widget_baseline */
|
|
WidgetDisplayRect, /* widget_display_rect */
|
|
NULL, /* widget_margins */
|
|
};
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfePrimitive translations */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static char default_translations[] ="\
|
|
c<Btn1Down>: Focus()\n\
|
|
:<Key>osfHelp: Help()\n\
|
|
<Enter>: Enter()\n\
|
|
<Leave>: Leave()";
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfePrimitive widget class record initialization */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
_XFE_WIDGET_CLASS_RECORD(primitive,Primitive) =
|
|
{
|
|
{
|
|
/* Core Part */
|
|
(WidgetClass) &xmPrimitiveClassRec, /* superclass */
|
|
"XfePrimitive", /* class_name */
|
|
sizeof(XfePrimitiveRec), /* widget_size */
|
|
ClassInitialize, /* class_initialize */
|
|
ClassPartInit, /* class_part_initiali */
|
|
FALSE, /* class_inited */
|
|
Initialize, /* initialize */
|
|
NULL, /* initialize_hook */
|
|
Realize, /* realize */
|
|
actions, /* actions */
|
|
XtNumber(actions), /* num_actions */
|
|
(XtResource *)resources, /* resources */
|
|
XtNumber(resources), /* num_resources */
|
|
NULLQUARK, /* xrm_class */
|
|
TRUE, /* compress_motion */
|
|
XtExposeCompressMaximal, /* compress_exposure */
|
|
TRUE, /* compress_enterleave */
|
|
FALSE, /* visible_interest */
|
|
Destroy, /* destroy */
|
|
Resize, /* resize */
|
|
Redisplay, /* expose */
|
|
SetValues, /* set_values */
|
|
NULL, /* set_values_hook */
|
|
XtInheritSetValuesAlmost, /* set_values_almost */
|
|
NULL, /* get_values_hook */
|
|
NULL, /* accept_focus */
|
|
XtVersion, /* version */
|
|
NULL, /* callback_private */
|
|
default_translations, /* tm_table */
|
|
QueryGeometry, /* query_geometry */
|
|
XtInheritDisplayAccelerator, /* display accel */
|
|
NULL, /* extension */
|
|
},
|
|
|
|
/* XmPrimitive Part */
|
|
{
|
|
XmInheritBorderHighlight, /* border_highlight */
|
|
XmInheritBorderUnhighlight, /* border_unhighlight */
|
|
XtInheritTranslations, /* translations */
|
|
NULL, /* arm_and_activate */
|
|
(XmSyntheticResource *)syn_resources, /* syn resources */
|
|
XtNumber(syn_resources), /* num syn_resources */
|
|
(XtPointer) &primClassExtRec, /* extension */
|
|
},
|
|
|
|
/* XfePrimitive Part */
|
|
{
|
|
ForgetGravity, /* bit_gravity */
|
|
PreferredGeometry, /* preferred_geometry */
|
|
UpdateBoundary, /* update_boundary */
|
|
NULL, /* prepare_components */
|
|
NULL, /* layout_components */
|
|
NULL, /* draw_background */
|
|
DrawShadow, /* draw_shadow */
|
|
NULL, /* draw_components */
|
|
NULL /* extension */
|
|
}
|
|
};
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* xfePrimitiveWidgetClass declaration. */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
_XFE_WIDGET_CLASS(primitive,Primitive);
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* Rep type registration functions */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
PrimitiveRegisterRepTypes(void)
|
|
{
|
|
static String buffer_names[] =
|
|
{
|
|
"buffer_shared",
|
|
"buffer_none",
|
|
"buffer_private",
|
|
NULL
|
|
};
|
|
|
|
XfeRepTypeRegister(XmRBufferType,buffer_names);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* Core Class Methods */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
ClassInitialize()
|
|
{
|
|
/* Register Xfe Converters */
|
|
XfeRegisterConverters();
|
|
|
|
/* Register XfePrimitive Types */
|
|
PrimitiveRegisterRepTypes();
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
ClassPartInit(WidgetClass wc)
|
|
{
|
|
XfePrimitiveWidgetClass cc = (XfePrimitiveWidgetClass) wc;
|
|
XfePrimitiveWidgetClass sc = (XfePrimitiveWidgetClass) wc->core_class.superclass;
|
|
|
|
/* Resolve inheritance of all XfePrimitive class methods */
|
|
_XfeResolve(cc,sc,xfe_primitive_class,bit_gravity,
|
|
XfeInheritBitGravity);
|
|
|
|
_XfeResolve(cc,sc,xfe_primitive_class,preferred_geometry,
|
|
XfeInheritPreferredGeometry);
|
|
|
|
_XfeResolve(cc,sc,xfe_primitive_class,update_boundary,
|
|
XfeInheritUpdateBoundary);
|
|
|
|
_XfeResolve(cc,sc,xfe_primitive_class,layout_components,
|
|
XfeInheritLayoutComponents);
|
|
|
|
_XfeResolve(cc,sc,xfe_primitive_class,draw_background,
|
|
XfeInheritDrawBackground);
|
|
|
|
_XfeResolve(cc,sc,xfe_primitive_class,draw_shadow,
|
|
XfeInheritDrawShadow);
|
|
|
|
_XfeResolve(cc,sc,xfe_primitive_class,draw_components,
|
|
XfeInheritDrawComponents);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
Initialize(Widget rw,Widget nw,ArgList args,Cardinal *nargs)
|
|
{
|
|
/* Make sure the shadow is ok */
|
|
XfeRepTypeCheck(nw,XmRShadowType,&_XfeShadowType(nw),XmSHADOW_OUT);
|
|
|
|
/* Make sure the buffer is ok */
|
|
XfeRepTypeCheck(nw,XmRBufferType,&_XfeBufferType(nw),XmBUFFER_NONE);
|
|
|
|
/* Initialize private members */
|
|
_XfeBufferPixmap(nw) = XmUNSPECIFIED_PIXMAP;
|
|
_XfeBackgroundGC(nw) = NULL;
|
|
|
|
/* Allocate the background gc if needed */
|
|
if (_XfeBufferType(nw) != XmBUFFER_NONE)
|
|
{
|
|
_XfePrimitiveAllocateBackgroundGC(nw);
|
|
}
|
|
|
|
/* Finish initialization */
|
|
_XfePrimitiveChainInitialize(rw,nw,xfePrimitiveWidgetClass);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
Destroy(Widget w)
|
|
{
|
|
/* Remove all CallBacks */
|
|
/* XtRemoveAllCallbacks(w,XmNenterCallback); */
|
|
/* XtRemoveAllCallbacks(w,XmNfocusCallback); */
|
|
/* XtRemoveAllCallbacks(w,XmNleaveCallback); */
|
|
/* XtRemoveAllCallbacks(w,XmNresizeCallback); */
|
|
|
|
/* Free or release a possible buffer */
|
|
BufferFree(w);
|
|
|
|
/* Free background gc if needed */
|
|
if (_XfeBackgroundGC(w))
|
|
{
|
|
_XfePrimitiveReleaseBackgroundGC(w);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
Redisplay(Widget w,XEvent *event,Region region)
|
|
{
|
|
/* Make sure the widget is realized before drawing ! */
|
|
if (!XtIsRealized(w))
|
|
{
|
|
return;
|
|
}
|
|
|
|
switch(_XfeBufferType(w))
|
|
{
|
|
/* No buffer: simply re-draw everything */
|
|
case XmBUFFER_NONE:
|
|
_XfePrimitiveDrawEverything(w,event,region);
|
|
break;
|
|
|
|
/* Single buffer: draw the buffer only */
|
|
case XmBUFFER_PRIVATE:
|
|
_XfePrimitiveDrawBuffer(w,event,region);
|
|
break;
|
|
|
|
/* Multiple buffer: update the buffer and draw it */
|
|
case XmBUFFER_SHARED:
|
|
_XfePrimitiveDrawEverything(w,event,region);
|
|
_XfePrimitiveDrawBuffer(w,event,region);
|
|
break;
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
Realize(Widget w,XtValueMask * mask,XSetWindowAttributes* wa)
|
|
{
|
|
XSetWindowAttributes attr;
|
|
|
|
/* Make sure only subclasses of XfePrimitive get instanciated */
|
|
if ((XtClass(w) == xfePrimitiveWidgetClass))
|
|
{
|
|
_XfeWarning(w,MESSAGE0);
|
|
|
|
return;
|
|
}
|
|
|
|
/* Let XmPrimitive create the window */
|
|
(*xmPrimitiveWidgetClass->core_class.realize)(w,mask,wa);
|
|
|
|
/* Set the Bit Gravity */
|
|
attr.bit_gravity = _XfePrimitiveAccessBitGravity(w);
|
|
|
|
XChangeWindowAttributes(XtDisplay(w),_XfeWindow(w),CWBitGravity,&attr);
|
|
|
|
/* Define the cursor if needed */
|
|
if (_XfeCursorGood(_XfeCursor(w)) && _XfePointerInside(w))
|
|
{
|
|
XfeCursorDefine(w,_XfeCursor(w));
|
|
}
|
|
|
|
/* invoke realize callbacks */
|
|
_XfeInvokeCallbacks(w,_XfeRealizeCallbacks(w),XmCR_REALIZE,NULL,True);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
Resize(Widget w)
|
|
{
|
|
/*printf("%s: Resize to (%d,%d)\n",XtName(w),_XfeWidth(w),_XfeHeight(w));*/
|
|
|
|
/* Obtain the Prefered Geometry */
|
|
_XfePrimitivePreferredGeometry(w,
|
|
&_XfePreferredWidth(w),
|
|
&_XfePreferredHeight(w));
|
|
|
|
/* Force the preferred dimensions if required */
|
|
if (_XfeUsePreferredWidth(w))
|
|
{
|
|
_XfeWidth(w) = _XfePreferredWidth(w);
|
|
}
|
|
|
|
if (_XfeUsePreferredHeight(w))
|
|
{
|
|
_XfeHeight(w) = _XfePreferredHeight(w);
|
|
}
|
|
|
|
/* Update the widget boundary */
|
|
_XfePrimitiveUpdateBoundary(w);
|
|
|
|
/* Layout the components */
|
|
_XfePrimitiveLayoutComponents(w);
|
|
|
|
switch(_XfeBufferType(w))
|
|
{
|
|
/* No buffer: nothing */
|
|
case XmBUFFER_NONE:
|
|
break;
|
|
|
|
/* Single buffer: update the buffer size and contents */
|
|
case XmBUFFER_PRIVATE:
|
|
BufferUpdate(w);
|
|
_XfePrimitiveDrawEverything(w,NULL,NULL);
|
|
break;
|
|
|
|
/* Multiple buffer: update the buffer size only */
|
|
case XmBUFFER_SHARED:
|
|
BufferUpdate(w);
|
|
break;
|
|
}
|
|
|
|
/* Invoke Resize Callbacks */
|
|
_XfeInvokeCallbacks(w,_XfeResizeCallbacks(w),XmCR_RESIZE,NULL,True);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static XtGeometryResult
|
|
QueryGeometry(Widget w,XtWidgetGeometry *req,XtWidgetGeometry *reply)
|
|
{
|
|
assert( req != NULL );
|
|
assert( reply != NULL );
|
|
|
|
reply->request_mode = CWWidth | CWHeight;
|
|
|
|
/* Set the reply dimensions */
|
|
reply->width = GetWidth(w);
|
|
|
|
reply->height = GetHeight(w);
|
|
|
|
/* XtGeometryYes: Request matches Prefered Geometry. */
|
|
if (((req->request_mode & CWWidth) && (req->width == reply->width)) &&
|
|
((req->request_mode & CWHeight) && (req->height == reply->height)))
|
|
{
|
|
return XtGeometryYes;
|
|
}
|
|
|
|
/* XtGeometryNo: Reply matches current Geometry. */
|
|
if ((reply->width == _XfeWidth(w)) && (reply->height == _XfeHeight(w)))
|
|
{
|
|
return XtGeometryNo;
|
|
}
|
|
|
|
/* XtGeometryAlmost: One of reply fields doesn't match cur/req Geometry. */
|
|
return XtGeometryAlmost;
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static Boolean
|
|
SetValues(Widget ow,Widget rw,Widget nw,ArgList args,Cardinal *nargs)
|
|
{
|
|
/* Reset the configuration Flags */
|
|
_XfeConfigFlags(nw) = XfeConfigNone;
|
|
|
|
/* Reset the preparation Flags */
|
|
_XfePrepareFlags(nw) = XfePrepareNone;
|
|
|
|
/* buffer_type */
|
|
if (_XfeBufferType(nw) != _XfeBufferType(ow))
|
|
{
|
|
_XfeBufferType(nw) = _XfeBufferType(ow);
|
|
|
|
_XfeWarning(nw,MESSAGE7);
|
|
}
|
|
|
|
/* preferred_height */
|
|
if (_XfePreferredHeight(nw) != _XfePreferredHeight(ow))
|
|
{
|
|
_XfePreferredHeight(nw) = _XfePreferredHeight(ow);
|
|
|
|
_XfeWarning(nw,MESSAGE2);
|
|
}
|
|
|
|
/* preferred_width */
|
|
if (_XfePreferredWidth(nw) != _XfePreferredWidth(ow))
|
|
{
|
|
_XfePreferredWidth(nw) = _XfePreferredWidth(ow);
|
|
|
|
_XfeWarning(nw,MESSAGE3);
|
|
}
|
|
|
|
/* pointer_inside */
|
|
if (_XfePointerInside(nw) != _XfePointerInside(ow))
|
|
{
|
|
_XfePointerInside(nw) = _XfePointerInside(ow);
|
|
|
|
_XfeWarning(nw,MESSAGE4);
|
|
}
|
|
|
|
/* num_popups */
|
|
if (_XfeNumPopups(nw) != _XfeNumPopups(ow))
|
|
{
|
|
_XfeNumPopups(nw) = _XfeNumPopups(ow);
|
|
|
|
_XfeWarning(nw,MESSAGE5);
|
|
}
|
|
|
|
/* popup_list */
|
|
if (_XfePopupList(nw) != _XfePopupList(ow))
|
|
{
|
|
_XfePopupList(nw) = _XfePopupList(ow);
|
|
|
|
_XfeWarning(nw,MESSAGE6);
|
|
}
|
|
|
|
/* resize_width */
|
|
if (_XfeUsePreferredWidth(nw) != _XfeUsePreferredWidth(ow))
|
|
{
|
|
if(_XfeUsePreferredWidth(nw))
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigGLE;
|
|
}
|
|
}
|
|
|
|
/* resize_height */
|
|
if (_XfeUsePreferredHeight(nw) != _XfeUsePreferredHeight(ow))
|
|
{
|
|
if(_XfeUsePreferredHeight(nw))
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigGLE;
|
|
}
|
|
}
|
|
|
|
/* height */
|
|
if (_XfeHeight(nw) != _XfeHeight(ow))
|
|
{
|
|
/* if resize_heigh is True, we dont allow width changes */
|
|
if (_XfeUsePreferredHeight(nw))
|
|
{
|
|
_XfeHeight(nw) = _XfeHeight(ow);
|
|
}
|
|
else
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigLE;
|
|
}
|
|
}
|
|
|
|
/* width */
|
|
if (_XfeWidth(nw) != _XfeWidth(ow))
|
|
{
|
|
/* if resize_width is True, we dont allow width changes */
|
|
if (_XfeUsePreferredWidth(nw))
|
|
{
|
|
_XfeWidth(nw) = _XfeWidth(ow);
|
|
}
|
|
else
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigLE;
|
|
}
|
|
}
|
|
|
|
/* cursor */
|
|
if (_XfeCursor(nw) != _XfeCursor(ow))
|
|
{
|
|
/* If the new cursor is good, define it */
|
|
if (_XfeCursorGood(_XfeCursor(nw)))
|
|
{
|
|
XfeCursorDefine(nw,_XfeCursor(nw));
|
|
}
|
|
else
|
|
{
|
|
XfeCursorUndefine(nw);
|
|
}
|
|
}
|
|
|
|
/* Changes that affect the layout and geometry */
|
|
if ((_XfeHighlightThickness(nw) != _XfeHighlightThickness(ow)) ||
|
|
(_XfeMarginTop(nw) != _XfeMarginTop(ow)) ||
|
|
(_XfeMarginBottom(nw) != _XfeMarginBottom(ow)) ||
|
|
(_XfeMarginLeft(nw) != _XfeMarginLeft(ow)) ||
|
|
(_XfeMarginRight(nw) != _XfeMarginRight(ow)) ||
|
|
(_XfeShadowThickness(nw) != _XfeShadowThickness(ow)) ||
|
|
(_XfeUnitType(nw) != _XfeUnitType(ow)))
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigGLE;
|
|
}
|
|
|
|
/* shadow_type */
|
|
if (_XfeShadowType(nw) != _XfeShadowType(ow))
|
|
{
|
|
/* Make sure the new shadow type is ok */
|
|
XfeRepTypeCheck(nw,XmRShadowType,&_XfeShadowType(nw),XmSHADOW_OUT);
|
|
|
|
_XfeConfigFlags(nw) |= XfeConfigExpose;
|
|
}
|
|
|
|
/* sensitive */
|
|
if (_XfeSensitive(nw) != _XfeSensitive(ow))
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigExpose;
|
|
}
|
|
|
|
/* pretend_sensitive */
|
|
if (_XfePretendSensitive(nw) != _XfePretendSensitive(ow))
|
|
{
|
|
_XfeConfigFlags(nw) |= XfeConfigExpose;
|
|
}
|
|
|
|
/* background_pixel or background_pixmap */
|
|
if (_XfeBackgroundPixel(nw) != _XfeBackgroundPixel(ow) ||
|
|
_XfeBackgroundPixmap(nw) != _XfeBackgroundPixmap(ow))
|
|
{
|
|
/* Update the old background GC if needed */
|
|
if (_XfeBufferType(nw) != XmBUFFER_NONE)
|
|
{
|
|
_XfePrimitiveUpdateBackgroundGC(nw);
|
|
}
|
|
}
|
|
|
|
return _XfePrimitiveChainSetValues(ow,rw,nw,xfePrimitiveWidgetClass);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XmPrimitive Extension Methods */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static Boolean
|
|
WidgetDisplayRect(Widget w,XRectangle *rect)
|
|
{
|
|
rect->x = _XfeBoundaryX(w);
|
|
rect->y = _XfeBoundaryY(w);
|
|
rect->height = _XfeBoundaryHeight(w);
|
|
rect->width = _XfeBoundaryWidth(w);
|
|
|
|
return (rect->width && rect->height);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfePrimitive Class Methods */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
InitializePostHook(Widget rw,Widget nw)
|
|
{
|
|
/* Set preparation flag so that all components get prepared */
|
|
_XfePrepareFlags(nw) = XfePrepareAll;
|
|
|
|
/* Prepare the Widget */
|
|
_XfePrimitivePrepareComponents(nw,_XfePrepareFlags(nw));
|
|
|
|
/* Obtain the preferred dimensions for the first time. */
|
|
_XfePrimitivePreferredGeometry(nw,
|
|
&_XfePreferredWidth(nw),
|
|
&_XfePreferredHeight(nw));
|
|
|
|
/* Set the new dimensions */
|
|
_XfeWidth(nw) = GetWidth(nw);
|
|
|
|
_XfeHeight(nw) = GetHeight(nw);
|
|
|
|
/* Update the widget boundary */
|
|
_XfePrimitiveUpdateBoundary(nw);
|
|
|
|
/* Layout the Widget */
|
|
_XfePrimitiveLayoutComponents(nw);
|
|
|
|
switch(_XfeBufferType(nw))
|
|
{
|
|
/* No buffer: nothing */
|
|
case XmBUFFER_NONE:
|
|
break;
|
|
|
|
/* Single buffer: update the buffer size and contents */
|
|
case XmBUFFER_PRIVATE:
|
|
BufferUpdate(nw);
|
|
_XfePrimitiveDrawEverything(nw,NULL,NULL);
|
|
break;
|
|
|
|
/* Multiple buffer: update the buffer size only */
|
|
case XmBUFFER_SHARED:
|
|
BufferUpdate(nw);
|
|
break;
|
|
}
|
|
|
|
/* Dont need to prepare components any more */
|
|
_XfePrepareFlags(nw) = XfePrepareNone;
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static Boolean
|
|
SetValuesPostHook(Widget ow,Widget rw,Widget nw)
|
|
{
|
|
Boolean result = False;
|
|
|
|
/* Prepare the widget components if needed */
|
|
if (_XfePrepareFlags(nw))
|
|
{
|
|
_XfePrimitivePrepareComponents(nw,_XfePrepareFlags(nw));
|
|
}
|
|
|
|
/* Update the widget's geometry if needed */
|
|
if (_XfeConfigFlags(nw) & XfeConfigGeometry)
|
|
{
|
|
/* Obtain the preferred dimensions */
|
|
_XfePrimitivePreferredGeometry(nw,
|
|
&_XfePreferredWidth(nw),
|
|
&_XfePreferredHeight(nw));
|
|
|
|
/* Set the new dimensions */
|
|
_XfeWidth(nw) = GetWidth(nw);
|
|
|
|
_XfeHeight(nw) = GetHeight(nw);
|
|
}
|
|
|
|
/* Update the widget boundary */
|
|
_XfePrimitiveUpdateBoundary(nw);
|
|
|
|
/* Layout the Widget if needed */
|
|
if (_XfeConfigFlags(nw) & XfeConfigLayout)
|
|
{
|
|
_XfePrimitiveLayoutComponents(nw);
|
|
|
|
switch(_XfeBufferType(nw))
|
|
{
|
|
/* No buffer: nothing */
|
|
case XmBUFFER_NONE:
|
|
break;
|
|
|
|
/* Single buffer: update the buffer size and contents */
|
|
case XmBUFFER_PRIVATE:
|
|
BufferUpdate(nw);
|
|
_XfePrimitiveDrawEverything(nw,NULL,NULL);
|
|
break;
|
|
|
|
/* Multiple buffer: update the buffer size only */
|
|
case XmBUFFER_SHARED:
|
|
BufferUpdate(nw);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Draw everything (into the buffer) */
|
|
if (_XfeBufferType(nw) != XmBUFFER_NONE)
|
|
{
|
|
if ((_XfeConfigFlags(nw) & XfeConfigLayout) ||
|
|
(_XfeConfigFlags(nw) & XfeConfigExpose))
|
|
{
|
|
/* Redraw the buffer */
|
|
_XfePrimitiveDrawEverything(nw,NULL,NULL);
|
|
|
|
/* Draw the buffer onto the window */
|
|
XfeExpose(nw,NULL,NULL);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result = (_XfeConfigFlags(nw) & XfeConfigExpose);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
PreferredGeometry(Widget w,Dimension *width,Dimension *height)
|
|
{
|
|
*width = _XfeOffsetLeft(w) + _XfeOffsetRight(w);
|
|
*height = _XfeOffsetTop(w) + _XfeOffsetBottom(w);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
DrawShadow(Widget w,XEvent * event,Region region,XRectangle * clip_rect)
|
|
{
|
|
/* Draw the shadow */
|
|
_XmDrawShadows(XtDisplay(w),
|
|
_XfePrimitiveDrawable(w),
|
|
_XfeTopShadowGC(w),_XfeBottomShadowGC(w),
|
|
_XfeHighlightThickness(w),
|
|
_XfeHighlightThickness(w),
|
|
_XfeWidth(w) - 2 * _XfeHighlightThickness(w),
|
|
_XfeHeight(w) - 2 * _XfeHighlightThickness(w),
|
|
_XfeShadowThickness(w),
|
|
_XfeShadowType(w));
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
UpdateBoundary(Widget w)
|
|
{
|
|
/* Assign the rect coordinates */
|
|
XfeRectSet(&_XfeBoundary(w),
|
|
|
|
_XfeOffsetLeft(w),
|
|
|
|
_XfeOffsetTop(w),
|
|
|
|
_XfeWidth(w) - _XfeOffsetLeft(w) - _XfeOffsetRight(w),
|
|
|
|
_XfeHeight(w) - _XfeOffsetTop(w) - _XfeOffsetBottom(w));
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfePrimitive Buffer Pixmap functions */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
BufferAllocate(Widget w)
|
|
{
|
|
assert( _XfeBufferType(w) != XmBUFFER_NONE );
|
|
|
|
switch(_XfeBufferType(w))
|
|
{
|
|
/* Single buffer: allocate a buffer big enough for widget */
|
|
case XmBUFFER_PRIVATE:
|
|
|
|
_XfeBufferPixmap(w) = XCreatePixmap(XtDisplay(w),
|
|
DefaultRootWindow(XtDisplay(w)),
|
|
_XfeWidth(w),
|
|
_XfeHeight(w),
|
|
_XfeDepth(w));
|
|
|
|
|
|
#if 0
|
|
printf("%s: Allocating a private buffer at (%d,%d)\n",
|
|
XtName(w),
|
|
_XfeWidth(w),_XfeHeight(w));
|
|
#endif
|
|
|
|
break;
|
|
|
|
/* Multiple buffer: ask the buffer manager for a buffer */
|
|
case XmBUFFER_SHARED:
|
|
|
|
#if 0
|
|
printf("%s: Allocating a shared buffer at (%d,%d)\n",
|
|
XtName(w),
|
|
_XfeWidth(w),_XfeHeight(w));
|
|
#endif
|
|
|
|
_XfeBufferPixmap(w) = _XfePixmapBufferAllocate(w);
|
|
|
|
break;
|
|
}
|
|
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
BufferFree(Widget w)
|
|
{
|
|
/*if (_XfeBufferType(w) != XmBUFFER_NONE );*/
|
|
|
|
switch(_XfeBufferType(w))
|
|
{
|
|
/* Single buffer: Free the buffer pixmap only if needed */
|
|
case XmBUFFER_PRIVATE:
|
|
|
|
if (_XfePixmapGood(_XfeBufferPixmap(w)))
|
|
{
|
|
XFreePixmap(XtDisplay(w),_XfeBufferPixmap(w));
|
|
}
|
|
|
|
break;
|
|
|
|
/* Multiple buffer: release the shared buffer */
|
|
case XmBUFFER_SHARED:
|
|
|
|
/*_XfePixmapBufferRelease(w,_XfeBufferPixmap(w));*/
|
|
|
|
break;
|
|
|
|
/* Nothing */
|
|
case XmBUFFER_NONE:
|
|
break;
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void
|
|
BufferUpdate(Widget w)
|
|
{
|
|
assert( _XfeBufferType(w) != XmBUFFER_NONE );
|
|
|
|
BufferFree(w);
|
|
BufferAllocate(w);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* Misc XfePrimitive functions */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
/*
|
|
* The preferred width is computed as follows. The criteria is listed in
|
|
* order of precedence.
|
|
*
|
|
* min_width := (2 * shadow + 2 * highlight) - this is the min
|
|
* width set by the
|
|
* XmPrimitive class'
|
|
* Initialize()
|
|
*
|
|
* default_width := XfeDEFAULT_PREFERRED_WIDTH - Defined to 0 (zero)
|
|
*
|
|
*
|
|
* 1. If (XmNusePreferredWidth == true) then force the preferred width
|
|
*
|
|
* 2. If (XmNusePreferredWidth == false) and
|
|
* (width == XfeDEFAULT_PREFERRED_WIDTH) or (width <= min_width)
|
|
* then force the preferred width.
|
|
*
|
|
* 3. If (XmNusePreferredWidth == false) and (width > min_width) then
|
|
* use the dimension given by w->core.width;
|
|
*
|
|
* The same logic applies to the height. This assumes the preferred
|
|
* width is something reasonable; but that is up to the subclasses.
|
|
*
|
|
*/
|
|
|
|
static Dimension
|
|
GetWidth(Widget w)
|
|
{
|
|
Dimension min_width;
|
|
Dimension width;
|
|
|
|
/* Compute the min possible width */
|
|
min_width = 2 * _XfeHighlightThickness(w) + 2 * _XfeShadowThickness(w);
|
|
|
|
/* A reasonable preferred width is needed */
|
|
assert( _XfePreferredWidth(w) > 0 );
|
|
assert( _XfePreferredWidth(w) >= min_width );
|
|
|
|
/* Force the preferred width if needed */
|
|
if (_XfeUsePreferredWidth(w) ||
|
|
(_XfeWidth(w) == XfeDEFAULT_PREFERRED_WIDTH) ||
|
|
(_XfeWidth(w) <= min_width))
|
|
{
|
|
width = _XfePreferredWidth(w);
|
|
}
|
|
else
|
|
{
|
|
width = _XfeWidth(w);
|
|
}
|
|
|
|
return width;
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static Dimension
|
|
GetHeight(Widget w)
|
|
{
|
|
Dimension min_height;
|
|
Dimension height;
|
|
|
|
/* Compute the min possible height */
|
|
min_height = 2 * _XfeHighlightThickness(w) + 2 * _XfeShadowThickness(w);
|
|
|
|
/* A reasonable preferred height is needed */
|
|
assert( _XfePreferredHeight(w) > 0 );
|
|
assert( _XfePreferredHeight(w) >= min_height );
|
|
|
|
/* Force the preferred height if needed */
|
|
if (_XfeUsePreferredHeight(w) ||
|
|
(_XfeHeight(w) == XfeDEFAULT_PREFERRED_HEIGHT) ||
|
|
(_XfeHeight(w) <= min_height))
|
|
{
|
|
height = _XfePreferredHeight(w);
|
|
}
|
|
else
|
|
{
|
|
height = _XfeHeight(w);
|
|
}
|
|
|
|
return height;
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfePrimitive Method invocation functions */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfePrimitivePreferredGeometry(Widget w,Dimension *width,Dimension *height)
|
|
{
|
|
XfePrimitiveWidgetClass pc = (XfePrimitiveWidgetClass) XtClass(w);
|
|
|
|
if (pc->xfe_primitive_class.preferred_geometry)
|
|
{
|
|
(*pc->xfe_primitive_class.preferred_geometry)(w,width,height);
|
|
}
|
|
|
|
/* Make sure preferred width is greater than zero */
|
|
if (*width == 0)
|
|
{
|
|
*width = XfePRIMITIVE_DEFAULT_WIDTH;
|
|
}
|
|
|
|
/* Make sure preferred height is greater than zero */
|
|
if (*height == 0)
|
|
{
|
|
*height = XfePRIMITIVE_DEFAULT_HEIGHT;
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfePrimitivePrepareComponents(Widget w,int flags)
|
|
{
|
|
WidgetClass cc;
|
|
XfePrimitiveWidgetClass pc;
|
|
Cardinal i;
|
|
Cardinal count;
|
|
|
|
/* Someone has to be nuts to have more than 32 subclasses... */
|
|
static XfePrepareProc proc_table[32];
|
|
|
|
/* Traverse all classes until we find XmPrimitive */
|
|
for (cc = XtClass(w),count = 0;
|
|
cc != xmPrimitiveWidgetClass;
|
|
cc = cc->core_class.superclass)
|
|
{
|
|
pc = (XfePrimitiveWidgetClass) cc;
|
|
|
|
/* Add the method to the table as long as it is not NULL */
|
|
if (pc->xfe_primitive_class.prepare_components)
|
|
{
|
|
proc_table[count++] = pc->xfe_primitive_class.prepare_components;
|
|
}
|
|
}
|
|
|
|
/* Invoke the methods in reverse order */
|
|
for (i = count; i; i--)
|
|
{
|
|
XfePrepareProc proc = proc_table[i - 1];
|
|
|
|
/* Invoke the prepare components method for this class */
|
|
(*proc)(w,flags);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfePrimitiveUpdateBoundary(Widget w)
|
|
{
|
|
XfePrimitiveWidgetClass pc = (XfePrimitiveWidgetClass) XtClass(w);
|
|
|
|
if (pc->xfe_primitive_class.update_boundary)
|
|
{
|
|
(*pc->xfe_primitive_class.update_boundary)(w);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfePrimitiveLayoutComponents(Widget w)
|
|
{
|
|
XfePrimitiveWidgetClass pc = (XfePrimitiveWidgetClass) XtClass(w);
|
|
|
|
if (pc->xfe_primitive_class.layout_components)
|
|
{
|
|
(*pc->xfe_primitive_class.layout_components)(w);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfePrimitiveDrawBackground(Widget w,
|
|
XEvent * event,
|
|
Region region,
|
|
XRectangle * clip_rect)
|
|
{
|
|
XfePrimitiveWidgetClass pc = (XfePrimitiveWidgetClass) XtClass(w);
|
|
|
|
if (pc->xfe_primitive_class.draw_background)
|
|
{
|
|
(*pc->xfe_primitive_class.draw_background)(w,event,region,clip_rect);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfePrimitiveDrawComponents(Widget w,
|
|
XEvent * event,
|
|
Region region,
|
|
XRectangle * clip_rect)
|
|
{
|
|
XfePrimitiveWidgetClass pc = (XfePrimitiveWidgetClass) XtClass(w);
|
|
|
|
if (pc->xfe_primitive_class.draw_components)
|
|
{
|
|
(*pc->xfe_primitive_class.draw_components)(w,event,region,clip_rect);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfePrimitiveDrawShadow(Widget w,
|
|
XEvent * event,
|
|
Region region,
|
|
XRectangle * rect)
|
|
{
|
|
XfePrimitiveWidgetClass pc = (XfePrimitiveWidgetClass) XtClass(w);
|
|
|
|
if (pc->xfe_primitive_class.draw_shadow)
|
|
{
|
|
(*pc->xfe_primitive_class.draw_shadow)(w,event,region,rect);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfePrimitiveBorderHighlight(Widget w)
|
|
{
|
|
XmPrimitiveWidgetClass pc = (XmPrimitiveWidgetClass) XtClass(w);
|
|
|
|
if (pc->primitive_class.border_highlight)
|
|
{
|
|
(*pc->primitive_class.border_highlight)(w);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfePrimitiveBorderUnhighlight(Widget w)
|
|
{
|
|
XmPrimitiveWidgetClass pc = (XmPrimitiveWidgetClass) XtClass(w);
|
|
|
|
if (pc->primitive_class.border_unhighlight)
|
|
{
|
|
(*pc->primitive_class.border_unhighlight)(w);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* Private XfePrimitive functions */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfePrimitiveChainInitialize(Widget rw,Widget nw,WidgetClass wc)
|
|
{
|
|
assert( nw != NULL );
|
|
|
|
if (XtClass(nw) == wc)
|
|
{
|
|
InitializePostHook(rw,nw);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ Boolean
|
|
_XfePrimitiveChainSetValues(Widget ow,Widget rw,Widget nw,WidgetClass wc)
|
|
{
|
|
assert( nw != NULL );
|
|
|
|
if (XtClass(nw) == wc)
|
|
{
|
|
return SetValuesPostHook(ow,rw,nw);
|
|
}
|
|
|
|
return False;
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ Drawable
|
|
_XfePrimitiveDrawable(Widget w)
|
|
{
|
|
Drawable d = None;
|
|
|
|
switch(_XfeBufferType(w))
|
|
{
|
|
case XmBUFFER_NONE:
|
|
d = _XfeWindow(w);
|
|
break;
|
|
|
|
case XmBUFFER_PRIVATE:
|
|
d = _XfeBufferPixmap(w);
|
|
break;
|
|
|
|
case XmBUFFER_SHARED:
|
|
d = _XfePixmapBufferAccess();
|
|
break;
|
|
}
|
|
|
|
return d;
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfePrimitiveDrawEverything(Widget w,XEvent * event,Region region)
|
|
{
|
|
static XRectangle rect;
|
|
|
|
/* Clear the buffer background if needed */
|
|
if (_XfeBufferType(w) != XmBUFFER_NONE)
|
|
{
|
|
_XfePrimitiveClearBackground(w);
|
|
}
|
|
|
|
/* Draw Background */
|
|
XfeRectSet(&rect,
|
|
_XfeBoundaryX(w) - _XfeMarginLeft(w),
|
|
_XfeBoundaryY(w) - _XfeMarginTop(w),
|
|
_XfeBoundaryWidth(w) + _XfeMarginLeft(w) + _XfeMarginRight(w),
|
|
_XfeBoundaryHeight(w) + _XfeMarginTop(w) + _XfeMarginBottom(w));
|
|
|
|
_XfePrimitiveDrawBackground(w,event,region,&rect);
|
|
|
|
/* Draw -or Erase the Widget's highlight if needed */
|
|
if (_XfeHighlighted(w) && _XfeHighlightThickness(w))
|
|
{
|
|
_XfePrimitiveBorderHighlight(w);
|
|
}
|
|
else
|
|
{
|
|
_XfePrimitiveBorderUnhighlight(w);
|
|
}
|
|
|
|
/* Draw Shadow */
|
|
_XfePrimitiveDrawShadow(w,event,region,&_XfeBoundary(w));
|
|
|
|
/* Draw Components */
|
|
_XfePrimitiveDrawComponents(w,event,region,&_XfeBoundary(w));
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfePrimitiveClearBackground(Widget w)
|
|
{
|
|
/* Clear the widget background including margins */
|
|
if (_XfeBufferType(w) == XmBUFFER_NONE)
|
|
{
|
|
XClearArea(XtDisplay(w),_XfeWindow(w),
|
|
_XfeHighlightThickness(w),_XfeHighlightThickness(w),
|
|
_XfeWidth(w) - 2 * _XfeHighlightThickness(w),
|
|
_XfeHeight(w) - 2 * _XfeHighlightThickness(w),
|
|
False);
|
|
|
|
/*XClearWindow(XtDisplay(w),_XfeWindow(w));*/
|
|
}
|
|
else
|
|
{
|
|
XFillRectangle(XtDisplay(w),
|
|
_XfePrimitiveDrawable(w),
|
|
_XfeBackgroundGC(w),
|
|
0,0,
|
|
_XfeWidth(w),_XfeHeight(w));
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfePrimitiveAllocateBackgroundGC(Widget w)
|
|
{
|
|
#if 0
|
|
/* Make sure the background gc gets allocated only once */
|
|
if (_XfeBackgroundGC(w))
|
|
{
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
assert( _XfeBackgroundGC(w) == NULL );
|
|
|
|
if (_XfePixmapGood(_XfeBackgroundPixmap(w)))
|
|
{
|
|
_XfeBackgroundGC(w) = XfeAllocateTileGc(w,_XfeBackgroundPixmap(w));
|
|
}
|
|
else
|
|
{
|
|
_XfeBackgroundGC(w) = XfeAllocateColorGc(w,_XfeBackgroundPixel(w),
|
|
None,True);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfePrimitiveReleaseBackgroundGC(Widget w)
|
|
{
|
|
#if 0
|
|
/* Make sure the gc has been allocated */
|
|
if (!_XfeBackgroundGC(w))
|
|
{
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
assert( _XfeBackgroundGC(w) != NULL );
|
|
|
|
/* Free the background gc */
|
|
XtReleaseGC(w,_XfeBackgroundGC(w));
|
|
|
|
_XfeBackgroundGC(w) = NULL;
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfePrimitiveUpdateBackgroundGC(Widget w)
|
|
{
|
|
_XfePrimitiveReleaseBackgroundGC(w);
|
|
_XfePrimitiveAllocateBackgroundGC(w);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfePrimitiveDrawBuffer(Widget w,XEvent * event,Region region)
|
|
{
|
|
XCopyArea(XtDisplay(w),
|
|
_XfePrimitiveDrawable(w),
|
|
_XfeWindow(w),
|
|
_XfeBackgroundGC(w),
|
|
_XfeHighlightThickness(w),_XfeHighlightThickness(w),
|
|
_XfeWidth(w) - 2 * _XfeHighlightThickness(w),
|
|
_XfeHeight(w) - 2 * _XfeHighlightThickness(w),
|
|
_XfeHighlightThickness(w),_XfeHighlightThickness(w));
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* XfePrimitive Action Procedures */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfePrimitiveEnter(Widget w,XEvent * event,char ** params,Cardinal * nparams)
|
|
{
|
|
_XfePointerInside(w) = True;
|
|
|
|
/* Make sure we are not pretending to be insensitive */
|
|
if (!_XfeIsSensitive(w))
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Call the XmPrimitive Enter() action */
|
|
_XmPrimitiveEnter(w,event,params,nparams);
|
|
|
|
/* Define the cursor if needed */
|
|
if (_XfeCursorGood(_XfeCursor(w)))
|
|
{
|
|
XfeCursorDefine(w,_XfeCursor(w));
|
|
}
|
|
|
|
/* Call enter callbacks */
|
|
_XfeInvokeCallbacks(w,_XfeEnterCallbacks(w),XmCR_ENTER,event,False);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfePrimitiveLeave(Widget w,XEvent * event,char ** params,Cardinal * nparams)
|
|
{
|
|
/* Make sure the pointer is indeed inside for this action */
|
|
if (!_XfePointerInside(w))
|
|
{
|
|
return;
|
|
}
|
|
|
|
_XfePointerInside(w) = False;
|
|
|
|
/* Make sure we are not pretending to be insensitive */
|
|
if (!_XfeIsSensitive(w))
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Call the XmPrimitive Leave() action */
|
|
_XmPrimitiveLeave(w,event,params,nparams);
|
|
|
|
/* Undefine the cursor if needed */
|
|
if (_XfeCursorGood(_XfeCursor(w)))
|
|
{
|
|
XfeCursorUndefine(w);
|
|
}
|
|
|
|
/* Call leave callbacks */
|
|
_XfeInvokeCallbacks(w,_XfeLeaveCallbacks(w),XmCR_LEAVE,event,False);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
_XfePrimitiveFocus(Widget w,XEvent * event,char ** params,Cardinal * nparams)
|
|
{
|
|
/* Make sure we are not pretending to be insensitive */
|
|
if (!_XfeIsSensitive(w))
|
|
{
|
|
return;
|
|
}
|
|
|
|
XmProcessTraversal(w,XmTRAVERSE_CURRENT);
|
|
|
|
/* Invoke Focus Callbacks */
|
|
_XfeInvokeCallbacks(w,_XfeFocusCallbacks(w),XmCR_FOCUS,event,False);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* */
|
|
/* Public pretend sensitive methods */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ void
|
|
XfeSetPretendSensitive(Widget w,Boolean state)
|
|
{
|
|
assert( _XfeIsAlive(w) );
|
|
assert( XfeIsPrimitive(w) );
|
|
|
|
if (!_XfeIsAlive(w))
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Make sure the state is different */
|
|
if (_XfePretendSensitive(w) == state)
|
|
{
|
|
return;
|
|
}
|
|
|
|
XfeSetValue(w,XmNpretendSensitive,state);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ Boolean
|
|
XfeIsPretendSensitive(Widget w)
|
|
{
|
|
assert( XfeIsPrimitive(w) );
|
|
|
|
if (!_XfeIsAlive(w))
|
|
{
|
|
return False;
|
|
}
|
|
|
|
return _XfePretendSensitive(w);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
/* extern */ Boolean
|
|
XfeIsSensitive(Widget w)
|
|
{
|
|
if (!_XfeIsAlive(w))
|
|
{
|
|
return False;
|
|
}
|
|
|
|
if (XfeIsPrimitive(w))
|
|
{
|
|
return _XfeIsSensitive(w);
|
|
}
|
|
|
|
return _XfeSensitive(w);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
|