diff lib/ConvDisp.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/ConvDisp.c	Mon Mar 08 04:44:30 2010 +0900
@@ -0,0 +1,538 @@
+#ifndef lint
+static char *rcsid = "$Id: ConvDisp.c,v 1.19 1992/08/05 01:51:35 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/Atoms.h>
+#include <X11/Xmu/Converters.h>
+#include "CachedAtom.h"
+#include "ConvDispP.h"
+
+#define DEBUG_VAR debug_ConvDisplay
+#include "DebugPrint.h"
+
+static XtResource resources[] = {
+#define offset(field) XtOffset(ConvDisplayObject, convDisplay.field)
+    { XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel),
+	offset(foreground), XtRString, XtDefaultForeground },
+    { XtNbackground, XtCBackground, XtRPixel, sizeof (Pixel),
+	offset(background), XtRString, XtDefaultBackground },
+    { XtNcursorBitmap, XtCCursorBitmap, XtRBitmap, sizeof (Pixmap),
+	offset(cursor), XtRImmediate, None },
+    { XtNhotX, XtCHotX, XtRPosition, sizeof (Position),
+	offset(hotx), XtRString, "3" },
+    { XtNhotY, XtCHotY, XtRPosition, sizeof (Position),
+	offset(hoty), XtRString, "2" },
+#undef offset
+};
+
+static void ClassInitialize();
+static void ClassPartInitialize();
+
+static void Initialize();
+static void Destroy();
+static Boolean SetValues();
+
+static Pixmap DefaultCursor();
+static void GetGC();
+static void ComputeBounds();
+
+static int StringWidth();
+static int LineHeight();
+static void DrawString();
+static int MaxChar();
+static void DrawCursor();
+static void GetCursorBounds();
+static void SetFonts();
+
+ConvDisplayClassRec convDisplayClassRec = {
+  { /* object fields */
+    /* superclass		*/	(WidgetClass) &objectClassRec,
+    /* class_name		*/	"ConvDisplay",
+    /* widget_size		*/	sizeof(ConvDisplayRec),
+    /* class_initialize		*/	ClassInitialize,
+    /* class_part_initialize	*/	ClassPartInitialize,
+    /* class_inited		*/	FALSE,
+    /* initialize		*/	Initialize,
+    /* initialize_hook		*/	NULL,
+    /* obj1			*/	NULL,
+    /* obj2			*/	NULL,
+    /* obj3			*/	0,
+    /* resources		*/	resources,
+    /* num_resources		*/	XtNumber(resources),
+    /* xrm_class		*/	NULLQUARK,
+    /* obj4			*/	FALSE,
+    /* obj5			*/	FALSE,
+    /* obj6			*/	FALSE,
+    /* obj7			*/	FALSE,
+    /* destroy			*/	Destroy,
+    /* obj8			*/	NULL,
+    /* obj9			*/	NULL,
+    /* set_values		*/	SetValues,
+    /* set_values_hook		*/	NULL,
+    /* obj10			*/	NULL,
+    /* get_values_hook		*/	NULL,
+    /* obj11			*/	NULL,
+    /* version			*/	XtVersion,
+    /* callback_private		*/	NULL,
+    /* obj12			*/	NULL,
+    /* obj13			*/	NULL,
+    /* obj14			*/	NULL,
+    /* extension		*/	NULL
+  },
+  { /* convDisplay fields */
+    /* StringWidth		*/	StringWidth,
+    /* LineHeight		*/	LineHeight,
+    /* DrawString		*/	DrawString,
+    /* MaxChar			*/	MaxChar,
+    /* DrawCursor		*/	DrawCursor,
+    /* GetCursorBounds		*/	GetCursorBounds,
+    /* SetFonts			*/	SetFonts,
+  }
+};
+
+WidgetClass convDisplayObjectClass = (WidgetClass)&convDisplayClassRec;
+
+static void
+ClassInitialize()
+{
+    static XtConvertArgRec screenConvertArg[] = {
+        { XtBaseOffset, (caddr_t) XtOffset(Widget, core.screen),
+	   sizeof(Screen *) }
+    };
+
+    /* add string->bitmap converter (for insert-cursor) */
+    XtAddConverter("String", "Bitmap", XmuCvtStringToBitmap,
+                   screenConvertArg, XtNumber(screenConvertArg));
+}
+
+static void
+ClassPartInitialize(cl)
+WidgetClass cl;
+{
+    ConvDisplayObjectClass class = (ConvDisplayObjectClass)cl;
+    ConvDisplayObjectClass super = (ConvDisplayObjectClass)class->object_class.superclass;
+    ConvDisplayClassPart *classpart = &(class->convDisplay_class);
+    ConvDisplayClassPart *superpart = &(super->convDisplay_class);
+
+    if (classpart->StringWidth == XtInheritStringWidth)
+	classpart->StringWidth = superpart->StringWidth;
+    if (classpart->LineHeight == XtInheritLineHeight)
+	classpart->LineHeight = superpart->LineHeight;
+    if (classpart->DrawString == XtInheritDrawString)
+	classpart->DrawString = superpart->DrawString;
+    if (classpart->MaxChar == XtInheritMaxChar)
+	classpart->MaxChar = superpart->MaxChar;
+    if (classpart->DrawCursor == XtInheritDrawCursor)
+	classpart->DrawCursor = superpart->DrawCursor;
+    if (classpart->GetCursorBounds == XtInheritGetCursorBounds)
+	classpart->GetCursorBounds = superpart->GetCursorBounds;
+    if (classpart->SetFonts == XtInheritSetFonts)
+	classpart->SetFonts = superpart->SetFonts;
+}
+
+/* ARGSUSED */
+static void
+Initialize(req, new, args, num_args)
+Widget req;
+Widget new;
+ArgList args;
+Cardinal *num_args;
+{
+    ConvDisplayObject obj = (ConvDisplayObject)new;
+
+    if (obj->convDisplay.cursor == None) {
+	obj->convDisplay.cursor = DefaultCursor(obj);
+	obj->convDisplay.cursorcreated = True;
+    } else {
+	obj->convDisplay.cursorcreated = False;
+    }
+    obj->convDisplay.cursorvisible = False;
+    GetGC(obj);
+    ComputeBounds(obj);
+}
+
+static void
+Destroy(w)
+Widget w;
+{
+    ConvDisplayObject obj = (ConvDisplayObject)w;
+
+    XtReleaseGC(w, obj->convDisplay.cursorgc);
+    if (obj->convDisplay.cursorcreated == True) {
+	XFreePixmap(XtDisplayOfObject(w), obj->convDisplay.cursor);
+    }
+}
+
+/* ARGSUSED */
+static Boolean
+SetValues(cur, req, wid, args, num_args)
+Widget cur;
+Widget req;
+Widget wid;
+ArgList args;
+Cardinal *num_args;
+{
+    ConvDisplayObject new = (ConvDisplayObject)wid;
+    ConvDisplayObject old = (ConvDisplayObject)cur;
+
+    if (new->convDisplay.foreground != old->convDisplay.foreground ||
+	new->convDisplay.background != old->convDisplay.background) {
+	XtReleaseGC(wid, old->convDisplay.cursorgc);
+	GetGC(new);
+    }
+
+    if (new->convDisplay.cursor != old->convDisplay.cursor ||
+	new->convDisplay.hotx != old->convDisplay.hotx ||
+	new->convDisplay.hoty != old->convDisplay.hoty) {
+	if (new->convDisplay.cursor != old->convDisplay.cursor &&
+	    old->convDisplay.cursorcreated) {
+	    XFreePixmap(XtDisplayOfObject(wid), old->convDisplay.cursor);
+	    new->convDisplay.cursorcreated = False;
+	}
+	ComputeBounds(new);
+    }
+
+    return False;
+}
+
+static Pixmap
+DefaultCursor(obj)
+ConvDisplayObject obj;
+{
+    static char default_bits[] = { 0x0c, 0x0c, 0x1e, 0x3f, 0x33 };
+    return XCreateBitmapFromData(XtDisplayOfObject((Widget)obj),
+				 RootWindowOfScreen(XtScreenOfObject((Widget)obj)),
+				 default_bits,
+				 6, 5);
+}
+
+static void
+GetGC(obj)
+ConvDisplayObject obj;
+{
+    XtGCMask mask = GCFunction|GCForeground|GCBackground;
+    XGCValues values;
+
+    values.function = GXxor;
+    values.foreground = obj->convDisplay.foreground ^ obj->convDisplay.background;
+    values.background = 0;
+    obj->convDisplay.cursorgc = XtGetGC((Widget)obj, mask, &values);
+}
+
+static void
+ComputeBounds(obj)
+ConvDisplayObject obj;
+{
+    unsigned int width, height;
+    Window junkroot;
+    int junkx, junky;
+    unsigned int junkbw, junkdepth;
+
+    if (obj->convDisplay.cursor == None ||
+	!XGetGeometry(XtDisplayOfObject((Widget)obj), obj->convDisplay.cursor,
+		      &junkroot, &junkx, &junky, &width, &height,
+		      &junkbw, &junkdepth)) {
+	obj->convDisplay.cursor = None;
+	width = height = 0;
+    }
+    obj->convDisplay.cursorbounds.width = width;
+    obj->convDisplay.cursorbounds.height = height;
+    obj->convDisplay.cursorbounds.x = -obj->convDisplay.hotx;
+    obj->convDisplay.cursorbounds.y = -obj->convDisplay.hoty;
+}
+
+/* ARGSUSED */
+static int
+StringWidth(w, str, start, end)
+Widget w;
+ICString *str;
+int start;
+int end;
+{
+    XtAppError(XtWidgetToApplicationContext(w),
+	       "ConvDisplay Object: StringWidth function isn't defined.");
+    return 0;	/* for lint */
+}
+
+/* ARGSUSED */
+static int
+LineHeight(w, ascentp)
+Widget w;
+Position *ascentp;
+{
+    XtAppError(XtWidgetToApplicationContext(w),
+	       "ConvDisplay Object: LineHeight function isn't defined.");
+    return 0;	/* for lint */
+}
+
+/* ARGSUSED */
+static void
+DrawString(w, canvas, str, start, end, x, y)
+Widget w;
+Widget canvas;
+ICString *str;
+int start;
+int end;
+int x;
+int y;
+{
+    XtAppError(XtWidgetToApplicationContext(w),
+	       "ConvDisplay Object: DrawString function isn't defined.");
+}
+
+/* ARGSUSED */
+static int
+MaxChar(w, str, start, width)
+Widget w;
+ICString *str;
+int start;
+int width;
+{
+    XtAppError(XtWidgetToApplicationContext(w),
+	       "ConvDisplay Object: MaxChar function isn't defined.");
+    return 0;	/* for lint */
+}
+
+static void
+DrawCursor(w, canvas, x, y, on)
+Widget w;
+Widget canvas;
+int x;
+int y;
+int on;
+{
+    ConvDisplayObject obj = (ConvDisplayObject)w;
+
+    if (!XtIsRealized(canvas) ||
+	obj->convDisplay.cursor == None ||
+	(obj->convDisplay.cursorvisible && on) ||
+	(!obj->convDisplay.cursorvisible && !on)) {
+	obj->convDisplay.cursorvisible = (on != 0);
+	return;
+    }
+
+    XCopyPlane(XtDisplay(canvas),
+	       obj->convDisplay.cursor, XtWindow(canvas),
+	       obj->convDisplay.cursorgc,
+	       0, 0,
+	       obj->convDisplay.cursorbounds.width,
+	       obj->convDisplay.cursorbounds.height,
+	       x + obj->convDisplay.cursorbounds.x,
+	       y + obj->convDisplay.cursorbounds.y,
+	       1L);
+    obj->convDisplay.cursorvisible = (on != 0);
+}
+
+static void
+GetCursorBounds(w, bounds)
+Widget w;
+XRectangle *bounds;
+{
+    ConvDisplayObject obj = (ConvDisplayObject)w;
+
+     bounds->x = obj->convDisplay.cursorbounds.x;
+     bounds->y = obj->convDisplay.cursorbounds.y;
+     bounds->width = obj->convDisplay.cursorbounds.width;
+     bounds->height = obj->convDisplay.cursorbounds.height;
+}
+
+/* ARGSUSED */
+static void
+SetFonts(w, fonts, num_fonts)
+Widget w;
+XFontStruct **fonts;
+Cardinal num_fonts;
+{
+    XtAppError(XtWidgetToApplicationContext(w),
+	       "ConvDisplay Object: SetFonts function isn't defined.");
+}
+
+
+/*
+ * public functions
+ */
+
+int
+CDStringWidth(w, str, start, end)
+Widget w;
+ICString *str;
+int start;
+int end;
+{
+    ConvDisplayObjectClass class = (ConvDisplayObjectClass)w->core.widget_class;
+
+    XtCheckSubclass(w, convDisplayObjectClass, "CDStringWidth()");
+    return (*class->convDisplay_class.StringWidth)(w, str, start, end);
+}
+
+int
+CDLineHeight(w, ascent)
+Widget w;
+Position *ascent;
+{
+    ConvDisplayObjectClass class = (ConvDisplayObjectClass)w->core.widget_class;
+
+    XtCheckSubclass(w, convDisplayObjectClass, "CDLineHeight()");
+    return (*class->convDisplay_class.LineHeight)(w, ascent);
+}
+
+void
+CDDrawString(w, canvas, str, start, end, x, y)
+Widget w;
+Widget canvas;
+ICString *str;
+int start;
+int end;
+int x;
+int y;
+{
+    ConvDisplayObjectClass class = (ConvDisplayObjectClass)w->core.widget_class;
+
+    XtCheckSubclass(w, convDisplayObjectClass, "CDDrawString()");
+    (*class->convDisplay_class.DrawString)(w, canvas, str, start, end, x, y);
+}
+
+int
+CDMaxChar(w, str, start, width)
+Widget w;
+ICString *str;
+int start;
+int width;
+{
+    ConvDisplayObjectClass class = (ConvDisplayObjectClass)w->core.widget_class;
+
+    XtCheckSubclass(w, convDisplayObjectClass, "CDMaxChar()");
+    return (*class->convDisplay_class.MaxChar)(w, str, start, width);
+}
+
+void
+CDDrawCursor(w, canvas, x, y, on)
+Widget w;
+Widget canvas;
+int x;
+int y;
+int on;
+{
+    ConvDisplayObjectClass class = (ConvDisplayObjectClass)w->core.widget_class;
+
+    XtCheckSubclass(w, convDisplayObjectClass, "CDDrawCursor()");
+    (*class->convDisplay_class.DrawCursor)(w, canvas, x, y, on);
+}
+
+void
+CDGetCursorBounds(w, bounds)
+Widget w;
+XRectangle *bounds;
+{
+    ConvDisplayObjectClass class = (ConvDisplayObjectClass)w->core.widget_class;
+
+    XtCheckSubclass(w, convDisplayObjectClass, "CDGetCursorBounds()");
+    (*class->convDisplay_class.GetCursorBounds)(w, bounds);
+}
+
+void
+CDSetFonts(w, fonts, num_fonts)
+Widget w;
+XFontStruct **fonts;
+Cardinal num_fonts;
+{
+    ConvDisplayObjectClass class = (ConvDisplayObjectClass)w->core.widget_class;
+
+    XtCheckSubclass(w, convDisplayObjectClass, "CDSetFonts()");
+    (*class->convDisplay_class.SetFonts)(w, fonts, num_fonts);
+}
+
+
+void
+CDSetBlockCursor(w, shape)
+Widget w;
+XRectangle *shape;
+{
+    ConvDisplayObject obj = (ConvDisplayObject)w;
+    Display *dpy = XtDisplayOfObject((Widget)obj);
+    Pixmap block;
+    GC tmpgc;
+    XGCValues values;
+
+    XtCheckSubclass(w, convDisplayObjectClass, "CDMakeBlockCursor()");
+
+    block = XCreatePixmap(dpy,
+			  RootWindowOfScreen(XtScreenOfObject((Widget)obj)),
+			  shape->width, shape->height, 1);
+
+    values.function = GXset;
+    tmpgc = XtGetGC(w, GCFunction, &values);
+    XFillRectangle(dpy, block, tmpgc, 0, 0, shape->width, shape->height);
+    XtReleaseGC(w, tmpgc);
+
+    XtVaSetValues(w,
+		  XtNcursorBitmap, block,
+		  XtNhotX, -shape->x,
+		  XtNhotY, -shape->y,
+		  NULL);
+}
+
+
+/*
+ * semi-public function (for subclass use)
+ */
+
+int
+_CDPickupFonts(widget, fontspecs, num_specs, fonts, num_fonts)
+Widget widget;
+FontSpec *fontspecs;
+Cardinal num_specs;
+XFontStruct **fonts;
+Cardinal num_fonts;
+{
+    Display *dpy = XtDisplayOfObject(widget);
+    Atom cs_reg = CachedInternAtom(dpy, "CHARSET_REGISTRY", False);
+    Atom cs_enc = CachedInternAtom(dpy, "CHARSET_ENCODING", False);
+    Atom atom;
+    Cardinal i, j;
+    FontSpec *fsp;
+    int npick;
+
+    DPRINT(("_CDPickupFonts()\n"));
+
+    /* pickup fonts */
+    npick = 0;
+    for (i = 0, fsp = fontspecs; i < num_specs; i++, fsp++) {
+	DPRINT(("\tlooking for a font..."));
+
+	fsp->font = NULL;
+	for (j = 0; j < num_fonts; j++) {
+	    if (fonts[j] != NULL &&
+		XGetFontProperty(fonts[j], cs_reg, (unsigned long *)&atom) &&
+		atom == fsp->registry &&
+		XGetFontProperty(fonts[j], cs_enc, (unsigned long *)&atom) &&
+		atom == fsp->encoding) {
+		DPRINT((" found"));
+		fsp->font = fonts[j];
+		npick++;
+		break;
+	    }
+	}
+	DPRINT(("\n"));
+    }
+
+    return npick;
+}