+\f
+
+/* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
+ id, which is just an int that this section returns. Bitmaps are
+ reference counted so they can be shared among frames.
+
+ Bitmap indices are guaranteed to be > 0, so a negative number can
+ be used to indicate no bitmap.
+
+ If you use x_create_bitmap_from_data, then you must keep track of
+ the bitmaps yourself. That is, creating a bitmap from the same
+ data more than once will not be caught. */
+
+
+/* Functions to access the contents of a bitmap, given an id. */
+
+int
+x_bitmap_height (f, id)
+ FRAME_PTR f;
+ int id;
+{
+ return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].height;
+}
+
+int
+x_bitmap_width (f, id)
+ FRAME_PTR f;
+ int id;
+{
+ return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].width;
+}
+
+int
+x_bitmap_pixmap (f, id)
+ FRAME_PTR f;
+ int id;
+{
+ return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap;
+}
+
+
+/* Allocate a new bitmap record. Returns index of new record. */
+
+static int
+x_allocate_bitmap_record (f)
+ FRAME_PTR f;
+{
+ struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+ int i;
+
+ if (dpyinfo->bitmaps == NULL)
+ {
+ dpyinfo->bitmaps_size = 10;
+ dpyinfo->bitmaps
+ = (struct x_bitmap_record *) xmalloc (dpyinfo->bitmaps_size * sizeof (struct x_bitmap_record));
+ dpyinfo->bitmaps_last = 1;
+ return 1;
+ }
+
+ if (dpyinfo->bitmaps_last < dpyinfo->bitmaps_size)
+ return ++dpyinfo->bitmaps_last;
+
+ for (i = 0; i < dpyinfo->bitmaps_size; ++i)
+ if (dpyinfo->bitmaps[i].refcount == 0)
+ return i + 1;
+
+ dpyinfo->bitmaps_size *= 2;
+ dpyinfo->bitmaps
+ = (struct x_bitmap_record *) xrealloc (dpyinfo->bitmaps,
+ dpyinfo->bitmaps_size * sizeof (struct x_bitmap_record));
+ return ++dpyinfo->bitmaps_last;
+}
+
+/* Add one reference to the reference count of the bitmap with id ID. */
+
+void
+x_reference_bitmap (f, id)
+ FRAME_PTR f;
+ int id;
+{
+ ++FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].refcount;
+}
+
+/* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
+
+int
+x_create_bitmap_from_data (f, bits, width, height)
+ struct frame *f;
+ char *bits;
+ unsigned int width, height;
+{
+ struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+ Pixmap bitmap;
+ int id;
+
+ bitmap = XCreateBitmapFromData (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ bits, width, height);
+
+ if (! bitmap)
+ return -1;
+
+ id = x_allocate_bitmap_record (f);
+ dpyinfo->bitmaps[id - 1].pixmap = bitmap;
+ dpyinfo->bitmaps[id - 1].file = NULL;
+ dpyinfo->bitmaps[id - 1].refcount = 1;
+ dpyinfo->bitmaps[id - 1].depth = 1;
+ dpyinfo->bitmaps[id - 1].height = height;
+ dpyinfo->bitmaps[id - 1].width = width;
+
+ return id;
+}
+
+/* Create bitmap from file FILE for frame F. */
+
+int
+x_create_bitmap_from_file (f, file)
+ struct frame *f;
+ Lisp_Object file;
+{
+ struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+ unsigned int width, height;
+ Pixmap bitmap;
+ int xhot, yhot, result, id;
+ Lisp_Object found;
+ int fd;
+ char *filename;
+
+ /* Look for an existing bitmap with the same name. */
+ for (id = 0; id < dpyinfo->bitmaps_last; ++id)
+ {
+ if (dpyinfo->bitmaps[id].refcount
+ && dpyinfo->bitmaps[id].file
+ && !strcmp (dpyinfo->bitmaps[id].file, (char *) XSTRING (file)->data))
+ {
+ ++dpyinfo->bitmaps[id].refcount;
+ return id + 1;
+ }
+ }
+
+ /* Search bitmap-file-path for the file, if appropriate. */
+ fd = openp (Vx_bitmap_file_path, file, "", &found, 0);
+ if (fd < 0)
+ return -1;
+ close (fd);
+
+ filename = (char *) XSTRING (found)->data;
+
+ result = XReadBitmapFile (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ filename, &width, &height, &bitmap, &xhot, &yhot);
+ if (result != BitmapSuccess)
+ return -1;
+
+ id = x_allocate_bitmap_record (f);
+ dpyinfo->bitmaps[id - 1].pixmap = bitmap;
+ dpyinfo->bitmaps[id - 1].refcount = 1;
+ dpyinfo->bitmaps[id - 1].file = (char *) xmalloc (XSTRING (file)->size + 1);
+ dpyinfo->bitmaps[id - 1].depth = 1;
+ dpyinfo->bitmaps[id - 1].height = height;
+ dpyinfo->bitmaps[id - 1].width = width;
+ strcpy (dpyinfo->bitmaps[id - 1].file, XSTRING (file)->data);
+
+ return id;
+}
+
+/* Remove reference to bitmap with id number ID. */
+
+int
+x_destroy_bitmap (f, id)
+ FRAME_PTR f;
+ int id;
+{
+ struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+
+ if (id > 0)
+ {
+ --dpyinfo->bitmaps[id - 1].refcount;
+ if (dpyinfo->bitmaps[id - 1].refcount == 0)
+ {
+ BLOCK_INPUT;
+ XFreePixmap (FRAME_X_DISPLAY (f), dpyinfo->bitmaps[id - 1].pixmap);
+ if (dpyinfo->bitmaps[id - 1].file)
+ {
+ free (dpyinfo->bitmaps[id - 1].file);
+ dpyinfo->bitmaps[id - 1].file = NULL;
+ }
+ UNBLOCK_INPUT;
+ }
+ }
+}
+
+/* Free all the bitmaps for the display specified by DPYINFO. */
+
+static void
+x_destroy_all_bitmaps (dpyinfo)
+ struct x_display_info *dpyinfo;
+{
+ int i;
+ for (i = 0; i < dpyinfo->bitmaps_last; i++)
+ if (dpyinfo->bitmaps[i].refcount > 0)
+ {
+ XFreePixmap (dpyinfo->display, dpyinfo->bitmaps[i].pixmap);
+ if (dpyinfo->bitmaps[i].file)
+ free (dpyinfo->bitmaps[i].file);
+ }
+ dpyinfo->bitmaps_last = 0;
+}