-/* File: main-x11.c */
+/* File: main-x11.c */
/*
* Copyright (c) 1997 Ben Harrison, and others
*/
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
/*
- * ÆüËܸì(EUC-JAPAN)Âбþ (-DJP)
- * ¡¦´Á»ú¥Õ¥©¥ó¥È¤Î°·¤¤¤òÄɲÃ
- * ¡¦ÆüËܸì¤ò´Þ¤àʸ»úÎó¤Îɽ¼¨¥ë¡¼¥Á¥ó XDrawMultiString() ¤ÎÄɲÃ
- * ¡¦ÆüËܸì¤Îɽ¼¨Éý¤Ï¡¤¥Õ¥©¥ó¥È¤Î¾ðÊó¤Ë¤è¤é¤¹ASCII¥Õ¥©¥ó¥È¤Î2Çܤ˸ÇÄê
+ * 日本語(EUC-JAPAN)対応 (-DJP)
+ * ・漢字フォントの扱いを追加
+ * ・日本語を含む文字列の表示ルーチン XDrawMultiString() の追加
+ * ・日本語の表示幅は,フォントの情報によらすASCIIフォントの2倍に固定
*
- * ̤Âбþ
- * EUCȾ³Ñ¤Î°·¤¤
+ * 未対応
+ * EUC半角の扱い
*
- * 1996/6/7 Íû ¹¸¿ (ri@kuis.kyoto-u.ac.jp)
+ * 1996/6/7 李 晃伸 (ri@kuis.kyoto-u.ac.jp)
*/
#endif
/*
#if 0
char *XSetIMValues(XIM, ...); /* Hack for XFree86 4.0 */
#endif
+#include <X11/Xatom.h>
#endif /* __MAKEDEPEND__ */
-
+#include <iconv.h>
/*
* Include some helpful X11 code.
*/
/* Init an infowin by giving father as an (info_win*) (or NULL), and data */
#define Infowin_init_dad(D,X,Y,W,H,B,FG,BG) \
Infowin_init_data(((D) ? ((D)->win) : (Window)(None)), \
- X,Y,W,H,B,FG,BG)
+ X,Y,W,H,B,FG,BG)
/* Init a top level infowin by pos,size,bord,Colors */
static infowin *Focuswin = (infowin*)(NULL);
#endif
static infoclr *Infoclr = (infoclr*)(NULL);
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
static infofnt *Infofnt = (infofnt*)(NULL);
static infofnt *Infokfnt = (infofnt*)(NULL);
#else
/**** Generic code ****/
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
#define Infokfnt_set(I) \
- (Infokfnt = (I))
+ (Infokfnt = (I))
#endif
/*
* Init the current metadpy, with various initialization stuff.
* If 'dad == None' assume 'dad == root'
*/
static errr Infowin_init_data(Window dad, int x, int y, int w, int h,
- int b, Pixell fg, Pixell bg)
+ int b, Pixell fg, Pixell bg)
{
Window xid;
{
/* Execute the request */
XFillRectangle(Metadpy->dpy, Infowin->win, Infoclr->gc,
- 0, 0, Infowin->w, Infowin->h);
+ 0, 0, Infowin->w, Infowin->h);
/* Success */
return (0);
/* Set up the GC mask */
gc_mask = (GCFunction | GCBackground | GCForeground |
- GCFillStyle | GCGraphicsExposures);
+ GCFillStyle | GCGraphicsExposures);
/* Create the GC detailed above */
gc = XCreateGC(Metadpy->dpy, Metadpy->root, gc_mask, &gcv);
{
infofnt *ifnt = Infofnt;
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
infofnt *ikfnt = Infokfnt;
#endif
/* Deal with 'name' */
string_free(ifnt->name);
}
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
if (ikfnt->name)
{
/* Free the name */
string_free(ikfnt->name);
}
#endif
+
/* Nuke info if needed */
if (ifnt->nuke)
{
/* Free the font */
+#ifdef USE_FONTSET
+ XFreeFontSet(Metadpy->dpy, ifnt->info);
+#else
XFreeFont(Metadpy->dpy, ifnt->info);
+#endif
}
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
if (ikfnt->nuke)
{
/* Free the font */
/*
* Prepare a new 'infofnt'
*/
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
static errr Infofnt_prepare(XFontStruct *info, XFontStruct *kinfo)
#else
#ifdef USE_FONTSET
{
infofnt *ifnt = Infofnt;
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
infofnt *ikfnt = Infokfnt;
#endif
XCharStruct *cs;
if(ascent < (*fontinfo)->ascent) ascent = (*fontinfo)->ascent;
if(descent < (*fontinfo)->descent) descent = (*fontinfo)->descent;
if(((*fontinfo)->max_byte1) > 0){
- /* ¿¥Ð¥¤¥Èʸ»ú¤Î¾ì¹ç¤ÏÉýȾʬ(ü¿ôÀÚ¤ê¾å¤²)¤Çɾ²Á¤¹¤ë */
+ /* 多バイト文字の場合は幅半分(端数切り上げ)で評価する */
if(width < (cs->width+1)/2) width = (cs->width+1)/2;
}else{
if(width < cs->width) width = cs->width;
else
ifnt->twid = ifnt->wid;
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
/* Assign the struct */
ikfnt->info = kinfo;
/*
* Initialize a new 'infofnt'.
*/
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
static errr Infofnt_init_real(XFontStruct *info, XFontStruct *kinfo)
#else
#ifdef USE_FONTSET
/* Wipe the thing */
(void)WIPE(Infofnt, infofnt);
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
WIPE(Infokfnt, infofnt);
#endif
/* No nuking */
Infofnt->nuke = 0;
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
Infokfnt->nuke = 0;
#endif
/* Attempt to prepare it */
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
return (Infofnt_prepare (info, kinfo));
#else
return (Infofnt_prepare(info));
* Inputs:
* name: The name of the requested Font
*/
-#ifdef _JP
-static errr Infofnt_init_data(cptr name, cptr kname)
+#ifdef USE_JP_FONTSTRUCT
+static void Infofnt_init_data(cptr name, cptr kname)
#else
-static errr Infofnt_init_data(cptr name)
+static void Infofnt_init_data(cptr name)
#endif
{
#endif
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
XFontStruct *kinfo;
#endif
/*** Load the info Fresh, using the name ***/
/* If the name is not given, report an error */
- if (!name) return (-1);
+ if (!name || !*name) quit("Missing font!");
-#ifdef _JP
- if (!kname) return (-1);
+#ifdef USE_JP_FONTSTRUCT
+ if (!kname || !*kname) quit("Missing kanji font!");
#endif
/* Attempt to load the font */
#ifdef USE_FONTSET
}
#else
info = XLoadQueryFont(Metadpy->dpy, name);
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
kinfo = XLoadQueryFont(Metadpy->dpy, kname);
#endif
#endif
/* The load failed, try to recover */
- if (!info) return (-1);
-#ifdef _JP
- if (!kinfo) return (-1);
+ if (!info) quit_fmt("Failed to find font:\"%s\"", name);
+#ifdef USE_JP_FONTSTRUCT
+ if (!kinfo) quit_fmt("Failed to find font:\"%s\"", kname);
#endif
/* Wipe the thing */
(void)WIPE(Infofnt, infofnt);
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
WIPE(Infokfnt, infofnt);
#endif
/* Attempt to prepare it */
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
if (Infofnt_prepare(info, kinfo))
#else
if (Infofnt_prepare(info))
XFreeFontSet(Metadpy->dpy, info);
#else
XFreeFont(Metadpy->dpy, info);
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
XFreeFont(Metadpy->dpy, kinfo);
#endif
#endif
/* Fail */
- return (-1);
+ quit_fmt("Failed to prepare font:\"%s\"", name);
}
/* Save a copy of the font name */
Infofnt->name = string_make(name);
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
Infokfnt->name = string_make(kname);
#endif
/* Mark it as nukable */
Infofnt->nuke = 1;
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
Infokfnt->nuke = 1;
#endif
-
- /* Success */
- return (0);
}
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
/*
- * EUCÆüËܸ쥳¡¼¥É¤ò´Þ¤àʸ»úÎó¤òɽ¼¨¤¹¤ë (Xlib)
+ * EUC日本語コードを含む文字列を表示する (Xlib)
*/
static void
XDrawMultiString(display,d,gc, x, y, string, len, afont,
#ifdef TOFU
if ( (*str) == 0x7f ) {
-
- /* 0x7F¤Ï¢£¤Ç·è¤áÂǤÁ */
-
- /* Ϣ³¤¹¤ë0x7F¤ÎŤµ¤ò¸¡½Ð */
- slen = 0;
- while ( str < endp && (*str) == 0x7f ) {
- slen++;
+
+ /* 0x7Fは■で決め打ち */
+
+ /* 連続する0x7Fの長さを検出 */
+ slen = 0;
+ while ( str < endp && (*str) == 0x7f ) {
+ slen++;
str++;
- }
-
- /* ÉÁ²è */
- XFillRectangle( display, d, gc, x, y-afont_ascent,
- slen * afont_width, afont_height);
+ }
+
+ /* 描画 */
+ XFillRectangle( display, d, gc, x, y-afont_ascent,
+ slen * afont_width, afont_height);
- /* ¥Ý¥¤¥ó¥¿¤ò¿Ê¤á¤ë */
- x += afont_width * slen;
+ /* ポインタを進める */
+ x += afont_width * slen;
}
else
#endif
if ( iskanji(*str) ) {
-
- /* UJIS¤Î»Ï¤Þ¤ê */
-
- /* Ϣ³¤¹¤ëUJISʸ»ú¤ÎŤµ¤ò¸¡½Ð */
- slen = 0;
- while ( str < endp && *str && iskanji(*str) ) {
- kanji[slen].byte1 = *str++ & 0x7f;
- kanji[slen++].byte2 = *str++ & 0x7f;
- }
-
- /* ÉÁ²è */
- XSetFont( display, gc, kfont->fid );
- XDrawImageString16( display, d, gc, x, y, kanji, slen );
+
+ /* UJISの始まり */
+
+ /* 連続するUJIS文字の長さを検出 */
+ slen = 0;
+ while ( str < endp && *str && iskanji(*str) ) {
+ kanji[slen].byte1 = *str++ & 0x7f;
+ kanji[slen++].byte2 = *str++ & 0x7f;
+ }
+
+ /* 描画 */
+ XSetFont( display, gc, kfont->fid );
+ XDrawImageString16( display, d, gc, x, y, kanji, slen );
- /* ¥Ý¥¤¥ó¥¿¤ò¿Ê¤á¤ë */
- x += kfont_width * slen;
-
+ /* ポインタを進める */
+ x += kfont_width * slen;
+
} else {
-
- /* Èó´Á»ú(=ASCII¤È²¾Äê)¤Î»Ï¤Þ¤ê */
-
- /* Ϣ³¤¹¤ëASCIIʸ»ú¤ò¸¡½Ð */
- p = str;
- slen = 0;
- while ( str < endp && *str && !iskanji(*str) ) {
+
+ /* 非漢字(=ASCIIと仮定)の始まり */
+
+ /* 連続するASCII文字を検出 */
+ p = str;
+ slen = 0;
+ while ( str < endp && *str && !iskanji(*str) ) {
#ifdef TOFU
- if (*str == 0x7f)break;
-#endif
- str++;
- slen++;
- }
-
- /* ÉÁ²è */
- XSetFont( display, gc, afont->fid );
- XDrawImageString( display, d, gc, x, y, p, slen );
-
- /* ¥Ý¥¤¥ó¥¿¤ò¿Ê¤á¤ë */
- x += afont_width * slen;
+ if (*str == 0x7f)break;
+#endif
+ str++;
+ slen++;
+ }
+
+ /* 描画 */
+ XSetFont( display, gc, afont->fid );
+ XDrawImageString( display, d, gc, x, y, p, slen );
+
+ /* ポインタを進める */
+ x += afont_width * slen;
}
}
}
/*** Actually draw 'str' onto the infowin ***/
-#if 1
-#ifndef JP
+#ifndef USE_FONTSET
/* Be sure the correct font is ready */
XSetFont(Metadpy->dpy, Infoclr->gc, Infofnt->info->fid);
#endif
-#endif
/*** Handle the fake mono we can enforce on fonts ***/
/* Monotize the font */
if (Infofnt->mono)
{
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
/* Be sure the correct font is ready */
XSetFont(Metadpy->dpy, Infoclr->gc, Infofnt->info->fid);
#endif
{
/* Note that the Infoclr is set up to contain the Infofnt */
XDrawImageString(Metadpy->dpy, Infowin->win, Infoclr->gc,
- x + i * Infofnt->wid + Infofnt->off, y, str + i, 1);
+ x + i * Infofnt->wid + Infofnt->off, y, str + i, 1);
}
}
else
{
/* Note that the Infoclr is set up to contain the Infofnt */
-#ifdef _JP
- /* ´Á»ú¥Õ¥©¥ó¥È¤Îɽ¼¨Éý¤Ï ASCII¥Õ¥©¥ó¥È¤Î2Çܤ˸ÇÄê */
+#ifdef USE_JP_FONTSTRUCT
+ /* 漢字フォントの表示幅は ASCIIフォントの2倍に固定 */
XDrawMultiString(Metadpy->dpy, Infowin->win, Infoclr->gc,
- x, y, str, len,
- Infofnt->info, Infofnt->wid, Infofnt->hgt,
- Infofnt->asc,
- Infokfnt->info, Infofnt->wid * 2);
+ x, y, str, len,
+ Infofnt->info, Infofnt->wid, Infofnt->hgt,
+ Infofnt->asc,
+ Infokfnt->info, Infofnt->wid * 2);
#else
#ifdef USE_FONTSET
- /* Delete rectangle first */
- XClearArea(Metadpy->dpy, Infowin->win, x, y - Infofnt->asc, len * Infofnt->wid, Infofnt->hgt, FALSE);
+
+ iconv_t cd = iconv_open("UTF-8", "EUC-JP");
+ size_t inlen = len;
+ size_t outlen = len * 2;
+ char *kanji = malloc(outlen);
+ char *sp; char *kp = kanji;
+ char sbuf[1024];
+ my_strcpy(sbuf, str, sizeof(sbuf));
+ sp = sbuf;
+ iconv(cd, &sp, &inlen, &kp, &outlen);
+ iconv_close(cd);
XmbDrawImageString(Metadpy->dpy, Infowin->win, Infofnt->info,
- Infoclr->gc, x, y, str, len);
+ Infoclr->gc, x, y, kanji, kp-kanji);
+ free(kanji);
#else
XDrawImageString(Metadpy->dpy, Infowin->win, Infoclr->gc,
- x, y, str, len);
+ x, y, str, len);
#endif
#endif
term t;
infofnt *fnt;
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
infofnt *kfnt;
#endif
XImage *tiles;
-#ifdef USE_TRANSPARENCY
-
/* Tempory storage for overlaying tiles. */
XImage *TmpImage;
#endif
-#endif
-
};
static term_data data[MAX_TERM_DATA];
+/* Use short names for the most commonly used elements of various structures. */
+#define DPY (Metadpy->dpy)
+#define WIN (Infowin->win)
+
+
+/* Describe a set of co-ordinates. */
+typedef struct co_ord co_ord;
+struct co_ord
+{
+ int x;
+ int y;
+};
+
+
+/*
+ * A special structure to store information about the text currently
+ * selected.
+ */
+typedef struct x11_selection_type x11_selection_type;
+struct x11_selection_type
+{
+ bool select; /* The selection is currently in use. */
+ bool drawn; /* The selection is currently displayed. */
+ term *t; /* The window where the selection is found. */
+ co_ord init; /* The starting co-ordinates. */
+ co_ord cur; /* The end co-ordinates (the current ones if still copying). */
+ co_ord old; /* The previous end co-ordinates. */
+ Time time; /* The time at which the selection was finalised. */
+};
+
+static x11_selection_type s_ptr[1];
+
/*
* Process a keypress event
}
case XK_Delete:
+ {
+ Term_keypress(0x7f);
+ return;
+ }
case XK_BackSpace:
{
Term_keypress('\010');
if (ks)
{
sprintf(msg, "%c%s%s%s%s_%lX%c", 31,
- mc ? "N" : "", ms ? "S" : "",
- mo ? "O" : "", mx ? "M" : "",
- (unsigned long)(ks), 13);
+ 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);
+ mc ? "N" : "", ms ? "S" : "",
+ mo ? "O" : "", mx ? "M" : "",
+ ev->keycode, 13);
}
/* Enqueue the "macro trigger" string */
}
+/*
+ * Find the square a particular pixel is part of.
+ */
+static void pixel_to_square(int * const x, int * const y,
+ const int ox, const int oy)
+{
+ (*x) = (ox - Infowin->ox) / Infofnt->wid;
+ (*y) = (oy - Infowin->oy) / Infofnt->hgt;
+}
+
+/*
+ * Find the pixel at the top-left corner of a square.
+ */
+static void square_to_pixel(int * const x, int * const y,
+ const int ox, const int oy)
+{
+ (*x) = ox * Infofnt->wid + Infowin->ox;
+ (*y) = oy * Infofnt->hgt + Infowin->oy;
+}
+
+/*
+ * Convert co-ordinates from starting corner/opposite corner to minimum/maximum.
+ */
+static void sort_co_ord(co_ord *min, co_ord *max,
+ const co_ord *b, const co_ord *a)
+{
+ min->x = MIN(a->x, b->x);
+ min->y = MIN(a->y, b->y);
+ max->x = MAX(a->x, b->x);
+ max->y = MAX(a->y, b->y);
+}
+
+/*
+ * Remove the selection by redrawing it.
+ */
+static void mark_selection_clear(int x1, int y1, int x2, int y2)
+{
+ Term_redraw_section(x1,y1,x2,y2);
+}
+
+/*
+ * Select an area by drawing a grey box around it.
+ * NB. These two functions can cause flicker as the selection is modified,
+ * as the game redraws the entire marked section.
+ */
+static void mark_selection_mark(int x1, int y1, int x2, int y2)
+{
+ square_to_pixel(&x1, &y1, x1, y1);
+ square_to_pixel(&x2, &y2, x2, y2);
+ XDrawRectangle(Metadpy->dpy, Infowin->win, clr[2]->gc, x1, y1,
+ x2-x1+Infofnt->wid - 1, y2-y1+Infofnt->hgt - 1);
+}
+
+/*
+ * Mark a selection by drawing boxes around it (for now).
+ */
+static void mark_selection(void)
+{
+ co_ord min, max;
+ term *old = Term;
+ bool draw = s_ptr->select;
+ bool clear = s_ptr->drawn;
+
+ /* Open the correct term if necessary. */
+ if (s_ptr->t != old) Term_activate(s_ptr->t);
+
+ if (clear)
+ {
+ sort_co_ord(&min, &max, &s_ptr->init, &s_ptr->old);
+ mark_selection_clear(min.x, min.y, max.x, max.y);
+ }
+ if (draw)
+ {
+ sort_co_ord(&min, &max, &s_ptr->init, &s_ptr->cur);
+ mark_selection_mark(min.x, min.y, max.x, max.y);
+ }
+
+ /* Finish on the current term. */
+ if (s_ptr->t != old) Term_activate(old);
+
+ s_ptr->old.x = s_ptr->cur.x;
+ s_ptr->old.y = s_ptr->cur.y;
+ s_ptr->drawn = s_ptr->select;
+}
+
+/*
+ * Forget a selection for one reason or another.
+ */
+static void copy_x11_release(void)
+{
+ /* Deselect the current selection. */
+ s_ptr->select = FALSE;
+
+ /* Remove its graphical represesntation. */
+ mark_selection();
+}
+
+/*
+ * Start to select some text on the screen.
+ */
+static void copy_x11_start(int x, int y)
+{
+ if (s_ptr->select) copy_x11_release();
+
+ /* Remember where the selection started. */
+ s_ptr->t = Term;
+ s_ptr->init.x = s_ptr->cur.x = s_ptr->old.x = x;
+ s_ptr->init.y = s_ptr->cur.y = s_ptr->old.y = y;
+}
+
+/*
+ * Respond to movement of the mouse when selecting text.
+ */
+static void copy_x11_cont(int x, int y, unsigned int buttons)
+{
+ /* Use the nearest square within bounds if the mouse is outside. */
+ x = MIN(MAX(x, 0), Term->wid-1);
+ y = MIN(MAX(y, 0), Term->hgt-1);
+
+ /* The left mouse button isn't pressed. */
+ if (~buttons & Button1Mask) return;
+
+ /* Not a selection in this window. */
+ if (s_ptr->t != Term) return;
+
+ /* Not enough movement. */
+ if (x == s_ptr->old.x && y == s_ptr->old.y && s_ptr->select) return;
+
+ /* Something is being selected. */
+ s_ptr->select = TRUE;
+
+ /* Track the selection. */
+ s_ptr->cur.x = x;
+ s_ptr->cur.y = y;
+
+ /* Hack - display it inefficiently. */
+ mark_selection();
+}
+
+/*
+ * Respond to release of the left mouse button by putting the selected text in
+ * the primary buffer.
+ */
+static void copy_x11_end(const Time time)
+{
+ /* No selection. */
+ if (!s_ptr->select) return;
+
+ /* Not a selection in this window. */
+ if (s_ptr->t != Term) return;
+
+ /* Remember when the selection was finalised. */
+ s_ptr->time = time;
+
+ /* Acquire the primary selection. */
+ XSetSelectionOwner(Metadpy->dpy, XA_PRIMARY, Infowin->win, time);
+ if (XGetSelectionOwner(Metadpy->dpy, XA_PRIMARY) != Infowin->win)
+ {
+ /* Failed to acquire the selection, so forget it. */
+ /* bell("Failed to acquire primary buffer."); */
+ s_ptr->select = FALSE;
+ mark_selection();
+ }
+}
+
+
+static Atom xa_targets, xa_timestamp, xa_text, xa_compound_text;
+
+/*
+ * Set the required variable atoms at start-up to avoid errors later.
+ */
+static void set_atoms(void)
+{
+ xa_targets = XInternAtom(DPY, "TARGETS", False);
+ xa_timestamp = XInternAtom(DPY, "TIMESTAMP", False);
+ xa_text = XInternAtom(DPY, "TEXT", False);
+ xa_compound_text = XInternAtom(DPY, "COMPOUND_TEXT", False);
+}
+
+
+static Atom request_target = 0;
+
+/*
+ * Send a message to request that the PRIMARY buffer be sent here.
+ */
+static void paste_x11_request(Atom target, const Time time)
+{
+ /*
+ * It's from some sample programs on the web.
+ * What does it mean? -- XXX
+ */
+ Atom property = XInternAtom(DPY, "__COPY_TEXT", False);
+
+ /* Check the owner. */
+ if (XGetSelectionOwner(DPY, XA_PRIMARY) == None)
+ {
+ /* No selection. */
+ /* bell("No selection found."); */
+ return;
+ }
+
+ request_target = target;
+
+ /* Request the event */
+ XConvertSelection(DPY, XA_PRIMARY, target, property, WIN, time);
+}
+
+
+/*
+ * Add the contents of the PRIMARY buffer to the input queue.
+ *
+ * Hack - This doesn't use the "time" of the event, and so accepts anything a
+ * client tries to send it.
+ */
+static void paste_x11_accept(const XSelectionEvent *ptr)
+{
+ unsigned long left;
+ const long offset = 0;
+ const long length = 32000;
+ XTextProperty xtextproperty;
+ errr err = 0;
+
+ /*
+ * It's from some sample programs on the web.
+ * What does it mean? -- XXX
+ */
+ Atom property = XInternAtom(DPY, "__COPY_TEXT", False);
+
+
+ /* Failure. */
+ if (ptr->property == None)
+ {
+ if (request_target == xa_compound_text)
+ {
+ /* Re-request as STRING */
+ paste_x11_request(XA_STRING, ptr->time);
+ }
+ else
+ {
+ request_target = 0;
+ plog("Paste failure (remote client could not send).");
+ }
+ return;
+ }
+
+ if (ptr->selection != XA_PRIMARY)
+ {
+ plog("Paste failure (remote client did not send primary selection).");
+ return;
+ }
+
+ if (ptr->target != request_target)
+ {
+ plog("Paste failure (selection in unknown format).");
+ return;
+ }
+
+ /* Get text */
+ if (XGetWindowProperty(Metadpy->dpy, Infowin->win, property, offset,
+ length, TRUE, request_target,
+ &xtextproperty.encoding,
+ &xtextproperty.format,
+ &xtextproperty.nitems,
+ &left,
+ &xtextproperty.value)
+ != Success)
+ {
+ /* Failure */
+ return;
+ }
+
+ if (request_target == xa_compound_text)
+ {
+ char **list;
+ int count;
+
+ XmbTextPropertyToTextList(DPY, &xtextproperty, &list, &count);
+
+ if (list)
+ {
+ int i;
+
+ for (i = 0; i < count; i++)
+ {
+ /* Paste the text. */
+ err = type_string(list[i], 0);
+
+ if (err) break;
+ }
+
+ /* Free the string */
+ XFreeStringList(list);
+ }
+ }
+ else /* if (request_target == XA_STRING) */
+ {
+ /* Paste the text. */
+ err = type_string((char *)xtextproperty.value, xtextproperty.nitems);
+ }
+
+ /* Free the data pasted. */
+ XFree(xtextproperty.value);
+
+ /* No room. */
+ if (err)
+ {
+ plog("Paste failure (too much text selected).");
+ }
+}
+
+
+/*
+ * Add a character to a string in preparation for sending it to another
+ * client as a STRING.
+ * This doesn't change anything, as clients tend not to have difficulty in
+ * receiving this format (although the standard specifies a restricted set).
+ * Strings do not have a colour.
+ */
+static bool paste_x11_send_text(XSelectionRequestEvent *rq)
+{
+ char buf[1024];
+ char *list[1000];
+ co_ord max, min;
+ TERM_LEN x,y;
+ int l,n;
+ TERM_COLOR a;
+ char c;
+
+ /* Too old, or incorrect call. */
+ if (rq->time < s_ptr->time) return FALSE;
+
+ /* Work out which way around to paste. */
+ sort_co_ord(&min, &max, &s_ptr->init, &s_ptr->cur);
+
+ /* Paranoia. */
+ if (XGetSelectionOwner(DPY, XA_PRIMARY) != WIN)
+ {
+ /* bell("Someone stole my selection!"); */
+ return FALSE;
+ }
+
+ /* Delete the old value of the property. */
+ XDeleteProperty(DPY, rq->requestor, rq->property);
+
+ for (n = 0, y = 0; y < Term->hgt; y++)
+ {
+#ifdef JP
+ int kanji = 0;
+#endif
+ if (y < min.y) continue;
+ if (y > max.y) break;
+
+ for (l = 0, x = 0; x < Term->wid; x++)
+ {
+#ifdef JP
+ if (x > max.x) break;
+
+ /* Find the character. */
+ Term_what(x, y, &a, &c);
+
+ if (1 == kanji) kanji = 2;
+ else if (iskanji(c)) kanji = 1;
+ else kanji = 0;
+
+ if (x < min.x) continue;
+
+ /*
+ * A single kanji character was divided in two...
+ * Delete the garbage.
+ */
+ if ((2 == kanji && x == min.x) ||
+ (1 == kanji && x == max.x))
+ c = ' ';
+#else
+ if (x > max.x) break;
+ if (x < min.x) continue;
+
+ /* Find the character. */
+ Term_what(x, y, &a, &c);
+#endif
+
+ /* Add it. */
+ buf[l] = c;
+ l++;
+ }
+
+ /* Ignore trailing spaces */
+ while (buf[l-1] == ' ') l--;
+
+ /* Terminate all line unless it's single line. */
+ if (min.y != max.y)
+ {
+ buf[l] = '\n';
+ l++;
+ }
+
+ /* End of string */
+ buf[l] = '\0';
+
+ list[n++] = (char *)string_make(buf);
+ }
+
+ /* End of the list */
+ list[n] = NULL;
+
+
+ if (rq->target == XA_STRING)
+ {
+ for (n = 0; list[n]; n++)
+ {
+ /* Send the (non-empty) string. */
+ XChangeProperty(DPY, rq->requestor, rq->property, rq->target, 8,
+ PropModeAppend, (unsigned char *)list[n], strlen(list[n]));
+ }
+ }
+
+ else if (rq->target == xa_text ||
+ rq->target == xa_compound_text)
+ {
+ XTextProperty text_prop;
+ XICCEncodingStyle style;
+
+ if (rq->target == xa_text)
+ style = XStdICCTextStyle;
+ else /* if (rq->target == xa_compound_text) */
+ style = XCompoundTextStyle;
+
+ if (Success ==
+ XmbTextListToTextProperty(DPY, list, n, style, &text_prop))
+ {
+ /* Send the compound text */
+ XChangeProperty(DPY,
+ rq->requestor,
+ rq->property,
+ text_prop.encoding,
+ text_prop.format,
+ PropModeAppend,
+ text_prop.value,
+ text_prop.nitems);
+
+ /* Free the data. */
+ XFree(text_prop.value);
+ }
+ }
+
+ /* Free the list of strings */
+ for (n = 0; list[n]; n++)
+ {
+ string_free(list[n]);
+ }
+
+ return TRUE;
+}
+
+/*
+ * Send some text requested by another X client.
+ */
+static void paste_x11_send(XSelectionRequestEvent *rq)
+{
+ XEvent event;
+ XSelectionEvent *ptr = &(event.xselection);
+
+ /* Set the event parameters. */
+ ptr->type = SelectionNotify;
+ ptr->property = rq->property;
+ ptr->display = rq->display;
+ ptr->requestor = rq->requestor;
+ ptr->selection = rq->selection;
+ ptr->target = rq->target;
+ ptr->time = rq->time;
+
+ /* Paste the appropriate information for each target type.
+ * Note that this currently rejects MULTIPLE targets.
+ */
+
+ if (rq->target == XA_STRING ||
+ rq->target == xa_text ||
+ rq->target == xa_compound_text)
+ {
+ if (!paste_x11_send_text(rq))
+ ptr->property = None;
+ }
+ else if (rq->target == xa_targets)
+ {
+ Atom target_list[4];
+ target_list[0] = XA_STRING;
+ target_list[1] = xa_text;
+ target_list[2] = xa_compound_text;
+ target_list[3] = xa_targets;
+ XChangeProperty(DPY, rq->requestor, rq->property, rq->target,
+ (8 * sizeof(target_list[0])), PropModeReplace,
+ (unsigned char *)target_list,
+ (sizeof(target_list) / sizeof(target_list[0])));
+ }
+ else if (rq->target == xa_timestamp)
+ {
+ XChangeProperty(DPY, rq->requestor, rq->property, rq->target,
+ (8 * sizeof(Time)), PropModeReplace,
+ (unsigned char *)s_ptr->time, 1);
+ }
+ else
+ {
+ ptr->property = None;
+ }
+
+ /* Send whatever event we're left with. */
+ XSendEvent(DPY, rq->requestor, FALSE, NoEventMask, &event);
+}
+
+
+/*
+ * Handle various events conditional on presses of a mouse button.
+ */
+static void handle_button(Time time, int x, int y, int button,
+ bool press)
+{
+ /* The co-ordinates are only used in Angband format. */
+ pixel_to_square(&x, &y, x, y);
+
+ if (press && button == 1) copy_x11_start(x, y);
+ if (!press && button == 1) copy_x11_end(time);
+ if (!press && button == 2) paste_x11_request(xa_compound_text, time);
+}
/*
term_data *td = NULL;
infowin *iwin = NULL;
- int i, x, y;
+ int i;
#ifdef USE_XIM
redo_checkevent:
/* Do not wait unless requested */
if (!wait && !XPending(Metadpy->dpy)) return (1);
+ /*
+ * Hack - redraw the selection, if needed.
+ * This doesn't actually check that one of its squares was drawn to,
+ * only that this may have happened.
+ */
+ if (s_ptr->select && !s_ptr->drawn) mark_selection();
+
/* Load the Event */
XNextEvent(Metadpy->dpy, xev);
/* Switch on the Type */
switch (xev->type)
{
-
-#if 0
-
case ButtonPress:
case ButtonRelease:
{
- int z = 0;
+ bool press = (xev->type == ButtonPress);
+
+ /* Where is the mouse */
+ int x = xev->xbutton.x;
+ int y = xev->xbutton.y;
+
+ int z;
/* Which button is involved */
if (xev->xbutton.button == Button1) z = 1;
else if (xev->xbutton.button == Button3) z = 3;
else if (xev->xbutton.button == Button4) z = 4;
else if (xev->xbutton.button == Button5) z = 5;
-
- /* Where is the mouse */
- x = xev->xbutton.x;
- y = xev->xbutton.y;
+ else z = 0;
/* XXX Handle */
+ handle_button(xev->xbutton.time, x, y, z, press);
break;
}
case EnterNotify:
case LeaveNotify:
{
- /* Where is the mouse */
- x = xev->xcrossing.x;
- y = xev->xcrossing.y;
-
/* XXX Handle */
break;
case MotionNotify:
{
/* Where is the mouse */
- x = xev->xmotion.x;
- y = xev->xmotion.y;
+ int x = xev->xmotion.x;
+ int y = xev->xmotion.y;
+ unsigned int z = xev->xmotion.state;
+
+ /* Convert to co-ordinates Angband understands. */
+ pixel_to_square(&x, &y, x, y);
+
+ /* Highlight the current square, if appropriate. */
+ /* highlight_square(window, y, x); */
+
+ /* Alter the selection if appropriate. */
+ copy_x11_cont(x, y, z);
/* XXX Handle */
break;
}
+ case SelectionNotify:
+ {
+ paste_x11_accept(&(xev->xselection));
+ break;
+ }
+
+ case SelectionRequest:
+ {
+ paste_x11_send(&(xev->xselectionrequest));
+ break;
+ }
+
+ case SelectionClear:
+ {
+ s_ptr->select = FALSE;
+ mark_selection();
+ break;
+ }
+
case KeyRelease:
{
/* Nothing */
break;
}
-#endif
-
case KeyPress:
{
- /* Save the mouse location */
- x = xev->xkey.x;
- y = xev->xkey.y;
-
/* Hack -- use "old" term */
Term_activate(&old_td->t);
/*
* Initialize sound
*/
-static void init_sound()
+static void init_sound(void)
{
int i;
char wav[128];
char dir_xtra_sound[1024];
/* Build the "sound" path */
- path_build(dir_xtra_sound, 1024, ANGBAND_DIR_XTRA, "sound");
+ path_build(dir_xtra_sound, sizeof(dir_xtra_sound), ANGBAND_DIR_XTRA, "sound");
/* Prepare the sounds */
for (i = 1; i < SOUND_MAX; i++)
sprintf(wav, "%s.wav", angband_sound_name[i]);
/* Access the sound */
- path_build(buf, 1024, dir_xtra_sound, wav);
+ path_build(buf, sizeof(buf), dir_xtra_sound, wav);
/* Save the sound filename, if it exists */
if (check_file(buf)) sound_file[i] = string_make(buf);
if (!sound_file[v]) return (1);
sprintf(buf,"./playwave.sh %s\n", sound_file[v]);
- system(buf);
- return (0);
+ return (system(buf) < 0);
}
#endif /* USE_SOUND */
/* Activate the font */
Infofnt_set(td->fnt);
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
Infokfnt_set(td->kfnt);
#endif
}
/* Create pixel */
pixel = create_pixel(Metadpy->dpy,
- color_table[i][1],
- color_table[i][2],
- color_table[i][3]);
+ color_table[i][1],
+ color_table[i][2],
+ color_table[i][3]);
/* Change the foreground */
Infoclr_set(clr[i]);
#ifdef USE_SOUND
/* Make a special sound */
- case TERM_XTRA_SOUND: return (Term_xtra_x11_sound(v));
+ case TERM_XTRA_SOUND: return (Term_xtra_x11_sound(v));
#endif
/* Flush the output XXX XXX */
case TERM_XTRA_LEVEL: return (Term_xtra_x11_level(v));
/* Clear the screen */
- case TERM_XTRA_CLEAR: Infowin_wipe(); return (0);
+ case TERM_XTRA_CLEAR: Infowin_wipe(); s_ptr->drawn = FALSE; return (0);
/* Delay for some milliseconds */
case TERM_XTRA_DELAY: usleep(1000 * v); return (0);
*/
static errr Term_curs_x11(int x, int y)
{
- /* Draw the cursor */
- Infoclr_set(xor);
+ if (use_graphics)
+ {
+ XDrawRectangle(Metadpy->dpy, Infowin->win, xor->gc,
+ x * Infofnt->wid + Infowin->ox,
+ y * Infofnt->hgt + Infowin->oy,
+ Infofnt->wid - 1, Infofnt->hgt - 1);
+ XDrawRectangle(Metadpy->dpy, Infowin->win, xor->gc,
+ x * Infofnt->wid + Infowin->ox + 1,
+ y * Infofnt->hgt + Infowin->oy + 1,
+ Infofnt->wid - 3, Infofnt->hgt - 3);
+ }
+ else
+ {
+ /* Draw the cursor */
+ Infoclr_set(xor);
-#ifdef JP
- if (use_bigtile && x + 1 < Term->wid && (Term->old->a[y][x+1] == 255 || (iskanji(Term->old->c[y][x]) && !(Term->old->a[y][x] & 0x80))))
-#else
- if (use_bigtile && x + 1 < Term->wid && Term->old->a[y][x+1] == 255)
-#endif
- Infofnt_text_non(x, y, " ", 2);
+ /* Hilite the cursor character */
+ Infofnt_text_non(x, y, " ", 1);
+ }
+
+ /* Success */
+ return (0);
+}
+
+
+/*
+ * Draw the double width cursor
+ */
+static errr Term_bigcurs_x11(int x, int y)
+{
+ if (use_graphics)
+ {
+ XDrawRectangle(Metadpy->dpy, Infowin->win, xor->gc,
+ x * Infofnt->wid + Infowin->ox,
+ y * Infofnt->hgt + Infowin->oy,
+ Infofnt->twid - 1, Infofnt->hgt - 1);
+ XDrawRectangle(Metadpy->dpy, Infowin->win, xor->gc,
+ x * Infofnt->wid + Infowin->ox + 1,
+ y * Infofnt->hgt + Infowin->oy + 1,
+ Infofnt->twid - 3, Infofnt->hgt - 3);
+ }
else
- /* Hilite the cursor character */
- Infofnt_text_non(x, y, " ", 1);
+ {
+ /* Draw the cursor */
+ Infoclr_set(xor);
+ /* Hilite the cursor character */
+ Infofnt_text_non(x, y, " ", 2);
+ }
/* Success */
return (0);
}
/* Mega-Hack -- Erase some space */
Infofnt_text_non(x, y, "", n);
+ /* Redraw the selection if any, as it may have been obscured. (later) */
+ s_ptr->drawn = FALSE;
+
/* Success */
return (0);
}
/*
* Draw some textual characters.
*/
-static errr Term_text_x11(int x, int y, int n, byte a, cptr s)
+static errr Term_text_x11(TERM_LEN x, TERM_LEN y, int n, TERM_COLOR a, cptr s)
{
/* Draw the text */
Infoclr_set(clr[a]);
/* Draw the text */
Infofnt_text_std(x, y, s, n);
+ /* Redraw the selection if any, as it may have been obscured. (later) */
+ s_ptr->drawn = FALSE;
+
/* Success */
return (0);
}
/*
* Draw some graphical characters.
*/
-# ifdef USE_TRANSPARENCY
-static errr Term_pict_x11(int x, int y, int n, const byte *ap, const char *cp, const byte *tap, const char *tcp)
-# else /* USE_TRANSPARENCY */
-static errr Term_pict_x11(int x, int y, int n, const byte *ap, const char *cp)
-# endif /* USE_TRANSPARENCY */
+static errr Term_pict_x11(TERM_LEN x, TERM_LEN y, int n, const TERM_COLOR *ap, const char *cp, const TERM_COLOR *tap, const char *tcp)
{
int i, x1, y1;
- byte a;
+ TERM_COLOR a;
char c;
-#ifdef USE_TRANSPARENCY
- byte ta;
+ TERM_COLOR ta;
char tc;
int x2, y2;
int k,l;
unsigned long pixel, blank;
-#endif /* USE_TRANSPARENCY */
term_data *td = (term_data*)(Term->data);
x1 = (c&0x7F) * td->fnt->twid;
y1 = (a&0x7F) * td->fnt->hgt;
-#ifdef USE_TRANSPARENCY
+ /* Illegal tile index */
+ if (td->tiles->width < x1 + td->fnt->wid ||
+ td->tiles->height < y1 + td->fnt->hgt)
+ {
+ /* Draw black square */
+ XFillRectangle(Metadpy->dpy, td->win->win, clr[0]->gc,
+ x, y,
+ td->fnt->twid, td->fnt->hgt);
+
+ /* Skip drawing tile */
+ continue;
+ }
ta = *tap++;
tc = *tcp++;
y2 = (ta&0x7F) * td->fnt->hgt;
/* Optimise the common case */
- if ((x1 == x2) && (y1 == y2))
+ if (((x1 == x2) && (y1 == y2)) ||
+ !(((byte)ta & 0x80) && ((byte)tc & 0x80)) ||
+ td->tiles->width < x2 + td->fnt->wid ||
+ td->tiles->height < y2 + td->fnt->hgt)
{
/* Draw object / terrain */
XPutImage(Metadpy->dpy, td->win->win,
- clr[0]->gc,
- td->tiles,
- x1, y1,
- x, y,
- td->fnt->twid, td->fnt->hgt);
+ clr[0]->gc,
+ td->tiles,
+ x1, y1,
+ x, y,
+ td->fnt->twid, td->fnt->hgt);
}
else
{
/* Draw to screen */
XPutImage(Metadpy->dpy, td->win->win,
- clr[0]->gc,
- td->TmpImage,
- 0, 0, x, y,
- td->fnt->twid, td->fnt->hgt);
+ clr[0]->gc,
+ td->TmpImage,
+ 0, 0, x, y,
+ td->fnt->twid, td->fnt->hgt);
}
-
-#else /* USE_TRANSPARENCY */
-
- /* Draw object / terrain */
- XPutImage(Metadpy->dpy, td->win->win,
- clr[0]->gc,
- td->tiles,
- x1, y1,
- x, y,
- td->fnt->twid, td->fnt->hgt);
-
-#endif /* USE_TRANSPARENCY */
}
+ /* Redraw the selection if any, as it may have been obscured. (later) */
+ s_ptr->drawn = FALSE;
+
/* Success */
return (0);
}
XIMStyles *xim_styles = NULL;
int i;
+ /* Unused */
+ (void)unused1;
+ (void)unused2;
+
xim = XOpenIM(display, NULL, NULL, NULL);
if(!xim){
printf("can't open IM\n");
{
int i;
- if (call_data == NULL){
+ /* Unused */
+ (void)xim;
+ (void)client_data;
+
+ if (call_data == NULL){
XRegisterIMInstantiateCallback(Metadpy->dpy, NULL, NULL, NULL, IMInstantiateCallback, NULL);
}
cptr name = angband_term_name[i];
cptr font;
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
cptr kfont;
#endif
}
}
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
/* Window specific font name */
sprintf(buf, "ANGBAND_X11_KFONT_%d", i);
/* Prepare the standard font */
-#ifdef _JP
+#ifdef USE_JP_FONTSTRUCT
MAKE(td->fnt, infofnt);
Infofnt_set(td->fnt);
MAKE(td->kfnt, infofnt);
MAKE(td->win, infowin);
Infowin_set(td->win);
Infowin_init_top(x, y, wid, hgt, 0,
- Metadpy->fg, Metadpy->bg);
+ Metadpy->fg, Metadpy->bg);
/* Ask for certain events */
#if defined(USE_XIM)
- Infowin_set_mask(ExposureMask | StructureNotifyMask | KeyPressMask | FocusChangeMask);
+ Infowin_set_mask(ExposureMask | StructureNotifyMask | KeyPressMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | FocusChangeMask);
#else
- Infowin_set_mask(ExposureMask | StructureNotifyMask | KeyPressMask);
+ Infowin_set_mask(ExposureMask | StructureNotifyMask | KeyPressMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask);
#endif
/* Set the window name */
/* Hooks */
t->xtra_hook = Term_xtra_x11;
t->curs_hook = Term_curs_x11;
+ t->bigcurs_hook = Term_bigcurs_x11;
t->wipe_hook = Term_wipe_x11;
t->text_hook = Term_text_x11;
int pict_wid = 0;
int pict_hgt = 0;
-#ifdef USE_TRANSPARENCY
-
char *TmpData;
-#endif /* USE_TRANSPARENCY */
-
#endif /* USE_GRAPHICS */
}
#ifdef USE_LOCALE
+
+#ifdef JP
+ /* Get locale information from environment variables */
setlocale(LC_ALL, "");
+
#ifdef DEFAULT_LOCALE
if(!strcmp(setlocale(LC_ALL, NULL), "C")){
printf("try default locale \"%s\"\n", DEFAULT_LOCALE);
setlocale(LC_ALL, DEFAULT_LOCALE);
}
#endif
+
+ if(!strcmp(setlocale(LC_ALL, NULL), "C"))
{
- char *current_locale = setlocale(LC_ALL, NULL);
-/* printf("set locale to \"%s\"\n", current_locale); */
- if(!strcmp(current_locale, "C")){
- printf("WARNING: Locale is not supported. Non-english font may be displayed incorrectly.\n");
- }
+ printf("WARNING: Locale is not supported. Non-english font may be displayed incorrectly.\n");
}
if(!XSupportsLocale()){
printf("can't support locale in X\n");
setlocale(LC_ALL, "C");
}
+#else
+ /* Set locale to "C" without using environment variables */
+ setlocale(LC_ALL, "C");
+#endif /* JP */
+
#endif /* USE_LOCALE */
{
/* Create pixel */
pixel = create_pixel(Metadpy->dpy,
- color_table[i][1],
- color_table[i][2],
- color_table[i][3]);
+ color_table[i][1],
+ color_table[i][2],
+ color_table[i][3]);
}
/* Initialize the color */
}
+ /* Prepare required atoms. */
+ set_atoms();
+
+
/* Initialize the windows */
for (i = 0; i < num_term; i++)
{
{
case GRAPHICS_ORIGINAL:
/* Try the "8x8.bmp" file */
- path_build(filename, 1024, ANGBAND_DIR_XTRA, "graf/8x8.bmp");
+ path_build(filename, sizeof(filename), ANGBAND_DIR_XTRA, "graf/8x8.bmp");
/* Use the "8x8.bmp" file if it exists */
if (0 == fd_close(fd_open(filename, O_RDONLY)))
case GRAPHICS_ADAM_BOLT:
/* Try the "16x16.bmp" file */
- path_build(filename, 1024, ANGBAND_DIR_XTRA, "graf/16x16.bmp");
+ path_build(filename, sizeof(filename), ANGBAND_DIR_XTRA, "graf/16x16.bmp");
/* Use the "16x16.bmp" file if it exists */
if (0 == fd_close(fd_open(filename, O_RDONLY)))
/* Resize tiles */
td->tiles =
ResizeImage(dpy, tiles_raw,
- pict_wid, pict_hgt,
- td->fnt->twid, td->fnt->hgt);
+ pict_wid, pict_hgt,
+ td->fnt->twid, td->fnt->hgt);
}
-#ifdef USE_TRANSPARENCY
/* Initialize the transparency masks */
for (i = 0; i < num_term; i++)
{
td->fnt->twid, td->fnt->hgt, 8, 0);
}
-#endif /* USE_TRANSPARENCY */
-
/* Free tiles_raw? XXX XXX */
}