PageRenderTime 45ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/src/ezd.sc

https://bitbucket.org/bunny351/ezd
Scala | 318 lines | 273 code | 45 blank | 0 comment | 7 complexity | bc8f17518146c5bafe0ea8561263af49 MD5 | raw file
  1. ;;; ezd - easy drawing for X11.
  2. ;;;
  3. ;;; Batch command loop and Scheme command interpreter.
  4. ;* Copyright 1990-1993 Digital Equipment Corporation
  5. ;* All Rights Reserved
  6. ;*
  7. ;* Permission to use, copy, and modify this software and its documentation is
  8. ;* hereby granted only under the following terms and conditions. Both the
  9. ;* above copyright notice and this permission notice must appear in all copies
  10. ;* of the software, derivative works or modified versions, and any portions
  11. ;* thereof, and both notices must appear in supporting documentation.
  12. ;*
  13. ;* Users of this software agree to the terms and conditions set forth herein,
  14. ;* and hereby grant back to Digital a non-exclusive, unrestricted, royalty-free
  15. ;* right and license under any changes, enhancements or extensions made to the
  16. ;* core functions of the software, including but not limited to those affording
  17. ;* compatibility with other hardware or software environments, but excluding
  18. ;* applications which incorporate this software. Users further agree to use
  19. ;* their best efforts to return to Digital any such changes, enhancements or
  20. ;* extensions that they make and inform Digital of noteworthy uses of this
  21. ;* software. Correspondence should be provided to Digital at:
  22. ;*
  23. ;* Director of Licensing
  24. ;* Western Research Laboratory
  25. ;* Digital Equipment Corporation
  26. ;* 250 University Avenue
  27. ;* Palo Alto, California 94301
  28. ;*
  29. ;* This software may be distributed (but not offered for sale or transferred
  30. ;* for compensation) to third parties, provided such third parties agree to
  31. ;* abide by the terms and conditions of this notice.
  32. ;*
  33. ;* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  34. ;* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
  35. ;* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
  36. ;* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  37. ;* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  38. ;* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  39. ;* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  40. ;* SOFTWARE.
  41. (module ezd
  42. (with xlib
  43. struct
  44. match
  45. commands
  46. pps
  47. ginfo
  48. display
  49. window
  50. drawing
  51. view
  52. graphic
  53. rectangle
  54. line
  55. text
  56. arc
  57. quilt
  58. psdraw
  59. events
  60. interact
  61. stringinput
  62. popupmenu
  63. buttons
  64. slider
  65. textree
  66. jtextree
  67. textdrawing
  68. mouseedit
  69. editcolor
  70. transpbuttons))
  71. (include "struct.sch")
  72. (include "commands.sch")
  73. (include "display.sch")
  74. (include "window.sch")
  75. (include "view.sch")
  76. (include "drawing.sch")
  77. (include "graphic.sch")
  78. (include "psdraw.sch")
  79. (include "events.sch")
  80. (include "xternal.sch")
  81. (define-c-external (C-SELECT int pointer pointer pointer pointer) int "select")
  82. ;;; Version tag
  83. (define *EZD-VERSION* "15mar93jfb")
  84. ;;; The program accepts five command line arguments arguments:
  85. ;;;
  86. ;;; -i interactive Scheme interpreter
  87. ;;; -l log commands to ezd.LOG
  88. ;;; -nopixmap don't use a pixmap when updating windows
  89. ;;; -p treat an end-of-file on stdin as a pause command
  90. ;;; -s allow interrupt signal
  91. ;;;
  92. ;;; If the environment variable EZDLOG is set, then commands are logged to a
  93. ;;; file with EZDLOG's value as its name. If the environment flag EZDNOPIXMAP
  94. ;;; is set, then pixmaps are not used for window updates.
  95. (define EZD-DONE #f)
  96. (define EZD-LOG #f)
  97. (define-c-external (GETENV pointer) pointer "getenv")
  98. (eval-when (eval)
  99. (define ENV-EZDLOG "")
  100. (define ENV-EZDNOPIXMAP ""))
  101. (eval-when (load)
  102. (define ENV-EZDLOG (c-string->string (getenv "EZDLOG")))
  103. (define ENV-EZDNOPIXMAP (c-string->string (getenv "EZDNOPIXMAP"))))
  104. (define NOPIXMAP (if (eq? env-ezdnopixmap "") #f #t))
  105. (define (READ-EVAL-DRAW clargs)
  106. (define PAUSE (member "-p" clargs))
  107. (set! ezd-log (if (or (member "-l" clargs) (not (equal? env-ezdlog "")))
  108. (let ((port (open-output-file (if (equal? env-ezdlog "")
  109. "ezd.LOG"
  110. env-ezdlog))))
  111. (format port ";;; *EZD-VERSION* ~a~%" *ezd-version*)
  112. port)
  113. #f))
  114. (set! nopixmap (or (member "-nopixmap" clargs) nopixmap))
  115. (if (member "-i" clargs)
  116. (read-eval-print)
  117. (let ((old-reset reset))
  118. (if (and (not (member "-p" clargs)) (not (member "-s" clargs)))
  119. (signal 2 1))
  120. (set! ezd-done #f)
  121. (set! in-read-eval-draw #t)
  122. (call-with-current-continuation
  123. (lambda (return)
  124. (set! reset (lambda () (return #t)))))
  125. (let loop ((command (or ezd-done (read))))
  126. (if ezd-log
  127. (if (or ezd-done (eof-object? command))
  128. (close-output-port ezd-log)
  129. (begin (write command ezd-log)
  130. (newline ezd-log))))
  131. (if (or ezd-done (eof-object? command))
  132. (begin (if (and (eof-object? command) pause)
  133. (ezd '(pause)))
  134. (ezd-reset))
  135. (begin (ezd command)
  136. (loop (or ezd-done (read))))))
  137. (set! reset old-reset)
  138. (set! ezd-done #f)
  139. (set! in-read-eval-draw #f))))
  140. ;;; One or more ezd commands are executed by the following function. Any
  141. ;;; graphical objects generated are added to the current drawing. This
  142. ;;; procedure is the command interface for ezd from Scheme user programs.
  143. (define (EZD . commands)
  144. (for-each
  145. (lambda (c)
  146. (let ((value (ezd-one c)))
  147. (if (isa-graphic? value)
  148. (drawing-add *current-drawing* value))))
  149. commands)
  150. #f)
  151. ;;; Execute a single ezd command and return its value. This is not an external
  152. ;;; interface.
  153. (define (EZD-ONE command)
  154. (if (pair? command)
  155. (let* ((x (assoc (car command) ezd-commands))
  156. (template (if x (cadr x)))
  157. (description (if x (caddr x)))
  158. (action (if x (cadddr x))))
  159. (when (and (not *display*)
  160. (not (memq (car command) '(include quit scheme))))
  161. (set! *display* (make-display ""))
  162. (ezd '(set-drawing ezd))
  163. (if (not (memq (car command)
  164. '(window save-drawing set-drawing)))
  165. (ezd '(window ezd 400 400 points "ezd")
  166. '(overlay ezd ezd))))
  167. (if x
  168. (let ((args (arg-parse template command)))
  169. (if (eq? args #f)
  170. (ezd-error 'ezd
  171. "Illegal command: ~s~% expected - ~a"
  172. command description)
  173. (apply action args)))
  174. (ezd-error 'ezd "Unrecognized command: ~s" command)))
  175. (ezd-error 'ezd "Command is not a list: ~s" command)))
  176. ;;; The following procedure resets the entire drawing system. All modules
  177. ;;; needing initialization in order to be rerun must define a reset procedure
  178. ;;; and have it called from here.
  179. (define (EZD-RESET)
  180. (ezd-module-init)
  181. (commands-module-init)
  182. (display-module-init)
  183. (window-module-init)
  184. (view-module-init)
  185. (drawing-module-init)
  186. (graphic-module-init)
  187. (events-module-init))
  188. ;;; The SCHEME command allows Scheme expressions to be evaluated within ezd.
  189. (define-ezd-command
  190. `(scheme (repeat ,any?))
  191. "(scheme <scheme expression> ...)"
  192. (lambda args (for-each eval (car args))))
  193. ;;; The INCLUDE command loads ezd commands or Scheme expressions (files with
  194. ;;; a suffix of .sc) from a file.
  195. (define (EZD-INCLUDE file)
  196. (if (and (>= (string-length file) 3)
  197. (equal? (substring file (- (string-length file) 3)
  198. (string-length file))
  199. ".sc"))
  200. (loadq file)
  201. (with-input-from-file
  202. file
  203. (lambda ()
  204. (let loop ((exp (read)))
  205. (unless (eof-object? exp)
  206. (ezd exp)
  207. (loop (read))))))))
  208. (define-ezd-command
  209. `(include ,string?)
  210. "(include \"file-name\")"
  211. ezd-include)
  212. ;;; The QUIT command terminates ezd processing.
  213. (define-ezd-command
  214. `(quit)
  215. "(quit)"
  216. (lambda ()
  217. (let ((handling-events (and (isa-display? *display*)
  218. (display-handling-events *display*)))
  219. (command-stream in-read-eval-draw))
  220. (ezd-reset)
  221. (if command-stream (set! ezd-done #t))
  222. (if handling-events
  223. (if (procedure? (top-level-value 'top-level))
  224. (reset)
  225. (exit))))))
  226. ;;; Command stepping. Each step identifies itself by a STEP command with some
  227. ;;; expression. The expression is assigned to *STEP* and then the value of
  228. ;;; *STEPPER* is evaluated. If it is true, then the program pauses until some
  229. ;;; event calls NEXT-STEP or *STEPPER* is set to #f.
  230. (define *STEP* #f) ;;; Value associated with this step.
  231. (define *STEPPER* #f) ;;; Expression to evaluate at each step to decide
  232. ;;; whether or not to continue.
  233. (define *NEXT-STEP* #f) ;;; Stepper advances when this is true.
  234. ;;; Define the stepper.
  235. (define (STEPPER exp)
  236. (set! *stepper* exp))
  237. (define-ezd-command
  238. `(stepper ,any?)
  239. "(stepper expression)"
  240. stepper)
  241. ;;; Test to see if the stepper requires a stop at this step.
  242. (define (STEP exp)
  243. (set! *step* exp)
  244. (set! *next-step* #f)
  245. (when (eval *stepper*)
  246. (display-event-handler *display*)
  247. (let loop ()
  248. (yselect *dpy* 1000000 0)
  249. (display-event-handler *display*)
  250. (if (and *stepper* (not *next-step*)) (loop)))))
  251. (define-ezd-command
  252. `(step ,any?)
  253. "(step expression)"
  254. step)
  255. ;;; Call this from an event handler to allow further processing.
  256. (define (NEXT-STEP)
  257. (set! *next-step* #t))
  258. ;;; The PAUSE command waits for some number of milliseconds, or until ezd
  259. ;;; completes, before returning.
  260. (define-ezd-command
  261. `(pause (optional ,positive-number?))
  262. "(pause [ millisecond pause time ])"
  263. (lambda (ms-pause)
  264. (if ms-pause
  265. (let ((timeval (make-string 8)))
  266. (ezd '(draw-now))
  267. (c-int-set! timeval 0 (quotient ms-pause 1000))
  268. (c-int-set! timeval 4 (* (remainder ms-pause 1000) 1000))
  269. (c-select 0 0 0 0 timeval))
  270. (wait-system-file #f))))
  271. ;;; Module reset/initialization procedure.
  272. (define (EZD-MODULE-INIT)
  273. (set! ezd-done #f))