|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T b
Length: 26226 (0x6672)
Types: TextFile
Names: »button.c.orig«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/X/Dragon/button.c.orig«
/******************************************************************************
* Dragon - a version of Mah-Jongg for X Windows
*
* Author: Gary E. Barnes March 1989
*
* button.c - Deals with the command buttons on the board
******************************************************************************/
#include "main.h"
#include <X11/Dialog.h>
extern int Side_X;
extern int Side_Y;
extern int Shadow_X;
extern int Shadow_Y;
extern unsigned int Tile_Width;
extern unsigned int Tile_Height;
extern void Button_Expose();
static void Cheat();
static void Game_Exit();
extern void Hints();
static void New_Game();
static void Other();
extern void Read_Game();
static void Redraw_All();
extern void Restart_Game();
static void Restore_Game();
static void Save_Game();
extern void Show_Samples();
static void Sides();
static void Sync_All();
extern void Setup_New_Game();
extern void Write_Game();
typedef void (*ActionProc)();
typedef struct _Button_Rec {
char *text;
ActionProc action;
Boolean toggle;
Boolean hilite;
int x;
int y;
int text_x;
int text_y;
XPoint border[6*4+4+1];
} Button_Rec, *Button;
#define Button_NULL ((Button)0)
#define NBUTTONS 8
Button_Rec Buttons1[NBUTTONS] = {
{ "New Game", New_Game, FALSE },
{ "Restart", Restart_Game, FALSE },
{ "Save", Save_Game, FALSE },
{ "Other", Other, TRUE },
{ "Hint", Hints, FALSE },
{ NULL },
{ "Restore", Restore_Game, FALSE },
{ "Quit", Game_Exit, FALSE },
};
Button_Rec Buttons2[NBUTTONS] = {
{ "Redraw", Redraw_All, FALSE },
{ "Sides", Sides, FALSE },
{ "Samples", Show_Samples, TRUE },
{ "Other", Other, TRUE },
{ "Cheat", Cheat, TRUE },
{ "Sync", Sync_All, TRUE },
{ NULL },
{ NULL },
};
static Button All_Buttons = &Buttons1[0];
static int Button_Width = 0;
static int Button_Height = 0;
static int Letter_Indent = 0;
static int Letter_Height = 0;
static int Letter_Width = 0;
Widget Complaint = (Widget)NULL;
Widget Complainer = (Widget)NULL;
\f
static void Complain_OK()
/******************************************************************************
* Called when the "OK" button on our complaint is pressed.
******************************************************************************/
{
XtPopdown( Complainer );
} /* Complain_OK */
\f
void Complain( about )
String about;
/******************************************************************************
* Pop up a dialog box and complain to the user.
******************************************************************************/
{
#undef SETARG
#define SETARG(name,value) \
if (argi >= XtNumber(args)) {fprintf(stderr,"BS args overrun!\n");} \
XtSetArg( args[argi], name, value ); ++argi;
Arg args[10];
int argi;
/*--Create our widgets if this is a first time. */
if (Complaint == (Widget)NULL) {
Complainer =
XtCreatePopupShell( "complainer", transientShellWidgetClass,
Dragon, (ArgList)NULL, (Cardinal)0 );
argi = 0;
SETARG( XtNcursor, Dragon_Resources.Cursor );
Complaint =
XtCreateManagedWidget( "complaint", dialogWidgetClass,
Complainer, args, (Cardinal)argi );
XtDialogAddButton( Complaint, "OK", Complain_OK, (caddr_t)NULL );
}
/*--Set the label on the complaint. */
argi = 0;
SETARG( XtNlabel, about );
XtSetValues( Complaint, args, (Cardinal)argi );
/*--Realize and pop up the dialog box. */
{ int xret, yret;
Window child;
(void)XTranslateCoordinates( XtDisplay(Dragon), XtWindow(Dragon),
RootWindowOfScreen(XtScreen(Dragon)),
0, 0, &xret, &yret, &child );
XtMoveWidget( Complainer, xret, yret );
}
XtPopup( Complainer, XtGrabNone );
XFlush( XtDisplay(Board) );
} /* Complain */
\f
int Cheating = FALSE;
/*ARGSUSED*/
static void Cheat( w, event, params, num_params )
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
{
DEBUG_CALL(Cheat);
Cheating = !Cheating;
DEBUG_RETURN(Cheat);
} /* Cheat */
\f
/*ARGSUSED*/
static void Game_Exit( w, event, params, num_params )
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
/******************************************************************************
* Called when we want to exit.
******************************************************************************/
{
XEvent event2;
DEBUG_CALL(Game_Exit);
for (;;) {
XNextEvent( XtDisplay(Board), &event2 );
if (event2.xany.type == ButtonRelease) { break; }
}
exit(0);
} /* Game_Exit */
\f
/*ARGSUSED*/
static void New_Game( w, event, params, num_params )
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
{
DEBUG_CALL(New_Game);
Setup_New_Game();
XClearArea( XtDisplay(Board), XtWindow(w), 0, 0, 0, 0, TRUE );
DEBUG_RETURN(New_Game);
} /* New_Game */
\f
/*ARGSUSED*/
static void Other( w, event, params, num_params )
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
/******************************************************************************
* Called to change button menus.
******************************************************************************/
{
DEBUG_CALL(Other);
if (All_Buttons == &Buttons1[0]) {
All_Buttons = &Buttons2[0];
} else {
All_Buttons = &Buttons1[0];
}
All_Buttons[3].hilite = !All_Buttons[3].hilite;
XClearArea( XtDisplay(Board), XtWindow(w),
0, 0, 0, (unsigned)(2*Tile_Height-Side_Y-Shadow_Y-1), FALSE );
Button_Expose( w, event, params, num_params );
DEBUG_RETURN(Other);
} /* Other */
\f
/*ARGSUSED*/
static void Redraw_All( w, event, params, num_params )
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
{
DEBUG_CALL(Redraw_All);
XClearArea( XtDisplay(Board), XtWindow(w), 0, 0, 0, 0, TRUE );
DEBUG_RETURN(Redraw_All);
} /* Redraw_All */
\f
/*ARGSUSED*/
static void Restore_Game( w, event, params, num_params )
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
/******************************************************************************
* Called to restore a previous game.
******************************************************************************/
{
extern char *getenv();
char name[1024];
FILE *file;
DEBUG_CALL(Restore_Game);
strcpy( &name[0], getenv( "HOME" ) );
strcat( &name[0], "/.dragon-save" );
file = fopen( &name[0], "r" );
if (file == (FILE*)NULL) {
Complain( "Cannot open the $HOME/.dragon-save file." );
} else {
Read_Game( file );
(void)fclose( file );
Redraw_All( w, event, params, num_params );
}
DEBUG_RETURN(Restore_Game);
} /* Restore_Game */
\f
/*ARGSUSED*/
static void Save_Game( w, event, params, num_params )
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
/******************************************************************************
* Called to save the current game.
******************************************************************************/
{
extern char *getenv();
char name[1024];
FILE *file;
DEBUG_CALL(Save_Game);
strcpy( &name[0], getenv( "HOME" ) );
strcat( &name[0], "/.dragon-save" );
file = fopen( &name[0], "w" );
if (file == (FILE*)NULL) {
Complain( "Cannot open the $HOME/.dragon-save file." );
} else {
Write_Game( file );
(void)fclose( file );
}
DEBUG_RETURN(Save_Game);
} /* Save_Game */
\f
/*ARGSUSED*/
static void Sides( w, event, params, num_params )
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
{
DEBUG_CALL(Cheat);
if (Tile_Control & SHADOW) {
if (Tile_Control & BLACKSIDE) {
if (Tile_Control & GRAYSIDE) {
Tile_Control &= ~(SHADOW | BLACKSIDE | GRAYSIDE);
} else {
Tile_Control &= ~SHADOW;
Tile_Control |= GRAYSIDE;
}
} else {
Tile_Control &= ~SHADOW;
Tile_Control |= BLACKSIDE;
}
} else {
Tile_Control |= SHADOW;
}
XClearArea( XtDisplay(Board), XtWindow(w), 0, 0, 0, 0, TRUE );
DEBUG_RETURN(Cheat);
} /* Sides */
\f
/*ARGSUSED*/
static void Sync_All( w, event, params, num_params )
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
{
static int onoff = FALSE;
DEBUG_CALL(Sync_All);
onoff = !onoff;
Dragon_Resources.Debug = onoff;
XSynchronize( XtDisplay(Board), onoff );
DEBUG_RETURN(Sync_All);
} /* Sync_All */
\f
void Do_Button_Configuration()
/******************************************************************************
* Called when the Board changes Tile sizes.
******************************************************************************/
{
#define BUTTONS_PER_LINE 4
#undef PNT
#define PNT(X,Y) pnt->x = X; pnt->y = Y; ++pnt;
int indent;
int x, dx;
int y, dy;
int i, j;
int f, s, t, l;
XPoint *pnt;
register Button but;
/*--Buttons will be three tiles wide and 2/3'rd of a tile high. */
DEBUG_CALL(Do_Button_Configuration);
Button_Width = 3 * Tile_Width;
dx = Button_Width + Tile_Width / 2;
Button_Height = 5 * Tile_Height / 9;
dy = Tile_Height * 8 / 10;
/*--Letters are as large as can fit within the buttons. */
indent = Button_Height / 5;
Letter_Indent = indent + 2;
s = Letter_Indent * 3 / 4;
t = s / 2;
f = indent - s + t;
Letter_Height = Button_Height - (2 * indent) - 2;
if ((Letter_Height & 1) == 0) { --Letter_Height; }
Letter_Width = (Button_Width - (2 * indent) - 2) / 8 - 2;
if ((Letter_Width & 1) == 0) { --Letter_Width; }
/*--Now place the buttons. */
for (j = 1; j >= 0; --j) {
if (j == 1) {
but = &Buttons1[0];
} else {
but = &Buttons2[0];
}
x = indent + 12;
y = indent + 4;
for (i = 0; i < NBUTTONS; ++i) {
if (but[i].text == NULL) { goto Next_Button; }
l = strlen(but[i].text);
if (l > 8) {
fprintf( stderr, "Button name too long: %s\n",
but[i].text );
l = 8;
}
but[i].x = x;
but[i].y = y;
but[i].text_x = (Button_Width - l * (Letter_Width+2) + 2) / 2;
but[i].text_y = indent + 1;
pnt = &but[i].border[0];
PNT( x, y + indent );
PNT( f, 0 );
PNT( 0, -s );
PNT( -t, 0 );
PNT( 0, t );
PNT( s, 0 );
PNT( 0, -f );
PNT( Button_Width - 2 * indent, 0 );
PNT( 0, f );
PNT( s, 0 );
PNT( 0, -t );
PNT( -t, 0 );
PNT( 0, s );
PNT( f, 0 );
PNT( 0, Button_Height - 2*indent);
PNT( -f, 0 );
PNT( 0, s );
PNT( t, 0 );
PNT( 0, -t );
PNT( -s, 0 );
PNT( 0, f );
PNT( -(Button_Width - 2*indent), 0 );
PNT( 0, -f );
PNT( -s, 0 );
PNT( 0, t );
PNT( t, 0 );
PNT( 0, -s );
PNT( -f, 0 );
PNT( 0, -Button_Height+2*indent );
Next_Button :
if (i % BUTTONS_PER_LINE + 1 == BUTTONS_PER_LINE) {
x = indent + 12;
y += dy;
} else {
x += dx;
}
}
}
DEBUG_RETURN(Do_Button_Configuration);
} /* Do_Button_Configuration */
\f
void Draw_Text( str, x, y )
char *str;
int x;
int y;
/******************************************************************************
* Called to draw the vector text in some button.
******************************************************************************/
{
static char pntserr[] = "DT pnts overflow!\n";
XPoint pnts[50];
int pnti;
int h1;
int w1;
#undef PNT
#define PNT(X,Y) \
if (pnti >= XtNumber(pnts)){fprintf(stderr,pntserr);} \
pnts[pnti].x = X; pnts[pnti].y = Y; ++pnti
;
/*--Position ourselves for the first letter. */
DEBUG_CALL(Draw_Text);
h1 = Letter_Height - 1;
w1 = Letter_Width - 1;
/*--Loop over all letters in the text. */
for ( ; *str != '\000'; x+=Letter_Width+2,++str) {
pnti = 0;
switch (*str) {
/*--The letters we have. */
case '0' :
{ int w6, h6, h26;
h6 = h1 / 6;
h26 = h1 - 4 * h6;
w6 = w1 / 6;
PNT( x, y+h6+h6 );
PNT( 0, h26 );
PNT( w6, h6 );
PNT( w6, h6 );
PNT( 2*w6, 0 );
PNT( w6, -h6 );
PNT( w6, -h6 );
PNT( 0, -h26 );
PNT( -w6, -h6 );
PNT( -w6, -h6 );
PNT( -2*w6, 0 );
PNT( -w6, h6 );
PNT( -w6, h6 );
break;
}
case '1' :
{
PNT( x+(w1+1)/2,y );
PNT( 0, h1 );
break;
}
case '2' :
{ int w6, w46, h6, h6r;
w6 = w1 / 6;
w46 = w1 - w6 - w6;
h6 = h1 / 6;
h6r = (h1 - h6 * 6) / 2;
PNT( x, y + h6 );
PNT( w6, -h6 );
PNT( w46, 0 );
PNT( w6, h6 );
PNT( 0, h6+h6r );
PNT( -w6, h6 );
PNT( -w46, 0 );
PNT( -w6, h6 );
PNT( 0, h1-5*h6-h6r);
PNT( 0, h6 );
PNT( w1, 0 );
break;
}
case '3' :
{ int w6, w46, h6, h6r;
w6 = w1 / 6;
w46 = w1 - w6 - w6;
h6 = h1 / 6;
h6r = (h1 - h6 * 6) / 2;
PNT( x, y + h6 );
PNT( w6, -h6 );
PNT( w46, 0 );
PNT( w6, h6 );
PNT( 0, h6+h6r );
PNT( -w6, h6 );
PNT( -w46/2, 0 );
PNT( w46/2, 0 );
PNT( w6, h6 );
PNT( 0, h1-5*h6-h6r);
PNT( -w6, h6 );
PNT( -w46, 0 );
PNT( -w6, -h6 );
break;
}
case '4' :
{ int w23, h23;
w23 = w1 * 2 / 3;
h23 = h1 * 2 / 3;
PNT( x + w1, y + h23 );
PNT( -w1, 0 );
PNT( w23, -h23 );
PNT( 0, h1 );
break;
}
case '5' :
{ int w6, w46, h6, h6r;
w6 = w1 / 6;
w46 = w1 - w6 - w6;
h6 = h1 / 6;
h6r = (h1 - h6 * 6) / 2;
PNT( x + w1, y );
PNT( -w1, 0 );
PNT( 0, h1-3*h6-h6r);
PNT( w1-w6, 0 );
PNT( w6, h6 );
PNT( 0, h6+h6r );
PNT( -w6, h6 );
PNT( -w46, 0 );
PNT( -w6, -h6 );
break;
}
case '6' :
{ int w6, w46, h6, h6r;
w6 = w1 / 6;
w46 = w1 - w6 - w6;
h6 = h1 / 6;
if (((h6-w6) & 1) == 1) { --h6; }
h6r = (h1 - h6 * 6) / 2;
PNT( x + w1, y+h6 );
PNT( -w6, -h6 );
PNT( -w46, 0 );
PNT( -w6, h6 );
PNT( 0, h1-2*h6);
PNT( w6, h6 );
PNT( w46, 0 );
PNT( w6, -h6 );
PNT( 0, -h6-h6r );
PNT( -w6, -h6 );
PNT( -w46, 0 );
PNT( -w6, h6 );
break;
}
case '7' :
{
PNT( x, y );
PNT( w1, 0 );
PNT( -w1, h1 );
break;
}
case '8' :
{ int w6, w46, h6, h6r;
w6 = w1 / 6;
w46 = w1 - w6 - w6;
h6 = h1 / 6;
if (((h6-w6) & 1) == 1) { --h6; }
h6r = (h1 - h6 * 6) / 2;
PNT( x + w1, y + h6 );
PNT( -w6, -h6 );
PNT( -w46, 0 );
PNT( -w6, h6 );
PNT( 0, h6+h6r );
PNT( w6, h6 );
PNT( w46, 0 );
PNT( w6, h6 );
PNT( 0, h1-5*h6-h6r);
PNT( -w6, h6 );
PNT( -w46, 0 );
PNT( -w6, -h6 );
PNT( 0, -h1+5*h6+h6r);
PNT( w6, -h6 );
PNT( w46, 0 );
PNT( w6, -h6 );
PNT( 0, -h6-h6r );
break;
}
case '9' :
{ int w6, w46, h6, h6r;
w6 = w1 / 6;
w46 = w1 - w6 - w6;
h6 = h1 / 6;
h6r = (h1 - h6 * 6) / 2;
PNT( x, y+h1-h6 );
PNT( w6, h6 );
PNT( w46, 0 );
PNT( w6, -h6 );
PNT( 0, -h1+2*h6);
PNT( -w6, -h6 );
PNT( -w46, 0 );
PNT( -w6, h6 );
PNT( 0, h6+h6r);
PNT( w6, h6 );
PNT( w46, 0 );
PNT( w6, -h6 );
break;
}
case 'a' : case 'A' :
{ int h2, w2, w5l, w5r;
h2 = h1 * 12 / 20;
w2 = (w1+1) / 2;
w5l = w1 / 5;
w5r = w1 - w5l;
PNT( x, y + h1 );
PNT( w5l, -(h1-h2));
PNT( w5r - w5l, 0 );
PNT( w2 - w5r, -h2 );
PNT( w5l - w2, h2 );
PNT( w5r - w5l, 0 );
PNT( w5l, h1-h2 );
break;
}
case 'b' : case 'B' :
{ int w6, h6;
int h2;
h2 = (h1+1) / 2;
w6 = w1 / 6;
h6 = h1 / 6;
PNT( x, y + h1 );
PNT( 0, -h1 );
PNT( w1-w6, 0 );
PNT( w6, h6 );
PNT( 0, h2-h6-h6);
PNT( -w6, h6 );
PNT( -(w1-w6), 0 );
PNT( w1-w6, 0 );
PNT( w6, h6 );
PNT( 0, h1-h2-h6-h6);
PNT( -w6, h6 );
PNT( -(w1-w6), 0 );
break;
}
case 'c' : case 'C' :
{ int w6, w46, h6, h46;
w6 = w1 / 6;
w46 = w1 - w6 - w6;
h6 = h1 / 6;
h46 = h1 - h6 - h6;
PNT( x + w1, y + h6 );
PNT( -w6, -h6 );
PNT( -w46, 0 );
PNT( -w6, h6 );
PNT( 0, h46 );
PNT( w6, h6 );
PNT( w46, 0 );
PNT( w6, -h6 );
break;
}
case 'd' : case 'D' :
{ int w6, w56, h6, h46;
w6 = w1 / 6;
w56 = w1 - w6;
h6 = h1 / 6;
h46 = h1 - h6 - h6;
PNT( x, y );
PNT( w56, 0 );
PNT( w6, h6 );
PNT( 0, h46 );
PNT( -w6, h6 );
PNT( -w56, 0 );
PNT( 0, -h1 );
break;
}
case 'e' : case 'E' :
{ int h2, w2;
h2 = (h1+1) / 2;
w2 = (w1+1) / 2;
PNT( x + w1, y );
PNT( -w1, 0 );
PNT( 0, h2 );
PNT( w2, 0 );
PNT( -w2, 0 );
PNT( 0, h1-h2 );
PNT( w1, 0 );
break;
}
case 'f' : case 'F' :
{ int h2, w2;
h2 = (h1+1) / 2;
w2 = (w1+1) / 2;
PNT( x + w1, y );
PNT( -w1, 0 );
PNT( 0, h2 );
PNT( w2, 0 );
PNT( -w2, 0 );
PNT( 0, h1-h2 );
break;
}
case 'g' : case 'G' :
{ int w6, w46, h6, h46;
w6 = w1 / 6;
w46 = w1 - w6 - w6;
h6 = h1 / 6;
h46 = h1 - h6 - h6;
PNT( x + w1, y + h6 );
PNT( -w6, -h6 );
PNT( -w46, 0 );
PNT( -w6, h6 );
PNT( 0, h46 );
PNT( w6, h6 );
PNT( w46, 0 );
PNT( w6, -h6 );
PNT( 0, h6-(h1+1)/2);
PNT( -(w1+1)/2, 0 );
break;
}
case 'h' : case 'H' :
{ int h2 = (h1+1) / 2;
PNT( x, y );
PNT( 0, h1 );
PNT( 0, -h2 );
PNT( w1, 0 );
PNT( 0, h2 );
PNT( 0, -h1 );
break;
}
case 'i' : case 'I' :
{ int w2 = (w1+1) / 2;
PNT( x, y );
PNT( w1, 0 );
PNT( -w2, 0 );
PNT( 0, h1 );
PNT( -w2, 0 );
PNT( w1, 0 );
break;
}
case 'k' : case 'K' :
{ int h2 = (h1+1) / 2;
PNT( x, y );
PNT( 0, h1 );
PNT( 0, -h2 );
PNT( w1, -(h1-h2));
PNT( -w1, h1-h2 );
PNT( w1, h2 );
break;
}
case 'l' : case 'L' :
{ PNT( x, y );
PNT( 0, h1 );
PNT( w1, 0 );
break;
}
case 'm' : case 'M' :
{ int w2 = (w1+1) / 2;
PNT( x, y + h1 );
PNT( 0, -h1 );
PNT( w2, h1 );
PNT( w1 - w2, -h1 );
PNT( 0, h1 );
break;
}
case 'n' : case 'N' :
PNT( x, y + h1 );
PNT( 0, -h1 );
PNT( w1, h1 );
PNT( 0, -h1 );
break;
case 'o' : case 'O' :
{ int w6, w46, h6, h46;
w6 = w1 / 6;
w46 = w1 - w6 - w6;
h6 = h1 / 6;
h46 = h1 - h6 - h6;
PNT( x + w1, y + h6 );
PNT( -w6, -h6 );
PNT( -w46, 0 );
PNT( -w6, h6 );
PNT( 0, h46 );
PNT( w6, h6 );
PNT( w46, 0 );
PNT( w6, -h6 );
PNT( 0, -h46 );
break;
}
case 'p' : case 'P' :
{ int w6, h6;
int h2;
h2 = (h1+1) / 2;
w6 = w1 / 6;
h6 = h1 / 6;
PNT( x, y + h1 );
PNT( 0, -h1 );
PNT( w1-w6, 0 );
PNT( w6, h6 );
PNT( 0, h2-h6-h6);
PNT( -w6, h6 );
PNT( -(w1-w6), 0 );
break;
}
case 'q' : case 'Q' :
{ int w6, w46, h6, h46;
w6 = w1 / 6;
w46 = w1 - w6 - w6;
h6 = h1 / 6;
h46 = h1 - h6 - h6;
PNT( x + w1, y + h6 );
PNT( -w6, -h6 );
PNT( -w46, 0 );
PNT( -w6, h6 );
PNT( 0, h46 );
PNT( w6, h6 );
PNT( w46, 0 );
PNT( -w6-w6, -h6 );
PNT( w6+w6, h6 );
PNT( w6, h6 );
PNT( -w6, -h6 );
PNT( w6, -h6 );
PNT( 0, -h46 );
break;
}
case 'r' : case 'R' :
{ int w6, h6;
int h2;
h2 = (h1+1) / 2;
w6 = w1 / 6;
h6 = h1 / 6;
PNT( x, y + h1 );
PNT( 0, -h1 );
PNT( w1-w6, 0 );
PNT( w6, h6 );
PNT( 0, h2-h6-h6);
PNT( -w6, h6 );
PNT( -(w1-w6), 0 );
PNT( w1-w6, 0 );
PNT( w6, h2 );
break;
}
case 's' : case 'S' :
{ int w6, w46, h6, h6r;
w6 = w1 / 6;
w46 = w1 - w6 - w6;
h6 = h1 / 6;
h6r = (h1 - h6 * 6) / 2;
PNT( x + w1, y + h6 );
PNT( -w6, -h6 );
PNT( -w46, 0 );
PNT( -w6, h6 );
PNT( 0, h6+h6r );
PNT( w6, h6 );
PNT( w46, 0 );
PNT( w6, h6 );
PNT( 0, h6+h6r );
PNT( -w6, h6 );
PNT( -w46, 0 );
PNT( -w6, -h6 );
break;
}
case 't' : case 'T' :
{ int w2 = (w1+1) / 2;
PNT( x, y );
PNT( w1, 0 );
PNT( -w2, 0 );
PNT( 0, h1 );
break;
}
case 'u' : case 'U' :
{ int w6, h6, h56;
w6 = w1 / 6;
h6 = h1 / 6;
h56 = h1 - h6;
PNT( x, y );
PNT( 0, h56 );
PNT( w6, h6 );
PNT( w1-w6-w6, 0 );
PNT( w6, -h6 );
PNT( 0, -h56 );
break;
}
case 'v' : case 'V' :
{ int w2;
w2 = (w1+1) / 2;
PNT( x, y );
PNT( w2, h1 );
PNT( w1-w2, -h1 );
break;
}
case 'w' : case 'W' :
{ int w4, w2;
w4 = w1 / 4;
w2 = (w1+1) / 2;
PNT( x, y );
PNT( w4, h1 );
PNT( w2-w4, -h1 );
PNT( w1-w2-w4, h1 );
PNT( w4, -h1 );
break;
}
case 'y' : case 'Y' :
{ int h2, w2;
h2 = (h1+1) / 2;
w2 = (w1+1) / 2;
PNT( x, y );
PNT( w2, h2 );
PNT( w1-w2, -h2 );
PNT( -(w1-w2), h2 );
PNT( -w2, h1-h2 );
break;
}
/*--Letters we don't have, and also blank. */
default :
; /* do nothing */
}
/*--Draw the letter. */
DEBUG_OTHER(Draw_Text,1 char);
if (pnti > 0) {
XDrawLines( XtDisplay(Board), XtWindow(Board), Normal_GC,
pnts, (Cardinal)pnti, CoordModePrevious );
}
}
DEBUG_RETURN(Draw_Text);
} /* Draw_Text */
\f
void Draw_Score( score, x, y )
int score;
int x;
int y;
/******************************************************************************
* Called to draw the score at x/y.
******************************************************************************/
{
char scr[4];
unsigned int w = (Letter_Width+2) * 3 + 4;
unsigned int h = Letter_Height + 6;
if (score == 0) {
int i, lx, ly;
Letter_Height *= 3;
Letter_Width *= 3;
lx = Board->core.width/6;
ly = Board->core.height/2 - 2 * Letter_Height;;
for (i = 5; i > 0; --i) {
Draw_Text( "You Win", lx, ly );
lx += 2*Letter_Width + 2;
ly += Letter_Height + 5;
}
Letter_Height /= 3;
Letter_Width /= 3;
}
y -= h + 2;
XFillRectangle( XtDisplay(Board), XtWindow(Board), Reverse_GC,
x, y, w, h );
XDrawRectangle( XtDisplay(Board), XtWindow(Board), Normal_GC,
x-2, y-2, w+4, h+4 );
XDrawRectangle( XtDisplay(Board), XtWindow(Board), Normal_GC,
x-1, y-1, w+2, h+2 );
XDrawRectangle( XtDisplay(Board), XtWindow(Board), Normal_GC,
x, y, w, h );
scr[0] = (score > 99 ? '0' + score / 100 : ' ');
scr[1] = (score > 9 ? '0' + score / 10 % 10 : ' ');
scr[2] = '0' + score % 10;
scr[3] = '\000';
Draw_Text( scr, x+3, y+3 );
} /* Draw_Score */
\f
static void Hilite( button )
Button button;
/******************************************************************************
* Xor the hilite pattern on the button indicated.
******************************************************************************/
{
XFillRectangle( XtDisplay(Board), XtWindow(Board), Xor_GC,
button->x + 1,
button->y + 1,
(unsigned int)(Button_Width - 1),
(unsigned int)(Button_Height - 1) );
} /* Hilite */
\f
/*ARGSUSED*/
void Button_Expose( w, event, params, num_params )
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
/******************************************************************************
* Called when the Board receives an Expose event.
******************************************************************************/
{
int i;
/*--Loop over all buttons and display all "real" buttons. */
DEBUG_CALL(Button_Expose);
for (i = 0; i < NBUTTONS; ++i) {
if (All_Buttons[i].text == NULL) { continue; }
/*--Clear the space for the button and then draw the outline. */
XFillRectangle( XtDisplay(Board), XtWindow(Board), Reverse_GC,
All_Buttons[i].x,
All_Buttons[i].y,
(unsigned int)(Button_Width + 1),
(unsigned int)(Button_Height + 1) );
XDrawLines( XtDisplay(Board), XtWindow(Board), Normal_GC,
All_Buttons[i].border,
(Cardinal)XtNumber(All_Buttons[0].border),
CoordModePrevious );
/*--Draw the text of the button and then do hiliting if we need it. */
Draw_Text( All_Buttons[i].text,
All_Buttons[i].x + All_Buttons[i].text_x,
All_Buttons[i].y + All_Buttons[i].text_y );
if (All_Buttons[i].hilite) {
Hilite( &All_Buttons[i] );
}
}
DEBUG_RETURN(Button_Expose);
} /* Button_Expose */
\f
static void De_Hilite_All()
/******************************************************************************
* Called to take the hilite off of any and all buttons everywhere.
******************************************************************************/
{
int i;
for (i = 0; i < NBUTTONS; ++i) {
if (All_Buttons[i].text == NULL) { continue; }
if (All_Buttons[i].hilite && !All_Buttons[i].toggle) {
All_Buttons[i].hilite = FALSE;
Hilite( &All_Buttons[i] );
XFlush( XtDisplay(Board) );
}
}
} /* De_Hitlite_All */
\f
/*ARGSUSED*/
void Button_Press( w, event, params, num_params )
Widget w;
XButtonEvent *event;
String *params;
Cardinal *num_params;
/******************************************************************************
* Called when the Board receives a BtnDown event.
******************************************************************************/
{
int i;
/*--First we make sure that nobody is hilited. */
DEBUG_CALL(Button_Press);
De_Hilite_All();
/*--See if some button just got clicked. */
for (i = 0; i < NBUTTONS; ++i) {
if (All_Buttons[i].text == NULL) { continue; }
if (event->x >= All_Buttons[i].x &&
event->x <= All_Buttons[i].x + Button_Width &&
event->y >= All_Buttons[i].y &&
event->y <= All_Buttons[i].y + Button_Height) {
/*--Hilite this button and then do whatever it is supposed to do. */
All_Buttons[i].hilite = !All_Buttons[i].hilite;
Hilite( &All_Buttons[i] );
XFlush( XtDisplay(Board) );
(*(All_Buttons[i].action))( w, event, params, num_params );
break;
}
}
DEBUG_RETURN(Button_Press);
} /* Button_Press */
\f
/*ARGSUSED*/
void Button_Release( w, event, params, num_params )
Widget w;
XButtonEvent *event;
String *params;
Cardinal *num_params;
/******************************************************************************
* Called when the Board receives a BtnUp event.
******************************************************************************/
{
/*--Turn off any and all button hilites. */
DEBUG_CALL(Button_Release);
De_Hilite_All();
DEBUG_RETURN(Button_Release);
} /* Button_Release */