119 #define SEL_RECT_ALL(X) ((X)->rctSel.left < 0) 120 #define SEL_RECT_EMPTY(X) (!SEL_RECT_ALL(X) && ((X)->rctSel.left == (X)->rctSel.right && (X)->rctSel.bottom == (X)->rctSel.top)) 121 #define NORMALIZE_SEL_RECT(X) {if(( (X).top > (X).bottom ) || ( (X).top == (X).bottom && (X).left > (X).right) ) \ 122 { int i1 = (X).left; (X).left = (X).right; (X).right = i1; \ 123 i1 = (X).top; (X).top = (X).bottom; (X).bottom = i1; }} 126 #define CURSOR_BLINK_RESET 0 127 #define CURSOR_BLINK_PERIOD 3 128 #define CURSOR_BLINK_OFF (CURSOR_BLINK_PERIOD - 1) 135 static void __internal_destroy(
TEXT_OBJECT *pThis);
137 static void __internal_highlight_colors(
TEXT_OBJECT *pThis, XColor clrHFG, XColor clrHBG);
138 static char * __internal_get_text(
TEXT_OBJECT *pThis);
139 static void __internal_set_text(
TEXT_OBJECT *pThis,
const char *szText,
unsigned long cbLen);
140 static int __internal_get_rows(
const TEXT_OBJECT *pThis);
141 static int __internal_get_cols(
TEXT_OBJECT *pThis);
142 static int __internal_get_filetype(
const TEXT_OBJECT *pThis);
143 static void __internal_set_filetype(
TEXT_OBJECT *pThis,
int iFileType);
144 static int __internal_get_linefeed(
const TEXT_OBJECT *pThis);
145 static void __internal_set_linefeed(
TEXT_OBJECT *pThis,
int iLineFeed);
146 static int __internal_get_insmode(
const TEXT_OBJECT *pThis);
147 static void __internal_set_insmode(
TEXT_OBJECT *pThis,
int iInsMode);
148 static int __internal_get_selmode(
const TEXT_OBJECT *pThis);
149 static void __internal_set_selmode(
TEXT_OBJECT *pThis,
int iSelMode);
150 static int __internal_get_tab(
const TEXT_OBJECT *pThis);
151 static void __internal_set_tab(
TEXT_OBJECT *pThis,
int iTab);
152 static int __internal_get_scrollmode(
const TEXT_OBJECT *pThis);
153 static void __internal_set_scrollmode(
TEXT_OBJECT *pThis,
int iScrollMode);
156 static int __internal_has_select(
const TEXT_OBJECT *pThis);
158 static int __internal_get_row(
const TEXT_OBJECT *pThis);
159 static void __internal_set_row(
TEXT_OBJECT *pThis,
int iRow);
160 static int __internal_get_col(
const TEXT_OBJECT *pThis);
161 static void __internal_set_col(
TEXT_OBJECT *pThis,
int iCol);
162 static void __internal_del_select(
TEXT_OBJECT *pThis);
163 static void __internal_replace_select(
TEXT_OBJECT *pThis,
const char *szText,
unsigned long cbLen);
164 static void __internal_del_chars(
TEXT_OBJECT *pThis,
int nChar);
165 static void __internal_ins_chars(
TEXT_OBJECT *pThis,
const char *pChar,
int nChar);
166 static void __internal_indent(
TEXT_OBJECT *pThis,
int nCol);
167 static int __internal_can_undo(
TEXT_OBJECT *pThis);
169 static int __internal_can_redo(
TEXT_OBJECT *pThis);
173 static void __internal_begin_highlight(
TEXT_OBJECT *pThis);
174 static void __internal_end_highlight(
TEXT_OBJECT *pThis);
176 static void __internal_mouse_click(
TEXT_OBJECT *pThis,
int iMouseXDelta,
int iMouseYDelta,
int iType,
int iACS);
177 static void __internal_begin_mouse_drag(
TEXT_OBJECT *pThis);
178 static void __internal_end_mouse_drag(
TEXT_OBJECT *pThis);
179 static void __internal_cursor_up(
TEXT_OBJECT *pThis);
180 static void __internal_cursor_down(
TEXT_OBJECT *pThis);
181 static void __internal_cursor_left(
TEXT_OBJECT *pThis);
182 static void __internal_cursor_right(
TEXT_OBJECT *pThis);
183 static void __internal_page_up(
TEXT_OBJECT *pThis);
184 static void __internal_page_down(
TEXT_OBJECT *pThis);
185 static void __internal_page_left(
TEXT_OBJECT *pThis);
186 static void __internal_page_right(
TEXT_OBJECT *pThis);
188 static void __internal_cursor_home(
TEXT_OBJECT *pThis);
189 static void __internal_cursor_end(
TEXT_OBJECT *pThis);
190 static void __internal_cursor_top(
TEXT_OBJECT *pThis);
191 static void __internal_cursor_bottom(
TEXT_OBJECT *pThis);
193 static void __internal_scroll_vertical(
TEXT_OBJECT *pThis,
int nRows);
194 static void __internal_scroll_horizontal(
TEXT_OBJECT *pThis,
int nCols);
199 static void __internal_cursor_blink(
TEXT_OBJECT *pThis,
int bHasFocus);
200 static int __internal_cursor_show(
int iBlinkState);
202 static void __internal_set_save_point(
TEXT_OBJECT *pThis);
203 static int __internal_get_modified(
TEXT_OBJECT *pThis);
214 __internal_highlight_colors,
219 __internal_get_filetype,
220 __internal_set_filetype,
221 __internal_get_linefeed,
222 __internal_set_linefeed,
223 __internal_get_insmode,
224 __internal_set_insmode,
225 __internal_get_selmode,
226 __internal_set_selmode,
229 __internal_get_scrollmode,
230 __internal_set_scrollmode,
231 __internal_get_select,
232 __internal_set_select,
233 __internal_has_select,
234 __internal_get_sel_text,
239 __internal_del_select,
240 __internal_replace_select,
241 __internal_del_chars,
242 __internal_ins_chars,
249 __internal_set_view_origin,
250 __internal_begin_highlight,
251 __internal_end_highlight,
252 __internal_mouse_click,
253 __internal_begin_mouse_drag,
254 __internal_end_mouse_drag,
255 __internal_cursor_up,
256 __internal_cursor_down,
257 __internal_cursor_left,
258 __internal_cursor_right,
260 __internal_page_down,
261 __internal_page_left,
262 __internal_page_right,
264 __internal_cursor_home,
265 __internal_cursor_end,
266 __internal_cursor_top,
267 __internal_cursor_bottom,
269 __internal_scroll_vertical,
270 __internal_scroll_horizontal,
273 __internal_cursor_blink,
275 __internal_set_save_point,
276 __internal_get_modified
288 static __inline__
const char * __internal_get_line_ending_text(
enum e_LineFeed iIndex)
296 #endif // WIN32 or POSIX - OS-dependent line endings 297 "\n",
"\r",
"\r\n",
"\n\r" 305 return szLineEndings[iIndex];
318 #define DEFAULT_TEXT_BUFFER_LINES 16384 326 if(pBuf && (cbBufSize || *pBuf))
330 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s line %d allocate for %d lines\n", __FUNCTION__, __LINE__, nLines);
333 if(nLines < DEFAULT_TEXT_BUFFER_LINES)
335 nLines = DEFAULT_TEXT_BUFFER_LINES;
338 cbLen =
sizeof(*pRval) + nLines *
sizeof(pRval->
aLines[0]);
343 WB_ERROR_PRINT(
"ERROR - %s - not enough memory (%ld)\n", __FUNCTION__,
344 (
unsigned long)(
sizeof(*pRval) + nLines *
sizeof(pRval->aLines[0])));
348 memset(pRval, 0, cbLen);
350 pRval->nArraySize = nLines;
353 if(pBuf && (cbBufSize || *pBuf))
360 cbBufSize = strlen(pBuf);
387 memcpy(p2, pBuf, cbLen);
393 while(p3 > p2 && (*(p3 - 1) <=
' ' ||
402 pRval->aLines[nL++] = p2;
408 }
while(pBuf && cbBufSize && nL < nLines);
410 pRval->nEntries = nL;
441 if(!ppBuf || !*ppBuf)
450 nNew = pBuf->
nEntries + nLinesToAdd;
454 nNew += DEFAULT_TEXT_BUFFER_LINES;
455 nNew -= (nNew % (DEFAULT_TEXT_BUFFER_LINES / 2));
457 pBuf =
WBReAlloc(pBuf,
sizeof(*pBuf) + nNew *
sizeof(pBuf->
aLines[0]));
498 if(!pBuf || pBuf->
nEntries <= nLine)
505 for(i1=0; i1 < TEXT_BUFFER_LINE_CACHE_SIZE && pBuf->
aLineCacheLen[i1]; i1++)
519 unsigned int nNewMax = 0, nNewMinMax = UINT_MAX;
524 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s line %d - (single line) nLine=%ld, nNewLen = %d\n",
525 __FUNCTION__, __LINE__, nLine, nNewLen);
537 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s line %d - nLine=%ld, nNewLen = %d\n",
538 __FUNCTION__, __LINE__, nLine, nNewLen);
545 while(i1 < TEXT_BUFFER_LINE_CACHE_SIZE && pBuf->aLineCacheLen[i1])
550 for(i2=i1 + 1; i2 < TEXT_BUFFER_LINE_CACHE_SIZE && pBuf->
aLineCacheLen[i2]; i2++)
558 if(i2 < TEXT_BUFFER_LINE_CACHE_SIZE)
574 if(nNewMax < pBuf->aLineCacheLen[i1])
591 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s exit (d) after WBTextBufferRefreshCache()\n", __FUNCTION__);
601 if(nNewMinMax <= nNewMax)
615 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s exit (c) after WBTextBufferRefreshCache()\n", __FUNCTION__);
621 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s exit (c)\n", __FUNCTION__);
632 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s exit (f)\n", __FUNCTION__);
642 if(nNewLen < nNewMinMax)
651 while(i2 < TEXT_BUFFER_LINE_CACHE_SIZE && pBuf->aLineCacheLen[i2])
663 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s exit (a)\n", __FUNCTION__);
673 if(i2 < TEXT_BUFFER_LINE_CACHE_SIZE)
676 for(i1=TEXT_BUFFER_LINE_CACHE_SIZE - 1; i1 > i2; i1--)
688 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s exit (b)\n", __FUNCTION__);
693 int iLine, i1, i2, i3;
731 for(iLine=0; iLine < pBuf->
nEntries; iLine++)
755 while(i2 < TEXT_BUFFER_LINE_CACHE_SIZE && pBuf->aLineCacheLen[i2])
765 if(i2 >= TEXT_BUFFER_LINE_CACHE_SIZE)
770 else if(i2 == TEXT_BUFFER_LINE_CACHE_SIZE - 1)
787 while(i3 < TEXT_BUFFER_LINE_CACHE_SIZE && pBuf->aLineCacheLen[i3])
803 while(i3 < TEXT_BUFFER_LINE_CACHE_SIZE)
819 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s exit point\n", __FUNCTION__);
853 "%s line %d: pObj iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
854 __FUNCTION__, __LINE__,
868 iFontHeight = iAscent + iDescent;
873 iFontHeight += iDescent / 2;
884 unsigned long (*callback)(
TEXT_OBJECT *pThis,
int nX,
int nY),
885 void *pColorContextPointer)
910 static void __internal_free_undo_redo_buffer(
void *pBuffer)
929 #define UNDO_LIMIT 256 932 static void __internal_add_undo(
TEXT_OBJECT *pThis,
int iOperation,
int iSelMode,
933 int iStartRow,
int iStartCol,
const WB_RECT *prctStartSel,
934 const char *pStartText,
int cbStartText,
935 int iEndRow,
int iEndCol,
const WB_RECT *prctEndSel,
936 const char *pEndText,
int cbEndText)
938 int cbLen, cbLen2, i1;
948 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
949 __FUNCTION__, __LINE__,
961 cbStartText = strlen(pStartText);
966 cbLen += cbStartText;
974 cbEndText = strlen(pEndText);
988 WB_ERROR_PRINT(
"ERROR - %s - unable to create undo buffer, errno=%d\n", __FUNCTION__, errno);
992 pUndo->iOperation = iOperation;
993 pUndo->iSelMode = iSelMode;
997 memcpy(&(pUndo->rctSelOld), prctStartSel,
sizeof(
WB_RECT));
1001 memset(&(pUndo->rctSelOld), 0,
sizeof(
WB_RECT));
1006 memcpy(&(pUndo->rctSelNew), prctEndSel,
sizeof(
WB_RECT));
1010 memset(&(pUndo->rctSelNew), 0,
sizeof(
WB_RECT));
1015 pUndo->nOld = cbLen;
1018 memcpy(pUndo->aData, pStartText, cbLen);
1019 pUndo->aData[cbLen++] = 0;
1022 pUndo->nOld = cbLen;
1026 memcpy(pUndo->aData + cbLen, pEndText, cbLen2);
1027 pUndo->aData[cbLen + cbLen2++] = 0;
1030 pUndo->nNew = cbLen2;
1035 pThis->
pUndo = pUndo;
1044 for(i1=1; i1 < UNDO_LIMIT && pTU->pNext; pTU = pTU->pNext, i1++) { }
1053 __internal_free_undo_redo_buffer(pTU2);
1061 pThis->
pRedo = NULL;
1063 __internal_free_undo_redo_buffer(pTU);
1081 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
1082 __FUNCTION__, __LINE__,
1089 cbLen = pUndo->nOld + pUndo->nNew +
sizeof(*pUndo);
1097 WB_ERROR_PRINT(
"ERROR - %s - unable to create redo buffer, errno=%d\n", __FUNCTION__, errno);
1101 memcpy(pRedo, pUndo, cbLen);
1106 pThis->
pRedo = pRedo;
1125 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
1126 __FUNCTION__, __LINE__,
1135 if(pUndo->iOperation == UNDO_SELECT)
1138 else if(pUndo->iOperation == UNDO_DELETE)
1142 else if(pUndo->iOperation == UNDO_INSERT)
1146 else if(pUndo->iOperation == UNDO_REPLACE)
1150 else if(pUndo->iOperation == UNDO_INDENT)
1170 __internal_add_redo(pThis, pUndo);
1187 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
1188 __FUNCTION__, __LINE__,
1192 cbLen = pRedo->nOld + pRedo->nNew +
sizeof(*pRedo);
1199 if(pRedo->iOperation == UNDO_SELECT)
1202 else if(pRedo->iOperation == UNDO_DELETE)
1206 else if(pRedo->iOperation == UNDO_INSERT)
1210 else if(pRedo->iOperation == UNDO_REPLACE)
1214 else if(pRedo->iOperation == UNDO_INDENT)
1242 WB_ERROR_PRINT(
"ERROR - %s - unable to create undo buffer from redo buffer, errno=%d\n", __FUNCTION__, errno);
1246 memcpy(pNewUndo, pRedo, cbLen);
1251 pThis->
pUndo = pNewUndo;
1263 static char * __internal_get_selected_text(
const TEXT_OBJECT *pThis,
1264 int iRow,
int iCol,
int iEndRow,
int iEndCol)
1266 int i1, i2, i3, cb1, cbLF=0;
1267 char *p1, *pRval = NULL;
1268 const char *szLineFeed = NULL;
1270 int iIsBoxMode, iIsLineMode;
1276 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
1277 __FUNCTION__, __LINE__,
1281 WB_DEBUG_PRINT(DebugLevel_Verbose,
"calling %s(%d,%d,%d,%d)\n", __FUNCTION__, iRow, iCol, iEndRow, iEndCol);
1307 iIsBoxMode = iIsLineMode = 0;
1329 || (iRow == iEndRow && iCol >= iEndCol)
1342 cb1 = (iEndRow - iRow + 1) * (2 + iEndCol - iCol);
1348 for(i1=iRow, cb1=4; i1 < pTB->
nEntries && i1 <= iEndRow; i1++)
1350 i2 = strlen(pTB->
aLines[i1]);
1368 szLineFeed = __internal_get_line_ending_text(pThis->
iLineFeed);
1380 cbLF = strlen(szLineFeed);
1388 for(i1=iRow, p1 = pRval; i1 < pTB->
nEntries && i1 <= iEndRow; i1++)
1390 char *pTheLine = pTB->
aLines[i1];
1393 i2 = i3 = strlen(pTheLine);
1432 else if(!iIsLineMode)
1439 else if(iEndCol == 0)
1446 if(!iIsBoxMode && !iIsLineMode && i1 == iRow)
1453 if(iIsLineMode || i1 > iCol)
1455 memcpy(p1, pTheLine, i2);
1477 memset(p1,
' ', i2);
1485 (iIsLineMode && iEndCol > 0) ||
1490 memcpy(p1, szLineFeed, cbLF);
1503 static void __internal_invalidate_cursor(
const TEXT_OBJECT *pThis,
int bPaintFlag)
1510 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
1511 __FUNCTION__, __LINE__,
1532 static void __internal_invalidate_rect(
TEXT_OBJECT *pThis,
WB_RECT *pRect,
int bPaintFlag)
1539 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
1540 __FUNCTION__, __LINE__,
1549 XClientMessageEvent evt;
1551 bzero(&evt,
sizeof(evt));
1552 evt.type = ClientMessage;
1563 WB_DEBUG_PRINT(DebugLevel_Light | DebugSubSystem_EditWindow | DebugSubSystem_Expose,
1564 "%s,%d - force recalc layout, window %u (%08xH)\n",
1570 WB_DEBUG_PRINT(DebugLevel_Medium | DebugSubSystem_EditWindow | DebugSubSystem_Expose,
1571 "%s - invalidate entire window %u (%08xH)\n",
1578 memcpy(&rctInvalid, pRect,
sizeof(*pRect));
1599 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s line %d - invalidate %d,%d,%d,%d for %u (%08xH)\n",
1600 __FUNCTION__, __LINE__,
1621 int iStartRow,
int iStartCol,
int iEndRow,
int iEndCol)
1630 memset(pRect, 0,
sizeof(*pRect));
1637 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
1638 __FUNCTION__, __LINE__,
1658 iFontHeight = pThis->
iAsc + pThis->
iDesc;
1669 pRect->
bottom = pRect->
top + iFontHeight;
1676 pRect->
right = INT_MAX;
1687 if(iStartRow == iEndRow)
1694 pRect->
right = INT_MAX;
1702 pRect->
bottom = pRect->
top + iFontHeight;
1708 pRect->
right = INT_MAX;
1713 + iFontHeight * (iStartRow - pThis->
rctView.
top);
1718 + iFontHeight * (iEndRow + 1 - pThis->
rctView.
top);
1723 + iFontHeight * (iEndRow - pThis->
rctView.
top);
1726 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s line %d - merged rect %d,%d,%d,%d\n",
1727 __FUNCTION__, __LINE__,
1734 int iStartRow,
int iStartCol,
int iEndRow,
int iEndCol)
1742 memset(pRect, 0,
sizeof(*pRect));
1749 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
1750 __FUNCTION__, __LINE__,
1754 __internal_calc_rect(pThis, &rctMerge, iStartRow, iStartCol, iEndRow, iEndCol);
1760 if(rctMerge.
top < pRect->
top)
1762 pRect->
top = rctMerge.
top;
1779 static void __internal_destroy(
TEXT_OBJECT *pThis)
1784 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
1785 __FUNCTION__, __LINE__,
1795 pThis->
pText = NULL;
1800 __internal_free_undo_redo_buffer(pThis->
pUndo);
1801 pThis->
pUndo = NULL;
1802 __internal_free_undo_redo_buffer(pThis->
pRedo);
1803 pThis->
pRedo = NULL;
1827 pThis->
pText = NULL;
1828 pThis->
pUndo = NULL;
1829 pThis->
pRedo = NULL;
1834 char szHFG[16], szHBG[16];
1847 #define COPY_COLOR_NAME(X,Y,Z) {const char *pX = X(WBGetDefaultDisplay()); if(pX) strncpy(Y,pX,sizeof(Y)); else strncpy(Y,Z,sizeof(Y));} 1865 static void __internal_highlight_colors(
TEXT_OBJECT *pThis, XColor clrHFG, XColor clrHBG)
1870 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
1871 __FUNCTION__, __LINE__,
1880 static char * __internal_get_text(
TEXT_OBJECT *pThis)
1882 return __internal_get_selected_text(pThis, -1, -1, -1, -1);
1885 static void __internal_set_text(
TEXT_OBJECT *pThis,
const char *szText,
unsigned long cbLen)
1892 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
1893 __FUNCTION__, __LINE__,
1908 pThis->
pText = pTemp;
1917 WB_ERROR_PRINT(
"TEXT OBJECT: %s - not enough memory for TEXT BUFFER errno=%d (no change)\n", __FUNCTION__, errno);
1922 WB_ERROR_PRINT(
"ERROR - %s - NOT a valid TEXT_OBJECT - %p\n", __FUNCTION__, pThis);
1931 static int __internal_get_rows(
const TEXT_OBJECT *pThis)
1938 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
1939 __FUNCTION__, __LINE__,
1959 static int __internal_get_cols(
TEXT_OBJECT *pThis)
1967 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
1968 __FUNCTION__, __LINE__,
1997 else if(pThis->
iCol > 0)
2009 static int __internal_get_filetype(
const TEXT_OBJECT *pThis)
2017 static void __internal_set_filetype(
TEXT_OBJECT *pThis,
int iFileType)
2022 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
2023 __FUNCTION__, __LINE__,
2035 static int __internal_get_linefeed(
const TEXT_OBJECT *pThis)
2043 static void __internal_set_linefeed(
TEXT_OBJECT *pThis,
int iLineFeed)
2048 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
2049 __FUNCTION__, __LINE__,
2056 static int __internal_get_insmode(
const TEXT_OBJECT *pThis)
2064 static void __internal_set_insmode(
TEXT_OBJECT *pThis,
int iInsMode)
2069 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
2070 __FUNCTION__, __LINE__,
2078 __internal_invalidate_cursor(pThis, 1);
2081 static int __internal_get_selmode(
const TEXT_OBJECT *pThis)
2089 static void __internal_set_selmode(
TEXT_OBJECT *pThis,
int iSelMode)
2094 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
2095 __FUNCTION__, __LINE__,
2102 static int __internal_get_tab(
const TEXT_OBJECT *pThis)
2111 static void __internal_set_tab(
TEXT_OBJECT *pThis,
int iTab)
2116 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
2117 __FUNCTION__, __LINE__,
2124 static int __internal_get_scrollmode(
const TEXT_OBJECT *pThis)
2132 static void __internal_set_scrollmode(
TEXT_OBJECT *pThis,
int iScrollMode)
2137 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
2138 __FUNCTION__, __LINE__,
2150 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
2151 __FUNCTION__, __LINE__,
2157 if(SEL_RECT_ALL(pThis))
2166 memcpy(pRct, &(pThis->
rctSel),
sizeof(*pRct));
2168 if(!SEL_RECT_EMPTY(pThis))
2170 NORMALIZE_SEL_RECT(*pRct);
2183 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
2184 __FUNCTION__, __LINE__,
2195 memcpy(&(pThis->
rctSel), pRct,
sizeof(*pRct));
2199 static int __internal_has_select(
const TEXT_OBJECT *pThis)
2203 return !SEL_RECT_EMPTY(pThis);
2214 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
2215 __FUNCTION__, __LINE__,
2225 else if(pRct->
left < 0)
2227 return __internal_get_selected_text(pThis, -1, -1, -1, -1);
2230 memcpy(&rctSel, pRct,
sizeof(rctSel));
2234 if(SEL_RECT_EMPTY(pThis))
2238 else if(SEL_RECT_ALL(pThis))
2240 return __internal_get_selected_text(pThis, -1, -1, -1, -1);
2243 memcpy(&rctSel, &(pThis->
rctSel),
sizeof(rctSel));
2246 NORMALIZE_SEL_RECT(rctSel);
2248 return __internal_get_selected_text(pThis, rctSel.
top, rctSel.
left,
2253 static int __internal_get_row(
const TEXT_OBJECT *pThis)
2261 static void __internal_set_row(
TEXT_OBJECT *pThis,
int iRow)
2266 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
2267 __FUNCTION__, __LINE__,
2271 if(iRow < 0 || !pThis->pText)
2283 static int __internal_get_col(
const TEXT_OBJECT *pThis)
2291 static void __internal_set_col(
TEXT_OBJECT *pThis,
int iCol)
2299 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
2300 __FUNCTION__, __LINE__,
2313 iAutoScrollWidth >>= 1;
2338 static void __internal_del_select(
TEXT_OBJECT *pThis)
2341 int iSelAll, iLen, i1, i2;
2349 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
2350 __FUNCTION__, __LINE__,
2354 __internal_invalidate_cursor(pThis, 0);
2357 iSelAll = SEL_RECT_ALL(pThis);
2359 if(!iSelAll && SEL_RECT_EMPTY(pThis))
2361 WB_DEBUG_PRINT(DebugLevel_Medium | DebugSubSystem_TextObject,
"%s line %d - empty selection\n", __FUNCTION__, __LINE__);
2372 "%s line %d: no selection to delete\n", __FUNCTION__, __LINE__);
2380 memcpy(&rctSel, &(pThis->
rctSel),
sizeof(rctSel));
2384 pTemp = __internal_get_selected_text(pThis, -1, -1, -1, -1);
2388 NORMALIZE_SEL_RECT(rctSel);
2390 pTemp = __internal_get_selected_text(pThis, rctSel.
top, rctSel.
left,
2397 "%s line %d: delete 'select all'\n", __FUNCTION__, __LINE__);
2402 pThis->
pText = NULL;
2407 __internal_add_undo(pThis, UNDO_DELETE, pThis->
iSelMode,
2408 0, 0, &(pThis->
rctSel), pTemp, -1,
2417 "%s line %d: delete single line, %d to %d (top=%d, bottom=%d)\n",
2418 __FUNCTION__, __LINE__,
2426 if(iLen >= rctSel.
left)
2428 if(iLen <= rctSel.
right)
2441 if(pTempL && pTempR)
2443 strcpy(pTempL, pTempR);
2451 __internal_add_undo(pThis, UNDO_DELETE, pThis->
iSelMode,
2464 iAutoScrollWidth >>= 1;
2486 "%s line %d: BOX MODE delete multiline, %d,%d to %d,%d\n",
2487 __FUNCTION__, __LINE__,
2494 "%s line %d: LINE MODE delete multiline, %d,%d to %d,%d\n",
2495 __FUNCTION__, __LINE__,
2502 "%s line %d: delete multiline, %d,%d to %d,%d\n",
2503 __FUNCTION__, __LINE__,
2511 if(rctSel.
right > 0)
2520 WB_ERROR_PRINT(
"ERROR - %s - memory allocation error, errno=%d\n", __FUNCTION__, errno);
2542 for(i1=pThis->
rctSel.
top + 1; i2 < pBuf->nEntries; i1++, i2++)
2556 if(rctSel.
right == 0)
2558 for(i1=rctSel.
top, i2=rctSel.
bottom; i2 < pBuf->nEntries; i1++, i2++)
2597 for(i1=rctSel.
top + 1, i2=rctSel.
bottom + 1; i2 < pBuf->nEntries; i1++, i2++)
2626 else if((rctSel.
bottom - rctSel.
top) == 1)
2637 __internal_add_undo(pThis, UNDO_DELETE, pThis->
iSelMode,
2670 WB_WARN_PRINT(
"WARNING - %s line %d - rctSel.top == %d\n", __FUNCTION__, __LINE__, rctSel.
top);
2674 if(rctSel.
left >= 0)
2678 WB_WARN_PRINT(
"WARNING - %s line %d - rctSel.left == %d\n", __FUNCTION__, __LINE__, rctSel.
left);
2688 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s line %d - need to optimize invalidate rect\n", __FUNCTION__, __LINE__);
2690 __internal_invalidate_rect(pThis, NULL, 1);
2693 static void __internal_replace_select(
TEXT_OBJECT *pThis,
const char *szText,
unsigned long cbLen)
2704 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
2705 __FUNCTION__, __LINE__,
2709 if(pThis->
iRow < 0 || pThis->
iCol< 0)
2720 iSelAll = SEL_RECT_ALL(pThis);
2722 memcpy(&rctSel, &(pThis->
rctSel),
sizeof(rctSel));
2729 else if(!SEL_RECT_EMPTY(pThis))
2731 NORMALIZE_SEL_RECT(rctSel);
2741 if(!iSelAll && SEL_RECT_EMPTY(pThis))
2743 WB_DEBUG_PRINT(DebugLevel_Medium | DebugSubSystem_TextObject,
"%s line %d - replace an empty select\n", __FUNCTION__, __LINE__);
2745 __internal_ins_chars(pThis, szText, cbLen);
2753 __internal_del_select(pThis);
2756 __internal_ins_chars(pThis, szText, cbLen);
2763 memcpy(&(pThis->
rctSel), &rctSel,
sizeof(pThis->
rctSel));
2779 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s line %d - need to optimize invalidate rect\n", __FUNCTION__, __LINE__);
2780 __internal_invalidate_rect(pThis, NULL, 1);
2786 static void __internal_del_chars(
TEXT_OBJECT *pThis,
int nChar)
2790 char *pL, *pL2, *pL3;
2811 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
2812 __FUNCTION__, __LINE__,
2816 __internal_invalidate_cursor(pThis, 0);
2821 __internal_calc_rect(pThis, &rctInvalid, pThis->
iRow, pThis->
iCol, pThis->
iRow, pThis->
iCol + 1);
2823 else if(pThis->
iCol > 0)
2825 __internal_calc_rect(pThis, &rctInvalid, pThis->
iRow, pThis->
iCol - 1, pThis->
iRow, pThis->
iCol);
2829 __internal_calc_rect(pThis, &rctInvalid, pThis->
iRow - 1, 0, -1, -1);
2854 if(nChar < 0 && pThis->iCol == 0 &&
2857 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s - backspace while I'm at start of file\n", __FUNCTION__);
2861 if(nChar > 0 && pThis->
iCol >= iLen &&
2865 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s - delete while I'm past end of file\n", __FUNCTION__);
2873 pThis->
iRow > 0 && pThis->
iCol == 0)
2897 WB_ERROR_PRINT(
"ERROR: %s - not enough memory to join lines\n", __FUNCTION__);
2933 for(i1=pThis->
iRow + 1; i1 < pBuf->nEntries; i1++)
2951 __internal_add_undo(pThis, UNDO_DELETE, pThis->
iSelMode,
2954 pThis->
iRow + 1, 0, NULL, NULL, 0);
2956 __internal_merge_rect(pThis, &rctInvalid, pThis->
iRow, 0, -1, -1);
2958 else if(nChar > 0 &&
2969 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s - joining \"%s\" at %d with \"%s\"\n", __FUNCTION__,
2970 pL, pThis->
iCol, pL2);
2976 WB_ERROR_PRINT(
"ERROR: %s - not enough memory to join\n", __FUNCTION__);
2990 for(i1=pThis->
iRow + 1; i1 < pBuf->nEntries; i1++)
3004 __internal_add_undo(pThis, UNDO_DELETE, pThis->
iSelMode,
3007 pThis->
iRow + 1, 0, NULL, NULL, 0);
3010 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s %d - fix the optimization for __internal_merge_rect\n", __FUNCTION__, __LINE__);
3014 __internal_merge_rect(pThis, &rctInvalid, 0, 0, -1, -1);
3032 if(nChar < 0 && pThis->iCol > 0)
3039 if(i2 > pThis->
iCol)
3056 for(i2a=0; i2a < i2; i2a++)
3061 if(pL2a && (pL3a - pL2a) == 1 &&
3062 ((
unsigned char)*pL2a == (
unsigned char)
HARD_TAB_CHAR || *pL2a ==
'\t'))
3064 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s %d - hard tab (%02xH) at row %d column %d\n",
3065 __FUNCTION__, __LINE__, (
unsigned char)*pL2a,
3066 pThis->
iRow, pThis->
iCol - i2 + i2a);
3073 __internal_add_undo(pThis, UNDO_DELETE, pThis->
iSelMode,
3076 pThis->
iRow, pThis->
iCol, NULL, NULL, 0);
3087 __internal_merge_rect(pThis, &rctInvalid, pThis->
iRow, pThis->
iCol, pThis->
iRow, -1);
3089 else if(nChar > 0 && iLen > pThis->
iCol)
3095 if(i2 > iLen - pThis->
iCol)
3097 i2 = iLen - pThis->
iCol;
3112 for(i2a=0; i2a < i2; i2a++)
3117 if(pL3a && (pL2a - pL3a) == 1 &&
3118 ((
unsigned char)*pL3a == (
unsigned char)
HARD_TAB_CHAR || *pL3a ==
'\t'))
3120 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s %d - hard tab (%02xH) at row %d column %d\n",
3121 __FUNCTION__, __LINE__, (
unsigned char)*pL3a,
3122 pThis->
iRow, pThis->
iCol - i2 + i2a);
3128 __internal_add_undo(pThis, UNDO_DELETE, pThis->
iSelMode,
3131 pThis->
iRow, pThis->
iCol + nChar, NULL, NULL, 0);
3142 __internal_merge_rect(pThis, &rctInvalid, pThis->
iRow, pThis->
iCol, pThis->
iRow, -1);
3149 WB_ERROR_PRINT(
"UNEXPECTED: %s - nChar=%d, iCol=%d, iRow=%d nEntries=%d\n",
3167 iAutoScrollWidth >>= 1;
3188 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s line %d - need to optimize invalidate rect\n", __FUNCTION__, __LINE__);
3189 __internal_invalidate_rect(pThis, NULL, 1);
3198 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s line %d - need to optimize invalidate rect\n", __FUNCTION__, __LINE__);
3200 __internal_invalidate_rect(pThis, NULL, 1);
3212 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s line %d - need to optimize invalidate rect\n", __FUNCTION__, __LINE__);
3214 __internal_invalidate_rect(pThis, NULL, 1);
3220 static void __internal_ins_chars(
TEXT_OBJECT *pThis,
const char *pChar,
int nChar)
3223 const char *p1, *p2;
3225 int i1, iLen=0, iMultiLine = 0;
3229 if(!pChar || !nChar)
3236 nChar = strlen(pChar);
3247 if(*p1 ==
'\n' || *p1 ==
'\r')
3256 __internal_invalidate_cursor(pThis, 0);
3261 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
3262 __FUNCTION__, __LINE__,
3266 if(pThis->
iRow < 0 || pThis->
iCol< 0)
3272 __internal_invalidate_cursor(pThis, 0);
3276 __internal_calc_rect(pThis, &rctInvalid, pThis->
iRow, pThis->
iCol, pThis->
iRow, -1);
3301 __internal_add_undo(pThis, UNDO_INSERT, pThis->
iSelMode,
3308 if(pThis->
iRow != 0)
3332 memset(pL,
' ', pThis->
iCol);
3333 pL[pThis->
iCol] = 0;
3347 if(iLen < pThis->iCol)
3349 i1 += pThis->
iCol - iLen;
3353 iLen >= pThis->
iCol)
3361 i1 = (pTempC - pTemp) + (p2 - p1);
3393 if(iLen < pThis->iCol)
3395 pTempL = pL + strlen(pL);
3397 memset(pTempL,
' ', pThis->
iCol - iLen);
3399 pTempL += pThis->
iCol - iLen;
3402 else if(iLen > pThis->
iCol &&
3410 memmove(pTempL + (p2 - p1), pTempL, strlen(pTempL) + 1);
3413 else if((p2 - p1) + pThis->
iCol >= iLen)
3417 pTempL[p2 - p1] = 0;
3420 __internal_add_undo(pThis, UNDO_INSERT, pThis->
iSelMode,
3423 pL + pThis->
iCol : NULL),
3426 pThis->
iRow, pThis->
iCol + (p2 - p1), NULL,
3429 memcpy(pL + pThis->
iCol, p1, p2 - p1);
3455 pThis->
iCol = nChar;
3457 __internal_add_undo(pThis, UNDO_INSERT, pThis->
iSelMode,
3465 const char *p3 = pChar + nChar;
3474 while(p2 < p3 && *p2 !=
'\n' && *p2 !=
'\r')
3514 + nTabs * pThis->
iTab 3521 memset(pL,
' ', pThis->
iCol);
3524 pL[pThis->
iCol] = 0;
3535 WB_ERROR_PRINT(
"ERROR: %s - not enough memory to add line\n", __FUNCTION__);
3539 pThis->
pText = pBuf;
3554 if(iLen < pThis->iCol)
3556 i1 += pThis->
iCol - iLen;
3560 && iLen > pThis->
iCol)
3562 if(iLen < pThis->iCol + (p2 - p1))
3564 i1 += (p2 - p1) - (iLen - pThis->
iCol);
3575 + nTabs * pThis->
iTab 3581 + nTabs * pThis->
iTab 3598 if(iLen < pThis->iCol)
3602 memset(pTemp,
' ', pThis->
iCol - iLen);
3603 pTemp[pThis->
iCol - iLen] = 0;
3607 else if(iLen > pThis->
iCol &&
3613 memmove(pL + pThis->
iCol + (p2 - p1), pL + pThis->
iCol, iLen - pThis->
iCol + 1);
3617 else if((p2 - p1) + pThis->
iCol >= iLen)
3619 pL[pThis->
iCol + p2 - p1] = 0;
3622 __internal_add_undo(pThis, UNDO_INSERT, pThis->
iSelMode,
3625 pL + pThis->
iCol : NULL),
3628 pThis->
iRow, pThis->
iCol + (p2 - p1), NULL,
3631 memcpy(pL + pThis->
iCol, p1, p2 - p1);
3637 pThis->
iCol += p2 - p1;
3642 if(p2 < p3 && (*p2 ==
'\r' || *p2 ==
'\n'))
3648 if(p2 < p3 && *p2 != c1 &&
3649 (*p2 ==
'\r' || *p2 ==
'\n'))
3658 WB_ERROR_PRINT(
"ERROR: %s - not enough memory to add line\n", __FUNCTION__);
3664 pThis->
pText = pBuf;
3666 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s - split line, %d, %d, %d\n", __FUNCTION__,
3683 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s - split line into \"%s\", \"%s\"\n", __FUNCTION__,
3702 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s line %d - need to optimize invalidate rect\n", __FUNCTION__, __LINE__);
3704 __internal_invalidate_rect(pThis, NULL, 1);
3719 iAutoScrollWidth >>= 1;
3735 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s line %d - need to optimize invalidate rect\n", __FUNCTION__, __LINE__);
3736 __internal_invalidate_rect(pThis, NULL, 1);
3740 __internal_invalidate_rect(pThis, &rctInvalid, 1);
3745 WB_WARN_PRINT(
"WARNING: %s line %d - invalidate entire window rect\n", __FUNCTION__, __LINE__);
3747 __internal_invalidate_rect(pThis, NULL, 1);
3750 if(iMultiLine || !pBuf)
3763 static void __internal_indent(
TEXT_OBJECT *pThis,
int nCol)
3770 static int __internal_can_undo(
TEXT_OBJECT *pThis)
3785 static int __internal_can_redo(
TEXT_OBJECT *pThis)
3809 memcpy(pRct, &(pThis->
rctView),
sizeof(*pRct));
3821 int nRows = __internal_get_rows(pThis);
3822 int nCols = __internal_get_cols(pThis);
3825 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
3826 __FUNCTION__, __LINE__,
3846 else if(pOrig->
x < nCols)
3855 else if(pOrig->
y < nRows)
3870 __internal_invalidate_rect(pThis, NULL, 1);
3874 static void __internal_begin_highlight(
TEXT_OBJECT *pThis)
3879 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
3880 __FUNCTION__, __LINE__,
3887 static void __internal_end_highlight(
TEXT_OBJECT *pThis)
3892 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
3893 __FUNCTION__, __LINE__,
3900 static void __internal_mouse_click(
TEXT_OBJECT *pThis,
int iMouseXDelta,
int iMouseYDelta,
int iType,
int iACS)
3903 int iRow = -1, iCol = -1;
3912 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
3913 __FUNCTION__, __LINE__,
3919 memset(&rctSel, 0,
sizeof(rctSel));
3924 if(!SEL_RECT_EMPTY(pThis))
3926 __internal_invalidate_rect(pThis, &(pThis->
rctHighLight), 0);
3934 iFontHeight = pThis->
iAsc + pThis->
iDesc;
3949 + (iMouseYDelta + iFontHeight / 4 - pThis->
rctWinView.
top) / iFontHeight;
3951 if(iRow < 0 || !pBuf)
3965 if(iCol < 0 || !pBuf || iRow >= pBuf->
nEntries || !pBuf->
aLines[iRow])
4003 else if(iType == 0 && iACS == 0)
4010 if(SEL_RECT_EMPTY(pThis))
4012 WB_DEBUG_PRINT(DebugLevel_Medium | DebugSubSystem_TextObject,
"%s line %d - empty selection, starting the drag\n", __FUNCTION__, __LINE__);
4037 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s line %d - need to optimize invalidate rect\n", __FUNCTION__, __LINE__);
4039 __internal_invalidate_rect(pThis, NULL, 1);
4042 static void __internal_begin_mouse_drag(
TEXT_OBJECT *pThis)
4047 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
4048 __FUNCTION__, __LINE__,
4056 static void __internal_end_mouse_drag(
TEXT_OBJECT *pThis)
4061 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
4062 __FUNCTION__, __LINE__,
4070 static void __internal_cursor_up(
TEXT_OBJECT *pThis)
4077 WB_ERROR_PRINT(
"ERROR: %p - invalid text object %p\n", __FUNCTION__, pThis);
4081 int iOldRow = pThis->
iRow;
4084 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
4085 __FUNCTION__, __LINE__,
4096 __internal_invalidate_cursor(pThis, 0);
4110 else if(pThis->
iRow > 0)
4121 if(SEL_RECT_EMPTY(pThis))
4123 WB_DEBUG_PRINT(DebugLevel_Medium | DebugSubSystem_TextObject,
"%s line %d - empty selection, starting select\n", __FUNCTION__, __LINE__);
4135 if(!SEL_RECT_EMPTY(pThis))
4137 __internal_invalidate_rect(pThis, &(pThis->
rctHighLight), 0);
4146 WB_WARN_PRINT(
"WARNING: %s line %d - invalidate entire window rect\n", __FUNCTION__, __LINE__);
4148 __internal_invalidate_rect(pThis, NULL, 1);
4165 * (pThis->
iRow - iOldRow);
4167 __internal_invalidate_cursor(pThis, 1);
4171 static void __internal_cursor_down(
TEXT_OBJECT *pThis)
4178 WB_ERROR_PRINT(
"ERROR: %p - invalid text object %p\n", __FUNCTION__, pThis);
4182 int iOldRow = pThis->
iRow;
4185 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
4186 __FUNCTION__, __LINE__,
4197 __internal_invalidate_cursor(pThis, 0);
4218 if(SEL_RECT_EMPTY(pThis))
4220 WB_DEBUG_PRINT(DebugLevel_Medium | DebugSubSystem_TextObject,
"%s line %d - empty selection, starting select\n", __FUNCTION__, __LINE__);
4232 if(!SEL_RECT_EMPTY(pThis))
4234 __internal_invalidate_rect(pThis, &(pThis->
rctHighLight), 0);
4243 WB_WARN_PRINT(
"WARNING: %s line %d - invalidate entire window rect\n", __FUNCTION__, __LINE__);
4245 __internal_invalidate_rect(pThis, NULL, 1);
4262 * (pThis->
iRow - iOldRow);
4264 __internal_invalidate_cursor(pThis, 1);
4268 static void __internal_cursor_left(
TEXT_OBJECT *pThis)
4275 WB_ERROR_PRINT(
"ERROR: %p - invalid text object %p\n", __FUNCTION__, pThis);
4279 int iOldCol = pThis->
iCol;
4282 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
4283 __FUNCTION__, __LINE__,
4289 __internal_invalidate_cursor(pThis, 0);
4298 else if(pThis->
iCol > 0)
4309 if(SEL_RECT_EMPTY(pThis))
4311 WB_DEBUG_PRINT(DebugLevel_Medium | DebugSubSystem_TextObject,
"%s line %d - empty selection, starting select\n", __FUNCTION__, __LINE__);
4323 if(!SEL_RECT_EMPTY(pThis))
4325 __internal_invalidate_rect(pThis, &(pThis->
rctHighLight), 0);
4348 WB_WARN_PRINT(
"WARNING: %s line %d - invalidate entire window rect\n", __FUNCTION__, __LINE__);
4350 __internal_invalidate_rect(pThis, NULL, 1);
4356 __internal_invalidate_cursor(pThis, 1);
4361 WB_WARN_PRINT(
"WARNING: %s line %d - invalidate entire window rect\n", __FUNCTION__, __LINE__);
4363 __internal_invalidate_rect(pThis, NULL, 1);
4367 static void __internal_cursor_right(
TEXT_OBJECT *pThis)
4374 WB_ERROR_PRINT(
"ERROR: %p - invalid text object %p\n", __FUNCTION__, pThis);
4378 int iOldCol = pThis->
iCol;
4381 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
4382 __FUNCTION__, __LINE__,
4388 __internal_invalidate_cursor(pThis, 0);
4397 else if(pThis->
iCol < 0)
4401 else if(pThis->
iCol < INT_MAX)
4413 if(pThis->
iRow != 0)
4420 if(pThis->
iCol >= iLen)
4438 if(SEL_RECT_EMPTY(pThis))
4440 WB_DEBUG_PRINT(DebugLevel_Medium | DebugSubSystem_TextObject,
"%s line %d - empty selection, starting select\n", __FUNCTION__, __LINE__);
4452 if(!SEL_RECT_EMPTY(pThis))
4454 __internal_invalidate_rect(pThis, &(pThis->
rctHighLight), 0);
4477 WB_WARN_PRINT(
"WARNING: %s line %d - invalidate entire window rect\n", __FUNCTION__, __LINE__);
4479 __internal_invalidate_rect(pThis, NULL, 1);
4485 __internal_invalidate_cursor(pThis, 1);
4490 WB_WARN_PRINT(
"WARNING: %s line %d - invalidate entire window rect\n", __FUNCTION__, __LINE__);
4492 __internal_invalidate_rect(pThis, NULL, 1);
4496 static void __internal_page_up(
TEXT_OBJECT *pThis)
4502 WB_ERROR_PRINT(
"ERROR: %p - invalid text object %p\n", __FUNCTION__, pThis);
4506 int iOldRow = pThis->
iRow;
4510 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
4511 __FUNCTION__, __LINE__,
4522 __internal_invalidate_cursor(pThis, 0);
4531 else if(pThis->
iRow <= iPageHeight)
4533 if(pThis->
iRow <= 0)
4542 pThis->
iRow -= iPageHeight;
4547 if(SEL_RECT_EMPTY(pThis))
4549 WB_DEBUG_PRINT(DebugLevel_Medium | DebugSubSystem_TextObject,
"%s line %d - empty selection, starting select\n", __FUNCTION__, __LINE__);
4561 if(!SEL_RECT_EMPTY(pThis))
4563 __internal_invalidate_rect(pThis, &(pThis->
rctHighLight), 0);
4572 int iDelta = iOldRow - pThis->
iRow;
4603 __internal_invalidate_rect(pThis, NULL, 1);
4607 static void __internal_page_down(
TEXT_OBJECT *pThis)
4613 WB_ERROR_PRINT(
"ERROR: %p - invalid text object %p\n", __FUNCTION__, pThis);
4617 int iOldRow = pThis->
iRow;
4621 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
4622 __FUNCTION__, __LINE__,
4633 __internal_invalidate_cursor(pThis, 0);
4642 else if((
int)pThis->
iRow >= ((int)pBuf->
nEntries - iPageHeight))
4644 if(pThis->
iRow >= 0)
4653 pThis->
iRow += iPageHeight;
4658 if(SEL_RECT_EMPTY(pThis))
4660 WB_DEBUG_PRINT(DebugLevel_Medium | DebugSubSystem_TextObject,
"%s line %d - empty selection, starting select\n", __FUNCTION__, __LINE__);
4672 if(!SEL_RECT_EMPTY(pThis))
4674 __internal_invalidate_rect(pThis, &(pThis->
rctHighLight), 0);
4683 int iDelta = pThis->
iRow - iOldRow;
4715 __internal_invalidate_rect(pThis, NULL, 1);
4718 static void __internal_page_left(
TEXT_OBJECT *pThis)
4726 WB_ERROR_PRINT(
"ERROR: %p - invalid text object %p\n", __FUNCTION__, pThis);
4730 int iOldCol = pThis->
iCol;
4734 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
4735 __FUNCTION__, __LINE__,
4740 "%s %d - page left by %d, iCol=%d\n",
4741 __FUNCTION__, __LINE__, iPageWidth, pThis->
iCol);
4745 __internal_invalidate_cursor(pThis, 0);
4754 else if(pThis->
iCol > iPageWidth)
4756 pThis->
iCol -= iPageWidth;
4765 if(SEL_RECT_EMPTY(pThis))
4767 WB_DEBUG_PRINT(DebugLevel_Medium | DebugSubSystem_TextObject,
"%s line %d - empty selection, starting select\n", __FUNCTION__, __LINE__);
4779 if(!SEL_RECT_EMPTY(pThis))
4781 __internal_invalidate_rect(pThis, &(pThis->
rctHighLight), 0);
4790 int iDelta = pThis->
iCol - iOldCol;
4821 __internal_invalidate_rect(pThis, NULL, 1);
4824 static void __internal_page_right(
TEXT_OBJECT *pThis)
4831 WB_ERROR_PRINT(
"ERROR: %p - invalid text object %p\n", __FUNCTION__, pThis);
4835 int iOldCol = pThis->
iCol;
4839 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
4840 __FUNCTION__, __LINE__,
4845 "%s %d - page right by %d, iCol=%d\n",
4846 __FUNCTION__, __LINE__, iPageWidth, pThis->
iCol);
4850 __internal_invalidate_cursor(pThis, 0);
4859 else if(pThis->
iCol < (INT_MAX - iPageWidth))
4861 pThis->
iCol += iPageWidth;
4870 pThis->
iCol = INT_MAX;
4875 if(SEL_RECT_EMPTY(pThis))
4877 WB_DEBUG_PRINT(DebugLevel_Medium | DebugSubSystem_TextObject,
"%s line %d - empty selection, starting select\n", __FUNCTION__, __LINE__);
4889 if(!SEL_RECT_EMPTY(pThis))
4891 __internal_invalidate_rect(pThis, &(pThis->
rctHighLight), 0);
4900 int iDelta = pThis->
iCol - iOldCol;
4923 __internal_invalidate_rect(pThis, NULL, 1);
4927 static void __internal_cursor_home(
TEXT_OBJECT *pThis)
4929 const char *pL, *p2;
4935 WB_ERROR_PRINT(
"ERROR: %p - invalid text object %p\n", __FUNCTION__, pThis);
4939 int iOldCol = pThis->
iCol;
4942 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
4943 __FUNCTION__, __LINE__,
4949 __internal_invalidate_cursor(pThis, 0);
4967 while(*p2 && *p2 <=
' ')
4974 pThis->
iCol = (int)(p2 - pL);
4981 if(SEL_RECT_EMPTY(pThis))
4983 WB_DEBUG_PRINT(DebugLevel_Medium | DebugSubSystem_TextObject,
"%s line %d - empty selection, starting select\n", __FUNCTION__, __LINE__);
4995 if(!SEL_RECT_EMPTY(pThis))
4997 __internal_invalidate_rect(pThis, &(pThis->
rctHighLight), 0);
5019 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s line %d - need to optimize invalidate rect\n", __FUNCTION__, __LINE__);
5021 __internal_invalidate_rect(pThis, NULL, 1);
5027 __internal_invalidate_cursor(pThis, 1);
5032 WB_WARN_PRINT(
"WARNING: %s line %d - invalidate entire window rect\n", __FUNCTION__, __LINE__);
5034 __internal_invalidate_rect(pThis, NULL, 1);
5039 static void __internal_cursor_end(
TEXT_OBJECT *pThis)
5047 WB_ERROR_PRINT(
"ERROR: %p - invalid text object %p\n", __FUNCTION__, pThis);
5051 int iOldCol = pThis->
iCol;
5054 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
5055 __FUNCTION__, __LINE__,
5061 __internal_invalidate_cursor(pThis, 0);
5085 if(SEL_RECT_EMPTY(pThis))
5087 WB_DEBUG_PRINT(DebugLevel_Medium | DebugSubSystem_TextObject,
"%s line %d - empty selection, starting select\n", __FUNCTION__, __LINE__);
5099 if(!SEL_RECT_EMPTY(pThis))
5101 __internal_invalidate_rect(pThis, &(pThis->
rctHighLight), 0);
5123 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s line %d - need to optimize invalidate rect\n", __FUNCTION__, __LINE__);
5125 __internal_invalidate_rect(pThis, NULL, 1);
5131 __internal_invalidate_cursor(pThis, 1);
5136 WB_WARN_PRINT(
"WARNING: %s line %d - invalidate entire window rect\n", __FUNCTION__, __LINE__);
5138 __internal_invalidate_rect(pThis, NULL, 1);
5143 static void __internal_cursor_top(
TEXT_OBJECT *pThis)
5150 WB_ERROR_PRINT(
"ERROR: %p - invalid text object %p\n", __FUNCTION__, pThis);
5154 int iOldRow = pThis->
iRow;
5158 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
5159 __FUNCTION__, __LINE__,
5172 if(SEL_RECT_EMPTY(pThis))
5174 WB_DEBUG_PRINT(DebugLevel_Medium | DebugSubSystem_TextObject,
"%s line %d - empty selection, starting select\n", __FUNCTION__, __LINE__);
5186 if(!SEL_RECT_EMPTY(pThis))
5188 __internal_invalidate_rect(pThis, &(pThis->
rctHighLight), 0);
5198 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s line %d - need to optimize invalidate rect\n", __FUNCTION__, __LINE__);
5200 __internal_invalidate_rect(pThis, NULL, 1);
5204 static void __internal_cursor_bottom(
TEXT_OBJECT *pThis)
5211 WB_ERROR_PRINT(
"ERROR: %p - invalid text object %p\n", __FUNCTION__, pThis);
5215 int iOldRow = pThis->
iRow;
5219 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
5220 __FUNCTION__, __LINE__,
5241 if(SEL_RECT_EMPTY(pThis))
5243 WB_DEBUG_PRINT(DebugLevel_Medium | DebugSubSystem_TextObject,
"%s line %d - empty selection, starting select\n", __FUNCTION__, __LINE__);
5255 if(!SEL_RECT_EMPTY(pThis))
5257 __internal_invalidate_rect(pThis, &(pThis->
rctHighLight), 0);
5264 if(!pBuf || iPageHeight > pBuf->
nEntries)
5275 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s line %d - need to optimize invalidate rect\n", __FUNCTION__, __LINE__);
5277 __internal_invalidate_rect(pThis, NULL, 1);
5281 static void __internal_scroll_vertical(
TEXT_OBJECT *pThis,
int nRows)
5287 WB_ERROR_PRINT(
"ERROR: %p - invalid text object %p\n", __FUNCTION__, pThis);
5294 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
5295 __FUNCTION__, __LINE__,
5300 "%s %d - scroll vertical by %d, iCol=%d\n",
5301 __FUNCTION__, __LINE__, nRows, pThis->
iCol);
5349 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s line %d - need to optimize invalidate rect\n", __FUNCTION__, __LINE__);
5351 __internal_invalidate_rect(pThis, NULL, 1);
5355 static void __internal_scroll_horizontal(
TEXT_OBJECT *pThis,
int nCols)
5361 WB_ERROR_PRINT(
"ERROR: %p - invalid text object %p\n", __FUNCTION__, pThis);
5368 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
5369 __FUNCTION__, __LINE__,
5374 "%s %d - scroll horizontal by %d, iCol=%d\n",
5375 __FUNCTION__, __LINE__, nCols, pThis->
iCol);
5396 else if(pThis->
iCol < 0)
5403 else if(pThis->
iCol + nCols > -INT_MAX && pThis->
iCol + nCols < INT_MAX)
5418 if(pThis->
iRow != 0)
5475 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s line %d - need to optimize invalidate rect\n", __FUNCTION__, __LINE__);
5477 __internal_invalidate_rect(pThis, NULL, 1);
5483 static XFontSet __attribute__((noinline)) __internal_verify_get_fontset(Display *pDisplay, XFontSet rFontSet,
WBGC gc)
5487 if(rFontSet == None)
5493 WB_ERROR_PRINT(
"%s - ERROR: WBQueryGCFont returns NULL\n", __FUNCTION__);
5500 XFreeFont(pDisplay, pFont);
5505 WB_ERROR_PRINT(
"%s - ERROR: WBFontSetFromFont returns None\n", __FUNCTION__);
5518 int __attribute__((noinline)) __internal_get_fontset_count_and_max_asc_desc(XFontSet fSet,
int *pAsc,
int *pDesc)
5520 int nFonts, i1, iAsc, iDesc;
5521 XFontStruct **ppFonts = NULL;
5522 char **ppNames = NULL;
5524 nFonts = XFontsOfFontSet(fSet, &ppFonts, &ppNames);
5526 if(nFonts <= 0 || !ppFonts)
5531 for(i1=0, iAsc=0, iDesc=0; i1 < nFonts; i1++)
5533 if(iAsc < ppFonts[i1]->ascent)
5535 iAsc = ppFonts[i1]->ascent;
5537 if(iDesc < ppFonts[i1]->descent)
5539 iDesc = ppFonts[i1]->descent;
5564 int iXDelta, iYDelta;
5565 int i1, iLen, iFontHeight, iFontWidth, iAsc, iDesc, iX, iY, iPX, iPY;
5569 unsigned long clrFG, clrBG, clrHFG, clrHBG;
5572 int nEntries, iAutoScrollWidth, iWindowHeightInLines;
5577 WB_ERROR_PRINT(
"ERROR: %s - text object %p not valid\n", __FUNCTION__, pThis);
5582 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
5583 __FUNCTION__, __LINE__,
5587 iXDelta = iYDelta = 0;
5591 memcpy(&geomV, pViewGeom,
sizeof(geomV));
5597 geomV.
x = geomV.
y = 0;
5625 memcpy(&geomP, pPaintGeom,
sizeof(geomP));
5629 memcpy(&geomP, &geomV,
sizeof(geomP));
5682 if(!(pThis->
clrHFG.flags & (DoRed | DoGreen | DoBlue)) &&
5683 !(pThis->
clrHFG.flags & (DoRed | DoGreen | DoBlue)))
5690 clrHBG = pThis->
clrHBG.pixel;
5691 clrHFG = pThis->
clrHFG.pixel;
5714 pThis->
iDesc = iDesc;
5719 #warning support proportional pitch fonts by assigning a font width < 0 ??? For now only fixed-pitch are supported by this object 5758 iFontHeight = iAsc + iDesc;
5780 iAutoScrollWidth >>= 1;
5805 iWindowHeightInLines = geomV.
height / iFontHeight;
5806 if(!iWindowHeightInLines)
5808 iWindowHeightInLines = 1;
5815 != geomV.
width / iFontWidth
5817 != iWindowHeightInLines
5828 || (pThis->
rctView.
top && nEntries < iWindowHeightInLines))
5834 != iWindowHeightInLines)
5842 pThis->
rctView.
top -= iWindowHeightInLines - 1;
5847 pThis->
rctView.
top += iWindowHeightInLines - 1;
5860 iAutoScrollWidth >>= 1;
5884 if(!SEL_RECT_EMPTY(pThis))
5886 if(SEL_RECT_ALL(pThis))
5888 memcpy(&rctSel, &(pThis->
rctView),
sizeof(rctSel));
5895 memcpy(&rctSel, &(pThis->
rctSel),
sizeof(rctSel));
5896 NORMALIZE_SEL_RECT(rctSel);
5909 if(geomV.
height >= iAsc + iDesc)
5914 + (rctSel.
right - rctSel.
left) * iFontWidth;
5917 + (rctSel.
bottom - rctSel.
top + 1) * iFontHeight;
5941 bzero(&rctSel,
sizeof(rctSel));
5960 if(gc2 != None && iPX > 0 && iPY > 0)
5962 pxTemp = XCreatePixmap(pDisplay, wID, iPX, iPY,
5963 DefaultDepth(pDisplay, DefaultScreen(pDisplay)));
6022 iY = geomV.
height - iFontHeight;
6030 iY = geomV.
y + iY / 2 + iAsc;
6100 for(i1=pThis->
rctView.
left; i1 < pThis->rctView.right; i1++, iX += iFontWidth)
6104 if(i1 == pThis->
iCol)
6143 WBDrawLine(pDisplay, pxTemp != None ? pxTemp : wID,
6144 gc2 != None ? gc2 : gc,
6149 rctChar.
top = iY - iAsc;
6150 rctChar.
bottom = iY + iDesc;
6151 rctChar.
left = iX + 1;
6152 rctChar.
right = iX + iFontWidth - 1;
6170 geomC.
width = iFontWidth;
6171 geomC.
height = iFontHeight;
6183 gc2 != None ? gc2 : gc,
6184 iX - iXDelta, iY - iYDelta, p1, iLen2);
6188 else if(i1 > pThis->
iCol)
6214 for(iCurRow=pThis->
rctView.
top; iCurRow <= nEntries && iCurRow <= pThis->rctView.bottom; iCurRow++)
6220 iY = geomV.
y + iFontHeight * (iCurRow - pThis->
rctView.
top)
6225 if(pBuf && iCurRow < nEntries)
6227 pL = pBuf->
aLines[iCurRow];
6248 (iCurRow < pThis->rctSel.
bottom ||
6254 if(iCurRow == pThis->
iRow ||
6259 for(i1=pThis->
rctView.
left; i1 <= pThis->rctView.right; i1++, iX += iFontWidth)
6276 iCurRow < pThis->rctSel.
bottom) ||
6282 int iY0 = iY - iAsc;
6292 iX - iXDelta, iY0 - iYDelta,
6293 iFontWidth, iFontHeight);
6304 iFontWidth, iFontHeight);
6320 if(iCurRow == pThis->
iRow && i1 == pThis->
iCol)
6326 int iY0 = iY + iDesc + 1;
6334 rctCursor.
top = iY0 - iYDelta;
6345 int iY0 = iY - iAsc - 1;
6346 int iY1 = iY + iDesc + 1;
6352 rctCursor.
top = iY0 - iYDelta;
6354 rctCursor.
bottom = iY1 - iYDelta;
6359 WBDrawLine(pDisplay, pxTemp != None ? pxTemp : wID,
6360 gc2 != None ? gc2 : gc,
6376 gc2 != None ? gc2 : gc,
6377 iX - iXDelta, iY - iYDelta, p1, iLen2);
6388 int iY0 = iY - iAsc;
6396 iX - iXDelta, iY0 - iYDelta,
6397 geomV.
width, iFontHeight);
6408 geomV.
width, iFontHeight);
6419 if(p1 && p1 && p2 > p1)
6422 gc2 != None ? gc2 : gc,
6423 iX - iXDelta, iY - iYDelta,
6443 int iX0=0, iY0=0, iW0=iPX, iH0=iPY;
6457 if(geomP.
x + geomP.
width < iX + iW0)
6459 iW0 = geomP.
x + geomP.
width - iX;
6469 if(geomP.
y + geomP.
height < iY + iH0)
6471 iH0 = geomP.
y + geomP.
height - iY;
6474 if(iH0 > 0 && iW0 > 0)
6476 XCopyArea(pDisplay, pxTemp, wID, gc->
gc,
6477 iX0, iY0, iW0, iH0, iX, iY);
6480 XFreePixmap(pDisplay, pxTemp);
6494 static int __internal_cursor_show(
int iBlinkState)
6496 return iBlinkState != CURSOR_BLINK_OFF ? 1 : 0;
6499 static void __internal_cursor_blink(
TEXT_OBJECT *pThis,
int bHasFocus)
6503 int bShow = __internal_cursor_show(pThis->
iBlinkState);
6506 "%s line %d: pThis iRow=%d iCol=%d rctSel=(%d,%d,%d,%d)\n",
6507 __FUNCTION__, __LINE__,
6517 __internal_invalidate_cursor(pThis, 1);
6524 __internal_invalidate_cursor(pThis, bShow != __internal_cursor_show(pThis->
iBlinkState));
6530 static void __internal_set_save_point(
TEXT_OBJECT *pThis)
6534 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s - not yet implemented\n", __FUNCTION__);
6537 static int __internal_get_modified(
TEXT_OBJECT *pThis)
6539 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s - not yet implemented - returning 'modified'\n", __FUNCTION__);
6553 static int internal_IsMBCharValid(
const char *pChar,
int *piLen)
6555 const unsigned char *p1;
6559 if((
unsigned char)*pChar < 0x80)
6576 p1 = (
const unsigned char *)pChar;
6598 if((
unsigned char)p1[1] >= 0x80 && (
unsigned char)p1[1] <= 0xbf)
6610 if(p1[1] >= 0x80 && p1[1] <= 0xbf &&
6611 p1[2] >= 0x80 && p1[2] <= 0xbf)
6626 if(p1[1] >= 0x80 && p1[1] <= 0xbf &&
6627 p1[2] >= 0x80 && p1[2] <= 0xbf &&
6628 p1[3] >= 0x80 && p1[3] <= 0xbf)
6644 *piLen = (
const char *)p1 - pChar;
6648 if(!iRval || ((
const char *)p1 - pChar) > 1)
6650 int iLen = ((
const char *)p1 - pChar);
6652 WB_DEBUG_PRINT(DebugLevel_Verbose,
"%s line %d - return=%d char=%02xH", __FUNCTION__, __LINE__, iRval, (
unsigned char)*pChar);
6667 static int internal_MBstrlen(
const char *pString)
6669 const char *p1 = pString;
6679 if(!internal_IsMBCharValid(p1, &iLen))
6698 static int internal_MBColIndex(
const char *pString,
int iCol)
6700 const char *p1 = pString;
6704 while(iCol > 0 && *p1)
6708 if(!internal_IsMBCharValid(p1, &iLen))
6722 return (p1 - pString);
6727 int fTab,
int fOverwrite,
int *piNewCol,
char **ppInserted)
6752 iLen = internal_MBstrlen(pString);
6760 i1 = internal_MBColIndex(pString, iCol);
6772 p1 = pString + strlen(pString);
6774 while(p1 > pString && *(p1 - 1) <=
' ')
6785 int iLen, iLenNew, iJoin;
6789 iLen = internal_MBstrlen(pString);
6799 iJoin = internal_MBstrlen(pJoin);
6801 pRval =
WBReAlloc(pString, iLenNew + iJoin + 2);
6807 p1 = pRval + strlen(pRval);
6809 while(iLen < iLenNew)
6820 int WBDelMBChars(
char *pString,
int iCol,
int nDel,
int *piNewCol,
char **ppDeleted)
6822 int iLen, iIndex, i1, iRval = nDel;
6823 char *pDelChar, *p1;
6836 if(!pString || !nDel || !*pString)
6846 iLen = internal_MBstrlen(pString);
6850 if(ppDeleted && iLen > iCol)
6856 *ppDeleted = pDelChar;
6868 while(iLen > iCol && iRval > 0)
6870 iIndex = internal_MBColIndex(pString, iCol);
6872 p1 = pString + iIndex;
6879 if(!internal_IsMBCharValid(p1, &i1))
6889 if(pDelChar && i1 > 0)
6891 memcpy(pDelChar, p1, i1);
6901 strcpy(p1, p1 + i1);
6906 if(ppDeleted && iCol > 0)
6912 *ppDeleted = pDelChar;
6927 while(iCol > 0 && iRval < 0)
6931 iIndex = internal_MBColIndex(pString, iCol - 1);
6933 p1 = pString + iIndex;
6940 if(!internal_IsMBCharValid(p1, &i1))
6950 if(pDelChar && i1 > 0)
6955 memmove(pDelChar + i1, pDelChar, strlen(pDelChar) + 1);
6956 memcpy(pDelChar, p1, i1);
6960 strcpy(p1, p1 + i1);
6991 return internal_MBstrlen(pString);
7004 iIndex = internal_MBColIndex(pString, iCol);
7008 if(!internal_IsMBCharValid(pString + iIndex, pcbLen))
7023 return pString + iIndex;
7028 const char *p1 = pString;
7032 if(pChar <= pString)
7039 while(*p1 && p1 < pChar)
7043 if(!internal_IsMBCharValid(p1, &iLen))
const char * CHGetHighlightForegroundColor(Display *pDisplay)
returns highlight foreground color
'base class' structure for TEXT_OBJECT
#define WBRectOverlapped(R1, R2)
Returns logical TRUE if the rectangle R1 overlaps/intersects R2.
WB_RECT rctWinViewOld
previous viewport, in window coordinates [for invalidating window efficiently]
int WBGetMBColIndex(const char *pString, const char *pChar)
Obtain the column index from a pointer within a multi-byte character string.
char * WBGetMBCharPtr(char *pString, int iCol, int *pcbLen)
Obtain the pointer to a specific multi-byte character within a multi-byte character string,...
TEXT_OBJECT * WBTextObjectConstructor(unsigned long cbStructSize, const char *szText, unsigned long cbLen, Window wIDOwner)
Generic constructor for a TEXT_OBJECT using defaults.
void WBTextObjectSetColorContextCallback(TEXT_OBJECT *pThis, unsigned long(*callback)(TEXT_OBJECT *pThis, int nRow, int nCol), void *pColorContextPointer)
assign callback function for 'color context' for a given character
int WBDrawLine(Display *display, Drawable d, WBGC gc, int x1, int y1, int x2, int y2)
Wrapper for XDrawLines()
#define WB_DEBUG_PRINT(L,...)
Preferred method of implementing conditional debug output.
void(* destroy)(TEXT_OBJECT *pThis)
Call this prior to de-allocating memory to free up any internal objects or storage.
int WBFontAscent(WB_FONTC pFont0)
Get the maximum character ascent from a WB_FONT.
Utilities for copying and drawing text, determining text extents, and so on.
int iMaxFontWidth
maximum width of font in pixels (mostly for proportional pitch) - cached by 'expose' handler
int x
the 'x' value of the point. can be negative.
int iFontWidth
average width of font in pixels (mostly for fixed pitch) - cached by 'expose' handler
int iFileType
file type - -1=Makefile, 0=plain text, others are 'file type' constants, bit flags to preserve hard t...
void WBTextBufferLineChange(TEXT_BUFFER *pBuf, unsigned long nLine, int nNewLen)
Text buffer 'cached information' update function indicating a change to a line's length.
OVERWRITE mode, character inserted on top of character to the right of the cursor (if any),...
int iScrollMode
scroll mode - 0=normal, 1='scroll lock'
char * aLines[2]
array of 'lines'. each pointer is suballocated via WBAlloc()
BOX (selects a 'box' using virtual spacing)
int WBStringLineCount(const char *pSrc, unsigned int nMaxChars)
Determine how many 'lines' are in a block of text by counting 'linefeed' characters.
int WBFontAvgCharWidth(WB_FONTC pFont0)
Get the average character width for a font.
char * WBSplitMBLine(char *pString, int iCol)
Split a multi-byte characters into a WBAlloc'd string, at a specified column, terminating the origina...
WB_RECT rctHighLight
highlight rect {0,0,0,0} implies NONE
static __inline__ void WBInitializeInPlaceTextObject(TEXT_OBJECT *pTextObject, Window wIDOwner)
initialize an 'in-place' TEXT_OBJECT structure
int WBDelMBChars(char *pString, int iCol, int nDel, int *piNewCol, char **ppDeleted)
Delete a specified number of multi-byte characters from a string 'in place', starting at a specified ...
int iCursorX
X position of cursor as last drawn in expose event.
unsigned int aLineCacheLen[TEXT_BUFFER_LINE_CACHE_SIZE]
The actual line lengths associated with 'aLineCache' (zero if unused)
XFontSet WBFontSetFromFont(Display *pDisplay, const XFontStruct *pFont)
Creates an 'XFontSet' from an XFontStruct for a given display.
int WBGetMBLength(const char *pString)
Obtain the length of a multi-byte character string in 'characters' (not bytes)
unsigned long(* pColorContextCallback)(TEXT_OBJECT *, int, int)
callback function to get the context color of a character. default is NULL.
mouse 'drag' (select mode)
WB_RECT rctSel
select boundary in characters, {0,0,0,0} implies NONE, {-1,x,x,x} implies ALL. if top == bottom,...
int WBPostPriorityEvent(Window wID, XEvent *pEvent)
Places a copy of the specified event at the end of the priority (internal) event queue.
int WBTextObjectCalculateLineHeight(int iAscent, int iDescent)
Calculate the correct per-line height (in pixels) for a specified font ascent and descent.
static __inline__ Display * WBGetDefaultDisplay(void)
Returns the default Display.
internal wrapper struct for X11 'geometry' definition
'configuration helper' main header file for the X11 Work Bench Toolkit API
Atom aRECALC_LAYOUT
notify window that it should re-calculate things like scrollbars and viewports
#define GCAll
A bit mask for ALL GC properties (used when copying a GC)
int iInsMode
insert mode - 0=overwrite, 1=insert
int iSelMode
selection mode - 0=normal, 1=line, 2=box
unsigned long nArraySize
allocated size of aLines array
int WBCheckReAllocTextBuffer(TEXT_BUFFER **ppBuf, int nLinesToAdd)
Re-allocator for TEXT_BUFFER object.
void * WBReAlloc(void *pBuf, int nNewSize)
High performance memory sub-allocator 're-allocate'.
LINE (always selects entire line when spanning multiple lines)
int WBSetForeground(WBGC hGC, unsigned long foreground)
Assign foreground color, a wrapper for XSetForeground()
static void __internal_do_expose(TEXT_OBJECT *pThis, Display *pDisplay, Window wID, WBGC gc, const WB_GEOM *pPaintGeom, const WB_GEOM *pViewGeom, WB_FONTC pFont)
char * WBJoinMBLine(char *pString, int iCol, const char *pJoin)
Split a multi-byte characters into a WBAlloc'd string, at a specified column, terminating the origina...
WB_RECT rctViewOld
previous viewport [for invalidating window efficiently]
#define COPY_COLOR_NAME(X, Y, Z)
macro to get a color name or use default if it does not exist in settings
unsigned int nMinMaxCol
The 'smallest maximum' recorded in 'aLineCache'.
'base class' structure for TEXT_OBJECT
void * pText
pointer to (abstracted) object containing the text. void pointer allows abstraction....
#define WBGeomOverlapped(G1, G2)
Returns logical TRUE if the geometry G1 overlaps/intersects G2.
int iCol
current col (cursor)
int iCursorHeight
height of cursor as last drawn in expose event (always 1 if 'overwrite' cursor)
int iPos
position within buffer (reserved, MBCS may require it)
reserved - specifies custom array, indicating the size of the array containing the character values,...
Internal-only structure for undo/redo buffer for text object.
int iCursorY
Y position of cursor as last drawn in expose event (top of cursor)
void * WBAlloc(int nSize)
High performance memory sub-allocator 'allocate'.
enum e_undo_operation UNDO_OPERATION
Internal-only enumeration for undo/redo buffer 'iOperation' member.
char * WBInsertMBChars(char *pString, int iCol, const char *pszMBString, int cbString, int fTab, int fOverwrite, int *piNewCol, char **ppInserted)
Insert multi-byte characters into a WBAlloc'd string, at a specified column.
void * pUndo
pointer to 'undo' buffer. NULL if empty.
void * pRedo
pointer to 'redo' buffer. NULL if empty.
const char * CHGetHighlightBackgroundColor(Display *pDisplay)
returns highlight background color
#define AUTO_HSCROLL_SIZE
#define WB_ERROR_PRINT(...)
Preferred method of implementing an 'error level' debug message for all subsystems.
void WBTextObjectDestructor(TEXT_OBJECT *pObj)
Generic detructor for a TEXT_OBJECT.
unsigned int nMaxCol
The maximum column number for any line, rounded up by 'DEFAULT_TAB_WIDTH'.
void WBFree(void *pBuf)
High performance memory sub-allocator 'free'.
static __inline__ void WBInvalidateRect(Window wID, const WB_RECT *pRCT, int bPaintFlag)
'Paint' helper, invalidates a WB_RECT for asynchronous Expose event generation
XColor clrHFG
highlight FG color
WBGC WBCreateGC(Display *pDisplay, Drawable dw, unsigned long valuemask, const XGCValues *values)
Creates a WBGC, wrapper for XCreateGC()
int y
the 'y' value of the point. can be negative.
int iBlinkState
cursor blink state
INSERT mode, character inserted at cursor.
WB_RECT rctView
viewport, in characters (rctView.top is the top visible line, always)
unsigned long nEntries
number of entries currently in the array - call WBCheckReAllocTextBuffer() before increasing
int WBCopyGC2(WBGC hGCOrig, unsigned long valuemask, WBGC hGCDest)
makes a copy of a WBGC, a wrapper for XCopyGC()
const TEXT_OBJECT_VTABLE * vtable
method function pointers (similar to C++ virtual member functions)
#define WB_POINTER_BUTTON1
WB_POINTER button bitmask indicating that button 1 is pressed.
e_undo_operation
Internal-only enumeration for undo/redo buffer 'iOperation' member.
A 'C++'-like object for managing text, that can be overridden for custom behavior.
#define DEFAULT_TAB_WIDTH
e_LineFeed
line feed (line ending) types for TEXT_OBJECT
void DTDrawString(Display *pDisplay, Drawable drawable, WB_FONTC pFont, WBGC gc, int x, int y, const char *pString, int nLength)
Draw text in a platform-independent manner for UTF-8 or multi-byte text, equivalent to WBDrawString()...
unsigned long aLineCache[TEXT_BUFFER_LINE_CACHE_SIZE]
An array of line indices, sorted longest to least, for the 'longest lines'.
int WBTextBufferLineLength(TEXT_BUFFER *pBuf, unsigned long nLine)
Text buffer 'cached information' query function indicating a line's cached length.
const char * WBStringNextLine(const char *pSrc, unsigned int *pnMaxChars)
Locate the next line in a block of text, returning its pointer (and updating remaining length)
XColor clrHBG
highlight BG color
internal wrapper struct for 'rectangle' definition
int WBFontDescent(WB_FONTC pFont0)
Get the maximum character descent from a WB_FONT.
int WBSetClipOrigin(WBGC hGC, int clip_x_origin, int clip_y_origin)
Set clip origin, a wrapper for XSetClipOrigin()
Display * WBGetWindowDisplay(Window wID)
returns the Display associated with a window
void WBFreeGC(WBGC hGC)
Free resources for a WBGC, wrapper for XFreeGC()
int WBFontMaxCharWidth(WB_FONTC pFont0)
Get the maximum character width for a font.
WB_RECT rctWinView
viewport, in window coordinates, or 'empty' if unknown
void * pColorContext
a user-controlled 'color context' pointer - can be anything, however
unsigned long WBGetGCFGColor(WBGC gc)
returns the currently assigned foreground color for a WBGC
unsigned long WBGetGCBGColor(WBGC gc)
returns the currently assigned background color for a WBGC
#define MIN_BORDER_SPACING
void WBFreeTextBuffer(TEXT_BUFFER *pBuf)
Re-allocator for TEXT_BUFFER object, returns ZERO on success. Pointer may be modified (or not).
static __inline__ int WBIsValidTextObject(const TEXT_OBJECT *pObj)
'TEXT_OBJECT' validator
int WBFillRectangle(Display *display, Drawable d, WBGC gc, int x, int y, unsigned int width, unsigned int height)
Wrapper for XFillRectangle()
void WBGetWindowGeom(Window wID, WB_GEOM *pGeom)
Returns the RAW geometry of the window as reported by the window manager.
Window wIDOwner
owner window (cached from paint/expose handling and/or cursor blink)
int iAsc
font height ascension
int WBSetBackground(WBGC hGC, unsigned long background)
Assign background color, a wrapper for XSetBackground()
void WBDebugPrint(const char *pFmt,...) __attribute__((format(printf
conditional debug message output
enum e_LineFeed iLineFeed
linefeed type (see enum). LineFeed_NONE implies SINGLE LINE
An allocated structure containing XFontStruct, XFontInfo, and XftFont [as applicable] for a specified...
int iTab
tab width in characters (0 = system default)
char * WBCopyString(const char *pSrc)
A simple utility that returns a WBAlloc() copy of a 0-byte terminated string.
#define TEXT_OBJECT_TAG
The 'tag' for a TEXT_OBJECT structure.
internal wrapper struct for 'point' definition
internal wrapper struct for GC with local cache
int iDesc
font height descension
'vtable' structure for TEXT_OBJECT
int iDragState
if '1' bit is set, cursor drag. if '2' bit is set, mouse drag
unsigned int ulTag
tag word, always assigned to TEXT_OBJECT_TAG
#define WB_WARN_PRINT(...)
Preferred method of implementing a 'warning level' debug message for all subsystems.
int iRow
current row (cursor)
cursor 'drag' (select mode)
void WBTextBufferRefreshCache(TEXT_BUFFER *pBuf)
Text buffer 'cached information' refresh function.
WB_FONTC WBQueryGCFont(WBGC gc)
return the WB_FONTC object that was assigned to a WBGC
TEXT_BUFFER * WBAllocTextBuffer(const char *pBuf, unsigned int cbBufSize)
Generic constructor for a TEXT_BUFFER using defaults.
WB_FONTC WBGetDefaultFont(void)
Returns a pointer to the default font WB_FONT for the default display. This is a shared resource; do ...