X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fmain-x11.c;h=ea659a44c1db4931782b714a36c9df5050ef00e9;hb=57f8ef6e42a487dc2af160c8f28a9caf956b223c;hp=c750dd5c43c738033e6dbbe91c264770fd7437c9;hpb=cff183cfbcb7567f542f67bf66e7ed801e5c5b86;p=hengband%2Fhengband.git diff --git a/src/main-x11.c b/src/main-x11.c index c750dd5c4..ea659a44c 100644 --- a/src/main-x11.c +++ b/src/main-x11.c @@ -1,4 +1,4 @@ -/* File: main-x11.c */ +/* File: main-x11.c */ /* * Copyright (c) 1997 Ben Harrison, and others @@ -9,17 +9,17 @@ */ -#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 /* @@ -123,9 +123,10 @@ #if 0 char *XSetIMValues(XIM, ...); /* Hack for XFree86 4.0 */ #endif +#include #endif /* __MAKEDEPEND__ */ - +#include /* * Include some helpful X11 code. */ @@ -348,6 +349,7 @@ struct infofnt cptr name; s16b wid; + s16b twid; s16b hgt; s16b asc; @@ -385,7 +387,7 @@ struct infofnt /* 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 */ @@ -454,7 +456,7 @@ static infowin *Infowin = (infowin*)(NULL); 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 @@ -467,9 +469,9 @@ static infofnt *Infofnt = (infofnt*)(NULL); /**** 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. @@ -744,7 +746,7 @@ static errr Infowin_init_real(Window xid) * 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; @@ -934,7 +936,7 @@ static errr Infowin_fill(void) { /* 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); @@ -1160,7 +1162,7 @@ static errr Infoclr_init_data(Pixell fg, Pixell bg, int op, int stip) /* 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); @@ -1226,7 +1228,7 @@ static errr Infofnt_nuke(void) { infofnt *ifnt = Infofnt; -#ifdef _JP +#ifdef USE_JP_FONTSTRUCT infofnt *ikfnt = Infokfnt; #endif /* Deal with 'name' */ @@ -1236,21 +1238,26 @@ static errr Infofnt_nuke(void) 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 */ @@ -1267,7 +1274,7 @@ static errr Infofnt_nuke(void) /* * Prepare a new 'infofnt' */ -#ifdef _JP +#ifdef USE_JP_FONTSTRUCT static errr Infofnt_prepare(XFontStruct *info, XFontStruct *kinfo) #else #ifdef USE_FONTSET @@ -1280,7 +1287,7 @@ static errr Infofnt_prepare(XFontStruct *info) { infofnt *ifnt = Infofnt; -#ifdef _JP +#ifdef USE_JP_FONTSTRUCT infofnt *ikfnt = Infokfnt; #endif XCharStruct *cs; @@ -1303,7 +1310,7 @@ static errr Infofnt_prepare(XFontStruct *info) 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; @@ -1324,7 +1331,12 @@ static errr Infofnt_prepare(XFontStruct *info) ifnt->wid = cs->width; #endif -#ifdef _JP + if (use_bigtile) + ifnt->twid = 2 * ifnt->wid; + else + ifnt->twid = ifnt->wid; + +#ifdef USE_JP_FONTSTRUCT /* Assign the struct */ ikfnt->info = kinfo; @@ -1355,7 +1367,7 @@ static errr Infofnt_prepare(XFontStruct *info) /* * Initialize a new 'infofnt'. */ -#ifdef _JP +#ifdef USE_JP_FONTSTRUCT static errr Infofnt_init_real(XFontStruct *info, XFontStruct *kinfo) #else #ifdef USE_FONTSET @@ -1369,17 +1381,17 @@ static errr Infofnt_init_real(XFontStruct *info) /* 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)); @@ -1396,10 +1408,10 @@ static errr Infofnt_init_real(XFontStruct *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 { @@ -1413,16 +1425,16 @@ static errr Infofnt_init_data(cptr name) #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 @@ -1436,16 +1448,16 @@ static errr Infofnt_init_data(cptr name) } #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 @@ -1455,11 +1467,11 @@ static errr Infofnt_init_data(cptr name) /* 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)) @@ -1471,34 +1483,31 @@ static errr Infofnt_init_data(cptr name) 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, @@ -1526,65 +1535,65 @@ 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; } } } @@ -1606,7 +1615,6 @@ static errr Infofnt_text_std(int x, int y, cptr str, int len) /* Get the length of the string */ if (len < 0) len = strlen(str); - /*** Decide where to place the string, vertically ***/ /* Ignore Vertical Justifications */ @@ -1621,19 +1629,17 @@ static errr Infofnt_text_std(int x, int y, cptr str, int len) /*** 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 @@ -1642,7 +1648,7 @@ static errr Infofnt_text_std(int x, int y, cptr str, int len) { /* 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); } } @@ -1650,20 +1656,33 @@ static errr Infofnt_text_std(int x, int y, cptr str, int len) 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 + + 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 @@ -1754,7 +1773,7 @@ struct term_data term t; infofnt *fnt; -#ifdef _JP +#ifdef USE_JP_FONTSTRUCT infofnt *kfnt; #endif @@ -1765,15 +1784,11 @@ struct term_data XImage *tiles; -#ifdef USE_TRANSPARENCY - /* Tempory storage for overlaying tiles. */ XImage *TmpImage; #endif -#endif - }; @@ -1788,6 +1803,38 @@ struct term_data 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 @@ -1890,6 +1937,10 @@ static void react_keypress(XKeyEvent *xev) } case XK_Delete: + { + Term_keypress(0x7f); + return; + } case XK_BackSpace: { Term_keypress('\010'); @@ -1902,18 +1953,18 @@ static void react_keypress(XKeyEvent *xev) 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 */ @@ -1929,6 +1980,528 @@ static void react_keypress(XKeyEvent *xev) } +/* + * 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; + int x,y,l,n; + byte 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); +} /* @@ -1943,7 +2516,7 @@ static errr CheckEvent(bool wait) term_data *td = NULL; infowin *iwin = NULL; - int i, x, y; + int i; #ifdef USE_XIM redo_checkevent: @@ -1952,6 +2525,13 @@ static errr CheckEvent(bool wait) /* 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); @@ -2035,13 +2615,16 @@ static errr CheckEvent(bool wait) /* 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; @@ -2049,12 +2632,10 @@ static errr CheckEvent(bool wait) 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; } @@ -2062,10 +2643,6 @@ static errr CheckEvent(bool wait) case EnterNotify: case LeaveNotify: { - /* Where is the mouse */ - x = xev->xcrossing.x; - y = xev->xcrossing.y; - /* XXX Handle */ break; @@ -2074,28 +2651,51 @@ static errr CheckEvent(bool wait) 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); @@ -2163,14 +2763,17 @@ static errr CheckEvent(bool wait) cols = ((Infowin->w - (ox + ox)) / td->fnt->wid); rows = ((Infowin->h - (oy + oy)) / td->fnt->hgt); - /* Paranoia */ - if (td == &data[0]) cols = 80; - if (td == &data[0]) rows = 24; - /* Hack -- minimal size */ if (cols < 1) cols = 1; if (rows < 1) rows = 1; + if (td == &data[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 * td->fnt->wid + (ox + ox); hgt = rows * td->fnt->hgt + (oy + oy); @@ -2221,6 +2824,80 @@ static errr CheckEvent(bool wait) } +#ifdef USE_SOUND + +/* + * An array of sound file names + */ +static cptr sound_file[SOUND_MAX]; + +/* + * Check for existance of a file + */ +static bool check_file(cptr s) +{ + FILE *fff; + + fff = fopen(s, "r"); + if (!fff) return (FALSE); + + fclose(fff); + return (TRUE); +} + +/* + * Initialize sound + */ +static void init_sound(void) +{ + int i; + char wav[128]; + char buf[1024]; + char dir_xtra_sound[1024]; + + /* Build the "sound" path */ + path_build(dir_xtra_sound, sizeof(dir_xtra_sound), ANGBAND_DIR_XTRA, "sound"); + + /* Prepare the sounds */ + for (i = 1; i < SOUND_MAX; i++) + { + /* Extract name of sound file */ + sprintf(wav, "%s.wav", angband_sound_name[i]); + + /* Access the sound */ + 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); + } + use_sound = TRUE; + return; +} + +/* + * Hack -- make a sound + */ +static errr Term_xtra_x11_sound(int v) +{ + char buf[1024]; + + /* Sound disabled */ + if (!use_sound) return (1); + + /* Illegal sound */ + if ((v < 0) || (v >= SOUND_MAX)) return (1); + + /* Unknown sound */ + if (!sound_file[v]) return (1); + + sprintf(buf,"./playwave.sh %s\n", sound_file[v]); + + return (system(buf) < 0); + +} +#endif /* USE_SOUND */ + + /* * Handle "activation" of a term */ @@ -2236,7 +2913,7 @@ static errr Term_xtra_x11_level(int v) /* Activate the font */ Infofnt_set(td->fnt); -#ifdef _JP +#ifdef USE_JP_FONTSTRUCT Infokfnt_set(td->kfnt); #endif } @@ -2273,9 +2950,9 @@ static errr Term_xtra_x11_react(void) /* 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]); @@ -2300,6 +2977,11 @@ static errr Term_xtra_x11(int n, int v) /* Make a noise */ case TERM_XTRA_NOISE: Metadpy_do_beep(); return (0); +#ifdef USE_SOUND + /* Make a special sound */ + case TERM_XTRA_SOUND: return (Term_xtra_x11_sound(v)); +#endif + /* Flush the output XXX XXX */ case TERM_XTRA_FRESH: Metadpy_update(1, 0, 0); return (0); @@ -2316,7 +2998,7 @@ static errr Term_xtra_x11(int n, int v) 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); @@ -2337,12 +3019,55 @@ static errr Term_xtra_x11(int n, int v) */ 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); - /* Hilite the cursor character */ - Infofnt_text_non(x, y, " ", 1); + /* 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 + { + /* Draw the cursor */ + Infoclr_set(xor); + /* Hilite the cursor character */ + Infofnt_text_non(x, y, " ", 2); + } /* Success */ return (0); } @@ -2359,6 +3084,9 @@ static errr Term_wipe_x11(int x, int y, int n) /* 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); } @@ -2375,6 +3103,9 @@ static errr Term_text_x11(int x, int y, int n, byte a, cptr s) /* 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); } @@ -2385,19 +3116,13 @@ static errr Term_text_x11(int x, int y, int n, byte a, cptr s) /* * 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 */ { int i, x1, y1; byte a; char c; - -#ifdef USE_TRANSPARENCY byte ta; char tc; @@ -2405,7 +3130,6 @@ static errr Term_pict_x11(int x, int y, int n, const byte *ap, const char *cp) int k,l; unsigned long pixel, blank; -#endif /* USE_TRANSPARENCY */ term_data *td = (term_data*)(Term->data); @@ -2416,34 +3140,48 @@ static errr Term_pict_x11(int x, int y, int n, const byte *ap, const char *cp) y += Infowin->oy; x += Infowin->ox; - for (i = 0; i < n; ++i) + for (i = 0; i < n; ++i, x += td->fnt->wid) { a = *ap++; c = *cp++; /* For extra speed - cache these values */ - x1 = (c&0x7F) * td->fnt->wid; + 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++; /* For extra speed - cache these values */ - x2 = (tc&0x7F) * td->fnt->wid; + x2 = (tc&0x7F) * td->fnt->twid; 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->wid, td->fnt->hgt); + clr[0]->gc, + td->tiles, + x1, y1, + x, y, + td->fnt->twid, td->fnt->hgt); } else { @@ -2451,7 +3189,7 @@ static errr Term_pict_x11(int x, int y, int n, const byte *ap, const char *cp) /* Mega Hack^2 - assume the top left corner is "black" */ blank = XGetPixel(td->tiles, 0, td->fnt->hgt * 6); - for (k = 0; k < td->fnt->wid; k++) + for (k = 0; k < td->fnt->twid; k++) { for (l = 0; l < td->fnt->hgt; l++) { @@ -2471,26 +3209,16 @@ static errr Term_pict_x11(int x, int y, int n, const byte *ap, const char *cp) /* Draw to screen */ XPutImage(Metadpy->dpy, td->win->win, - clr[0]->gc, - td->TmpImage, - 0, 0, x, y, - td->fnt->wid, 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->wid, td->fnt->hgt); - -#endif /* USE_TRANSPARENCY */ - x += td->fnt->wid; } + /* Redraw the selection if any, as it may have been obscured. (later) */ + s_ptr->drawn = FALSE; + /* Success */ return (0); } @@ -2508,6 +3236,10 @@ IMInstantiateCallback(Display *display, XPointer unused1, XPointer unused2) 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"); @@ -2556,7 +3288,11 @@ static void IMDestroyCallback(XIM xim, XPointer client_data, XPointer call_data) { int i; - if (call_data == NULL){ + /* Unused */ + (void)xim; + (void)client_data; + + if (call_data == NULL){ XRegisterIMInstantiateCallback(Metadpy->dpy, NULL, NULL, NULL, IMInstantiateCallback, NULL); } @@ -2582,12 +3318,10 @@ static errr term_data_init(term_data *td, int i) { term *t = &td->t; - bool fixed = (i == 0); - cptr name = angband_term_name[i]; cptr font; -#ifdef _JP +#ifdef USE_JP_FONTSTRUCT cptr kfont; #endif @@ -2680,7 +3414,7 @@ static errr term_data_init(term_data *td, int i) } } -#ifdef _JP +#ifdef USE_JP_FONTSTRUCT /* Window specific font name */ sprintf(buf, "ANGBAND_X11_KFONT_%d", i); @@ -2753,21 +3487,24 @@ static errr term_data_init(term_data *td, int i) y = (str != NULL) ? atoi(str) : -1; - if (!fixed) - { - /* 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 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; - } + /* 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) + { + if (cols < 80) cols = 80; + if (rows < 24) rows = 24; + } /* Window specific inner border offset (ox) */ sprintf(buf, "ANGBAND_X11_IBOX_%d", i); @@ -2783,7 +3520,7 @@ static errr term_data_init(term_data *td, int i) /* Prepare the standard font */ -#ifdef _JP +#ifdef USE_JP_FONTSTRUCT MAKE(td->fnt, infofnt); Infofnt_set(td->fnt); MAKE(td->kfnt, infofnt); @@ -2797,7 +3534,7 @@ static errr term_data_init(term_data *td, int i) /* Hack -- key buffer size */ - num = (fixed ? 1024 : 16); + num = ((i == 0) ? 1024 : 16); /* Assume full size windows */ wid = cols * td->fnt->wid + (ox + ox); @@ -2807,23 +3544,13 @@ static errr term_data_init(term_data *td, int i) 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) -#if 0 - /* XIM ¤¬Í­¸ú¤Ê¤Î¤Ï¥á¥¤¥ó¥¦¥£¥ó¥É¥¦¤Î¤ß¤Ê¤Î¤Ç¡¢¼óÈø¤ò°ì´Ó¤µ¤»¤ë¤¿¤á - Ä̾ï¤Î¥­¡¼ÆþÎϤâ̵¸ú¤Ë¤¹¤ë */ - if(i == 0){ - Infowin_set_mask(ExposureMask | StructureNotifyMask | KeyPressMask); - }else{ - Infowin_set_mask(ExposureMask | StructureNotifyMask); - } -#else - Infowin_set_mask(ExposureMask | StructureNotifyMask | KeyPressMask | FocusChangeMask); -#endif + 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 */ @@ -2853,19 +3580,21 @@ static errr term_data_init(term_data *td, int i) /* Oops */ if (sh == NULL) quit("XAllocSizeHints failed"); - /* Fixed window size */ - if (fixed) + /* Main window has a differing minimum size */ + if (i == 0) { - /* Fixed size */ + /* Main window min size is 80x24 */ sh->flags = PMinSize | PMaxSize; - sh->min_width = sh->max_width = wid; - sh->min_height = sh->max_height = hgt; + sh->min_width = 80 * td->fnt->wid + (ox + ox); + sh->min_height = 24 * td->fnt->hgt + (oy + oy); + sh->max_width = 255 * td->fnt->wid + (ox + ox); + sh->max_height = 255 * td->fnt->hgt + (oy + oy); } - /* Variable window size */ + /* Other windows can be shrunk to 1x1 */ else { - /* Variable size */ + /* Other windows */ sh->flags = PMinSize | PMaxSize; sh->min_width = td->fnt->wid + (ox + ox); sh->min_height = td->fnt->hgt + (oy + oy); @@ -2915,6 +3644,7 @@ static errr term_data_init(term_data *td, int i) /* 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; @@ -2938,7 +3668,7 @@ errr init_x11(int argc, char *argv[]) cptr dpy_name = ""; - int num_term = MAX_TERM_DATA; + int num_term = 3; #ifdef USE_GRAPHICS @@ -2947,11 +3677,7 @@ errr init_x11(int argc, char *argv[]) int pict_wid = 0; int pict_hgt = 0; -#ifdef USE_TRANSPARENCY - char *TmpData; -#endif /* USE_TRANSPARENCY */ - #endif /* USE_GRAPHICS */ @@ -2970,6 +3696,24 @@ errr init_x11(int argc, char *argv[]) smoothRescaling = FALSE; continue; } + + if (prefix(argv[i], "-a")) + { + arg_graphics = GRAPHICS_ADAM_BOLT; + continue; + } + + if (prefix(argv[i], "-o")) + { + arg_graphics = GRAPHICS_ORIGINAL; + continue; + } + + if (prefix(argv[i], "-b")) + { + arg_bigtile = use_bigtile = TRUE; + continue; + } #endif /* USE_GRAPHICS */ if (prefix(argv[i], "-n")) @@ -2980,29 +3724,42 @@ errr init_x11(int argc, char *argv[]) continue; } + if (prefix(argv[i], "--")) + { + /* Ignore */ + continue; + } + plog_fmt("Ignoring option: %s", argv[i]); } #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 */ @@ -3039,9 +3796,9 @@ errr init_x11(int argc, char *argv[]) { /* 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 */ @@ -3049,6 +3806,10 @@ errr init_x11(int argc, char *argv[]) } + /* Prepare required atoms. */ + set_atoms(); + + /* Initialize the windows */ for (i = 0; i < num_term; i++) { @@ -3080,39 +3841,48 @@ errr init_x11(int argc, char *argv[]) XRegisterIMInstantiateCallback(Metadpy->dpy, NULL, NULL, NULL, IMInstantiateCallback, NULL); #endif +#ifdef USE_SOUND + /* initialize sound */ + if (arg_sound) init_sound(); +#endif + #ifdef USE_GRAPHICS /* Try graphics */ - if (arg_graphics) + switch (arg_graphics) { - /* Try the "16x16.bmp" file */ - path_build(filename, 1024, ANGBAND_DIR_XTRA, "graf/16x16.bmp"); + case GRAPHICS_ORIGINAL: + /* Try the "8x8.bmp" file */ + path_build(filename, sizeof(filename), ANGBAND_DIR_XTRA, "graf/8x8.bmp"); - /* Use the "16x16.bmp" file if it exists */ + /* 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 = 16; + pict_wid = pict_hgt = 8; - ANGBAND_GRAF = "new"; + ANGBAND_GRAF = "old"; + break; } - else + /* Fall through */ + + case GRAPHICS_ADAM_BOLT: + /* Try the "16x16.bmp" file */ + 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))) { - /* Try the "8x8.bmp" file */ - path_build(filename, 1024, ANGBAND_DIR_XTRA, "graf/8x8.bmp"); + /* Use graphics */ + use_graphics = TRUE; - /* 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 = 16; - pict_wid = pict_hgt = 8; + ANGBAND_GRAF = "new"; - ANGBAND_GRAF = "old"; - } + break; } } @@ -3142,11 +3912,10 @@ errr init_x11(int argc, char *argv[]) /* Resize tiles */ td->tiles = ResizeImage(dpy, tiles_raw, - pict_wid, pict_hgt, - td->fnt->wid, 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++) { @@ -3161,18 +3930,16 @@ errr init_x11(int argc, char *argv[]) ii = 1; jj = (depth - 1) >> 2; while (jj >>= 1) ii <<= 1; - total = td->fnt->wid * td->fnt->hgt * ii; + total = td->fnt->twid * td->fnt->hgt * ii; TmpData = (char *)malloc(total); td->TmpImage = XCreateImage(dpy,visual,depth, ZPixmap, 0, TmpData, - td->fnt->wid, td->fnt->hgt, 8, 0); + td->fnt->twid, td->fnt->hgt, 8, 0); } -#endif /* USE_TRANSPARENCY */ - /* Free tiles_raw? XXX XXX */ }