File: basicwin.sml

package info (click to toggle)
smlnj 110.79-8
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, sid
  • size: 82,564 kB
  • sloc: ansic: 32,532; asm: 6,314; sh: 2,296; makefile: 1,821; perl: 1,170; pascal: 295; yacc: 190; cs: 78; python: 77; lisp: 19
file content (179 lines) | stat: -rw-r--r-- 5,460 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
(* basicwin.sml
 *
 * COPYRIGHT (c) 1990,1991 by John H. Reppy.  See COPYRIGHT file for details.
 *
 * This code was transcribed from a C program that is under the following copyright:
 *
 * Copyright 1989 O'Reilly and Associates, Inc.
 *)

structure BasicWin : sig

    val doit' : (string list * string * Int32.int) -> OS.Process.status
    val doit  : string -> OS.Process.status
    val main  : (string * string list) -> OS.Process.status

  end = struct

    structure G = Geometry
    structure EXB = EXeneBase

    val minWid = 300 and minHt = 200
    val minSz = G.SIZE{wid = minWid, ht = minHt}

  (* a trace module for debugging output (see CML manual) *)
    val basicWTM = TraceCML.traceModule(XDebug.eXeneTM, "basicWin")
    fun trace f = TraceCML.trace (basicWTM, f)

  fun init dpyName = let
val _ = trace(fn () => ["open display ", dpyName, "\n"])
	val dpy = (EXB.openDisplay (dpyName, NONE))
		handle EXB.BadAddr s => (
		  TextIO.print s; TextIO.print "\n";
		  RunCML.shutdown OS.Process.failure)
	val scr = EXB.defaultScreenOf dpy
	val winSz = let val G.SIZE{wid, ht} = EXB.sizeOfScr scr
	      in
		G.SIZE{wid = wid div 3, ht = ht div 4}
	      end
	val (win, inEnv) =
	      EXeneWin.createSimpleTopWin scr {
		  geom = G.WGEOM{pos=G.PT{x=0, y=0}, sz=winSz, border=1},
		  border = EXB.blackOfScr scr,
		  backgrnd = EXB.whiteOfScr scr
		}
(** The real basicwin gets the list of icon sizes for the display here **)
	val iconTile = EXB.createTileFromImage scr IconBitmap.iconBitmap
	in
trace(fn () => ["set props\n"]);
	  EXeneWin.setWMProperties win {
	      argv = SMLofNJ.getArgs(),
	      win_name = SOME "Basic Window Program",
	      icon_name = SOME "basicwin",
	      size_hints = [
		  ICCC.HINT_PPosition,
		  ICCC.HINT_PSize,
		  ICCC.HINT_PMinSize minSz
		],
	      wm_hints = [ICCC.HINT_IconTile iconTile],
	      class_hints = SOME{res_name="basicwin", res_class="Basicwin"}
	    };
	  EXeneWin.mapWin win;
	  (dpy, scr, inEnv, win)
	end

  fun mkPen scr = Drawing.newPen [
	  Drawing.PV_Foreground(EXB.blackOfScr scr),
	  Drawing.PV_LineWidth 6,
	  Drawing.PV_LineStyle_OnOffDash,
	  Drawing.PV_CapStyle_Round,
	  Drawing.PV_JoinStyle_Round,
	  Drawing.PV_DashOffset 0,
	  Drawing.PV_Dash_List [12, 24]
	]

  fun loadFont dpy = Font.openFont dpy "9x15"

  fun placeText (win, pen, font, G.SIZE{wid, ht}) = let
val _ = trace(fn () => ["placeText:\n"])
	val drawString = Drawing.drawString (Drawing.drawableOfWin win) pen font
	val textWidth = Font.textWidth font
	val (fontHt, fontDescent) = let val {ascent, descent} = Font.fontHt font
	      in
		(ascent + descent, descent)
	      end
	fun draw (yPos, s) = let
	      val w = textWidth s
	      in
		drawString(G.PT{x = ((wid - w) div 2), y = yPos}, s)
	      end
	val yOffset = (ht div 2) - fontHt - fontDescent
	val G.SIZE{wid=scrWid, ht=scrHt} = EXB.sizeOfScr(EXeneWin.screenOfWin win)
	val depth = EXB.depthOfScr(EXeneWin.screenOfWin win)
	in
trace(fn () => ["placeText: draw text\n"]);
	  app draw [
	      (fontHt,			"Hi! I'm a window, who are you?"),
	      (ht - (2*fontHt),		"To terminate program: press any key"),
	      (yOffset,			"Screen Dimensions:"),
	      (yOffset + fontHt,	" Height - "^(Int.toString scrHt)^" pixels"),
	      (yOffset + (2*fontHt),	" Width  - "^(Int.toString scrWid)^" pixels"),
	      (yOffset + (3*fontHt),	" Depth  - "^(Int.toString depth)^" plane(s)"),
	      (ht - fontHt,		"or button while in this window")
	    ]
	end

  fun placeGraphics (win, pen, G.SIZE{wid=winWid, ht=winHt}) = let
val _ = trace(fn () => ["placeGraphics:\n"])
	val wid = (3 * winWid) div 4
	val ht = winHt div 2
	in
	  Drawing.drawRect (Drawing.drawableOfWin win) pen
	    (G.RECT{
		x = (winWid div 2) - (wid div 2),
		y = (winHt div 2) - (ht div 2),
		wid = wid, ht = ht
	      })
	end

  fun tooSmall (win, pen, font) = let
	val {ascent, ...} = Font.fontHt font
	in
	  Drawing.drawString (Drawing.drawableOfWin win) pen font
	    (G.PT{x=2, y=ascent+2}, "Too Small")
	end

  fun basicwin dpy = let
	open Interact
val _ = trace(fn () => ["init\n"]);
	val (dpy, scr, InEnv{m, k, ci, ...}, win) = init dpy
	val m = CML.wrap(m, msgBodyOf)
	val k = CML.wrap(k, msgBodyOf)
	val ci = CML.wrap(ci, msgBodyOf)
val _ = trace(fn () => ["mkPen\n"]);
	val pen = mkPen scr
val _ = trace(fn () => ["load\n"]);
	val font = loadFont dpy
	fun quit _ = (
	      trace(fn () => ["QUIT\n"]);
	      EXB.closeDisplay dpy;
	      RunCML.shutdown OS.Process.success)
	fun sizeTooSmall (G.SIZE{wid, ht}) = (wid < minWid) orelse (ht < minHt)
	fun loop (sz) = let
	      fun handleM (MOUSE_FirstDown _) = quit()
		| handleM (MOUSE_LastUp _) = quit()
		| handleM _ = loop (sz)
	      fun handleCI (CI_Resize(G.RECT{wid, ht, ...})) =
		    loop (G.SIZE{wid=wid, ht=ht})
		| handleCI (CI_Redraw _) = (
		    if (sizeTooSmall sz)
		      then tooSmall(win, pen, font)
		      else (
			placeText(win, pen, font, sz);
			placeGraphics (win, pen, sz));
		    loop sz)
		| handleCI (CI_Die) = quit()
	      in
		CML.select [
		    CML.wrap(m, handleM),
		    CML.wrap(k, quit),
		    CML.wrap(ci, handleCI)
		  ]
	      end
	in
trace(fn () => ["go\n"]);
	  loop(minSz)
	end

  fun doit' (flgs, dpy, tq) = (
        XDebug.init flgs;
        RunCML.doit (
	  fn () => (XDebug.xspawn("basicwin", fn () => basicwin dpy); ()),
	  SOME(Time.fromMilliseconds tq)))

  fun doit s = doit' ([], s, 20)

  fun main (prog, "-display" :: server :: _) = basicwin server
    | main _ = basicwin ""

end