sysstmac.c.1 60 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126
  1. /* sysstmac.c Copyright (C) 1989-99 Codemist Ltd */
  2. /*
  3. * Macintosh system-specific stuff
  4. */
  5. /* Signature: 78d97b29 18-Apr-1999 */
  6. #include "machine.h"
  7. #include <stdarg.h>
  8. #include <stddef.h>
  9. #include <string.h>
  10. #include <ctype.h>
  11. #include "tags.h"
  12. #include "externs.h"
  13. #include <unix.h>
  14. #include <files.h>
  15. #include <unix.h>
  16. #include <retrace.h>
  17. #include <timer.h>
  18. #include <ansi_private.h>
  19. #include "macwin.h"
  20. #include <Dialogs.h>
  21. #undef nil /* #define'd by Think C headers but not wanted (by me) */
  22. int get_home_directory(char *b, int length);
  23. int get_users_home_directory(char *b, int length);
  24. #include "filename.c"
  25. /*
  26. * This is a dummy definition of get_truename, here so that everything
  27. * will link. Both the calling convention used here and the exact
  28. * meaning and implementation may be under gentle review!
  29. */
  30. char *get_truename(char *filename, char *old, size_t n)
  31. {
  32. char *w;
  33. process_file_name(filename, old, n);
  34. if (*filename == 0)
  35. { aerror("truename");
  36. return NULL;
  37. }
  38. w = (char *)malloc(1+strlen(filename));
  39. if (w == NULL) return w;
  40. strcpy(w, filename);
  41. return w;
  42. }
  43. bool file_exists(char *filename, char *old, size_t n, char *tt)
  44. {
  45. FileParam pb;
  46. char buf[FILENAME_MAX];
  47. process_file_name(filename, old, n);
  48. pb.ioNamePtr = __c2p((const char*)filename, buf);
  49. pb.ioFRefNum = 0;
  50. pb.ioFVersNum = 0;
  51. pb.ioFDirIndex = 0;
  52. if (PBGetFInfo((ParmBlkPtr)&pb, 0) != noErr) return NO;
  53. strcpy(tt, ctime(&(pb.ioFlMdDat)));
  54. return YES;
  55. }
  56. char *my_getenv(char *s)
  57. {
  58. return getenv(s);
  59. }
  60. int
  61. myexec(char *filename, ...)
  62. {
  63. int i;
  64. short ans;
  65. EventRecord event;
  66. #if 1 /* __powerc */
  67. FSSpec fsp;
  68. LaunchParamBlockRec lpb;
  69. C2PStr(filename);
  70. ans = FSMakeFSSpec( 0,0,(unsigned char*)filename,&fsp);
  71. P2CStr((unsigned char*)filename);
  72. if (!ans) {
  73. lpb.launchBlockID = extendedBlock;
  74. lpb.launchEPBLength = extendedBlockLen;
  75. lpb.launchFileFlags = 0;
  76. lpb.launchControlFlags = launchContinue + launchNoFileFlags;
  77. lpb.launchAppSpec = &fsp;
  78. lpb.launchAppParameters = 0;
  79. ans = LaunchApplication(&lpb);
  80. }
  81. #else
  82. static struct {
  83. unsigned char *name;
  84. short memuse;
  85. char lc[2];
  86. long extBlocLen;
  87. short fFlags;
  88. long launchFlags;
  89. } buf;
  90. unsigned char pname[255];
  91. extern void _Launch();
  92. buf.name = __c2p(filename, (char *)pname);
  93. buf.memuse = 0;
  94. buf.lc[0] = 'L'; buf.lc[1] = 'C';
  95. buf.extBlocLen = 6;
  96. buf.fFlags = 128; /* RO */
  97. buf.launchFlags = 0xC0000000;
  98. asm {
  99. lea buf,a0
  100. dc.w _Launch
  101. move.w d0,ans;
  102. }
  103. #endif
  104. if (ans==0)
  105. for (i=0; i<20; i++) WaitNextEvent(everyEvent, &event, 10, 0L);
  106. return ans;
  107. }
  108. int my_system(char *s)
  109. {
  110. return myexec(s);
  111. }
  112. void my_pclose(FILE *a)
  113. {
  114. return;
  115. }
  116. int create_directory(char *filename, char *old, size_t n)
  117. {
  118. process_file_name(filename, old, n);
  119. if (*filename==0) return 1;
  120. return 1; /* Unfinished */
  121. }
  122. int delete_file(char *filename, char *old, size_t n)
  123. {
  124. process_file_name(filename, old, n);
  125. if (*filename==0) return 1;
  126. return remove(filename);
  127. }
  128. int get_home_directory(char *b, int length)
  129. {
  130. char *w = my_getenv("home");
  131. if (w != NULL) strcpy(b, w);
  132. else
  133. strcpy(b, ":"); /* Not satisfactory */
  134. return strlen(b);
  135. }
  136. static int get_users_home_directory(char *b, int length)
  137. {
  138. char *w, h[LONGEST_LEGAL_FILENAME];
  139. sprintf(h, "home$%s", b);
  140. w = my_getenv(h);
  141. if (w != NULL) strcpy(b, w);
  142. else
  143. strcpy(b, ":"); /* Not satisfactory */
  144. return strlen(b);
  145. }
  146. int batchp(void)
  147. {
  148. return !isatty(fileno(stdin));
  149. }
  150. /*static char CurApName[64];*/
  151. /*
  152. * The next procedure is responsible for establishing information about
  153. * where the main checkpoint image should be recovered from, and where
  154. * and fasl files should come from.
  155. */
  156. char *find_image_directory(int argc, char *argv[])
  157. {
  158. char image[LONGEST_LEGAL_FILENAME];
  159. char pgmname[LONGEST_LEGAL_FILENAME];
  160. char *w;
  161. /*
  162. * For the Macintosh I use the data fork of the application image as
  163. * a place to store useful stuff.
  164. */
  165. WDPBRec pb1;
  166. CInfoPBRec pb2;
  167. int i, j, r, p = LONGEST_LEGAL_FILENAME;
  168. long id;
  169. pgmname[--p] = 0;
  170. sprintf(image, "%#s", LMGetCurApName()); /* name of current application */
  171. strcpy(program_name, image);
  172. i = strlen(image);
  173. strcpy(image+i, " Image");
  174. i += 6;
  175. p -= i;
  176. memcpy(&pgmname[p], image, i); /* copy to the end of a buffer */
  177. pb1.ioNamePtr = (unsigned char *)image;
  178. PBHGetVolSync(&pb1); /* find current working dir/volume */
  179. id = pb1.ioWDDirID; /* working directory identifier */
  180. while (id != 0) {
  181. pb2.dirInfo.ioFDirIndex = -1; /* use dir ID, not file name/index */
  182. pb2.dirInfo.ioVRefNum = pb1.ioVRefNum; /* look in this volume */
  183. pb2.dirInfo.ioDrDirID = id; /* get info about this directory */
  184. pb2.dirInfo.ioNamePtr = (unsigned char *)image;
  185. r = PBGetCatInfoSync(&pb2); /* Read catalogue - find name & parent */
  186. if (r != 0) break; /* failed - must be at top of tree */
  187. id = pb2.dirInfo.ioDrParID; /* go on up to parent directory */
  188. i = image[0] & 0xff; /* length of name of this directory */
  189. pgmname[--p] = ':';
  190. p -= i;
  191. if (p < 10) {
  192. fprintf(stderr, "\nPlease re-install this package nearer the top of\n");
  193. fprintf(stderr, "your directory hierarchy. It will not work this far down\n");
  194. abort();
  195. }
  196. memcpy(&pgmname[p], &image[1], i); /* stick names together with ':'s */
  197. }
  198. strcpy(image, &pgmname[p]); /* Put complete name in convenient place */
  199. /*
  200. * I copy from local vectors into malloc'd space to hand my
  201. * answer back.
  202. */
  203. w = (char *)malloc(1+strlen(&pgmname[p]));
  204. /*
  205. * The error exit here seem unsatisfactory...
  206. */
  207. if (w == NULL)
  208. { fprintf(stderr, "\n+++ Panic - run out of space\n");
  209. exit(EXIT_FAILURE);
  210. }
  211. strcpy(w, &pgmname[p]);
  212. return w;
  213. }
  214. int truncate_file(FILE *f, long int where)
  215. {
  216. short a;
  217. short ff = f->refnum;
  218. if (fflush(f) != 0) return 1;
  219. a = SetEOF(ff, where); /* Returns zero if successs */
  220. return (int)a;
  221. }
  222. static bool ticker_active = NO;
  223. int32 software_ticks = INITIAL_SOFTWARE_TICKS;
  224. int32 software_tick_count = 0, prev_software_tick_count = 0;
  225. void add_ticker(void)
  226. {
  227. if (ticker_active) return;
  228. if (countdown<0) countdown = SOFTWARE_TICKS; /* Reset if expired */
  229. ticker_active = YES;
  230. }
  231. void remove_ticker(void)
  232. {
  233. /* if (!ticker_active) return; */
  234. ticker_active = NO;
  235. }
  236. int file_readable(char *filename, char *old, size_t n)
  237. {
  238. FILE *fp;
  239. process_file_name(filename, old, n);
  240. if (*filename == 0) return 0;
  241. /* The "correct" way to do this is via stat, but this is much simpler! */
  242. fp = fopen(filename,"r");
  243. if (fp == NULL) return 0;
  244. else
  245. { fclose(fp);
  246. return 1;
  247. }
  248. }
  249. int file_writeable(char *filename, char *old, size_t n)
  250. {
  251. FILE *fp;
  252. process_file_name(filename, old, n);
  253. if (*filename == 0) return 0;
  254. fp = fopen(filename,"a");
  255. if (fp == NULL) return 0;
  256. else
  257. { fclose(fp);
  258. return 1;
  259. }
  260. }
  261. int rename_file(char *from_name, char *from_old, size_t from_size,
  262. char *to_name, char *to_old, size_t to_size)
  263. {
  264. process_file_name(from_name, from_old, from_size);
  265. process_file_name(to_name, to_old, to_size);
  266. if (*from_name == 0 || *to_name == 0) return 0;
  267. return rename(from_name,to_name);
  268. }
  269. int change_directory(char *filename, char *old, size_t n)
  270. {
  271. WDPBRec P;
  272. Str255 pname;
  273. process_file_name(filename, old, n);
  274. if (*filename==0) return 1;
  275. strcpy((char*)pname, filename);
  276. C2PStr((char*)pname);
  277. P.ioNamePtr = pname;
  278. return PBHSetVol(&P, 0);
  279. }
  280. int directoryp(char *filename, char *old, size_t n)
  281. {
  282. struct stat statrec;
  283. process_file_name(filename, old, n);
  284. stat(filename, &statrec);
  285. return S_ISDIR(statrec.st_mode);
  286. }
  287. int get_current_directory(char *s, int n)
  288. {
  289. return 0;
  290. }
  291. #include "scandir.c"
  292. void list_directory_members(char *filename, char *old,
  293. size_t n, directory_callback *fn)
  294. {
  295. process_file_name(filename, old, n);
  296. scan_files(filename, fn);
  297. }
  298. /* ************************************************************ */
  299. /* ********** StdWin Interface ******************************** */
  300. /* ************************************************************ */
  301. /* ************************************************************ */
  302. #include "stdwin.h"
  303. #include "tools.h"
  304. #include "editwin.h"
  305. #include "text.h" /* Rather a cheat as I need to look
  306. * low down in here */
  307. static WINDOW *CSL_window;
  308. static EDITWIN *CSL_ew;
  309. static EDITWIN *help_ew;
  310. int max_nlines = 250;
  311. #ifndef HELP_DATA
  312. #define HELP_DATA "help.data"
  313. #endif
  314. #ifndef HELP_INDEX
  315. #define HELP_INDEX "help.index"
  316. #endif
  317. static MENU *adminmenu;
  318. static MENU *editmenu;
  319. static MENU *loadmenu;
  320. static MENU *libmenu;
  321. static MENU *switchmenu;
  322. static MENU *helpmenu;
  323. /* static MENU *fontmenu; */
  324. /* static MENU *sizemenu; */
  325. #define ADMIN_MENU (1001)
  326. #define MMFile 0
  327. #define MMSaveas 1
  328. #define MMHelp 2 /* main window menu items */
  329. #define MMHelpSel 3
  330. #define MMHelpAsk 4
  331. #define MMInt 5
  332. #define MMAbort 6
  333. #define MMPause 7
  334. #define MMDummy 8
  335. #define MMTime 9
  336. #define MMSpace 10
  337. #define MMOTime 11
  338. #define EDIT_MENU (1002)
  339. #define MMCut 0
  340. #define MMCopy 1
  341. #define MMPaste 2
  342. #define MMClear 3
  343. #define MMSelAll 4
  344. #define HELP_LEN (36)
  345. #define HELP_MENU (1003)
  346. static struct hlp {
  347. char name[HELP_LEN];
  348. long offset;
  349. int length;
  350. } *hlp;
  351. int help_length;
  352. int helpstamp;
  353. #define LOAD_MENU (1004)
  354. static char *loads[] = {
  355. (char*)NULL};
  356. #define LIB_MENU (1005)
  357. static char *libraries[] = {
  358. (char*)NULL};
  359. #define SWITCH_MENU (1006)
  360. static struct sw {
  361. char *name;
  362. int state;
  363. } switches[] = {
  364. {(char*)NULL, 0}};
  365. /* #define FONT_MENU (1007) */
  366. /* static char *fonts[] = { "Monaco", "Courier", NULL}; */
  367. /* static current_font = 0; */
  368. /* #define SIZE_MENU (1008) */
  369. /* static char *sizes[] = { "8", "9", "10", "11", "12", NULL}; */
  370. /* static current_size = 1; */
  371. get_full_name(char *name, FSSpec *spec)
  372. {
  373. char nn[LONGEST_LEGAL_FILENAME];
  374. char mm[LONGEST_LEGAL_FILENAME];
  375. char *w;
  376. int i, r;
  377. int p = LONGEST_LEGAL_FILENAME;
  378. long id;
  379. CInfoPBRec pb2;
  380. nn[--p] = 0;
  381. i = spec->name[0];
  382. p -= i;
  383. memcpy(&nn[p], &(spec->name[1]), i); /* Copy base name */
  384. id = spec->parID;
  385. while (id != 0) {
  386. pb2.dirInfo.ioFDirIndex = -1; /* use dirID, not file name/index */
  387. pb2.dirInfo.ioVRefNum = spec->vRefNum; /* look in this volume */
  388. pb2.dirInfo.ioDrDirID = id; /* get info about this directory */
  389. pb2.dirInfo.ioNamePtr = (unsigned char *)mm;
  390. if (PBGetCatInfoSync(&pb2)) break; /* Read catalogue - find name & parent*/
  391. /* Fail at top of tree? */
  392. id = pb2.dirInfo.ioDrParID; /* go on up to parent directory */
  393. i = mm[0] & 0xff; /* length of name of this directory */
  394. nn[--p] = ':';
  395. p -= i;
  396. if (p < 10) {
  397. fprintf(stderr, "\nCannot access file so far from root\n");
  398. strcpy(name, "");
  399. return FALSE;
  400. }
  401. memcpy(&nn[p], &mm[1], i); /* stick names together with ':'s */
  402. }
  403. strcpy(name, &nn[p]);
  404. return TRUE;
  405. }
  406. static void menusetup(void)
  407. {
  408. MENU *mp;
  409. int i;
  410. adminmenu= mp= wmenucreate(ADMIN_MENU, "Admin");
  411. wmenuadditem(mp, "Input file...", 'F');
  412. wmenuadditem(mp, "Saveas...", -1);
  413. wmenuadditem(mp, "Help Window", 'H');
  414. wmenuadditem(mp, "Help Selection", 'S');
  415. wmenuadditem(mp, "Help Topic...", -1);
  416. wmenuadditem(mp, "Interrupt", 'I');
  417. wmenuadditem(mp, "Quit", 'Q');
  418. wmenuadditem(mp, "Pause", 'P');
  419. wmenuadditem(mp, "---------", -1);
  420. wmenuadditem(mp, "0.00", -1);
  421. wmenuadditem(mp, "[GC 0]", -1);
  422. wmenuadditem(mp, "", -1);
  423. wmenuadditem(mp, "", -1);
  424. wmenuenable(mp, MMDummy, NO);
  425. wmenuenable(mp, MMTime, NO);
  426. wmenuenable(mp, MMSpace, NO);
  427. wmenuenable(mp, MMOTime, NO);
  428. editmenu= mp= wmenucreate(EDIT_MENU, "Edit");
  429. wmenuadditem(mp, "Cut", 'X');
  430. wmenuadditem(mp, "Copy", 'C');
  431. wmenuadditem(mp, "Paste", 'V');
  432. wmenuadditem(mp, "Clear", 'B');
  433. wmenuadditem(mp, "Select All", 'A');
  434. /* fontmenu= mp= wmenucreate(FONT_MENU, "Font"); */
  435. /* for (i=0; fonts[i]!= NULL; i++) wmenuadditem(mp, fonts[i], -1); */
  436. /* wmenucheck(mp, current_font, YES); */
  437. /* sizemenu= mp= wmenucreate(SIZE_MENU, "FontSize"); */
  438. /* for (i=0; sizes[i]!= NULL; i++) wmenuadditem(mp, sizes[i], -1); */
  439. /* wmenucheck(mp, current_size, YES); */
  440. /* helpmenu= mp= wmenucreate(HELP_MENU, "Help"); */
  441. helpmenu = mp = (MENU*)GetMenu(HELP_MENU);
  442. if (mp != 0) /* This checks against problems */
  443. InsertMenu((MenuHandle)mp, 0); DrawMenuBar();
  444. {
  445. FILE* hlpindx = fopen(HELP_INDEX, "r");
  446. if (hlpindx != NULL) {
  447. fscanf(hlpindx, "%d\n", &helpstamp);
  448. fscanf(hlpindx, "%d", &help_length);
  449. hlp = (struct hlp*) calloc(1+help_length, sizeof(struct hlp));
  450. if (hlp == NULL) {
  451. help_length = 0;
  452. goto loader; /* Insufficient memory */
  453. }
  454. for (i=0; i<help_length; i++) {
  455. int ch, p=0;
  456. fscanf(hlpindx, "%d %d ", &(hlp[i].offset), &(hlp[i].length));
  457. while (p<HELP_LEN-1) {
  458. ch = getc(hlpindx);
  459. if (ch == '\n') break;
  460. hlp[i].name[p++] = ch; /* Was toupper here */
  461. }
  462. while (ch != '\n') ch = getc(hlpindx);
  463. hlp[i].name[p] = '\0';
  464. /*wmenuadditem(mp, hlp[i].name, -1);*/
  465. }
  466. fclose(hlpindx);
  467. }
  468. else {
  469. help_length = 0;
  470. strcpy(hlp[0].name, "No help");
  471. hlp[0].offset = -1;
  472. hlp[0].length = 0;
  473. }
  474. }
  475. loader:
  476. loadmenu= mp= wmenucreate(LOAD_MENU, "Load");
  477. for (i=0; loads[i]!= NULL; i++)
  478. wmenuadditem(mp, loads[i], -1);
  479. libmenu= mp= wmenucreate(LIB_MENU, "Library");
  480. for (i=0; libraries[i]!= NULL; i++)
  481. wmenuadditem(mp, libraries[i], -1);
  482. switchmenu= mp= wmenucreate(SWITCH_MENU, "Switch");
  483. for (i=0; switches[i].name!= NULL; i++) {
  484. wmenuadditem(mp, switches[i].name, -1);
  485. wmenucheck(mp, i, switches[i].state);
  486. }
  487. }
  488. static void fixmenus(void)
  489. {
  490. bool focus;
  491. focus= (CSL_ew->tp->foclen != 0);
  492. wmenuenable(editmenu, MMCut, focus);
  493. wmenuenable(editmenu, MMCopy, focus);
  494. wmenuenable(editmenu, MMClear, focus);
  495. wmenuenable(adminmenu, MMHelpSel, focus);
  496. /* wmenuenable(editmenu, MMPaste, YES); */
  497. if (help_ew != NULL) {
  498. focus= (help_ew->tp->foclen != 0);
  499. if (focus) {
  500. wmenuenable(editmenu, MMCut, focus);
  501. wmenuenable(editmenu, MMCopy, focus);
  502. wmenuenable(editmenu, MMClear, focus);
  503. wmenuenable(adminmenu, MMHelpSel, focus);
  504. }
  505. }
  506. }
  507. #define TTYBUF_SIZE 256
  508. static char tty_buff[TTYBUF_SIZE];
  509. static int tty_index = 0;
  510. static bool tty_ready = NO;
  511. static int tty_nnl = 0;
  512. static int tty_offset;
  513. #define STDOUT_BUFSIZE 1024
  514. #define LONGEST_PRINTF 120
  515. static char stdout_buffer[STDOUT_BUFSIZE];
  516. static char *stdout_p;
  517. static int stdout_n;
  518. extern int _w_font;
  519. void start_up_window_manager(int use_wimp)
  520. {
  521. int CSL_width, CSL_height;
  522. _w_font = 4; /* Font family */
  523. menusetup();
  524. wsetdefwinsize(82*wcharwidth('0'), 25*wlineheight());
  525. CSL_ew = ewcreate(NULL);
  526. CSL_window = CSL_ew->win;
  527. wsettitle(CSL_window, "Reduce 3.7");
  528. fixmenus();
  529. /* wmenudetach(CSL_window, helpmenu); */
  530. wmenuenable(editmenu, MMTime, NO); /* These are not selectable */
  531. wmenuenable(editmenu, MMOTime, NO); /* These are not selectable */
  532. wmenuenable(editmenu, MMSpace, NO);
  533. wmenudetach(CSL_window, loadmenu); /* These are only valid when reading */
  534. wmenudetach(CSL_window, libmenu);
  535. wmenudetach(CSL_window, switchmenu);
  536. /* wmessage("Welcome to X-Reduce\n\n"); */
  537. stdout_n = 0;
  538. stdout_p = stdout_buffer;
  539. help_ew = NULL;
  540. }
  541. static char *help_buff;
  542. bool
  543. helpwindow(int index)
  544. {
  545. FILE* help = fopen(HELP_DATA, "r");
  546. int ch;
  547. int width, height;
  548. int size = hlp[index].length;
  549. if (help == NULL) return FALSE;
  550. fscanf(help, "%d\n", &ch);
  551. if (ch != helpstamp) return FALSE; /* not same generation */
  552. /* fprintf(stderr, "Help on index %d offset=%d size=%d\n",
  553. index, hlp[index].offset, hlp[index].length); */
  554. fseek(help, hlp[index].offset, SEEK_SET);
  555. if (help_ew) {
  556. free(help_buff);
  557. tesetfocus(help_ew->tp, 0, tegetlen(help_ew->tp));
  558. ewreplace(help_ew, "");
  559. }
  560. else {
  561. help_ew = ewcreate(NULL);
  562. wsettitle(help_ew->win, "Help for Reduce 3.7");
  563. }
  564. help_buff = malloc(size+1);
  565. if (help_buff == NULL) {
  566. dprintf("Insufficient memory");
  567. wfleep();
  568. return FALSE;
  569. }
  570. /* fprintf(stderr, "reading %d bytes to buffer\n", size); */
  571. fread(help_buff, size, 1, help);
  572. /* fprintf(stderr, "help starts as %.100s\n", help_buff); */
  573. help_buff[size] = '\0';
  574. wmenudetach(help_ew->win, loadmenu);
  575. wmenudetach(help_ew->win, libmenu);
  576. wmenudetach(help_ew->win, switchmenu);
  577. /* wmenudetach(help_ew->win, adminmenu); */
  578. ewreplace(help_ew, help_buff);
  579. tesetfocus(help_ew->tp, 0, 0);
  580. fclose(help);
  581. return TRUE;
  582. }
  583. void help_buffer(char *buf, int len)
  584. {
  585. int i;
  586. for (i=0; i<help_length; i++) {
  587. /* fprintf(stderr, "Check against %s\n", hlp[i].name); */
  588. if (strncmp(hlp[i].name, buf, len) == 0) {
  589. helpwindow(i);
  590. break;
  591. }
  592. }
  593. if (i == help_length) wfleep();
  594. }
  595. void help_selection(EDITWIN *ew)
  596. {
  597. int i;
  598. char *text;
  599. TEXTEDIT *tp = ew->tp;
  600. if (tp->foclen == 0) {
  601. wfleep();
  602. return;
  603. }
  604. text= tegettext(tp);
  605. help_buffer(text+tp->foc, tp->foclen);
  606. }
  607. extern int pause_set = 0;
  608. void event_loop(void)
  609. {
  610. for (;;) { /* Loop while there are events */
  611. EVENT e;
  612. EDITWIN *ew;
  613. bool closed;
  614. wgetevent(&e);
  615. /* fprintf(stderr, "Event: type=%d win=%p data=%d\n", e.type, e.window, e.u.command); */
  616. ew= ewfind(e.window);
  617. if (ew == CSL_ew) {
  618. switch (e.type) {
  619. case WE_CHAR:
  620. switch(e.u.character) {
  621. case 'A'-'@': /* ^A == beginning of line */
  622. {
  623. TEXTEDIT* tp = CSL_ew->tp;
  624. tesetfocus(tp,
  625. zsubgap(tp->start[tewhichline(tp,
  626. zaddgap(tp->foc),
  627. tp->focprev)]),
  628. -1);
  629. break;
  630. }
  631. case 'B'-'@': /* ^B back a character */
  632. tearrow(CSL_ew->tp, WC_LEFT);
  633. break;
  634. case 127: /* Delete character */
  635. case 'D'-'@': /* ^D delete at cursor */
  636. {
  637. TEXTEDIT* tp = CSL_ew->tp;
  638. tearrow(tp, WC_RIGHT);
  639. {
  640. int f1 = tp->foc;
  641. int i;
  642. int ss = tp->start[tp->nlines-tty_nnl];
  643. int ee = ss + tty_offset;
  644. if (ss <= f1 && f1 < ee) {
  645. if (tty_offset>0) tty_offset--;
  646. }
  647. e.type = WE_COMMAND;
  648. e.u.command = WC_BACKSPACE;
  649. ewevent(ew,&e, NULL);
  650. break;
  651. }
  652. }
  653. case 'E'-'@': /* ^E end of line */
  654. {
  655. TEXTEDIT* tp = CSL_ew->tp;
  656. int line = tewhichline(tp, zaddgap(tp->foc), tp->focprev);
  657. int xxx = zsubgap(tetextround(tp, line, tp->right));
  658. tesetfocus(tp, xxx, -1);
  659. break;
  660. }
  661. case 'F'-'@': /* ^F forward a character */
  662. tearrow(CSL_ew->tp, WC_RIGHT);
  663. break;
  664. case 'K'-'@': /* ^K kill to end of line */
  665. { /* This does not take notice of offset */
  666. TEXTEDIT* tp = CSL_ew->tp;
  667. int f1;
  668. int i;
  669. int ss;
  670. int ee;
  671. tesetfocus(tp,
  672. tp->foc,
  673. zsubgap(tetextround(tp,
  674. tewhichline(tp, zaddgap(tp->foc),
  675. tp->focprev),
  676. tp->right)));
  677. f1 = tp->foc;
  678. ss = tp->start[tp->nlines-tty_nnl];
  679. ee = ss + tty_offset;
  680. for (i=0; i<tp->foclen; i++)
  681. if (ss <= f1+i && f1+i < ee) {
  682. if (tty_offset>0) tty_offset--;
  683. }
  684. ewreplace(ew, "");
  685. break;
  686. }
  687. case 'N'-'@': /* ^N next line */
  688. tearrow(CSL_ew->tp, WC_DOWN);
  689. break;
  690. case 'P'-'@': /* ^P previous line */
  691. tearrow(CSL_ew->tp, WC_UP);
  692. break;
  693. case 'Z'-'@': /* ^Z move to end of buffer */
  694. {
  695. TEXTEDIT* tp = CSL_ew->tp;
  696. tesetfocus(tp, tp->buflen - tp->gaplen, -1);
  697. break;
  698. }
  699. default:
  700. ewevent(ew, &e, &closed);
  701. if (tty_ready == YES && !pause_set) return;
  702. }
  703. break;
  704. case WE_COMMAND:
  705. switch (e.u.command) {
  706. case WC_CANCEL:
  707. interrupt_pending = YES;
  708. break;
  709. case WC_CLOSE:
  710. pause_for_user();
  711. exit(1);
  712. case WC_RETURN:
  713. {
  714. TEXTEDIT* tp = CSL_ew->tp;
  715. int f1 = zaddgap(tp->foc);
  716. int ee = tp->start[tp->nlines-tty_nnl] + tty_offset;
  717. /* printf("f1=%d ee=%d offset=%d\n", f1, ee, tty_offset); */
  718. if (f1 >= ee) {
  719. tty_nnl++;
  720. if (f1 == tp->buflen) {
  721. ewevent(ew, &e, &closed);
  722. tty_ready = YES;
  723. if (!pause_set) return;
  724. }
  725. }
  726. }
  727. break;
  728. case WC_DEL:
  729. case WC_BACKSPACE:
  730. /* Need to check to see if we are deleting
  731. * in the offset area */
  732. {
  733. TEXTEDIT* tp = CSL_ew->tp;
  734. int f1 = tp->foc;
  735. int i;
  736. int ss = tp->start[tp->nlines-tty_nnl];
  737. int ee = ss + tty_offset;
  738. if (tp->foclen == 0) {
  739. if (ss < f1 && f1 <= ee && tty_offset>0) tty_offset--;
  740. }
  741. else {
  742. for (i=0; i<tp->foclen; i++) {
  743. if (ss <= f1+i && f1+i < ee && tty_offset>0) tty_offset--;
  744. }
  745. }
  746. }
  747. break;
  748. case WC_LEFT:
  749. case WC_RIGHT:
  750. default:
  751. break;
  752. }
  753. ewevent(ew, &e, &closed);
  754. break;
  755. case WE_MENU:
  756. switch (e.u.m.id) {
  757. case ADMIN_MENU:
  758. switch (e.u.m.item) {
  759. case MMFile:
  760. {
  761. short wd;
  762. TEXTEDIT *tp = CSL_ew->tp;
  763. struct StandardFileReply sfr;
  764. StandardGetFile(NULL, -1, NULL, &sfr);
  765. if (sfr.sfGood && !sfr.sfIsFolder && !sfr.sfIsVolume) {
  766. char name[256];
  767. if (!get_full_name(name, &(sfr.sfFile))) break;
  768. tesetfocus(tp, tp->buflen - tp->gaplen, -1);
  769. ewreplace(CSL_ew, "in \"");
  770. ewreplace(CSL_ew, name);
  771. ewreplace(CSL_ew, "\"");
  772. /*tetoend(tp); */
  773. }
  774. break;
  775. }
  776. case MMSaveas:
  777. ewsaveas(CSL_ew);
  778. break;
  779. case MMHelp:
  780. helpwindow(0);
  781. break;
  782. case MMHelpSel:
  783. help_selection(ew);
  784. break;
  785. case MMHelpAsk:
  786. {
  787. char buf[40];
  788. int len;
  789. if (waskstr("Help on topic", buf, 40)) {
  790. len = strlen(buf);
  791. help_buffer(buf, len);
  792. }
  793. }
  794. break;
  795. case MMAbort:
  796. pause_for_user();
  797. exit(1);
  798. case MMInt:
  799. interrupt_pending = YES;
  800. return;
  801. case MMPause:
  802. pause_set = !pause_set;
  803. wmenucheck(adminmenu, MMPause, pause_set);
  804. if (pause_set) wsettitle(CSL_window, "<Paused> Reduce 3.7");
  805. else wsettitle(CSL_window, "Reduce 3.7");
  806. break;
  807. }
  808. break;
  809. case EDIT_MENU:
  810. switch (e.u.m.item) {
  811. case MMCopy:
  812. ewcopy(ew);
  813. break;
  814. case MMPaste:
  815. {
  816. char* text = wgetclip();
  817. char* tt = text;
  818. int valid = YES;
  819. if (text == NULL) wfleep();
  820. else {
  821. TEXTEDIT *tp = CSL_ew->tp;
  822. tesetfocus(tp, tp->buflen - tp->gaplen, -1);
  823. while (*tt != '\0')
  824. if (*tt++=='\n') valid = NO;
  825. if (valid) ewreplace(ew, text);
  826. else /*wmessage("Cannot Paste text including new line"); */
  827. Alert(129, NULL);
  828. }
  829. }
  830. break;
  831. case MMCut:
  832. ewcopy(ew);
  833. case MMClear:
  834. /* Need to check to see if we are deleting
  835. * in the offset area */
  836. {
  837. TEXTEDIT* tp = CSL_ew->tp;
  838. int f1 = tp->foc;
  839. int i;
  840. int ss = tp->start[tp->nlines-tty_nnl];
  841. int ee = ss + tty_offset;
  842. for (i=0; i<tp->foclen; i++)
  843. if (ss <= f1+i && f1+i < ee) {
  844. if (tty_offset>0) tty_offset--;
  845. }
  846. }
  847. ewreplace(ew, "");
  848. break;
  849. case MMSelAll:
  850. tesetfocus(ew->tp, 0, tegetlen(ew->tp));
  851. break;
  852. }
  853. break;
  854. case LOAD_MENU:
  855. {
  856. char *load = "load_package ";
  857. char *tt = loads[e.u.m.item];
  858. TEXTEDIT *tp = CSL_ew->tp;
  859. tesetfocus(tp, tp->buflen - tp->gaplen, -1);
  860. tp->aim= UNDEF;
  861. tp->focprev= FALSE;
  862. ewreplace(CSL_ew, load);
  863. ewreplace(CSL_ew, tt);
  864. tty_ready = YES;
  865. ewreplace(CSL_ew, ";\n");
  866. tty_nnl++;
  867. wmenuenable(loadmenu, e.u.m.item, NO);
  868. return;
  869. }
  870. case LIB_MENU:
  871. {
  872. char *load = "load_package ";
  873. char *tt = libraries[e.u.m.item];
  874. TEXTEDIT *tp = CSL_ew->tp;
  875. tesetfocus(tp, tp->buflen - tp->gaplen, -1);
  876. tp->aim= UNDEF;
  877. tp->focprev= FALSE;
  878. ewreplace(CSL_ew, load);
  879. ewreplace(CSL_ew, tt);
  880. tty_ready = YES;
  881. ewreplace(CSL_ew, ";\n");
  882. tty_nnl++;
  883. wmenuenable(loadmenu, e.u.m.item, NO);
  884. return;
  885. }
  886. case SWITCH_MENU:
  887. {
  888. char *load = (switches[e.u.m.item].state ? "off " : "on ");
  889. char *tt = switches[e.u.m.item].name;
  890. TEXTEDIT *tp = CSL_ew->tp;
  891. tesetfocus(tp, tp->buflen - tp->gaplen, -1);
  892. ewreplace(CSL_ew, load);
  893. ewreplace(CSL_ew, tt);
  894. tty_ready = YES;
  895. ewreplace(CSL_ew, ";\n");
  896. tty_nnl++;
  897. switches[e.u.m.item].state = ~ switches[e.u.m.item].state;
  898. wmenucheck(switchmenu, e.u.m.item, switches[e.u.m.item].state);
  899. return;
  900. }
  901. case HELP_MENU:
  902. helpwindow(e.u.m.item);
  903. break;
  904. /* case FONT_MENU: */
  905. /* if (ew == NULL) { */
  906. /* wfleep(); */
  907. /* break; */
  908. /* } */
  909. /* { */
  910. /* int f = wsetfont(fonts[e.u.m.item]); */
  911. /* if (f) { */
  912. /* TEXTATTR attr; */
  913. /* extern void getinfo_(); */
  914. /* wgetwintextattr(CSL_window, &attr); */
  915. /* attr.font = f; */
  916. /* wsetwintextattr(CSL_window, &attr); */
  917. /* getfinfo_(); */
  918. /* wmenucheck(fontmenu, current_font, NO); */
  919. /* wmenucheck(fontmenu, current_font = e.u.m.item, YES); */
  920. /* } */
  921. /* } */
  922. /* break; */
  923. /* case SIZE_MENU: */
  924. /* if (ew == NULL) { */
  925. /* wfleep(); */
  926. /* break; */
  927. /* } */
  928. /* wsetsize(atoi(sizes[e.u.m.item])); */
  929. /* { */
  930. /* TEXTATTR attr; */
  931. /* extern void getinfo_(); */
  932. /* wgetwintextattr(CSL_window, &attr); */
  933. /* attr.size = atoi(sizes[e.u.m.item]); */
  934. /* wsetwintextattr(CSL_window, &attr); */
  935. /* getfinfo_(); */
  936. /* } */
  937. /* wmenucheck(sizemenu, current_size, NO); */
  938. /* wmenucheck(sizemenu, current_size = e.u.m.item, YES); */
  939. /* break; */
  940. }
  941. break;
  942. case WE_CLOSE:
  943. pause_for_user();
  944. exit(1);
  945. default:
  946. ewevent(ew, &e, &closed);
  947. break;
  948. }
  949. }
  950. else if (ew == help_ew) {
  951. /* printf("%d %d\n", e.type, e.u.character); */
  952. switch (e.type) {
  953. case WE_MOUSE_UP: /* Extend to a word on single click */
  954. if (!ew->tp->mdown) break;
  955. ew->tp->mdown= FALSE;
  956. if (e.u.where.clicks > 1) {
  957. teclicknew(ew->tp, e.u.where.h, e.u.where.v, FALSE, TRUE);
  958. help_selection(ew);
  959. }
  960. break;
  961. case WE_CHAR:
  962. switch(e.u.character) {
  963. case 'A'-'@': /* ^A == beginning of line */
  964. {
  965. TEXTEDIT* tp = help_ew->tp;
  966. tesetfocus(tp,
  967. zsubgap(tp->start[tewhichline(tp,
  968. zaddgap(tp->foc),
  969. tp->focprev)]),
  970. -1);
  971. break;
  972. }
  973. case 'B'-'@': /* ^B back a character */
  974. tearrow(help_ew->tp, WC_LEFT);
  975. break;
  976. case 'E'-'@': /* ^E end of line */
  977. {
  978. TEXTEDIT* tp = help_ew->tp;
  979. int line = tewhichline(tp, zaddgap(tp->foc), tp->focprev);
  980. int xxx = zsubgap(tetextround(tp, line, tp->right));
  981. tesetfocus(tp, xxx, -1);
  982. break;
  983. }
  984. case 'F'-'@': /* ^F forward a character */
  985. tearrow(help_ew->tp, WC_RIGHT);
  986. break;
  987. case 'K'-'@': /* ^K is Page up */
  988. {
  989. int i;
  990. int j;
  991. wgetdefwinsize(&i, &j);
  992. j = j/wlineheight() -1;
  993. for (i=0; i<j; i++) tearrow(help_ew->tp, WC_UP);
  994. break;
  995. }
  996. case 'N'-'@': /* ^N next line */
  997. tearrow(help_ew->tp, WC_DOWN);
  998. break;
  999. case 'P'-'@': /* ^P previous line */
  1000. tearrow(help_ew->tp, WC_UP);
  1001. break;
  1002. case 'Z'-'@': /* ^Z move to end of buffer */
  1003. {
  1004. TEXTEDIT* tp = help_ew->tp;
  1005. tesetfocus(tp, tp->buflen - tp->gaplen, -1);
  1006. break;
  1007. }
  1008. case 'V'-'@': /* ^V page down */
  1009. case ' ':
  1010. case 'L'-'@': /* ^L is Page down */
  1011. {
  1012. int i;
  1013. int j;
  1014. wgetdefwinsize(&i, &j);
  1015. j = j/wlineheight() -1;
  1016. for (i=0; i<j; i++) tearrow(help_ew->tp, WC_DOWN);
  1017. break;
  1018. }
  1019. case 'i':
  1020. case 'I':
  1021. {
  1022. char buf[40];
  1023. int len;
  1024. if (waskstr("Help on topic", buf, 40)) {
  1025. len = strlen(buf);
  1026. help_buffer(buf, len);
  1027. }
  1028. break;
  1029. }
  1030. case 'n':
  1031. case 'N':
  1032. {
  1033. extern char *strstr(const char*, const char*);
  1034. char *p = strstr((const char*)help_buff, (const char*)"Next: ");
  1035. int i = 0;
  1036. if (p == NULL) {
  1037. wfleep(); break;
  1038. }
  1039. p += 6;
  1040. while (p[i]!= ',') i++;
  1041. help_buffer(p,i);
  1042. break;
  1043. }
  1044. case 'p':
  1045. case 'P':
  1046. {
  1047. extern char *strstr(const char*, const char*);
  1048. char *p = strstr((const char*)help_buff, "Prev: ");
  1049. int i = 0;
  1050. if (p == NULL) {
  1051. wfleep(); break;
  1052. }
  1053. p += 6;
  1054. while (p[i]!= ',') i++;
  1055. help_buffer(p,i);
  1056. break;
  1057. }
  1058. case 'q':
  1059. case 'Q':
  1060. help_ew->saved = TRUE; /* Fake it */
  1061. free(help_buff);
  1062. ewclose(help_ew);
  1063. help_ew = 0;
  1064. break;
  1065. case 'u':
  1066. case 'U':
  1067. {
  1068. extern char *strstr(const char*, const char*);
  1069. char *p = strstr((const char*)help_buff, "Up: ");
  1070. int i = 0;
  1071. if (p == NULL) {
  1072. wfleep(); break;
  1073. }
  1074. p += 4;
  1075. while (p[i]!= '\n') i++;
  1076. help_buffer(p,i);
  1077. break;
  1078. }
  1079. }
  1080. break;
  1081. case WE_MENU:
  1082. switch (e.u.m.id) {
  1083. case ADMIN_MENU:
  1084. switch (e.u.m.item) {
  1085. case MMSaveas:
  1086. ewsaveas(help_ew);
  1087. break;
  1088. case MMHelp:
  1089. if (help_length) helpwindow(0);
  1090. break;
  1091. case MMHelpSel:
  1092. help_selection(ew);
  1093. break;
  1094. case MMHelpAsk:
  1095. {
  1096. char buf[40];
  1097. int len;
  1098. if (waskstr("Help on topic", buf, 40)) {
  1099. len = strlen(buf);
  1100. help_buffer(buf, len);
  1101. }
  1102. break;
  1103. }
  1104. case MMAbort:
  1105. help_ew->saved = TRUE; /* Fake it */
  1106. free(help_buff);
  1107. ewclose(help_ew);
  1108. help_ew = 0;
  1109. break;
  1110. }
  1111. break;
  1112. case EDIT_MENU:
  1113. switch (e.u.m.item) {
  1114. case MMCopy:
  1115. ewcopy(ew);
  1116. break;
  1117. case MMSelAll:
  1118. tesetfocus(ew->tp, 0, tegetlen(ew->tp));
  1119. break;
  1120. }
  1121. break;
  1122. case HELP_MENU:
  1123. helpwindow(e.u.m.item);
  1124. break;
  1125. }
  1126. break;
  1127. case WE_COMMAND:
  1128. switch (e.u.command) {
  1129. case WC_CANCEL:
  1130. interrupt_pending=YES;
  1131. break;
  1132. case WC_RETURN:
  1133. help_selection(ew);
  1134. break;
  1135. case WC_DEL:
  1136. case WC_BACKSPACE:
  1137. helpwindow(0);
  1138. break;
  1139. default:
  1140. ewevent(ew, &e, &closed);
  1141. break;
  1142. }
  1143. if (e.u.command != WC_CLOSE) {
  1144. break;
  1145. }
  1146. case WE_CLOSE:
  1147. help_ew->saved = TRUE; /* Fake it */
  1148. free(help_buff);
  1149. ewclose(help_ew);
  1150. help_ew = 0;
  1151. break;
  1152. default:
  1153. ewevent(ew, &e, &closed);
  1154. if (closed) {
  1155. help_ew->saved = TRUE; /* Fake it */
  1156. free(help_buff);
  1157. ewclose(help_ew);
  1158. help_ew = 0;
  1159. }
  1160. break;
  1161. }
  1162. }
  1163. else if (ew != NULL) ewevent(ew, &e, &closed);
  1164. else wfleep();
  1165. fixmenus();
  1166. }
  1167. }
  1168. void poll_for_attn(void)
  1169. {
  1170. for (;;) { /* Loop while there are events */
  1171. EVENT e;
  1172. EDITWIN *ew;
  1173. bool closed;
  1174. if (!pause_set) {
  1175. if (!wpollevent(&e)) return;
  1176. }
  1177. else wgetevent(&e);
  1178. /* fprintf(stderr, "Event: type=%d win=%p data=%d\n", e.type, e.window, e.u.command); */
  1179. ew= ewfind(e.window);
  1180. if (ew == CSL_ew) {
  1181. switch (e.type) {
  1182. case WE_CHAR:
  1183. switch(e.u.character) {
  1184. case 'A'-'@': /* ^A == beginning of line */
  1185. {
  1186. TEXTEDIT* tp = CSL_ew->tp;
  1187. tesetfocus(tp,
  1188. zsubgap(tp->start[tewhichline(tp,
  1189. zaddgap(tp->foc),
  1190. tp->focprev)]),
  1191. -1);
  1192. break;
  1193. }
  1194. case 'B'-'@': /* ^B back a character */
  1195. tearrow(CSL_ew->tp, WC_LEFT);
  1196. break;
  1197. case 'D'-'@': /* ^D delete at cursor */
  1198. {
  1199. TEXTEDIT* tp = CSL_ew->tp;
  1200. tearrow(tp, WC_RIGHT);
  1201. e.type = WE_COMMAND;
  1202. e.u.command = WC_BACKSPACE;
  1203. ewevent(ew,&e, NULL);
  1204. break;
  1205. }
  1206. case 'E'-'@': /* ^E end of line */
  1207. {
  1208. TEXTEDIT* tp = CSL_ew->tp;
  1209. int line = tewhichline(tp, zaddgap(tp->foc), tp->focprev);
  1210. int xxx = zsubgap(tetextround(tp, line, tp->right));
  1211. tesetfocus(tp, xxx, -1);
  1212. break;
  1213. }
  1214. case 'F'-'@': /* ^F forward a character */
  1215. tearrow(CSL_ew->tp, WC_RIGHT);
  1216. break;
  1217. case 'K'-'@': /* ^K kill all type ahead */
  1218. tty_index = 0;
  1219. break;
  1220. case 'N'-'@': /* ^N next line */
  1221. tearrow(CSL_ew->tp, WC_DOWN);
  1222. break;
  1223. case 'P'-'@': /* ^P previous line */
  1224. tearrow(CSL_ew->tp, WC_UP);
  1225. break;
  1226. case 'Z'-'@': /* ^Z move to end of buffer */
  1227. {
  1228. TEXTEDIT* tp = CSL_ew->tp;
  1229. tesetfocus(tp, tp->buflen - tp->gaplen, -1);
  1230. break;
  1231. }
  1232. case 'V'-'@': /* ^V page down */
  1233. case ' ':
  1234. {
  1235. int i;
  1236. int j;
  1237. wgetdefwinsize(&i, &j);
  1238. j = j/wlineheight() -1;
  1239. for (i=0; i<j; i++) tearrow(help_ew->tp, WC_DOWN);
  1240. break;
  1241. }
  1242. default:
  1243. if (tty_index > TTYBUF_SIZE-2) wfleep();
  1244. else tty_buff[tty_index++] = e.u.character;
  1245. break;
  1246. }
  1247. break;
  1248. case WE_COMMAND:
  1249. switch (e.u.command) {
  1250. case WC_CANCEL:
  1251. interrupt_pending = YES;
  1252. break;
  1253. case WC_CLOSE:
  1254. pause_for_user();
  1255. exit(1);
  1256. case WC_RETURN:
  1257. if (tty_index > TTYBUF_SIZE-2) wfleep();
  1258. else tty_buff[tty_index++] = '\n';
  1259. break;
  1260. case WC_TAB:
  1261. if (tty_index > TTYBUF_SIZE-2) wfleep();
  1262. else tty_buff[tty_index++] = '\t';
  1263. break;
  1264. case WC_DEL:
  1265. case WC_BACKSPACE:
  1266. if (tty_index>0) tty_index--;
  1267. break;
  1268. }
  1269. break;
  1270. case WE_MENU:
  1271. switch (e.u.m.id) {
  1272. case ADMIN_MENU:
  1273. switch (e.u.m.item) {
  1274. case MMHelp:
  1275. helpwindow(0);
  1276. break;
  1277. case MMHelpSel:
  1278. help_selection(ew);
  1279. break;
  1280. case MMAbort:
  1281. pause_for_user();
  1282. exit(1);
  1283. case MMInt:
  1284. interrupt_pending = YES;
  1285. return;
  1286. case MMPause:
  1287. pause_set = !pause_set;
  1288. wmenucheck(adminmenu, MMPause, pause_set);
  1289. if (pause_set) wsettitle(CSL_window, "<Paused> Reduce 3.7");
  1290. else wsettitle(CSL_window, "Reduce 3.7");
  1291. break;
  1292. }
  1293. break;
  1294. case EDIT_MENU:
  1295. switch (e.u.m.item) {
  1296. case MMCopy:
  1297. ewcopy(ew);
  1298. break;
  1299. case MMPaste:
  1300. break;
  1301. case MMCut:
  1302. ewcopy(ew);
  1303. case MMClear:
  1304. ewreplace(ew, "");
  1305. break;
  1306. case MMSelAll:
  1307. tesetfocus(ew->tp, 0, tegetlen(ew->tp));
  1308. break;
  1309. }
  1310. break;
  1311. case HELP_MENU:
  1312. helpwindow(e.u.m.item);
  1313. break;
  1314. }
  1315. break;
  1316. case WE_CLOSE:
  1317. pause_for_user();
  1318. exit(1);
  1319. default:
  1320. ewevent(ew, &e, &closed);
  1321. break;
  1322. }
  1323. }
  1324. else if (ew == help_ew) {
  1325. switch (e.type) {
  1326. case WE_MOUSE_UP: /* Extend to a word on single click */
  1327. if (!ew->tp->mdown)
  1328. break;
  1329. ew->tp->mdown= FALSE;
  1330. if (e.u.where.clicks > 1) {
  1331. teclicknew(ew->tp, e.u.where.h, e.u.where.v, FALSE, TRUE);
  1332. help_selection(ew);
  1333. }
  1334. break;
  1335. case WE_CHAR:
  1336. /* fprintf(stderr, "WE_CHAR %d(%c)\n", e.u.character,e.u.character); */
  1337. switch(e.u.character) {
  1338. case 'A'-'@': /* ^A == beginning of line */
  1339. {
  1340. TEXTEDIT* tp = help_ew->tp;
  1341. tesetfocus(tp,
  1342. zsubgap(tp->start[tewhichline(tp,
  1343. zaddgap(tp->foc),
  1344. tp->focprev)]),
  1345. -1);
  1346. break;
  1347. }
  1348. case 'B'-'@': /* ^B back a character */
  1349. tearrow(help_ew->tp, WC_LEFT);
  1350. break;
  1351. case 'E'-'@': /* ^E end of line */
  1352. {
  1353. TEXTEDIT* tp = help_ew->tp;
  1354. int line = tewhichline(tp, zaddgap(tp->foc), tp->focprev);
  1355. int xxx = zsubgap(tetextround(tp, line, tp->right));
  1356. tesetfocus(tp, xxx, -1);
  1357. break;
  1358. }
  1359. case 'F'-'@': /* ^F forward a character */
  1360. tearrow(help_ew->tp, WC_RIGHT);
  1361. break;
  1362. case 'N'-'@': /* ^N next line */
  1363. tearrow(help_ew->tp, WC_DOWN);
  1364. break;
  1365. case 'P'-'@': /* ^P previous line */
  1366. tearrow(help_ew->tp, WC_UP);
  1367. break;
  1368. case 'Z'-'@': /* ^Z move to end of buffer */
  1369. {
  1370. TEXTEDIT* tp = help_ew->tp;
  1371. tesetfocus(tp, tp->buflen - tp->gaplen, -1);
  1372. break;
  1373. }
  1374. case 'L'-'@': /* ^L is PgDn */
  1375. case 'V'-'@': /* ^V page down */
  1376. case ' ':
  1377. {
  1378. int i;
  1379. int j;
  1380. wgetdefwinsize(&i, &j);
  1381. j = j/wlineheight() -1;
  1382. for (i=0; i<j; i++) tearrow(help_ew->tp, WC_DOWN);
  1383. break;
  1384. }
  1385. case 'K'-'@': /* ^K is PgUp */
  1386. {
  1387. int i;
  1388. int j;
  1389. wgetdefwinsize(&i, &j);
  1390. j = j/wlineheight() -1;
  1391. for (i=0; i<j; i++) tearrow(help_ew->tp, WC_UP);
  1392. break;
  1393. }
  1394. }
  1395. break;
  1396. case WE_MENU:
  1397. switch (e.u.m.id) {
  1398. case ADMIN_MENU:
  1399. switch (e.u.m.item) {
  1400. case MMHelp:
  1401. if (help_length) helpwindow(0);
  1402. break;
  1403. case MMHelpSel:
  1404. help_selection(ew);
  1405. break;
  1406. }
  1407. break;
  1408. case EDIT_MENU:
  1409. switch (e.u.m.item) {
  1410. case MMCopy:
  1411. ewcopy(ew);
  1412. break;
  1413. case MMSelAll:
  1414. tesetfocus(ew->tp, 0,
  1415. tegetlen(ew->tp));
  1416. break;
  1417. }
  1418. break;
  1419. case HELP_MENU:
  1420. helpwindow(e.u.m.item);
  1421. break;
  1422. }
  1423. break;
  1424. case WE_COMMAND:
  1425. switch (e.u.command) {
  1426. case WC_CANCEL:
  1427. interrupt_pending = YES;
  1428. break;
  1429. case WC_RETURN:
  1430. help_selection(ew);
  1431. break;
  1432. case WC_DEL:
  1433. case WC_BACKSPACE:
  1434. helpwindow(0);
  1435. break;
  1436. default:
  1437. ewevent(ew, &e, &closed);
  1438. break;
  1439. }
  1440. if (e.u.command != WC_CLOSE) {
  1441. break;
  1442. }
  1443. case WE_CLOSE:
  1444. help_ew->saved = TRUE; /* Fake it */
  1445. free(help_buff);
  1446. ewclose(help_ew);
  1447. help_ew = 0;
  1448. break;
  1449. default:
  1450. ewevent(ew, &e, &closed);
  1451. if (closed) {
  1452. help_ew->saved = TRUE; /* Fake it */
  1453. free(help_buff);
  1454. ewclose(help_ew);
  1455. help_ew = 0;
  1456. }
  1457. break;
  1458. }
  1459. }
  1460. else if (ew != NULL) ewevent(ew, &e, &closed);
  1461. else wfleep();
  1462. fixmenus();
  1463. }
  1464. }
  1465. void flush_screen(void)
  1466. {
  1467. TEXTEDIT* tp = CSL_ew->tp;
  1468. if (stdout_n != 0) {
  1469. /* fprintf(stderr, stdout_buffer); */
  1470. ewreplace(CSL_ew, stdout_buffer);
  1471. stdout_n = 0; stdout_p = stdout_buffer;
  1472. }
  1473. if (tp->nlines > max_nlines+5) { /* Allow a five line slop */
  1474. techangefocus(tp, 0, zsubgap(tp->start[tp->nlines-max_nlines]));
  1475. tp->aim= UNDEF;
  1476. tp->focprev= FALSE;
  1477. /* ewreplace(CSL_ew, ""); */
  1478. tereplace(tp, "");
  1479. /* fprintf(stderr, "-> %d\n", tp->nlines); */
  1480. /* focus to end */
  1481. tesetfocus(tp, tp->buflen - tp->gaplen, -1);
  1482. }
  1483. wupdate(CSL_window);
  1484. }
  1485. static clock_t prev_clock = 0;
  1486. void accept_tick(void)
  1487. {
  1488. clock_t t0 = clock();
  1489. #ifdef SOFTWARE_TICKS_PER_SECOND
  1490. software_tick_count++;
  1491. #endif
  1492. #ifdef SOFTWARE_TICKS_PER_SECOND
  1493. if (prev_clock != 0)
  1494. { double t1 = (double)(t0-prev_clock)/(double)CLOCKS_PER_SEC;
  1495. double ratio =
  1496. (double)(software_tick_count - prev_software_tick_count)/t1;
  1497. int32 w;
  1498. /*
  1499. * t1 is how long since I was last here, ratio is the number of
  1500. * ticks per second over that time-span.
  1501. */
  1502. ratio = ratio / (double)SOFTWARE_TICKS_PER_SECOND;
  1503. prev_software_tick_count = software_tick_count;
  1504. /*
  1505. * Now ratio is the extent by which I was taking ticks too fast.
  1506. * To dampen out my correction I will scale software_ticks by the
  1507. * square root of this.
  1508. */
  1509. ratio = sqrt(ratio);
  1510. w = (int)(1000.0 * ratio);
  1511. /*
  1512. * I clamp the correction fator so I never adjust my clock rate by
  1513. * a factor of more than (about) 3.
  1514. */
  1515. if (w > 3000) w = 3000;
  1516. else if (w < 300) w = 300;
  1517. /*
  1518. * Furthermore I attempt to keep software_ticks within integer range.
  1519. */
  1520. if (software_ticks < (0x7fffffff/3000) &&
  1521. software_ticks > 50)
  1522. software_ticks = (w*software_ticks)/1000;
  1523. }
  1524. #endif
  1525. /*
  1526. * This is where I can put things that need to be done regularly.
  1527. * This will need to involve prodding the window manager etc etc.
  1528. * At present I do NOTHING...
  1529. */
  1530. t0 = clock();
  1531. remove_ticker();
  1532. if (t0 > prev_clock + CLOCKS_PER_SEC) {
  1533. /*
  1534. * Time spent doing all of this is counted as "overhead" or "system time"
  1535. * and not included in the times that I will report to my users...
  1536. */
  1537. if (clock_stack == &consolidated_time[0]) {
  1538. consolidated_time[0] +=
  1539. ((double)(clock_t)(t0 - base_time))/((double)CLOCKS_PER_SEC);
  1540. base_time = clock();
  1541. }
  1542. report_time((int32)(100.0*consolidated_time[0]), (int32)(100.0*gc_time));
  1543. }
  1544. push_clock();
  1545. wupdate(CSL_window);
  1546. poll_for_attn();
  1547. polltick_pending = NO;
  1548. ensure_screen();
  1549. add_ticker();
  1550. pop_clock();
  1551. return;
  1552. }
  1553. static char time_string[32], space_string[32];
  1554. void report_time(int32 t, int32 gct)
  1555. {
  1556. sprintf(time_string, "%d.%.2d secs", t/100, t%100);
  1557. wmenusetitem(adminmenu, MMTime, time_string);
  1558. sprintf(time_string, "+ %d.%.2d secs", gct/100, gct%100);
  1559. wmenusetitem(adminmenu, MMOTime, time_string);
  1560. }
  1561. void report_space(int gc_count, double percent)
  1562. {
  1563. sprintf(space_string, "[GC %d]:%.2f%%", gc_count, percent);
  1564. wmenusetitem(adminmenu, MMSpace, space_string);
  1565. }
  1566. #ifndef HAVE_UNIVERSAL_HEADERS
  1567. #define ModalFilterUPP ProcPtr
  1568. #define NewModalFilterProc(x) ((ProcPtr)x)
  1569. #endif
  1570. extern pascal Boolean
  1571. filter_addnl(DialogPtr, EventRecord, short *);
  1572. void pause_for_user(void)
  1573. /*
  1574. * This is called at the end of a run so that the user gets a chance to read
  1575. * the final screen-full of output. It pops up a dialog box that will
  1576. * wait for a button push. I take the view that if output is going to a
  1577. * file then the delay is not needed, since the user can always check for
  1578. * messages there. This has the effect that non-interactive build sequences
  1579. * will often run without the pause - a good thing! Note however that this
  1580. * mean that you MUST use the close box to exit from a wimp session. Just
  1581. * "quit;" or "(stop 0)" will not do.
  1582. */
  1583. {
  1584. ModalFilterUPP filterupp = NewModalFilterProc(filter_addnl);
  1585. remove_ticker();
  1586. ensure_screen();
  1587. CSL_ew->saved = TRUE; /* Fake it */
  1588. if (spool_file != NULL) return;
  1589. /*
  1590. * Here I just loop handling events until the user hits the CLOSE box
  1591. * on my window.
  1592. */
  1593. /* wmessage("Leaving Reduce 3.7"); */
  1594. set_arrow();
  1595. Alert(128, filterupp);
  1596. ewclose(CSL_ew);
  1597. wdone();
  1598. }
  1599. int wimpget(char *tty_buffer)
  1600. /*
  1601. * This is the main call from the body of CSL into the window manager
  1602. * to obtain input from the user. It is expected to copy some input
  1603. * characters into tty_buffer and return the number of characters
  1604. * provided. In this implementation I read the text back from the
  1605. * stdwin textedit buffer, looking rather too low.
  1606. * Any type ahead is handled in here.
  1607. */
  1608. {
  1609. TEXTEDIT* tp = CSL_ew->tp;
  1610. int i;
  1611. int n;
  1612. int lineno;
  1613. tty_nnl = 1; /* Offset from nlines */
  1614. push_clock();
  1615. remove_ticker();
  1616. if (stdout_n != 0) flush_screen();
  1617. wmenuattach(CSL_window, loadmenu);
  1618. wmenuattach(CSL_window, libmenu);
  1619. wmenuattach(CSL_window, switchmenu);
  1620. lineno = tp->nlines-1; /* Need to do this after the toend */
  1621. tty_offset = tp->foc - tp->start[lineno];
  1622. if (tty_offset<0) tty_offset += tp->gaplen;
  1623. wmenuenable(adminmenu, MMPause, NO);
  1624. if(tty_index>0) {
  1625. int i = 0;
  1626. for (; i<tty_index; i++)
  1627. if (tty_buff[i] == '\n') tty_nnl++;
  1628. tty_buff[tty_index] = '\0';
  1629. ewreplace(CSL_ew, tty_buff);
  1630. tty_index = 0;
  1631. }
  1632. event_loop();
  1633. /* fprintf(stderr, "Event loop ended\n"); */
  1634. lineno = tp->nlines-tty_nnl;
  1635. /* fprintf(stderr, "Offset=%d Length=%d\n",
  1636. tty_offset,
  1637. tp->foc- tp->start[lineno]-tty_offset);
  1638. for (i=0; i<tp->foc- tp->start[lineno]-tty_offset; i++) {
  1639. fprintf(stderr, "%c", *(tegettext(tp)+tp->start[lineno]+tty_offset+i));
  1640. }
  1641. fprintf(stderr, "\n"); */
  1642. memcpy(tty_buffer, tegettext(tp)+tp->start[lineno]+tty_offset,
  1643. tp->foc- tp->start[lineno]-tty_offset);
  1644. wmenudetach(CSL_window, loadmenu);
  1645. wmenudetach(CSL_window, libmenu);
  1646. wmenudetach(CSL_window, switchmenu);
  1647. wmenuenable(adminmenu, MMPause, YES);
  1648. add_ticker();
  1649. n = tp->foc- tp->start[lineno]-tty_offset;
  1650. if (n<0) {
  1651. n += tp->gaplen;
  1652. fprintf(stderr, "N correction\n");
  1653. }
  1654. tty_ready = NO;
  1655. pop_clock();
  1656. return n;
  1657. }
  1658. int char_cnt = 0;
  1659. void putc_stdout(int c)
  1660. {
  1661. *stdout_p++ = c;
  1662. *stdout_p = 0;
  1663. stdout_n++;
  1664. char_cnt++;
  1665. remove_ticker();
  1666. if (c == '\n' || stdout_n > STDOUT_BUFSIZE - LONGEST_PRINTF) {
  1667. push_clock(); flush_screen();
  1668. if (char_cnt>200) { /* Where 200 is a random number */
  1669. poll_for_attn(); char_cnt = 0;
  1670. }
  1671. pop_clock();
  1672. }
  1673. if (polltick_pending) accept_tick();
  1674. add_ticker();
  1675. }
  1676. void vfprintf_stdout(char *fmt, va_list a)
  1677. {
  1678. int n;
  1679. /*
  1680. * I have given myself LONGEST_PRINTF locations in the array for
  1681. * this vsprintf to fill in. If it overflows I am in big trouble!
  1682. */
  1683. n = vsprintf(stdout_p, fmt, a);
  1684. stdout_p += n;
  1685. stdout_n += n;
  1686. char_cnt += n;
  1687. remove_ticker();
  1688. if (stdout_n > STDOUT_BUFSIZE - LONGEST_PRINTF) {
  1689. push_clock(); flush_screen();
  1690. if (char_cnt>200) {
  1691. poll_for_attn(); char_cnt = 0;
  1692. }
  1693. pop_clock();
  1694. }
  1695. if (polltick_pending) accept_tick();
  1696. add_ticker();
  1697. }
  1698. #define NARGS 25
  1699. static char *argv[NARGS+1];
  1700. static char argbuf[256];
  1701. /*
  1702. * init_command_line - prepare initial command line
  1703. *
  1704. * The command line is preset to show the name of the program.
  1705. * The program name is quoted as necessary.
  1706. *
  1707. */
  1708. static char*
  1709. init_command_line(char *buf1, char *buf2)
  1710. {
  1711. register char *s, *t = buf2;
  1712. int c, space = 0, dquote = 0, squote = 0, quote = 0;
  1713. sprintf(s = buf1, "%#s", LMGetCurApName());
  1714. while (c = *s++) {
  1715. if (c == ' ')
  1716. space = 1;
  1717. else if (c == '"')
  1718. dquote = 1;
  1719. else if (c == '\'')
  1720. squote = 1;
  1721. }
  1722. if (space || dquote || squote)
  1723. *t++ = quote = dquote && !squote ? '\'' : '"';
  1724. for (s = buf1; c = *s++; *t++ = c) {
  1725. if (c == quote || c == '\\')
  1726. *t++ = '\\';
  1727. }
  1728. if (quote)
  1729. *t++ = quote;
  1730. *t++ = ' ';
  1731. *t++ = 0;
  1732. return t;
  1733. }
  1734. /*
  1735. * parse - divide command line into "words"
  1736. *
  1737. * Words are delimited by one or more spaces. Any characters within
  1738. * matching single (') or double (") quotes are taken literally. Any
  1739. * character preceded by a backslash (\) is taken literally.
  1740. *
  1741. */
  1742. static int
  1743. parse(char *s, char *t)
  1744. {
  1745. int c, quote = 0, argc = 0;
  1746. while (c = *s++) {
  1747. if (c == ' ')
  1748. continue;
  1749. if (argc < NARGS)
  1750. argv[argc++] = t;
  1751. do {
  1752. if (c == '\\' && *s)
  1753. c = *s++;
  1754. else if (c == '"' || c == '\'') {
  1755. if (!quote) {
  1756. quote = c;
  1757. continue;
  1758. }
  1759. if (c == quote) {
  1760. quote = 0;
  1761. continue;
  1762. }
  1763. }
  1764. *t++ = c;
  1765. } while (*s && ((c = *s++) != ' ' || quote));
  1766. *t++ = 0;
  1767. }
  1768. return(argc);
  1769. }
  1770. #ifdef OLD
  1771. int wgetargs(char ***av)
  1772. {
  1773. short i, argc;
  1774. char buf[256];
  1775. char *t = init_command_line(buf, argbuf);
  1776. if( !waskstr(" Arguments for REDUCE 3.7", t, 256)) exit(1);
  1777. t[-1] = ' ';
  1778. sprintf(buf, "%s", argbuf);
  1779. argc = parse(buf, argbuf);
  1780. *av = argv;
  1781. /* for(i=0;i<argc; i++) wmessage(argv[i]); */
  1782. return(argc);
  1783. }
  1784. #else
  1785. enum { /* Dialog names for main box */
  1786. exDEF = 3,
  1787. exLOG,
  1788. exVER,
  1789. exXTA
  1790. };
  1791. enum { /* Dialog names for additional box */
  1792. exBAT = 3,
  1793. exBAC,
  1794. exTRA,
  1795. exCLD,
  1796. exLAP,
  1797. exQUI,
  1798. exREC,
  1799. exRED,
  1800. exRAN,
  1801. exSIZ,
  1802. exOTH,
  1803. exLGG,
  1804. exDFF,
  1805. exVBE
  1806. };
  1807. /*
  1808. * get_args - process "command line"
  1809. *
  1810. */
  1811. /* Dialog numbers */
  1812. #define START_1 (129)
  1813. #define START_2 (128)
  1814. /*Rect bounds = {60, 20, 320, 220};
  1815. Rect boundx = {80, 30, 400, 500};
  1816. */
  1817. int DoExtra(char ***av)
  1818. {
  1819. DialogPtr ee;
  1820. short i;
  1821. int verbos = 0;
  1822. int deflt = 0;
  1823. int logging = 0;
  1824. char buff[256];
  1825. char name[256];
  1826. char nams[256];
  1827. Rect box;
  1828. short type;
  1829. Handle item;
  1830. char *t = init_command_line(buff, argbuf);
  1831. char *s = t-1;
  1832. int argc;
  1833. ModalFilterUPP filterupp = NewModalFilterProc(filter_addnl);
  1834. int batch =0, back = 0, cold = 0, lap = 0, quiet = 0;
  1835. int trap = 0, recover = 0, redirect = 0;
  1836. /* ee = NewDialog(NULL, &boundx, "\p", 1, 1, (WindowPtr)-1, 0, 256L,
  1837. GetResource('DITL',132)); */
  1838. ee = GetNewDialog(START_2, NULL, (WindowPtr)-1);
  1839. GetDItem(ee, 1, &type, &item, &box);
  1840. SetPort(ee);
  1841. InsetRect(&box, -4, -4);
  1842. PenSize(3, 3);
  1843. FrameRoundRect(&box, 16, 16);
  1844. set_arrow();
  1845. do { /* engage in dialog */
  1846. ModalDialog(filterupp, &i);
  1847. switch (i) {
  1848. case cancel:
  1849. DisposDialog(ee);
  1850. exit(0);
  1851. case exBAT:
  1852. batch = !batch;
  1853. break;
  1854. case exBAC:
  1855. back = !back;
  1856. break;
  1857. case exTRA:
  1858. trap = !trap;
  1859. break;
  1860. case exCLD:
  1861. cold = !cold;
  1862. break;
  1863. case exLAP:
  1864. lap = !lap;
  1865. break;
  1866. case exQUI:
  1867. quiet = !quiet;
  1868. break;
  1869. case exREC:
  1870. recover = !recover;
  1871. break;
  1872. case exRED:
  1873. redirect = waskfile("Redirection File: ", nams, 256, 1);
  1874. break;
  1875. case exLGG:
  1876. logging = waskfile("Log File: ", name, 256, 1);
  1877. break;
  1878. case exDFF:
  1879. deflt = !deflt;
  1880. break;
  1881. case exVBE:
  1882. verbos = !verbos;
  1883. break;
  1884. }
  1885. } while (i != ok);
  1886. if (batch) { strcpy(t, " -b"); t += 3; }
  1887. if (back) { strcpy(t, " -g"); t += 3; }
  1888. if (cold) { strcpy(t, " -z"); t += 3; }
  1889. if (lap) { strcpy(t, " -s"); t += 3; }
  1890. if (quiet) { strcpy(t, " -q"); t += 3; }
  1891. if (recover) { strcpy(t, " -y"); t += 3; }
  1892. if (trap) { strcpy(t, " -x"); t += 3; }
  1893. if (verbos) { strcpy(t, " -v"); t += 3; }
  1894. if (logging) { strcpy(t, " -l"); t += 3;
  1895. strcpy(t, name); t += strlen(name);
  1896. }
  1897. if (redirect) { strcpy(t, " --"); t += 3;
  1898. strcpy(t, nams); t += strlen(nams);
  1899. }
  1900. {
  1901. char bb[256];
  1902. GetDItem(ee, exRAN, &type, &item, &box);
  1903. GetIText(item, (unsigned char *)bb);
  1904. #ifndef CLEVERGLUE
  1905. P2CStr((unsigned char *)bb);
  1906. #endif
  1907. if (bb[0]!='\0') {
  1908. strcpy(t, " -r"); t += 3;
  1909. strcpy(t, bb); t += strlen(bb);
  1910. }
  1911. GetDItem(ee, exSIZ, &type, &item, &box);
  1912. GetIText(item, (unsigned char *)bb);
  1913. #ifndef CLEVERGLUE
  1914. P2CStr((unsigned char *)bb);
  1915. #endif
  1916. if (bb[0]!='\0') {
  1917. strcpy(t, " -k"); t += 3;
  1918. strcpy(t, bb); t += strlen(bb);
  1919. }
  1920. GetDItem(ee, exOTH, &type, &item, &box);
  1921. GetIText(item, (unsigned char *)bb);
  1922. #ifndef CLEVERGLUE
  1923. P2CStr((unsigned char *)bb);
  1924. #endif
  1925. if (bb[0]!='\0') {
  1926. strcpy(t, bb); t += strlen(bb);
  1927. }
  1928. }
  1929. out:
  1930. DisposDialog(ee);
  1931. if (!deflt) *s = ' ';
  1932. sprintf(buff, "%s", argbuf);
  1933. argc = parse(buff, argbuf);
  1934. *av = argv;
  1935. /* for(i=0;i<argc; i++) wmessage(argv[i]); */
  1936. return(argc);
  1937. }
  1938. int wgetargs(char ***av)
  1939. {
  1940. DialogPtr dd;
  1941. short i;
  1942. int verbos = 0;
  1943. int deflt = 0;
  1944. int logging = 0;
  1945. char buff[256];
  1946. char name[256];
  1947. char nams[256];
  1948. int p = 0;
  1949. Rect box;
  1950. short type;
  1951. Handle item;
  1952. char *t = init_command_line(buff, argbuf);
  1953. char *s = t-1;
  1954. int argc;
  1955. ModalFilterUPP filterupp = NewModalFilterProc(filter_addnl);
  1956. /* dd = NewDialog(NULL, &bounds, "\p", 1, 1, (WindowPtr)-1, 0, 256L,
  1957. GetResource('DITL',131)); */
  1958. dd = GetNewDialog(START_1, NULL, (WindowPtr)-1);
  1959. GetDItem(dd, 1, &type, &item, &box);
  1960. SetPort(dd);
  1961. InsetRect(&box, -4, -4);
  1962. PenSize(3, 3);
  1963. FrameRoundRect(&box, 16, 16);
  1964. set_arrow();
  1965. do { /* engage in dialog */
  1966. ModalDialog(filterupp, &i);
  1967. switch (i) {
  1968. case cancel:
  1969. DisposDialog(dd);
  1970. exit(0);
  1971. case exDEF:
  1972. deflt = !deflt;
  1973. break;
  1974. case exVER:
  1975. verbos = !verbos;
  1976. break;
  1977. case exLOG:
  1978. logging = waskfile("Log File: ", name, 256, 1);
  1979. break;
  1980. case exXTA:
  1981. set_watch();
  1982. DisposDialog(dd);
  1983. return DoExtra(av);
  1984. }
  1985. } while (i != ok);
  1986. set_watch();
  1987. {
  1988. char aa[256];
  1989. if (verbos) {
  1990. strcpy(t, " -v");
  1991. t += 3; }
  1992. if (logging) {
  1993. strcpy(t, " -l"); t += 3;
  1994. strcpy(t, name); p += strlen(aa);
  1995. }
  1996. }
  1997. if (!deflt) *s = ' ';
  1998. DisposDialog(dd);
  1999. sprintf(buff, "%s", argbuf);
  2000. argc = parse(buff, argbuf);
  2001. *av = argv;
  2002. /* for(i=0;i<argc; i++) wmessage(argv[i]); */
  2003. return(argc);
  2004. }
  2005. #endif
  2006. /* end of sysmac.c */