2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: icon.c /main/3 1995/10/27 10:39:09 rswiston $ */
24 /*****************************************************************************
25 *****************************************************************************
29 ** Description: Icon support functions for the CDE Drag & Drop Demo.
31 ** (c) Copyright 1993, 1994 Hewlett-Packard Company
32 ** (c) Copyright 1993, 1994 International Business Machines Corp.
33 ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
34 ** (c) Copyright 1993, 1994 Unix System Labs, Inc., a subsidiary of
37 ****************************************************************************
38 ************************************<+>*************************************/
42 #include <Xm/Screen.h>
49 /*************************************************************************
51 * Data Structures & Private Declarations For Icon Handling Functions
53 **************************************************************************/
55 #define ICON_TEXT_YGAP 2
57 #define ICON_PATH "/usr/dt/appconfig/icons/C"
58 #define ICON_BITMAP_SUFFIX "m.bm"
59 #define ICON_MASK_SUFFIX "m_m.bm"
62 * Default Generic Icon Bitmap & Mask
67 static unsigned char iconBits[] = {
68 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x0f, 0x08, 0x00, 0x00, 0x08,
69 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x88, 0x9d, 0x6d, 0x08,
70 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x88, 0xf9, 0xed, 0x08,
71 0x08, 0x00, 0x00, 0x08, 0xc8, 0x6e, 0x7d, 0x08, 0x08, 0x00, 0x00, 0x08,
72 0xc8, 0x9d, 0xef, 0x09, 0x08, 0x00, 0x00, 0x08, 0xc8, 0xdd, 0xb3, 0x08,
73 0x08, 0x00, 0x00, 0x08, 0xc8, 0xdf, 0xfd, 0x09, 0x08, 0x00, 0x00, 0x08,
74 0xc8, 0xf6, 0xde, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08,
75 0x88, 0xed, 0xd2, 0x08, 0x08, 0x00, 0x00, 0x08, 0xc8, 0xbb, 0xf3, 0x08,
76 0x08, 0x00, 0x00, 0x08, 0x48, 0xdf, 0x5e, 0x08, 0x08, 0x00, 0x00, 0x08,
77 0xc8, 0x36, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08,
78 0x08, 0x00, 0x00, 0x08, 0xf8, 0xff, 0xff, 0x0f};
80 #define iconMaskWidth 32
81 #define iconMaskHeight 32
82 static unsigned char iconMaskBits[] = {
83 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x0f,
84 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x0f,
85 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x0f,
86 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x0f,
87 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x0f,
88 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x0f,
89 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x0f,
90 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x0f,
91 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x0f,
92 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x0f,
93 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x0f};
100 #define blankHeight 16
101 static unsigned char blankBits[] = {
102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
108 * Private Icon Handling Function Declarations
111 static void iconClearBitmap(Display*, Window, GC, Pixmap, int, int);
112 static Pixmap iconDefaultBitmap(Display*, Window, IconBitmapPart,
113 unsigned short*, unsigned short*);
114 static void iconFree(IconInfo*);
115 static Pixmap iconGetBitmap(Widget, char*, IconBitmapPart, unsigned short*,
117 static char *iconGetIconPath(void*, int, IconTyping, IconBitmapPart);
118 static Pixmap iconMergeBitmaps(Widget, Pixmap, int, int, Pixmap, int, int,
121 /*************************************************************************
123 * Public Icon Handling Functions
125 **************************************************************************/
130 * Create a double icon from a single icon. The double icon has a bitmap
131 * consisting of 2 images of the original bitmap offset from one another.
143 newIcon->bitmap = iconMergeBitmaps(widget,
144 oldIcon->bitmap, oldIcon->icon.width, oldIcon->icon.height,
145 oldIcon->bitmap, oldIcon->icon.width, oldIcon->icon.height,
146 xOffset, yOffset, False);
147 newIcon->mask = iconMergeBitmaps(widget,
148 oldIcon->mask, oldIcon->icon.width, oldIcon->icon.height,
149 oldIcon->mask, oldIcon->icon.width, oldIcon->icon.height,
150 xOffset, yOffset, True);
151 newIcon->icon.width = oldIcon->icon.width + 10;
152 newIcon->icon.height = oldIcon->icon.height + 10;
153 newIcon->name = XtNewString("Multiple");
154 newIcon->icon.x = xx;
155 newIcon->icon.y = yy;
156 newIcon->dragIcon = DtDndCreateSourceIcon(widget,
157 newIcon->bitmap, newIcon->mask);
163 * Remove the icon from its list and deallocate memory used by the icon.
172 if (iconPtr == NULL || drawArea == NULL) {
176 if (iconPtr->next != NULL) { /* iconPtr is not the tail of the list */
177 iconPtr->next->prev = iconPtr->prev;
180 if (iconPtr->prev != NULL) { /* iconPtr is not the head of the list */
181 iconPtr->prev->next = iconPtr->next;
183 if (iconPtr->next == NULL) { /* iconPtr is the tail of the list */
184 iconList = iconPtr->prev;
186 iconList = iconPtr->next;
189 while (iconList != NULL && iconList->prev != NULL) {
190 iconList = iconList->prev;
194 XtVaSetValues(drawArea, XmNuserData, iconList, NULL);
200 * Render given icon in the window of the given widget.
207 static GC graphicsContext = NULL;
208 static XFontStruct *fontStruct;
209 Display *display = XtDisplayOfObject(widget);
210 Window window = XtWindow(widget);
211 int screen = DefaultScreen(display);
214 if (graphicsContext == NULL) {
215 gcValues.foreground = BlackPixel(display, screen);
216 gcValues.background = WhitePixel(display, screen);
217 graphicsContext = XCreateGC(display, window,
218 GCForeground | GCBackground, &gcValues);
225 gcValues.clip_mask = iconPtr->mask;
226 gcValues.clip_x_origin = iconPtr->icon.x;
227 gcValues.clip_y_origin = iconPtr->icon.y;
228 XChangeGC(display, graphicsContext,
229 GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcValues);
230 XCopyPlane(display, iconPtr->bitmap, window, graphicsContext, 0, 0,
231 iconPtr->icon.width, iconPtr->icon.height,
232 iconPtr->icon.x, iconPtr->icon.y, 1L);
235 * Draw icon name centered below icon
238 if (iconPtr->name != NULL) {
240 int direction, ascent, decent;
244 if (fontStruct == NULL) {
245 xmScreen = XmGetXmScreen(XtScreen(widget));
246 XtVaGetValues(xmScreen, XmNfont, &fontStruct, NULL);
248 XTextExtents(fontStruct, iconPtr->name, strlen(iconPtr->name),
249 &direction, &ascent, &decent, &overall);
251 nameX = (iconPtr->icon.x + (iconPtr->icon.width/2)) -
253 nameY = iconPtr->icon.y + iconPtr->icon.height +
254 ICON_TEXT_YGAP + ascent;
256 gcValues.font = fontStruct->fid;
257 gcValues.clip_mask = None;
258 XChangeGC(display, graphicsContext,
259 GCFont | GCClipMask, &gcValues);
260 XDrawString(display, window, graphicsContext, nameX, nameY,
261 iconPtr->name, strlen(iconPtr->name));
268 * Initialize given icon with given data. Get icon bitmap based on data
269 * associated with the icon. This data may be a file name, a buffer or
270 * a type name. Create source icon for dragging based on the bitmap and mask.
285 iconPath = iconGetIconPath(data, dataLen, typing, IconMask);
286 iconPtr->mask = iconGetBitmap(widget, iconPath, IconMask,
287 &(iconPtr->icon.width), &(iconPtr->icon.height));
290 iconPath = iconGetIconPath(data, dataLen, typing, IconBitmap);
291 iconPtr->bitmap = iconGetBitmap(widget, iconPath, IconBitmap,
292 &(iconPtr->icon.width), &(iconPtr->icon.height));
297 iconPtr->name = XtNewString(name);
298 iconPtr->dragIcon = DtDndCreateSourceIcon(widget,
299 iconPtr->bitmap, iconPtr->mask);
305 * Allocate memory for a new icon structure and clear.
312 iconPtr = (IconInfo*) XtMalloc(sizeof(IconInfo));
313 memset(iconPtr, 0x00, sizeof(IconInfo));
318 /*************************************************************************
320 * Private Icon Handling Functions
322 **************************************************************************/
327 * Clear a bitmap by filling it with zeros.
339 static Pixmap blankBitmap = NULL;
341 if (blankBitmap == NULL) {
342 blankBitmap = XCreateBitmapFromData(display, window,
343 (char *)blankBits, blankWidth, blankHeight);
345 for (xx = 0; xx < width + blankWidth; xx += blankWidth) {
346 for (yy = 0; yy < height + blankHeight; yy += blankHeight) {
347 XCopyArea(display, blankBitmap, bitmap,
348 graphicsContext, 0, 0,
349 blankWidth, blankHeight, xx, yy);
357 * Create default icon bitmap or mask and set width and height accordingly.
363 IconBitmapPart iconPart,
364 unsigned short *width,
365 unsigned short *height)
367 static Pixmap bitmap;
370 if (iconPart == IconMask) { /* create default mask */
372 mask = XCreateBitmapFromData(display, window,
373 (char *)iconMaskBits, iconMaskWidth, iconMaskHeight);
375 *width = iconMaskWidth;
376 *height = iconMaskHeight;
380 } else { /* create default bitmap */
381 if (bitmap == NULL) {
382 bitmap = XCreateBitmapFromData(display, window,
383 (char *)iconBits, iconWidth, iconHeight);
386 *height = iconHeight;
395 * Deallocate the icon and associated resources.
401 Display *display = XtDisplayOfObject(iconPtr->dragIcon);
403 if (iconPtr == NULL) {
407 XtFree(iconPtr->name);
409 * REMIND: This needs to free other things too...
410 * XFreePixmap(display, iconPtr->bitmap);
411 * XFreePixmap(display, iconPtr->mask);
412 * Free(iconPtr->dragIcon);
414 XtFree((char *)iconPtr);
420 * Get a bitmap for the icon based on the path and name of the icon.
421 * If no bitmap file is found use a built-in default.
427 IconBitmapPart iconPart,
428 unsigned short *returnWidth,
429 unsigned short *returnHeight)
431 Display *display = XtDisplayOfObject(widget);
432 Window window = DefaultRootWindow(display);
436 unsigned int width, height;
438 *returnWidth = *returnHeight = 0;
440 if (iconPath != NULL) {
442 status = XReadBitmapFile(display, window, iconPath,
443 &width, &height, &bitmap, &xHot, &yHot);
445 if (status == BitmapSuccess) {
446 *returnWidth = (unsigned short) width;
447 *returnHeight = (unsigned short) height;
450 "Unable to read icon from bitmap file \"%s\".\n"
451 "Using default icon bitmap.\n",
453 bitmap = iconDefaultBitmap(display, window, iconPart,
454 returnWidth, returnHeight);
457 bitmap = iconDefaultBitmap(display, window, iconPart,
458 returnWidth, returnHeight);
466 * Get the file path and name for an icon based on the given data and
467 * method of typing that data. This function assumes the data typing
468 * database has been loaded with DtDtsLoadDataTypes().
475 IconBitmapPart iconPart)
477 char iconPath[MAXPATHLEN + 1],
483 iconName = DtDtsFileToAttributeValue(data, "ICON");
486 iconName = DtDtsBufferToAttributeValue(data, dataLen,
490 iconName = DtDtsDataTypeToAttributeValue(data, "ICON", NULL);
495 if (iconName != NULL) {
496 if (iconPart == IconMask) {
497 iconSuffix = ICON_MASK_SUFFIX;
499 iconSuffix = ICON_BITMAP_SUFFIX;
501 sprintf(iconPath, "%s/%s.%s", ICON_PATH, iconName, iconSuffix);
502 DtDtsFreeAttributeValue(iconName);
504 return XtNewString(iconPath);
510 * Create new bitmap consisting of the offset composition of the given bitmaps.
525 Display *display = XtDisplayOfObject(widget);
526 Window window = DefaultRootWindow(display);
527 int screen = DefaultScreen(display);
528 Pixmap mergedBitmap, blankBitmap;
529 int extraX, extraY, width, height;
530 static GC graphicsContext = NULL;
533 extraX = width2 - width1 + xOffset + 1;
534 if (extraX < 0) extraX = 0;
535 width = width1 + extraX;
537 extraY = height2 - height1 + yOffset + 1;
538 if (extraY < 0) extraY = 0;
539 height = height1 + extraY;
541 mergedBitmap = XCreatePixmap(display, window, width, height, 1);
543 if (graphicsContext == NULL) {
544 graphicsContext = XCreateGC(display, mergedBitmap, 0L, NULL);
548 iconClearBitmap(display, window, graphicsContext, mergedBitmap,
552 XCopyArea(display, bitmap2, mergedBitmap, graphicsContext, 0, 0,
553 width2, height2, xOffset, yOffset);
555 XCopyArea(display, bitmap1, mergedBitmap, graphicsContext, 0, 0,
556 width1, height1, 0, 0);