MultiSink.c

Go to the documentation of this file.
00001 /* $XConsortium: MultiSink.c,v 1.6 95/01/23 18:34:46 kaleb Exp $ */
00002 
00003 /*
00004  * Copyright 1991 by OMRON Corporation
00005  *
00006  * Permission to use, copy, modify, distribute, and sell this software and its
00007  * documentation for any purpose is hereby granted without fee, provided that
00008  * the above copyright notice appear in all copies and that both that
00009  * copyright notice and this permission notice appear in supporting
00010  * documentation, and that the name of OMRON not be used in advertising
00011  * or publicity pertaining to distribution of the software without specific,
00012  * written prior permission.  OMRON makes no representations about the
00013  * suitability of this software for any purpose.  It is provided "as is"
00014  * without express or implied warranty.
00015  *
00016  * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
00017  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
00018  * EVENT SHALL OMRON BE LIABLE FOR ANY SPECIAL, INDIRECT OR
00019  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
00020  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
00021  * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00022  * PERFORMANCE OF THIS SOFTWARE.
00023  *
00024  *      Author: Li Yuhong        OMRON Corporation
00025  */
00026 
00027 /***********************************************************
00028 
00029 Copyright (c) 1987, 1988, 1994  X Consortium
00030 
00031 Permission is hereby granted, free of charge, to any person obtaining a copy
00032 of this software and associated documentation files (the "Software"), to deal
00033 in the Software without restriction, including without limitation the rights
00034 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00035 copies of the Software, and to permit persons to whom the Software is
00036 furnished to do so, subject to the following conditions:
00037 
00038 The above copyright notice and this permission notice shall be included in
00039 all copies or substantial portions of the Software.
00040 
00041 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00042 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00043 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
00044 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00045 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00046 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00047 
00048 Except as contained in this notice, the name of the X Consortium shall not be
00049 used in advertising or otherwise to promote the sale, use or other dealings
00050 in this Software without prior written authorization from the X Consortium.
00051 
00052 
00053 Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
00054 
00055                         All Rights Reserved
00056 
00057 Permission to use, copy, modify, and distribute this software and its 
00058 documentation for any purpose and without fee is hereby granted, 
00059 provided that the above copyright notice appear in all copies and that
00060 both that copyright notice and this permission notice appear in 
00061 supporting documentation, and that the name of Digital not be
00062 used in advertising or publicity pertaining to distribution of the
00063 software without specific, written prior permission.  
00064 
00065 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
00066 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
00067 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
00068 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
00069 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
00070 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00071 SOFTWARE.
00072 
00073 ******************************************************************/
00074 
00075 #include <X11/IntrinsicP.h>
00076 #include <X11/StringDefs.h>
00077 #include <X11/Xatom.h>
00078 #include <X11/Xaw3d/XawInit.h>
00079 #include <X11/Xaw3d/MultiSinkP.h>
00080 #include <X11/Xaw3d/MultiSrcP.h>
00081 #include <X11/Xaw3d/TextP.h>
00082 #include "XawI18n.h"
00083 #include <stdio.h>
00084 #include <ctype.h>
00085 
00086 #ifdef GETLASTPOS
00087 #undef GETLASTPOS               /* We will use our own GETLASTPOS. */
00088 #endif
00089 
00090 #define GETLASTPOS XawTextSourceScan(source, (XawTextPosition) 0, XawstAll, XawsdRight, 1, TRUE)
00091 
00092 static void Initialize(), Destroy();
00093 static Boolean SetValues();
00094 static int MaxLines(), MaxHeight();
00095 static void SetTabs();
00096 
00097 static void DisplayText(), InsertCursor(), FindPosition();
00098 static void FindDistance(), Resolve(), GetCursorBounds();
00099 
00100 #define offset(field) XtOffsetOf(MultiSinkRec, multi_sink.field)
00101 
00102 static XtResource resources[] = {
00103     {XtNfontSet, XtCFontSet, XtRFontSet, sizeof (XFontSet),
00104         offset(fontset), XtRString, XtDefaultFontSet},
00105     {XtNecho, XtCOutput, XtRBoolean, sizeof(Boolean),
00106         offset(echo), XtRImmediate, (XtPointer) True},
00107     {XtNdisplayNonprinting, XtCOutput, XtRBoolean, sizeof(Boolean),
00108         offset(display_nonprinting), XtRImmediate, (XtPointer) True},
00109 };
00110 #undef offset
00111 
00112 #define SuperClass              (&textSinkClassRec)
00113 MultiSinkClassRec multiSinkClassRec = {
00114   { /* core_class fields */     
00115     /* superclass               */      (WidgetClass) SuperClass,
00116     /* class_name               */      "MultiSink",
00117     /* widget_size              */      sizeof(MultiSinkRec),
00118     /* class_initialize         */      XawInitializeWidgetSet,
00119     /* class_part_initialize    */      NULL,
00120     /* class_inited             */      FALSE,
00121     /* initialize               */      Initialize,
00122     /* initialize_hook          */      NULL,
00123     /* obj1                     */      NULL,
00124     /* obj2                     */      NULL,
00125     /* obj3                     */      0,
00126     /* resources                */      resources,
00127     /* num_resources            */      XtNumber(resources),
00128     /* xrm_class                */      NULLQUARK,
00129     /* obj4                     */      FALSE,
00130     /* obj5                     */      FALSE,
00131     /* obj6                     */      FALSE,
00132     /* obj7                     */      FALSE,
00133     /* destroy                  */      Destroy,
00134     /* obj8                     */      NULL,
00135     /* obj9                     */      NULL,
00136     /* set_values               */      SetValues,
00137     /* set_values_hook          */      NULL,
00138     /* obj10                    */      NULL,
00139     /* get_values_hook          */      NULL,
00140     /* obj11                    */      NULL,
00141     /* version                  */      XtVersion,
00142     /* callback_private         */      NULL,
00143     /* obj12                    */      NULL,
00144     /* obj13                    */      NULL,
00145     /* obj14                    */      NULL,
00146     /* extension                */      NULL
00147   },
00148   { /* text_sink_class fields */
00149     /* DisplayText              */      DisplayText,
00150     /* InsertCursor             */      InsertCursor,
00151     /* ClearToBackground        */      XtInheritClearToBackground,
00152     /* FindPosition             */      FindPosition,
00153     /* FindDistance             */      FindDistance,
00154     /* Resolve                  */      Resolve,
00155     /* MaxLines                 */      MaxLines,
00156     /* MaxHeight                */      MaxHeight,
00157     /* SetTabs                  */      SetTabs,
00158     /* GetCursorBounds          */      GetCursorBounds
00159   },
00160   { /* multi_sink_class fields */
00161     /* unused                   */      0
00162   }
00163 };
00164 
00165 WidgetClass multiSinkObjectClass = (WidgetClass)&multiSinkClassRec;
00166 
00167 /* Utilities */
00168 
00169 static int 
00170 #if NeedFunctionPrototypes
00171 CharWidth (
00172     Widget w,
00173     int x,
00174     wchar_t c)
00175 #else
00176 CharWidth (w, x, c)
00177     Widget w;
00178     int x;
00179     wchar_t c;
00180 #endif
00181 {
00182     int    i, width;
00183     MultiSinkObject sink = (MultiSinkObject) w;
00184     XFontSet fontset = sink->multi_sink.fontset;
00185     Position *tab;
00186 
00187     if ( c == _Xaw_atowc(XawLF) ) return(0);
00188 
00189     if (c == _Xaw_atowc(XawTAB)) {
00190         /* Adjust for Left Margin. */
00191         x -= ((TextWidget) XtParent(w))->text.margin.left;
00192 
00193         if (x >= (int)XtParent(w)->core.width) return 0;
00194         for (i = 0, tab = sink->text_sink.tabs ; 
00195              i < sink->text_sink.tab_count ; i++, tab++) {
00196             if (x < *tab) {
00197                 if (*tab < (int)XtParent(w)->core.width)
00198                     return *tab - x;
00199                 else
00200                     return 0;
00201             }
00202         }
00203         return 0;
00204     }
00205 
00206     if (XwcTextEscapement (fontset, &c, 1) == 0)
00207         if (sink->multi_sink.display_nonprinting)
00208             c = _Xaw_atowc('@');
00209         else {
00210             c = _Xaw_atowc(XawSP);
00211         }
00212 
00213     /*
00214      * if more efficiency(suppose one column is one ASCII char)
00215 
00216     width = XwcGetColumn(fontset->font_charset, fontset->num_of_fonts, c) *
00217             fontset->font_struct_list[0]->min_bounds.width;
00218      *
00219      * WARNING: Very Slower!!!
00220      *
00221      * Li Yuhong.
00222      */
00223 
00224     width = XwcTextEscapement(fontset, &c, 1);
00225 
00226     return width;
00227 }
00228 
00229 /*      Function Name: PaintText
00230  *      Description: Actually paints the text into the windoe.
00231  *      Arguments: w - the text widget.
00232  *                 gc - gc to paint text with.
00233  *                 x, y - location to paint the text.
00234  *                 buf, len - buffer and length of text to paint.
00235  *      Returns: the width of the text painted, or 0.
00236  *
00237  * NOTE:  If this string attempts to paint past the end of the window
00238  *        then this function will return zero.
00239  */
00240 
00241 static Dimension
00242 PaintText(w, gc, x, y, buf, len)
00243     Widget w;
00244     GC gc;
00245     Position x, y;
00246     wchar_t* buf;
00247     int len;
00248 {
00249     MultiSinkObject sink = (MultiSinkObject) w;
00250     TextWidget ctx = (TextWidget) XtParent(w);
00251 
00252     XFontSet fontset = sink->multi_sink.fontset;
00253     Position max_x;
00254     Dimension width = XwcTextEscapement(fontset, buf, len);
00255     XFontSetExtents *ext = XExtentsOfFontSet(fontset);
00256     max_x = (Position) ctx->core.width;
00257 
00258     if ( ((int) width) <= -x)              /* Don't draw if we can't see it. */
00259       return(width);
00260 
00261     XwcDrawImageString(XtDisplay(ctx), XtWindow(ctx), fontset, gc,
00262                      (int) x, (int) y, buf, len);
00263     if ( (((Position) width + x) > max_x) && (ctx->text.margin.right != 0) ) {
00264         x = ctx->core.width - ctx->text.margin.right;
00265         width = ctx->text.margin.right;
00266         XFillRectangle(XtDisplay((Widget) ctx), XtWindow( (Widget) ctx),
00267                        sink->multi_sink.normgc, (int) x,
00268                        (int) y - abs(ext->max_logical_extent.y),
00269                        (unsigned int) width,
00270                        (unsigned int) ext->max_logical_extent.height);
00271         return(0);
00272     }
00273     return(width);
00274 }
00275 
00276 /* Sink Object Functions */
00277 
00278 /*
00279  * This function does not know about drawing more than one line of text.
00280  */
00281  
00282 static void 
00283 DisplayText(w, x, y, pos1, pos2, highlight)
00284     Widget w;
00285     Position x, y;
00286     Boolean highlight;
00287     XawTextPosition pos1, pos2;
00288 {
00289     MultiSinkObject sink = (MultiSinkObject) w;
00290     Widget source = XawTextGetSource(XtParent(w));
00291     wchar_t buf[BUFSIZ];
00292     XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset);
00293 
00294     int j, k;
00295     XawTextBlock blk;
00296     GC gc = highlight ? sink->multi_sink.invgc : sink->multi_sink.normgc;
00297     GC invgc = highlight ? sink->multi_sink.normgc : sink->multi_sink.invgc;
00298 
00299     if (!sink->multi_sink.echo) return;
00300 
00301     y += abs(ext->max_logical_extent.y);
00302     for ( j = 0 ; pos1 < pos2 ; ) {
00303         pos1 = XawTextSourceRead(source, pos1, &blk, (int) pos2 - pos1);
00304         for (k = 0; k < blk.length; k++) {
00305             if (j >= BUFSIZ) {  /* buffer full, dump the text. */
00306                 x += PaintText(w, gc, x, y, buf, j);
00307                 j = 0;
00308             }
00309             buf[j] = ((wchar_t *)blk.ptr)[k];
00310             if (buf[j] == _Xaw_atowc(XawLF))
00311                 continue;
00312 
00313             else if (buf[j] == _Xaw_atowc(XawTAB)) {
00314                 Position temp = 0;
00315                 Dimension width;
00316 
00317                 if ((j != 0) && ((temp = PaintText(w, gc, x, y, buf, j)) == 0))
00318                   return;
00319 
00320                 x += temp;
00321                 width = CharWidth(w, x, _Xaw_atowc(XawTAB));
00322                 XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w),
00323                                invgc, (int) x,
00324                                (int) y - abs(ext->max_logical_extent.y),
00325                                (unsigned int)width,
00326                                (unsigned int)ext->max_logical_extent.height);
00327                 x += width;
00328                 j = -1;
00329             }
00330             else if (XwcTextEscapement (sink->multi_sink.fontset, &buf[j], 1) == 0) {
00331                 if (sink->multi_sink.display_nonprinting)
00332                     buf[j] = _Xaw_atowc('@');
00333                 else
00334                     buf[j] = _Xaw_atowc(' ');
00335             }
00336             j++;
00337         }
00338     }
00339     if (j > 0)
00340         (void) PaintText(w, gc, x, y, buf, j);
00341 }
00342 
00343 #define insertCursor_width 6
00344 #define insertCursor_height 3
00345 static char insertCursor_bits[] = {0x0c, 0x1e, 0x33};
00346 
00347 static Pixmap
00348 CreateInsertCursor(s)
00349     Screen *s;
00350 {
00351     return (XCreateBitmapFromData (DisplayOfScreen(s), RootWindowOfScreen(s),
00352                   insertCursor_bits, insertCursor_width, insertCursor_height));
00353 }
00354 
00355 /*      Function Name: GetCursorBounds
00356  *      Description: Returns the size and location of the cursor.
00357  *      Arguments: w - the text object.
00358  * RETURNED        rect - an X rectangle to return the cursor bounds in.
00359  *      Returns: none.
00360  */
00361 
00362 static void
00363 GetCursorBounds(w, rect)
00364     Widget w;
00365     XRectangle * rect;
00366 {
00367     MultiSinkObject sink = (MultiSinkObject) w;
00368 
00369     rect->width = (unsigned short) insertCursor_width;
00370     rect->height = (unsigned short) insertCursor_height;
00371     rect->x = sink->multi_sink.cursor_x - (short) (rect->width / 2);
00372     rect->y = sink->multi_sink.cursor_y - (short) rect->height;
00373 }
00374 
00375 /*
00376  * The following procedure manages the "insert" cursor.
00377  */
00378 
00379 static void
00380 InsertCursor (w, x, y, state)
00381     Widget w;
00382     Position x, y;
00383     XawTextInsertState state;
00384 {
00385     MultiSinkObject sink = (MultiSinkObject) w;
00386     Widget text_widget = XtParent(w);
00387     XRectangle rect;
00388 
00389     sink->multi_sink.cursor_x = x;
00390     sink->multi_sink.cursor_y = y;
00391 
00392     GetCursorBounds(w, &rect);
00393     if (state != sink->multi_sink.laststate && XtIsRealized(text_widget)) 
00394         XCopyPlane(XtDisplay(text_widget),
00395                    sink->multi_sink.insertCursorOn,
00396                    XtWindow(text_widget), sink->multi_sink.xorgc,
00397                    0, 0, (unsigned int) rect.width, (unsigned int) rect.height,
00398                    (int) rect.x, (int) rect.y, 1);
00399     sink->multi_sink.laststate = state;
00400 }
00401 
00402 /*
00403  * Given two positions, find the distance between them.
00404  */
00405 
00406 static void
00407 FindDistance (w, fromPos, fromx, toPos, resWidth, resPos, resHeight)
00408     Widget w;
00409     XawTextPosition fromPos;    /* First position. */
00410     int fromx;                  /* Horizontal location of first position. */
00411     XawTextPosition toPos;      /* Second position. */
00412     int* resWidth;              /* Distance between fromPos and resPos. */
00413     XawTextPosition* resPos;    /* Actual second position used. */
00414     int* resHeight;             /* Height required. */
00415 {
00416     MultiSinkObject sink = (MultiSinkObject) w;
00417     Widget source = XawTextGetSource(XtParent(w));
00418 
00419     XawTextPosition index, lastPos;
00420     wchar_t c;
00421     XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset);
00422     XawTextBlock blk;
00423 
00424     /* we may not need this */
00425     lastPos = GETLASTPOS;
00426     XawTextSourceRead(source, fromPos, &blk, (int) toPos - fromPos);
00427     *resWidth = 0;
00428     for (index = fromPos; index != toPos && index < lastPos; index++) {
00429         if (index - blk.firstPos >= blk.length)
00430             XawTextSourceRead(source, index, &blk, (int) toPos - fromPos);
00431         c = ((wchar_t *)blk.ptr)[index - blk.firstPos];
00432         *resWidth += CharWidth(w, fromx + *resWidth, c);
00433         if (c == _Xaw_atowc(XawLF)) {
00434             index++;
00435             break;
00436         }
00437     }
00438     *resPos = index;
00439     *resHeight = ext->max_logical_extent.height;
00440 }
00441 
00442 
00443 static void
00444 FindPosition(w, fromPos, fromx, width, stopAtWordBreak, resPos, resWidth, resHeight)
00445     Widget w;
00446     XawTextPosition fromPos;    /* Starting position. */
00447     int fromx;                  /* Horizontal location of starting position.*/
00448     int width;                  /* Desired width. */
00449     int stopAtWordBreak;        /* Whether the resulting position should be at
00450                                    a word break. */
00451     XawTextPosition *resPos;    /* Resulting position. */
00452     int* resWidth;              /* Actual width used. */
00453     int* resHeight;             /* Height required. */
00454 {
00455     MultiSinkObject sink = (MultiSinkObject) w;
00456     Widget source = XawTextGetSource(XtParent(w));
00457 
00458     XawTextPosition lastPos, index, whiteSpacePosition = 0;
00459     int     lastWidth = 0, whiteSpaceWidth = 0;
00460     Boolean whiteSpaceSeen;
00461     wchar_t c;
00462     XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset);
00463     XawTextBlock blk;
00464 
00465     lastPos = GETLASTPOS;
00466 
00467     XawTextSourceRead(source, fromPos, &blk, BUFSIZ);
00468     *resWidth = 0;
00469     whiteSpaceSeen = FALSE;
00470     c = 0;
00471     for (index = fromPos; *resWidth <= width && index < lastPos; index++) {
00472         lastWidth = *resWidth;
00473         if (index - blk.firstPos >= blk.length)
00474             XawTextSourceRead(source, index, &blk, BUFSIZ);
00475         c = ((wchar_t *)blk.ptr)[index - blk.firstPos];
00476         *resWidth += CharWidth(w, fromx + *resWidth, c);
00477 
00478         if ((c == _Xaw_atowc(XawSP) || c == _Xaw_atowc(XawTAB)) && 
00479             *resWidth <= width) {
00480             whiteSpaceSeen = TRUE;
00481             whiteSpacePosition = index;
00482             whiteSpaceWidth = *resWidth;
00483         }
00484         if (c == _Xaw_atowc(XawLF)) {
00485             index++;
00486             break;
00487         }
00488     }
00489     if (*resWidth > width && index > fromPos) {
00490         *resWidth = lastWidth;
00491         index--;
00492         if (stopAtWordBreak && whiteSpaceSeen) {
00493             index = whiteSpacePosition + 1;
00494             *resWidth = whiteSpaceWidth;
00495         }
00496     }
00497     if (index == lastPos && c != _Xaw_atowc(XawLF)) index = lastPos + 1;
00498     *resPos = index;
00499     *resHeight = ext->max_logical_extent.height;
00500 }
00501 
00502 static void
00503 Resolve (w, pos, fromx, width, leftPos, rightPos)
00504     Widget w;
00505     XawTextPosition pos;
00506     int fromx, width;
00507     XawTextPosition *leftPos, *rightPos;
00508 {
00509     int resWidth, resHeight;
00510     Widget source = XawTextGetSource(XtParent(w));
00511 
00512     FindPosition(w, pos, fromx, width, FALSE, leftPos, &resWidth, &resHeight);
00513     if (*leftPos > GETLASTPOS)
00514       *leftPos = GETLASTPOS;
00515     *rightPos = *leftPos;
00516 }
00517 
00518 static void
00519 GetGC(sink)
00520     MultiSinkObject sink;
00521 {
00522     XtGCMask valuemask = (GCGraphicsExposures | GCForeground | GCBackground );
00523     XGCValues values;
00524 
00525     values.graphics_exposures = (Bool) FALSE;
00526     
00527     values.foreground = sink->text_sink.foreground;
00528     values.background = sink->text_sink.background;
00529 
00530     sink->multi_sink.normgc = XtAllocateGC( (Widget)sink, 0, valuemask, &values, GCFont, 0 );
00531     
00532     values.foreground = sink->text_sink.background;
00533     values.background = sink->text_sink.foreground;
00534     sink->multi_sink.invgc = XtAllocateGC( (Widget)sink, 0, valuemask, &values, GCFont, 0 );
00535     
00536     values.function = GXxor;
00537     values.background = (unsigned long) 0L;     /* (pix ^ 0) = pix */
00538     values.foreground = (sink->text_sink.background ^ 
00539                          sink->text_sink.foreground);
00540     valuemask = GCGraphicsExposures | GCFunction | GCForeground | GCBackground;
00541     
00542     /* if this GC is not used for fontset rendering then AllocateGC aint needed. Dont hurt tho.*/
00543     sink->multi_sink.xorgc = XtAllocateGC( (Widget)sink, 0, valuemask, &values, GCFont, 0 );
00544 }
00545 
00546 
00547 /***** Public routines *****/
00548 
00549 /*      Function Name: Initialize
00550  *      Description: Initializes the TextSink Object.
00551  *      Arguments: request, new - the requested and new values for the object
00552  *                                instance.
00553  *      Returns: none.
00554  *
00555  */
00556 
00557 /* ARGSUSED */
00558 static void
00559 Initialize(request, new, args, num_args)
00560     Widget request, new;
00561     ArgList args;
00562     Cardinal* num_args;
00563 {
00564     MultiSinkObject sink = (MultiSinkObject) new;
00565 
00566     GetGC(sink);
00567     
00568     sink->multi_sink.insertCursorOn= CreateInsertCursor(XtScreenOfObject(new));
00569     sink->multi_sink.laststate = XawisOff;
00570     sink->multi_sink.cursor_x = sink->multi_sink.cursor_y = 0;
00571 }
00572 
00573 /*      Function Name: Destroy
00574  *      Description: This function cleans up when the object is 
00575  *                   destroyed.
00576  *      Arguments: w - the MultiSink Object.
00577  *      Returns: none.
00578  */
00579 
00580 static void
00581 Destroy(w)
00582     Widget w;
00583 {
00584    MultiSinkObject sink = (MultiSinkObject) w;
00585 
00586    XtReleaseGC(w, sink->multi_sink.normgc);
00587    XtReleaseGC(w, sink->multi_sink.invgc);
00588    XtReleaseGC(w, sink->multi_sink.xorgc);
00589 
00590    XFreePixmap(XtDisplayOfObject(w), sink->multi_sink.insertCursorOn);
00591 }
00592 
00593 /*      Function Name: SetValues
00594  *      Description: Sets the values for the MultiSink
00595  *      Arguments: current - current state of the object.
00596  *                 request - what was requested.
00597  *                 new - what the object will become.
00598  *      Returns: True if redisplay is needed.
00599  */
00600 
00601 /* ARGSUSED */
00602 static Boolean
00603 SetValues(current, request, new, args, num_args)
00604     Widget current, request, new;
00605     ArgList args;
00606     Cardinal* num_args;
00607 {
00608     MultiSinkObject w = (MultiSinkObject) new;
00609     MultiSinkObject old_w = (MultiSinkObject) current;
00610 
00611     /* Font set is not in the GC! Do not make a new GC when font set changes! */
00612 
00613     if ( w->multi_sink.fontset != old_w->multi_sink.fontset ) {
00614         ((TextWidget)XtParent(new))->text.redisplay_needed = True;
00615 #ifndef NO_TAB_FIX
00616         SetTabs( w, w->text_sink.tab_count, w->text_sink.char_tabs );
00617 #endif
00618     }
00619 
00620     if (   w->text_sink.background != old_w->text_sink.background ||
00621            w->text_sink.foreground != old_w->text_sink.foreground     ) {
00622 
00623         XtReleaseGC((Widget)w, w->multi_sink.normgc);
00624         XtReleaseGC((Widget)w, w->multi_sink.invgc);
00625         XtReleaseGC((Widget)w, w->multi_sink.xorgc);
00626         GetGC(w);
00627         ((TextWidget)XtParent(new))->text.redisplay_needed = True;
00628     } else {
00629         if ( (w->multi_sink.echo != old_w->multi_sink.echo) ||
00630              (w->multi_sink.display_nonprinting != 
00631                                      old_w->multi_sink.display_nonprinting) )
00632             ((TextWidget)XtParent(new))->text.redisplay_needed = True;
00633     }
00634     
00635     return False;
00636 }
00637 
00638 /*      Function Name: MaxLines
00639  *      Description: Finds the Maximum number of lines that will fit in
00640  *                   a given height.
00641  *      Arguments: w - the MultiSink Object.
00642  *                 height - height to fit lines into.
00643  *      Returns: the number of lines that will fit.
00644  */
00645 
00646 /* ARGSUSED */
00647 static int
00648 MaxLines(w, height)
00649     Widget w;
00650     Dimension height;
00651 {
00652   MultiSinkObject sink = (MultiSinkObject) w;
00653   int font_height;
00654   XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset);
00655 
00656   font_height = ext->max_logical_extent.height;
00657   return( ((int) height) / font_height );
00658 }
00659 
00660 /*      Function Name: MaxHeight
00661  *      Description: Finds the Minium height that will contain a given number 
00662  *                   lines.
00663  *      Arguments: w - the MultiSink Object.
00664  *                 lines - the number of lines.
00665  *      Returns: the height.
00666  */
00667 
00668 /* ARGSUSED */
00669 static int
00670 #if NeedFunctionPrototypes
00671 MaxHeight( 
00672     Widget w, 
00673     int lines )
00674 #else
00675 MaxHeight( w, lines )
00676     Widget w;
00677     int lines;
00678 #endif
00679 {
00680   MultiSinkObject sink = (MultiSinkObject) w;
00681   XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset);
00682 
00683   return(lines * ext->max_logical_extent.height); 
00684 }
00685 
00686 /*      Function Name: SetTabs
00687  *      Description: Sets the Tab stops.
00688  *      Arguments: w - the MultiSink Object.
00689  *                 tab_count - the number of tabs in the list.
00690  *                 tabs - the text positions of the tabs.
00691  *      Returns: none
00692  */
00693 
00694 static void 
00695 #if NeedFunctionPrototypes
00696 SetTabs( 
00697     Widget w, 
00698     int tab_count, 
00699     short* tabs )
00700 #else
00701 SetTabs( w, tab_count, tabs )
00702     Widget w;
00703     int tab_count;
00704     short* tabs;
00705 #endif
00706 {
00707   MultiSinkObject sink = (MultiSinkObject) w;
00708   int i;
00709   Atom XA_FIGURE_WIDTH;
00710   unsigned long figure_width = 0;
00711   XFontStruct *font;
00712 
00713   /*
00714    * Bug:
00715    *   Suppose the first font of fontset stores the unit of column.
00716    *
00717    * By Li Yuhong, Mar. 14, 1991
00718    */
00719   { XFontStruct **f_list;
00720     char        **f_name;
00721 
00722     (void) XFontsOfFontSet(sink->multi_sink.fontset, &f_list, &f_name);
00723     font = f_list[0];
00724   }
00725 
00726 /*
00727  * Find the figure width of the current font.
00728  */
00729 
00730   XA_FIGURE_WIDTH = XInternAtom(XtDisplayOfObject(w), "FIGURE_WIDTH", FALSE);
00731   if ( (XA_FIGURE_WIDTH != None) && 
00732        ( (!XGetFontProperty(font, XA_FIGURE_WIDTH, &figure_width)) ||
00733          (figure_width == 0)) ) 
00734     if (font->per_char && font->min_char_or_byte2 <= '$' &&
00735         font->max_char_or_byte2 >= '$')
00736       figure_width = font->per_char['$' - font->min_char_or_byte2].width;
00737     else
00738       figure_width = font->max_bounds.width;
00739 
00740   if (tab_count > sink->text_sink.tab_count) {
00741     sink->text_sink.tabs = (Position *)
00742         XtRealloc((char *) sink->text_sink.tabs,
00743                   (Cardinal) (tab_count * sizeof(Position)));
00744     sink->text_sink.char_tabs = (short *)
00745         XtRealloc((char *) sink->text_sink.char_tabs,
00746                   (Cardinal) (tab_count * sizeof(short)));
00747   }
00748 
00749   for ( i = 0 ; i < tab_count ; i++ ) {
00750     sink->text_sink.tabs[i] = tabs[i] * figure_width;
00751     sink->text_sink.char_tabs[i] = tabs[i];
00752   }
00753     
00754   sink->text_sink.tab_count = tab_count;
00755 
00756 #ifndef NO_TAB_FIX
00757   ((TextWidget)XtParent(w))->text.redisplay_needed = True;
00758 #endif
00759 }
00760 
00761 void
00762 #if NeedFunctionPrototypes
00763 _XawMultiSinkPosToXY(
00764     Widget w, 
00765     XawTextPosition pos, 
00766     Position *x,
00767     Position *y )
00768 #else
00769 _XawMultiSinkPosToXY( w, pos, x, y )
00770     Widget w;
00771     XawTextPosition pos;
00772     Position *x, *y;
00773 #endif
00774 {
00775     MultiSinkObject sink = (MultiSinkObject) ((TextWidget)w)->text.sink;
00776     XFontSetExtents *ext = XExtentsOfFontSet( sink->multi_sink.fontset );
00777 
00778     _XawTextPosToXY( w, pos, x, y );
00779     *y += abs( ext->max_logical_extent.y );
00780 }

Generated on Sun Mar 4 15:03:55 2007 for Scilab [trunk] by  doxygen 1.5.1