10bbfda8aSnia/*
20bbfda8aSnia * Bitmap image handling functions
30bbfda8aSnia *
40bbfda8aSnia * These are what's called "XBM", and represented by the Pixmap X data
50bbfda8aSnia * type (which has noting to do with "XPM" X PixMaps, just to confuse
60bbfda8aSnia * you).  This is the format used for various builtin images, buttons,
70bbfda8aSnia * and cursors, and is also the fallback type for any user-specified
80bbfda8aSnia * images.  Assuming any user has made and specified an XBM since the
90bbfda8aSnia * 1980's.
100bbfda8aSnia */
110bbfda8aSnia
120bbfda8aSnia#include "ctwm.h"
130bbfda8aSnia
140bbfda8aSnia#include <X11/Xmu/Drawing.h>
150bbfda8aSnia
160bbfda8aSnia#include "screen.h"
170bbfda8aSnia#include "util.h"
180bbfda8aSnia
190bbfda8aSnia#include "image.h"
200bbfda8aSnia#include "image_bitmap.h"
210bbfda8aSnia#include "image_bitmap_builtin.h"
220bbfda8aSnia
230bbfda8aSnia
240bbfda8aSnia/* Shared with cursor.c for bitmap cursors */
250bbfda8aSniaint  HotX, HotY;
260bbfda8aSnia
270bbfda8aSnia
280bbfda8aSniastatic Image *LoadBitmapImage(const char  *name, ColorPair cp);
290bbfda8aSniastatic Pixmap FindBitmap(const char *name, unsigned int *widthp,
300bbfda8aSnia                         unsigned int *heightp);
310bbfda8aSnia
320bbfda8aSnia
330bbfda8aSnia/*
340bbfda8aSnia * External API's
350bbfda8aSnia */
360bbfda8aSnia
370bbfda8aSnia/* Simple load-by-name */
380bbfda8aSniaPixmap
390bbfda8aSniaGetBitmap(const char *name)
400bbfda8aSnia{
410bbfda8aSnia	return FindBitmap(name, &JunkWidth, &JunkHeight);
420bbfda8aSnia}
430bbfda8aSnia
440bbfda8aSnia
450bbfda8aSnia/*
460bbfda8aSnia * Load with FG/BG adjusted to given colorpair
470bbfda8aSnia */
480bbfda8aSniaImage *
490bbfda8aSniaGetBitmapImage(const char *name, ColorPair cp)
500bbfda8aSnia{
510bbfda8aSnia	/* Non-animated */
520bbfda8aSnia	if(! strchr(name, '%')) {
530bbfda8aSnia		return (LoadBitmapImage(name, cp));
540bbfda8aSnia	}
550bbfda8aSnia
560bbfda8aSnia	/* Animated */
570bbfda8aSnia	return get_image_anim_cp(name, cp, LoadBitmapImage);
580bbfda8aSnia}
590bbfda8aSnia
600bbfda8aSnia
610bbfda8aSnia/*
620bbfda8aSnia * Internal bits used by the above
630bbfda8aSnia */
640bbfda8aSnia
650bbfda8aSnia/***********************************************************************
660bbfda8aSnia *
670bbfda8aSnia *  Procedure:
680bbfda8aSnia *      FindBitmap - read in a bitmap file and return size
690bbfda8aSnia *
700bbfda8aSnia *  Returned Value:
710bbfda8aSnia *      the pixmap associated with the bitmap
720bbfda8aSnia *      widthp  - pointer to width of bitmap
730bbfda8aSnia *      heightp - pointer to height of bitmap
740bbfda8aSnia *
750bbfda8aSnia *  Inputs:
760bbfda8aSnia *      name    - the filename to read
770bbfda8aSnia *
780bbfda8aSnia ***********************************************************************
790bbfda8aSnia */
800bbfda8aSniastatic Pixmap
810bbfda8aSniaFindBitmap(const char *name, unsigned int *widthp,
820bbfda8aSnia           unsigned int *heightp)
830bbfda8aSnia{
840bbfda8aSnia	char *bigname;
850bbfda8aSnia	Pixmap pm;
860bbfda8aSnia
870bbfda8aSnia	if(!name) {
880bbfda8aSnia		return None;
890bbfda8aSnia	}
900bbfda8aSnia
910bbfda8aSnia	/*
920bbfda8aSnia	 * Names of the form :name refer to hardcoded images that are scaled to
930bbfda8aSnia	 * look nice in title buttons.  Eventually, it would be nice to put in a
940bbfda8aSnia	 * menu symbol as well....
950bbfda8aSnia	 */
960bbfda8aSnia	if(name[0] == ':') {
970bbfda8aSnia		return get_builtin_plain_pixmap(name, widthp, heightp);
980bbfda8aSnia	}
990bbfda8aSnia
1000bbfda8aSnia	/*
1010bbfda8aSnia	 * Generate a full pathname with any special prefix characters (such
1020bbfda8aSnia	 * as ~) expanded.
1030bbfda8aSnia	 */
1040bbfda8aSnia	bigname = ExpandFilename(name);
1050bbfda8aSnia	if(!bigname) {
1060bbfda8aSnia		/* Something failed bad */
1070bbfda8aSnia		return None;
1080bbfda8aSnia	}
1090bbfda8aSnia
1100bbfda8aSnia	/*
1110bbfda8aSnia	 * look along bitmapFilePath resource same as toolkit clients
1120bbfda8aSnia	 */
1130bbfda8aSnia	pm = XmuLocateBitmapFile(ScreenOfDisplay(dpy, Scr->screen), bigname, NULL,
1140bbfda8aSnia	                         0, (int *)widthp, (int *)heightp, &HotX, &HotY);
1150bbfda8aSnia	if(pm == None && Scr->IconDirectory && bigname[0] != '/') {
1160bbfda8aSnia		/*
1170bbfda8aSnia		 * Didn't find it.  Attempt to find icon in old IconDirectory
1180bbfda8aSnia		 * (now obsolete)
1190bbfda8aSnia		 */
1200bbfda8aSnia		free(bigname);
1210bbfda8aSnia		asprintf(&bigname, "%s/%s", Scr->IconDirectory, name);
1220bbfda8aSnia		if(XReadBitmapFile(dpy, Scr->Root, bigname, widthp, heightp, &pm,
1230bbfda8aSnia		                   &HotX, &HotY) != BitmapSuccess) {
1240bbfda8aSnia			pm = None;
1250bbfda8aSnia		}
1260bbfda8aSnia	}
1270bbfda8aSnia	free(bigname);
1280bbfda8aSnia	if((pm == None) && reportfilenotfound) {
1290bbfda8aSnia		fprintf(stderr, "%s:  unable to find bitmap \"%s\"\n", ProgramName, name);
1300bbfda8aSnia	}
1310bbfda8aSnia
1320bbfda8aSnia	return pm;
1330bbfda8aSnia}
1340bbfda8aSnia
1350bbfda8aSnia
1360bbfda8aSniastatic Image *
1370bbfda8aSniaLoadBitmapImage(const char *name, ColorPair cp)
1380bbfda8aSnia{
1390bbfda8aSnia	Image        *image;
1400bbfda8aSnia	Pixmap       bm;
1410bbfda8aSnia	unsigned int width, height;
1420bbfda8aSnia	XGCValues    gcvalues;
1430bbfda8aSnia
1440bbfda8aSnia	if(Scr->rootGC == (GC) 0) {
1450bbfda8aSnia		Scr->rootGC = XCreateGC(dpy, Scr->Root, 0, &gcvalues);
1460bbfda8aSnia	}
1470bbfda8aSnia	bm = FindBitmap(name, &width, &height);
1480bbfda8aSnia	if(bm == None) {
1490bbfda8aSnia		return NULL;
1500bbfda8aSnia	}
1510bbfda8aSnia
1520bbfda8aSnia	image = AllocImage();
1530bbfda8aSnia	image->pixmap = XCreatePixmap(dpy, Scr->Root, width, height, Scr->d_depth);
1540bbfda8aSnia	gcvalues.background = cp.back;
1550bbfda8aSnia	gcvalues.foreground = cp.fore;
1560bbfda8aSnia	XChangeGC(dpy, Scr->rootGC, GCForeground | GCBackground, &gcvalues);
1570bbfda8aSnia	XCopyPlane(dpy, bm, image->pixmap, Scr->rootGC, 0, 0, width, height,
1580bbfda8aSnia	           0, 0, (unsigned long) 1);
1590bbfda8aSnia	XFreePixmap(dpy, bm);
1600bbfda8aSnia	image->width  = width;
1610bbfda8aSnia	image->height = height;
1620bbfda8aSnia	return image;
1630bbfda8aSnia}
1640bbfda8aSnia
165