00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include <unistd.h>
00012 #include <laser-nav.h>
00013 #include "plot_gtk.h"
00014
00015 struct pln_point positions[FWIDTH*FHEIGHT];
00016 int poscount = 0;
00017
00021 void print_usage()
00022 {
00023 fprintf(file_err, "Used to plot points in GTK. GNU GPL v.2.\n"
00024 "CTU FEE in Prague - Department of "
00025 "Control Engineering\n\n");
00026 fprintf(file_err, "Usage : [options]\n\n");
00027 fprintf(file_err, " -g\t\tTest the GTK graphic part\n");
00028 fprintf(file_err, " -h\t\tThis help\n");
00029 fprintf(file_err, " -t\t\tText mode only\n");
00030 fprintf(file_err, "\n");
00031
00032 exit(0);
00033 }
00034
00041 int parseopt(int argc, char **argv)
00042 {
00043 int ch;
00044
00045 file_out = stdout;
00046 file_err = stderr;
00047
00048 optind = 0;
00049
00050 while ((ch = getopt(argc, argv, "ght")) != -1) {
00051 switch(ch) {
00052
00053 case 'g': option.opt_flag |= OPT_GTK_TEST;
00054 test_animation(argc, argv);
00055 break;
00056
00057 case 'h': print_usage(); break;
00058
00059 case 't': option.opt_flag |= OPT_TEXT_MODE;
00060 break;
00061 default: print_usage(); break;
00062 }
00063 }
00064
00065 return 0;
00066 }
00067
00068
00069
00070
00071
00072
00073
00074 void quit ()
00075 {
00076 gtk_exit (0);
00077 }
00078
00082
00083
00084
00085
00089 void load_pixmaps (GtkWidget *widget, struct moveable_obj *moveable,
00090 struct pixmap_obj *pixmaps)
00091 {
00092 int i = 0;
00093
00094
00095 while (pixmaps[i].xpm_filename) {
00096
00097 pixmaps[i].pixmap = gdk_pixmap_create_from_xpm(widget->window,
00098 NULL, NULL, pixmaps[i].xpm_filename);
00099 i++;
00100 }
00101
00102
00103
00104
00105
00106 pixmaps->seq_count = i;
00107 }
00108
00112 void load_scene_pixmap(GtkWidget *widget)
00113 {
00114
00115 load_pixmaps(widget, moveable, xpm_background);
00116 load_pixmaps(widget, moveable, xpm_sample);
00117 }
00118
00122 static gboolean key_event(GtkWidget *widget, GdkEventKey *event)
00123 {
00124 GdkModifierType state;
00125
00126 switch (event->keyval) {
00127
00128 case 65361:
00129 break;
00130
00131 case 65363:
00132 break;
00133
00134 case 65362:
00135 break;
00136
00137 case 65364:
00138 break;
00139
00140 case 65293:
00141 break;
00142
00143 case 'q':
00144 case 'Q':
00145 case 65307:
00146 quit();
00147 }
00148
00149 return TRUE;
00150 }
00151
00155 static gboolean button_event(GtkWidget *widget, GdkEventMotion *event)
00156 {
00157 int x, y;
00158 GdkModifierType state;
00159
00160
00161 if (event->is_hint)
00162 gdk_window_get_pointer (event->window, &x, &y, &state);
00163 else {
00164 x = event->x;
00165 y = event->y;
00166 state = event->state;
00167 }
00168
00169 return TRUE;
00170 }
00171
00175 static gboolean motion_notify_event( GtkWidget *widget, GdkEventMotion *event)
00176 {
00177 int x, y;
00178 GdkModifierType state;
00179
00180 if (event->is_hint)
00181 gdk_window_get_pointer (event->window, &x, &y, &state);
00182 else {
00183 x = event->x;
00184 y = event->y;
00185 state = event->state;
00186 }
00187
00188 return TRUE;
00189 }
00190
00191 static gint configure_event (GtkWidget *widget, GdkEventConfigure *event)
00192 {
00193
00194 if (xpm_scene) {
00195 gdk_pixmap_unref (xpm_scene);
00196 }
00197
00198
00199 xpm_scene = gdk_pixmap_new (widget->window,
00200 widget->allocation.width,
00201 widget->allocation.height,
00202 -1);
00203
00204 return TRUE;
00205 }
00206
00210 gint expose_event (GtkWidget *widget, GdkEventExpose *event)
00211 {
00212 int i;
00213
00214
00215 gdk_draw_pixmap (widget->window,
00216 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
00217 xpm_scene,
00218 event->area.x, event->area.y,
00219 event->area.x, event->area.y,
00220 event->area.width, event->area.height);
00221
00222 return FALSE;
00223 }
00224
00225 void (*repaint_objects)();
00226
00230 gint repaint (gpointer data)
00231 {
00232 GtkWidget *drawing_area = (GtkWidget *)data;
00233 GdkRectangle update_rect;
00234
00235
00236 (*repaint_objects)();
00237
00238
00239 update_rect.x = 0;
00240 update_rect.y = 0;
00241 update_rect.width = drawing_area->allocation.width;
00242 update_rect.height = drawing_area->allocation.height;
00243
00244
00245 gtk_widget_draw (drawing_area, &update_rect);
00246 }
00247
00251 void test_repaint()
00252 {
00253 int i;
00254
00255
00256 gdk_draw_drawable (xpm_scene,
00257 drawing_area->style->fg_gc[GTK_WIDGET_STATE (drawing_area)],
00258 xpm_background[0].pixmap,
00259 0, 0,
00260 0, 0,
00261 drawing_area->allocation.width,
00262 drawing_area->allocation.height);
00263 }
00264
00272 void init_animation(int argc, char *argv[], void (*repaint_func)())
00273 {
00274
00275 gtk_init (&argc, &argv);
00276
00277
00278 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
00279
00280 gtk_signal_connect (GTK_OBJECT (window), "destroy",
00281 GTK_SIGNAL_FUNC (quit), NULL);
00282
00283
00284 drawing_area = gtk_drawing_area_new ();
00285 gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_area),
00286 xpm_background[0].width,
00287 xpm_background[0].height);
00288 gtk_container_add (GTK_CONTAINER (window), drawing_area);
00289
00290 gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
00291 (GtkSignalFunc) expose_event, NULL);
00292 gtk_signal_connect (GTK_OBJECT(drawing_area),"configure_event",
00293 (GtkSignalFunc) configure_event, NULL);
00294 gtk_signal_connect (GTK_OBJECT (drawing_area), "motion_notify_event",
00295 (GtkSignalFunc) motion_notify_event, NULL);
00296 gtk_signal_connect (GTK_OBJECT(drawing_area),"button_press_event",
00297 (GtkSignalFunc) button_event, NULL);
00298 gtk_signal_connect (GTK_OBJECT(drawing_area),"button_release_event",
00299 (GtkSignalFunc) button_event, NULL);
00300 gtk_signal_connect (GTK_OBJECT(window),"key_press_event",
00301 (GtkSignalFunc) key_event, NULL);
00302
00303
00304 gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK
00305 | GDK_LEAVE_NOTIFY_MASK
00306 | GDK_BUTTON_PRESS_MASK
00307 | GDK_POINTER_MOTION_MASK
00308 | GDK_POINTER_MOTION_HINT_MASK);
00309
00310 gtk_widget_show(drawing_area);
00311 gtk_widget_show(window);
00312
00313
00314 gtk_timeout_add (SCENE_REFRESH, repaint, drawing_area);
00315 repaint_objects = repaint_func;
00316
00317
00318 load_scene_pixmap(window);
00319
00320
00321 gtk_main();
00322 }
00323
00327 void test_animation(int argc, char *argv[])
00328 {
00329 init_animation(argc, argv, test_repaint);
00330 }
00331
00335 void scene_repaint()
00336 {
00337 int i;
00338 int x;
00339
00340
00341 gdk_draw_drawable (xpm_scene,
00342 drawing_area->style->fg_gc[GTK_WIDGET_STATE (drawing_area)],
00343 xpm_background[0].pixmap,
00344 0, 0,
00345 0, 0,
00346 drawing_area->allocation.width,
00347 drawing_area->allocation.height);
00348
00349
00350 for (i=0; i<poscount; i++) {
00351 gdk_draw_drawable (xpm_scene,
00352 drawing_area->style->fg_gc[GTK_WIDGET_STATE (drawing_area)],
00353 xpm_sample[4].pixmap,
00354 0, 0,
00355 (int)(positions[i].x/FWIDTH*(632-2*BORDER)+BORDER)
00356 - xpm_sample[0].height/2,
00357 (int)((FHEIGHT-positions[i].y)/FHEIGHT*(452-2*BORDER)+BORDER)
00358 - xpm_sample[0].width/2,
00359 drawing_area->allocation.width,
00360 drawing_area->allocation.height);
00361 }
00362 }
00363
00364
00365
00366
00370 void initdata()
00371 {
00372 double a=(double)0.287430, b=(double)0.1, c;
00373
00374 pthread_mutex_init(&plot_mutex, NULL);
00375
00376
00377
00378
00379
00380 test_cal_position(positions, &poscount);
00381
00382
00383
00384 }
00385
00389 void destroydata()
00390 {
00391 pthread_mutex_destroy(&plot_mutex);
00392 }
00393
00400 int main(int _argc, char **_argv)
00401 {
00402 argc = _argc;
00403 argv = _argv;
00404
00405
00406 parseopt(argc, argv);
00407
00408
00409 initdata();
00410
00411 if (!(option.opt_flag & OPT_TEXT_MODE)) {
00412
00413 init_animation(argc, argv, scene_repaint);
00414 }
00415
00416
00417 destroydata();
00418
00419 return 0;
00420 }