608
+ − 1 /* Routines shared between window-system backends for glyph objects.
563
+ − 2 Copyright (C) 1993, 1994 Free Software Foundation, Inc.
+ − 3 Copyright (C) 1995 Board of Trustees, University of Illinois.
+ − 4 Copyright (C) 1995 Tinker Systems
771
+ − 5 Copyright (C) 1995, 1996, 2001 Ben Wing
563
+ − 6 Copyright (C) 1995 Sun Microsystems
+ − 7 Copyright (C) 1998, 1999, 2000 Andy Piper.
+ − 8
+ − 9 This file is part of XEmacs.
+ − 10
+ − 11 XEmacs is free software; you can redistribute it and/or modify it
+ − 12 under the terms of the GNU General Public License as published by the
+ − 13 Free Software Foundation; either version 2, or (at your option) any
+ − 14 later version.
+ − 15
+ − 16 XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ − 17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ − 18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ − 19 for more details.
+ − 20
+ − 21 You should have received a copy of the GNU General Public License
+ − 22 along with XEmacs; see the file COPYING. If not, write to
+ − 23 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ − 24 Boston, MA 02111-1307, USA. */
+ − 25
+ − 26 /* Synched up with: Not in FSF. */
+ − 27
+ − 28 /* taken from glyphs-*.c
+ − 29 HINT HINT HINT Bill Perry: Please put code here and avoid massive
+ − 30 duplication in *-gtk.c!!! */
+ − 31
+ − 32 #include <config.h>
+ − 33 #include "lisp.h"
+ − 34
800
+ − 35 #include "buffer.h"
563
+ − 36 #include "elhash.h"
800
+ − 37 #include "faces.h"
563
+ − 38 #include "frame.h"
800
+ − 39 #include "glyphs.h"
+ − 40 #include "imgproc.h"
563
+ − 41 #include "insdel.h"
800
+ − 42 #include "lstream.h"
563
+ − 43 #include "opaque.h"
+ − 44 #include "sysdep.h"
800
+ − 45 #include "window.h"
+ − 46
563
+ − 47 #include "sysfile.h"
+ − 48
+ − 49 Lisp_Object Q_resource_type, Q_resource_id;
+ − 50
+ − 51 void
+ − 52 shared_resource_validate (Lisp_Object instantiator)
+ − 53 {
+ − 54 if ((NILP (find_keyword_in_vector (instantiator, Q_file))
+ − 55 &&
+ − 56 NILP (find_keyword_in_vector (instantiator, Q_resource_id)))
+ − 57 ||
+ − 58 NILP (find_keyword_in_vector (instantiator, Q_resource_type)))
+ − 59 sferror ("Must supply :file, :resource-id and :resource-type",
+ − 60 instantiator);
+ − 61 }
+ − 62
+ − 63
+ − 64 Lisp_Object
+ − 65 shared_resource_normalize (Lisp_Object inst, Lisp_Object console_type,
+ − 66 Lisp_Object dest_mask, Lisp_Object tag)
+ − 67 {
+ − 68 /* This function can call lisp */
+ − 69 Lisp_Object file = Qnil;
+ − 70 struct gcpro gcpro1, gcpro2;
+ − 71 Lisp_Object alist = Qnil;
+ − 72
+ − 73 GCPRO2 (file, alist);
+ − 74
+ − 75 file = potential_pixmap_file_instantiator (inst, Q_file, Q_data,
+ − 76 console_type);
+ − 77
+ − 78 if (CONSP (file)) /* failure locating filename */
+ − 79 signal_double_image_error ("Opening pixmap file",
+ − 80 "no such file or directory",
+ − 81 Fcar (file));
+ − 82
+ − 83 if (NILP (file)) /* no conversion necessary */
+ − 84 RETURN_UNGCPRO (inst);
+ − 85
+ − 86 alist = tagged_vector_to_alist (inst);
+ − 87
+ − 88 {
+ − 89 alist = remassq_no_quit (Q_file, alist);
+ − 90 alist = Fcons (Fcons (Q_file, file), alist);
+ − 91 }
+ − 92
+ − 93 {
+ − 94 Lisp_Object result = alist_to_tagged_vector (tag, alist);
+ − 95 free_alist (alist);
+ − 96 RETURN_UNGCPRO (result);
+ − 97 }
+ − 98 }
+ − 99
608
+ − 100 /* Originally from xmu.c, but is now shared across X11, GTK, and MSW. */
+ − 101 /*
+ − 102 * Based on an optimized version provided by Jim Becker, August 5, 1988.
+ − 103 */
+ − 104
+ − 105
+ − 106 #ifndef BitmapSuccess
+ − 107 #define BitmapSuccess 0
+ − 108 #define BitmapOpenFailed 1
+ − 109 #define BitmapFileInvalid 2
+ − 110 #define BitmapNoMemory 3
+ − 111 #endif
+ − 112
+ − 113 #define MAX_SIZE 255
+ − 114
+ − 115 /* shared data for the image read/parse logic */
+ − 116 static short hexTable[256]; /* conversion value */
+ − 117 static int hex_initialized; /* easier to fill in at run time */
+ − 118
+ − 119
+ − 120 /*
+ − 121 * Table index for the hex values. Initialized once, first time.
+ − 122 * Used for translation value or delimiter significance lookup.
+ − 123 */
+ − 124 static void initHexTable (void)
+ − 125 {
+ − 126 /*
+ − 127 * We build the table at run time for several reasons:
+ − 128 *
+ − 129 * 1. portable to non-ASCII machines.
+ − 130 * 2. still reentrant since we set the init flag after setting table.
+ − 131 * 3. easier to extend.
+ − 132 * 4. less prone to bugs.
+ − 133 */
+ − 134 hexTable['0'] = 0; hexTable['1'] = 1;
+ − 135 hexTable['2'] = 2; hexTable['3'] = 3;
+ − 136 hexTable['4'] = 4; hexTable['5'] = 5;
+ − 137 hexTable['6'] = 6; hexTable['7'] = 7;
+ − 138 hexTable['8'] = 8; hexTable['9'] = 9;
+ − 139 hexTable['A'] = 10; hexTable['B'] = 11;
+ − 140 hexTable['C'] = 12; hexTable['D'] = 13;
+ − 141 hexTable['E'] = 14; hexTable['F'] = 15;
+ − 142 hexTable['a'] = 10; hexTable['b'] = 11;
+ − 143 hexTable['c'] = 12; hexTable['d'] = 13;
+ − 144 hexTable['e'] = 14; hexTable['f'] = 15;
+ − 145
+ − 146 /* delimiters of significance are flagged w/ negative value */
+ − 147 hexTable[' '] = -1; hexTable[','] = -1;
+ − 148 hexTable['}'] = -1; hexTable['\n'] = -1;
+ − 149 hexTable['\t'] = -1;
+ − 150
+ − 151 hex_initialized = 1;
+ − 152 }
+ − 153
+ − 154 /*
+ − 155 * read next hex value in the input stream, return -1 if EOF
+ − 156 */
+ − 157 static int NextInt (FILE *fstream)
+ − 158 {
+ − 159 int ch;
+ − 160 int value = 0;
+ − 161 int gotone = 0;
+ − 162 int done = 0;
+ − 163
+ − 164 /* loop, accumulate hex value until find delimiter */
+ − 165 /* skip any initial delimiters found in read stream */
+ − 166
+ − 167 while (!done) {
+ − 168 ch = getc(fstream);
+ − 169 if (ch == EOF) {
+ − 170 value = -1;
+ − 171 done++;
+ − 172 } else {
+ − 173 /* trim high bits, check type and accumulate */
+ − 174 ch &= 0xff;
+ − 175 if (isascii(ch) && isxdigit(ch)) {
+ − 176 value = (value << 4) + hexTable[ch];
+ − 177 gotone++;
+ − 178 } else if ((hexTable[ch]) < 0 && gotone)
+ − 179 done++;
+ − 180 }
+ − 181 }
+ − 182 return value;
+ − 183 }
+ − 184
+ − 185
+ − 186 /*
+ − 187 * The data returned by the following routine is always in left-most byte
+ − 188 * first and left-most bit first. If it doesn't return BitmapSuccess then
+ − 189 * its arguments won't have been touched. This routine should look as much
+ − 190 * like the Xlib routine XReadBitmapfile as possible.
+ − 191 */
611
+ − 192 static int
647
+ − 193 read_bitmap_data (FILE *fstream, int *width, int *height, UChar_Binary **datap,
611
+ − 194 int *x_hot, int *y_hot)
608
+ − 195 {
+ − 196 UChar_Binary *data = NULL; /* working variable */
647
+ − 197 Char_ASCII line[MAX_SIZE]; /* input line from file */
608
+ − 198 int size; /* number of bytes of data */
647
+ − 199 Char_ASCII name_and_type[MAX_SIZE]; /* an input line */
+ − 200 Char_ASCII *type; /* for parsing */
608
+ − 201 int value; /* from an input line */
+ − 202 int version10p; /* boolean, old format */
+ − 203 int padding; /* to handle alignment */
+ − 204 int bytes_per_line; /* per scanline of data */
647
+ − 205 int ww = 0; /* width */
+ − 206 int hh = 0; /* height */
608
+ − 207 int hx = -1; /* x hotspot */
+ − 208 int hy = -1; /* y hotspot */
+ − 209
+ − 210 #ifndef Xmalloc
+ − 211 #define Xmalloc(size) malloc(size)
+ − 212 #endif
+ − 213
+ − 214 /* first time initialization */
+ − 215 if (!hex_initialized) initHexTable();
+ − 216
+ − 217 /* error cleanup and return macro */
+ − 218 #define RETURN(code) { if (data) free (data); return code; }
+ − 219
+ − 220 while (fgets(line, MAX_SIZE, fstream)) {
+ − 221 if (strlen(line) == MAX_SIZE-1) {
+ − 222 RETURN (BitmapFileInvalid);
+ − 223 }
+ − 224 if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) {
+ − 225 if (!(type = strrchr(name_and_type, '_')))
+ − 226 type = name_and_type;
+ − 227 else
+ − 228 type++;
+ − 229
+ − 230 if (!strcmp("width", type))
647
+ − 231 ww = value;
608
+ − 232 if (!strcmp("height", type))
647
+ − 233 hh = value;
608
+ − 234 if (!strcmp("hot", type)) {
+ − 235 if (type-- == name_and_type || type-- == name_and_type)
+ − 236 continue;
+ − 237 if (!strcmp("x_hot", type))
+ − 238 hx = value;
+ − 239 if (!strcmp("y_hot", type))
+ − 240 hy = value;
+ − 241 }
+ − 242 continue;
+ − 243 }
+ − 244
+ − 245 if (sscanf(line, "static short %s = {", name_and_type) == 1)
+ − 246 version10p = 1;
+ − 247 else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1)
+ − 248 version10p = 0;
+ − 249 else if (sscanf(line, "static char %s = {", name_and_type) == 1)
+ − 250 version10p = 0;
+ − 251 else
+ − 252 continue;
+ − 253
+ − 254 if (!(type = strrchr(name_and_type, '_')))
+ − 255 type = name_and_type;
+ − 256 else
+ − 257 type++;
+ − 258
+ − 259 if (strcmp("bits[]", type))
+ − 260 continue;
+ − 261
+ − 262 if (!ww || !hh)
+ − 263 RETURN (BitmapFileInvalid);
+ − 264
+ − 265 if ((ww % 16) && ((ww % 16) < 9) && version10p)
+ − 266 padding = 1;
+ − 267 else
+ − 268 padding = 0;
+ − 269
+ − 270 bytes_per_line = (ww+7)/8 + padding;
+ − 271
+ − 272 size = bytes_per_line * hh;
+ − 273 data = (UChar_Binary *) Xmalloc ((unsigned int) size);
+ − 274 if (!data)
+ − 275 RETURN (BitmapNoMemory);
+ − 276
+ − 277 if (version10p) {
+ − 278 UChar_Binary *ptr;
+ − 279 int bytes;
+ − 280
+ − 281 for (bytes=0, ptr=data; bytes<size; (bytes += 2)) {
+ − 282 if ((value = NextInt(fstream)) < 0)
+ − 283 RETURN (BitmapFileInvalid);
+ − 284 *(ptr++) = value;
+ − 285 if (!padding || ((bytes+2) % bytes_per_line))
+ − 286 *(ptr++) = value >> 8;
+ − 287 }
+ − 288 } else {
+ − 289 UChar_Binary *ptr;
+ − 290 int bytes;
+ − 291
+ − 292 for (bytes=0, ptr=data; bytes<size; bytes++, ptr++) {
+ − 293 if ((value = NextInt(fstream)) < 0)
+ − 294 RETURN (BitmapFileInvalid);
+ − 295 *ptr=value;
+ − 296 }
+ − 297 }
+ − 298 break;
+ − 299 } /* end while */
+ − 300
+ − 301 if (data == NULL) {
+ − 302 RETURN (BitmapFileInvalid);
+ − 303 }
+ − 304
+ − 305 *datap = data;
+ − 306 data = NULL;
+ − 307 *width = ww;
+ − 308 *height = hh;
+ − 309 if (x_hot) *x_hot = hx;
+ − 310 if (y_hot) *y_hot = hy;
+ − 311
+ − 312 RETURN (BitmapSuccess);
+ − 313 }
+ − 314
+ − 315
611
+ − 316 int
771
+ − 317 read_bitmap_data_from_file (Lisp_Object filename,
611
+ − 318 /* Remaining args are RETURNED */
647
+ − 319 int *width,
+ − 320 int *height,
611
+ − 321 UChar_Binary **datap,
+ − 322 int *x_hot, int *y_hot)
608
+ − 323 {
771
+ − 324 FILE *fstream;
+ − 325 int status;
+ − 326 Extbyte *fileext;
608
+ − 327
771
+ − 328 LISP_STRING_TO_EXTERNAL (filename, fileext, Qnative);
+ − 329 if ((fstream = fopen (fileext, "r")) == NULL)
+ − 330 return BitmapOpenFailed;
+ − 331 status = read_bitmap_data (fstream, width, height, datap, x_hot, y_hot);
+ − 332 retry_fclose (fstream);
+ − 333 return status;
608
+ − 334 }
+ − 335
563
+ − 336 void
+ − 337 syms_of_glyphs_shared (void)
+ − 338 {
+ − 339 DEFKEYWORD (Q_resource_id);
+ − 340 DEFKEYWORD (Q_resource_type);
+ − 341 }