OSDN Git Service

add missing "#ifdef X11LARGETILE"
[jnethack/source.git] / win / X11 / winmap.c
index 28d973e..d732027 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 winmap.c        $NHDT-Date: 1447844616 2015/11/18 11:03:36 $  $NHDT-Branch: master $:$NHDT-Revision: 1.25 $ */
+/* NetHack 3.6 winmap.c        $NHDT-Date: 1455389908 2016/02/13 18:58:28 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.29 $ */
 /* Copyright (c) Dean Luick, 1992                                 */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -25,7 +25,9 @@
 #include <X11/Xaw/Cardinals.h>
 #include <X11/Xaw/Scrollbar.h>
 #include <X11/Xaw/Viewport.h>
+#include <X11/Xaw/Label.h>
 #include <X11/Xatom.h>
+#include <X11/keysym.h>
 
 #ifdef PRESERVE_NO_SYSV
 #ifdef SYSV
@@ -67,6 +69,17 @@ static void FDECL(get_text_gc, (struct xwindow *, Font));
 static void FDECL(get_char_info, (struct xwindow *));
 static void FDECL(display_cursor, (struct xwindow *));
 
+#ifdef X11LARGETILE
+struct pxm_slot_t {
+    int fg;
+    int bg;
+    int age;
+    Pixmap pixmap;
+};
+#define MAX_PXM_SLOTS 100
+    struct pxm_slot_t pxm_slot[MAX_PXM_SLOTS]; 
+#endif
+
 /* Global functions ======================================================= */
 
 void
@@ -102,11 +115,12 @@ int bkglyph UNUSED;
         int color, och;
         unsigned special;
 #ifdef TEXTCOLOR
+        int colordif;
         register unsigned char *co_ptr;
 #endif
 
         /* map glyph to character and color */
-        (void) mapglyph(glyph, &och, &color, &special, x, y);
+        (void) mapglyph(glyph, &och, &color, &special, x, y, 0);
         ch = (uchar) och;
 
         if (special != map_info->tile_map.glyphs[y][x].special) {
@@ -116,24 +130,23 @@ int bkglyph UNUSED;
 
         /* Only update if we need to. */
         ch_ptr = &map_info->text_map.text[y][x];
-
-#ifdef TEXTCOLOR
-        co_ptr = &map_info->text_map.colors[y][x];
-        if (*ch_ptr != ch || *co_ptr != color)
-#else
-        if (*ch_ptr != ch)
-#endif
-        {
+        if (*ch_ptr != ch) {
             *ch_ptr = ch;
+            if (!map_info->is_tile)
+                update_bbox = TRUE;
+        }
 #ifdef TEXTCOLOR
-            if ((special & MG_PET) && iflags.hilite_pet)
-                color += CLR_MAX;
-            if ((special & MG_OBJPILE) && iflags.hilite_pile)
-            *co_ptr = color;
-#endif
+        co_ptr = &map_info->text_map.colors[y][x];
+        colordif = (((special & MG_PET) != 0 && iflags.hilite_pet)
+                    || ((special & MG_OBJPILE) != 0 && iflags.hilite_pile)
+                    || ((special & (MG_DETECT | MG_BW_LAVA)) != 0))
+                      ? CLR_MAX : 0;
+        if (*co_ptr != (uchar) (color + colordif)) {
+            *co_ptr = (uchar) (color + colordif);
             if (!map_info->is_tile)
                 update_bbox = TRUE;
         }
+#endif
     }
 
     if (update_bbox) { /* update row bbox */
@@ -152,8 +165,10 @@ int bkglyph UNUSED;
 /*ARGSUSED*/
 void
 X11_cliparound(x, y)
-int x, y;
+int x UNUSED;
+int y UNUSED;
 {
+    return;
 }
 #endif /* CLIPPING */
 
@@ -167,10 +182,22 @@ int x, y;
  * or just keep it on a per-window basis.
  */
 Pixmap tile_pixmap = None;
+#ifdef X11LARGETILE
+Pixmap tile_clipmask = None;
+GC     tile_gc;
+/*JP #ifdef USE_XPM*/
+XpmImage tile_image;
+/* #endif*/
+
+#define TILE_WIDTH      appResources.tile_width
+#define TILE_HEIGHT     appResources.tile_height
+int     TILE_PER_COL;
+#else
 static int tile_width;
 static int tile_height;
 static int tile_count;
 static XImage *tile_image = 0;
+#endif
 
 /*
  * This structure is used for small bitmaps that are used for annotating
@@ -220,6 +247,7 @@ void
 post_process_tiles()
 {
     Display *dpy = XtDisplay(toplevel);
+#ifndef X11LARGETILE
     unsigned int width, height;
 
     if (tile_image == 0)
@@ -235,8 +263,53 @@ post_process_tiles()
               tile_image, 0, 0, 0, 0, /* src, dest top left */
               width, height);
 
+#ifdef MONITOR_HEAP
+    /* if we let XDestroyImage() handle it, our tracking will be off */
+    if (tile_image->data)
+        free((genericptr_t) tile_image->data), tile_image->data = 0;
+#endif
     XDestroyImage(tile_image); /* data bytes free'd also */
     tile_image = 0;
+#else
+    Colormap cmap;
+# ifdef USE_XPM
+    XpmAttributes attributes;
+# endif
+    Arg args[16];
+    XGCValues val;
+
+# ifdef USE_XPM
+    if(tile_image.data){
+      XtSetArg(args[0], XtNcolormap, &cmap);
+      XtGetValues(toplevel, args, ONE);
+      
+      attributes.valuemask = XpmCloseness | XpmColormap;
+      attributes.colormap = cmap;
+      attributes.closeness = 25000;
+
+      XpmCreatePixmapFromXpmImage(
+                dpy,
+                XtWindow(toplevel),
+                &tile_image,
+                &tile_pixmap,
+                &tile_clipmask,
+                &attributes
+                );
+
+      val.function = GXcopy;
+      val.clip_mask = tile_clipmask;
+
+      tile_gc = XCreateGC(
+                dpy,
+                XtWindow(toplevel),
+                GCFunction | GCClipMask,
+                &val
+                );
+                
+      XpmFreeXpmImage(&tile_image);
+    }
+# endif
+#endif
 
     init_annotation(&pet_annotation, appResources.pet_mark_bitmap,
                     appResources.pet_mark_color);
@@ -296,9 +369,15 @@ struct xwindow *wp;
     attributes.valuemask = XpmCloseness;
     attributes.closeness = 25000;
 
+# ifndef X11LARGETILE
     errorcode = XpmReadFileToImage(dpy, appResources.tile_file, &tile_image,
                                    0, &attributes);
+# else
+    errorcode = XpmReadFileToXpmImage(appResources.tile_file, &tile_image,
+                    NULL);
+# endif
 
+# ifndef X11LARGETILE
     if (errorcode == XpmColorFailed) {
         Sprintf(buf, "Insufficient colors available to load %s.",
                 appResources.tile_file);
@@ -309,6 +388,7 @@ struct xwindow *wp;
         errorcode = XpmReadFileToImage(dpy, appResources.tile_file,
                                        &tile_image, 0, &attributes);
     }
+# endif
 
     if (errorcode != XpmSuccess) {
         if (errorcode == XpmColorFailed) {
@@ -325,6 +405,9 @@ struct xwindow *wp;
         goto tiledone;
     }
 
+# ifdef X11LARGETILE
+        TILE_PER_COL = tile_image.width / TILE_WIDTH;
+# else
     /* assume a fixed number of tiles per row */
     if (tile_image->width % TILES_PER_ROW != 0
         || tile_image->width <= TILES_PER_ROW) {
@@ -348,6 +431,7 @@ struct xwindow *wp;
     }
     tile_width = image_width / TILES_PER_ROW;
     tile_height = image_height / (tile_count / TILES_PER_ROW);
+# endif
 #else /* !USE_XPM */
     /* any less than 16 colours makes tiles useless */
     ddepth = DefaultDepthOfScreen(screen);
@@ -523,8 +607,14 @@ ntiles %ld\n",
     values.graphics_exposures = False;
     values.foreground =
         WhitePixelOfScreen(screen)
+# ifndef X11LARGETILE
         ^ XGetPixel(tile_image, 0,
                     tile_height * glyph2tile[cmap_to_glyph(S_corr)]);
+# else
+        ^ XGetPixel(tile_image, 
+                tile_width*(glyph2tile[cmap_to_glyph(S_corr)]%TILE_PER_COL),
+                tile_height*(glyph2tile[cmap_to_glyph(S_corr)]/TILE_PER_COL));
+# endif
     values.function = GXxor;
     tile_info->white_gc = XtGetGC(wp->w, mask, &values);
 
@@ -544,11 +634,26 @@ tiledone:
         free((genericptr_t) tile_bytes);
     if (colors)
         free((genericptr_t) colors);
+# ifdef X11LARGETILE
+    {
+        int i;
+        for(i = 0; i < MAX_PXM_SLOTS; i++){
+            pxm_slot[i].age = 0;
+            pxm_slot[i].bg = pxm_slot[i].fg = -99;
+            pxm_slot[i].pixmap=0;
+        }
+    }
+# endif
 #endif
 
     if (result) { /* succeeded */
+#ifndef X11LARGETILE
         tile_info->square_height = tile_height;
         tile_info->square_width = tile_width;
+#else
+        tile_info->square_height = TILE_HEIGHT;
+        tile_info->square_width = TILE_WIDTH;
+#endif
         tile_info->square_ascent = 0;
         tile_info->square_lbearing = 0;
         tile_info->image_width = image_width;
@@ -839,7 +944,8 @@ Font font;
     set_color_gc(CLR_BRIGHT_CYAN, XtNbright_cyan);
     set_color_gc(CLR_WHITE, XtNwhite);
 #else
-    set_gc(wp->w, font, XtNforeground, bgpixel, &map_info->text_map.copy_gc,
+    set_gc(wp->w, font, XtNforeground, bgpixel,
+           &map_info->text_map.copy_gc,
            &map_info->text_map.inv_copy_gc);
 #endif
 }
@@ -878,6 +984,7 @@ struct xwindow *wp;
         XClearWindow(XtDisplay(wp->w), XtWindow(wp->w));
         set_map_size(wp, COLNO, ROWNO);
         check_cursor_visibility(wp);
+        highlight_yn(TRUE); /* change fg/bg to match map */
     } else if (wp->prevx != wp->cursx || wp->prevy != wp->cursy) {
         register unsigned int x = wp->prevx, y = wp->prevy;
 
@@ -937,17 +1044,17 @@ struct xwindow *wp;
 
     map_all_stone(map_info);
     (void) memset((genericptr_t) map_info->text_map.text, ' ',
-                  sizeof(map_info->text_map.text));
+                  sizeof map_info->text_map.text);
 #ifdef TEXTCOLOR
     (void) memset((genericptr_t) map_info->text_map.colors, NO_COLOR,
-                  sizeof(map_info->text_map.colors));
+                  sizeof map_info->text_map.colors);
 #endif
 
     /* force a full update */
     (void) memset((genericptr_t) map_info->t_start, (char) 0,
-                  sizeof(map_info->t_start));
+                  sizeof map_info->t_start);
     (void) memset((genericptr_t) map_info->t_stop, (char) COLNO - 1,
-                  sizeof(map_info->t_stop));
+                  sizeof map_info->t_stop);
     display_map_window(wp);
 }
 
@@ -972,8 +1079,8 @@ struct xwindow *wp;
 #ifdef VERBOSE
     printf("Font information:\n");
     printf("fid = %ld, direction = %d\n", fs->fid, fs->direction);
-    printf("first = %d, last = %d\n", fs->min_char_or_byte2,
-           fs->max_char_or_byte2);
+    printf("first = %d, last = %d\n",
+           fs->min_char_or_byte2, fs->max_char_or_byte2);
     printf("all chars exist? %s\n", fs->all_chars_exist ? "yes" : "no");
     printf("min_bounds:lb=%d rb=%d width=%d asc=%d des=%d attr=%d\n",
            fs->min_bounds.lbearing, fs->min_bounds.rbearing,
@@ -984,8 +1091,8 @@ struct xwindow *wp;
            fs->max_bounds.width, fs->max_bounds.ascent,
            fs->max_bounds.descent, fs->max_bounds.attributes);
     printf("per_char = 0x%lx\n", (unsigned long) fs->per_char);
-    printf("Text: (max) width = %d, height = %d\n", text_map->square_width,
-           text_map->square_height);
+    printf("Text: (max) width = %d, height = %d\n",
+           text_map->square_width, text_map->square_height);
 #endif
 
     if (fs->min_bounds.width != fs->max_bounds.width)
@@ -996,9 +1103,9 @@ struct xwindow *wp;
  * keyhit buffer
  */
 #define INBUF_SIZE 64
-int inbuf[INBUF_SIZE];
-int incount = 0;
-int inptr = 0; /* points to valid data */
+static int inbuf[INBUF_SIZE];
+static int incount = 0;
+static int inptr = 0; /* points to valid data */
 
 /*
  * Keyboard and button event handler for map window.
@@ -1017,9 +1124,15 @@ Cardinal *num_params;
     Cardinal in_nparams = (num_params ? *num_params : 0);
     char c;
     char keystring[MAX_KEY_STRING];
+#if 1 /*JP*/
+    KeySym keysym = 0;
+#endif
 
     switch (event->type) {
     case ButtonPress:
+        if (!iflags.wc_mouse_support)
+            return;
+
         button = (XButtonEvent *) event;
 #ifdef VERBOSE_INPUT
         printf("button press\n");
@@ -1059,9 +1172,57 @@ Cardinal *num_params;
              * Assume that mod1 is really the meta key.
              */
             meta = !!(key->state & Mod1Mask);
+#if 0 /*JP*/
             nbytes = XLookupString(key, keystring, MAX_KEY_STRING,
                                    (KeySym *) 0, (XComposeStatus *) 0);
+#else
+            nbytes = XLookupString(key, keystring, MAX_KEY_STRING,
+                                  &keysym, (XComposeStatus *) 0);
+#endif
+        }
+#if 1 /*JP*/
+        /*
+              \8b­\88ø\82É
+         */
+        if(!iflags.num_pad){
+            if(keysym == XK_KP_1 || keysym == XK_KP_End){
+                keystring[0] = 'b';
+                nbytes = 1;
+            }
+            else if(keysym == XK_KP_2 || keysym == XK_KP_Down){
+                keystring[0] = 'j';
+                nbytes = 1;
+            }
+            else if(keysym == XK_KP_3 || keysym == XK_KP_Page_Down){
+                keystring[0] = 'n';
+                nbytes = 1;
+            }
+            else if(keysym == XK_KP_4 || keysym == XK_KP_Left){
+                keystring[0] = 'h';
+                nbytes = 1;
+            }
+            else if(keysym == XK_KP_5 || keysym == XK_KP_Begin){
+                keystring[0] = '.';
+                nbytes = 1;
+            }
+            else if(keysym == XK_KP_6 || keysym == XK_KP_Right){
+                keystring[0] = 'l';
+                nbytes = 1;
+            }
+            else if(keysym == XK_KP_7 || keysym == XK_KP_Home){
+                keystring[0] = 'y';
+                nbytes = 1;
+            }
+            else if(keysym == XK_KP_8 || keysym == XK_KP_Up){
+                keystring[0] = 'k';
+                nbytes = 1;
+            }
+            else if(keysym == XK_KP_9 || keysym == XK_KP_Page_Up){
+                keystring[0] = 'u';
+                nbytes = 1;
+            }
         }
+#endif
     key_events:
         /* Modifier keys return a zero length string when pressed. */
         if (nbytes) {
@@ -1215,7 +1376,7 @@ XtPointer widget_data; /* expose event from Window widget */
 /*
  * Do the actual work of the putting characters onto our X window.  This
  * is called from the expose event routine, the display window (flush)
- * routine, and the display cursor routine.  The later involves inverting
+ * routine, and the display cursor routine.  The last involves inverting
  * the foreground and background colors, which are also inverted when the
  * position's color is above CLR_MAX.
  *
@@ -1243,8 +1404,8 @@ boolean inverted;
     }
 
 #ifdef VERBOSE_UPDATE
-    printf("update: [0x%x] %d %d %d %d\n", (int) wp->w, start_row, stop_row,
-           start_col, stop_col);
+    printf("update: [0x%x] %d %d %d %d\n",
+           (int) wp->w, start_row, stop_row, start_col, stop_col);
 #endif
     win_start_row = start_row;
     win_start_col = start_col;
@@ -1255,8 +1416,18 @@ boolean inverted;
         Display *dpy = XtDisplay(wp->w);
         Screen *screen = DefaultScreenOfDisplay(dpy);
 
+#ifdef X11LARGETILE
+        /* each slots ages */
+        {
+            int i;
+
+            for(i = 0; i < MAX_PXM_SLOTS; i++)
+                pxm_slot[i].age++;
+        }
+#endif
         for (row = start_row; row <= stop_row; row++) {
             for (cur_col = start_col; cur_col <= stop_col; cur_col++) {
+#ifndef X11LARGETILE
                 int glyph = tile_map->glyphs[row][cur_col].glyph;
                 int tile = glyph2tile[glyph];
                 int src_x, src_y;
@@ -1267,8 +1438,91 @@ boolean inverted;
                 src_y = (tile / TILES_PER_ROW) * tile_height;
                 XCopyArea(dpy, tile_pixmap, XtWindow(wp->w),
                           tile_map->black_gc, /* no grapics_expose */
-                          src_x, src_y, tile_width, tile_height, dest_x,
-                          dest_y);
+                          src_x, src_y, tile_width, tile_height,
+                          dest_x, dest_y);
+#else
+                struct rm *lev = &levl[cur_col][row];
+                int glyph = tile_map->glyphs[row][cur_col].glyph;
+                int bg = back_to_glyph(cur_col, row);
+                int tile = 0;
+                int bgtile = 0;
+                int dest_x = 0;
+                int dest_y = 0;
+                int src_x;
+                int src_y;
+                int bgsrc_x;
+                int bgsrc_y;
+                
+                if(tile_pixmap){
+                    if(youmonst.data && (Blind || (viz_array && !cansee(cur_col, row))))
+                        bg = lev->glyph;
+
+                    bgtile = glyph2tile[bg];
+                    tile = glyph2tile[glyph];
+                    dest_x = cur_col * tile_map->square_width;
+                    dest_y = row * tile_map->square_height;
+                    bgsrc_x = (bgtile % TILE_PER_COL) * TILE_WIDTH;
+                    bgsrc_y = (bgtile / TILE_PER_COL) * TILE_HEIGHT;
+                    src_x = (tile % TILE_PER_COL) * TILE_WIDTH;
+                    src_y = (tile / TILE_PER_COL) * TILE_HEIGHT;
+                    {
+                        int i, match;
+                        int maxage = 0;
+                        
+                        if(bgtile != -1){
+                            match = -1;
+                            for(i = 0; i < MAX_PXM_SLOTS; i++){
+                                if(tile == pxm_slot[i].fg && bgtile == pxm_slot[i].bg){
+                                    match = i;
+                                    break;
+                                }
+                            }
+                            if(match == -1){
+                                /* no match found:dispose the oldest slot and compose pixmap */
+                                for(i = 0; i < MAX_PXM_SLOTS; i++)
+                                    if(maxage < pxm_slot[i].age){
+                                        match = i;
+                                        maxage = pxm_slot[i].age;
+                                    }
+                                if(!pxm_slot[match].pixmap) 
+                                    pxm_slot[match].pixmap = XCreatePixmap(
+                                        dpy, XtWindow(toplevel),
+                                        TILE_WIDTH, TILE_HEIGHT, DefaultDepth(dpy, DefaultScreen(dpy)));
+                                XCopyArea(dpy, tile_pixmap, pxm_slot[match].pixmap,
+                                          tile_map->black_gc,
+                                          bgsrc_x, bgsrc_y,
+                                          TILE_WIDTH, TILE_HEIGHT,
+                                          0,0);
+                                
+                                XSetClipOrigin(dpy, tile_gc, 0 - src_x, 0 - src_y);
+                                
+                                XCopyArea(dpy, tile_pixmap, pxm_slot[match].pixmap,
+                                          tile_gc,
+                                          src_x, src_y,
+                                          TILE_WIDTH, TILE_HEIGHT,
+                                          0,0);
+                                pxm_slot[match].fg = tile;
+                                pxm_slot[match].bg = bgtile;
+                            }
+                            /* slot ready */
+                            pxm_slot[match].age = 0;
+                            XCopyArea(dpy, pxm_slot[match].pixmap, XtWindow(wp->w),
+                                      tile_map->black_gc,
+                                      0, 0,
+                                      TILE_WIDTH, TILE_HEIGHT,
+                                      dest_x, dest_y);
+                        }
+                        else{
+                            /* no clip mask */
+                            XCopyArea(dpy, tile_pixmap, XtWindow(wp->w),
+                                      tile_map->black_gc,
+                                      src_x, src_y,
+                                      TILE_WIDTH, TILE_HEIGHT,
+                                      dest_x, dest_y);
+                        }
+                    }
+                }
+#endif /* X11LARGETILE */
 
                 if (glyph_is_pet(glyph) && iflags.hilite_pet) {
                     /* draw pet annotation (a heart) */
@@ -1324,7 +1578,7 @@ boolean inverted;
         struct text_map_info_t *text_map = &map_info->text_map;
 
 #ifdef TEXTCOLOR
-        if (iflags.use_color) {
+        {
             register char *c_ptr;
             char *t_ptr;
             int cur_col, color, win_ystart;
@@ -1351,8 +1605,13 @@ boolean inverted;
                     }
 
                     XDrawImageString(XtDisplay(wp->w), XtWindow(wp->w),
-                                     cur_inv ? text_map->inv_color_gcs[color]
-                                             : text_map->color_gcs[color],
+                                     iflags.use_color
+                                        ? (cur_inv
+                                           ? text_map->inv_color_gcs[color]
+                                           : text_map->color_gcs[color])
+                                        : (cur_inv
+                                           ? text_map->inv_copy_gc
+                                           : text_map->copy_gc),
                                      text_map->square_lbearing
                                          + (text_map->square_width * cur_col),
                                      win_ystart, t_ptr, count);
@@ -1362,8 +1621,8 @@ boolean inverted;
                     cur_col += count;
                 } /* col loop */
             }     /* row loop */
-        } else
-#endif /* TEXTCOLOR */
+        }
+#else   /* !TEXTCOLOR */
         {
             int win_row, win_xstart;
 
@@ -1385,6 +1644,7 @@ boolean inverted;
                                  count);
             }
         }
+#endif  /* ?TEXTCOLOR */
     }
 }
 
@@ -1406,10 +1666,8 @@ Dimension cols, rows;
     }
 
     num_args = 0;
-    XtSetArg(args[num_args], XtNwidth, wp->pixel_width);
-    num_args++;
-    XtSetArg(args[num_args], XtNheight, wp->pixel_height);
-    num_args++;
+    XtSetArg(args[num_args], XtNwidth, wp->pixel_width); num_args++;
+    XtSetArg(args[num_args], XtNheight, wp->pixel_height); num_args++;
     XtSetValues(wp->w, args, num_args);
 }
 
@@ -1420,10 +1678,10 @@ struct xwindow *wp;
     struct map_info_t *map_info = wp->map_information;
     struct text_map_info_t *text_map = &map_info->text_map;
 
-    (void) memset((genericptr_t) text_map->text, ' ', sizeof(text_map->text));
+    (void) memset((genericptr_t) text_map->text, ' ', sizeof text_map->text);
 #ifdef TEXTCOLOR
     (void) memset((genericptr_t) text_map->colors, NO_COLOR,
-                  sizeof(text_map->colors));
+                  sizeof text_map->colors);
 #endif
 
     get_char_info(wp);
@@ -1466,7 +1724,11 @@ Widget parent;
         XtSetArg(args[num_args], XtNinput, False);
         num_args++;
 
+#if 0 /*JP*/
         wp->popup = parent = XtCreatePopupShell("nethack",
+#else
+        wp->popup = parent = XtCreatePopupShell("jnethack",
+#endif
                                                 topLevelShellWidgetClass,
                                                 toplevel, args, num_args);
         /*
@@ -1610,6 +1872,11 @@ struct xwindow *wp;
                          (XtPointer) 0);
     else
         wp->type = NHW_NONE; /* allow re-use */
+
+    /* when map goes away, presumably we're exiting, so get rid of the
+       cached extended commands menu (if we aren't actually exiting, it
+       will get recreated if needed again) */
+    release_extended_cmds();
 }
 
 boolean exit_x_event; /* exit condition for the event loop */