00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "dev/leds.h"
00034 #include "display.h"
00035 #include "nodes.h"
00036 #include "node.h"
00037 #include "ether.h"
00038 #include "lib/list.h"
00039 #include "lib/memb.h"
00040 #include "sensor.h"
00041
00042 #include <gtk/gtk.h>
00043
00044 #include <sys/time.h>
00045 #include <stdlib.h>
00046 #include <stdio.h>
00047 #include <unistd.h>
00048
00049 static GdkPixmap *pixmap = NULL;
00050 static GtkWidget *drawing_area;
00051 static GdkFont *font;
00052
00053 #define DISPLAY_WIDTH 400
00054 #define DISPLAY_HEIGHT 400
00055
00056 #define BASESTATION_SIZE 4
00057
00058 #define MAPSCALE 20
00059 #define SCALE 2
00060
00061 #define MARK_SIZE 8
00062
00063 #define RADIO_SIZE 20
00064
00065 #define DOT_SIZE ether_strength()
00066 #define DOT_INTENSITY 3
00067
00068 struct dot {
00069 struct dot *next;
00070 int x, y;
00071 int destx, desty;
00072 int size;
00073 int intensity;
00074 };
00075
00076 MEMB(dotsmem, struct dot, 20000);
00077 LIST(dots);
00078 LIST(tempdots);
00079
00080 static int window_is_open;
00081
00082 static GdkGC *intensity_gcs[DOT_INTENSITY];
00083
00084 static GdkGC *intensity_clusterhead;
00085 static GdkGC *intensity_clusterhead_lightgray;
00086 static GdkGC *intensity_clusterhead_red;
00087
00088 static GdkGC *green, *red, *yellow, *black, *white;
00089
00090 static struct nodes_node *marked_node;
00091
00092
00093 void
00094 display_redraw(void)
00095 {
00096 int i;
00097 struct nodes_node *n;
00098 int x, y;
00099 struct dot *d;
00100
00101 if(!window_is_open) {
00102 return;
00103 }
00104
00105 gdk_draw_rectangle(pixmap,
00106 white,
00107 TRUE,
00108 0, 0,
00109 drawing_area->allocation.width,
00110 drawing_area->allocation.height);
00111
00112
00113 for(i = 0; i < nodes_num(); ++i) {
00114 n = nodes_node(i);
00115 x = n->x;
00116 y = n->y;
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 if(n == marked_node) {
00129 gdk_draw_arc(pixmap,
00130 red,
00131 FALSE,
00132 x * SCALE - MARK_SIZE * SCALE,
00133 y * SCALE - MARK_SIZE * SCALE,
00134 MARK_SIZE * 2 * SCALE, MARK_SIZE * 2 * SCALE,
00135 0, 360 * 64);
00136 }
00137
00138 }
00139
00140 for(i = 0; i < nodes_num(); ++i) {
00141 n = nodes_node(i);
00142 x = n->x;
00143 y = n->y;
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 {
00168
00169 if(strlen(n->text) > 0) {
00170 gdk_draw_string(pixmap,
00171 font,
00172 black,
00173 x * SCALE + 10,
00174 y * SCALE + 7,
00175 n->text);
00176
00177 }
00178 gdk_draw_rectangle(pixmap,
00179 black,
00180 TRUE,
00181 x * SCALE,
00182 y * SCALE,
00183 2, 2);
00184
00185
00186
00187
00188
00189
00190 if(n->leds & LEDS_GREEN) {
00191 gdk_draw_rectangle(pixmap,
00192 green,
00193 TRUE,
00194 x * SCALE + 2,
00195 y * SCALE,
00196 4, 4);
00197 }
00198 if(n->leds & LEDS_YELLOW) {
00199 gdk_draw_rectangle(pixmap,
00200 yellow,
00201 TRUE,
00202 x * SCALE,
00203 y * SCALE + 2,
00204 4, 4);
00205 }
00206 if(n->leds & LEDS_RED) {
00207 gdk_draw_rectangle(pixmap,
00208 red,
00209 TRUE,
00210 x * SCALE + 2,
00211 y * SCALE + 2,
00212 4, 4);
00213 }
00214 if(n->linex != 0 && n->liney != 0) {
00215 gdk_draw_line(pixmap,
00216 green,
00217 x * SCALE,
00218 y * SCALE,
00219 n->linex * SCALE,
00220 n->liney * SCALE);
00221 gdk_draw_rectangle(pixmap,
00222 green,
00223 TRUE,
00224 n->linex * SCALE - 2,
00225 n->liney * SCALE - 2,
00226 4, 4);
00227 }
00228
00229 if(n->radio_status) {
00230 gdk_draw_arc(pixmap,
00231 green,
00232 FALSE,
00233 x * SCALE - RADIO_SIZE * SCALE,
00234 y * SCALE - RADIO_SIZE * SCALE,
00235 RADIO_SIZE * 2 * SCALE, RADIO_SIZE * 2 * SCALE,
00236 0, 360 * 64);
00237 }
00238
00239
00240 }
00241
00242 }
00243
00244 for(d = list_head(dots); d != NULL; d = d->next) {
00245 gdk_draw_arc(pixmap,
00246 intensity_gcs[d->intensity - 1],
00247 FALSE,
00248 d->x * SCALE - d->size * SCALE,
00249 d->y * SCALE - d->size * SCALE,
00250 d->size * 2 * SCALE, d->size * 2 * SCALE,
00251 0, 360 * 64);
00252 }
00253
00254
00255 gtk_widget_draw(drawing_area, NULL);
00256
00257 }
00258
00259 void
00260 display_tick(void)
00261 {
00262 struct dot *d, *e;
00263 struct ether_packet *p;
00264
00265 if(!window_is_open) {
00266 return;
00267 }
00268
00269
00270
00271
00272
00273
00274 list_init(tempdots);
00275
00276 for(d = list_head(dots);
00277 d != NULL;
00278 d = e) {
00279 if(d != NULL) {
00280 e = d->next;
00281 } else {
00282 e = NULL;
00283 }
00284 if(d->size > 20) {
00285 d->size /= 2;
00286 } else {
00287 d->size -= 4;
00288 }
00289
00290 if(d->size > 0) {
00291 list_push(tempdots, d);
00292 } else {
00293 memb_free(&dotsmem, (void *)d);
00294 }
00295 }
00296 list_copy(dots, tempdots);
00297
00298
00299 for(p = ether_packets(); p != NULL; p = p->next) {
00300 d = (struct dot *)memb_alloc(&dotsmem);
00301
00302 if(d != NULL) {
00303 d->x = p->x;
00304 d->y = p->y;
00305 d->size = DOT_SIZE;
00306 d->intensity = DOT_INTENSITY;
00307 list_push(dots, d);
00308 }
00309 }
00310 }
00311
00312 static gint
00313 configure_event(GtkWidget *widget, GdkEventConfigure *event)
00314 {
00315 if(pixmap != NULL) {
00316 gdk_pixmap_unref(pixmap);
00317 }
00318
00319 pixmap = gdk_pixmap_new(widget->window,
00320 widget->allocation.width,
00321 widget->allocation.height,
00322 -1);
00323
00324 if(pixmap == NULL) {
00325 printf("gdk_pixmap_new == NULL\n");
00326 exit(1);
00327 }
00328 gdk_draw_rectangle(pixmap,
00329 widget->style->black_gc,
00330 TRUE,
00331 0, 0,
00332 widget->allocation.width,
00333 widget->allocation.height);
00334
00335 return TRUE;
00336 }
00337
00338
00339 static gint
00340 expose_event (GtkWidget * widget, GdkEventExpose * event)
00341 {
00342
00343 gdk_draw_pixmap(widget->window,
00344 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
00345 pixmap,
00346 event->area.x, event->area.y,
00347 event->area.x, event->area.y,
00348 event->area.width, event->area.height);
00349 return FALSE;
00350 }
00351
00352 static gint
00353 key_press_event (GtkWidget * widget, GdkEventKey * event)
00354 {
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365 if(event->keyval == 'q') {
00366 gtk_exit(0);
00367
00368 }
00369 if(event->keyval == 'p') {
00370 display_output_fig();
00371 }
00372 return TRUE;
00373 }
00374
00375 static gint
00376 key_release_event (GtkWidget * widget, GdkEventKey * event)
00377 {
00378 return TRUE;
00379 }
00380
00381 static gint
00382 button_press_event (GtkWidget * widget, GdkEventKey * event)
00383 {
00384 struct dot *d;
00385 struct sensor_data s;
00386 GdkModifierType state;
00387 int x, y;
00388
00389 gdk_window_get_pointer (event->window, &x, &y, &state);
00390
00391 x = ((GdkEventButton*)event)->x / SCALE;
00392 y = ((GdkEventButton*)event)->y / SCALE;
00393
00394 if(state & GDK_BUTTON1_MASK) {
00395 d = (struct dot *)memb_alloc(&dotsmem);
00396
00397 if(d != NULL) {
00398 d->x = x;
00399 d->y = y;
00400 d->size = sensor_strength();
00401 d->intensity = DOT_INTENSITY - 2;
00402 list_push(dots, d);
00403 }
00404 sensor_data_init(&s);
00405 s.pir = 1;
00406 s.button = 0;
00407 s.vib = 0;
00408 ether_send_sensor_data(&s, x, y, sensor_strength());
00409 } else if(state & GDK_BUTTON2_MASK) {
00410 sensor_data_init(&s);
00411 s.pir = 0;
00412 s.button = 1;
00413 s.vib = 0;
00414 if(marked_node != NULL) {
00415 ether_send_sensor_data(&s, marked_node->x, marked_node->y, 1);
00416 }
00417 } else if(state & GDK_BUTTON3_MASK) {
00418 sensor_data_init(&s);
00419 s.pir = 0;
00420 s.button = 0;
00421 s.vib = 1;
00422 if(marked_node != NULL) {
00423 ether_send_sensor_data(&s, marked_node->x, marked_node->y, 1);
00424 }
00425 }
00426
00427 return TRUE;
00428 }
00429
00430 static gint
00431 pointer_motion_event (GtkWidget * widget, GdkEventMotion * event)
00432 {
00433 struct dot *d;
00434 struct sensor_data s;
00435 GdkModifierType state;
00436
00437 int x, y;
00438 struct nodes_node *node, *closest;
00439 int nodex, nodey;
00440 unsigned long dist;
00441 int i;
00442
00443 if(event->is_hint) {
00444 return TRUE;
00445 }
00446
00447 gdk_window_get_pointer (event->window, &x, &y, &state);
00448 x /= SCALE;
00449 y /= SCALE;
00450
00451
00452 if(state & GDK_BUTTON1_MASK) {
00453 d = (struct dot *)memb_alloc(&dotsmem);
00454
00455 if(d != NULL) {
00456 d->x = x;
00457 d->y = y;
00458 d->size = sensor_strength();
00459 d->intensity = DOT_INTENSITY - 2;
00460 list_push(dots, d);
00461 }
00462 sensor_data_init(&s);
00463 s.pir = 1;
00464 ether_send_sensor_data(&s, x, y, sensor_strength());
00465 } else {
00466
00467
00468
00469 closest = NULL;
00470 dist = 0;
00471 for(i = 0; i < nodes_num(); ++i) {
00472 node = nodes_node(i);
00473 nodex = node->x;
00474 nodey = node->y;
00475
00476 if(closest == NULL ||
00477 (x - nodex) * (x - nodex) + (y - nodey) * (y - nodey) < dist) {
00478 dist = (x - nodex) * (x - nodex) + (y - nodey) * (y - nodey);
00479 closest = node;
00480 }
00481 }
00482 marked_node = closest;
00483 }
00484 return TRUE;
00485 }
00486
00487 static void
00488 quit(void)
00489 {
00490 gtk_exit(0);
00491 }
00492
00493 static void (* idle)(void);
00494 static gint
00495 idle_callback(gpointer data)
00496 {
00497 idle();
00498 return TRUE;
00499 }
00500
00501 static GdkGC *
00502 get_color(unsigned short r, unsigned short g, unsigned short b)
00503 {
00504 GdkGCValues values;
00505 GdkColor color;
00506
00507 color.pixel = 0;
00508 color.red = r;
00509 color.green = g;
00510 color.blue = b;
00511
00512 if(gdk_colormap_alloc_color(gdk_colormap_get_system(),
00513 &color, FALSE, TRUE)) {
00514 }
00515
00516 values.foreground = color;
00517
00518 return gdk_gc_new_with_values(drawing_area->window,
00519 &values,
00520 GDK_GC_FOREGROUND);
00521 }
00522
00523 static void
00524 stdin_callback(gpointer data, gint source, GdkInputCondition condition)
00525 {
00526 char buf[1000];
00527 int len;
00528
00529 len = read(STDIN_FILENO, &buf, sizeof(buf));
00530 printf("read len %d\n", len);
00531 buf[len] = 0;
00532 ether_send_serial(buf);
00533 }
00534
00535 void
00536 display_init(void (* idlefunc)(void), int time, int with_gui)
00537 {
00538 int i;
00539 GtkWidget *window;
00540 GtkWidget *vbox;
00541 GdkGCValues values;
00542 GdkColor color;
00543
00544 memb_init(&dotsmem);
00545 list_init(dots);
00546 list_init(tempdots);
00547
00548 gtk_init(NULL, NULL);
00549
00550 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
00551 gtk_window_set_title(GTK_WINDOW(window), "Contiki simulation display");
00552
00553 vbox = gtk_vbox_new(FALSE, 0);
00554 gtk_container_add(GTK_CONTAINER (window), vbox);
00555 gtk_widget_show(vbox);
00556
00557 gtk_signal_connect(GTK_OBJECT (window), "destroy",
00558 GTK_SIGNAL_FUNC (quit), NULL);
00559
00560 font = gdk_font_load("-*-courier-medium-r-*-*-12-*-*-*-*-*-iso8859-1");
00561
00562
00563
00564 drawing_area = gtk_drawing_area_new();
00565 gtk_drawing_area_size(GTK_DRAWING_AREA (drawing_area),
00566 DISPLAY_WIDTH,
00567 DISPLAY_HEIGHT);
00568 gtk_box_pack_start(GTK_BOX(vbox), drawing_area, TRUE, TRUE, 0);
00569
00570 gtk_widget_show(drawing_area);
00571
00572
00573
00574 gtk_signal_connect(GTK_OBJECT (drawing_area), "expose_event",
00575 (GtkSignalFunc) expose_event, NULL);
00576 gtk_signal_connect(GTK_OBJECT (drawing_area), "configure_event",
00577 (GtkSignalFunc) configure_event, NULL);
00578
00579
00580
00581 gtk_signal_connect(GTK_OBJECT (window), "key_press_event",
00582 (GtkSignalFunc) key_press_event, NULL);
00583 gtk_signal_connect(GTK_OBJECT (window), "key_release_event",
00584 (GtkSignalFunc) key_release_event, NULL);
00585
00586 gtk_signal_connect(GTK_OBJECT (window), "button_press_event",
00587 (GtkSignalFunc) button_press_event, NULL);
00588
00589 gtk_signal_connect(GTK_OBJECT (window), "motion_notify_event",
00590 (GtkSignalFunc) pointer_motion_event, NULL);
00591
00592 gtk_widget_set_events(drawing_area,GDK_KEY_PRESS_MASK
00593 | GDK_KEY_RELEASE_MASK | GDK_BUTTON_PRESS_MASK
00594 | GDK_POINTER_MOTION_MASK);
00595
00596
00597 if(with_gui) {
00598 gtk_widget_show(window);
00599 window_is_open = with_gui;
00600 }
00601
00602
00603 idle = idlefunc;
00604 gtk_timeout_add(time, idle_callback, NULL);
00605
00606 if(with_gui) {
00607
00608 for(i = 0; i < DOT_INTENSITY; ++i) {
00609 color.pixel = 0;
00610 color.red = 0;
00611 color.green = ((DOT_INTENSITY + 1) * 0xffff) / (i + 1);
00612 color.blue = ((DOT_INTENSITY + 1) * 0xffff) / (i + 1);
00613
00614 if(gdk_colormap_alloc_color(gdk_colormap_get_system(),
00615 &color, FALSE, TRUE)) {
00616 }
00617
00618 values.foreground = color;
00619
00620 intensity_gcs[i] = gdk_gc_new_with_values(drawing_area->window, &values,
00621 GDK_GC_FOREGROUND);
00622 }
00623
00624 color.pixel = 0;
00625 color.red = 0xbfff;
00626 color.green = 0xbfff;
00627 color.blue = 0xbfff;
00628
00629 if(gdk_colormap_alloc_color(gdk_colormap_get_system(),
00630 &color, FALSE, TRUE)) {
00631 }
00632
00633 values.foreground = color;
00634
00635 intensity_clusterhead = gdk_gc_new_with_values(drawing_area->window, &values,
00636 GDK_GC_FOREGROUND);
00637
00638 color.pixel = 0;
00639 color.red = 0xefff;
00640 color.green = 0xefff;
00641 color.blue = 0xefff;
00642
00643 if(gdk_colormap_alloc_color(gdk_colormap_get_system(),
00644 &color, FALSE, TRUE)) {
00645 }
00646
00647 values.foreground = color;
00648
00649 intensity_clusterhead_lightgray = gdk_gc_new_with_values(drawing_area->window, &values,
00650 GDK_GC_FOREGROUND);
00651
00652 color.pixel = 0;
00653 color.red = 0xffff;
00654 color.green = 0;
00655 color.blue = 0;
00656
00657 if(gdk_colormap_alloc_color(gdk_colormap_get_system(),
00658 &color, FALSE, TRUE)) {
00659 }
00660
00661 values.foreground = color;
00662
00663 intensity_clusterhead_red = gdk_gc_new_with_values(drawing_area->window, &values,
00664 GDK_GC_FOREGROUND);
00665
00666
00667 red = get_color(0xffff, 0, 0);
00668 green = get_color(0, 0xffff, 0);
00669 yellow = get_color(0xffff, 0xffff, 0);
00670 black = get_color(0, 0, 0);
00671 white = get_color(0xffff, 0xffff, 0xffff);
00672 }
00673
00674 gdk_input_add(STDIN_FILENO, GDK_INPUT_READ, stdin_callback, NULL);
00675 }
00676
00677 void
00678 display_run(void)
00679 {
00680 gtk_main();
00681 }
00682
00683 void
00684 display_output_fig(void)
00685 {
00686 int i;
00687 struct nodes_node *n;
00688 int x, y;
00689 int dot_radius = 75;
00690 int scale = 50;
00691 FILE *fp;
00692 char name[40];
00693 struct timeval tv;
00694
00695 gettimeofday(&tv, NULL);
00696 snprintf(name, sizeof(name), "network-%lu.fig", tv.tv_sec);
00697
00698 fp = fopen(name, "w");
00699 fprintf(fp, "#FIG 3.2\n"
00700 "Landscape\n"
00701 "Center\n"
00702 "Inches\n"
00703 "Letter\n"
00704 "100.00\n"
00705 "Single\n"
00706 "-2\n"
00707 "1200 2\n"
00708 );
00709
00710 for(i = 0; i < nodes_num(); ++i) {
00711 n = nodes_node(i);
00712 x = n->x * scale;
00713 y = n->y * scale;
00714
00715 fprintf(fp, "1 3 1 1 0 7 50 -1 0 4.000 1 0.0000 %d %d %d %d %d %d %d %d\n",
00716 x, y,
00717 dot_radius, dot_radius,
00718 x, y,
00719 x + dot_radius, y + dot_radius);
00720
00721 if(strlen(n->text) > 0) {
00722 fprintf(fp, "4 0 0 50 -1 16 18 0.0000 4 135 720 %d %d %s\\001\n",
00723 x + 2 * scale, y, n->text);
00724 }
00725
00726 if(n->linex != 0 && n->liney != 0) {
00727 fprintf(fp, "2 1 1 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2\n"
00728 "1 1 4.00 60.00 120.00\n"
00729 "%d %d %d %d\n",
00730 x, y,
00731 n->linex * scale, n->liney * scale);
00732 }
00733
00734 }
00735
00736 fclose(fp);
00737 }
00738