home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
-
- /*
- * The following source code is part of the Microline Widget Library.
- * The Microline widget library is made available to Mozilla developers
- * under the Netscape Public License (NPL) by Neuron Data. To learn
- * more about Neuron Data, please visit the Neuron Data Home Page at
- * http://www.neurondata.com.
- */
-
- #include <XmL/XmL.h>
- #include <Xm/XmP.h>
- #include <Xm/LabelP.h>
- #include <Xm/DrawnBP.h>
- #include <Xm/MessageB.h>
- #include <Xm/Protocols.h>
- #include <Xm/AtomMgr.h>
- #ifdef MOTIF11
- #include <Xm/VendorE.h>
- #else
- #include <Xm/VendorS.h>
- #endif
- #include <Xm/BulletinB.h>
- #include <Xm/MenuShell.h>
-
- #include <stdlib.h>
- #include <stdio.h>
-
- #ifdef SUNOS4
- int fprintf(FILE *, char *, ...);
- #endif
-
- static void XmLDrawnBDestroyCB(Widget w, XtPointer clientData, XtPointer);
- static void XmLDrawnBDrawCB(Widget, XtPointer, XtPointer);
- static void XmLDrawnBDrawStringCB(Widget, XtPointer, XtPointer);
- static int XmLDrawCalc(Widget w, Dimension width, Dimension height,
- unsigned char alignment, XRectangle *rect, XRectangle *clipRect,
- int *x, int *y);
- static void XmLFontGetAverageWidth(XFontStruct *fs, short *width);
- static void XmLMessageBoxResponse(Widget, XtPointer, XtPointer);
- static void XmLMessageBoxWMDelete(Widget, XtPointer, XtPointer);
- static void XmLSortFunc(char *lvec, char *rvec);
-
- struct _XmLArrayRec
- {
- char _autonumber, _growFast;
- int _count, _size;
- void **_items;
- };
-
- XmLArray
- XmLArrayNew(char autonumber,
- char growFast)
- {
- XmLArray array;
-
- array = (XmLArray)malloc(sizeof(struct _XmLArrayRec));
- array->_count = 0;
- array->_size = 0;
- array->_items = 0;
- array->_autonumber = autonumber;
- array->_growFast = growFast;
- return array;
- }
-
- void
- XmLArrayFree(XmLArray array)
- {
- if (array->_items)
- free((char *)array->_items);
- free((char *)array);
- }
-
- void
- XmLArrayAdd(XmLArray array,
- int pos,
- int count)
- {
- int i;
- void **items;
-
- if (count < 1)
- return;
- if (pos < 0 || pos > array->_count)
- pos = array->_count;
- if (array->_count + count >= array->_size)
- {
- if (array->_growFast)
- {
- if (!array->_size)
- array->_size = count + 256;
- else
- array->_size = (array->_count + count) * 2;
- }
- else
- array->_size = array->_count + count;
- items = (void **)malloc(sizeof(void *) * array->_size);
- if (array->_items)
- {
- for (i = 0; i < array->_count; i++)
- items[i] = array->_items[i];
- free((char *)array->_items);
- }
- array->_items = items;
- }
- for (i = array->_count + count - 1; i >= pos + count; i--)
- {
- array->_items[i] = array->_items[i - count];
- if (array->_autonumber)
- ((XmLArrayItem *)array->_items[i])->pos = i;
- }
- for (i = pos; i < pos + count; i++)
- array->_items[i] = 0;
- array->_count += count;
- }
-
- int
- XmLArrayDel(XmLArray array,
- int pos,
- int count)
- {
- int i;
-
- if (pos < 0 || pos + count > array->_count)
- return -1;
- for (i = pos; i < array->_count - count; i++)
- {
- array->_items[i] = array->_items[i + count];
- if (array->_autonumber)
- ((XmLArrayItem *)array->_items[i])->pos = i;
- }
- array->_count -= count;
- if (!array->_count)
- {
- if (array->_items)
- free((char *)array->_items);
- array->_items = 0;
- array->_size = 0;
- }
- return 0;
- }
-
- int
- XmLArraySet(XmLArray array,
- int pos,
- void *item)
- {
- if (pos < 0 || pos >= array->_count)
- return -1;
- if (array->_items[pos])
- fprintf(stderr, "XmLArraySet: warning: overwriting pointer\n");
- array->_items[pos] = item;
- if (array->_autonumber)
- ((XmLArrayItem *)array->_items[pos])->pos = pos;
- return 0;
- }
-
- void *
- XmLArrayGet(XmLArray array,
- int pos)
- {
- if (pos < 0 || pos >= array->_count)
- return 0;
- return array->_items[pos];
- }
-
- int
- XmLArrayGetCount(XmLArray array)
- {
- return array->_count;
- }
-
- int
- XmLArrayMove(XmLArray array,
- int newPos,
- int pos,
- int count)
- {
- void **items;
- int i;
-
- if (count <= 0)
- return -1;
- if (newPos < 0 || newPos + count > array->_count)
- return -1;
- if (pos < 0 || pos + count > array->_count)
- return -1;
- if (pos == newPos)
- return 0;
- /* copy items to move */
- items = (void **)malloc(sizeof(void *) * count);
- for (i = 0; i < count; i++)
- items[i] = array->_items[pos + i];
- /* move real items around */
- if (newPos < pos)
- for (i = pos + count - 1; i >= newPos + count; i--)
- {
- array->_items[i] = array->_items[i - count];
- if (array->_autonumber)
- ((XmLArrayItem *)array->_items[i])->pos = i;
- }
- else
- for (i = pos; i < newPos; i++)
- {
- array->_items[i] = array->_items[i + count];
- if (array->_autonumber)
- ((XmLArrayItem *)array->_items[i])->pos = i;
- }
- /* move items copy back */
- for (i = 0; i < count; i++)
- {
- array->_items[newPos + i] = items[i];
- if (array->_autonumber)
- ((XmLArrayItem *)array->_items[newPos + i])->pos = newPos + i;
- }
- free((char *)items);
- return 0;
- }
-
- int
- XmLArrayReorder(XmLArray array,
- int *newPositions,
- int pos,
- int count)
- {
- int i;
- void **items;
-
- if (count <= 0)
- return -1;
- if (pos < 0 || pos + count > array->_count)
- return -1;
- for (i = 0; i < count; i++)
- {
- if (newPositions[i] < pos || newPositions[i] >= pos + count)
- return -1;
- }
- items = (void **)malloc(sizeof(void *) * count);
- for (i = 0; i < count; i++)
- items[i] = array->_items[newPositions[i]];
- for (i = 0; i < count; i++)
- {
- array->_items[pos + i] = items[i];
- if (array->_autonumber)
- ((XmLArrayItem *)array->_items[pos + i])->pos = pos + i;
- }
- free((char *)items);
- return 0;
- }
-
- int
- XmLArraySort(XmLArray array,
- XmLArrayCompareFunc compare,
- void *userData,
- int pos,
- int count)
- {
- int i;
-
- if (pos < 0 || pos + count > array->_count)
- return -1;
- XmLSort(&array->_items[pos], count, sizeof(void *),
- (XmLSortCompareFunc)compare, userData);
- if (array->_autonumber)
- for (i = pos; i < pos + count; i++)
- ((XmLArrayItem *)array->_items[i])->pos = i;
- return 0;
- }
-
-
- Boolean
- XmLCvtStringToUChar(Display *dpy,
- char *resname,
- XmLStringToUCharMap *map,
- XrmValuePtr fromVal,
- XrmValuePtr toVal)
- {
- char *from;
- int i, /*num,*/ valid;
-
- from = (char *)fromVal->addr;
- valid = 0;
- i = 0;
- while (map[i].name)
- {
- if (!strcmp(from, map[i].name))
- {
- valid = 1;
- break;
- }
- i++;
- }
- if (!valid)
- {
- XtDisplayStringConversionWarning(dpy, from, resname);
- toVal->size = 0;
- toVal->addr = 0;
- return False;
- }
- if (toVal->addr)
- {
- if (toVal->size < sizeof(unsigned char))
- {
- toVal->size = sizeof(unsigned char);
- return False;
- }
- *(unsigned char *)(toVal->addr) = map[i].value;
- }
- else
- toVal->addr = (caddr_t)&map[i].value;
- toVal->size = sizeof(unsigned char);
- return True;
- }
-
- int
- XmLDateDaysInMonth(int m,
- int y)
- {
- static int d[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
-
- if (m < 1 || m > 12 || y < 1753 || y > 9999)
- return -1;
- if (m == 2 && (!((y % 4) && (y % 100)) || !(y % 400)))
- return 29;
- return d[m - 1];
- }
-
- /* Calculation from Communications Of The ACM, Vol 6, No 8, p 444 */
- /* sun is 0, sat is 6 */
- int
- XmLDateWeekDay(int m,
- int d,
- int y)
- {
- long jd, j1, j2;
-
- if (m < 1 || m > 12 || d < 1 || d > XmLDateDaysInMonth(m, y) ||
- y < 1753 || y > 9999)
- return -1;
- if (m > 2)
- m -= 3;
- else
- {
- m += 9;
- y--;
- }
- j1 = y / 100;
- j2 = y - 100 * j1;
- jd = (146097 * j1) / 4 + (1461 * j2) / 4 + (153 * m + 2) / 5 +
- 1721119 + d;
- return (jd + 1) % 7;
- }
-
- typedef struct
- {
- GC gc;
- int type;
- int dir;
- XFontStruct *fontStruct;
- } XmLDrawnBData;
-
- void
- XmLDrawnButtonSetType(Widget w,
- int drawnType,
- int drawnDir)
- {
- XmLDrawnBData *dd;
- XmDrawnButtonWidget b;
- XmString str;
- XmFontList fontlist;
- XGCValues values;
- XtGCMask mask;
- Dimension width, height, dim;
- Dimension highlightThickness, shadowThickness;
- Dimension marginWidth, marginHeight;
- Dimension marginTop, marginBottom, marginLeft, marginRight;
-
- if (!XtIsSubclass(w, xmDrawnButtonWidgetClass))
- {
- XmLWarning(w, "DrawnButtonSetType() - not an XmDrawnButton");
- return;
- }
- XtVaSetValues(w,
- XmNpushButtonEnabled, True,
- NULL);
- XtRemoveAllCallbacks(w, XmNexposeCallback);
- XtRemoveAllCallbacks(w, XmNresizeCallback);
- if (drawnType == XmDRAWNB_STRING && drawnDir == XmDRAWNB_RIGHT)
- {
- XtVaSetValues(w,
- XmNlabelType, XmSTRING,
- NULL);
- return;
- }
- b = (XmDrawnButtonWidget)w;
- dd = (XmLDrawnBData *)malloc(sizeof(XmLDrawnBData));
- dd->type = drawnType;
- dd->dir = drawnDir;
- dd->gc = 0;
- if (dd->type == XmDRAWNB_STRING)
- {
- XtVaGetValues(w,
- XmNlabelString, &str,
- XmNfontList, &fontlist,
- XmNhighlightThickness, &highlightThickness,
- XmNshadowThickness, &shadowThickness,
- XmNmarginHeight, &marginHeight,
- XmNmarginWidth, &marginWidth,
- XmNmarginTop, &marginTop,
- XmNmarginBottom, &marginBottom,
- XmNmarginLeft, &marginLeft,
- XmNmarginRight, &marginRight,
- NULL);
- if (!str && XtName(w))
- str = XmStringCreateSimple(XtName(w));
- if (!str)
- str = XmStringCreateSimple("");
- XmStringExtent(fontlist, str, &width, &height);
- XmStringFree(str);
- if (drawnDir == XmDRAWNB_UP || drawnDir == XmDRAWNB_DOWN)
- {
- dim = width;
- width = height;
- height = dim;
- }
- height += (highlightThickness + shadowThickness +
- marginHeight) * 2 + marginTop + marginBottom;
- width += (highlightThickness + shadowThickness +
- marginWidth) * 2 + marginLeft + marginRight;
- /* change to pixmap type so label string isnt drawn */
- XtVaSetValues(w,
- XmNlabelType, XmPIXMAP,
- NULL);
- XtVaSetValues(w,
- XmNwidth, width,
- XmNheight, height,
- NULL);
- XtAddCallback(w, XmNexposeCallback, XmLDrawnBDrawStringCB,
- (XtPointer)dd);
- XtAddCallback(w, XmNresizeCallback, XmLDrawnBDrawStringCB,
- (XtPointer)dd);
- }
- else
- {
- mask = GCForeground;
- values.foreground = b->primitive.foreground;
- dd->gc = XtGetGC(w, mask, &values);
- XtAddCallback(w, XmNexposeCallback, XmLDrawnBDrawCB, (XtPointer)dd);
- XtAddCallback(w, XmNresizeCallback, XmLDrawnBDrawCB, (XtPointer)dd);
- }
- XtAddCallback(w, XmNdestroyCallback, XmLDrawnBDestroyCB, (XtPointer)dd);
- }
-
- static void
- XmLDrawnBDestroyCB(Widget w,
- XtPointer clientData,
- XtPointer callData)
- {
- XmLDrawnBData *dd;
-
- dd = (XmLDrawnBData *)clientData;
- if (dd->type == XmDRAWNB_STRING)
- {
- if (dd->gc)
- {
- XFreeGC(XtDisplay(w), dd->gc);
- XFreeFont(XtDisplay(w), dd->fontStruct);
- }
- }
- else
- XtReleaseGC(w, dd->gc);
- free((char *)dd);
- }
-
- static void
- XmLDrawnBDrawStringCB(Widget w,
- XtPointer clientData,
- XtPointer callData)
- {
- XmLDrawnBData *dd;
- XmFontList fontlist;
- XmString str;
- XmStringDirection stringDir;
- unsigned char drawDir, alignment;
- int width, height, xoff, yoff, drawWidth;
- Pixel fg;
- Dimension highlightThickness;
- Dimension shadowThickness, marginWidth, marginHeight;
- Dimension marginLeft, marginRight, marginTop, marginBottom;
-
- if (!XtIsRealized(w))
- return;
- dd = (XmLDrawnBData *)clientData;
- XtVaGetValues(w,
- XmNlabelString, &str,
- NULL);
- if (!str && XtName(w))
- str = XmStringCreateSimple(XtName(w));
- if (!str)
- return;
- XtVaGetValues(w,
- XmNforeground, &fg,
- XmNfontList, &fontlist,
- XmNalignment, &alignment,
- XmNhighlightThickness, &highlightThickness,
- XmNshadowThickness, &shadowThickness,
- XmNmarginWidth, &marginWidth,
- XmNmarginHeight, &marginHeight,
- XmNmarginLeft, &marginLeft,
- XmNmarginRight, &marginRight,
- XmNmarginTop, &marginTop,
- XmNmarginBottom, &marginBottom,
- NULL);
- xoff = highlightThickness + shadowThickness + marginLeft + marginWidth;
- yoff = highlightThickness + shadowThickness + marginTop + marginHeight;
- width = XtWidth(w) - xoff - xoff + marginLeft - marginRight;
- height = XtHeight(w) - yoff - yoff + marginTop - marginBottom;
- if (XmIsManager(XtParent(w)))
- XtVaGetValues(XtParent(w),
- XmNstringDirection, &stringDir,
- NULL);
- else
- stringDir = XmSTRING_DIRECTION_L_TO_R;
- switch (dd->dir)
- {
- case XmDRAWNB_LEFT:
- drawDir = XmSTRING_LEFT;
- break;
- case XmDRAWNB_UP:
- drawDir = XmSTRING_UP;
- break;
- case XmDRAWNB_DOWN:
- drawDir = XmSTRING_DOWN;
- break;
- default:
- drawDir = XmSTRING_RIGHT;
- break;
- }
- if (drawDir == XmSTRING_LEFT || drawDir == XmSTRING_RIGHT)
- drawWidth = width;
- else
- drawWidth = height;
- if (!dd->gc)
- {
- dd->gc = XCreateGC(XtDisplay(w), XtWindow(w), 0, NULL);
- dd->fontStruct = XLoadQueryFont(XtDisplay(w), "fixed");
- if (!dd->fontStruct)
- {
- XmLWarning(w, "DrawnBDrawString() - FATAL can't load fixed font");
- return;
- }
- XSetFont(XtDisplay(w), dd->gc, dd->fontStruct->fid);
- }
- XSetForeground(XtDisplay(w), dd->gc, fg);
- XmLStringDrawDirection(XtDisplay(w), XtWindow(w), fontlist,
- str, dd->gc, xoff, yoff, drawWidth, alignment, stringDir, drawDir);
- XmStringFree(str);
- }
-
- static void
- XmLDrawnBDrawCB(Widget w,
- XtPointer clientData,
- XtPointer callData)
- {
- XmLDrawnBData *dd;
- XmDrawnButtonWidget b;
- /* unsigned char drawDir;*/
- /* unsigned char alignment;*/
- Display *dpy;
- Window win;
- GC gc;
- XPoint p[2][5];
- XSegment seg;
- int np[2];
- int i, j, temp;
- int md, type, dir;
- int avgx, avgy, xoff, yoff, st;
-
- if (!XtIsRealized(w))
- return;
- dd = (XmLDrawnBData *)clientData;
- type = dd->type;
- dir = dd->dir;
- gc = dd->gc;
- b = (XmDrawnButtonWidget)w;
- win = XtWindow(w);
- dpy = XtDisplay(w);
- st = b->primitive.shadow_thickness;
- i = st * 2 + b->primitive.highlight_thickness * 2;
- /* calculate max dimension */
- md = XtWidth(w) - i;
- if (md > ((int)XtHeight(w) - i))
- md = XtHeight(w) - i;
- if (md < 4)
- return;
- xoff = ((int)XtWidth(w) - md) / 2;
- yoff = ((int)XtHeight(w) - md) / 2;
- np[0] = 0;
- np[1] = 0;
- switch (type)
- {
- case XmDRAWNB_ARROW:
- p[0][0].x = md / 6;
- p[0][0].y = md / 6;
- p[0][1].x = md / 6;
- p[0][1].y = md - md / 6;
- p[0][2].x = md - md / 6;
- p[0][2].y = md / 2;
- np[0] = 3;
- break;
- case XmDRAWNB_ARROWLINE:
- p[0][0].x = md / 5;
- p[0][0].y = md / 5;
- p[0][1].x = md / 5;
- p[0][1].y = md - md / 5;
- p[0][2].x = md - md / 5;
- p[0][2].y = md / 2;
- np[0] = 3;
- p[1][0].x = md - md / 5 + 1;
- p[1][0].y = md / 5;
- p[1][1].x = md - md / 5 + 1;
- p[1][1].y = md - md / 5;
- p[1][2].x = md - md / 10;
- p[1][2].y = md - md / 5;
- p[1][3].x = md - md / 10;
- p[1][3].y = md / 5;
- np[1] = 4;
- break;
- case XmDRAWNB_DOUBLEARROW:
- /* odd major dimensions can give jagged lines */
- if (md % 2)
- md -= 1;
- p[0][0].x = md / 10;
- p[0][0].y = md / 10;
- p[0][1].x = md / 10;
- p[0][1].y = md - md / 10;
- p[0][2].x = md / 2;
- p[0][2].y = md / 2;
- np[0] = 3;
- p[1][0].x = md - md / 2;
- p[1][0].y = md / 10;
- p[1][1].x = md - md / 2;
- p[1][1].y = md - md / 10;
- p[1][2].x = md - md / 10;
- p[1][2].y = md / 2;
- np[1] = 3;
- break;
- case XmDRAWNB_SQUARE:
- p[0][0].x = md / 3;
- p[0][0].y = md / 3;
- p[0][1].x = md / 3;
- p[0][1].y = md - md / 3;
- p[0][2].x = md - md / 3;
- p[0][2].y = md - md / 3;
- p[0][3].x = md - md / 3;
- p[0][3].y = md / 3;
- np[0] = 4;
- break;
- case XmDRAWNB_DOUBLEBAR:
- p[0][0].x = md / 3;
- p[0][0].y = md / 4;
- p[0][1].x = md / 3;
- p[0][1].y = md - md / 4;
- p[0][2].x = md / 2 - md / 10;
- p[0][2].y = md - md / 4;
- p[0][3].x = md / 2 - md / 10;
- p[0][3].y = md / 4;
- np[0] = 4;
- p[1][0].x = md - md / 3;
- p[1][0].y = md / 4;
- p[1][1].x = md - md / 3;
- p[1][1].y = md - md / 4;
- p[1][2].x = md - md / 2 + md / 10;
- p[1][2].y = md - md / 4;
- p[1][3].x = md - md / 2 + md / 10;
- p[1][3].y = md / 4;
- np[1] = 4;
- break;
- }
- for (i = 0; i < 2; i++)
- {
- avgx = 0;
- avgy = 0;
- for (j = 0; j < np[i]; j++)
- {
- switch (dir)
- {
- case XmDRAWNB_RIGHT:
- /* points unchanged */
- break;
- case XmDRAWNB_LEFT:
- p[i][j].x = md - p[i][j].x;
- break;
- case XmDRAWNB_UP:
- temp = p[i][j].x;
- p[i][j].x = p[i][j].y;
- p[i][j].y = md - temp;
- break;
- case XmDRAWNB_DOWN:
- temp = p[i][j].x;
- p[i][j].x = p[i][j].y;
- p[i][j].y = temp;
- break;
- }
- p[i][j].x += xoff;
- p[i][j].y += yoff;
- avgx += p[i][j].x;
- avgy += p[i][j].y;
- }
- if (!np[i])
- continue;
- avgx /= np[i];
- avgy /= np[i];
- XFillPolygon(dpy, win, gc, p[i], np[i], Nonconvex, CoordModeOrigin);
- p[i][np[i]].x = p[i][0].x;
- p[i][np[i]].y = p[i][0].y;
- for (j = 0; j < np[i]; j++)
- {
- seg.x1 = p[i][j].x;
- seg.y1 = p[i][j].y;
- seg.x2 = p[i][j + 1].x;
- seg.y2 = p[i][j + 1].y;
- if ((seg.x1 <= avgx && seg.x2 <= avgx) ||
- (seg.y1 <= avgy && seg.y2 <= avgy))
- XDrawSegments(dpy, win,
- b->primitive.bottom_shadow_GC, &seg, 1);
- else
- XDrawSegments(dpy, win,
- b->primitive.top_shadow_GC, &seg, 1);
- }
- }
- }
-
- #define XmLDrawNODRAW 0
- #define XmLDrawNOCLIP 1
- #define XmLDrawCLIPPED 2
-
- static int
- XmLDrawCalc(Widget w,
- Dimension width,
- Dimension height,
- unsigned char alignment,
- XRectangle *rect,
- XRectangle *clipRect,
- int *x,
- int *y)
- {
- if (rect->width <= 4 || rect->height <= 4 ||
- clipRect->width < 3 || clipRect->height < 3 ||
- !width || !height ||
- !XtIsRealized(w) ||
- XmLRectIntersect(rect, clipRect) == XmLRectOutside)
- return XmLDrawNODRAW;
- if (alignment == XmALIGNMENT_TOP_LEFT ||
- alignment == XmALIGNMENT_LEFT ||
- alignment == XmALIGNMENT_BOTTOM_LEFT)
- *x = rect->x + 2;
- else if (alignment == XmALIGNMENT_TOP ||
- alignment == XmALIGNMENT_CENTER ||
- alignment == XmALIGNMENT_BOTTOM)
- *x = rect->x + ((int)rect->width - (int)width) / 2;
- else
- *x = rect->x + rect->width - width - 2;
- if (alignment == XmALIGNMENT_TOP ||
- alignment == XmALIGNMENT_TOP_LEFT ||
- alignment == XmALIGNMENT_TOP_RIGHT)
- *y = rect->y + 2;
- else if (alignment == XmALIGNMENT_LEFT ||
- alignment == XmALIGNMENT_CENTER ||
- alignment == XmALIGNMENT_RIGHT)
- *y = rect->y + ((int)rect->height - (int)height) / 2;
- else
- *y = rect->y + rect->height - height - 2;
- if (clipRect->x == rect->x &&
- clipRect->y == rect->y &&
- clipRect->width == rect->width &&
- clipRect->height == rect->height &&
- (int)width + 4 <= (int)clipRect->width &&
- (int)height + 4 <= (int)clipRect->height)
- return XmLDrawNOCLIP;
- return XmLDrawCLIPPED;
- }
-
- void
- XmLDrawToggle(Widget w,
- Boolean state,
- Dimension size,
- unsigned char alignment,
- GC gc,
- Pixel backgroundColor,
- Pixel topColor,
- Pixel bottomColor,
- Pixel checkColor,
- XRectangle *rect,
- XRectangle *clipRect)
- {
- Display *dpy;
- Window win;
- XPoint point[5];
- int x, y, cx[3], cy[4], drawType;
-
- drawType = XmLDrawCalc(w, size, size, alignment, rect, clipRect, &x, &y);
- if (size < 3 || drawType == XmLDrawNODRAW)
- return;
- dpy = XtDisplay(w);
- win = XtWindow(w);
- if (drawType == XmLDrawCLIPPED)
- XSetClipRectangles(dpy, gc, 0, 0, clipRect, 1, Unsorted);
- /* background */
- XSetForeground(dpy, gc, backgroundColor);
- XFillRectangle(dpy, win, gc, x, y, size, size);
- /* box shadow */
- XSetForeground(dpy, gc, topColor);
- point[0].x = x;
- point[0].y = y + size - 1;
- point[1].x = x;
- point[1].y = y;
- point[2].x = x + size - 1;
- point[2].y = y;
- XDrawLines(dpy, win, gc, point, 3, CoordModeOrigin);
- point[1].x = x + size - 1;
- point[1].y = y + size - 1;
- XSetForeground(dpy, gc, bottomColor);
- XDrawLines(dpy, win, gc, point, 3, CoordModeOrigin);
- if (state == True)
- {
- /* check */
- cx[0] = x + 1;
- cx[1] = x + (((int)size - 3) / 3) + 1;
- cx[2] = x + size - 2;
- cy[0] = y + 1;
- cy[1] = y + (((int)size - 3) / 2) + 1;
- cy[2] = y + ((((int)size - 3) * 2) / 3) + 1;
- cy[3] = y + size - 2;
- point[0].x = cx[0];
- point[0].y = cy[1];
- point[1].x = cx[1];
- point[1].y = cy[3];
- point[2].x = cx[2];
- point[2].y = cy[0];
- point[3].x = cx[1];
- point[3].y = cy[2];
- point[4].x = point[0].x;
- point[4].y = point[0].y;
- XSetForeground(dpy, gc, checkColor);
- XFillPolygon(dpy, win, gc, point, 4, Nonconvex, CoordModeOrigin);
- XDrawLines(dpy, win, gc, point, 5, CoordModeOrigin);
- }
- if (drawType == XmLDrawCLIPPED)
- XSetClipMask(dpy, gc, None);
- }
-
- int
- XmLRectIntersect(XRectangle *r1,
- XRectangle *r2)
- {
- if (!r1->width || !r1->height || !r2->width || !r2->height)
- return XmLRectOutside;
- if (r1->x + (int)r1->width - 1 < r2->x ||
- r1->x > r2->x + (int)r2->width - 1 ||
- r1->y + (int)r1->height - 1 < r2->y ||
- r1->y > r2->y + (int)r2->height - 1)
- return XmLRectOutside;
- if (r1->x >= r2->x &&
- r1->x + (int)r1->width <= r2->x + (int)r2->width &&
- r1->y >= r2->y &&
- r1->y + (int)r1->height <= r2->y + (int)r2->height)
- return XmLRectInside; /* r1 inside r2 */
- return XmLRectPartial;
- }
-
-
- XmFontList
- XmLFontListCopyDefault(Widget widget)
- {
- Widget parent;
- XFontStruct *font;
- XmFontList fontList, fl;
-
- fontList = 0;
- parent = XtParent(widget);
- while (parent)
- {
- fl = 0;
- if (XmIsVendorShell(parent) || XmIsMenuShell(parent))
- XtVaGetValues(parent, XmNdefaultFontList, &fl, NULL);
- else if (XmIsBulletinBoard(parent))
- XtVaGetValues(parent, XmNbuttonFontList, &fl, NULL);
- if (fl)
- {
- fontList = XmFontListCopy(fl);
- parent = 0;
- }
- if (parent)
- parent = XtParent(parent);
- }
- if (!fontList)
- {
- font = XLoadQueryFont(XtDisplay(widget), "fixed");
- if (!font)
- XmLWarning(widget,
- "FontListCopyDefault() - FATAL ERROR - can't load fixed font");
- fontList = XmFontListCreate(font, XmSTRING_DEFAULT_CHARSET);
- }
- return fontList;
- }
-
- void
- XmLFontListGetDimensions(XmFontList fontList,
- short *width,
- short *height,
- Boolean useAverageWidth)
- {
- XmStringCharSet charset;
- XmFontContext context;
- XFontStruct *fs;
- short w, h;
- #if XmVersion < 2000
- /* --- begin code to work around Motif 1.x internal bug */
- typedef struct {
- XmFontList nextFontList;
- Boolean unused;
- } XmFontListContextRec;
- typedef struct {
- XFontStruct *font;
- XmStringCharSet unused;
- } XmFontListRec;
- XmFontList nextFontList;
- #endif
-
- *width = 0;
- *height = 0;
- if (XmFontListInitFontContext(&context, fontList))
- {
- while (1)
- {
- #if XmVersion < 2000
- /* --- begin code to work around Motif internal bug */
- /* --- this code must be removed for Motif 2.0 */
- nextFontList = ((XmFontListContextRec *)context)->nextFontList;
- if (!nextFontList)
- break;
- if (!((XmFontListRec *)nextFontList)->font)
- break;
- /* --- end Motif workaround code */
- #endif
- if (XmFontListGetNextFont(context, &charset, &fs) == False)
- break;
- XtFree(charset);
- if (useAverageWidth == True)
- XmLFontGetAverageWidth(fs, &w);
- else
- w = fs->max_bounds.width;
- h = fs->max_bounds.ascent + fs->max_bounds.descent;
- if (*height < h)
- *height = h;
- if (*width < w)
- *width = w;
- }
- XmFontListFreeFontContext(context);
- }
- }
-
- static void
- XmLFontGetAverageWidth(XFontStruct *fs,
- short *width)
- {
- long aw, n;
- int r, c, mm, i;
- XCharStruct *cs;
-
- n = 0;
- aw = 0;
- mm = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
- for (r = fs->min_byte1; r <= fs->max_byte1; r++)
- for (c = fs->min_char_or_byte2; c <= fs->max_char_or_byte2; c++)
- {
- if (!fs->per_char)
- continue;
- i = ((r - fs->min_byte1) * mm) + (c - fs->min_char_or_byte2);
- cs = &fs->per_char[i];
- if (!cs->width)
- continue;
- aw += cs->width;
- n++;
- }
- if (n)
- aw = aw / n;
- else
- aw = fs->min_bounds.width;
- *width = (short)aw;
- }
-
- int _XmLKey;
-
- void XmLInitialize(void)
- {
- static int first = 1;
-
- if (!first)
- return;
- first = 0;
-
- #ifdef XmLEVAL
- fprintf(stderr, "XmL: This is an evalation version of the Microline\n");
- fprintf(stderr, "XmL: Widget Library. Some features are disabled.\n");
- #endif
-
- #ifdef XmLJAVA
- if (_XmLKey != 444)
- {
- fprintf(stderr, "XmL: Error: This version of the library will only");
- fprintf(stderr, "XmL: work with JAVA.\n");
- exit(0);
- }
- #endif
- }
-
- int
- XmLMessageBox(Widget w,
- char *string,
- Boolean okOnly)
- {
- int status = 0;
- Widget dialog, shell;
- Arg args[3];
- XtAppContext context;
- XmString str, titleStr;
- String shellTitle;
- Atom WM_DELETE_WINDOW;
-
- str = XmStringCreateLtoR(string, XmSTRING_DEFAULT_CHARSET);
- XtSetArg(args[0], XmNmessageString, str);
- XtSetArg(args[1], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL);
- shell = XmLShellOfWidget(w);
- if (shell)
- XtVaGetValues(shell, XmNtitle, &shellTitle, NULL);
- if (shell && shellTitle)
- titleStr = XmStringCreateLtoR(shellTitle,
- XmSTRING_DEFAULT_CHARSET);
- else
- titleStr = XmStringCreateSimple("Notice");
- XtSetArg(args[2], XmNdialogTitle, titleStr);
- if (okOnly == True)
- dialog = XmCreateMessageDialog(XtParent(w), "popup", args, 3);
- else
- dialog = XmCreateQuestionDialog(XtParent(w), "popup", args, 3);
- WM_DELETE_WINDOW = XmInternAtom(XtDisplay(w), "WM_DELETE_WINDOW",
- False);
- XmAddWMProtocolCallback(shell, WM_DELETE_WINDOW, XmLMessageBoxWMDelete,
- (caddr_t)&status);
- XmStringFree(str);
- XmStringFree(titleStr);
- XtAddCallback(dialog, XmNokCallback, XmLMessageBoxResponse,
- (XtPointer)&status);
- if (okOnly == True)
- {
- XtUnmanageChild(XmMessageBoxGetChild(dialog,
- XmDIALOG_CANCEL_BUTTON));
- XtUnmanageChild(XmMessageBoxGetChild(dialog,
- XmDIALOG_HELP_BUTTON));
- }
- else
- {
- XtAddCallback(dialog, XmNcancelCallback, XmLMessageBoxResponse,
- (XtPointer)&status);
- XtAddCallback(dialog, XmNhelpCallback, XmLMessageBoxResponse,
- (XtPointer)&status);
- }
- XtManageChild(dialog);
-
- context = XtWidgetToApplicationContext(w);
- while (!status || XtAppPending(context))
- XtAppProcessEvent(context, XtIMAll);
- XtDestroyWidget(dialog);
- return status;
- }
-
- static void
- XmLMessageBoxWMDelete(Widget w,
- XtPointer clientData,
- XtPointer callData)
- {
- int *status = (int *)clientData;
- *status = 1;
- }
-
- static void
- XmLMessageBoxResponse(Widget w,
- XtPointer clientData,
- XtPointer callData)
- {
- int *status = (int *)clientData;
- XmAnyCallbackStruct *reason;
-
- reason = (XmAnyCallbackStruct *)callData;
- switch (reason->reason)
- {
- case XmCR_OK:
- *status = 1;
- break;
- case XmCR_CANCEL:
- *status = 2;
- break;
- case XmCR_HELP:
- *status = 3;
- break;
- }
- }
-
- void
- XmLPixmapDraw(Widget w,
- Pixmap pixmap,
- Pixmap pixmask,
- int pixmapWidth,
- int pixmapHeight,
- unsigned char alignment,
- GC gc,
- XRectangle *rect,
- XRectangle *clipRect)
- {
- Display *dpy;
- Window win;
- int px, py, x, y, width, height, drawType;
-
- if (pixmap == XmUNSPECIFIED_PIXMAP)
- return;
- dpy = XtDisplay(w);
- win = XtWindow(w);
- width = pixmapWidth;
- height = pixmapHeight;
- if (!width || !height)
- {
- alignment = XmALIGNMENT_TOP_LEFT;
- width = clipRect->width - 4;
- height = clipRect->height - 4;
- }
- drawType = XmLDrawCalc(w, width, height, alignment,
- rect, clipRect, &x, &y);
- if (drawType == XmLDrawNODRAW)
- return;
- px = 0;
- py = 0;
- /* clip top */
- if (clipRect->y > y && clipRect->y < y + height - 1)
- {
- py = clipRect->y - y;
- y += py;
- height -= py;
- }
- /* clip bottom */
- if (clipRect->y + (int)clipRect->height - 1 >= y &&
- clipRect->y + (int)clipRect->height - 1 <= y + height - 1)
- height = clipRect->y + clipRect->height - y;
- /* clip left */
- if (clipRect->x > x && clipRect->x < x + width - 1)
- {
- px = clipRect->x - x;
- x += px;
- width -= px;
- }
- /* clip right */
- if (clipRect->x + (int)clipRect->width - 1 >= x &&
- clipRect->x + (int)clipRect->width - 1 <= x + width - 1)
- width = clipRect->x + clipRect->width - x;
-
- if (pixmask != XmUNSPECIFIED_PIXMAP)
- {
- XSetClipMask(dpy, gc, pixmask);
- XSetClipOrigin(dpy, gc, x - px, y - py);
- }
- XSetGraphicsExposures(dpy, gc, False);
- XCopyArea(dpy, pixmap, win, gc, px, py, width, height, x, y);
- XSetGraphicsExposures(dpy, gc, True);
- if (pixmask != XmUNSPECIFIED_PIXMAP)
- {
- XSetClipMask(dpy, gc, None);
- XSetClipOrigin(dpy, gc, 0, 0);
- }
- }
-
- Widget
- XmLShellOfWidget(Widget w)
- {
- while(1)
- {
- if (!w)
- return 0;
- if (XtIsSubclass(w, shellWidgetClass))
- return w;
- w = XtParent(w);
- }
- }
-
- static XmLSortCompareFunc XmLSortCompare;
- static int XmLSortEleSize;
- static void *XmLSortUserData;
-
- void
- XmLSort(void *base,
- int numItems,
- unsigned int itemSize,
- XmLSortCompareFunc compare,
- void *userData)
- {
- XmLSortCompareFunc oldCompare;
- int oldEleSize;
- void *oldUserData;
- char *lvec, *rvec;
-
- if (numItems < 2)
- return;
-
- /* for sorts within a sort compare function, we must
- save any global sort variables on the local stack
- and restore them when finished */
- oldCompare = XmLSortCompare;
- oldEleSize = XmLSortEleSize;
- oldUserData = XmLSortUserData;
- XmLSortCompare = compare;
- XmLSortEleSize = itemSize;
- XmLSortUserData = userData;
-
- lvec = (char *)base;
- rvec = lvec + (numItems - 1) * itemSize;
- XmLSortFunc(lvec, rvec);
-
- XmLSortCompare = oldCompare;
- XmLSortEleSize = oldEleSize;
- XmLSortUserData = oldUserData;
- }
-
- #define SWAP(p1, p2) \
- { \
- if (p1 != p2) \
- { \
- int zi; \
- char zc; \
- for (zi = 0; zi < XmLSortEleSize; zi++) \
- { \
- zc = (p1)[zi]; \
- (p1)[zi] = (p2)[zi]; \
- (p2)[zi] = zc; \
- } \
- }\
- }
-
- static void
- XmLSortFunc(char *lvec,
- char *rvec)
- {
- int i;
- char *nlvec, *nrvec, *pvec;
-
- start:
- i = (*XmLSortCompare)(XmLSortUserData, lvec, rvec);
-
- /* two item sort */
- if (rvec == lvec + XmLSortEleSize)
- {
- if (i > 0)
- SWAP(lvec, rvec)
- return;
- }
-
- /* find mid of three items */
- pvec = lvec + ((rvec - lvec) / (XmLSortEleSize * 2)) * XmLSortEleSize;
- if (i < 0)
- {
- i = (*XmLSortCompare)(XmLSortUserData, lvec, pvec);
- if (i > 0)
- pvec = lvec;
- else if (i == 0)
- pvec = rvec;
- }
- else if (i > 0)
- {
- i = (*XmLSortCompare)(XmLSortUserData, rvec, pvec);
- if (i > 0)
- pvec = rvec;
- else if (i == 0)
- pvec = lvec;
- }
- else
- {
- pvec = lvec + XmLSortEleSize;
- while (1)
- {
- i = (*XmLSortCompare)(XmLSortUserData, lvec, pvec);
- if (i < 0)
- break;
- else if (i > 0)
- {
- pvec = lvec;
- break;
- }
- if (pvec == rvec)
- return;
- pvec += XmLSortEleSize;
- }
- }
-
- /* partition the set */
- nlvec = lvec;
- nrvec = rvec;
- while (1)
- {
- if (pvec == nrvec)
- pvec = nlvec;
- else if (pvec == nlvec)
- pvec = nrvec;
- SWAP(nrvec, nlvec)
- while ((*XmLSortCompare)(XmLSortUserData, nlvec, pvec) < 0)
- nlvec += XmLSortEleSize;
- while ((*XmLSortCompare)(XmLSortUserData, nrvec, pvec) >= 0)
- nrvec -= XmLSortEleSize;
- if (nlvec > nrvec)
- break;
- }
-
- /* sort partitioned sets */
- if (lvec < nlvec - XmLSortEleSize)
- XmLSortFunc(lvec, nlvec - XmLSortEleSize);
- if (nlvec < rvec)
- {
- lvec = nlvec;
- goto start;
- }
- }
-
- void
- XmLStringDraw(Widget w,
- XmString string,
- XmStringDirection stringDir,
- XmFontList fontList,
- unsigned char alignment,
- GC gc,
- XRectangle *rect,
- XRectangle *clipRect)
- {
- Display *dpy;
- Window win;
- Dimension width, height;
- int x, y, drawType;
- unsigned char strAlignment;
-
- if (!string)
- return;
- dpy = XtDisplay(w);
- win = XtWindow(w);
- XmStringExtent(fontList, string, &width, &height);
- drawType = XmLDrawCalc(w, width, height, alignment,
- rect, clipRect, &x, &y);
- if (drawType == XmLDrawNODRAW)
- return;
- x = rect->x + 2;
- if (alignment == XmALIGNMENT_LEFT ||
- alignment == XmALIGNMENT_TOP_LEFT ||
- alignment == XmALIGNMENT_BOTTOM_LEFT)
- strAlignment = XmALIGNMENT_BEGINNING;
- else if (alignment == XmALIGNMENT_CENTER ||
- alignment == XmALIGNMENT_TOP ||
- alignment == XmALIGNMENT_BOTTOM)
- strAlignment = XmALIGNMENT_CENTER;
- else
- strAlignment = XmALIGNMENT_END;
- /* XmStringDraw clipping doesnt work in all cases
- so we use a clip region for clipping */
- if (drawType == XmLDrawCLIPPED)
- XSetClipRectangles(dpy, gc, 0, 0, clipRect, 1, Unsorted);
- XmStringDraw(dpy, win, fontList, string, gc,
- x, y, rect->width - 4, strAlignment, stringDir, clipRect);
- if (drawType == XmLDrawCLIPPED)
- XSetClipMask(dpy, gc, None);
- }
-
- void
- XmLStringDrawDirection(Display *dpy,
- Window win,
- XmFontList fontlist,
- XmString string,
- GC gc,
- int x,
- int y,
- Dimension width,
- unsigned char alignment,
- unsigned char layout_direction,
- unsigned char drawing_direction)
- {
- Screen *screen;
- XFontStruct *fontStruct;
- XImage *sourceImage, *destImage;
- Pixmap pixmap;
- GC pixmapGC;
- /* int sourceWidth, sourceHeight;*/
- int destWidth, destHeight;
- int stringWidth, stringHeight;
- int i, j, bytesPerLine;
- Dimension dW, dH;
- char *data;
-
- screen = DefaultScreenOfDisplay(dpy);
- XmStringExtent(fontlist, string, &dW, &dH);
- stringWidth = (int)dW;
- stringHeight = (int)dH;
- if (!stringWidth || !stringHeight)
- return;
-
- /* draw string into 1 bit deep pixmap */
- pixmap = XCreatePixmap(dpy, win, stringWidth, stringHeight, 1);
- pixmapGC = XCreateGC(dpy, pixmap, 0, NULL);
- fontStruct = XLoadQueryFont(dpy, "fixed");
- if (!fontStruct)
- {
- fprintf(stderr, "XmLStringDrawDirection: error - ");
- fprintf(stderr, "can't load fixed font\n");
- return;
- }
- XSetFont(dpy, pixmapGC, fontStruct->fid);
- XSetBackground(dpy, pixmapGC, 0L);
- XSetForeground(dpy, pixmapGC, 0L);
- XFillRectangle(dpy, pixmap, pixmapGC, 0, 0, stringWidth, stringHeight);
- XSetForeground(dpy, pixmapGC, 1L);
- XmStringDraw(dpy, pixmap, fontlist, string, pixmapGC, 0, 0, stringWidth,
- XmALIGNMENT_BEGINNING, layout_direction, 0);
- XFreeFont(dpy, fontStruct);
-
- /* copy 1 bit deep pixmap into source image */
- sourceImage = XGetImage(dpy, pixmap, 0, 0, stringWidth, stringHeight,
- 1, XYPixmap);
- XFreePixmap(dpy, pixmap);
-
- /* draw rotated text into destination image */
- if (drawing_direction == XmSTRING_UP || drawing_direction == XmSTRING_DOWN)
- {
- destWidth = stringHeight;
- destHeight = stringWidth;
- }
- else
- {
- destWidth = stringWidth;
- destHeight = stringHeight;
- }
- bytesPerLine = (destWidth - 1) / 8 + 1;
- data = (char *)malloc(bytesPerLine * destHeight);
- destImage = XCreateImage(dpy, DefaultVisualOfScreen(screen),
- 1, XYBitmap, 0, data, destWidth, destHeight, 8, 0);
- for (i = 0; i < stringWidth; i++)
- for (j = 0; j < stringHeight; j++)
- {
- if (drawing_direction == XmSTRING_UP)
- XPutPixel(destImage, j, i,
- XGetPixel(sourceImage, stringWidth - i - 1, j));
- else if (drawing_direction == XmSTRING_DOWN)
- XPutPixel(destImage, stringHeight - j - 1, stringWidth - i - 1,
- XGetPixel(sourceImage, stringWidth - i - 1, j));
- else if (drawing_direction == XmSTRING_LEFT)
- XPutPixel(destImage, i, stringHeight - j - 1,
- XGetPixel(sourceImage, stringWidth - i - 1, j));
- else
- XPutPixel(destImage, i, j,
- XGetPixel(sourceImage, i, j));
- }
- XDestroyImage(sourceImage);
-
- /* copy rotated image into 1 bit deep pixmap */
- pixmap = XCreatePixmap(dpy, win, destWidth, destHeight, 1);
- XPutImage(dpy, pixmap, pixmapGC, destImage, 0, 0, 0, 0,
- destWidth, destHeight);
- XDestroyImage(destImage);
- XFreeGC(dpy, pixmapGC);
-
- /* adjust position for alignment */
- if (drawing_direction == XmSTRING_UP || drawing_direction == XmSTRING_DOWN)
- {
- if (alignment == XmALIGNMENT_BEGINNING)
- ;
- else if (alignment == XmALIGNMENT_CENTER)
- y += width / 2 - stringWidth / 2;
- else if (alignment == XmALIGNMENT_END)
- y += (int)width - stringWidth;
- }
- else
- {
- if (alignment == XmALIGNMENT_BEGINNING)
- ;
- else if (alignment == XmALIGNMENT_CENTER)
- x += width / 2 - stringWidth / 2;
- else if (alignment == XmALIGNMENT_END)
- x += (int)width - stringWidth;
- }
-
- /* draw the pixmap as a stipple in the window */
- XSetStipple(dpy, gc, pixmap);
- XSetFillStyle(dpy, gc, FillStippled);
- XSetTSOrigin(dpy, gc, x % destWidth, y % destHeight);
- XFillRectangle(dpy, win, gc, x, y, destWidth, destHeight);
- XFreePixmap(dpy, pixmap);
- XSetFillStyle(dpy, gc, FillSolid);
- }
-
- void
- XmLWarning(Widget w,
- char *msg)
- {
- XtAppContext app;
- char s[512], *cname, *name;
- WidgetClass c;
-
- app = XtWidgetToApplicationContext(w);
- name = XtName(w);
- if (!name)
- name = "[No Name]";
- c = XtClass(w);
- cname = c->core_class.class_name;
- if (!cname)
- cname = "[No Class]";
- sprintf(s, "%s: %s: %s\n", cname, name, msg);
- XtAppWarning(app, s);
- }
-