1/* $XConsortium: tsource.c,v 2.24 91/10/21 14:32:36 eswu Exp $ */ 2 3/* 4 * COPYRIGHT 1987 5 * DIGITAL EQUIPMENT CORPORATION 6 * MAYNARD, MASSACHUSETTS 7 * ALL RIGHTS RESERVED. 8 * 9 * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND 10 * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. 11 * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR 12 * ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. 13 * 14 * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS, 15 * APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT 16 * SET FORTH ABOVE. 17 * 18 * 19 * Permission to use, copy, modify, and distribute this software and its 20 * documentation for any purpose and without fee is hereby granted, provided 21 * that the above copyright notice appear in all copies and that both that 22 * copyright notice and this permission notice appear in supporting documentation, 23 * and that the name of Digital Equipment Corporation not be used in advertising 24 * or publicity pertaining to distribution of the software without specific, 25 * written prior permission. 26 */ 27/* $XFree86: xc/programs/xmh/tsource.c,v 1.3 2002/04/05 21:06:29 dickey Exp $ */ 28 29/* File: tsource.c -- the code for a toc source */ 30 31#include "xmh.h" 32#include "tocintrnl.h" 33#include <X11/Xatom.h> 34#include "tsourceP.h" 35 36/**************************************************************** 37 * 38 * Full class record constant 39 * 40 ****************************************************************/ 41 42/* Private Data */ 43 44#define Offset(field) XtOffsetOf(TocSourceRec, toc_source.field) 45 46static XtResource resources[] = { 47 {XtNtoc, XtCToc, XtRPointer, sizeof(caddr_t), 48 Offset(toc), XtRPointer, NULL}, 49}; 50 51#undef Offset 52 53static void Initialize(Widget, Widget, ArgList, Cardinal *num_args); 54static XawTextPosition Read(Widget, XawTextPosition, XawTextBlock *, int); 55static XawTextPosition Scan(Widget, XawTextPosition, XawTextScanType, XawTextScanDirection, int, Bool); 56static XawTextPosition Search(Widget, XawTextPosition, XawTextScanDirection, XawTextBlock *); 57static int Replace(Widget, XawTextPosition, XawTextPosition, XawTextBlock *); 58 59#define SuperClass (&textSrcClassRec) 60TocSourceClassRec tocSourceClassRec = { 61 { 62/* core_class fields */ 63 /* superclass */ (WidgetClass) SuperClass, 64 /* class_name */ "TocSrc", 65 /* widget_size */ sizeof(TocSourceRec), 66 /* class_initialize */ NULL, 67 /* class_part_initialize */ NULL, 68 /* class_inited */ FALSE, 69 /* initialize */ Initialize, 70 /* initialize_hook */ NULL, 71 /* realize */ NULL, 72 /* actions */ NULL, 73 /* num_actions */ 0, 74 /* resources */ resources, 75 /* num_resources */ XtNumber(resources), 76 /* xrm_class */ NULLQUARK, 77 /* compress_motion */ FALSE, 78 /* compress_exposure */ FALSE, 79 /* compress_enterleave */ FALSE, 80 /* visible_interest */ FALSE, 81 /* destroy */ NULL, 82 /* resize */ NULL, 83 /* expose */ NULL, 84 /* set_values */ NULL, 85 /* set_values_hook */ NULL, 86 /* set_values_almost */ NULL, 87 /* get_values_hook */ NULL, 88 /* accept_focus */ NULL, 89 /* version */ XtVersion, 90 /* callback_private */ NULL, 91 /* tm_table */ NULL, 92 /* query_geometry */ NULL, 93 /* display_accelerator */ NULL, 94 /* extension */ NULL 95 }, 96/* textSrc_class fields */ 97 { 98 /* Read */ Read, 99 /* Replace */ Replace, 100 /* Scan */ Scan, 101 /* Search */ Search, 102 /* SetSelection */ XtInheritSetSelection, 103 /* ConvertSelection */ XtInheritConvertSelection 104 }, 105/* toc_source_class fields */ 106 { 107 /* keeping the compiler happy */ 0 108 } 109}; 110 111WidgetClass tocSourceWidgetClass = (WidgetClass)&tocSourceClassRec; 112 113/************************************************************ 114 * 115 * Class specific methods. 116 * 117 ************************************************************/ 118 119Msg MsgFromPosition( 120 Toc toc, 121 XawTextPosition position, 122 XawTextScanDirection dir) 123{ 124 Msg msg; 125 int h, l, m; 126 if (position > toc->lastPos) position = toc->lastPos; 127 if (dir == XawsdLeft) position--; 128 l = 0; 129 h = toc->nummsgs - 1; 130 while (l < h - 1) { 131 m = (l + h) / 2; 132 if (toc->msgs[m]->position > position) 133 h = m; 134 else 135 l = m; 136 } 137 msg = toc->msgs[h]; 138 if (msg->position > position) 139 msg = toc->msgs[h = l]; 140 while (!msg->visible) 141 msg = toc->msgs[h++]; 142 if (position < msg->position || position > msg->position + msg->length) 143 Punt("Error in MsgFromPosition!"); 144 return msg; 145} 146 147 148static XawTextPosition 149CoerceToLegalPosition(Toc toc, XawTextPosition position) 150{ 151 return (position < 0) ? 0 : 152 ((position > toc->lastPos) ? toc->lastPos : position); 153} 154 155static XawTextPosition 156Read( 157 Widget w, 158 XawTextPosition position, 159 XawTextBlock *block, 160 int length) 161{ 162 TocSourceWidget source = (TocSourceWidget) w; 163 Toc toc = source->toc_source.toc; 164 Msg msg; 165 int count; 166 167 if (position < toc->lastPos) { 168 block->firstPos = position; 169 msg = MsgFromPosition(toc, position, XawsdRight); 170 block->ptr = msg->buf + (position - msg->position); 171 count = msg->length - (position - msg->position); 172 block->length = (count < length) ? count : length; 173 position += block->length; 174 } 175 else { 176 block->firstPos = 0; 177 block->length = 0; 178 block->ptr = ""; 179 } 180 block->format = FMT8BIT; 181 return position; 182} 183 184/* Right now, we can only replace a piece with another piece of the same size, 185 and it can't cross between lines. */ 186 187static int 188Replace( 189 Widget w, 190 XawTextPosition startPos, 191 XawTextPosition endPos, 192 XawTextBlock *block) 193{ 194 TocSourceWidget source = (TocSourceWidget) w; 195 Toc toc = source->toc_source.toc; 196 Msg msg; 197 int i; 198 199 if (block->length != endPos - startPos) 200 return XawEditError; 201 msg = MsgFromPosition(toc, startPos, XawsdRight); 202 for (i = 0; i < block->length; i++) 203 msg->buf[startPos - msg->position + i] = block->ptr[i]; 204/* for (i=0 ; i<toc->numwidgets ; i++) 205 XawTextInvalidate(toc->widgets[i], startPos, endPos); 206* 207* CDP 9/1/89 208*/ 209 return XawEditDone; 210} 211 212 213#define Look(ti, c)\ 214{ \ 215 if ((dir == XawsdLeft && ti <= 0) || \ 216 (dir == XawsdRight && ti >= toc->lastPos)) \ 217 c = 0; \ 218 else { \ 219 if (ti + doff < msg->position || \ 220 ti + doff >= msg->position + msg->length) \ 221 msg = MsgFromPosition(toc, ti, dir); \ 222 c = msg->buf[ti + doff - msg->position]; \ 223 } \ 224} 225 226 227 228static XawTextPosition 229Scan( 230 Widget w, 231 XawTextPosition position, 232 XawTextScanType sType, 233 XawTextScanDirection dir, 234 int count, 235 Bool include) 236{ 237 TocSourceWidget source = (TocSourceWidget) w; 238 Toc toc = source->toc_source.toc; 239 XawTextPosition textindex; 240 Msg msg; 241 char c; 242 int ddir, doff, i, whiteSpace = 0; 243 ddir = (dir == XawsdRight) ? 1 : -1; 244 doff = (dir == XawsdRight) ? 0 : -1; 245 246 if (toc->lastPos == 0) return 0; 247 textindex = position; 248 if (textindex + doff < 0) return 0; 249 if (dir == XawsdRight && textindex >= toc->lastPos) return toc->lastPos; 250 msg = MsgFromPosition(toc, textindex, dir); 251 switch (sType) { 252 case XawstPositions: 253 if (!include && count > 0) 254 count--; 255 textindex = CoerceToLegalPosition(toc, textindex + count * ddir); 256 break; 257 case XawstWhiteSpace: 258 for (i = 0; i < count; i++) { 259 whiteSpace = -1; 260 while (textindex >= 0 && textindex <= toc->lastPos) { 261 Look(textindex, c); 262 if ((c == ' ') || (c == '\t') || (c == '\n')) { 263 if (whiteSpace < 0) whiteSpace = textindex; 264 } else if (whiteSpace >= 0) 265 break; 266 textindex += ddir; 267 } 268 } 269 if (!include) { 270 if (whiteSpace < 0 && dir == XawsdRight) 271 whiteSpace = toc->lastPos; 272 textindex = whiteSpace; 273 } 274 textindex = CoerceToLegalPosition(toc, textindex); 275 break; 276 case XawstEOL: 277 case XawstParagraph: 278 for (i = 0; i < count; i++) { 279 while (textindex >= 0 && textindex <= toc->lastPos) { 280 Look(textindex, c); 281 if (c == '\n') 282 break; 283 textindex += ddir; 284 } 285 if (i < count - 1) 286 textindex += ddir; 287 } 288 if (include) 289 textindex += ddir; 290 textindex = CoerceToLegalPosition(toc, textindex); 291 break; 292 case XawstAll: 293 if (dir == XawsdLeft) 294 textindex = 0; 295 else 296 textindex = toc->lastPos; 297 break; 298 default: 299 break; 300 } 301 return textindex; 302} 303 304/*ARGSUSED*/ 305static XawTextPosition Search( 306 Widget w, 307 XawTextPosition position, 308 XawTextScanDirection direction, 309 XawTextBlock *block) 310{ 311 /* TocSourceWidget source = (TocSourceWidget) w; 312 * Toc toc = source->toc_source.toc; 313 * not implemented 314 */ 315 return XawTextSearchError; 316} 317 318/* Public definitions. */ 319 320/* ARGSUSED*/ 321static void Initialize( 322 Widget request, 323 Widget new, 324 ArgList args, 325 Cardinal *num_args) 326{ 327 Toc toc; 328 TocSourceWidget source = (TocSourceWidget) new; 329 330 source->text_source.edit_mode = XawtextRead; /* force read only. */ 331 332 toc = source->toc_source.toc; 333 334 toc->hasselection = FALSE; 335 toc->left = toc->right = 0; 336} 337 338void 339TSourceInvalid(Toc toc, XawTextPosition position, int length) 340{ 341 XawTextInvalidate(XtParent(toc->source), position, 342 (XawTextPosition) position+length-1); 343} 344