home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume17 / tcleditr / part06 < prev    next >
Encoding:
Text File  |  1992-03-17  |  53.7 KB  |  2,179 lines

  1. Newsgroups: comp.sources.x
  2. Path: uunet!think.com!mips!msi!dcmartin
  3. From: crowley@chaco.cs.unm.edu (Charlie Crowley)
  4. Subject: v17i007: point text editor (TCL and TK), Part06/16
  5. Message-ID: <1992Mar18.141431.26767@msi.com>
  6. Originator: dcmartin@fascet
  7. Sender: dcmartin@msi.com (David C. Martin - Moderator)
  8. Organization: Molecular Simulations, Inc.
  9. References: <csx-17i002-tcl-editor@uunet.UU.NET>
  10. Date: Wed, 18 Mar 1992 14:14:31 GMT
  11. Approved: dcmartin@msi.com
  12.  
  13. Submitted-by: crowley@chaco.cs.unm.edu (Charlie Crowley)
  14. Posting-number: Volume 17, Issue 7
  15. Archive-name: tcl-editor/part06
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 5 (of 15)."
  24. # Contents:  anaObjects.c display.c mouse.c search.c
  25. # Wrapped by crowley@chaco.cs.unm.edu on Tue Mar 10 15:05:39 1992
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'anaObjects.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'anaObjects.c'\"
  29. else
  30. echo shar: Extracting \"'anaObjects.c'\" \(10933 characters\)
  31. sed "s/^X//" >'anaObjects.c' <<'END_OF_FILE'
  32. X/* $Header: /nfs/unmvax/faculty/crowley/x/pt/RCS/anaObjects.c,v 1.3 1992/03/04 17:07:18 crowley Exp crowley $ */
  33. X
  34. X#ifdef HYPERTEXT
  35. X#include <sys/types.h>
  36. X#include <sys/file.h>
  37. X#include <string.h>
  38. X#include "pt.h"
  39. X
  40. typedef struct object_table_tag {
  41. X    char *name;
  42. X    int size;
  43. X} object_table_entry;
  44. X
  45. static object_table_entry ObjectTable[] = {
  46. X    {"", 0},    /* dummy so we can avoid magic numbers of 0 */
  47. X    {"Attribute", sizeof(AttributeStruct)},
  48. X    {"Block", sizeof(BlockStruct)},
  49. X    {"Document", sizeof(DocumentStruct)},
  50. X    {"File", sizeof(FileStruct)},
  51. X    {"Link", sizeof(LinkStruct)},
  52. X    {"Map", sizeof(MapStruct)},
  53. X    {"Marker", sizeof(BlockMarkerStruct)},
  54. X    {"Text", sizeof(TextStruct)},
  55. X    {"View", sizeof(ViewStruct)},
  56. X};
  57. X
  58. DBM *
  59. OpenObjects(name)
  60. X    String name;
  61. X{
  62. X    return dbm_open( name, O_RDWR | O_CREAT, 0644 );
  63. X}
  64. X
  65. void
  66. CloseObjects( db )
  67. X    DBM *db;
  68. X{
  69. X    dbm_close( db );
  70. X}
  71. X
  72. void
  73. DumpDB( db )
  74. X    DBM *db;
  75. X{
  76. X    datum d_out;
  77. X    
  78. X    d_out = dbm_firstkey( db );
  79. X    while( d_out.dptr != NULL ) {
  80. X        AnaObject object = (AnaObject)d_out.dptr;
  81. X        printf("magic=%d id=%d next=%d name is %s\n",
  82. X            object->magic, object->this_one,
  83. X            object->next, object->name);
  84. X        d_out = dbm_nextkey( db );
  85. X    }
  86. X}
  87. X
  88. AnaObject
  89. GetObject( db, magic, id, allocate )
  90. X    DBM *db;
  91. X    MagicNumber magic;
  92. X    ID id;
  93. X    AllocationMode allocate;
  94. X{
  95. X    datum d_in, d_out;
  96. X    AnaObject object;
  97. X
  98. X    d_in.dptr = (char *)&id;
  99. X    d_in.dsize = sizeof(ID);
  100. X    d_out = dbm_fetch( db, d_in );
  101. X    if( d_out.dptr == NULL ) {
  102. X        printf("ndbm ERROR in Get%s can't find id=%d\n",
  103. X            ObjectTable[magic].name, id);
  104. X        dbm_clearerr( db );
  105. X        return NULL;
  106. X    }
  107. X    if( d_out.dsize != ObjectTable[magic].size ) {
  108. X        printf("ndbm ERROR in Get%s id=%d, wrong size.",
  109. X            ObjectTable[magic].name, id);
  110. X        printf(" Size is %d and it should be %d\n", d_out.dsize,
  111. X            ObjectTable[magic].size );
  112. X        return NULL;
  113. X    }
  114. X    object = (AnaObject)d_out.dptr;
  115. X    if( object->magic != magic ) {
  116. X        printf("ndbm ERROR in Get%s id=%d, wrong magic number.",
  117. X            ObjectTable[magic].name, id);
  118. X        printf("Magic number is %d and it should be %d\n",
  119. X            object->magic, magic);
  120. X        return NULL;
  121. X    }
  122. X    if( allocate ) {
  123. X        object = (AnaObject)PtMalloc( d_out.dsize, "ana object" );
  124. X        /* copy d_out.dptr into object */
  125. X        memcpy( (char *)object, (char *)d_out.dptr, d_out.dsize );
  126. X    }
  127. X    return object;
  128. X}
  129. X
  130. void
  131. PutObject( db, magic, object, release )
  132. X    DBM *db;
  133. X    MagicNumber magic;
  134. X    AnaObject object;
  135. X    ReleaseMode release;
  136. X{
  137. X    datum d_key, d_object;
  138. X    int ret;
  139. X
  140. X    if( object == NULL )
  141. X        return;
  142. X    d_key.dptr = (char *)&(object->this_one);
  143. X    d_key.dsize = sizeof(ID);
  144. X    d_object.dptr = (char *)object;
  145. X    d_object.dsize = ObjectTable[magic].size;
  146. X    ret = dbm_store( db, d_key, d_object, DBM_REPLACE);
  147. X    if( ret != 0 )
  148. X        printf("ndbm ERROR in Put%s, ret=%d\n",
  149. X            ObjectTable[magic].name, ret);
  150. X    if( release )
  151. X        PtFree( (char *)object );
  152. X}
  153. X
  154. Block
  155. GetBlock( db, blockID, allocate )
  156. X    DBM *db;
  157. X    BlockID blockID;
  158. X    AllocationMode allocate;
  159. X{
  160. X    return (Block)GetObject( db, BlockMagic, (ID)blockID, allocate );
  161. X}
  162. X
  163. void
  164. PutBlock( db, block, release )
  165. X    DBM *db;
  166. X    Block block;
  167. X    ReleaseMode release;
  168. X{
  169. X    PutObject( db, BlockMagic, (AnaObject)block, release );
  170. X}
  171. X
  172. Attribute
  173. GetAttribute( db, attributeID, allocate )
  174. X    DBM *db;
  175. X    AttributeID attributeID;
  176. X    AllocationMode allocate;
  177. X{
  178. X    return (Attribute)GetObject(db,AttributeMagic,(ID)attributeID,allocate);
  179. X}
  180. X
  181. void
  182. PutAttribute( db, attribute, release )
  183. X    DBM *db;
  184. X    Attribute attribute;
  185. X    ReleaseMode release;
  186. X{
  187. X    PutObject( db, AttributeMagic, (AnaObject)attribute, release );
  188. X}
  189. X
  190. Map
  191. GetMap( db, mapID, allocate )
  192. X    DBM *db;
  193. X    MapID mapID;
  194. X    AllocationMode allocate;
  195. X{
  196. X    return (Map)GetObject( db, MapMagic, (ID)mapID, allocate );
  197. X}
  198. X
  199. void
  200. PutMap( db, map, release )
  201. X    DBM *db;
  202. X    Map map;
  203. X    ReleaseMode release;
  204. X{
  205. X    PutObject( db, MapMagic, (AnaObject)map, release );
  206. X}
  207. X
  208. XFile
  209. GetFile( db, fileID, allocate )
  210. X    DBM *db;
  211. X    FileID fileID;
  212. X    AllocationMode allocate;
  213. X{
  214. X    return (File)GetObject( db, FileMagic, (ID)fileID, allocate );
  215. X}
  216. X
  217. void
  218. PutFile( db, file, release )
  219. X    DBM *db;
  220. X    File file;
  221. X    ReleaseMode release;
  222. X{
  223. X    PutObject( db, FileMagic, (AnaObject)file, release );
  224. X}
  225. X
  226. Text
  227. GetText( db, textID, allocate )
  228. X    DBM *db;
  229. X    TextID textID;
  230. X    AllocationMode allocate;
  231. X{
  232. X    return (Text)GetObject( db, TextMagic, (ID)textID, allocate );
  233. X}
  234. X
  235. void
  236. PutText( db, text, release )
  237. X    DBM *db;
  238. X    Text text;
  239. X    ReleaseMode release;
  240. X{
  241. X    PutObject( db, TextMagic, (AnaObject)text, release );
  242. X}
  243. X
  244. Link
  245. GetLink( db, linkID, allocate )
  246. X    DBM *db;
  247. X    LinkID linkID;
  248. X    AllocationMode allocate;
  249. X{
  250. X    return (Link)GetObject( db, LinkMagic, (ID)linkID, allocate );
  251. X}
  252. X
  253. void
  254. PutLink( db, link, release )
  255. X    DBM *db;
  256. X    Link link;
  257. X    ReleaseMode release;
  258. X{
  259. X    PutObject( db, LinkMagic, (AnaObject)link, release );
  260. X}
  261. X
  262. View
  263. GetView( db, viewID, allocate )
  264. X    DBM *db;
  265. X    ViewID viewID;
  266. X    AllocationMode allocate;
  267. X{
  268. X    return (View)GetObject( db, ViewMagic, (ID)viewID, allocate );
  269. X}
  270. X
  271. void
  272. PutView( db, view, release )
  273. X    DBM *db;
  274. X    View view;
  275. X    ReleaseMode release;
  276. X{
  277. X    PutObject( db, ViewMagic, (AnaObject)view, release );
  278. X}
  279. X
  280. Document
  281. GetDocument( db, documentID, allocate )
  282. X    DBM *db;
  283. X    DocumentID documentID;
  284. X    AllocationMode allocate;
  285. X{
  286. X    return (Document)GetObject(db, DocumentMagic, (ID)documentID, allocate);
  287. X}
  288. X
  289. void
  290. PutDocument( db, document, release )
  291. X    DBM *db;
  292. X    Document document;
  293. X    ReleaseMode release;
  294. X{
  295. X    PutObject( db, DocumentMagic, (AnaObject)document, release );
  296. X}
  297. X
  298. Block
  299. CreateBlock( db, document, name, attribute, hint, file )
  300. X    DBM *db;
  301. X    Document document;
  302. X    char *name;
  303. X    AttributeID attribute;
  304. X    Offset hint;
  305. X    FileID file;
  306. X{
  307. X    Block block;
  308. X    int i;
  309. X
  310. X    block = (Block)PtMalloc( sizeof(BlockStruct), "ana block" );
  311. X    block->magic = BlockMagic;
  312. X    block->this_one = (document->nextFreeID)++;
  313. X    block->next = document->firstBlock;
  314. X    document->firstBlock = block->this_one;
  315. X    strncpy( block->name, name, NAME_SIZE );
  316. X    for( i = 1; i < MAX_ATTRIBUTES; ++i )
  317. X         block->attribute[i] = NullObject;
  318. X    block->attribute[0] = attribute;
  319. X    block->hint = hint;
  320. X    block->file = file;
  321. X    block->numLinks = 0;
  322. X    block->firstFromLink = NullObject;
  323. X    block->firstToLink = NullObject;
  324. X    PutBlock( db, block, NO_RELEASE );
  325. X    return block;
  326. X}
  327. X
  328. Attribute
  329. CreateAttribute( db, document, name )
  330. X    DBM *db;
  331. X    Document document;
  332. X    char *name;
  333. X{
  334. X    Attribute attribute;
  335. X
  336. X    attribute = (Attribute)PtMalloc( sizeof(AttributeStruct),
  337. X                        "ana attribute" );
  338. X    attribute->magic = AttributeMagic;
  339. X    attribute->this_one = (document->nextFreeID)++;
  340. X    attribute->next = document->firstAttribute;
  341. X    document->firstAttribute = attribute->this_one;
  342. X    strncpy( attribute->name, name, NAME_SIZE );
  343. X    PutAttribute( db, attribute, NO_RELEASE );
  344. X    return attribute;
  345. X}
  346. X
  347. X/*ARGSUSED*/
  348. AttributeID
  349. LookupAttributeByName( db, document, name )
  350. X    DBM *db;
  351. X    Document document;
  352. X    char *name;
  353. X{
  354. X    extern DBM *currentDB;
  355. X
  356. X    Attribute attribute;
  357. X    int attributeID = document->firstAttribute;
  358. X
  359. X    while( attributeID != NullObject ) {
  360. X        attribute = GetAttribute( currentDB, attributeID, NO_ALLOCATE );
  361. X        if( strcmp(name,attribute->name) == 0 )
  362. X            return attributeID;
  363. X        attributeID = attribute->next;
  364. X    }
  365. X    return NullObject;
  366. X}
  367. X
  368. Map
  369. CreateMap( db, document, name )
  370. X    DBM *db;
  371. X    Document document;
  372. X    char *name;
  373. X{
  374. X    Map map;
  375. X    int i;
  376. X
  377. X    map = (Map)PtMalloc( sizeof(MapStruct), "ana map" );
  378. X    map->magic = MapMagic;
  379. X    map->this_one = (document->nextFreeID)++;
  380. X    map->next = document->firstMap;
  381. X    document->firstMap = map->this_one;
  382. X    strncpy( map->name, name, NAME_SIZE );
  383. X    for( i = 0; i < MAP_SIZE; ++i ) {
  384. X        map->domain[i] = NullObject;
  385. X        map->range[i][0] = '\0';
  386. X    }
  387. X    PutMap( db, map, NO_RELEASE );
  388. X    return map;
  389. X}
  390. X
  391. X/*ARGSUSED*/
  392. MapID
  393. LookupMapByName( db, document, name )
  394. X    DBM *db;
  395. X    Document document;
  396. X    char *name;
  397. X{
  398. X    extern DBM *currentDB;
  399. X
  400. X    Map map;
  401. X    int mapID = document->firstMap;
  402. X
  403. X    while( mapID != NullObject ) {
  404. X        map = GetMap( currentDB, mapID, NO_ALLOCATE );
  405. X        if( strcmp(name,map->name) == 0 )
  406. X            return mapID;
  407. X        mapID = map->next;
  408. X    }
  409. X    return NullObject;
  410. X}
  411. X
  412. Link
  413. CreateLink( db, document, name, attribute, from, to )
  414. X    DBM *db;
  415. X    Document document;
  416. X    char *name;
  417. X    AttributeID attribute;
  418. X    BlockID from, to;
  419. X{
  420. X    Link link;
  421. X    int i;
  422. X
  423. X    link = (Link)PtMalloc( sizeof(LinkStruct), "ana link" );
  424. X    link->magic = LinkMagic;
  425. X    link->this_one = (document->nextFreeID)++;
  426. X    link->next = document->firstLink;
  427. X    document->firstLink = link->this_one;
  428. X    strncpy( link->name, name, NAME_SIZE );
  429. X    for( i = 1; i < MAX_ATTRIBUTES; ++i )
  430. X         link->attribute[i] = NullObject;
  431. X    link->attribute[0] = attribute;
  432. X    link->nextFromLink = NullObject;
  433. X    link->from = from;
  434. X    link->nextToLink = NullObject;
  435. X    link->to = to;
  436. X    PutLink( db, link, NO_RELEASE );
  437. X    return link;
  438. X}
  439. X
  440. XFile
  441. CreateFile( db, document, name )
  442. X    DBM *db;
  443. X    Document document;
  444. X    char *name;
  445. X{
  446. X    File file;
  447. X
  448. X    file = (File)PtMalloc( sizeof(FileStruct), "ana file" );
  449. X    file->magic = FileMagic;
  450. X    strncpy( file->name, name , NAME_SIZE );
  451. X    file->this_one = (document->nextFreeID)++;
  452. X    file->next = document->firstFile;
  453. X    document->firstFile = file->this_one;
  454. X    PutFile( db, file, NO_RELEASE );
  455. X    return file;
  456. X}
  457. X
  458. X/*ARGSUSED*/
  459. XFileID
  460. LookupFileByName( db, document, name )
  461. X    DBM *db;
  462. X    Document document;
  463. X    char *name;
  464. X{
  465. X    extern DBM *currentDB;
  466. X
  467. X    File file;
  468. X    int fileID = document->firstFile;
  469. X
  470. X    while( fileID != NullObject ) {
  471. X        file = GetFile( currentDB, fileID, NO_ALLOCATE );
  472. X        if( strcmp(name,file->name) == 0 )
  473. X            return fileID;
  474. X        fileID = file->next;
  475. X    }
  476. X    return NullObject;
  477. X}
  478. X
  479. Text
  480. CreateText( db, document, s )
  481. X    DBM *db;
  482. X    Document document;
  483. X    char *s;
  484. X{
  485. X    Text text;
  486. X
  487. X    text = (Text)PtMalloc( sizeof(TextStruct), "ana text" );
  488. X    text->magic = TextMagic;
  489. X    text->this_one = (document->nextFreeID)++;
  490. X    text->next = document->firstText;
  491. X    document->firstText = text->this_one;
  492. X    strncpy( text->s, s, NAME_SIZE );
  493. X    PutText( db, text, NO_RELEASE );
  494. X    return text;
  495. X}
  496. X
  497. View
  498. CreateView( db, document, name, blockID, fromLinkMap, toLinkMap, blockMap )
  499. X    DBM *db;
  500. X    Document document;
  501. X    char *name;
  502. X    BlockID blockID;
  503. X    MapID fromLinkMap, toLinkMap, blockMap;
  504. X{
  505. X    View view;
  506. X
  507. X    view = (View)PtMalloc( sizeof(ViewStruct), "ana view" );
  508. X    view->magic = ViewMagic;
  509. X    view->this_one = (document->nextFreeID)++;
  510. X    view->next = document->firstView;
  511. X    document->firstView = view->this_one;
  512. X    strncpy( view->name, name, NAME_SIZE );
  513. X    view->blockID = blockID;
  514. X    view->fromLinkMap = fromLinkMap;
  515. X    view->toLinkMap = toLinkMap;
  516. X    view->blockMap = blockMap;
  517. X    PutView( db, view, NO_RELEASE );
  518. X    return view;
  519. X}
  520. X
  521. Document
  522. CreateDocument( db, name )
  523. X    DBM *db;
  524. X    char *name;
  525. X{
  526. X    Document document;
  527. X
  528. X    document = (Document)PtMalloc( sizeof(DocumentStruct), "ana document" );
  529. X    document->magic = DocumentMagic;
  530. X    document->this_one = 1;
  531. X    document->next = NullObject;
  532. X    strncpy( document->name, name, NAME_SIZE );
  533. X    /* start IDs at 100 so we can use low ids for conventional */
  534. X    /* purposes, like open fileIds as IDs */
  535. X    document->nextFreeID = 100;
  536. X    document->initialView = NullObject;
  537. X    document->firstBlock = NullObject;
  538. X    document->firstAttribute = NullObject;
  539. X    document->firstLink = NullObject;
  540. X    document->firstFile = NullObject;
  541. X    document->firstView = NullObject;
  542. X    document->firstMap = NullObject;
  543. X    document->firstText = NullObject;
  544. X    PutDocument( db, document, NO_RELEASE );
  545. X    return document;
  546. X}
  547. X#endif
  548. X
  549. END_OF_FILE
  550. if test 10933 -ne `wc -c <'anaObjects.c'`; then
  551.     echo shar: \"'anaObjects.c'\" unpacked with wrong size!
  552. fi
  553. # end of 'anaObjects.c'
  554. fi
  555. if test -f 'display.c' -a "${1}" != "-c" ; then 
  556.   echo shar: Will not clobber existing file \"'display.c'\"
  557. else
  558. echo shar: Extracting \"'display.c'\" \(12952 characters\)
  559. sed "s/^X//" >'display.c' <<'END_OF_FILE'
  560. X/* $Header: /nfs/unmvax/faculty/crowley/x/pt/RCS/display.c,v 1.7 1992/03/04 17:07:18 crowley Exp crowley $ */
  561. X
  562. X#include <math.h>
  563. X#include <string.h>
  564. X#include <stdio.h>
  565. X#include "pt.h"
  566. X#include <X11/StringDefs.h>
  567. X
  568. static int maxLineLength = 1;
  569. X
  570. X/* character table for fillLine (in windtext.c) */
  571. char charTable[257];
  572. X
  573. X/* screen line buffer */
  574. char screenLine[MAXCOLS];
  575. X
  576. void
  577. drawWindowFast(w, firstRow, lastRow, firstCol, lastCol )
  578. X    struct window *w;
  579. X    int firstRow, lastRow, firstCol, lastCol;
  580. X{
  581. X    extern int debug;
  582. X
  583. X        fillWindow(w, firstRow, lastRow, firstCol, lastCol );
  584. X    banner( w, 1 );
  585. X}
  586. X
  587. void
  588. drawWindow(w)
  589. X    register struct window *w;
  590. X{
  591. X    extern int debug;
  592. X
  593. X    if( w == NULL )
  594. X        return;
  595. X    fillWindow(w, 0, w->nRows-1, 0, w->nCols-1);
  596. X    banner( w, 1 );
  597. X}
  598. X
  599. static char *
  600. XFormatTitle( format, w, ff )
  601. X    char * format;
  602. X        struct window *w;
  603. X        struct openFile *ff;
  604. X{
  605. X    extern char textBuffer[];
  606. X    extern char msgBuffer[];
  607. X    extern int pathNames;
  608. X    extern int overType;
  609. X    extern int hypertextOn;
  610. X        extern struct openFile *files;
  611. X
  612. X    char * to = msgBuffer;
  613. X    char * copy_in;
  614. X    char ch;
  615. X
  616. X    while( (ch = *format++) != '\0' ) {
  617. X        if( ch != '%' ) {
  618. X            *to++ = ch;
  619. X            continue;
  620. X        }
  621. X        /* read a '%' */
  622. X        switch( ch = *format++ ) {
  623. X        default:    /* anything, including a literal '%' */
  624. X            textBuffer[0] = ch;
  625. X            textBuffer[1] = '\0';
  626. X            copy_in = textBuffer;
  627. X            break;
  628. X        case 'n':    /* file name */
  629. X            copy_in = &((ff->origName)[pathNames?0:w->nameOffset]);
  630. X            break;
  631. X        case 'N':    /* full path file name */
  632. X            copy_in = &((ff->origName)[0]);
  633. X            break;
  634. X        case 's':    /* short file name */
  635. X            copy_in = &((ff->origName)[w->nameOffset]);
  636. X            break;
  637. X        case 'c':    /* changed  flag */
  638. X            {/* get the change indicator string */
  639. X                char * to = textBuffer;
  640. X                char delimiter = *format++;
  641. X                while( 1 ) {
  642. X                    ch = *format++;
  643. X                    if( ch == delimiter )
  644. X                        break;
  645. X                    /* allow for missing delimiters */
  646. X                    if( ch == '\0' ) {
  647. X                        --format;
  648. X                        msg(
  649. X"Missing change flag in title format", 1 );
  650. X                        break;
  651. X                    }
  652. X                    *to++ = ch;
  653. X                }
  654. X                *to = '\0';
  655. X            }
  656. X            if( ff->flags&IS_CHANGED ) {
  657. X                copy_in = textBuffer;
  658. X            } else
  659. X                copy_in = "";
  660. X            break;
  661. X        case 'o':    /* overType flag */
  662. X            {/* get the overtype indicator string */
  663. X                char * to = textBuffer;
  664. X                char delimiter = *format++;
  665. X                while( 1 ) {
  666. X                    ch = *format++;
  667. X                    if( ch == delimiter )
  668. X                        break;
  669. X                    /* allow for missing delimiters */
  670. X                    if( ch == '\0' ) {
  671. X                        --format;
  672. X                        msg(
  673. X"Missing overtype flag in title format", 1 );
  674. X                        break;
  675. X                    }
  676. X                    *to++ = ch;
  677. X                }
  678. X                *to = '\0';
  679. X            }
  680. X            if( overType ) {
  681. X                copy_in = textBuffer;
  682. X            } else
  683. X                copy_in = "";
  684. X            break;
  685. X        case 'r':    /* readOnly flag */
  686. X            {/* get the readOnly indicator string */
  687. X                char * to = textBuffer;
  688. X                char delimiter = *format++;
  689. X                while( 1 ) {
  690. X                    ch = *format++;
  691. X                    if( ch == delimiter )
  692. X                        break;
  693. X                    /* allow for missing delimiters */
  694. X                    if( ch == '\0' ) {
  695. X                        --format;
  696. X                        msg(
  697. X"Missing read only flag in title format", 1 );
  698. X                        break;
  699. X                    }
  700. X                    *to++ = ch;
  701. X                }
  702. X                *to = '\0';
  703. X            }
  704. X            if( ff->flags&READ_ONLY ) {
  705. X                copy_in = textBuffer;
  706. X            } else
  707. X                copy_in = "";
  708. X            break;
  709. X        case 'l':    /* beginning line number */
  710. X            sprintf( textBuffer, "%d", w->numTopline );
  711. X            copy_in = textBuffer;
  712. X            break;
  713. X        case 'L':    /* ending line number */
  714. X            sprintf( textBuffer, "%d", w->numBotline - 1 );
  715. X            copy_in = textBuffer;
  716. X            break;
  717. X        case 'p':    /* beginning position number */
  718. X            sprintf( textBuffer, "%d", w->posTopline );
  719. X            copy_in = textBuffer;
  720. X            break;
  721. X        case 'P':    /* ending position number */
  722. X            sprintf( textBuffer, "%d", w->posBotline - 1 );
  723. X            copy_in = textBuffer;
  724. X            break;
  725. X        case 'S':    /* file size (in bytes) */
  726. X            sprintf( textBuffer, "%d", ff->fileSize );
  727. X            copy_in = textBuffer;
  728. X            break;
  729. X        case 'v':    /* beginning column number */
  730. X            sprintf( textBuffer, "%d", w->indent + 1 );
  731. X            copy_in = textBuffer;
  732. X            break;
  733. X        case 'V':    /* ending column number */
  734. X            sprintf( textBuffer, "%d", w->indent + w->nCols );
  735. X            copy_in = textBuffer;
  736. X            break;
  737. X#ifdef HYPERTEXT
  738. X        case 'M':    /* block map name */
  739. X            if( w->blockMap!=NULL && hypertextOn )
  740. X                sprintf( textBuffer, "%s", w->blockMap->name );
  741. X            else
  742. X                textBuffer[0] = '\0';
  743. X            copy_in = textBuffer;
  744. X            break;
  745. X#endif
  746. X        }
  747. X        while( *copy_in != '\0' )
  748. X            *to++ = *copy_in++;
  749. X    }
  750. X    *to = '\0';
  751. X    
  752. X    return msgBuffer;
  753. X}
  754. X
  755. void
  756. banner( w, doSlider )
  757. X    register struct window *w;
  758. X    int doSlider;
  759. X{
  760. X    extern int msgInTitleLine;
  761. X    extern int debug;
  762. X    extern char * titleFormat;
  763. X    extern char * iconFormat;
  764. X
  765. X    long lp;
  766. X        struct openFile *ff;
  767. X
  768. X    /* remember that we don't have to draw the banner again */
  769. X    msgInTitleLine = 0;
  770. X
  771. X    /* guard against calls with a NULL argument */
  772. X    if( w == NULL )
  773. X        return;
  774. X
  775. X    if( w->fileId == -1 ) {
  776. X        return;
  777. X    } else {
  778. X        ff = &(files[w->fileId]);
  779. X        lp = ff->fileSize;
  780. X    }
  781. X    
  782. X    /* set the window and icon titles */
  783. X    sprintf( textBuffer, "wm title %s {%s}", w->tk_pathname,
  784. X            FormatTitle( titleFormat, w, ff) );
  785. X    (void)ExecTclCommand( textBuffer );
  786. X    sprintf( textBuffer,"wm iconname %s {%s}", w->tk_pathname,
  787. X            FormatTitle( iconFormat, w, ff) );
  788. X    (void)ExecTclCommand( textBuffer );
  789. X
  790. X    if( doSlider )
  791. X        SetSlider( w, lp );
  792. X}
  793. X
  794. void
  795. SetSlider( w, total )
  796. X    struct window *w;
  797. X    int total;
  798. X{
  799. X    extern char msgBuffer[];
  800. X
  801. X    int inwindow, first, last;
  802. X
  803. X    /* set vertical scroll bar */
  804. X    if( total == 0 ) /* guard again zerodivide */
  805. X        total = 1;
  806. X    first = w->posTopline;
  807. X    last = w->posBotline - 2;
  808. X    if( last < first )
  809. X        last = first;
  810. X    inwindow = last - first;
  811. X    if( inwindow < 0 )
  812. X        inwindow = 0;
  813. X    sprintf( msgBuffer, "%s.VScrollAndText.VScroll set %d %d %d %d",
  814. X        w->tk_pathname, total, inwindow, first, last );
  815. X    (void)ExecTclCommand( msgBuffer );
  816. X
  817. X    /* set horizontal scroll bar */
  818. X    total = w->nCols;
  819. X    if( total < maxLineLength )
  820. X        total = maxLineLength;
  821. X    if( total <= 0 )
  822. X        total = 1;
  823. X    inwindow = w->nCols;
  824. X    first = w->indent;
  825. X    if( first >= total )
  826. X        first = total - 1;
  827. X    last = w->indent+w->nCols-1;
  828. X    if( last < first )
  829. X        last = first + 1;
  830. X    if( last >= total )
  831. X        last = total - 1;
  832. X    sprintf( msgBuffer, "%s.SplitterAndHScroll.HScroll set %d %d %d %d",
  833. X        w->tk_pathname, total, inwindow, first, last );
  834. X    (void)ExecTclCommand( msgBuffer );
  835. X}
  836. X
  837. void
  838. fillWindow(w, firstRow, lastRow, firstCol, lastCol)
  839. X    register struct window *w;
  840. X    int firstRow, lastRow, firstCol, lastCol;
  841. X{
  842. X    extern int debug;
  843. X    extern int hypertextOn;
  844. X    extern struct window *selWindow;
  845. X    extern Display *MainDisplay;
  846. X
  847. X    Offset cp;
  848. X    int i, y, row, lineNumber;
  849. X    int col1, col2;
  850. X    struct fontDataStruct *font;
  851. X    int fid;
  852. X
  853. X    if( w == NULL )
  854. X        return;
  855. X
  856. X#ifdef HYPERTEXT
  857. X    if( w->file != NULL && !hypertextOn )
  858. X        /* a hypertext file but not in hypertext mode */
  859. X        fid = w->realFileId;
  860. X    else
  861. X#endif
  862. X        fid = w->fileId;
  863. X    
  864. X    font = &(w->font);
  865. X
  866. X    maxLineLength = 1;    /* reset this count */
  867. X
  868. X    /* fill the rows one at a time */
  869. X
  870. X    /* initialize */
  871. X    cp = w->posTopline;
  872. X    lineNumber = w->numTopline;
  873. X    y = w->topMargin + font->ascent;
  874. X
  875. X    /* skip the rows above the ones we are redrawing */
  876. X    for( row = 0; row < firstRow; ++row ) {
  877. X        i = 1;
  878. X        cp = nextLine( fid, cp, &i);
  879. X        y += font->height;
  880. X        ++lineNumber;
  881. X    }
  882. X    
  883. X    /* clear the area we are redrawing */
  884. X    XClearArea(MainDisplay, w->x_window_id, 0, y - font->ascent,
  885. X        Tk_Width(w->tk_text), (lastRow - row + 1)*(font->height),
  886. X        False );
  887. X        /* 0 width => clear the whole width of the window */
  888. X        /* False means: do not generate exposure events */
  889. X
  890. X    /* rewrite the lines required */
  891. X    for( ; row <= lastRow; ++row ) {
  892. X        if( row == firstRow )
  893. X            col1 = firstCol;
  894. X        else
  895. X            col1 = 0;
  896. X        if( row == lastRow )
  897. X            col2 = lastCol;
  898. X        else
  899. X            col2 = w->nCols - 1;
  900. X        cp = fillLine( w, cp, row, col1, col2, y, 1 );
  901. X        if( cp == -1 ) {
  902. X            ++row;    /* at least the EOF marker printed out */
  903. X            break;
  904. X        }
  905. X        y += font->height;
  906. X        ++lineNumber;
  907. X    }
  908. X
  909. X    /* count down through the rows we are not drawing */
  910. X    for( ; row < w->nRows; ++row ) {
  911. X        if( cp == -1 )
  912. X            break;
  913. X        i = 1;
  914. X        cp = nextLine( fid, cp, &i);
  915. X        ++lineNumber;
  916. X    }
  917. X
  918. X    /* If we got to the end of the file we want posBotline to be */
  919. X    /* the size of the file (which will be one past the last character */
  920. X    /* in the file since we start counting at 0) */
  921. X    if( cp == -1 )
  922. X        cp = fileSize( w->fileId );
  923. X    w->posBotline = cp;
  924. X    w->numBotline = lineNumber;
  925. X}
  926. X
  927. X/* I know I shouldn't use global variables for procedure parameters */
  928. X/* but these are called for every single character so I am compromising */
  929. struct window *w;
  930. char *sLine;
  931. GC gc, gc_normal;
  932. int x, y;
  933. int inSelection;
  934. int logicalCol;
  935. int row;
  936. int indent;
  937. Offset cp;
  938. struct fontDataStruct *font;
  939. X
  940. void
  941. DrawString()
  942. X{
  943. X    extern char screenLine[];
  944. X    extern int underlineSelection;
  945. X    extern Display *MainDisplay;
  946. X    extern int debug;
  947. X
  948. X    int char_len, pix_len;
  949. X
  950. X    *sLine = '\0';
  951. X    char_len = sLine - screenLine;
  952. X    pix_len = char_len * font->width;
  953. X    if( char_len > 0 ) {
  954. X        if( inSelection && (underlineSelection > 0) )
  955. X            gc = gc_normal;
  956. X        XDrawImageString( MainDisplay, w->x_window_id, gc, x, y,
  957. X            screenLine, char_len );
  958. X        if( inSelection && (underlineSelection > 0) ) {
  959. X            int y2 = y + 1;
  960. X            XDrawLine(MainDisplay, w->x_window_id, gc, x, y2,
  961. X                            x+pix_len-1, y2);
  962. X            if( underlineSelection == 2 )
  963. X                XDrawLine( MainDisplay, w->x_window_id, gc,
  964. X                        x, y2+1, x+pix_len-1, y2+1 );
  965. X        }
  966. X        x += pix_len;
  967. X    }
  968. X    sLine = screenLine;
  969. X}
  970. X
  971. Offset
  972. fillLine(w_in, cp_in, row_in, firstCol, lastCol, y_in, fillToEol)
  973. X    struct window *w_in;
  974. X    Offset cp_in;
  975. X    int row_in, firstCol, lastCol, y_in, fillToEol;
  976. X{
  977. X    extern struct window *selWindow;
  978. X    extern char charTable[];
  979. X    extern char screenLine[];
  980. X    extern int tabWidth;
  981. X    extern int eofChar;
  982. X    extern Display *MainDisplay;
  983. X    extern Offset selBegin, selEnd;
  984. X    extern int hypertextOn;
  985. X    extern int getSpanSize;
  986. X
  987. X    int uch;
  988. X    int tabStop;
  989. X    int fid;
  990. X    unsigned char *firstByte;
  991. X    unsigned char *lastByte;
  992. X    char *sLineMax;
  993. X    
  994. X    /* make these values available to DrawString and CheckForSelection */
  995. X    cp = cp_in;
  996. X    w = w_in;
  997. X    y = y_in;
  998. X    row = row_in;
  999. X    font = &(w->font);
  1000. X    
  1001. X#ifdef HYPERTEXT
  1002. X    if( w->file != NULL && !hypertextOn )
  1003. X        /* a hypertext file but not in hypertext mode */
  1004. X        fid = w->realFileId;
  1005. X    else
  1006. X#endif
  1007. X        fid = w->fileId;
  1008. X
  1009. X    /* set up for the loop */
  1010. X    inSelection = 0;
  1011. X    gc_normal = font->gc_normal;
  1012. X    gc = gc_normal;
  1013. X    logicalCol = 0;
  1014. X    indent = w->indent;
  1015. X    lastCol += indent;
  1016. X    x = w->leftMargin;
  1017. X    sLine = screenLine;
  1018. X    sLineMax = sLine + MAXCOLS - 1;
  1019. X
  1020. X    /* set things up so we will call getSpan first thing */
  1021. X    firstByte = (unsigned char *)1;
  1022. X    lastByte = (unsigned char *)0;
  1023. X    
  1024. X    /* handle line numbering */
  1025. X    if( w->lineNumbers && firstCol == 0 ) {
  1026. X        int ln = row + w->numTopline;
  1027. X        int i;
  1028. X        char s[12];
  1029. X        
  1030. X        sprintf(s, "%4d:", ln);
  1031. X        for( i = 0; i < 5; ++i )
  1032. X            *sLine++ = s[i];
  1033. X    }
  1034. X
  1035. X    /* loop until we get to the end of the line or the window */
  1036. X    while( logicalCol <= lastCol ) {
  1037. X        /****Begin CheckForSelection();****/
  1038. X        if( selBegin <= cp && cp <= selEnd && w == selWindow ) {
  1039. X            /* we are inside the selection */
  1040. X            if( !inSelection ) {
  1041. X                DrawString();
  1042. X                gc = font->gc_selected;
  1043. X                inSelection = 1;
  1044. X            }
  1045. X        } else {
  1046. X            /* we are not inside the selection */
  1047. X            if( inSelection ) {
  1048. X                DrawString();
  1049. X                gc = font->gc_normal;
  1050. X                inSelection = 0;
  1051. X            }
  1052. X        }
  1053. X        /****End CheckForSelection();****/
  1054. X        if( firstByte > lastByte ) {
  1055. X            if( getSpan( fid, cp, &firstByte, &lastByte, 0 ) ) {
  1056. X                uch = BLOCK_EOF;
  1057. X                goto atEOF;
  1058. X            }
  1059. X        }
  1060. X++getSpanSize;
  1061. X        uch = (unsigned char)(*firstByte++);
  1062. X        ++cp;
  1063. X        /* check limits of line buffer */
  1064. X        if( sLine > sLineMax )
  1065. X            sLine = sLineMax;
  1066. X        switch( charTable[uch] ) {
  1067. X        
  1068. X        case 2:        /* end of file */
  1069. X    atEOF:
  1070. X            if( eofChar != -1 )
  1071. X                *sLine++ = (char)eofChar;
  1072. X            cp = -1;    /* indicate end of file written */
  1073. X            goto endLoop;
  1074. X
  1075. X        case 1:        /* newline -- end of line  */
  1076. X            *sLine++ = ' ';
  1077. X            goto endLoop;
  1078. X
  1079. X        case 3:    /* tab */
  1080. X            tabStop = tabWidth - (logicalCol % tabWidth)
  1081. X                    + logicalCol;
  1082. X            if( (sLine+tabWidth) > sLineMax )
  1083. X                sLine = sLineMax-tabWidth;
  1084. X            while( ++logicalCol <= tabStop )
  1085. X                if( logicalCol >= indent )
  1086. X                    *sLine++ = ' ';
  1087. X            --logicalCol;    /* one ++ too many above */
  1088. X            break;
  1089. X
  1090. X        case 0:    /* other (one char position) character */
  1091. X            if( logicalCol++ >= indent ) {
  1092. X                *sLine++ = uch;
  1093. X            }
  1094. X            break;
  1095. X
  1096. X        }
  1097. X    }
  1098. endLoop:
  1099. X    /* write out the last part of the text */
  1100. X    DrawString();
  1101. X    if( fillToEol )
  1102. X        /* clear to the end of the line */
  1103. X        XClearArea(MainDisplay, w->x_window_id, x, y - font->ascent,
  1104. X            0, font->height, False );
  1105. X            /* 0 width => clear the whole width of the window */
  1106. X            /* False means: do not generate exposure events */
  1107. X
  1108. X
  1109. X    /* find the end of the line */
  1110. X    /* only look if we have not already gotten to EOF */
  1111. X    while( uch != '\n' && uch != BLOCK_EOF ) {
  1112. X            /* NOTE: */
  1113. X            /* Since we are postincrementing we could move cp */
  1114. X            /* two past EOF, check if this is a problem in some */
  1115. X            /* other place that uses the returned value (cp) */
  1116. X        uch = getFileByte( fid, cp++ );
  1117. X        if( uch == '\t' )
  1118. X            logicalCol += tabWidth - (logicalCol % tabWidth) - 1;
  1119. X        ++logicalCol;
  1120. X    }
  1121. X
  1122. X    /* adjust for the NL */
  1123. X    --logicalCol;
  1124. X    if( logicalCol > maxLineLength )
  1125. X        maxLineLength = logicalCol;
  1126. X
  1127. X    return cp;
  1128. X}
  1129. X
  1130. END_OF_FILE
  1131. if test 12952 -ne `wc -c <'display.c'`; then
  1132.     echo shar: \"'display.c'\" unpacked with wrong size!
  1133. fi
  1134. # end of 'display.c'
  1135. fi
  1136. if test -f 'mouse.c' -a "${1}" != "-c" ; then 
  1137.   echo shar: Will not clobber existing file \"'mouse.c'\"
  1138. else
  1139. echo shar: Extracting \"'mouse.c'\" \(11478 characters\)
  1140. sed "s/^X//" >'mouse.c' <<'END_OF_FILE'
  1141. X/* $Header: /nfs/unmvax/faculty/crowley/x/pt/RCS/mouse.c,v 1.9 1992/03/04 17:07:18 crowley Exp crowley $ */
  1142. X
  1143. X#include <stdio.h>
  1144. X#include "pt.h"
  1145. X#include <X11/Xatom.h>
  1146. X
  1147. X/* mouse motion constants (for the arrays) */
  1148. X#define MM_NOMOTION    0
  1149. X#define MM_NORTH    1
  1150. X#define MM_EAST        2
  1151. X#define MM_SOUTH    3
  1152. X#define MM_WEST        4
  1153. X
  1154. static int mouseMotionActive = 0;
  1155. static int currentDirection;
  1156. X
  1157. X/* variables to handle timing */
  1158. static int intervalOn = 0;
  1159. static Tk_TimerToken timer_token;
  1160. static struct window * mouse_w;
  1161. X
  1162. X/* global mouse motion variables */
  1163. struct mmData * mm_data;
  1164. int mm_length[5];
  1165. int mm_x, mm_y, mm_row, mm_col;
  1166. int mm_origin_x[5];
  1167. int mm_origin_y[5];
  1168. Offset mm_cp = -1;
  1169. GC gc;
  1170. X
  1171. static Tk_Uid BeginSelection;
  1172. static Tk_Uid BeginExtend;
  1173. static Tk_Uid ExtendSel;
  1174. static Tk_Uid EndExtending;
  1175. static Tk_Uid BeginMouseMenu1;
  1176. static Tk_Uid BeginMouseMenu2;
  1177. static Tk_Uid ContinueMouseMenu;
  1178. static Tk_Uid CancelMouseMenu;
  1179. static Tk_Uid EndMouseMenu;
  1180. X
  1181. void
  1182. InitMouse()
  1183. X{
  1184. X    BeginSelection    = Tk_GetUid( "BeginSelection" );
  1185. X    BeginExtend    = Tk_GetUid( "BeginExtend" );
  1186. X    ExtendSel    = Tk_GetUid( "ExtendSelection" );
  1187. X    EndExtending    = Tk_GetUid( "EndExtending" );
  1188. X    BeginMouseMenu1    = Tk_GetUid( "BeginMouseMenu1" );
  1189. X    BeginMouseMenu2    = Tk_GetUid( "BeginMouseMenu2" );
  1190. X    ContinueMouseMenu=Tk_GetUid( "ContinueMouseMenu" );
  1191. X    CancelMouseMenu    = Tk_GetUid( "CancelMouseMenu" );
  1192. X    EndMouseMenu    = Tk_GetUid( "EndMouseMenu" );
  1193. X}
  1194. X
  1195. static void DrawInitialMenu();
  1196. X
  1197. static void
  1198. DrawMenuString( w, direction )
  1199. X        struct window * w;
  1200. X    int direction;
  1201. X{
  1202. X    extern Display *MainDisplay;
  1203. X
  1204. X    XDrawImageString( MainDisplay, w->x_window_id, gc,
  1205. X        mm_origin_x[direction], mm_origin_y[direction],
  1206. X        mm_data[direction].label, mm_data[direction].length);
  1207. X}
  1208. X
  1209. X/*ARGSUSED*/
  1210. static void
  1211. mmTimeout( client_data )
  1212. X    ClientData client_data;
  1213. X{
  1214. X    intervalOn = 0;
  1215. X    DrawInitialMenu( mouse_w );
  1216. X}
  1217. X
  1218. void
  1219. Mouse( w, cmd, x, y )
  1220. X    struct window * w;
  1221. X    char * cmd;
  1222. X    int x;
  1223. X    int y;
  1224. X{
  1225. X    extern struct window *selWindow;
  1226. X    extern Offset selBegin, selEnd;
  1227. X    extern int selMode;
  1228. X    extern int menuDelay;
  1229. X    extern struct mmData mm1Data[];
  1230. X    extern struct mmData mm2Data[];
  1231. X    extern Cursor currentCursor;
  1232. X    extern Display *MainDisplay;
  1233. X    extern Window MainWindow;
  1234. X    extern int mouseSpriteMenu;
  1235. X    extern int menuTolerance;
  1236. X    extern Tcl_Interp * interp;
  1237. X    extern char msgBuffer[];
  1238. X    
  1239. X    static int lastRow = -1;
  1240. X    static int lastCol = -1;
  1241. X
  1242. X    int row, col, n;
  1243. X    Offset cp, beginRowCp;
  1244. X    /* two abbreviations */
  1245. X    struct fontDataStruct *font = &(w->font);
  1246. X    int fid = w->fileId;
  1247. X    Tk_Uid cmd_uid = Tk_GetUid( cmd );
  1248. X
  1249. X    row = (y - w->topMargin) / font->height;
  1250. X    col = (x - w->leftMargin) / font->width;
  1251. X    cp = xyToOffset( w, row, col );
  1252. X    n = -1;
  1253. X    beginRowCp = prevLine( fid, cp, &n );
  1254. X
  1255. if( cmd_uid == BeginSelection ) {
  1256. X    Offset oldBegin, oldEnd;
  1257. X
  1258. X    lastRow = row;
  1259. X    lastCol = col;
  1260. X    if( mouseMotionActive )
  1261. X        goto restoreCursor;
  1262. X
  1263. X    /* determine the proper selection mode */
  1264. X    else if( selBegin <= cp && cp <= selEnd && w == selWindow ) {
  1265. X        if( selMode++ == SELLINE )
  1266. X            selMode = SELCHAR;
  1267. X        if( selMode == SELLINE ) {
  1268. X            sprintf(msgBuffer,"Line %d",LineNumberOfSelection());
  1269. X            msg( msgBuffer, 1 );
  1270. X        }
  1271. X        drawSelection( 1 );
  1272. X        /* Extend the selection by the selection mode */
  1273. X        oldBegin = selBegin;
  1274. X        oldEnd = selEnd;
  1275. X        modeExtend( selWindow, cp, row, col, beginRowCp );
  1276. X        /* see if we need to erase the whole selection */
  1277. X        /* this can happen if you click inside a large, */
  1278. X        /* drawn-through selection within the double click */
  1279. X        /* interval. */
  1280. X        if( oldBegin < selBegin || selEnd < oldEnd )
  1281. X            drawSelection( 1 );
  1282. X        if( selMode != SELBLOCK ) {
  1283. X            int row1, row2, col1, col2;
  1284. X            Offset begin = selBegin;
  1285. X            Offset end = selEnd;
  1286. X            /* restrict begin-end range to what is */
  1287. X            /* visible on the screen */
  1288. X            if( begin < selWindow->posTopline )
  1289. X                begin = selWindow->posTopline;
  1290. X            if( end >= selWindow->posBotline )
  1291. X                end = selWindow->posBotline - 1;
  1292. X            if( begin <= end ) {
  1293. X                /* at least part of the selection */
  1294. X                /* is on the screen */
  1295. X                int n = -1;
  1296. X                Offset cp = prevLine(selWindow->fileId,
  1297. X                        begin, &n);
  1298. X                OffsetToXY( selWindow, begin, &row1,
  1299. X                        &col1 );
  1300. X                OffsetToXY( selWindow, end, &row2,
  1301. X                        &col2 );
  1302. X                DrawSection( selWindow, cp, row1, col1,
  1303. X                        row2, col2 );
  1304. X            }
  1305. X        } else {
  1306. X            drawWindow( selWindow );
  1307. X        }
  1308. X
  1309. X    } else {
  1310. X        drawSelection( 1 );
  1311. X        selEnd = selBegin = cp;
  1312. X        selWindow = w;
  1313. X        selMode = SELCHAR;
  1314. X        DrawSection(selWindow, beginRowCp, row, col, row, col);
  1315. X    }
  1316. X    AssertSelectionOwnership();
  1317. X
  1318. X} else if( cmd_uid == BeginExtend ) {
  1319. X    ExtendSelection( cp, row, col, beginRowCp );
  1320. X
  1321. X} else if( cmd_uid == ExtendSel ) {
  1322. X    if( row == lastRow && col == lastCol )
  1323. X        return;
  1324. X    lastRow = row;
  1325. X    lastCol = col;
  1326. X
  1327. X    /* extend or contract the selection. */
  1328. X    ExtendSelection( cp, row, col, beginRowCp );
  1329. X
  1330. X} else if( cmd_uid == EndExtending )
  1331. X    /*EMPTY*/
  1332. X{
  1333. X    /* nothing to do on end selection */
  1334. X
  1335. X} else if( cmd_uid == BeginMouseMenu1 ) {
  1336. X    mm_data = mm1Data;
  1337. X    goto BeginEitherMenu;
  1338. X
  1339. X} else if( cmd_uid == BeginMouseMenu2 ) {
  1340. X    mm_data = mm2Data;
  1341. X
  1342. BeginEitherMenu:
  1343. X    /* remember the important parameters */
  1344. X    mm_x = x;
  1345. X    mm_y = y;
  1346. X    mm_row = row;
  1347. X    mm_col = col;
  1348. X    mm_cp = cp;
  1349. X    mouseMotionActive = 1;
  1350. X    currentDirection = MM_NOMOTION;
  1351. X    /* record all the label lengths */
  1352. X    for( n = 0; n < 5; ++n )
  1353. X        mm_length[n] = strlen(mm_data[n].label);
  1354. X
  1355. X    if( mouseSpriteMenu ) {
  1356. X        XDefineCursor( MainDisplay, Tk_WindowId(w->tk_toplevel),
  1357. X                mm_data[currentDirection].cursor );
  1358. X    } else {
  1359. X        intervalOn = 1;
  1360. X        mouse_w = w;
  1361. X        timer_token = Tk_CreateTimerHandler( menuDelay, mmTimeout, 0 );
  1362. X    }
  1363. X
  1364. X} else if( cmd_uid == ContinueMouseMenu ) {
  1365. X    int newDirection;
  1366. X
  1367. X    x -= mm_x;
  1368. X    y -= mm_y;
  1369. X    /* make it insensitive to small changes */
  1370. X    if( abs(x) < menuTolerance && abs(y) < menuTolerance )
  1371. X        newDirection = MM_NOMOTION;
  1372. X    else if( x > y ) {
  1373. X        if( x > -y )
  1374. X            newDirection = MM_EAST;
  1375. X        else
  1376. X            newDirection = MM_NORTH;
  1377. X    } else {
  1378. X        if( x > -y )
  1379. X            newDirection = MM_SOUTH;
  1380. X        else
  1381. X            newDirection = MM_WEST;
  1382. X    }
  1383. X    if( mouseMotionActive && (currentDirection != newDirection) ) {
  1384. X        if( mouseSpriteMenu ) {
  1385. X            XDefineCursor( MainDisplay, Tk_WindowId(w->tk_toplevel),
  1386. X                    mm_data[newDirection].cursor );
  1387. X        } else if( !intervalOn ) {
  1388. X            /* unhighlight the old item */
  1389. X            gc = font->gc_normal;
  1390. X            DrawMenuString( w, currentDirection );
  1391. X            /* highlight the new item */
  1392. X            gc = font->gc_selected;
  1393. X            DrawMenuString( w, newDirection );
  1394. X        }
  1395. X    }
  1396. X    currentDirection = newDirection;
  1397. X
  1398. X} else if( cmd_uid == EndMouseMenu ) {
  1399. X    if( mouseMotionActive ) {
  1400. X        int row1, row2;
  1401. X        char * cmd = mm_data[currentDirection].tcl_command;
  1402. X        if( striccmp(cmd,"ExtendSelection") != 0 ) {
  1403. X            (void)ExecTclCommand( cmd );
  1404. X        } else
  1405. X            /* extend or contract the selection */
  1406. X            ExtendSelection( cp, row, col, beginRowCp );
  1407. restoreCursor:
  1408. X        if( mouseSpriteMenu ) {
  1409. X            XDefineCursor( MainDisplay, Tk_WindowId(w->tk_toplevel),
  1410. X                            currentCursor);
  1411. X        } else {
  1412. X            /* redraw the text we wrote over */
  1413. X            if( intervalOn ) {
  1414. X                intervalOn = 0;
  1415. X                Tk_DeleteTimerHandler( timer_token );
  1416. X            } else {
  1417. X                if( (row1 = mm_row - 2) < 0 )
  1418. X                    row1 = 0;
  1419. X                row2 = mm_row + 2;
  1420. X                drawWindowFast( w, row1, row2, 0, w->nCols );
  1421. X            }
  1422. X        }
  1423. X        mouseMotionActive = 0;
  1424. X    }
  1425. X} else if( cmd_uid == CancelMouseMenu ) {
  1426. X    goto restoreCursor;
  1427. X} else {    /* must be a Point command */
  1428. X    printf("Mouse command `%s' not understood\n", cmd );
  1429. X}
  1430. X}
  1431. X
  1432. static void
  1433. DrawInitialMenu( w )
  1434. X        struct window * w;
  1435. X{
  1436. X    extern Display *MainDisplay;
  1437. X
  1438. X    int col9;
  1439. X    /* two abbreviations */
  1440. X    struct fontDataStruct *font = &(w->font);
  1441. X
  1442. X    /* write out the circular menu items */
  1443. X
  1444. X    /* first figure out where everything goes */
  1445. X    mm_origin_y[MM_NOMOTION] = w->topMargin + font->ascent
  1446. X                        + mm_row * font->height;
  1447. X    mm_origin_y[MM_WEST] = mm_origin_y[MM_NOMOTION];
  1448. X    mm_origin_y[MM_EAST] = mm_origin_y[MM_NOMOTION];
  1449. X    mm_origin_y[MM_NORTH] = mm_origin_y[MM_NOMOTION] - font->height - 2;
  1450. X    mm_origin_y[MM_SOUTH] = mm_origin_y[MM_NOMOTION] + font->height + 2;
  1451. X
  1452. X    col9 = mm_col - mm_length[MM_NOMOTION]/2;
  1453. X    mm_origin_x[MM_NOMOTION] = w->leftMargin + col9 * font->width;
  1454. X    mm_origin_x[MM_WEST] = mm_origin_x[MM_NOMOTION]
  1455. X                - mm_length[MM_WEST] * font->width - 2;
  1456. X    mm_origin_x[MM_EAST] = mm_origin_x[MM_NOMOTION]
  1457. X                + mm_length[MM_NOMOTION] * font->width + 2;
  1458. X    col9 = mm_col - mm_length[MM_NORTH]/2;
  1459. X    mm_origin_x[MM_NORTH] = w->leftMargin + col9 * font->width;
  1460. X    col9 = mm_col - mm_length[MM_SOUTH]/2;
  1461. X    mm_origin_x[MM_SOUTH] = w->leftMargin + col9 * font->width;
  1462. X
  1463. X    /* draw rectangles around the strings */
  1464. X    gc = (w->font).gc_normal;
  1465. X    XDrawRectangle(MainDisplay, w->x_window_id, gc,
  1466. X        mm_origin_x[MM_NOMOTION] - 1,
  1467. X        mm_origin_y[MM_NOMOTION] - font->ascent - 1,
  1468. X        font->width * mm_length[MM_NOMOTION] + 2,
  1469. X        font->height + 2);
  1470. X    XDrawRectangle(MainDisplay, w->x_window_id, gc,
  1471. X        mm_origin_x[MM_NORTH] - 1,
  1472. X        mm_origin_y[MM_NORTH] - font->ascent - 1,
  1473. X        font->width * mm_length[MM_NORTH] + 2,
  1474. X        font->height + 2);
  1475. X    XDrawRectangle(MainDisplay, w->x_window_id, gc,
  1476. X        mm_origin_x[MM_EAST] - 1,
  1477. X        mm_origin_y[MM_EAST] - font->ascent - 1,
  1478. X        font->width * mm_length[MM_EAST] + 2,
  1479. X        font->height + 2);
  1480. X    XDrawRectangle(MainDisplay, w->x_window_id, gc,
  1481. X        mm_origin_x[MM_SOUTH] - 1,
  1482. X        mm_origin_y[MM_SOUTH] - font->ascent - 1,
  1483. X        font->width * mm_length[MM_SOUTH] + 2,
  1484. X        font->height + 2);
  1485. X    XDrawRectangle(MainDisplay, w->x_window_id, gc,
  1486. X        mm_origin_x[MM_WEST] - 1,
  1487. X        mm_origin_y[MM_WEST] - font->ascent - 1,
  1488. X        font->width * mm_length[MM_WEST] + 2,
  1489. X        font->height + 2);
  1490. X    /* now write the strings */
  1491. X    gc = (w->font).gc_normal;
  1492. X    DrawMenuString( w, MM_NOMOTION );
  1493. X    DrawMenuString( w, MM_NORTH );
  1494. X    DrawMenuString( w, MM_WEST );
  1495. X    DrawMenuString( w, MM_SOUTH );
  1496. X    DrawMenuString( w, MM_EAST );
  1497. X    /* this one will be written twice */
  1498. X    gc = (w->font).gc_selected;
  1499. X    DrawMenuString( w, currentDirection );
  1500. X}
  1501. X
  1502. X/* global variables for making cursor from pixmaps */
  1503. static Pixmap pixmap;
  1504. static GC mouse_gc;
  1505. static XColor black, white;
  1506. static int ascent;
  1507. extern Display *MainDisplay;
  1508. X
  1509. static void
  1510. MakeCursors( mm_data )
  1511. X    struct mmData * mm_data;
  1512. X{
  1513. X
  1514. X    int i;
  1515. X
  1516. X    for( i = 0; i < 5; ++i ) {
  1517. X        mm_data[i].length = strlen( mm_data[i].label );
  1518. X        if( mm_data[i].length > 0 ) {
  1519. X            XDrawImageString( MainDisplay, pixmap, mouse_gc, 2,
  1520. X                ascent+2, mm_data[i].label, mm_data[i].length );
  1521. X            mm_data[i].cursor = XCreatePixmapCursor( MainDisplay,
  1522. X                pixmap, None, &white, &black, 1, 1 );
  1523. X        } else
  1524. X            mm_data[i].cursor = NULL;
  1525. X    }
  1526. X}
  1527. X
  1528. void
  1529. MakeMouseMenuCursors()
  1530. X{
  1531. X    extern Pixel ptWhitePixel, ptBlackPixel;
  1532. X    extern struct mmData mm1Data[];
  1533. X    extern struct mmData mm2Data[];
  1534. X    extern char * mouseMenuFont;
  1535. X
  1536. X    XFontStruct *fontInfo;
  1537. X
  1538. X    /* set up the pixmap and stuff to create the cursors */
  1539. X    pixmap = XCreatePixmap( MainDisplay, DefaultRootWindow(MainDisplay),
  1540. X            28, 17, 1 );
  1541. X    fontInfo = XLoadQueryFont( MainDisplay, mouseMenuFont );
  1542. X    if( fontInfo == NULL )
  1543. X        /* we assume every X server has a "fixed" font */
  1544. X        fontInfo = XLoadQueryFont( MainDisplay, "fixed" );
  1545. X    ascent = fontInfo->ascent;
  1546. X    mouse_gc = XCreateGC(MainDisplay, pixmap, 0, NULL);
  1547. X    XSetFont(MainDisplay, mouse_gc, fontInfo->fid);
  1548. X
  1549. X    /* clear out the edges of the pixmap */
  1550. X    XFillRectangle( MainDisplay, pixmap, mouse_gc, 0, 0, 28, 17 );
  1551. X    black.pixel = ptBlackPixel;
  1552. X    ptBlackPixel = BlackPixel(MainDisplay, MainDisplay->default_screen);
  1553. X    XQueryColor( MainDisplay, DefaultColormap(MainDisplay,
  1554. X                DefaultScreen(MainDisplay)), &black);
  1555. X    white.pixel = ptWhitePixel;
  1556. X    XQueryColor( MainDisplay, DefaultColormap(MainDisplay,
  1557. X                DefaultScreen(MainDisplay)), &white);
  1558. X
  1559. X    MakeCursors( mm1Data );
  1560. X    MakeCursors( mm2Data ); 
  1561. X
  1562. X    XFreeGC( MainDisplay, mouse_gc );
  1563. X    XFreePixmap( MainDisplay, pixmap );
  1564. X}
  1565. X
  1566. END_OF_FILE
  1567. if test 11478 -ne `wc -c <'mouse.c'`; then
  1568.     echo shar: \"'mouse.c'\" unpacked with wrong size!
  1569. fi
  1570. # end of 'mouse.c'
  1571. fi
  1572. if test -f 'search.c' -a "${1}" != "-c" ; then 
  1573.   echo shar: Will not clobber existing file \"'search.c'\"
  1574. else
  1575. echo shar: Extracting \"'search.c'\" \(14573 characters\)
  1576. sed "s/^X//" >'search.c' <<'END_OF_FILE'
  1577. X/* $Header: /nfs/unmvax/faculty/crowley/x/pt/RCS/search.c,v 1.7 1992/03/04 17:07:18 crowley Exp crowley $ */
  1578. X
  1579. X#include <ctype.h>
  1580. X#include <string.h>
  1581. X#include <stdio.h>
  1582. X#include "pt.h"
  1583. X#include <X11/StringDefs.h>
  1584. X
  1585. static char searchString[STRINGSIZE];
  1586. X
  1587. int
  1588. searchFor( w, searchMode, str, update, lof )
  1589. X    struct window *w;
  1590. X    int searchMode;
  1591. X    char * str;
  1592. X    int update;
  1593. X    int lof;
  1594. X{
  1595. X    extern struct window *selWindow;
  1596. X    extern Offset selBegin, selEnd;
  1597. X    extern int selMode;
  1598. X    extern char msgBuffer[];
  1599. X    extern int ignoreCase;
  1600. X    extern int debug;
  1601. X    extern int underlineSelection;
  1602. X    extern int wrapAroundSearches;
  1603. X
  1604. X    int n, i, linesFromTop, fileId, nLines;
  1605. X    int patLength;
  1606. X    int saveUnderlineSelection;
  1607. X    int wrappedAround = 0;
  1608. X    Offset cp, cp2, startCp, stopCp;
  1609. X    char ch, *p, *limit;
  1610. X    int fid = w->fileId;
  1611. X    Offset newSelBegin, newSelEnd;
  1612. X
  1613. X    fileId = w->fileId;
  1614. X
  1615. X        if( str != NULL ) {
  1616. X                /* get pointers we can change */
  1617. X                p = searchString;
  1618. X                limit = searchString + STRINGSIZE;
  1619. X                while( 1 ) {
  1620. X                        ch = *str++;
  1621. X                        /* case insensitive search? */
  1622. X                        if( isupper(ch) && ignoreCase )
  1623. X                                ch = tolower(ch);
  1624. X                        if( (*p++ = ch) == '\0' )
  1625. X                                break;
  1626. X                        if( p >= limit ) {
  1627. X                                *--p = '\0';
  1628. X                                break;
  1629. X                        }
  1630. X                }
  1631. X        }
  1632. X
  1633. X    /* do not allow searching for the empty string */
  1634. X    if( searchString[0] == '\0' ) {
  1635. X        sprintf(msgBuffer, "Search string is empty");
  1636. X        goto errorExit;
  1637. X    }
  1638. X
  1639. X    /* avoid overflowing msgBuffer */
  1640. X    n = strlen( searchString );
  1641. X    if( n > (STRINGSIZE-64) )
  1642. X        n = STRINGSIZE - 64;
  1643. X    /* 64 is enough for "Searching circularly for `%s'" */
  1644. X    sprintf(msgBuffer, "Searching %s for `%s'",
  1645. X        ((searchMode == 0) ? "forwards" : "backwards"),
  1646. X        searchString);
  1647. X    msg( msgBuffer, 1 );
  1648. X
  1649. X    patLength = strlen(searchString);
  1650. X    nLines = 0;
  1651. X    cp = fileSize(w->fileId);
  1652. X    if( searchMode == 1 ) {
  1653. X        startCp = 0;
  1654. X        if( w == selWindow )
  1655. X            stopCp = selBegin - 1;
  1656. X        else
  1657. X            stopCp = cp - 1;
  1658. X    } else {    /* seachMode == 0 */
  1659. X        stopCp = cp;
  1660. X        if( w == selWindow ) {
  1661. X            startCp = selBegin + 1;
  1662. X            if( startCp >= stopCp ) {    /* already done? */
  1663. X                if( wrapAroundSearches )
  1664. X                    startCp = 0;
  1665. X                else
  1666. X                    goto notFound;
  1667. X            }
  1668. X        } else
  1669. X            startCp = 0;
  1670. X    }
  1671. X    linesFromTop = 0;
  1672. X    /* adjust the line number */
  1673. X    /* just put in the two while loops and forget the IF test */
  1674. X    /* at most one of the WHILE loops will actually loop */
  1675. X    /* adjust for backwards searching */
  1676. X    cp2 = w->posTopline;
  1677. X    if( searchMode == 1 ) {
  1678. X        cp = stopCp + 1;
  1679. X        if( cp > fileSize(w->fileId) )
  1680. X            --cp;
  1681. X    } else {
  1682. X        cp = startCp - 1;
  1683. X        if( cp < 0 )
  1684. X            cp = 0;
  1685. X    }
  1686. X    /* normalize cp to the beginning of its line */
  1687. X    i = -1;
  1688. X    cp = prevLine( fid, cp, &i );
  1689. X    while( cp2 < cp ) {
  1690. X        ++linesFromTop;
  1691. X        i = 1;
  1692. X        cp2 = nextLine( fid, cp2, &i );
  1693. X    }
  1694. X    while( cp2 > cp ) {
  1695. X        --linesFromTop;
  1696. X        i = 1;
  1697. X        cp2 = prevLine( fid, cp2, &i );
  1698. X    }
  1699. X
  1700. X    if( searchMode == 0 ) {
  1701. X        cp = searchSpans(fileId, startCp, stopCp,
  1702. X            searchString, patLength, &n);
  1703. X        nLines += n;
  1704. X        if( wrapAroundSearches && cp == -1 ) {
  1705. X            wrappedAround = 1;
  1706. X            cp = searchSpans(fileId, 0L, startCp,
  1707. X                searchString, patLength, &n);
  1708. X            nLines = n;
  1709. X            linesFromTop = -(selWindow->numTopline);
  1710. X        }
  1711. X    } else {
  1712. X        cp = searchReverseSpans(fileId, startCp, stopCp,
  1713. X                searchString, patLength, &n);
  1714. X        nLines -= n;
  1715. X        /* a fix so that backwards search from the backwards */
  1716. X        /* search command is circular if the normal search */
  1717. X        /* mode is circular */
  1718. X/********************* DO NOT DO THIS YET ************
  1719. X THE PROBLEM IS GETTING THE LINE NUMBERS TO WORK OUT
  1720. X FINISH IT LATER
  1721. X        if( cp == -1 ) {
  1722. X            wrappedAround = 1;
  1723. X            cp = searchReverseSpans(fileId, stopCp,
  1724. X                fileSize(w->fileId) - patLength,
  1725. X                searchString, patLength, &n);
  1726. X            nLines = n;
  1727. X            linesFromTop = -(selWindow->numTopline);
  1728. X        }
  1729. X*******************************************************/
  1730. X    }
  1731. X
  1732. X    if( cp != -1 ) {
  1733. X        if( selWindow != w ) {
  1734. X            drawSelection( 1 );
  1735. X            selWindow = w;
  1736. X        }
  1737. X        newSelBegin = cp;
  1738. X        newSelEnd = newSelBegin + patLength - 1;
  1739. X        selMode = SELCHAR;
  1740. X    } else
  1741. X        goto notFound;
  1742. X
  1743. if( !update ) {
  1744. X    selBegin = newSelBegin;
  1745. X    selEnd = newSelEnd;
  1746. X} else {
  1747. X    (void)indentToShowSelection(-1);
  1748. X    saveUnderlineSelection = underlineSelection;
  1749. X    underlineSelection = 0;
  1750. X    if( newSelBegin >= selWindow->posBotline
  1751. X                || newSelBegin < selWindow->posTopline ) {
  1752. X        /* remember where we came from */
  1753. X        selWindow->rowLastline = selWindow->numTopline;
  1754. X        selBegin = newSelBegin;
  1755. X        selEnd = newSelEnd;
  1756. X         n = -1;
  1757. X         cp2 = selBegin;
  1758. X        cp2 = prevLine( fid, cp2, &n);
  1759. X        /* find the number of lines in the window */
  1760. X        n = selWindow->nRows;
  1761. X        if( lof > n )
  1762. X            /* if lof would place it outside the */
  1763. X            /* window then put it in the middle of the window */
  1764. X            n >>= 1;
  1765. X        else
  1766. X            /* otherwise put it lof lines down */
  1767. X            n = lof;
  1768. X        selWindow->posTopline = cp2;
  1769. X        selWindow->posTopline = prevLine(fid,selWindow->posTopline,&n);
  1770. X        selWindow->numTopline += linesFromTop + nLines - n;
  1771. X        drawWindow(selWindow);
  1772. X    } else {
  1773. X        int row1, row2, col1, col2;
  1774. X        /* the found string is already showing in the window */
  1775. X        drawSelection( 1 );
  1776. X        selBegin = newSelBegin;
  1777. X        selEnd = newSelEnd;
  1778. X        OffsetToXY( selWindow, selBegin, &row1, &col1 );
  1779. X        OffsetToXY( selWindow, selEnd, &row2, &col2 );
  1780. X        drawWindowFast( selWindow, row1, row2, 0, selWindow->nCols );
  1781. X    }
  1782. X    underlineSelection = saveUnderlineSelection;
  1783. X}
  1784. X
  1785. X    AssertSelectionOwnership();
  1786. X    /* this will erase the "Searching for..." msg in the case where */
  1787. X    /* the selWindow does not extend to the bottom line */
  1788. X    if( wrappedAround && update )
  1789. X        msg(
  1790. X"Circular search has wrapped around the beginning of the file", 1);
  1791. X    return selBegin;
  1792. X
  1793. notFound:
  1794. X    /* avoid overflowing msgBuffer */
  1795. X    n = strlen(searchString);
  1796. X    if( n > (STRINGSIZE-64) )
  1797. X        n = STRINGSIZE - 64;
  1798. X    /* 64 is enough for "String `%s' not found." */
  1799. X    ch = searchString[n];
  1800. X    searchString[n] = '\0';
  1801. X    sprintf(msgBuffer, "`%s' not found.", searchString);
  1802. X    searchString[n] = ch;
  1803. errorExit:
  1804. X    msg(msgBuffer, 1);
  1805. X    return -1;
  1806. X}
  1807. X
  1808. X
  1809. int
  1810. RegexSearch( w, searchMode, str, update, lof )
  1811. X    struct window *w;
  1812. X    int searchMode;
  1813. X    char * str;
  1814. X    int update;
  1815. X    int lof;
  1816. X{
  1817. X    extern struct window *selWindow;
  1818. X    extern Offset selBegin, selEnd;
  1819. X    extern int selMode;
  1820. X    extern char msgBuffer[];
  1821. X    extern char textBuffer[];
  1822. X    extern int ignoreCase;
  1823. X    extern int debug;
  1824. X    extern int underlineSelection;
  1825. X    extern int wrapAroundSearches;
  1826. X    extern int regex_bopat[];
  1827. X    extern int regex_eopat[];
  1828. X
  1829. X    int n, i, linesFromTop, fileId, nLines;
  1830. X    int saveUnderlineSelection;
  1831. X    int wrappedAround = 0;
  1832. X    Offset cp, cp2, startCp, stopCp;
  1833. X    char ch, *p;
  1834. X    int fid = w->fileId;
  1835. X    Offset newSelBegin, newSelEnd;
  1836. X
  1837. X    fileId = w->fileId;
  1838. X    
  1839. X    p = re_comp( str );
  1840. X    if( p != NULL ) {
  1841. X        sprintf(msgBuffer, "Regular expression error: %s", p);
  1842. X        printf("%s\n", msgBuffer);
  1843. X        goto errorExit;
  1844. X    }
  1845. X
  1846. X    /* avoid overflowing msgBuffer */
  1847. X    sprintf(textBuffer, "Searching %%s for `%%%ds'", STRINGSIZE-64);
  1848. X    sprintf(msgBuffer, textBuffer,
  1849. X        ((searchMode == 0) ? "forwards" : "backwards"), str);
  1850. X    msg( msgBuffer, 1 );
  1851. X
  1852. X    nLines = 0;
  1853. X
  1854. X    cp = fileSize(w->fileId);
  1855. X    if( searchMode == 1 ) {
  1856. X        startCp = 0;
  1857. X        if( w == selWindow )
  1858. X            stopCp = selBegin - 1;
  1859. X        else
  1860. X            stopCp = cp - 1;
  1861. X    } else {    /* seachMode == 0 */
  1862. X        stopCp = cp - 1;
  1863. X        if( w == selWindow ) {
  1864. X            startCp = selBegin + 1;
  1865. X            if( startCp > stopCp ) {    /* already done? */
  1866. X                if( wrapAroundSearches )
  1867. X                    startCp = 0;
  1868. X                else
  1869. X                    goto notFound;
  1870. X            }
  1871. X        } else
  1872. X            startCp = 0;
  1873. X    }
  1874. X    linesFromTop = 0;
  1875. X    /* adjust the line number */
  1876. X    /* just put in the two while loops and forget the IF test */
  1877. X    /* at most one of the WHILE loops will actually loop */
  1878. X    /* adjust for backwards searching */
  1879. X    cp2 = w->posTopline;
  1880. X    if( searchMode == 1 ) {
  1881. X        cp = stopCp + 1;
  1882. X        if( cp > fileSize(w->fileId) )
  1883. X            --cp;
  1884. X    } else {
  1885. X        cp = startCp - 1;
  1886. X        if( cp < 0 )
  1887. X            cp = 0;
  1888. X    }
  1889. X    /* normalize cp to the beginning of its line */
  1890. X    i = -1;
  1891. X    cp = prevLine( fid, cp, &i );
  1892. X    while( cp2 < cp ) {
  1893. X        ++linesFromTop;
  1894. X        i = 1;
  1895. X        cp2 = nextLine( fid, cp2, &i );
  1896. X    }
  1897. X    while( cp2 > cp ) {
  1898. X        --linesFromTop;
  1899. X        i = 1;
  1900. X        cp2 = prevLine( fid, cp2, &i );
  1901. X    }
  1902. X
  1903. X    if( searchMode == 0 ) {
  1904. X        i = re_exec( fileId, startCp, stopCp, &n );
  1905. X        nLines += n;
  1906. X        if( wrapAroundSearches && i != 1 ) {
  1907. X            wrappedAround = 1;
  1908. X            i = re_exec( fileId, 0L, startCp-1, &n );
  1909. X            nLines = n;
  1910. X            linesFromTop = -(selWindow->numTopline);
  1911. X        }
  1912. X    } else {
  1913. X        i = re_exec_reversed( fileId, startCp, stopCp, &n );
  1914. X        nLines -= n;
  1915. X        /* a fix so that backwards search from the backwards */
  1916. X        /* search command is circular if the normal search */
  1917. X        /* mode is circular */
  1918. X/********************* DO NOT DO THIS YET ************
  1919. X THE PROBLEM IS GETTING THE LINE NUMBERS TO WORK OUT
  1920. X FINISH IT LATER
  1921. X        if( cp == -1 ) {
  1922. X            wrappedAround = 1;
  1923. X            cp = searchReverseSpans(fileId, stopCp,
  1924. X                fileSize(w->fileId) - patLength,
  1925. X                str, patLength, &n);
  1926. X            nLines = n;
  1927. X            linesFromTop = -(selWindow->numTopline);
  1928. X        }
  1929. X*******************************************************/
  1930. X    }
  1931. X
  1932. X    if( i < 1 )
  1933. X        goto notFound;
  1934. X    if( selWindow != w ) {
  1935. X        drawSelection( 1 );
  1936. X        selWindow = w;
  1937. X    }
  1938. X    newSelBegin = regex_bopat[0];
  1939. X    newSelEnd = regex_eopat[0] - 1;
  1940. X    selMode = SELCHAR;
  1941. X
  1942. if( !update ) {
  1943. X    selBegin = newSelBegin;
  1944. X    selEnd = newSelEnd;
  1945. X} else {
  1946. X    (void)indentToShowSelection(-1);
  1947. X    saveUnderlineSelection = underlineSelection;
  1948. X    underlineSelection = 0;
  1949. X    if( newSelBegin >= selWindow->posBotline
  1950. X                || newSelBegin < selWindow->posTopline ) {
  1951. X        /* remember where we came from */
  1952. X        selWindow->rowLastline = selWindow->numTopline;
  1953. X        selBegin = newSelBegin;
  1954. X        selEnd = newSelEnd;
  1955. X         n = -1;
  1956. X         cp2 = selBegin;
  1957. X        cp2 = prevLine( fid, cp2, &n);
  1958. X        /* find the number of lines in the window */
  1959. X        n = selWindow->nRows;
  1960. X        if( lof > n )
  1961. X            /* if lof would place it outside the */
  1962. X            /* window then put it in the middle of the window */
  1963. X            n >>= 1;
  1964. X        else
  1965. X            /* otherwise put it lof lines down */
  1966. X            n = lof;
  1967. X        selWindow->posTopline = cp2;
  1968. X        selWindow->posTopline = prevLine(fid,selWindow->posTopline,&n);
  1969. X        selWindow->numTopline += linesFromTop + nLines - n;
  1970. X        drawWindow(selWindow);
  1971. X    } else {
  1972. X        int row1, row2, col1, col2;
  1973. X        /* the found string is already showing in the window */
  1974. X        drawSelection( 1 );
  1975. X        selBegin = newSelBegin;
  1976. X        selEnd = newSelEnd;
  1977. X        OffsetToXY( selWindow, selBegin, &row1, &col1 );
  1978. X        OffsetToXY( selWindow, selEnd, &row2, &col2 );
  1979. X        drawWindowFast( selWindow, row1, row2, 0, selWindow->nCols );
  1980. X    }
  1981. X    underlineSelection = saveUnderlineSelection;
  1982. X}
  1983. X
  1984. X    AssertSelectionOwnership();
  1985. X    /* this will erase the "Searching for..." msg in the case where */
  1986. X    /* the selWindow does not extend to the bottom line */
  1987. X    if( wrappedAround && update )
  1988. X        msg(
  1989. X"Circular search has wrapped around the beginning of the file", 1);
  1990. X    return selBegin;
  1991. X
  1992. notFound:
  1993. X    /* avoid overflowing msgBuffer */
  1994. X    n = strlen(str);
  1995. X    if( n > (STRINGSIZE-64) )
  1996. X        n = STRINGSIZE - 64;
  1997. X    /* 64 is enough for "String `%s' not found." */
  1998. X    ch = str[n];
  1999. X    str[n] = '\0';
  2000. X    sprintf(msgBuffer, "`%s' not found.", str);
  2001. X    str[n] = ch;
  2002. errorExit:
  2003. X    msg(msgBuffer, 1);
  2004. X    return -1;
  2005. X}
  2006. X
  2007. X
  2008. X#ifdef OLDOLD
  2009. int
  2010. OldRegexSearch( w, searchMode, str, update, lof )
  2011. X    struct window *w;
  2012. X    int searchMode;
  2013. X    char * str;
  2014. X    int update;
  2015. X    int lof;
  2016. X{
  2017. X    extern struct window *selWindow;
  2018. X    extern Offset selBegin, selEnd;
  2019. X    extern int selMode;
  2020. X    extern char msgBuffer[];
  2021. X    extern int ignoreCase;
  2022. X    extern int debug;
  2023. X    extern int underlineSelection;
  2024. X    extern int wrapAroundSearches;
  2025. X    extern int regex_bopat[];
  2026. X    extern int regex_eopat[];
  2027. X
  2028. X    int n, i, linesFromTop, fileId, fid2, nLines;
  2029. X    int patLength;
  2030. X    int saveUnderlineSelection;
  2031. X    int ret, answer;
  2032. X    int wrappedAround = 0;
  2033. X    Offset cp, cp2, startCp, stopCp;
  2034. X    char ch, *p, *limit, *from, *to;
  2035. X    int fid = w->fileId;
  2036. X    Offset newSelBegin, newSelEnd;
  2037. X
  2038. X    fileId = w->fileId;
  2039. X
  2040. X    p = re_comp( str );
  2041. X    if( p != NULL ) {
  2042. X        sprintf(msgBuffer, "RE ERROR: %s", p);
  2043. X        printf("%s\n", msgBuffer);
  2044. X        goto errorExit;
  2045. X    }
  2046. X
  2047. X    /* avoid overflowing msgBuffer */
  2048. X    n = strlen( str );
  2049. X    if( n > (STRINGSIZE-64) )
  2050. X        n = STRINGSIZE - 64;
  2051. X    /* 64 is enough for "Searching circularly for `%s'" */
  2052. X    sprintf(msgBuffer, "Searching %s for `%s'",
  2053. X        ((searchMode == 0) ? "forwards" : "backwards"),
  2054. X        str);
  2055. X    msg( msgBuffer, 1 );
  2056. X
  2057. X/******** handle backwards, wrap around, etc. ********/
  2058. X
  2059. X    cp = fileSize(w->fileId);
  2060. X    stopCp = cp;
  2061. X    if( w == selWindow ) {
  2062. X        startCp = selBegin + 1;
  2063. X        if( startCp >= stopCp ) {    /* already done? */
  2064. X            if( wrapAroundSearches )
  2065. X                startCp = 0;
  2066. X            else
  2067. X                goto notFound;
  2068. X        }
  2069. X    } else
  2070. X        startCp = 0;
  2071. X
  2072. X    n = re_exec( fileId, startCp, stopCp, &i);
  2073. X
  2074. X    if( n < 1 )
  2075. X        goto notFound;
  2076. X
  2077. X    if( selWindow != w ) {
  2078. X        drawSelection( 1 );
  2079. X        selWindow = w;
  2080. X    }
  2081. X    newSelBegin = regex_bopat[0];
  2082. X    newSelEnd = regex_eopat[0] - 1;
  2083. X    selMode = SELCHAR;
  2084. X
  2085. if( !update ) {
  2086. X    selBegin = newSelBegin;
  2087. X    selEnd = newSelEnd;
  2088. X} else {
  2089. X    (void)indentToShowSelection(-1);
  2090. X    saveUnderlineSelection = underlineSelection;
  2091. X    underlineSelection = 0;
  2092. X    if( newSelBegin >= selWindow->posBotline
  2093. X                || newSelBegin < selWindow->posTopline ) {
  2094. X        /* remember where we came from */
  2095. X        selWindow->rowLastline = selWindow->numTopline;
  2096. X        selBegin = newSelBegin;
  2097. X        selEnd = newSelEnd;
  2098. X         n = -1;
  2099. X         cp2 = selBegin;
  2100. X        cp2 = prevLine( fid, cp2, &n);
  2101. X        /* find the number of lines in the window */
  2102. X        n = selWindow->nRows;
  2103. X        if( lof > n )
  2104. X            /* if lof would place it outside the */
  2105. X            /* window then put it in the middle of the window */
  2106. X            n >>= 1;
  2107. X        else
  2108. X            /* otherwise put it lof lines down */
  2109. X            n = lof;
  2110. X        selWindow->posTopline = cp2;
  2111. X        selWindow->posTopline = prevLine(fid,selWindow->posTopline,&n);
  2112. X        selWindow->numTopline += linesFromTop + nLines - n;
  2113. X        drawWindow(selWindow);
  2114. X    } else {
  2115. X        int row1, row2, col1, col2;
  2116. X        /* the found string is already showing in the window */
  2117. X        drawSelection( 1 );
  2118. X        selBegin = newSelBegin;
  2119. X        selEnd = newSelEnd;
  2120. X        OffsetToXY( selWindow, selBegin, &row1, &col1 );
  2121. X        OffsetToXY( selWindow, selEnd, &row2, &col2 );
  2122. X        drawWindowFast( selWindow, row1, row2, 0, selWindow->nCols );
  2123. X    }
  2124. X    underlineSelection = saveUnderlineSelection;
  2125. X}
  2126. X
  2127. X    AssertSelectionOwnership();
  2128. X    /* this will erase the "Searching for..." msg in the case where */
  2129. X    /* the selWindow does not extend to the bottom line */
  2130. X    if( wrappedAround && update )
  2131. X        msg(
  2132. X"Circular search has wrapped around the beginning of the file", 1);
  2133. X    return selBegin;
  2134. X
  2135. notFound:
  2136. X    /* avoid overflowing msgBuffer */
  2137. X    n = strlen(str);
  2138. X    if( n > (STRINGSIZE-64) )
  2139. X        n = STRINGSIZE - 64;
  2140. X    /* 64 is enough for "String `%s' not found." */
  2141. X    ch = str[n];
  2142. X    str[n] = '\0';
  2143. X    sprintf(msgBuffer, "`%s' not found.", str);
  2144. X    str[n] = ch;
  2145. errorExit:
  2146. X    msg(msgBuffer, 1);
  2147. X    return -1;
  2148. X}
  2149. X#endif
  2150. X
  2151. END_OF_FILE
  2152. if test 14573 -ne `wc -c <'search.c'`; then
  2153.     echo shar: \"'search.c'\" unpacked with wrong size!
  2154. fi
  2155. # end of 'search.c'
  2156. fi
  2157. echo shar: End of archive 5 \(of 15\).
  2158. cp /dev/null ark5isdone
  2159. MISSING=""
  2160. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ; do
  2161.     if test ! -f ark${I}isdone ; then
  2162.     MISSING="${MISSING} ${I}"
  2163.     fi
  2164. done
  2165. if test "${MISSING}" = "" ; then
  2166.     echo You have unpacked all 15 archives.
  2167.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2168. else
  2169.     echo You still need to unpack the following archives:
  2170.     echo "        " ${MISSING}
  2171. fi
  2172. ##  End of shell archive.
  2173. exit 0
  2174. -- 
  2175. --
  2176. Molecular Simulations, Inc.            mail: dcmartin@msi.com
  2177. 796 N. Pastoria Avenue                uucp: uunet!dcmartin
  2178. Sunnyvale, California 94086            at&t: 408/522-9236
  2179.