/*****************************************************************************/ /* */ /* */ /* X patience version 2 -- module Xaw-widget.c */ /* */ /* A pseudo-widget for the Athena Widget interface */ /* written by Michael Bischoff (mbi@mo.math.nat.tu-bs.de) */ /* March-1994 */ /* see COPYRIGHT.xpat2 for Copyright details */ /* */ /* */ /*****************************************************************************/ #if defined(useXaw) || defined(useXm) #include "X-pat.h" #include #include #include "TableauP.h" static XtResource resources[] = { #define offset(field) XtOffsetOf(TableauRec, tableau.field) /* {name, class, type, size, offset, default_type, default_addr}, */ {XtNmessageFile,XtCMessageFile,XtRString,sizeof(String), offset(messagefile), XtRString, NULL}, {XtNkeyboardFile,XtCKeyboardFile,XtRString,sizeof(String),offset(keyboardfile),XtRString, NULL}, {XtNxpmdir, XtCXpmdir, XtRString, sizeof(String), offset(xpmdir), XtRString, NULL}, {XtNxpmcls, XtCXpmcls, XtRInt, sizeof(int), offset(xpmcls), XtRImmediate, (XtPointer)DEFAULT_CLOSENESS}, #ifdef LOADCARDS {XtNcardset, XtCCardset, XtRString, sizeof(String), offset(cardset), XtRString, NULL}, #endif {XtNruleset, XtCRuleset, XtRString, sizeof(String), offset(rules), XtRString, NULL}, {XtNfaceup, XtCFaceup, XtRInt, sizeof(int), offset(faceup), XtRImmediate, (XtPointer)-1}, {XtNfacedown,XtCFacedown,XtRInt, sizeof(int), offset(facedown), XtRImmediate, (XtPointer)-1}, {XtNdecks, XtCDecks, XtRInt, sizeof(int), offset(decks), XtRImmediate, (XtPointer)-1}, {XtNslots, XtCSlots, XtRInt, sizeof(int), offset(slots), XtRImmediate, (XtPointer)-1}, {XtNjokers, XtCJokers, XtRInt, sizeof(int), offset(jokers), XtRImmediate, (XtPointer)-1}, {XtNtmps, XtCTmps, XtRInt, sizeof(int), offset(tmps), XtRImmediate, (XtPointer)-1}, {XtNparam0, XtCParam, XtRInt, sizeof(int), offset(param0), XtRImmediate, (XtPointer)-1}, {XtNparam1, XtCParam, XtRInt, sizeof(int), offset(param1), XtRImmediate, (XtPointer)-1}, {XtNparam2, XtCParam, XtRInt, sizeof(int), offset(param2), XtRImmediate, (XtPointer)-1}, {XtNparam3, XtCParam, XtRInt, sizeof(int), offset(param3), XtRImmediate, (XtPointer)-1}, {XtNgapx, XtCGap, XtRDimension, sizeof(Dimension), offset(xgap), XtRImmediate, (XtPointer)4}, {XtNgapy, XtCGap, XtRDimension, sizeof(Dimension), offset(ygap), XtRImmediate, (XtPointer)4}, {XtNarrw, XtCArr, XtRDimension, sizeof(Dimension), offset(arrowwidth),XtRImmediate, (XtPointer)255}, {XtNarrh, XtCArr, XtRDimension, sizeof(Dimension), offset(arrowheight),XtRImmediate, (XtPointer)255}, {XtNmaWidth, XtCMaWidth, XtRDimension, sizeof(Dimension), offset(markwidth), XtRImmediate, (XtPointer)999}, {XtNcbColor, XtCCbColor, XtRPixel, sizeof(Pixel), offset(cbcolor), XtRString, "DarkGreen"}, {XtNmaColor, XtCMaColor, XtRPixel, sizeof(Pixel), offset(markcolor), XtRString, XtDefaultBackground}, {XtNarColor, XtCArColor, XtRPixel, sizeof(Pixel), offset(arrowcolor), XtRString, "White"}, {XtNredColor,XtCRedColor,XtRPixel, sizeof(Pixel), offset(redcolor), XtRString, "Red3"}, {XtNrng, XtCRng, XtRInt, sizeof(int), offset(rng), XtRImmediate, (XtPointer)1}, #ifdef useXm { XmNnavigationType, XmCNavigationType, XmRNavigationType, sizeof (unsigned char), XtOffsetOf(XmPrimitiveRec, primitive.navigation_type), XmRImmediate, (XtPointer) XmTAB_GROUP }, #endif #undef offset }; /* actions on the desktop area */ /*ARGSUSED*/ static void TableauKey(Widget w, XEvent *xev, String *s, Cardinal *num) { key_press((XKeyPressedEvent *)xev); } /*ARGSUSED*/ static void TableauBtn_up(Widget w, XEvent *xev, String *s, Cardinal *num) { button_release((XButtonPressedEvent *)xev); } /*ARGSUSED*/ static void TableauBtn_down(Widget w, XEvent *xev, String *s, Cardinal *num) { button_press((XButtonPressedEvent *)xev); } /*ARGSUSED*/ static void TableauMove(Widget w, XEvent *xev, String *s, Cardinal *num) { mouse_motion((XPointerMovedEvent *)xev); } /*ARGSUSED*/ static void Redisplay(Widget w, XEvent *xev, Region region) { redraw_table((XExposeEvent *)xev); } static XtActionsRec actions[] = { /* {name, procedure}, */ { "tableau_k", TableauKey }, { "tableau_d", TableauBtn_down }, { "tableau_u", TableauBtn_up }, { "tableau_m", TableauMove }, }; static char translations[] = "\ : tableau_k() \n\ : tableau_d() \n\ : tableau_u() \n\ : tableau_m() \n\ "; static Boolean SetValues(Widget current, Widget request, Widget desired, ArgList args, Cardinal *num_args) { return FALSE; } static void Initialize(Widget request, Widget xnew, ArgList args, Cardinal *n); static void Resize(Widget gw); static void Realize(Widget w, XtValueMask *valuemask, XSetWindowAttributes *winattr) { *valuemask |= CWBorderPixel | CWEventMask | CWBackingStore | CWBitGravity; winattr->backing_store = WhenMapped; winattr->border_pixel = blackpixel; winattr->bit_gravity = NorthWestGravity; winattr->event_mask = KeyPressMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask | Button3MotionMask; (*(tableauClassRec.core_class.superclass)->core_class.realize)(w, valuemask, winattr); } TableauClassRec tableauClassRec = { { /* core fields */ #ifdef useXm /* superclass */ (WidgetClass) &xmPrimitiveClassRec, #else /* superclass */ (WidgetClass) &widgetClassRec, #endif /* class_name */ "Tableau", /* widget_size */ sizeof(TableauRec), /* class_initialize */ NULL, /* class_part_initialize */ NULL, /* class_inited */ FALSE, /* initialize */ Initialize, /* initialize_hook */ NULL, /* realize */ Realize, /* actions */ actions, /* num_actions */ XtNumber(actions), /* resources */ resources, /* num_resources */ XtNumber(resources), /* xrm_class */ NULLQUARK, /* compress_motion */ TRUE, /* compress_exposure */ TRUE, /* compress_enterleave */ TRUE, /* visible_interest */ FALSE, /* destroy */ NULL, /* resize */ Resize, /* expose */ Redisplay, /* set_values */ SetValues, /* set_values_hook */ NULL, /* set_values_almost */ XtInheritSetValuesAlmost, /* get_values_hook */ NULL, /* accept_focus */ NULL, /* version */ XtVersion, /* callback_private */ NULL, /* tm_table */ translations, /* query_geometry */ XtInheritQueryGeometry, /* display_accelerator */ XtInheritDisplayAccelerator, /* extension */ NULL }, #ifdef useXm /* Primitive Class part */ { /* border_highlight */ XmInheritBorderHighlight, /* border_unhighlight */ XmInheritBorderUnhighlight, /* translations */ NULL, /* arm_and_activate_proc */ NULL, /* Synthetic Resources */ NULL, /* num syn res */ 0, /* extension */ NULL }, #endif { /* tableau fields */ /* empty */ 0 } }; WidgetClass tableauWidgetClass = (WidgetClass)&tableauClassRec; static Widget toplev = NULL; static void Resize(Widget gw) { TableauWidget w = (TableauWidget) gw; #ifdef LABER printf("Resize(): Parent wants me to have size %d,%d\n", w->core.width, w->core.height); #endif resize_event(w->core.width, w->core.height); /* (*pileWidgetClass->core_class.superclass->core_class.resize)(gw); */ } void AskWidgetForResize(XSize_t x, XSize_t y) { #ifdef useXm Arg Args[2]; XtSetArg(Args[0], XtNwidth, x); XtSetArg(Args[1], XtNheight, y); if (toplev) XtSetValues(toplev, Args, 2); #else XtWidgetGeometry Geo; XtGeometryResult r; Geo.width = x; Geo.height = y; do { Geo.request_mode = CWWidth | CWHeight; #ifdef LABER printf("resize to %d %d yielded ", Geo.width, Geo.height); #endif r = XtMakeGeometryRequest(toplev, &Geo, &Geo); #ifdef LABER switch (r) { case XtGeometryYes: printf("YES!\n");break; case XtGeometryNo: printf("NO!\n"); break; case XtGeometryAlmost:printf("Almost!\n"); break; case XtGeometryDone: printf("Done!\n"); break; } #endif } while (r == XtGeometryAlmost); #endif } static GC simpleGC(Pixel bg, Pixel fg) { XGCValues gcv; long gcflags; gcv.background = bg; gcv.foreground = fg; gcv.graphics_exposures = True; gcflags = GCForeground | GCBackground | GCGraphicsExposures; return XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv); } #define CHECK(x, mi, ma) { if ((x) < mi || (x) > ma) (x) = (mi); } extern char *loadfilename; extern GC hintgc; static void Initialize(Widget request, Widget xnew, ArgList args, Cardinal *n) { static int is_inited = 0; TableauWidget new = (TableauWidget)xnew; TableauPart *p = &new->tableau; toplev = xnew; if (is_inited) { fprintf(stderr, "Sorry, currently only one instance of Tableau is allowed\n"); exit(EXIT_FAILURE); } read_message_file(p->messagefile ? p->messagefile : "messages"); read_keyboard_file(p->keyboardfile ? p->keyboardfile : "keys"); /* assign global data for old Xlib program */ dpy = XtDisplay(new); screen = DefaultScreen(dpy); graphic.is_color = (DisplayCells(dpy, screen) > 2); #if defined(GFX2) && defined(LOADCARDS) if (!graphic.is_color && !p->cardset) p->cardset = "french"; /* use B&W cardset, xpm requires too much colours */ #endif /* validity checks */ CHECK(p->decks, -1, 9); CHECK(p->slots, -1, 32); CHECK(p->faceup, -1, 30); CHECK(p->facedown, -1, 30); CHECK(p->jokers, -1, 16); CHECK(p->tmps, -1, 16); CHECK(p->param0, -1, 99); CHECK(p->param1, -1, 99); CHECK(p->param2, -1, 99); CHECK(p->param3, -1, 99); rng = p->rng; if (loadfilename) load_game(loadfilename); else { long orgseed; orgseed = game.seed; /* this is destroyed by new_rules */ if (!p->rules) p->rules = "Gypsy"; new_rules(p->rules, p->decks, p->slots, p->faceup, p->facedown, p->jokers, p->tmps, p->param0, p->param1, p->param2, p->param3); newgame(orgseed); } init_gfx(); /* make GCs */ init_cards( #ifdef LOADCARDS p->cardset, #else NULL, #endif -1, -1, p->redcolor, p->cbcolor, 1, p->xpmdir, p->xpmcls); geo.aw = geo.ah = CARD_WIDTH / 16; if (p->arrowwidth <= 30 && p->arrowheight <= 30) { geo.aw = p->arrowwidth; geo.ah = p->arrowheight; } if (geo.aw > 0 && geo.ah > 0) hintgc = simpleGC(BlackPixel(dpy, screen), p->arrowcolor); graphic.xgap = p->xgap; graphic.ygap = p->ygap; graphic.autolayout = 1; #ifdef LABER printf("size = (%d,%d) and (%d,%d) in Initialize(), computing minwindow:\n", graphic.width, graphic.height, new->core.width, new->core.height); #endif generic_minwindow(); graphic.width = geo.min_width; graphic.height = geo.min_height; #ifdef LABER printf("result is (%d,%d)\n", graphic.width, graphic.height); #endif init_mark(p->markcolor, p->markwidth); /* initialize card marks */ /* make icon here */ /* now the size is known */ #ifdef LABER printf("Init widget: res %d grap %d\n", new->core.width, graphic.width); #endif if (new->core.width < graphic.width) new->core.width = graphic.width; if (new->core.height < graphic.height) new->core.height = graphic.height; } #endif