TSP: The Transport Sample Protocol



Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

gdisp_utils.c

Go to the documentation of this file.
00001 
00043 /*
00044  * System includes.
00045  */
00046 #include <stdio.h>
00047 #include <stdlib.h>
00048 #include <assert.h>
00049 #include <string.h>
00050 #include <time.h>
00051 #include <sys/time.h>
00052 #include <unistd.h>
00053 
00054 
00055 /*
00056  * GDISP+ includes.
00057  */
00058 #include "gdisp_kernel.h"
00059 #include "gdisp_prototypes.h"
00060 #include "gdisp_fonts.h"
00061 
00062 
00063 /*
00064  --------------------------------------------------------------------
00065                              STATIC ROUTINES
00066  --------------------------------------------------------------------
00067 */
00068 
00069 
00070 /*
00071  * Button with a label and a pixmap.
00072  */
00073 static GtkWidget*
00074 gdisp_createLabelPixmapBox (Kernel_T  *kernel,
00075                             GtkWidget *parent,
00076                             Pixmap_ID  pixmapId,
00077                             gchar     *labelData)
00078 {
00079 
00080   GtkWidget *hBox    = (GtkWidget*)NULL;
00081   GtkWidget *label   = (GtkWidget*)NULL;
00082   GtkWidget *wPixmap = (GtkWidget*)NULL;
00083   Pixmap_T  *pixmap  =  (Pixmap_T*)NULL;
00084 
00085   /*
00086    * Create horizontal box for nesting the pixmap and the label.
00087    */
00088   hBox = gtk_hbox_new(FALSE, /* homogeneous */
00089                       1      /* spacing     */ );
00090   gtk_container_set_border_width(GTK_CONTAINER(hBox),2);
00091 
00092 
00093   /*
00094    * Now, create the pixmap according to specified data.
00095    */
00096   pixmap = gdisp_getPixmapById(kernel,
00097                                pixmapId,
00098                                parent);
00099 
00100   wPixmap = gtk_pixmap_new(pixmap->pixmap,
00101                            pixmap->mask);
00102 
00103 
00104   /*
00105    * Create a label according to specified data.
00106    */
00107   label = gtk_label_new(labelData);
00108 
00109 
00110   /*
00111    * Pack the pixmap and label into the box.
00112    */
00113   gtk_box_pack_start(GTK_BOX(hBox),
00114                      wPixmap,
00115                      FALSE /* expand  */,
00116                      FALSE /* fill    */,
00117                      3     /* padding */);
00118 
00119   gtk_box_pack_start(GTK_BOX(hBox),
00120                      label,
00121                      FALSE /* expand  */,
00122                      FALSE /* fill    */,
00123                      3     /* padding */);
00124 
00125 
00126   /*
00127    * Show all widgets.
00128    */
00129   gtk_widget_show(wPixmap);
00130   gtk_widget_show(label);
00131   gtk_widget_show(hBox);
00132 
00133 
00134   /*
00135    * Return the packing box.
00136    */
00137   return(hBox);
00138 
00139 }
00140 
00141 
00142 /*
00143  --------------------------------------------------------------------
00144                              PUBLIC ROUTINES
00145  --------------------------------------------------------------------
00146 */
00147 
00148 
00149 /*
00150  * PGCD computation.
00151  */
00152 guint
00153 gdisp_computePgcd ( guint a,
00154                     guint b )
00155 {
00156 
00157   guint pgcd    = MAX(a,b);
00158   guint divisor = MIN(a,b);
00159   guint remain  = 1;
00160 
00161   while (remain != 0) {
00162 
00163     remain  = pgcd % divisor;
00164     pgcd    = divisor;
00165     divisor = remain;
00166 
00167   }
00168 
00169   return pgcd;
00170 
00171 }
00172 
00173 
00174 /*
00175  * Take here a time stamp expressed in 'nanoseconds'.
00176  */
00177 HRTime_T
00178 gdisp_getHRTime (void)
00179 {
00180   /*
00181    * Returned time is expressed in 'nanoseconds'.
00182    */
00183 #if defined(GDISP_SYSTEM_HAVE_GETHRTIME)
00184 
00185   return gethrtime();
00186 
00187 #else
00188 
00189   struct timeval tp;
00190 
00191   gettimeofday(&tp,(void*)NULL);
00192 
00193   return (  (HRTime_T)tp.tv_sec  * G_GINT64_CONSTANT(1000000000)
00194           + (HRTime_T)tp.tv_usec * G_GINT64_CONSTANT(      1000));
00195 
00196 #endif
00197 }
00198 
00199 
00200 
00201 /*
00202  * Sleep for a while expressed in 'microseconds'.
00203  */
00204 void
00205 gdisp_uSleep (guint uSeconds)
00206 {
00207 
00208 #if defined(GDISP_SYSTEM_HAVE_NANOSLEEP)
00209 
00210   struct timespec ts;
00211 
00212   ts.tv_sec  =  uSeconds / 1000000;
00213   ts.tv_nsec = (uSeconds % 1000000) * 1000;
00214 
00215   nanosleep(&ts,(struct timespec*)NULL);
00216 
00217 #else
00218 
00219 #if defined(GDISP_SYSTEM_HAVE_THREADSAFE_USLEEP)
00220 
00221   usleep(uSeconds);
00222 
00223 #endif /* GDISP_SYSTEM_HAVE_THREADSAFE_USLEEP */
00224 
00225 #endif /* GDISP_SYSTEM_HAVE_NANOSLEEP */
00226 
00227 }
00228 
00229 
00230 /*
00231  * Wait 'time2wait' and no more than 'time2wait', from 'timeStamp'.
00232  * ---> Requested 'time2wait' expressed in nano-seconds.
00233  */
00234 HRTime_T
00235 gdisp_waitTime (HRTime_T timeStamp,
00236                 HRTime_T time2wait)
00237 {
00238 
00239   struct timespec realDelta;
00240 
00241   /*
00242    * Current time 'now' is expressed in 'nanoseconds'.
00243    */
00244   HRTime_T now           = gdisp_getHRTime();
00245   HRTime_T realTime2wait = time2wait - (now - timeStamp);
00246 
00247   if (realTime2wait >= 0) {
00248 
00249     realDelta.tv_sec  = realTime2wait / _ONE_SECOND_IN_NANOSECONDS_;
00250     realDelta.tv_nsec = realTime2wait % _ONE_SECOND_IN_NANOSECONDS_;
00251 
00252     nanosleep(&realDelta,(struct timespec*)NULL);
00253 
00254   }
00255 
00256   return gdisp_getHRTime();
00257 
00258 }
00259 
00260 
00261 /*
00262  * Create a button bar.
00263  * By now, only 'apply' and 'done' buttons are available.
00264  */
00265 GtkWidget*
00266 gdisp_createButtonBar (Kernel_T   *kernel,
00267                        GtkWidget  *window,
00268                        GtkWidget **applyButton,
00269                        GtkWidget **doneButton)
00270 {
00271 
00272   GtkWidget *hBox       = (GtkWidget*)NULL;
00273   GtkWidget *hBoxButton = (GtkWidget*)NULL;
00274 
00275 
00276   /*
00277    * Create horizontal box for nesting all buttons.
00278    */
00279   hBox = gtk_hbox_new(FALSE, /* homogeneous */
00280                       1      /* spacing     */ );
00281   gtk_container_set_border_width(GTK_CONTAINER(hBox),2);
00282 
00283 
00284   /*
00285    * 'done' button.
00286    */
00287   if (doneButton != (GtkWidget**)NULL) {
00288 
00289     /*
00290      * Create a new button.
00291      */
00292     *doneButton = gtk_button_new();
00293     hBoxButton  = gdisp_createLabelPixmapBox(kernel,
00294                                              window,
00295                                              GD_PIX_doneButton,
00296                                              "Done");
00297     gtk_container_add(GTK_CONTAINER(*doneButton),
00298                       hBoxButton);
00299 
00300     gtk_box_pack_end(GTK_BOX(hBox),
00301                      *doneButton,
00302                      FALSE /* expand  */,
00303                      FALSE /* fill    */,
00304                      3     /* padding */);
00305 
00306     gtk_widget_show(*doneButton);
00307 
00308   }
00309 
00310 
00311   /*
00312    * 'apply' button.
00313    */
00314   if (applyButton != (GtkWidget**)NULL) {
00315 
00316     /*
00317      * Create a new button.
00318      */
00319     *applyButton = gtk_button_new();
00320     hBoxButton   = gdisp_createLabelPixmapBox(kernel,
00321                                               window,
00322                                               GD_PIX_applyButton,
00323                                               "Apply");
00324     gtk_container_add(GTK_CONTAINER(*applyButton),
00325                       hBoxButton);
00326 
00327     gtk_box_pack_end(GTK_BOX(hBox),
00328                      *applyButton,
00329                      FALSE /* expand  */,
00330                      FALSE /* fill    */,
00331                      3     /* padding */);
00332 
00333     gtk_widget_show(*applyButton);
00334 
00335   }
00336 
00337 
00338   /*
00339    * finally, show the horizontal packing box.
00340    */
00341   gtk_widget_show(hBox);
00342 
00343   return hBox;
00344 
00345 }
00346 
00347 
00348 /*
00349  * Font loading.
00350  */
00351 void
00352 gdisp_loadFonts(GdkFont *fonts[GD_FONT_MAX_SIZE][GD_FONT_MAX_TYPE])
00353 {
00354 
00355   gchar *fontNames[GD_FONT_MAX_SIZE][GD_FONT_MAX_TYPE] =
00356     { { GD_NormalFont_10_, GD_ItalicFont_10_, GD_FixedFont_10_ },
00357       { GD_NormalFont_12_, GD_ItalicFont_12_, GD_FixedFont_12_ },
00358       { GD_NormalFont_14_, GD_ItalicFont_14_, GD_FixedFont_14_ } };
00359 
00360   FontSize_T fontSize = GD_FONT_SMALL;
00361   FontType_T fontType = GD_FONT_NORMAL;
00362 
00363   /*
00364    * Back up to default font in case of problem.
00365    */
00366   for (fontSize=GD_FONT_SMALL; fontSize<GD_FONT_MAX_SIZE; fontSize++) {
00367 
00368     for (fontType=GD_FONT_NORMAL; fontType<GD_FONT_MAX_TYPE; fontType++) {
00369 
00370       fonts[fontSize][fontType] =
00371         gdk_font_load(fontNames[fontSize][fontType]);
00372 
00373       if (fonts[fontSize][fontType] == (GdkFont*)NULL)
00374         fonts[fontSize][fontType] = gdk_font_load(GD_DefaultFontName_);
00375 
00376     } /* loop on types */
00377 
00378   } /* loop on sizes */
00379 
00380 }
00381 
00382 
00383 /*
00384  * Font destruction.
00385  */
00386 void
00387 gdisp_destroyFonts(GdkFont *fonts[GD_FONT_MAX_SIZE][GD_FONT_MAX_TYPE])
00388 {
00389 
00390   FontSize_T fontSize = GD_FONT_SMALL;
00391   FontType_T fontType = GD_FONT_NORMAL;
00392 
00393   /*
00394    * Destroy all fonts.
00395    */
00396   for (fontSize=GD_FONT_SMALL; fontSize<GD_FONT_MAX_SIZE; fontSize++) {
00397 
00398     for (fontType=GD_FONT_NORMAL; fontType<GD_FONT_MAX_TYPE; fontType++) {
00399 
00400       gdk_font_unref(fonts[fontSize][fontType]);
00401 
00402     } /* loop on types */
00403 
00404   } /* loop on sizes */
00405 
00406 }
00407 
00408 
00409 /*
00410  * Get back pixmap according to message type.
00411  */
00412 GtkWidget*
00413 gdisp_getMessagePixmaps (Kernel_T  *kernel,
00414                          GtkWidget *parent,
00415                          Message_T  messageType,
00416                          gchar     *message)
00417 {
00418 
00419   GtkWidget *pixmapWidget = (GtkWidget*)NULL;
00420   GtkWidget *hBox         = (GtkWidget*)NULL;
00421   GtkWidget *label        = (GtkWidget*)NULL;
00422   Pixmap_T  *pixmap       =  (Pixmap_T*)NULL;
00423 
00424 
00425   /*
00426    * Start by creating a horizontal packing box.
00427    */
00428   hBox = gtk_hbox_new(FALSE, /* homogeneous */
00429                       3      /* spacing     */ );
00430   gtk_container_border_width(GTK_CONTAINER(hBox),0);
00431   gtk_widget_show(hBox);
00432 
00433   /*
00434    * Choose the correct logo according to the message type.
00435    * Avoid creating the pixmap each time the function is called.
00436    * Remember the pixmap address in the Kernel.
00437    */
00438   switch (messageType) {
00439 
00440   case GD_MESSAGE :
00441 
00442     pixmap = gdisp_getPixmapById(kernel,
00443                                  GD_PIX_info,
00444                                  parent);
00445     break;
00446 
00447   case GD_WARNING :
00448 
00449     pixmap = gdisp_getPixmapById(kernel,
00450                                  GD_PIX_warning,
00451                                  parent);
00452     break;
00453 
00454   case GD_ERROR   :
00455   default         :
00456 
00457     pixmap = gdisp_getPixmapById(kernel,
00458                                  GD_PIX_error,
00459                                  parent);
00460     break;
00461 
00462   }
00463 
00464   pixmapWidget = gtk_pixmap_new(pixmap->pixmap,
00465                                 pixmap->mask);
00466 
00467   gtk_widget_show(pixmapWidget);
00468 
00469   gtk_box_pack_start(GTK_BOX(hBox),
00470                      pixmapWidget,
00471                      FALSE /* expand  */,
00472                      FALSE /* fill    */,
00473                      0     /* padding */);
00474 
00475   /*
00476    * Create the label with the message.
00477    */
00478   label = gtk_label_new(message);
00479 
00480   gtk_box_pack_start(GTK_BOX(hBox),
00481                      label,
00482                      FALSE /* expand  */,
00483                      FALSE /* fill    */,
00484                      0     /* padding */);
00485 
00486   gtk_widget_show(label);
00487 
00488   return hBox;
00489 
00490 }
00491 
00492 
00493 /*
00494  * Get back pixmap according to provider identity.
00495  */
00496 Pixmap_T*
00497 gdisp_getProviderIdPixmap ( Kernel_T   *kernel,
00498                             GtkWidget  *parent,
00499                             guint       providerIdentity)
00500 {
00501 
00502   Pixmap_T  *pixmap = (Pixmap_T*)NULL;
00503   Pixmap_ID  pixmapTable[GD_MAX_PROVIDER_NUMBER] = { GD_PIX_magentaBall,
00504                                                      GD_PIX_cyanBall,
00505                                                      GD_PIX_yellowBall,
00506                                                      GD_PIX_blueBall,
00507                                                      GD_PIX_greenBall,
00508                                                      GD_PIX_redBall };
00509 
00510   /*
00511    * Get back the correct pixmap according to provider identity.
00512    * Create the pixmap if it does not already exist.
00513    */
00514   pixmap = gdisp_getPixmapById(kernel,
00515                                pixmapTable[providerIdentity],
00516                                parent);
00517 
00518   return pixmap;
00519 
00520 }
00521 
00522 
00523 /*
00524  * Convert a string list to a string table.
00525  * A string list is a list of coma-separated string as follows :
00526  *
00527  *           gchar *stringList      = "boat,car,bus,train";
00528  *
00529  * This string list is converted into a string table as follows :
00530  *
00531  *           gchar *stringTable[]   = { "boat", "car", "bus", "train" };
00532  *           guint  stringTableSize = 4;
00533  */
00534 void
00535 gdisp_getStringTableFromStringList ( gchar   *stringList,
00536                                      gchar ***stringTable,
00537                                      guint   *stringTableSize )
00538 {
00539 
00540   gchar  *delimiter =           ",";
00541   gchar **token     = (gchar**)NULL;
00542 
00543   /*
00544    * Initialisation.
00545    */
00546   *stringTable     = (gchar**)NULL;
00547   *stringTableSize = 0;
00548 
00549   /*
00550    * Checks.
00551    */
00552   if (stringList == (gchar*)NULL || strlen(stringList) == 0) {
00553 
00554     return;
00555 
00556   }
00557 
00558   /*
00559    * Use GLib string functions to perform the work.
00560    */
00561   *stringTable = g_strsplit(stringList,
00562                             delimiter,
00563                             (gint)0 /* split all the string */);
00564 
00565   /*
00566    * Compute the number of created strings in the table.
00567    */
00568   token = *stringTable;
00569   while (*token != (gchar*)NULL) {
00570 
00571     token++;
00572     (*stringTableSize)++; /* Increase the content, not the pointer */
00573 
00574   }
00575 
00576 }
00577 
00578 
00579 void
00580 gdisp_freeStringTable ( gchar ***stringTable,
00581                         guint   *stringTableSize )
00582 {
00583 
00584   /*
00585    * Use GLib string functions to perform the work.
00586    */
00587   g_strfreev(*stringTable);
00588 
00589   *stringTable     = (gchar**)NULL; 
00590   *stringTableSize = 0;
00591 
00592 }
00593 
00594 
00595 /*
00596  * Look into the string table and search in each string an occurence
00597  * of the string 'name'.
00598  */
00599 gchar*
00600 gdisp_strStr ( gchar   *name,
00601                gchar  **stringTable,
00602                guint    stringTableSize )
00603 {
00604 
00605   gchar **stringPtr = stringTable;
00606 
00607   /*
00608    * Run over the whole string table...
00609    */
00610   while (stringPtr < stringTable + stringTableSize) {
00611 
00612     /*
00613      * ... and try to find the requested "name".
00614      */
00615     if (strstr(name,*stringPtr) != (gchar*)NULL) {
00616 
00617       /*
00618        * Got you...
00619        */
00620       return *stringPtr;
00621 
00622     }
00623 
00624     stringPtr++;
00625 
00626   }
00627 
00628   /*
00629    * Nothing emerged from the process...
00630    */
00631   return (gchar*)NULL;
00632 
00633 }
00634 
00635 
00636 /*
00637  * Loop over all graphic plots of graphic pages, and apply
00638  * the given callback to each plots.
00639  */
00640 void
00641 gdisp_loopOnGraphicPlots ( Kernel_T  *kernel,
00642                            void     (*callback)(Kernel_T*,
00643                                                 Page_T*,
00644                                                 PlotSystemData_T*,
00645                                                 void*),
00646                            void      *userData )
00647 {
00648 
00649   PlotSystemData_T *plotSystemData    = (PlotSystemData_T*)NULL;
00650   PlotSystemData_T *plotSystemDataEnd = (PlotSystemData_T*)NULL;
00651   GList            *pageItem          =            (GList*)NULL;
00652   Page_T           *page              =           (Page_T*)NULL;
00653 
00654 
00655   /* ************************************************************
00656    *
00657    * BEGIN : Loop over all graphic plots of all pages, do actions...
00658    *
00659    * ************************************************************/
00660 
00661   pageItem = g_list_first(kernel->pageList);
00662   while (pageItem != (GList*)NULL) {
00663 
00664     page = (Page_T*)pageItem->data;
00665 
00666     plotSystemData    = page->pPlotSystemData;
00667     plotSystemDataEnd = page->pPlotSystemData + (page->pRows * page->pColumns);
00668 
00669     while (plotSystemData < plotSystemDataEnd) {
00670 
00671       (*callback)(kernel,
00672                   page,
00673                   plotSystemData,
00674                   userData),
00675 
00676       plotSystemData++;
00677 
00678     }
00679 
00680     pageItem = g_list_next(pageItem);
00681 
00682   }
00683 
00684   /* ************************************************************
00685    *
00686    * END.
00687    *
00688    * ************************************************************/
00689 
00690 }
00691 
00692 
00693 /*
00694  * Determine whether a point is inside a closed polygon.
00695  */
00696 gboolean
00697 gdisp_positionIsInsideZone ( PlotSystemZone_T *zone,
00698                              gdouble           x,
00699                              gdouble           y)
00700 {
00701 
00702   guint    i        = 0;
00703   guint    j        = 0;
00704   gboolean isInside = FALSE;
00705 
00706   for (i=0; i<zone->pszPointNb; i++) {
00707 
00708     j++;
00709 
00710     if (j == zone->pszPointNb) {
00711       j=0;
00712     }
00713 
00714     if (zone->pszY[i] < y && zone->pszY[j] >= y ||
00715         zone->pszY[j] < y && zone->pszY[i] >= y    ) {
00716 
00717       if (zone->pszX[i] + (y - zone->pszY[i]) /
00718           (zone->pszY[j] - zone->pszY[i]) *
00719           (zone->pszX[j] - zone->pszX[i]) < x) {
00720 
00721         isInside = (isInside == FALSE ? TRUE : FALSE);
00722 
00723       }
00724 
00725     }
00726 
00727   }
00728 
00729   return isInside;
00730 
00731 }
Framework Home Page.

Beware !! TSP wave is coming...