Main Page | Data Structures | Directories | File List | Data Fields | Globals

tclSadie_app.c

Go to the documentation of this file.
00001 
00020 /* This file is part of tclSadie.
00021 
00022    tclSadie is free software; you can redistribute it and/or modify it
00023    under the terms of the GNU General Public License as published by
00024    the Free Software Foundation; either version 2 of the License, or
00025    (at your option) any later version.
00026 
00027    tclSadie is distributed in the hope that it will be useful, but
00028    WITHOUT ANY WARRANTY; without even the implied warranty of
00029    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00030    General Public License for more details.
00031 
00032    You should have received a copy of the GNU General Public License
00033    along with tclSadie; if not, write to the Free Software Foundation,
00034    Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.  */
00035 
00036 #if HAVE_CONFIG_H
00037 #include <config.h>
00038 #endif /* HAVE_CONFIG_H */
00039 #include <tcl.h>
00040 #include <tk.h>
00041 #include <sadie.h>
00042 #include "tclsadie.h"
00043 #if WITH_DMALLOC
00044 #include <dmalloc.h>
00045 #endif /* WITH_DMALLOC */
00046 
00048 extern int tclsadie_plotter (PIXEL * line, uint32_t nbnd, uint32_t npix,
00049                              const char *minxlbl, const char *maxxlbl,
00050                              int option, PIXEL gmin, PIXEL gmax, void *data);
00051 
00053 enum err_template_index
00054 {
00055   ERR_TKDIALOG, 
00056   ERR_WINDOW, 
00057   ERR_TITLE, 
00058   ERR_TEXT, 
00059   ERR_BITMAP, 
00060   ERR_DEFAULT, 
00061   ERR_STRING, 
00062   max_err_index  
00063 };
00064 
00071 static void
00072 dispose_template (tclsadie_cmd_skelp_t * template_handle)   /* O  free this. */
00073 {
00074   int i, objc;
00075   Tcl_Obj ** objv;
00076 
00077   if ((template_handle != NULL) && (*template_handle != NULL))
00078     {
00079       objc = (*template_handle)->len;
00080       objv = (*template_handle)->cmd;
00081       if (objv != NULL)
00082         {
00083           for (i = 0; i < objc; i++)
00084             {
00085               if (objv[i])
00086                 Tcl_DecrRefCount (objv[i]);
00087             }
00088           free (objv);
00089         }
00090       free (*template_handle);
00091       *template_handle = NULL;
00092     }
00093 }
00094 
00101 int
00102 dispose_private_data (void * rawdata)
00103 {
00104   tclsadie_app_datap_t thedata;
00105 
00106   if (rawdata == NULL)
00107     return 0;
00108   thedata = (tclsadie_app_datap_t) rawdata;
00109   dispose_template (&(thedata->log_refresh));
00110   dispose_template (&(thedata->err_popup));
00111   if (thedata->sadievar != NULL)
00112     Tcl_DecrRefCount (thedata->sadievar);
00113   if (thedata->sessionlog_canvas != NULL)
00114     Tcl_DecrRefCount (thedata->sessionlog_canvas);
00115   free (thedata);
00116   return 0;
00117 }
00118 
00127 void
00128 tclsadie_demolish_private_data (ClientData clientData)
00129 {
00130   (void) sad_remove_app_data();
00131 }
00132 
00141 static int
00142 make_refresh_template (tclsadie_cmd_skelp_t * refresh_handle)
00143 {
00144   tclsadie_cmd_skelp_t refresh = NULL;
00145   int err = TCL_OK;
00146 
00147   if (refresh_handle == NULL)
00148     return TCL_ERROR;
00149   refresh = malloc (sizeof (struct Tclsadie_cmd_skel));
00150   if (refresh == NULL)
00151     err = TCL_ERROR;
00152   else
00153     {
00154       refresh->cmd = malloc (sizeof (Tcl_Obj *));
00155       if (refresh->cmd == NULL)
00156         err = TCL_ERROR;
00157       else
00158         {
00159           *(refresh->cmd) = Tcl_NewStringObj (DEFAULT_SESSION_LOG_REFRESH, -1);
00160           if (*(refresh->cmd) == NULL)
00161             {
00162               err = TCL_ERROR;
00163               free (refresh->cmd);
00164             }
00165           else
00166             {
00167               Tcl_IncrRefCount (*(refresh->cmd));
00168               refresh->len = 1;
00169             }
00170         }
00171       if (err != TCL_OK)
00172         free (refresh);
00173     }
00174   *refresh_handle = (err == TCL_OK) ? refresh : NULL;
00175   return err;
00176 }
00177 
00187 static int
00188 make_popup_template (tclsadie_cmd_skelp_t * popup_handle)
00189 {
00190   tclsadie_cmd_skelp_t popup = NULL;
00191   Tcl_Obj ** pcmd;
00192   int i, j, n_null;
00193   int err = TCL_OK;
00194 
00195   if (popup_handle == NULL)
00196     return TCL_ERROR;
00197   popup = malloc (sizeof (struct Tclsadie_cmd_skel));
00198   if (popup == NULL)
00199     err = TCL_ERROR;
00200   else
00201     {
00202       pcmd = calloc (max_err_index, sizeof (Tcl_Obj *));
00203       if (pcmd == NULL)
00204         err = TCL_ERROR;
00205       else
00206         {
00207           pcmd[ERR_TKDIALOG] = Tcl_NewStringObj ("tk_dialog", -1);
00208           pcmd[ERR_WINDOW] = Tcl_NewStringObj (DEFAULT_ERR_POPUP, -1);
00209           pcmd[ERR_TITLE] = Tcl_NewStringObj ("Warning", -1);
00210           pcmd[ERR_TEXT] = NULL;                /* Placeholder NULL. */
00211           pcmd[ERR_BITMAP] = Tcl_NewStringObj ("warning", -1);
00212           pcmd[ERR_DEFAULT] = Tcl_NewIntObj (0);
00213           pcmd[ERR_STRING] = Tcl_NewStringObj ("OK", -1);
00214           n_null = 0;
00215           for (i = 0; i < max_err_index; i++)
00216             {
00217               if (pcmd[i] == NULL)
00218                 n_null++;
00219               else
00220                 Tcl_IncrRefCount (pcmd[i]);
00221             }
00222           if (n_null == 1)
00223             {
00224               popup->cmd = pcmd;
00225               popup->len = max_err_index;
00226             }
00227           else
00228             {
00229               err = TCL_ERROR; /* Must match the number of placeholders. */
00230               j = max_err_index;
00231               while (j)
00232                 {
00233                   if (pcmd[--j])
00234                     Tcl_DecrRefCount (pcmd[j]);
00235                 }
00236               free (pcmd);
00237             }
00238         }
00239       if (err != TCL_OK)
00240         free (popup);
00241     }
00242   *popup_handle = (err == TCL_OK) ? popup : NULL;
00243   return err;
00244 }
00245 
00257 int
00258 tclsadie_private_data_init (Tcl_Interp * interp)
00259 {
00260   tclsadie_app_datap_t data;
00261   int err = TCL_OK;
00262   
00263   data = malloc (sizeof (struct Tclsadie_app_data));
00264   if (data == NULL)
00265     return TCL_ERROR;
00266   data->main_interp = interp;
00267   data->sessionlog_canvas
00268     = Tcl_NewStringObj (DEFAULT_SESSION_LOG_CANVAS, -1);
00269   if (data->sessionlog_canvas == NULL)
00270     err = TCL_ERROR;
00271   else
00272     {
00273       Tcl_IncrRefCount (data->sessionlog_canvas);
00274       data->sadievar = Tcl_NewStringObj (SADIEVAR_ARRAYNAME, -1);
00275       if (data->sadievar == NULL)
00276         err = TCL_ERROR;
00277       else
00278         {
00279           Tcl_IncrRefCount (data->sadievar);
00280           err = make_refresh_template (&(data->log_refresh));
00281           if (err == TCL_OK)
00282             {
00283               err = make_popup_template (&(data->err_popup));
00284               if (err != TCL_OK)
00285                 dispose_template (&(data->log_refresh));
00286             }
00287           if (err != TCL_OK)
00288             Tcl_DecrRefCount (data->sadievar);
00289         }
00290       if (err != TCL_OK)
00291         Tcl_DecrRefCount (data->sessionlog_canvas);
00292     }
00293   if (err != TCL_OK)
00294     free (data);
00295   else if ((sad_register_data_destructor (dispose_private_data) != 0)
00296            || (sad_add_app_data (data) != 0))
00297     {
00298       err = TCL_ERROR;
00299       dispose_private_data (data);
00300     }
00301   else
00302     Tcl_CreateExitHandler (tclsadie_demolish_private_data, NULL);
00303   return err;
00304 }
00305 
00307 static const char spacer[] = ":   ";
00308 
00310 static const char messix[] = DEFAULT_MESSAGE_INDEX;
00311 
00326 static void
00327 update_message (Tcl_Interp * interp, Tcl_Obj * sadievar,
00328                 char option, char * msg)
00329 {
00330   char messbuf[SLEN];
00331   size_t nfree = SLEN;
00332   char *c = NULL;
00333   Tcl_Obj * txt = NULL;
00334   Tcl_Obj * index = NULL;
00335 
00336   if ((!interp) || (!msg) || (!sadievar) || (nfree == 0))
00337     return;
00338   c = messbuf;
00339   *(c++) = option;
00340   if ((--nfree) > sizeof (spacer))
00341     {
00342       strncpy (c, spacer, sizeof (spacer));
00343       nfree -= (sizeof (spacer) - 1);
00344       c = messbuf + sizeof (spacer);
00345       strncpy (c, msg, nfree);
00346       txt = Tcl_NewStringObj (messbuf, -1);
00347       if (txt != NULL)
00348         {
00349           Tcl_IncrRefCount (txt);
00350           index = Tcl_NewStringObj (messix, -1);
00351           if (index != NULL)
00352             {
00353               Tcl_IncrRefCount (index);
00354               Tcl_ObjSetVar2 (interp, sadievar, index, txt, TCL_GLOBAL_ONLY);
00355               Tcl_DecrRefCount (index);
00356             }
00357           Tcl_DecrRefCount (txt);
00358         }
00359     }
00360 }
00361 
00378 void
00379 tclsadie_warning_messenger (char option, char * msg, void * data)
00380 {
00381   tclsadie_app_datap_t private_data;
00382   Tcl_Interp * interp;
00383   Tcl_Obj * svar;
00384 
00385   if (data == NULL)
00386     return;
00387   private_data = (tclsadie_app_datap_t) data;
00388   interp = private_data->main_interp;
00389   svar = private_data->sadievar;
00390   if ((interp != NULL) && (svar != NULL))
00391     update_message (interp, svar, option, msg);
00392 }
00393 
00410 void
00411 tclsadie_error_messenger (char option, char * msg, void * data)
00412 {
00413   tclsadie_app_datap_t private_data;
00414   Tcl_Interp * interp;
00415   tclsadie_cmd_skelp_t popup;
00416   Tcl_Obj * svar;
00417   Tcl_Obj ** pcmd;
00418   int plen;
00419 
00420   if (data == NULL)
00421     return;
00422   private_data = (tclsadie_app_datap_t) data;
00423   interp = private_data->main_interp;
00424   popup = private_data->err_popup;
00425   svar = private_data->sadievar;
00426   if ((interp != NULL) && (popup != NULL) && (svar != NULL))
00427     {
00428       pcmd = popup->cmd;
00429       plen = popup->len;
00430       if ((pcmd != NULL) && (plen > 0))
00431         {
00432           pcmd[ERR_TEXT] = Tcl_NewStringObj (msg, -1);
00433           if (pcmd[ERR_TEXT] != NULL)
00434             {
00435               Tcl_IncrRefCount (pcmd[ERR_TEXT]);
00436               if (Tcl_EvalObjv (interp, plen, pcmd, TCL_EVAL_GLOBAL) == TCL_OK)
00437                 update_message (interp, svar, option, msg);
00438               Tcl_DecrRefCount (pcmd[ERR_TEXT]);
00439               pcmd[ERR_TEXT] = NULL;
00440             }
00441         }
00442     }
00443 }
00444 
00453 int
00454 tclsadie_app_init (void)
00455 {
00456   return ((sad_register_plotter_callback (tclsadie_plotter)
00457            || sad_register_creator_callback (ProgMeter_Create)
00458            || sad_register_updator_callback (ProgMeter_Update)
00459            || sad_register_destructor_callback (ProgMeter_Destroy)
00460            || sad_register_message_callback (SAD_ERROR,
00461                                              tclsadie_error_messenger)
00462            || sad_register_message_callback (SAD_WARNING,
00463                                              tclsadie_warning_messenger)
00464            || sad_register_message_callback (SAD_INFO,
00465                                              tclsadie_warning_messenger))
00466            || sad_register_message_callback (SAD_DEFAULT,
00467                                              tclsadie_warning_messenger))
00468           ? TCL_ERROR : TCL_OK;
00469 }

Generated on Fri Jul 8 14:55:01 2005 for tclSadie by  doxygen 1.4.2