/* * Motif Tools Library, Version 3.1 * $Id: LayoutString.c,v 1.2 2001/10/29 16:27:45 andre Exp $ * * Written by David Flanagan. * Copyright (c) 1992-2001 by David Flanagan. * All Rights Reserved. See the file COPYRIGHT for details. * This is open source software. See the file LICENSE for details. * There is no warranty for this software. See NO_WARRANTY for details. * * $Log: LayoutString.c,v $ * Revision 1.2 2001/10/29 16:27:45 andre * AA-2001-10-29-0: Fix for weired characters in helper dialogs (PE,Project Configi, Calendar, Cluster Config, * Complex Config) * Queue Control Reschedule functionality added (corresponds qmod -r ) * Cluster config Reschedule Unknown bug fixed * Job Custom dialogue core dump fix * * Revision 1.1.1.1 2001/07/18 11:06:02 root * Initial checkin. * * Revision 1.2 2001/06/12 16:25:28 andre * *** empty log message *** * * */ #include #include #include /* an empty string value unique to us. */ static char empty_string[] = ""; #define offset(field) XtOffsetOf(XmtLayoutStringRec, layout_string.field) static XtResource resources[] = { {XmtNlabel, XtCLabel, XtRString, sizeof(String), offset(label), XtRString, (XtPointer) empty_string}, {XmtNlabelString, XmCLabelString, XmRXmString, sizeof(XmString), offset(label_string), XmRXmString, (XtPointer)NULL}, {XmtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), offset(foreground), XtRImmediate, (XtPointer) -1}, {XmtNbackground, XtCBackground, XtRPixel, sizeof(Pixel), offset(background), XtRImmediate, (XtPointer) -1} }; #undef offset #if NeedFunctionPrototypes static void Initialize(Widget, Widget, ArgList, Cardinal *); static void Destroy(Widget); static Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal *); static void Redisplay(Widget, XEvent *, Region); static XtGeometryResult QueryGeometry(Widget, XtWidgetGeometry *, XtWidgetGeometry *); static void ChangeFont(Widget); #else static void Initialize(); static void Destroy(); static Boolean SetValues(); static void Redisplay(); static XtGeometryResult QueryGeometry(); static void ChangeFont(); #endif #define superclass (&xmtLayoutGadgetClassRec) externaldef(xmtlayoutstringclasrec) XmtLayoutStringClassRec xmtLayoutStringClassRec = { { /* rect_class fields */ /* superclass */ (WidgetClass)superclass, /* class_name */ "XmtLayoutString", /* widget_size */ sizeof(XmtLayoutStringRec), /* class_initialize */ NULL, /* class_part_initialize*/ NULL, /* class_inited */ FALSE, /* initialize */ Initialize, /* initialize_hook */ NULL, /* rect1 */ NULL, /* rect2 */ NULL, /* rect3 */ 0, /* resources */ resources, /* num_resources */ XtNumber(resources), /* xrm_class */ NULLQUARK, /* rect4 */ FALSE, /* rect5 */ FALSE, /* rect6 */ FALSE, /* rect7 */ FALSE, /* destroy */ Destroy, /* resize */ NULL, /* expose */ Redisplay, /* set_values */ SetValues, /* set_values_hook */ NULL, /* set_values_almost */ XtInheritSetValuesAlmost, /* get_values_hook */ NULL, /* rect9 */ NULL, /* version */ XtVersion, /* callback_offsets */ NULL, /* rect10 */ NULL, /* query_geometry */ QueryGeometry, /* rect11 */ NULL, /* extension */ NULL }, { /* XmtLayoutGadget field */ /* change_font */ ChangeFont, }, { /* XmtLayoutString fields */ /* extension */ NULL } }; externaldef(xmtlayoutstringgadgetclass) WidgetClass xmtLayoutStringGadgetClass = (WidgetClass)&xmtLayoutStringClassRec; #define MARGINWIDTH 2 #define MARGINHEIGHT 2 #if NeedFunctionPrototypes static void GetGC(XmtLayoutWidget lw, XmtLayoutStringGadget ls) #else static void GetGC(lw, ls) XmtLayoutWidget lw; XmtLayoutStringGadget ls; #endif { XGCValues gcv; if ((ls->layout_string.foreground == -1) || (ls->layout_string.foreground == lw->manager.foreground)) ls->layout_string.gc = None; else { gcv.foreground = ls->layout_string.foreground; /* a background for XmStringDrawImage (& Motif2.0 renditions) */ if (ls->layout_string.background != -1) gcv.background = ls->layout_string.background; else gcv.background = lw->core.background_pixel; /* we need to specify some font so XmDrawString() doesn't barf */ gcv.font = lw->layout.font->fid; ls->layout_string.gc = XtGetGC((Widget)ls, GCForeground | GCBackground | GCFont, &gcv); } } #if NeedFunctionPrototypes static void GetBackgroundGC(XmtLayoutWidget lw, XmtLayoutStringGadget ls) #else static void GetBackgroundGC(lw, ls) XmtLayoutWidget lw; XmtLayoutStringGadget ls; #endif { XGCValues gcv; if ((ls->layout_string.background == -1) || (ls->layout_string.background == lw->core.background_pixel)) ls->layout_string.background_gc = NULL; else { gcv.foreground = ls->layout_string.background; ls->layout_string.background_gc = XtGetGC((Widget)ls, GCForeground, &gcv); } } #if NeedFunctionPrototypes static void MeasureString(XmtLayoutWidget lw, XmtLayoutStringGadget ls) #else static void MeasureString(lw, ls) XmtLayoutWidget lw; XmtLayoutStringGadget ls; #endif { if (ls->layout_string.label_string) #if XmVersion < 2000 XmStringExtent(lw->layout.font_list, ls->layout_string.label_string, &ls->layout_string.width, &ls->layout_string.height); #else /* Motif 2.0 or later */ XmStringExtent(lw->layout.render_table, ls->layout_string.label_string, &ls->layout_string.width, &ls->layout_string.height); #endif else ls->layout_string.width = ls->layout_string.height = 0; ls->layout_string.width += 2*MARGINWIDTH; ls->layout_string.height += 2*MARGINHEIGHT; } #if NeedFunctionPrototypes static void ChangeFont(Widget w) #else static void ChangeFont(w) Widget w; #endif { XmtLayoutWidget lw = (XmtLayoutWidget)XtParent(w); XmtLayoutStringGadget ls = (XmtLayoutStringGadget)w; MeasureString(lw, ls); } /* ARGSUSED */ #if NeedFunctionPrototypes static void Initialize(Widget request, Widget init, ArgList arglist, Cardinal *num_args) #else static void Initialize(request, init, arglist, num_args) Widget request; Widget init; ArgList arglist; Cardinal *num_args; #endif { XmtLayoutStringGadget ls = (XmtLayoutStringGadget) init; XmtLayoutWidget lw = (XmtLayoutWidget) XtParent(init); Constraint(ls, type) = XmtLayoutString; /* copy the XmString, if specified */ if (ls->layout_string.label_string) ls->layout_string.label_string = XmStringCopy(ls->layout_string.label_string); else if (ls->layout_string.label) { /* we don't copy the string; just convert it to an XmString */ /* and then set it to "" because we don't own it. */ ls->layout_string.label_string = XmtCreateLocalizedXmString((Widget) lw, ls->layout_string.label); ls->layout_string.label = empty_string; } MeasureString(lw, ls); GetGC(lw, ls); GetBackgroundGC(lw, ls); } #if NeedFunctionPrototypes static void Destroy(Widget w) #else static void Destroy(w) Widget w; #endif { XmtLayoutStringGadget ls = (XmtLayoutStringGadget) w; if (ls->layout_string.label_string) XmStringFree(ls->layout_string.label_string); if (ls->layout_string.gc) XtReleaseGC(w, ls->layout_string.gc); if (ls->layout_string.background_gc) XtReleaseGC(w, ls->layout_string.background_gc); } /* ARGSUSED */ #if NeedFunctionPrototypes static Boolean SetValues(Widget current, Widget request, Widget set, ArgList arglist, Cardinal *num_args) #else static Boolean SetValues(current, request, set, arglist, num_args) Widget current; Widget request; Widget set; ArgList arglist; Cardinal *num_args; #endif { XmtLayoutStringGadget cs = (XmtLayoutStringGadget) current; XmtLayoutStringGadget ss = (XmtLayoutStringGadget) set; XmtLayoutWidget lw = (XmtLayoutWidget) XtParent(set); Boolean redisplay = False; Boolean relayout = False; Dimension cs_width, cs_height; if (ss->layout_string.label_string != cs->layout_string.label_string) { if (cs->layout_string.label_string) XmStringFree(cs->layout_string.label_string); if (ss->layout_string.label_string) ss->layout_string.label_string = XmStringCopy(ss->layout_string.label_string); cs_width = cs->layout_string.width; cs_height = cs->layout_string.height; MeasureString(lw, ss); if (cs_width != ss->layout_string.width || cs_height != ss->layout_string.height) relayout = True; else redisplay = True; } else if (ss->layout_string.label != empty_string) { if (cs->layout_string.label_string) XmStringFree(cs->layout_string.label_string); ss->layout_string.label_string = XmtCreateLocalizedXmString((Widget) lw, ss->layout_string.label); ss->layout_string.label = empty_string; cs_width = cs->layout_string.width; cs_height = cs->layout_string.height; MeasureString(lw, ss); if (cs_width != ss->layout_string.width || cs_height != ss->layout_string.height) relayout = True; else redisplay = True; } if (ss->layout_string.foreground != cs->layout_string.foreground) { if (ss->layout_string.gc) XtReleaseGC(set, ss->layout_string.gc); GetGC(lw, ss); redisplay = True; } if (ss->layout_string.background != cs->layout_string.background) { if (ss->layout_string.background_gc) XtReleaseGC(set, ss->layout_string.gc); GetBackgroundGC(lw, ss); redisplay = True; } /* * If the string has changed, then everything will need to be updated. * Instead of calling _XmtLayoutChildren() directly, though, we just * set our core.width and core.height fields to their new values, * The new size will be noticed in Layout.c:ConstraintSetValues(), * and _XmtLayoutChildren() will be invoked there. This way, if the * string changes, but the size stays the same, no change will be made. */ if (relayout) { /* _XmtLayoutChildren(lw, True); */ ss->rectangle.width = ss->layout_string.width; ss->rectangle.height = ss->layout_string.height; } /* * Returning True from this procedure doesn't do any good, presumably * because the Intrinsics think that we're an Object, not a RectObj * (This is one of the gross Motif hacks, described in Layout.c) * So we generate an Expose event ourselves. */ if (redisplay && XtIsRealized((Widget)lw)) { Redisplay((Widget)ss, (XEvent *)NULL, (Region)NULL); } else if ( relayout && XtIsRealized((Widget)lw)) { XClearArea(XtDisplay((Widget)lw), XtWindow((Widget)lw), cs->rectangle.x, cs->rectangle.y, cs->rectangle.width, cs->rectangle.height, True); } return False; } /* ARGSUSED */ #if NeedFunctionPrototypes static XtGeometryResult QueryGeometry(Widget w, XtWidgetGeometry *request, XtWidgetGeometry *reply) #else static XtGeometryResult QueryGeometry(w, request, reply) Widget w; XtWidgetGeometry *request; XtWidgetGeometry *reply; #endif { XmtLayoutStringGadget ls = (XmtLayoutStringGadget) w; reply->request_mode = CWWidth | CWHeight; reply->width = ls->layout_string.width; reply->height = ls->layout_string.height; return XtGeometryYes; } /* ARGSUSED */ #if NeedFunctionPrototypes static void Redisplay(Widget w, XEvent *event, Region region) #else static void Redisplay(w, event, region) Widget w; XEvent *event; Region region; #endif { XmtLayoutStringGadget ls = (XmtLayoutStringGadget) w; XmtLayoutWidget lw = (XmtLayoutWidget) XtParent(w); if (lw->core.window == None) return; if (ls->layout_string.background_gc) XFillRectangle(XtDisplay((Widget)lw), XtWindow((Widget)lw), ls->layout_string.background_gc, ls->rectangle.x, ls->rectangle.y, ls->rectangle.width, ls->rectangle.height); XmStringDrawImage(lw->core.screen->display, lw->core.window, #if XmVersion < 2000 lw->layout.font_list, #else /* Motif 2.0 or later */ lw->layout.render_table, #endif ls->layout_string.label_string, (ls->layout_string.gc?ls->layout_string.gc:lw->layout.gc), ls->rectangle.x + MARGINWIDTH, ls->rectangle.y + MARGINHEIGHT, ls->rectangle.width - 2*MARGINWIDTH, XmALIGNMENT_BEGINNING, XmSTRING_DIRECTION_L_TO_R, NULL); } #if NeedFunctionPrototypes Widget XmtCreateLayoutString(Widget parent, String name, ArgList arglist, Cardinal num_args) #else Widget XmtCreateLayoutString(parent, name, arglist, num_args) Widget parent; String name; ArgList arglist; Cardinal num_args; #endif { return XtCreateWidget(name, xmtLayoutStringGadgetClass, parent, arglist, num_args); }