OSDN Git Service

鍛冶師もう一度書き直し。どうも配列のindex == フラグ番号というのがプロ
[hengband/hengband.git] / src / main-x11.c
1 /* File: main-x11.c */
2
3 /*
4  * Copyright (c) 1997 Ben Harrison, and others
5  *
6  * This software may be copied and distributed for educational, research,
7  * and not for profit purposes provided that this copyright and statement
8  * are included in all such copies.
9  */
10
11
12 #ifdef _JP
13 /*
14  * ÆüËܸì(EUC-JAPAN)Âбþ (-DJP)
15  *    ¡¦´Á»ú¥Õ¥©¥ó¥È¤Î°·¤¤¤òÄɲÃ
16  *    ¡¦ÆüËܸì¤ò´Þ¤àʸ»úÎó¤Îɽ¼¨¥ë¡¼¥Á¥ó XDrawMultiString() ¤ÎÄɲÃ
17  *    ¡¦ÆüËܸì¤Îɽ¼¨Éý¤Ï¡¤¥Õ¥©¥ó¥È¤Î¾ðÊó¤Ë¤è¤é¤¹ASCII¥Õ¥©¥ó¥È¤Î2Çܤ˸ÇÄê
18  *
19  * Ì¤Âбþ
20  *      EUCȾ³Ñ¤Î°·¤¤
21  *
22  * 1996/6/7  Íû ¹¸¿­ (ri@kuis.kyoto-u.ac.jp)
23  */
24 #endif
25 /*
26  * This file helps Angband work with UNIX/X11 computers.
27  *
28  * To use this file, compile with "USE_X11" defined, and link against all
29  * the various "X11" libraries which may be needed.
30  *
31  * See also "main-xaw.c".
32  *
33  * Part of this file provides a user interface package composed of several
34  * pseudo-objects, including "metadpy" (a display), "infowin" (a window),
35  * "infoclr" (a color), and "infofnt" (a font).  Actually, the package was
36  * originally much more interesting, but it was bastardized to keep this
37  * file simple.
38  *
39  * The rest of this file is an implementation of "main-xxx.c" for X11.
40  *
41  * Most of this file is by Ben Harrison (benh@phial.com).
42  */
43
44 /*
45  * The following shell script can be used to launch Angband, assuming that
46  * it was extracted into "~/Angband", and compiled using "USE_X11", on a
47  * Linux machine, with a 1280x1024 screen, using 6 windows (with the given
48  * characteristics), with gamma correction of 1.8 -> (1 / 1.8) * 256 = 142,
49  * and without graphics (add "-g" for graphics).  Just copy this comment
50  * into a file, remove the leading " * " characters (and the head/tail of
51  * this comment), and make the file executable.
52  * 
53  *
54  * #!/bin/csh
55  * 
56  * # Describe attempt
57  * echo "Launching angband..."
58  * sleep 2
59  * 
60  * # Main window
61  * setenv ANGBAND_X11_FONT_0 10x20
62  * setenv ANGBAND_X11_AT_X_0 5
63  * setenv ANGBAND_X11_AT_Y_0 510
64  * 
65  * # Message window
66  * setenv ANGBAND_X11_FONT_1 8x13
67  * setenv ANGBAND_X11_AT_X_1 5
68  * setenv ANGBAND_X11_AT_Y_1 22
69  * setenv ANGBAND_X11_ROWS_1 35
70  * 
71  * # Inventory window
72  * setenv ANGBAND_X11_FONT_2 8x13
73  * setenv ANGBAND_X11_AT_X_2 635
74  * setenv ANGBAND_X11_AT_Y_2 182
75  * setenv ANGBAND_X11_ROWS_3 23
76  * 
77  * # Equipment window
78  * setenv ANGBAND_X11_FONT_3 8x13
79  * setenv ANGBAND_X11_AT_X_3 635
80  * setenv ANGBAND_X11_AT_Y_3 22
81  * setenv ANGBAND_X11_ROWS_3 12
82  * 
83  * # Monster recall window
84  * setenv ANGBAND_X11_FONT_4 6x13
85  * setenv ANGBAND_X11_AT_X_4 817
86  * setenv ANGBAND_X11_AT_Y_4 847
87  * setenv ANGBAND_X11_COLS_4 76
88  * setenv ANGBAND_X11_ROWS_4 11
89  * 
90  * # Object recall window
91  * setenv ANGBAND_X11_FONT_5 6x13
92  * setenv ANGBAND_X11_AT_X_5 817
93  * setenv ANGBAND_X11_AT_Y_5 520
94  * setenv ANGBAND_X11_COLS_5 76
95  * setenv ANGBAND_X11_ROWS_5 24
96  * 
97  * # The build directory
98  * cd ~/Angband
99  *
100  * # Gamma correction
101  * setenv ANGBAND_X11_GAMMA 142
102  * 
103  * # Launch Angband
104  * ./src/angband -mx11 -- -n6 &
105  *
106  */
107
108
109 #include "angband.h"
110
111
112 #ifdef USE_X11
113
114
115 #ifndef __MAKEDEPEND__
116 #include <X11/Xlib.h>
117 #include <X11/Xutil.h>
118 #include <X11/keysym.h>
119 #include <X11/keysymdef.h>
120 #ifdef USE_LOCALE
121 #include <X11/Xlocale.h>
122 #endif
123 #if 0
124 char *XSetIMValues(XIM, ...); /* Hack for XFree86 4.0 */
125 #endif
126 #endif /* __MAKEDEPEND__ */
127
128
129 /*
130  * Include some helpful X11 code.
131  */
132 #include "maid-x11.c"
133
134
135 /*
136  * Hack -- avoid some compiler warnings
137  */
138 #define IGNORE_UNUSED_FUNCTIONS
139
140
141 /*
142  * Notes on Colors:
143  *
144  *   1) On a monochrome (or "fake-monochrome") display, all colors
145  *   will be "cast" to "fg," except for the bg color, which is,
146  *   obviously, cast to "bg".  Thus, one can ignore this setting.
147  *
148  *   2) Because of the inner functioning of the color allocation
149  *   routines, colors may be specified as (a) a typical color name,
150  *   (b) a hexidecimal color specification (preceded by a pound sign),
151  *   or (c) by strings such as "fg", "bg", "zg".
152  *
153  *   3) Due to the workings of the init routines, many colors
154  *   may also be dealt with by their actual pixel values.  Note that
155  *   the pixel with all bits set is "zg = (1<<metadpy->depth)-1", which
156  *   is not necessarily either black or white.
157  */
158
159
160
161 /**** Generic Types ****/
162
163
164 /*
165  * An X11 pixell specifier
166  */
167 typedef unsigned long Pixell;
168
169 /*
170  * The structures defined below
171  */
172 typedef struct metadpy metadpy;
173 typedef struct infowin infowin;
174 typedef struct infoclr infoclr;
175 typedef struct infofnt infofnt;
176
177
178 /*
179  * A structure summarizing a given Display.
180  *
181  *      - The Display itself
182  *      - The default Screen for the display
183  *      - The virtual root (usually just the root)
184  *      - The default colormap (from a macro)
185  *
186  *      - The "name" of the display
187  *
188  *      - The socket to listen to for events
189  *
190  *      - The width of the display screen (from a macro)
191  *      - The height of the display screen (from a macro)
192  *      - The bit depth of the display screen (from a macro)
193  *
194  *      - The black Pixell (from a macro)
195  *      - The white Pixell (from a macro)
196  *
197  *      - The background Pixell (default: black)
198  *      - The foreground Pixell (default: white)
199  *      - The maximal Pixell (Equals: ((2 ^ depth)-1), is usually ugly)
200  *
201  *      - Bit Flag: Force all colors to black and white (default: !color)
202  *      - Bit Flag: Allow the use of color (default: depth > 1)
203  *      - Bit Flag: We created 'dpy', and so should nuke it when done.
204  */
205 struct metadpy
206 {
207         Display *dpy;
208         Screen *screen;
209         Window root;
210         Colormap cmap;
211 #ifdef USE_XIM
212         XIM xim;
213 #endif
214
215         char *name;
216
217         int fd;
218
219         uint width;
220         uint height;
221         uint depth;
222
223         Pixell black;
224         Pixell white;
225
226         Pixell bg;
227         Pixell fg;
228         Pixell zg;
229
230         uint mono:1;
231         uint color:1;
232         uint nuke:1;
233 };
234
235
236
237 /*
238  * A Structure summarizing Window Information.
239  *
240  * I assume that a window is at most 30000 pixels on a side.
241  * I assume that the root windw is also at most 30000 square.
242  *
243  *      - The Window
244  *      - The current Input Event Mask
245  *
246  *      - The location of the window
247  *      - The width, height of the window
248  *      - The border width of this window
249  *
250  *      - Byte: 1st Extra byte
251  *
252  *      - Bit Flag: This window is currently Mapped
253  *      - Bit Flag: This window needs to be redrawn
254  *      - Bit Flag: This window has been resized
255  *
256  *      - Bit Flag: We should nuke 'win' when done with it
257  *
258  *      - Bit Flag: 1st extra flag
259  *      - Bit Flag: 2nd extra flag
260  *      - Bit Flag: 3rd extra flag
261  *      - Bit Flag: 4th extra flag
262  */
263 struct infowin
264 {
265         Window win;
266 #ifdef USE_XIM
267         XIC xic;
268         long xic_mask;
269 #endif
270
271         long mask;
272
273         s16b ox, oy;
274
275         s16b x, y;
276         s16b w, h;
277         u16b b;
278
279         byte byte1;
280
281         uint mapped:1;
282         uint redraw:1;
283         uint resize:1;
284
285         uint nuke:1;
286
287         uint flag1:1;
288         uint flag2:1;
289         uint flag3:1;
290         uint flag4:1;
291 };
292
293
294
295
296
297
298 /*
299  * A Structure summarizing Operation+Color Information
300  *
301  *      - The actual GC corresponding to this info
302  *
303  *      - The Foreground Pixell Value
304  *      - The Background Pixell Value
305  *
306  *      - Num (0-15): The operation code (As in Clear, Xor, etc)
307  *      - Bit Flag: The GC is in stipple mode
308  *      - Bit Flag: Destroy 'gc' at Nuke time.
309  */
310 struct infoclr
311 {
312         GC gc;
313
314         Pixell fg;
315         Pixell bg;
316
317         uint code:4;
318         uint stip:1;
319         uint nuke:1;
320 };
321
322
323
324 /*
325  * A Structure to Hold Font Information
326  *
327  *      - The 'XFontStruct*' (yields the 'Font')
328  *
329  *      - The font name
330  *
331  *      - The default character width
332  *      - The default character height
333  *      - The default character ascent
334  *
335  *      - Byte: Pixel offset used during fake mono
336  *
337  *      - Flag: Force monospacing via 'wid'
338  *      - Flag: Nuke info when done
339  */
340 struct infofnt
341 {
342 #ifdef USE_FONTSET
343         XFontSet info;
344 #else
345         XFontStruct *info;
346 #endif
347
348         cptr name;
349
350         s16b wid;
351         s16b twid;
352         s16b hgt;
353         s16b asc;
354
355         byte off;
356
357         uint mono:1;
358         uint nuke:1;
359 };
360
361
362
363
364 /**** Generic Macros ****/
365
366
367
368 /* Set current metadpy (Metadpy) to 'M' */
369 #define Metadpy_set(M) \
370         Metadpy = M
371
372
373 /* Initialize 'M' using Display 'D' */
374 #define Metadpy_init_dpy(D) \
375         Metadpy_init_2(D,cNULL)
376
377 /* Initialize 'M' using a Display named 'N' */
378 #define Metadpy_init_name(N) \
379         Metadpy_init_2((Display*)(NULL),N)
380
381 /* Initialize 'M' using the standard Display */
382 #define Metadpy_init() \
383         Metadpy_init_name("")
384
385
386 /* Init an infowin by giving father as an (info_win*) (or NULL), and data */
387 #define Infowin_init_dad(D,X,Y,W,H,B,FG,BG) \
388         Infowin_init_data(((D) ? ((D)->win) : (Window)(None)), \
389                           X,Y,W,H,B,FG,BG)
390
391
392 /* Init a top level infowin by pos,size,bord,Colors */
393 #define Infowin_init_top(X,Y,W,H,B,FG,BG) \
394         Infowin_init_data(None,X,Y,W,H,B,FG,BG)
395
396
397 /* Request a new standard window by giving Dad infowin and X,Y,W,H */
398 #define Infowin_init_std(D,X,Y,W,H,B) \
399         Infowin_init_dad(D,X,Y,W,H,B,Metadpy->fg,Metadpy->bg)
400
401
402 /* Set the current Infowin */
403 #define Infowin_set(I) \
404         (Infowin = (I))
405
406
407 /* Set the current Infoclr */
408 #define Infoclr_set(C) \
409         (Infoclr = (C))
410
411
412 #define Infoclr_init_ppo(F,B,O,M) \
413         Infoclr_init_data(F,B,O,M)
414
415 #define Infoclr_init_cco(F,B,O,M) \
416         Infoclr_init_ppo(Infoclr_Pixell(F),Infoclr_Pixell(B),O,M)
417
418 #define Infoclr_init_ppn(F,B,O,M) \
419         Infoclr_init_ppo(F,B,Infoclr_Opcode(O),M)
420
421 #define Infoclr_init_ccn(F,B,O,M) \
422         Infoclr_init_cco(F,B,Infoclr_Opcode(O),M)
423
424
425 /* Set the current infofnt */
426 #define Infofnt_set(I) \
427         (Infofnt = (I))
428
429
430 /* Errr: Expose Infowin */
431 #define Infowin_expose() \
432         (!(Infowin->redraw = 1))
433
434 /* Errr: Unxpose Infowin */
435 #define Infowin_unexpose() \
436         (Infowin->redraw = 0)
437
438
439
440 /**** Generic Globals ****/
441
442
443 /*
444  * The "default" values
445  */
446 static metadpy metadpy_default;
447
448
449 /*
450  * The "current" variables
451  */
452 static metadpy *Metadpy = &metadpy_default;
453 static infowin *Infowin = (infowin*)(NULL);
454 #ifdef USE_XIM
455 static infowin *Focuswin = (infowin*)(NULL);
456 #endif
457 static infoclr *Infoclr = (infoclr*)(NULL);
458 #ifdef _JP
459 static infofnt *Infofnt = (infofnt*)(NULL);
460 static infofnt *Infokfnt = (infofnt*)(NULL);
461 #else
462 static infofnt *Infofnt = (infofnt*)(NULL);
463 #endif
464
465
466
467
468 /**** Generic code ****/
469
470
471 #ifdef _JP
472 #define Infokfnt_set(I) \
473         (Infokfnt = (I))
474 #endif
475 /*
476  * Init the current metadpy, with various initialization stuff.
477  *
478  * Inputs:
479  *      dpy:  The Display* to use (if NULL, create it)
480  *      name: The name of the Display (if NULL, the current)
481  *
482  * Notes:
483  *      If 'name' is NULL, but 'dpy' is set, extract name from dpy
484  *      If 'dpy' is NULL, then Create the named Display
485  *      If 'name' is NULL, and so is 'dpy', use current Display
486  *
487  * Return -1 if no Display given, and none can be opened.
488  */
489 static errr Metadpy_init_2(Display *dpy, cptr name)
490 {
491         metadpy *m = Metadpy;
492
493         /*** Open the display if needed ***/
494
495         /* If no Display given, attempt to Create one */
496         if (!dpy)
497         {
498                 /* Attempt to open the display */
499                 dpy = XOpenDisplay(name);
500
501                 /* Failure */
502                 if (!dpy) return (-1);
503
504                 /* We will have to nuke it when done */
505                 m->nuke = 1;
506         }
507
508         /* Since the Display was given, use it */
509         else
510         {
511                 /* We will not have to nuke it when done */
512                 m->nuke = 0;
513         }
514
515
516         /*** Save some information ***/
517
518         /* Save the Display itself */
519         m->dpy = dpy;
520
521         /* Get the Screen and Virtual Root Window */
522         m->screen = DefaultScreenOfDisplay(dpy);
523         m->root = RootWindowOfScreen(m->screen);
524
525         /* Get the default colormap */
526         m->cmap = DefaultColormapOfScreen(m->screen);
527
528         /* Extract the true name of the display */
529         m->name = DisplayString(dpy);
530
531         /* Extract the fd */
532         m->fd = ConnectionNumber(Metadpy->dpy);
533
534         /* Save the Size and Depth of the screen */
535         m->width = WidthOfScreen(m->screen);
536         m->height = HeightOfScreen(m->screen);
537         m->depth = DefaultDepthOfScreen(m->screen);
538
539         /* Save the Standard Colors */
540         m->black = BlackPixelOfScreen(m->screen);
541         m->white = WhitePixelOfScreen(m->screen);
542
543         /*** Make some clever Guesses ***/
544
545         /* Guess at the desired 'fg' and 'bg' Pixell's */
546         m->bg = m->black;
547         m->fg = m->white;
548
549         /* Calculate the Maximum allowed Pixel value.  */
550         m->zg = (1 << m->depth) - 1;
551
552         /* Save various default Flag Settings */
553         m->color = ((m->depth > 1) ? 1 : 0);
554         m->mono = ((m->color) ? 0 : 1);
555
556         /* Return "success" */
557         return (0);
558 }
559
560
561 #ifndef IGNORE_UNUSED_FUNCTIONS
562
563 /*
564  * Nuke the current metadpy
565  */
566 static errr Metadpy_nuke(void)
567 {
568         metadpy *m = Metadpy;
569
570
571         /* If required, Free the Display */
572         if (m->nuke)
573         {
574                 /* Close the Display */
575                 XCloseDisplay(m->dpy);
576
577                 /* Forget the Display */
578                 m->dpy = (Display*)(NULL);
579
580                 /* Do not nuke it again */
581                 m->nuke = 0;
582         }
583
584         /* Return Success */
585         return (0);
586 }
587
588 #endif /* IGNORE_UNUSED_FUNCTIONS */
589
590
591 /*
592  * General Flush/ Sync/ Discard routine
593  */
594 static errr Metadpy_update(int flush, int sync, int discard)
595 {
596         /* Flush if desired */
597         if (flush) XFlush(Metadpy->dpy);
598
599         /* Sync if desired, using 'discard' */
600         if (sync) XSync(Metadpy->dpy, discard);
601
602         /* Success */
603         return (0);
604 }
605
606
607 /*
608  * Make a simple beep
609  */
610 static errr Metadpy_do_beep(void)
611 {
612         /* Make a simple beep */
613         XBell(Metadpy->dpy, 100);
614
615         return (0);
616 }
617
618
619
620 /*
621  * Set the name (in the title bar) of Infowin
622  */
623 static errr Infowin_set_name(cptr name)
624 {
625         Status st;
626         XTextProperty tp;
627         char buf[128];
628         char *bp = buf;
629         strcpy(buf, name);
630         st = XStringListToTextProperty(&bp, 1, &tp);
631         if (st) XSetWMName(Metadpy->dpy, Infowin->win, &tp);
632         return (0);
633 }
634
635
636 #ifndef IGNORE_UNUSED_FUNCTIONS
637
638 /*
639  * Set the icon name of Infowin
640  */
641 static errr Infowin_set_icon_name(cptr name)
642 {
643         Status st;
644         XTextProperty tp;
645         char buf[128];
646         char *bp = buf;
647         strcpy(buf, name);
648         st = XStringListToTextProperty(&bp, 1, &tp);
649         if (st) XSetWMIconName(Metadpy->dpy, Infowin->win, &tp);
650         return (0);
651 }
652
653
654 /*
655  * Nuke Infowin
656  */
657 static errr Infowin_nuke(void)
658 {
659         infowin *iwin = Infowin;
660
661         /* Nuke if requested */
662         if (iwin->nuke)
663         {
664                 /* Destory the old window */
665                 XDestroyWindow(Metadpy->dpy, iwin->win);
666         }
667
668         /* Success */
669         return (0);
670 }
671
672 #endif /* IGNORE_UNUSED_FUNCTIONS */
673
674
675 /*
676  * Prepare a new 'infowin'.
677  */
678 static errr Infowin_prepare(Window xid)
679 {
680         infowin *iwin = Infowin;
681
682         Window tmp_win;
683         XWindowAttributes xwa;
684         int x, y;
685         unsigned int w, h, b, d;
686
687         /* Assign stuff */
688         iwin->win = xid;
689
690         /* Check For Error XXX Extract some ACTUAL data from 'xid' */
691         XGetGeometry(Metadpy->dpy, xid, &tmp_win, &x, &y, &w, &h, &b, &d);
692
693         /* Apply the above info */
694         iwin->x = x;
695         iwin->y = y;
696         iwin->w = w;
697         iwin->h = h;
698         iwin->b = b;
699
700         /* Check Error XXX Extract some more ACTUAL data */
701         XGetWindowAttributes(Metadpy->dpy, xid, &xwa);
702
703         /* Apply the above info */
704         iwin->mask = xwa.your_event_mask;
705         iwin->mapped = ((xwa.map_state == IsUnmapped) ? 0 : 1);
706
707         /* And assume that we are exposed */
708         iwin->redraw = 1;
709
710         /* Success */
711         return (0);
712 }
713
714
715 #ifndef IGNORE_UNUSED_FUNCTIONS
716
717 /*
718  * Initialize a new 'infowin'.
719  */
720 static errr Infowin_init_real(Window xid)
721 {
722         /* Wipe it clean */
723         (void)WIPE(Infowin, infowin);
724
725         /* Start out non-nukable */
726         Infowin->nuke = 0;
727
728         /* Attempt to Prepare ourself */
729         return (Infowin_prepare(xid));
730 }
731
732 #endif /* IGNORE_UNUSED_FUNCTIONS */
733
734
735 /*
736  * Init an infowin by giving some data.
737  *
738  * Inputs:
739  *      dad: The Window that should own this Window (if any)
740  *      x,y: The position of this Window
741  *      w,h: The size of this Window
742  *      b,d: The border width and pixel depth
743  *
744  * Notes:
745  *      If 'dad == None' assume 'dad == root'
746  */
747 static errr Infowin_init_data(Window dad, int x, int y, int w, int h,
748                               int b, Pixell fg, Pixell bg)
749 {
750         Window xid;
751
752         /* Wipe it clean */
753         (void)WIPE(Infowin, infowin);
754
755
756         /*** Error Check XXX ***/
757
758
759         /*** Create the Window 'xid' from data ***/
760
761         /* What happened here?  XXX XXX XXX */
762
763         /* If no parent given, depend on root */
764         if (dad == None)
765
766 /* #ifdef USE_GRAPHICS
767
768                 xid = XCreateWindow(Metadpy->dpy, Metadpy->root, x, y, w, h, b, 8, InputOutput, CopyFromParent, 0, 0);
769
770         else
771 */
772
773 /* #else */
774
775                 dad = Metadpy->root;
776
777 /* #endif */
778
779         /* Create the Window XXX Error Check */
780         xid = XCreateSimpleWindow(Metadpy->dpy, dad, x, y, w, h, b, fg, bg);
781
782         /* Start out selecting No events */
783         XSelectInput(Metadpy->dpy, xid, 0L);
784
785
786         /*** Prepare the new infowin ***/
787
788         /* Mark it as nukable */
789         Infowin->nuke = 1;
790
791         /* Attempt to Initialize the infowin */
792         return (Infowin_prepare(xid));
793 }
794
795
796
797 /*
798  * Modify the event mask of an Infowin
799  */
800 static errr Infowin_set_mask(long mask)
801 {
802         /* Save the new setting */
803         Infowin->mask = mask;
804
805         /* Execute the Mapping */
806         XSelectInput(Metadpy->dpy, Infowin->win, Infowin->mask);
807
808         /* Success */
809         return (0);
810 }
811
812
813 /*
814  * Request that Infowin be mapped
815  */
816 static errr Infowin_map(void)
817 {
818         /* Execute the Mapping */
819         XMapWindow(Metadpy->dpy, Infowin->win);
820
821         /* Success */
822         return (0);
823 }
824
825
826 #ifndef IGNORE_UNUSED_FUNCTIONS
827
828 /*
829  * Request that Infowin be unmapped
830  */
831 static errr Infowin_unmap(void)
832 {
833         /* Execute the Un-Mapping */
834         XUnmapWindow(Metadpy->dpy, Infowin->win);
835
836         /* Success */
837         return (0);
838 }
839
840 #endif /* IGNORE_UNUSED_FUNCTIONS */
841
842
843 /*
844  * Request that Infowin be raised
845  */
846 static errr Infowin_raise(void)
847 {
848         /* Raise towards visibility */
849         XRaiseWindow(Metadpy->dpy, Infowin->win);
850
851         /* Success */
852         return (0);
853 }
854
855
856 #ifndef IGNORE_UNUSED_FUNCTIONS
857
858 /*
859  * Request that Infowin be lowered
860  */
861 static errr Infowin_lower(void)
862 {
863         /* Lower towards invisibility */
864         XLowerWindow(Metadpy->dpy, Infowin->win);
865
866         /* Success */
867         return (0);
868 }
869
870 #endif /* IGNORE_UNUSED_FUNCTIONS */
871
872
873 /*
874  * Request that Infowin be moved to a new location
875  */
876 static errr Infowin_impell(int x, int y)
877 {
878         /* Execute the request */
879         XMoveWindow(Metadpy->dpy, Infowin->win, x, y);
880
881         /* Success */
882         return (0);
883 }
884
885
886 /*
887  * Resize an infowin
888  */
889 static errr Infowin_resize(int w, int h)
890 {
891         /* Execute the request */
892         XResizeWindow(Metadpy->dpy, Infowin->win, w, h);
893
894         /* Success */
895         return (0);
896 }
897
898
899 #ifndef IGNORE_UNUSED_FUNCTIONS
900
901 /*
902  * Move and Resize an infowin
903  */
904 static errr Infowin_locate(int x, int y, int w, int h)
905 {
906         /* Execute the request */
907         XMoveResizeWindow(Metadpy->dpy, Infowin->win, x, y, w, h);
908
909         /* Success */
910         return (0);
911 }
912
913 #endif /* IGNORE_UNUSED_FUNCTIONS */
914
915
916 /*
917  * Visually clear Infowin
918  */
919 static errr Infowin_wipe(void)
920 {
921         /* Execute the request */
922         XClearWindow(Metadpy->dpy, Infowin->win);
923
924         /* Success */
925         return (0);
926 }
927
928
929 #ifndef IGNORE_UNUSED_FUNCTIONS
930
931 /*
932  * Visually Paint Infowin with the current color
933  */
934 static errr Infowin_fill(void)
935 {
936         /* Execute the request */
937         XFillRectangle(Metadpy->dpy, Infowin->win, Infoclr->gc,
938                        0, 0, Infowin->w, Infowin->h);
939
940         /* Success */
941         return (0);
942 }
943
944 #endif /* IGNORE_UNUSED_FUNCTIONS */
945
946
947 /*
948  * A NULL terminated pair list of legal "operation names"
949  *
950  * Pairs of values, first is texttual name, second is the string
951  * holding the decimal value that the operation corresponds to.
952  */
953 static cptr opcode_pairs[] =
954 {
955         "cpy", "3",
956         "xor", "6",
957         "and", "1",
958         "ior", "7",
959         "nor", "8",
960         "inv", "10",
961         "clr", "0",
962         "set", "15",
963
964         "src", "3",
965         "dst", "5",
966
967         "+andReverse", "2",
968         "+andInverted", "4",
969         "+noop", "5",
970         "+equiv", "9",
971         "+orReverse", "11",
972         "+copyInverted", "12",
973         "+orInverted", "13",
974         "+nand", "14",
975         NULL
976 };
977
978
979 /*
980  * Parse a word into an operation "code"
981  *
982  * Inputs:
983  *      str: A string, hopefully representing an Operation
984  *
985  * Output:
986  *      0-15: if 'str' is a valid Operation
987  *      -1:   if 'str' could not be parsed
988  */
989 static int Infoclr_Opcode(cptr str)
990 {
991         register int i;
992
993         /* Scan through all legal operation names */
994         for (i = 0; opcode_pairs[i*2]; ++i)
995         {
996                 /* Is this the right oprname? */
997                 if (streq(opcode_pairs[i*2], str))
998                 {
999                         /* Convert the second element in the pair into a Code */
1000                         return (atoi(opcode_pairs[i*2+1]));
1001                 }
1002         }
1003
1004         /* The code was not found, return -1 */
1005         return (-1);
1006 }
1007
1008
1009 #ifndef IGNORE_UNUSED_FUNCTIONS
1010
1011 /*
1012  * Request a Pixell by name.  Note: uses 'Metadpy'.
1013  *
1014  * Inputs:
1015  *      name: The name of the color to try to load (see below)
1016  *
1017  * Output:
1018  *      The Pixell value that metched the given name
1019  *      'Metadpy->fg' if the name was unparseable
1020  *
1021  * Valid forms for 'name':
1022  *      'fg', 'bg', 'zg', '<name>' and '#<code>'
1023  */
1024 static Pixell Infoclr_Pixell(cptr name)
1025 {
1026         XColor scrn;
1027
1028         /* Attempt to Parse the name */
1029         if (name && name[0])
1030         {
1031                 /* The 'bg' color is available */
1032                 if (streq(name, "bg")) return (Metadpy->bg);
1033
1034                 /* The 'fg' color is available */
1035                 if (streq(name, "fg")) return (Metadpy->fg);
1036
1037                 /* The 'zg' color is available */
1038                 if (streq(name, "zg")) return (Metadpy->zg);
1039
1040                 /* The 'white' color is available */
1041                 if (streq(name, "white")) return (Metadpy->white);
1042
1043                 /* The 'black' color is available */
1044                 if (streq(name, "black")) return (Metadpy->black);
1045
1046                 /* Attempt to parse 'name' into 'scrn' */
1047                 if (!(XParseColor(Metadpy->dpy, Metadpy->cmap, name, &scrn)))
1048                 {
1049                         plog_fmt("Warning: Couldn't parse color '%s'\n", name);
1050                 }
1051
1052                 /* Attempt to Allocate the Parsed color */
1053                 if (!(XAllocColor(Metadpy->dpy, Metadpy->cmap, &scrn)))
1054                 {
1055                         plog_fmt("Warning: Couldn't allocate color '%s'\n", name);
1056                 }
1057
1058                 /* The Pixel was Allocated correctly */
1059                 else return (scrn.pixel);
1060         }
1061
1062         /* Warn about the Default being Used */
1063         plog_fmt("Warning: Using 'fg' for unknown color '%s'\n", name);
1064
1065         /* Default to the 'Foreground' color */
1066         return (Metadpy->fg);
1067 }
1068
1069
1070 /*
1071  * Initialize a new 'infoclr' with a real GC.
1072  */
1073 static errr Infoclr_init_1(GC gc)
1074 {
1075         infoclr *iclr = Infoclr;
1076
1077         /* Wipe the iclr clean */
1078         (void)WIPE(iclr, infoclr);
1079
1080         /* Assign the GC */
1081         iclr->gc = gc;
1082
1083         /* Success */
1084         return (0);
1085 }
1086
1087
1088 /*
1089  * Nuke an old 'infoclr'.
1090  */
1091 static errr Infoclr_nuke(void)
1092 {
1093         infoclr *iclr = Infoclr;
1094
1095         /* Deal with 'GC' */
1096         if (iclr->nuke)
1097         {
1098                 /* Free the GC */
1099                 XFreeGC(Metadpy->dpy, iclr->gc);
1100         }
1101
1102         /* Forget the current */
1103         Infoclr = (infoclr*)(NULL);
1104
1105         /* Success */
1106         return (0);
1107 }
1108
1109 #endif /* IGNORE_UNUSED_FUNCTIONS */
1110
1111
1112 /*
1113  * Initialize an infoclr with some data
1114  *
1115  * Inputs:
1116  *      fg:   The Pixell for the requested Foreground (see above)
1117  *      bg:   The Pixell for the requested Background (see above)
1118  *      op:   The Opcode for the requested Operation (see above)
1119  *      stip: The stipple mode
1120  */
1121 static errr Infoclr_init_data(Pixell fg, Pixell bg, int op, int stip)
1122 {
1123         infoclr *iclr = Infoclr;
1124
1125         GC gc;
1126         XGCValues gcv;
1127         unsigned long gc_mask;
1128
1129
1130
1131         /*** Simple error checking of opr and clr ***/
1132
1133         /* Check the 'Pixells' for realism */
1134         if (bg > Metadpy->zg) return (-1);
1135         if (fg > Metadpy->zg) return (-1);
1136
1137         /* Check the data for trueness */
1138         if ((op < 0) || (op > 15)) return (-1);
1139
1140
1141         /*** Create the requested 'GC' ***/
1142
1143         /* Assign the proper GC function */
1144         gcv.function = op;
1145
1146         /* Assign the proper GC background */
1147         gcv.background = bg;
1148
1149         /* Assign the proper GC foreground */
1150         gcv.foreground = fg;
1151
1152         /* Hack -- Handle XOR (xor is code 6) by hacking bg and fg */
1153         if (op == 6) gcv.background = 0;
1154         if (op == 6) gcv.foreground = (bg ^ fg);
1155
1156         /* Assign the proper GC Fill Style */
1157         gcv.fill_style = (stip ? FillStippled : FillSolid);
1158
1159         /* Turn off 'Give exposure events for pixmap copying' */
1160         gcv.graphics_exposures = False;
1161
1162         /* Set up the GC mask */
1163         gc_mask = (GCFunction | GCBackground | GCForeground |
1164                    GCFillStyle | GCGraphicsExposures);
1165
1166         /* Create the GC detailed above */
1167         gc = XCreateGC(Metadpy->dpy, Metadpy->root, gc_mask, &gcv);
1168
1169
1170         /*** Initialize ***/
1171
1172         /* Wipe the iclr clean */
1173         (void)WIPE(iclr, infoclr);
1174
1175         /* Assign the GC */
1176         iclr->gc = gc;
1177
1178         /* Nuke it when done */
1179         iclr->nuke = 1;
1180
1181         /* Assign the parms */
1182         iclr->fg = fg;
1183         iclr->bg = bg;
1184         iclr->code = op;
1185         iclr->stip = stip ? 1 : 0;
1186
1187         /* Success */
1188         return (0);
1189 }
1190
1191
1192
1193 /*
1194  * Change the 'fg' for an infoclr
1195  *
1196  * Inputs:
1197  *      fg:   The Pixell for the requested Foreground (see above)
1198  */
1199 static errr Infoclr_change_fg(Pixell fg)
1200 {
1201         infoclr *iclr = Infoclr;
1202
1203
1204         /*** Simple error checking of opr and clr ***/
1205
1206         /* Check the 'Pixells' for realism */
1207         if (fg > Metadpy->zg) return (-1);
1208
1209
1210         /*** Change ***/
1211
1212         /* Change */
1213         XSetForeground(Metadpy->dpy, iclr->gc, fg);
1214
1215         /* Success */
1216         return (0);
1217 }
1218
1219
1220
1221 #ifndef IGNORE_UNUSED_FUNCTIONS
1222
1223 /*
1224  * Nuke an old 'infofnt'.
1225  */
1226 static errr Infofnt_nuke(void)
1227 {
1228         infofnt *ifnt = Infofnt;
1229
1230 #ifdef _JP
1231         infofnt *ikfnt = Infokfnt;
1232 #endif
1233         /* Deal with 'name' */
1234         if (ifnt->name)
1235         {
1236                 /* Free the name */
1237                 string_free(ifnt->name);
1238         }
1239
1240 #ifdef _JP
1241         if (ikfnt->name)
1242         {
1243                 /* Free the name */
1244                 string_free(ikfnt->name);
1245         }
1246 #endif
1247         /* Nuke info if needed */
1248         if (ifnt->nuke)
1249         {
1250                 /* Free the font */
1251                 XFreeFont(Metadpy->dpy, ifnt->info);
1252         }
1253
1254 #ifdef _JP
1255         if (ikfnt->nuke)
1256         {
1257                 /* Free the font */
1258                 XFreeFont(Metadpy->dpy, ikfnt->info);
1259         }
1260 #endif
1261         /* Success */
1262         return (0);
1263 }
1264
1265 #endif /* IGNORE_UNUSED_FUNCTIONS */
1266
1267
1268 /*
1269  * Prepare a new 'infofnt'
1270  */
1271 #ifdef _JP
1272 static errr Infofnt_prepare(XFontStruct *info, XFontStruct *kinfo)
1273 #else
1274 #ifdef USE_FONTSET
1275 static errr Infofnt_prepare(XFontSet info)
1276 #else
1277 static errr Infofnt_prepare(XFontStruct *info)
1278 #endif
1279 #endif
1280
1281 {
1282         infofnt *ifnt = Infofnt;
1283
1284 #ifdef _JP
1285         infofnt *ikfnt = Infokfnt;
1286 #endif
1287         XCharStruct *cs;
1288 #ifdef USE_FONTSET
1289         XFontStruct **fontinfo;
1290         char **fontname;
1291         int n_fonts;
1292         int ascent, descent, width;
1293 #endif
1294
1295         /* Assign the struct */
1296         ifnt->info = info;
1297
1298 #ifdef USE_FONTSET
1299         n_fonts = XFontsOfFontSet(info, &fontinfo, &fontname);
1300
1301         ascent = descent = width = 0;
1302         while(n_fonts-- > 0){
1303                 cs = &((*fontinfo)->max_bounds);
1304                 if(ascent < (*fontinfo)->ascent) ascent = (*fontinfo)->ascent;
1305                 if(descent < (*fontinfo)->descent) descent = (*fontinfo)->descent;
1306                 if(((*fontinfo)->max_byte1) > 0){
1307                         /* Â¿¥Ð¥¤¥Èʸ»ú¤Î¾ì¹ç¤ÏÉýȾʬ(ü¿ôÀÚ¤ê¾å¤²)¤Çɾ²Á¤¹¤ë */
1308                         if(width < (cs->width+1)/2) width = (cs->width+1)/2;
1309                 }else{
1310                         if(width < cs->width) width = cs->width;
1311                 }
1312                 fontinfo++;
1313                 fontname++;
1314         }
1315         ifnt->asc = ascent;
1316         ifnt->hgt = ascent + descent;
1317         ifnt->wid = width;
1318 #else
1319         /* Jump into the max bouonds thing */
1320         cs = &(info->max_bounds);
1321
1322         /* Extract default sizing info */
1323         ifnt->asc = info->ascent;
1324         ifnt->hgt = info->ascent + info->descent;
1325         ifnt->wid = cs->width;
1326 #endif
1327
1328         if (use_bigtile)
1329                 ifnt->twid = 2 * ifnt->wid;
1330         else
1331                 ifnt->twid = ifnt->wid;
1332
1333 #ifdef _JP
1334     /* Assign the struct */
1335     ikfnt->info = kinfo;
1336  
1337     /* Jump into the max bouonds thing */
1338     cs = &(kinfo->max_bounds);
1339  
1340     /* Extract default sizing info */
1341     ikfnt->asc = kinfo->ascent;
1342     ikfnt->hgt = kinfo->ascent + kinfo->descent;
1343     ikfnt->wid = cs->width;
1344 #endif
1345 #ifndef JP
1346 #ifdef OBSOLETE_SIZING_METHOD
1347         /* Extract default sizing info */
1348         ifnt->asc = cs->ascent;
1349         ifnt->hgt = (cs->ascent + cs->descent);
1350         ifnt->wid = cs->width;
1351 #endif
1352 #endif
1353
1354         /* Success */
1355         return (0);
1356 }
1357
1358
1359 #ifndef IGNORE_UNUSED_FUNCTIONS
1360
1361 /*
1362  * Initialize a new 'infofnt'.
1363  */
1364 #ifdef _JP
1365 static errr Infofnt_init_real(XFontStruct *info, XFontStruct *kinfo)
1366 #else
1367 #ifdef USE_FONTSET
1368 static errr Infofnt_init_real(XFontSet info)
1369 #else
1370 static errr Infofnt_init_real(XFontStruct *info)
1371 #endif
1372 #endif
1373
1374 {
1375         /* Wipe the thing */
1376         (void)WIPE(Infofnt, infofnt);
1377
1378 #ifdef _JP
1379         WIPE(Infokfnt, infofnt);
1380 #endif
1381         /* No nuking */
1382         Infofnt->nuke = 0;
1383
1384 #ifdef _JP
1385         Infokfnt->nuke = 0;
1386 #endif
1387         /* Attempt to prepare it */
1388 #ifdef _JP
1389         return (Infofnt_prepare (info, kinfo));
1390 #else
1391         return (Infofnt_prepare(info));
1392 #endif
1393
1394 }
1395
1396 #endif /* IGNORE_UNUSED_FUNCTIONS */
1397
1398
1399 /*
1400  * Init an infofnt by its Name
1401  *
1402  * Inputs:
1403  *      name: The name of the requested Font
1404  */
1405 #ifdef _JP
1406 static errr Infofnt_init_data(cptr name, cptr kname)
1407 #else
1408 static errr Infofnt_init_data(cptr name)
1409 #endif
1410
1411 {
1412 #ifdef USE_FONTSET
1413         XFontSet info;
1414         char **missing_list;
1415         int missing_count;
1416         char *default_font;
1417 #else
1418         XFontStruct *info;
1419 #endif
1420
1421
1422 #ifdef _JP
1423         XFontStruct *kinfo;
1424 #endif
1425         /*** Load the info Fresh, using the name ***/
1426
1427         /* If the name is not given, report an error */
1428         if (!name) return (-1);
1429
1430 #ifdef _JP
1431         if (!kname) return (-1);
1432 #endif
1433         /* Attempt to load the font */
1434 #ifdef USE_FONTSET
1435         info = XCreateFontSet(Metadpy->dpy, name, &missing_list, &missing_count, &default_font);
1436         if(missing_count > 0){
1437                 printf("missing font(s): \n");
1438                 while(missing_count-- > 0){
1439                         printf("\t%s\n", missing_list[missing_count]);
1440                 }
1441                 XFreeStringList(missing_list);
1442         }
1443 #else
1444         info = XLoadQueryFont(Metadpy->dpy, name);
1445 #ifdef _JP
1446         kinfo = XLoadQueryFont(Metadpy->dpy, kname);
1447 #endif
1448 #endif
1449
1450
1451         /* The load failed, try to recover */
1452         if (!info) return (-1);
1453 #ifdef _JP
1454         if (!kinfo) return (-1);
1455 #endif
1456
1457
1458
1459         /*** Init the font ***/
1460
1461         /* Wipe the thing */
1462         (void)WIPE(Infofnt, infofnt);
1463
1464 #ifdef _JP
1465         WIPE(Infokfnt, infofnt);
1466 #endif
1467         /* Attempt to prepare it */
1468 #ifdef _JP
1469         if (Infofnt_prepare(info, kinfo))
1470 #else
1471         if (Infofnt_prepare(info))
1472 #endif
1473
1474         {
1475                 /* Free the font */
1476 #ifdef USE_FONTSET
1477                 XFreeFontSet(Metadpy->dpy, info);
1478 #else
1479                 XFreeFont(Metadpy->dpy, info);
1480 #ifdef _JP
1481                 XFreeFont(Metadpy->dpy, kinfo);
1482 #endif
1483 #endif
1484                 /* Fail */
1485                 return (-1);
1486         }
1487
1488         /* Save a copy of the font name */
1489         Infofnt->name = string_make(name);
1490 #ifdef _JP
1491         Infokfnt->name = string_make(kname);
1492 #endif
1493
1494         /* Mark it as nukable */
1495         Infofnt->nuke = 1;
1496 #ifdef _JP
1497         Infokfnt->nuke = 1;
1498 #endif
1499
1500         /* Success */
1501         return (0);
1502 }
1503
1504
1505 #ifdef _JP
1506 /*
1507  * EUCÆüËܸ쥳¡¼¥É¤ò´Þ¤àʸ»úÎó¤òɽ¼¨¤¹¤ë (Xlib)
1508  */
1509 static void
1510 XDrawMultiString(display,d,gc, x, y, string, len, afont, 
1511       afont_width, afont_height, afont_ascent, kfont, kfont_width)
1512     Display *display;
1513     Drawable d;
1514     GC gc;
1515     int       x, y;
1516     char      *string;
1517     int len;
1518     XFontStruct *afont;
1519     int afont_width, afont_height, afont_ascent;
1520     XFontStruct *kfont;
1521     int kfont_width;
1522 {
1523     XChar2b       kanji[500];
1524     char *p;
1525     unsigned char *str;
1526     unsigned char *endp;
1527     int slen;
1528     str = string;
1529     endp = string + len;
1530
1531     while ( str < endp && *str ) {
1532
1533 #ifdef TOFU      
1534       if ( (*str) == 0x7f ) {
1535           
1536           /* 0x7F¤Ï¢£¤Ç·è¤áÂǤÁ */
1537           
1538           /* Ï¢Â³¤¹¤ë0x7F¤ÎŤµ¤ò¸¡½Ð */
1539           slen = 0;
1540           while ( str < endp && (*str) == 0x7f ) {
1541               slen++; 
1542               str++;
1543           }
1544           
1545           /* ÉÁ²è */
1546           XFillRectangle( display, d, gc, x, y-afont_ascent, 
1547                           slen * afont_width, afont_height);
1548  
1549           /* ¥Ý¥¤¥ó¥¿¤ò¿Ê¤á¤ë */
1550           x += afont_width * slen;
1551       } 
1552       else  
1553 #endif
1554       if ( iskanji(*str) ) {
1555           
1556           /* UJIS¤Î»Ï¤Þ¤ê */
1557           
1558           /* Ï¢Â³¤¹¤ëUJISʸ»ú¤ÎŤµ¤ò¸¡½Ð */
1559           slen = 0;
1560           while ( str < endp && *str && iskanji(*str) ) {
1561               kanji[slen].byte1 = *str++ & 0x7f;
1562               kanji[slen++].byte2 = *str++ & 0x7f;
1563           }
1564           
1565           /* ÉÁ²è */
1566           XSetFont( display, gc, kfont->fid );
1567           XDrawImageString16( display, d, gc, x, y, kanji, slen );
1568
1569  
1570           /* ¥Ý¥¤¥ó¥¿¤ò¿Ê¤á¤ë */
1571           x += kfont_width * slen;
1572           
1573       } else {
1574           
1575           /* Èó´Á»ú(=ASCII¤È²¾Äê)¤Î»Ï¤Þ¤ê */
1576           
1577           /* Ï¢Â³¤¹¤ëASCIIʸ»ú¤ò¸¡½Ð */
1578           p = str;
1579           slen = 0;
1580           while ( str < endp && *str && !iskanji(*str) ) {
1581 #ifdef TOFU
1582               if (*str == 0x7f)break;
1583 #endif
1584               str++;
1585               slen++;
1586           }
1587           
1588           /* ÉÁ²è */
1589           XSetFont( display, gc, afont->fid );
1590           XDrawImageString( display, d, gc, x, y, p, slen );
1591           
1592           /* ¥Ý¥¤¥ó¥¿¤ò¿Ê¤á¤ë */
1593           x += afont_width * slen;
1594       }
1595     }
1596 }
1597 #endif
1598
1599 /*
1600  * Standard Text
1601  */
1602 static errr Infofnt_text_std(int x, int y, cptr str, int len)
1603 {
1604         int i;
1605
1606
1607         /*** Do a brief info analysis ***/
1608
1609         /* Do nothing if the string is null */
1610         if (!str || !*str) return (-1);
1611
1612         /* Get the length of the string */
1613         if (len < 0) len = strlen(str);
1614
1615         /*** Decide where to place the string, vertically ***/
1616
1617         /* Ignore Vertical Justifications */
1618         y = (y * Infofnt->hgt) + Infofnt->asc + Infowin->oy;
1619
1620
1621         /*** Decide where to place the string, horizontally ***/
1622
1623         /* Line up with x at left edge of column 'x' */
1624         x = (x * Infofnt->wid) + Infowin->ox;
1625
1626
1627         /*** Actually draw 'str' onto the infowin ***/
1628
1629 #if 1
1630 #ifndef JP
1631         /* Be sure the correct font is ready */
1632         XSetFont(Metadpy->dpy, Infoclr->gc, Infofnt->info->fid);
1633 #endif
1634 #endif
1635
1636         /*** Handle the fake mono we can enforce on fonts ***/
1637
1638         /* Monotize the font */
1639         if (Infofnt->mono)
1640         {
1641 #ifdef _JP
1642                 /* Be sure the correct font is ready */
1643                 XSetFont(Metadpy->dpy, Infoclr->gc, Infofnt->info->fid);
1644 #endif
1645                 /* Do each character */
1646                 for (i = 0; i < len; ++i)
1647                 {
1648                         /* Note that the Infoclr is set up to contain the Infofnt */
1649                         XDrawImageString(Metadpy->dpy, Infowin->win, Infoclr->gc,
1650                                          x + i * Infofnt->wid + Infofnt->off, y, str + i, 1);
1651                 }
1652         }
1653
1654         /* Assume monoospaced font */
1655         else
1656         {
1657                 /* Note that the Infoclr is set up to contain the Infofnt */
1658 #ifdef _JP
1659                 /* ´Á»ú¥Õ¥©¥ó¥È¤Îɽ¼¨Éý¤Ï ASCII¥Õ¥©¥ó¥È¤Î2Çܤ˸ÇÄê */
1660                 XDrawMultiString(Metadpy->dpy, Infowin->win, Infoclr->gc,
1661                                  x, y, str, len,
1662                                  Infofnt->info, Infofnt->wid, Infofnt->hgt,
1663                                  Infofnt->asc, 
1664                                  Infokfnt->info, Infofnt->wid * 2);
1665 #else
1666 #ifdef USE_FONTSET
1667                 XmbDrawImageString(Metadpy->dpy, Infowin->win, Infofnt->info,
1668                                    Infoclr->gc, x, y, str, len);
1669 #else
1670                 XDrawImageString(Metadpy->dpy, Infowin->win, Infoclr->gc,
1671                                  x, y, str, len);
1672 #endif
1673 #endif
1674
1675         }
1676
1677
1678         /* Success */
1679         return (0);
1680 }
1681
1682
1683 /*
1684  * Painting where text would be
1685  */
1686 static errr Infofnt_text_non(int x, int y, cptr str, int len)
1687 {
1688         int w, h;
1689
1690
1691         /*** Find the width ***/
1692
1693         /* Negative length is a flag to count the characters in str */
1694         if (len < 0) len = strlen(str);
1695
1696         /* The total width will be 'len' chars * standard width */
1697         w = len * Infofnt->wid;
1698
1699
1700         /*** Find the X dimensions ***/
1701
1702         /* Line up with x at left edge of column 'x' */
1703         x = x * Infofnt->wid + Infowin->ox;
1704
1705
1706         /*** Find other dimensions ***/
1707
1708         /* Simply do 'Infofnt->hgt' (a single row) high */
1709         h = Infofnt->hgt;
1710
1711         /* Simply do "at top" in row 'y' */
1712         y = y * h + Infowin->oy;
1713
1714
1715         /*** Actually 'paint' the area ***/
1716
1717         /* Just do a Fill Rectangle */
1718         XFillRectangle(Metadpy->dpy, Infowin->win, Infoclr->gc, x, y, w, h);
1719
1720         /* Success */
1721         return (0);
1722 }
1723
1724
1725
1726 /*************************************************************************/
1727
1728
1729 /*
1730  * Angband specific code follows... (ANGBAND)
1731  */
1732
1733
1734 /*
1735  * Hack -- cursor color
1736  */
1737 static infoclr *xor;
1738
1739 /*
1740  * Actual color table
1741  */
1742 static infoclr *clr[256];
1743
1744 /*
1745  * Color info (unused, red, green, blue).
1746  */
1747 static byte color_table[256][4];
1748
1749 /*
1750  * Forward declare
1751  */
1752 typedef struct term_data term_data;
1753
1754 /*
1755  * A structure for each "term"
1756  */
1757 struct term_data
1758 {
1759         term t;
1760
1761         infofnt *fnt;
1762 #ifdef _JP
1763         infofnt *kfnt;
1764 #endif
1765
1766
1767         infowin *win;
1768
1769 #ifdef USE_GRAPHICS
1770
1771         XImage *tiles;
1772
1773 #ifdef USE_TRANSPARENCY
1774
1775         /* Tempory storage for overlaying tiles. */
1776         XImage *TmpImage;
1777
1778 #endif
1779
1780 #endif
1781
1782 };
1783
1784
1785 /*
1786  * The number of term data structures
1787  */
1788 #define MAX_TERM_DATA 8
1789
1790 /*
1791  * The array of term data structures
1792  */
1793 static term_data data[MAX_TERM_DATA];
1794
1795
1796
1797 /*
1798  * Process a keypress event
1799  *
1800  * Also appears in "main-xaw.c".
1801  */
1802 static void react_keypress(XKeyEvent *xev)
1803 {
1804         int i, n, mc, ms, mo, mx;
1805
1806         uint ks1;
1807
1808         XKeyEvent *ev = (XKeyEvent*)(xev);
1809
1810         KeySym ks;
1811
1812         char buf[128];
1813         char msg[128];
1814
1815 #ifdef USE_XIM
1816         int valid_keysym = TRUE;
1817 #endif
1818
1819         /* Check for "normal" keypresses */
1820 #ifdef USE_XIM
1821         if(Focuswin && Focuswin->xic){
1822                 Status status;
1823                 n = XmbLookupString(Focuswin->xic, ev, buf, 125, &ks, &status);
1824                 if(status == XBufferOverflow){
1825                         printf("Input is too long, and dropped\n");
1826                         return;
1827                 }
1828                 if(status != XLookupKeySym && status != XLookupBoth){
1829                         valid_keysym = FALSE;
1830                 }
1831         }else{
1832                 n = XLookupString(ev, buf, 125, &ks, NULL);
1833         }
1834 #else
1835         n = XLookupString(ev, buf, 125, &ks, NULL);
1836 #endif
1837
1838         /* Terminate */
1839         buf[n] = '\0';
1840
1841 #ifdef USE_XIM
1842         if(!valid_keysym){
1843                 /* Enqueue the normal key(s) */
1844                 for (i = 0; buf[i]; i++) Term_keypress(buf[i]);
1845
1846                 /* All done */
1847                 return;
1848         }
1849 #endif
1850
1851         /* Hack -- Ignore "modifier keys" */
1852         if (IsModifierKey(ks)) return;
1853
1854
1855         /* Hack -- convert into an unsigned int */
1856         ks1 = (uint)(ks);
1857
1858         /* Extract four "modifier flags" */
1859         mc = (ev->state & ControlMask) ? TRUE : FALSE;
1860         ms = (ev->state & ShiftMask) ? TRUE : FALSE;
1861         mo = (ev->state & Mod1Mask) ? TRUE : FALSE;
1862         mx = (ev->state & Mod2Mask) ? TRUE : FALSE;
1863
1864
1865         /* Normal keys with no modifiers */
1866         if (n && !mo && !mx && !IsSpecialKey(ks))
1867         {
1868                 /* Enqueue the normal key(s) */
1869                 for (i = 0; buf[i]; i++) Term_keypress(buf[i]);
1870
1871                 /* All done */
1872                 return;
1873         }
1874
1875
1876         /* Handle a few standard keys (bypass modifiers) XXX XXX XXX */
1877         switch (ks1)
1878         {
1879                 case XK_Escape:
1880                 {
1881                         Term_keypress(ESCAPE);
1882                         return;
1883                 }
1884
1885                 case XK_Return:
1886                 {
1887                         Term_keypress('\r');
1888                         return;
1889                 }
1890
1891                 case XK_Tab:
1892                 {
1893                         Term_keypress('\t');
1894                         return;
1895                 }
1896
1897                 case XK_Delete:
1898                 {
1899                         Term_keypress(0x7f);
1900                         return;
1901                 }
1902                 case XK_BackSpace:
1903                 {
1904                         Term_keypress('\010');
1905                         return;
1906                 }
1907         }
1908
1909
1910         /* Hack -- Use the KeySym */
1911         if (ks)
1912         {
1913                 sprintf(msg, "%c%s%s%s%s_%lX%c", 31,
1914                         mc ? "N" : "", ms ? "S" : "",
1915                         mo ? "O" : "", mx ? "M" : "",
1916                         (unsigned long)(ks), 13);
1917         }
1918
1919         /* Hack -- Use the Keycode */
1920         else
1921         {
1922                 sprintf(msg, "%c%s%s%s%sK_%X%c", 31,
1923                         mc ? "N" : "", ms ? "S" : "",
1924                         mo ? "O" : "", mx ? "M" : "",
1925                         ev->keycode, 13);
1926         }
1927
1928         /* Enqueue the "macro trigger" string */
1929         for (i = 0; msg[i]; i++) Term_keypress(msg[i]);
1930
1931
1932         /* Hack -- auto-define macros as needed */
1933         if (n && (macro_find_exact(msg) < 0))
1934         {
1935                 /* Create a macro */
1936                 macro_add(msg, buf);
1937         }
1938 }
1939
1940
1941
1942
1943 /*
1944  * Process events
1945  */
1946 static errr CheckEvent(bool wait)
1947 {
1948         term_data *old_td = (term_data*)(Term->data);
1949
1950         XEvent xev_body, *xev = &xev_body;
1951
1952         term_data *td = NULL;
1953         infowin *iwin = NULL;
1954
1955         int i, x, y;
1956
1957 #ifdef USE_XIM
1958  redo_checkevent:
1959 #endif
1960
1961         /* Do not wait unless requested */
1962         if (!wait && !XPending(Metadpy->dpy)) return (1);
1963
1964         /* Load the Event */
1965         XNextEvent(Metadpy->dpy, xev);
1966
1967 #ifdef USE_XIM
1968 /* #define DEBUG_EVENT */
1969 #ifdef DEBUG_EVENT
1970         {
1971                 printf("event: type=%d", xev->type);
1972                 switch(xev->type){
1973                 case KeyPress:
1974                         printf("(KeyPress), keycode=%X", xev->xkey.keycode);
1975                         break;
1976                 case FocusIn:
1977                         printf("(FocusIn)");
1978                         break;
1979                 case FocusOut:
1980                         printf("(FocusOut)");
1981                         break;
1982                 case ReparentNotify:
1983                         printf("(ReparentNotify)");
1984                         break;
1985                 case ConfigureNotify:
1986                         printf("(ConfigureNotify)");
1987                         break;
1988                 case MapNotify:
1989                         printf("(MapNotify)");
1990                         break;
1991                 case Expose:
1992                         printf("(Expose)");
1993                         break;
1994                 case ClientMessage:
1995                         printf("(ClientMessage)");
1996                         break;
1997                 }
1998                         
1999         }
2000 #endif
2001         if (XFilterEvent(xev, xev->xany.window)
2002                 /*XFilterEvent(xev, (data[0].win)->win)*/){
2003 #ifdef DEBUG_EVENT
2004                 printf(", [filtered by IM]\n");
2005 #endif
2006                 goto redo_checkevent;
2007         }
2008 #ifdef DEBUG_EVENT
2009         printf("\n");
2010 #endif
2011 #endif
2012
2013         /* Notice new keymaps */
2014         if (xev->type == MappingNotify)
2015         {
2016                 XRefreshKeyboardMapping(&xev->xmapping);
2017                 return 0;
2018         }
2019
2020
2021         /* Scan the windows */
2022         for (i = 0; i < MAX_TERM_DATA; i++)
2023         {
2024                 if (!data[i].win) continue;
2025                 if (xev->xany.window == data[i].win->win)
2026                 {
2027                         td = &data[i];
2028                         iwin = td->win;
2029                         break;
2030                 }
2031         }
2032
2033         /* Unknown window */
2034         if (!td || !iwin) return (0);
2035
2036
2037         /* Hack -- activate the Term */
2038         Term_activate(&td->t);
2039
2040         /* Hack -- activate the window */
2041         Infowin_set(iwin);
2042
2043
2044         /* Switch on the Type */
2045         switch (xev->type)
2046         {
2047
2048 #if 0
2049
2050                 case ButtonPress:
2051                 case ButtonRelease:
2052                 {
2053                         int z = 0;
2054
2055                         /* Which button is involved */
2056                         if (xev->xbutton.button == Button1) z = 1;
2057                         else if (xev->xbutton.button == Button2) z = 2;
2058                         else if (xev->xbutton.button == Button3) z = 3;
2059                         else if (xev->xbutton.button == Button4) z = 4;
2060                         else if (xev->xbutton.button == Button5) z = 5;
2061
2062                         /* Where is the mouse */
2063                         x = xev->xbutton.x;
2064                         y = xev->xbutton.y;
2065
2066                         /* XXX Handle */
2067
2068                         break;
2069                 }
2070
2071                 case EnterNotify:
2072                 case LeaveNotify:
2073                 {
2074                         /* Where is the mouse */
2075                         x = xev->xcrossing.x;
2076                         y = xev->xcrossing.y;
2077
2078                         /* XXX Handle */
2079
2080                         break;
2081                 }
2082
2083                 case MotionNotify:
2084                 {
2085                         /* Where is the mouse */
2086                         x = xev->xmotion.x;
2087                         y = xev->xmotion.y;
2088
2089                         /* XXX Handle */
2090
2091                         break;
2092                 }
2093
2094                 case KeyRelease:
2095                 {
2096                         /* Nothing */
2097                         break;
2098                 }
2099
2100 #endif
2101
2102                 case KeyPress:
2103                 {
2104                         /* Save the mouse location */
2105                         x = xev->xkey.x;
2106                         y = xev->xkey.y;
2107
2108                         /* Hack -- use "old" term */
2109                         Term_activate(&old_td->t);
2110
2111                         /* Process the key */
2112                         react_keypress(&(xev->xkey));
2113
2114                         break;
2115                 }
2116
2117                 case Expose:
2118                 {
2119                         int x1, x2, y1, y2;
2120                         
2121                         /* Ignore "extra" exposes */
2122                         /*if (xev->xexpose.count) break;*/
2123
2124                         /* Clear the window */
2125                         /*Infowin_wipe();*/
2126                         
2127                         x1 = (xev->xexpose.x - Infowin->ox)/Infofnt->wid;
2128                         x2 = (xev->xexpose.x + xev->xexpose.width -
2129                                  Infowin->ox)/Infofnt->wid;
2130                         
2131                         y1 = (xev->xexpose.y - Infowin->oy)/Infofnt->hgt;
2132                         y2 = (xev->xexpose.y + xev->xexpose.height -
2133                                  Infowin->oy)/Infofnt->hgt;
2134                         
2135                         Term_redraw_section(x1, y1, x2, y2);
2136
2137                         /* Redraw */
2138                         /*Term_redraw();*/
2139
2140                         break;
2141                 }
2142
2143                 case MapNotify:
2144                 {
2145                         Infowin->mapped = 1;
2146                         Term->mapped_flag = TRUE;
2147                         break;
2148                 }
2149
2150                 case UnmapNotify:
2151                 {
2152                         Infowin->mapped = 0;
2153                         Term->mapped_flag = FALSE;
2154                         break;
2155                 }
2156
2157                 /* Move and/or Resize */
2158                 case ConfigureNotify:
2159                 {
2160                         int cols, rows, wid, hgt;
2161
2162                         int ox = Infowin->ox;
2163                         int oy = Infowin->oy;
2164
2165                         /* Save the new Window Parms */
2166                         Infowin->x = xev->xconfigure.x;
2167                         Infowin->y = xev->xconfigure.y;
2168                         Infowin->w = xev->xconfigure.width;
2169                         Infowin->h = xev->xconfigure.height;
2170
2171                         /* Determine "proper" number of rows/cols */
2172                         cols = ((Infowin->w - (ox + ox)) / td->fnt->wid);
2173                         rows = ((Infowin->h - (oy + oy)) / td->fnt->hgt);
2174
2175                         /* Hack -- minimal size */
2176                         if (cols < 1) cols = 1;
2177                         if (rows < 1) rows = 1;
2178
2179                         if (td == &data[0])
2180                         {
2181                                 /* Hack the main window must be at least 80x24 */
2182                                 if (cols < 80) cols = 80;
2183                                 if (rows < 24) rows = 24;
2184                         }
2185
2186                         /* Desired size of window */
2187                         wid = cols * td->fnt->wid + (ox + ox);
2188                         hgt = rows * td->fnt->hgt + (oy + oy);
2189
2190                         /* Resize the Term (if needed) */
2191                         Term_resize(cols, rows);
2192
2193                         /* Resize the windows if any "change" is needed */
2194                         if ((Infowin->w != wid) || (Infowin->h != hgt))
2195                         {
2196                                 /* Resize window */
2197                                 Infowin_set(td->win);
2198                                 Infowin_resize(wid, hgt);
2199                         }
2200
2201                         break;
2202                 }
2203 #ifdef USE_XIM
2204                 case FocusIn:
2205                 {
2206                         if(iwin->xic){
2207                                 XSetICFocus(iwin->xic);
2208                         }
2209                         Focuswin = iwin;
2210                         break;
2211                 }
2212                 case FocusOut:
2213                 {
2214                         if(iwin->xic){
2215                                 XUnsetICFocus(iwin->xic);
2216                         }
2217                         /* Focuswin = NULL;*/
2218                         break;
2219                 }
2220 #endif
2221         }
2222
2223
2224         /* Hack -- Activate the old term */
2225         Term_activate(&old_td->t);
2226
2227         /* Hack -- Activate the proper window */
2228         Infowin_set(old_td->win);
2229
2230
2231         /* Success */
2232         return (0);
2233 }
2234
2235
2236 #ifdef USE_SOUND
2237
2238 /*
2239  * An array of sound file names
2240  */
2241 static cptr sound_file[SOUND_MAX];
2242
2243 /*
2244  * Check for existance of a file
2245  */
2246 static bool check_file(cptr s)
2247 {
2248         FILE *fff;
2249
2250         fff = fopen(s, "r");
2251         if (!fff) return (FALSE);
2252         
2253         fclose(fff);
2254         return (TRUE);
2255 }
2256
2257 /*
2258  * Initialize sound
2259  */
2260 static void init_sound(void)
2261 {
2262         int i;
2263         char wav[128];
2264         char buf[1024];
2265         char dir_xtra_sound[1024];
2266                 
2267         /* Build the "sound" path */
2268         path_build(dir_xtra_sound, 1024, ANGBAND_DIR_XTRA, "sound");
2269                 
2270         /* Prepare the sounds */
2271         for (i = 1; i < SOUND_MAX; i++)
2272         {
2273                 /* Extract name of sound file */
2274                 sprintf(wav, "%s.wav", angband_sound_name[i]);
2275                 
2276                 /* Access the sound */
2277                 path_build(buf, 1024, dir_xtra_sound, wav);
2278                 
2279                 /* Save the sound filename, if it exists */
2280                 if (check_file(buf)) sound_file[i] = string_make(buf);
2281         }
2282         use_sound = TRUE;
2283         return;
2284 }
2285
2286 /*
2287  * Hack -- make a sound
2288  */
2289 static errr Term_xtra_x11_sound(int v)
2290 {
2291         char buf[1024];
2292         
2293         /* Sound disabled */
2294         if (!use_sound) return (1);
2295         
2296         /* Illegal sound */
2297         if ((v < 0) || (v >= SOUND_MAX)) return (1);
2298         
2299         /* Unknown sound */
2300         if (!sound_file[v]) return (1);
2301         
2302         sprintf(buf,"./playwave.sh %s\n", sound_file[v]);
2303         system(buf);
2304         
2305         return (0);
2306         
2307 }
2308 #endif /* USE_SOUND */
2309
2310
2311 /*
2312  * Handle "activation" of a term
2313  */
2314 static errr Term_xtra_x11_level(int v)
2315 {
2316         term_data *td = (term_data*)(Term->data);
2317
2318         /* Handle "activate" */
2319         if (v)
2320         {
2321                 /* Activate the window */
2322                 Infowin_set(td->win);
2323
2324                 /* Activate the font */
2325                 Infofnt_set(td->fnt);
2326 #ifdef _JP
2327                 Infokfnt_set(td->kfnt);
2328 #endif
2329         }
2330
2331         /* Success */
2332         return (0);
2333 }
2334
2335
2336 /*
2337  * React to changes
2338  */
2339 static errr Term_xtra_x11_react(void)
2340 {
2341         int i;
2342         
2343         if (Metadpy->color)
2344         {
2345                 /* Check the colors */
2346                 for (i = 0; i < 256; i++)
2347                 {
2348                         if ((color_table[i][0] != angband_color_table[i][0]) ||
2349                             (color_table[i][1] != angband_color_table[i][1]) ||
2350                             (color_table[i][2] != angband_color_table[i][2]) ||
2351                             (color_table[i][3] != angband_color_table[i][3]))
2352                         {
2353                                 Pixell pixel;
2354
2355                                 /* Save new values */
2356                                 color_table[i][0] = angband_color_table[i][0];
2357                                 color_table[i][1] = angband_color_table[i][1];
2358                                 color_table[i][2] = angband_color_table[i][2];
2359                                 color_table[i][3] = angband_color_table[i][3];
2360
2361                                 /* Create pixel */
2362                                 pixel = create_pixel(Metadpy->dpy,
2363                                                      color_table[i][1],
2364                                                      color_table[i][2],
2365                                                      color_table[i][3]);
2366
2367                                 /* Change the foreground */
2368                                 Infoclr_set(clr[i]);
2369                                 Infoclr_change_fg(pixel);
2370                         }
2371                 }
2372         }
2373
2374         /* Success */
2375         return (0);
2376 }
2377
2378
2379 /*
2380  * Handle a "special request"
2381  */
2382 static errr Term_xtra_x11(int n, int v)
2383 {
2384         /* Handle a subset of the legal requests */
2385         switch (n)
2386         {
2387                 /* Make a noise */
2388                 case TERM_XTRA_NOISE: Metadpy_do_beep(); return (0);
2389
2390 #ifdef USE_SOUND
2391                 /* Make a special sound */
2392                 case TERM_XTRA_SOUND: return (Term_xtra_x11_sound(v));
2393 #endif
2394
2395                 /* Flush the output XXX XXX */
2396                 case TERM_XTRA_FRESH: Metadpy_update(1, 0, 0); return (0);
2397
2398                 /* Process random events XXX */
2399                 case TERM_XTRA_BORED: return (CheckEvent(0));
2400
2401                 /* Process Events XXX */
2402                 case TERM_XTRA_EVENT: return (CheckEvent(v));
2403
2404                 /* Flush the events XXX */
2405                 case TERM_XTRA_FLUSH: while (!CheckEvent(FALSE)); return (0);
2406
2407                 /* Handle change in the "level" */
2408                 case TERM_XTRA_LEVEL: return (Term_xtra_x11_level(v));
2409
2410                 /* Clear the screen */
2411                 case TERM_XTRA_CLEAR: Infowin_wipe(); return (0);
2412
2413                 /* Delay for some milliseconds */
2414                 case TERM_XTRA_DELAY: usleep(1000 * v); return (0);
2415
2416                 /* React to changes */
2417                 case TERM_XTRA_REACT: return (Term_xtra_x11_react());
2418         }
2419
2420         /* Unknown */
2421         return (1);
2422 }
2423
2424
2425 /*
2426  * Draw the cursor as an inverted rectangle.
2427  *
2428  * Consider a rectangular outline like "main-mac.c".  XXX XXX
2429  */
2430 static errr Term_curs_x11(int x, int y)
2431 {
2432         /* Draw the cursor */
2433         Infoclr_set(xor);
2434
2435 #ifdef JP
2436         if (x + 1 < Term->wid &&
2437             ((use_bigtile && Term->old->a[y][x+1] == 255) ||
2438              (iskanji(Term->old->c[y][x]) && !(Term->old->a[y][x] & 0x80))))
2439 #else
2440         if (use_bigtile && x + 1 < Term->wid && Term->old->a[y][x+1] == 255)
2441 #endif
2442                 Infofnt_text_non(x, y, "  ", 2);
2443         else
2444         /* Hilite the cursor character */
2445         Infofnt_text_non(x, y, " ", 1);
2446
2447         /* Success */
2448         return (0);
2449 }
2450
2451
2452 /*
2453  * Erase some characters.
2454  */
2455 static errr Term_wipe_x11(int x, int y, int n)
2456 {
2457         /* Erase (use black) */
2458         Infoclr_set(clr[TERM_DARK]);
2459
2460         /* Mega-Hack -- Erase some space */
2461         Infofnt_text_non(x, y, "", n);
2462
2463         /* Success */
2464         return (0);
2465 }
2466
2467
2468 /*
2469  * Draw some textual characters.
2470  */
2471 static errr Term_text_x11(int x, int y, int n, byte a, cptr s)
2472 {
2473         /* Draw the text */
2474         Infoclr_set(clr[a]);
2475
2476         /* Draw the text */
2477         Infofnt_text_std(x, y, s, n);
2478
2479         /* Success */
2480         return (0);
2481 }
2482
2483
2484 #ifdef USE_GRAPHICS
2485
2486 /*
2487  * Draw some graphical characters.
2488  */
2489 # ifdef USE_TRANSPARENCY
2490 static errr Term_pict_x11(int x, int y, int n, const byte *ap, const char *cp, const byte *tap, const char *tcp)
2491 # else /* USE_TRANSPARENCY */
2492 static errr Term_pict_x11(int x, int y, int n, const byte *ap, const char *cp)
2493 # endif /* USE_TRANSPARENCY */
2494 {
2495         int i, x1, y1;
2496
2497         byte a;
2498         char c;
2499
2500 #ifdef USE_TRANSPARENCY
2501         byte ta;
2502         char tc;
2503
2504         int x2, y2;
2505         int k,l;
2506
2507         unsigned long pixel, blank;
2508 #endif /* USE_TRANSPARENCY */
2509
2510         term_data *td = (term_data*)(Term->data);
2511
2512         y *= Infofnt->hgt;
2513         x *= Infofnt->wid;
2514
2515         /* Add in affect of window boundaries */
2516         y += Infowin->oy;
2517         x += Infowin->ox;
2518
2519         for (i = 0; i < n; ++i, x += td->fnt->wid)
2520         {
2521                 a = *ap++;
2522                 c = *cp++;
2523
2524                 /* For extra speed - cache these values */
2525                 x1 = (c&0x7F) * td->fnt->twid;
2526                 y1 = (a&0x7F) * td->fnt->hgt;
2527
2528 #ifdef USE_TRANSPARENCY
2529
2530                 ta = *tap++;
2531                 tc = *tcp++;
2532
2533                 /* For extra speed - cache these values */
2534                 x2 = (tc&0x7F) * td->fnt->twid;
2535                 y2 = (ta&0x7F) * td->fnt->hgt;
2536                 
2537                 /* Optimise the common case */
2538                 if (((x1 == x2) && (y1 == y2)) ||
2539                     !(((byte)ta & 0x80) && ((byte)tc & 0x80)))
2540                 {
2541                         /* Draw object / terrain */
2542                         XPutImage(Metadpy->dpy, td->win->win,
2543                                 clr[0]->gc,
2544                                 td->tiles,
2545                                 x1, y1,
2546                                 x, y,
2547                                 td->fnt->twid, td->fnt->hgt);   
2548                 }
2549                 else
2550                 {
2551
2552                         /* Mega Hack^2 - assume the top left corner is "black" */
2553                         blank = XGetPixel(td->tiles, 0, td->fnt->hgt * 6);
2554
2555                         for (k = 0; k < td->fnt->twid; k++)
2556                         {
2557                                 for (l = 0; l < td->fnt->hgt; l++)
2558                                 {
2559                                         /* If mask set... */
2560                                         if ((pixel = XGetPixel(td->tiles, x1 + k, y1 + l)) == blank)
2561                                         {
2562                                                 /* Output from the terrain */
2563                                                 pixel = XGetPixel(td->tiles, x2 + k, y2 + l);
2564                                         }
2565                                         
2566                                         /* Store into the temp storage. */
2567                                         XPutPixel(td->TmpImage, k, l, pixel);
2568                                 }
2569                         }
2570
2571
2572                         /* Draw to screen */
2573
2574                         XPutImage(Metadpy->dpy, td->win->win,
2575                               clr[0]->gc,
2576                              td->TmpImage,
2577                              0, 0, x, y,
2578                              td->fnt->twid, td->fnt->hgt);
2579                 }
2580
2581 #else /* USE_TRANSPARENCY */
2582
2583                 /* Draw object / terrain */
2584                 XPutImage(Metadpy->dpy, td->win->win,
2585                           clr[0]->gc,
2586                           td->tiles,
2587                           x1, y1,
2588                           x, y,
2589                           td->fnt->twid, td->fnt->hgt);
2590
2591 #endif /* USE_TRANSPARENCY */
2592         }
2593
2594         /* Success */
2595         return (0);
2596 }
2597
2598 #endif /* USE_GRAPHICS */
2599
2600 #ifdef USE_XIM
2601 static void IMDestroyCallback(XIM, XPointer, XPointer);
2602
2603 static void
2604 IMInstantiateCallback(Display *display, XPointer unused1, XPointer unused2)
2605 {
2606         XIM xim;
2607         XIMCallback ximcallback;
2608         XIMStyles *xim_styles = NULL;
2609         int i;
2610
2611         xim = XOpenIM(display, NULL, NULL, NULL);
2612         if(!xim){
2613                 printf("can't open IM\n");
2614                 return;
2615         }
2616
2617         /* initialize destroy callback */
2618         ximcallback.callback = IMDestroyCallback;
2619         ximcallback.client_data = NULL;
2620         XSetIMValues(xim, XNDestroyCallback, &ximcallback, NULL);
2621
2622         /* set style (only "Root" is supported yet...) */
2623         XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL);
2624         for (i = 0; i < xim_styles->count_styles; i++){
2625                 if(xim_styles->supported_styles[i] == (XIMPreeditNothing | XIMStatusNothing)) break;
2626         }
2627         if(i >= xim_styles->count_styles){
2628                 printf("Sorry, your IM does not support 'Root' preedit style...\n");
2629                 XCloseIM(xim);
2630                 return;
2631         }
2632         XFree(xim_styles);
2633
2634         Metadpy->xim = xim;
2635
2636         for (i = 0; i < MAX_TERM_DATA; i++)
2637         {
2638                 infowin *iwin = data[i].win;
2639                 if (!iwin) continue;
2640                 iwin->xic = XCreateIC(xim, XNInputStyle, (XIMPreeditNothing | XIMStatusNothing), XNClientWindow, iwin->win, XNFocusWindow, iwin->win, NULL);
2641                 if(!iwin->xic){
2642                         printf("Can't create input context for Term%d\n", i);
2643                         continue;
2644                 }
2645                 if(XGetICValues(iwin->xic, XNFilterEvents, &iwin->xic_mask, NULL) != NULL){
2646 /*                      printf("Can't get XNFilterEvents\n"); */
2647                         iwin->xic_mask = 0L;
2648                 }
2649                 XSelectInput(Metadpy->dpy, iwin->win, iwin->mask | iwin->xic_mask);
2650         }
2651
2652         return;
2653 }
2654
2655 static void IMDestroyCallback(XIM xim, XPointer client_data, XPointer call_data)
2656 {
2657         int i;
2658
2659     if (call_data == NULL){
2660                 XRegisterIMInstantiateCallback(Metadpy->dpy, NULL, NULL, NULL, IMInstantiateCallback, NULL);
2661         }
2662
2663         for(i = 0; i < MAX_TERM_DATA; i++)
2664         {
2665                 infowin *iwin = data[i].win;
2666                 if(!iwin) continue;
2667                 if(iwin->xic_mask){
2668                         XSelectInput(Metadpy->dpy, iwin->win, iwin->mask);
2669                         iwin->xic_mask = 0L;
2670                 }
2671                 iwin->xic = NULL;
2672         }
2673
2674         Metadpy->xim = NULL;
2675 }
2676 #endif
2677
2678 /*
2679  * Initialize a term_data
2680  */
2681 static errr term_data_init(term_data *td, int i)
2682 {
2683         term *t = &td->t;
2684
2685         cptr name = angband_term_name[i];
2686
2687         cptr font;
2688 #ifdef _JP
2689         cptr kfont;
2690 #endif
2691
2692
2693         int x = 0;
2694         int y = 0;
2695
2696         int cols = 80;
2697         int rows = 24;
2698
2699         int ox = 1;
2700         int oy = 1;
2701
2702         int wid, hgt, num;
2703
2704         char buf[80];
2705
2706         cptr str;
2707
2708         int val;
2709
2710         XClassHint *ch;
2711
2712         char res_name[20];
2713         char res_class[20];
2714
2715         XSizeHints *sh;
2716 #ifdef USE_XIM
2717         XWMHints *wh;
2718 #endif
2719
2720         /* Window specific font name */
2721         sprintf(buf, "ANGBAND_X11_FONT_%d", i);
2722
2723         /* Check environment for that font */
2724         font = getenv(buf);
2725
2726         /* Check environment for "base" font */
2727         if (!font) font = getenv("ANGBAND_X11_FONT");
2728
2729         /* No environment variables, use default font */
2730         if (!font)
2731         {
2732                 switch (i)
2733                 {
2734                         case 0:
2735                         {
2736                                 font = DEFAULT_X11_FONT_0;
2737                         }
2738                         break;
2739                         case 1:
2740                         {
2741                                 font = DEFAULT_X11_FONT_1;
2742                         }
2743                         break;
2744                         case 2:
2745                         {
2746                                 font = DEFAULT_X11_FONT_2;
2747                         }
2748                         break;
2749                         case 3:
2750                         {
2751                                 font = DEFAULT_X11_FONT_3;
2752                         }
2753                         break;
2754                         case 4:
2755                         {
2756                                 font = DEFAULT_X11_FONT_4;
2757                         }
2758                         break;
2759                         case 5:
2760                         {
2761                                 font = DEFAULT_X11_FONT_5;
2762                         }
2763                         break;
2764                         case 6:
2765                         {
2766                                 font = DEFAULT_X11_FONT_6;
2767                         }
2768                         break;
2769                         case 7:
2770                         {
2771                                 font = DEFAULT_X11_FONT_7;
2772                         }
2773                         break;
2774                         default:
2775                         {
2776                                 font = DEFAULT_X11_FONT;
2777                         }
2778                 }
2779         }
2780
2781 #ifdef _JP
2782         /* Window specific font name */
2783         sprintf(buf, "ANGBAND_X11_KFONT_%d", i);
2784
2785         /* Check environment for that font */
2786         kfont = getenv(buf);
2787
2788         /* Check environment for "base" font */
2789         if (!kfont) kfont = getenv("ANGBAND_X11_KFONT");
2790
2791         /* No environment variables, use default font */
2792         if (!kfont)
2793         {
2794                 switch (i)
2795                 {
2796                         case 0:
2797                         {
2798                                 kfont = DEFAULT_X11_KFONT_0;
2799                         }
2800                         break;
2801                         case 1:
2802                         {
2803                                 kfont = DEFAULT_X11_KFONT_1;
2804                         }
2805                         break;
2806                         case 2:
2807                         {
2808                                 kfont = DEFAULT_X11_KFONT_2;
2809                         }
2810                         break;
2811                         case 3:
2812                         {
2813                                 kfont = DEFAULT_X11_KFONT_3;
2814                         }
2815                         break;
2816                         case 4:
2817                         {
2818                                 kfont = DEFAULT_X11_KFONT_4;
2819                         }
2820                         break;
2821                         case 5:
2822                         {
2823                                 kfont = DEFAULT_X11_KFONT_5;
2824                         }
2825                         break;
2826                         case 6:
2827                         {
2828                                 kfont = DEFAULT_X11_KFONT_6;
2829                         }
2830                         break;
2831                         case 7:
2832                         {
2833                                 kfont = DEFAULT_X11_KFONT_7;
2834                         }
2835                         break;
2836                         default:
2837                         {
2838                                 kfont = DEFAULT_X11_KFONT;
2839                         }
2840                 }
2841         }
2842 #endif
2843         /* Window specific location (x) */
2844         sprintf(buf, "ANGBAND_X11_AT_X_%d", i);
2845         str = getenv(buf);
2846         x = (str != NULL) ? atoi(str) : -1;
2847
2848         /* Window specific location (y) */
2849         sprintf(buf, "ANGBAND_X11_AT_Y_%d", i);
2850         str = getenv(buf);
2851         y = (str != NULL) ? atoi(str) : -1;
2852
2853
2854         /* Window specific cols */
2855         sprintf(buf, "ANGBAND_X11_COLS_%d", i);
2856         str = getenv(buf);
2857         val = (str != NULL) ? atoi(str) : -1;
2858         if (val > 0) cols = val;
2859
2860         /* Window specific rows */
2861         sprintf(buf, "ANGBAND_X11_ROWS_%d", i);
2862         str = getenv(buf);
2863         val = (str != NULL) ? atoi(str) : -1;
2864         if (val > 0) rows = val;
2865
2866         /* Hack the main window must be at least 80x24 */
2867         if (!i)
2868         {
2869                 if (cols < 80) cols = 80;
2870                 if (rows < 24) rows = 24;
2871         }
2872
2873         /* Window specific inner border offset (ox) */
2874         sprintf(buf, "ANGBAND_X11_IBOX_%d", i);
2875         str = getenv(buf);
2876         val = (str != NULL) ? atoi(str) : -1;
2877         if (val > 0) ox = val;
2878
2879         /* Window specific inner border offset (oy) */
2880         sprintf(buf, "ANGBAND_X11_IBOY_%d", i);
2881         str = getenv(buf);
2882         val = (str != NULL) ? atoi(str) : -1;
2883         if (val > 0) oy = val;
2884
2885
2886         /* Prepare the standard font */
2887 #ifdef _JP
2888         MAKE(td->fnt, infofnt);
2889         Infofnt_set(td->fnt);
2890         MAKE(td->kfnt, infofnt);
2891         Infokfnt_set(td->kfnt);
2892         Infofnt_init_data(font, kfont);
2893 #else
2894         MAKE(td->fnt, infofnt);
2895         Infofnt_set(td->fnt);
2896         Infofnt_init_data(font);
2897 #endif
2898
2899
2900         /* Hack -- key buffer size */
2901         num = ((i == 0) ? 1024 : 16);
2902
2903         /* Assume full size windows */
2904         wid = cols * td->fnt->wid + (ox + ox);
2905         hgt = rows * td->fnt->hgt + (oy + oy);
2906
2907         /* Create a top-window */
2908         MAKE(td->win, infowin);
2909         Infowin_set(td->win);
2910         Infowin_init_top(x, y, wid, hgt, 0,
2911                          Metadpy->fg, Metadpy->bg);
2912
2913         /* Ask for certain events */
2914 #if defined(USE_XIM)
2915         Infowin_set_mask(ExposureMask | StructureNotifyMask | KeyPressMask | FocusChangeMask);
2916 #else
2917         Infowin_set_mask(ExposureMask | StructureNotifyMask | KeyPressMask);
2918 #endif
2919
2920         /* Set the window name */
2921         Infowin_set_name(name);
2922
2923         /* Save the inner border */
2924         Infowin->ox = ox;
2925         Infowin->oy = oy;
2926
2927         /* Make Class Hints */
2928         ch = XAllocClassHint();
2929
2930         if (ch == NULL) quit("XAllocClassHint failed");
2931
2932         strcpy(res_name, name);
2933         res_name[0] = FORCELOWER(res_name[0]);
2934         ch->res_name = res_name;
2935
2936         strcpy(res_class, "Angband");
2937         ch->res_class = res_class;
2938
2939         XSetClassHint(Metadpy->dpy, Infowin->win, ch);
2940
2941         /* Make Size Hints */
2942         sh = XAllocSizeHints();
2943
2944         /* Oops */
2945         if (sh == NULL) quit("XAllocSizeHints failed");
2946
2947         /* Main window has a differing minimum size */
2948         if (i == 0)
2949         {
2950                 /* Main window min size is 80x24 */
2951                 sh->flags = PMinSize | PMaxSize;
2952                 sh->min_width = 80 * td->fnt->wid + (ox + ox);
2953                 sh->min_height = 24 * td->fnt->hgt + (oy + oy);
2954                 sh->max_width = 255 * td->fnt->wid + (ox + ox);
2955                 sh->max_height = 255 * td->fnt->hgt + (oy + oy);
2956         }
2957
2958         /* Other windows can be shrunk to 1x1 */
2959         else
2960         {
2961                 /* Other windows */
2962                 sh->flags = PMinSize | PMaxSize;
2963                 sh->min_width = td->fnt->wid + (ox + ox);
2964                 sh->min_height = td->fnt->hgt + (oy + oy);
2965                 sh->max_width = 256 * td->fnt->wid + (ox + ox);
2966                 sh->max_height = 256 * td->fnt->hgt + (oy + oy);
2967         }
2968
2969         /* Resize increment */
2970         sh->flags |= PResizeInc;
2971         sh->width_inc = td->fnt->wid;
2972         sh->height_inc = td->fnt->hgt;
2973
2974         /* Base window size */
2975         sh->flags |= PBaseSize;
2976         sh->base_width = (ox + ox);
2977         sh->base_height = (oy + oy);
2978
2979         /* Use the size hints */
2980         XSetWMNormalHints(Metadpy->dpy, Infowin->win, sh);
2981
2982         /* Map the window */
2983         Infowin_map();
2984
2985 #ifdef USE_XIM
2986         /* Make WM Hints */
2987         wh = XAllocWMHints();
2988         if(wh == NULL) quit("XAllocWMHints failed");
2989         wh->flags = InputHint;
2990         wh->input = True;
2991         XSetWMHints(Metadpy->dpy, Infowin->win, wh);
2992 #endif
2993
2994         /* Move the window to requested location */
2995         if ((x >= 0) && (y >= 0)) Infowin_impell(x, y);
2996
2997
2998         /* Initialize the term */
2999         term_init(t, cols, rows, num);
3000
3001         /* Use a "soft" cursor */
3002         t->soft_cursor = TRUE;
3003
3004         /* Erase with "white space" */
3005         t->attr_blank = TERM_WHITE;
3006         t->char_blank = ' ';
3007
3008         /* Hooks */
3009         t->xtra_hook = Term_xtra_x11;
3010         t->curs_hook = Term_curs_x11;
3011         t->wipe_hook = Term_wipe_x11;
3012         t->text_hook = Term_text_x11;
3013
3014         /* Save the data */
3015         t->data = td;
3016
3017         /* Activate (important) */
3018         Term_activate(t);
3019
3020         /* Success */
3021         return (0);
3022 }
3023
3024
3025 /*
3026  * Initialization function for an "X11" module to Angband
3027  */
3028 errr init_x11(int argc, char *argv[])
3029 {
3030         int i;
3031
3032         cptr dpy_name = "";
3033
3034         int num_term = 3;
3035
3036 #ifdef USE_GRAPHICS
3037
3038         char filename[1024];
3039
3040         int pict_wid = 0;
3041         int pict_hgt = 0;
3042
3043 #ifdef USE_TRANSPARENCY
3044
3045         char *TmpData;
3046 #endif /* USE_TRANSPARENCY */
3047
3048 #endif /* USE_GRAPHICS */
3049
3050
3051         /* Parse args */
3052         for (i = 1; i < argc; i++)
3053         {
3054                 if (prefix(argv[i], "-d"))
3055                 {
3056                         dpy_name = &argv[i][2];
3057                         continue;
3058                 }
3059                 
3060 #ifdef USE_GRAPHICS
3061                 if (prefix(argv[i], "-s"))
3062                 {
3063                         smoothRescaling = FALSE;
3064                         continue;
3065                 }
3066
3067                 if (prefix(argv[i], "-a"))
3068                 {
3069                         arg_graphics = GRAPHICS_ADAM_BOLT;
3070                         continue;
3071                 }
3072
3073                 if (prefix(argv[i], "-o"))
3074                 {
3075                         arg_graphics = GRAPHICS_ORIGINAL;
3076                         continue;
3077                 }
3078
3079                 if (prefix(argv[i], "-b"))
3080                 {
3081                         arg_bigtile = use_bigtile = TRUE;
3082                         continue;
3083                 }
3084 #endif /* USE_GRAPHICS */
3085
3086                 if (prefix(argv[i], "-n"))
3087                 {
3088                         num_term = atoi(&argv[i][2]);
3089                         if (num_term > MAX_TERM_DATA) num_term = MAX_TERM_DATA;
3090                         else if (num_term < 1) num_term = 1;
3091                         continue;
3092                 }
3093
3094                 if (prefix(argv[i], "--"))
3095                 {
3096                         /* Ignore */
3097                         continue;
3098                 }
3099
3100                 plog_fmt("Ignoring option: %s", argv[i]);
3101         }
3102
3103 #ifdef USE_LOCALE
3104         setlocale(LC_ALL, "");
3105 #ifdef DEFAULT_LOCALE
3106         if(!strcmp(setlocale(LC_ALL, NULL), "C")){
3107                 printf("try default locale \"%s\"\n", DEFAULT_LOCALE);
3108                 setlocale(LC_ALL, DEFAULT_LOCALE);
3109         }
3110 #endif
3111         {
3112                 char *current_locale = setlocale(LC_ALL, NULL);
3113 /*              printf("set locale to \"%s\"\n", current_locale); */
3114                 if(!strcmp(current_locale, "C")){
3115                         printf("WARNING: Locale is not supported. Non-english font may be displayed incorrectly.\n");
3116                 }
3117         }
3118
3119         if(!XSupportsLocale()){
3120                 printf("can't support locale in X\n");
3121                 setlocale(LC_ALL, "C");
3122         }
3123 #endif /* USE_LOCALE */
3124
3125
3126         /* Init the Metadpy if possible */
3127         if (Metadpy_init_name(dpy_name)) return (-1);
3128
3129
3130         /* Prepare cursor color */
3131         MAKE(xor, infoclr);
3132         Infoclr_set(xor);
3133         Infoclr_init_ppn(Metadpy->fg, Metadpy->bg, "xor", 0);
3134
3135
3136         /* Prepare normal colors */
3137         for (i = 0; i < 256; ++i)
3138         {
3139                 Pixell pixel;
3140
3141                 MAKE(clr[i], infoclr);
3142
3143                 Infoclr_set(clr[i]);
3144
3145                 /* Acquire Angband colors */
3146                 color_table[i][0] = angband_color_table[i][0];
3147                 color_table[i][1] = angband_color_table[i][1];
3148                 color_table[i][2] = angband_color_table[i][2];
3149                 color_table[i][3] = angband_color_table[i][3];
3150
3151                 /* Default to monochrome */
3152                 pixel = ((i == 0) ? Metadpy->bg : Metadpy->fg);
3153
3154                 /* Handle color */
3155                 if (Metadpy->color)
3156                 {
3157                         /* Create pixel */
3158                         pixel = create_pixel(Metadpy->dpy,
3159                                              color_table[i][1],
3160                                              color_table[i][2],
3161                                              color_table[i][3]);
3162                 }
3163
3164                 /* Initialize the color */
3165                 Infoclr_init_ppn(pixel, Metadpy->bg, "cpy", 0);
3166         }
3167
3168
3169         /* Initialize the windows */
3170         for (i = 0; i < num_term; i++)
3171         {
3172                 term_data *td = &data[i];
3173
3174                 /* Initialize the term_data */
3175                 term_data_init(td, i);
3176
3177                 /* Save global entry */
3178                 angband_term[i] = Term;
3179         }
3180
3181         /* Raise the "Angband" window */
3182         Infowin_set(data[0].win);
3183         Infowin_raise();
3184
3185         /* Activate the "Angband" window screen */
3186         Term_activate(&data[0].t);
3187
3188 #ifdef USE_XIM
3189         {
3190                 char *p;
3191                 p = XSetLocaleModifiers("");
3192                 if(!p || !*p){
3193                         p = XSetLocaleModifiers("@im=");
3194                 }
3195 /*              printf("XMODIFIERS=\"%s\"\n", p); */
3196         }
3197         XRegisterIMInstantiateCallback(Metadpy->dpy, NULL, NULL, NULL, IMInstantiateCallback, NULL);
3198 #endif
3199
3200 #ifdef USE_SOUND
3201         /* initialize sound */
3202         if (arg_sound) init_sound();
3203 #endif
3204
3205 #ifdef USE_GRAPHICS
3206
3207         /* Try graphics */
3208         switch (arg_graphics)
3209         {
3210         case GRAPHICS_ORIGINAL:
3211                 /* Try the "8x8.bmp" file */
3212                 path_build(filename, 1024, ANGBAND_DIR_XTRA, "graf/8x8.bmp");
3213
3214                 /* Use the "8x8.bmp" file if it exists */
3215                 if (0 == fd_close(fd_open(filename, O_RDONLY)))
3216                 {
3217                         /* Use graphics */
3218                         use_graphics = TRUE;
3219
3220                         pict_wid = pict_hgt = 8;
3221
3222                         ANGBAND_GRAF = "old";
3223                         break;
3224                 }
3225                 /* Fall through */
3226
3227         case GRAPHICS_ADAM_BOLT:
3228                 /* Try the "16x16.bmp" file */
3229                 path_build(filename, 1024, ANGBAND_DIR_XTRA, "graf/16x16.bmp");
3230
3231                 /* Use the "16x16.bmp" file if it exists */
3232                 if (0 == fd_close(fd_open(filename, O_RDONLY)))
3233                 {
3234                         /* Use graphics */
3235                         use_graphics = TRUE;
3236
3237                         pict_wid = pict_hgt = 16;
3238
3239                         ANGBAND_GRAF = "new";
3240
3241                         break;
3242                 }
3243         }
3244
3245         /* Load graphics */
3246         if (use_graphics)
3247         {
3248                 Display *dpy = Metadpy->dpy;
3249
3250                 XImage *tiles_raw;
3251
3252                 /* Load the graphical tiles */
3253                 tiles_raw = ReadBMP(dpy, filename);
3254
3255                 /* Initialize the windows */
3256                 for (i = 0; i < num_term; i++)
3257                 {
3258                         term_data *td = &data[i];
3259
3260                         term *t = &td->t;
3261
3262                         /* Graphics hook */
3263                         t->pict_hook = Term_pict_x11;
3264
3265                         /* Use graphics sometimes */
3266                         t->higher_pict = TRUE;
3267
3268                         /* Resize tiles */
3269                         td->tiles =
3270                         ResizeImage(dpy, tiles_raw,
3271                                     pict_wid, pict_hgt,
3272                                     td->fnt->twid, td->fnt->hgt);
3273                 }
3274
3275 #ifdef USE_TRANSPARENCY
3276                 /* Initialize the transparency masks */
3277                 for (i = 0; i < num_term; i++)
3278                 {
3279                         term_data *td = &data[i];
3280                         int ii, jj;
3281                         int depth = DefaultDepth(dpy, DefaultScreen(dpy));
3282                         Visual *visual = DefaultVisual(dpy, DefaultScreen(dpy));
3283                         int total;
3284
3285
3286                         /* Determine total bytes needed for image */
3287                         ii = 1;
3288                         jj = (depth - 1) >> 2;
3289                         while (jj >>= 1) ii <<= 1;
3290                         total = td->fnt->twid * td->fnt->hgt * ii;
3291                         
3292                         
3293                         TmpData = (char *)malloc(total);
3294
3295                         td->TmpImage = XCreateImage(dpy,visual,depth,
3296                                 ZPixmap, 0, TmpData,
3297                                 td->fnt->twid, td->fnt->hgt, 8, 0);
3298
3299                 }
3300 #endif /* USE_TRANSPARENCY */
3301
3302
3303                 /* Free tiles_raw? XXX XXX */
3304         }
3305
3306 #endif /* USE_GRAPHICS */
3307
3308
3309         /* Success */
3310         return (0);
3311 }
3312
3313 #endif /* USE_X11 */
3314