source: tags/initial/GDE/PHYLIP/interface.c

Last change on this file was 2, checked in by oldcode, 24 years ago

Initial revision

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.0 KB
Line 
1/* stderr */
2
3/* Interface
4   By Sean T. Lamont
5   For use with the Macntosh version of the Phylogeny Inference Package,
6   version 3.5c. (c) Copyright 1992 by Joseph Felsenstein.
7   Permission is granted to copy and use this program provided no fee is
8   charged for it and provided that this copyright notice is not removed.
9
10   This file defines a 2-window environment which replicates many
11   of the standard c I/O functions (puts, printf,gets,scanf)
12   in a maclike environment, with a scrollback buffer.  This
13   is necessary because of the very weak implementation of IO under
14   straight C, and the difficulty of using separate windows. It also
15   adds the ability to "quit" out of an application while it is running,
16   and some very basic point-and-click interface type of stuff on the
17   screen.
18
19   Functions you need to know how to use:
20   macsetup(char *name):  initializes the interface, brings up a window of
21                          the name of the argument, for I/O.
22   macprintf(char *string,arg,arg):  like printf but into the window
23   macgets(char *string);            like puts   but into the window
24   macscanf(char *string, arg,arg)   like scanf  but from the window
25   macgets (char *string,arg,arg)    like gets but from the window.
26
27   It is recommended that you include "interface.h" file, which sets
28   up these #define's for you (IE all calls to scanf will call
29   macscanf, etc.)
30
31  textmode(); makes the current drawing window the text window
32   gfxmode(); makes the current drawing window the gfx window,
33              unhides the graphics window.
34
35  eventloop():  process mouse events, menus, etc., and wait for
36                "go away" event.  You are implicitly doing this\
37                 when you run macgets/macscanf.  If you want to query
38                 the event handler during non-IO periods of time this
39                 would be what to call (or alternatively, printf("");
40 */
41
42
43#include <stdarg.h>
44#include <stdio.h>
45#include "interface.h"
46
47#define SCROLLLINES 250
48
49#define SCROLLCOLUMNS 80
50#define SCROLLMEM    22000
51#define LINEDEPTH  (int)12
52#define PAGELINES (int)(260 / 12)
53#define TEXT 0
54#define GFX 1
55
56/* Global variables, most for use with input/output */
57int disablescrollback = 0;
58int mode = TEXT;
59WindowPtr gfxWindow;
60WindowPtr textWindow;
61MenuHandle appleMenu,fileMenu;
62char *lines[SCROLLLINES]; /* the scrollback buffer */
63int cursorx=0; /* the current x position that the text cursor is at */
64int cursory=0; /* the current y position that the text cursor is at */
65int numlines_=0;/* the next place we put a new line.                 */
66int memptr=0;  /* the next place in our space we get memory from.   */
67int linectr=0;
68char memory[SCROLLMEM];
69char line[256];/* used to accumulate output before newlines.        */
70Rect textBounds = {40,5,300,500}; /* position of window 1          */
71Rect gfxBounds  = {0,0,350,500}; /* position of window 2          */
72Rect textrect   = {0,0,260,479};   /* region to clear within window */
73Rect barBounds  = {0,480,260,495}; /* position of the scroll bar    */
74RgnHandle rgn;                     /* used by scrollrect            */
75ControlHandle bar;                 /* this is the scrollbar control */
76int lasttop=0;                     /* used by update / scrollrect   */
77char inputs[256];                  /* used by the input routines    */
78int  inputcount = 0;               /* offset into the string.       */
79int  collect    = false;           /* boolean: collect chars?       */
80
81void macsetup(tname,gname)
82char *tname,*gname;
83{
84static char buf1[128];
85static char buf2[128];
86
87strcpy(buf1+1,tname);
88strcpy(buf2+1,gname);
89buf1[0]=strlen(tname);
90buf2[0]=strlen(gname);
91MaxApplZone();
92InitGraf(&thePort);
93InitFonts();
94FlushEvents(everyEvent,0);
95InitWindows();
96InitMenus();
97TEInit();
98InitDialogs(0L);
99InitCursor();
100textWindow = NewWindow(0L,&textBounds,buf1,true,documentProc,
101            (WindowPtr) -1L, true,0);
102gfxWindow = NewWindow(0L,&gfxBounds,buf2,false,noGrowDocProc,
103            (WindowPtr) -1L, true,0);
104rgn=NewRgn();
105SetPort(textWindow);
106bar=NewControl(textWindow,&barBounds,"",true,0,0,
107                   0,scrollBarProc,0);
108InsertMenu(appleMenu=NewMenu(1,"\p\024"),0);     /* add apple menu  */
109InsertMenu(fileMenu=NewMenu(2,"\pFile"),0);      /* add file menu   */
110TextFont(courier);
111TextSize(10);
112DrawMenuBar();
113AppendMenu(fileMenu,"\pQuit/Q");
114AddResMenu(appleMenu, 'DRVR');
115macprintf("\n");
116}
117
118
119void queryevent()
120{
121int status;
122status=handleevent();
123if (status <= 0)
124     process_window_closure(status);
125}
126
127void eventloop()
128{
129int status;
130
131while (1){
132        status=handleevent();
133if (status <= 0)
134                process_window_closure(status);  }
135}
136
137
138process_window_closure(status)
139int status;
140{
141if (status == -1){
142                CloseWindow(gfxWindow);   /* "Close main window", so run all the */
143                CloseWindow(textWindow);  /* cleanup stuff.                      */
144                DisposeRgn(rgn);
145#undef exit
146                exit(0);
147#define exit(status) eventloop()
148}
149else if (status == 0)
150   HideWindow(gfxWindow);}
151
152
153
154int handleevent()
155{
156pascal void scroll();
157char pstring[256];
158OSErr res;
159EventRecord ev;
160WindowPtr win;
161ControlHandle ctrl;
162short menuid,menuitem;
163Point MouseLoc;
164long menu,i;
165int cx,cy;
166int PathRefNum;
167long  count=80;
168SFReply fileinfo;
169char c,pasteword[64];
170Str255 name;
171GrafPtr savePort;
172FILE *fp;
173Rect drect;
174Rect      rect  = {0,0,1000,1000};   /* the limit for dragging windows */
175int ok=GetNextEvent(everyEvent,&ev);
176int where=FindWindow(ev.where,&win);
177if (ev.what == keyDown && collect && mode != GFX){
178     SetCtlValue(bar,GetCtlMax(bar));
179     redraw(numlines_ -  (GetCtlMax(bar) - GetCtlValue(bar)) - PAGELINES);
180     }
181if ((ev.what == keyDown) &&
182    (ev.modifiers &  cmdKey) &&
183    (toupper((char)(ev.message & charCodeMask)) == 'Q')  )
184         return -1;
185if (( ev.what == keyDown ) && collect && mode == GFX){
186     textmode();
187     process_char((char)(ev.message & charCodeMask));}
188if (ev.what == mouseDown && !disablescrollback && where ==inContent & mode == TEXT){
189        SelectWindow(win);
190        GlobalToLocal(&ev.where);
191         switch (FindControl(ev.where,win,&ctrl)){
192        case inThumb:
193        TrackControl(ctrl,ev.where,nil);
194         break;
195        case inUpButton:
196        TrackControl(ctrl,ev.where,scroll);
197         break;
198        case inPageUp:
199           SetCtlValue(bar,GetCtlValue(bar) - 10);
200         break;
201        case inDownButton:
202         TrackControl(ctrl,ev.where,scroll);
203         break;
204        case inPageDown:
205            SetCtlValue(bar,GetCtlValue(bar) + 10);
206         break;
207        default:
208         if (collect && mode == TEXT){
209            GetMouse(&MouseLoc);
210            cy = (int)((double)MouseLoc.v / (double)(LINEDEPTH)) +
211                 (numlines_ - (GetCtlMax(bar) - GetCtlValue(bar))
212                   - PAGELINES + 1);
213            for (i=0;i<strlen(lines[cy%SCROLLLINES]);++i)
214                 if ((lines[cy%SCROLLLINES])[i] == '(' ||
215                     (lines[cy%SCROLLLINES])[i] == '('   )
216                      (lines[cy%SCROLLLINES])[i]=' ';
217            sscanf(lines[cy%SCROLLLINES]," %[0-9a-zA-Z]",pasteword);
218              SetCtlValue(bar,GetCtlMax(bar));
219              redraw(numlines_ -  (GetCtlMax(bar) - GetCtlValue(bar)) - PAGELINES);
220            for (i=0;i<strlen(pasteword);++i)
221                 process_char(pasteword[i]);
222            process_char(0x0d);
223            }
224
225            break;
226           }
227        redraw(numlines_ -  (GetCtlMax(bar) - GetCtlValue(bar)) - PAGELINES);
228    if (GetCtlMax(bar) == GetCtlValue(bar)){
229        macflush();
230                numlines_--;}
231    }
232
233else if (ev.what == activateEvt)
234    InvalRect(&win->portRect);
235  else if (ev.what == updateEvt && mode == TEXT){
236        BeginUpdate(textWindow);
237        lasttop=100000;
238    redraw(numlines_ -  (GetCtlMax(bar) - GetCtlValue(bar)) - PAGELINES);
239        DrawControls(textWindow);
240        EndUpdate(textWindow);
241        }
242
243else if (ev.what == mouseDown && where == inSysWindow)
244    SystemClick(&ev,win);
245else if (ev.what == mouseDown && where == inDrag) {
246        DragWindow(win,ev.where,&rect);}
247       
248else if (ev.what == mouseDown  && where == inGoAway)
249     return (win == gfxWindow ? 1: -1);
250
251if (ev.what == mouseDown && where == inMenuBar){
252        menu=MenuSelect(ev.where);
253        menuitem = LoWord(menu);
254        menuid   = HiWord(menu);
255if (menuid == 2 && menuitem == 1)
256                return -1;
257if (menuid == 1){
258        GetPort(&savePort);
259        GetItem(appleMenu, menuitem, name);
260    OpenDeskAcc(name);
261        SetPort(savePort);}
262
263        }
264else if (collect && mode == TEXT && (ev.what == keyDown))
265           process_char((char)(ev.message & charCodeMask));
266       
267return 1;
268}
269
270
271void macgets(s)
272char *s;
273{
274int status;
275collect=true;
276if (mode == GFX){
277  do {status=handleevent();} /* loop until this is false, or hit cr  */
278     while (collect && status);
279
280if (status<= 0) process_window_closure(status);
281
282 }
283
284else {
285    macflush();               /* flush any waiting output (prompt?)   */
286        numlines_--;
287    inputcount=0;
288    collect=true;              /* tell the event loop to colect chars  */
289    do {status=handleevent();} /* loop until this is false, or hit cr  */
290       while (collect&&(status>0));
291    if (status<= 0) process_window_closure(status);
292    inputs[inputcount]=0;
293    strcpy(s,inputs);
294    macprintf("\n");
295    }
296}
297
298int macscanf(char *s,...)
299{
300int i;
301char buf[256];
302void *p[10];
303va_list args;
304gets(buf);
305
306va_start(args,s);
307for (i=0;i<10;++i)
308        p[i]=va_arg(args,void *);
309va_end(args);
310return sscanf(buf,s,p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7],p[8],p[9]);
311}
312
313void macputs(s)
314char *s;
315{
316macprintf("%s\n",s);
317}
318
319macputchar(c)
320char c;
321{
322macprintf("%c",c);
323}
324
325void macprintf(char *s,...)
326{
327char buf[256];
328
329va_list args;
330int i;
331if (mode == GFX)
332     return;
333if (strcmp(s,"\033[2J\033[H") ==0)
334     return;
335disablescrollback=1;
336va_start(args,s);
337vsprintf(buf,s,args);
338va_end(args);
339queryevent();
340SetPort(textWindow);
341MoveTo(cursorx,cursory);
342for (i=0;i<strlen(buf);++i){
343        if (isprint(buf[i]))
344                line[linectr++]=buf[i]; 
345        else if (buf[i] == '\n'){
346                macflush();
347                linectr=0;
348                macnewline();
349                }
350        }
351        disablescrollback=0;
352}
353
354macflush()
355{
356line[linectr]=0;
357if ((memptr+strlen(line) +1) > SCROLLMEM)
358     memptr=0;
359
360lines[(numlines_)%SCROLLLINES]=&memory[(numlines_%SCROLLLINES)*SCROLLCOLUMNS];
361strcpy(lines[(numlines_++)%SCROLLLINES],line);
362MoveTo(0,cursory);
363putstring(line);
364}
365
366macclear()
367{
368cursorx=0;
369cursory=0;
370EraseRect(&textrect);
371}
372
373macnewline()
374{
375int i;
376cursorx=0;
377cursory+=LINEDEPTH;
378if (cursory >  260  ){
379        cursory-=LINEDEPTH;}
380MoveTo(cursorx,cursory);
381 SetCtlMax(bar,((numlines_ > SCROLLLINES ) ? SCROLLLINES  :
382               (numlines_ )) - PAGELINES);
383SetCtlValue(bar,GetCtlMax(bar));
384 redraw(numlines_ -  (GetCtlMax(bar) - GetCtlValue(bar)) - PAGELINES);
385
386}
387
388
389redraw(pos)
390int pos;
391{
392int i,j,y=0;
393int lastbot = lasttop+pos;
394int delta   = pos-lasttop;
395int delta2  = lasttop-pos;
396int lbound  = pos;
397int ubound  = pos+PAGELINES;
398int tmpx    = cursorx;
399int tmpy    = cursory;
400if (numlines_ < PAGELINES)
401        delta=delta2=10000;
402textmode();
403pos = (pos < 0 ? 0 : pos);
404if (delta >= 0 && delta < SCROLLLINES ){
405        ScrollRect(&textrect,0,-delta*LINEDEPTH,rgn);
406        lbound = pos+PAGELINES-delta;
407        }
408else if (delta2 > 0 && delta2 < SCROLLLINES ){
409        ScrollRect(&textrect,0,delta2*LINEDEPTH,rgn);
410        ubound=delta2+pos;
411
412}
413
414else if (numlines_ >= PAGELINES)
415     EraseRect(&textrect);
416if (numlines_ == ubound)
417     ubound--;
418for (i=pos;i<pos-1+((PAGELINES < numlines_) ? numlines_ : PAGELINES);++i){
419        MoveTo(0,y);
420        if (i>= lbound && i<= ubound)
421                putstring(lines[i%SCROLLLINES]);
422        y+=LINEDEPTH;
423       
424 }
425 MoveTo(0,y);
426 y+=LINEDEPTH;
427lasttop = pos;
428MoveTo(tmpx,tmpy);
429}
430
431putstring(string)
432char *string;
433{
434char buf[256];
435strcpy(buf+1,string);
436buf[0]=strlen(string);
437DrawString(buf);
438cursorx+=StringWidth(buf);
439}
440
441textmode()
442{
443SetPort(textWindow);
444SelectWindow(textWindow);
445ShowWindow(textWindow);
446HideWindow(gfxWindow);
447mode = TEXT;
448}
449
450gfxmode()
451{
452int status,ok;
453EventRecord ev;
454char c;
455
456SetPort(gfxWindow);
457ShowWindow(gfxWindow);
458HideWindow(textWindow);
459SelectWindow(gfxWindow);
460mode = GFX;
461}
462
463pascal void scroll(c,p)
464ControlHandle c;
465int p;
466{
467int direction=((p == inDownButton) ? 1 : (p ==  0)  ? 0 : -1);
468SetCtlValue(bar,GetCtlValue(bar) + direction);
469/* redraw(numlines_ -  (GetCtlMax(bar) - GetCtlValue(bar)) - PAGELINES);
470*/
471}
472
473 process_char(c)
474char c;
475{
476Rect drect;
477
478if (isprint(c)){
479                inputs[inputcount++]=c;
480                line[linectr++]=c;
481                if (GetCtlValue(bar) == GetCtlMax(bar) && mode==TEXT) {
482                macflush();
483                numlines_--;}
484                }
485        else{
486        switch (c){
487                case 0x03:     /* if it's the enter key */
488                case 0x0d:     /* or the return key     */
489                        collect=false; /* stop collecting chars */
490                        break;
491                case 0x08: /* delete */
492                case 0x1c: /* or back space */
493                        if (inputcount > 0 && mode == TEXT) {
494                                cursorx-=CharWidth(inputs[--inputcount]);
495                                MoveTo(cursorx,cursory);
496                                inputs[inputcount]=0;
497                        drect.top=cursory-LINEDEPTH;
498                        drect.left=0;
499                        drect.bottom=cursory+3;
500                        drect.right=344;
501                        EraseRect(&drect);
502                        line[--linectr]=0;
503                                if (GetCtlValue(bar) == GetCtlMax(bar)){
504                                macflush();
505                                numlines_--;}
506                                }
507                        break;
508                default:
509                        break;}
510          }
511}
512
513void fixmacfile(filename)
514char *filename;
515{
516OSErr retcode;
517FInfo  fndrinfo;
518char filename1[100];
519char filename2[100];
520strcpy(filename1,filename);
521strcpy(filename2,filename);
522retcode=GetFInfo(CtoPstr(filename1),0,&fndrinfo);
523fndrinfo.fdType='TEXT';
524fndrinfo.fdCreator='MSWD';
525retcode=SetFInfo(CtoPstr(filename2),0,&fndrinfo);
526}
527
Note: See TracBrowser for help on using the repository browser.