diff options
author | Bardur Arantsson <bardur@scientician.net> | 2014-12-13 13:54:38 +0100 |
---|---|---|
committer | Bardur Arantsson <bardur@scientician.net> | 2014-12-13 13:54:38 +0100 |
commit | dc505ea036e9f2cd9ec655d142d60ea97aebbf0a (patch) | |
tree | ea6fa193f2b6e130a7af3563602d4151dd6a1427 | |
parent | d9dc4907574b52afc7b5181e9813fd36da2ca201 (diff) |
Remove xaw frontend and inline maid-x11.c
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/config.h | 3 | ||||
-rw-r--r-- | src/maid-x11.c | 96 | ||||
-rw-r--r-- | src/main-x11.c | 80 | ||||
-rw-r--r-- | src/main-xaw.c | 1512 | ||||
-rw-r--r-- | src/main.c | 20 |
6 files changed, 80 insertions, 1633 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bb49ff19..3b2c5b2f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,7 +6,7 @@ ADD_SUBDIRECTORY (squelch) # Sources SET(SRCS - main-gcu.c main-x11.c main-xaw.c main-sdl.c main-gtk2.c + main-gcu.c main-x11.c main-sdl.c main-gtk2.c z-rand.c z-util.c z-form.c z-term.c variable.cc tables.cc hooks.cc util.cc cave.cc dungeon.cc melee1.cc melee2.cc messages.cc modules.cc diff --git a/src/config.h b/src/config.h index e117ba6d..ce9b2d4b 100644 --- a/src/config.h +++ b/src/config.h @@ -30,8 +30,7 @@ * OPTION: See the Makefile(s), where several options may be declared. * * Some popular options include "USE_GCU" (allow use with Unix "curses"), - * "USE_X11" (allow basic use with Unix X11) and "USE_XAW" (allow use with - * Unix X11 plus the Athena Widget set). + * and "USE_X11" (allow basic use with Unix X11). * * The old "USE_NCU" option has been replaced with "USE_GCU". * diff --git a/src/maid-x11.c b/src/maid-x11.c deleted file mode 100644 index dff8da6e..00000000 --- a/src/maid-x11.c +++ /dev/null @@ -1,96 +0,0 @@ -/* File: maid-x11.c */ - -/* - * Copyright (c) 1997 Ben Harrison, 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. - */ - -#if defined(USE_X11) || defined(USE_XAW) - -/* - * This file defines some "XImage" manipulation functions for X11. - * - * Original code by Desvignes Sebastien (desvigne@solar12.eerie.fr). - * - * BMP format support by Denis Eropkin (denis@dream.homepage.ru). - * - * Major fixes and cleanup by Ben Harrison (benh@phial.com). - * - * This file is designed to be "included" by "main-x11.c" or "main-xaw.c", - * which will have already "included" several relevant header files. - */ - -#ifndef IsModifierKey - -/* - * Keysym macros, used on Keysyms to test for classes of symbols - * These were stolen from one of the X11 header files - * - * Also appears in "main-x11.c". - */ - -#define IsKeypadKey(keysym) \ -(((unsigned)(keysym) >= XK_KP_Space) && ((unsigned)(keysym) <= XK_KP_Equal)) - -#define IsCursorKey(keysym) \ -(((unsigned)(keysym) >= XK_Home) && ((unsigned)(keysym) < XK_Select)) - -#define IsPFKey(keysym) \ -(((unsigned)(keysym) >= XK_KP_F1) && ((unsigned)(keysym) <= XK_KP_F4)) - -#define IsFunctionKey(keysym) \ -(((unsigned)(keysym) >= XK_F1) && ((unsigned)(keysym) <= XK_F35)) - -#define IsMiscFunctionKey(keysym) \ -(((unsigned)(keysym) >= XK_Select) && ((unsigned)(keysym) < XK_KP_Space)) - -#define IsModifierKey(keysym) \ -(((unsigned)(keysym) >= XK_Shift_L) && ((unsigned)(keysym) <= XK_Hyper_R)) - -#endif /* IsModifierKey */ - - -/* - * Checks if the keysym is a special key or a normal key - * Assume that XK_MISCELLANY keysyms are special - * - * Also appears in "main-x11.c". - */ -#define IsSpecialKey(keysym) \ -((unsigned)(keysym) >= 0xFF00) - - -/* - * Hack -- Convert an RGB value to an X11 Pixel, or die. - */ -static unsigned long create_pixel(Display *dpy, byte red, byte green, byte blue) -{ - Colormap cmap = DefaultColormapOfScreen(DefaultScreenOfDisplay(dpy)); - - char cname[8]; - - XColor xcolour; - - /* Build the color */ - - xcolour.red = red * 255 + red; - xcolour.green = green * 255 + green; - xcolour.blue = blue * 255 + blue; - xcolour.flags = DoRed | DoGreen | DoBlue; - - /* Attempt to Allocate the Parsed color */ - if (!(XAllocColor(dpy, cmap, &xcolour))) - { - quit_fmt("Couldn't allocate bitmap color '%s'\n", cname); - } - - return (xcolour.pixel); -} - - - - -#endif /* USE_X11 || USE_XAW */ diff --git a/src/main-x11.c b/src/main-x11.c index 68697061..e4ea7455 100644 --- a/src/main-x11.c +++ b/src/main-x11.c @@ -117,10 +117,86 @@ #define NAME_MAX _POSIX_NAME_MAX #endif + +/* + * This file is designed to be "included" by "main-x11.c" or "main-xaw.c", + * which will have already "included" several relevant header files. + */ + +#ifndef IsModifierKey + /* - * Include some helpful X11 code. + * Keysym macros, used on Keysyms to test for classes of symbols + * These were stolen from one of the X11 header files + * + * Also appears in "main-x11.c". */ -#include "maid-x11.c" + +#define IsKeypadKey(keysym) \ +(((unsigned)(keysym) >= XK_KP_Space) && ((unsigned)(keysym) <= XK_KP_Equal)) + +#define IsCursorKey(keysym) \ +(((unsigned)(keysym) >= XK_Home) && ((unsigned)(keysym) < XK_Select)) + +#define IsPFKey(keysym) \ +(((unsigned)(keysym) >= XK_KP_F1) && ((unsigned)(keysym) <= XK_KP_F4)) + +#define IsFunctionKey(keysym) \ +(((unsigned)(keysym) >= XK_F1) && ((unsigned)(keysym) <= XK_F35)) + +#define IsMiscFunctionKey(keysym) \ +(((unsigned)(keysym) >= XK_Select) && ((unsigned)(keysym) < XK_KP_Space)) + +#define IsModifierKey(keysym) \ +(((unsigned)(keysym) >= XK_Shift_L) && ((unsigned)(keysym) <= XK_Hyper_R)) + +#endif /* IsModifierKey */ + + +/* + * Checks if the keysym is a special key or a normal key + * Assume that XK_MISCELLANY keysyms are special + * + * Also appears in "main-x11.c". + */ +#define IsSpecialKey(keysym) \ +((unsigned)(keysym) >= 0xFF00) + + +/* + * Hack -- Convert an RGB value to an X11 Pixel, or die. + * + * Original code by Desvignes Sebastien (desvigne@solar12.eerie.fr). + * + * BMP format support by Denis Eropkin (denis@dream.homepage.ru). + * + * Major fixes and cleanup by Ben Harrison (benh@phial.com). + */ +static unsigned long create_pixel(Display *dpy, byte red, byte green, byte blue) +{ + Colormap cmap = DefaultColormapOfScreen(DefaultScreenOfDisplay(dpy)); + + char cname[8]; + + XColor xcolour; + + /* Build the color */ + + xcolour.red = red * 255 + red; + xcolour.green = green * 255 + green; + xcolour.blue = blue * 255 + blue; + xcolour.flags = DoRed | DoGreen | DoBlue; + + /* Attempt to Allocate the Parsed color */ + if (!(XAllocColor(dpy, cmap, &xcolour))) + { + quit_fmt("Couldn't allocate bitmap color '%s'\n", cname); + } + + return (xcolour.pixel); +} + + /* diff --git a/src/main-xaw.c b/src/main-xaw.c deleted file mode 100644 index 96e3b5b3..00000000 --- a/src/main-xaw.c +++ /dev/null @@ -1,1512 +0,0 @@ -/* 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; - - - /* 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); -} - - - -/* - * 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); -} - - -/* - * 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); - - 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); -} - - - - -/* - * 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 = ""; - - - - /* Parse args */ - for (i = 1; i < argc; i++) - { - if (prefix(argv[i], "-d")) - { - dpy_name = &argv[i][2]; - continue; - } - - - 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; - } - - fprintf(stderr, "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]); - - - - /* Success */ - return (0); -} - -#endif /* USE_XAW */ - @@ -285,13 +285,6 @@ usage: puts(" -- -b Turn off software backing store"); #endif /* USE_GTK2 */ -#ifdef USE_XAW - puts(" -mxaw To use XAW"); - puts(" -- Sub options"); - puts(" -- -n# Number of terms to use"); - puts(" -- -d<name> Display to use"); -#endif /* USE_XAW */ - #ifdef USE_X11 puts(" -mx11 To use X11"); puts(" -- Sub options"); @@ -352,19 +345,6 @@ usage: } #endif -#ifdef USE_XAW - /* Attempt to use the "main-xaw.c" support */ - if (!done && (!mstr || (streq(mstr, "xaw")))) - { - extern errr init_xaw(int, char**); - if (0 == init_xaw(argc, argv)) - { - ANGBAND_SYS = "xaw"; - done = TRUE; - } - } -#endif - #ifdef USE_X11 /* Attempt to use the "main-x11.c" support */ if (!done && (!mstr || (streq(mstr, "x11")))) |