commit | author | age
|
8c7455
|
1 |
// G4Term.cpp |
JS |
2 |
|
|
3 |
#include <gtk/gtk.h> |
|
4 |
#include "G4TrackIncl.h" |
|
5 |
#include <pthread.h> |
|
6 |
#include <time.h> |
|
7 |
#include <stdlib.h> |
|
8 |
#include <errno.h> |
|
9 |
#include "G4Term.h" |
|
10 |
#include "PingPong.h" |
|
11 |
#include "IncrDlg.h" |
|
12 |
#include "FrameDlg.h" |
|
13 |
#include "FilterDlg.h" |
|
14 |
#include "UnitsDlg.h" |
|
15 |
#include <string.h> |
|
16 |
#include "config.h" |
|
17 |
|
|
18 |
|
|
19 |
|
|
20 |
|
|
21 |
const char* piterm_version=VERSION; |
|
22 |
const char* piterm_comment="Terminal program to communicate with the Polhemus G4 Tracker"; |
|
23 |
|
|
24 |
enum {CNX_BUT,DNX_BUT,SINGLE_BUT,START_BUT,STOP_BUT,NUMBUTTONS}; |
|
25 |
pthread_t contThread; |
|
26 |
int gRunCont=0; |
|
27 |
int gConnected=0; |
|
28 |
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER; |
|
29 |
|
|
30 |
int isQuats=0; |
|
31 |
int sysId; |
|
32 |
|
|
33 |
|
|
34 |
|
|
35 |
typedef struct _THREADINFO { |
|
36 |
PingPong pp; |
|
37 |
GtkWidget* text; |
|
38 |
FILE* fCap; |
|
39 |
}THREADINFO; |
|
40 |
|
|
41 |
typedef struct _FILEINFO { |
|
42 |
FILE* f; |
|
43 |
char filename[200]; |
|
44 |
}FILEINFO; |
|
45 |
|
|
46 |
int main(int argc,char* argv[]){ |
|
47 |
|
|
48 |
|
|
49 |
GtkWidget* win; |
|
50 |
GtkWidget* butArr[NUMBUTTONS]; |
|
51 |
GtkWidget *cnx_but_box,*act_button_box,*vbox,*hbox,*cfg_button_box; |
|
52 |
GtkWidget* textview,*scrWin; |
|
53 |
GtkWidget *capture,*boresight,*unboresight,*rotate,*translate,*filter,*incr,*units,*clear,*about,*quit; |
|
54 |
GtkWidget* image; |
|
55 |
|
|
56 |
FILEINFO fi; |
|
57 |
fi.f=NULL; |
|
58 |
memset(fi.filename,0,sizeof(fi.filename)); |
|
59 |
|
|
60 |
gtk_init(&argc,&argv); |
|
61 |
|
|
62 |
// This should have defaulted to true, but it didn't |
|
63 |
g_object_set(gtk_settings_get_default(),"gtk-button_images",TRUE,NULL); |
|
64 |
|
|
65 |
win=gtk_window_new(GTK_WINDOW_TOPLEVEL); |
|
66 |
gtk_window_set_title(GTK_WINDOW(win),"Polhemus G4 Terminal"); |
|
67 |
gtk_container_set_border_width(GTK_CONTAINER(win),10); |
|
68 |
gtk_window_set_position(GTK_WINDOW(win),GTK_WIN_POS_CENTER); |
|
69 |
|
|
70 |
vbox=gtk_box_new(GTK_ORIENTATION_VERTICAL,10); |
|
71 |
gtk_box_set_homogeneous(GTK_BOX(vbox),FALSE); |
|
72 |
|
|
73 |
hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,10); |
|
74 |
gtk_box_set_homogeneous(GTK_BOX(hbox),FALSE); |
|
75 |
|
|
76 |
|
|
77 |
// connection buttons |
|
78 |
cnx_but_box=gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL); |
|
79 |
gtk_button_box_set_layout(GTK_BUTTON_BOX(cnx_but_box),GTK_BUTTONBOX_SPREAD); |
|
80 |
butArr[CNX_BUT]=gtk_button_new_from_stock(GTK_STOCK_CONNECT); |
|
81 |
butArr[DNX_BUT]=gtk_button_new_from_stock(GTK_STOCK_DISCONNECT); |
|
82 |
gtk_container_add(GTK_CONTAINER(cnx_but_box),butArr[CNX_BUT]); |
|
83 |
gtk_container_add(GTK_CONTAINER(cnx_but_box),butArr[DNX_BUT]); |
|
84 |
gtk_widget_set_sensitive(butArr[DNX_BUT],FALSE); |
|
85 |
|
|
86 |
g_signal_connect(butArr[CNX_BUT],"clicked",G_CALLBACK(OnCnx),butArr); |
|
87 |
g_signal_connect(butArr[DNX_BUT],"clicked",G_CALLBACK(OnDnx),butArr); |
|
88 |
|
|
89 |
gtk_box_pack_start(GTK_BOX(vbox),cnx_but_box,FALSE,FALSE,10); |
|
90 |
|
|
91 |
// action buttons |
|
92 |
act_button_box=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,10); |
|
93 |
butArr[SINGLE_BUT]=gtk_button_new_with_label("Single Frame"); |
|
94 |
butArr[START_BUT]=gtk_button_new_with_label("Start Continuous"); |
|
95 |
butArr[STOP_BUT]=gtk_button_new_with_label("Stop Continuous"); |
|
96 |
gtk_box_pack_start(GTK_BOX(act_button_box),butArr[SINGLE_BUT],TRUE,TRUE,10); |
|
97 |
gtk_box_pack_start(GTK_BOX(act_button_box),butArr[START_BUT],TRUE,TRUE,10); |
|
98 |
gtk_box_pack_start(GTK_BOX(act_button_box),butArr[STOP_BUT],TRUE,TRUE,10); |
|
99 |
gtk_box_pack_start(GTK_BOX(vbox),act_button_box,FALSE,FALSE,10); |
|
100 |
gtk_widget_set_sensitive(butArr[SINGLE_BUT],FALSE); |
|
101 |
gtk_widget_set_sensitive(butArr[START_BUT],FALSE); |
|
102 |
gtk_widget_set_sensitive(butArr[STOP_BUT],FALSE); |
|
103 |
|
|
104 |
|
|
105 |
g_object_set_data(G_OBJECT(butArr[START_BUT]),"stop_but",(gpointer)butArr[STOP_BUT]); |
|
106 |
|
|
107 |
|
|
108 |
|
|
109 |
|
|
110 |
|
|
111 |
// output window |
|
112 |
scrWin=gtk_scrolled_window_new(NULL,NULL); |
|
113 |
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrWin),GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC); |
|
114 |
gtk_widget_set_size_request(scrWin,700,500); |
|
115 |
textview=gtk_text_view_new(); |
|
116 |
gtk_text_view_set_editable(GTK_TEXT_VIEW(textview),FALSE); |
|
117 |
gtk_container_add(GTK_CONTAINER(scrWin),textview); |
|
118 |
gtk_box_pack_start(GTK_BOX(vbox),scrWin,TRUE,TRUE,10); |
|
119 |
|
|
120 |
g_object_set_data(G_OBJECT(butArr[SINGLE_BUT]),"file",&fi); |
|
121 |
g_object_set_data(G_OBJECT(butArr[START_BUT]),"file",&fi); |
|
122 |
g_signal_connect_swapped(butArr[SINGLE_BUT],"clicked",G_CALLBACK(OnSingle),textview); |
|
123 |
g_signal_connect_swapped(butArr[START_BUT],"clicked",G_CALLBACK(OnStartCont),textview); |
|
124 |
g_signal_connect(butArr[STOP_BUT],"clicked",G_CALLBACK(OnStopCont),(gpointer)butArr[START_BUT]); |
|
125 |
|
|
126 |
|
|
127 |
gtk_box_pack_start(GTK_BOX(hbox),vbox,TRUE,TRUE,10); |
|
128 |
|
|
129 |
//config buttons |
|
130 |
cfg_button_box=gtk_button_box_new(GTK_ORIENTATION_VERTICAL); |
|
131 |
gtk_button_box_set_layout(GTK_BUTTON_BOX(cfg_button_box),GTK_BUTTONBOX_CENTER); |
|
132 |
capture=gtk_button_new_with_label("Capture..."); |
|
133 |
image=gtk_image_new_from_stock(GTK_STOCK_FLOPPY,GTK_ICON_SIZE_BUTTON); |
|
134 |
gtk_button_set_image(GTK_BUTTON(capture),image); |
|
135 |
boresight=gtk_button_new_with_label("Boresight"); |
|
136 |
unboresight=gtk_button_new_with_label("Unboresight"); |
|
137 |
rotate=gtk_button_new_with_label("Frame Rotation"); |
|
138 |
translate=gtk_button_new_with_label("Frame Translation"); |
|
139 |
filter=gtk_button_new_with_label("Filters"); |
|
140 |
incr=gtk_button_new_with_label("Increments"); |
|
141 |
units=gtk_button_new_with_label("Units"); |
|
142 |
clear=gtk_button_new_from_stock(GTK_STOCK_CLEAR); |
|
143 |
about=gtk_button_new_from_stock(GTK_STOCK_ABOUT); |
|
144 |
quit=gtk_button_new_from_stock(GTK_STOCK_CLOSE); |
|
145 |
|
|
146 |
gtk_container_add(GTK_CONTAINER(cfg_button_box),capture); |
|
147 |
gtk_container_add(GTK_CONTAINER(cfg_button_box),boresight); |
|
148 |
gtk_container_add(GTK_CONTAINER(cfg_button_box),unboresight); |
|
149 |
gtk_container_add(GTK_CONTAINER(cfg_button_box),rotate); |
|
150 |
gtk_container_add(GTK_CONTAINER(cfg_button_box),translate); |
|
151 |
gtk_container_add(GTK_CONTAINER(cfg_button_box),filter); |
|
152 |
gtk_container_add(GTK_CONTAINER(cfg_button_box),incr); |
|
153 |
gtk_container_add(GTK_CONTAINER(cfg_button_box),units); |
|
154 |
gtk_container_add(GTK_CONTAINER(cfg_button_box),clear); |
|
155 |
gtk_container_add(GTK_CONTAINER(cfg_button_box),about); |
|
156 |
gtk_container_add(GTK_CONTAINER(cfg_button_box),quit); |
|
157 |
|
|
158 |
gtk_box_pack_start(GTK_BOX(hbox),cfg_button_box,FALSE,FALSE,10); |
|
159 |
|
|
160 |
|
|
161 |
gtk_container_add(GTK_CONTAINER(win),hbox); |
|
162 |
|
|
163 |
g_signal_connect(capture,"clicked",G_CALLBACK(OnCapture),&fi); |
|
164 |
g_signal_connect(boresight,"clicked",G_CALLBACK(OnBoresight),(gpointer)1); |
|
165 |
g_signal_connect(unboresight,"clicked",G_CALLBACK(OnBoresight),(gpointer)0); |
|
166 |
g_signal_connect(rotate,"clicked",G_CALLBACK(OnRotate),NULL); |
|
167 |
g_signal_connect(translate,"clicked",G_CALLBACK(OnTranslate),NULL); |
|
168 |
g_signal_connect(filter,"clicked",G_CALLBACK(OnFilter),NULL); |
|
169 |
g_signal_connect(incr,"clicked",G_CALLBACK(OnIncr),NULL); |
|
170 |
g_signal_connect(clear,"clicked",G_CALLBACK(OnClear),(gpointer)textview); |
|
171 |
g_signal_connect(about,"clicked",G_CALLBACK(OnAbout),(gpointer)win); |
|
172 |
g_signal_connect(units,"clicked",G_CALLBACK(OnUnits),win); |
|
173 |
|
|
174 |
|
|
175 |
|
|
176 |
gtk_widget_show_all(win); |
|
177 |
|
|
178 |
|
|
179 |
g_signal_connect(win,"destroy",G_CALLBACK(OnClose),NULL); |
|
180 |
g_signal_connect(quit,"clicked",G_CALLBACK(OnClose),NULL); |
|
181 |
|
|
182 |
gtk_main(); |
|
183 |
|
|
184 |
if (fi.f) |
|
185 |
fclose(fi.f); |
|
186 |
|
|
187 |
return 0; |
|
188 |
|
|
189 |
} |
|
190 |
|
|
191 |
|
|
192 |
void OnCnx(GtkWidget* w,gpointer g){ |
|
193 |
|
|
194 |
int rv; |
|
195 |
GtkWidget* mb,*fdlg; |
|
196 |
GtkWidget** buttons=(GtkWidget**)g; |
|
197 |
gchar* filename; |
|
198 |
GtkFileFilter* filter1,*filter2; |
|
199 |
|
|
200 |
// query for the source config file to use |
|
201 |
fdlg=gtk_file_chooser_dialog_new("Choose Source Configuration File",NULL,GTK_FILE_CHOOSER_ACTION_OPEN, |
|
202 |
GTK_STOCK_OK,GTK_RESPONSE_ACCEPT,GTK_STOCK_CANCEL,GTK_RESPONSE_CANCEL,NULL); |
|
203 |
|
|
204 |
filter1=gtk_file_filter_new(); |
|
205 |
gtk_file_filter_add_pattern(filter1,"*.g4c"); |
|
206 |
gtk_file_filter_set_name(filter1,"G4 Source Cfg File"); |
|
207 |
filter2=gtk_file_filter_new(); |
|
208 |
gtk_file_filter_add_pattern(filter2,"*.*"); |
|
209 |
gtk_file_filter_set_name(filter2,"All Files"); |
|
210 |
|
|
211 |
|
|
212 |
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fdlg),filter1); |
|
213 |
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fdlg),filter2); |
|
214 |
if (gtk_dialog_run(GTK_DIALOG(fdlg))==GTK_RESPONSE_CANCEL){ |
|
215 |
gtk_widget_destroy(fdlg); |
|
216 |
return; |
|
217 |
} |
|
218 |
|
|
219 |
filename=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fdlg)); |
|
220 |
gtk_widget_destroy(fdlg); |
|
221 |
if (filename==NULL) |
|
222 |
return; |
|
223 |
|
|
224 |
|
|
225 |
|
|
226 |
// connect to G4 |
|
227 |
rv=g4_init_sys(&sysId,filename,NULL); |
|
228 |
g_free(filename); |
|
229 |
if (rv!=G4_ERROR_NONE){ |
|
230 |
mb=gtk_message_dialog_new(NULL,GTK_DIALOG_MODAL,GTK_MESSAGE_WARNING,GTK_BUTTONS_OK,"Error connecting to G4 Tracker\nError: %d",rv); |
|
231 |
gtk_dialog_run(GTK_DIALOG(mb)); |
|
232 |
gtk_widget_destroy(mb); |
|
233 |
return; |
|
234 |
} |
|
235 |
|
|
236 |
|
|
237 |
gtk_widget_set_sensitive(w,FALSE); |
|
238 |
gtk_widget_set_sensitive(buttons[DNX_BUT],TRUE); |
|
239 |
gtk_widget_set_sensitive(buttons[SINGLE_BUT],TRUE); |
|
240 |
gtk_widget_set_sensitive(buttons[START_BUT],TRUE); |
|
241 |
gConnected=1; |
|
242 |
|
|
243 |
} |
|
244 |
|
|
245 |
|
|
246 |
void OnDnx(GtkWidget* w,gpointer g){ |
|
247 |
|
|
248 |
GtkWidget** buttons=(GtkWidget**)g; |
|
249 |
|
|
250 |
// disconnect from G4 |
|
251 |
g4_close_tracker(); |
|
252 |
|
|
253 |
gtk_widget_set_sensitive(w,FALSE); |
|
254 |
gtk_widget_set_sensitive(buttons[CNX_BUT],TRUE); |
|
255 |
gtk_widget_set_sensitive(buttons[SINGLE_BUT],FALSE); |
|
256 |
gtk_widget_set_sensitive(buttons[START_BUT],FALSE); |
|
257 |
gtk_widget_set_sensitive(buttons[STOP_BUT],FALSE); |
|
258 |
gConnected=0; |
|
259 |
|
|
260 |
} |
|
261 |
|
|
262 |
void OnSingle(GtkWidget* textview,gpointer w){ |
|
263 |
|
|
264 |
GtkWidget* dlg; |
|
265 |
// get a list of actual hubs |
|
266 |
int hubs,res; |
|
267 |
G4_CMD_STRUCT cs; |
|
268 |
FILEINFO* pfi=(FILEINFO*)g_object_get_data(G_OBJECT(w),"file"); |
|
269 |
cs.cmd=G4_CMD_GET_ACTIVE_HUBS; |
|
270 |
cs.cds.id=G4_CREATE_ID(sysId,0,0); |
|
271 |
cs.cds.action=G4_ACTION_GET; |
|
272 |
cs.cds.pParam=NULL; |
|
273 |
g4_set_query(&cs); |
|
274 |
hubs=cs.cds.iParam; |
|
275 |
|
|
276 |
if (hubs==0){ |
|
277 |
dlg=gtk_message_dialog_new(NULL,GTK_DIALOG_MODAL,GTK_MESSAGE_WARNING,GTK_BUTTONS_OK, |
|
278 |
"No Hubs Detected"); |
|
279 |
gtk_dialog_run(GTK_DIALOG(dlg)); |
|
280 |
gtk_widget_destroy(dlg); |
|
281 |
return; |
|
282 |
} |
|
283 |
|
|
284 |
int* hubList=new int[hubs]; |
|
285 |
|
|
286 |
cs.cds.pParam=hubList; |
|
287 |
res=g4_set_query(&cs); |
|
288 |
G4_FRAMEDATA* fd=new G4_FRAMEDATA[hubs]; |
|
289 |
|
|
290 |
|
|
291 |
|
|
292 |
|
|
293 |
res=g4_get_frame_data(fd,sysId,hubList,hubs); |
|
294 |
res&=0xffff; |
|
295 |
if (res) |
|
296 |
OutputData(textview,fd,hubs,pfi->f); |
|
297 |
|
|
298 |
delete[] fd; |
|
299 |
delete[] hubList; |
|
300 |
} |
|
301 |
int count1=0; |
|
302 |
void OutputData(GtkWidget* textview,G4_FRAMEDATA* fd,int num,FILE* f){ |
|
303 |
|
|
304 |
GtkTextBuffer* buffer; |
|
305 |
GtkTextIter iter; |
|
306 |
GtkTextMark* mark; |
|
307 |
char buf[500]; |
|
308 |
int len; |
|
309 |
|
|
310 |
|
|
311 |
|
|
312 |
for (int i=0;i<num;i++){ |
|
313 |
for (int a=0;a<G4_SENSORS_PER_HUB;a++){ |
|
314 |
if (fd[i].stationMap & (0x01<<a)){ |
|
315 |
if (!isQuats) |
|
316 |
// {unsigned short fr=fd[i].sfd[a].pos[0]/39.37f*32767.0f/8.0f; |
|
317 |
// sprintf(buf,"Hub %d, Sensor %d, %u -- %u %.3f %.3f %.3f %.3f %.3f\n",fd[i].hub,a+1, |
|
318 |
// fd[i].frame,fr,fd[i].sfd[a].pos[1],fd[i].sfd[a].pos[2],fd[i].sfd[a].ori[0], |
|
319 |
// fd[i].sfd[a].ori[1],fd[i].sfd[a].ori[2]);} |
|
320 |
len=sprintf(buf,"Hub %d, Sensor %d, %u -- %.3f %.3f %.3f %.3f %.3f %.3f\n",fd[i].hub,a+1, |
|
321 |
fd[i].frame,fd[i].sfd[a].pos[0],fd[i].sfd[a].pos[1],fd[i].sfd[a].pos[2],fd[i].sfd[a].ori[0], |
|
322 |
fd[i].sfd[a].ori[1],fd[i].sfd[a].ori[2]); |
|
323 |
else |
|
324 |
len=sprintf(buf,"Hub %d, Sensor %d, %u -- %.3f %.3f %.3f %.3f %.3f %.3f %.3f\n",fd[i].hub,a+1, |
|
325 |
fd[i].frame, fd[i].sfd[a].pos[0],fd[i].sfd[a].pos[1],fd[i].sfd[a].pos[2],fd[i].sfd[a].ori[0], |
|
326 |
fd[i].sfd[a].ori[1],fd[i].sfd[a].ori[2],fd[i].sfd[a].ori[3]); |
|
327 |
|
|
328 |
//write to display |
|
329 |
buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); |
|
330 |
gtk_text_buffer_get_end_iter(buffer,&iter); |
|
331 |
gtk_text_buffer_insert(buffer,&iter,buf,-1); |
|
332 |
|
|
333 |
// scroll it down every 500 if cont |
|
334 |
if (!gRunCont || (!count1++%500==0)){ |
|
335 |
mark=gtk_text_buffer_create_mark(buffer,"mark",&iter,TRUE); |
|
336 |
gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(textview),mark); |
|
337 |
gtk_text_buffer_delete_mark(buffer,mark); |
|
338 |
if (f) |
|
339 |
fwrite(buf,1,len,f); |
|
340 |
} |
|
341 |
}// End if |
|
342 |
}// end a |
|
343 |
}// end i |
|
344 |
} |
|
345 |
|
|
346 |
|
|
347 |
void OnClear(GtkWidget* w,gpointer g){ |
|
348 |
|
|
349 |
GtkTextView* text=GTK_TEXT_VIEW(g); |
|
350 |
GtkTextBuffer* buffer=gtk_text_view_get_buffer(text); |
|
351 |
gtk_text_buffer_set_text(buffer,"",-1); |
|
352 |
} |
|
353 |
|
|
354 |
|
|
355 |
void OnStartCont(GtkWidget* textview,gpointer g){ |
|
356 |
|
|
357 |
GtkWidget* stopButton; |
|
358 |
// get hub list |
|
359 |
|
|
360 |
THREADINFO* pTi=new THREADINFO; |
|
361 |
FILEINFO* pfi=(FILEINFO*)g_object_get_data(G_OBJECT(g),"file"); |
|
362 |
pTi->pp.InitPingPong(sizeof(G4_FRAMEDATA)*50); |
|
363 |
pTi->text=textview; |
|
364 |
pTi->fCap=pfi->f; |
|
365 |
|
|
366 |
stopButton=GTK_WIDGET(g_object_get_data(G_OBJECT(g),"stop_but")); |
|
367 |
gtk_widget_set_sensitive(GTK_WIDGET(g),FALSE); |
|
368 |
gtk_widget_set_sensitive(stopButton,TRUE); |
|
369 |
|
|
370 |
|
|
371 |
|
|
372 |
|
|
373 |
gRunCont=1; |
|
374 |
pthread_create(&contThread,NULL,ContThreadFxn,&pTi->pp); |
|
375 |
|
|
376 |
g_timeout_add(4,(GSourceFunc)GetContData,pTi); |
|
377 |
//g_idle_add((GSourceFunc)GetContData,pTi); |
|
378 |
|
|
379 |
|
|
380 |
|
|
381 |
|
|
382 |
} |
|
383 |
|
|
384 |
|
|
385 |
void OnStopCont(GtkWidget* w,gpointer g){ |
|
386 |
|
|
387 |
GtkWidget* start=GTK_WIDGET(g); |
|
388 |
gRunCont=0; |
|
389 |
pthread_join(contThread,NULL); |
|
390 |
|
|
391 |
gtk_widget_set_sensitive(w,FALSE); |
|
392 |
gtk_widget_set_sensitive(start,TRUE); |
|
393 |
|
|
394 |
} |
|
395 |
|
|
396 |
#include <unistd.h> |
|
397 |
void* ContThreadFxn(void* p){ |
|
398 |
|
|
399 |
PingPong* pPP=(PingPong*)p; |
|
400 |
struct timespec ts,tr; |
|
401 |
G4_CMD_STRUCT cs; |
|
402 |
int num_hubs; |
|
403 |
G4_FRAMEDATA* fd; |
|
404 |
int* hubList; |
|
405 |
int actHubsRead; |
|
406 |
|
|
407 |
cs.cmd=G4_CMD_GET_ACTIVE_HUBS; |
|
408 |
cs.cds.id=G4_CREATE_ID(sysId,0,0); |
|
409 |
cs.cds.action=G4_ACTION_GET; |
|
410 |
cs.cds.pParam=NULL; |
|
411 |
g4_set_query(&cs); |
|
412 |
|
|
413 |
|
|
414 |
num_hubs=cs.cds.iParam; |
|
415 |
if (num_hubs==0){ |
|
416 |
gRunCont=0; |
|
417 |
return NULL; |
|
418 |
} |
|
419 |
hubList=new int[num_hubs]; |
|
420 |
cs.cds.pParam=hubList; |
|
421 |
g4_set_query(&cs); |
|
422 |
|
|
423 |
|
|
424 |
fd=new G4_FRAMEDATA[num_hubs]; |
|
425 |
int slRes; |
|
426 |
|
|
427 |
|
|
428 |
while (gRunCont){ |
|
429 |
pthread_mutex_lock(&mutex); |
|
430 |
actHubsRead=g4_get_frame_data(fd,sysId,hubList,num_hubs); |
|
431 |
actHubsRead&=0xffff; // just look at what's been read |
|
432 |
if (actHubsRead) |
|
433 |
pPP->WritePP((BYTE*)fd,sizeof(G4_FRAMEDATA)*actHubsRead); |
|
434 |
|
|
435 |
pthread_mutex_unlock(&mutex); |
|
436 |
|
|
437 |
ts.tv_sec=0; |
|
438 |
ts.tv_nsec=4000000; |
|
439 |
do { |
|
440 |
slRes=nanosleep(&ts,&tr); |
|
441 |
ts.tv_nsec=tr.tv_nsec; |
|
442 |
}while(slRes==-1); |
|
443 |
|
|
444 |
} |
|
445 |
|
|
446 |
delete[] fd; |
|
447 |
delete[] hubList; |
|
448 |
|
|
449 |
return NULL; |
|
450 |
} |
|
451 |
|
|
452 |
gboolean GetContData(gpointer g){ |
|
453 |
|
|
454 |
THREADINFO* pTi=(THREADINFO*)g; |
|
455 |
G4_FRAMEDATA fd[10];// max 10 hubs |
|
456 |
int len; |
|
457 |
int fd_size=sizeof(G4_FRAMEDATA); |
|
458 |
int num_hubs; |
|
459 |
if (gRunCont){ |
|
460 |
pthread_mutex_lock(&mutex); |
|
461 |
do { |
|
462 |
len=pTi->pp.ReadPP((BYTE*)fd); |
|
463 |
if (len){ |
|
464 |
num_hubs=len/fd_size; |
|
465 |
OutputData(pTi->text,fd,num_hubs,pTi->fCap); |
|
466 |
} |
|
467 |
}while (len); |
|
468 |
pthread_mutex_unlock(&mutex); |
|
469 |
} |
|
470 |
|
|
471 |
return gRunCont?TRUE:FALSE; |
|
472 |
} |
|
473 |
|
|
474 |
void OnBoresight(GtkWidget* w,gpointer g){ |
|
475 |
|
|
476 |
// set boresight to 0,0,0 |
|
477 |
int bore=(int)(long)g; |
|
478 |
float boreAng[3]={0.0f,0.0f,0.0}; |
|
479 |
G4_CMD_STRUCT cs; |
|
480 |
|
|
481 |
if (!gConnected) |
|
482 |
return; |
|
483 |
cs.cmd=G4_CMD_BORESIGHT; |
|
484 |
cs.cds.id=G4_CREATE_ID(sysId,-1,0); |
|
485 |
cs.cds.action=(bore==1)?G4_ACTION_SET:G4_ACTION_RESET; |
|
486 |
cs.cds.iParam=G4_TYPE_EULER_DEGREE; |
|
487 |
cs.cds.pParam=boreAng; |
|
488 |
g4_set_query(&cs); |
|
489 |
|
|
490 |
} |
|
491 |
|
|
492 |
void OnRotate(GtkWidget*,gpointer){ |
|
493 |
|
|
494 |
float aer[3]; |
|
495 |
G4_CMD_STRUCT cs; |
|
496 |
if (!gConnected) |
|
497 |
return; |
|
498 |
|
|
499 |
|
|
500 |
cs.cmd=G4_CMD_FOR_ROTATE; |
|
501 |
cs.cds.id=G4_CREATE_ID(sysId,0,0); |
|
502 |
cs.cds.action=G4_ACTION_GET; |
|
503 |
cs.cds.iParam=G4_TYPE_EULER_DEGREE; |
|
504 |
cs.cds.pParam=aer; |
|
505 |
g4_set_query(&cs); |
|
506 |
|
|
507 |
FrameDlg fdlg(FD_ROT,aer); |
|
508 |
int resp=fdlg.present_dlg(); |
|
509 |
if (resp==GTK_RESPONSE_OK){ |
|
510 |
fdlg.GetData(aer); |
|
511 |
cs.cds.action=G4_ACTION_SET; |
|
512 |
g4_set_query(&cs); |
|
513 |
|
|
514 |
} |
|
515 |
|
|
516 |
|
|
517 |
} |
|
518 |
|
|
519 |
void OnTranslate(GtkWidget* w,gpointer g){ |
|
520 |
|
|
521 |
float xyz[3]; |
|
522 |
G4_CMD_STRUCT cs; |
|
523 |
if (!gConnected) |
|
524 |
return; |
|
525 |
|
|
526 |
cs.cmd=G4_CMD_FOR_TRANSLATE; |
|
527 |
cs.cds.id=G4_CREATE_ID(sysId,0,0); |
|
528 |
cs.cds.action=G4_ACTION_GET; |
|
529 |
cs.cds.iParam=G4_TYPE_INCH; |
|
530 |
cs.cds.pParam=xyz; |
|
531 |
g4_set_query(&cs); |
|
532 |
|
|
533 |
FrameDlg dlg(FD_TRANS,xyz); |
|
534 |
int resp=dlg.present_dlg(); |
|
535 |
if (resp==GTK_RESPONSE_OK){ |
|
536 |
dlg.GetData(xyz); |
|
537 |
cs.cds.action=G4_ACTION_SET; |
|
538 |
g4_set_query(&cs); |
|
539 |
} |
|
540 |
|
|
541 |
|
|
542 |
} |
|
543 |
|
|
544 |
void OnFilter(GtkWidget*,gpointer){ |
|
545 |
|
|
546 |
G4_CMD_STRUCT cs; |
|
547 |
float filt[2][4]; |
|
548 |
|
|
549 |
if (!gConnected) |
|
550 |
return; |
|
551 |
|
|
552 |
// get current values and fill dialog |
|
553 |
cs.cmd=G4_CMD_FILTER; |
|
554 |
cs.cds.id=G4_CREATE_ID(sysId,0,0);// using hub 0 to fill dialog |
|
555 |
cs.cds.action=G4_ACTION_GET; |
|
556 |
cs.cds.iParam=G4_DATA_POS; |
|
557 |
cs.cds.pParam=filt[0]; |
|
558 |
g4_set_query(&cs); |
|
559 |
|
|
560 |
cs.cds.iParam=G4_DATA_ORI; |
|
561 |
cs.cds.pParam=filt[1]; |
|
562 |
g4_set_query(&cs); |
|
563 |
|
|
564 |
FilterDlg dlg(filt[0],filt[1]); |
|
565 |
int resp=dlg.present_dlg(); |
|
566 |
|
|
567 |
if (resp==GTK_RESPONSE_OK){ |
|
568 |
dlg.GetFilterData(filt[0],filt[1]); |
|
569 |
cs.cds.id=G4_CREATE_ID(sysId,-1,0); // set for all hubs |
|
570 |
cs.cds.action=G4_ACTION_SET; |
|
571 |
g4_set_query(&cs); |
|
572 |
|
|
573 |
cs.cds.iParam=G4_DATA_POS; |
|
574 |
cs.cds.pParam=filt[0]; |
|
575 |
g4_set_query(&cs); |
|
576 |
} |
|
577 |
|
|
578 |
} |
|
579 |
|
|
580 |
void OnIncr(GtkWidget* w,gpointer g){ |
|
581 |
|
|
582 |
float incr[2]; |
|
583 |
G4_CMD_STRUCT cs; |
|
584 |
|
|
585 |
cs.cmd=G4_CMD_INCREMENT; |
|
586 |
cs.cds.id=G4_CREATE_ID(sysId,-1,0); |
|
587 |
cs.cds.action=G4_ACTION_GET; |
|
588 |
cs.cds.iParam=G4_TYPE_INCH<<16|G4_TYPE_EULER_DEGREE; |
|
589 |
cs.cds.pParam=incr; |
|
590 |
|
|
591 |
g4_set_query(&cs); |
|
592 |
|
|
593 |
IncrDlg dlg(incr[0],incr[1]); |
|
594 |
int rv=dlg.present_dlg(); |
|
595 |
if (rv==GTK_RESPONSE_OK){ |
|
596 |
dlg.get_increments(incr[0],incr[1]); |
|
597 |
cs.cds.action=G4_ACTION_SET; |
|
598 |
g4_set_query(&cs); |
|
599 |
} |
|
600 |
|
|
601 |
} |
|
602 |
|
|
603 |
|
|
604 |
void OnUnits(GtkWidget* w,gpointer g){ |
|
605 |
|
|
606 |
G4_CMD_STRUCT cs; |
|
607 |
int p_unit,o_unit; |
|
608 |
cs.cmd=G4_CMD_UNITS; |
|
609 |
cs.cds.id=G4_CREATE_ID(sysId,0,0); // system wide |
|
610 |
cs.cds.action=G4_ACTION_GET; |
|
611 |
cs.cds.iParam=G4_DATA_POS; |
|
612 |
cs.cds.pParam=&p_unit; |
|
613 |
g4_set_query(&cs); |
|
614 |
|
|
615 |
cs.cds.iParam=G4_DATA_ORI; |
|
616 |
cs.cds.pParam=&o_unit; |
|
617 |
g4_set_query(&cs); |
|
618 |
|
|
619 |
UnitsDlg dlg(p_unit,o_unit); |
|
620 |
int resp=dlg.present_dlg(); |
|
621 |
if (resp==GTK_RESPONSE_OK){ |
|
622 |
dlg.GetUnits(p_unit,o_unit); |
|
623 |
cs.cds.action=G4_ACTION_SET; |
|
624 |
g4_set_query(&cs); |
|
625 |
cs.cds.iParam=G4_DATA_POS; |
|
626 |
cs.cds.pParam=&p_unit; |
|
627 |
g4_set_query(&cs); |
|
628 |
isQuats=o_unit==G4_TYPE_QUATERNION?1:0; |
|
629 |
} |
|
630 |
|
|
631 |
|
|
632 |
} |
|
633 |
|
|
634 |
|
|
635 |
|
|
636 |
void OnAbout(GtkWidget* w,gpointer g){ |
|
637 |
|
|
638 |
const gchar* authors[]={"James C. Farr, Polhemus Inc.",NULL}; |
|
639 |
|
|
640 |
gtk_show_about_dialog(GTK_WINDOW(g),"authors",authors,"comments",piterm_comment,"copyright","Copyright © Polhemus 2009-2013","program-name","G4Term","version",piterm_version, |
|
641 |
"website","http://www.polhemus.com/",NULL); |
|
642 |
|
|
643 |
} |
|
644 |
|
|
645 |
|
|
646 |
void OnCapture(GtkWidget* w,gpointer g){ |
|
647 |
|
|
648 |
GtkWidget* dlg; |
|
649 |
FILEINFO* pfi=(FILEINFO*)g; |
|
650 |
gchar* filename; |
|
651 |
int resp; |
|
652 |
|
|
653 |
if (pfi->f){ |
|
654 |
dlg=gtk_message_dialog_new(NULL,GTK_DIALOG_MODAL,GTK_MESSAGE_QUESTION,GTK_BUTTONS_YES_NO, |
|
655 |
"Data is presently being captured to %s.\n Would you like to stop capturing now?", |
|
656 |
pfi->filename); |
|
657 |
resp=gtk_dialog_run(GTK_DIALOG(dlg)); |
|
658 |
gtk_widget_destroy(dlg); |
|
659 |
if (resp==GTK_RESPONSE_YES){ |
|
660 |
fclose(pfi->f); |
|
661 |
pfi->f=NULL; |
|
662 |
} |
|
663 |
} |
|
664 |
else { |
|
665 |
dlg=gtk_file_chooser_dialog_new("Select a Capture File",NULL,GTK_FILE_CHOOSER_ACTION_SAVE, |
|
666 |
GTK_STOCK_SAVE,GTK_RESPONSE_ACCEPT,GTK_STOCK_CANCEL, |
|
667 |
GTK_RESPONSE_CANCEL,NULL); |
|
668 |
resp=gtk_dialog_run(GTK_DIALOG(dlg)); |
|
669 |
if (resp==GTK_RESPONSE_ACCEPT){ |
|
670 |
filename=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlg)); |
|
671 |
strcpy(pfi->filename,filename); |
|
672 |
g_free(filename); |
|
673 |
pfi->f=fopen(pfi->filename,"a"); |
|
674 |
} |
|
675 |
gtk_widget_destroy(dlg); |
|
676 |
|
|
677 |
} |
|
678 |
|
|
679 |
} |
|
680 |
|
|
681 |
void OnClose(GtkWidget* w,gpointer g){ |
|
682 |
|
|
683 |
if (gConnected) |
|
684 |
g4_close_tracker(); |
|
685 |
|
|
686 |
gtk_main_quit(); |
|
687 |
|
|
688 |
} |