|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ S T ┃
Length: 26542 (0x67ae) Types: TextFile Names: »StaticText.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─ ⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z« └─⟦2109abc41⟧ └─ ⟦this⟧ »./X.V10R4/Toolkit/Xr/src/Xrlib/Editor/StaticText.c«
/* * $Source: /u1/Xr/src/Xrlib/Editor/RCS/StaticText.c,v $ * $Header: StaticText.c,v 1.1 86/12/17 09:05:33 swick Exp $ */ #ifndef lint static char *rcsid_StaticText_c = "$Header: StaticText.c,v 1.1 86/12/17 09:05:33 swick Exp $"; #endif lint #include <Xr/xr-copyright.h> /* $Header: StaticText.c,v 1.1 86/12/17 09:05:33 swick Exp $ */ /* Copyright 1986, Hewlett-Packard Company */ /* Copyright 1986, Massachussetts Institute of Technology */ static char rcsid[] = "$Header: StaticText.c,v 1.1 86/12/17 09:05:33 swick Exp $"; /*************************************<+>************************************* ***************************************************************************** ** ** File: StaticText.c ** ** Project: X-ray Toolbox ** ** Description: ** This file contains the static text field editor source code. ** ** ** ------------------------ MODIFICATION RECORD ------------------------ * * $Log: StaticText.c,v $ * Revision 1.1 86/12/17 09:05:33 swick * Initial revision * * Revision 7.0 86/11/13 08:28:09 08:28:09 fred () * Final QA Release * * Revision 6.0 86/11/10 15:36:42 15:36:42 fred () * QA #2 release * * Revision 5.2 86/11/07 14:23:50 14:23:50 fred () * Added new copyright message. * * Revision 5.1 86/11/03 14:48:50 14:48:50 fred () * MSG_SIZE and MSG_NEW now fail if the editor rectangle width is smaller * than the longer word in the string. * * Revision 5.0 86/10/28 08:34:48 08:34:48 fred () * QA #1.1 release * * Revision 4.1 86/10/22 07:30:13 07:30:13 fred () * Added 'message' parameter to createSText(). * * Revision 4.0 86/10/20 12:14:13 12:14:13 fred () * QA #1 release * * Revision 3.4 86/10/17 06:48:14 06:48:14 fred () * Fixed a bug where trailing spaces were not properly stripped * during text alignment. * * Revision 3.3 86/10/16 11:08:56 11:08:56 fred () * Filled in the procedure headers. * * Revision 3.2 86/10/16 09:18:56 09:18:56 fred () * Performance enhanced: added use of register variables. * * Revision 3.1 86/10/09 07:55:28 07:55:28 fred () * Added default color check to create routine. * * Revision 3.0 86/10/02 16:02:06 16:02:06 fred () * Alpha release set to 3.0 * * Revision 2.3 86/09/25 09:48:19 09:48:19 fred () * Modified MSG_SIZE, so that the leading is not included for the * last line of text. * * Revision 2.2 86/09/22 13:12:58 13:12:58 fred () * Added calls to XrEditorGroup(). * * Revision 2.1 86/09/19 12:17:59 12:17:59 fred () * Modified names of the info and data structures. * * Revision 2.0 86/09/16 08:11:27 08:11:27 fred () * Updated input processing routine to use new SELECT strategy. * * Revision 1.2 86/09/16 05:51:20 05:51:20 fred () * Modified to swallow a select up event. * * Revision 1.1 86/09/03 13:58:32 13:58:32 fred () * Initial revision * * ***************************************************************************** *************************************<+>*************************************/ #include <X/Xlib.h> #include <Xr/defs.h> #include <Xr/types.h> #include <Xr/in_types.h> extern INT32 stFreeMemory(); extern INT32 createSText(); extern INT32 drawSText(); extern INT32 processSText(); \f /*************************************<->************************************* * * xrEditor * * XrStaticText (staticText, message, data) * * xrEditor * staticText; * INT32 message; * INT8 * data; * * Description: * ----------- * This is the main entry point and message handler for the static * text field editor. It takes all message requests, and passes * them onto the appropriate handler; invalid messages will fail * and return an error. * * * Inputs: * ------ * staticText = For all messages but MSG_NEW and MSG_SIZE, this * contains the instance pointer. * * message = This indicates which action the editor should perform. * * data = This is the message specific data. It's usage depend upon * the 'message' parameter, and may be a scalar or a pointer. * * Outputs: * ------- * Upon successful completion of a command, the instance pointer * is returned; additional information may be returned by * means of the 'data' parameter. * * Upon failure, NULL is returned, and xrErrno is set. * * Procedures Called * ----------------- * _MsgNew() [MsgCommon.c] * _MsgFree() [MsgCommon.c] * _MsgGetState() [MsgCommon.c] * _MsgSetState() [MsgCommon.c] * _MsgRedraw() [MsgCommon.c] * _MsgEdit() [MsgCommon.c] * _XrMakeInvisible() [editorUtil.c] * XrCopyRect() [calc.c] * drawSText() * sizeSText() * *************************************<->***********************************/ xrEditor * XrStaticText (staticText, message, data) register xrEditor * staticText; INT32 message; INT8 * data; { /* Determine the action being requested */ switch (message) { case MSG_NEW: { /* * Create a new instance of the static text editor. * The only parameter of interest is the 'data' * parameter, which is a pointer to a filled instance * of the xrStaticTextInfo structure. */ return ((xrEditor *) _MsgNew (staticText, data, sizeof(xrStaticTextData), createSText, drawSText, stFreeMemory, XrStaticText, NULL)); } case MSG_FREE: { /* * Destroy the specified static text instance. * The 'staticText' parameter specifies the instance to * be destroyed; the 'data' parameter is unused. */ return ((xrEditor *) _MsgFree (staticText, stFreeMemory)); } case MSG_GETSTATE: { /* * Return the settings of the state flags for the * specified static text instance. The 'staticText' * parameter specifies the instance to be queried, while * the 'data' parameter must point to an INT8 value, into * which the state flags will be placed. */ return ((xrEditor *) _MsgGetState (staticText, data)); } case MSG_SETSTATE: { /* * Change the state flag settings for the specified * instance. The 'staticText' parameter specifies the * instance to bemdified, and the 'data' parameter is * interpreted as an INT8 value, containing the new * state flag settings. */ return ((xrEditor *) _MsgSetState (staticText, data, drawSText, NULL)); } case MSG_SIZE: { /* * Return the size of the rectangle needed to enclose * an instance of this editor, using the specifications * passed in by the application program. The 'data' * parameter must point to a partially filled out instance * of the 'xrStaticTextInfo' structure; upon completion, * the 'editorRect' field of the 'info' structure will * be filled. */ xrStaticTextInfo *stInfoPtr; stInfoPtr = (xrStaticTextInfo *)data; if (stInfoPtr == NULL) { xrErrno = XrINVALIDPTR; return ((xrEditor *)NULL); } else if (sizeSText (stInfoPtr, &stInfoPtr->editorRect) == FALSE) { /* Size request failed; xrErrno set by sizeSText */ return ((xrEditor *)NULL); } return ((xrEditor *) TRUE); } case MSG_REDRAW: { /* * Redraw the static text instance. * The 'staticText' parameter specifies the instance to redraw, * while the 'data' parameter is interpreted as an INT32 value, * specifying the type of redraw to perform. */ return ((xrEditor *) _MsgRedraw (staticText, data, drawSText, NULL)); } case MSG_MOVE: { /* * Relocate a static text instance to a new location. * The 'staticText' parameter specifies the instance to be * moved, while the 'data' parameter must point to a POINT * structure, containing the new editor rectangle origin. */ POINT * ptPtr = (POINT *) data; RECTANGLE workRect; if (staticText == NULL) { xrErrno = XrINVALIDID; return ((xrEditor *) NULL); } else if (data == NULL) { xrErrno = XrINVALIDPTR; return ((xrEditor *) NULL); } /* Reset the origin for the editorRect */ XrCopyRect (&staticText->editorRect, &workRect); staticText->editorRect.x = ptPtr->x; staticText->editorRect.y = ptPtr->y; if (staticText->editorState & XrVISIBLE) { /* Remove the instance from the window, if visible */ _XrMakeInvisible (staticText->editorWindowId, &workRect, TRUE); /* Redisplay the instance, if it was visible */ drawSText (staticText, NULL); } /* Force the editor group rectangle to be recalculated */ XrEditorGroup (NULL, MSG_ADJUSTGROUPRECT, staticText); return (staticText); } case MSG_RESIZE: { /* * Resize an existing static text instance. * The 'staticText' parameter indicates the instance to be * resized, while the 'data' parameter must point to a * RECTANGLE structure, containing the new editor rectangle. */ RECTANGLE * rectPtr = (RECTANGLE *) data; RECTANGLE workRect; if (staticText == NULL) { xrErrno = XrINVALIDID; return ((xrEditor *) NULL); } else if (data == NULL) { xrErrno = XrINVALIDPTR; return ((xrEditor *) NULL); } /* Validate the rectangle size */ if ((rectPtr->width <= 0) || (rectPtr->height <= 0)) { xrErrno = XrINVALIDRECT; return ((xrEditor *) NULL); } /* Save the new rectangle definition */ XrCopyRect (&staticText->editorRect, &workRect); XrCopyRect (rectPtr, &staticText->editorRect); if (staticText->editorState & XrVISIBLE) { /* Remove the instance from the window, if visible */ _XrMakeInvisible (staticText->editorWindowId, &workRect, TRUE); /* Redisplay the instance, if it was visible */ drawSText (staticText, NULL); } /* Force the editor group rectangle to be recalculated */ XrEditorGroup (NULL, MSG_ADJUSTGROUPRECT, staticText); return (staticText); } case MSG_EDIT: { /* * Process the incoming event, and generate a return * event, to indicate to the application program * how the editor instance was modified. The 'data' * parameter must point to the event to be processed. */ return ((xrEditor *) _MsgEdit (staticText, data, processSText, XrSTATICTEXT)); } default: /* All other commands are invalid */ xrErrno = XrINVALIDMSG; return ((xrEditor *)NULL); } /* end of switch */ } /* end of XrStaticText() */ \f /*************************************<->************************************* * * static * INT32 * stFreeMemory (stDataPtr) * * Description: * ----------- * This routine is called both when an existing instance is freed, * and when a MSG_NEW request fails after createSText() has been * called. It will free up all resources which createSText() * allocated for the instance. * * * Inputs: * ------ * stDataPtr = Pointer to the instance's internal 'data' structure. * * Outputs: * ------- * * Procedures Called * ----------------- * *************************************<->***********************************/ static INT32 stFreeMemory (stDataPtr) xrStaticTextData * stDataPtr; { (*xrFree) (stDataPtr->textString); } \f /*************************************<->************************************* * * static * INT32 * sizeSText (stInfoPtr, rectPtr) * * Description: * ----------- * This routine will validate most of the parameters contained within * the 'info' structure pointed to by 'stInfoPtr', and will then * calculate the size of the editor rectangle needed to contain the * specified instance. * * * Inputs: * ------ * stInfoPtr = Pointer to an instance of the 'xrStaticTextInfo' * structure, which describes the instance to be sized. * * rectPtr = Pointer to a RECTANGLE structure, in which the editor * rectangle definition will be placed. * * Outputs: * ------- * Upon successful completion, TRUE is returned, and the editor * rectangle is returned. * * Upon failure, FALSE is returned, and xrErrno is set. * * Procedures Called * ----------------- * _XrTextInfo() [textUtil.c] * parseText() * *************************************<->***********************************/ static INT32 sizeSText (stInfoPtr, rectPtr) register xrStaticTextInfo * stInfoPtr; register RECTANGLE * rectPtr; { FontInfo * fontPtr; xrTextInfo fontData; register INT32 alignment = stInfoPtr->alignment; /* Validate all parameters */ if (stInfoPtr->editorRect.width <= 0) { xrErrno = XrINVALIDRECT; return (FALSE); } else if (stInfoPtr->string == NULL) { xrErrno = XrINVALIDPTR; return (FALSE); } else if (strlen (stInfoPtr->string) == 0) { xrErrno = XrINVALIDPARM; return (FALSE); } else if ((alignment != XrCENTER_ALIGNED) && (alignment != XrLEFT_ALIGNED) && (alignment != XrRIGHT_ALIGNED) && (alignment != XrNO_ALIGNMENT)) { xrErrno = XrINVALIDOPTION; return (FALSE); } /* Set the rectangle coordinates */ rectPtr->x = 0; rectPtr->y = 0; /* Set up the variables we'll need for our calculations */ fontPtr = stInfoPtr->editorFont ? stInfoPtr->editorFont : xrBaseFontInfo; _XrTextInfo (fontPtr, &fontData); if (parseText (0, stInfoPtr->string, alignment, rectPtr, &fontData, FALSE) == FALSE) return (FALSE); else return (TRUE); } \f /*************************************<->************************************* * * static * INT32 * createSText (stDataPtr, stInfoPtr, message) * * Description: * ----------- * This routine takes the instance definition, contained within the * 'xrStaticTextInfo' structure pointed to by 'stInfoPtr', and creates * an instance to match it. All information describing the new * instance will be saved in the structure pointed to by 'stDataPtr'. * * * Inputs: * ------ * stDataPtr = Points to the 'data' structure, in which all state * information for the new instance will be stored. * * stInfoPtr = Points to the 'info' structure describing the instance * to be created. * * message = Not used; parameter is include so that this routine * may be called by _MsgNew(). * * Outputs: * ------- * Upon successful completion, TRUE is returned. * * Upon failure, FALSE is returned, and xrErrno is set. * * Procedures Called * ----------------- * _XrTextInfo() [textUtil.c] * *************************************<->***********************************/ static INT32 createSText (stDataPtr, stInfoPtr, message) register xrStaticTextData * stDataPtr; register xrStaticTextInfo * stInfoPtr; INT32 message; { register INT32 alignment = stInfoPtr->alignment; register INT8 * strPtr = stInfoPtr->string; FontInfo * fontPtr; RECTANGLE workRect; /* Validate all parameters */ if ((stInfoPtr->editorRect.width <= 0) || (stInfoPtr->editorRect.height <= 0)) { xrErrno = XrINVALIDRECT; return (FALSE); } /* Allocate some space to hold the text string */ if ((stDataPtr->textString = (xrMalloc)(strlen(strPtr) + 1)) == NULL) { xrErrno = XrOUTOFMEM; return (FALSE); } /* Check for an invalid editor rectangle */ XrCopyRect (&stInfoPtr->editorRect, &workRect); if (sizeSText (stInfoPtr, &workRect) == FALSE) return (FALSE); /* Copy the rest of the information describing the instance */ strcpy (stDataPtr->textString, strPtr); stDataPtr->textAlignment = alignment; fontPtr = stInfoPtr->editorFont ? stInfoPtr->editorFont : xrBaseFontInfo; _XrTextInfo (fontPtr, &stDataPtr->textFont); stDataPtr->stFGColor = (stInfoPtr->editorFGColor == -1) ? xrForegroundColor : stInfoPtr->editorFGColor; stDataPtr->stBGColor = (stInfoPtr->editorBGColor == -1) ? xrBackgroundColor : stInfoPtr->editorBGColor; return (TRUE); } \f /*************************************<->************************************* * * static * INT32 * drawSText (staticText, drawOption) * * Description: * ----------- * This routine draws a static text instance. The way in which it * is drawn depends upon the state of the XrVISIBLE state flag only. * * * Inputs: * ------ * staticText = Points to the instance structure associated with the * instance to be drawn. This contains all the data * necessary to draw the particular static text instance. * * drawOption = Not used by this procedure; it is here only so that * this routine may be called by _MsgNew(). * * Outputs: * ------- * * Procedures Called * ----------------- * _XrMakeInvisible() [editorUtil.c] * _XrInitEditorGCs() [gcUtil.c] * parseText() * *************************************<->***********************************/ static INT32 drawSText (staticText, drawOption) xrEditor * staticText; INT32 drawOption; { Window windowId; register xrStaticTextData * stDataPtr; stDataPtr = (xrStaticTextData *) staticText->editorData; windowId = staticText->editorWindowId; /* * If the instance is not visible, then fill its area with the * background tile for the window, thus making the instance invisible. */ if (!(staticText->editorState & XrVISIBLE)) { _XrMakeInvisible (windowId, &staticText->editorRect, TRUE); return; } /* Initialize the graphics context we will be needing */ _XrInitEditorGCs (stDataPtr->stFGColor, stDataPtr->stBGColor, stDataPtr->textFont.fontInfo->id); /* Display the text */ parseText (windowId, stDataPtr->textString, stDataPtr->textAlignment, &staticText->editorRect, &stDataPtr->textFont, TRUE); } \f /*************************************<->************************************* * * static * INT32 * parseText (windowId, string, textAlignment, rectPtr, fontPtr, draw) * * Description: * ----------- * This is the real work horse routine during the drawing of an * instance. It takes the static text string, and parses out each * line, and then displays it. It continues until either the complete * string has been displayed, or the bottom of the editor rectangle * is reached. * * This routine is also used when a MSG_SIZE request is made. For * this case, the text is parse only, and the size of the rectangle * needed to contain all of it is calculated. * * * Inputs: * ------ * windowId = Id for window in which text is to be displayed. * * string = String to be parsed and potentially displayed. * * textAlignment = Type of alignment to use. * * rectPtr = If drawing, then this is the editor rectangle; else * this needs to be filled with the editor rectangle. * * fontPtr = Points to the font information. * * draw = TRUE, if the instance is to be drawn; FALSE if the instance * is to be sized only. * * Outputs: * ------- * Returns TRUE if the text is successfully parsed. * * Returns FALSE otherwise. * * Procedures Called * ----------------- * XrStringWidth() [utilities.c] * _XrImageText8() [textUtil.c] * *************************************<->***********************************/ static INT32 parseText (windowId, string, textAlignment, rectPtr, fontPtr, draw) Window windowId; INT8 * string; INT32 textAlignment; RECTANGLE * rectPtr; register xrTextInfo * fontPtr; INT32 draw; { register INT16 width, delta; INT16 lowerBoundary; register INT8 * end, * start; INT8 * previousEnd, * stripPtr; INT16 oldWidth; INT32 forcedBreak; INT32 wordCount; INT16 stringWidth; INT16 x, y; /* Set up the variables we'll need to draw the instance */ delta = fontPtr->ascent + fontPtr->descent + fontPtr->leading; width = rectPtr->width; start = end = string; if (draw) { lowerBoundary = rectPtr->y + rectPtr->height - fontPtr->descent - fontPtr->ascent; /* This is a release 10 fix */ y = rectPtr->y; /* + fontPtr->ascent; */ } else y = 0; /* Draw the static raster instance */ while (1) { wordCount = 0; oldWidth = 0; forcedBreak = FALSE; /* If doing alignment, then strip leading spaces */ if (textAlignment != XrNO_ALIGNMENT) { while (*start == ' ') start++; end = start; } /* Parse out a single line */ while (1) { /* Parse out a single word */ if (*end == ' ') /* Count each space as a word */ end++; else if ((*end=='\n') ||(*end=='\r') || (*end=='\f') || (*end=='\013')) { /* Force to a new line */ forcedBreak = TRUE; break; } else if (*end == NULL) { /* End of string reached */ if (wordCount == 0) { if (draw == FALSE) rectPtr->height = y - fontPtr->leading; return (TRUE); } break; } else /* Extract a word upto a separator */ while ((*end != NULL) && (*end != ' ') && (*end != '\n') && (*end != '\r') && (*end != '\f') && (*end != '\013')) end++; stringWidth = XrStringWidth(fontPtr->fontInfo, start, end - start,0,0); wordCount++; /* See if we have surpassed the rectangle right border */ if (stringWidth > width) { /* * Back track to the last word which fit, unless this * is the only word on the line. */ if (wordCount > 1) { end = previousEnd; stringWidth= oldWidth; } else if (wordCount == 1) { xrErrno = XrINVALIDRECT; return (FALSE); } break; } previousEnd = end; oldWidth = stringWidth; } /* Display the line, if one was extracted */ if ((wordCount > 0) && (draw)) { if (y > lowerBoundary) break; /* If doing alignment, then strip trailing spaces */ stripPtr = end - 1; if (textAlignment != XrNO_ALIGNMENT) { while ((*stripPtr == ' ') && (stripPtr > start+1)) stripPtr--; stringWidth = XrStringWidth(fontPtr->fontInfo, start, stripPtr - start + 1, 0, 0); } /* Justify the line of text */ switch (textAlignment) { case XrCENTER_ALIGNED: x = rectPtr->x + (width >> 1) - (stringWidth >> 1); break; case XrRIGHT_ALIGNED: x = rectPtr->x + rectPtr->width - 1 - stringWidth; break; case XrNO_ALIGNMENT: case XrLEFT_ALIGNED: x = rectPtr->x; break; } /* Display the string */ _XrImageText8 (windowId, xrEditorGC1, stripPtr + 1 - start, x, y, start); } if (forcedBreak) end++; /* Continue with the next line */ y += delta; start = end; } return (TRUE); } \f /*************************************<->************************************* * * static * INT32 * processSText (staticText, event, returnEvent) * * xrEditor * staticText; * XButtonEvent * event; * xrEvent * returnEvent; * * Description: * ----------- * This is the event processing routine for the static text editor. * Since we already know by this point that the event was a SELECT, * and that it occurred within the instance, we simply need to * fill in the return event structure, so that it can be pushed onto * the input queue. * * * Inputs: * ------ * staticText = Points to the instance structure. * * event = Points to the SELECT event being processed. * * returnEvent = Points to the X-ray event structure, which will * be pushed onto the input queue on return. * * Outputs: * ------- * * Procedures Called * ----------------- * *************************************<->***********************************/ static INT32 processSText (staticText, event, returnEvent) xrEditor * staticText; XButtonEvent * event; xrEvent * returnEvent; { returnEvent->value1 = XrSELECT; }