1 : /* -*- Mode: C; tab-width: 3; indent-tabs-mode: t; c-basic-offset: 3 -*- */
2 : /*
3 : data_interpretor.c
4 : heraia - an hexadecimal file editor and analyser based on ghex
5 :
6 : (C) Copyright 2005 - 2007 Olivier Delhomme
7 : e-mail : heraia@delhomme.org
8 : URL : http://heraia.tuxfamily.org
9 :
10 : This program is free software; you can redistribute it and/or modify
11 : it under the terms of the GNU General Public License as published by
12 : the Free Software Foundation; either version 2, or (at your option)
13 : any later version.
14 :
15 : This program is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 :
20 : You should have received a copy of the GNU General Public License
21 : along with this program; if not, write to the Free Software
22 : Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 :
24 : #include "heraia_types.h"
25 :
26 : static guint which_endianness(heraia_window_t *main_window);
27 : static void interpret_as_date(heraia_window_t *main_window, DecodeDateFunc decode_it, gchar *widget_name, guint length, guint endianness);
28 : static void interpret_as_number(heraia_window_t *main_window, DecodeFunc decode_it, gchar *widget_name, guint length, guint endianness);
29 : static void close_data_interpretor_window(GtkWidget *widget, gpointer data);
30 : static void connect_data_interpretor_signals(heraia_window_t *main_window);
31 :
32 : /**
33 : * Determines which endianness is selected that is to say
34 : * which radio button is active in the window
35 : */
36 : static guint which_endianness(heraia_window_t *main_window)
37 1 : {
38 1 : GtkRadioButton *rb = GTK_RADIO_BUTTON(heraia_get_widget(main_window->xmls->main, "diw_rb_little_endian"));
39 1 : GtkWidget *activated = NULL;
40 1 : const gchar *widget_name = NULL;
41 :
42 1 : activated = gtk_radio_button_get_active_from_widget(rb);
43 1 : widget_name = gtk_widget_get_name(activated);
44 :
45 1 : if (g_ascii_strcasecmp(widget_name, "diw_rb_little_endian") == 0)
46 : {
47 1 : return H_DI_LITTLE_ENDIAN;
48 : }
49 0 : else if (g_ascii_strcasecmp(widget_name, "diw_rb_big_endian") == 0)
50 : {
51 0 : return H_DI_BIG_ENDIAN;
52 : }
53 0 : else if (g_ascii_strcasecmp(widget_name, "diw_rb_middle_endian") == 0)
54 : {
55 0 : return H_DI_MIDDLE_ENDIAN;
56 : }
57 : else
58 0 : return H_DI_LITTLE_ENDIAN; /* default interpretation case */
59 : }
60 :
61 :
62 : /**
63 : * Here we do interpret a date according to the decode_it function
64 : * We are assuming that main_window != NULL and main_window->xml != NULL
65 : * . heraia_window_t *main_window : the main structure
66 : * . DecodeDateFunc decode_it : a function to be called to decode the stream
67 : * . gchar *widget_name : the name of the widget where the result may go
68 : * . guint length : the length of the data to be decoded
69 : * . guint endianness : the endianness to be applied to the datas
70 : */
71 : static void interpret_as_date(heraia_window_t *main_window, DecodeDateFunc decode_it, gchar *widget_name, guint length, guint endianness)
72 4 : {
73 4 : gint result = 0; /* used to test different results of function calls */
74 4 : guchar *c = NULL; /* the character under the cursor */
75 4 : gchar *text = NULL;
76 4 : data_window_t *data_window = main_window->current_DW;
77 4 : GtkWidget *entry = heraia_get_widget(main_window->xmls->main, widget_name);
78 4 : date_and_time_t *mydate = NULL; /* date resulting of interpretation */
79 :
80 4 : c = (guchar *) g_malloc0 (sizeof(guchar) * length);
81 4 : mydate = (date_and_time_t *) g_malloc0 (sizeof(date_and_time_t));
82 :
83 4 : result = ghex_get_data(data_window, length, endianness, c);
84 :
85 4 : if (result == TRUE)
86 : {
87 4 : text = decode_it(c, mydate);
88 :
89 4 : if (text != NULL)
90 : {
91 4 : gtk_entry_set_text(GTK_ENTRY(entry), text);
92 : }
93 : else
94 : {
95 0 : text = g_strdup_printf("Something's wrong!");
96 0 : gtk_entry_set_text(GTK_ENTRY(entry), text);
97 : }
98 : }
99 : else
100 : {
101 0 : text = g_strdup_printf("Cannot interpret as a %d byte(s) date", length);
102 0 : gtk_entry_set_text(GTK_ENTRY(entry), text);
103 : }
104 :
105 4 : g_free(c);
106 4 : g_free(text);
107 4 : }
108 :
109 :
110 : /**
111 : * Here we do interpret a number according to the decode_it function
112 : * We are assuming that main_window != NULL and main_window->xml != NULL
113 : * . heraia_window_t *main_window : the main structure
114 : * . DecodeFunc decode_it : a function to be called to decode the stream
115 : * . gchar *widget_name : the name of the widget where the result may go
116 : * . guint length : the length of the data to be decoded
117 : * . guint endianness : the endianness to be applied to the datas
118 : */
119 : static void interpret_as_number(heraia_window_t *main_window, DecodeFunc decode_it, gchar *widget_name, guint length, guint endianness)
120 10 : {
121 10 : gint result = 0; /* used to test different results of function calls */
122 10 : guchar *c = NULL; /* the character under the cursor */
123 10 : gchar *text = NULL;
124 10 : data_window_t *data_window = main_window->current_DW; /* We allready know that it's not NULL */
125 10 : GtkWidget *entry = heraia_get_widget(main_window->xmls->main, widget_name); /* we might test the result as this is user input*/
126 :
127 10 : c = (guchar *) g_malloc0(sizeof(guchar) * length);
128 :
129 10 : result = ghex_get_data(data_window, length, endianness, c);
130 :
131 10 : if (result == TRUE)
132 : {
133 10 : text = decode_it(c);
134 :
135 10 : if (text != NULL)
136 : {
137 10 : gtk_entry_set_text(GTK_ENTRY(entry), text);
138 : }
139 : else
140 : {
141 0 : text = g_strdup_printf("Something's wrong!");
142 0 : gtk_entry_set_text(GTK_ENTRY(entry), text);
143 : }
144 : }
145 : else
146 : {
147 0 : text = g_strdup_printf("Cannot interpret as a %d byte(s) number", length);
148 0 : gtk_entry_set_text(GTK_ENTRY(entry), text);
149 : }
150 :
151 10 : g_free(c);
152 10 : g_free(text);
153 10 : }
154 :
155 :
156 : /**
157 : * "Emulates" the user click on the main window menu entry called DIMenu
158 : * whose aim is to display or hide the data interpretor window
159 : */
160 : static void close_data_interpretor_window(GtkWidget *widget, gpointer data)
161 0 : {
162 0 : heraia_window_t *main_window = (heraia_window_t *) data;
163 :
164 0 : if (main_window != NULL && main_window->xmls != NULL && main_window->xmls->main)
165 : {
166 0 : g_signal_emit_by_name(heraia_get_widget(main_window->xmls->main, "DIMenu"), "activate");
167 : }
168 0 : }
169 :
170 : /**
171 : * Refreshes the data interpretor window with the new values
172 : */
173 : void refresh_data_interpretor_window(GtkWidget *widget, gpointer data)
174 1 : {
175 1 : heraia_window_t *main_window = (heraia_window_t *) data; /* data interpretor window structure */
176 1 : guint endianness = 0;
177 :
178 1 : if (main_window != NULL && main_window->current_DW != NULL && main_window->win_prop->main_dialog->displayed == TRUE)
179 : {
180 1 : endianness = which_endianness(main_window); /* Endianness is computed only once here */
181 1 : interpret_as_number(main_window, decode_8bits_unsigned, "diw_8bits_us", 1, endianness);
182 1 : interpret_as_number(main_window, decode_8bits_signed, "diw_8bits_s", 1, endianness);
183 1 : interpret_as_number(main_window, decode_16bits_unsigned, "diw_16bits_us", 2, endianness);
184 1 : interpret_as_number(main_window, decode_16bits_signed, "diw_16bits_s", 2, endianness);
185 1 : interpret_as_number(main_window, decode_32bits_unsigned, "diw_32bits_us", 4, endianness);
186 1 : interpret_as_number(main_window, decode_32bits_signed, "diw_32bits_s", 4, endianness);
187 1 : interpret_as_number(main_window, decode_64bits_unsigned, "diw_64bits_us", 8, endianness);
188 1 : interpret_as_number(main_window, decode_64bits_signed, "diw_64bits_s", 8, endianness);
189 1 : interpret_as_number(main_window, decode_to_bits, "diw_base_bits", 1, endianness);
190 1 : interpret_as_number(main_window, decode_packed_BCD, "diw_base_bcd", 1, endianness);
191 :
192 1 : interpret_as_date(main_window, decode_C_date, "diw_C_date", 4, endianness);
193 1 : interpret_as_date(main_window, decode_dos_date, "diw_msdos_date", 4, endianness);
194 1 : interpret_as_date(main_window, decode_filetime_date, "diw_filetime_date", 8, endianness);
195 1 : interpret_as_date(main_window, decode_HFS_date, "diw_HFS_date", 4, endianness);
196 :
197 1 : refresh_all_ud_data_interpretor(main_window, endianness);
198 : }
199 1 : }
200 :
201 :
202 : /**
203 : * Connects data interpretor window's signals to the
204 : * right functions
205 : */
206 : static void connect_data_interpretor_signals(heraia_window_t *main_window)
207 1 : {
208 : /* When data interpretor's window is killed or destroyed */
209 1 : g_signal_connect(G_OBJECT(heraia_get_widget(main_window->xmls->main, "data_interpretor_window")), "delete_event",
210 : G_CALLBACK(delete_dt_window_event), main_window);
211 :
212 1 : g_signal_connect(G_OBJECT(heraia_get_widget(main_window->xmls->main, "data_interpretor_window")), "destroy",
213 : G_CALLBACK(destroy_dt_window), main_window);
214 :
215 : /* Menu "close" */
216 1 : g_signal_connect(G_OBJECT(heraia_get_widget(main_window->xmls->main, "diw_close_menu")), "activate",
217 : G_CALLBACK(close_data_interpretor_window), main_window);
218 :
219 : /* Radio Button "Little Endian" */
220 1 : g_signal_connect(G_OBJECT(heraia_get_widget(main_window->xmls->main, "diw_rb_little_endian")), "toggled",
221 : G_CALLBACK(refresh_data_interpretor_window), main_window);
222 :
223 : /* Radio Button "Big Endian" */
224 1 : g_signal_connect(G_OBJECT(heraia_get_widget(main_window->xmls->main, "diw_rb_big_endian")), "toggled",
225 : G_CALLBACK(refresh_data_interpretor_window), main_window);
226 :
227 : /* Radio Button "Middle Endian" */
228 1 : g_signal_connect(G_OBJECT(heraia_get_widget(main_window->xmls->main, "diw_rb_middle_endian")), "toggled",
229 : G_CALLBACK(refresh_data_interpretor_window), main_window);
230 1 : }
231 :
232 : /**
233 : * Inits the data interpretor structure and window
234 : * with default values
235 : * Should be called only once
236 : */
237 : void data_interpretor_init_interface(heraia_window_t *main_window)
238 1 : {
239 1 : data_window_t *dw = NULL;
240 :
241 1 : if (main_window != NULL)
242 : {
243 : /* Signals connections */
244 1 : connect_data_interpretor_signals(main_window);
245 :
246 1 : dw = main_window->current_DW;
247 :
248 1 : if (dw != NULL)
249 : {
250 : /* Says whether the data interpretor window is displayed or not */
251 : /* dw->window_displayed = H_DI_DISPLAYED; */
252 1 : dw->diw = heraia_get_widget(main_window->xmls->main, "data_interpretor_window");
253 1 : dw->tab_displayed = 0; /* the first tab */
254 : }
255 : }
256 1 : }
|