PageRenderTime 51ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 1ms

/ATF2/control-software/epics-3.14.10/extensions/src/edm/lib/utility.cc

http://atf2flightsim.googlecode.com/
C++ | 3629 lines | 2627 code | 919 blank | 83 comment | 665 complexity | 8e08f9bfd7309f7b0e9709e4193907f0 MD5 | raw file
Possible License(s): BSD-2-Clause, LGPL-2.0, IPL-1.0, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. // edm - extensible display manager
  2. // Copyright (C) 1999 John W. Sinclair
  3. // This program is free software; you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation; either version 2 of the License, or
  6. // (at your option) any later version.
  7. // This program is distributed in the hope that it will be useful,
  8. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. // GNU General Public License for more details.
  11. // You should have received a copy of the GNU General Public License
  12. // along with this program; if not, write to the Free Software
  13. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. // utility functions
  15. #include "utility.h"
  16. #include "environment.str"
  17. static int g_serverSocketFd = -1;
  18. int debugMode ( void ) {
  19. int val;
  20. char *envPtr;
  21. envPtr = getenv( "EDMDEBUGMODE" );
  22. if ( envPtr ) {
  23. val = atol(envPtr);
  24. if ( !val ) val = 1; // if value is non-numeric make it 1
  25. return val;
  26. }
  27. else {
  28. return 0;
  29. }
  30. }
  31. static int g_needDiagModeInit = 1;
  32. static int g_diagMode = 0;
  33. int diagnosticMode ( void ) {
  34. int val;
  35. char *envPtr;
  36. if ( g_needDiagModeInit ) {
  37. g_needDiagModeInit = 0;
  38. envPtr = getenv( "EDMDIAGNOSTICMODE" );
  39. if ( envPtr ) {
  40. g_diagMode = atol(envPtr);
  41. if ( !g_diagMode ) val = 1; // if value is non-numeric make it 1
  42. }
  43. else {
  44. g_diagMode = 0;
  45. }
  46. }
  47. return g_diagMode;
  48. }
  49. static int g_needDiagInit = 1;
  50. static char g_diagFileName[255+1];
  51. int logDiagnostic (
  52. char *text
  53. ) {
  54. char *envPtr;
  55. char time_string[34+1];
  56. static FILE *diagFile = NULL;
  57. static pid_t procPid;
  58. static char hostName[63+1], buf[255+1];
  59. int i, ii, l, fd;
  60. mode_t curMode;
  61. if ( g_needDiagInit ) {
  62. g_needDiagInit = 0;
  63. procPid = getpid();
  64. gethostname( hostName, 63 );
  65. sys_get_datetime_string( 31, time_string );
  66. time_string[31] = 0;
  67. Strncat( time_string, " : ", 34 );
  68. envPtr = getenv( environment_str8 );
  69. if ( envPtr ) {
  70. strncpy( g_diagFileName, envPtr, 255 );
  71. if ( envPtr[strlen(envPtr)] != '/' ) {
  72. Strncat( g_diagFileName, "/", 255 );
  73. }
  74. }
  75. else {
  76. strncpy( g_diagFileName, "/tmp/", 255 );
  77. }
  78. Strncat( g_diagFileName, "edmStdErr", 255 );
  79. Strncat( g_diagFileName, "_XXXXXX", 255 );
  80. mkstemp( g_diagFileName );
  81. l = strlen( g_diagFileName );
  82. for ( i=l-7, ii=0; i<l; i++, ii++ ) {
  83. buf[ii] = g_diagFileName[i];
  84. }
  85. buf[ii] = 0;
  86. close( 2 );
  87. curMode = umask( 0 );
  88. fd = open( g_diagFileName, O_CREAT|O_WRONLY );
  89. umask( curMode );
  90. fprintf( stderr, time_string );
  91. fprintf( stderr, "host %s, pid %-d - ", hostName, procPid );
  92. fprintf( stderr, "first diagnostic message\n" );
  93. fprintf( stderr, time_string );
  94. fprintf( stderr, text );
  95. envPtr = getenv( environment_str8 );
  96. if ( envPtr ) {
  97. strncpy( g_diagFileName, envPtr, 255 );
  98. if ( envPtr[strlen(envPtr)] != '/' ) {
  99. Strncat( g_diagFileName, "/", 255 );
  100. }
  101. }
  102. else {
  103. strncpy( g_diagFileName, "/tmp/", 255 );
  104. }
  105. Strncat( g_diagFileName, "edmDiag", 255 );
  106. Strncat( g_diagFileName, buf, 255 );
  107. curMode = umask( 0 );
  108. diagFile = fopen( g_diagFileName, "a" );
  109. umask( curMode );
  110. if ( diagFile ) {
  111. fprintf( diagFile, time_string );
  112. fprintf( diagFile, "host %s, pid %-d - ", hostName, procPid );
  113. fprintf( diagFile, "first diagnostic message\n" );
  114. fprintf( diagFile, time_string );
  115. fprintf( diagFile, text );
  116. }
  117. else {
  118. return 2;
  119. }
  120. }
  121. else {
  122. curMode = umask( 0 );
  123. diagFile = fopen( g_diagFileName, "a" );
  124. umask( curMode );
  125. if ( diagFile ) {
  126. sys_get_datetime_string( 31, time_string );
  127. time_string[31] = 0;
  128. Strncat( time_string, " : ", 34 );
  129. fprintf( diagFile, time_string );
  130. fprintf( diagFile, text );
  131. }
  132. else {
  133. return 2;
  134. }
  135. }
  136. fclose( diagFile );
  137. return 1;
  138. }
  139. char *getEnvironmentVar (
  140. char *name
  141. ) {
  142. FILE *f;
  143. char *tk, *context, buf[32000+1];
  144. static char *var = NULL;
  145. if ( !getenv(name) ) return NULL;
  146. strncpy( buf, getenv(name), 255 );
  147. buf[255] = 0;
  148. //fprintf( stderr, "name = [%s]\n", buf );
  149. context = NULL;
  150. tk = strtok_r( buf, " \t\n", &context );
  151. if ( !tk ) return NULL;
  152. if ( tk[0] != '@' ) return getenv( name );
  153. // else name translates to file from which values are read
  154. strncpy( buf, getenv(name), 255 );
  155. buf[255] = 0;
  156. context = NULL;
  157. tk = strtok_r( buf, "@ \t\n", &context );
  158. if ( !tk ) return NULL;
  159. //fprintf( stderr, "read env var values from file: [%s]\n", tk );
  160. f = fileOpen( tk, "r" );
  161. tk = fgets( buf, 32000, f );
  162. buf[32000] = 0;
  163. if ( !tk ) {
  164. fclose( f );
  165. return NULL;
  166. }
  167. context = NULL;
  168. tk = strtok_r( buf, "\n", &context );
  169. if ( !tk ) return NULL;
  170. if ( var ) delete var;
  171. var = new char[strlen(tk)+1];
  172. strcpy( var, tk );
  173. return var;
  174. }
  175. void setServerSocketFd (
  176. int fd
  177. ) {
  178. g_serverSocketFd = fd;
  179. }
  180. // From Stevens' book
  181. #ifdef OPEN_MAX
  182. static int g_openMax = OPEN_MAX;
  183. #else
  184. static int g_openMax = 0;
  185. #endif
  186. #define OPEN_MAX_GUESS 256
  187. static int open_max ( void ) {
  188. if ( !g_openMax ) {
  189. errno = 0;
  190. if ( ( g_openMax = sysconf( _SC_OPEN_MAX ) ) < 0 ) {
  191. g_openMax = OPEN_MAX_GUESS;
  192. }
  193. }
  194. return g_openMax;
  195. }
  196. // From Stevens' book
  197. int executeCmd (
  198. const char *cmdString
  199. ) {
  200. pid_t pid;
  201. int status, i, l;
  202. struct sigaction ignore, saveintr, savequit;
  203. sigset_t chldmask, savemask;
  204. char buf[2048+1];
  205. if ( !cmdString ) return 1;
  206. l = strlen( cmdString);
  207. if ( l > 2048 ) return 1;
  208. strcpy( buf, cmdString );
  209. ignore.sa_handler = SIG_IGN;
  210. sigemptyset( &ignore.sa_mask );
  211. ignore.sa_flags = 0;
  212. if ( sigaction( SIGINT, &ignore, &saveintr ) < 0 ) return -1;
  213. if ( sigaction( SIGQUIT, &ignore, &savequit ) < 0 ) return -1;
  214. sigemptyset( &chldmask );
  215. sigaddset( &chldmask, SIGCHLD );
  216. if ( sigprocmask( SIG_BLOCK, &chldmask, &savemask ) < 0 ) return -1;
  217. if ( ( pid = fork() ) < 0 ) {
  218. status = -1;
  219. }
  220. else if ( pid == 0 ) { // child
  221. // restore previous signal actions & reset signal mask
  222. sigaction( SIGINT, &saveintr, NULL );
  223. sigaction( SIGQUIT, &savequit, NULL );
  224. sigprocmask( SIG_SETMASK, &savemask, NULL );
  225. if ( g_serverSocketFd != -1 ) {
  226. close( g_serverSocketFd );
  227. }
  228. // close all open files
  229. for ( i=3; i<open_max(); i++ ) {
  230. close( i );
  231. }
  232. // create new process group session
  233. setsid();
  234. execl( "/bin/sh", "sh", "-c", buf, (char *) NULL );
  235. _exit(127);
  236. }
  237. else { // parent
  238. while ( waitpid( pid, &status, 0 ) < 0 ) {
  239. if ( errno != EINTR ) {
  240. status = -1;
  241. break;
  242. }
  243. }
  244. }
  245. // restore previous signal actions & reset signal mask
  246. if ( sigaction( SIGINT, &saveintr, NULL ) < 0 ) return -1;
  247. if ( sigaction( SIGQUIT, &savequit, NULL ) < 0 ) return -1;
  248. if ( sigprocmask( SIG_SETMASK, &savemask, NULL ) < 0 ) return -1;
  249. return status;
  250. }
  251. #ifdef __linux__
  252. static void *executeCmdThread (
  253. THREAD_HANDLE h )
  254. {
  255. #endif
  256. #ifdef darwin
  257. static void *executeCmdThread (
  258. THREAD_HANDLE h )
  259. {
  260. #endif
  261. #ifdef __solaris__
  262. static void *executeCmdThread (
  263. THREAD_HANDLE h )
  264. {
  265. #endif
  266. #ifdef __osf__
  267. static void executeCmdThread (
  268. THREAD_HANDLE h )
  269. {
  270. #endif
  271. #ifdef HP_UX
  272. static void *executeCmdThread (
  273. THREAD_HANDLE h )
  274. {
  275. #endif
  276. int stat;
  277. char *cmd = (char *) thread_get_app_data( h );
  278. stat = executeCmd( cmd );
  279. stat = thread_request_free_ptr( (void *) cmd );
  280. stat = thread_detached_exit( h, NULL ); // this call deallocates h
  281. #ifdef __linux__
  282. return (void *) NULL;
  283. #endif
  284. #ifdef darwin
  285. return (void *) NULL;
  286. #endif
  287. #ifdef __solaris__
  288. return (void *) NULL;
  289. #endif
  290. }
  291. void executeCommandInThread (
  292. char *_cmd
  293. ) {
  294. char *cmd;
  295. THREAD_HANDLE thread;
  296. int stat;
  297. if ( !_cmd ) return;
  298. if ( blankOrComment(_cmd) ) return;
  299. cmd = new char[strlen(_cmd)+1];
  300. strcpy( cmd, _cmd );
  301. stat = thread_create_handle( &thread, (void *) cmd );
  302. stat = thread_create_proc( thread, executeCmdThread );
  303. stat = thread_detach( thread );
  304. }
  305. char *expandEnvVars (
  306. char *inStr,
  307. int maxOut,
  308. char *outStr
  309. ) {
  310. // expands all environment vars of the form $(envVar) found in inStr
  311. // and sends the expanded string to outStr
  312. int i, ii, iii, inL, state, bufOnHeap;
  313. char *ptr, stackBuf[255+1];
  314. char *buf;
  315. static const int DONE = -1;
  316. static const int FINDING_DOLLAR = 1;
  317. static const int FINDING_LEFT_PAREN = 2;
  318. static const int FINDING_RIGHT_PAREN = 3;
  319. if ( !inStr || !outStr || ( maxOut < 1 ) ) return NULL;
  320. inL = strlen( inStr );
  321. if ( inL < 1 ) return NULL;
  322. if ( maxOut > 255 ) {
  323. buf = new char[maxOut+1];
  324. bufOnHeap = 1;
  325. }
  326. else {
  327. buf = stackBuf;
  328. bufOnHeap = 0;
  329. }
  330. state = FINDING_DOLLAR;
  331. strcpy( outStr, "" );
  332. i = ii = 0;
  333. while ( state != DONE ) {
  334. switch ( state ) {
  335. case FINDING_DOLLAR:
  336. if ( i >= inL ) {
  337. state = DONE;
  338. break;
  339. }
  340. if ( inStr[i] == '\n' ) {
  341. state = DONE;
  342. }
  343. else if ( inStr[i] == '$' ) {
  344. state = FINDING_LEFT_PAREN;
  345. }
  346. else {
  347. if ( ii >= maxOut ) goto limitErr; // out string too big
  348. outStr[ii] = inStr[i];
  349. ii++;
  350. }
  351. break;
  352. case FINDING_LEFT_PAREN:
  353. if ( i >= inL ) goto syntaxErr; // never found '(' after '$'
  354. if ( inStr[i] == '\n' ) goto syntaxErr; // never found '(' after '$'
  355. if ( inStr[i] != '(' ) goto syntaxErr; // char after '$' was not '('
  356. strcpy( buf, "" );
  357. iii = 0;
  358. state = FINDING_RIGHT_PAREN;
  359. break;
  360. case FINDING_RIGHT_PAREN:
  361. if ( i >= inL ) goto syntaxErr; // never found ')'
  362. if ( inStr[i] == '\n' ) goto syntaxErr; // never found ')'
  363. if ( inStr[i] == ')' ) {
  364. // add terminating 0
  365. if ( iii >= maxOut ) goto syntaxErr; // env var value too big
  366. buf[iii] = 0;
  367. // translate and output env var value using buf
  368. if ( !blank( buf ) ) {
  369. ptr = getenv( buf );
  370. if ( ptr ) {
  371. for ( iii=0; iii<(int) strlen(ptr); iii++ ) {
  372. if ( ii > maxOut ) goto limitErr;
  373. outStr[ii] = ptr[iii];
  374. ii++;
  375. }
  376. }
  377. }
  378. state = FINDING_DOLLAR;
  379. }
  380. else {
  381. if ( iii >= maxOut ) goto syntaxErr; // env var value too big
  382. buf[iii] = inStr[i];
  383. iii++;
  384. }
  385. break;
  386. }
  387. i++;
  388. }
  389. // normalReturn
  390. // add terminating 0
  391. if ( ii > maxOut ) goto limitErr;
  392. outStr[ii] = 0;
  393. if ( bufOnHeap ) delete [] buf;
  394. return outStr;
  395. syntaxErr:
  396. fprintf( stderr, "Syntax error in env var reference\n" );
  397. if ( bufOnHeap ) delete [] buf;
  398. return NULL;
  399. limitErr:
  400. fprintf( stderr, "Parameter size limit exceeded in env var reference\n" );
  401. if ( bufOnHeap ) delete [] buf;
  402. return NULL;
  403. }
  404. int blank (
  405. char *string )
  406. {
  407. unsigned int i, l;
  408. l = strlen(string);
  409. if ( !l ) return 1;
  410. for ( i=0; i<l; i++ ) {
  411. if ( !isspace( (int) string[i] ) ) return 0;
  412. }
  413. return 1;
  414. }
  415. int blankOrComment (
  416. char *string )
  417. {
  418. // return 1 for blank string or if first char is comment character
  419. unsigned int i, l;
  420. l = strlen(string);
  421. if ( !l ) return 1;
  422. for ( i=0; i<l; i++ ) {
  423. if ( !isspace( (int) string[i] ) ) {
  424. if ( string[i] == '#' ) return 1;
  425. return 0;
  426. }
  427. }
  428. return 1;
  429. }
  430. XtIntervalId appAddTimeOut (
  431. XtAppContext app,
  432. unsigned long interval,
  433. XtTimerCallbackProc proc,
  434. XtPointer client_data )
  435. {
  436. if ( interval < 10 ) {
  437. interval = 10; // ms
  438. }
  439. return XtAppAddTimeOut( app, interval, proc, client_data );
  440. }
  441. void genericProcessAllEvents (
  442. int sync,
  443. XtAppContext app,
  444. Display *d )
  445. {
  446. XEvent Xev;
  447. int result, isXEvent, count;
  448. count = 1000;
  449. if ( sync ) {
  450. XFlush( d );
  451. XSync( d, False ); /* wait for all X transactions to complete */
  452. }
  453. do {
  454. result = XtAppPending( app );
  455. if ( result ) {
  456. isXEvent = XtAppPeekEvent( app, &Xev );
  457. if ( isXEvent ) {
  458. if ( Xev.type != Expose ) {
  459. XtAppProcessEvent( app, result );
  460. }
  461. else {
  462. // XtAppNextEvent( app, &Xev ); // discard
  463. XtAppProcessEvent( app, result );
  464. }
  465. }
  466. else { // process all timer or alternate events
  467. XtAppProcessEvent( app, result );
  468. }
  469. }
  470. count--;
  471. } while ( result && count );
  472. }
  473. void processAllEventsWithSync (
  474. XtAppContext app,
  475. Display *d )
  476. {
  477. genericProcessAllEvents( 1, app, d );
  478. }
  479. void processAllEvents (
  480. XtAppContext app,
  481. Display *d )
  482. {
  483. genericProcessAllEvents( 0, app, d );
  484. }
  485. static void trimWhiteSpace (
  486. char *str )
  487. {
  488. char buf[127+1];
  489. int first, last, i, ii, l;
  490. l = strlen(str);
  491. if ( l > 126 ) l = 126;
  492. ii = 0;
  493. i = 0;
  494. while ( ( i < l ) && isspace( str[i] ) ) {
  495. i++;
  496. }
  497. first = i;
  498. i = l-1;
  499. while ( ( i >= first ) && isspace( str[i] ) ) {
  500. i--;
  501. }
  502. last = i;
  503. for ( i=first; i<=last; i++ ) {
  504. buf[ii] = str[i];
  505. ii++;
  506. }
  507. buf[ii] = 0;
  508. strcpy( str, buf );
  509. }
  510. #define DONE -1
  511. #define SIGN_OR_NUM 1
  512. #define NUM 2
  513. #define SIGN_OR_NUM2 3
  514. #define NUM1 4
  515. #define SIGN_OR_POINT_OR_NUM 5
  516. #define POINT_OR_NUM 6
  517. #define EXP_OR_POINT_OR_NUM 7
  518. #define EXP_OR_NUM 8
  519. #define NUM2 9
  520. int isLegalInteger (
  521. char *str )
  522. {
  523. char buf[127+1];
  524. int i, l, legal, state, hex;
  525. strncpy( buf, str, 127 );
  526. trimWhiteSpace( buf );
  527. l = strlen(buf);
  528. if ( l < 1 ) return 0;
  529. hex = 0;
  530. i = 0;
  531. if ( l > 2 ) {
  532. if ( ( buf[0] == '0' ) && ( ( buf[1] == 'x' ) || ( buf[1] == 'X' ) ) ) {
  533. hex = 1;
  534. i = 2;
  535. }
  536. }
  537. state = SIGN_OR_NUM;
  538. legal = 1;
  539. while ( state != DONE ) {
  540. if ( i >= l ) state = DONE;
  541. switch ( state ) {
  542. case SIGN_OR_NUM:
  543. if ( buf[i] == '-' ) {
  544. i++;
  545. state = NUM;
  546. continue;
  547. }
  548. if ( buf[i] == '+' ) {
  549. i++;
  550. state = NUM;
  551. continue;
  552. }
  553. if ( hex ) {
  554. if ( isxdigit(buf[i]) ) {
  555. i++;
  556. state = NUM;
  557. continue;
  558. }
  559. }
  560. else {
  561. if ( isdigit(buf[i]) ) {
  562. i++;
  563. state = NUM;
  564. continue;
  565. }
  566. }
  567. legal = 0;
  568. state = DONE;
  569. break;
  570. case NUM:
  571. if ( hex ) {
  572. if ( isxdigit(buf[i]) ) {
  573. i++;
  574. continue;
  575. }
  576. }
  577. else {
  578. if ( isdigit(buf[i]) ) {
  579. i++;
  580. continue;
  581. }
  582. }
  583. legal = 0;
  584. state = DONE;
  585. break;
  586. }
  587. }
  588. return legal;
  589. }
  590. int isLegalFloat (
  591. char *str )
  592. {
  593. char buf[127+1];
  594. int i, l, legal, state;
  595. strncpy( buf, str, 127 );
  596. trimWhiteSpace( buf );
  597. l = strlen(buf);
  598. if ( l < 1 ) return 0;
  599. state = SIGN_OR_POINT_OR_NUM;
  600. i = 0;
  601. legal = 1;
  602. while ( state != DONE ) {
  603. if ( i >= l ) state = DONE;
  604. switch ( state ) {
  605. case SIGN_OR_POINT_OR_NUM:
  606. if ( buf[i] == '-' ) {
  607. i++;
  608. state = POINT_OR_NUM;
  609. continue;
  610. }
  611. if ( buf[i] == '+' ) {
  612. i++;
  613. state = POINT_OR_NUM;
  614. continue;
  615. }
  616. if ( buf[i] == '.' ) {
  617. i++;
  618. state = NUM1;
  619. continue;
  620. }
  621. if ( isdigit(buf[i]) ) {
  622. i++;
  623. state = EXP_OR_POINT_OR_NUM;
  624. continue;
  625. }
  626. legal = 0;
  627. state = DONE;
  628. break;
  629. case NUM1:
  630. if ( isdigit(buf[i]) ) {
  631. i++;
  632. state = EXP_OR_NUM;
  633. continue;
  634. }
  635. legal = 0;
  636. state = DONE;
  637. break;
  638. case EXP_OR_POINT_OR_NUM:
  639. if ( buf[i] == 'E' ) {
  640. i++;
  641. state = SIGN_OR_NUM2;
  642. continue;
  643. }
  644. if ( buf[i] == 'e' ) {
  645. i++;
  646. state = SIGN_OR_NUM2;
  647. continue;
  648. }
  649. if ( buf[i] == '.' ) {
  650. i++;
  651. state = EXP_OR_NUM;
  652. continue;
  653. }
  654. if ( isdigit(buf[i]) ) {
  655. i++;
  656. continue;
  657. }
  658. legal = 0;
  659. state = DONE;
  660. break;
  661. case POINT_OR_NUM:
  662. if ( buf[i] == '.' ) {
  663. i++;
  664. state = EXP_OR_NUM;
  665. continue;
  666. }
  667. if ( isdigit(buf[i]) ) {
  668. i++;
  669. state = EXP_OR_POINT_OR_NUM;
  670. continue;
  671. }
  672. legal = 0;
  673. state = DONE;
  674. break;
  675. case EXP_OR_NUM:
  676. if ( buf[i] == 'E' ) {
  677. i++;
  678. state = SIGN_OR_NUM2;
  679. continue;
  680. }
  681. if ( buf[i] == 'e' ) {
  682. i++;
  683. state = SIGN_OR_NUM2;
  684. continue;
  685. }
  686. if ( isdigit(buf[i]) ) {
  687. i++;
  688. continue;
  689. }
  690. legal = 0;
  691. state = DONE;
  692. break;
  693. case SIGN_OR_NUM2:
  694. if ( buf[i] == '-' ) {
  695. i++;
  696. state = NUM2;
  697. continue;
  698. }
  699. if ( buf[i] == '+' ) {
  700. i++;
  701. state = NUM2;
  702. continue;
  703. }
  704. if ( isdigit(buf[i]) ) {
  705. i++;
  706. state = NUM2;
  707. continue;
  708. }
  709. legal = 0;
  710. state = DONE;
  711. break;
  712. case NUM2:
  713. if ( isdigit(buf[i]) ) {
  714. i++;
  715. continue;
  716. }
  717. legal = 0;
  718. state = DONE;
  719. break;
  720. }
  721. }
  722. return legal;
  723. }
  724. int writeStringToFile (
  725. FILE *f,
  726. char *str )
  727. {
  728. int stat, i, j;
  729. char tmp[255+1];
  730. if ( strcmp( str, "" ) == 0 ) {
  731. stat = fprintf( f, "<<<empty>>>\n" );
  732. if ( stat == -1 ) return 0;
  733. }
  734. else if ( blank(str) ) {
  735. {
  736. char buf[300+1];
  737. strcpy( buf, "<<<blank>>>" );
  738. Strncat( buf, str, 300 );
  739. for ( i=0, j=0; i<(int)strlen(buf); i++ ) {
  740. if ( buf[i] == 10 ) {
  741. tmp[j] = 0;
  742. stat = fprintf( f, "%s\\n", tmp );
  743. if ( stat == -1 ) return 0;
  744. j = 0;
  745. }
  746. else if ( buf[i] == '\\' ) {
  747. tmp[j] = 0;
  748. stat = fprintf( f, "%s\\\\", tmp );
  749. if ( stat == -1 ) return 0;
  750. j = 0;
  751. }
  752. else {
  753. tmp[j] = buf[i];
  754. j++;
  755. if ( j == 255 ) {
  756. tmp[j] = 0;
  757. stat = fprintf( f, "%s", tmp );
  758. if ( stat == -1 ) return 0;
  759. j = 0;
  760. }
  761. }
  762. }
  763. if ( j ) {
  764. tmp[j] = 0;
  765. stat = fprintf( f, "%s\n", tmp );
  766. if ( stat == -1 ) return 0;
  767. j = 0;
  768. }
  769. else {
  770. stat = fprintf( f, "\n" );
  771. if ( stat == -1 ) return 0;
  772. }
  773. }
  774. }
  775. else {
  776. for ( i=0, j=0; i<(int)strlen(str); i++ ) {
  777. if ( str[i] == 10 ) {
  778. tmp[j] = 0;
  779. stat = fprintf( f, "%s\\n", tmp );
  780. if ( stat == -1 ) return 0;
  781. j = 0;
  782. }
  783. else if ( str[i] == '\\' ) {
  784. tmp[j] = 0;
  785. stat = fprintf( f, "%s\\\\", tmp );
  786. if ( stat == -1 ) return 0;
  787. j = 0;
  788. }
  789. else {
  790. tmp[j] = str[i];
  791. j++;
  792. if ( j == 255 ) {
  793. tmp[j] = 0;
  794. stat = fprintf( f, "%s", tmp );
  795. if ( stat == -1 ) return 0;
  796. j = 0;
  797. }
  798. }
  799. }
  800. if ( j ) {
  801. tmp[j] = 0;
  802. stat = fprintf( f, "%s\n", tmp );
  803. if ( stat == -1 ) return 0;
  804. j = 0;
  805. }
  806. else {
  807. stat = fprintf( f, "\n" );
  808. if ( stat == -1 ) return 0;
  809. }
  810. }
  811. return 1;
  812. }
  813. #if 0
  814. void readStringFromFile (
  815. char *str,
  816. int maxChars,
  817. FILE *f )
  818. {
  819. char *ptr;
  820. int i, l;
  821. unsigned int ii;
  822. ptr = fgets( str, maxChars, f );
  823. if ( !ptr ) {
  824. strcpy( str, "" );
  825. return;
  826. }
  827. l = strlen(str);
  828. if ( l > maxChars ) l = maxChars;
  829. if ( l < 1 ) l = 1;
  830. str[l-1] = 0;
  831. if ( strcmp( str, "<<<empty>>>" ) == 0 ) {
  832. strcpy( str, "" );
  833. }
  834. else if ( strncmp( str, "<<<blank>>>", 11 ) == 0 ) {
  835. {
  836. char buf[300+1];
  837. strncpy( buf, str, 300 );
  838. for ( i=0, ii=11; ii<strlen(str); i++, ii++ ) {
  839. str[i] = buf[ii];
  840. }
  841. if ( i > maxChars ) i = maxChars;
  842. str[i] = 0;
  843. }
  844. }
  845. }
  846. #endif
  847. #if 1
  848. void readStringFromFile (
  849. char *str,
  850. int maxChars,
  851. FILE *f )
  852. {
  853. char *ptr;
  854. int i, j, l, max, first, escape;
  855. char buf[10000+1];
  856. if ( maxChars < 1 ) return;
  857. if ( maxChars > 10000 )
  858. max = 10000;
  859. else
  860. max = maxChars-1;
  861. ptr = fgets( buf, 10000, f );
  862. if ( !ptr ) {
  863. strcpy( str, "4 0 0" );
  864. return;
  865. }
  866. buf[10000] = 0;
  867. l = strlen(buf);
  868. buf[l-1] = 0;
  869. if ( l > max ) l = max;
  870. if ( strcmp( buf, "<<<empty>>>" ) == 0 ) {
  871. strcpy( str, "" );
  872. return;
  873. }
  874. else if ( strncmp( buf, "<<<blank>>>", 11 ) == 0 ) {
  875. first = 11;
  876. }
  877. else {
  878. first = 0;
  879. }
  880. escape = 0;
  881. for ( i=first, j=0; i<l; i++ ) {
  882. if ( escape ) {
  883. if ( buf[i] == '\\' ) {
  884. str[j] = buf[i];
  885. if ( j < max ) j++;
  886. }
  887. else if ( buf[i] == 'n' ) {
  888. str[j] = 10;
  889. if ( j < max ) j++;
  890. }
  891. else {
  892. str[j] = buf[i];
  893. if ( j < max ) j++;
  894. }
  895. escape = 0;
  896. }
  897. else {
  898. if ( buf[i] == '\\' ) {
  899. escape = 1;
  900. }
  901. else if ( buf[i] == 1 ) {
  902. str[j] = 10;
  903. if ( j < max ) j++;
  904. }
  905. else {
  906. str[j] = buf[i];
  907. if ( j < max ) j++;
  908. }
  909. }
  910. }
  911. str[j] = 0;
  912. }
  913. #endif
  914. int xDrawText (
  915. Display *d,
  916. Window win,
  917. gcClass *gc,
  918. XFontStruct *fs,
  919. int _x,
  920. int _y,
  921. int _alignment,
  922. char *value ) {
  923. int stringLength, stringWidth, stringX, stringY;
  924. stringLength = strlen( value );
  925. if ( fs ) {
  926. stringWidth = XTextWidth( fs, value, stringLength );
  927. stringY = _y + fs->ascent;
  928. }
  929. else {
  930. stringWidth = 0;
  931. stringY = _y;
  932. }
  933. stringX = _x;
  934. if ( _alignment == XmALIGNMENT_BEGINNING ) {
  935. // no change
  936. }
  937. else if ( _alignment == XmALIGNMENT_CENTER )
  938. stringX = _x - stringWidth/2;
  939. else if ( _alignment == XmALIGNMENT_END )
  940. stringX = _x - stringWidth;
  941. XDrawString( d, win,
  942. gc->normGC(), stringX, stringY, value, stringLength );
  943. return 1;
  944. }
  945. int xEraseText (
  946. Display *d,
  947. Window win,
  948. gcClass *gc,
  949. XFontStruct *fs,
  950. int _x,
  951. int _y,
  952. int _alignment,
  953. char *value ) {
  954. int stringLength, stringWidth, stringX, stringY;
  955. stringLength = strlen( value );
  956. if ( fs ) {
  957. stringWidth = XTextWidth( fs, value, stringLength );
  958. stringY = _y + fs->ascent;
  959. }
  960. else {
  961. stringWidth = 0;
  962. stringY = _y;
  963. }
  964. stringX = _x;
  965. if ( _alignment == XmALIGNMENT_BEGINNING ) {
  966. // no change
  967. }
  968. else if ( _alignment == XmALIGNMENT_CENTER )
  969. stringX = _x - stringWidth/2;
  970. else if ( _alignment == XmALIGNMENT_END )
  971. stringX = _x - stringWidth;
  972. XDrawString( d, win,
  973. gc->eraseGC(), stringX, stringY, value, stringLength );
  974. return 1;
  975. }
  976. int xDrawImageText (
  977. Display *d,
  978. Window win,
  979. gcClass *gc,
  980. XFontStruct *fs,
  981. int _x,
  982. int _y,
  983. int _alignment,
  984. char *value ) {
  985. int stringLength, stringWidth, stringX, stringY;
  986. stringLength = strlen( value );
  987. if ( fs ) {
  988. stringWidth = XTextWidth( fs, value, stringLength );
  989. stringY = _y + fs->ascent;
  990. }
  991. else {
  992. stringWidth = 0;
  993. stringY = _y;
  994. }
  995. stringX = _x;
  996. if ( _alignment == XmALIGNMENT_BEGINNING ) {
  997. // no change
  998. }
  999. else if ( _alignment == XmALIGNMENT_CENTER )
  1000. stringX = _x - stringWidth/2;
  1001. else if ( _alignment == XmALIGNMENT_END )
  1002. stringX = _x - stringWidth;
  1003. XDrawImageString( d, win,
  1004. gc->normGC(), stringX, stringY, value, stringLength );
  1005. return 1;
  1006. }
  1007. int xEraseImageText (
  1008. Display *d,
  1009. Window win,
  1010. gcClass *gc,
  1011. XFontStruct *fs,
  1012. int _x,
  1013. int _y,
  1014. int _alignment,
  1015. char *value ) {
  1016. int stringLength, stringWidth, stringX, stringY;
  1017. stringLength = strlen( value );
  1018. if ( fs ) {
  1019. stringWidth = XTextWidth( fs, value, stringLength );
  1020. stringY = _y + fs->ascent;
  1021. }
  1022. else {
  1023. stringWidth = 0;
  1024. stringY = _y;
  1025. }
  1026. stringX = _x;
  1027. if ( _alignment == XmALIGNMENT_BEGINNING ) {
  1028. // no change
  1029. }
  1030. else if ( _alignment == XmALIGNMENT_CENTER )
  1031. stringX = _x - stringWidth/2;
  1032. else if ( _alignment == XmALIGNMENT_END )
  1033. stringX = _x - stringWidth;
  1034. XDrawImageString( d, win,
  1035. gc->eraseGC(), stringX, stringY, value, stringLength );
  1036. return 1;
  1037. }
  1038. int drawImageText (
  1039. Widget widget,
  1040. gcClass *gc,
  1041. XFontStruct *fs,
  1042. int _x,
  1043. int _y,
  1044. int _alignment,
  1045. char *value ) {
  1046. int stringLength, stringWidth, stringX, stringY;
  1047. stringLength = strlen( value );
  1048. if ( fs ) {
  1049. stringWidth = XTextWidth( fs, value, stringLength );
  1050. stringY = _y + fs->ascent;
  1051. }
  1052. else {
  1053. stringWidth = 0;
  1054. stringY = _y;
  1055. }
  1056. stringX = _x;
  1057. if ( _alignment == XmALIGNMENT_BEGINNING ) {
  1058. // no change
  1059. }
  1060. else if ( _alignment == XmALIGNMENT_CENTER )
  1061. stringX = _x - stringWidth/2;
  1062. else if ( _alignment == XmALIGNMENT_END )
  1063. stringX = _x - stringWidth;
  1064. XDrawImageString( XtDisplay(widget), XtWindow(widget),
  1065. gc->normGC(), stringX, stringY, value, stringLength );
  1066. return 1;
  1067. }
  1068. int eraseImageText (
  1069. Widget widget,
  1070. gcClass *gc,
  1071. XFontStruct *fs,
  1072. int _x,
  1073. int _y,
  1074. int _alignment,
  1075. char *value ) {
  1076. int stringLength, stringWidth, stringX, stringY;
  1077. stringLength = strlen( value );
  1078. if ( fs ) {
  1079. stringWidth = XTextWidth( fs, value, stringLength );
  1080. stringY = _y + fs->ascent;
  1081. }
  1082. else {
  1083. stringWidth = 0;
  1084. stringY = _y;
  1085. }
  1086. stringX = _x;
  1087. if ( _alignment == XmALIGNMENT_BEGINNING ) {
  1088. // no change
  1089. }
  1090. else if ( _alignment == XmALIGNMENT_CENTER )
  1091. stringX = _x - stringWidth/2;
  1092. else if ( _alignment == XmALIGNMENT_END )
  1093. stringX = _x - stringWidth;
  1094. XDrawImageString( XtDisplay(widget), XtWindow(widget),
  1095. gc->eraseGC(), stringX, stringY, value, stringLength );
  1096. return 1;
  1097. }
  1098. int drawText (
  1099. Widget widget,
  1100. gcClass *gc,
  1101. XFontStruct *fs,
  1102. int _x,
  1103. int _y,
  1104. int _alignment,
  1105. char *value ) {
  1106. int stat;
  1107. stat = xDrawText( XtDisplay(widget), XtWindow(widget),
  1108. gc, fs, _x, _y, _alignment, value );
  1109. return stat;
  1110. }
  1111. int eraseText (
  1112. Widget widget,
  1113. gcClass *gc,
  1114. XFontStruct *fs,
  1115. int _x,
  1116. int _y,
  1117. int _alignment,
  1118. char *value ) {
  1119. int stat;
  1120. stat = xEraseText( XtDisplay(widget), XtWindow(widget),
  1121. gc, fs, _x, _y, _alignment, value );
  1122. return stat;
  1123. }
  1124. int textBoundaries (
  1125. XFontStruct *fs,
  1126. int _x,
  1127. int _y,
  1128. int _alignment,
  1129. char *value,
  1130. int *x0,
  1131. int *y0,
  1132. int *x1,
  1133. int *y1 ) {
  1134. int stringLength, stringWidth, stringX, asc, dsc;
  1135. stringLength = strlen( value );
  1136. if ( fs ) {
  1137. asc = fs->ascent;
  1138. dsc = fs->descent;
  1139. stringWidth = XTextWidth( fs, value, stringLength );
  1140. }
  1141. else {
  1142. asc = 10;
  1143. dsc = 5;
  1144. stringWidth = 0;
  1145. }
  1146. stringX = _x;
  1147. if ( _alignment == XmALIGNMENT_BEGINNING ) {
  1148. // no change
  1149. }
  1150. else if ( _alignment == XmALIGNMENT_CENTER )
  1151. stringX = _x - stringWidth/2;
  1152. else if ( _alignment == XmALIGNMENT_END )
  1153. stringX = _x - stringWidth;
  1154. *y0 = _y;
  1155. *y1 = _y + asc + dsc;
  1156. *x0 = stringX;
  1157. *x1 = stringX + stringWidth;
  1158. return 1;
  1159. }
  1160. int fileIsLocked (
  1161. FILE *f )
  1162. {
  1163. int stat;
  1164. int fd = fileno(f);
  1165. struct flock l;
  1166. l.l_type = F_WRLCK;
  1167. l.l_start = 0;
  1168. l.l_whence = SEEK_SET;
  1169. l.l_len = 1;
  1170. l.l_pid = 0;
  1171. stat = fcntl( fd, F_GETLK, &l );
  1172. if ( stat < 0 ) {
  1173. return 1; /* failure, assume file is locked */
  1174. }
  1175. if ( l.l_pid == 0 )
  1176. return 0; /* not locked */
  1177. else
  1178. return 1; /* locked */
  1179. }
  1180. int lockFile (
  1181. FILE *f )
  1182. {
  1183. int stat;
  1184. int fd = fileno(f);
  1185. struct flock l;
  1186. l.l_type = F_WRLCK;
  1187. l.l_start = 0;
  1188. l.l_whence = SEEK_SET;
  1189. l.l_len = 1;
  1190. stat = fcntl( fd, F_SETLK, &l );
  1191. if ( stat < 0 )
  1192. return 0; /* even, failure */
  1193. else
  1194. return 1; /* odd, success */
  1195. }
  1196. int unlockFile (
  1197. FILE *f )
  1198. {
  1199. int stat;
  1200. int fd = fileno(f);
  1201. struct flock l;
  1202. l.l_type = F_UNLCK;
  1203. l.l_start = 0;
  1204. l.l_whence = SEEK_SET;
  1205. l.l_len = 1;
  1206. stat = fcntl( fd, F_SETLK, &l );
  1207. if ( stat < 0 )
  1208. return 0; /* even, failure */
  1209. else
  1210. return 1; /* odd, success */
  1211. return 1;
  1212. }
  1213. void buildFileName (
  1214. char *inName,
  1215. char *prefix,
  1216. char *postfix,
  1217. char *expandedName,
  1218. int maxSize )
  1219. {
  1220. char *gotOne;
  1221. gotOne = strstr( inName, "/" );
  1222. if ( gotOne ) {
  1223. strncpy( expandedName, inName, maxSize );
  1224. }
  1225. else {
  1226. strncpy( expandedName, prefix, maxSize );
  1227. Strncat( expandedName, inName, maxSize );
  1228. }
  1229. if ( strlen(expandedName) > strlen(postfix) ) {
  1230. if ( strcmp( &expandedName[strlen(expandedName)-strlen(postfix)], postfix )
  1231. != 0 ) {
  1232. Strncat( expandedName, postfix, maxSize );
  1233. }
  1234. }
  1235. else {
  1236. Strncat( expandedName, postfix, maxSize );
  1237. }
  1238. }
  1239. int getFileName (
  1240. char *name,
  1241. char *fullName,
  1242. int maxSize )
  1243. {
  1244. int start, end, i, ii, l, ret_stat;
  1245. if ( !fullName || !name ) {
  1246. ret_stat = 0;
  1247. goto err_return;
  1248. }
  1249. l = strlen(fullName);
  1250. start = 0;
  1251. for ( i=l-1; i>=0; i-- ) {
  1252. if ( fullName[i] == '/' ) {
  1253. start = i+1;
  1254. break;
  1255. }
  1256. }
  1257. end = l-1;
  1258. for ( i=l-1; i>=start; i-- ) {
  1259. if ( fullName[i] == '.' ) {
  1260. end = i-1;
  1261. break;
  1262. }
  1263. }
  1264. strcpy( name, "" );
  1265. for ( i=start, ii=0; (i<=end) && (ii<maxSize); i++, ii++ ) {
  1266. name[ii] = fullName[i];
  1267. }
  1268. if ( ii >= maxSize ) ii = maxSize-1;
  1269. name[ii] = 0;
  1270. return 1;
  1271. err_return:
  1272. if ( name ) strcpy( name, "" );
  1273. return ret_stat;
  1274. }
  1275. int getFilePrefix (
  1276. char *prefix,
  1277. char *fullName,
  1278. int maxSize )
  1279. {
  1280. int start, end, i, ii, l, ret_stat;
  1281. if ( !fullName || !prefix ) {
  1282. ret_stat = 0;
  1283. goto err_return;
  1284. }
  1285. l = strlen(fullName);
  1286. start = 0;
  1287. end = -1;
  1288. for ( i=l-1; i>=0; i-- ) {
  1289. if ( fullName[i] == '/' ) {
  1290. end = i;
  1291. break;
  1292. }
  1293. }
  1294. strcpy( prefix, "" );
  1295. for ( i=start, ii=0; (i<=end) && (ii<maxSize); i++, ii++ ) {
  1296. prefix[ii] = fullName[i];
  1297. }
  1298. if ( ii >= maxSize ) ii = maxSize-1;
  1299. prefix[ii] = 0;
  1300. return 1;
  1301. err_return:
  1302. if ( prefix ) strcpy( prefix, "" );
  1303. return ret_stat;
  1304. }
  1305. int getFilePostfix (
  1306. char *postfix,
  1307. char *fullName,
  1308. int maxSize )
  1309. {
  1310. int start, end, i, ii, l, ret_stat;
  1311. if ( !fullName || !postfix ) {
  1312. ret_stat = 0;
  1313. goto err_return;
  1314. }
  1315. l = strlen(fullName);
  1316. start = l;
  1317. end = l-1;
  1318. for ( i=l-1; i>=0; i-- ) {
  1319. if ( fullName[i] == '/' ) break;
  1320. if ( fullName[i] == '.' ) {
  1321. start = i;
  1322. break;
  1323. }
  1324. }
  1325. strcpy( postfix, "" );
  1326. for ( i=start, ii=0; (i<=end) && (ii<maxSize); i++, ii++ ) {
  1327. postfix[ii] = fullName[i];
  1328. }
  1329. if ( ii >= maxSize ) ii = maxSize-1;
  1330. postfix[ii] = 0;
  1331. return 1;
  1332. err_return:
  1333. if ( postfix ) strcpy( postfix, "" );
  1334. return ret_stat;
  1335. }
  1336. char *getNextDataString (
  1337. char *str,
  1338. int max,
  1339. FILE *f )
  1340. {
  1341. int blankOrComment;
  1342. char *gotOne, *tk, *context, buf[255+1];
  1343. do {
  1344. gotOne = fgets( str, max, f );
  1345. if ( !gotOne ) return NULL;
  1346. strncpy( buf, str, 255 );
  1347. context = NULL;
  1348. tk = strtok_r( buf, " \t\n", &context );
  1349. blankOrComment = 0;
  1350. if ( tk ) {
  1351. if ( tk[0] == '#' ) blankOrComment = 1;
  1352. }
  1353. else {
  1354. blankOrComment = 1;
  1355. }
  1356. } while ( blankOrComment );
  1357. return str;
  1358. }
  1359. // these routines consider an ascii 1 to mean new line
  1360. void XDrawStrings (
  1361. Display *d,
  1362. Window w,
  1363. GC gc,
  1364. int x,
  1365. int y,
  1366. int h,
  1367. char *str,
  1368. int len )
  1369. {
  1370. int i, start, l, strL;
  1371. i = start = l = 0;
  1372. strL = strlen( str );
  1373. while ( i < strL ) {
  1374. if ( ( str[i] == 1 ) || ( str[i] == 10 ) ) {
  1375. if ( l ) {
  1376. XDrawString( d, w, gc, x, y, &str[start], l );
  1377. l = 0;
  1378. }
  1379. start = i+1;
  1380. y += h;
  1381. }
  1382. else {
  1383. l++;
  1384. }
  1385. i++;
  1386. }
  1387. if ( l ) {
  1388. XDrawString( d, w, gc, x, y, &str[start], l );
  1389. }
  1390. }
  1391. void getStringBoxSize (
  1392. char *str,
  1393. int len,
  1394. XFontStruct **fs,
  1395. int alignment,
  1396. int *width,
  1397. int *height )
  1398. {
  1399. int i, start, l, strL, stringWidth, maxWidth, maxHeight, charHeight;
  1400. maxWidth = 2;
  1401. maxHeight = 0;
  1402. i = start = l = 0;
  1403. strL = strlen( str );
  1404. while ( i < strL ) {
  1405. if ( ( str[i] == 1 ) || ( str[i] == 10 ) ) {
  1406. if ( l ) {
  1407. if ( fs && *fs ) {
  1408. stringWidth = XTextWidth( *fs, &str[start], l );
  1409. charHeight = (*fs)->ascent + (*fs)->descent;
  1410. }
  1411. else {
  1412. stringWidth = 10;
  1413. charHeight = 2;
  1414. }
  1415. if ( stringWidth > maxWidth ) maxWidth = stringWidth;
  1416. l = 0;
  1417. }
  1418. start = i+1;
  1419. maxHeight += charHeight;
  1420. }
  1421. else {
  1422. l++;
  1423. }
  1424. i++;
  1425. }
  1426. if ( l ) {
  1427. if ( fs && *fs ) {
  1428. stringWidth = XTextWidth( *fs, &str[start], l );
  1429. charHeight = (*fs)->ascent + (*fs)->descent;
  1430. }
  1431. else {
  1432. stringWidth = 10;
  1433. charHeight = 2;
  1434. }
  1435. if ( stringWidth > maxWidth ) maxWidth = stringWidth;
  1436. maxHeight += charHeight;
  1437. }
  1438. *width = maxWidth;
  1439. *height = maxHeight;
  1440. }
  1441. void XDrawStringsAligned (
  1442. Display *d,
  1443. Window w,
  1444. GC gc,
  1445. int x,
  1446. int y,
  1447. int fieldWidth,
  1448. char *str,
  1449. int len,
  1450. XFontStruct **fs,
  1451. int alignment )
  1452. {
  1453. int charHeight, i, start, l, strL, stringWidth, stringX;
  1454. i = start = l = 0;
  1455. strL = strlen( str );
  1456. while ( i < strL ) {
  1457. if ( ( str[i] == 1 ) || ( str[i] == 10 ) ) {
  1458. if ( l ) {
  1459. if ( fs && *fs ) {
  1460. stringWidth = XTextWidth( *fs, &str[start], l );
  1461. charHeight = (*fs)->ascent + (*fs)->descent;
  1462. }
  1463. else {
  1464. stringWidth = 10;
  1465. charHeight = 2;
  1466. }
  1467. if ( alignment == XmALIGNMENT_BEGINNING )
  1468. stringX = x;
  1469. else if ( alignment == XmALIGNMENT_CENTER )
  1470. stringX = x + fieldWidth/2 - stringWidth/2;
  1471. else if ( alignment == XmALIGNMENT_END )
  1472. stringX = x + fieldWidth - stringWidth;
  1473. XDrawString( d, w, gc, stringX, y, &str[start], l );
  1474. l = 0;
  1475. }
  1476. start = i+1;
  1477. y += charHeight;
  1478. }
  1479. else {
  1480. l++;
  1481. }
  1482. i++;
  1483. }
  1484. if ( l ) {
  1485. if ( fs && *fs ) {
  1486. stringWidth = XTextWidth( *fs, &str[start], l );
  1487. charHeight = (*fs)->ascent + (*fs)->descent;
  1488. }
  1489. else {
  1490. stringWidth = 10;
  1491. charHeight = 2;
  1492. }
  1493. if ( alignment == XmALIGNMENT_BEGINNING )
  1494. stringX = x;
  1495. else if ( alignment == XmALIGNMENT_CENTER )
  1496. stringX = x + fieldWidth/2 - stringWidth/2;
  1497. else if ( alignment == XmALIGNMENT_END )
  1498. stringX = x + fieldWidth - stringWidth;
  1499. XDrawString( d, w, gc, stringX, y, &str[start], l );
  1500. }
  1501. }
  1502. void XDrawImageStringsAligned (
  1503. Display *d,
  1504. Window w,
  1505. GC gc,
  1506. int x,
  1507. int y,
  1508. int fieldWidth,
  1509. char *str,
  1510. int len,
  1511. XFontStruct **fs,
  1512. int alignment )
  1513. {
  1514. int charHeight, i, start, l, strL, stringWidth, stringX;
  1515. i = start = l = 0;
  1516. strL = strlen( str );
  1517. while ( i < strL ) {
  1518. if ( ( str[i] == 1 ) || ( str[i] == 10 ) ) {
  1519. if ( l ) {
  1520. if ( fs && *fs ) {
  1521. stringWidth = XTextWidth( *fs, &str[start], l );
  1522. charHeight = (*fs)->ascent + (*fs)->descent;
  1523. }
  1524. else {
  1525. stringWidth = 10;
  1526. charHeight = 2;
  1527. }
  1528. if ( alignment == XmALIGNMENT_BEGINNING )
  1529. stringX = x;
  1530. else if ( alignment == XmALIGNMENT_CENTER )
  1531. stringX = x + fieldWidth/2 - stringWidth/2;
  1532. else if ( alignment == XmALIGNMENT_END )
  1533. stringX = x + fieldWidth - stringWidth;
  1534. XDrawImageString( d, w, gc, stringX, y, &str[start], l );
  1535. l = 0;
  1536. }
  1537. start = i+1;
  1538. y += charHeight;
  1539. }
  1540. else {
  1541. l++;
  1542. }
  1543. i++;
  1544. }
  1545. if ( l ) {
  1546. if ( fs && *fs ) {
  1547. stringWidth = XTextWidth( *fs, &str[start], l );
  1548. charHeight = (*fs)->ascent + (*fs)->descent;
  1549. }
  1550. else {
  1551. stringWidth = 10;
  1552. charHeight = 2;
  1553. }
  1554. if ( alignment == XmALIGNMENT_BEGINNING )
  1555. stringX = x;
  1556. else if ( alignment == XmALIGNMENT_CENTER )
  1557. stringX = x + fieldWidth/2 - stringWidth/2;
  1558. else if ( alignment == XmALIGNMENT_END )
  1559. stringX = x + fieldWidth - stringWidth;
  1560. XDrawImageString( d, w, gc, stringX, y, &str[start], l );
  1561. }
  1562. }
  1563. void XDrawImageStrings (
  1564. Display *d,
  1565. Window w,
  1566. GC gc,
  1567. int x,
  1568. int y,
  1569. int h,
  1570. char *str,
  1571. int len )
  1572. {
  1573. int i, start, l, strL;
  1574. i = start = l = 0;
  1575. strL = strlen( str );
  1576. while ( i < strL ) {
  1577. if ( ( str[i] == 1 ) || ( str[i] == 10 ) ) {
  1578. if ( l ) {
  1579. XDrawImageString( d, w, gc, x, y, &str[start], l );
  1580. l = 0;
  1581. }
  1582. start = i+1;
  1583. y += h;
  1584. }
  1585. else {
  1586. l++;
  1587. }
  1588. i++;
  1589. }
  1590. if ( l ) {
  1591. XDrawImageString( d, w, gc, x, y, &str[start], l );
  1592. }
  1593. }
  1594. #if 0
  1595. // these routines consider an ascii 1 to mean new line
  1596. void XDrawStrings (
  1597. Display *d,
  1598. Window w,
  1599. GC gc,
  1600. int x,
  1601. int y,
  1602. int h,
  1603. char *str,
  1604. int len )
  1605. {
  1606. char buf[255+1], *tk, *context;
  1607. strncpy( buf, str, 255 );
  1608. context = NULL;
  1609. tk = strtok_r( buf, "\001", &context );
  1610. while ( tk ) {
  1611. XDrawString( d, w, gc, x, y, tk, strlen(tk) );
  1612. tk = strtok_r( NULL, "\001", &context );
  1613. y += h;
  1614. }
  1615. }
  1616. void XDrawImageStrings (
  1617. Display *d,
  1618. Window w,
  1619. GC gc,
  1620. int x,
  1621. int y,
  1622. int h,
  1623. char *str,
  1624. int len )
  1625. {
  1626. char buf[255+1], *tk, *context;
  1627. strncpy( buf, str, 255 );
  1628. context = NULL;
  1629. tk = strtok_r( buf, "\001", &context );
  1630. while ( tk ) {
  1631. XDrawImageString( d, w, gc, x, y, tk, strlen(tk) );
  1632. tk = strtok_r( NULL, "\001", &context );
  1633. y += h;
  1634. }
  1635. }
  1636. #endif
  1637. int countSymbolsAndValues (
  1638. char *string,
  1639. int *total,
  1640. int *maxLen
  1641. ) {
  1642. // string contains s1=v1,s2=v2,s3=v3,...
  1643. // this routine counts the number of symbol,value pairs
  1644. // maxLen equals the longest string found
  1645. char *context, *tk, buf[511+1];
  1646. if ( !string ) return 100; // fail
  1647. strncpy( buf, string, 511 );
  1648. buf[511] = 0;
  1649. *maxLen = 0;
  1650. *total = 0;
  1651. context = NULL;
  1652. tk = strtok_r( buf, ",=", &context );
  1653. while ( tk ) {
  1654. tk = strtok_r( NULL, ",=", &context );
  1655. if ( !tk ) return 101; // missing value
  1656. if ( strlen(tk) > (unsigned int) *maxLen ) *maxLen = (int) strlen(tk);
  1657. (*total)++;
  1658. tk = strtok_r( NULL, ",=", &context );
  1659. }
  1660. return 1;
  1661. }
  1662. int parseSymbolsAndValues (
  1663. char *string,
  1664. int max,
  1665. char *symbols[],
  1666. char *values[],
  1667. int *numFound
  1668. ) {
  1669. // string contains s1=v1,s2=v2,s3=v3,...
  1670. // this routine puts s1, s2, s3, ... into symbols
  1671. // and v1, v2, v3, ... into values
  1672. int l;
  1673. char *context, *tk, buf[10000+1];
  1674. if ( !string ) return 100; // fail
  1675. l = strlen(string);
  1676. if ( l > 10000 ) l = 10000;
  1677. strncpy( buf, string, l );
  1678. buf[l] = 0;
  1679. *numFound = 0;
  1680. context = NULL;
  1681. tk = strtok_r( buf, ",=", &context );
  1682. while ( tk ) {
  1683. l = strlen(tk) + 1;
  1684. symbols[*numFound] = new char[l];
  1685. strcpy( symbols[*numFound], tk );
  1686. trimWhiteSpace( symbols[*numFound] );
  1687. tk = strtok_r( NULL, ",=", &context );
  1688. if ( !tk ) {
  1689. return 101; // missing value
  1690. }
  1691. if ( strcmp( tk, "''" ) == 0 ) {
  1692. l = 1;
  1693. values[*numFound] = new char[l];
  1694. strcpy( values[*numFound], "" );
  1695. }
  1696. else if ( strcmp( tk, "\\'\\'" ) == 0 ) {
  1697. l = 1;
  1698. values[*numFound] = new char[l];
  1699. strcpy( values[*numFound], "" );
  1700. }
  1701. else if ( strcmp( tk, "\\\"\\\"" ) == 0 ) {
  1702. l = 1;
  1703. values[*numFound] = new char[l];
  1704. strcpy( values[*numFound], "" );
  1705. }
  1706. else {
  1707. l = strlen(tk) + 1;
  1708. values[*numFound] = new char[l];
  1709. strcpy( values[*numFound], tk );
  1710. }
  1711. (*numFound)++;
  1712. tk = strtok_r( NULL, ",=", &context );
  1713. }
  1714. return 1;
  1715. }
  1716. int parseLocalSymbolsAndValues (
  1717. char *string,
  1718. int max,
  1719. int maxLen,
  1720. char *symbols[],
  1721. char *values[],
  1722. int *numFound
  1723. ) {
  1724. // string contains s1=v1,s2=v2,s3=v3,...
  1725. // this routine puts s1, s2, s3, ... into symbols
  1726. // and v1, v2, v3, ... into values
  1727. int l;
  1728. char *context, *tk, buf[10000+1];
  1729. if ( !string ) return 100; // fail
  1730. l = strlen(string);
  1731. if ( l > 10000 ) l = 10000;
  1732. strncpy( buf, string, l );
  1733. buf[l] = 0;
  1734. *numFound = 0;
  1735. context = NULL;
  1736. tk = strtok_r( buf, ",=", &context );
  1737. while ( tk ) {
  1738. l = strlen(tk) + 1;
  1739. strncpy( symbols[*numFound], tk, maxLen );
  1740. symbols[*numFound][maxLen] = 0;
  1741. trimWhiteSpace( symbols[*numFound] );
  1742. tk = strtok_r( NULL, ",=", &context );
  1743. if ( !tk ) return 101; // missing value
  1744. if ( strcmp( tk, "''" ) == 0 ) {
  1745. l = 1;
  1746. values[*numFound] = new char[l];
  1747. strcpy( values[*numFound], "" );
  1748. }
  1749. else if ( strcmp( tk, "\\'\\'" ) == 0 ) {
  1750. l = 1;
  1751. values[*numFound] = new char[l];
  1752. strcpy( values[*numFound], "" );
  1753. }
  1754. else if ( strcmp( tk, "\\\"\\\"" ) == 0 ) {
  1755. l = 1;
  1756. values[*numFound] = new char[l];
  1757. strcpy( values[*numFound], "" );
  1758. }
  1759. else {
  1760. l = strlen(tk) + 1;
  1761. values[*numFound] = new char[l];
  1762. strcpy( values[*numFound], tk );
  1763. }
  1764. (*numFound)++;
  1765. tk = strtok_r( NULL, ",=", &context );
  1766. }
  1767. return 1;
  1768. }
  1769. int get_scale_params1 (
  1770. double min,
  1771. double max,
  1772. double *adj_min,
  1773. double *adj_max,
  1774. int *num_label_ticks,
  1775. int *majors_per_label,
  1776. int *minors_per_major,
  1777. char *format
  1778. ) {
  1779. double dmin, dmax, diff, mag, norm;
  1780. int imag, inorm, imin, imax, inc1, inc2, inc5, imin1, imax1,
  1781. imin2, imax2, imin5, imax5, best, bestInc, bestMin, bestMax, idiff, idiv,
  1782. choice, ok;
  1783. dmin = min;
  1784. dmax = max;
  1785. if ( dmax <= dmin ) dmax = dmin + 1.0;
  1786. diff = dmax - dmin;
  1787. /* fprintf( stderr, "dmin = %-g, dmax = %-g, diff = %-g\n", dmin, dmax, diff ); */
  1788. mag = log10( diff );
  1789. imag = (int ) floor( mag ) - 1;
  1790. norm = diff * pow(10.0,-1.0*imag);
  1791. inorm = (int) ceil( norm );
  1792. //fprintf( stderr, "mag = %-g, imag = %-d\n", mag, imag );
  1793. //fprintf( stderr, "norm = %-d\n", inorm );
  1794. /* normalize min & max */
  1795. imin = (int) floor( dmin * pow(10.0,-1.0*imag) );
  1796. imax = (int) ceil( dmax * pow(10.0,-1.0*imag) );
  1797. ok = 0;
  1798. inc1 = imax - imin;
  1799. imin1 = imin;
  1800. imax1 = imax;
  1801. if ( inc1 < 8 ) ok = 1;
  1802. //fprintf( stderr, "1st adj min 1 = %-d, 1st adj max 1 = %-d\n", imin1, imax1 );
  1803. if ( imin < 0 ) {
  1804. if ( imin % 2 )
  1805. imin2 = imin - 2 - ( imin % 2 );
  1806. else
  1807. imin2 = imin;
  1808. }
  1809. else {
  1810. imin2 = imin - ( imin % 2 );
  1811. }
  1812. if ( imax < 0 ) {
  1813. imax2 = imax + 2 + ( imax % 2 );
  1814. }
  1815. else {
  1816. if ( imax % 2 )
  1817. imax2 = imax + 2 - ( imax % 2 );
  1818. else
  1819. imax2 = imax;
  1820. }
  1821. inc2 = ( imax2 - imin2 ) / 2;
  1822. if ( inc2 < 8 ) ok = 1;
  1823. //fprintf( stderr, "1st adj min 2 = %-d, 1st adj max 2 = %-d\n", imin2, imax2 );
  1824. if ( imin < 0 ) {
  1825. if ( imin % 5 )
  1826. imin5 = imin - 5 - ( imin % 5 );
  1827. else
  1828. imin5 = imin;
  1829. }
  1830. else {
  1831. imin5 = imin - ( imin % 5 );
  1832. }
  1833. if ( imax < 0 ) {
  1834. imax5 = imax + 5 + ( imax % 5 );
  1835. }
  1836. else {
  1837. if ( imax % 5 )
  1838. imax5 = imax + 5 - ( imax % 5 );
  1839. else
  1840. imax5 = imax;
  1841. }
  1842. inc5 = ( imax5 - imin5 ) / 5;
  1843. if ( inc5 < 8 ) ok = 1;
  1844. //fprintf( stderr, "1st adj min 5 = %-d, 1st adj max 5 = %-d\n", imin5, imax5 );
  1845. //fprintf( stderr, "1 inc1 = %-d\n", inc1 );
  1846. //fprintf( stderr, "1 inc2 = %-d\n", inc2 );
  1847. //fprintf( stderr, "1 inc5 = %-d\n", inc5 );
  1848. if ( ! ok ) {
  1849. imag++;
  1850. /* normalize min & max */
  1851. imin = (int) floor( dmin * pow(10.0,-1.0*imag) );
  1852. imax = (int) ceil( dmax * pow(10.0,-1.0*imag) );
  1853. inc1 = imax - imin;
  1854. imin1 = imin;
  1855. imax1 = imax;
  1856. if ( inc1 < 8 ) ok = 1;
  1857. //fprintf( stderr, "1st adj min 1 = %-d, 1st adj max 1 = %-d\n", imin1, imax1 );
  1858. if ( imin < 0 ) {
  1859. if ( imin % 2 )
  1860. imin2 = imin - 2 - ( imin % 2 );
  1861. else
  1862. imin2 = imin;
  1863. }
  1864. else {
  1865. imin2 = imin - ( imin % 2 );
  1866. }
  1867. if ( imax < 0 ) {
  1868. imax2 = imax + 2 + ( imax % 2 );
  1869. }
  1870. else {
  1871. if ( imax % 2 )
  1872. imax2 = imax + 2 - ( imax % 2 );
  1873. else
  1874. imax2 = imax;
  1875. }
  1876. inc2 = ( imax2 - imin2 ) / 2;
  1877. if ( inc2 < 8 ) ok = 1;
  1878. //fprintf( stderr, "1st adj min 2 = %-d, 1st adj max 2 = %-d\n", imin2, imax2 );
  1879. if ( imin < 0 ) {
  1880. if ( imin % 5 )
  1881. imin5 = imin - 5 - ( imin % 5 );
  1882. else
  1883. imin5 = imin;
  1884. }
  1885. else {
  1886. imin5 = imin - ( imin % 5 );
  1887. }
  1888. if ( imax < 0 ) {
  1889. imax5 = imax + 5 + ( imax % 5 );
  1890. }
  1891. else {
  1892. if ( imax % 5 )
  1893. imax5 = imax + 5 - ( imax % 5 );
  1894. else
  1895. imax5 = imax;
  1896. }
  1897. inc5 = ( imax5 - imin5 ) / 5;
  1898. if ( inc5 < 8 ) ok = 1;
  1899. //fprintf( stderr, "1st adj min 5 = %-d, 1st adj max 5 = %-d\n", imin5, imax5 );
  1900. //fprintf( stderr, "2 inc1 = %-d\n", inc1 );
  1901. //fprintf( stderr, "2 inc2 = %-d\n", inc2 );
  1902. //fprintf( stderr, "2 inc5 = %-d\n", inc5 );
  1903. }
  1904. // find best
  1905. best = abs( inc1 - 6 );
  1906. bestInc = inc1;
  1907. bestMin = imin1;
  1908. bestMax = imax1;
  1909. idiv = inc1;
  1910. choice = 1;
  1911. if ( abs( inc2 - 6 ) < best ) {
  1912. best = abs( inc2 - 6 );
  1913. bestInc = inc2;
  1914. bestMin = imin2;
  1915. bestMax = imax2;
  1916. idiv = inc2;
  1917. choice = 2;
  1918. }
  1919. if ( abs( inc5 - 6 ) < best ) {
  1920. best = abs( inc5 - 6 );
  1921. bestInc = inc5;
  1922. bestMin = imin5;
  1923. bestMax = imax5;
  1924. idiv = inc5;
  1925. choice = 5;
  1926. }
  1927. idiff = ( bestMax - bestMin );
  1928. *adj_min = (double) bestMin * pow(10.0,imag);
  1929. *adj_max = (double) bestMax * pow(10.0,imag);
  1930. *num_label_ticks = idiv;
  1931. if ( choice == 1 ) {
  1932. *majors_per_label = 5;
  1933. *minors_per_major = 2;
  1934. }
  1935. else if ( choice == 2 ) {
  1936. *majors_per_label = 2;
  1937. *minors_per_major = 2;
  1938. }
  1939. else { // 5
  1940. *majors_per_label = 5;
  1941. *minors_per_major = 2;
  1942. }
  1943. strcpy( format, "-g" );
  1944. if ( !ok ) return 0;
  1945. return 1;
  1946. }
  1947. int get_log10_scale_params1 (
  1948. double min,
  1949. double max,
  1950. double *adj_min,
  1951. double *adj_max,
  1952. int *num_label_ticks,
  1953. int *majors_per_label,
  1954. int *minors_per_major,
  1955. char *format
  1956. ) {
  1957. //double dmin, dmax, diff, mag, norm;
  1958. //int imag, inorm, imin, imax, inc1, inc2, inc5, imin1, imax1,
  1959. // imin2, imax2, imin5, imax5, best, bestInc, bestMin, bestMax, idiff, idiv,
  1960. // choice, ok, div;
  1961. int imin, imax, inc1, imin1, imax1,
  1962. bestInc, bestMin, bestMax, idiff, idiv,
  1963. choice, ok, div;
  1964. //fprintf( stderr, "\n\n=========================================================\n" );
  1965. //fprintf( stderr, "get_log10_scale_params1, min=%-g, max=%-g\n", min, max );
  1966. div = 1;
  1967. ok = 0;
  1968. imin = (int) floor( min );
  1969. imax = (int) ceil( max );
  1970. //fprintf( stderr, "imin = %-d, imax = %-d\n", imin, imax );
  1971. do {
  1972. if ( imin < 0 ) {
  1973. if ( imin % div )
  1974. imin1 = imin - div - ( imin % div );
  1975. else
  1976. imin1 = imin;
  1977. }
  1978. else {
  1979. imin1 = imin - ( imin % div );
  1980. }
  1981. if ( imax < 0 ) {
  1982. if ( imax % div )
  1983. imax1 = imax + div + ( imax % div );
  1984. else
  1985. imax1 = imax;
  1986. }
  1987. else {
  1988. if ( imax % div )
  1989. imax1 = imax + div - ( imax % div );
  1990. else
  1991. imax1 = imax;
  1992. }
  1993. inc1 = ( imax1 - imin1 ) / div;
  1994. if ( inc1 < 1 ) inc1 = 1;
  1995. if ( inc1 < 8 ) ok = 1;
  1996. //fprintf( stderr, "1st adj min 1 = %-d, 1st adj max 1 = %-d\n", imin1, imax1 );
  1997. //fprintf( stderr, "inc1 = %-d\n", inc1 );
  1998. if ( !ok ) div *= 10;
  1999. } while ( !ok );
  2000. //fprintf( stderr, "2 inc1 = %-d\n", inc1 );
  2001. bestInc = inc1;
  2002. bestMin = imin1;
  2003. bestMax = imax1;
  2004. idiv = inc1;
  2005. choice = 1;
  2006. idiff = ( bestMax - bestMin );
  2007. *adj_min = floor( (double) bestMin );
  2008. *adj_max = ceil( (double) bestMax );
  2009. *num_label_ticks = idiv;
  2010. *majors_per_label = div;
  2011. *minors_per_major = 9;
  2012. strcpy( format, "-g" );
  2013. return 1;
  2014. }
  2015. int get_scale_params (
  2016. double min,
  2017. double max,
  2018. double *adj_min,
  2019. double *adj_max,
  2020. double *label_tick,
  2021. int *majors_per_label,
  2022. int *minors_per_major,
  2023. char *format
  2024. ) {
  2025. int num_label_ticks, stat;
  2026. stat = get_scale_params1 (
  2027. min, max, adj_min, adj_max,
  2028. &num_label_ticks, majors_per_label,
  2029. minors_per_major, format );
  2030. if ( num_label_ticks < 1 ) num_label_ticks = 1;
  2031. *label_tick = ( *adj_max - *adj_min ) /
  2032. (double) num_label_ticks;
  2033. return stat;
  2034. }
  2035. int formatString (
  2036. double value,
  2037. char *string,
  2038. int len,
  2039. char *fmt
  2040. ) {
  2041. char buf[128];
  2042. if ( !string ) return 0;
  2043. if ( len < 1 ) return 0;
  2044. snprintf( buf, 127, fmt, value );
  2045. buf[127] = 0;
  2046. strncpy( string, buf, len );
  2047. return 1;
  2048. }
  2049. int formatString (
  2050. double value,
  2051. char *string,
  2052. int len
  2053. ) {
  2054. char buf[128];
  2055. if ( !string ) return 0;
  2056. if ( len < 1 ) return 0;
  2057. snprintf( buf, 127, "%-g", value );
  2058. buf[127] = 0;
  2059. if ( strlen(buf) > 8 ) {
  2060. snprintf( buf, 127, "%-3g", value );
  2061. buf[127] = 0;
  2062. }
  2063. strncpy( string, buf, len );
  2064. return 1;
  2065. }
  2066. static void updateFontInfo (
  2067. char *string,
  2068. char *fontTag,
  2069. XFontStruct **fs,
  2070. int *ascent,
  2071. int *descent,
  2072. int *height,
  2073. int *width )
  2074. {
  2075. int l;
  2076. if ( string )
  2077. l = strlen(string);
  2078. else
  2079. l = 0;
  2080. if ( fs && *fs ) {
  2081. *ascent = (*fs)->ascent;
  2082. *descent = (*fs)->descent;
  2083. *height = *ascent + *descent;
  2084. *width = XTextWidth( *fs, string, l );
  2085. }
  2086. else {
  2087. *ascent = 10;
  2088. *descent = 5;
  2089. *height = *ascent + *descent;
  2090. *width = 10;
  2091. }
  2092. }
  2093. int xScaleHeight (
  2094. char *fontTag,
  2095. XFontStruct *fs
  2096. ) {
  2097. int label_tick_height, fontAscent, fontDescent, fontHeight,
  2098. stringWidth;
  2099. updateFontInfo( " ", fontTag, &fs,
  2100. &fontAscent, &fontDescent, &fontHeight,
  2101. &stringWidth );
  2102. label_tick_height = (int) ( 0.8 * (double) ( fontHeight - 2 ) );
  2103. return fontHeight + label_tick_height * 2;
  2104. }
  2105. int xScaleMargin (
  2106. char *fontTag,
  2107. XFontStruct *fs,
  2108. double adj_min,
  2109. double adj_max
  2110. ) {
  2111. int stat, scaleOfs, l;
  2112. char buf[31+1];
  2113. int stringWidth;
  2114. stat = formatString( adj_min, buf, 31 );
  2115. if ( fs ) {
  2116. stringWidth = XTextWidth( fs, buf, strlen(buf) );
  2117. }
  2118. else {
  2119. stringWidth = 0;
  2120. }
  2121. scaleOfs = stringWidth;
  2122. stat = formatString( adj_max, buf, 31 );
  2123. if ( fs ) {
  2124. stringWidth = XTextWidth( fs, buf, strlen(buf) );
  2125. }
  2126. else {
  2127. stringWidth = 0;
  2128. }
  2129. l = stringWidth;
  2130. if ( l > scaleOfs ) scaleOfs = l;
  2131. scaleOfs = scaleOfs / 2 + 6;
  2132. return scaleOfs;
  2133. }
  2134. int xTimeScaleHeight (
  2135. char *fontTag,
  2136. XFontStruct *fs
  2137. ) {
  2138. int label_tick_height, fontAscent, fontDescent, fontHeight,
  2139. stringWidth;
  2140. updateFontInfo( " ", fontTag, &fs,
  2141. &fontAscent, &fontDescent, &fontHeight,
  2142. &stringWidth );
  2143. label_tick_height = (int) ( 0.8 * (double) ( fontHeight - 2 ) );
  2144. return (int) ( fontHeight * 2.5 + label_tick_height * 2 );
  2145. }
  2146. int xTimeScaleMargin (
  2147. char *fontTag,
  2148. XFontStruct *fs,
  2149. double adj_min,
  2150. double adj_max
  2151. ) {
  2152. int scaleOfs;
  2153. char buf[3

Large files files are truncated, but you can click here to view the full file