1 //	bfe2 - structure dump
2 //	Copyright (c) 1999-2003 Brand Huntsman and Lee Salzman
3 //
4 
5 
6 #include "common.h"
7 #include "functions.h"
8 
9 
10 //////////////////////////////////////////////////////////////////////////
11 
12 // global
13 s_structwin *structwin_head, *structwin_tail;
14 
15 // local
16 GtkCList *s_list;
17 
18 #define STRUCT_COLUM_TITLES 5
19 gchar *struct_column_titles[] = { "Open", "Base", "Elements", "Fields", "Name" };
20 #define SWIN_COLUM_TITLES 3
21 gchar *swin_column_titles[] = { "Base", "Field", "Value" };
22 #define LWIN_COLUM_TITLES 4
23 gchar *lwin_column_titles[] = { "Base", "Index", "Field", "Value" };
24 
25 //////////////////////////////////////////////////////////////////////////
26 
27 
refresh_structure(GtkWidget * widget,gpointer data)28 void refresh_structure( GtkWidget *widget, gpointer data ){
29 	structuresUpdateWindow((s_structwin *)data);
30 }
31 
32 
s_destroy_window(GtkWidget * widget,gpointer data)33 void s_destroy_window( GtkWidget *widget, gpointer data ){
34 	s_structwin *s;
35 
36 	s = (s_structwin *)gtk_clist_get_row_data(s_list, (int)data);
37 
38 	gtk_widget_destroy(s->window);
39 	s->window = NULL;
40 
41 	gtk_clist_set_text(s_list, (int)data, 0, NULL);
42 }
43 #define LEN_STRUCTWIN_TITLE LEN_STRUCT_NAME + 32
open_structure(GtkWidget * widget,gint row,gint column,GdkEventButton * event,gpointer data)44 void open_structure( GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data ){
45 	GtkWidget *vbox, *hbox;
46 	char title[LEN_STRUCTWIN_TITLE], n[LEN_NUMBER];
47 	s_structwin *s;
48 
49 	s = (s_structwin *)gtk_clist_get_row_data(s_list, row);
50 
51 	gtk_clist_unselect_row(s_list, row, column);
52 
53 	if(s->window) return;
54 
55 	// create window
56 	if(s->nr_elts == 1)
57 		snprintf(title, LEN_STRUCTWIN_TITLE, "BFE - Structure - %s", s->name);
58 	else snprintf(title, LEN_STRUCTWIN_TITLE, "BFE - List - %s", s->name);
59 	s->window = new_window(GTK_WINDOW_TOPLEVEL, title, 400, 300);
60 	gtk_signal_connect(GTK_OBJECT(s->window), "destroy", GTK_SIGNAL_FUNC(s_destroy_window), (gpointer)row);
61 	vbox = new_window_vbox(s->window);
62 
63 	// create list
64 	if(s->nr_elts > 1){
65 		// list
66 		s->list = new_list(vbox, LWIN_COLUM_TITLES, lwin_column_titles);
67 		gtk_clist_set_column_justification(s->list, 0, GTK_JUSTIFY_CENTER);
68 		gtk_clist_set_column_justification(s->list, 1, GTK_JUSTIFY_CENTER);
69 		gtk_clist_set_column_justification(s->list, 2, GTK_JUSTIFY_RIGHT);
70 		gtk_clist_set_column_justification(s->list, 3, GTK_JUSTIFY_LEFT);
71 	} else {
72 		// structure
73 		s->list = new_list(vbox, SWIN_COLUM_TITLES, swin_column_titles);
74 		gtk_clist_set_column_justification(s->list, 0, GTK_JUSTIFY_CENTER);
75 		gtk_clist_set_column_justification(s->list, 1, GTK_JUSTIFY_RIGHT);
76 		gtk_clist_set_column_justification(s->list, 2, GTK_JUSTIFY_LEFT);
77 	}
78 	gtk_clist_column_titles_show(s->list);
79 
80 	hbox = new_hbox(vbox, FALSE);
81 
82 	if(s->nr_elts > 1){
83 		new_label(hbox, FALSE, "Start", FALSE);
84 		s->start_text = new_text_entry(hbox, FALSE, 50);
85 		gtk_entry_set_text(GTK_ENTRY(s->start_text), "0");
86 		gtk_entry_set_max_length(GTK_ENTRY(s->start_text), 6);
87 
88 		new_label(hbox, FALSE, "Total", FALSE);
89 		s->total_text = new_text_entry(hbox, FALSE, 50);
90 		snprintf(n, LEN_NUMBER, "%u", s->nr_elts);
91 		gtk_entry_set_text(GTK_ENTRY(s->total_text), n);
92 		gtk_entry_set_max_length(GTK_ENTRY(s->total_text), 6);
93 	} else {
94 		new_gap(hbox);
95 	}
96 
97 	s->refresh_button = new_button(hbox, TRUE, " Refresh ");
98 	gtk_signal_connect(GTK_OBJECT(s->refresh_button), "clicked", GTK_SIGNAL_FUNC(refresh_structure), (gpointer)s);
99 
100 	s->close_button = new_button(hbox, FALSE, " Close ");
101 	gtk_signal_connect(GTK_OBJECT(s->close_button), "clicked", GTK_SIGNAL_FUNC(s_destroy_window), (gpointer)row);
102 
103 	gtk_clist_set_text(s_list, row, 0, "X");
104 
105 	structuresUpdateWindow(s);
106 }
107 
108 
109 //////////////////////////////////////////////////////////////////////////
110 
111 
structuresInit(GtkWidget * vbox)112 void structuresInit( GtkWidget *vbox ){
113 	s_list = new_list(vbox, STRUCT_COLUM_TITLES, struct_column_titles);
114 	gtk_clist_column_titles_show(s_list);
115 	gtk_clist_set_column_justification(s_list, 0, GTK_JUSTIFY_CENTER);
116 	gtk_clist_set_column_justification(s_list, 1, GTK_JUSTIFY_CENTER);
117 	gtk_clist_set_column_justification(s_list, 2, GTK_JUSTIFY_RIGHT);
118 	gtk_clist_set_column_justification(s_list, 3, GTK_JUSTIFY_RIGHT);
119 	gtk_clist_set_column_justification(s_list, 4, GTK_JUSTIFY_LEFT);
120 
121 	// setup selection handler
122 	gtk_signal_connect(GTK_OBJECT(s_list), "select_row", GTK_SIGNAL_FUNC(open_structure), NULL);
123 
124 	// structwin_head and structwin_tail are set in prefs.c
125 }
126 
127 
structuresUpdate()128 void structuresUpdate( ){
129 	char base[LEN_ADDRESS], elts[LEN_NUMBER], fields[LEN_NUMBER], *row[STRUCT_COLUM_TITLES];
130 	s_structwin *s;
131 	uint r;
132 
133 	row[0] = NULL;
134 	row[1] = base;
135 	row[2] = elts;
136 	row[3] = fields;
137 	// row[4] is set below
138 
139 	gtk_clist_freeze(s_list);
140 	gtk_clist_clear(s_list);
141 
142 	r = 0;
143 	for(s = structwin_head; s != NULL; s = s->next){
144 		snprintf(base, LEN_ADDRESS, "%.8X", s->base);
145 		snprintf(elts, LEN_NUMBER, "%u", s->nr_elts);
146 		snprintf(fields, LEN_NUMBER, "%u", s->nr_fields);
147 		row[4] = s->name;
148 		gtk_clist_append(s_list, row);
149 		gtk_clist_set_row_data(s_list, r, (gpointer)s);
150 		r++;
151 	}
152 	gtk_clist_thaw(s_list);
153 }
154 
155 
156 #define LEN_VALUE 20
structuresUpdateWindow(s_structwin * s)157 void structuresUpdateWindow( s_structwin *s ){
158 	char base[LEN_ADDRESS], n[LEN_NUMBER], value[LEN_VALUE];
159 	char *row0[LWIN_COLUM_TITLES], *row1[LWIN_COLUM_TITLES];
160 	uint x, size, offset, start, total;
161 	uint32 val, val1;
162 	s_field *f;
163 
164 	if(bochs_offline) return;
165 	if(s->window == NULL) return;
166 
167 	if(s->nr_elts > 1){
168 		if(sscanf(gtk_entry_get_text(GTK_ENTRY(s->start_text)), "%u", &start) != 1)
169 			start = 0;
170 		if(sscanf(gtk_entry_get_text(GTK_ENTRY(s->total_text)), "%u", &total) != 1)
171 			total = s->nr_fields;
172 
173 		if(total < 1 || total > s->nr_elts){
174 			total = s->nr_elts;
175 			snprintf(n, LEN_NUMBER, "%u", total);
176 			gtk_entry_set_text(GTK_ENTRY(s->total_text), n);
177 		}
178 		if(start < 0 || start >= s->nr_elts){
179 			start = 0;
180 			gtk_entry_set_text(GTK_ENTRY(s->start_text), "0");
181 		}
182 		if(start + total > s->nr_elts){
183 			total = s->nr_elts - start;
184 			snprintf(n, LEN_NUMBER, "%u", total);
185 			gtk_entry_set_text(GTK_ENTRY(s->total_text), n);
186 		}
187 	} else {
188 		start = 0;
189 		total = 1;
190 	}
191 
192 	for(f = s->fields_head, size = 0; f != NULL; f = f->next) size += f->size;
193 
194 	row0[0] = base;
195 	if(s->nr_elts == 1) row0[1] = NULL;
196 	else row0[1] = n;
197 	row0[2] = NULL;
198 	row0[3] = NULL;
199 
200 	row1[0] = NULL;
201 	if(s->nr_elts == 1){
202 		// row1[1] is set below
203 		row1[2] = value;
204 		row1[3] = NULL;
205 	} else {
206 		row1[1] = NULL;
207 		// row1[2] is set below
208 		row1[3] = value;
209 	}
210 
211 	gtk_clist_freeze(s->list);
212 	gtk_clist_clear(s->list);
213 
214 	for(x = start; x < start + total; x++){
215 		offset = 0;
216 
217 		snprintf(base, LEN_ADDRESS, "%.8X", s->base + (x * size));
218 		if(s->nr_elts > 1) snprintf(n, LEN_NUMBER, "(%u)", x);
219 		gtk_clist_append(s->list, row0);
220 
221 		for(f = s->fields_head; f != NULL; f = f->next){
222 		   if(f->name[0] == '\\' && f->name[1] == '\\'){
223 			if(s->nr_elts == 1) row1[1] = NULL;
224 			else row1[2] = NULL;
225 			value[0] = '\0';
226 			gtk_clist_append(s->list, row1);
227 		   } else {
228 			if(s->nr_elts == 1) row1[1] = f->name;
229 			else row1[2] = f->name;
230 			switch(f->size){
231 			case 1:
232 				fprintf(writepipe, "x /1bx 0x%X\n", s->base + (x * size) + offset);
233 				fscanf(readpipe, " %*s %*s 0x%X ", &val);
234 				snprintf(value, LEN_VALUE, "= %.2X", val);
235 				break;
236 			case 2:
237 				fprintf(writepipe, "x /1hx 0x%X\n", s->base + (x * size) + offset);
238 				fscanf(readpipe, " %*s %*s 0x%X ", &val);
239 				snprintf(value, LEN_VALUE, "= %.4X", val);
240 				break;
241 			case 4:
242 				fprintf(writepipe, "x /1wx 0x%X\n", s->base + (x * size) + offset);
243 				fscanf(readpipe, " %*s %*s 0x%X ", &val);
244 				snprintf(value, LEN_VALUE, "= %.8X", val);
245 				break;
246 			case 8:
247 				fprintf(writepipe, "x /2wx 0x%X\n", s->base + (x * size) + offset);
248 				fscanf(readpipe, " %*s %*s 0x%X 0x%X", &val, &val1);
249 				snprintf(value, LEN_VALUE, "= %.8X%.8X", val1, val);
250 				break;
251 			default:
252 				g_print("BFE: encountered a structure value with a non power of 2 size, or a size larger than 8 bytes.\n");
253 				snprintf(value, LEN_VALUE, "<invalid size>");
254 			}
255 
256 			prompt_read();
257 			offset += f->size;
258 			gtk_clist_append(s->list, row1);
259 		   }
260 		}
261 	}
262 	gtk_clist_thaw(s->list);
263 }
264 
265 
structuresEnablePage(gboolean v)266 void structuresEnablePage( gboolean v ){
267 	s_structwin *s;
268 
269 	gtk_widget_set_sensitive(GTK_WIDGET(s_list), v);
270 	for(s = structwin_head; s != NULL; s = s->next)
271 		if(s->window) gtk_widget_set_sensitive(s->refresh_button, v);
272 }
273