display.c

00001 /*
00002  * Copyright (c) 2004 Swedish Institute of Computer Science.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without modification,
00006  * are permitted provided that the following conditions are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright notice,
00009  *    this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright notice,
00011  *    this list of conditions and the following disclaimer in the documentation
00012  *    and/or other materials provided with the distribution.
00013  * 3. The name of the author may not be used to endorse or promote products
00014  *    derived from this software without specific prior written permission.
00015  *
00016  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
00017  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00018  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
00019  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00020  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00021  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
00024  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
00025  * OF SUCH DAMAGE.
00026  *
00027  * $Id: display.c,v 1.10 2010/02/23 18:44:08 adamdunkels Exp $
00028  *
00029  * Author: Adam Dunkels <adam@sics.se>
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     /*    if(n->type == NODE_TYPE_CLUSTERHEAD) {
00119       gdk_draw_arc(pixmap,
00120                    intensity_clusterhead_lightgray,
00121                    TRUE,
00122                    x * SCALE - DOT_SIZE * SCALE,
00123                    y * SCALE - DOT_SIZE * SCALE,
00124                    DOT_SIZE * 2 * SCALE, DOT_SIZE * 2 * SCALE,
00125                    0, 360 * 64);
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     /*    if(n->type == NODE_TYPE_CLUSTERHEAD) {
00146       gdk_draw_rectangle(pixmap,
00147                          intensity_clusterhead_red,
00148                          TRUE,
00149                          x * SCALE,
00150                          y * SCALE,
00151                          3, 3);
00152       for(j = 0; j < nodes_num(); ++j) {
00153         m = nodes_node(j);
00154         if(m->type == NODE_TYPE_CLUSTERHEAD &&
00155            ((x - m->x) * (x - m->x) +
00156             (y - m->y) * (y - m->y) < ether_strength() * ether_strength())) {
00157           gdk_draw_line(pixmap,
00158                         intensity_clusterhead,
00159                         x * SCALE,
00160                         y * SCALE,
00161                         m->x * SCALE,
00162                         m->y * SCALE);
00163           
00164           
00165         }
00166         }
00167         } else */ {
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       /*      gdk_draw_rectangle(pixmap,
00185                          drawing_area->style->white_gc,
00186                          TRUE,
00187                          x * SCALE,
00188                          y * SCALE,
00189                          2, 2);*/
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   /* Fade out active dots. The intensity value of each dot is counted
00270      downwards, and those dots that still have an intensity are placed
00271      in a temporary list. The temporary list is then copied into the
00272      list of all dots. */
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     /*    --(d->intensity);*/
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   /* Check if there are any new dots that should be placed in the list. */
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   /*  draw_screen();*/
00335   return TRUE;
00336 }
00337 
00338 /* Redraw the screen from the backing pixmap */
00339 static gint
00340 expose_event (GtkWidget * widget, GdkEventExpose * event)
00341 {
00342   /*  draw_screen();*/
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   /*  if(event->keyval == GDK_Shift_L ||
00356      event->keyval == GDK_Shift_R) {
00357      return TRUE;
00358   }
00359   keys[lastkey] = event->keyval;
00360   ++lastkey;
00361   if(lastkey >= NUMKEYS) {
00362     lastkey = 0;
00363     }*/
00364 
00365   if(event->keyval == 'q') {
00366     gtk_exit(0);
00367     /*   exit(0);*/
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     /* Find the closest node and mark it. */
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   /* Create the drawing area */
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   /* Signals used to handle backing pixmap */
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   /* Event signals */
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   /*  gtk_window_iconify(window);*/
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 /*-----------------------------------------------------------------------------------*/

Generated on Mon Apr 11 14:23:44 2011 for Contiki 2.5 by  doxygen 1.6.1