OSDN Git Service

[fix] #41478 階段を上ったときにクラッシュ
[hengband/hengband.git] / src / maid-x11.c
index c3d301f..1ec8cb2 100644 (file)
@@ -1,4 +1,4 @@
-/* File: maid-x11.c */
+/* File: maid-x11.c */
 
 /*
  * Copyright (c) 1997 Ben Harrison, and others
@@ -8,8 +8,10 @@
  * are included in all such copies.
  */
 
-#include <math.h>
+#ifdef USE_X11
 
+#include <math.h>
+#include "main/x11-gamma-builder.h"
 
 /*
  * This file defines some "XImage" manipulation functions for X11.
   ((unsigned)(keysym) >= 0xFF00)
 
 
-#ifdef SUPPORT_GAMMA
 static bool gamma_table_ready = FALSE;
-#endif /* SUPPORT_GAMMA */
+static int gamma_val = 0;
 
 
 /*
  * Hack -- Convert an RGB value to an X11 Pixel, or die.
  */
+#ifdef USE_XFT
+static XftColor create_pixel(Display *dpy, byte red, byte green, byte blue)
+#else
 static unsigned long create_pixel(Display *dpy, byte red, byte green, byte blue)
+#endif
 {
        Colormap cmap = DefaultColormapOfScreen(DefaultScreenOfDisplay(dpy));
        XColor xcolour;
-
-#ifdef SUPPORT_GAMMA
-
-       int gamma = 0;
-
        if (!gamma_table_ready)
        {
-               cptr str = getenv("ANGBAND_X11_GAMMA");
-               if (str != NULL) gamma = atoi(str);
+               concptr str = getenv("ANGBAND_X11_GAMMA");
+               if (str != NULL) gamma_val = atoi(str);
                
                gamma_table_ready = TRUE;
                
                /* Only need to build the table if gamma exists */
-               if (gamma) build_gamma_table(gamma);
+               if (gamma_val) build_gamma_table(gamma_val);
        }
 
        /* Hack -- Gamma Correction */
-       if (gamma > 0)
+       if (gamma_val > 0)
        {
                red = gamma_table[red];
                green = gamma_table[green];
                blue = gamma_table[blue];
        }
 
-#endif /* SUPPORT_GAMMA */
-
        /* Build the color */
        
        xcolour.red = red * 255;
@@ -111,30 +109,39 @@ static unsigned long create_pixel(Display *dpy, byte red, byte green, byte blue)
        xcolour.blue = blue * 255;
        xcolour.flags = DoRed | DoGreen | DoBlue;
 
+#ifdef USE_XFT
+       XftColor color;
+       XRenderColor xcol;
+       xcol.red = xcolour.red;
+       xcol.green = xcolour.green;
+       xcol.blue = xcolour.blue;
+       if (!XftColorAllocValue(dpy, DefaultVisual(dpy, 0), cmap, &xcol, &color))
+       {
+               quit_fmt("Couldn't allocate bitmap color '#%02x%02x%02x'\n",
+                        red, green, blue);
+       }
+
+       return color;
+#else
        /* Attempt to Allocate the Parsed color */
        if (!(XAllocColor(dpy, cmap, &xcolour)))
        {
                quit_fmt("Couldn't allocate bitmap color '#%02x%02x%02x'\n",
-                        red, green, blue);
+                        red, green, blue);
        }
 
        return (xcolour.pixel);
+#endif
 }
 
 
-
-#ifdef USE_GRAPHICS
+#ifndef USE_XFT
 
 /*
  * The Win32 "BITMAPFILEHEADER" type.
- *
- * Note the "bfAlign" field, which is a complete hack to ensure that the
- * "u32b" fields in the structure get aligned.  Thus, when reading this
- * header from the file, we must be careful to skip this field.
  */
 typedef struct BITMAPFILEHEADER
 {
-       u16b bfAlign;    /* HATE this */
        u16b bfType;
        u32b bfSize;
        u16b bfReserved1;
@@ -170,6 +177,34 @@ typedef struct RGBQUAD
 } RGBQUAD;
 
 
+/*** Helper functions for system independent file loading. ***/
+
+static byte get_byte(FILE *fff)
+{
+       /* Get a character, and return it */
+       return (getc(fff) & 0xFF);
+}
+
+static void rd_byte(FILE *fff, byte *ip)
+{
+       *ip = get_byte(fff);
+}
+
+static void rd_u16b(FILE *fff, u16b *ip)
+{
+       (*ip) = get_byte(fff);
+       (*ip) |= ((u16b)(get_byte(fff)) << 8);
+}
+
+static void rd_u32b(FILE *fff, u32b *ip)
+{
+       (*ip) = get_byte(fff);
+       (*ip) |= ((u32b)(get_byte(fff)) << 8);
+       (*ip) |= ((u32b)(get_byte(fff)) << 16);
+       (*ip) |= ((u32b)(get_byte(fff)) << 24);
+}
+
+
 /*
  * Read a Win32 BMP file.
  *
@@ -189,8 +224,6 @@ static XImage *ReadBMP(Display *dpy, char *Name)
        BITMAPFILEHEADER fileheader;
        BITMAPINFOHEADER infoheader;
 
-       vptr fileheaderhack = (vptr)((char *)(&fileheader) + 2);
-
        XImage *Res = NULL;
 
        char *Data;
@@ -216,10 +249,24 @@ static XImage *ReadBMP(Display *dpy, char *Name)
        }
 
        /* Read the "BITMAPFILEHEADER" */
-       fread(fileheaderhack, sizeof(fileheader) - 2, 1, f);
+       rd_u16b(f, &(fileheader.bfType));
+       rd_u32b(f, &(fileheader.bfSize));
+       rd_u16b(f, &(fileheader.bfReserved1));
+       rd_u16b(f, &(fileheader.bfReserved2));
+       rd_u32b(f, &(fileheader.bfOffBits));
 
        /* Read the "BITMAPINFOHEADER" */
-       fread(&infoheader, sizeof(infoheader), 1, f);
+       rd_u32b(f, &(infoheader.biSize));
+       rd_u32b(f, &(infoheader.biWidth));
+       rd_u32b(f, &(infoheader.biHeight));
+       rd_u16b(f, &(infoheader.biPlanes));
+       rd_u16b(f, &(infoheader.biBitCount));
+       rd_u32b(f, &(infoheader.biCompresion));
+       rd_u32b(f, &(infoheader.biSizeImage));
+       rd_u32b(f, &(infoheader.biXPelsPerMeter));
+       rd_u32b(f, &(infoheader.biYPelsPerMeter));
+       rd_u32b(f, &(infoheader.biClrUsed));
+       rd_u32b(f, &(infoheader.biClrImportand));
 
        /* Verify the header */
        if (feof(f) ||
@@ -239,7 +286,11 @@ static XImage *ReadBMP(Display *dpy, char *Name)
        {
                RGBQUAD clrg;
 
-               fread(&clrg, 4, 1, f);
+               /* Read an "RGBQUAD" */
+               rd_byte(f, &(clrg.b));
+               rd_byte(f, &(clrg.g));
+               rd_byte(f, &(clrg.r));
+               rd_byte(f, &(clrg.filler));
                
                /* Analyze the color */
                clr_pixels[i] = create_pixel(dpy, clrg.r, clrg.g, clrg.b);
@@ -255,8 +306,8 @@ static XImage *ReadBMP(Display *dpy, char *Name)
        C_MAKE(Data, total, char);
 
        Res = XCreateImage(dpy, visual, depth, ZPixmap, 0 /*offset*/,
-                          Data, infoheader.biWidth, infoheader.biHeight,
-                          8 /*bitmap_pad*/, 0 /*bytes_per_line*/);
+                          Data, infoheader.biWidth, infoheader.biHeight,
+                          8 /*bitmap_pad*/, 0 /*bytes_per_line*/);
 
        /* Failure */
        if (Res == NULL)
@@ -301,7 +352,7 @@ static XImage *ReadBMP(Display *dpy, char *Name)
                        {
                                /* Technically 1 bit is legal too */
                                quit_fmt("Illegal biBitCount %d in %s",
-                                        infoheader.biBitCount, Name);
+                                        infoheader.biBitCount, Name);
                        }
                }
        }
@@ -344,8 +395,8 @@ static bool smoothRescaling = TRUE;
  * redScan, greenScan and blueScan must be sufficiently sized
  */
 static void GetScaledRow(XImage *Im, int x, int y, int iw, int ow,
-                         unsigned long *redScan, unsigned long *greenScan,
-                         unsigned long *blueScan)
+                        unsigned long *redScan, unsigned long *greenScan,
+                        unsigned long *blueScan)
 {
        int xi, si, sifrac, ci, cifrac, addWhole, addFrac;
        unsigned long pix;
@@ -486,8 +537,8 @@ static void GetScaledRow(XImage *Im, int x, int y, int iw, int ow,
  * are divided first.
  */
 static void PutRGBScan(XImage *Im, int x, int y, int w, int div,
-                       unsigned long *redScan, unsigned long *greenScan,
-                       unsigned long *blueScan)
+                      unsigned long *redScan, unsigned long *greenScan,
+                      unsigned long *blueScan)
 {
        int xi;
        unsigned long pix;
@@ -512,7 +563,7 @@ static void PutRGBScan(XImage *Im, int x, int y, int w, int div,
  * vertical directions (eg. shrink horizontal, grow vertical).
  */
 static void ScaleIcon(XImage *ImIn, XImage *ImOut,
-                     int x1, int y1, int x2, int y2,
+                     int x1, int y1, int x2, int y2,
                      int ix, int iy, int ox, int oy)
 {
        int div;
@@ -545,9 +596,9 @@ static void ScaleIcon(XImage *ImIn, XImage *ImOut,
                for (yi = 0; yi < oy; yi++)
                {
                        GetScaledRow(ImIn, x1, y1 + yi, ix, ox,
-                                    tempRed, tempGreen, tempBlue);
+                                    tempRed, tempGreen, tempBlue);
                        PutRGBScan(ImOut, x2, y2 + yi, ox, div,
-                                  tempRed, tempGreen, tempBlue);
+                                  tempRed, tempGreen, tempBlue);
                }
        }
        else if (iy < oy)
@@ -577,7 +628,7 @@ static void ScaleIcon(XImage *ImIn, XImage *ImOut,
                                {
                                        /* only get next row if in same icon */
                                        GetScaledRow(ImIn, x1, si + 1, ix, ox,
-                                                    nextRed, nextGreen, nextBlue);
+                                                    nextRed, nextGreen, nextBlue);
                                }
                        }
 
@@ -586,16 +637,16 @@ static void ScaleIcon(XImage *ImIn, XImage *ImOut,
                        for (xi = 0; xi < ox; xi++)
                        {
                                tempRed[xi] = (prevRed[xi] * (oy - sifrac) +
-                                              nextRed[xi] * sifrac);
+                                              nextRed[xi] * sifrac);
                                tempGreen[xi] = (prevGreen[xi] * (oy - sifrac) +
-                                                nextGreen[xi] * sifrac);
+                                                nextGreen[xi] * sifrac);
                                tempBlue[xi] = (prevBlue[xi] * (oy - sifrac) +
-                                               nextBlue[xi] * sifrac);
+                                               nextBlue[xi] * sifrac);
                        }
 
                        /* write row to output image: */
                        PutRGBScan(ImOut, x2, y2 + yi, ox, div,
-                                  tempRed, tempGreen, tempBlue);
+                                  tempRed, tempGreen, tempBlue);
 
                        /* advance sampling position: */
                        sifrac += iy;
@@ -646,7 +697,7 @@ static void ScaleIcon(XImage *ImIn, XImage *ImOut,
                        while (si < ci)
                        {
                                GetScaledRow(ImIn, x1, si, ix, ox,
-                                            nextRed, nextGreen, nextBlue);
+                                            nextRed, nextGreen, nextBlue);
                                for (xi = 0; xi < ox; xi++)
                                {
                                        tempRed[xi]   += nextRed[xi]   * oy;
@@ -660,7 +711,7 @@ static void ScaleIcon(XImage *ImIn, XImage *ImOut,
                        {
                                /* only get next row if still in icon: */
                                GetScaledRow(ImIn, x1, si, ix, ox,
-                                            nextRed, nextGreen, nextBlue);
+                                            nextRed, nextGreen, nextBlue);
                        }
                        sifrac = cifrac;
                        for (xi = 0; xi < ox; xi++)
@@ -671,7 +722,7 @@ static void ScaleIcon(XImage *ImIn, XImage *ImOut,
                        }
                        /* write row to output image: */
                        PutRGBScan(ImOut, x2, y2 + yi, ox, div,
-                                  tempRed, tempGreen, tempBlue);
+                                  tempRed, tempGreen, tempBlue);
                }
        }
 }
@@ -679,7 +730,7 @@ static void ScaleIcon(XImage *ImIn, XImage *ImOut,
 
 
 static XImage *ResizeImageSmooth(Display *dpy, XImage *Im,
-                                 int ix, int iy, int ox, int oy)
+                                int ix, int iy, int ox, int oy)
 {
        Visual *visual = DefaultVisual(dpy, DefaultScreen(dpy));
 
@@ -699,8 +750,8 @@ static XImage *ResizeImageSmooth(Display *dpy, XImage *Im,
        Data = (char *)malloc(width2 * height2 * Im->bits_per_pixel / 8);
 
        Tmp = XCreateImage(dpy, visual,
-                          Im->depth, ZPixmap, 0, Data, width2, height2,
-                          32, 0);
+                          Im->depth, ZPixmap, 0, Data, width2, height2,
+                          32, 0);
 
        /* compute values for decomposing pixel into color values: */
        redMask = Im->red_mask;
@@ -731,7 +782,7 @@ static XImage *ResizeImageSmooth(Display *dpy, XImage *Im,
                for (x1 = 0, x2 = 0; (x1 < width1) && (x2 < width2); x1 += ix, x2 += ox)
                {
                        ScaleIcon(Im, Tmp, x1, y1, x2, y2,
-                                 ix, iy, ox, oy);
+                                 ix, iy, ox, oy);
                }
        }
 
@@ -745,7 +796,7 @@ static XImage *ResizeImageSmooth(Display *dpy, XImage *Im,
  * Also appears in "main-xaw.c".
  */
 static XImage *ResizeImage(Display *dpy, XImage *Im,
-                           int ix, int iy, int ox, int oy)
+                          int ix, int iy, int ox, int oy)
 {
        Visual *visual = DefaultVisual(dpy, DefaultScreen(dpy));
 
@@ -773,8 +824,8 @@ static XImage *ResizeImage(Display *dpy, XImage *Im,
        Data = (char *)malloc(width2 * height2 * Im->bits_per_pixel / 8);
 
        Tmp = XCreateImage(dpy, visual,
-                          Im->depth, ZPixmap, 0, Data, width2, height2,
-                          32, 0);
+                          Im->depth, ZPixmap, 0, Data, width2, height2,
+                          32, 0);
 
        if (ix > ox)
        {
@@ -839,6 +890,6 @@ static XImage *ResizeImage(Display *dpy, XImage *Im,
        return Tmp;
 }
 
-#endif /* USE_GRAPHICS */
-
+#endif /* !USE_XFT */
 
+#endif /* USE_X11 */