From f4890b17e6d13e9c5171c16cc473f060718cb99d Mon Sep 17 00:00:00 2001 From: Tamas TEVESZ Date: Tue, 28 Sep 2010 04:07:31 +0200 Subject: [PATCH] WINGs: Remove wruler and wtext Apparently not used (not by wdm either). Signed-off-by: Tamas TEVESZ --- WINGs/Makefile.am | 2 - WINGs/WINGs/WINGs.h | 212 +-- WINGs/wruler.c | 532 ------ WINGs/wtext.c | 3958 ------------------------------------------- 4 files changed, 18 insertions(+), 4686 deletions(-) delete mode 100644 WINGs/wruler.c delete mode 100644 WINGs/wtext.c diff --git a/WINGs/Makefile.am b/WINGs/Makefile.am index 75bfc0e1..c766ccc2 100644 --- a/WINGs/Makefile.am +++ b/WINGs/Makefile.am @@ -51,13 +51,11 @@ libWINGs_la_SOURCES = \ wpixmap.c \ wpopupbutton.c \ wprogressindicator.c \ - wruler.c \ wscroller.c \ wscrollview.c \ wslider.c \ wsplitview.c \ wtabview.c \ - wtext.c \ wtextfield.c \ wview.c \ wwindow.c diff --git a/WINGs/WINGs/WINGs.h b/WINGs/WINGs/WINGs.h index 93a8a014..845d1073 100644 --- a/WINGs/WINGs/WINGs.h +++ b/WINGs/WINGs/WINGs.h @@ -287,26 +287,24 @@ enum { typedef int W_Class; enum { - WC_Window = 0, - WC_Frame = 1, - WC_Label = 2, - WC_Button = 3, - WC_TextField = 4, - WC_Scroller = 5, - WC_ScrollView = 6, - WC_List = 7, - WC_Browser = 8, - WC_PopUpButton = 9, - WC_ColorWell = 10, - WC_Slider = 11, - WC_Matrix = 12, /* not ready */ - WC_SplitView = 13, - WC_TabView = 14, - WC_ProgressIndicator = 15, - WC_MenuView = 16, - WC_Ruler = 17, - WC_Text = 18, - WC_Box = 19 + WC_Window, + WC_Frame, + WC_Label, + WC_Button, + WC_TextField, + WC_Scroller, + WC_ScrollView, + WC_List, + WC_Browser, + WC_PopUpButton, + WC_ColorWell, + WC_Slider, + WC_SplitView, + WC_TabView, + WC_ProgressIndicator, + WC_MenuView, + WC_Text, + WC_Box }; /* All widgets must start with the following structure @@ -350,7 +348,6 @@ typedef struct W_Slider WMSlider; typedef struct W_Matrix WMMatrix; /* not ready */ typedef struct W_SplitView WMSplitView; typedef struct W_TabView WMTabView; -typedef struct W_Ruler WMRuler; typedef struct W_Text WMText; typedef struct W_Box WMBox; @@ -436,18 +433,6 @@ typedef enum WMFontStyle { } WMFontStyle; -/* WMRuler: */ -typedef struct { - WMArray *tabs; /* a growable array of tabstops */ - unsigned short left; /* left margin marker */ - unsigned short right; /* right margin marker */ - unsigned short first; /* indentation marker for first line only */ - unsigned short body; /* body indentation marker */ - unsigned short retainCount; -} WMRulerMargins; -/* All indentation and tab markers are _relative_ to the left margin marker */ - - typedef void WMEventProc(XEvent *event, void *clientData); typedef void WMEventHook(XEvent *event); @@ -1540,167 +1525,6 @@ void WMSetSplitViewResizeSubviewsProc(WMSplitView *sPtr, int WMGetSplitViewDividerThickness(WMSplitView *sPtr); -/* ...................................................................... */ - -WMRuler* WMCreateRuler (WMWidget *parent); - -WMRulerMargins* WMGetRulerMargins(WMRuler *rPtr); - -void WMSetRulerMargins(WMRuler *rPtr, WMRulerMargins margins); - -Bool WMIsMarginEqualToMargin(WMRulerMargins *aMargin, WMRulerMargins *anotherMargin); - -int WMGetGrabbedRulerMargin(WMRuler *rPtr); - -int WMGetReleasedRulerMargin(WMRuler *rPtr); - -int WMGetRulerOffset(WMRuler *rPtr); - -void WMSetRulerOffset(WMRuler *rPtr, int pixels); - -void WMSetRulerMoveAction(WMRuler *rPtr, WMAction *action, void *clientData); - -void WMSetRulerReleaseAction(WMRuler *rPtr, WMAction *action, void *clientData); - -/* ....................................................................... */ - - -#define WMCreateText(parent) WMCreateTextForDocumentType \ - ((parent), (NULL), (NULL)) - -WMText* WMCreateTextForDocumentType(WMWidget *parent, WMAction *parser, - WMAction *writer); - -void WMSetTextDelegate(WMText *tPtr, WMTextDelegate *delegate); - -void WMFreezeText(WMText *tPtr); - -#define WMRefreshText(tPtr) WMThawText((tPtr)) - -void WMThawText(WMText *tPtr); - -int WMScrollText(WMText *tPtr, int amount); - -int WMPageText(WMText *tPtr, Bool direction); - -void WMSetTextHasHorizontalScroller(WMText *tPtr, Bool shouldhave); - -void WMSetTextHasVerticalScroller(WMText *tPtr, Bool shouldhave); - -void WMSetTextHasRuler(WMText *tPtr, Bool shouldhave); - -void WMShowTextRuler(WMText *tPtr, Bool show); - -int WMGetTextRulerShown(WMText *tPtr); - -void WMSetTextEditable(WMText *tPtr, Bool editable); - -int WMGetTextEditable(WMText *tPtr); - -void WMSetTextUsesMonoFont(WMText *tPtr, Bool mono); - -int WMGetTextUsesMonoFont(WMText *tPtr); - -void WMSetTextIndentNewLines(WMText *tPtr, Bool indent); - -void WMSetTextIgnoresNewline(WMText *tPtr, Bool ignore); - -int WMGetTextIgnoresNewline(WMText *tPtr); - -void WMSetTextDefaultFont(WMText *tPtr, WMFont *font); - -WMFont* WMGetTextDefaultFont(WMText *tPtr); - -void WMSetTextDefaultColor(WMText *tPtr, WMColor *color); - -WMColor* WMGetTextDefaultColor(WMText *tPtr); - -void WMSetTextRelief(WMText *tPtr, WMReliefType relief); - -void WMSetTextForegroundColor(WMText *tPtr, WMColor *color); - -void WMSetTextBackgroundColor(WMText *tPtr, WMColor *color); - -void WMSetTextBackgroundPixmap(WMText *tPtr, WMPixmap *pixmap); - -void WMPrependTextStream(WMText *tPtr, char *text); - -void WMAppendTextStream(WMText *tPtr, char *text); - -#define WMClearText(tPtr) WMAppendTextStream \ - ((tPtr), (NULL)) - -/* free the text */ -char* WMGetTextStream(WMText *tPtr); - -/* free the text */ -char* WMGetTextSelectedStream(WMText *tPtr); - -/* destroy the array */ -WMArray* WMGetTextObjects(WMText *tPtr); - -/* destroy the array */ -WMArray* WMGetTextSelectedObjects(WMText *tPtr); - -void WMSetTextSelectionColor(WMText *tPtr, WMColor *color); - -WMColor* WMGetTextSelectionColor(WMText *tPtr); - -void WMSetTextSelectionFont(WMText *tPtr, WMFont *font); - -WMFont* WMGetTextSelectionFont(WMText *tPtr); - -void WMSetTextSelectionUnderlined(WMText *tPtr, int underlined); - -int WMGetTextSelectionUnderlined(WMText *tPtr); - -void WMSetTextAlignment(WMText *tPtr, WMAlignment alignment); - -Bool WMFindInTextStream(WMText *tPtr, char *needle, Bool direction, - Bool caseSensitive); - -Bool WMReplaceTextSelection(WMText *tPtr, char *replacement); - - -/* parser related stuff... use only if implementing a new parser */ - -void* WMCreateTextBlockWithObject(WMText *tPtr, WMWidget *w, char *description, - WMColor *color, unsigned short first, - unsigned short extraInfo); - -void* WMCreateTextBlockWithPixmap(WMText *tPtr, WMPixmap *p, char *description, - WMColor *color, unsigned short first, - unsigned short extraInfo); - -void* WMCreateTextBlockWithText(WMText *tPtr, char *text, WMFont *font, - WMColor *color, unsigned short first, - unsigned short length); - -void WMSetTextBlockProperties(WMText *tPtr, void *vtb, unsigned int first, - unsigned int kanji, unsigned int underlined, - int script, WMRulerMargins *margins); - -/* do NOT free the margins */ -void WMGetTextBlockProperties(WMText *tPtr, void *vtb, unsigned int *first, - unsigned int *kanji, unsigned int *underlined, - int *script, WMRulerMargins *margins); - -int WMGetTextInsertType(WMText *tPtr); - -/*int WMGetTextBlocks(WMText *tPtr); - -void WMSetCurrentTextBlock(WMText *tPtr, int current); - -int WMGetCurrentTextBlock(WMText *tPtr);*/ - -void WMPrependTextBlock(WMText *tPtr, void *vtb); - -void WMAppendTextBlock(WMText *tPtr, void *vtb); - -void* WMRemoveTextBlock(WMText *tPtr); - -void WMDestroyTextBlock(WMText *tPtr, void *vtb); - /* ....................................................................... */ diff --git a/WINGs/wruler.c b/WINGs/wruler.c deleted file mode 100644 index f8d4af03..00000000 --- a/WINGs/wruler.c +++ /dev/null @@ -1,532 +0,0 @@ -/* - * WINGs WMRuler: nifty ruler widget for WINGs :-) - * - * Copyright (c) 1999-2000 Nwanua Elumeze - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "WINGsP.h" -#include "wconfig.h" - -#define MIN_DOC_WIDTH 10 - -typedef struct W_Ruler { - W_Class widgetClass; - W_View *view; - W_View *pview; /* the parent's view (for drawing the line) */ - - WMAction *moveAction; /* what to when while moving */ - WMAction *releaseAction; /* what to do when released */ - void *clientData; - - WMColor *fg; - GC fgGC, bgGC; - WMFont *font; - WMRulerMargins margins; - int offset; - int motion; /* the position of the _moving_ marker(s) */ - int end; /* the last tick on the baseline (restrict markers to it) */ - - Pixmap drawBuffer; - - struct { - unsigned int whichMarker:3; - /* 0, 1, 2, 3, 4, 5, 6 */ - /* none, left, right, first, body, tabstop, first & body */ - - unsigned int buttonPressed:1; - unsigned int redraw:1; - unsigned int RESERVED:27; - } flags; -} Ruler; - -/* Marker for left margin - - |\ - | \ - |__\ - | - | - - */ -static void drawLeftMarker(Ruler * rPtr) -{ - XPoint points[4]; - int xpos = (rPtr->flags.whichMarker == 1 ? rPtr->motion : rPtr->margins.left); - - XDrawLine(rPtr->view->screen->display, rPtr->drawBuffer, rPtr->fgGC, xpos, 8, xpos, 22); - points[0].x = xpos; - points[0].y = 1; - points[1].x = points[0].x + 6; - points[1].y = 8; - points[2].x = points[0].x + 6; - points[2].y = 9; - points[3].x = points[0].x; - points[3].y = 9; - XFillPolygon(rPtr->view->screen->display, rPtr->drawBuffer, rPtr->fgGC, - points, 4, Convex, CoordModeOrigin); -} - -/* Marker for right margin - - /| - / | -/__| - | - | - - */ -static void drawRightMarker(Ruler * rPtr) -{ - XPoint points[4]; - int xpos = (rPtr->flags.whichMarker == 2 ? rPtr->motion : rPtr->margins.right); - - XDrawLine(rPtr->view->screen->display, rPtr->drawBuffer, rPtr->fgGC, xpos, 8, xpos, 22); - points[0].x = xpos + 1; - points[0].y = 0; - points[1].x = points[0].x - 6; - points[1].y = 7; - points[2].x = points[0].x - 6; - points[2].y = 9; - points[3].x = points[0].x; - points[3].y = 9; - XFillPolygon(rPtr->view->screen->display, rPtr->drawBuffer, rPtr->fgGC, - points, 4, Convex, CoordModeOrigin); -} - -/* Marker for first line only - _____ - |___| - | - - */ -static void drawFirstMarker(Ruler * rPtr) -{ - int xpos = ((rPtr->flags.whichMarker == 3 || rPtr->flags.whichMarker == 6) ? - rPtr->motion : rPtr->margins.first); - - XFillRectangle(rPtr->view->screen->display, rPtr->drawBuffer, rPtr->fgGC, xpos - 5, 10, 11, 5); - XDrawLine(rPtr->view->screen->display, rPtr->drawBuffer, rPtr->fgGC, xpos, 12, xpos, 22); -} - -/* Marker for rest of body - _____ - \ / - \./ - */ -static void drawBodyMarker(Ruler * rPtr) -{ - XPoint points[4]; - int xpos = ((rPtr->flags.whichMarker == 4 || rPtr->flags.whichMarker == 6) ? - rPtr->motion : rPtr->margins.body); - - points[0].x = xpos - 5; - points[0].y = 16; - points[1].x = points[0].x + 11; - points[1].y = 16; - points[2].x = points[0].x + 5; - points[2].y = 22; - XFillPolygon(rPtr->view->screen->display, rPtr->drawBuffer, rPtr->fgGC, - points, 3, Convex, CoordModeOrigin); -} - -static void createDrawBuffer(Ruler * rPtr) -{ - if (!rPtr->view->flags.realized) - return; - - if (rPtr->drawBuffer) - XFreePixmap(rPtr->view->screen->display, rPtr->drawBuffer); - - rPtr->drawBuffer = XCreatePixmap(rPtr->view->screen->display, - rPtr->view->window, rPtr->view->size.width, 40, - rPtr->view->screen->depth); - XFillRectangle(rPtr->view->screen->display, rPtr->drawBuffer, - rPtr->bgGC, 0, 0, rPtr->view->size.width, 40); -} - -static void drawRulerOnPixmap(Ruler * rPtr) -{ - int i, j, w, m; - char c[3]; - int marks[9] = { 11, 3, 5, 3, 7, 3, 5, 3 }; - - if (!rPtr->drawBuffer || !rPtr->view->flags.realized) - return; - - XFillRectangle(rPtr->view->screen->display, rPtr->drawBuffer, - rPtr->bgGC, 0, 0, rPtr->view->size.width, 40); - - WMDrawString(rPtr->view->screen, rPtr->drawBuffer, rPtr->fg, - rPtr->font, rPtr->margins.left + 2, 26, _("0 inches"), 10); - - /* marker ticks */ - i = j = m = 0; - w = rPtr->view->size.width - rPtr->margins.left; - while (m < w) { - XDrawLine(rPtr->view->screen->display, rPtr->drawBuffer, - rPtr->fgGC, rPtr->margins.left + m, 23, rPtr->margins.left + m, marks[i % 8] + 23); - if (i != 0 && i % 8 == 0) { - if (j < 10) - snprintf(c, 3, "%d", ++j); - else - snprintf(c, 3, "%2d", ++j); - WMDrawString(rPtr->view->screen, rPtr->drawBuffer, rPtr->fg, - rPtr->font, rPtr->margins.left + 2 + m, 26, c, 2); - } - m = (++i) * 10; - } - - rPtr->end = rPtr->margins.left + m - 10; - if (rPtr->margins.right > rPtr->end) - rPtr->margins.right = rPtr->end; - /* base line */ - XDrawLine(rPtr->view->screen->display, rPtr->drawBuffer, rPtr->fgGC, - rPtr->margins.left, 22, rPtr->margins.left + m - 10, 22); - - drawLeftMarker(rPtr); - drawRightMarker(rPtr); - drawFirstMarker(rPtr); - drawBodyMarker(rPtr); - - rPtr->flags.redraw = False; -} - -static void paintRuler(Ruler * rPtr) -{ - if (!rPtr->drawBuffer || !rPtr->view->flags.realized) - return; - - if (rPtr->flags.redraw) - drawRulerOnPixmap(rPtr); - XCopyArea(rPtr->view->screen->display, rPtr->drawBuffer, - rPtr->view->window, rPtr->bgGC, 0, 0, rPtr->view->size.width, 40, 0, 0); -} - -static Bool verifyMarkerMove(Ruler * rPtr, int x) -{ - if (rPtr->flags.whichMarker < 1 || rPtr->flags.whichMarker > 6) - return False; - - switch (rPtr->flags.whichMarker) { - case 1: - if (x > rPtr->margins.right - 10 || x < rPtr->offset || - rPtr->margins.body + x > rPtr->margins.right - MIN_DOC_WIDTH || - rPtr->margins.first + x > rPtr->margins.right - MIN_DOC_WIDTH) - return False; - break; - - case 2: - if (x < rPtr->margins.first + MIN_DOC_WIDTH || x < rPtr->margins.body + MIN_DOC_WIDTH || x < rPtr->margins.left + MIN_DOC_WIDTH || x > rPtr->end) /*rPtr->view->size.width) */ - return False; - break; - - case 3: - if (x >= rPtr->margins.right - MIN_DOC_WIDTH || x < rPtr->margins.left) - return False; - break; - - case 4: - if (x >= rPtr->margins.right - MIN_DOC_WIDTH || x < rPtr->margins.left) - return False; - break; - - case 6: - if (x >= rPtr->margins.right - MIN_DOC_WIDTH || x < rPtr->margins.left) - return False; - break; - - default: - return False; - } - - rPtr->motion = x; - return True; -} - -static int whichMarker(Ruler * rPtr, int x, int y) -{ - if (x < rPtr->offset || y > 22) - return 0; - - if (rPtr->margins.left - x >= -6 && y <= 9 && (rPtr->margins.left - x <= 0) && y >= 4) { - rPtr->motion = rPtr->margins.left; - return 1; - } - if (rPtr->margins.right - x >= -1 && y <= 11 && rPtr->margins.right - x <= 5 && y >= 4) { - rPtr->motion = rPtr->margins.right; - return 2; - } -#if 0 - /* both first and body? */ - if (rPtr->margins.first - x <= 4 && rPtr->margins.first - x >= -5 - && rPtr->margins.body - x <= 4 && rPtr->margins.body - x >= -5 && y >= 15 && y <= 17) { - rPtr->motion = rPtr->margins.first; - return 6; - } -#endif - - if (rPtr->margins.first - x <= 4 && y <= 15 && rPtr->margins.first - x >= -5 && y >= 10) { - rPtr->motion = rPtr->margins.first; - return 3; - } - if (rPtr->margins.body - x <= 4 && y <= 21 && rPtr->margins.body - x >= -5 && y >= 17) { - rPtr->motion = rPtr->margins.body; - return 4; - } - /* do tabs (5) */ - - return 0; -} - -static void rulerDidResize(W_ViewDelegate * self, WMView * view) -{ - Ruler *rPtr = (Ruler *) view->self; - - createDrawBuffer(rPtr); - rPtr->flags.redraw = True; - paintRuler(rPtr); - -} - -static void handleEvents(XEvent * event, void *data) -{ - Ruler *rPtr = (Ruler *) data; - - switch (event->type) { - case Expose: - rulerDidResize(rPtr->view->delegate, rPtr->view); - break; - - case MotionNotify: - if (rPtr->flags.buttonPressed && (event->xmotion.state & Button1Mask)) { - if (verifyMarkerMove(rPtr, event->xmotion.x)) { - GC gc = WMColorGC(WMDarkGrayColor(rPtr->view->screen)); - - if (rPtr->moveAction) - (rPtr->moveAction) (rPtr, rPtr->clientData); - rPtr->flags.redraw = True; - paintRuler(rPtr); - XSetLineAttributes(rPtr->view->screen->display, gc, 1, - LineSolid, CapNotLast, JoinMiter); - XDrawLine(rPtr->pview->screen->display, - rPtr->pview->window, - gc, rPtr->motion + 1, 40, - rPtr->motion + 1, rPtr->pview->size.height - 5); - } - } - break; - - case ButtonPress: - if (event->xbutton.button != Button1) - return; - rPtr->flags.buttonPressed = True; - rPtr->flags.whichMarker = whichMarker(rPtr, event->xmotion.x, event->xmotion.y); - break; - - case ButtonRelease: - if (event->xbutton.button != Button1) - return; - rPtr->flags.buttonPressed = False; - switch (rPtr->flags.whichMarker) { - case 1:{ - int change = rPtr->margins.left - rPtr->motion; - - rPtr->margins.first -= change; - rPtr->margins.body -= change; - rPtr->margins.left = rPtr->motion; - rPtr->flags.redraw = True; - paintRuler(rPtr); - break; - } - case 2: - rPtr->margins.right = rPtr->motion; - break; - case 3: - rPtr->margins.first = rPtr->motion; - break; - case 4: - rPtr->margins.body = rPtr->motion; - break; - case 6: - rPtr->margins.first = rPtr->margins.body = rPtr->motion; - break; - } - if (rPtr->releaseAction) - (rPtr->releaseAction) (rPtr, rPtr->clientData); - break; - } -} - -W_ViewDelegate _RulerViewDelegate = { - NULL, - NULL, - rulerDidResize, - NULL, - NULL -}; - -WMRuler *WMCreateRuler(WMWidget * parent) -{ - Ruler *rPtr = wmalloc(sizeof(Ruler)); - unsigned int w = WMWidgetWidth(parent); - - rPtr->widgetClass = WC_Ruler; - - rPtr->view = W_CreateView(W_VIEW(parent)); - - if (!rPtr->view) { - wfree(rPtr); - return NULL; - } - - rPtr->view->self = rPtr; - - rPtr->drawBuffer = (Pixmap) NULL; - - W_ResizeView(rPtr->view, w, 40); - - WMCreateEventHandler(rPtr->view, ExposureMask | StructureNotifyMask - | EnterWindowMask | LeaveWindowMask | FocusChangeMask - | ButtonReleaseMask | ButtonPressMask | KeyReleaseMask - | KeyPressMask | Button1MotionMask, handleEvents, rPtr); - - rPtr->view->delegate = &_RulerViewDelegate; - - rPtr->fg = WMBlackColor(rPtr->view->screen); - rPtr->fgGC = WMColorGC(rPtr->fg); - rPtr->bgGC = WMColorGC(WMGrayColor(rPtr->view->screen)); - rPtr->font = WMSystemFontOfSize(rPtr->view->screen, 8); - - rPtr->offset = 22; - rPtr->margins.left = 22; - rPtr->margins.body = 22; - rPtr->margins.first = 42; - rPtr->margins.right = (w < 502 ? w : 502); - rPtr->margins.tabs = NULL; - - rPtr->flags.whichMarker = 0; /* none */ - rPtr->flags.buttonPressed = False; - rPtr->flags.redraw = True; - - rPtr->moveAction = NULL; - rPtr->releaseAction = NULL; - - rPtr->pview = W_VIEW(parent); - - return rPtr; -} - -void WMSetRulerMargins(WMRuler * rPtr, WMRulerMargins margins) -{ - if (!rPtr) - return; - rPtr->margins.left = margins.left + rPtr->offset; - rPtr->margins.right = margins.right + rPtr->offset; - rPtr->margins.first = margins.first + rPtr->offset; - rPtr->margins.body = margins.body + rPtr->offset; - rPtr->margins.tabs = margins.tabs; /*for loop */ - rPtr->flags.redraw = True; - paintRuler(rPtr); - -} - -WMRulerMargins *WMGetRulerMargins(WMRuler * rPtr) -{ - WMRulerMargins *margins = wmalloc(sizeof(WMRulerMargins)); - - if (!rPtr) { - margins->first = margins->body = margins->left = 0; - margins->right = 100; - return margins; - } - - margins->left = rPtr->margins.left - rPtr->offset; - margins->right = rPtr->margins.right - rPtr->offset; - margins->first = rPtr->margins.first - rPtr->offset; - margins->body = rPtr->margins.body - rPtr->offset; - /*for */ - margins->tabs = rPtr->margins.tabs; - - return margins; -} - -Bool WMIsMarginEqualToMargin(WMRulerMargins * aMargin, WMRulerMargins * anotherMargin) -{ - if (aMargin == anotherMargin) - return True; - else if (!aMargin || !anotherMargin) - return False; - if (aMargin->left != anotherMargin->left) - return False; - if (aMargin->first != anotherMargin->first) - return False; - if (aMargin->body != anotherMargin->body) - return False; - if (aMargin->right != anotherMargin->right) - return False; - - return True; -} - -void WMSetRulerOffset(WMRuler * rPtr, int pixels) -{ - if (!rPtr || pixels < 0 || pixels + MIN_DOC_WIDTH >= rPtr->view->size.width) - return; - rPtr->offset = pixels; - /*rulerDidResize(rPtr, rPtr->view); */ -} - -int WMGetRulerOffset(WMRuler * rPtr) -{ - if (!rPtr) - return 0; /* what value should return if no ruler? -1 or 0? */ - return rPtr->offset; -} - -void WMSetRulerReleaseAction(WMRuler * rPtr, WMAction * action, void *clientData) -{ - if (!rPtr) - return; - - rPtr->releaseAction = action; - rPtr->clientData = clientData; -} - -void WMSetRulerMoveAction(WMRuler * rPtr, WMAction * action, void *clientData) -{ - if (!rPtr) - return; - - rPtr->moveAction = action; - rPtr->clientData = clientData; -} - -/* _which_ one was released */ -int WMGetReleasedRulerMargin(WMRuler * rPtr) -{ - if (!rPtr) - return 0; - return rPtr->flags.whichMarker; -} - -/* _which_ one is being grabbed */ -int WMGetGrabbedRulerMargin(WMRuler * rPtr) -{ - if (!rPtr) - return 0; - return rPtr->flags.whichMarker; -} diff --git a/WINGs/wtext.c b/WINGs/wtext.c deleted file mode 100644 index ece4b398..00000000 --- a/WINGs/wtext.c +++ /dev/null @@ -1,3958 +0,0 @@ - -/* WINGs WMText: multi-line/font/color/graphic text widget, by Nwanua. */ - -#include "WINGsP.h" -#include -#include -#include - -#define DO_BLINK 0 - -/* TODO: - * - verify what happens with XK_return in insertTextInt... - * - selection code... selects can be funny if it crosses over. use rect? - * - also inspect behaviour for WACenter and WARight - * - what if a widget grabs the click... howto say: "pressed me"? - * note that WMCreateEventHandler takes one data, but need widget & tPtr - * - FIX: graphix blocks MUST be skipped if monoFont even though they exist! - * - check if support for Horizontal Scroll is complete - * - Tabs now are simply replaced by 4 spaces... - * - redo blink code to reduce paint event... use pixmap buffer... - * - add paragraph support (full) and '\n' code in getStream.. -*/ - -/* a Section is a section of a TextBlock that describes what parts - of a TextBlock has been laid out on which "line"... - o this greatly aids redraw, scroll and selection. - o this is created during layoutLine, but may be later modified. - o there may be many Sections per TextBlock, hence the array */ -typedef struct { - unsigned int x, y; /* where to draw it from */ - unsigned short w, h; /* its width and height */ - unsigned short begin; /* where the layout begins */ - unsigned short end; /* where it ends */ - unsigned short max_d; /* a quick hack for layOut if(laidOut) */ - unsigned short last:1; /* is it the last section on a "line"? */ - unsigned int _y:31; /* the "line" it and other textblocks are on */ -} Section; - -/* a TextBlock is a node in a doubly-linked list of TextBlocks containing: - o text for the block, color and font - o or a pointer to the pixmap - o OR a pointer to the widget and the (text) description for its graphic -*/ - -typedef struct _TextBlock { - struct _TextBlock *next; /* next text block in linked list */ - struct _TextBlock *prior; /* prior text block in linked list */ - - char *text; /* pointer to text (could be kanji) */ - /* or to the object's description */ - union { - WMFont *font; /* the font */ - WMWidget *widget; /* the embedded widget */ - WMPixmap *pixmap; /* the pixmap */ - } d; /* description */ - - unsigned short used; /* number of chars in this block */ - unsigned short allocated; /* size of allocation (in chars) */ - WMColor *color; /* the color */ - - Section *sections; /* the region for layouts (a growable array) */ - /* an _array_! of size _nsections_ */ - - unsigned short s_begin; /* where the selection begins */ - unsigned short s_end; /* where it ends */ - - unsigned int first:1; /* first TextBlock in paragraph */ - unsigned int blank:1; /* ie. blank paragraph */ - unsigned int kanji:1; /* is of 16-bit characters or not */ - unsigned int graphic:1; /* graphic or text: text=0 */ - unsigned int object:1; /* embedded object or pixmap */ - unsigned int underlined:1; /* underlined or not */ - unsigned int selected:1; /* selected or not */ - unsigned int nsections:8; /* over how many "lines" a TextBlock wraps */ - int script:8; /* script in points: negative for subscript */ - unsigned int marginN:8; /* which of the margins in the tPtr to use */ - unsigned int nClicks:2; /* single, double, triple clicks */ - unsigned int RESERVED:7; -} TextBlock; - -/* I'm lazy: visible.h vs. visible.size.height :-) */ -typedef struct { - int y, x, h, w; -} myRect; - -typedef struct W_Text { - W_Class widgetClass; /* the class number of this widget */ - W_View *view; /* the view referring to this instance */ - - WMRuler *ruler; /* the ruler widget to manipulate paragraphs */ - - WMScroller *vS; /* the vertical scroller */ - unsigned int vpos; /* the current vertical position */ - unsigned int prevVpos; /* the previous vertical position */ - - WMScroller *hS; /* the horizontal scroller */ - unsigned int hpos; /* the current horizontal position */ - unsigned int prevHpos; /* the previous horizontal position */ - - WMFont *dFont; /* the default font */ - WMColor *dColor; /* the default color */ - WMPixmap *dBulletPix; /* the default pixmap for bullets */ - - WMColor *fgColor; /* The current foreground color */ - WMColor *bgColor; /* The background color */ - - GC stippledGC; /* the GC to overlay selected graphics with */ - Pixmap db; /* the buffer on which to draw */ - WMPixmap *bgPixmap; /* the background pixmap */ - - myRect visible; /* the actual rectangle that can be drawn into */ - myRect cursor; /* the position and (height) of cursor */ - myRect sel; /* the selection rectangle */ - - WMPoint clicked; /* where in the _document_ was clicked */ - - unsigned short tpos; /* the position in the currentTextBlock */ - unsigned short docWidth; /* the width of the entire document */ - unsigned int docHeight; /* the height of the entire document */ - - TextBlock *firstTextBlock; - TextBlock *lastTextBlock; - TextBlock *currentTextBlock; - - WMArray *gfxItems; /* a nice array of graphic items */ - -#if DO_BLINK - WMHandlerID timerID; /* for nice twinky-winky */ -#endif - - WMAction *parser; - WMAction *writer; - WMTextDelegate *delegate; - Time lastClickTime; - - WMRulerMargins *margins; /* an array of margins */ - - unsigned int nMargins:7; /* the total number of margins in use */ - struct { - unsigned int monoFont:1; /* whether to ignore formats and graphic */ - unsigned int focused:1; /* whether this instance has input focus */ - unsigned int editable:1; /* "silly user, you can't edit me" */ - unsigned int ownsSelection:1; /* "I ownz the current selection!" */ - unsigned int pointerGrabbed:1; /* "heh, gib me pointer" */ - unsigned int extendSelection:1; /* shift-drag to select more regions */ - - unsigned int rulerShown:1; /* whether the ruler is shown or not */ - unsigned int frozen:1; /* whether screen updates are to be made */ - unsigned int cursorShown:1; /* whether to show the cursor */ - unsigned int acceptsGraphic:1; /* accept graphic when dropped */ - unsigned int horizOnDemand:1; /* if a large image should appear */ - unsigned int needsLayOut:1; /* in case of Append/Deletes */ - unsigned int ignoreNewLine:1; /* turn it into a ' ' in streams > 1 */ - unsigned int indentNewLine:1; /* add " " for a newline typed */ - unsigned int laidOut:1; /* have the TextBlocks all been laid out */ - unsigned int waitingForSelection:1; /* I don't wanna wait in vain... */ - unsigned int prepend:1; /* prepend=1, append=0 (for parsers) */ - WMAlignment alignment:2; /* the alignment for text */ - WMReliefType relief:3; /* the relief to display with */ - unsigned int isOverGraphic:2; /* the mouse is over a graphic */ - unsigned int first:1; /* for plain text parsing, newline? */ - /* unsigned int RESERVED:1; */ - } flags; - - WMArray *xdndSourceTypes; - WMArray *xdndDestinationTypes; -} Text; - -#define NOTIFY(T,C,N,A) {\ - WMNotification *notif = WMCreateNotification(N,T,A);\ - if ((T)->delegate && (T)->delegate->C)\ - (*(T)->delegate->C)((T)->delegate,notif);\ - WMPostNotification(notif);\ - WMReleaseNotification(notif);} - -#define TYPETEXT 0 - -#if 0 -/* just to print blocks of text not terminated by \0 */ -static void output(char *ptr, int len) -{ - char *s; - - s = wmalloc(len + 1); - memcpy(s, ptr, len); - s[len] = 0; - /* printf(" s is [%s] (%d)\n", s, strlen(s)); */ - printf("[%s]\n", s); - wfree(s); -} -#endif - -#if DO_BLINK -#define CURSOR_BLINK_ON_DELAY 600 -#define CURSOR_BLINK_OFF_DELAY 400 -#endif - -#define STIPPLE_WIDTH 8 -#define STIPPLE_HEIGHT 8 -static char STIPPLE_BITS[] = { - 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa -}; - -static char *default_bullet[] = { - "6 6 4 1", - " c None s None", - ". c black", - "X c white", - "o c #808080", - " ... ", - ".XX.. ", - ".XX..o", - ".....o", - " ...oo", - " ooo " -}; - -static void handleEvents(XEvent * event, void *data); -static void layOutDocument(Text * tPtr); -static void updateScrollers(Text * tPtr); - -static int getMarginNumber(Text * tPtr, WMRulerMargins * margins) -{ - unsigned int i = 0; - - for (i = 0; i < tPtr->nMargins; i++) { - - if (WMIsMarginEqualToMargin(&tPtr->margins[i], margins)) - return i; - } - - return -1; -} - -static int newMargin(Text * tPtr, WMRulerMargins * margins) -{ - int n; - - if (!margins) { - tPtr->margins[0].retainCount++; - return 0; - } - - n = getMarginNumber(tPtr, margins); - - if (n == -1) { - - if (tPtr->nMargins >= 127) { - n = tPtr->nMargins - 1; - return n; - } - - tPtr->margins = wrealloc(tPtr->margins, (++tPtr->nMargins) * sizeof(WMRulerMargins)); - - n = tPtr->nMargins - 1; - tPtr->margins[n].left = margins->left; - tPtr->margins[n].first = margins->first; - tPtr->margins[n].body = margins->body; - tPtr->margins[n].right = margins->right; - /* for each tab... */ - tPtr->margins[n].retainCount = 1; - } else { - tPtr->margins[n].retainCount++; - } - - return n; -} - -static Bool sectionWasSelected(Text * tPtr, TextBlock * tb, XRectangle * rect, int s) -{ - unsigned short i, w, lw, selected = False, extend = False; - myRect sel; - - /* if selection rectangle completely encloses the section */ - if ((tb->sections[s]._y >= tPtr->visible.y + tPtr->sel.y) - && (tb->sections[s]._y + tb->sections[s].h <= tPtr->visible.y + tPtr->sel.y + tPtr->sel.h)) { - sel.x = 0; - sel.w = tPtr->visible.w; - selected = extend = True; - - /* or if it starts on a line and then goes further down */ - } else if ((tb->sections[s]._y <= tPtr->visible.y + tPtr->sel.y) - && (tb->sections[s]._y + tb->sections[s].h <= tPtr->visible.y + tPtr->sel.y + tPtr->sel.h) - && (tb->sections[s]._y + tb->sections[s].h >= tPtr->visible.y + tPtr->sel.y)) { - sel.x = WMAX(tPtr->sel.x, tPtr->clicked.x); - sel.w = tPtr->visible.w; - selected = extend = True; - - /* or if it begins before a line, but ends on it */ - } else if ((tb->sections[s]._y >= tPtr->visible.y + tPtr->sel.y) - && (tb->sections[s]._y + tb->sections[s].h >= tPtr->visible.y + tPtr->sel.y + tPtr->sel.h) - && (tb->sections[s]._y <= tPtr->visible.y + tPtr->sel.y + tPtr->sel.h)) { - - if (1 || tPtr->sel.x + tPtr->sel.w > tPtr->clicked.x) - sel.w = tPtr->sel.x + tPtr->sel.w; - else - sel.w = tPtr->sel.x; - - sel.x = 0; - selected = True; - - /* or if the selection rectangle lies entirely within a line */ - } else if ((tb->sections[s]._y <= tPtr->visible.y + tPtr->sel.y) - && (tPtr->sel.w >= 2) - && (tb->sections[s]._y + tb->sections[s].h >= tPtr->visible.y + tPtr->sel.y + tPtr->sel.h)) { - sel.x = tPtr->sel.x; - sel.w = tPtr->sel.w; - selected = True; - } - - if (selected) { - selected = False; - - /* if not within (modified) selection rectangle */ - if (tb->sections[s].x > sel.x + sel.w || tb->sections[s].x + tb->sections[s].w < sel.x) - return False; - - if (tb->graphic) { - if (tb->sections[s].x + tb->sections[s].w <= sel.x + sel.w && tb->sections[s].x >= sel.x) { - rect->width = tb->sections[s].w; - rect->x = tb->sections[s].x; - selected = True; - } - } else { - - i = tb->sections[s].begin; - lw = 0; - - if (0 && tb->sections[s].x >= sel.x) { - tb->s_begin = tb->sections[s].begin; - goto _selEnd; - } - - while (++i <= tb->sections[s].end) { - - w = WMWidthOfString(tb->d.font, &(tb->text[i - 1]), 1); - lw += w; - - if (lw + tb->sections[s].x >= sel.x || i == tb->sections[s].end) { - lw -= w; - i--; - tb->s_begin = (tb->selected ? WMIN(tb->s_begin, i) : i); - break; - } - } - - if (i > tb->sections[s].end) { - printf("WasSelected: (i > tb->sections[s].end) \n"); - return False; - } - - _selEnd: rect->x = tb->sections[s].x + lw; - lw = 0; - while (++i <= tb->sections[s].end) { - - w = WMWidthOfString(tb->d.font, &(tb->text[i - 1]), 1); - lw += w; - - if (lw + rect->x >= sel.x + sel.w || i == tb->sections[s].end) { - - if (i != tb->sections[s].end) { - lw -= w; - i--; - } - - rect->width = lw; - if (tb->sections[s].last && sel.x + sel.w - >= tb->sections[s].x + tb->sections[s].w && extend) { - rect->width += (tPtr->visible.w - rect->x - lw); - } - - tb->s_end = (tb->selected ? WMAX(tb->s_end, i) : i); - selected = True; - break; - } - } - } - } - - if (selected) { - rect->y = tb->sections[s]._y - tPtr->vpos; - rect->height = tb->sections[s].h; - if (tb->graphic) { - printf("DEBUG: graphic s%d h%d\n", s, tb->sections[s].h); - } - } - return selected; - -} - -static void setSelectionProperty(WMText * tPtr, WMFont * font, WMColor * color, int underlined) -{ - TextBlock *tb; - int isFont = False; - - tb = tPtr->firstTextBlock; - if (!tb || !tPtr->flags.ownsSelection) - return; - - if (font && (!color || underlined == -1)) - isFont = True; - - while (tb) { - if (tPtr->flags.monoFont || tb->selected) { - - if (tPtr->flags.monoFont || (tb->s_end - tb->s_begin == tb->used) - || tb->graphic) { - - if (isFont) { - if (!tb->graphic) { - WMReleaseFont(tb->d.font); - tb->d.font = WMRetainFont(font); - } - } else if (underlined != -1) { - tb->underlined = underlined; - } else { - WMReleaseColor(tb->color); - tb->color = WMRetainColor(color); - } - - } else if (tb->s_end <= tb->used && tb->s_begin < tb->s_end) { - - TextBlock *midtb, *otb = tb; - - if (underlined != -1) { - midtb = (TextBlock *) WMCreateTextBlockWithText(tPtr, - &(tb->text[tb->s_begin]), - tb->d.font, tb->color, - False, - (tb->s_end - tb->s_begin)); - } else { - midtb = (TextBlock *) WMCreateTextBlockWithText(tPtr, - &(tb->text[tb->s_begin]), - (isFont ? font : tb->d. - font), - (isFont ? tb-> - color : color), False, - (tb->s_end - tb->s_begin)); - } - - if (midtb) { - if (underlined != -1) { - midtb->underlined = underlined; - } else { - midtb->underlined = otb->underlined; - } - - midtb->selected = !True; - midtb->s_begin = 0; - midtb->s_end = midtb->used; - tPtr->currentTextBlock = tb; - WMAppendTextBlock(tPtr, midtb); - tb = tPtr->currentTextBlock; - } - - if (otb->used - otb->s_end > 0) { - TextBlock *ntb; - ntb = (TextBlock *) - WMCreateTextBlockWithText(tPtr, - &(otb->text[otb->s_end]), otb->d.font, - otb->color, False, otb->used - otb->s_end); - - if (ntb) { - ntb->underlined = otb->underlined; - ntb->selected = False; - WMAppendTextBlock(tPtr, ntb); - tb = tPtr->currentTextBlock; - } - } - - if (midtb) { - tPtr->currentTextBlock = midtb; - } - - otb->selected = False; - otb->used = otb->s_begin; - } - } - - tb = tb->next; - } - - tPtr->flags.needsLayOut = True; - WMThawText(tPtr); - - /* in case the size changed... */ - if (isFont && tPtr->currentTextBlock) { - TextBlock *tb = tPtr->currentTextBlock; - - printf("%d %d %d\n", tPtr->sel.y, tPtr->sel.h, tPtr->sel.w); - tPtr->sel.y = 3 + tb->sections[0]._y; - tPtr->sel.h = tb->sections[tb->nsections - 1]._y - tb->sections[0]._y; - tPtr->sel.w = tb->sections[tb->nsections - 1].w; - if (tb->sections[tb->nsections - 1]._y != tb->sections[0]._y) { - tPtr->sel.x = 0; - } - printf("%d %d %d\n\n\n", tPtr->sel.y, tPtr->sel.h, tPtr->sel.w); - } - -} - -static Bool removeSelection(Text * tPtr) -{ - TextBlock *tb = NULL; - Bool first = False; - - if (!(tb = tPtr->firstTextBlock)) - return False; - - while (tb) { - if (tb->selected) { - if (!first && !tb->graphic) { - WMReleaseFont(tPtr->dFont); - tPtr->dFont = WMRetainFont(tb->d.font); - first = True; - } - - if ((tb->s_end - tb->s_begin == tb->used) || tb->graphic) { - tPtr->currentTextBlock = tb; - if (tb->next) { - tPtr->tpos = 0; - } else if (tb->prior) { - if (tb->prior->graphic) - tPtr->tpos = 1; - else - tPtr->tpos = tb->prior->used; - } else - tPtr->tpos = 0; - - WMDestroyTextBlock(tPtr, WMRemoveTextBlock(tPtr)); - tb = tPtr->currentTextBlock; - continue; - - } else if (tb->s_end <= tb->used) { - memmove(&(tb->text[tb->s_begin]), &(tb->text[tb->s_end]), tb->used - tb->s_end); - tb->used -= (tb->s_end - tb->s_begin); - tb->selected = False; - tPtr->tpos = tb->s_begin; - } - - } - - tb = tb->next; - } - return True; -} - -static TextBlock *getFirstNonGraphicBlockFor(TextBlock * tb, short dir) -{ - TextBlock *hold = tb; - - if (!tb) - return NULL; - - while (tb) { - if (!tb->graphic) - break; - tb = (dir ? tb->next : tb->prior); - } - - if (!tb) { - tb = hold; - while (tb) { - if (!tb->graphic) - break; - tb = (dir ? tb->prior : tb->next); - } - } - - if (!tb) - return NULL; - - return tb; -} - -static Bool updateStartForCurrentTextBlock(Text * tPtr, int x, int y, int *dir, TextBlock * tb) -{ - if (tPtr->flags.monoFont && tb->graphic) { - tb = getFirstNonGraphicBlockFor(tb, *dir); - if (!tb) - return 0; - - if (tb->graphic) { - tPtr->currentTextBlock = (dir ? tPtr->lastTextBlock : tPtr->firstTextBlock); - tPtr->tpos = 0; - return 0; - } - } - - if (!tb->sections) { - layOutDocument(tPtr); - return 0; - } - - *dir = !(y <= tb->sections[0].y); - if (*dir) { - if ((y <= tb->sections[0]._y + tb->sections[0].h) - && (y >= tb->sections[0]._y)) { - /* if it's on the same line */ - if (x < tb->sections[0].x) - *dir = 0; - } - } else { - if ((y <= tb->sections[tb->nsections - 1]._y + tb->sections[tb->nsections - 1].h) - && (y >= tb->sections[tb->nsections - 1]._y)) { - /* if it's on the same line */ - if (x > tb->sections[tb->nsections - 1].x) - *dir = 1; - } - } - - return 1; -} - -static void paintText(Text * tPtr) -{ - TextBlock *tb; - WMFont *font; - char *text; - int len, y, c, s, done = False, prev_y = -23, dir /* 1 = down */ ; - WMScreen *scr = tPtr->view->screen; - Display *dpy = tPtr->view->screen->display; - Window win = tPtr->view->window; - WMColor *color; - - if (!tPtr->view->flags.realized || !tPtr->db || tPtr->flags.frozen) - return; - - XFillRectangle(dpy, tPtr->db, WMColorGC(tPtr->bgColor), 0, 0, tPtr->visible.w, tPtr->visible.h); - - if (tPtr->bgPixmap) { - WMDrawPixmap(tPtr->bgPixmap, tPtr->db, - (tPtr->visible.w - tPtr->visible.x - tPtr->bgPixmap->width) / 2, - (tPtr->visible.h - tPtr->visible.y - tPtr->bgPixmap->height) / 2); - } - - if (!(tb = tPtr->currentTextBlock)) { - if (!(tb = tPtr->firstTextBlock)) { - goto _copy_area; - } - } - - done = False; - - /* first, which direction? Don't waste time looking all over, - since the parts to be drawn will most likely be near what - was previously drawn */ - if (!updateStartForCurrentTextBlock(tPtr, 0, tPtr->vpos, &dir, tb)) - goto _copy_area; - - while (tb) { - - if (tb->graphic && tPtr->flags.monoFont) - goto _getSibling; - - if (dir) { - if (tPtr->vpos <= tb->sections[tb->nsections - 1]._y + tb->sections[tb->nsections - 1].h) - break; - } else { - if (tPtr->vpos >= tb->sections[tb->nsections - 1]._y + tb->sections[tb->nsections - 1].h) - break; - } - - _getSibling: - if (dir) { - if (tb->next) - tb = tb->next; - else - break; - } else { - if (tb->prior) - tb = tb->prior; - else - break; - } - } - - /* first, place all text that can be viewed */ - while (!done && tb) { - if (tb->graphic) { - tb = tb->next; - continue; - } - - tb->selected = False; - - for (s = 0; s < tb->nsections && !done; s++) { - - if (tb->sections[s]._y > tPtr->vpos + tPtr->visible.h) { - done = True; - break; - } - - if (tb->sections[s].y + tb->sections[s].h < tPtr->vpos) - continue; - - if (tPtr->flags.monoFont) { - font = tPtr->dFont; - color = tPtr->fgColor; - } else { - font = tb->d.font; - color = tb->color; - } - - if (tPtr->flags.ownsSelection) { - XRectangle rect; - - if (sectionWasSelected(tPtr, tb, &rect, s)) { - tb->selected = True; - XFillRectangle(dpy, tPtr->db, WMColorGC(scr->gray), - rect.x, rect.y, rect.width, rect.height); - } - } - - prev_y = tb->sections[s]._y; - - len = tb->sections[s].end - tb->sections[s].begin; - text = &(tb->text[tb->sections[s].begin]); - y = tb->sections[s].y - tPtr->vpos; - WMDrawString(scr, tPtr->db, color, font, tb->sections[s].x - tPtr->hpos, y, text, len); - - if (!tPtr->flags.monoFont && tb->underlined) { - XDrawLine(dpy, tPtr->db, WMColorGC(color), - tb->sections[s].x - tPtr->hpos, - y + font->y + 1, - tb->sections[s].x + tb->sections[s].w - tPtr->hpos, y + font->y + 1); - } - } - tb = (!done ? tb->next : NULL); - } - - /* now , show all graphic items that can be viewed */ - c = WMGetArrayItemCount(tPtr->gfxItems); - if (c > 0 && !tPtr->flags.monoFont) { - int j, h; - - for (j = 0; j < c; j++) { - tb = (TextBlock *) WMGetFromArray(tPtr->gfxItems, j); - - /* if it's not viewable, and mapped, unmap it */ - if (tb->sections[0]._y + tb->sections[0].h <= tPtr->vpos - || tb->sections[0]._y >= tPtr->vpos + tPtr->visible.h) { - - if (tb->object) { - if ((W_VIEW(tb->d.widget))->flags.mapped) { - WMUnmapWidget(tb->d.widget); - } - } - } else { - /* if it's viewable, and not mapped, map it */ - if (tb->object) { - W_View *view = W_VIEW(tb->d.widget); - - if (!view->flags.realized) - WMRealizeWidget(tb->d.widget); - if (!view->flags.mapped) { - XMapWindow(view->screen->display, view->window); - XFlush(view->screen->display); - view->flags.mapped = 1; - } - } - - if (tb->object) { - WMMoveWidget(tb->d.widget, - tb->sections[0].x + tPtr->visible.x - tPtr->hpos, - tb->sections[0].y + tPtr->visible.y - tPtr->vpos); - h = WMWidgetHeight(tb->d.widget) + 1; - - } else { - WMDrawPixmap(tb->d.pixmap, tPtr->db, - tb->sections[0].x - tPtr->hpos, - tb->sections[0].y - tPtr->vpos); - h = tb->d.pixmap->height + 1; - - } - - if (tPtr->flags.ownsSelection) { - XRectangle rect; - - if (sectionWasSelected(tPtr, tb, &rect, 0)) { - Drawable d = (0 && tb->object ? - (WMWidgetView(tb->d.widget))->window : tPtr->db); - - tb->selected = True; - XFillRectangle(dpy, d, tPtr->stippledGC, - /*XFillRectangle(dpy, tPtr->db, tPtr->stippledGC, */ - rect.x, rect.y, rect.width, rect.height); - } - } - - if (!tPtr->flags.monoFont && tb->underlined) { - XDrawLine(dpy, tPtr->db, WMColorGC(tb->color), - tb->sections[0].x - tPtr->hpos, - tb->sections[0].y + h - tPtr->vpos, - tb->sections[0].x + tb->sections[0].w - tPtr->hpos, - tb->sections[0].y + h - tPtr->vpos); - } - } - } - } - - _copy_area: - if (tPtr->flags.editable && tPtr->flags.cursorShown && tPtr->cursor.x != -23 && tPtr->flags.focused) { - int y = tPtr->cursor.y - tPtr->vpos; - XDrawLine(dpy, tPtr->db, WMColorGC(tPtr->fgColor), - tPtr->cursor.x, y, tPtr->cursor.x, y + tPtr->cursor.h); - } - - XCopyArea(dpy, tPtr->db, win, WMColorGC(tPtr->bgColor), 0, 0, - tPtr->visible.w, tPtr->visible.h, tPtr->visible.x, tPtr->visible.y); - - W_DrawRelief(scr, win, 0, 0, tPtr->view->size.width, tPtr->view->size.height, tPtr->flags.relief); - - if (tPtr->ruler && tPtr->flags.rulerShown) - XDrawLine(dpy, win, WMColorGC(tPtr->fgColor), 2, 42, tPtr->view->size.width - 4, 42); - -} - -static void mouseOverObject(Text * tPtr, int x, int y) -{ - TextBlock *tb; - Bool result = False; - - x -= tPtr->visible.x; - x += tPtr->hpos; - y -= tPtr->visible.y; - y += tPtr->vpos; - - if (tPtr->flags.ownsSelection) { - if (tPtr->sel.x <= x - && tPtr->sel.y <= y && tPtr->sel.x + tPtr->sel.w >= x && tPtr->sel.y + tPtr->sel.h >= y) { - tPtr->flags.isOverGraphic = 1; - result = True; - } - } - - if (!result) { - int j, c = WMGetArrayItemCount(tPtr->gfxItems); - - if (c < 1) - tPtr->flags.isOverGraphic = 0; - - for (j = 0; j < c; j++) { - tb = (TextBlock *) WMGetFromArray(tPtr->gfxItems, j); - - if (!tb || !tb->sections) { - tPtr->flags.isOverGraphic = 0; - return; - } - - if (!tb->object) { - if (tb->sections[0].x <= x - && tb->sections[0].y <= y - && tb->sections[0].x + tb->sections[0].w >= x - && tb->sections[0].y + tb->d.pixmap->height >= y) { - tPtr->flags.isOverGraphic = 3; - result = True; - break; - } - } - } - - } - - if (!result) - tPtr->flags.isOverGraphic = 0; - - tPtr->view->attribs.cursor = (result ? tPtr->view->screen->defaultCursor : tPtr->view->screen->textCursor); - { - XSetWindowAttributes attribs; - attribs.cursor = tPtr->view->attribs.cursor; - XChangeWindowAttributes(tPtr->view->screen->display, tPtr->view->window, CWCursor, &attribs); - } -} - -#if DO_BLINK - -static void blinkCursor(void *data) -{ - Text *tPtr = (Text *) data; - - if (tPtr->flags.cursorShown) { - tPtr->timerID = WMAddTimerHandler(CURSOR_BLINK_OFF_DELAY, blinkCursor, data); - } else { - tPtr->timerID = WMAddTimerHandler(CURSOR_BLINK_ON_DELAY, blinkCursor, data); - } - paintText(tPtr); - tPtr->flags.cursorShown = !tPtr->flags.cursorShown; -} -#endif - -static void updateCursorPosition(Text * tPtr) -{ - TextBlock *tb = NULL; - int x, y, h, s; - - if (tPtr->flags.needsLayOut) - layOutDocument(tPtr); - - if (!(tb = tPtr->currentTextBlock)) { - if (!(tb = tPtr->firstTextBlock)) { - WMFont *font = tPtr->dFont; - tPtr->tpos = 0; - tPtr->cursor.h = font->height + abs(font->height - font->y); - - tPtr->cursor.y = 2; - tPtr->cursor.x = 2; - return; - } - } - - if (tb->blank) { - tPtr->tpos = 0; - y = tb->sections[0].y; - h = tb->sections[0].h; - x = tb->sections[0].x; - - } else if (tb->graphic) { - y = tb->sections[0].y; - h = tb->sections[0].h; - x = tb->sections[0].x; - if (tPtr->tpos == 1) - x += tb->sections[0].w; - - } else { - if (tPtr->tpos > tb->used) - tPtr->tpos = tb->used; - - for (s = 0; s < tb->nsections - 1; s++) { - - if (tPtr->tpos >= tb->sections[s].begin && tPtr->tpos <= tb->sections[s].end) - break; - } - - y = tb->sections[s]._y; - h = tb->sections[s].h; - x = tb->sections[s].x + WMWidthOfString((tPtr->flags.monoFont ? tPtr->dFont : tb->d.font), - &tb->text[tb->sections[s].begin], - tPtr->tpos - tb->sections[s].begin); - } - - tPtr->cursor.y = y; - tPtr->cursor.h = h; - tPtr->cursor.x = x; - - /* scroll the bars if the cursor is not visible */ - if (tPtr->flags.editable && tPtr->cursor.x != -23) { - if (tPtr->cursor.y + tPtr->cursor.h > tPtr->vpos + tPtr->visible.y + tPtr->visible.h) { - tPtr->vpos += - (tPtr->cursor.y + tPtr->cursor.h + 10 - - (tPtr->vpos + tPtr->visible.y + tPtr->visible.h)); - } else if (tPtr->cursor.y < tPtr->vpos + tPtr->visible.y) { - tPtr->vpos -= (tPtr->vpos + tPtr->visible.y - tPtr->cursor.y); - } - - } - - updateScrollers(tPtr); -} - -static void cursorToTextPosition(Text * tPtr, int x, int y) -{ - TextBlock *tb = NULL; - int done = False, s, pos, len, _w, _y, dir = 1; /* 1 == "down" */ - char *text; - - if (tPtr->flags.needsLayOut) - layOutDocument(tPtr); - - y += (tPtr->vpos - tPtr->visible.y); - if (y < 0) - y = 0; - - x -= (tPtr->visible.x - 2); - if (x < 0) - x = 0; - - /* clicked is relative to document, not window... */ - tPtr->clicked.x = x; - tPtr->clicked.y = y; - - if (!(tb = tPtr->currentTextBlock)) { - if (!(tb = tPtr->firstTextBlock)) { - WMFont *font = tPtr->dFont; - tPtr->tpos = 0; - tPtr->cursor.h = font->height + abs(font->height - font->y); - tPtr->cursor.y = 2; - tPtr->cursor.x = 2; - return; - } - } - - /* first, which direction? Most likely, newly clicked - position will be close to previous */ - if (!updateStartForCurrentTextBlock(tPtr, x, y, &dir, tb)) - return; - - s = (dir ? 0 : tb->nsections - 1); - if (y >= tb->sections[s]._y && y <= tb->sections[s]._y + tb->sections[s].h) { - goto _doneV; - } - - /* get the first (or last) section of the TextBlock that - lies about the vertical click point */ - done = False; - while (!done && tb) { - - if (tPtr->flags.monoFont && tb->graphic) { - if ((dir ? tb->next : tb->prior)) - tb = (dir ? tb->next : tb->prior); - continue; - } - - s = (dir ? 0 : tb->nsections - 1); - while (!done && (dir ? (s < tb->nsections) : (s >= 0))) { - - if ((dir ? (y <= tb->sections[s]._y + tb->sections[s].h) : (y >= tb->sections[s]._y))) { - done = True; - } else { - dir ? s++ : s--; - } - } - - if (!done) { - if ((dir ? tb->next : tb->prior)) { - tb = (dir ? tb->next : tb->prior); - } else { - pos = tb->used; - break; /* goto _doneH; */ - } - } - } - - if (s < 0 || s >= tb->nsections) { - s = (dir ? tb->nsections - 1 : 0); - } - - _doneV: - /* we have the line, which TextBlock on that line is it? */ - pos = (dir ? 0 : tb->sections[s].begin); - if (tPtr->flags.monoFont && tb->graphic) { - TextBlock *hold = tb; - tb = getFirstNonGraphicBlockFor(hold, dir); - - if (!tb) { - tPtr->tpos = 0; - tb = hold; - s = 0; - goto _doNothing; - } - } - - if (tb->blank) - _w = 0; - - _y = tb->sections[s]._y; - - while (tb) { - - if (tPtr->flags.monoFont && tb->graphic) { - tb = (dir ? tb->next : tb->prior); - continue; - } - - if (dir) { - if (tb->graphic) { - if (tb->object) - _w = WMWidgetWidth(tb->d.widget) - 5; - else - _w = tb->d.pixmap->width - 5; - - if (tb->sections[0].x + _w >= x) - break; - } else { - text = &(tb->text[tb->sections[s].begin]); - len = tb->sections[s].end - tb->sections[s].begin; - _w = WMWidthOfString(tb->d.font, text, len); - if (tb->sections[s].x + _w >= x) - break; - - } - } else { - if (tb->sections[s].x <= x) - break; - } - - if ((dir ? tb->next : tb->prior)) { - TextBlock *nxt = (dir ? tb->next : tb->prior); - if (tPtr->flags.monoFont && nxt->graphic) { - nxt = getFirstNonGraphicBlockFor(nxt, dir); - if (!nxt) { - pos = (dir ? 0 : tb->sections[s].begin); - tPtr->cursor.x = tb->sections[s].x; - goto _doneH; - } - } - - if (_y != nxt->sections[dir ? 0 : nxt->nsections - 1]._y) { - /* this must be the last/first on this line. stop */ - pos = (dir ? tb->sections[s].end : 0); - tPtr->cursor.x = tb->sections[s].x; - if (!tb->blank) { - if (tb->graphic) { - if (tb->object) - tPtr->cursor.x += WMWidgetWidth(tb->d.widget); - else - tPtr->cursor.x += tb->d.pixmap->width; - } else if (pos > tb->sections[s].begin) { - tPtr->cursor.x += - WMWidthOfString(tb->d.font, - &(tb->text[tb->sections[s].begin]), - pos - tb->sections[s].begin); - } - } - goto _doneH; - } - } - - if ((dir ? tb->next : tb->prior)) { - tb = (dir ? tb->next : tb->prior); - } else { - done = True; - break; - } - - if (tb) - s = (dir ? 0 : tb->nsections - 1); - } - - /* we have said TextBlock, now where within it? */ - if (tb) { - if (tb->graphic) { - int gw = (tb->object ? WMWidgetWidth(tb->d.widget) : tb->d.pixmap->width); - - tPtr->cursor.x = tb->sections[0].x; - - if (x > tPtr->cursor.x + gw / 2) { - pos = 1; - tPtr->cursor.x += gw; - } else { - printf("first %d\n", tb->first); - if (tb->prior) { - if (tb->prior->graphic) - pos = 1; - else - pos = tb->prior->used; - tb = tb->prior; - } else - pos = 0; - - } - - s = 0; - goto _doneH; - - } else { - WMFont *f = tb->d.font; - len = tb->sections[s].end - tb->sections[s].begin; - text = &(tb->text[tb->sections[s].begin]); - - _w = x - tb->sections[s].x; - pos = 0; - - while (pos < len && WMWidthOfString(f, text, pos + 1) < _w) - pos++; - - tPtr->cursor.x = tb->sections[s].x + (pos ? WMWidthOfString(f, text, pos) : 0); - - pos += tb->sections[s].begin; - } - } - - _doneH: - if (tb->graphic) { - tPtr->tpos = (pos <= 1) ? pos : 0; - } else { - tPtr->tpos = (pos < tb->used) ? pos : tb->used; - } - _doNothing: - if (!tb) - printf("...for this app will surely crash :-)\n"); - - tPtr->currentTextBlock = tb; - tPtr->cursor.h = tb->sections[s].h; - tPtr->cursor.y = tb->sections[s]._y; - - /* scroll the bars if the cursor is not visible */ - if (tPtr->flags.editable && tPtr->cursor.x != -23) { - if (tPtr->cursor.y + tPtr->cursor.h > tPtr->vpos + tPtr->visible.y + tPtr->visible.h) { - tPtr->vpos += - (tPtr->cursor.y + tPtr->cursor.h + 10 - - (tPtr->vpos + tPtr->visible.y + tPtr->visible.h)); - updateScrollers(tPtr); - } else if (tPtr->cursor.y < tPtr->vpos + tPtr->visible.y) { - tPtr->vpos -= (tPtr->vpos + tPtr->visible.y - tPtr->cursor.y); - updateScrollers(tPtr); - } - - } - -} - -static void updateScrollers(Text * tPtr) -{ - - if (tPtr->flags.frozen) - return; - - if (tPtr->vS) { - if (tPtr->docHeight <= tPtr->visible.h) { - WMSetScrollerParameters(tPtr->vS, 0, 1); - tPtr->vpos = 0; - } else { - float hmax = (float)(tPtr->docHeight); - WMSetScrollerParameters(tPtr->vS, - ((float)tPtr->vpos) / (hmax - (float)tPtr->visible.h), - (float)tPtr->visible.h / hmax); - } - } else - tPtr->vpos = 0; - - if (tPtr->hS) { - if (tPtr->docWidth <= tPtr->visible.w) { - WMSetScrollerParameters(tPtr->hS, 0, 1); - tPtr->hpos = 0; - } else { - float wmax = (float)(tPtr->docWidth); - WMSetScrollerParameters(tPtr->hS, - ((float)tPtr->hpos) / (wmax - (float)tPtr->visible.w), - (float)tPtr->visible.w / wmax); - } - } else - tPtr->hpos = 0; -} - -static void scrollersCallBack(WMWidget * w, void *self) -{ - Text *tPtr = (Text *) self; - Bool scroll = False; - int which; - - if (!tPtr->view->flags.realized || tPtr->flags.frozen) - return; - - if (w == tPtr->vS) { - int height; - height = tPtr->visible.h; - - which = WMGetScrollerHitPart(tPtr->vS); - switch (which) { - - case WSDecrementLine: - if (tPtr->vpos > 0) { - if (tPtr->vpos > 16) - tPtr->vpos -= 16; - else - tPtr->vpos = 0; - scroll = True; - } - break; - - case WSIncrementLine:{ - int limit = tPtr->docHeight - height; - if (tPtr->vpos < limit) { - if (tPtr->vpos < limit - 16) - tPtr->vpos += 16; - else - tPtr->vpos = limit; - scroll = True; - } - } - break; - - case WSDecrementPage: - if (((int)tPtr->vpos - (int)height) >= 0) - tPtr->vpos -= height; - else - tPtr->vpos = 0; - - scroll = True; - break; - - case WSIncrementPage: - tPtr->vpos += height; - if (tPtr->vpos > (tPtr->docHeight - height)) - tPtr->vpos = tPtr->docHeight - height; - scroll = True; - break; - - case WSKnob: - tPtr->vpos = WMGetScrollerValue(tPtr->vS) - * (float)(tPtr->docHeight - height); - scroll = True; - break; - - case WSKnobSlot: - case WSNoPart: - break; - } - scroll = (tPtr->vpos != tPtr->prevVpos); - tPtr->prevVpos = tPtr->vpos; - } - - if (w == tPtr->hS) { - int width = tPtr->visible.w; - - which = WMGetScrollerHitPart(tPtr->hS); - switch (which) { - - case WSDecrementLine: - if (tPtr->hpos > 0) { - if (tPtr->hpos > 16) - tPtr->hpos -= 16; - else - tPtr->hpos = 0; - scroll = True; - } - break; - - case WSIncrementLine:{ - int limit = tPtr->docWidth - width; - if (tPtr->hpos < limit) { - if (tPtr->hpos < limit - 16) - tPtr->hpos += 16; - else - tPtr->hpos = limit; - scroll = True; - } - } - break; - - case WSDecrementPage: - if (((int)tPtr->hpos - (int)width) >= 0) - tPtr->hpos -= width; - else - tPtr->hpos = 0; - - scroll = True; - break; - - case WSIncrementPage: - tPtr->hpos += width; - if (tPtr->hpos > (tPtr->docWidth - width)) - tPtr->hpos = tPtr->docWidth - width; - scroll = True; - break; - - case WSKnob: - tPtr->hpos = WMGetScrollerValue(tPtr->hS) - * (float)(tPtr->docWidth - width); - scroll = True; - break; - - case WSKnobSlot: - case WSNoPart: - break; - } - scroll = (tPtr->hpos != tPtr->prevHpos); - tPtr->prevHpos = tPtr->hpos; - } - - if (scroll) { - updateScrollers(tPtr); - paintText(tPtr); - } -} - -typedef struct { - TextBlock *tb; - unsigned short begin, end; /* what part of the text block */ -} myLineItems; - -static int layOutLine(Text * tPtr, myLineItems * items, int nitems, int x, int y) -{ - int i, j = 0, lw = 0, line_height = 0, max_d = 0, len, n; - WMFont *font; - char *text; - TextBlock *tb, *tbsame = NULL; - - if (!items || nitems == 0) - return 0; - - for (i = 0; i < nitems; i++) { - tb = items[i].tb; - - if (tb->graphic) { - if (!tPtr->flags.monoFont) { - if (tb->object) { - WMWidget *wdt = tb->d.widget; - line_height = WMAX(line_height, WMWidgetHeight(wdt)); - if (tPtr->flags.alignment != WALeft) - lw += WMWidgetWidth(wdt); - } else { - line_height = WMAX(line_height, tb->d.pixmap->height + max_d); - if (tPtr->flags.alignment != WALeft) - lw += tb->d.pixmap->width; - } - } - - } else { - font = (tPtr->flags.monoFont) ? tPtr->dFont : tb->d.font; - /*max_d = WMAX(max_d, abs(font->height-font->y)); */ - max_d = 2; - line_height = WMAX(line_height, font->height + max_d); - text = &(tb->text[items[i].begin]); - len = items[i].end - items[i].begin; - if (tPtr->flags.alignment != WALeft) - lw += WMWidthOfString(font, text, len); - } - } - - if (tPtr->flags.alignment == WARight) { - j = tPtr->visible.w - lw; - } else if (tPtr->flags.alignment == WACenter) { - j = (int)((float)(tPtr->visible.w - lw)) / 2.0; - } - - for (i = 0; i < nitems; i++) { - tb = items[i].tb; - - if (tbsame == tb) { /* extend it, since it's on same line */ - tb->sections[tb->nsections - 1].end = items[i].end; - n = tb->nsections - 1; - } else { - tb->sections = wrealloc(tb->sections, (++tb->nsections) * sizeof(Section)); - n = tb->nsections - 1; - tb->sections[n]._y = y + max_d; - tb->sections[n].max_d = max_d; - tb->sections[n].x = x + j; - tb->sections[n].h = line_height; - tb->sections[n].begin = items[i].begin; - tb->sections[n].end = items[i].end; - } - - tb->sections[n].last = (i + 1 == nitems); - - if (tb->graphic) { - if (!tPtr->flags.monoFont) { - if (tb->object) { - WMWidget *wdt = tb->d.widget; - tb->sections[n].y = max_d + y + line_height - WMWidgetHeight(wdt); - tb->sections[n].w = WMWidgetWidth(wdt); - } else { - tb->sections[n].y = y + line_height + max_d - tb->d.pixmap->height; - tb->sections[n].w = tb->d.pixmap->width; - } - x += tb->sections[n].w; - } - } else { - font = (tPtr->flags.monoFont) ? tPtr->dFont : tb->d.font; - len = items[i].end - items[i].begin; - text = &(tb->text[items[i].begin]); - - tb->sections[n].y = y + line_height - font->y; - tb->sections[n].w = - WMWidthOfString(font, - &(tb->text[tb->sections[n].begin]), - tb->sections[n].end - tb->sections[n].begin); - - x += WMWidthOfString(font, text, len); - } - - tbsame = tb; - } - - return line_height; - -} - -static void layOutDocument(Text * tPtr) -{ - TextBlock *tb; - myLineItems *items = NULL; - unsigned int itemsSize = 0, nitems = 0, begin, end; - WMFont *font; - unsigned int x, y = 0, lw = 0, width = 0, bmargin; - char *start = NULL, *mark = NULL; - - if (tPtr->flags.frozen || (!(tb = tPtr->firstTextBlock))) - return; - - assert(tPtr->visible.w > 20); - - tPtr->docWidth = tPtr->visible.w; - x = tPtr->margins[tb->marginN].first; - bmargin = tPtr->margins[tb->marginN].body; - - /* only partial layOut needed: re-Lay only affected textblocks */ - if (tPtr->flags.laidOut) { - tb = tPtr->currentTextBlock; - - /* search backwards for textblocks on same line */ - while (tb->prior) { - if (!tb->sections || tb->nsections < 1) { - tb = tPtr->firstTextBlock; - tPtr->flags.laidOut = False; - y = 0; - goto _layOut; - } - - if (!tb->prior->sections || tb->prior->nsections < 1) { - tb = tPtr->firstTextBlock; - tPtr->flags.laidOut = False; - y = 0; - goto _layOut; - } - - if (tb->sections[0]._y != tb->prior->sections[tb->prior->nsections - 1]._y) { - break; - } - tb = tb->prior; - } - - if (tb->prior && tb->prior->sections && tb->prior->nsections > 0) { - y = tb->prior->sections[tb->prior->nsections - 1]._y + - tb->prior->sections[tb->prior->nsections - 1].h - - tb->prior->sections[tb->prior->nsections - 1].max_d; - } else { - y = 0; - } - } - - _layOut: - while (tb) { - - if (tb->sections && tb->nsections > 0) { - wfree(tb->sections); - tb->sections = NULL; - tb->nsections = 0; - } - - if (tb->first && tb->blank && tb->next && !tb->next->first) { - TextBlock *next = tb->next; - tPtr->currentTextBlock = tb; - WMDestroyTextBlock(tPtr, WMRemoveTextBlock(tPtr)); - tb = next; - tb->first = True; - continue; - } - - if (tb->first && tb != tPtr->firstTextBlock) { - y += layOutLine(tPtr, items, nitems, x, y); - x = tPtr->margins[tb->marginN].first; - bmargin = tPtr->margins[tb->marginN].body; - nitems = 0; - lw = 0; - } - - if (tb->graphic) { - if (!tPtr->flags.monoFont) { - if (tb->object) - width = WMWidgetWidth(tb->d.widget); - else - width = tb->d.pixmap->width; - - if (width > tPtr->docWidth) - tPtr->docWidth = width; - - lw += width; - if (lw >= tPtr->visible.w - x) { - y += layOutLine(tPtr, items, nitems, x, y); - nitems = 0; - x = bmargin; - lw = width; - } - - if (nitems + 1 > itemsSize) { - items = wrealloc(items, (++itemsSize) * sizeof(myLineItems)); - } - - items[nitems].tb = tb; - items[nitems].begin = 0; - items[nitems].end = 0; - nitems++; - } - - } else if ((start = tb->text)) { - begin = end = 0; - font = tPtr->flags.monoFont ? tPtr->dFont : tb->d.font; - - while (start) { - mark = strchr(start, ' '); - if (mark) { - end += (int)(mark - start) + 1; - start = mark + 1; - } else { - end += strlen(start); - start = mark; - } - - if (end > tb->used) - end = tb->used; - - if (end - begin > 0) { - - width = WMWidthOfString(font, &tb->text[begin], end - begin); - - /* if it won't fit, char wrap it */ - if (width >= tPtr->visible.w) { - char *t = &tb->text[begin]; - int l = end - begin, i = 0; - do { - width = WMWidthOfString(font, t, ++i); - } while (width < tPtr->visible.w && i < l); - if (i > 2) - i--; - end = begin + i; - start = &tb->text[end]; - } - - lw += width; - } - - if (lw >= tPtr->visible.w - x) { - y += layOutLine(tPtr, items, nitems, x, y); - lw = width; - x = bmargin; - nitems = 0; - } - - if (nitems + 1 > itemsSize) { - items = wrealloc(items, (++itemsSize) * sizeof(myLineItems)); - } - - items[nitems].tb = tb; - items[nitems].begin = begin; - items[nitems].end = end; - nitems++; - - begin = end; - } - } - - /* not yet fully ready. but is already VERY FAST for a 3Mbyte file ;-) */ - if (0 && tPtr->flags.laidOut - && tb->next && tb->next->sections && tb->next->nsections > 0 - && (tPtr->vpos + tPtr->visible.h < tb->next->sections[0]._y)) { - if (tPtr->lastTextBlock->sections && tPtr->lastTextBlock->nsections > 0) { - TextBlock *ltb = tPtr->lastTextBlock; - int ly = ltb->sections[ltb->nsections - 1]._y; - int lh = ltb->sections[ltb->nsections - 1].h; - int ss, sd; - - lh += 1 + tPtr->visible.y + ltb->sections[ltb->nsections - 1].max_d; - printf("it's %d\n", tPtr->visible.y + ltb->sections[ltb->nsections - 1].max_d); - - y += layOutLine(tPtr, items, nitems, x, y); - ss = ly + lh - y; - sd = tPtr->docHeight - y; - - printf("dif %d-%d: %d\n", ss, sd, ss - sd); - y += tb->next->sections[0]._y - y; - nitems = 0; - printf("nitems%d\n", nitems); - if (ss - sd != 0) - y = tPtr->docHeight + ss - sd; - - break; - } else { - tPtr->flags.laidOut = False; - } - } - - tb = tb->next; - } - - if (nitems > 0) - y += layOutLine(tPtr, items, nitems, x, y); - - if (tPtr->docHeight != y + 10) { - tPtr->docHeight = y + 10; - updateScrollers(tPtr); - } - - if (tPtr->docWidth > tPtr->visible.w && !tPtr->hS) { - XEvent event; - - tPtr->flags.horizOnDemand = True; - WMSetTextHasHorizontalScroller((WMText *) tPtr, True); - event.type = Expose; - handleEvents(&event, (void *)tPtr); - - } else if (tPtr->docWidth <= tPtr->visible.w && tPtr->hS && tPtr->flags.horizOnDemand) { - tPtr->flags.horizOnDemand = False; - WMSetTextHasHorizontalScroller((WMText *) tPtr, False); - } - - tPtr->flags.laidOut = True; - - if (items && itemsSize > 0) - wfree(items); - -} - -static void textDidResize(W_ViewDelegate * self, WMView * view) -{ - Text *tPtr = (Text *) view->self; - unsigned short w = tPtr->view->size.width; - unsigned short h = tPtr->view->size.height; - unsigned short rh = 0, vw = 0, rel; - - rel = (tPtr->flags.relief == WRFlat); - - if (tPtr->ruler && tPtr->flags.rulerShown) { - WMMoveWidget(tPtr->ruler, 2, 2); - WMResizeWidget(tPtr->ruler, w - 4, 40); - rh = 40; - } - - if (tPtr->vS) { - WMMoveWidget(tPtr->vS, 1 - (rel ? 1 : 0), rh + 1 - (rel ? 1 : 0)); - WMResizeWidget(tPtr->vS, 20, h - rh - 2 + (rel ? 2 : 0)); - vw = 20; - WMSetRulerOffset(tPtr->ruler, 22); - } else - WMSetRulerOffset(tPtr->ruler, 2); - - if (tPtr->hS) { - if (tPtr->vS) { - WMMoveWidget(tPtr->hS, vw, h - 21); - WMResizeWidget(tPtr->hS, w - vw - 1, 20); - } else { - WMMoveWidget(tPtr->hS, vw + 1, h - 21); - WMResizeWidget(tPtr->hS, w - vw - 2, 20); - } - } - - tPtr->visible.x = (tPtr->vS) ? 24 : 4; - tPtr->visible.y = (tPtr->ruler && tPtr->flags.rulerShown) ? 43 : 3; - tPtr->visible.w = tPtr->view->size.width - tPtr->visible.x - 8; - tPtr->visible.h = tPtr->view->size.height - tPtr->visible.y; - tPtr->visible.h -= (tPtr->hS) ? 20 : 0; - tPtr->margins[0].right = tPtr->visible.w; - - if (tPtr->view->flags.realized) { - - if (tPtr->db) { - XFreePixmap(tPtr->view->screen->display, tPtr->db); - tPtr->db = (Pixmap) NULL; - } - - if (tPtr->visible.w < 40) - tPtr->visible.w = 40; - if (tPtr->visible.h < 20) - tPtr->visible.h = 20; - - if (!tPtr->db) { - tPtr->db = XCreatePixmap(tPtr->view->screen->display, - tPtr->view->window, tPtr->visible.w, - tPtr->visible.h, tPtr->view->screen->depth); - } - } - - WMThawText(tPtr); -} - -W_ViewDelegate _TextViewDelegate = { - NULL, - NULL, - textDidResize, - NULL, - NULL -}; - -#define TEXT_BUFFER_INCR 8 -#define reqBlockSize(requested) (requested + TEXT_BUFFER_INCR) - -static void clearText(Text * tPtr) -{ - tPtr->vpos = tPtr->hpos = 0; - tPtr->docHeight = tPtr->docWidth = 0; - tPtr->cursor.x = -23; - - if (!tPtr->firstTextBlock) - return; - - while (tPtr->currentTextBlock) - WMDestroyTextBlock(tPtr, WMRemoveTextBlock(tPtr)); - - tPtr->firstTextBlock = NULL; - tPtr->currentTextBlock = NULL; - tPtr->lastTextBlock = NULL; - WMEmptyArray(tPtr->gfxItems); -} - -/* possibly remove a single character from the currentTextBlock, - or if there's a selection, remove it... - note that Delete and Backspace are treated differently */ -static void deleteTextInteractively(Text * tPtr, KeySym ksym) -{ - TextBlock *tb; - Bool back = (Bool) (ksym == XK_BackSpace); - Bool done = 1, wasFirst = 0; - - if (!tPtr->flags.editable) - return; - - if (!(tb = tPtr->currentTextBlock)) - return; - - if (tPtr->flags.ownsSelection) { - if (removeSelection(tPtr)) - layOutDocument(tPtr); - return; - } - - wasFirst = tb->first; - if (back && tPtr->tpos < 1) { - if (tb->prior) { - if (tb->prior->blank) { - tPtr->currentTextBlock = tb->prior; - WMRemoveTextBlock(tPtr); - tPtr->currentTextBlock = tb; - tb->first = True; - layOutDocument(tPtr); - return; - } else { - if (tb->blank) { - TextBlock *prior = tb->prior; - tPtr->currentTextBlock = tb; - WMRemoveTextBlock(tPtr); - tb = prior; - } else { - tb = tb->prior; - } - - if (tb->graphic) - tPtr->tpos = 1; - else - tPtr->tpos = tb->used; - - tPtr->currentTextBlock = tb; - done = 1; - if (wasFirst) { - if (tb->next) - tb->next->first = False; - layOutDocument(tPtr); - return; - } - } - } - } - - if ((tb->used > 0) && ((back ? tPtr->tpos > 0 : 1)) - && (tPtr->tpos <= tb->used) && !tb->graphic) { - if (back) - tPtr->tpos--; - memmove(&(tb->text[tPtr->tpos]), &(tb->text[tPtr->tpos + 1]), tb->used - tPtr->tpos); - tb->used--; - done = 0; - } - - /* if there are no characters left to back over in the textblock, - but it still has characters to the right of the cursor: */ - if ((back ? (tPtr->tpos == 0 && !done) : (tPtr->tpos >= tb->used)) - || tb->graphic) { - - /* no more chars, and it's marked as blank? */ - if (tb->blank) { - TextBlock *sibling = (back ? tb->prior : tb->next); - - if (tb->used == 0 || tb->graphic) - WMDestroyTextBlock(tPtr, WMRemoveTextBlock(tPtr)); - - if (sibling) { - tPtr->currentTextBlock = sibling; - if (tb->graphic) - tPtr->tpos = (back ? 1 : 0); - else - tPtr->tpos = (back ? sibling->used : 0); - } - /* no more chars, so mark it as blank */ - } else if (tb->used == 0) { - tb->blank = 1; - } else if (tb->graphic) { - Bool hasNext = (tb->next != NULL); - - WMDestroyTextBlock(tPtr, WMRemoveTextBlock(tPtr)); - if (hasNext) { - tPtr->tpos = 0; - } else if (tPtr->currentTextBlock) { - tPtr->tpos = (tPtr->currentTextBlock->graphic ? 1 : tPtr->currentTextBlock->used); - } - } else - printf("DEBUG: unaccounted for... catch this!\n"); - } - - layOutDocument(tPtr); -} - -static void insertTextInteractively(Text * tPtr, char *text, int len) -{ - TextBlock *tb; - char *newline = NULL; - - if (!tPtr->flags.editable) { - return; - } - - if (len < 1 || !text) - return; - - if (tPtr->flags.ignoreNewLine && *text == '\n' && len == 1) - return; - - if (tPtr->flags.ownsSelection) - removeSelection(tPtr); - - if (tPtr->flags.ignoreNewLine) { - int i; - for (i = 0; i < len; i++) { - if (text[i] == '\n') - text[i] = ' '; - } - } - - tb = tPtr->currentTextBlock; - if (!tb || tb->graphic) { - tPtr->tpos = 0; - WMAppendTextStream(tPtr, text); - layOutDocument(tPtr); - return; - } - - if ((newline = strchr(text, '\n'))) { - int nlen = (int)(newline - text); - int s = tb->used - tPtr->tpos; - - if (!tb->blank && nlen > 0) { - char *save = NULL; - - if (s > 0) { - save = wmalloc(s); - memcpy(save, &tb->text[tPtr->tpos], s); - tb->used -= (tb->used - tPtr->tpos); - } - insertTextInteractively(tPtr, text, nlen); - newline++; - WMAppendTextStream(tPtr, newline); - if (s > 0) { - insertTextInteractively(tPtr, save, s); - wfree(save); - } - } else { - if (tPtr->tpos > 0 && tPtr->tpos < tb->used && !tb->graphic && tb->text) { - - unsigned short savePos = tPtr->tpos; - void *ntb = WMCreateTextBlockWithText(tPtr, &tb->text[tPtr->tpos], - tb->d.font, tb->color, True, - tb->used - tPtr->tpos); - - if (tb->sections[0].end == tPtr->tpos) - WMAppendTextBlock(tPtr, WMCreateTextBlockWithText(tPtr, - NULL, tb->d.font, - tb->color, True, 0)); - - tb->used = savePos; - WMAppendTextBlock(tPtr, ntb); - tPtr->tpos = 0; - - } else if (tPtr->tpos == tb->used) { - if (tPtr->flags.indentNewLine) { - WMAppendTextBlock(tPtr, WMCreateTextBlockWithText(tPtr, - " ", tb->d.font, - tb->color, True, 4)); - tPtr->tpos = 4; - } else { - WMAppendTextBlock(tPtr, WMCreateTextBlockWithText(tPtr, - NULL, tb->d.font, - tb->color, True, 0)); - tPtr->tpos = 0; - } - } else if (tPtr->tpos == 0) { - if (tPtr->flags.indentNewLine) { - WMPrependTextBlock(tPtr, WMCreateTextBlockWithText(tPtr, - " ", tb->d.font, - tb->color, True, 4)); - } else { - WMPrependTextBlock(tPtr, WMCreateTextBlockWithText(tPtr, - NULL, tb->d.font, - tb->color, True, 0)); - } - tPtr->tpos = 0; - if (tPtr->currentTextBlock->next) - tPtr->currentTextBlock = tPtr->currentTextBlock->next; - } - } - } else { - if (tb->used + len >= tb->allocated) { - tb->allocated = reqBlockSize(tb->used + len); - tb->text = wrealloc(tb->text, tb->allocated); - } - - if (tb->blank) { - memcpy(tb->text, text, len); - tb->used = len; - tPtr->tpos = len; - tb->text[tb->used] = 0; - tb->blank = False; - - } else { - memmove(&(tb->text[tPtr->tpos + len]), &tb->text[tPtr->tpos], tb->used - tPtr->tpos + 1); - memmove(&tb->text[tPtr->tpos], text, len); - tb->used += len; - tPtr->tpos += len; - tb->text[tb->used] = 0; - } - - } - - layOutDocument(tPtr); -} - -static void selectRegion(Text * tPtr, int x, int y) -{ - - if (x < 0 || y < 0) - return; - - y += (tPtr->flags.rulerShown ? 40 : 0); - y += tPtr->vpos; - if (y > 10) - y -= 10; /* the original offset */ - - x -= tPtr->visible.x - 2; - if (x < 0) - x = 0; - - tPtr->sel.x = WMAX(0, WMIN(tPtr->clicked.x, x)); - tPtr->sel.w = abs(tPtr->clicked.x - x); - tPtr->sel.y = WMAX(0, WMIN(tPtr->clicked.y, y)); - tPtr->sel.h = abs(tPtr->clicked.y - y); - - tPtr->flags.ownsSelection = True; - paintText(tPtr); -} - -static void releaseSelection(Text * tPtr) -{ - TextBlock *tb = tPtr->firstTextBlock; - - while (tb) { - tb->selected = False; - tb = tb->next; - } - tPtr->flags.ownsSelection = False; - WMDeleteSelectionHandler(tPtr->view, XA_PRIMARY, CurrentTime); - - paintText(tPtr); -} - -WMData *requestHandler(WMView * view, Atom selection, Atom target, void *cdata, Atom * type) -{ - Text *tPtr = view->self; - Display *dpy = tPtr->view->screen->display; - Atom _TARGETS; - Atom TEXT = XInternAtom(dpy, "TEXT", False); - Atom COMPOUND_TEXT = XInternAtom(dpy, "COMPOUND_TEXT", False); - WMData *data = NULL; - - if (target == XA_STRING || target == TEXT || target == COMPOUND_TEXT) { - char *text = WMGetTextSelectedStream(tPtr); - - if (text) { - data = WMCreateDataWithBytes(text, strlen(text)); - WMSetDataFormat(data, TYPETEXT); - } - *type = target; - return data; - } else - printf("didn't get it\n"); - - _TARGETS = XInternAtom(dpy, "TARGETS", False); - if (target == _TARGETS) { - Atom *ptr; - - ptr = wmalloc(4 * sizeof(Atom)); - ptr[0] = _TARGETS; - ptr[1] = XA_STRING; - ptr[2] = TEXT; - ptr[3] = COMPOUND_TEXT; - - data = WMCreateDataWithBytes(ptr, 4 * 4); - WMSetDataFormat(data, 32); - - *type = target; - return data; - } - - return NULL; -} - -static void lostHandler(WMView * view, Atom selection, void *cdata) -{ - releaseSelection((WMText *) view->self); -} - -static WMSelectionProcs selectionHandler = { - requestHandler, lostHandler, NULL -}; - -static void ownershipObserver(void *observerData, WMNotification * notification) -{ - if (observerData != WMGetNotificationClientData(notification)) - lostHandler(WMWidgetView(observerData), XA_PRIMARY, NULL); -} - -static void autoSelectText(Text * tPtr, int clicks) -{ - int x, start; - TextBlock *tb; - char *mark = NULL, behind, ahead; - - if (!(tb = tPtr->currentTextBlock)) - return; - - if (clicks == 2) { - - switch (tb->text[tPtr->tpos]) { - case ' ': - return; - /* - case '<': case '>': behind = '<'; ahead = '>'; break; - case '{': case '}': behind = '{'; ahead = '}'; break; - case '[': case ']': behind = '['; ahead = ']'; break; - */ - default: - behind = ahead = ' '; - } - - tPtr->sel.y = tPtr->cursor.y + 5; - tPtr->sel.h = 6; /*tPtr->cursor.h-10; */ - - if (tb->graphic) { - tPtr->sel.x = tb->sections[0].x; - tPtr->sel.w = tb->sections[0].w; - } else { - WMFont *font = tPtr->flags.monoFont ? tPtr->dFont : tb->d.font; - - start = tPtr->tpos; - while (start > 0 && tb->text[start - 1] != behind) - start--; - - x = tPtr->cursor.x; - if (tPtr->tpos > start) { - x -= WMWidthOfString(font, &tb->text[start], tPtr->tpos - start); - } - tPtr->sel.x = (x < 0 ? 0 : x) + 1; - - if ((mark = strchr(&tb->text[start], ahead))) { - tPtr->sel.w = WMWidthOfString(font, &tb->text[start], - (int)(mark - &tb->text[start])); - } else if (tb->used > start) { - tPtr->sel.w = WMWidthOfString(font, &tb->text[start], tb->used - start); - } - } - - } else if (clicks == 3) { - TextBlock *cur = tb; - - while (tb && !tb->first) { - tb = tb->prior; - } - tPtr->sel.y = tb->sections[0]._y; - - tb = cur; - while (tb->next && !tb->next->first) { - tb = tb->next; - } - tPtr->sel.h = tb->sections[tb->nsections - 1]._y + 5 - tPtr->sel.y; - - tPtr->sel.x = 0; - tPtr->sel.w = tPtr->docWidth; - tPtr->clicked.x = 0; /* only for now, fix sel. code */ - } - - if (!tPtr->flags.ownsSelection) { - WMCreateSelectionHandler(tPtr->view, XA_PRIMARY, tPtr->lastClickTime, &selectionHandler, NULL); - tPtr->flags.ownsSelection = True; - } - paintText(tPtr); - -} - -# if 0 -static void fontChanged(void *observerData, WMNotification * notification) -{ - WMText *tPtr = (WMText *) observerData; - WMFont *font = (WMFont *) WMGetNotificationClientData(notification); - printf("fontChanged\n"); - - if (!tPtr || !font) - return; - - if (tPtr->flags.ownsSelection) - WMSetTextSelectionFont(tPtr, font); -} -#endif - -static void handleTextKeyPress(Text * tPtr, XEvent * event) -{ - char buffer[64]; - KeySym ksym; - int control_pressed = False; - TextBlock *tb = NULL; - - if (((XKeyEvent *) event)->state & ControlMask) - control_pressed = True; - buffer[XLookupString(&event->xkey, buffer, 63, &ksym, NULL)] = 0; - - switch (ksym) { - - case XK_Home: - if ((tPtr->currentTextBlock = tPtr->firstTextBlock)) - tPtr->tpos = 0; - updateCursorPosition(tPtr); - paintText(tPtr); - break; - - case XK_End: - if ((tPtr->currentTextBlock = tPtr->lastTextBlock)) { - if (tPtr->currentTextBlock->graphic) - tPtr->tpos = 1; - else - tPtr->tpos = tPtr->currentTextBlock->used; - } - updateCursorPosition(tPtr); - paintText(tPtr); - break; - - case XK_Left: - if (!(tb = tPtr->currentTextBlock)) - break; - if (tb->graphic) - goto L_imaGFX; - - if (tPtr->tpos == 0) { - L_imaGFX: - if (tb->prior) { - tPtr->currentTextBlock = tb->prior; - if (tPtr->currentTextBlock->graphic) - tPtr->tpos = 1; - else - tPtr->tpos = tPtr->currentTextBlock->used; - - if (!tb->first && tPtr->tpos > 0) - tPtr->tpos--; - } else - tPtr->tpos = 0; - } else - tPtr->tpos--; - updateCursorPosition(tPtr); - paintText(tPtr); - break; - - case XK_Right: - if (!(tb = tPtr->currentTextBlock)) - break; - if (tb->graphic) - goto R_imaGFX; - if (tPtr->tpos == tb->used) { - R_imaGFX: - if (tb->next) { - tPtr->currentTextBlock = tb->next; - tPtr->tpos = 0; - if (!tb->next->first && tb->next->used > 0) - tPtr->tpos++; - } else { - if (tb->graphic) - tPtr->tpos = 1; - else - tPtr->tpos = tb->used; - } - } else - tPtr->tpos++; - updateCursorPosition(tPtr); - paintText(tPtr); - break; - - case XK_Down: - cursorToTextPosition(tPtr, tPtr->cursor.x + tPtr->visible.x, - tPtr->clicked.y + tPtr->cursor.h - tPtr->vpos); - paintText(tPtr); - break; - - case XK_Up: - cursorToTextPosition(tPtr, tPtr->cursor.x + tPtr->visible.x, - tPtr->visible.y + tPtr->cursor.y - tPtr->vpos - 3); - paintText(tPtr); - break; - - case XK_BackSpace: - case XK_Delete: -#ifdef XK_KP_Delete - case XK_KP_Delete: -#endif - deleteTextInteractively(tPtr, ksym); - updateCursorPosition(tPtr); - paintText(tPtr); - break; - - case XK_Control_R: - case XK_Control_L: - control_pressed = True; - break; - - case XK_Tab: - insertTextInteractively(tPtr, " ", 4); - updateCursorPosition(tPtr); - paintText(tPtr); - break; - - case XK_Return: - *buffer = '\n'; - default: - if (*buffer != 0 && !control_pressed) { - insertTextInteractively(tPtr, buffer, strlen(buffer)); - updateCursorPosition(tPtr); - paintText(tPtr); - - } else if (control_pressed && ksym == XK_r) { - Bool i = !tPtr->flags.rulerShown; - WMShowTextRuler(tPtr, i); - tPtr->flags.rulerShown = i; - } else if (control_pressed && *buffer == '\a') { - XBell(tPtr->view->screen->display, 0); - } else { - WMRelayToNextResponder(tPtr->view, event); - } - } - - if (!control_pressed && tPtr->flags.ownsSelection) { - releaseSelection(tPtr); - } -} - -static void pasteText(WMView * view, Atom selection, Atom target, Time timestamp, void *cdata, WMData * data) -{ - Text *tPtr = (Text *) view->self; - char *text; - - tPtr->flags.waitingForSelection = 0; - - if (data) { - text = (char *)WMDataBytes(data); - - if (tPtr->parser) { - (tPtr->parser) (tPtr, (void *)text); - layOutDocument(tPtr); - } else - insertTextInteractively(tPtr, text, strlen(text)); - updateCursorPosition(tPtr); - paintText(tPtr); - - } else { - int n; - - text = XFetchBuffer(tPtr->view->screen->display, &n, 0); - - if (text) { - text[n] = 0; - if (tPtr->parser) { - (tPtr->parser) (tPtr, (void *)text); - layOutDocument(tPtr); - } else - insertTextInteractively(tPtr, text, n); - updateCursorPosition(tPtr); - paintText(tPtr); - - XFree(text); - } - } - -} - -static void handleActionEvents(XEvent * event, void *data) -{ - Text *tPtr = (Text *) data; - Display *dpy = event->xany.display; - KeySym ksym; - - switch (event->type) { - case KeyPress: - ksym = XLookupKeysym((XKeyEvent *) event, 0); - if (ksym == XK_Shift_R || ksym == XK_Shift_L) { - tPtr->flags.extendSelection = True; - return; - } - - if (tPtr->flags.focused) { - XGrabPointer(dpy, W_VIEW(tPtr)->window, False, - PointerMotionMask | ButtonPressMask | ButtonReleaseMask, - GrabModeAsync, GrabModeAsync, None, - tPtr->view->screen->invisibleCursor, CurrentTime); - tPtr->flags.pointerGrabbed = True; - handleTextKeyPress(tPtr, event); - - } - break; - - case KeyRelease: - ksym = XLookupKeysym((XKeyEvent *) event, 0); - if (ksym == XK_Shift_R || ksym == XK_Shift_L) { - tPtr->flags.extendSelection = False; - return; - /* end modify flag so selection can be extended */ - } - break; - - case MotionNotify: - - if (tPtr->flags.pointerGrabbed) { - tPtr->flags.pointerGrabbed = False; - XUngrabPointer(dpy, CurrentTime); - } - - if (tPtr->flags.waitingForSelection) - break; - - if ((event->xmotion.state & Button1Mask)) { - - if (WMIsDraggingFromView(tPtr->view)) { - WMDragImageFromView(tPtr->view, event); - break; - } - - if (!tPtr->flags.ownsSelection) { - WMCreateSelectionHandler(tPtr->view, - XA_PRIMARY, event->xbutton.time, &selectionHandler, NULL); - tPtr->flags.ownsSelection = True; - } - selectRegion(tPtr, event->xmotion.x, event->xmotion.y); - break; - } - - mouseOverObject(tPtr, event->xmotion.x, event->xmotion.y); - break; - - case ButtonPress: - - if (tPtr->flags.pointerGrabbed) { - tPtr->flags.pointerGrabbed = False; - XUngrabPointer(dpy, CurrentTime); - break; - } - - if (tPtr->flags.waitingForSelection) - break; - - if (tPtr->flags.extendSelection && tPtr->flags.ownsSelection) { - selectRegion(tPtr, event->xmotion.x, event->xmotion.y); - return; - } - - if (tPtr->flags.ownsSelection) - releaseSelection(tPtr); - - if (event->xbutton.button == Button1) { - TextBlock *tb = tPtr->currentTextBlock; - - if (WMIsDoubleClick(event)) { - - tPtr->lastClickTime = event->xbutton.time; - if (tb && tb->graphic && !tb->object) { - if (tPtr->delegate && tPtr->delegate->didDoubleClickOnPicture) { - char *desc; - - desc = wmalloc(tb->used + 1); - memcpy(desc, tb->text, tb->used); - desc[tb->used] = 0; - (*tPtr->delegate->didDoubleClickOnPicture) (tPtr->delegate, desc); - wfree(desc); - } - } else { - autoSelectText(tPtr, 2); - } - break; - } else if (event->xbutton.time - tPtr->lastClickTime < WINGsConfiguration.doubleClickDelay) { - tPtr->lastClickTime = event->xbutton.time; - autoSelectText(tPtr, 3); - break; - } - - if (!tPtr->flags.focused) { - WMSetFocusToWidget(tPtr); - tPtr->flags.focused = True; - } else if (tb && tPtr->flags.isOverGraphic && tb->graphic && !tb->object && tb->d.pixmap) { - - WMSetViewDragImage(tPtr->view, tb->d.pixmap); - WMDragImageFromView(tPtr->view, event); - break; - } - - tPtr->lastClickTime = event->xbutton.time; - cursorToTextPosition(tPtr, event->xmotion.x, event->xmotion.y); - paintText(tPtr); - } - - if (event->xbutton.button == WINGsConfiguration.mouseWheelDown) { - WMScrollText(tPtr, 16); - break; - } - - if (event->xbutton.button == WINGsConfiguration.mouseWheelUp) { - WMScrollText(tPtr, -16); - break; - } - - if (event->xbutton.button == Button2) { - char *text = NULL; - int n; - - if (!tPtr->flags.editable) { - XBell(dpy, 0); - break; - } - - if (!WMRequestSelection(tPtr->view, XA_PRIMARY, XA_STRING, - event->xbutton.time, pasteText, NULL)) { - - text = XFetchBuffer(tPtr->view->screen->display, &n, 0); - tPtr->flags.waitingForSelection = 0; - - if (text) { - text[n] = 0; - - if (tPtr->parser) { - (tPtr->parser) (tPtr, (void *)text); - layOutDocument(tPtr); - } else - insertTextInteractively(tPtr, text, n); - - XFree(text); -#if 0 - NOTIFY(tPtr, didChange, WMTextDidChangeNotification, - (void *)WMInsertTextEvent); -#endif - updateCursorPosition(tPtr); - paintText(tPtr); - - } else { - tPtr->flags.waitingForSelection = True; - } - } - break; - } - - case ButtonRelease: - if (tPtr->flags.pointerGrabbed) { - tPtr->flags.pointerGrabbed = False; - XUngrabPointer(dpy, CurrentTime); - break; - } - - if (tPtr->flags.waitingForSelection) - break; - - if (WMIsDraggingFromView(tPtr->view)) - WMDragImageFromView(tPtr->view, event); - } - -} - -static void handleEvents(XEvent * event, void *data) -{ - Text *tPtr = (Text *) data; - - switch (event->type) { - case Expose: - - if (event->xexpose.count != 0) - break; - - if (tPtr->hS) { - if (!(W_VIEW(tPtr->hS))->flags.realized) - WMRealizeWidget(tPtr->hS); - } - - if (tPtr->vS) { - if (!(W_VIEW(tPtr->vS))->flags.realized) - WMRealizeWidget(tPtr->vS); - } - - if (tPtr->ruler) { - if (!(W_VIEW(tPtr->ruler))->flags.realized) - WMRealizeWidget(tPtr->ruler); - - } - - if (!tPtr->db) - textDidResize(tPtr->view->delegate, tPtr->view); - - paintText(tPtr); - break; - - case FocusIn: - if (W_FocusedViewOfToplevel(W_TopLevelOfView(tPtr->view)) - != tPtr->view) - return; - tPtr->flags.focused = True; -#if DO_BLINK - if (tPtr->flags.editable && !tPtr->timerID) { - tPtr->timerID = WMAddTimerHandler(12 + 0 * CURSOR_BLINK_ON_DELAY, blinkCursor, tPtr); - } -#endif - - break; - - case FocusOut: - tPtr->flags.focused = False; - paintText(tPtr); -#if DO_BLINK - if (tPtr->timerID) { - WMDeleteTimerHandler(tPtr->timerID); - tPtr->timerID = NULL; - } -#endif - break; - - case DestroyNotify: - clearText(tPtr); - if (tPtr->db) - XFreePixmap(tPtr->view->screen->display, tPtr->db); - if (tPtr->gfxItems) - WMEmptyArray(tPtr->gfxItems); -#if DO_BLINK - if (tPtr->timerID) - WMDeleteTimerHandler(tPtr->timerID); -#endif - WMReleaseFont(tPtr->dFont); - WMReleaseColor(tPtr->dColor); - WMDeleteSelectionHandler(tPtr->view, XA_PRIMARY, CurrentTime); - WMRemoveNotificationObserver(tPtr); - - WMFreeArray(tPtr->xdndSourceTypes); - WMFreeArray(tPtr->xdndDestinationTypes); - - wfree(tPtr); - - break; - - } -} - -static void insertPlainText(Text * tPtr, char *text) -{ - char *start, *mark; - void *tb = NULL; - - start = text; - while (start) { - mark = strchr(start, '\n'); - if (mark) { - tb = WMCreateTextBlockWithText(tPtr, - start, tPtr->dFont, - tPtr->dColor, tPtr->flags.first, (int)(mark - start)); - start = mark + 1; - tPtr->flags.first = True; - } else { - if (start && strlen(start)) { - tb = WMCreateTextBlockWithText(tPtr, start, tPtr->dFont, - tPtr->dColor, tPtr->flags.first, strlen(start)); - } else - tb = NULL; - tPtr->flags.first = False; - start = mark; - } - - if (tPtr->flags.prepend) - WMPrependTextBlock(tPtr, tb); - else - WMAppendTextBlock(tPtr, tb); - } -} - -static void rulerMoveCallBack(WMWidget * w, void *self) -{ - Text *tPtr = (Text *) self; - - if (!tPtr) - return; - if (W_CLASS(tPtr) != WC_Text) - return; - - paintText(tPtr); -} - -static void rulerReleaseCallBack(WMWidget * w, void *self) -{ - Text *tPtr = (Text *) self; - - if (!tPtr) - return; - if (W_CLASS(tPtr) != WC_Text) - return; - - WMThawText(tPtr); - return; -} - -static WMArray *dropDataTypes(WMView * self) -{ - return ((Text *) self->self)->xdndSourceTypes; -} - -static WMDragOperationType wantedDropOperation(WMView * self) -{ - return WDOperationCopy; -} - -static Bool acceptDropOperation(WMView * self, WMDragOperationType allowedOperation) -{ - return (allowedOperation == WDOperationCopy); -} - -static WMData *fetchDragData(WMView * self, char *type) -{ - TextBlock *tb = ((WMText *) self->self)->currentTextBlock; - char *desc; - WMData *data; - - if (strcmp(type, "text/plain")) { - if (!tb) - return NULL; - - desc = wmalloc(tb->used + 1); - memcpy(desc, tb->text, tb->used); - desc[tb->used] = 0; - data = WMCreateDataWithBytes(desc, strlen(desc) + 1); - - wfree(desc); - - return data; - } - - return NULL; -} - -static WMDragSourceProcs _DragSourceProcs = { - dropDataTypes, - wantedDropOperation, - NULL, - acceptDropOperation, - NULL, - NULL, - fetchDragData -}; - -static WMArray *requiredDataTypes(WMView * self, WMDragOperationType request, WMArray * sourceDataTypes) -{ - return ((Text *) self->self)->xdndDestinationTypes; -} - -static WMDragOperationType allowedOperation(WMView * self, WMDragOperationType request, WMArray * sourceDataTypes) -{ - return WDOperationCopy; -} - -static void performDragOperation(WMView * self, WMArray * dropData, WMArray * operations, WMPoint * dropLocation) -{ - WMText *tPtr = (WMText *) self->self; - WMData *data; - char *colorName; - WMColor *color; - - if (tPtr) { - - /* only one required type, implies only one drop data */ - - /* get application/X-color if any */ - data = (WMData *) WMPopFromArray(dropData); - if (data != NULL) { - colorName = (char *)WMDataBytes(data); - color = WMCreateNamedColor(W_VIEW_SCREEN(self), colorName, True); - - if (color) { - WMSetTextSelectionColor(tPtr, color); - WMReleaseColor(color); - } - } - } -} - -static WMDragDestinationProcs _DragDestinationProcs = { - NULL, - requiredDataTypes, - allowedOperation, - NULL, - performDragOperation, - NULL -}; - -char *getStream(WMText * tPtr, int sel, int array) -{ - TextBlock *tb = NULL; - char *text = NULL; - unsigned long where = 0; - - if (!tPtr) - return NULL; - - if (!(tb = tPtr->firstTextBlock)) - return NULL; - - if (tPtr->writer) { - (tPtr->writer) (tPtr, (void *)text); - return text; - } - - tb = tPtr->firstTextBlock; - while (tb) { - - if (!tb->graphic || (tb->graphic && !tPtr->flags.monoFont)) { - - if (!sel || (tb->graphic && tb->selected)) { - - if (!tPtr->flags.ignoreNewLine && (tb->first || tb->blank) - && tb != tPtr->firstTextBlock) { - text = wrealloc(text, where + 1); - text[where++] = '\n'; - } - - if (tb->blank) - goto _gSnext; - - if (tb->graphic && array) { - text = wrealloc(text, where + 4); - text[where++] = 0xFA; - text[where++] = (tb->used >> 8) & 0x0ff; - text[where++] = tb->used & 0x0ff; - text[where++] = tb->allocated; /* extra info */ - } - text = wrealloc(text, where + tb->used); - memcpy(&text[where], tb->text, tb->used); - where += tb->used; - - } else if (sel && tb->selected) { - - if (!tPtr->flags.ignoreNewLine && tb->blank) { - text = wrealloc(text, where + 1); - text[where++] = '\n'; - } - - if (tb->blank) - goto _gSnext; - - text = wrealloc(text, where + (tb->s_end - tb->s_begin)); - memcpy(&text[where], &tb->text[tb->s_begin], tb->s_end - tb->s_begin); - where += tb->s_end - tb->s_begin; - - } - - } - _gSnext: tb = tb->next; - } - - /* +1 for the end of string, let's be nice */ - text = wrealloc(text, where + 1); - text[where] = 0; - return text; -} - -static void releaseStreamObjects(void *data) -{ - if (data) - wfree(data); -} - -WMArray *getStreamObjects(WMText * tPtr, int sel) -{ - WMArray *array = WMCreateArrayWithDestructor(4, releaseStreamObjects); - WMData *data; - char *stream; - unsigned short len; - char *start, *fa, *desc; - - stream = getStream(tPtr, sel, 1); - if (!stream) - return NULL; - - start = stream; - while (start) { - - fa = strchr(start, 0xFA); - if (fa) { - if ((int)(fa - start) > 0) { - desc = start; - desc[(int)(fa - start)] = 0; - data = WMCreateDataWithBytes((void *)desc, (int)(fa - start)); - WMSetDataFormat(data, TYPETEXT); - WMAddToArray(array, (void *)data); - } - - len = *(fa + 1) * 0xff + *(fa + 2); - data = WMCreateDataWithBytes((void *)(fa + 4), len); - WMSetDataFormat(data, *(fa + 3)); - WMAddToArray(array, (void *)data); - start = fa + len + 4; - - } else { - if (start && strlen(start)) { - data = WMCreateDataWithBytes((void *)start, strlen(start)); - WMSetDataFormat(data, TYPETEXT); - WMAddToArray(array, (void *)data); - } - start = fa; - } - } - - wfree(stream); - return array; -} - -#define XDND_TEXT_DATA_TYPE "text/plain" -#define XDND_COLOR_DATA_TYPE "application/X-color" -static WMArray *getXdndSourceTypeArray() -{ - WMArray *types = WMCreateArray(1); - WMAddToArray(types, XDND_TEXT_DATA_TYPE); - return types; -} - -static WMArray *getXdndDestinationTypeArray() -{ - WMArray *types = WMCreateArray(1); - WMAddToArray(types, XDND_COLOR_DATA_TYPE); - return types; -} - -WMText *WMCreateTextForDocumentType(WMWidget * parent, WMAction * parser, WMAction * writer) -{ - Text *tPtr; - Display *dpy; - WMScreen *scr; - XGCValues gcv; - - tPtr = wmalloc(sizeof(Text)); - tPtr->widgetClass = WC_Text; - tPtr->view = W_CreateView(W_VIEW(parent)); - if (!tPtr->view) { - perror("could not create text's view\n"); - wfree(tPtr); - return NULL; - } - - dpy = tPtr->view->screen->display; - scr = tPtr->view->screen; - - tPtr->view->self = tPtr; - tPtr->view->attribs.cursor = scr->textCursor; - tPtr->view->attribFlags |= CWOverrideRedirect | CWCursor; - W_ResizeView(tPtr->view, 250, 200); - - tPtr->dColor = WMBlackColor(scr); - tPtr->fgColor = WMBlackColor(scr); - tPtr->bgColor = WMWhiteColor(scr); - W_SetViewBackgroundColor(tPtr->view, tPtr->bgColor); - - gcv.graphics_exposures = False; - gcv.foreground = W_PIXEL(scr->gray); - gcv.background = W_PIXEL(scr->darkGray); - gcv.fill_style = FillStippled; - /* why not use scr->stipple here? */ - gcv.stipple = XCreateBitmapFromData(dpy, W_DRAWABLE(scr), STIPPLE_BITS, STIPPLE_WIDTH, STIPPLE_HEIGHT); - tPtr->stippledGC = XCreateGC(dpy, W_DRAWABLE(scr), - GCForeground | GCBackground | GCStipple - | GCFillStyle | GCGraphicsExposures, &gcv); - - tPtr->ruler = NULL; - tPtr->vS = NULL; - tPtr->hS = NULL; - - tPtr->dFont = WMSystemFontOfSize(scr, 12); - - tPtr->view->delegate = &_TextViewDelegate; - - tPtr->delegate = NULL; - -#if DO_BLINK - tPtr->timerID = NULL; -#endif - - WMCreateEventHandler(tPtr->view, ExposureMask | StructureNotifyMask - | EnterWindowMask | LeaveWindowMask | FocusChangeMask, handleEvents, tPtr); - - WMCreateEventHandler(tPtr->view, ButtonReleaseMask | ButtonPressMask - | KeyReleaseMask | KeyPressMask | Button1MotionMask, handleActionEvents, tPtr); - - WMAddNotificationObserver(ownershipObserver, tPtr, WMSelectionOwnerDidChangeNotification, tPtr); - - WMSetViewDragSourceProcs(tPtr->view, &_DragSourceProcs); - WMSetViewDragDestinationProcs(tPtr->view, &_DragDestinationProcs); - - { - WMArray *types = WMCreateArray(2); - WMAddToArray(types, "application/X-color"); - WMAddToArray(types, "application/X-image"); - WMRegisterViewForDraggedTypes(tPtr->view, types); - } - - /*WMAddNotificationObserver(fontChanged, tPtr, - WMFontPanelDidChangeNotification, tPtr); */ - - tPtr->firstTextBlock = NULL; - tPtr->lastTextBlock = NULL; - tPtr->currentTextBlock = NULL; - tPtr->tpos = 0; - - tPtr->gfxItems = WMCreateArray(4); - - tPtr->parser = parser; - tPtr->writer = writer; - - tPtr->sel.x = tPtr->sel.y = 2; - tPtr->sel.w = tPtr->sel.h = 0; - - tPtr->clicked.x = tPtr->clicked.y = 2; - - tPtr->visible.x = tPtr->visible.y = 2; - tPtr->visible.h = tPtr->view->size.height; - tPtr->visible.w = tPtr->view->size.width - 4; - - tPtr->cursor.x = -23; - - tPtr->docWidth = 0; - tPtr->docHeight = 0; - tPtr->dBulletPix = WMCreatePixmapFromXPMData(tPtr->view->screen, default_bullet); - tPtr->db = (Pixmap) NULL; - tPtr->bgPixmap = NULL; - - tPtr->margins = WMGetRulerMargins(NULL); - tPtr->margins->right = tPtr->visible.w; - tPtr->nMargins = 1; - - tPtr->flags.rulerShown = False; - tPtr->flags.monoFont = False; - tPtr->flags.focused = False; - tPtr->flags.editable = True; - tPtr->flags.ownsSelection = False; - tPtr->flags.pointerGrabbed = False; - tPtr->flags.extendSelection = False; - tPtr->flags.frozen = False; - tPtr->flags.cursorShown = True; - tPtr->flags.acceptsGraphic = False; - tPtr->flags.horizOnDemand = False; - tPtr->flags.needsLayOut = False; - tPtr->flags.ignoreNewLine = False; - tPtr->flags.indentNewLine = False; - tPtr->flags.laidOut = False; - tPtr->flags.ownsSelection = False; - tPtr->flags.waitingForSelection = False; - tPtr->flags.prepend = False; - tPtr->flags.isOverGraphic = False; - tPtr->flags.relief = WRSunken; - tPtr->flags.isOverGraphic = 0; - tPtr->flags.alignment = WALeft; - tPtr->flags.first = True; - - tPtr->xdndSourceTypes = getXdndSourceTypeArray(); - tPtr->xdndDestinationTypes = getXdndDestinationTypeArray(); - - return tPtr; -} - -void WMPrependTextStream(WMText * tPtr, char *text) -{ - CHECK_CLASS(tPtr, WC_Text); - - if (!text) { - if (tPtr->flags.ownsSelection) - releaseSelection(tPtr); - clearText(tPtr); - updateScrollers(tPtr); - return; - } - - tPtr->flags.prepend = True; - if (text && tPtr->parser) - (tPtr->parser) (tPtr, (void *)text); - else - insertPlainText(tPtr, text); - - tPtr->flags.needsLayOut = True; - tPtr->tpos = 0; - if (!tPtr->flags.frozen) { - layOutDocument(tPtr); - } -} - -void WMAppendTextStream(WMText * tPtr, char *text) -{ - CHECK_CLASS(tPtr, WC_Text); - - if (!text) { - if (tPtr->flags.ownsSelection) - releaseSelection(tPtr); - clearText(tPtr); - updateScrollers(tPtr); - return; - } - - tPtr->flags.prepend = False; - if (text && tPtr->parser) - (tPtr->parser) (tPtr, (void *)text); - else - insertPlainText(tPtr, text); - - tPtr->flags.needsLayOut = True; - if (tPtr->currentTextBlock) { - if (tPtr->currentTextBlock->graphic) - tPtr->tpos = 1; - else - tPtr->tpos = tPtr->currentTextBlock->used; - } - - if (!tPtr->flags.frozen) { - layOutDocument(tPtr); - } -} - -char *WMGetTextStream(WMText * tPtr) -{ - CHECK_CLASS(tPtr, WC_Text); - - return getStream(tPtr, 0, 0); -} - -char *WMGetTextSelectedStream(WMText * tPtr) -{ - CHECK_CLASS(tPtr, WC_Text); - - return getStream(tPtr, 1, 0); -} - -WMArray *WMGetTextObjects(WMText * tPtr) -{ - CHECK_CLASS(tPtr, WC_Text); - - return getStreamObjects(tPtr, 0); -} - -WMArray *WMGetTextSelectedObjects(WMText * tPtr) -{ - CHECK_CLASS(tPtr, WC_Text); - - return getStreamObjects(tPtr, 1); -} - -void WMSetTextDelegate(WMText * tPtr, WMTextDelegate * delegate) -{ - CHECK_CLASS(tPtr, WC_Text); - - tPtr->delegate = delegate; -} - -void *WMCreateTextBlockWithObject(WMText * tPtr, WMWidget * w, - char *description, WMColor * color, - unsigned short first, unsigned short extraInfo) -{ - TextBlock *tb; - - if (!w || !description || !color) - return NULL; - - tb = wmalloc(sizeof(TextBlock)); - - tb->text = wstrdup(description); - tb->used = strlen(description); - tb->blank = False; - tb->d.widget = w; - tb->color = WMRetainColor(color); - tb->marginN = newMargin(tPtr, NULL); - tb->allocated = extraInfo; - tb->first = first; - tb->kanji = False; - tb->graphic = True; - tb->object = True; - tb->underlined = False; - tb->selected = False; - tb->script = 0; - tb->sections = NULL; - tb->nsections = 0; - tb->prior = NULL; - tb->next = NULL; - - return tb; -} - -void *WMCreateTextBlockWithPixmap(WMText * tPtr, WMPixmap * p, - char *description, WMColor * color, - unsigned short first, unsigned short extraInfo) -{ - TextBlock *tb; - - if (!p || !description || !color) - return NULL; - - tb = wmalloc(sizeof(TextBlock)); - - tb->text = wstrdup(description); - tb->used = strlen(description); - tb->blank = False; - tb->d.pixmap = WMRetainPixmap(p); - tb->color = WMRetainColor(color); - tb->marginN = newMargin(tPtr, NULL); - tb->allocated = extraInfo; - tb->first = first; - tb->kanji = False; - tb->graphic = True; - tb->object = False; - tb->underlined = False; - tb->selected = False; - tb->script = 0; - tb->sections = NULL; - tb->nsections = 0; - tb->prior = NULL; - tb->next = NULL; - - return tb; -} - -void *WMCreateTextBlockWithText(WMText * tPtr, char *text, WMFont * font, WMColor * color, - unsigned short first, unsigned short len) -{ - TextBlock *tb; - - if (!font || !color) - return NULL; - - tb = wmalloc(sizeof(TextBlock)); - - tb->allocated = reqBlockSize(len); - tb->text = (char *)wmalloc(tb->allocated); - - if (len < 1 || !text || (*text == '\n' && len == 1)) { - *tb->text = ' '; - tb->used = 1; - tb->blank = True; - } else { - memcpy(tb->text, text, len); - tb->used = len; - tb->blank = False; - } - tb->text[tb->used] = 0; - - tb->d.font = WMRetainFont(font); - tb->color = WMRetainColor(color); - tb->marginN = newMargin(tPtr, NULL); - tb->first = first; - tb->kanji = False; - tb->graphic = False; - tb->underlined = False; - tb->selected = False; - tb->script = 0; - tb->sections = NULL; - tb->nsections = 0; - tb->prior = NULL; - tb->next = NULL; - return tb; -} - -void -WMSetTextBlockProperties(WMText * tPtr, void *vtb, unsigned int first, - unsigned int kanji, unsigned int underlined, int script, WMRulerMargins * margins) -{ - TextBlock *tb = (TextBlock *) vtb; - if (!tb) - return; - - tb->first = first; - tb->kanji = kanji; - tb->underlined = underlined; - tb->script = script; - tb->marginN = newMargin(tPtr, margins); -} - -void -WMGetTextBlockProperties(WMText * tPtr, void *vtb, unsigned int *first, - unsigned int *kanji, unsigned int *underlined, int *script, WMRulerMargins * margins) -{ - TextBlock *tb = (TextBlock *) vtb; - if (!tb) - return; - - if (first) - *first = tb->first; - if (kanji) - *kanji = tb->kanji; - if (underlined) - *underlined = tb->underlined; - if (script) - *script = tb->script; - if (margins) - margins = &tPtr->margins[tb->marginN]; -} - -void WMPrependTextBlock(WMText * tPtr, void *vtb) -{ - TextBlock *tb = (TextBlock *) vtb; - - if (!tb) - return; - - if (tb->graphic) { - if (tb->object) { - WMWidget *w = tb->d.widget; - if (W_CLASS(w) != WC_TextField && W_CLASS(w) != WC_Text) { - (W_VIEW(w))->attribs.cursor = tPtr->view->screen->defaultCursor; - (W_VIEW(w))->attribFlags |= CWOverrideRedirect | CWCursor; - } - } - WMAddToArray(tPtr->gfxItems, (void *)tb); - tPtr->tpos = 1; - - } else { - tPtr->tpos = tb->used; - } - - if (!tPtr->lastTextBlock || !tPtr->firstTextBlock) { - tb->next = tb->prior = NULL; - tb->first = True; - tPtr->lastTextBlock = tPtr->firstTextBlock = tPtr->currentTextBlock = tb; - return; - } - - if (!tb->first) { - tb->marginN = tPtr->currentTextBlock->marginN; - } - - tb->next = tPtr->currentTextBlock; - tb->prior = tPtr->currentTextBlock->prior; - if (tPtr->currentTextBlock->prior) - tPtr->currentTextBlock->prior->next = tb; - - tPtr->currentTextBlock->prior = tb; - if (!tb->prior) - tPtr->firstTextBlock = tb; - - tPtr->currentTextBlock = tb; -} - -void WMAppendTextBlock(WMText * tPtr, void *vtb) -{ - TextBlock *tb = (TextBlock *) vtb; - - if (!tb) - return; - - if (tb->graphic) { - if (tb->object) { - WMWidget *w = tb->d.widget; - if (W_CLASS(w) != WC_TextField && W_CLASS(w) != WC_Text) { - (W_VIEW(w))->attribs.cursor = tPtr->view->screen->defaultCursor; - (W_VIEW(w))->attribFlags |= CWOverrideRedirect | CWCursor; - } - } - WMAddToArray(tPtr->gfxItems, (void *)tb); - tPtr->tpos = 1; - - } else { - tPtr->tpos = tb->used; - } - - if (!tPtr->lastTextBlock || !tPtr->firstTextBlock) { - tb->next = tb->prior = NULL; - tb->first = True; - tPtr->lastTextBlock = tPtr->firstTextBlock = tPtr->currentTextBlock = tb; - return; - } - - if (!tb->first) { - tb->marginN = tPtr->currentTextBlock->marginN; - } - - tb->next = tPtr->currentTextBlock->next; - tb->prior = tPtr->currentTextBlock; - if (tPtr->currentTextBlock->next) - tPtr->currentTextBlock->next->prior = tb; - - tPtr->currentTextBlock->next = tb; - - if (!tb->next) - tPtr->lastTextBlock = tb; - - tPtr->currentTextBlock = tb; -} - -void *WMRemoveTextBlock(WMText * tPtr) -{ - TextBlock *tb = NULL; - - if (!tPtr->firstTextBlock || !tPtr->lastTextBlock || !tPtr->currentTextBlock) { - return NULL; - } - - tb = tPtr->currentTextBlock; - if (tb->graphic) { - WMRemoveFromArray(tPtr->gfxItems, (void *)tb); - - if (tb->object) { - WMUnmapWidget(tb->d.widget); - } - } - - if (tPtr->currentTextBlock == tPtr->firstTextBlock) { - if (tPtr->currentTextBlock->next) - tPtr->currentTextBlock->next->prior = NULL; - - tPtr->firstTextBlock = tPtr->currentTextBlock->next; - tPtr->currentTextBlock = tPtr->firstTextBlock; - - } else if (tPtr->currentTextBlock == tPtr->lastTextBlock) { - tPtr->currentTextBlock->prior->next = NULL; - tPtr->lastTextBlock = tPtr->currentTextBlock->prior; - tPtr->currentTextBlock = tPtr->lastTextBlock; - } else { - tPtr->currentTextBlock->prior->next = tPtr->currentTextBlock->next; - tPtr->currentTextBlock->next->prior = tPtr->currentTextBlock->prior; - tPtr->currentTextBlock = tPtr->currentTextBlock->next; - } - - return (void *)tb; -} - -#if 0 -static void destroyWidget(WMWidget * widget) -{ - WMDestroyWidget(widget); - // -- never do this -- wfree(widget); -} -#endif - -void WMDestroyTextBlock(WMText * tPtr, void *vtb) -{ - TextBlock *tb = (TextBlock *) vtb; - if (!tb) - return; - - if (tb->graphic) { - if (tb->object) { - /* naturally, there's a danger to destroying widgets whose action - * brings us here: ie. press a button to destroy it... - * need to find a safer way. till then... this stays commented out */ - /* 5 months later... destroy it 10 seconds after now which should - * be enough time for the widget's action to be completed... :-) */ - /* This is a bad assumption. Just destroy the widget here. - * if the caller needs it, it can protect it with W_RetainView() - * WMAddTimerHandler(10000, destroyWidget, (void *)tb->d.widget);*/ - WMDestroyWidget(tb->d.widget); - } else { - WMReleasePixmap(tb->d.pixmap); - } - } else { - WMReleaseFont(tb->d.font); - } - - WMReleaseColor(tb->color); - /* isn't this going to memleak if nsections==0? if (tb->sections && tb->nsections > 0) */ - if (tb->sections) - wfree(tb->sections); - wfree(tb->text); - wfree(tb); -} - -void WMSetTextForegroundColor(WMText * tPtr, WMColor * color) -{ - if (tPtr->fgColor) - WMReleaseColor(tPtr->fgColor); - - tPtr->fgColor = WMRetainColor(color ? color : tPtr->view->screen->black); - - paintText(tPtr); -} - -void WMSetTextBackgroundColor(WMText * tPtr, WMColor * color) -{ - if (tPtr->bgColor) - WMReleaseColor(tPtr->bgColor); - - tPtr->bgColor = WMRetainColor(color ? color : tPtr->view->screen->white); - W_SetViewBackgroundColor(tPtr->view, tPtr->bgColor); - - paintText(tPtr); -} - -void WMSetTextBackgroundPixmap(WMText * tPtr, WMPixmap * pixmap) -{ - if (tPtr->bgPixmap) - WMReleasePixmap(tPtr->bgPixmap); - - if (pixmap) - tPtr->bgPixmap = WMRetainPixmap(pixmap); - else - tPtr->bgPixmap = NULL; -} - -void WMSetTextRelief(WMText * tPtr, WMReliefType relief) -{ - tPtr->flags.relief = relief; - textDidResize(tPtr->view->delegate, tPtr->view); -} - -void WMSetTextHasHorizontalScroller(WMText * tPtr, Bool shouldhave) -{ - if (shouldhave && !tPtr->hS) { - tPtr->hS = WMCreateScroller(tPtr); - (W_VIEW(tPtr->hS))->attribs.cursor = tPtr->view->screen->defaultCursor; - (W_VIEW(tPtr->hS))->attribFlags |= CWOverrideRedirect | CWCursor; - WMSetScrollerArrowsPosition(tPtr->hS, WSAMinEnd); - WMSetScrollerAction(tPtr->hS, scrollersCallBack, tPtr); - WMMapWidget(tPtr->hS); - } else if (!shouldhave && tPtr->hS) { - WMUnmapWidget(tPtr->hS); - WMDestroyWidget(tPtr->hS); - tPtr->hS = NULL; - } - - tPtr->hpos = 0; - tPtr->prevHpos = 0; - textDidResize(tPtr->view->delegate, tPtr->view); -} - -void WMSetTextHasRuler(WMText * tPtr, Bool shouldhave) -{ - if (shouldhave && !tPtr->ruler) { - tPtr->ruler = WMCreateRuler(tPtr); - (W_VIEW(tPtr->ruler))->attribs.cursor = tPtr->view->screen->defaultCursor; - (W_VIEW(tPtr->ruler))->attribFlags |= CWOverrideRedirect | CWCursor; - WMSetRulerReleaseAction(tPtr->ruler, rulerReleaseCallBack, tPtr); - WMSetRulerMoveAction(tPtr->ruler, rulerMoveCallBack, tPtr); - } else if (!shouldhave && tPtr->ruler) { - WMShowTextRuler(tPtr, False); - WMDestroyWidget(tPtr->ruler); - tPtr->ruler = NULL; - } - textDidResize(tPtr->view->delegate, tPtr->view); -} - -void WMShowTextRuler(WMText * tPtr, Bool show) -{ - if (!tPtr->ruler) - return; - - if (tPtr->flags.monoFont) - show = False; - - tPtr->flags.rulerShown = show; - if (show) { - WMMapWidget(tPtr->ruler); - } else { - WMUnmapWidget(tPtr->ruler); - } - - textDidResize(tPtr->view->delegate, tPtr->view); -} - -Bool WMGetTextRulerShown(WMText * tPtr) -{ - if (!tPtr->ruler) - return False; - - return tPtr->flags.rulerShown; -} - -void WMSetTextHasVerticalScroller(WMText * tPtr, Bool shouldhave) -{ - if (shouldhave && !tPtr->vS) { - tPtr->vS = WMCreateScroller(tPtr); - (W_VIEW(tPtr->vS))->attribs.cursor = tPtr->view->screen->defaultCursor; - (W_VIEW(tPtr->vS))->attribFlags |= CWOverrideRedirect | CWCursor; - WMSetScrollerArrowsPosition(tPtr->vS, WSAMaxEnd); - WMSetScrollerAction(tPtr->vS, scrollersCallBack, tPtr); - WMMapWidget(tPtr->vS); - } else if (!shouldhave && tPtr->vS) { - WMUnmapWidget(tPtr->vS); - WMDestroyWidget(tPtr->vS); - tPtr->vS = NULL; - } - - tPtr->vpos = 0; - tPtr->prevVpos = 0; - textDidResize(tPtr->view->delegate, tPtr->view); -} - -Bool WMScrollText(WMText * tPtr, int amount) -{ - Bool scroll = False; - - if (amount == 0 || !tPtr->view->flags.realized) - return False; - - if (amount < 0) { - if (tPtr->vpos > 0) { - if (tPtr->vpos > abs(amount)) - tPtr->vpos += amount; - else - tPtr->vpos = 0; - scroll = True; - } - } else { - int limit = tPtr->docHeight - tPtr->visible.h; - if (tPtr->vpos < limit) { - if (tPtr->vpos < limit - amount) - tPtr->vpos += amount; - else - tPtr->vpos = limit; - scroll = True; - } - } - - if (scroll && tPtr->vpos != tPtr->prevVpos) { - updateScrollers(tPtr); - paintText(tPtr); - } - tPtr->prevVpos = tPtr->vpos; - return scroll; -} - -Bool WMPageText(WMText * tPtr, Bool direction) -{ - if (!tPtr->view->flags.realized) - return False; - - return WMScrollText(tPtr, direction ? tPtr->visible.h : -tPtr->visible.h); -} - -void WMSetTextEditable(WMText * tPtr, Bool editable) -{ - tPtr->flags.editable = editable; -} - -int WMGetTextEditable(WMText * tPtr) -{ - return tPtr->flags.editable; -} - -void WMSetTextIndentNewLines(WMText * tPtr, Bool indent) -{ - tPtr->flags.indentNewLine = indent; -} - -void WMSetTextIgnoresNewline(WMText * tPtr, Bool ignore) -{ - tPtr->flags.ignoreNewLine = ignore; -} - -Bool WMGetTextIgnoresNewline(WMText * tPtr) -{ - return tPtr->flags.ignoreNewLine; -} - -void WMSetTextUsesMonoFont(WMText * tPtr, Bool mono) -{ - if (mono) { - if (tPtr->flags.rulerShown) - WMShowTextRuler(tPtr, False); - if (tPtr->flags.alignment != WALeft) - tPtr->flags.alignment = WALeft; - } - - tPtr->flags.monoFont = mono; - textDidResize(tPtr->view->delegate, tPtr->view); -} - -Bool WMGetTextUsesMonoFont(WMText * tPtr) -{ - return tPtr->flags.monoFont; -} - -void WMSetTextDefaultFont(WMText * tPtr, WMFont * font) -{ - if (tPtr->dFont) - WMReleaseFont(tPtr->dFont); - - if (font) { - tPtr->dFont = WMRetainFont(font); - } else { - tPtr->dFont = WMSystemFontOfSize(tPtr->view->screen, 12); - } -} - -WMFont *WMGetTextDefaultFont(WMText * tPtr) -{ - return WMRetainFont(tPtr->dFont); -} - -void WMSetTextDefaultColor(WMText * tPtr, WMColor * color) -{ - if (tPtr->dColor) - WMReleaseColor(tPtr->dColor); - - if (color) { - tPtr->dColor = WMRetainColor(color); - } else { - tPtr->dColor = WMBlackColor(tPtr->view->screen); - } -} - -WMColor *WMGetTextDefaultColor(WMText * tPtr) -{ - return tPtr->dColor; -} - -void WMSetTextAlignment(WMText * tPtr, WMAlignment alignment) -{ - if (tPtr->flags.monoFont) - tPtr->flags.alignment = WALeft; - else - tPtr->flags.alignment = alignment; - WMThawText(tPtr); -} - -int WMGetTextInsertType(WMText * tPtr) -{ - return tPtr->flags.prepend; -} - -void WMSetTextSelectionColor(WMText * tPtr, WMColor * color) -{ - setSelectionProperty(tPtr, NULL, color, -1); -} - -WMColor *WMGetTextSelectionColor(WMText * tPtr) -{ - TextBlock *tb; - - tb = tPtr->currentTextBlock; - - if (!tb || !tPtr->flags.ownsSelection) - return NULL; - - if (!tb->selected) - return NULL; - - return tb->color; -} - -void WMSetTextSelectionFont(WMText * tPtr, WMFont * font) -{ - setSelectionProperty(tPtr, font, NULL, -1); -} - -WMFont *WMGetTextSelectionFont(WMText * tPtr) -{ - TextBlock *tb; - - tb = tPtr->currentTextBlock; - - if (!tb || !tPtr->flags.ownsSelection) - return NULL; - - if (!tb->selected) - return NULL; - - if (tb->graphic) { - tb = getFirstNonGraphicBlockFor(tb, 1); - if (!tb) - return NULL; - } - return (tb->selected ? tb->d.font : NULL); -} - -void WMSetTextSelectionUnderlined(WMText * tPtr, int underlined) -{ - /* // check this */ - if (underlined != 0 && underlined != 1) - return; - - setSelectionProperty(tPtr, NULL, NULL, underlined); -} - -int WMGetTextSelectionUnderlined(WMText * tPtr) -{ - TextBlock *tb; - - tb = tPtr->currentTextBlock; - - if (!tb || !tPtr->flags.ownsSelection) - return 0; - - if (!tb->selected) - return 0; - - return tb->underlined; -} - -void WMFreezeText(WMText * tPtr) -{ - tPtr->flags.frozen = True; -} - -void WMThawText(WMText * tPtr) -{ - tPtr->flags.frozen = False; - - if (tPtr->flags.monoFont) { - int j, c = WMGetArrayItemCount(tPtr->gfxItems); - TextBlock *tb; - - /* make sure to unmap widgets no matter where they are */ - /* they'll be later remapped if needed by paintText */ - for (j = 0; j < c; j++) { - if ((tb = (TextBlock *) WMGetFromArray(tPtr->gfxItems, j))) { - if (tb->object && ((W_VIEW(tb->d.widget))->flags.mapped)) - WMUnmapWidget(tb->d.widget); - } - } - } - - tPtr->flags.laidOut = False; - layOutDocument(tPtr); - updateScrollers(tPtr); - paintText(tPtr); - tPtr->flags.needsLayOut = False; - -} - -/* find first occurence of a string */ -static char *mystrstr(char *haystack, char *needle, unsigned short len, char *end, Bool caseSensitive) -{ - char *ptr; - - if (!haystack || !needle || !end) - return NULL; - - for (ptr = haystack; ptr < end; ptr++) { - if (caseSensitive) { - if (*ptr == *needle && !strncmp(ptr, needle, len)) - return ptr; - - } else { - if (tolower(*ptr) == tolower(*needle) && !strncasecmp(ptr, needle, len)) - return ptr; - - } - } - return NULL; -} - -/* find last occurence of a string */ -static char *mystrrstr(char *haystack, char *needle, unsigned short len, char *end, Bool caseSensitive) -{ - char *ptr; - - if (!haystack || !needle || !end) - return NULL; - - for (ptr = haystack - 2; ptr > end; ptr--) { - if (caseSensitive) { - if (*ptr == *needle && !strncmp(ptr, needle, len)) - return ptr; - } else { - if (tolower(*ptr) == tolower(*needle) && !strncasecmp(ptr, needle, len)) - return ptr; - - } - } - return NULL; -} - -Bool WMFindInTextStream(WMText * tPtr, char *needle, Bool direction, Bool caseSensitive) -{ - TextBlock *tb; - char *mark = NULL; - unsigned short pos; - -#if 0 - if (!(tb = tPtr->currentTextBlock)) { - if (!(tb = ((direction > 0) ? tPtr->firstTextBlock : tPtr->lastTextBlock))) { - return False; - } - } else { - /* if(tb != ((direction>0) ?tPtr->firstTextBlock : tPtr->lastTextBlock)) - tb = (direction>0) ? tb->next : tb->prior; */ - if (tb != tPtr->lastTextBlock) - tb = tb->prior; - } -#endif - tb = tPtr->currentTextBlock; - pos = tPtr->tpos; - - while (tb) { - if (!tb->graphic) { - - if (direction > 0) { - if (pos + 1 < tb->used) - pos++; - - if (tb->used - pos > 0 && pos > 0) { - mark = mystrstr(&tb->text[pos], needle, - strlen(needle), &tb->text[tb->used], caseSensitive); - - } else { - tb = tb->next; - pos = 0; - continue; - } - - } else { - if (pos - 1 > 0) - pos--; - - if (pos > 0) { - mark = mystrrstr(&tb->text[pos], needle, - strlen(needle), tb->text, caseSensitive); - } else { - tb = tb->prior; - if (!tb) - return False; - pos = tb->used; - continue; - } - } - - if (mark) { - WMFont *font = tPtr->flags.monoFont ? tPtr->dFont : tb->d.font; - - tPtr->tpos = (int)(mark - tb->text); - tPtr->currentTextBlock = tb; - updateCursorPosition(tPtr); - tPtr->sel.y = tPtr->cursor.y + 5; - tPtr->sel.h = tPtr->cursor.h - 10; - tPtr->sel.x = tPtr->cursor.x + 1; - tPtr->sel.w = WMIN(WMWidthOfString(font, - &tb->text[tPtr->tpos], strlen(needle)), - tPtr->docWidth - tPtr->sel.x); - tPtr->flags.ownsSelection = True; - paintText(tPtr); - - return True; - } - - } - tb = (direction > 0) ? tb->next : tb->prior; - if (tb) { - pos = (direction > 0) ? 0 : tb->used; - } - } - - return False; -} - -Bool WMReplaceTextSelection(WMText * tPtr, char *replacement) -{ - if (!tPtr->flags.ownsSelection) - return False; - - removeSelection(tPtr); - - if (replacement) { - insertTextInteractively(tPtr, replacement, strlen(replacement)); - updateCursorPosition(tPtr); - paintText(tPtr); - } - - return True; - -}