/*
* 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 REV_INFO
#ifndef lint
static char rcsid[] = "$TOG: Dog.c /main/7 1997/05/02 10:11:08 dbl $"
#endif
#endif
/*****************************************************************************
*
* Dog.c - Dog widget source file
*
******************************************************************************/
#include <stdio.h>
#include <X11/StringDefs.h>
#include <Xm/XmP.h>
#include <Xm/DrawP.h>
#include "DogP.h"
#ifdef USING_UIL
#include <Mrm/MrmAppl.h>
#endif /* USING_UIL */
#include "up.bm"
#include "down.bm"
#include "bark.bm"
#ifndef MAX
#define MAX(x,y) ((x) > (y) ? (x) : (y))
#endif
#define WagTime(w) XmField(w,offsets,Dog,wag_time, int)
#define BarkTime(w) XmField(w,offsets,Dog,bark_time, int)
#define BarkCallback(w) XmField(w,offsets,Dog,bark_callback,XtCallbackList)
#define UpPixmap(w) XmField(w,offsets,Dog,up_pixmap,Pixmap)
#define DownPixmap(w) XmField(w,offsets,Dog,down_pixmap,Pixmap)
#define BarkPixmap(w) XmField(w,offsets,Dog,bark_pixmap,Pixmap)
#define CurrPixmap(w) XmField(w,offsets,Dog,curr_pixmap,Pixmap)
#define CurrPx(w) XmField(w,offsets,Dog,curr_px,int)
#define Wagging(w) XmField(w,offsets,Dog,wagging,Boolean)
#define Barking(w) XmField(w,offsets,Dog,barking,Boolean)
#define DrawGC(w) XmField(w,offsets,Dog,draw_GC,GC)
#define PixmapX(w) XmField(w,offsets,Dog,pixmap_x,Position)
#define PixmapY(w) XmField(w,offsets,Dog,pixmap_y,Position)
#define DrawX(w) XmField(w,offsets,Dog,draw_x,Position)
#define DrawY(w) XmField(w,offsets,Dog,draw_y,Position)
#define DrawWidth(w) XmField(w,offsets,Dog,draw_width,Dimension)
#define DrawHeight(w) XmField(w,offsets,Dog,draw_height,Dimension)
#define CurrWidth(w) XmField(w,offsets,Dog,curr_width,Dimension)
#define CurrHeight(w) XmField(w,offsets,Dog,curr_height,Dimension)
#define HighlightThickness(w) \
XmField(w,offsets,XmPrimitive,highlight_thickness,Dimension)
#define ShadowThickness(w) \
XmField(w,offsets,XmPrimitive,shadow_thickness,Dimension)
#define Foreground(w) XmField(w,offsets,XmPrimitive,foreground,Pixel)
#define Highlighted(w) XmField(w,offsets,XmPrimitive,highlighted,Boolean)
#define TopShadowGC(w) XmField(w,offsets,XmPrimitive,top_shadow_GC,GC)
#define BottomShadowGC(w) XmField(w,offsets,XmPrimitive,bottom_shadow_GC,GC)
#define BackgroundPixel(w) XmField(w,offsets,Core,background_pixel,Pixel)
#define Width(w) XmField(w,offsets,Core,width,Dimension)
#define Height(w) XmField(w,offsets,Core,height,Dimension)
#define WagId(w) XmField(w,offsets,Dog,wagId,XtIntervalId)
#define BarkId(w) XmField(w,offsets,Dog,barkId,XtIntervalId)
#define SetPixmap(w, px, pixmap, width, height) \
CurrPx(w) = px; CurrPixmap(w) = pixmap; \
CurrWidth(w) = width; CurrHeight(w) = height
#define MakePixmap(b,wd,ht) \
XCreatePixmapFromBitmapData(XtDisplay(w),RootWindowOfScreen(XtScreen(w)), \
(char *)(b), (wd), (ht), Foreground(w), BackgroundPixel(w), \
DefaultDepthOfScreen(XtScreen(w)))
static void ClassInitialize();
static void Initialize();
static void Redisplay();
static void Resize();
static void Destroy();
static Boolean SetValues();
static XtGeometryResult QueryGeometry();
static void bark_dog();
static void end_bark();
static void start_wag();
static void stop_wag();
static void do_wag();
static void create_GC();
static void create_pixmaps();
static void destroy_pixmaps();
static char defaultTranslations[] =
"<Btn1Down>: Bark()\n\
~Shift<Btn2Down>: StartWag()\n\
Shift<Btn2Down>: StopWag()\n\
<Key>Return: Bark()\n\
Ctrl <Key>Return: Bark()\n\
<Key>osfActivate: Bark()\n\
<Key>space: Bark()\n\
Ctrl <Key>space: Bark()\n\
<Key>osfSelect: Bark()\n\
<Key>W: StartWag()\n\
<Key>S: StopWag()\n\
<Key>osfHelp: PrimitiveHelp()";
static XtActionsRec actionsList[] = {
{ "Bark", (XtActionProc) bark_dog},
{ "StartWag", (XtActionProc) start_wag},
{ "StopWag", (XtActionProc) stop_wag}
};
static XmPartResource resources[] = {
{DogNwagTime, DogCWagTime, XtRInt, sizeof(int),
XmPartOffset(Dog,wag_time), XmRImmediate, (caddr_t)100},
{DogNbarkTime, DogCBarkTime, XtRInt, sizeof(int),
XmPartOffset(Dog,bark_time), XmRImmediate, (caddr_t)1000},
{DogNbarkCallback, XtCCallback, XtRCallback, sizeof(caddr_t),
XmPartOffset(Dog,bark_callback), XtRCallback, NULL}
};
DogClassRec dogClassRec = {
{ /* core_class fields */
(WidgetClass) &xmPrimitiveClassRec, /* superclass */
"Dog", /* class_name */
sizeof(DogPart), /* widget_size */
ClassInitialize, /* class_initialize */
NULL, /* class_part_initialize*/
False, /* class_inited */
Initialize, /* initialize */
NULL, /* initialize_notify */
XtInheritRealize, /* realize */
actionsList, /* actions */
XtNumber(actionsList), /* num_actions */
(XtResourceList)resources, /* resources */
XtNumber(resources), /* num_resources */
NULLQUARK, /* xrm_class */
True, /* compress_motion */
True, /* 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 */
XtVersionDontCheck, /* version */
NULL, /* callback_private */
defaultTranslations, /* tm_table */
QueryGeometry, /* query_geometry */
NULL, /* disp accelerator */
NULL /* extension */
},
{ /* primitive_class record */
XmInheritWidgetProc, /* border_highlight */
XmInheritWidgetProc, /* border_unhighlight */
XtInheritTranslations, /* translations */
bark_dog, /* arm_and_activate */
NULL, /* syn resources */
0, /* num syn_resources */
NULL, /* extension */
},
{ /* dog_class record */
NULL, /* extension */
}
};
externaldef(dogwidgetclass) WidgetClass dogWidgetClass =
(WidgetClass) &dogClassRec;
static XmOffsetPtr offsets; /* Part Offset table for XmResolvePartOffsets */
/**********************************************************************
*
* DogCreate - Convenience routine, used by Uil/Mrm.
*
*********************************************************************/
Widget DogCreate(parent, name, arglist, nargs)
Widget parent;
char *name;
Arg *arglist;
int nargs;
{
return(XtCreateWidget (name, dogWidgetClass, parent, arglist, nargs));
}
#ifdef USING_UIL
/**********************************************************************
*
* DogMrmInitialize - register Dog widget class with Mrm
*
*********************************************************************/
int DogMrmInitialize()
{
return(MrmRegisterClass (MrmwcUnknown, "Dog" , "DogCreate", DogCreate,
(WidgetClass)&dogClassRec));
}
#endif /* USING_UIL */
/**********************************************************************
*
* _DogDrawPixmap - draw the current pixmap
*
*********************************************************************/
void _DogDrawPixmap(dw)
DogWidget dw;
{
Widget w = (Widget) dw;
if (XtIsRealized(w)) {
XCopyArea(XtDisplay(w),CurrPixmap(w),
XtWindow(w),DrawGC(w),
PixmapX(w), PixmapY(w),
DrawWidth(w), DrawHeight(w),
DrawX(w), DrawY(w));
}
}
/**********************************************************************
*
* _DogPosition(w) - position the current pixmap
*
*********************************************************************/
void _DogPosition(w)
DogWidget w;
{
Dimension margin = ShadowThickness(w) + HighlightThickness(w);
if (CurrWidth(w) < MAX(Width(w) - 2 * margin,0)) {
PixmapX(w) = 0;
DrawX(w) = Width(w)/2 - CurrWidth(w)/2;
DrawWidth(w) = CurrWidth(w);
}
else {
PixmapX(w) = (CurrWidth(w) - (Width(w) - 2 * margin))/2;
DrawX(w) = margin;
DrawWidth(w) = Width(w) - 2 * margin;
}
if (CurrHeight(w) < MAX(Height(w) - 2 * margin,0)) {
PixmapY(w)= 0;
DrawY(w) = Height(w)/2 - CurrHeight(w)/2;
DrawHeight(w) = CurrHeight(w);
}
else {
PixmapY(w) = (CurrHeight(w) - (Height(w) - 2 * margin))/2;
DrawY(w) = margin;
DrawHeight(w) = Height(w) - 2 * margin;
}
}
/**********************************************************************
*
* Class methods
*
*********************************************************************/
static void ClassInitialize()
{
XmResolvePartOffsets(dogWidgetClass, &offsets);
}
static void create_GC(w)
DogWidget w;
{
XGCValues values;
XtGCMask valueMask;
valueMask = GCForeground | GCBackground | GCGraphicsExposures;
values.foreground = Foreground(w);
values.background = BackgroundPixel(w);
values.graphics_exposures = False;
DrawGC(w) = XtGetGC((Widget)w,valueMask,&values);
}
static void create_pixmaps(w)
DogWidget w;
{
UpPixmap(w) = MakePixmap(up_bits, up_width, up_height);
DownPixmap(w) = MakePixmap(down_bits, down_width, down_height);
BarkPixmap(w) = MakePixmap(bark_bits, bark_width, bark_height);
}
static void Initialize(request, new)
DogWidget request;
DogWidget new;
{
if (Width(request) == 0)
Width(new) = MAX(MAX(up_width, down_width),bark_width) +
2*(ShadowThickness(new)+HighlightThickness(new));
if (Height(request) == 0)
Height(new) = MAX(MAX(up_height, down_height),bark_height) +
2*(ShadowThickness(new)+HighlightThickness(new));
create_GC(new);
create_pixmaps(new);
SetPixmap(new, DownPx, DownPixmap(new), down_width, down_height);
Wagging(new) = False;
Barking(new) = False;
WagId(new) = 0;
BarkId(new) = 0;
Resize(new);
}
static void destroy_pixmaps(w)
DogWidget w;
{
XFreePixmap (XtDisplay(w), UpPixmap(w));
XFreePixmap (XtDisplay(w), DownPixmap(w));
XFreePixmap (XtDisplay(w), BarkPixmap(w));
}
static void Destroy(w)
DogWidget w;
{
XtReleaseGC ((Widget)w, DrawGC(w));
destroy_pixmaps(w);
if (WagId(w) != 0)
XtRemoveTimeOut( WagId(w));
if (BarkId(w) != 0)
XtRemoveTimeOut( BarkId(w));
XtRemoveAllCallbacks ((Widget)w, DogNbarkCallback);
}
static void Resize(w)
DogWidget w;
{
_DogPosition(w);
}
static Boolean DifferentBackground(w, p)
Widget w;
Widget p;
{
if (XmIsPrimitive(w) && XmIsManager(p))
{
Pixel w_bg, p_bg;
Pixmap w_px, p_px;
XtVaGetValues(w, XmNbackground, &w_bg, XmNbackgroundPixmap, &w_px, NULL);
XtVaGetValues(p, XmNbackground, &p_bg, XmNbackgroundPixmap, &p_px, NULL);
return ((w_bg == p_bg) && (w_px == p_px));
}
return (False);
}
static void Redisplay(w, event, region)
Widget w;
XEvent *event;
Region region;
{
if (XtIsRealized(w)) {
XmeDrawShadows(XtDisplay (w), XtWindow (w),
TopShadowGC(w), BottomShadowGC(w),
HighlightThickness(w), HighlightThickness(w),
Width(w) - 2 * HighlightThickness(w),
Height(w) - 2 * HighlightThickness(w),
ShadowThickness(w),
XmSHADOW_OUT);
if (Highlighted(w))
(*((DogWidgetClass)XtClass(w)) ->
primitive_class.border_highlight)((Widget)w);
else if (DifferentBackground ((Widget)w, XtParent (w)))
(*((DogWidgetClass)XtClass(w)) ->
primitive_class.border_unhighlight)((Widget)w);
_DogDrawPixmap((DogWidget)w);
}
}
static Boolean SetValues(current, request, new)
DogWidget current;
DogWidget request;
DogWidget new;
{
Boolean redraw = False;
if (ShadowThickness(new) != ShadowThickness(current) ||
HighlightThickness(new) != HighlightThickness(current)) {
_DogPosition(new);
redraw = True;
}
if (Foreground(new) != Foreground(current) ||
BackgroundPixel(new) != BackgroundPixel(current)) {
XtReleaseGC ((Widget)current, DrawGC(current));
create_GC(new);
destroy_pixmaps(new);
create_pixmaps(new);
switch (CurrPx(new)) {
case(UpPx) :
SetPixmap(new,UpPx,UpPixmap(new),up_width,up_height);
break;
case(DownPx) :
SetPixmap(new,DownPx,DownPixmap(new),down_width,down_height);
break;
case(BarkPx) :
SetPixmap(new,BarkPx,BarkPixmap(new),bark_width,bark_height);
break;
}
redraw = True;
}
return (redraw);
}
static XtGeometryResult QueryGeometry (w, intended, reply)
DogWidget w;
XtWidgetGeometry *intended;
XtWidgetGeometry *reply;
{
reply->request_mode = 0;
if (intended->request_mode & (~(CWWidth | CWHeight)) != 0)
return (XtGeometryNo);
reply->request_mode = (CWWidth | CWHeight);
reply->width = MAX(MAX(down_width,up_width),bark_width) +
2*(ShadowThickness(w)+HighlightThickness(w));
reply->height = MAX(MAX(down_height,up_height),bark_height) +
2*(ShadowThickness(w)+HighlightThickness(w));
if (reply->width != intended->width ||
reply->height != intended->height ||
intended->request_mode != reply->request_mode)
return (XtGeometryAlmost);
else {
reply->request_mode = 0;
return (XtGeometryYes);
}
}
/**********************************************************************
*
* Widget actions
*
*********************************************************************/
static void bark_dog(w, event)
DogWidget w;
XEvent *event;
{
XmProcessTraversal((Widget)w, XmTRAVERSE_CURRENT);
XtCallCallbacks ((Widget)w, DogNbarkCallback, NULL);
if (Barking(w) == True) return;
Barking(w) = True;
SetPixmap(w,BarkPx,BarkPixmap(w),bark_width,bark_height);
_DogPosition(w);
_DogDrawPixmap(w);
BarkId(w) = XtAppAddTimeOut (XtWidgetToApplicationContext((Widget)w),
BarkTime(w), end_bark, w);
}
static void end_bark(w, t)
DogWidget w;
XtIntervalId *t;
{
SetPixmap(w,DownPx,DownPixmap(w),down_width,down_height);
_DogPosition(w);
_DogDrawPixmap(w);
Barking(w) = False;
BarkId(w) = 0;
if (Wagging(w) == True)
WagId(w) = XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)w),
WagTime(w), do_wag, w);
}
static void start_wag(w, event)
DogWidget w;
XEvent *event;
{
XmProcessTraversal((Widget)w, XmTRAVERSE_CURRENT);
if (Wagging(w) == True) return;
Wagging(w) = True;
if (Barking(w) == True) return;
WagId(w) = XtAppAddTimeOut (XtWidgetToApplicationContext((Widget)w),
WagTime(w), do_wag, w);
}
static void stop_wag(w, event)
DogWidget w;
XEvent *event;
{
XmProcessTraversal((Widget)w, XmTRAVERSE_CURRENT);
Wagging(w) = False;
if (WagId(w) != 0)
XtRemoveTimeOut( WagId(w));
WagId(w) = 0;
}
static void do_wag(w, t)
XtPointer w;
XtIntervalId *t;
{
DogWidget dw = (DogWidget)w;
if (Barking(dw) == True) return;
if (Wagging(dw) == False) return;
switch(CurrPx(dw)) {
case(UpPx):
SetPixmap(dw,DownPx,DownPixmap(dw),down_width,down_height);
break;
case(DownPx):
SetPixmap(dw,UpPx,UpPixmap(dw),up_width,up_height);
break;
}
_DogPosition(dw);
_DogDrawPixmap(dw);
XtAppAddTimeOut (XtWidgetToApplicationContext((Widget)dw),
WagTime(dw), do_wag, dw);
}