#endif
#include <stdint.h>
-#include <X11/Intrinsic.h>
-#include <X11/StringDefs.h>
-#include <X11/Shell.h>
-#include <X11/Xatom.h>
-#include <X11/Xaw/Dialog.h>
-#include <X11/Xaw/Form.h>
-#include <X11/Xaw/List.h>
-#include <X11/Xaw/Label.h>
-#include <X11/Xaw/SimpleMenu.h>
-#include <X11/Xaw/SmeBSB.h>
-#include <X11/Xaw/SmeLine.h>
-#include <X11/Xaw/Box.h>
-#include <X11/Xaw/Paned.h>
-#include <X11/Xaw/MenuButton.h>
-#include <X11/cursorfont.h>
-#include <X11/Xaw/Text.h>
-#include <X11/Xaw/AsciiText.h>
-#include <X11/Xaw/Viewport.h>
-#include <X11/Xaw/Toggle.h>
-#include <X11/Xaw/Scrollbar.h>
+#include <cairo/cairo.h>
+#include <cairo/cairo-xlib.h>
#include "common.h"
#include "backend.h"
#include "xboard.h"
+#include "xboard2.h"
#include "dialogs.h"
#include "menus.h"
#include "gettext.h"
void
UnCaret ()
{
+#ifdef TODO_GTK
Arg args[2];
if(previous) {
XtSetValues(previous, args, 1);
}
previous = NULL;
+#endif
}
void
SetFocus (Widget w, XtPointer data, XEvent *event, Boolean *b)
{
+#ifdef TODO_GTK
Arg args[2];
char *s;
int j;
XtSetValues(w, args, j);
XtSetKeyboardFocus((Widget) data, w);
previous = w;
+#endif
}
void
BoardFocus ()
{
+#ifdef TODO_GTK
XtSetKeyboardFocus(shellWidget, formWidget);
+#endif
}
//--------------------------- Engine-specific options menu ----------------------------------
int dialogError;
Option *dialogOptions[NrOfDialogs];
+#ifdef TODO_GTK
static Arg layoutArgs[] = {
{ XtNborderWidth, 0 },
{ XtNdefaultDistance, 0 },
{ XtNborderWidth, 0 },
{ XtNresizable, (XtArgVal) True },
};
+#endif
+
+void
+MarkMenuItem (char *menuRef, int state)
+{
+ MenuItem *item = MenuNameToItem(menuRef);
+
+#ifdef TODO_GTK
+ if(item) {
+ Arg args[2];
+ XtSetArg(args[0], XtNleftBitmap, state ? xMarkPixmap : None);
+ XtSetValues(item->handle, args, 1);
+ }
+#endif
+}
void
GetWidgetText (Option *opt, char **buf)
{
+#ifdef TODO_GTK
Arg arg;
XtSetArg(arg, XtNstring, buf);
XtGetValues(opt->handle, &arg, 1);
+#endif
}
void
SetWidgetText (Option *opt, char *buf, int n)
{
+#ifdef TODO_GTK
Arg arg;
XtSetArg(arg, XtNstring, buf);
XtSetValues(opt->handle, &arg, 1);
if(n >= 0) SetFocus(opt->handle, shells[n], NULL, False);
+#endif
}
void
GetWidgetState (Option *opt, int *state)
{
+#ifdef TODO_GTK
Arg arg;
XtSetArg(arg, XtNstate, state);
XtGetValues(opt->handle, &arg, 1);
+#endif
}
void
SetWidgetState (Option *opt, int state)
{
+#ifdef TODO_GTK
Arg arg;
XtSetArg(arg, XtNstate, state);
XtSetValues(opt->handle, &arg, 1);
+#endif
}
void
SetWidgetLabel (Option *opt, char *buf)
{
+#ifdef TODO_GTK
Arg arg;
XtSetArg(arg, XtNlabel, (XtArgVal) buf);
XtSetValues(opt->handle, &arg, 1);
+#endif
}
void
SetDialogTitle (DialogClass dlg, char *title)
{
+#ifdef TODO_GTK
Arg args[16];
XtSetArg(args[0], XtNtitle, title);
XtSetValues(shells[dlg], args, 1);
+#endif
}
void
-LoadListBox (Option *opt, char *emptyText)
+LoadListBox (Option *opt, char *emptyText, int n1, int n2)
{
+#ifdef TODO_GTK
static char *dummyList[2];
dummyList[0] = emptyText; // empty listboxes tend to crash X, so display user-supplied warning string instead
XawListChange(opt->handle, *(char*)opt->target ? opt->target : dummyList, 0, 0, True);
+#endif
}
int
ReadScroll (Option *opt, float *top, float *bottom)
{ // retreives fractions of top and bottom of thumb
+#ifdef TODO_GTK
Arg args[16];
Widget w = XtParent(opt->handle); // viewport
Widget v = XtNameToWidget(w, "vertical");
XtSetArg(args[j], XtNtopOfThumb, top); j++;
XtGetValues(v, args, j);
*bottom = *top + h;
+#endif
return TRUE;
}
void
SetScroll (Option *opt, float f)
{ // sets top of thumb to given fraction
+#ifdef TODO_GTK
static char *params[3] = { "", "Continuous", "Proportional" };
static XEvent event;
Widget w = XtParent(opt->handle); // viewport
XtCallActionProc(v, "NotifyThumb", &event, params, 0);
// XtCallActionProc(v, "NotifyScroll", &event, params+2, 1);
XtCallActionProc(v, "EndScroll", &event, params, 0);
+#endif
}
void
HighlightListBoxItem (Option *opt, int nr)
{
+#ifdef TODO_GTK
XawListHighlight(opt->handle, nr);
+#endif
}
void
HighlightWithScroll (Option *opt, int sel, int max)
{
+#ifdef TODO_GTK
float top, bottom, f, g;
HighlightListBoxItem(opt, sel);
if(!ReadScroll(opt, &top, &bottom)) return; // no scroll bar
if(sel < (3*top + bottom)/4) f = (sel - 0.25f*(bottom-top))/max;
if(f < 0.f) f = 0.; if(f + 1.f/max > 1.f) f = 1. - 1./max;
if(f != g) SetScroll(opt, f);
+#endif
}
int
SelectedListBoxItem (Option *opt)
{
+#ifdef TODO_GTK
XawListReturnStruct *rs;
rs = XawListShowCurrent(opt->handle);
return rs->list_index;
+#else
+ return 0;
+#endif
}
void
FocusOnWidget (Option *opt, DialogClass dlg)
{
UnCaret();
+#ifdef TODO_GTK
XtSetKeyboardFocus(shells[dlg], opt->handle);
+#endif
}
void
SetIconName (DialogClass dlg, char *name)
{
+#ifdef TODO_GTK
Arg args[16];
int j = 0;
XtSetArg(args[j], XtNiconName, (XtArgVal) name); j++;
// XtSetArg(args[j], XtNtitle, (XtArgVal) name); j++;
XtSetValues(shells[dlg], args, j);
+#endif
}
static void
static void
SpinCallback (Widget w, XtPointer client_data, XtPointer call_data)
{
+#ifdef TODO_GTK
String name, val;
Arg args[16];
char buf[MSG_SIZ], *p;
} else return;
snprintf(buf, MSG_SIZ, "%d", j);
SetWidgetText(opt, buf, TransientDlg);
+#endif
}
static void
ComboSelect (Widget w, caddr_t addr, caddr_t index) // callback for all combo items
{
+#ifdef TODO_GTK
Arg args[16];
Option *opt = dialogOptions[((intptr_t)addr)>>24]; // applicable option list
int i = ((intptr_t)addr)>>16 & 255; // option number
XtSetArg(args[0], XtNlabel, _(((char**)opt[i].choice)[j]));
XtSetValues(opt[i].handle, args, 1);
+#endif
}
Widget
CreateMenuItem (Widget menu, char *msg, XtCallbackProc CB, int n)
{
+#ifdef TODO_GTK
int j=0;
Widget entry;
Arg args[16];
entry = XtCreateManagedWidget("item", smeBSBObjectClass, menu, args, j+1);
XtAddCallback(entry, XtNcallback, CB, (caddr_t)(intptr_t) n);
return entry;
+#else
+ return NULL;
+#endif
}
static Widget
CreateComboPopup (Widget parent, Option *opt, int n, int fromList, int def)
{ // fromList determines if the item texts are taken from a list of strings, or from a menu table
+#ifdef TODO_GTK
int i;
Widget menu, entry;
Arg arg;
}
}
return menu;
+#else
+ return NULL;
+#endif
}
char moveTypeInTranslations[] =
filterTranslations, gameListTranslations, memoTranslations
};
-void
+void * shells[NrOfDialogs];
+
AddHandler (Option *opt, int nr)
{
+#ifdef TODO_GTK
XtOverrideTranslations(opt->handle, XtParseTranslationTable(translationTable[nr]));
+#endif
}
//----------------------------Generic dialog --------------------------------------------
// cloned from Engine Settings dialog (and later merged with it)
+#ifdef TODO_GTK
Widget shells[NrOfDialogs];
+#else
+void *shells[NrOfDialogs];
+#endif
DialogClass parents[NrOfDialogs];
WindowPlacement *wp[NrOfDialogs] = { // Beware! Order must correspond to DialogClass enum
NULL, &wpComment, &wpTags, NULL, NULL, NULL, NULL, &wpMoveHistory, &wpGameList, &wpEngineOutput, &wpEvalGraph,
- NULL, NULL, NULL, NULL, &wpMain
+ NULL, NULL, NULL, NULL, /*&wpMain*/ NULL
};
int
void
RaiseWindow (DialogClass dlg)
{
+#ifdef TODO_GTK
static XEvent xev;
Window root = RootWindow(xDisplay, DefaultScreen(xDisplay));
Atom atom = XInternAtom (xDisplay, "_NET_ACTIVE_WINDOW", False);
XFlush(xDisplay);
XSync(xDisplay, False);
+#endif
}
int
PopDown (DialogClass n)
{ // pops down any dialog created by GenericPopUp (or returns False if it wasn't up), unmarks any associated marked menu
+#ifdef TODO_GTK
int j;
Arg args[10];
Dimension windowH, windowW; Position windowX, windowY;
currentOption = dialogOptions[TransientDlg]; // just in case a transient dialog was up (to allow its check and combo callbacks to work)
RaiseWindow(parents[n]);
if(parents[n] == BoardWindow) XtSetKeyboardFocus(shellWidget, formWidget);
+#endif
return 1;
}
+#ifdef TODO_GTK
void
GenericPopDown (Widget w, XEvent *event, String *prms, Cardinal *nprms)
{ // to cause popdown through a translation (Delete Window button!)
PopDown(dlg);
shells[dlg] = sh; // restore
}
+#endif
int
AppendText (Option *opt, char *s)
{
+ int len;
+#ifdef TODO_GTK
XawTextBlock t;
char *v;
- int len;
GetWidgetText(opt, &v);
len = strlen(v);
t.ptr = s; t.firstPos = 0; t.length = strlen(s); t.format = XawFmt8Bit;
XawTextReplace(opt->handle, len, len, &t);
+#endif
return len;
}
void
SetColor (char *colorName, Option *box)
{ // sets the color of a widget
+#ifdef TODO_GTK
Arg args[5];
Pixel buttonColor;
XrmValue vFrom, vTo;
} else buttonColor = timerBackgroundPixel;
XtSetArg(args[0], XtNbackground, buttonColor);;
XtSetValues(box->handle, args, 1);
+#endif
}
void
ColorChanged (Widget w, XtPointer data, XEvent *event, Boolean *b)
{ // for detecting a typed change in color
char buf[10];
+#ifdef TODO_GTK
if ( (XLookupString(&(event->xkey), buf, 2, NULL, NULL) == 1) && *buf == '\r' )
RefreshColor((int)(intptr_t) data, 0);
+#endif
}
static void
GraphEventProc(Widget widget, caddr_t client_data, XEvent *event)
{ // handle expose and mouse events on Graph widget
+#ifdef TODO_GTK
Dimension w, h;
Arg args[16];
- int j, button=10, f=1;
- Option *opt;
+ int j, button=10, f=1, sizing=0;
+ Option *opt, *graph = (Option *) client_data;
+ PointerCallback *userHandler = graph->target;
+
if (!XtIsRealized(widget)) return;
switch(event->type) {
- case Expose:
- if (((XExposeEvent*)event)->count > 0) return; // don't bother if further exposure is pending
- /* Get client area */
+ case Expose: // make handling of expose events generic, just copying from memory buffer (->choice) to display (->textValue)
+ /* Get window size */
j = 0;
XtSetArg(args[j], XtNwidth, &w); j++;
XtSetArg(args[j], XtNheight, &h); j++;
XtGetValues(widget, args, j);
- break;
+
+ if(w < graph->max || w > graph->max + 1 || h != graph->value) { // use width fudge of 1 pixel
+ if(((XExposeEvent*)event)->count >= 0) { // suppress sizing on expose for ordered redraw in response to sizing.
+ sizing = 1;
+ graph->max = w; graph->value = h; // note: old values are kept if we we don't exceed width fudge
+ }
+ } else w = graph->max;
+
+ if(sizing && ((XExposeEvent*)event)->count > 0) { graph->max = 0; return; } // don't bother if further exposure is pending during resize
+ if(!graph->textValue || sizing) { // create surfaces of new size for display widget
+ if(graph->textValue) cairo_surface_destroy((cairo_surface_t *)graph->textValue);
+ graph->textValue = (char*) cairo_xlib_surface_create(xDisplay, XtWindow(widget), DefaultVisual(xDisplay, 0), w, h);
+ }
+ if(sizing) { // the memory buffer was already created in GenericPopup(),
+ // to give drawing routines opportunity to use it before first expose event
+ // (which are only processed when main gets to the event loop, so after all init!)
+ // so only change when size is no longer good
+ if(graph->choice) cairo_surface_destroy((cairo_surface_t *) graph->choice);
+ graph->choice = (char**) cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h);
+ break;
+ }
+ w = ((XExposeEvent*)event)->width;
+ if(((XExposeEvent*)event)->x + w > graph->max) w--; // cut off fudge pixel
+ if(w) ExposeRedraw(graph, ((XExposeEvent*)event)->x, ((XExposeEvent*)event)->y, w, ((XExposeEvent*)event)->height);
+ return;
case MotionNotify:
f = 0;
w = ((XButtonEvent*)event)->x; h = ((XButtonEvent*)event)->y;
}
}
button *= f;
- opt = ((PointerCallback*) client_data)(button, w, h);
+ opt = userHandler(button, w, h);
if(opt) { // user callback specifies a context menu; pop it up
XUngrabPointer(xDisplay, CurrentTime);
XtCallActionProc(widget, "XawPositionSimpleMenu", event, &(opt->name), 1);
XtPopupSpringLoaded(opt->handle);
}
XSync(xDisplay, False);
+#endif
+}
+
+void
+GraphExpose (Option *opt, int x, int y, int w, int h)
+{
+#ifdef TODO_GTK
+ XExposeEvent e;
+ if(!opt->handle) return;
+ e.x = x; e.y = y; e.width = w; e.height = h; e.count = -1; e.type = Expose; // count = -1: kludge to suppress sizing
+ GraphEventProc(opt->handle, (caddr_t) opt, (XEvent *) &e); // fake expose event
+#endif
}
static void
GenericCallback (Widget w, XtPointer client_data, XtPointer call_data)
{ // all Buttons in a dialog (including OK, cancel) invoke this
+#ifdef TODO_GTK
String name;
Arg args[16];
char buf[MSG_SIZ];
} else ((ButtonCallback*) currentOption[data].target)(data);
shells[dlg] = oldSh; // in case of multiple instances, restore previous (as this one could be popped down now)
+#endif
}
void
TabProc (Widget w, XEvent *event, String *prms, Cardinal *nprms)
{ // for transfering focus to the next text-edit
+#ifdef TODO_GTK
Option *opt;
for(opt = currentOption; opt->type != EndMark; opt++) {
if(opt->handle == w) {
}
}
}
+#endif
}
void
WheelProc (Widget w, XEvent *event, String *prms, Cardinal *nprms)
{ // for scrolling a widget seen through a viewport with the mouse wheel (ListBox!)
+#ifdef TODO_GTK
int j=0, n = atoi(prms[0]);
static char *params[3] = { "", "Continuous", "Proportional" };
Arg args[16];
XtCallActionProc(v, "NotifyThumb", event, params, 0);
// XtCallActionProc(w, "NotifyScroll", event, params+2, 1);
XtCallActionProc(v, "EndScroll", event, params, 0);
+#endif
}
static char *oneLiner =
static void
SqueezeIntoBox (Option *opt, int nr, int width)
{ // size buttons in bar to fit, clipping button names where necessary
+#ifdef TODO_GTK
int i, wtot = 0;
Dimension widths[20], oldWidths[20];
Arg arg;
XtSetValues(opt[i].handle, &arg, 1);
}
opt->min = wtot;
+#endif
}
int
SetPositionAndSize (Arg *args, Widget leftNeigbor, Widget topNeigbor, int b, int w, int h, int chaining)
{ // sizing and positioning most widgets have in common
int j = 0;
+#ifdef TODO_GTK
// first position the widget w.r.t. earlier ones
if(chaining & 1) { // same row: position w.r.t. last (on current row) and lastrow
XtSetArg(args[j], XtNfromVert, topNeigbor); j++;
if(!appData.monoMode) {
if(!b && appData.dialogColor[0]) XtSetArg(args[j], XtNbackground, dialogColor), j++;
if(b == 3 && appData.buttonColor[0]) XtSetArg(args[j], XtNbackground, buttonColor), j++;
- if(b == 3) b = 1;
}
+ if(b == 3) b = 1;
// border
XtSetArg(args[j], XtNborderWidth, b); j++;
+#endif
return j;
}
int
GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent, int modal, int top)
{
+#ifdef TODO_GTK
Arg args[24];
Widget popup, layout, dialog=NULL, edit=NULL, form, last, b_ok, b_cancel, previousPane = NULL, textField = NULL, oldForm, oldLastRow, oldForeLast;
Window root, child;
if(engineDlg) { // Settings popup for engine: format through heuristic
int n = currentCps->nrOptions;
- if(!n) { DisplayNote(_("Engine has no options")); currentCps = NULL; return 0; }
if(n > 50) width = 4; else if(n>24) width = 2; else width = 1;
height = n / width + 1;
if(n && (currentOption[n-1].type == Button || currentOption[n-1].type == SaveButton)) currentOption[n].min = SAME_ROW; // OK on same line
#if ENABLE_NLS
if(option[i].choice) XtSetArg(args[j], XtNfontSet, *(XFontSet*)option[i].choice), j++;
#else
- if(option[i].choice) XtSetArg(args[j], XtNfont, *(XFontStruct*)option[i].choice), j++;
+ if(option[i].choice) XtSetArg(args[j], XtNfont, (XFontStruct*)option[i].choice), j++;
#endif
XtSetArg(args[j], XtNresizable, False); j++;
XtSetArg(args[j], XtNjustify, XtJustifyLeft); j++;
option[i].handle = (void*)
(last = XtCreateManagedWidget("graph", widgetClass, form, args, j));
XtAddEventHandler(last, ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask, False,
- (XtEventHandler) GraphEventProc, option[i].target); // mandatory user-supplied expose handler
+ (XtEventHandler) GraphEventProc, &option[i]); // mandatory user-supplied expose handler
if(option[i].min & SAME_ROW) last = forelast, forelast = lastrow;
+ option[i].choice = (char**) cairo_image_surface_create (CAIRO_FORMAT_ARGB32, option[i].max, option[i].value); // image buffer
break;
case PopUp: // note: used only after Graph, so 'last' refers to the Graph widget
option[i].handle = (void*) CreateComboPopup(last, option + i, i + 256*dlgNr, TRUE, option[i].value);
XtSetValues(popup, args, j);
}
RaiseWindow(dlgNr);
+#endif
return 1; // tells caller he must do initialization (e.g. add specific event handlers)
}
/* function called when the data to Paste is ready */
+#ifdef TODO_GTK
static void
SendTextCB (Widget w, XtPointer client_data, Atom *selection,
Atom *type, XtPointer value, unsigned long *len, int *format)
SendString(buf);
XtFree(value);
}
+#endif
void
SendText (int n)
{
+#ifdef TODO_GTK
char *p = (char*) textOptions[n].choice;
if(strstr(p, "$name")) {
XtGetSelectionValue(menuBarWidget,
CurrentTime
);
} else SendString(p);
+#endif
}
void
SetInsertPos (Option *opt, int pos)
{
+#ifdef TODO_GTK
Arg args[16];
XtSetArg(args[0], XtNinsertPosition, pos);
XtSetValues(opt->handle, args, 1);
// SetFocus(opt->handle, shells[InputBoxDlg], NULL, False); // No idea why this does not work, and the following is needed:
- XSetInputFocus(xDisplay, XtWindow(opt->handle), RevertToPointerRoot, CurrentTime);
+// XSetInputFocus(xDisplay, XtWindow(opt->handle), RevertToPointerRoot, CurrentTime);
+#endif
}
+#ifdef TODO_GTK
void
TypeInProc (Widget w, XEvent *event, String *prms, Cardinal *nprms)
{ // can be used as handler for any text edit in any dialog (from GenericPopUp, that is)
GenericCallback (w, (XtPointer)(intptr_t) (30000 + n + (dlgNr<<16)), NULL);
}
}
+#endif
void
HardSetFocus (Option *opt)
{
+#ifdef TODO_GTK
XSetInputFocus(xDisplay, XtWindow(opt->handle), RevertToPointerRoot, CurrentTime);
+#endif
}