1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
/* Copyright (C) 2000-2004 Damir Zucic */
/*=============================================================================
make_pixmap.c
Purpose:
Make pixmap from an array of strings. Array is obtained from the
file which is included in calling function; MakePixmap_ receives
pointer to char pointer. Xpm library is not used here. Xpm is quite
good, but raw Xlib was chosen to make the whole garlic package as
portable as possible. Though many systems have Xpm library, there
are still some which don't. Pixmap should be hard-coded (included)
in calling function.
Input:
(1) Pointer to WindowS structure, where some output data will be
stored.
(2) Pointer to GUIS structure.
(3) Pointer to char pointer, with pixmap data. There are no special
checks: if pixmap file is bad, core dump may be expected. Check
each pixmap with a program like cxpm. Up to 256 color allowed.
pixmap data. It has file scope. This file is not checked; if
it is bad, core dump may be expected. If icon pixmap is changed
it may be checked with cxpm program. Up to 256 colors allowed.
Output:
(1) Pixmap created.
(2) Pixmap dimensions, number of colors and pixmap ID added to
WindowDataS structure. Note that pixmap width and height are
treated as window dimensions! Thus, window dimensions are set
too in this function.
(3) Pixmap flag set.
(4) Return value.
Return value:
(1) Positive on success.
(2) Negative on failure.
========includes:============================================================*/
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include "defines.h"
#include "typedefs.h"
/*======function prototypes:=================================================*/
void ErrorMessage_ (char *, char *, char *,
char *, char *, char *, char *);
void RGBSFromXColor_ (RGBS *, XColor *);
unsigned long PixelFromRGBS_ (RGBS *, GUIS *);
/*======make pixmap from an array of strings, version 1:=====================*/
int MakePixmap_ (WindowS *winSP, GUIS *guiSP, char **dataPP)
{
unsigned int width, height, colorsN;
Status status;
XColor colorS;
RGBS rgbS;
unsigned long black_colorID;
Pixmap pixmapID;
int i, j;
char line_copyA[STRINGSIZE];
int n;
char *P, *P1;
unsigned long pixel;
unsigned long colorIDA[256];
int offset;
/* Extract pixmap dimensions and number of colors: */
if (sscanf (*dataPP, "%u %u %u", &width, &height, &colorsN) != 3)
{
ErrorMessage_ ("garlic", "MakePixmap_", "",
"Failed to extract data from pixmap header!\n", "", "", "");
return -1;
}
/* Check the number of colors: */
if (colorsN > 256)
{
ErrorMessage_ ("garlic", "MakePixmap_", "",
"Number of colors in pixmap limited to 256!\n", "", "", "");
return -2;
}
/* Copy values: */
winSP->width = width;
winSP->height = height;
winSP->colorsN = colorsN;
/* Prepare the black color (replacement for unrecognized colors): */
status = XParseColor (guiSP->displaySP, guiSP->colormapID, "black", &colorS);
if (status)
{
RGBSFromXColor_ (&rgbS, &colorS);
black_colorID = PixelFromRGBS_ (&rgbS, guiSP);
}
else
{
ErrorMessage_ ("garlic", "MakePixmap_", "",
"Unable to parse black color!\n", "", "", "");
return -3;
}
/* Create pixmap: */
pixmapID = XCreatePixmap (guiSP->displaySP,
DefaultRootWindow (guiSP->displaySP),
width, height, guiSP->depth);
winSP->pixmapID = pixmapID;
winSP->pixmapF = 1;
/* Parse colors: */
/* (Note: be sure that pixmap is good, no check is done here!) */
for (i = 1; i < (int) colorsN + 1; i++)
{
/** Copy the i-th line: **/
strncpy (line_copyA, *(dataPP + i), STRINGSIZE - 1);
line_copyA[STRINGSIZE - 1] = '\0';
/** The first token is the color array index: **/
n = line_copyA[0];
/** Skip the first character and take one token; **/
/** it should be letter 'c' or 's' - ignore it: **/
P1 = line_copyA + 1;
P = strtok (P1, " \t");
/** The next token is color specification; **/
P = strtok (NULL, " \t\"");
/** This token is expected to specify some color; parse it: **/
status = XParseColor (guiSP->displaySP, guiSP->colormapID, P, &colorS);
if (status)
{
RGBSFromXColor_ (&rgbS, &colorS);
pixel = PixelFromRGBS_ (&rgbS, guiSP);
}
else pixel = black_colorID;
colorIDA[n] = pixel;
}
/* Parse pixels and draw pixmap using default graphics context: */
offset = winSP->colorsN + 1;
for (j = 0; j < (int) height; j++)
{
offset = j + colorsN + 1;
for (i = 0; i < (int) width; i++)
{
P = *(dataPP + offset) + i;
n = *P;
XSetForeground (guiSP->displaySP,
guiSP->theGCA[0],
colorIDA[n]);
XDrawPoint (guiSP->displaySP, pixmapID,
guiSP->theGCA[0],
i, j);
}
}
return 1;
}
/*===========================================================================*/
|