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