summaryrefslogtreecommitdiff
path: root/src/main-xaw.c
diff options
context:
space:
mode:
authorManoj Srivastava <srivasta@debian.org>2014-05-14 23:54:09 -0700
committerManoj Srivastava <srivasta@debian.org>2014-05-14 23:54:09 -0700
commit4f8b58cc5366bfc2ea3b56fe6ff0443464d10f0f (patch)
treea0a9cad00e7916b9a97e14831fb362f21871cbef /src/main-xaw.c
tome (2.3.11-ah-2) unstable; urgency=low
* Modified the install paths to deploy to the FHS compliant /usr/games/tome and /var/games/tome, as we have always done * This is a major change, and includes theming. Some of the options have changed. Because of this, the manual page has been removed; there is a command line help option and in game help until the manual page is rewritten. # imported from the archive
Diffstat (limited to 'src/main-xaw.c')
-rw-r--r--src/main-xaw.c1888
1 files changed, 1888 insertions, 0 deletions
diff --git a/src/main-xaw.c b/src/main-xaw.c
new file mode 100644
index 00000000..8795e00d
--- /dev/null
+++ b/src/main-xaw.c
@@ -0,0 +1,1888 @@
+/* File: main-xaw.c */
+
+/*
+ * Copyright (c) 1997 Ben Harrison, Torbjorn Lindgren, and others
+ *
+ * This software may be copied and distributed for educational, research,
+ * and not for profit purposes provided that this copyright and statement
+ * are included in all such copies.
+ */
+
+
+/*
+ * This file helps Angband work with UNIX/X11 computers.
+ *
+ * To use this file, compile with "USE_XAW" defined, and link against all
+ * the various "X11" libraries which may be needed.
+ *
+ * See also "main-x11.c".
+ *
+ * The Angband widget is not as self-contained as it really should be.
+ * Originally everything was output to a Pixmap which was later copied
+ * to the screen when necessary. The idea was abandoned since Pixmaps
+ * create big performance problems for some really old X terminals (such
+ * as 3/50's running Xkernel).
+ *
+ * Initial framework (and some code) by Ben Harrison (benh@phial.com).
+ *
+ * Most of this file is by Torbjorn Lindgren (tl@cd.chalmers.se).
+ *
+ * Major modifications by Ben Harrison (benh@phial.com).
+ */
+
+
+#include "angband.h"
+
+
+#ifdef USE_XAW
+
+
+#ifndef __MAKEDEPEND__
+#include <X11/Xlib.h>
+#include <X11/StringDefs.h>
+#include <X11/Xutil.h>
+#include <X11/Intrinsic.h>
+#include <X11/Shell.h>
+#include <X11/keysym.h>
+#include <X11/keysymdef.h>
+#include <X11/IntrinsicP.h>
+#include <X11/CoreP.h>
+#include <X11/ShellP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xaw/SimpleP.h>
+#include <X11/Xaw/Simple.h>
+#include <X11/Xaw/XawInit.h>
+#endif /* __MAKEDEPEND__ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+
+/* /me pffts Solaris */
+#ifndef NAME_MAX
+#define NAME_MAX _POSIX_NAME_MAX
+#endif
+
+
+/*
+ * Include some helpful X11 code.
+ */
+#include "maid-x11.c"
+
+
+
+/**** Resources ****/
+
+
+/*
+
+Name Class RepType Default Value
+---- ----- ------- -------------
+background Background Pixel XtDefaultBackground
+border BorderColor Pixel XtDefaultForeground
+borderWidth BorderWidth Dimension 1
+cursor Cursor Cursor None
+cursorName Cursor String NULL
+destroyCallback Callback Pointer NULL
+height Height Dimension 0
+insensitiveBorder Insensitive Pixmap Gray
+mappedWhenManaged MappedWhenManaged Boolean True
+pointerColor Foreground Pixel XtDefaultForeground
+pointerColorBackground Background Pixel XtDefaultBackground
+sensitive Sensitive Boolean True
+width Width Dimension 0
+x Position Position 0
+y Position Position 0
+
+
+The colors can be changed using the standard Angband user pref files,
+which can also be used to provide black text on a white background,
+by setting color zero to "#FFFFFF" and color one to "#000000", since
+the other colors are unused.
+
+*/
+
+
+/*
+ * New resource names
+ */
+#define XtNstartRows "startRows"
+#define XtNstartColumns "startColumns"
+#define XtNminRows "minRows"
+#define XtNminColumns "minColumns"
+#define XtNmaxRows "maxRows"
+#define XtNmaxColumns "maxColumns"
+#define XtNinternalBorder "internalBorder"
+#define XtNredrawCallback "redrawCallback"
+
+/*
+ * Total normal colors
+ */
+#define NUM_COLORS 256
+
+/*
+ * Special "XOR" color
+ */
+#define COLOR_XOR 256
+
+
+
+/**** The Widget Code ****/
+
+
+/*
+ * Forward declarations
+ */
+typedef struct AngbandPart AngbandPart;
+typedef struct AngbandRec *AngbandWidget;
+typedef struct AngbandRec AngbandRec;
+typedef struct AngbandClassRec *AngbandWidgetClass;
+typedef struct AngbandClassPart AngbandClassPart;
+typedef struct AngbandClassRec AngbandClassRec;
+
+typedef struct term_data term_data;
+
+
+/*
+ * A structure for each "term"
+ */
+struct term_data
+{
+ term t;
+
+ AngbandWidget widget;
+};
+
+
+/*
+ * Maximum number of windows
+ */
+#define MAX_TERM_DATA 8
+
+
+/*
+ * An array of term_data's
+ */
+static term_data data[MAX_TERM_DATA];
+
+
+/*
+ * Current number of windows open
+ */
+static int num_term = MAX_TERM_DATA;
+
+
+/*
+ * New fields for the Angband widget record
+ */
+struct AngbandPart
+{
+ /* Settable resources */
+ int start_rows;
+ int start_columns;
+ int min_rows;
+ int min_columns;
+ int max_rows;
+ int max_columns;
+ int internal_border;
+ String font;
+
+ XtCallbackList redraw_callbacks;
+
+#ifdef USE_GRAPHICS
+
+ /* Tiles */
+ XImage *tiles;
+
+ /* Tempory storage for overlaying tiles. */
+ XImage *TmpImage;
+
+#endif /* USE_GRAPHICS */
+
+ /* Private state */
+ XFontStruct *fnt;
+ Dimension fontheight;
+ Dimension fontwidth;
+ Dimension fontascent;
+
+ /* Color info for GC's */
+ byte color[NUM_COLORS][4];
+
+ /* GC's (including "xor") */
+ GC gc[NUM_COLORS + 1];
+};
+
+
+/*
+ * Full instance record declaration
+ */
+struct AngbandRec
+{
+ CorePart core;
+ SimplePart simple;
+ AngbandPart angband;
+};
+
+
+/*
+ * New fields for the Angband widget class record
+ */
+struct AngbandClassPart
+{
+ int dummy;
+};
+
+
+/*
+ * Full class record declaration
+ */
+struct AngbandClassRec
+{
+ CoreClassPart core_class;
+ SimpleClassPart simple_class;
+ AngbandClassPart angband_class;
+};
+
+
+
+/*
+ * Hack -- see below
+ */
+#define offset(field) XtOffsetOf(AngbandRec, angband.field)
+
+
+/*
+ * Fallback resources for Angband widget
+ */
+static XtResource resources[] =
+{
+ { XtNstartRows, XtCValue, XtRInt, sizeof(int),
+ offset(start_rows), XtRImmediate, (XtPointer) 24 },
+ { XtNstartColumns, XtCValue, XtRInt, sizeof(int),
+ offset(start_columns), XtRImmediate, (XtPointer) 80 },
+ { XtNminRows, XtCValue, XtRInt, sizeof(int),
+ offset(min_rows), XtRImmediate, (XtPointer) 1 },
+ { XtNminColumns, XtCValue, XtRInt, sizeof(int),
+ offset(min_columns), XtRImmediate, (XtPointer) 1 },
+ { XtNmaxRows, XtCValue, XtRInt, sizeof(int),
+ offset(max_rows), XtRImmediate, (XtPointer) 255 },
+ { XtNmaxColumns, XtCValue, XtRInt, sizeof(int),
+ offset(max_columns), XtRImmediate, (XtPointer) 255 },
+ { XtNinternalBorder, XtCValue, XtRInt, sizeof(int),
+ offset(internal_border), XtRImmediate, (XtPointer) 2 },
+ { XtNfont, XtCFont, XtRString, sizeof(char *),
+ offset(font), XtRString, DEFAULT_X11_FONT },
+ { XtNredrawCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
+ offset(redraw_callbacks), XtRCallback, (XtPointer)NULL }
+};
+
+
+/*
+ * Hack -- see above
+ */
+#undef offset
+
+
+/*
+ * Forward declarations for Widget functions
+ */
+static void Initialize(AngbandWidget request, AngbandWidget wnew);
+static void Redisplay(AngbandWidget w, XEvent *event, Region region);
+static Boolean SetValues(AngbandWidget current, AngbandWidget request,
+ AngbandWidget wnew, ArgList args, Cardinal *num_args);
+static void Destroy(AngbandWidget widget);
+static void Resize_term(AngbandWidget wnew);
+
+/*
+ * Forward declaration for internal functions
+ */
+static void calculateSizeHints(AngbandWidget wnew);
+static XFontStruct *getFont(AngbandWidget widget,
+ String font, Boolean fallback);
+
+
+/*
+ * Hack -- see below
+ */
+#define superclass (&simpleClassRec)
+
+
+/*
+ * Class record constanst
+ */
+AngbandClassRec angbandClassRec =
+{
+ {
+ /* Core class fields initialization */
+ /* superclass */ (WidgetClass) superclass,
+ /* class_name */ "Angband",
+ /* widget_size */ sizeof(AngbandRec),
+ /* class_initialize */ NULL,
+ /* class_part_initialize*/ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ (XtInitProc) Initialize,
+ /* initialize_hook */ NULL,
+ /* realize */ XtInheritRealize,
+ /* actions */ NULL,
+ /* num_actions */ 0,
+ /* resources */ resources,
+ /* num_resources */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ TRUE,
+ /* compress_exposure */ XtExposeCompressMultiple,
+ /* compress_enterleave */ TRUE,
+ /* visible_interest */ FALSE,
+ /* destroy */ (XtWidgetProc) Destroy,
+ /* resize */ (XtWidgetProc) Resize_term,
+ /* expose */ (XtExposeProc) Redisplay,
+ /* set_values */ (XtSetValuesFunc) SetValues,
+ /* set_values_hook */ NULL,
+ /* set_values_almost */ XtInheritSetValuesAlmost,
+ /* get_values_hook */ NULL,
+ /* accept_focus */ NULL,
+ /* version */ XtVersion,
+ /* callback_private */ NULL,
+ /* tm_table */ NULL,
+ /* query_geometry */ NULL,
+ /* display_accelerator */ XtInheritDisplayAccelerator,
+ /* extension */ NULL
+ },
+ /* Simple class fields initialization */
+ {
+ /* change_sensitive */ XtInheritChangeSensitive
+#ifndef OLDXAW
+ , NULL
+#endif
+ },
+ /* Angband class fields initialization */
+ {
+ /* nothing */ 0
+ }
+};
+
+/*
+ * Hack -- see above
+ */
+#undef superclass
+
+
+/*
+ * Class record pointer
+ */
+WidgetClass angbandWidgetClass = (WidgetClass) &angbandClassRec;
+
+
+/*
+ * Public procedures
+ */
+
+/*
+ * Simple routine to save the state of the game when the display connection
+ * is broken. Remember, you cannot do anything in this function that will
+ * generate X protocol requests.
+ */
+static int x_io_error_handler(Display *d)
+{
+ /* We have nothing to save */
+ if (!character_generated) return 0;
+
+ save_dungeon();
+ save_player();
+
+ return 0;
+}
+
+
+/*
+ * Clear an area
+ */
+static void AngbandClearArea(AngbandWidget widget,
+ int x, int y, int w, int h, int a)
+{
+ /* Figure out which area to clear */
+ y = y * widget->angband.fontheight + widget->angband.internal_border;
+ x = x * widget->angband.fontwidth + widget->angband.internal_border;
+
+ /* Clear the area */
+ XFillRectangle(XtDisplay(widget), XtWindow(widget),
+ widget->angband.gc[a],
+ x, y,
+ widget->angband.fontwidth * w,
+ widget->angband.fontheight * h);
+}
+
+
+
+/*
+ * Output some text
+ */
+static void AngbandOutputText(AngbandWidget widget, int x, int y,
+ String txt, int len, int a)
+{
+ /* Do nothing if the string is null */
+ if (!txt || !*txt) return;
+
+ /* Check the length, and fix it if it's below zero */
+ if (len < 0) len = strlen(txt);
+
+ /* Figure out where to place the text */
+ y = (y * widget->angband.fontheight + widget->angband.fontascent +
+ widget->angband.internal_border);
+ x = (x * widget->angband.fontwidth + widget->angband.internal_border);
+
+ /* Place the string */
+ XDrawImageString(XtDisplay(widget), XtWindow(widget),
+ widget->angband.gc[a], x, y, txt, len);
+}
+
+
+#ifdef USE_GRAPHICS
+
+/*
+ * Draw some graphical characters.
+ */
+static void AngbandOutputPict(AngbandWidget widget, int x, int y, int n,
+ const byte *ap, const char *cp, const byte *tap, const char *tcp,
+ const byte *eap, const char *ecp)
+{
+ int i, x1, y1;
+
+ byte a;
+ char c;
+
+ byte ta;
+ char tc;
+
+ int x2, y2;
+
+ byte ea;
+ char ec;
+
+ int x3, y3;
+ bool_ has_overlay;
+
+ int k, l;
+ unsigned long pixel, blank;
+
+ /* Figure out where to place the text */
+ y = (y * widget->angband.fontheight + widget->angband.internal_border);
+ x = (x * widget->angband.fontwidth + widget->angband.internal_border);
+
+ for (i = 0; i < n; ++i)
+ {
+ a = *ap++;
+ c = *cp++;
+
+ /* For extra speed - cache these values */
+ x1 = (c & 0x7F) * widget->angband.fontwidth;
+ y1 = (a & 0x7F) * widget->angband.fontheight;
+
+ ta = *tap++;
+ tc = *tcp++;
+
+ /* For extra speed - cache these values */
+ x2 = (tc & 0x7F) * widget->angband.fontwidth;
+ y2 = (ta & 0x7F) * widget->angband.fontheight;
+
+ ea = *eap++;
+ ec = *ecp++;
+ has_overlay = (ea && ec);
+
+ /* For extra speed -- cache these values */
+ x3 = (ec & 0x7F) * widget->angband.fontwidth;
+ y3 = (ea & 0x7F) * widget->angband.fontheight;
+
+ /* Optimise the common case */
+ if ((x1 == x2) && (y1 == y2))
+ {
+
+ /* No overlay */
+ if (!has_overlay)
+ {
+ /* Draw object / terrain */
+ XPutImage(XtDisplay(widget), XtWindow(widget),
+ widget->angband.gc[0],
+ widget->angband.tiles,
+ x1, y1,
+ x, y,
+ widget->angband.fontwidth,
+ widget->angband.fontheight);
+ }
+
+ /* Terrain overlay */
+ else
+ {
+ /* Mega Hack^2 - assume the top left corner is "black" */
+ blank = XGetPixel(widget->angband.tiles,
+ 0, widget->angband.fontheight * 6);
+
+ for (k = 0; k < widget->angband.fontwidth; k++)
+ {
+ for (l = 0; l < widget->angband.fontheight; l++)
+ {
+ /* If mask set... */
+ if ((pixel = XGetPixel(widget->angband.tiles,
+ x3 + k, y3 + l)) == blank)
+ {
+ /* Output from the terrain */
+ pixel = XGetPixel(widget->angband.tiles,
+ x1 + k, y1 + l);
+ }
+
+ /* Store into the temp storage */
+ XPutPixel(widget->angband.TmpImage,
+ k, l, pixel);
+ }
+ }
+
+ /* Draw terrain + overlay */
+ XPutImage(XtDisplay(widget), XtWindow(widget),
+ widget->angband.gc[0],
+ widget->angband.TmpImage,
+ 0, 0,
+ x, y,
+ widget->angband.fontwidth,
+ widget->angband.fontheight);
+ }
+
+ }
+ else
+ {
+ /* Mega Hack^2 - assume the top left corner is "black" */
+ blank = XGetPixel(widget->angband.tiles,
+ 0, widget->angband.fontheight * 6);
+
+ for (k = 0; k < widget->angband.fontwidth; k++)
+ {
+ for (l = 0; l < widget->angband.fontheight; l++)
+ {
+ /* Get overlay pixel */
+ if (has_overlay)
+ {
+ pixel = XGetPixel(widget->angband.tiles,
+ x3 + k, y3 + l);
+ }
+
+ /* Hack -- no overlay */
+ else
+ {
+ pixel = blank;
+ }
+
+ /* If it's blank */
+ if (pixel == blank)
+ {
+ /* Use obj/mon */
+ pixel = XGetPixel(widget->angband.tiles,
+ x1 + k, y1 + l);
+ }
+
+ /* Use terrain if it's blank too */
+ if (pixel == blank)
+ {
+ pixel = XGetPixel(widget->angband.tiles,
+ x2 + k, y2 + l);
+ }
+
+ /* Store into the temp storage. */
+ XPutPixel(widget->angband.TmpImage,
+ k, l, pixel);
+ }
+ }
+
+ /* Draw to screen */
+
+ /* Draw object / terrain */
+ XPutImage(XtDisplay(widget), XtWindow(widget),
+ widget->angband.gc[0],
+ widget->angband.TmpImage,
+ 0, 0,
+ x, y,
+ widget->angband.fontwidth,
+ widget->angband.fontheight);
+ }
+
+ x += widget->angband.fontwidth;
+ }
+}
+
+#endif /* USE_GRAPHICS */
+
+/*
+ * Private procedures
+ */
+
+
+/*
+ * Procedure Initialize() is called during the widget creation
+ * process. Initialize() load fonts and calculates window geometry.
+ * The request parameter is filled in by parents to this widget. The
+ * wnew parameter is the request parameter plus data filled in by this
+ * widget. All changes should be done to the wnew parameter.
+ */
+static void Initialize(AngbandWidget request, AngbandWidget wnew)
+{
+ Display *dpy = XtDisplay(wnew);
+
+ int depth = DefaultDepthOfScreen(XtScreen((Widget) wnew));
+
+ XGCValues gcv;
+ TopLevelShellWidget parent =
+ (TopLevelShellWidget)XtParent((Widget) wnew);
+ int i;
+
+ /* Default background pixel */
+ unsigned long bg = create_pixel(dpy,
+ angband_color_table[0][1],
+ angband_color_table[0][2],
+ angband_color_table[0][3]);
+
+ /* Default foreground pixel */
+ unsigned long fg = create_pixel(dpy,
+ angband_color_table[1][1],
+ angband_color_table[1][2],
+ angband_color_table[1][3]);
+
+ /* Fix the background color */
+ wnew->core.background_pixel = bg;
+
+ /* Get some information about the font */
+ wnew->angband.fnt = getFont(wnew, wnew->angband.font, TRUE);
+ wnew->angband.fontheight = wnew->angband.fnt->ascent +
+ wnew->angband.fnt->descent;
+ wnew->angband.fontwidth = wnew->angband.fnt->max_bounds.width;
+ wnew->angband.fontascent = wnew->angband.fnt->ascent;
+
+ /* Create and initialize the graphics contexts */ /* GXset? */
+ gcv.font = wnew->angband.fnt->fid;
+ gcv.graphics_exposures = FALSE;
+ gcv.background = bg;
+
+ for (i = 0; i < NUM_COLORS; i++)
+ {
+ unsigned long pixel;
+
+ /* Acquire Angband colors */
+ wnew->angband.color[i][0] = angband_color_table[i][0];
+ wnew->angband.color[i][1] = angband_color_table[i][1];
+ wnew->angband.color[i][2] = angband_color_table[i][2];
+ wnew->angband.color[i][3] = angband_color_table[i][3];
+
+ if (depth > 1)
+ {
+ /* Create pixel */
+ pixel = create_pixel(dpy,
+ wnew->angband.color[i][1],
+ wnew->angband.color[i][2],
+ wnew->angband.color[i][3]);
+ }
+ else
+ {
+ /* Use background or foreground */
+ pixel = ((i == 0) ? bg : fg);
+ }
+
+ gcv.foreground = pixel;
+
+ /* Copy */
+ gcv.function = 3;
+
+ wnew->angband.gc[i] = XtGetGC((Widget)wnew,
+ (GCFont | GCForeground | GCFunction |
+ GCBackground | GCGraphicsExposures),
+ &gcv);
+ }
+
+ /* Create a special GC for highlighting */
+ gcv.foreground = (BlackPixelOfScreen(XtScreen((Widget)wnew)) ^
+ WhitePixelOfScreen(XtScreen((Widget)wnew)));
+ gcv.background = 0;
+
+ gcv.function = GXxor;
+ wnew->angband.gc[COLOR_XOR] = XtGetGC((Widget)wnew,
+ (GCFunction | GCForeground | GCBackground |
+ GCGraphicsExposures),
+ &gcv);
+
+ /* Calculate window geometry */
+ wnew->core.height = (wnew->angband.start_rows * wnew->angband.fontheight +
+ 2 * wnew->angband.internal_border);
+ wnew->core.width = (wnew->angband.start_columns * wnew->angband.fontwidth +
+ 2 * wnew->angband.internal_border);
+
+ /* We need to be able to resize the Widget if the user wants to */
+ /* change font on the fly! */
+ parent->shell.allow_shell_resize = TRUE;
+
+ /* Calculates all the size hints */
+ calculateSizeHints(wnew);
+}
+
+
+/*
+ * Procedure Destroy() is called during the destruction of the widget.
+ * Destroy() releases and frees GCs, frees the pixmaps and frees the
+ * fonts.
+ */
+static void Destroy(AngbandWidget widget)
+{
+ int n;
+
+ /* Free all GC's */
+ for (n = 0; n < NUM_COLORS + 1; n++)
+ {
+ XtReleaseGC((Widget)widget, widget->angband.gc[n]);
+ }
+
+ /* Free the font */
+ XFreeFont(XtDisplay((Widget)widget), widget->angband.fnt);
+}
+
+
+static void Resize_term(AngbandWidget wnew)
+{
+ int cols, rows, wid, hgt;
+
+ int ox = wnew->angband.internal_border;
+ int oy = wnew->angband.internal_border;
+
+ int i;
+ term_data *old_td;
+ term_data *td = &data[0];
+
+
+ /*
+ * Mega-Hack -- avoid calling this before the terms package is
+ * initialised
+ */
+ if (!Term) return;
+
+ old_td = (term_data*)(Term->data);
+
+ /* Hack - Find the term to activate */
+ for (i = 0; i < num_term; i++)
+ {
+ td = &data[i];
+
+ /* Paranoia: none of the widgets matched */
+ if (!td) return;
+
+ /* Have we found it? */
+ if (td->widget == wnew) break;
+ }
+
+ /* Paranoia -- No matches */
+ if (i == num_term) return;
+
+ /* Activate the proper Term */
+ Term_activate(&td->t);
+
+ /* Determine "proper" number of rows/cols */
+ cols = ((wnew->core.width - (ox + ox)) / wnew->angband.fontwidth);
+ rows = ((wnew->core.height - (oy + oy)) / wnew->angband.fontheight);
+
+ /* Hack -- minimal size */
+ if (cols < 1) cols = 1;
+ if (rows < 1) rows = 1;
+
+ if (i == 0)
+ {
+ /* Hack the main window must be at least 80x24 */
+ if (cols < 80) cols = 80;
+ if (rows < 24) rows = 24;
+ }
+
+ /* Desired size of window */
+ wid = cols * wnew->angband.fontwidth + (ox + ox);
+ hgt = rows * wnew->angband.fontheight + (oy + oy);
+
+ /* Resize the Term (if needed) */
+ (void) Term_resize(cols, rows);
+
+ /* Activate the old term */
+ Term_activate(&old_td->t);
+}
+
+/*
+ * Procedure Redisplay() is called as the result of an Expose event.
+ * Use the redraw callback to do a full redraw
+ */
+static void Redisplay(AngbandWidget wnew, XEvent *xev, Region region)
+{
+ int x1, x2, y1, y2;
+
+ int i;
+
+ term_data *old_td = (term_data*)(Term->data);
+ term_data *td = &data[0];
+
+ /* Hack - Find the term to activate */
+ for (i = 0; i < num_term; i++)
+ {
+ td = &data[i];
+
+ /* Have we found it? */
+ if (td->widget == wnew) break;
+
+ /* Paranoia: none of the widgets matched */
+ if (!td) return;
+ }
+
+ /* Activate the proper Term */
+ Term_activate(&td->t);
+
+ /* Find the bounds of the exposed region */
+
+ /*
+ * This probably could be obtained from the Region parameter -
+ * but I don't know anything about XAW.
+ */
+ x1 = (xev->xexpose.x - wnew->angband.internal_border)
+ / wnew->angband.fontwidth;
+ x2 = (xev->xexpose.x + xev->xexpose.width -
+ wnew->angband.internal_border) / wnew->angband.fontwidth;
+
+ y1 = (xev->xexpose.y - wnew->angband.internal_border)
+ / wnew->angband.fontheight;
+ y2 = (xev->xexpose.y + xev->xexpose.height -
+ wnew->angband.internal_border) / wnew->angband.fontheight;
+
+ Term_redraw_section(x1, y1, x2, y2);
+
+ /* Activate the old term */
+ Term_activate(&old_td->t);
+
+
+#if 0
+ if (XtHasCallbacks((Widget)widget, XtNredrawCallback) == XtCallbackHasSome)
+ {
+ XtCallCallbacks((Widget)widget, XtNredrawCallback, NULL);
+ }
+#endif /* 0 */
+}
+
+
+/*
+ * Font and internal_border can be changed on the fly.
+ *
+ * The entire widget is redrawn if any of those parameters change (all
+ * can potentially have effects that spans the whole widget).
+ *
+ * Color changes are handled elsewhere.
+ *
+ * This function is very underspecified, in terms of how these changes can
+ * occur, and what is true about the various AngbandWidget's passed in. It
+ * is very likely that this code no longer works.
+ */
+static Boolean SetValues(AngbandWidget current, AngbandWidget request,
+ AngbandWidget wnew, ArgList args,
+ Cardinal *num_args)
+{
+ Display *dpy = XtDisplay(wnew);
+
+ Boolean font_changed = FALSE;
+ Boolean border_changed = FALSE;
+ int height, width;
+ int i;
+
+
+ /* Handle font change */
+ if (wnew->angband.font != current->angband.font)
+ {
+ /* Check if the font exists */
+ wnew->angband.fnt = getFont(wnew, wnew->angband.font, FALSE);
+
+ /* The font didn't exist */
+ if (wnew->angband.fnt == NULL)
+ {
+ wnew->angband.fnt = current->angband.fnt;
+ wnew->angband.font = current->angband.font;
+ XtWarning("Couldn't find the requested font!");
+ }
+ else
+ {
+ font_changed = TRUE;
+
+ /* Free the old font */
+ XFreeFont(XtDisplay((Widget)wnew), current->angband.fnt);
+ /* Update font information */
+ wnew->angband.fontheight = wnew->angband.fnt->ascent +
+ wnew->angband.fnt->descent;
+ wnew->angband.fontwidth = wnew->angband.fnt->max_bounds.width;
+ wnew->angband.fontascent = wnew->angband.fnt->ascent;
+ }
+ }
+
+ /* Handle font change */
+ if (font_changed)
+ {
+ /* Update all GC's */
+ for (i = 0; i < NUM_COLORS; i++)
+ {
+ /* Steal the old GC */
+ wnew->angband.gc[i] = current->angband.gc[i];
+ current->angband.gc[i] = NULL;
+
+ /* Be sure the correct font is ready */
+ XSetFont(dpy, wnew->angband.gc[i], wnew->angband.fnt->fid);
+ }
+
+ /* Steal the old GC */
+ wnew->angband.gc[NUM_COLORS] = current->angband.gc[NUM_COLORS];
+ current->angband.gc[NUM_COLORS] = NULL;
+ }
+
+
+ /* Check if internal border width has changed, used later */
+ if (current->angband.internal_border != wnew->angband.internal_border)
+ {
+ border_changed = TRUE;
+ }
+
+
+ /* If the font or the internal border has changed, all geometry */
+ /* has to be recalculated */
+ if (font_changed || border_changed)
+ {
+ /* Change window size */
+ height = ((current->core.height - 2 * current->angband.internal_border) /
+ current->angband.fontheight * wnew->angband.fontheight +
+ 2 * current->angband.internal_border);
+ width = ((current->core.width - 2 * current->angband.internal_border) /
+ current->angband.fontwidth * wnew->angband.fontwidth +
+ 2 * wnew->angband.internal_border);
+
+ /* Get the new width */
+ if (XtMakeResizeRequest((Widget)wnew, width, height, NULL, NULL) ==
+ XtGeometryNo)
+ {
+ /* Not allowed */
+ XtWarning("Size change denied!");
+ }
+ else
+ {
+ /* Recalculate size hints */
+ calculateSizeHints(wnew);
+ }
+ }
+
+ /* Tell it to redraw the widget if anything has changed */
+ return (font_changed || border_changed);
+}
+
+
+/*
+ * Calculate size hints
+ */
+static void calculateSizeHints(AngbandWidget wnew)
+{
+ TopLevelShellWidget parent =
+ (TopLevelShellWidget)XtParent((Widget) wnew);
+
+ /* Calculate minimum size */
+ parent->wm.size_hints.min_height =
+ (wnew->angband.min_rows * wnew->angband.fontheight +
+ 2 * wnew->angband.internal_border);
+
+ /* Calculate minimum size */
+ parent->wm.size_hints.min_width =
+ (wnew->angband.min_columns * wnew->angband.fontwidth +
+ 2 * wnew->angband.internal_border);
+
+ /* Calculate minimum size */
+ parent->wm.size_hints.flags |= PMinSize;
+
+ /* Calculate maximum size */
+ parent->wm.size_hints.max_height =
+ (wnew->angband.max_rows * wnew->angband.fontheight +
+ 2 * wnew->angband.internal_border);
+
+ /* Calculate maximum size */
+ parent->wm.size_hints.max_width =
+ (wnew->angband.max_columns * wnew->angband.fontwidth +
+ 2 * wnew->angband.internal_border);
+
+ /* Calculate maximum size */
+ parent->wm.size_hints.flags |= PMaxSize;
+
+ /* Calculate increment size */
+ parent->wm.size_hints.height_inc = wnew->angband.fontheight;
+ parent->wm.size_hints.width_inc = wnew->angband.fontwidth;
+ parent->wm.size_hints.flags |= PResizeInc;
+
+ /* Calculate base size */
+ parent->wm.base_height = 2 * wnew->angband.internal_border;
+ parent->wm.base_width = 2 * wnew->angband.internal_border;
+ parent->wm.size_hints.flags |= PBaseSize;
+}
+
+
+/*
+ * Load a font
+ */
+static XFontStruct *getFont(AngbandWidget widget,
+ String font, Boolean fallback)
+{
+ Display *dpy = XtDisplay((Widget) widget);
+ char buf[256];
+ XFontStruct *fnt = NULL;
+
+ if (!(fnt = XLoadQueryFont(dpy, font)) && fallback)
+ {
+ sprintf(buf, "Can't find the font \"%s\", trying fixed\n", font);
+ XtWarning(buf);
+ if (!(fnt = XLoadQueryFont(dpy, "fixed")))
+ {
+ XtError("Can't fint the font \"fixed\"!, bailing out\n");
+ }
+ }
+
+ return fnt;
+}
+
+
+
+/*** The Angband code ****/
+
+
+
+
+
+/*
+ * Number of fallback resources per window
+ */
+#define TERM_FALLBACKS 6
+
+
+
+/*
+ * The names of the term_data's
+ */
+char *termNames[MAX_TERM_DATA] =
+{
+ "angband",
+ "mirror",
+ "recall",
+ "choice",
+ "term-4",
+ "term-5",
+ "term-6",
+ "term-7"
+};
+
+
+/*
+ * The special Arg's
+ */
+Arg specialArgs[TERM_FALLBACKS] =
+{
+ { XtNstartRows, 24},
+ { XtNstartColumns, 80},
+ { XtNminRows, 24},
+ { XtNminColumns, 80},
+ { XtNmaxRows, 255},
+ { XtNmaxColumns, 255}
+};
+
+
+/*
+ * The default Arg's
+ */
+Arg defaultArgs[TERM_FALLBACKS] =
+{
+ { XtNstartRows, 24},
+ { XtNstartColumns, 80},
+ { XtNminRows, 1},
+ { XtNminColumns, 1},
+ { XtNmaxRows, 255},
+ { XtNmaxColumns, 255}
+};
+
+
+/*
+ * The application context
+ */
+XtAppContext appcon;
+
+
+/*
+ * User changable information about widgets
+ */
+static String fallback[] =
+{
+ "Angband.angband.iconName: ToME",
+ "Angband.angband.title: ToME",
+ "Angband.term-1.iconName: Mirror",
+ "Angband.term-1.title: Mirror",
+ "Angband.term-2.iconName: Recall",
+ "Angband.term-2.title: Recall",
+ "Angband.term-3.iconName: Choice",
+ "Angband.term-3.title: Choice",
+ "Angband.term-4.iconName: Term 4",
+ "Angband.term-4.title: Term 4",
+ "Angband.term-5.iconName: Term 5",
+ "Angband.term-5.title: Term 5",
+ "Angband.term-6.iconName: Term 6",
+ "Angband.term-6.title: Term 6",
+ "Angband.term-7.iconName: Term 7",
+ "Angband.term-7.title: Term 7",
+ NULL
+};
+
+
+
+/*
+ * Do a redraw
+ */
+static void react_redraw(Widget widget,
+ XtPointer client_data, XtPointer call_data)
+{
+ term_data *old_td = (term_data*)(Term->data);
+ term_data *td = (term_data*)client_data;
+
+ /* Activate the proper Term */
+ Term_activate(&td->t);
+
+ /* Request a redraw */
+ Term_redraw();
+
+ /* Activate the old Term */
+ Term_activate(&old_td->t);
+}
+
+
+
+/*
+ * Process a keypress event
+ *
+ * Also appears in "main-x11.c".
+ */
+static void react_keypress(XKeyEvent *xev)
+{
+ int i, n, mc, ms, mo, mx;
+
+ uint ks1;
+
+ XKeyEvent *ev = (XKeyEvent*)(xev);
+
+ KeySym ks;
+
+ char buf[128];
+ char msg[128];
+
+
+ /* Check for "normal" keypresses */
+ n = XLookupString(ev, buf, 125, &ks, NULL);
+
+ /* Terminate */
+ buf[n] = '\0';
+
+
+ /* Hack -- Ignore "modifier keys" */
+ if (IsModifierKey(ks)) return;
+
+
+ /* Hack -- convert into an unsigned int */
+ ks1 = (uint)(ks);
+
+ /* Extract four "modifier flags" */
+ mc = (ev->state & ControlMask) ? TRUE : FALSE;
+ ms = (ev->state & ShiftMask) ? TRUE : FALSE;
+ mo = (ev->state & Mod1Mask) ? TRUE : FALSE;
+ mx = (ev->state & Mod2Mask) ? TRUE : FALSE;
+
+
+ /* Normal keys with no modifiers */
+ if (n && !mo && !mx && !IsSpecialKey(ks))
+ {
+ /* Enqueue the normal key(s) */
+ for (i = 0; buf[i]; i++) Term_keypress(buf[i]);
+
+ /* All done */
+ return;
+ }
+
+
+ /* Handle a few standard keys (bypass modifiers) XXX XXX XXX */
+ switch (ks1)
+ {
+ case XK_Escape:
+ {
+ Term_keypress(ESCAPE);
+ return;
+ }
+
+ case XK_Return:
+ {
+ Term_keypress('\r');
+ return;
+ }
+
+ case XK_Tab:
+ {
+ Term_keypress('\t');
+ return;
+ }
+
+ case XK_Delete:
+ case XK_BackSpace:
+ {
+ Term_keypress('\010');
+ return;
+ }
+ }
+
+
+ /* Hack -- Use the KeySym */
+ if (ks)
+ {
+ sprintf(msg, "%c%s%s%s%s_%lX%c", 31,
+ mc ? "N" : "", ms ? "S" : "",
+ mo ? "O" : "", mx ? "M" : "",
+ (unsigned long)(ks), 13);
+ }
+
+ /* Hack -- Use the Keycode */
+ else
+ {
+ sprintf(msg, "%c%s%s%s%sK_%X%c", 31,
+ mc ? "N" : "", ms ? "S" : "",
+ mo ? "O" : "", mx ? "M" : "",
+ ev->keycode, 13);
+ }
+
+ /* Enqueue the "macro trigger" string */
+ for (i = 0; msg[i]; i++) Term_keypress(msg[i]);
+
+
+ /* Hack -- auto-define macros as needed */
+ if (n && (macro_find_exact(msg) < 0))
+ {
+ /* Create a macro */
+ macro_add(msg, buf);
+ }
+}
+
+
+/*
+ * Handle an event
+ */
+static void handle_event(Widget widget, XtPointer client_data, XEvent *event,
+ Boolean *continue_to_dispatch)
+{
+ term_data *old_td = (term_data*)(Term->data);
+ term_data *td = (term_data *)client_data;
+
+ /* Continue to process the event by default */
+ *continue_to_dispatch = TRUE;
+
+ /* Activate the Term */
+ Term_activate(&td->t);
+
+ switch (event->type)
+ {
+ case KeyPress:
+ {
+ /* Hack -- use old term */
+ Term_activate(&old_td->t);
+
+ /* Handle the keypress */
+ react_keypress(&(event->xkey));
+
+ /* We took care of the event */
+ *continue_to_dispatch = FALSE;
+
+ break;
+ }
+
+ /* Oops */
+ default:
+ {
+ break;
+ }
+ }
+
+ /* Activate the old term */
+ Term_activate(&old_td->t);
+
+ return;
+}
+
+
+/*
+ * Process an event (or just check for one)
+ */
+errr CheckEvent(bool_ wait)
+{
+ XEvent event;
+
+ /* No events ready, and told to just check */
+ if (!wait && !XtAppPending(appcon)) return 1;
+
+ /* Process */
+ while (1)
+ {
+ XtAppNextEvent(appcon, &event);
+ XtDispatchEvent(&event);
+ if (!XtAppPending(appcon)) break;
+ }
+
+ return (0);
+}
+
+
+/*
+ * Monstrous hack.
+ */
+static void Term_xtra_xaw_react_aux(term_data *td)
+{
+ AngbandWidget wnew = td->widget;
+
+ Display *dpy = XtDisplay((Widget) wnew);
+
+ int depth = DefaultDepthOfScreen(XtScreen((Widget) wnew));
+
+ int i;
+
+ /* See if any colors need to be changed */
+ for (i = 0; i < NUM_COLORS; i++)
+ {
+ if (depth > 1)
+ {
+ if ((wnew->angband.color[i][0] != angband_color_table[i][0]) ||
+ (wnew->angband.color[i][1] != angband_color_table[i][1]) ||
+ (wnew->angband.color[i][2] != angband_color_table[i][2]) ||
+ (wnew->angband.color[i][3] != angband_color_table[i][3]))
+ {
+ unsigned long pixel;
+
+ /* Save new values */
+ wnew->angband.color[i][0] = angband_color_table[i][0];
+ wnew->angband.color[i][1] = angband_color_table[i][1];
+ wnew->angband.color[i][2] = angband_color_table[i][2];
+ wnew->angband.color[i][3] = angband_color_table[i][3];
+
+ /* Create pixel */
+ pixel = create_pixel(dpy,
+ wnew->angband.color[i][1],
+ wnew->angband.color[i][2],
+ wnew->angband.color[i][3]);
+
+
+ /* Change */
+ XSetForeground(dpy, wnew->angband.gc[i], pixel);
+ }
+ }
+ }
+}
+
+
+/*
+ * Monstrous hack.
+ */
+static errr Term_xtra_xaw_react(void)
+{
+ int i;
+
+ /* Initialize the windows */
+ for (i = 0; i < num_term; i++)
+ {
+ term_data *td = &data[i];
+
+ if (!td) break;
+
+ Term_xtra_xaw_react_aux(td);
+ }
+
+ return (0);
+}
+
+
+/*
+ * Handle a "special request"
+ */
+static errr Term_xtra_xaw(int n, int v)
+{
+ term_data *td = (term_data*)(Term->data);
+
+ Widget widget = (Widget)(td->widget);
+
+ Display *dpy = XtDisplay(widget);
+
+ /* Handle a subset of the legal requests */
+ switch (n)
+ {
+ /* Make a noise */
+ case TERM_XTRA_NOISE:
+ XBell(dpy, 100);
+ return (0);
+
+ /* Flush the output */
+ case TERM_XTRA_FRESH:
+ XFlush(dpy);
+ /* Allow flushed events to be showed */
+ CheckEvent(FALSE);
+ return (0);
+
+ /* Process random events */
+ case TERM_XTRA_BORED:
+ return (CheckEvent(0));
+
+ /* Process events */
+ case TERM_XTRA_EVENT:
+ return (CheckEvent(v));
+
+ /* Flush events */
+ case TERM_XTRA_FLUSH:
+ while (!CheckEvent(FALSE));
+ return (0);
+
+ /* Clear the window */
+ case TERM_XTRA_CLEAR:
+ XClearWindow(dpy, XtWindow(widget));
+ return (0);
+
+ /* Delay */
+ case TERM_XTRA_DELAY:
+ usleep(1000 * v);
+ return (0);
+
+ /* Get Delay of some milliseconds */
+ case TERM_XTRA_GET_DELAY:
+ {
+ int ret;
+ struct timeval tv;
+
+ ret = gettimeofday(&tv, NULL);
+ Term_xtra_long = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
+
+ return ret;
+ }
+
+ /* Subdirectory scan */
+ case TERM_XTRA_SCANSUBDIR:
+ {
+ DIR *directory;
+ struct dirent *entry;
+
+ scansubdir_max = 0;
+
+ directory = opendir(scansubdir_dir);
+ if (!directory)
+ return 1;
+
+ while (entry = readdir(directory))
+ {
+ char file[PATH_MAX + NAME_MAX + 2];
+ struct stat filedata;
+
+ file[PATH_MAX + NAME_MAX] = 0;
+ strncpy(file, scansubdir_dir, PATH_MAX);
+ strncat(file, "/", 2);
+ strncat(file, entry->d_name, NAME_MAX);
+ if (!stat(file, &filedata) && S_ISDIR((filedata.st_mode)))
+ {
+ string_free(scansubdir_result[scansubdir_max]);
+ scansubdir_result[scansubdir_max] = string_make(entry->d_name);
+ ++scansubdir_max;
+ }
+ }
+ }
+
+ case TERM_XTRA_REACT:
+ return (Term_xtra_xaw_react());
+ }
+
+ /* Unknown */
+ return (1);
+}
+
+
+
+/*
+ * Erase a number of characters
+ */
+static errr Term_wipe_xaw(int x, int y, int n)
+{
+ term_data *td = (term_data*)(Term->data);
+
+ /* Erase using color 0 */
+ AngbandClearArea(td->widget, x, y, n, 1, 0);
+
+ /* Success */
+ return (0);
+}
+
+
+
+/*
+ * Draw the cursor, by hiliting with XOR
+ *
+ * Should perhaps use rectangle outline, ala "main-mac.c". XXX XXX XXX
+ */
+static errr Term_curs_xaw(int x, int y)
+{
+ term_data *td = (term_data*)(Term->data);
+
+ /* Hilite the cursor character */
+ AngbandClearArea(td->widget, x, y, 1, 1, COLOR_XOR);
+
+ /* Success */
+ return (0);
+}
+
+
+/*
+ * Draw a number of characters
+ */
+static errr Term_text_xaw(int x, int y, int n, byte a, cptr s)
+{
+ term_data *td = (term_data*)(Term->data);
+
+ /* Draw the text */
+ AngbandOutputText(td->widget, x, y, (String)s, n, a);
+
+ /* Success */
+ return (0);
+}
+
+
+#ifdef USE_GRAPHICS
+
+/*
+ * Draw some graphical characters.
+ */
+static errr Term_pict_xaw(int x, int y, int n, const byte *ap, const char *cp,
+ const byte *tap, const char *tcp, const byte *eap, const char *ecp)
+{
+ term_data *td = (term_data*)(Term->data);
+
+ /* Draw the pictures */
+ AngbandOutputPict(td->widget, x, y, n, ap, cp, tap, tcp, eap, ecp);
+
+ /* Success */
+ return (0);
+}
+
+#endif /* USE_GRAPHICS */
+
+
+/*
+ * Raise a term
+ */
+static void term_raise(term_data *td)
+{
+ Widget widget = (Widget)(td->widget);
+
+ XRaiseWindow(XtDisplay(XtParent(widget)), XtWindow(XtParent(widget)));
+}
+
+
+/*
+ * Initialize a term_data
+ */
+static errr term_data_init(term_data *td, Widget topLevel,
+ int key_buf, String name,
+ ArgList widget_arg, Cardinal widget_arg_no, int i)
+{
+ Widget parent;
+ term *t = &td->t;
+
+ int cols = 80;
+ int rows = 24;
+
+ char buf[80];
+ cptr str;
+
+ int val;
+
+ /* Create the shell widget */
+ parent = XtCreatePopupShell(name, topLevelShellWidgetClass, topLevel,
+ NULL, 0);
+
+ /* Window specific cols */
+ sprintf(buf, "ANGBAND_X11_COLS_%d", i);
+ str = getenv(buf);
+ val = (str != NULL) ? atoi(str) : -1;
+ if (val > 0) cols = val;
+
+ /* Window specific rows */
+ sprintf(buf, "ANGBAND_X11_ROWS_%d", i);
+ str = getenv(buf);
+ val = (str != NULL) ? atoi(str) : -1;
+ if (val > 0) rows = val;
+
+ /* Hack the main window must be at least 80x24 */
+ if (i == 0)
+ {
+ if (cols < 80) cols = 80;
+ if (rows < 24) rows = 24;
+ }
+
+ /* Reset the initial size */
+ widget_arg[0].value = rows;
+ widget_arg[1].value = cols;
+
+ /* Create the interior widget */
+ td->widget = (AngbandWidget)
+ XtCreateManagedWidget(name, angbandWidgetClass,
+ parent, widget_arg, widget_arg_no);
+
+ /* Initialize the term (full size) */
+ term_init(t, cols, rows, key_buf);
+
+ /* Use a "soft" cursor */
+ t->soft_cursor = TRUE;
+
+ /* Erase with "white space" */
+ t->attr_blank = TERM_WHITE;
+ t->char_blank = ' ';
+
+ /* Hooks */
+ t->xtra_hook = Term_xtra_xaw;
+ t->curs_hook = Term_curs_xaw;
+ t->wipe_hook = Term_wipe_xaw;
+ t->text_hook = Term_text_xaw;
+
+ /* Save the data */
+ t->data = td;
+
+ /* Register the keypress event handler */
+ XtAddEventHandler((Widget)td->widget, KeyPressMask,
+ False, (XtEventHandler) handle_event, td);
+
+ /* Redraw callback */
+ XtAddCallback((Widget)td->widget, XtNredrawCallback,
+ react_redraw, td);
+
+ /* Realize the widget */
+ XtRealizeWidget(parent);
+
+ /* Make it visible */
+ XtPopup(parent, XtGrabNone);
+
+ /* Activate (important) */
+ Term_activate(t);
+
+ Resize_term(td->widget);
+
+ return 0;
+}
+
+
+/*
+ * Initialization function for an X Athena Widget module to Angband
+ *
+ * We should accept "-d<dpy>" requests in the "argv" array. XXX XXX XXX
+ */
+errr init_xaw(int argc, char *argv[])
+{
+ int i;
+ Widget topLevel;
+ Display *dpy;
+
+ cptr dpy_name = "";
+
+
+#ifdef USE_GRAPHICS
+
+ char filename[1024];
+
+ int pict_wid = 0;
+ int pict_hgt = 0;
+ bool_ force_old_graphics = FALSE;
+
+ char *TmpData;
+
+#endif /* USE_GRAPHICS */
+
+ /* Parse args */
+ for (i = 1; i < argc; i++)
+ {
+ if (prefix(argv[i], "-d"))
+ {
+ dpy_name = &argv[i][2];
+ continue;
+ }
+
+#ifdef USE_GRAPHICS
+
+ if (prefix(argv[i], "-s"))
+ {
+ smoothRescaling = FALSE;
+ continue;
+ }
+
+ if (prefix(argv[i], "-o"))
+ {
+ force_old_graphics = TRUE;
+ continue;
+ }
+
+#endif /* USE_GRAPHICS */
+
+ if (prefix(argv[i], "-n"))
+ {
+ num_term = atoi(&argv[i][2]);
+ if (num_term > MAX_TERM_DATA) num_term = MAX_TERM_DATA;
+ else if (num_term < 1) num_term = 1;
+ continue;
+ }
+
+ plog_fmt("Ignoring option: %s", argv[i]);
+ }
+
+
+ /* Attempt to open the local display */
+ dpy = XOpenDisplay(dpy_name);
+
+ /* Failure -- assume no X11 available */
+ if (!dpy) return ( -1);
+
+ /* Close the local display */
+ XCloseDisplay(dpy);
+
+
+#ifdef USE_XAW_LANG
+
+ /* Support locale processing */
+ XtSetLanguageProc(NULL, NULL, NULL);
+
+#endif /* USE_XAW_LANG */
+
+
+ /* Initialize the toolkit */
+ topLevel = XtAppInitialize(&appcon, "Angband", NULL, 0, &argc, argv,
+ fallback, NULL, 0);
+
+ XSetIOErrorHandler(x_io_error_handler);
+
+ /* Initialize the windows */
+ for (i = 0; i < num_term; i++)
+ {
+ term_data *td = &data[i];
+
+ term_data_init(td, topLevel, 1024, termNames[i],
+ (i == 0) ? specialArgs : defaultArgs,
+ TERM_FALLBACKS, i);
+
+ angband_term[i] = Term;
+ }
+
+ /* Activate the "Angband" window screen */
+ Term_activate(&data[0].t);
+
+ /* Raise the "Angband" window */
+ term_raise(&data[0]);
+
+
+#ifdef USE_GRAPHICS
+
+ /* Try graphics */
+ if (arg_graphics)
+ {
+ /* Try the "16x16.bmp" file */
+ path_build(filename, 1024, ANGBAND_DIR_XTRA, "graf/16x16.bmp");
+
+ /* Use the "16x16.bmp" file if it exists */
+ if (!force_old_graphics &&
+ (0 == fd_close(fd_open(filename, O_RDONLY))))
+ {
+ /* Use graphics */
+ use_graphics = TRUE;
+
+ pict_wid = pict_hgt = 16;
+
+ ANGBAND_GRAF = "new";
+ }
+ else
+ {
+ /* Try the "8x8.bmp" file */
+ path_build(filename, 1024, ANGBAND_DIR_XTRA, "graf/8x8.bmp");
+
+ /* Use the "8x8.bmp" file if it exists */
+ if (0 == fd_close(fd_open(filename, O_RDONLY)))
+ {
+ /* Use graphics */
+ use_graphics = TRUE;
+
+ pict_wid = pict_hgt = 8;
+
+ ANGBAND_GRAF = "old";
+ }
+ }
+ }
+
+ /* Load graphics */
+ if (use_graphics)
+ {
+ /* Hack -- Get the Display */
+ term_data *td = &data[0];
+ Widget widget = (Widget)(td->widget);
+ Display *dpy = XtDisplay(widget);
+
+ XImage *tiles_raw;
+
+ /* Load the graphical tiles */
+ tiles_raw = ReadBMP(dpy, filename);
+
+ /* Initialize the windows */
+ for (i = 0; i < num_term; i++)
+ {
+ term_data *td = &data[i];
+
+ term *t = &td->t;
+
+ t->pict_hook = Term_pict_xaw;
+
+ t->higher_pict = TRUE;
+
+ /* Resize tiles */
+ td->widget->angband.tiles =
+ ResizeImage(dpy, tiles_raw,
+ pict_wid, pict_hgt,
+ td->widget->angband.fontwidth,
+ td->widget->angband.fontheight);
+ }
+
+ /* Initialize the transparency temp storage*/
+ for (i = 0; i < num_term; i++)
+ {
+ term_data *td = &data[i];
+ int ii, jj;
+ int depth = DefaultDepth(dpy, DefaultScreen(dpy));
+ Visual *visual = DefaultVisual(dpy, DefaultScreen(dpy));
+ int total;
+
+
+ /* Determine total bytes needed for image */
+ ii = 1;
+ jj = (depth - 1) >> 2;
+ while (jj >>= 1) ii <<= 1;
+ total = td->widget->angband.fontwidth *
+ td->widget->angband.fontheight * ii;
+
+
+ TmpData = (char *)malloc(total);
+
+ td->widget->angband.TmpImage = XCreateImage(dpy,
+ visual, depth,
+ ZPixmap, 0, TmpData,
+ td->widget->angband.fontwidth,
+ td->widget->angband.fontheight, 8, 0);
+
+ }
+
+
+ /* Free tiles_raw? XXX XXX */
+ }
+
+#endif /* USE_GRAPHICS */
+
+ /* Success */
+ return (0);
+}
+
+#endif /* USE_XAW */
+