diff options
author | kaleb <empty> | 1994-01-31 09:50:35 +0000 |
---|---|---|
committer | kaleb <empty> | 1994-01-31 09:50:35 +0000 |
commit | 60827302402d9a11bcd76f81b21089e88462bc4f (patch) | |
tree | 4a0b8ea634547a1cc612844b8b25a81d9ce159bc /xc | |
parent | bf06bac8a1fa02146bdf79d724ac576022949cb6 (diff) |
Initial revision
Diffstat (limited to 'xc')
-rw-r--r-- | xc/lib/Xaw/MultiSink.c | 757 | ||||
-rw-r--r-- | xc/lib/Xaw/MultiSink.h | 95 | ||||
-rw-r--r-- | xc/lib/Xaw/MultiSinkP.h | 134 | ||||
-rw-r--r-- | xc/lib/Xaw/MultiSrc.c | 1437 | ||||
-rw-r--r-- | xc/lib/Xaw/MultiSrc.h | 140 | ||||
-rw-r--r-- | xc/lib/Xaw/MultiSrcP.h | 171 | ||||
-rw-r--r-- | xc/lib/Xaw/VendorEP.h | 54 | ||||
-rw-r--r-- | xc/lib/Xaw/XawI18n.c | 67 | ||||
-rw-r--r-- | xc/lib/Xaw/XawI18n.h | 101 | ||||
-rw-r--r-- | xc/lib/Xaw/XawIm.c | 1739 | ||||
-rw-r--r-- | xc/lib/Xaw/XawImP.h | 143 |
11 files changed, 4838 insertions, 0 deletions
diff --git a/xc/lib/Xaw/MultiSink.c b/xc/lib/Xaw/MultiSink.c new file mode 100644 index 000000000..05974b3e1 --- /dev/null +++ b/xc/lib/Xaw/MultiSink.c @@ -0,0 +1,757 @@ +/* $XConsortium: MultiSink.c,v 1.0 94/01/01 00:00:00 kaleb Exp $ */ + +/* + * Copyright 1991 by OMRON Corporation + * Copyright 1991 by Massachusetts Institute of Technology + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, 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 names of OMRON and MIT not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. OMRON and MIT make no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * OMRON AND MIT DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OMRON OR MIT BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Li Yuhong OMRON Corporation + */ + +/*********************************************************** +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts, +and the Massachusetts Institute of Technology, Cambridge, Massachusetts. + + All Rights Reserved + +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 names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#include <X11/IntrinsicP.h> +#include <X11/StringDefs.h> +#include <X11/Xatom.h> +#include <X11/Xaw/XawInit.h> +#include <X11/Xaw/MultiSinkP.h> +#include <X11/Xaw/MultiSrcP.h> +#include <X11/Xaw/TextP.h> +#include "XawI18n.h" +#include <stdio.h> +#include <ctype.h> + +#ifdef GETLASTPOS +#undef GETLASTPOS /* We will use our own GETLASTPOS. */ +#endif + +#define GETLASTPOS XawTextSourceScan(source, (XawTextPosition) 0, XawstAll, XawsdRight, 1, TRUE) + +static void Initialize(), Destroy(); +static Boolean SetValues(); +static int MaxLines(), MaxHeight(); +static void SetTabs(); + +static void DisplayText(), InsertCursor(), FindPosition(); +static void FindDistance(), Resolve(), GetCursorBounds(); + +#define offset(field) XtOffsetOf(MultiSinkRec, multi_sink.field) + +static XtResource resources[] = { + {XtNfontSet, XtCFontSet, XtRFontSet, sizeof (XFontSet), + offset(fontset), XtRString, XtDefaultFontSet}, + {XtNecho, XtCOutput, XtRBoolean, sizeof(Boolean), + offset(echo), XtRImmediate, (XtPointer) True}, + {XtNdisplayNonprinting, XtCOutput, XtRBoolean, sizeof(Boolean), + offset(display_nonprinting), XtRImmediate, (XtPointer) True}, +}; +#undef offset + +#define SuperClass (&textSinkClassRec) +MultiSinkClassRec multiSinkClassRec = { + { /* core_class fields */ + /* superclass */ (WidgetClass) SuperClass, + /* class_name */ "MultiSink", + /* widget_size */ sizeof(MultiSinkRec), + /* class_initialize */ XawInitializeWidgetSet, + /* class_part_initialize */ NULL, + /* 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 + }, + { /* text_sink_class fields */ + /* DisplayText */ DisplayText, + /* InsertCursor */ InsertCursor, + /* ClearToBackground */ XtInheritClearToBackground, + /* FindPosition */ FindPosition, + /* FindDistance */ FindDistance, + /* Resolve */ Resolve, + /* MaxLines */ MaxLines, + /* MaxHeight */ MaxHeight, + /* SetTabs */ SetTabs, + /* GetCursorBounds */ GetCursorBounds + }, + { /* multi_sink_class fields */ + /* unused */ 0 + } +}; + +WidgetClass multiSinkObjectClass = (WidgetClass)&multiSinkClassRec; + +/* Utilities */ + +static int +CharWidth (w, x, c) + Widget w; + int x; + wchar_t c; +{ + int i, width, nonPrinting; + MultiSinkObject sink = (MultiSinkObject) w; + XFontSet fontset = sink->multi_sink.fontset; + Position *tab; + + if ( c == atowc(XawLF) ) return(0); + + if (c == atowc(XawTAB)) { + /* Adjust for Left Margin. */ + x -= ((TextWidget) XtParent(w))->text.margin.left; + + if (x >= (int)XtParent(w)->core.width) return 0; + for (i = 0, tab = sink->text_sink.tabs ; + i < sink->text_sink.tab_count ; i++, tab++) { + if (x < *tab) { + if (*tab < (int)XtParent(w)->core.width) + return *tab - x; + else + return 0; + } + } + return 0; + } + + if ( (nonPrinting = !iswprint(c)) ) + if (sink->multi_sink.display_nonprinting) + c += atowc('@'); + else { + c = atowc(XawSP); + nonPrinting = False; + } + + /* + * if more effeciency(suppose one column is one ASCII char) + + width = XwcGetColumn(fontset->font_charset, fontset->num_of_fonts, c) * + fontset->font_struct_list[0]->min_bounds.width; + * + * WARNING: Very Slower!!! + * + * Li Yuhong. + */ + + width = XwcTextEscapement(fontset, &c, 1); + + if (nonPrinting) + width += CharWidth(w, x, atowc('^')); + + return width; +} + +/* Function Name: PaintText + * Description: Actually paints the text into the windoe. + * Arguments: w - the text widget. + * gc - gc to paint text with. + * x, y - location to paint the text. + * buf, len - buffer and length of text to paint. + * Returns: the width of the text painted, or 0. + * + * NOTE: If this string attempts to paint past the end of the window + * then this function will return zero. + */ + +static Dimension +PaintText(w, gc, x, y, buf, len) + Widget w; + GC gc; + Position x, y; + wchar_t* buf; + int len; +{ + MultiSinkObject sink = (MultiSinkObject) w; + TextWidget ctx = (TextWidget) XtParent(w); + + XFontSet fontset = sink->multi_sink.fontset; + Position max_x; + Dimension width = XwcTextEscapement(fontset, buf, len); + XFontSetExtents *ext = XExtentsOfFontSet(fontset); + max_x = (Position) ctx->core.width; + + if ( ((int) width) <= -x) /* Don't draw if we can't see it. */ + return(width); + + XwcDrawImageString(XtDisplay(ctx), XtWindow(ctx), fontset, gc, + (int) x, (int) y, buf, len); + if ( (((Position) width + x) > max_x) && (ctx->text.margin.right != 0) ) { + x = ctx->core.width - ctx->text.margin.right; + width = ctx->text.margin.right; + XFillRectangle(XtDisplay((Widget) ctx), XtWindow( (Widget) ctx), + sink->multi_sink.normgc, (int) x, + (int) y - abs(ext->max_logical_extent.y), + (unsigned int) width, + (unsigned int) ext->max_logical_extent.height); + return(0); + } + return(width); +} + +/* Sink Object Functions */ + +/* + * This function does not know about drawing more than one line of text. + */ + +static void +DisplayText(w, x, y, pos1, pos2, highlight) + Widget w; + Position x, y; + Boolean highlight; + XawTextPosition pos1, pos2; +{ + MultiSinkObject sink = (MultiSinkObject) w; + Widget source = XawTextGetSource(XtParent(w)); + wchar_t buf[BUFSIZ]; + XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); + + int j, k; + XawTextBlock blk; + GC gc = highlight ? sink->multi_sink.invgc : sink->multi_sink.normgc; + GC invgc = highlight ? sink->multi_sink.normgc : sink->multi_sink.invgc; + + if (!sink->multi_sink.echo) return; + + y += abs(ext->max_logical_extent.y); + for ( j = 0 ; pos1 < pos2 ; ) { + pos1 = XawTextSourceRead(source, pos1, &blk, (int) pos2 - pos1); + for (k = 0; k < blk.length; k++) { + if (j >= BUFSIZ) { /* buffer full, dump the text. */ + x += PaintText(w, gc, x, y, buf, j); + j = 0; + } + buf[j] = ((wchar_t *)blk.ptr)[k]; + if (buf[j] == atowc(XawLF)) /* line feeds ('\n') are not printed. */ + continue; + + else if (buf[j] == atowc('\t')) { + Position temp = 0; + Dimension width; + + if ((j != 0) && ((temp = PaintText(w, gc, x, y, buf, j)) == 0)) + return; + + x += temp; + width = CharWidth(w, x, atowc('\t')); + XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w), + invgc, (int) x, + (int) y - abs(ext->max_logical_extent.y), + (unsigned int)width, + (unsigned int)ext->max_logical_extent.height); + x += width; + j = -1; + } + else if (!iswprint(buf[j])) { + if (sink->multi_sink.display_nonprinting) { + /* DP10646 control function: C PAD PAD PAD */ + buf[j + 1] = (buf[j] & 0x7F) + atowc('@'); + buf[j] = atowc('^'); + j++; + } + else + buf[j] = atowc(' '); + } + j++; + } + } + if (j > 0) + (void) PaintText(w, gc, x, y, buf, j); +} + +#define insertCursor_width 6 +#define insertCursor_height 3 +static char insertCursor_bits[] = {0x0c, 0x1e, 0x33}; + +static Pixmap +CreateInsertCursor(s) + Screen *s; +{ + return (XCreateBitmapFromData (DisplayOfScreen(s), RootWindowOfScreen(s), + insertCursor_bits, insertCursor_width, insertCursor_height)); +} + +/* Function Name: GetCursorBounds + * Description: Returns the size and location of the cursor. + * Arguments: w - the text object. + * RETURNED rect - an X rectangle to return the cursor bounds in. + * Returns: none. + */ + +static void +GetCursorBounds(w, rect) + Widget w; + XRectangle * rect; +{ + MultiSinkObject sink = (MultiSinkObject) w; + + rect->width = (unsigned short) insertCursor_width; + rect->height = (unsigned short) insertCursor_height; + rect->x = sink->multi_sink.cursor_x - (short) (rect->width / 2); + rect->y = sink->multi_sink.cursor_y - (short) rect->height; +} + +/* + * The following procedure manages the "insert" cursor. + */ + +static void +InsertCursor (w, x, y, state) + Widget w; + Position x, y; + XawTextInsertState state; +{ + MultiSinkObject sink = (MultiSinkObject) w; + Widget text_widget = XtParent(w); + XRectangle rect; + + sink->multi_sink.cursor_x = x; + sink->multi_sink.cursor_y = y; + + GetCursorBounds(w, &rect); + if (state != sink->multi_sink.laststate && XtIsRealized(text_widget)) + XCopyPlane(XtDisplay(text_widget), + sink->multi_sink.insertCursorOn, + XtWindow(text_widget), sink->multi_sink.xorgc, + 0, 0, (unsigned int) rect.width, (unsigned int) rect.height, + (int) rect.x, (int) rect.y, 1); + sink->multi_sink.laststate = state; +} + +/* + * Given two positions, find the distance between them. + */ + +static void +FindDistance (w, fromPos, fromx, toPos, resWidth, resPos, resHeight) + Widget w; + XawTextPosition fromPos; /* First position. */ + int fromx; /* Horizontal location of first position. */ + XawTextPosition toPos; /* Second position. */ + int* resWidth; /* Distance between fromPos and resPos. */ + XawTextPosition* resPos; /* Actual second position used. */ + int* resHeight; /* Height required. */ +{ + MultiSinkObject sink = (MultiSinkObject) w; + Widget source = XawTextGetSource(XtParent(w)); + + XawTextPosition index, lastPos; + wchar_t c; + XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); + XawTextBlock blk; + + /* we may not need this */ + lastPos = GETLASTPOS; + XawTextSourceRead(source, fromPos, &blk, (int) toPos - fromPos); + *resWidth = 0; + for (index = fromPos; index != toPos && index < lastPos; index++) { + if (index - blk.firstPos >= blk.length) + XawTextSourceRead(source, index, &blk, (int) toPos - fromPos); + c = ((wchar_t *)blk.ptr)[index - blk.firstPos]; + *resWidth += CharWidth(w, fromx + *resWidth, c); + if (c == atowc(XawLF)) { + index++; + break; + } + } + *resPos = index; + *resHeight = ext->max_logical_extent.height; +} + + +static void +FindPosition(w, fromPos, fromx, width, stopAtWordBreak, resPos, resWidth, resHeight) + Widget w; + XawTextPosition fromPos; /* Starting position. */ + int fromx; /* Horizontal location of starting position.*/ + int width; /* Desired width. */ + int stopAtWordBreak; /* Whether the resulting position should be at + a word break. */ + XawTextPosition *resPos; /* Resulting position. */ + int* resWidth; /* Actual width used. */ + int* resHeight; /* Height required. */ +{ + MultiSinkObject sink = (MultiSinkObject) w; + Widget source = XawTextGetSource(XtParent(w)); + + XawTextPosition lastPos, index, whiteSpacePosition; + int lastWidth, whiteSpaceWidth; + Boolean whiteSpaceSeen; + wchar_t c; + XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); + XawTextBlock blk; + + lastPos = GETLASTPOS; + + XawTextSourceRead(source, fromPos, &blk, BUFSIZ); + *resWidth = 0; + whiteSpaceSeen = FALSE; + c = 0; + for (index = fromPos; *resWidth <= width && index < lastPos; index++) { + lastWidth = *resWidth; + if (index - blk.firstPos >= blk.length) + XawTextSourceRead(source, index, &blk, BUFSIZ); + c = ((wchar_t *)blk.ptr)[index - blk.firstPos]; + *resWidth += CharWidth(w, fromx + *resWidth, c); + + if ((c == atowc(XawSP) || c == atowc(XawTAB)) && *resWidth <= width) { + whiteSpaceSeen = TRUE; + whiteSpacePosition = index; + whiteSpaceWidth = *resWidth; + } + if (c == atowc(XawLF)) { + index++; + break; + } + } + if (*resWidth > width && index > fromPos) { + *resWidth = lastWidth; + index--; + if (stopAtWordBreak && whiteSpaceSeen) { + index = whiteSpacePosition + 1; + *resWidth = whiteSpaceWidth; + } + } + if (index == lastPos && c != atowc(XawLF)) index = lastPos + 1; + *resPos = index; + *resHeight = ext->max_logical_extent.height; +} + +static void +Resolve (w, pos, fromx, width, leftPos, rightPos) + Widget w; + XawTextPosition pos; + int fromx, width; + XawTextPosition *leftPos, *rightPos; +{ + int resWidth, resHeight; + Widget source = XawTextGetSource(XtParent(w)); + + FindPosition(w, pos, fromx, width, FALSE, leftPos, &resWidth, &resHeight); + if (*leftPos > GETLASTPOS) + *leftPos = GETLASTPOS; + *rightPos = *leftPos; +} + +static void +GetGC(sink) + MultiSinkObject sink; +{ + XtGCMask valuemask = (GCGraphicsExposures | GCForeground | GCBackground ); + XGCValues values; + + values.graphics_exposures = (Bool) FALSE; + + values.foreground = sink->text_sink.foreground; + values.background = sink->text_sink.background; + + sink->multi_sink.normgc = XtAllocateGC( (Widget)sink, 0, valuemask, &values, GCFont, 0 ); + + values.foreground = sink->text_sink.background; + values.background = sink->text_sink.foreground; + sink->multi_sink.invgc = XtAllocateGC( (Widget)sink, 0, valuemask, &values, GCFont, 0 ); + + values.function = GXxor; + values.background = (unsigned long) 0L; /* (pix ^ 0) = pix */ + values.foreground = (sink->text_sink.background ^ + sink->text_sink.foreground); + valuemask = GCGraphicsExposures | GCFunction | GCForeground | GCBackground; + + /* if this GC is not used for fontset rendering then AllocateGC aint needed. Dont hurt tho.*/ + sink->multi_sink.xorgc = XtAllocateGC( (Widget)sink, 0, valuemask, &values, GCFont, 0 ); +} + + +/***** Public routines *****/ + +/* Function Name: Initialize + * Description: Initializes the TextSink Object. + * Arguments: request, new - the requested and new values for the object + * instance. + * Returns: none. + * + */ + +/* ARGSUSED */ +static void +Initialize(request, new, args, num_args) + Widget request, new; + ArgList args; + Cardinal* num_args; +{ + MultiSinkObject sink = (MultiSinkObject) new; + + GetGC(sink); + + sink->multi_sink.insertCursorOn= CreateInsertCursor(XtScreenOfObject(new)); + sink->multi_sink.laststate = XawisOff; + sink->multi_sink.cursor_x = sink->multi_sink.cursor_y = 0; +} + +/* Function Name: Destroy + * Description: This function cleans up when the object is + * destroyed. + * Arguments: w - the MultiSink Object. + * Returns: none. + */ + +static void +Destroy(w) + Widget w; +{ + MultiSinkObject sink = (MultiSinkObject) w; + + XtReleaseGC(w, sink->multi_sink.normgc); + XtReleaseGC(w, sink->multi_sink.invgc); + XtReleaseGC(w, sink->multi_sink.xorgc); + + XFreePixmap(XtDisplayOfObject(w), sink->multi_sink.insertCursorOn); +} + +/* Function Name: SetValues + * Description: Sets the values for the MultiSink + * Arguments: current - current state of the object. + * request - what was requested. + * new - what the object will become. + * Returns: True if redisplay is needed. + */ + +/* ARGSUSED */ +static Boolean +SetValues(current, request, new, args, num_args) + Widget current, request, new; + ArgList args; + Cardinal* num_args; +{ + MultiSinkObject w = (MultiSinkObject) new; + MultiSinkObject old_w = (MultiSinkObject) current; + + /* Font set is not in the GC! Do not make a new GC when font set changes! */ + + if ( w->multi_sink.fontset != old_w->multi_sink.fontset ) { + ((TextWidget)XtParent(new))->text.redisplay_needed = True; +#ifndef NO_TAB_FIX + SetTabs( w, w->text_sink.tab_count, w->text_sink.char_tabs ); +#endif + } + + if ( w->text_sink.background != old_w->text_sink.background || + w->text_sink.foreground != old_w->text_sink.foreground ) { + + XtReleaseGC((Widget)w, w->multi_sink.normgc); + XtReleaseGC((Widget)w, w->multi_sink.invgc); + XtReleaseGC((Widget)w, w->multi_sink.xorgc); + GetGC(w); + ((TextWidget)XtParent(new))->text.redisplay_needed = True; + } else { + if ( (w->multi_sink.echo != old_w->multi_sink.echo) || + (w->multi_sink.display_nonprinting != + old_w->multi_sink.display_nonprinting) ) + ((TextWidget)XtParent(new))->text.redisplay_needed = True; + } + + return False; +} + +/* Function Name: MaxLines + * Description: Finds the Maximum number of lines that will fit in + * a given height. + * Arguments: w - the MultiSink Object. + * height - height to fit lines into. + * Returns: the number of lines that will fit. + */ + +/* ARGSUSED */ +static int +MaxLines(w, height) + Widget w; + Dimension height; +{ + MultiSinkObject sink = (MultiSinkObject) w; + int font_height; + XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); + + font_height = ext->max_logical_extent.height; + return( ((int) height) / font_height ); +} + +/* Function Name: MaxHeight + * Description: Finds the Minium height that will contain a given number + * lines. + * Arguments: w - the MultiSink Object. + * lines - the number of lines. + * Returns: the height. + */ + +/* ARGSUSED */ +static int +#if NeedFunctionPrototypes +MaxHeight( + Widget w, + int lines ) +#else +MaxHeight( w, lines ) + Widget w; + int lines; +#endif +{ + MultiSinkObject sink = (MultiSinkObject) w; + XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); + + return(lines * ext->max_logical_extent.height); +} + +/* Function Name: SetTabs + * Description: Sets the Tab stops. + * Arguments: w - the MultiSink Object. + * tab_count - the number of tabs in the list. + * tabs - the text positions of the tabs. + * Returns: none + */ + +static void +#if NeedFunctionPrototypes +SetTabs( + Widget w, + int tab_count, + short* tabs ) +#else +SetTabs( w, tab_count, tabs ) + Widget w; + int tab_count; + short* tabs; +#endif +{ + MultiSinkObject sink = (MultiSinkObject) w; + int i; + Atom XA_FIGURE_WIDTH; + unsigned long figure_width = 0; + XFontStruct *font; + + /* + * Bug: + * Suppose the first font of fontset stores the unit of column. + * + * By Li Yuhong, Mar. 14, 1991 + */ + { XFontStruct **f_list; + char **f_name; + + (void) XFontsOfFontSet(sink->multi_sink.fontset, &f_list, &f_name); + font = f_list[0]; + } + +/* + * Find the figure width of the current font. + */ + + XA_FIGURE_WIDTH = XInternAtom(XtDisplayOfObject(w), "FIGURE_WIDTH", FALSE); + if ( (XA_FIGURE_WIDTH != None) && + ( (!XGetFontProperty(font, XA_FIGURE_WIDTH, &figure_width)) || + (figure_width == 0)) ) + if (font->per_char && font->min_char_or_byte2 <= '$' && + font->max_char_or_byte2 >= '$') + figure_width = font->per_char['$' - font->min_char_or_byte2].width; + else + figure_width = font->max_bounds.width; + + if (tab_count > sink->text_sink.tab_count) { + sink->text_sink.tabs = (Position *) + XtRealloc((char *) sink->text_sink.tabs, + (Cardinal) (tab_count * sizeof(Position))); + sink->text_sink.char_tabs = (short *) + XtRealloc((char *) sink->text_sink.char_tabs, + (Cardinal) (tab_count * sizeof(short))); + } + + for ( i = 0 ; i < tab_count ; i++ ) { + sink->text_sink.tabs[i] = tabs[i] * figure_width; + sink->text_sink.char_tabs[i] = tabs[i]; + } + + sink->text_sink.tab_count = tab_count; + +#ifndef NO_TAB_FIX + ((TextWidget)XtParent(w))->text.redisplay_needed = True; +#endif +} + +void +#if NeedFunctionPrototypes +_XawMultiSinkPosToXY( + Widget w, + XawTextPosition pos, + Position *x, + Position *y ) +#else +_XawMultiSinkPosToXY( w, pos, x, y ) + Widget w; + XawTextPosition pos; + Position *x, *y; +#endif +{ + MultiSinkObject sink = (MultiSinkObject) ((TextWidget)w)->text.sink; + XFontSetExtents *ext = XExtentsOfFontSet( sink->multi_sink.fontset ); + + _XawTextPosToXY( w, pos, x, y ); + *y += abs( ext->max_logical_extent.y ); +} diff --git a/xc/lib/Xaw/MultiSink.h b/xc/lib/Xaw/MultiSink.h new file mode 100644 index 000000000..1f6e8b7bf --- /dev/null +++ b/xc/lib/Xaw/MultiSink.h @@ -0,0 +1,95 @@ +/* $XConsortium: MultiSink.h,v 1.0 94/01/01 00:00:00 kaleb Exp $ */ + +/* + * Copyright 1991 by OMRON Corporation + * Copyright 1991 by Massachusetts Institute of Technology + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, 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 names of OMRON and MIT not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. OMRON and MIT make no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * OMRON AND MIT DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OMRON OR MIT BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Li Yuhong OMRON Corporation + */ + +/*********************************************************** +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts, +and the Massachusetts Institute of Technology, Cambridge, Massachusetts. + + All Rights Reserved + +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 names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XawMultiSink_h +#define _XawMultiSink_h + +/*********************************************************************** + * + * MultiSink Object + * + ***********************************************************************/ + +#include <X11/Xaw/TextSink.h> + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + echo Output Boolean True + displayNonprinting Output Boolean True + fontSet FontSet XFontSet XtDefaultFontSet + +*/ + +#define XtCOutput "Output" + +#define XtNdisplayNonprinting "displayNonprinting" +#define XtNecho "echo" + +#ifndef XtNfontSet /*Sheeran, Omron KK, 93/03/04*/ +#define XtNfontSet "fontSet" +#endif + +#ifndef XtCFontSet /*Sheeran, Omron KK, 93/03/04*/ +#define XtCFontSet "FontSet" +#endif + +/* Class record constants */ + +extern WidgetClass multiSinkObjectClass; + +typedef struct _MultiSinkClassRec *MultiSinkObjectClass; +typedef struct _MultiSinkRec *MultiSinkObject; + + +#endif /* _XawMultiSrc_h */ +/* DON'T ADD STUFF AFTER THIS #endif */ diff --git a/xc/lib/Xaw/MultiSinkP.h b/xc/lib/Xaw/MultiSinkP.h new file mode 100644 index 000000000..c18467789 --- /dev/null +++ b/xc/lib/Xaw/MultiSinkP.h @@ -0,0 +1,134 @@ +/* $XConsortium: MultiSinkP.h,v 1.0 94/01/01 00:00:00 kaleb Exp $ */ + +/* + * Copyright 1991 by OMRON Corporation + * Copyright 1991 by Massachusetts Institute of Technology + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, 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 names of OMRON and MIT not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. OMRON and MIT make no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * OMRON AND MIT DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OMRON OR MIT BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Li Yuhong OMRON Corporation + */ + + +/*********************************************************** +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts, +and the Massachusetts Institute of Technology, Cambridge, Massachusetts. + + All Rights Reserved + +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 names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + * multiSinkP.h - Private definitions for multiSink object + * + */ + +#ifndef _XawMultiSinkP_h +#define _XawMultiSinkP_h + +/*********************************************************************** + * + * MultiSink Object Private Data + * + ***********************************************************************/ + +#include <X11/Xaw/TextSinkP.h> +#include <X11/Xaw/MultiSink.h> + +/************************************************************ + * + * New fields for the MultiSink object class record. + * + ************************************************************/ + +typedef struct _MultiSinkClassPart { + int foo; +} MultiSinkClassPart; + +/* Full class record declaration */ + +typedef struct _MultiSinkClassRec { + ObjectClassPart object_class; + TextSinkClassPart text_sink_class; + MultiSinkClassPart multi_sink_class; +} MultiSinkClassRec; + +extern MultiSinkClassRec multiSinkClassRec; + +/* New fields for the MultiSink object record */ +typedef struct { + /* public resources */ + Boolean echo; + Boolean display_nonprinting; + + /* private state */ + GC normgc, invgc, xorgc; + Pixmap insertCursorOn; + XawTextInsertState laststate; + short cursor_x, cursor_y; /* Cursor Location. */ + XFontSet fontset; /* font set to draw */ +} MultiSinkPart; + +/**************************************************************** + * + * Full instance record declaration + * + ****************************************************************/ + +typedef struct _MultiSinkRec { + ObjectPart object; + TextSinkPart text_sink; + MultiSinkPart multi_sink; +} MultiSinkRec; + + +/******************************************** + * + * Semi-private functions + * for use by other Xaw modules only + * + *******************************************/ + +extern void _XawMultiSinkPosToXY( +#if NeedFunctionPrototypes + Widget /* w */, + XawTextPosition /* pos */, + Position * /* x */, + Position * /*y */ +#endif +); + +#endif /* _XawMultiSinkP_h */ + diff --git a/xc/lib/Xaw/MultiSrc.c b/xc/lib/Xaw/MultiSrc.c new file mode 100644 index 000000000..8f8243049 --- /dev/null +++ b/xc/lib/Xaw/MultiSrc.c @@ -0,0 +1,1437 @@ +/* $XConsortium: MultiSrc.c,v 1.0 94/01/01 00:00:00 kaleb Exp $ */ + +/* + * Copyright 1991 by OMRON Corporation + * Copyright 1991 by Massachusetts Institute of Technology + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, 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 names of OMRON and MIT not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. OMRON and MIT make no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * OMRON AND MIT DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OMRON OR MIT BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Chris Peterson MIT X Consortium + * Li Yuhong OMRON Corporation + * Frank Sheeran OMRON Corporation + * + * Much code taken from X11R3 String and Disk Sources. + */ + +/* + * MultiSrc.c - MultiSrc object. (For use with the text widget). + * + */ + +#include <X11/IntrinsicP.h> +#include <X11/StringDefs.h> +#include <stdio.h> +#include <ctype.h> +#include <errno.h> +#include <X11/Xfuncs.h> +#include <X11/Xaw/XawInit.h> +#include <X11/Xaw/MultiSrcP.h> +#include <X11/Xaw/XawImP.h> +#include <X11/Xmu/Misc.h> +#include <X11/Xmu/CharSet.h> +#include "XawI18n.h" + +/**************************************************************** + * + * Full class record constant + * + ****************************************************************/ + +/* Private Data */ + +static int magic_value = MAGIC_VALUE; + +#define offset(field) XtOffsetOf(MultiSrcRec, multi_src.field) + +static XtResource resources[] = { + {XtNstring, XtCString, XtRString, sizeof (XtPointer), + offset(string), XtRPointer, NULL}, + {XtNtype, XtCType, XtRMultiType, sizeof (XawAsciiType), + offset(type), XtRImmediate, (XtPointer)XawAsciiString}, + /* not used. */ + {XtNdataCompression, XtCDataCompression, XtRBoolean, sizeof (Boolean), + offset(data_compression), XtRImmediate, (XtPointer) FALSE}, + {XtNpieceSize, XtCPieceSize, XtRInt, sizeof (XawTextPosition), + offset(piece_size), XtRImmediate, (XtPointer) BUFSIZ}, + {XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer), + offset(callback), XtRCallback, (XtPointer)NULL}, + {XtNuseStringInPlace, XtCUseStringInPlace, XtRBoolean, sizeof (Boolean), + offset(use_string_in_place), XtRImmediate, (XtPointer) FALSE}, + {XtNlength, XtCLength, XtRInt, sizeof (int), + offset(multi_length), XtRInt, (XtPointer) &magic_value}, + +}; +#undef offset + +static XawTextPosition Scan(), Search(), ReadText(); +static int ReplaceText(); +static MultiPiece * FindPiece(), * AllocNewPiece(); +static FILE * InitStringOrFile(); +static void FreeAllPieces(), RemovePiece(), BreakPiece(), LoadPieces(); +static void RemoveOldStringOrFile(), CvtStringToMultiType(); +static void ClassInitialize(), Initialize(), Destroy(), GetValuesHook(); +static String StorePiecesInString(); +static Boolean SetValues(), WriteToFile(); + +#define MyWStrncpy( t,s,wcnt ) (void) memmove( (t), (s), (wcnt)*sizeof(wchar_t)) + +#ifndef MyWStrncpy +static void (MyWStrncpy)(); +#endif + +extern char *tmpnam(); +#ifdef X_NOT_STDC_ENV +extern int errno; +#endif +#if !defined(WIN32) && (defined(X_NOT_STDC_ENV) || (defined(sun) && !defined(SVR4))) +extern int sys_nerr; +extern char* sys_errlist[]; +#endif + +#ifdef X_NOT_POSIX +#define Off_t long +#define Size_t unsigned int +#else +#define Off_t off_t +#define Size_t size_t +#endif + +extern wchar_t* _XawTextMBToWC(); +extern char *_XawTextWCToMB(); + +#define superclass (&textSrcClassRec) +MultiSrcClassRec multiSrcClassRec = { + { /* object_class fields */ + /* superclass */ (WidgetClass) superclass, + /* class_name */ "MultiSrc", + /* widget_size */ sizeof(MultiSrcRec), + /* class_initialize */ ClassInitialize, + /* class_part_initialize */ NULL, + /* class_inited */ FALSE, + /* initialize */ Initialize, + /* initialize_hook */ NULL, + /* pad */ NULL, + /* pad */ NULL, + /* pad */ 0, + /* resources */ resources, + /* num_resources */ XtNumber(resources), + /* xrm_class */ NULLQUARK, + /* pad */ FALSE, + /* pad */ FALSE, + /* pad */ FALSE, + /* pad */ FALSE, + /* destroy */ Destroy, + /* pad */ NULL, + /* pad */ NULL, + /* set_values */ SetValues, + /* set_values_hook */ NULL, + /* pad */ NULL, + /* get_values_hook */ GetValuesHook, + /* pad */ NULL, + /* version */ XtVersion, + /* callback_private */ NULL, + /* pad */ NULL, + /* pad */ NULL, + /* pad */ NULL, + /* extension */ NULL + }, + { /* textSrc_class fields */ + /* Read */ ReadText, + /* Replace */ ReplaceText, + /* Scan */ Scan, + /* Search */ Search, + /* SetSelection */ XtInheritSetSelection, + /* ConvertSelection */ XtInheritConvertSelection + }, + { /* multiSrc_class fields */ + /* Keep the compiler happy */ '\0' + } +}; + +WidgetClass multiSrcObjectClass = (WidgetClass)&multiSrcClassRec; + +/************************************************************ + * + * Semi-Public Interfaces. + * + ************************************************************/ + +/* Function Name: ClassInitialize + * Description: Class Initialize routine, called only once. + * Arguments: none. + * Returns: none. + */ + +static void +ClassInitialize() +{ + XawInitializeWidgetSet(); + XtAddConverter( XtRString, XtRMultiType, CvtStringToMultiType, + NULL, (Cardinal) 0); +} + +/* Function Name: Initialize + * Description: Initializes the simple menu widget + * Arguments: request - the widget requested by the argument list. + * new - the new widget with both resource and non + * resource values. + * Returns: none. + */ + +/* ARGSUSED */ +static void +Initialize(request, new, args, num_args) + Widget request, new; + ArgList args; + Cardinal* num_args; +{ + MultiSrcObject src = (MultiSrcObject) new; + FILE * file; + +/* + * Set correct flags (override resources) depending upon widget class. + */ + + src->multi_src.changes = FALSE; + src->multi_src.allocated_string = FALSE; + + file = InitStringOrFile(src, src->multi_src.type == XawAsciiFile); + LoadPieces(src, file, NULL); + + if (file != NULL) fclose(file); + src->text_src.text_format = FMTWIDE; + +} + +/* Function Name: ReadText + * Description: This function reads the source. + * Arguments: w - the MultiSource widget. + * pos - position of the text to retreive. + * RETURNED text - text block that will contain returned text. + * length - maximum number of characters to read. + * Returns: The number of characters read into the buffer. + */ + +static XawTextPosition +ReadText(w, pos, text, length) + Widget w; + XawTextPosition pos; + XawTextBlock* text; + int length; +{ + MultiSrcObject src = (MultiSrcObject) w; + XawTextPosition count, start; + MultiPiece * piece = FindPiece(src, pos, &start); + + text->format = FMTWIDE; + text->firstPos = pos; + text->ptr = (char *)(piece->text + (pos - start)); + count = piece->used - (pos - start); + text->length = (length > count) ? count : length; + return(pos + text->length); +} + +/* Function Name: ReplaceText. + * Description: Replaces a block of text with new text. + * Arguments: w - the MultiSource widget. + * startPos, endPos - ends of text that will be removed. + * text - new text to be inserted into buffer at startPos. + * Returns: XawEditError or XawEditDone. + */ + +/*ARGSUSED*/ +static int +ReplaceText( w, startPos, endPos, u_text_p) + Widget w; + XawTextPosition startPos, endPos; + XawTextBlock* u_text_p; +{ + MultiSrcObject src = (MultiSrcObject) w; + MultiPiece *start_piece, *end_piece, *temp_piece; + XawTextPosition start_first, end_first; + int length, firstPos; + wchar_t *wptr; + Boolean local_artificial_block = False; + XawTextBlock text; + + /* STEP 1: The user handed me a text block called `u_text' that may be in either + FMTWIDE or FMT8BIT (ie MB.) Later code needs the block `text' to hold FMTWIDE. + So, this copies `u_text' to `text', and if `u_text' was MB, I knock it up to WIDE. */ + + if ( u_text_p->length == 0 ) /* if so, the block contents never refered to. */ + text.length = 0; + + else if ( u_text_p->format == FMTWIDE) { + local_artificial_block = False; /* ie, don't have to free it ourselves*/ + text.firstPos = u_text_p->firstPos; + text.length = u_text_p->length; + text.ptr = u_text_p->ptr; + /* text.format is unneeded */ + + } else { + /* WARNING! u_text->firstPos and length are in units of CHAR, not CHARACTERS! */ + + local_artificial_block = True; /* ie, have to free it ourselves */ + text.firstPos = 0; + text.length = u_text_p->length; /* _XawTextMBToWC converts this to wchar len. */ + + text.ptr = (char*)_XawTextMBToWC( XtDisplay(XtParent(w)), + &(u_text_p->ptr[u_text_p->firstPos]), &(text.length) ); + + /* I assert the following assignment is not needed - since Step 4 + depends on length, it has no need of a terminating NULL. I think + the ASCII-version has the same needless NULL. */ + /*((wchar_t*)text.ptr)[ text.length ] = NULL;*/ + } + + + /* STEP 2: some initialization... */ + + if (src->text_src.edit_mode == XawtextRead) + return(XawEditError); + + start_piece = FindPiece(src, startPos, &start_first); + end_piece = FindPiece(src, endPos, &end_first); + + + /* STEP 3: remove the empty pieces... */ + + if (start_piece != end_piece) { + temp_piece = start_piece->next; + + /* If empty and not the only piece then remove it. */ + + if ( ((start_piece->used = startPos - start_first) == 0) && + !((start_piece->next == NULL) && (start_piece->prev == NULL)) ) + RemovePiece(src, start_piece); + + while (temp_piece != end_piece) { + temp_piece = temp_piece->next; + RemovePiece(src, temp_piece->prev); + } + end_piece->used -= endPos - end_first; + if (end_piece->used != 0) + MyWStrncpy(end_piece->text, (end_piece->text + endPos - end_first), + (int) end_piece->used); + } + else { /* We are fully in one piece. */ + if ( (start_piece->used -= endPos - startPos) == 0) { + if ( !((start_piece->next == NULL) && (start_piece->prev == NULL)) ) + RemovePiece(src, start_piece); + } + else { + MyWStrncpy(start_piece->text + (startPos - start_first), + start_piece->text + (endPos - start_first), + (int) (start_piece->used - (startPos - start_first)) ); + if ( src->multi_src.use_string_in_place && + ((src->multi_src.length - (endPos - startPos)) < + (src->multi_src.piece_size - 1)) ) + start_piece->text[src->multi_src.length - (endPos - startPos)] = (wchar_t)NULL; + } + } + + src->multi_src.length += text.length -(endPos - startPos); + /*((TextWidget)src->object.parent)->text.lastPos = src->multi_src.length;*/ + + + + /* STEP 4: insert the new stuff */ + + if ( text.length != 0) { + + start_piece = FindPiece(src, startPos, &start_first); + + length = text.length; + firstPos = text.firstPos; + + while (length > 0) { + wchar_t* ptr; + int fill; + + if (src->multi_src.use_string_in_place) { + if (start_piece->used == (src->multi_src.piece_size - 1)) { + /* + * The string is used in place, then the string + * is not allowed to grow. + */ + start_piece->used = src->multi_src.length = + src->multi_src.piece_size - 1; + /*((TextWidget)src->object.parent)->text.lastPos = src->multi_src.length;*/ + + + start_piece->text[src->multi_src.length] = (wchar_t)NULL; + return(XawEditError); + } + } + + + if (start_piece->used == src->multi_src.piece_size) { + BreakPiece(src, start_piece); + start_piece = FindPiece(src, startPos, &start_first); + } + + fill = Min((int)(src->multi_src.piece_size - start_piece->used), length); + + ptr = start_piece->text + (startPos - start_first); + MyWStrncpy(ptr + fill, ptr, + (int) start_piece->used - (startPos - start_first)); + wptr =(wchar_t *)text.ptr; + (void)wcsncpy(ptr, wptr + firstPos, fill); + + startPos += fill; + firstPos += fill; + start_piece->used += fill; + length -= fill; + } + } + + if ( local_artificial_block == True ) + + /* In other words, text is not the u_text that the user handed me but + one I made myself. I only care, because I need to free the string. */ + + XtFree( text.ptr ); + + if (src->multi_src.use_string_in_place) + start_piece->text[start_piece->used] = (wchar_t)NULL; + + src->multi_src.changes = TRUE; + + XtCallCallbacks(w, XtNcallback, NULL); + + return(XawEditDone); +} + +/* Function Name: Scan + * Description: Scans the text source for the number and type + * of item specified. + * Arguments: w - the MultiSource widget. + * position - the position to start scanning. + * type - type of thing to scan for. + * dir - direction to scan. + * count - which occurance if this thing to search for. + * include - whether or not to include the character found in + * the position that is returned. + * Returns: the position of the item found. + * + * Note: While there are only 'n' characters in the file there are n+1 + * possible cursor positions (one before the first character and + * one after the last character. + */ + +static +XawTextPosition +Scan( w, position, type, dir, count, include ) + Widget w; + XawTextPosition position; + XawTextScanType type; + XawTextScanDirection dir; + int count; + Boolean include; +{ + MultiSrcObject src = (MultiSrcObject) w; + int inc; + MultiPiece * piece; + XawTextPosition first, first_eol_position; + wchar_t * ptr; + + if (type == XawstAll) { /* Optimize this common case. */ + if (dir == XawsdRight) + return(src->multi_src.length); + return(0); /* else. */ + } + + + /* STEP 1: basic sanity checks */ + + if (position > src->multi_src.length) + position = src->multi_src.length; + + + if ( dir == XawsdRight ) { + if (position == src->multi_src.length) + return(src->multi_src.length); + inc = 1; + } + else { + if (position == 0) + return(0); + inc = -1; + position--; + } + + piece = FindPiece(src, position, &first); + + if ( piece->used == 0 ) return(0); /* i.e., buffer is empty. */ + + ptr = (position - first) + piece->text; + + switch (type) { + case XawstEOL: + case XawstParagraph: + case XawstWhiteSpace: + for ( ; count > 0 ; count-- ) { + Boolean non_space = FALSE, first_eol = TRUE; + /* CONSTCOND */ + while (TRUE) { + wchar_t c = *ptr; + + ptr += inc; + position += inc; + + if (type == XawstWhiteSpace) { + if (iswspace(c)) { + if (non_space) + break; + } + else + non_space = TRUE; + } + else if (type == XawstEOL) { + if (c == atowc('\n')) break; + } + else { /* XawstParagraph */ + if (first_eol) { + if (c == atowc('\n')) { + first_eol_position = position; + first_eol = FALSE; + } + } + else + if ( c == atowc('\n')) + break; + else if ( !iswspace(c) ) + first_eol = TRUE; + } + + + if ( ptr < piece->text ) { + piece = piece->prev; + if (piece == NULL) /* Begining of text. */ + return(0); + ptr = piece->text + piece->used - 1; + } + else if ( ptr >= (piece->text + piece->used) ) { + piece = piece->next; + if (piece == NULL) /* End of text. */ + return(src->multi_src.length); + ptr = piece->text; + } + } + } + if (!include) { + if ( type == XawstParagraph) + position = first_eol_position; + position -= inc; + } + break; + case XawstPositions: + position += count * inc; + break; +/* case XawstAll: ---- handled in special code above */ + } + + if ( dir == XawsdLeft ) + position++; + + if (position >= src->multi_src.length) + return(src->multi_src.length); + if (position < 0) + return(0); + + return(position); +} + +/* Function Name: Search + * Description: Searchs the text source for the text block passed + * Arguments: w - the MultiSource Widget. + * position - the position to start scanning. + * dir - direction to scan. + * text - the text block to search for. + * Returns: the position of the item found. + */ + +static XawTextPosition +Search(w, position, dir, text ) + Widget w; + XawTextPosition position; + XawTextScanDirection dir; + XawTextBlock* text; +{ + MultiSrcObject src = (MultiSrcObject) w; + int inc, count = 0; + wchar_t * ptr; + wchar_t* wtarget; + int wtarget_len; + Display * d = XtDisplay(XtParent(w)); + MultiPiece * piece; + wchar_t* buf; + XawTextPosition first; + + + /* STEP 1: First, a brief sanity check. */ + + if ( dir == XawsdRight ) + inc = 1; + else { + inc = -1; + if (position == 0) + return(XawTextSearchError); /* scanning left from 0??? */ + position--; + } + + + /* STEP 2: Ensure I have a local wide string.. */ + + /* Since this widget stores 32bit chars, I check here to see if + I'm being passed a string claiming to be 8bit chars (ie, MB text.) + If that is the case, naturally I convert to 32bit format. */ + + /*if the block was FMT8BIT, length will convert to REAL wchar count below */ + wtarget_len = text->length; + + if ( text->format == FMTWIDE ) + wtarget = &( ((wchar_t*)text->ptr) [text->firstPos] ); + else + { + /* The following converts wtarget_len from byte len to wchar count */ + wtarget = _XawTextMBToWC( d, &text->ptr[ text->firstPos ], &wtarget_len ); + } + + /* OK, I can now assert that wtarget holds wide characters, wtarget_len + holds an accurate count of those characters, and that firstPos has been + effectively factored out of the following computations. */ + + + /* STEP 3: SEARCH! */ + + buf = (wchar_t *)XtMalloc((unsigned)sizeof(wchar_t) * wtarget_len ); + (void)wcsncpy(buf, wtarget, wtarget_len ); + piece = FindPiece(src, position, &first); + ptr = (position - first) + piece->text; + + /* CONSTCOND */ + while (TRUE) { + if (*ptr == ((dir == XawsdRight) ? *(buf + count) + : *(buf + wtarget_len - count - 1)) ) { + if (count == (text->length - 1)) + break; + else + count++; + } + else { + if (count != 0) { + position -=inc * count; + ptr -= inc * count; + } + count = 0; + } + + ptr += inc; + position += inc; + + while ( ptr < piece->text ) { + piece = piece->prev; + if (piece == NULL) { /* Begining of text. */ + XtFree((char *)buf); + return(XawTextSearchError); + } + ptr = piece->text + piece->used - 1; + } + + while ( ptr >= (piece->text + piece->used) ) { + piece = piece->next; + if (piece == NULL) { /* End of text. */ + XtFree((char *)buf); + return(XawTextSearchError); + } + ptr = piece->text; + } + } + + XtFree( (char *) buf ); + if (dir == XawsdLeft) + return( position ); + return( position - ( wtarget_len - 1 ) ); +} + +/* Function Name: SetValues + * Description: Sets the values for the MultiSource. + * Arguments: current - current state of the widget. + * request - what was requested. + * new - what the widget will become. + * Returns: True if redisplay is needed. + */ + +/* ARGSUSED */ +static Boolean +SetValues(current, request, new, args, num_args) + Widget current, request, new; + ArgList args; + Cardinal* num_args; +{ + MultiSrcObject src = (MultiSrcObject) new; + MultiSrcObject old_src = (MultiSrcObject) current; + XtAppContext app_con = XtWidgetToApplicationContext(new); + Boolean total_reset = FALSE, string_set = FALSE; + FILE * file; + int i; + + if ( old_src->multi_src.use_string_in_place != + src->multi_src.use_string_in_place ) { + XtAppWarning( app_con, + "MultiSrc: The XtNuseStringInPlace resources may not be changed."); + src->multi_src.use_string_in_place = + old_src->multi_src.use_string_in_place; + } + + for (i = 0; i < *num_args ; i++ ) + if (streq(args[i].name, XtNstring)) { + string_set = TRUE; + break; + } + + if ( string_set || (old_src->multi_src.type != src->multi_src.type) ) { + RemoveOldStringOrFile(old_src, string_set); + file = InitStringOrFile(src, string_set); + + /* Load pieces does this logic for us, but it shouldn't. Its messy.*/ + /*if (old_src->multi_src.type == XawAsciiString) + LoadPieces(src, NULL, src->multi_src.string); + else*/ + LoadPieces(src, file, NULL); + if (file != NULL) fclose(file); + XawTextSetSource( XtParent(new), new, 0); /* Tell text widget + what happened. */ + total_reset = TRUE; + } + + if ( old_src->multi_src.multi_length != src->multi_src.multi_length ) + src->multi_src.piece_size = src->multi_src.multi_length; + + if ( !total_reset && (old_src->multi_src.piece_size + != src->multi_src.piece_size) ) { + String mb_string = StorePiecesInString( old_src ); + + if ( mb_string != 0 ) { + FreeAllPieces( old_src ); + LoadPieces( src, NULL, mb_string ); + XtFree( mb_string ); + } else { + /* If the buffer holds bad chars, don't touch it... */ + XtAppWarningMsg( app_con, + "convertError", "multiSource", "XawError", + XtName( XtParent( (Widget) old_src ) ), NULL, NULL ); + XtAppWarningMsg( app_con, + "convertError", "multiSource", "XawError", + "Non-character code(s) in buffer.", NULL, NULL ); + } + } + + return(FALSE); +} + +/* Function Name: GetValuesHook + * Description: This is a get values hook routine that sets the + * values specific to the multi source. + * Arguments: w - the MultiSource Widget. + * args - the argument list. + * num_args - the number of args. + * Returns: none. + */ + +static void +GetValuesHook(w, args, num_args) + Widget w; + ArgList args; + Cardinal* num_args; +{ + MultiSrcObject src = (MultiSrcObject) w; + int i; + + if (src->multi_src.type == XawAsciiString) { + for (i = 0; i < *num_args ; i++ ) + if (streq(args[i].name, XtNstring)) { + if (src->multi_src.use_string_in_place) { + *((char **) args[i].value) = (char *) + src->multi_src.first_piece->text; + } + else { + if (_XawMultiSave(w)) /* If save sucessful. */ + *((char **) args[i].value) = src->multi_src.string; + } + break; + } + } +} + +/* Function Name: Destroy + * Description: Destroys an multi source (frees all data) + * Arguments: src - the Multi source Widget to free. + * Returns: none. + */ + +static void +Destroy (w) + Widget w; +{ + RemoveOldStringOrFile((MultiSrcObject) w, True); +} + +/************************************************************ + * + * Public routines + * + ************************************************************/ + +/* Function Name: XawMultiSourceFreeString + * Description: Frees the string returned by a get values call + * on the string when the source is of type string. + * Arguments: w - the MultiSrc widget. + * Returns: none. + * + * The public interface is XawAsciiSourceFreeString! + */ + +void +#if NeedFunctionPrototypes +_XawMultiSourceFreeString( + Widget w) +#else +_XawMultiSourceFreeString(w) + Widget w; +#endif +{ + MultiSrcObject src = (MultiSrcObject) w; + +/*if (src->multi_src.allocated_string&& src->multi_src.type != XawAsciiFile) {*/ + /* ASSERT: src->multi_src.allocated_string -> we MUST free .string! */ + if ( src->multi_src.allocated_string ) { + XtFree(src->multi_src.string); + src->multi_src.allocated_string = FALSE; + src->multi_src.string = NULL; + } +} + +/* Function Name: _XawMultiSave + * Description: Saves all the pieces into a file or string as required. + * Arguments: w - the multiSrc Widget. + * Returns: TRUE if the save was successful. + * + * The public interface is XawAsciiSave(w)! + */ + +Boolean +#if NeedFunctionPrototypes +_XawMultiSave( + Widget w) +#else +_XawMultiSave(w) + Widget w; +#endif +{ + MultiSrcObject src = (MultiSrcObject) w; + XtAppContext app_con = XtWidgetToApplicationContext(w); + char * mb_string; + +/* + * If using the string in place then there is no need to play games + * to get the internal info into a readable string. + */ + + if (src->multi_src.use_string_in_place) + return(TRUE); + + if (src->multi_src.type == XawAsciiFile) { + + if (!src->multi_src.changes) /* No changes to save. */ + return(TRUE); + + mb_string = StorePiecesInString( src ); + + if ( mb_string != 0 ) { + if ( WriteToFile( mb_string, src->multi_src.string ) == FALSE ) { + XtFree( mb_string ); + return( FALSE ); + } + XtFree( mb_string ); + src->multi_src.changes = FALSE; + return( TRUE ); + } else { + /* If the buffer holds bad chars, don't touch it... */ + XtAppWarningMsg( app_con, + "convertError", "multiSource", "XawError", + "Due to illegal characters, file not saved.", NULL, NULL); + return( FALSE ); + } + } + else { + + /* THIS FUNCTIONALITY IS UNDOCUMENTED, probably UNNEEDED? The manual + says this routine's only function is to save files to disk. -Sheeran */ + + mb_string = StorePiecesInString( src ); + + if ( mb_string == 0 ) { + /* If the buffer holds bad chars, don't touch it... */ + XtAppWarningMsg( app_con, + "convertError", "multiSource", "XawError", + XtName( XtParent( (Widget) src ) ), NULL, NULL); + return( FALSE ); + } + + /* assert: mb_string holds good characters so the buffer is fine */ + if (src->multi_src.allocated_string == TRUE) + XtFree(src->multi_src.string); + else + src->multi_src.allocated_string = TRUE; + + src->multi_src.string = mb_string; + } + src->multi_src.changes = FALSE; + return(TRUE); +} + +/* Function Name: XawMultiSaveAsFile + * Description: Save the current buffer as a file. + * Arguments: w - the MultiSrc widget. + * name - name of the file to save this file into. + * Returns: True if the save was sucessful. + * + * The public interface is XawAsciiSaveAsFile! + */ + +Boolean +#if NeedFunctionPrototypes +_XawMultiSaveAsFile( + Widget w, + _Xconst char* name) +#else +_XawMultiSaveAsFile(w, name) + Widget w; + String name; +#endif +{ + MultiSrcObject src = (MultiSrcObject) w; + String mb_string; + Boolean ret; + + mb_string = StorePiecesInString( src ); + + if ( mb_string != 0 ) { + ret = WriteToFile( mb_string, name ); + XtFree( mb_string ); + return( ret ); + } + + /* otherwise there was a conversion error. So print widget name too. */ + XtAppWarningMsg( XtWidgetToApplicationContext(w), + "convertError", "multiSource", "XawError", + XtName( XtParent( (Widget) src ) ), NULL, NULL); + return( False ); +} + +/************************************************************ + * + * Private Functions. + * + ************************************************************/ + +static void +RemoveOldStringOrFile(src, checkString) + MultiSrcObject src; + Boolean checkString; +{ + FreeAllPieces(src); + + if (checkString && src->multi_src.allocated_string) { + XtFree(src->multi_src.string); + src->multi_src.allocated_string = False; + src->multi_src.string = NULL; + } +} + +/* Function Name: WriteToFile + * Description: Write the string specified to the begining of the file + * specified. + * Arguments: string - string to write. + * name - the name of the file + * Returns: returns TRUE if sucessful, FALSE otherwise. + */ + +static Boolean +WriteToFile(string, name) + String string, name; +{ + int fd; + + if ( ((fd = creat(name, 0666)) == -1 ) || + (write(fd, string, sizeof(unsigned char) * strlen(string)) == -1) ) + return(FALSE); + + if ( close(fd) == -1 ) + return(FALSE); + + return(TRUE); +} + + +/* Function Name: StorePiecesInString + * Description: store the pieces in memory into a char string. + * Arguments: src - the multiSrc to gather data from + * Returns: char *mb_string. Caller must free. + * or 0: conversion error. Caller must panic! + */ + +static String +StorePiecesInString(src) + MultiSrcObject src; +{ + wchar_t* wc_string; + char *mb_string; + int char_count = src->multi_src.length; + XawTextPosition first; + MultiPiece * piece; + + /* I believe the char_count + 1 and the NULL termination are unneeded! FS*/ + + wc_string = (wchar_t*) XtMalloc((unsigned)(char_count + 1) * sizeof(wchar_t)); + + for (first = 0, piece = src->multi_src.first_piece ; piece != NULL; + first += piece->used, piece = piece->next) + (void) wcsncpy( wc_string + first, piece->text, piece->used ); + + wc_string[ char_count ] = (wchar_t)NULL; /* NULL terminate this sucker. */ + + + /* This will refill all pieces to capacity. */ + + if ( src->multi_src.data_compression ) { + FreeAllPieces( src ); + LoadPieces( src, NULL, (char *)wc_string ); + } + + /* Lastly, convert it to a MB format and send it back. */ + + mb_string = _XawTextWCToMB( XtDisplayOfObject( (Widget)src ), + wc_string, &char_count ); + + /* NOTE THAT mb_string MAY BE ZERO IF THE CONVERSION FAILED. */ + XtFree( (char*) wc_string ); + return( mb_string ); +} + + +/* Function Name: InitStringOrFile. + * Description: Initializes the string or file. + * Arguments: src - the MultiSource. + * Returns: none - May exit though. + */ + +static FILE * +InitStringOrFile(src, newString) + MultiSrcObject src; + Boolean newString; +{ + char * open_mode; + FILE * file; + char fileName[TMPSIZ]; + Display *d = XtDisplayOfObject((Widget)src); + + if (src->multi_src.type == XawAsciiString) { + + if (src->multi_src.string == NULL) + src->multi_src.length = 0; + + else if (! src->multi_src.use_string_in_place) { + int length; + String temp = XtNewString(src->multi_src.string); + if ( src->multi_src.allocated_string ) + XtFree( src->multi_src.string ); + src->multi_src.allocated_string = True; + src->multi_src.string = temp; + + length = strlen(src->multi_src.string); + + /* Wasteful, throwing away the WC string, but need side effect! */ + (void) _XawTextMBToWC(d, src->multi_src.string, &length); + src->multi_src.length = (XawTextPosition) length; + } else { + src->multi_src.length = strlen(src->multi_src.string); + /* In case the length resource is incorrectly set */ + if (src->multi_src.length > src->multi_src.multi_length) + src->multi_src.multi_length = src->multi_src.length; + + if (src->multi_src.multi_length == MAGIC_VALUE) + src->multi_src.piece_size = src->multi_src.length; + else + src->multi_src.piece_size = src->multi_src.multi_length + 1; + } + + /*((TextWidget)src->object.parent)->text.lastPos = src->multi_src.length;*/ + return(NULL); + } + +/* + * type is XawAsciiFile. + */ + + src->multi_src.is_tempfile = FALSE; + + switch (src->text_src.edit_mode) { + case XawtextRead: + if (src->multi_src.string == NULL) + XtErrorMsg("NoFile", "multiSourceCreate", "XawError", + "Creating a read only disk widget and no file specified.", + NULL, 0); + open_mode = "r"; + break; + case XawtextAppend: + case XawtextEdit: + if (src->multi_src.string == NULL) { + + if ( src->multi_src.allocated_string ) + XtFree( src->multi_src.string ); + src->multi_src.allocated_string = False; + src->multi_src.string = fileName; + + (void) tmpnam(src->multi_src.string); + src->multi_src.is_tempfile = TRUE; + open_mode = "w"; + } else + open_mode = "r+"; + break; + default: + XtErrorMsg("badMode", "multiSourceCreate", "XawError", + "Bad editMode for multi source; must be Read, Append or Edit.", + NULL, NULL); + } + + /* Allocate new memory for the temp filename, because it is held in + * a stack memory buffer. We must verify that all routines that set + * .string first check .allocated_string and free it - plumbing Sheeran. + */ + if (newString || src->multi_src.is_tempfile) { + if ( src->multi_src.allocated_string ) + XtFree( src->multi_src.string ); + src->multi_src.string = XtNewString(src->multi_src.string); + src->multi_src.allocated_string = TRUE; + } + + if (!src->multi_src.is_tempfile) { + if ((file = fopen(src->multi_src.string, open_mode)) != 0) { + (void) fseek(file, (Off_t)0, 2); + src->multi_src.length = ftell (file); + return file; + } else { + String params[2]; + Cardinal num_params = 2; + char msg[11]; + + params[0] = src->multi_src.string; +#if defined(X_NOT_STDC_ENV) || (defined(sun) && !defined(SVR4)) + if (errno <= sys_nerr) + params[1] = sys_errlist[errno]; + else { + sprintf(msg, "errno=%.4d", errno); + params[1] = msg; + } +#else + params[1] = msg; +#endif + XtAppWarningMsg(XtWidgetToApplicationContext((Widget)src), + "openError", "multiSourceCreate", "XawWarning", + "Cannot open file %s; %s", params, &num_params); + } + } + src->multi_src.length = 0; + return((FILE *)NULL); +#undef StrLen +} + +/* LoadPieces: This routine takes either the MB contents of open file `file' or the +MB contents of string or the MB contents of src->multi_src.string and places +them in Pieces in WC format. + +CAUTION: You must have src->multi_src.length set to file length bytes +when src->multi_src.type == XawAsciiFile. src->multi_src.length must be +the length of the parameter string if string is non-NULL. */ + +static void +LoadPieces(src, file, string) + MultiSrcObject src; + FILE* file; + char* string; +{ + Display *d = XtDisplayOfObject((Widget)src); + wchar_t* local_str, *ptr; + MultiPiece* piece = NULL; + XawTextPosition left; + int bytes = sizeof(wchar_t); + char* temp_mb_holder = NULL; + + /* + * This is tricky - the _XawTextMBtoWC converter uses its 3rd arg + * in as MB length, out as WC length. We want local_length to be + * WC count. + */ + int local_length = src->multi_src.length; + + if (string != NULL) { + /* + * ASSERT: IF our caller passed a non-null string, THEN + * src->multi_src.length is currently string's * byte count, + * AND string is in a MB format. + */ + local_str = _XawTextMBToWC(d, (char *)string, &local_length); + src->multi_src.length = (XawTextPosition) local_length; + } else if (src->multi_src.type != XawAsciiFile) { + /* + * here, we are not changing the contents, just reloading, + * so don't change len... + */ + local_length = src->multi_src.string ? + strlen( src->multi_src.string ) : 0; + local_str = _XawTextMBToWC( d, (char*)src->multi_src.string, &local_length ); + } else { + if (src->multi_src.length != 0) { + temp_mb_holder = + XtMalloc((unsigned)(src->multi_src.length + 1) * sizeof(unsigned char)); + fseek(file, (Off_t)0, 0); + src->multi_src.length = fread (temp_mb_holder, + (Size_t)sizeof(unsigned char), + (Size_t)src->multi_src.length, file); + if (src->multi_src.length <= 0) + XtAppErrorMsg( XtWidgetToApplicationContext ((Widget) src), + "readError", "multiSource", "XawError", + "fread returned error.", NULL, NULL); + local_length = src->multi_src.length; + local_str = _XawTextMBToWC(d, temp_mb_holder, &local_length); + src->multi_src.length = local_length; + + if ( local_str == 0 ) { + String params[2]; + Cardinal num_params; + static char err_text[] = + "<<< FILE CONTENTS NOT REPRESENTABLE IN THIS LOCALE >>>"; + + params[0] = XtName(XtParent((Widget)src)); + params[1] = src->multi_src.string; + num_params = 2; + + XtAppWarningMsg( XtWidgetToApplicationContext((Widget)src), + "readLocaleError", "multiSource", "XawError", + "%s: The file `%s' contains characters not representable in this locale.", + params, &num_params); + src->multi_src.length = sizeof err_text; + local_length = src->multi_src.length; + local_str = _XawTextMBToWC(d, err_text, &local_length); + src->multi_src.length = local_length; + } + } else { /*ASSERT that since following while loop looks at local_length + this isn't needed. Sheeran, Omron KK, 1993/07/15 + temp_mb_holder[src->multi_src.length] = '\0';*/ + local_str = (wchar_t*)temp_mb_holder; + } + } + + if (src->multi_src.use_string_in_place) { + piece = AllocNewPiece(src, piece); + piece->used = Min(src->multi_src.length, src->multi_src.piece_size); + piece->text = (wchar_t*)src->multi_src.string; + return; + } + + ptr = local_str; + left = local_length; + + do { + piece = AllocNewPiece(src, piece); + + piece->text = (wchar_t*)XtMalloc(src->multi_src.piece_size * bytes); + piece->used = Min(left, src->multi_src.piece_size); + if (piece->used != 0) + (void) wcsncpy(piece->text, ptr, piece->used); + + left -= piece->used; + ptr += piece->used; + } while (left > 0); + + if ( temp_mb_holder ) + XtFree( (char*) temp_mb_holder ); +} + + +/* Function Name: AllocNewPiece + * Description: Allocates a new piece of memory. + * Arguments: src - The MultiSrc Widget. + * prev - the piece just before this one, or NULL. + * Returns: the allocated piece. + */ + +static MultiPiece * +AllocNewPiece(src, prev) + MultiSrcObject src; + MultiPiece * prev; +{ + MultiPiece * piece = XtNew(MultiPiece); + + if (prev == NULL) { + src->multi_src.first_piece = piece; + piece->next = NULL; + } + else { + if (prev->next != NULL) + (prev->next)->prev = piece; + piece->next = prev->next; + prev->next = piece; + } + + piece->prev = prev; + + return(piece); +} + +/* Function Name: FreeAllPieces + * Description: Frees all the pieces + * Arguments: src - The MultiSrc Widget. + * Returns: none. + */ + +static void +FreeAllPieces(src) + MultiSrcObject src; +{ + MultiPiece * next, * first = src->multi_src.first_piece; + + if (first->prev != NULL) + printf("Xaw MultiSrc Object: possible memory leak in FreeAllPieces().\n"); + + for ( ; first != NULL ; first = next ) { + next = first->next; + RemovePiece(src, first); + } +} + +/* Function Name: RemovePiece + * Description: Removes a piece from the list. + * Arguments: + * piece - the piece to remove. + * Returns: none. + */ + +static void +RemovePiece(src, piece) + MultiSrcObject src; + MultiPiece* piece; +{ + if (piece->prev == NULL) + src->multi_src.first_piece = piece->next; + else + (piece->prev)->next = piece->next; + + if (piece->next != NULL) + (piece->next)->prev = piece->prev; + + if (!src->multi_src.use_string_in_place) + XtFree((char *)piece->text); + + XtFree((char *)piece); +} + +/* Function Name: FindPiece + * Description: Finds the piece containing the position indicated. + * Arguments: src - The MultiSrc Widget. + * position - the position that we are searching for. + * RETURNED first - the position of the first character in this piece. + * Returns: piece - the piece that contains this position. + */ + +static MultiPiece * +FindPiece(src, position, first) + MultiSrcObject src; + XawTextPosition position, *first; +{ + MultiPiece * old_piece, * piece = src->multi_src.first_piece; + XawTextPosition temp; + + for ( temp = 0 ; piece != NULL ; temp += piece->used, piece = piece->next ) { + *first = temp; + old_piece = piece; + + if ((temp + piece->used) > position) + return(piece); + } + return(old_piece); /* if we run off the end the return the last piece */ +} + +/* Function Name: BreakPiece + * Description: Breaks a full piece into two new pieces. + * Arguments: src - The MultiSrc Widget. + * piece - the piece to break. + * Returns: none. + */ + +#define HALF_PIECE (src->multi_src.piece_size/2) + +static void +BreakPiece(src, piece) + MultiSrcObject src; + MultiPiece* piece; +{ + MultiPiece * new = AllocNewPiece(src, piece); + + new->text = (wchar_t*)XtMalloc(src->multi_src.piece_size * sizeof(wchar_t)); + (void) wcsncpy(new->text, piece->text + HALF_PIECE, + src->multi_src.piece_size - HALF_PIECE); + piece->used = HALF_PIECE; + new->used = src->multi_src.piece_size - HALF_PIECE; +} + +/* Convert string "XawAsciiString" and "XawAsciiFile" to quarks. */ + +/* ARGSUSED */ +static void +CvtStringToMultiType(args, num_args, fromVal, toVal) + XrmValuePtr args; /* unused */ + Cardinal* num_args; /* unused */ + XrmValuePtr fromVal; + XrmValuePtr toVal; +{ + static XawAsciiType type; + static XrmQuark XtQEstring = NULLQUARK; + static XrmQuark XtQEfile; + XrmQuark q; + char lowerName[BUFSIZ]; + + if (XtQEstring == NULLQUARK) { + XtQEstring = XrmPermStringToQuark(XtEstring); + XtQEfile = XrmPermStringToQuark(XtEfile); + } + + XmuCopyISOLatin1Lowered(lowerName, (char *) fromVal->addr); + q = XrmStringToQuark(lowerName); + + if (q == XtQEstring) type = XawAsciiString; + if (q == XtQEfile) type = XawAsciiFile; + + (*toVal).size = sizeof(XawAsciiType); + (*toVal).addr = (XPointer) &type; + return; +} diff --git a/xc/lib/Xaw/MultiSrc.h b/xc/lib/Xaw/MultiSrc.h new file mode 100644 index 000000000..0c93f73b6 --- /dev/null +++ b/xc/lib/Xaw/MultiSrc.h @@ -0,0 +1,140 @@ +/* $XConsortium: MultiSrc.h,v 1.0 94/01/01 00:00:00 kaleb Exp $ */ + +/* + * Copyright 1991 by OMRON Corporation + * Copyright 1991 by Massachusetts Institute of Technology + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, 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 names of OMRON and MIT not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. OMRON and MIT make no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * OMRON AND MIT DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OMRON OR MIT BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Li Yuhong OMRON Corporation + */ + +/* Copyright 1989 Massachusetts Institute of Technology + * + * 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 M.I.T. not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. M.I.T. makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + */ + + +/* + * This file was modified from AsciiSrc.h. + * + * By Li Yuhong, Sept. 18, 1990 + */ + +#ifndef _XawMultiSrc_h +#define _XawMultiSrc_h + +#include <X11/Xaw/TextSrc.h> +/*Xfuncproto.h included by Intrinsic.h*/ + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + callback Callback Callback (none) + dataCompression DataCompression Boolean True + length Length int (internal) + pieceSize PieceSize int BUFSIZ + string String String NULL + type Type XawAsciiType XawAsciiString + useStringInPlace UseStringInPlace Boolean False + +*/ + +/* Class record constants */ + +extern WidgetClass multiSrcObjectClass; + +typedef struct _MultiSrcClassRec *MultiSrcObjectClass; +typedef struct _MultiSrcRec *MultiSrcObject; + +/* + * Just to make people's lives a bit easier. + */ + +#define MultiSourceObjectClass MultiSrcObjectClass +#define MultiSourceObject MultiSrcObject + +/* + * Resource Definitions. + */ + +#define XtCDataCompression "DataCompression" +#define XtCPieceSize "PieceSize" +#define XtCType "Type" +#define XtCUseStringInPlace "UseStringInPlace" + +#define XtNdataCompression "dataCompression" +#define XtNpieceSize "pieceSize" +#define XtNtype "type" +#define XtNuseStringInPlace "useStringInPlace" + +#define XtRMultiType "MultiType" + +#define XtEstring "string" +#define XtEfile "file" + +/************************************************************ + * + * THESE ROUTINES ARE NOT PUBLIC: Source should call + * + * the AsciiSrc API which currently forwards requests here. + * + * future versions (like theres going to be an R7 Xaw!) may + * + * eliminate this file or at least these functions entirely. + * + ************************************************************/ + +_XFUNCPROTOBEGIN + + +extern void XawMultiSourceFreeString( +#if NeedFunctionPrototypes + Widget /* w */ +#endif +); + +extern Boolean _XawMultiSave( +#if NeedFunctionPrototypes + Widget /* w */ +#endif +); + +extern Boolean _XawMultiSaveAsFile( +#if NeedFunctionPrototypes + Widget /* w */, + _Xconst char* /* name */ +#endif +); + + +_XFUNCPROTOEND + +#endif /* _XawMultiSrc_h - Don't add anything after this line. */ + diff --git a/xc/lib/Xaw/MultiSrcP.h b/xc/lib/Xaw/MultiSrcP.h new file mode 100644 index 000000000..ed6557929 --- /dev/null +++ b/xc/lib/Xaw/MultiSrcP.h @@ -0,0 +1,171 @@ +/* $XConsortium: MultiSrcP.h,v 1.0 94/01/01 00:00:00 kaleb Exp $ */ + +/* + * Copyright 1991 by OMRON Corporation + * Copyright 1991 by Massachusetts Institute of Technology + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, 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 names of OMRON and MIT not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. OMRON and MIT make no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * OMRON AND MIT DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OMRON OR MIT BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Li Yuhong OMRON Corporation + */ + + +/*********************************************************** +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts, +and the Massachusetts Institute of Technology, Cambridge, Massachusetts. + + All Rights Reserved + +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 names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + * MultiSrcP.h - Private Header for Multi Text Source. + * + * This is the private header file for the Multi Text Source. + * It is intended to be used with the Text widget, the simplest way to use + * this text source is to use the MultiText Object. + * + * Date: June 29, 1989 + * + * By: Chris D. Peterson + * MIT X Consortium + * kit@expo.lcs.mit.edu + */ + +/* + * TextSrcP.h - Private definitions for MultiSrc object + * + */ + +/* + * This file was changed from AsciiSrcP.h. + * + * By Li Yuhong, Sept. 18, 1990 + */ + +#ifndef _XawMultiSrcP_h +#define _XawMultiSrcP_h + +#include <X11/Xaw/TextSrcP.h> +#include <X11/Xaw/MultiSrc.h> + +/************************************************************ + * + * Private declarations. + * + ************************************************************/ + +#ifdef L_tmpnam +#define TMPSIZ L_tmpnam +#else +#define TMPSIZ 32 /* bytes to allocate for tmpnam */ +#endif + +#define MAGIC_VALUE ((XawTextPosition) -1) /* Magic value. */ + +#define streq(a, b) ( strcmp((a), (b)) == 0 ) + +typedef struct _MultiPiece { /* Piece of the text file of BUFSIZ allocated + characters. */ + wchar_t* text; /* The text in this buffer. */ + XawTextPosition used; /* The number of characters of this buffer + that have been used. */ + struct _MultiPiece *prev, *next; /* linked list pointers. */ +} MultiPiece; + +/************************************************************ + * + * New fields for the MultiSrc object class record. + * + ************************************************************/ + +typedef struct _MultiSrcClassPart { char foo; } MultiSrcClassPart; + +/* Full class record declaration */ +typedef struct _MultiSrcClassRec { + ObjectClassPart object_class; + TextSrcClassPart text_src_class; + MultiSrcClassPart multi_src_class; +} MultiSrcClassRec; + +extern MultiSrcClassRec multiSrcClassRec; + +/* New fields for the MultiSrc object record */ + +typedef struct _MultiSrcPart { + + /* Resources. */ + + XIC ic; /* for X Input Method. */ + XtPointer string; /* either the string, or the file name, depend- + ing upon the `type'. ALWAYS IN MB FORMAT. */ + XawAsciiType type; /* either string or disk. */ + XawTextPosition piece_size; /* Size of text buffer for each piece. */ + Boolean data_compression; /* compress to minimum memory automatically + on save? */ + XtCallbackList callback; /* A callback list to call when the source is + changed. */ + Boolean use_string_in_place; /* Use the string passed in place. */ + int multi_length; /* length field for multi string emulation. */ + +/* Private data. */ + + Boolean is_tempfile; /* Is this a temporary file? */ + Boolean changes; /* Has this file been edited? */ + Boolean allocated_string; /* Have I allocated the + string in multi_src->string? */ + XawTextPosition length; /* length of file - IN CHARACTERS, NOT BYTES. */ + MultiPiece * first_piece; /* first piece of the text. */ +} MultiSrcPart; + +/**************************************************************** + * + * Full instance record declaration + * + ****************************************************************/ + +typedef struct _MultiSrcRec { + ObjectPart object; + TextSrcPart text_src; + MultiSrcPart multi_src; +} MultiSrcRec; + +#if NeedFunctionPrototypes +extern void _XawMultiSourceFreeString( Widget ); +#else +extern void _XawMultiSourceFreeString(); +#endif + +#endif /* _XawMultiSrcP_h --- Don't add anything after this line. */ diff --git a/xc/lib/Xaw/VendorEP.h b/xc/lib/Xaw/VendorEP.h new file mode 100644 index 000000000..6adf77419 --- /dev/null +++ b/xc/lib/Xaw/VendorEP.h @@ -0,0 +1,54 @@ +/* $XConsortium: VendorEP.h,v 1.0 94/01/01 00:00:00 kaleb Exp $ */ + +/* + * Copyright 1991 by OMRON Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, 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 OMRON not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. OMRON makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * OMRON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Author: Seiji Kuwari OMRON Corporation + * kuwa@omron.co.jp + * kuwa%omron.co.jp@uunet.uu.net + */ + +#ifndef _VendorEP_h +#define _VendorEP_h + +#include <X11/Xaw/XawImP.h> + +typedef struct { + XtPointer extension; +} XawVendorShellExtClassPart; + +typedef struct _VendorShellExtClassRec { + ObjectClassPart object_class; + XawVendorShellExtClassPart vendor_shell_ext_class; +} XawVendorShellExtClassRec; + +typedef struct { + Widget parent; + XawImPart im; + XawIcPart ic; +} XawVendorShellExtPart; + +typedef struct XawVendorShellExtRec { + ObjectPart object; + XawVendorShellExtPart vendor_ext; +} XawVendorShellExtRec, *XawVendorShellExtWidget; + +#endif /* _VendorEP_h */ diff --git a/xc/lib/Xaw/XawI18n.c b/xc/lib/Xaw/XawI18n.c new file mode 100644 index 000000000..8351e31c1 --- /dev/null +++ b/xc/lib/Xaw/XawI18n.c @@ -0,0 +1,67 @@ +/* $XConsortium: XawI18n.c,v 1.0 94/01/01 00:00:00 kaleb Exp $ */ + +/* Copyright 1991 NCR Corporation - Dayton, Ohio, USA */ +/* + * Copyright 1990, 1991 by OMRON Corporation, NTT Software Corporation, + * and Nippon Telegraph and Telephone Corporation + * Copyright 1991 by the Massachusetts Institute of Technology + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, 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 names of OMRON, NTT Software, NTT, and M.I.T. + * not be used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. OMRON, NTT Software, + * NTT, and M.I.T. make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * OMRON, NTT SOFTWARE, NTT, AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL OMRON, NTT SOFTWARE, NTT, OR M.I.T. BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Li Yuhong OMRON Corporation + * + */ + +#include <X11/IntrinsicP.h> +#include "XawI18n.h" + +#if NeedFunctionPrototypes +wchar_t atowc( + unsigned char c) +#else +wchar_t atowc(c) + unsigned char c; +#endif +{ + wchar_t wc; + unsigned char str[2]; + + str[0] = c; + str[1] = '\0'; + + mbtowc(&wc, str, 1); + return wc; +} + +#ifdef NCR + +int _iswspace(wchar_t w) +{ + int ret = 0; + + wchar_t s = atowc(' '); + + if (s == w) + ret = 1; + + return ret; +} + +#endif diff --git a/xc/lib/Xaw/XawI18n.h b/xc/lib/Xaw/XawI18n.h new file mode 100644 index 000000000..c2adc691d --- /dev/null +++ b/xc/lib/Xaw/XawI18n.h @@ -0,0 +1,101 @@ +/* $XConsortium: XawI18n.h,v 1.0 94/01/01 00:00:00 kaleb Exp $ */ + +/************************************************************ +Copyright 1993 by The Massachusetts Institute of Technology + +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 +no- tice appear in all copies and that both that copyright +no- tice and this permission notice appear in supporting +docu- mentation, and that the name of MIT not be used in +advertising or publicity pertaining to distribution of the +software without specific prior written permission. +M.I.T. makes no representation about the suitability of +this software for any purpose. It is provided "as is" +without any express or implied warranty. + +MIT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT- +NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MIT BE LI- +ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH +THE USE OR PERFORMANCE OF THIS SOFTWARE. + +********************************************************/ + +/* Everyone does this differently. POSIX and Standard C don't have + * nearly enough to be useful. Does ISO 10646 specify header files + * and their contents? There's got to be a better way! + */ + +/* it'd be nice if we could agree that IRIX 5.x is SVR4. */ +#if defined(SVR4) || defined(sgi) +#ifndef NCR +#include <wctype.h> +#include <widec.h> +#define wcslen(c) wslen(c) +#define wcscpy(d,s) wscpy(d,s) +#define wcsncpy(d,s,l) wsncpy(d,s,l) +#else +/* this all goes away when NCR installs their widechar package */ +#include <libw.h> +#define iswprint(c) wisprint(c) +#define iswspace(c) _iswspace(c) +extern int _iswspace(wchar_t); +#define wcslen(c) _Xwcslen(c) +#define wcscpy(d,s) _Xwcscpy(d,s) +#define wcsncpy(d,s,l) _Xwcsncpy(d,s,l) +#endif +#endif + +#if (defined(luna) && defined(MACH)) || defined(hpux) || (defined(__osf__) && defined(__WCHAR_T_LEN)) || defined(WIN32) +#include <wchar.h> +#endif + +/* now deal with the exceptions */ + +#if defined(sony) && !defined(SVR4) +#include <jctype.h> +#define iswspace(c) jisspace(c) +#define iswprint(c) jisalpha(c) || jisnumeric(c) || jiskigou(c) || jisspace(c) +#endif + +#if defined(__osf__) && !defined(__WCHAR_T_LEN) +/* OSF/1 1.x on DECstation 3100 */ +#include <jctype.h> +#define iswspace(c) isjspace(c) +#define iswprint(c) isjalphanum(c) || isjpunct(c) || isjspace(c) +#endif + +#if defined(ultrix) || (defined(sun) && !defined(SVR4)) || defined(bsdi) +#define wcslen(c) _Xwcslen(c) +#define wcscpy(d,s) _Xwcscpy(d,s) +#define wcsncpy(d,s,l) _Xwcsncpy(d,s,l) +#endif + +extern wchar_t atowc ( +#if NeedFunctionPrototypes + unsigned char c +#endif +); + + +/* + * At this point the only place these are undefined is on, e.g. + * SunOS 4.x and Ultrix, whose locale support only includes LC_CTYPE + * anyway. + */ + +#include <ctype.h> + +#ifndef iswprint +#define iswprint(c) (isascii(c) && isprint(c)) +#endif + +#ifndef iswspace +#define iswspace(c) (isascii(c) && isspace(c)) +#endif + diff --git a/xc/lib/Xaw/XawIm.c b/xc/lib/Xaw/XawIm.c new file mode 100644 index 000000000..2b6af4941 --- /dev/null +++ b/xc/lib/Xaw/XawIm.c @@ -0,0 +1,1739 @@ +/* $XConsortium: XawIm.c,v 1.0 94/01/01 00:00:00 kaleb Exp $ */ + +/* + * Copyright 1991 by OMRON Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, 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 OMRON not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. OMRON makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * OMRON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Author: Seiji Kuwari OMRON Corporation + * kuwa@omron.co.jp + * kuwa%omron.co.jp@uunet.uu.net + */ + +#include <X11/IntrinsicP.h> +#include <X11/StringDefs.h> +#include <X11/Xos.h> +#include <X11/Xlocale.h> +#include <X11/Xfuncs.h> +#include <X11/ShellP.h> +#include <X11/Xaw/TextP.h> +#include <X11/Xaw/MultiSrc.h> +#include <X11/Xaw/MultiSinkP.h> +#include <X11/Xaw/XawImP.h> +#include <X11/Xaw/VendorEP.h> +#include <ctype.h> + +#if NeedVarargsPrototypes +# include <stdarg.h> +# define Va_start(a,b) va_start(a,b) +#else +# include <varargs.h> +# define Va_start(a,b) va_start(a) +#endif + +#define maxAscentOfFontSet(fontset) \ + ( - (XExtentsOfFontSet((fontset)))->max_logical_extent.y) + +#define maxHeightOfFontSet(fontset) \ + ((XExtentsOfFontSet((fontset)))->max_logical_extent.height) + +#define maxDescentOfFontSet(fontset) \ + (maxHeightOfFontSet(fontset) - maxAscentOfFontSet(fontset)) + +#define Offset(field) (XtOffsetOf(XawIcTablePart, field)) + +/***************************************************** + * + * Forward reference prototypes + * + *****************************************************/ + +static XawIcTableList CurrentSharedIcTable( +#if NeedFunctionPrototypes + XawVendorShellExtPart* /* ve */ +#endif +); + +static void DestroyIC( +#if NeedFunctionPrototypes + Widget /* w */, + XawVendorShellExtPart* /* ve */ +#endif +); + +static XtResource resources[] = +{ + { + XtNfontSet, XtCFontSet, XtRFontSet, sizeof(XFontSet), + Offset (font_set), XtRString, XtDefaultFontSet + }, + { + XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), + Offset (foreground), XtRString, (XtPointer)"XtDefaultForeground" + }, + { + XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel), + Offset (background), XtRString, (XtPointer)"XtDefaultBackground" + }, + { + XtNbackgroundPixmap, XtCPixmap, XtRPixmap, sizeof(Pixmap), + Offset (bg_pixmap), XtRImmediate, (XtPointer) XtUnspecifiedPixmap + }, + { + XtNinsertPosition, XtCTextPosition, XtRInt, sizeof (XawTextPosition), + Offset (cursor_position), XtRImmediate, (XtPointer) 0 + } +}; +#undef Offset + + +static void SetVaArg( arg, value ) + XPointer *arg, value; +{ + *arg = value; +} + +static VendorShellWidget SearchVendorShell( w ) + Widget w; +{ + while(w && !XtIsShell(w)) w = XtParent(w); + if (w && XtIsVendorShell(w)) return((VendorShellWidget)w); + return(NULL); +} + +static XContext extContext = (XContext)NULL; + +static XawVendorShellExtPart *SetExtPart( w, vew ) + VendorShellWidget w; + XawVendorShellExtWidget vew; +{ + contextDataRec *contextData; + + if (extContext == (XContext)NULL) extContext = XUniqueContext(); + + contextData = XtNew(contextDataRec); + contextData->parent = (Widget)w; + contextData->ve = (Widget)vew; + if (XSaveContext(XtDisplay(w), (Window)w, extContext, (char *)contextData)) { + return(NULL); + } + return(&(vew->vendor_ext)); +} + +static XawVendorShellExtPart *GetExtPart( w ) + VendorShellWidget w; +{ + contextDataRec *contextData; + XawVendorShellExtWidget vew; + + if (XFindContext(XtDisplay(w), (Window)w, extContext, + (XPointer*)&contextData)) { + return(NULL); + } + vew = (XawVendorShellExtWidget)contextData->ve; + return(&(vew->vendor_ext)); +} + +static Boolean IsSharedIC( ve ) + XawVendorShellExtPart * ve; +{ + return( ve->ic.shared_ic ); +} + +static XawIcTableList GetIcTableShared( w, ve ) + Widget w; + XawVendorShellExtPart * ve; +{ + XawIcTableList p; + + for (p = ve->ic.ic_table; p; p = p->next) { + if (p->widget == w) { + if (IsSharedIC(ve)) { + return(ve->ic.shared_ic_table); + } else { + return(p); + } + } + } + return(NULL); +} + +static XawIcTableList GetIcTable( w, ve ) + Widget w; + XawVendorShellExtPart * ve; +{ + XawIcTableList p; + + for (p = ve->ic.ic_table; p; p = p->next) { + if (p->widget == w) { + return(p); + } + } + return(NULL); +} + +static XIMStyle GetInputStyleOfIC( ve ) + XawVendorShellExtPart * ve; +{ + + if (!ve) return((XIMStyle)0); + return(ve->ic.input_style); +} + +static XIMStyle GetInputStyleOfIM( p ) + String p; +{ + if (!p || !*p) + return((XIMStyle)0); + if (!strcmp(p, "OverTheSpot")) { + return((XIMPreeditPosition | XIMStatusArea)); + } else if (!strcmp(p, "OffTheSpot")) { + return((XIMPreeditArea | XIMStatusArea)); + } else if (!strcmp(p, "Root")) { + return((XIMPreeditNothing | XIMStatusNothing)); + } else { + return((XIMStyle)0); + } +} + +static void ConfigureCB( w, closure, event ) + Widget w; + XtPointer closure; + XEvent * event; +{ + XawIcTableList p; + XawVendorShellExtPart *ve; + VendorShellWidget vw; + XVaNestedList pe_attr; + XRectangle pe_area; + XawTextMargin *margin; + + if (event->type != ConfigureNotify) return; + + if ((vw = SearchVendorShell(w)) == NULL) return; + + if (ve = GetExtPart(vw)) { + if (IsSharedIC(ve)) return; + if ((ve->im.xim == NULL) || + ((p = GetIcTableShared(w, ve)) == NULL) || + (p->xic == NULL) || !(p->input_style & XIMPreeditPosition)) return; + pe_area.x = 0; + pe_area.y = 0; + pe_area.width = w->core.width; + pe_area.height = w->core.height; + margin = &(((TextWidget)w)->text.margin); + pe_area.x += margin->left; + pe_area.y += margin->top; + pe_area.width -= (margin->left + margin->right - 1); + pe_area.height -= (margin->top + margin->bottom - 1); + + pe_attr = XVaCreateNestedList(0, XNArea, &pe_area, NULL); + XSetICValues(p->xic, XNPreeditAttributes, pe_attr, NULL); + XtFree(pe_attr); + } +} + +static XContext errContext = (XContext)NULL; + +static Widget SetErrCnxt( w, xim ) + Widget w; + XIM xim; +{ + contextErrDataRec *contextErrData; + + if (errContext == (XContext)NULL) errContext = XUniqueContext(); + + contextErrData = XtNew(contextErrDataRec); + contextErrData->widget = w; + contextErrData->xim = xim; + if (XSaveContext(XtDisplay(w), (Window)xim, errContext, + (char *)contextErrData)) { + return(NULL); + } + return(contextErrData->widget); +} + +static Widget GetErrCnxt( error_im ) + XIM error_im; +{ + contextErrDataRec *contextErrData; + + if (XFindContext(XDisplayOfIM(error_im), (Window)error_im, errContext, + (XPointer*)&contextErrData)) { + return(NULL); + } + return(contextErrData->widget); +} + +static void CloseIM( ve ) + XawVendorShellExtPart * ve; +{ + if (ve->im.xim) + XCloseIM(ve->im.xim); +} + +static Dimension SetVendorShellHeight( ve, height ) + XawVendorShellExtPart* ve; + Dimension height; +{ + Arg args[2]; + Cardinal i = 0; + + if (ve->im.area_height < height || height == 0) { + XtSetArg(args[i], XtNheight, + (ve->parent->core.height + height - ve->im.area_height)); + ve->im.area_height = height; + XtSetValues(ve->parent, args, 1); + } + return(ve->im.area_height); +} + +static void DestroyAllIM( ve ) + XawVendorShellExtPart * ve; +{ + XawIcTableList p; + contextErrDataRec *contextErrData; + + /* + * Destory all ICs + */ + if (IsSharedIC(ve)) { + if ((p = ve->ic.shared_ic_table) && p->xic) { + DestroyIC(p->widget, ve); + p->xic = NULL; + p->ic_focused = FALSE; + } + } else { + for (p = ve->ic.ic_table; p; p = p->next) { + if (p->xic == NULL) continue; + DestroyIC(p->widget, ve); + p->xic = NULL; + p->ic_focused = FALSE; + } + } + if (!ve->im.xim) return; + /* + * Close Input Method + */ + CloseIM(ve); + if (!XFindContext(XDisplayOfIM(ve->im.xim), (Window)ve->im.xim, errContext, + (XPointer*)&contextErrData)) { + if (contextErrData) XtFree((char *)contextErrData); + } + XDeleteContext(XDisplayOfIM(ve->im.xim), (Window)ve->im.xim, errContext); + ve->im.xim = NULL; + + /* + * resize vendor shell to core size + */ + (void) SetVendorShellHeight(ve, 0); + /* + XawVendorShellExtResize(vw); + */ + return; +} + +static void FreeAllDataOfVendorShell(ve, vw) + XawVendorShellExtPart * ve; + VendorShellWidget vw; +{ + XawIcTableList p, next; + contextErrDataRec *contextErrData; + + if (!XFindContext(XtDisplay(vw), (Window)vw, extContext, + (XPointer*)&contextErrData)) { + if (contextErrData) XtFree((char *)contextErrData); + } + XDeleteContext(XtDisplay(vw), (Window)vw, extContext); + if (ve->im.im_list) { + XtFree((char *)ve->im.im_list[0]); + XtFree((char *)ve->im.im_list); + } + if (ve->ic.ic_list) { + XtFree((char *)ve->ic.ic_list[0]); + XtFree((char *)ve->ic.ic_list); + } + if (ve->ic.shared_ic_table) + XtFree((char *)ve->ic.shared_ic_table); + if (ve->im.resources) XtFree((char *)ve->im.resources); + for (p = ve->ic.ic_table; p; p = next) { + next = p->next; + XtFree((char *)ve->ic.ic_table); + } +} + +static void VendorShellDestroyed( w, cl_data, ca_data ) + Widget w; + XtPointer cl_data, ca_data; +{ + XawVendorShellExtPart *ve; + + if ( ( ve = GetExtPart( (VendorShellWidget) w ) ) == NULL ) return; + DestroyAllIM( ve ); + FreeAllDataOfVendorShell( ve, (VendorShellWidget) w ); + return; +} + +static int IOErrorHandler( error_im ) + XIM error_im; +{ + VendorShellWidget vw; + XawVendorShellExtPart * ve; + + if ((vw = (VendorShellWidget)GetErrCnxt(error_im)) == NULL + || (ve = GetExtPart(vw)) == NULL) return(0); + + DestroyAllIM(ve); + return(0); +} + +/* + * Attempt to open an input method + */ + +static void OpenIM(ve) + XawVendorShellExtPart * ve; +{ + char *p, modifiers[32]; + XIM xim = NULL; + XIMStyles *xim_styles; + XIMStyle input_style; + int i, j; + + if (ve->im.open_im == False) return; + ve->im.xim = NULL; + if (!strcmp(setlocale(LC_ALL, NULL), "C")) return; + if (ve->im.im_list_num <= 0) XSetLocaleModifiers("@im=None"); + for (i = 0; i < ve->im.im_list_num; i++) { + strcpy(modifiers, "@im="); + strcat(modifiers, ve->im.im_list[i]); + XSetLocaleModifiers(modifiers); + if (xim = XOpenIM(XtDisplay(ve->parent), NULL, NULL, NULL)) + break; + } + if (!xim) { + if ((p = XSetLocaleModifiers("")) && *p) { + xim = XOpenIM(XtDisplay(ve->parent), NULL, NULL, NULL); + } + } + if (!xim) { + XtWarning("we can not open any input method"); + return; + } + if (XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL) + || !xim_styles) { + XtWarning("input method doesn't support any style"); + XCloseIM(xim); + return; + } + for (j = 0; j < ve->ic.ic_list_num; j++) { + input_style = GetInputStyleOfIM(ve->ic.ic_list[j]); + if (input_style == (XIMStyle)0) continue; + for (i = 0; (unsigned short)i < xim_styles->count_styles; i++) { + if (input_style == xim_styles->supported_styles[i]) { + ve->ic.input_style = input_style; + SetErrCnxt(ve->parent, xim); +/* _XipSetIOErrorHandler(IOErrorHandler); */ + ve->im.xim = xim; + XFree(xim_styles); + return; + } + } + } + XCloseIM(xim); + XtWarning("input method doesn't support my input style"); + XFree(xim_styles); +} + +static Boolean ResizeVendorShell_Core(vw, ve, p) + VendorShellWidget vw; + XawVendorShellExtPart * ve; + XawIcTableList p; +{ + XVaNestedList pe_attr, st_attr; + XRectangle pe_area, st_area; + XRectangle *get_pe_area = NULL, *get_st_area = NULL; + + st_area.width = 0; + if (p->input_style & XIMStatusArea) { + st_attr = XVaCreateNestedList(0, XNArea, &get_st_area, NULL); + XGetICValues(p->xic, XNStatusAttributes, st_attr, NULL); + XFree(st_attr); + if (p->xic == NULL) { + return(FALSE); + } + st_area.x = 0; + st_area.y = vw->core.height - ve->im.area_height; + st_area.width = get_st_area->width; + st_area.height = get_st_area->height; + XFree(get_st_area); + st_attr = XVaCreateNestedList(0, XNArea, &st_area, NULL); + XSetICValues(p->xic, XNStatusAttributes, st_attr, NULL); + XFree(st_attr); + if (p->xic == NULL) { + return(FALSE); + } + } + if (p->input_style & XIMPreeditArea) { + pe_attr = XVaCreateNestedList(0, XNArea, &get_pe_area, NULL); + XGetICValues(p->xic, XNPreeditAttributes, pe_attr, NULL); + XFree(pe_attr); + if (p->xic == NULL) { + return(FALSE); + } + pe_area.x = st_area.width; + pe_area.y = vw->core.height - ve->im.area_height; + pe_area.width = vw->core.width; + pe_area.height = get_pe_area->height; + if (p->input_style & XIMStatusArea) { + pe_area.width -= st_area.width; + } + XFree(get_pe_area); + pe_attr = XVaCreateNestedList(0, XNArea, &pe_area, NULL); + XSetICValues(p->xic, XNPreeditAttributes, pe_attr, NULL); + XFree(pe_attr); + } + return(TRUE); +} + +static void ResizeVendorShell(vw, ve) + VendorShellWidget vw; + XawVendorShellExtPart * ve; +{ + XawIcTableList p; + + if (IsSharedIC(ve)) { + p = ve->ic.shared_ic_table; + if (p->xic == NULL) return; + ResizeVendorShell_Core(vw, ve, p); + return; + } + for (p = ve->ic.ic_table; p; p = p->next) { + if (p->xic == NULL) continue; + if (ResizeVendorShell_Core(vw, ve, p) == FALSE) return; + } +} + +static XawIcTableList CreateIcTable( w, ve ) + Widget w; + XawVendorShellExtPart * ve; +{ + XawIcTableList table; + + table = (XawIcTableList) XtMalloc(sizeof(XawIcTablePart)); + if (table == NULL) return(NULL); + table->widget = w; + table->xic = NULL; + table->flg = table->prev_flg = 0; + table->font_set = NULL; + table->foreground = table->background = 0xffffffff; + table->bg_pixmap = 0; + table->cursor_position = 0xffff; + table->line_spacing = 0; + table->ic_focused = FALSE; + table->openic_error = FALSE; + return(table); +} + +static Boolean RegisterToVendorShell( w, ve ) + Widget w; + XawVendorShellExtPart * ve; +{ + XawIcTableList table; + + if ((table = CreateIcTable(w, ve)) == NULL) return(FALSE); + table->next = ve->ic.ic_table; + ve->ic.ic_table = table; + return(TRUE); +} + +static void UnregisterFromVendorShell(w, ve) + Widget w; + XawVendorShellExtPart * ve; +{ + XawIcTableList *prev, p; + + for (prev = &ve->ic.ic_table; p = *prev; prev = &p->next) { + if (p->widget == w) { + *prev = p->next; + XtFree((char *)p); + break; + } + } + return; +} + +static void SetICValuesShared(w, ve, p, check) + Widget w; + XawVendorShellExtPart * ve; + XawIcTableList p; + Boolean check; +{ + XawIcTableList pp; + + if ((pp = GetIcTable(w, ve)) == NULL) return; + if (check == TRUE && CurrentSharedIcTable(ve) != pp) return; + + if (pp->prev_flg & CICursorP && p->cursor_position != pp->cursor_position) { + p->cursor_position = pp->cursor_position; + p->flg |= CICursorP; + } + if (pp->prev_flg & CIFontSet && p->font_set != pp->font_set) { + p->font_set = pp->font_set; + p->flg |= (CIFontSet|CICursorP); + } + if (pp->prev_flg & CIFg && p->foreground != pp->foreground) { + p->foreground = pp->foreground; + p->flg |= CIFg; + } + if (pp->prev_flg & CIBg && p->background != pp->background) { + p->background = pp->background; + p->flg |= CIBg; + } + if (pp->prev_flg & CIBgPixmap && p->bg_pixmap != pp->bg_pixmap) { + p->bg_pixmap = pp->bg_pixmap; + p->flg |= CIBgPixmap; + } + if (pp->prev_flg & CILineS && p->line_spacing != pp->line_spacing) { + p->line_spacing = pp->line_spacing; + p->flg |= CILineS; + } +} + +static Boolean IsCreatedIC(w, ve) + Widget w; + XawVendorShellExtPart * ve; +{ + XawIcTableList p; + + if (ve->im.xim == NULL) return(FALSE); + if ((p = GetIcTableShared(w, ve)) == NULL) return(FALSE); + if (p->xic == NULL) return(FALSE); + return(TRUE); +} + +static void SizeNegotiation(p, width, height) + XawIcTableList p; + Dimension width, height; +{ + XRectangle pe_area, st_area; + XVaNestedList pe_attr = NULL, st_attr = NULL; + int ic_cnt = 0, pe_cnt = 0, st_cnt = 0; + XRectangle *pe_area_needed = NULL, *st_area_needed = NULL; + XPointer ic_a[5]; + + if (p->input_style & XIMPreeditArea) { + pe_attr = XVaCreateNestedList(0, XNAreaNeeded, &pe_area_needed, NULL); + SetVaArg( &ic_a[ic_cnt], (XPointer) XNPreeditAttributes); ic_cnt++; + SetVaArg( &ic_a[ic_cnt], (XPointer) pe_attr); ic_cnt++; + } + if (p->input_style & XIMStatusArea) { + st_attr = XVaCreateNestedList(0, XNAreaNeeded, &st_area_needed, NULL); + SetVaArg( &ic_a[ic_cnt], (XPointer) XNStatusAttributes); ic_cnt++; + SetVaArg( &ic_a[ic_cnt], (XPointer) st_attr); ic_cnt++; + } + SetVaArg( &ic_a[ic_cnt], (XPointer) NULL); + + if (ic_cnt > 0) { + XGetICValues(p->xic, ic_a[0], ic_a[1], ic_a[2], ic_a[3], ic_a[4]); + if (pe_attr) XFree(pe_attr); + if (st_attr) XFree(st_attr); + if (p->xic == NULL) { + p->openic_error = True; + return; + } + pe_attr = st_attr = NULL; + ic_cnt = pe_cnt = st_cnt = 0; + if (p->input_style & XIMStatusArea) { + st_area.height = st_area_needed->height; + st_area.x = 0; + st_area.y = height - st_area.height; + if (p->input_style & XIMPreeditArea) { + st_area.width = st_area_needed->width; + } else { + st_area.width = width; + } + + XFree(st_area_needed); + st_attr = XVaCreateNestedList(0, XNArea, &st_area, NULL); + SetVaArg( &ic_a[ic_cnt], (XPointer) XNStatusAttributes); ic_cnt++; + SetVaArg( &ic_a[ic_cnt], (XPointer) st_attr); ic_cnt++; + } + if (p->input_style & XIMPreeditArea) { + if (p->input_style & XIMStatusArea) { + pe_area.x = st_area.width; + pe_area.width = width - st_area.width; + } else { + pe_area.x = 0; + pe_area.width = width; + } + pe_area.height = pe_area_needed->height; + XFree(pe_area_needed); + pe_area.y = height - pe_area.height; + pe_attr = XVaCreateNestedList(0, XNArea, &pe_area, NULL); + SetVaArg( &ic_a[ic_cnt], (XPointer) XNPreeditAttributes); ic_cnt++; + SetVaArg( &ic_a[ic_cnt], (XPointer) pe_attr); ic_cnt++; + } + SetVaArg( &ic_a[ic_cnt], (XPointer) NULL); + XSetICValues(p->xic, ic_a[0], ic_a[1], ic_a[2], ic_a[3], ic_a[4]); + if (pe_attr) XFree(pe_attr); + if (st_attr) XFree(st_attr); + if (p->xic == NULL) { + p->openic_error = True; + return; + } + } +} + +static void CreateIC( w, ve ) + Widget w; + XawVendorShellExtPart* ve; +{ + XawIcTableList p; + XPoint position; + XRectangle pe_area, st_area; + XVaNestedList pe_attr = NULL, st_attr = NULL; + XPointer ic_a[20], pe_a[20], st_a[20]; + Dimension height = 0; + int ic_cnt = 0, pe_cnt = 0, st_cnt = 0; + XawTextMargin *margin; + + if (!XtIsRealized(w)) return; + if (((ve->im.xim == NULL) || (p = GetIcTableShared(w, ve)) == NULL) || + p->xic || (p->openic_error != FALSE)) return; + + p->input_style = GetInputStyleOfIC(ve); + + if (IsSharedIC(ve)) SetICValuesShared(w, ve, p, FALSE); + XFlush(XtDisplay(w)); + + if (p->input_style & (XIMPreeditArea|XIMPreeditPosition|XIMStatusArea)) { + if (p->flg & CIFontSet) { + SetVaArg( &pe_a[pe_cnt], (XPointer) XNFontSet); pe_cnt++; + SetVaArg( &pe_a[pe_cnt], (XPointer) p->font_set); pe_cnt++; + SetVaArg( &st_a[st_cnt], (XPointer) XNFontSet); st_cnt++; + SetVaArg( &st_a[st_cnt], (XPointer) p->font_set); st_cnt++; + height = maxAscentOfFontSet(p->font_set) + + maxDescentOfFontSet(p->font_set); + height = SetVendorShellHeight(ve, height); + } + if (p->flg & CIFg) { + SetVaArg( &pe_a[pe_cnt], (XPointer) XNForeground); pe_cnt++; + SetVaArg( &pe_a[pe_cnt], (XPointer) p->foreground); pe_cnt++; + SetVaArg( &st_a[st_cnt], (XPointer) XNForeground); st_cnt++; + SetVaArg( &st_a[st_cnt], (XPointer) p->foreground); st_cnt++; + } + if (p->flg & CIBg) { + SetVaArg( &pe_a[pe_cnt], (XPointer) XNBackground); pe_cnt++; + SetVaArg( &pe_a[pe_cnt], (XPointer) p->background); pe_cnt++; + SetVaArg( &st_a[st_cnt], (XPointer) XNBackground); st_cnt++; + SetVaArg( &st_a[st_cnt], (XPointer) p->background); st_cnt++; + } + if (p->flg & CIBgPixmap) { + SetVaArg( &pe_a[pe_cnt], (XPointer) XNBackgroundPixmap); pe_cnt++; + SetVaArg( &pe_a[pe_cnt], (XPointer) p->bg_pixmap); pe_cnt++; + SetVaArg( &st_a[st_cnt], (XPointer) XNBackgroundPixmap); st_cnt++; + SetVaArg( &st_a[st_cnt], (XPointer) p->bg_pixmap); st_cnt++; + } + if (p->flg & CILineS) { + SetVaArg( &pe_a[pe_cnt], (XPointer) XNLineSpace); pe_cnt++; + SetVaArg( &pe_a[pe_cnt], (XPointer) p->line_spacing); pe_cnt++; + SetVaArg( &st_a[st_cnt], (XPointer) XNLineSpace); st_cnt++; + SetVaArg( &st_a[st_cnt], (XPointer) p->line_spacing); st_cnt++; + } + } + if (p->input_style & XIMPreeditArea) { + pe_area.x = 0; + pe_area.y = ve->parent->core.height - height; + pe_area.width = ve->parent->core.width; + pe_area.height = height; + SetVaArg( &pe_a[pe_cnt], (XPointer) XNArea); pe_cnt++; + SetVaArg( &pe_a[pe_cnt], (XPointer) &pe_area); pe_cnt++; + } + if (p->input_style & XIMPreeditPosition) { + pe_area.x = 0; + pe_area.y = 0; + pe_area.width = w->core.width; + pe_area.height = w->core.height; + margin = &(((TextWidget)w)->text.margin); + pe_area.x += margin->left; + pe_area.y += margin->top; + pe_area.width -= (margin->left + margin->right - 1); + pe_area.height -= (margin->top + margin->bottom - 1); + SetVaArg( &pe_a[pe_cnt], (XPointer) XNArea); pe_cnt++; + SetVaArg( &pe_a[pe_cnt], (XPointer) &pe_area); pe_cnt++; + if (p->flg & CICursorP) { + _XawMultiSinkPosToXY(w, p->cursor_position, &position.x, &position.y); + } else { + position.x = position.y = 0; + } + SetVaArg( &pe_a[pe_cnt], (XPointer) XNSpotLocation); pe_cnt++; + SetVaArg( &pe_a[pe_cnt], (XPointer) &position); pe_cnt++; + } + if (p->input_style & XIMStatusArea) { + st_area.x = 0; + st_area.y = ve->parent->core.height - height; + st_area.width = ve->parent->core.width; + st_area.height = height; + SetVaArg( &st_a[st_cnt], (XPointer) XNArea); st_cnt++; + SetVaArg( &st_a[st_cnt], (XPointer) &st_area); st_cnt++; + } + + SetVaArg( &ic_a[ic_cnt], (XPointer) XNInputStyle); ic_cnt++; + SetVaArg( &ic_a[ic_cnt], (XPointer) p->input_style); ic_cnt++; + SetVaArg( &ic_a[ic_cnt], (XPointer) XNClientWindow); ic_cnt++; + SetVaArg( &ic_a[ic_cnt], (XPointer) XtWindow(ve->parent)); ic_cnt++; + SetVaArg( &ic_a[ic_cnt], (XPointer) XNFocusWindow); ic_cnt++; + SetVaArg( &ic_a[ic_cnt], (XPointer) XtWindow(w)); ic_cnt++; + + if (pe_cnt > 0) { + SetVaArg( &pe_a[pe_cnt], (XPointer) NULL); + pe_attr = XVaCreateNestedList(0, pe_a[0], pe_a[1], pe_a[2], pe_a[3], + pe_a[4], pe_a[5], pe_a[6], pe_a[7], pe_a[8], + pe_a[9], pe_a[10], pe_a[11], pe_a[12], + pe_a[13], pe_a[14], pe_a[15], pe_a[16], + pe_a[17], pe_a[18], pe_a[19]); + SetVaArg( &ic_a[ic_cnt], (XPointer) XNPreeditAttributes); ic_cnt++; + SetVaArg( &ic_a[ic_cnt], (XPointer) pe_attr); ic_cnt++; + } + + if (st_cnt > 0) { + SetVaArg( &st_a[st_cnt], (XPointer) NULL); + st_attr = XVaCreateNestedList(0, st_a[0], st_a[1], st_a[2], st_a[3], + st_a[4], st_a[5], st_a[6], st_a[7], st_a[8], + st_a[9], st_a[10], st_a[11], st_a[12], + st_a[13], st_a[14], st_a[15], st_a[16], + st_a[17], st_a[18], st_a[19]); + SetVaArg( &ic_a[ic_cnt], (XPointer) XNStatusAttributes); ic_cnt++; + SetVaArg( &ic_a[ic_cnt], (XPointer) st_attr); ic_cnt++; + } + SetVaArg( &ic_a[ic_cnt], (XPointer) NULL); + + p->xic = XCreateIC(ve->im.xim, ic_a[0], ic_a[1], ic_a[2], ic_a[3], + ic_a[4], ic_a[5], ic_a[6], ic_a[7], ic_a[8], ic_a[9], + ic_a[10], ic_a[11], ic_a[12], ic_a[13], ic_a[14], + ic_a[15], ic_a[16], ic_a[17], ic_a[18], ic_a[19]); + if (pe_attr) XtFree(pe_attr); + if (st_attr) XtFree(st_attr); + + if (p->xic == NULL) { + p->openic_error = True; + return; + } + + SizeNegotiation(p, ve->parent->core.width, ve->parent->core.height); + + p->flg &= ~(CIFontSet | CIFg | CIBg | CIBgPixmap | CICursorP | CILineS); + + if (!IsSharedIC(ve)) { + if (p->input_style & XIMPreeditPosition) { + XtAddEventHandler(w, (EventMask)StructureNotifyMask, FALSE, + (XtEventHandler)ConfigureCB, (Opaque)NULL); + } + } +} + +static void SetICValues( w, ve, focus ) + Widget w; + XawVendorShellExtPart *ve; + Boolean focus; +{ + XawIcTableList p; + XPoint position; + XRectangle pe_area, st_area; + XVaNestedList pe_attr = NULL, st_attr = NULL; + XPointer ic_a[20], pe_a[20], st_a[20]; + int ic_cnt = 0, pe_cnt = 0, st_cnt = 0; + XawTextMargin *margin; + int height; + + if ((ve->im.xim == NULL) || ((p = GetIcTableShared(w, ve)) == NULL) || + (p->xic == NULL)) return; + + if (IsSharedIC(ve)) SetICValuesShared(w, ve, p, TRUE); + XFlush(XtDisplay(w)); + if (focus == FALSE && + !(p->flg & (CIFontSet | CIFg | CIBg | + CIBgPixmap | CICursorP | CILineS))) return; +#ifdef SPOT + if ((p->input_style & XIMPreeditPosition) + && ((!IsSharedIC(ve) && ((p->flg & ~CIICFocus) == CICursorP)) + || (IsSharedIC(ve) && p->flg == CICursorP))) { + _XawMultiSinkPosToXY(w, p->cursor_position, &position.x, &position.y); + _XipChangeSpot(p->xic, position.x, position.y); + p->flg &= ~CICursorP; + return; + } +#endif + + if (p->input_style & (XIMPreeditArea|XIMPreeditPosition|XIMStatusArea)) { + if (p->flg & CIFontSet) { + SetVaArg( &pe_a[pe_cnt], (XPointer) XNFontSet); pe_cnt++; + SetVaArg( &pe_a[pe_cnt], (XPointer) p->font_set); pe_cnt++; + SetVaArg( &st_a[st_cnt], (XPointer) XNFontSet); st_cnt++; + SetVaArg( &st_a[st_cnt], (XPointer) p->font_set); st_cnt++; + height = maxAscentOfFontSet(p->font_set) + + maxDescentOfFontSet(p->font_set); + height = SetVendorShellHeight(ve, height); + } + if (p->flg & CIFg) { + SetVaArg( &pe_a[pe_cnt], (XPointer) XNForeground); pe_cnt++; + SetVaArg( &pe_a[pe_cnt], (XPointer) p->foreground); pe_cnt++; + SetVaArg( &st_a[st_cnt], (XPointer) XNForeground); st_cnt++; + SetVaArg( &st_a[st_cnt], (XPointer) p->foreground); st_cnt++; + } + if (p->flg & CIBg) { + SetVaArg( &pe_a[pe_cnt], (XPointer) XNBackground); pe_cnt++; + SetVaArg( &pe_a[pe_cnt], (XPointer) p->background); pe_cnt++; + SetVaArg( &st_a[st_cnt], (XPointer) XNBackground); st_cnt++; + SetVaArg( &st_a[st_cnt], (XPointer) p->background); st_cnt++; + } + if (p->flg & CIBgPixmap) { + SetVaArg( &pe_a[pe_cnt], (XPointer) XNBackgroundPixmap); pe_cnt++; + SetVaArg( &pe_a[pe_cnt], (XPointer) p->bg_pixmap); pe_cnt++; + SetVaArg( &st_a[st_cnt], (XPointer) XNBackgroundPixmap); st_cnt++; + SetVaArg( &st_a[st_cnt], (XPointer) p->bg_pixmap); st_cnt++; + } + if (p->flg & CILineS) { + SetVaArg( &pe_a[pe_cnt], (XPointer) XNLineSpace); pe_cnt++; + SetVaArg( &pe_a[pe_cnt], (XPointer) p->line_spacing); pe_cnt++; + SetVaArg( &st_a[st_cnt], (XPointer) XNLineSpace); st_cnt++; + SetVaArg( &st_a[st_cnt], (XPointer) p->line_spacing); st_cnt++; + } + } + if (p->input_style & XIMPreeditPosition) { + if (p->flg & CICursorP) { + _XawMultiSinkPosToXY(w, p->cursor_position, &position.x, &position.y); + SetVaArg( &pe_a[pe_cnt], (XPointer) XNSpotLocation); pe_cnt++; + SetVaArg( &pe_a[pe_cnt], (XPointer) &position); pe_cnt++; + } + } + if (IsSharedIC(ve)) { + if (p->input_style & XIMPreeditPosition) { + pe_area.x = 0; + pe_area.y = 0; + pe_area.width = w->core.width; + pe_area.height = w->core.height; + margin = &(((TextWidget)w)->text.margin); + pe_area.x += margin->left; + pe_area.y += margin->top; + pe_area.width -= (margin->left + margin->right - 1); + pe_area.height -= (margin->top + margin->bottom - 1); + SetVaArg( &pe_a[pe_cnt], (XPointer) XNArea); pe_cnt++; + SetVaArg( &pe_a[pe_cnt], (XPointer) &pe_area); pe_cnt++; + } + } + + if (pe_cnt > 0) { + SetVaArg( &pe_a[pe_cnt], (XPointer) NULL); + pe_attr = XVaCreateNestedList(0, pe_a[0], pe_a[1], pe_a[2], pe_a[3], + pe_a[4], pe_a[5], pe_a[6], pe_a[7], + pe_a[8], pe_a[9], pe_a[10], pe_a[11], + pe_a[12], pe_a[13], pe_a[14], pe_a[15], + pe_a[16], pe_a[17], pe_a[18], pe_a[19]); + SetVaArg( &ic_a[ic_cnt], (XPointer) XNPreeditAttributes); ic_cnt++; + SetVaArg( &ic_a[ic_cnt], (XPointer) pe_attr); ic_cnt++; + } + if (st_cnt > 0) { + SetVaArg( &st_a[st_cnt], (XPointer) NULL); + st_attr = XVaCreateNestedList(0, st_a[0], st_a[1], st_a[2], st_a[3], + st_a[4], st_a[5], st_a[6], st_a[7], + st_a[8], st_a[9], st_a[10], st_a[11], + st_a[12], st_a[13], st_a[14], st_a[15], + st_a[16], st_a[17], st_a[18], st_a[19]); + SetVaArg( &ic_a[ic_cnt], (XPointer) XNStatusAttributes); ic_cnt++; + SetVaArg( &ic_a[ic_cnt], (XPointer) st_attr); ic_cnt++; + } + if (focus == TRUE) { + SetVaArg( &ic_a[ic_cnt], (XPointer) XNFocusWindow); ic_cnt++; + SetVaArg( &ic_a[ic_cnt], (XPointer) XtWindow(w)); ic_cnt++; + } + if (ic_cnt > 0) { + SetVaArg( &ic_a[ic_cnt], (XPointer) NULL); + XSetICValues(p->xic, ic_a[0], ic_a[1], ic_a[2], ic_a[3], ic_a[4], + ic_a[5], ic_a[6], ic_a[7], ic_a[8], ic_a[9], ic_a[10], + ic_a[11], ic_a[12], ic_a[13], ic_a[14], ic_a[15], + ic_a[16], ic_a[17], ic_a[18], ic_a[19]); + if (pe_attr) XtFree(pe_attr); + if (st_attr) XtFree(st_attr); + } + + if (IsSharedIC(ve) && p->flg & CIFontSet) + SizeNegotiation(p, ve->parent->core.width, ve->parent->core.height); + + p->flg &= ~(CIFontSet | CIFg | CIBg | CIBgPixmap | CICursorP | CILineS); +} + +static void SharedICChangeFocusWindow(w, ve, p) + Widget w; + XawVendorShellExtPart *ve; + XawIcTableList p; +{ + XawIcTableList pp; + + if (w == NULL) { + ve->ic.current_ic_table = NULL; + return; + } + if ((pp = GetIcTable(w, ve)) == NULL) return; + ve->ic.current_ic_table = pp; + SetICValues(w, ve, TRUE); +} + +static XawIcTableList CurrentSharedIcTable( ve ) + XawVendorShellExtPart * ve; +{ + return(ve->ic.current_ic_table); +} + +static void SetICFocus(w, ve) + Widget w; + XawVendorShellExtPart * ve; +{ + XawIcTableList p, pp; + + if ((ve->im.xim == NULL) || ((p = GetIcTableShared(w, ve)) == NULL) || + (p->xic == NULL)) return; + + if (IsSharedIC(ve)) { + pp = CurrentSharedIcTable(ve); + if (pp == NULL || pp->widget != w) { + SharedICChangeFocusWindow(w, ve, p); + } + } + if (p->flg & CIICFocus && p->ic_focused == FALSE) { + p->ic_focused = TRUE; + XSetICFocus(p->xic); + } + p->flg &= ~CIICFocus; +} + +static void UnsetICFocus(w, ve) + Widget w; + XawVendorShellExtPart * ve; +{ + XawIcTableList p, pp; + + if ((ve->im.xim == NULL) || ((p = GetIcTableShared(w, ve)) == NULL) || + (p->xic == NULL)) return; + + if (IsSharedIC(ve) && (pp = CurrentSharedIcTable(ve))) { + if (pp->widget != w) { + return; + } + SharedICChangeFocusWindow(NULL, ve, p); + } + if (p->ic_focused == TRUE) { + XUnsetICFocus(p->xic); + p->ic_focused = FALSE; + } +} + +static void SetValues( w, ve, args, num_args ) + Widget w; + XawVendorShellExtPart * ve; + ArgList args; + Cardinal num_args; +{ + ArgList arg; + + XrmName argName; + XrmResourceList xrmres; + int i; + XawIcTablePart *p, save_tbl; + + if ((p = GetIcTable(w, ve)) == NULL) return; + + memcpy(&save_tbl, p, sizeof(XawIcTablePart)); + + for (arg = args ; num_args != 0; num_args--, arg++) { + argName = XrmStringToName(arg->name); + for (xrmres = (XrmResourceList)ve->im.resources, i = 0; + i < ve->im.num_resources; i++, xrmres++) { + if (argName == xrmres->xrm_name) { + _XtCopyFromArg(arg->value, + (char *)p - xrmres->xrm_offset - 1, + xrmres->xrm_size); + break; + } + } + } + if (p->font_set != save_tbl.font_set) { + p->flg |= CIFontSet; + } + if (p->foreground != save_tbl.foreground) { + p->flg |= CIFg; + } + if (p->background !=save_tbl.background) { + p->flg |= CIBg; + } + if (p->bg_pixmap != save_tbl.bg_pixmap) { + p->flg |= CIBgPixmap; + } + if (p->cursor_position != save_tbl.cursor_position) { + p->flg |= CICursorP; + } + if (p->line_spacing != save_tbl.line_spacing) { + p->flg |= CILineS; + } + p->prev_flg |= p->flg; +} + +static void SetFocus( w, ve ) + Widget w; + XawVendorShellExtPart *ve; +{ + XawIcTableList p; + if ((p = GetIcTableShared(w, ve)) == NULL) return; + + if ( p->ic_focused == FALSE || IsSharedIC(ve)) { + p->flg |= CIICFocus; + } + p->prev_flg |= p->flg; +} + +static void DestroyIC(w, ve) + Widget w; + XawVendorShellExtPart *ve; +{ + XawIcTableList p; + + if ((ve->im.xim == NULL) || ((p = GetIcTableShared(w, ve)) == NULL) || + (p->xic == NULL)) return; + if (IsSharedIC(ve)) { + if (GetIcTable(w, ve) == ve->ic.current_ic_table) { + UnsetICFocus(w, ve); + } + return; + } + XDestroyIC(p->xic); + if (!IsSharedIC(ve)) { + if (p->input_style & XIMPreeditPosition) { + XtRemoveEventHandler(w, (EventMask)StructureNotifyMask, FALSE, + (XtEventHandler)ConfigureCB, (Opaque)NULL); + } + } +} + +static void SetFocusValues( inwidg, args, num_args, focus ) + Widget inwidg; + ArgList args; + Cardinal num_args; + Boolean focus; +{ + XawVendorShellExtPart *ve; + VendorShellWidget vw; + + if ((vw = SearchVendorShell(inwidg)) == NULL) return; + if (ve = GetExtPart(vw)) { + if (num_args > 0) SetValues(inwidg, ve, args, num_args); + if (focus) SetFocus(inwidg, ve); + if (XtIsRealized((Widget)vw) && ve->im.xim) { + if (IsCreatedIC(inwidg, ve)) { + SetICValues(inwidg, ve, FALSE); + if (focus) SetICFocus(inwidg, ve); + } else { + CreateIC(inwidg, ve); + SetICFocus(inwidg, ve); + } + } + } +} + +static void UnsetFocus( inwidg ) + Widget inwidg; +{ + XawVendorShellExtPart *ve; + VendorShellWidget vw; + XawIcTableList p; + + if ((vw = SearchVendorShell(inwidg)) == NULL) return; + if (ve = GetExtPart(vw)) { + if ((p = GetIcTableShared(inwidg, ve)) == NULL) return; + if (p->flg & CIICFocus) { + p->flg &= ~CIICFocus; + } + p->prev_flg &= ~CIICFocus; + if (ve->im.xim && XtIsRealized((Widget)vw) && p->xic) { + UnsetICFocus(inwidg, ve); + } + } +} + +static Boolean IsRegistered( w, ve ) + Widget w; + XawVendorShellExtPart* ve; +{ + XawIcTableList p; + + for (p = ve->ic.ic_table; p; p = p->next) + { + if (p->widget == w) return(TRUE); + } + return(FALSE); +} + +static void Register(inwidg, ve) + Widget inwidg; + XawVendorShellExtPart* ve; +{ + if (ve->im.xim == NULL) + { + OpenIM(ve); + } + + if (IsRegistered(inwidg, ve)) return; + + if (RegisterToVendorShell(inwidg, ve) == FALSE) return; + + if (ve->im.xim == NULL) return; + + if (XtIsRealized(ve->parent)) + { + CreateIC(inwidg, ve); + SetICFocus(inwidg, ve); + } +} + +static Boolean NoRegistered(ve) + XawVendorShellExtPart* ve; +{ + if (ve->ic.ic_table == NULL) return(TRUE); + return(FALSE); +} + +static void Unregister(inwidg, ve) + Widget inwidg; + XawVendorShellExtPart* ve; +{ + if (!IsRegistered(inwidg, ve)) return; + + DestroyIC(inwidg, ve); + + UnregisterFromVendorShell(inwidg, ve); + + if (NoRegistered(ve)) + { + CloseIM(ve); + ve->im.xim = NULL; + /* + * resize vendor shell to core size + */ + (void) SetVendorShellHeight(ve, 0); + } +} + +static void AllCreateIC( ve ) + XawVendorShellExtPart* ve; +{ + XawIcTableList p; + + if (ve->im.xim == NULL) return; + if (IsSharedIC(ve) && ve->ic.ic_table[0].widget) { + p = ve->ic.shared_ic_table; + if (p->xic == NULL) + CreateIC(ve->ic.ic_table[0].widget, ve); + SetICFocus(ve->ic.ic_table[0].widget, ve); + return; + } + for (p = ve->ic.ic_table; p; p = p->next) { + if (p->xic == NULL) + CreateIC(p->widget, ve); + } + for (p = ve->ic.ic_table; p; p = p->next) { + SetICFocus(p->widget, ve); + } +} + + +static void Reconnect(ve) + XawVendorShellExtPart* ve; +{ + XawIcTableList p; + + ve->im.open_im = True; + if (ve->im.xim == NULL) { + OpenIM(ve); + } + if (ve->im.xim == NULL) return; + + if (IsSharedIC(ve)) { + p = ve->ic.shared_ic_table; + p->flg = p->prev_flg; + p->openic_error = FALSE; + } else { + for (p = ve->ic.ic_table; p; p = p->next) { + p->flg = p->prev_flg; + p->openic_error = FALSE; + } + } + AllCreateIC(ve); +} + + +static void CompileResourceList( res, num_res ) + XtResourceList res; + unsigned int num_res; +{ + unsigned int count; + +#define xrmres ((XrmResourceList) res) + for (count = 0; count < num_res; res++, count++) { + xrmres->xrm_name = XrmPermStringToQuark(res->resource_name); + xrmres->xrm_class = XrmPermStringToQuark(res->resource_class); + xrmres->xrm_type = XrmPermStringToQuark(res->resource_type); + xrmres->xrm_offset = -res->resource_offset - 1; + xrmres->xrm_default_type = XrmPermStringToQuark(res->default_type); + } +#undef xrmres +} + + +static char** ParseIMNameList(p, num) + char* p; + int* num; +{ + char *s, *save_s, *ss, *list[32], **lp, *end; + int i = 0; + + *num = 0; + if (!p || !*p) return ((char **)NULL); + while (*p && isspace(*p)) p++; + if (!*p) return ((char **)NULL); + if ((s = XtMalloc(strlen(p) + 1)) == NULL) return((char **)NULL); + strcpy(s, p); + save_s = s; + + while(1) { + list[i] = s; + ss = index(s, ','); + if (!ss) { + end = s + strlen(s); + } else { + end = ss; + } + while (isspace(*end)) end--; + *end = '\0'; + i++; + if (!ss) break; + s = ss + 1; + while (*s && isspace(*s)) p++; + if (!*s) break; + } + if ((lp = (char **)XtMalloc(sizeof(char *) * (i + 1))) == NULL) { + XtFree(save_s); + return((char **)NULL); + } + memcpy((char *)lp, (char *)list, sizeof(char *) * i); + *(lp + i) = NULL; + *num = i; + return(lp); +} + +static Boolean Initialize( vw, ve ) + VendorShellWidget vw; + XawVendorShellExtPart* ve; +{ + int i; + + if (!XtIsVendorShell((Widget)vw)) return(FALSE); + ve->parent = (Widget)vw; + ve->im.xim = NULL; + ve->im.area_height = 0; + ve->im.resources = (XrmResourceList)XtMalloc(sizeof(resources)); + if (ve->im.resources == NULL) return(FALSE); + memcpy((char *)ve->im.resources, (char *)resources, sizeof(resources)); + ve->im.num_resources = XtNumber(resources); + CompileResourceList( (XtResourceList) ve->im.resources, + ve->im.num_resources ); + if ((ve->ic.shared_ic_table = CreateIcTable( (Widget)vw, ve)) == NULL) + return(FALSE); + ve->ic.current_ic_table = NULL; + ve->ic.ic_table = NULL; + ve->im.im_list = ParseIMNameList(ve->im.input_method, &i); + ve->im.im_list_num = i; + ve->ic.ic_list = ParseIMNameList(ve->im.preedit_type, &i); + ve->ic.ic_list_num = i; + return(TRUE); +} + + +/* Destroy() + * + * This frees all (most?) of the resources malloced by XawIm. + * It is called by _XawImDestroy, which is called by Vendor.c's + * VendorExt's Destroy method. Sheeran, Omron KK, 93/08/05 */ + +static void Destroy( w, ve ) + Widget w; + XawVendorShellExtPart* ve; +{ + contextDataRec *contextData; + contextErrDataRec *contextErrData; + + if (!XtIsVendorShell( w ) ) + return; + XtFree( (char*) ve->im.resources ); + + if (extContext != (XContext)NULL && + !XFindContext (XtDisplay (w), (Window)w, + extContext, (XPointer*)&contextData)) + XtFree( (char*) contextData ); + + if (errContext != (XContext)NULL && + !XFindContext (XDisplayOfIM( ve->im.xim ), (Window) ve->im.xim, + errContext, (XPointer*) &contextErrData)) + XtFree( (char*) contextErrData ); +} + +/********************************************* + * + * SEMI-PRIVATE FUNCTIONS + * For use by other Xaw modules + * + ********************************************/ + +void +#if NeedFunctionPrototypes +_XawImResizeVendorShell( + Widget w ) +#else +_XawImResizeVendorShell( w ) + Widget w; +#endif +{ + XawVendorShellExtPart *ve; + + if ( ( ve = GetExtPart( (VendorShellWidget) w ) ) && ve->im.xim ) { + ResizeVendorShell( (VendorShellWidget) w, ve ); + } +} + + +Dimension +#if NeedFunctionPrototypes +_XawImGetShellHeight( + Widget w ) +#else +_XawImGetShellHeight( w ) + Widget w; +#endif +{ + XawVendorShellExtPart *ve; + + if (!XtIsVendorShell( w ) ) return( w->core.height ); + if ( ve = GetExtPart( (VendorShellWidget) w ) ) { + return( w->core.height - ve->im.area_height ); + } + return( w->core.height ); +} + +void +#if NeedFunctionPrototypes +_XawImRealize( + Widget w ) +#else +_XawImRealize( w ) + Widget w; +#endif +{ + XawVendorShellExtPart *ve; + extern void XawVendorShellExtResize(); + + if ( !XtIsRealized( w ) || !XtIsVendorShell( w ) ) return; + if ( ve = GetExtPart( (VendorShellWidget) w ) ) { + XtAddEventHandler( w, (EventMask)StructureNotifyMask, FALSE, + XawVendorShellExtResize, (XtPointer)NULL ); + AllCreateIC(ve); + } +} + +void +#if NeedFunctionPrototypes +_XawImInitialize( + Widget w, + Widget ext ) +#else +_XawImInitialize( w, ext ) + Widget w, ext; +#endif +{ + XawVendorShellExtPart *ve; + + if ( !XtIsVendorShell( w ) ) return; + if ( ve = SetExtPart( (VendorShellWidget) w, (XawVendorShellExtWidget)ext ) ) { + if ( Initialize( (VendorShellWidget) w, ve ) == FALSE ) return; + XtAddCallback( w, XtNdestroyCallback, VendorShellDestroyed, + (XtPointer) NULL ); + } +} + +void +#if NeedFunctionPrototypes +_XawImReconnect( + Widget inwidg ) +#else +_XawImReconnect( inwidg ) + Widget inwidg; +#endif +{ + XawVendorShellExtPart *ve; + VendorShellWidget vw; + + if ((vw = SearchVendorShell(inwidg)) == NULL) return; + if (ve = GetExtPart(vw)) { + Reconnect(ve); + } +} + +void +#if NeedFunctionPrototypes +_XawImRegister( + Widget inwidg) +#else +_XawImRegister(inwidg) + Widget inwidg; +#endif +{ + XawVendorShellExtPart *ve; + VendorShellWidget vw; + + if ((vw = SearchVendorShell(inwidg)) == NULL) return; + if (ve = GetExtPart(vw)) { + Register(inwidg, ve); + } +} + +void +#if NeedFunctionPrototypes +_XawImUnregister( + Widget inwidg) +#else +_XawImUnregister(inwidg) + Widget inwidg; +#endif +{ + XawVendorShellExtPart *ve; + VendorShellWidget vw; + + if ((vw = SearchVendorShell(inwidg)) == NULL) return; + if (ve = GetExtPart(vw)) { + Unregister(inwidg, ve); + } +} + +void +#if NeedFunctionPrototypes +_XawImSetValues( + Widget inwidg, + ArgList args, + Cardinal num_args ) +#else +_XawImSetValues( inwidg, args, num_args ) + Widget inwidg; + ArgList args; + Cardinal num_args; +#endif +{ + SetFocusValues( inwidg, args, num_args, FALSE ); +} + +void +#if NeedVarargsPrototypes +_XawImVASetValues( Widget inwidg, ... ) +#else +_XawImVASetValues( inwidg, va_alist ) + Widget inwidg; + va_dcl +#endif +{ + va_list var; + ArgList args = NULL; + Cardinal num_args; + int total_count, typed_count; + + Va_start( var, inwidg ); + _XtCountVaList( var, &total_count, &typed_count ); + va_end( var ); + + Va_start( var, inwidg ); + + _XtVaToArgList( inwidg, var, total_count, &args, &num_args ); + _XawImSetValues( inwidg, args, num_args ); + if ( args != NULL ) { + XtFree( (XtPointer) args ); + } + va_end( var ); +} + +void +#if NeedFunctionPrototypes +_XawImSetFocusValues( + Widget inwidg, + ArgList args, + Cardinal num_args) +#else +_XawImSetFocusValues(inwidg, args, num_args) + Widget inwidg; + ArgList args; + Cardinal num_args; +#endif +{ + SetFocusValues(inwidg, args, num_args, TRUE); +} + +void +#if NeedVarargsPrototypes +_XawImVASetFocusValues(Widget inwidg, ...) +#else +_XawImVASetFocusValues(inwidg, va_alist) + Widget inwidg; + va_dcl +#endif +{ + va_list var; + ArgList args = NULL; + Cardinal num_args; + int total_count, typed_count; + + Va_start(var, inwidg); + _XtCountVaList(var, &total_count, &typed_count); + va_end(var); + + Va_start(var,inwidg); + + _XtVaToArgList(inwidg, var, total_count, &args, &num_args); + _XawImSetFocusValues(inwidg, args, num_args); + if (args != NULL) { + XtFree((XtPointer)args); + } + va_end(var); +} + +void +#if NeedFunctionPrototypes +_XawImUnsetFocus( + Widget inwidg) +#else +_XawImUnsetFocus(inwidg) + Widget inwidg; +#endif +{ + UnsetFocus(inwidg); +} + +int +#if NeedFunctionPrototypes +_XawImWcLookupString( + Widget inwidg, + XKeyPressedEvent *event, + wchar_t* buffer_return, + int bytes_buffer, + KeySym *keysym_return, + Status *status_return) +#else +_XawImWcLookupString( inwidg, event, buffer_return, bytes_buffer, + keysym_return, status_return) + Widget inwidg; + XKeyPressedEvent* event; + wchar_t* buffer_return; + int bytes_buffer; + KeySym* keysym_return; + Status* status_return; +#endif +{ + XawVendorShellExtPart* ve; + VendorShellWidget vw; + XawIcTableList p; + int i, ret; + char tmp_buf[64], *tmp_p; + wchar_t* buf_p; + + if ((vw = SearchVendorShell(inwidg)) && (ve = GetExtPart(vw)) && + ve->im.xim && (p = GetIcTableShared(inwidg, ve)) && p->xic) { + return(XwcLookupString(p->xic, event, buffer_return, bytes_buffer, + keysym_return, status_return)); + } + ret = XLookupString( event, tmp_buf, 64, keysym_return, + (XComposeStatus*) status_return ); + for ( i = 0, tmp_p = tmp_buf, buf_p = buffer_return; i < ret; i++ ) { + *buf_p++ = atowc(*tmp_p++); + } + return( ret ); +} + +int +#if NeedFunctionPrototypes +_XawImGetImAreaHeight( + Widget w) +#else +_XawImGetImAreaHeight( w ) + Widget w; +#endif +{ + XawVendorShellExtPart *ve; + VendorShellWidget vw; + + if ((vw = SearchVendorShell(w)) && (ve = GetExtPart(vw))) { + return(ve->im.area_height); + } + return(0); +} + +void +#if NeedFunctionPrototypes +_XawImCallVendorShellExtResize( + Widget w) +#else +_XawImCallVendorShellExtResize( w ) + Widget w; +#endif +{ + XawVendorShellExtPart *ve; + VendorShellWidget vw; + extern void XawVendorShellExtResize(); + + if ((vw = SearchVendorShell(w)) && (ve = GetExtPart(vw))) { + XawVendorShellExtResize(vw); + } +} + + +/* _XawImDestroy() + * + * This should be called by the VendorExt from its + * core Destroy method. Sheeran, Omron KK 93/08/05 */ + +void +#if NeedFunctionPrototypes +_XawImDestroy( + Widget w, + Widget ext ) +#else +_XawImDestroy( w, ext ) + Widget w; + Widget ext; +#endif +{ + XawVendorShellExtPart *ve; + + if ( !XtIsVendorShell( w ) ) return; + if ( ve = GetExtPart( (VendorShellWidget) w ) ) + Destroy( w, ve ); +} diff --git a/xc/lib/Xaw/XawImP.h b/xc/lib/Xaw/XawImP.h new file mode 100644 index 000000000..fd15dc3a9 --- /dev/null +++ b/xc/lib/Xaw/XawImP.h @@ -0,0 +1,143 @@ +/* $XConsortium: XawImP.h,v 1.0 94/01/01 00:00:00 kaleb Exp $ */ + +/* + * Copyright 1991 by OMRON Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, 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 OMRON not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. OMRON makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * OMRON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Author: Seiji Kuwari OMRON Corporation + * kuwa@omron.co.jp + * kuwa%omron.co.jp@uunet.uu.net + */ + +#ifndef _XawImP_h +#define _XawImP_h + +#define XtNinputMethod "inputMethod" +#define XtCInputMethod "InputMethod" +#define XtNpreeditType "preeditType" +#define XtCPreeditType "PreeditType" +#define XtNopenIm "openIm" +#define XtCOpenIm "OpenIm" +#define XtNsharedIc "sharedIc" +#define XtCSharedIc "SharedIc" + +#include <X11/Xaw/Text.h> + +#define CIICFocus (1 << 0) +#define CIFontSet (1 << 1) +#define CIFg (1 << 2) +#define CIBg (1 << 3) +#define CIBgPixmap (1 << 4) +#define CICursorP (1 << 5) +#define CILineS (1 << 6) + +typedef struct _XawImPart +{ + XIM xim; + XrmResourceList resources; + Cardinal num_resources; + Boolean open_im; + Boolean initialized; + Dimension area_height; + String input_method; + String preedit_type; + String *im_list; + Cardinal im_list_num; +} XawImPart; + +typedef struct _XawIcTablePart +{ + Widget widget; + XIC xic; + XIMStyle input_style; + unsigned long flg; + unsigned long prev_flg; + Boolean ic_focused; + XFontSet font_set; + Pixel foreground; + Pixel background; + Pixmap bg_pixmap; + XawTextPosition cursor_position; + unsigned long line_spacing; + Boolean openic_error; + struct _XawIcTablePart *next; +} XawIcTablePart, *XawIcTableList; + +typedef struct _XawIcPart +{ + String *ic_list; + Cardinal ic_list_num; + XIMStyle input_style; + Boolean shared_ic; + XawIcTableList shared_ic_table; + XawIcTableList current_ic_table; + XawIcTableList ic_table; +} XawIcPart; + +typedef struct _contextDataRec +{ + Widget parent; + Widget ve; +} contextDataRec; + +typedef struct _contextErrDataRec +{ + Widget widget; + XIM xim; +} contextErrDataRec; + +#if NeedFunctionPrototypes +void _XawImResizeVendorShell( Widget ); +Dimension _XawImGetShellHeight( Widget ); +void _XawImRealize( Widget ); +void _XawImInitialize( Widget, Widget ); +void _XawImReconnect( Widget ); +void _XawImRegister( Widget ); +void _XawImUnregister( Widget ); +void _XawImSetValues( Widget, ArgList, Cardinal ); +void _XawImVASetValues( Widget, ... ); +void _XawImSetFocusValues( Widget, ArgList, Cardinal ); +void _XawImVASetFocusValues( Widget, ... ); +void _XawImUnsetFocus( Widget ); +int _XawImWcLookupString( Widget,XKeyPressedEvent*,wchar_t*,int,KeySym*,Status* ); +int _XawImGetImAreaHeight( Widget ); +void _XawImCallVendorShellExtResize( Widget ); +void _XawImDestroy( Widget, Widget ); +#else +void _XawImResizeVendorShell(); +Dimension _XawImGetShellHeight(); +void _XawImRealize(); +void _XawImInitialize(); +void _XawImReconnect(); +void _XawImRegister(); +void _XawImUnregister(); +void _XawImSetValues(); +void _XawImVASetValues(); +void _XawImSetFocusValues(); +void _XawImVASetFocusValues(); +void _XawImUnsetFocus(); +int _XawImWcLookupString(); +int _XawImGetImAreaShellHeight(); +void _XawImCallVendorShellExtResize(); +void _XawImDestroy(); +#endif + + +#endif /* _XawImP_h */ |