summaryrefslogtreecommitdiffstats
path: root/src/gui/gui.gtkon
blob: b684e13eb48fd574e53a6228343f4c241b2d5d5a (plain)
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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
/*
 | Frontend for the 0xFFFF flasher in gtkaml
 | author: pancake <youterm.com>
 */

Window using="Gtk" gtkon:version=0.4
	using:Extras="Extras"
	using:SQueues="SQueues"
	name="MainWindow"
	title="0xFFFF GUI"
{
	/* delete-event="{OnWindow1DeleteEvent}" */
	VBox {
		MenuBar !expand {
			MenuItem label="_File" with-mnemonic {
				submenu {
					Menu {
						ImageMenuItem stock-id="gtk-new" activate=OnFileNewEvent;
						ImageMenuItem stock-id="gtk-open" activate=OnFileOpenEvent;
						SeparatorMenuItem;
						ImageMenuItem stock-id="gtk-quit" activate=OnQuitEvent;
					}
				}
			}
			MenuItem label="_Target" with-mnemonic {
				submenu {
					Menu {
						ImageMenuItem stock-id="gtk-connect" activate=OnConnect;
						ImageMenuItem stock-id="gtk-stop" activate=OnStop;
						ImageMenuItem stock-id="gtk-info" activate=OnGetInformation;
						ImageMenuItem label="Reset" activate=OnReset;
					}
				}
			}
			MenuItem label="_Help" with-mnemonic {
				submenu {
					Menu {
						ImageMenuItem stock-id="gtk-about" activate=OnMenuHelpAboutActivatedEvent;
					}
				}
			}
		}

		HBox border-width="5" {
			VBox border-width="3" spacing="3" {
				ScrolledWindow can-focus="true" hscrollbar-policy="{PolicyType.AUTOMATIC}" vscrollbar-policy="{PolicyType.AUTOMATIC}" {
					TreeView $.tv;
				}

			}
			VBox !expand border-width="3" spacing="3" {
				Button label="gtk-connect" use-stock !expand clicked=OnConnect;
				Button label="gtk-stop" use-stock !expand clicked=OnStop;
				Button label="gtk-info" use-stock !expand clicked=OnGetInformation;
				Label label="";
				/*
				   <!--      <Button label="Options" use-stock="false" expand="false"/>
				   <Button label="Fiasco!" use-stock="false" expand="false"/>
				   <Button label="Unpack!" use-stock="false" expand/> -->
				 */
				Button label="gtk-add" use-stock="true" !expand clicked=OnFileOpenEvent;
				Button label="gtk-remove" use-stock="true" expand="false" clicked=list_del;
				Label label="";
				Button label="gtk-media-record" use-stock="true" expand="false" clicked=OnFileFlashEvent;
			}
		}
		ProgressBar $.pb !expand;

		//<!-- <Statusbar expand="false"/> -->
	}
	AboutDialog gtkaml:standalone $.aboutdialog1 delete-event=aboutdialog1.hide_on_delete
		border-width="5" title="About 0xFFFF gui" resizable="false" modal="true"
		window-position="{WindowPosition.CENTER_ON_PARENT}" has-separator="false"
		program-name="0xFFFF" version="0.5" copyright="Copyright (c) 2007-2009 pancake"
		comments="The Free Nokia Internet Tablet flasher"
		website="http://www.nopcode.org/0xFFFF/" 
		authors='{new string[] {"pancake (pancake@youterm.com)", null}}';

	-{


		private void doCloseApplication () {
			Gtk.main_quit ();
		}

		private void OnReset() {
			q->push("reset:device", 1);
		}

		private void OnFileFlashEvent() {
			ListStore ls = (ListStore)tv.get_model();
			weak string str;
			TreeIter iter;

			int n = ls.iter_n_children(null);
			if (n >0) {
				if (showYesNo("Do you want to flash these files?")) {
					ls.get_iter_first(out iter);
					do {
						ls.get(iter, 2, out str, -1);
						//stdout.printf("polla:%s\n", str);
						q->push2("flash", str, 1);
					} while(ls.iter_next(ref iter));
				}
			} else showMessage("No files selected", MessageType.ERROR);
		}

		private void OnFileOpenEvent () {
			FileChooserDialog fc = new FileChooserDialog("Select file to open",
					this, FileChooserAction.OPEN,
					"gtk-cancel", ResponseType.CANCEL,
					"gtk-open", ResponseType.ACCEPT);
			int resp = fc.run ();
			fc.hide ();
			if (resp == ResponseType.ACCEPT) {
				string file = fc.get_filename();
				string *type = External.fpid_file(file);
				string size = "%ld".printf(External.fpid_size(file));
				if (type == null)
					showMessage("Invalid file type", MessageType.ERROR);
				else add_file(type, size, file);
			}
			fc.destroy ();
		}

		public bool loadFile( string filename ) {
			int err = 0;
			try {
				string contents; size_t length;
				FileUtils.get_contents (filename, out contents, out length);
				//textview1.buffer.set_text (contents, length);
			} catch(Error e) {
				showError ("Unexpected error while loading the file, please contact the author with the following information:\n\n" + e.message);
				err++;
			}
			return err == 0;
		}

		public bool showYesNo(string s) {
			MessageDialog md = new MessageDialog (this,
					DialogFlags.DESTROY_WITH_PARENT,
					MessageType.QUESTION, ButtonsType.YES_NO, s);
			int ret = md.run ();
			md.destroy ();
			return ret==ResponseType.YES;
		}

		public void showMessage(string s, MessageType mt) {
			MessageDialog md = new MessageDialog (this,
					DialogFlags.DESTROY_WITH_PARENT,
					mt, ButtonsType.CLOSE, s);
			md.run ();
			md.destroy ();
		}

		private void OnMenuHelpAboutActivatedEvent () {
			aboutdialog1.transient_for = this;
			aboutdialog1.response.connect ((x)=> { aboutdialog1.hide (); });
			aboutdialog1.run ();
		}

		public void showError (string s) {
			MessageDialog md = new MessageDialog (this,
					DialogFlags.DESTROY_WITH_PARENT,
					MessageType.ERROR,
					ButtonsType.CLOSE,
					s);
			md.run ();
			md.destroy ();
		}

		private void OnFileNewEvent () {
			list_clear();
			// TODO: clear file list
		}

		private void OnQuitEvent () {
			doCloseApplication();
			// TODO: send message to gracefully kill 0xFFFF
			// TODO: handle ^C when flashing
		}

		public void list_clear() {
			((ListStore)tv.model).clear();
		}

		public void list_del() {
			TreeIter iter;
			TreeModel model;

			TreeSelection sel = tv.get_selection();

			if (sel.count_selected_rows() == 1) {
				sel.get_selected(out model, out iter);
				((ListStore)tv.model).remove(iter);
			}
		}

		public void add_file(string type, string size, string file) {
			ListStore listmodel = (ListStore)tv.get_model();
			Gtk.TreeIter iter;
			listmodel.append (out iter);
			listmodel.set (iter, 0, type, 1, size, 2, file, -1);
		}

		public static void setup_treeview (Gtk.TreeView view) {
			/* use liststore to hold accountname, accounttype, balance and color attribute */
			/* for more info how gtkTreeview works take a look in the GTK API */

			var listmodel = new Gtk.ListStore(4, typeof(string), typeof(string), typeof(string), typeof(string));       
			view.set_model(listmodel);

			view.insert_column_with_attributes (-1, "Type", new Gtk.CellRendererText(), "text", 0, null);
			view.insert_column_with_attributes (-1, "Size", new Gtk.CellRendererText(), "text", 1, null);

			var cell = new Gtk.CellRendererText (); 
			cell.set ("foreground_set", true, null);
			view.insert_column_with_attributes (-1, "Name", cell, "text", 2, "foreground", 3, null);

			//        Gtk.TreeIter iter;
			//       listmodel.append (out iter);
			//      listmodel.set (iter, 0, "initfs", 1, "3M", 2, "initfs.jffs", -1);
			//listmodel.set (iter, 0, "initfs", 1, "3M", 2, "initfs.jffs", 3, "green", -1);

			//     listmodel.append (out iter);
			//    listmodel.set (iter, 0, "rootfs", 1, "52M", 2, "rootfs.jffs", -1);
		}

		public static bool readFunc() {
			weak string msg = p->get(0);

			if (msg != null && msg[0]!='\0') {
				stdout.printf("[<] msg received: %s\n", msg);
				string[] foo = msg.split(":",2);
				if (foo[1] != null) {
					switch(foo[0]) {
						case "bar":
							viewer.pb.fraction = foo[1].to_int() / 100;
							viewer.pb.text = foo[1]+"%";
							break;
						case "error":
							viewer.showMessage(foo[1], MessageType.ERROR);
							break;
						case "info":
							viewer.showMessage(foo[1], MessageType.INFO);
							break;
						default:
							stderr.printf("[E] Unknown message type\n");
							break;
					}
					//viewer.showMessage(msg, MessageType.INFO);
				}
				p->pop();
			}
			return true;
		}

		static SQueue *q = null;
		static SQueue *p = null;

		private void OnGetInformation() {
			msg("info:device");
		}

		private void OnConnect() {
			//msg("connect:device");
			OnStop();
			External.system("sudo 0xFFFF -Q &");
			p->close();
			q->close();
			p = q = null;
		}

		private void OnStop() {
			External.system("sudo pkill 0xFFFF");
		}

		private bool chk_queues() {
			if (p == null)
				p = SQueue.open("/tmp/0xFFFF.1", SQueueMode.OPEN);
			if (q == null)
				q = SQueue.open("/tmp/0xFFFF.2", SQueueMode.OPEN);
			if (p == null || q == null) {
				showMessage("Cannot connect to queues", MessageType.ERROR);
				return false;
			}
			return true;
		}

		public void msg(string str) {
			if (!chk_queues())
				return;
			if (q->push(str, 0)<1) {
				stderr.printf("Oops on push\n");
				q->free();
				q = null;
				p->free();
				p = null;
			}
		}

		static MainWindow viewer;

		static int main (string[] args) {
			Gtk.init (ref args);
			viewer = new MainWindow();
			if (args.length > 1)
				viewer.loadFile (args[1]);
			viewer.resize(600,400);
			viewer.set_position(WindowPosition.CENTER);
			viewer.delete_event.connect ((x,y) => { Gtk.main_quit(); return false; });
			setup_treeview(viewer.tv);
			viewer.show_all ();
			//	viewer.showMessage("This software is beta and does not guaranties correct functionality", MessageType.WARNING);
			Timeout.add(200, (SourceFunc)(readFunc));
			Gtk.main ();
			return 0;
		}

	}-
}