xref: /inferno-os/appl/wm/mpeg.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1implement WmMpeg;
2
3include "sys.m";
4	sys: Sys;
5
6include "draw.m";
7	draw: Draw;
8	Rect, Display, Image: import draw;
9	ctxt: ref Draw->Context;
10
11include "tk.m";
12	tk: Tk;
13	Toplevel: import tk;
14
15include	"tkclient.m";
16	tkclient: Tkclient;
17
18include	"mpeg.m";
19	mpeg: Mpeg;
20
21WmMpeg: module
22{
23	init:	fn(ctxt: ref Draw->Context, argv: list of string);
24};
25
26Stopped, Playing: con iota;
27
28dx, dy: int;
29dw, dh: int;
30adjust: int;
31
32task_cfg := array[] of {
33	"canvas .c -background =5",
34	"frame .b",
35	"button .b.File -text File -command {send cmd file}",
36	"button .b.Stop -text Stop -command {send cmd stop}",
37	"button .b.Pause -text Pause -command {send cmd pause}",
38	"button .b.Play -text Play -command {send cmd play}",
39	"button .b.Picture -text Picture -command {send cmd pict}",
40	"frame .f",
41	"label .f.file -text {File:}",
42	"label .f.name",
43	"pack .f.file .f.name -side left",
44	"pack .b.File .b.Stop .b.Pause .b.Play .b.Picture -side left",
45	"pack .f -fill x",
46	"pack .b -anchor w",
47	"pack .c -side bottom -fill both -expand 1",
48	"pack propagate . 0",
49};
50
51init(xctxt: ref Draw->Context, nil: list of string)
52{
53	sys = load Sys  Sys->PATH;
54	draw = load Draw Draw->PATH;
55	tk = load Tk Tk->PATH;
56	tkclient = load Tkclient Tkclient->PATH;
57	mpeg = load Mpeg  Mpeg->PATH;
58
59	ctxt = xctxt;
60
61	tkclient->init();
62
63	(t, menubut)  := tkclient->toplevel(ctxt.screen, "", "Mpeg Player", Tkclient->Appl);
64
65	cmd := chan of string;
66	tk->namechan(t, cmd, "cmd");
67
68	tkclient->tkcmds(t, task_cfg);
69
70	tk->cmd(t, "bind . <Configure> {send cmd resize}");
71	tk->cmd(t, "update");
72
73	fname := "";
74	ctl := chan of string;
75	state := Stopped;
76
77	for(;;) alt {
78	menu := <-menubut =>
79		if(menu == "exit") {
80			if(state == Playing) {
81				mpeg->ctl("stop");
82				<-ctl;
83			}
84			return;
85		}
86		tkclient->wmctl(t, menu);
87	press := <-cmd =>
88		case press {
89		"file" =>
90			pat := list of {
91				"*.mpg (MPEG movie file)"
92			};
93			fname = tkclient->filename(ctxt.screen, t, "Locate MPEG clip", pat, "");
94			if(fname != nil) {
95				tk->cmd(t, ".f.name configure -text {"+fname+"}");
96				tk->cmd(t, "update");
97			}
98		"play" =>
99			s := mpeg->play(ctxt.display, nil, 0, canvsize(t), fname, ctl);
100			if(s != nil) {
101				tkclient->dialog(t, "error -fg red", "Play MPEG",
102					"Media player error:\n"+s,
103					0, "Stop Play"::nil);
104				break;
105			}
106			state = Playing;
107		"resize" =>
108			if(state != Playing)
109				break;
110			r := canvsize(t);
111			s := sys->sprint("window %d %d %d %d",
112					r.min.x, r.min.y, r.max.x, r.max.y);
113			mpeg->ctl(s);
114		"pict" =>
115			if(adjust)
116				break;
117			adjust = 1;
118			spawn pict(t);
119		* =>
120			# Stop & Pause
121			mpeg->ctl(press);
122		}
123	done := <-ctl =>
124		state = Stopped;
125	}
126}
127
128canvsize(t: ref Toplevel): Rect
129{
130	r: Rect;
131
132	r.min.x = int tk->cmd(t, ".c cget -actx") + dx;
133	r.min.y = int tk->cmd(t, ".c cget -acty") + dy;
134	r.max.x = r.min.x + int tk->cmd(t, ".c cget -width") + dw;
135	r.max.y = r.min.y + int tk->cmd(t, ".c cget -height") + dh;
136
137	return r;
138}
139
140pict_cfg := array[] of {
141	"scale .dx -orient horizontal -from -5 -to 5 -label {Origin X}"+
142		" -command { send c dx}",
143	"scale .dy -orient horizontal -from -5 -to 5 -label {Origin Y}"+
144		" -command { send c dy}",
145	"scale .dw -orient horizontal -from -5 -to 5 -label {Width}"+
146		" -command {send c dw}",
147	"scale .dh -orient horizontal -from -5 -to 5 -label {Height}"+
148		" -command {send c dh}",
149	"pack .Wm_t -fill x",
150	"pack .dx .dy .dw .dh -fill x",
151	"pack propagate . 0",
152	"update",
153};
154
155pict(parent: ref Toplevel)
156{
157	targ := +" -borderwidth 2 -relief raised";
158
159	(t, menubut) := tkclient->toplevel(ctxt.screen, tkclient->geom(parent), "Mpeg Picture", 0);
160
161	pchan := chan of string;
162	tk->namechan(t, pchan, "c");
163
164	tkclient->tkcmds(t, pict_cfg);
165
166	for(;;) alt {
167	menu := <-menubut =>
168		if(menu == "exit") {
169			adjust = 0;
170			return;
171		}
172		tkclient->wmctl(t, menu);
173	tcip := <-pchan =>
174		case tcip {
175		"dx" =>	dx = int tk->cmd(t, ".dx get");
176		"dy" => dy = int tk->cmd(t, ".dy get");
177		"dw" => dw = int tk->cmd(t, ".dw get");
178		"dh" => dh = int tk->cmd(t, ".dh get");
179		}
180		r := canvsize(parent);
181		s := sys->sprint("window %d %d %d %d",
182				r.min.x, r.min.y, r.max.x, r.max.y);
183		mpeg->ctl(s);
184	}
185}
186