gitkrenderer.c

Go to the documentation of this file.
00001 
00019 #define GITK_LIB_C
00020 #define GITK_RENDERER_C
00021 
00022 #include "gitkincludes.h"
00023 
00024 
00025 gboolean gitkrnull_init(guint *argc, gchar ***argv);
00026 void gitkrnull_done(void);
00027 void gitkrnull_dialog_show(GitkDialogPtr dialog);
00028 void gitkrnull_dialog_hide(GitkDialogPtr dialog);
00029 void gitkrnull_event_loop_start(void);
00030 void gitkrnull_event_loop_end(void);
00031 
00032 
00037 gboolean gitk_renderer_init(guint * const argc, gchar *** const argv, gboolean info_only) {
00038   gchar *envvar;
00039 
00040   if(!gitk_renderer_activate(argc,argv)) { if(!info_only) { free(gitk_renderer_name);gitk_renderer_name=NULL; } }
00041   //-- if no (valid) renderer has been choosen yet, check for env-variable
00042   if(!gitk_renderer_name && (envvar=getenv("GITK_RENDERER"))!=NULL) { //-- use that renderer
00043     gitk_renderer_name=strdup(envvar);
00044     gitk_log1("selected renderer (env) : \"%s\"",gitk_renderer_name);
00045     if(!gitk_renderer_activate(argc,argv)) { if(!info_only) { free(gitk_renderer_name);gitk_renderer_name=NULL; } }
00046   }
00047   //-- if no (valid) renderer has been choosen yet, check if there is a link to 'libgitk-renderer-default.so'
00048   if(!gitk_renderer_name) {
00049     gitk_renderer_name=strdup("default");
00050     gitk_log1("selected renderer (def) : \"%s\"",gitk_renderer_name);
00051     if(!gitk_renderer_activate(argc,argv)) { if(!info_only) { free(gitk_renderer_name);gitk_renderer_name=NULL; } }
00052     else {
00053       char link_target[FILENAME_MAX],plugin_name[FILENAME_MAX];
00054       char *sptr;
00055       int res;
00056   
00057       gitk_log("checking for symlink");
00058       (void)snprintf(plugin_name,FILENAME_MAX,LIBDIR""G_DIR_SEPARATOR_S"libgitk-renderer-%s.so",gitk_renderer_name);
00059       if((res=readlink((const char *)plugin_name,link_target,FILENAME_MAX-1))!=-1) {
00060         link_target[res]='\0';
00061         free(gitk_renderer_name);
00062         gitk_log1("... is symlink to : \"%s\"",link_target);
00063         sptr=&link_target[17];
00064         while((*sptr!='.') && (*sptr!='\0')) sptr++;
00065         *sptr='\0';
00066         gitk_renderer_name=strdup(&link_target[17]);
00067         gitk_log1("real renderer name is : \"%s\"",gitk_renderer_name);
00068       }
00069       else {
00070         gitk_log1("... is not symlink : res=%d",res);
00071       }
00072     }
00073   }
00074   //-- if no (valid) renderer has been choosen yet, check which renderers are installed and
00075   //-- open one of them, this is for console launchers (the gitkLauncher will pass the correct renderer)
00076   if(!gitk_renderer_name) {
00077     gint numplugins=0;
00078     gchar *envvar,*fn;
00079     DIR *dirp=opendir(LIBDIR);
00080     struct dirent *dire;
00081     guint sl;
00082 
00083     gitk_log("scanning available renderers");
00084     
00085     //-- check number of installed plugins
00086     while((dire=readdir(dirp))!=NULL) {
00087       fn=dire->d_name;
00088       sl=strlen(fn);
00089       //-- if it starts and ends with defined strings
00090       if((sl>20) && !strncmp(fn,"libgitk-renderer-",17) && !strncmp(&fn[sl-3],".so",3)) {
00091         //-- renderer_name=fn[18...sl-3];
00092         gitk_log1("renderer : \"%s\"",fn);
00093         numplugins++;
00094       }
00095     }
00096     closedir(dirp);
00097     gitk_log1("%d renderers found",numplugins);
00098     //-- decide which one (if more then one is available) based on the contents
00099     //-- of the DISPLAY env-var (unset ? (text or audio) : (graphical))
00100     if((envvar=getenv("DISPLAY"))) {
00101       gitk_log1("envvar DISPLAY is : \"%s\"",envvar);
00102       //-- use a graphical renderer
00103       // contains(GITKR_INFO_MEDIA_DOMAIN,"image");
00104     }
00105     else {
00106       gitk_log("envvar DISPLAY is not set");
00107       //-- use a text or speech based renderer
00108       // contains(GITKR_INFO_MEDIA_DOMAIN,"text");
00109     }
00110     if(!gitk_renderer_activate(argc,argv)) { if(!info_only) { free((void *)gitk_renderer_name);gitk_renderer_name=NULL; } }
00111   }
00112   return(gitk_renderer_name!=NULL);
00113 }
00114 
00120 gboolean gitk_renderer_activate(guint * const argc, gchar *** const argv) {
00121   gboolean res=FALSE;
00122   
00123   g_assert(gitk_renderer==NULL);
00124   
00125   //-- try only to activate a renderer, if the renderer_name is not empty
00126   if(gitk_renderer_name && *gitk_renderer_name) {
00127     gitk_renderer=g_new0(GitkRenderer,1);
00128     //-- try only to activate a renderer, if we are not in check mode (renderer-name="dummy")
00129     if(!strncmp(gitk_renderer_name,"dummy",5)) {
00130       gitk_log("check mode activated");
00131       check_mode=TRUE;
00132       gitk_renderer->gitkr_init=(GitkrInitPtr)gitkrnull_init;
00133       gitk_renderer->gitkr_done=(GitkrDonePtr)gitkrnull_done;
00134       gitk_renderer->gitkr_event_loop_start=(GitkrEventLoopStartPtr)gitkrnull_dialog_show;
00135       gitk_renderer->gitkr_event_loop_end=(GitkrEventLoopEndPtr)gitkrnull_dialog_hide;
00136       gitk_renderer->gitkr_dialog_show=(GitkrElementsShowPtr)gitkrnull_event_loop_start;
00137       gitk_renderer->gitkr_dialog_hide=(GitkrElementsHidePtr)gitkrnull_event_loop_end;
00138       gitk_log("dummy renderer init okay");
00139       res=TRUE;
00140     }
00141     else {
00142       gchar plugin_name[FILENAME_MAX],*plugin_path;
00143       // load renderer
00144       //-- don't need to specify absolute location, dlopen finds everything in LD_LIBRAY_PATH/ld.so.conf
00145       snprintf(plugin_name,FILENAME_MAX,"libgitk-renderer-%s",gitk_renderer_name);
00146       //plugin_path=g_module_build_path(LIBDIR,plugin_name);
00147       //gitk_log1("load renderer from \"%s\"",plugin_path);
00148       gitk_log1("load renderer from \"%s\"",plugin_name);
00149       if((gitk_renderer->plugin=g_module_open(plugin_name,G_MODULE_BIND_LAZY))!=NULL) {
00150         gitk_log("renderer loaded");
00151         if(g_module_symbol(gitk_renderer->plugin,"gitkr_info"               ,(gpointer *)&gitk_renderer->gitkr_info) &&
00152            g_module_symbol(gitk_renderer->plugin,"gitkr_init"               ,(gpointer *)&gitk_renderer->gitkr_init) &&
00153            g_module_symbol(gitk_renderer->plugin,"gitkr_done"               ,(gpointer *)&gitk_renderer->gitkr_done) &&
00154            g_module_symbol(gitk_renderer->plugin,"gitkr_event_loop_start"   ,(gpointer *)&gitk_renderer->gitkr_event_loop_start) &&
00155            g_module_symbol(gitk_renderer->plugin,"gitkr_event_loop_end"     ,(gpointer *)&gitk_renderer->gitkr_event_loop_end) &&
00156            g_module_symbol(gitk_renderer->plugin,"gitkr_event_loop_restart" ,(gpointer *)&gitk_renderer->gitkr_event_loop_restart) &&
00157            g_module_symbol(gitk_renderer->plugin,"gitkr_dialog_show"        ,(gpointer *)&gitk_renderer->gitkr_dialog_show) &&
00158            g_module_symbol(gitk_renderer->plugin,"gitkr_dialog_hide"        ,(gpointer *)&gitk_renderer->gitkr_dialog_hide)
00159           ) {
00160           gitk_log("functions connected");
00161 #ifdef ENABLE_NLS
00162           {
00163             gchar *renderer_package_name;
00164             //-- definitely do this before gitk_renderer->gitkr_init() !
00165             renderer_package_name=gitk_renderer->gitkr_info(GITKR_INFO_PACKAGE);
00166             gitk_log1("renderer package is \"%s\"",renderer_package_name);
00167             (void)bindtextdomain(renderer_package_name, gitk_renderer->gitkr_info(GITKR_INFO_LOCALEDIR));
00168             (void)bind_textdomain_codeset(renderer_package_name,"UTF-8");
00169           }
00170 #endif
00171           if(gitk_renderer->gitkr_init(argc,argv)) {
00172             gitk_log("renderer init okay");
00173             res=TRUE;
00174           }
00175         }
00176         else gitk_err2("can't connect functions in renderer \"%s\": %s",gitk_renderer_name,g_module_error());
00177       }
00178       else gitk_log2("can't open renderer \"%s\": %s",gitk_renderer_name,g_module_error());
00179       g_free(plugin_path);
00180     }
00181   }
00182   else gitk_log("empty renderer name supplied");
00183   if(!res) gitk_renderer_done();
00184   return(res);
00185 }
00186 
00191 void gitk_renderer_done(void) {
00192   if(gitk_renderer) {
00193     if(gitk_renderer->plugin) {
00194       if(gitk_renderer->gitkr_done) gitk_renderer->gitkr_done();
00195       // This make the gtk+ renderer crash on programm exit
00196       // It not seems to be due to gtk+/gtk/gtkmain.c:
00197       //   gdk_event_handler_set ((GdkEventFunc)gtk_main_do_event, NULL, NULL);
00198       // but because of gtk+/gtk/gtkmain.c:
00199       //   g_atexit (gtk_exit_func);
00200       // which is triggered, when exiting the program. If already tried to reset
00201       // those handlers in gitk_renderer->gitkr_done();
00202       //
00203       g_module_close(gitk_renderer->plugin);
00204     }
00205     g_free(gitk_renderer);
00206     gitk_renderer=NULL;
00207   } 
00208 }
00209 
00210 
00211 /* dummy renderer (for make check) */
00212 
00216 gboolean gitkrnull_init(guint *argc, gchar ***argv) {
00217   return(TRUE);
00218 }
00219 
00223 void gitkrnull_done(void) {
00224 }
00225 
00229 void gitkrnull_dialog_show(GitkDialogPtr dialog) {
00230 }
00231 
00235 void gitkrnull_dialog_hide(GitkDialogPtr dialog) {
00236 }
00237 
00241 void gitkrnull_event_loop_start(void) {
00242 }
00243 
00247 void gitkrnull_event_loop_end(void) {
00248 }
00249 

Generated on Thu Oct 28 10:59:09 2004 for gitk by doxygen 1.3.6