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