00001
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #if HAVE_CONFIG_H
00037 #include <config.h>
00038 #endif
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
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)
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;
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;
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 }