Mercurial > kinput2.yaz
diff lib/ICLabel.c @ 0:92745d501b9a
initial import from kinput2-v3.1
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Mon, 08 Mar 2010 04:44:30 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/ICLabel.c Mon Mar 08 04:44:30 2010 +0900 @@ -0,0 +1,365 @@ +#ifndef lint +static char *rcsid = "$Id: ICLabel.c,v 1.11 1991/09/23 04:01:20 ishisone Rel $"; +#endif +/* + * Copyright (c) 1990 Software Research Associates, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Software Research Associates not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Software Research + * Associates makes no representations about the suitability of this software + * for any purpose. It is provided "as is" without express or implied + * warranty. + * + * Author: Makoto Ishisone, Software Research Associates, Inc., Japan + */ + +#include <X11/IntrinsicP.h> +#include <X11/StringDefs.h> +#include <X11/Xmu/Converters.h> +#if XtSpecificationRelease > 4 +#include <X11/Xfuncs.h> +#endif +#include "ICLabelP.h" +#include "ConvDisp.h" + +static XtResource resources[] = { +#define offset(field) XtOffset(ICLabelWidget, iclabel.field) + { XtNhorizontalSpacing, XtCSpacing, XtRDimension, sizeof(Dimension), + offset(hspace), XtRString, "1" }, + { XtNverticalSpacing, XtCSpacing, XtRDimension, sizeof(Dimension), + offset(vspace), XtRString, "1" }, + { XtNlabel, XtCLabel, XtRPointer, sizeof(ICString*), + offset(label), XtRImmediate, NULL }, + { XtNjustify, XtCJustify, XtRJustify, sizeof(XtJustify), + offset(justify), XtRImmediate, (XtPointer)XtJustifyCenter }, + { XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor), + offset(cursor), XtRImmediate, (XtPointer)None }, +#undef offset +}; + +static void ClassInitialize(); +static void Initialize(), Destroy(); +static void Realize(); +static void Redisplay(); +static Boolean SetValues(); +static XtGeometryResult QueryGeometry(); +static void InsertChild(); + +static void computeSize(); +static ICString *copyString(); +static void freeString(); + +static CompositeClassExtensionRec CompositeExtension = { + /* next_extension */ NULL, + /* record_type */ NULLQUARK, + /* version */ XtCompositeExtensionVersion, + /* record_size */ sizeof(CompositeClassExtensionRec), + /* accept_objects */ True, +}; + +ICLabelClassRec icLabelClassRec = { + { /* core fields */ + /* superclass */ (WidgetClass) &compositeClassRec, + /* class_name */ "ICLabel", + /* widget_size */ sizeof(ICLabelRec), + /* class_initialize */ ClassInitialize, + /* class_part_initialize */ NULL, + /* class_inited */ FALSE, + /* initialize */ Initialize, + /* initialize_hook */ NULL, + /* realize */ Realize, + /* actions */ NULL, + /* num_actions */ 0, + /* resources */ resources, + /* num_resources */ XtNumber(resources), + /* xrm_class */ NULLQUARK, + /* compress_motion */ TRUE, + /* compress_exposure */ TRUE, + /* compress_enterleave */ TRUE, + /* visible_interest */ FALSE, + /* destroy */ Destroy, + /* resize */ NULL, + /* expose */ Redisplay, + /* set_values */ SetValues, + /* set_values_hook */ NULL, + /* set_values_almost */ XtInheritSetValuesAlmost, + /* get_values_hook */ NULL, + /* accept_focus */ NULL, + /* version */ XtVersion, + /* callback_private */ NULL, + /* tm_table */ NULL, + /* query_geometry */ QueryGeometry, + /* display_accelerator */ XtInheritDisplayAccelerator, + /* extension */ NULL + }, + { /* composite fields */ + /* geometry_manager */ NULL, + /* change_managed */ NULL, + /* insert_child */ InsertChild, + /* delete_child */ XtInheritDeleteChild, + /* extension */ (XtPointer)&CompositeExtension, + }, + { /* iclabel fields */ + /* empty */ 0 + } +}; + +WidgetClass icLabelWidgetClass = (WidgetClass)&icLabelClassRec; + +static void +ClassInitialize() +{ + XtAddConverter(XtRString, XtRJustify, XmuCvtStringToJustify, NULL, 0); +} + +/* ARGSUSED */ +static void +Initialize(req, new, args, num_args) +Widget req; +Widget new; +ArgList args; +Cardinal *num_args; +{ + ICLabelWidget iclw = (ICLabelWidget)new; + + if (iclw->iclabel.label != NULL) { + iclw->iclabel.label = copyString(iclw->iclabel.label); + } + iclw->iclabel.width = 0; +} + +static void +Destroy(w) +Widget w; +{ + ICLabelWidget iclw = (ICLabelWidget)w; + + if (iclw->iclabel.label != NULL) freeString(iclw->iclabel.label); +} + +static void +Realize(w, maskp, attr) +Widget w; +XtValueMask *maskp; +XSetWindowAttributes *attr; +{ + ICLabelWidget iclw = (ICLabelWidget)w; + + if (iclw->iclabel.cursor != None) { + *maskp |= CWCursor; + attr->cursor = iclw->iclabel.cursor; + } + (*icLabelWidgetClass->core_class.superclass->core_class.realize)(w, maskp, attr); +} + +/* ARGSUSED */ +static void +Redisplay(w, ev, region) +Widget w; +XEvent *ev; +Region region; +{ + ICLabelWidget iclw = (ICLabelWidget)w; + Widget dispobj = iclw->iclabel.displayobj; + int x, y; + + if (iclw->iclabel.label == NULL || iclw->iclabel.displayobj == NULL) return; + + switch (iclw->iclabel.justify) { + case XtJustifyLeft: + x = iclw->iclabel.hspace; + break; + case XtJustifyRight: + x = iclw->core.width - (iclw->iclabel.vspace + iclw->iclabel.width); + break; + case XtJustifyCenter: + default: + x = (iclw->core.width - iclw->iclabel.width) / 2; + break; + } + y = (iclw->core.height - iclw->iclabel.fontheight) / 2; + + CDDrawString(dispobj, w, iclw->iclabel.label, 0, -1, x, y); +} + +/* ARGSUSED */ +static Boolean +SetValues(cur, req, wid, args, num_args) +Widget cur; +Widget req; +Widget wid; +ArgList args; +Cardinal *num_args; +{ + ICLabelWidget old = (ICLabelWidget)cur; + ICLabelWidget new = (ICLabelWidget)wid; + Boolean widthspecified = False; + Boolean heightspecified = False; + Boolean redisplay = False; + Boolean label_changed = False; + int i; + + for (i = 0; i < *num_args; i++) { + if (!strcmp(args->name, XtNwidth)) widthspecified = True; + else if (!strcmp(args->name, XtNheight)) heightspecified = True; + } + + if (new->iclabel.label != old->iclabel.label) { + /* compute maximum pixel width of the list items */ + if (old->iclabel.label != NULL) freeString(old->iclabel.label); + if (new->iclabel.label != NULL) { + new->iclabel.label = copyString(new->iclabel.label); + if (new->iclabel.displayobj != NULL) { + new->iclabel.width = CDStringWidth(new->iclabel.displayobj, + new->iclabel.label, 0, -1); + } + } else { + new->iclabel.width = 0; + } + label_changed = True; + redisplay = True; + } + + if (new->iclabel.hspace != old->iclabel.hspace || + new->iclabel.vspace != old->iclabel.vspace || + label_changed) { + computeSize(new, widthspecified, heightspecified); + redisplay = True; + } else if (new->iclabel.justify != old->iclabel.justify) { + redisplay = True; + } + + if (new->iclabel.cursor != old->iclabel.cursor && XtIsRealized(wid)) { + XDefineCursor(XtDisplay(wid), XtWindow(wid), new->iclabel.cursor); + } + + return redisplay; +} + +static XtGeometryResult +QueryGeometry(w, req, ret) +Widget w; +XtWidgetGeometry *req; +XtWidgetGeometry *ret; +{ + ICLabelWidget iclw = (ICLabelWidget)w; + + ret->request_mode = CWWidth | CWHeight; + + ret->width = iclw->iclabel.width + iclw->iclabel.hspace * 2; + ret->height = iclw->iclabel.fontheight + iclw->iclabel.vspace * 2; + + if ((!(req->request_mode & CWWidth) || ret->width == req->width) && + (!(req->request_mode & CWHeight) || ret->height == req->height)) { + return XtGeometryYes; + } else if (ret->width == iclw->core.width && + ret->height == iclw->core.height) { + return XtGeometryNo; + } + return XtGeometryAlmost; +} + +static void +InsertChild(w) +Widget w; +{ + ICLabelWidget iclw = (ICLabelWidget)XtParent(w); + CompositeWidgetClass super = (CompositeWidgetClass)XtClass(iclw)->core_class.superclass; + String params[1]; + Cardinal num_params; + + if (!XtIsSubclass(w, convDisplayObjectClass)) { + params[0] = XtClass(iclw)->core_class.class_name; + num_params = 1; + XtAppErrorMsg(XtWidgetToApplicationContext(w), + "childError", "class", "WidgetError", + "%s: child must be subclass of ConvDisplayObject", + params, &num_params); + } + if (iclw->composite.num_children != 0) { + params[0] = XtClass(iclw)->core_class.class_name; + num_params = 1; + XtAppErrorMsg(XtWidgetToApplicationContext(w), + "childError", "number", "WidgetError", + "%s: can only take one child", + params, &num_params); + } + + (*super->composite_class.insert_child)(w); + + iclw->iclabel.displayobj = w; + iclw->iclabel.fontheight = CDLineHeight(w, (Position *)NULL); + + if (iclw->iclabel.label != NULL) { + iclw->iclabel.width = CDStringWidth(iclw->iclabel.displayobj, + iclw->iclabel.label, 0, -1); + } + computeSize(iclw, iclw->core.width != 0, iclw->core.height != 0); +} + +static void +computeSize(iclw, fixwidth, fixheight) +ICLabelWidget iclw; +Boolean fixwidth; +Boolean fixheight; +{ + if (!fixwidth) { + iclw->core.width = iclw->iclabel.width + iclw->iclabel.hspace * 2; + } + if (!fixheight) { + iclw->core.height = iclw->iclabel.fontheight + iclw->iclabel.vspace * 2; + } +} + +static ICString * +copyString(from) +ICString *from; +{ + ICString *to = XtNew(ICString); + + to->nbytes = from->nbytes; + to->nchars = from->nchars; + to->attr = from->attr; + to->data = XtMalloc(from->nbytes); + (void)bcopy(from->data, to->data, from->nbytes); + return to; +} + +static void +freeString(s) +ICString *s; +{ + XtFree(s->data); + XtFree((char *)s); +} + + +/* + * public function + */ + +void +ICLRecomputeSize(w) +Widget w; +{ + ICLabelWidget iclw = (ICLabelWidget)w; + Dimension width, height; + + if (iclw->iclabel.displayobj != NULL) { + iclw->iclabel.fontheight = CDLineHeight(iclw->iclabel.displayobj, + (Position *)NULL); + if (iclw->iclabel.label != NULL) { + iclw->iclabel.width = CDStringWidth(iclw->iclabel.displayobj, + iclw->iclabel.label, 0, -1); + } + width = iclw->iclabel.width + iclw->iclabel.hspace * 2; + height = iclw->iclabel.fontheight + iclw->iclabel.vspace * 2; + XtMakeResizeRequest(w, width, height, + (Dimension *)NULL, (Dimension *)NULL); + } /* else do nothing */ +}