/* * Initial main.c file generated by Glade. Edit as required. * Glade will not overwrite this file. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include "interface.h" #include "callbacks.h" #include "support.h" #include "main.h" #include "init_fnc.h" #include "bookmark.h" #include "bdb.h" #include "do_connect.h" #include "gui_layout.h" #include "misc_gtk.h" #include "unode.h" #include "dcgui.xpm" GtkWidget *main_window=NULL; GtkWidget *dl_popup=NULL; GtkWidget *ul_popup=NULL; GtkWidget *q_popup=NULL; GtkWidget *user_popup=NULL; GtkWidget *start_dl_popup=NULL; GtkWidget *gdl_popup=NULL; GtkWidget *uaddr_popup=NULL; GtkWidget *done_popup=NULL; GtkWidget *fav_popup=NULL; /* sigchld handling */ extern void sig_chld(int); /* this string is "$HOME/.dctc" */ GString *dctc_main_dir=NULL; GString *dctc_dir; GString *dctc_active_client_file; GString *last_search[2]={NULL,NULL}; /* the last search is kept because if multi-hub search is enabled */ /* the command(s) must be resent */ gint last_search_tag=-1; /* when a search may start a multi-hub search, this value is the tag return by gtk_timeout_add */ int local_udp_socket=-1; /* this socket is used to send data to DCTC UDP communication socket, it is not bind to anything */ /***************************/ /* periodic internal tasks */ /***************************/ guint32 running_client_list_refresh_rate=0; /* delay between 2 refresh of the running client list (in 1/1000ths of seconds) */ guint running_client_list_refresh_rate_gta=0; /* handle returned by gtk_timeout_add for this refresh (only meaningful if the previous var !=0) */ guint32 favorite_client_autostart_check_rate=0; /* delay between 2 checks of the favorite client autostart (in 1/1000ths of seconds) */ guint favorite_client_autostart_check_rate_gta=0; /* handle returned by gtk_timeout_add for this refresh (only meaningful if the previous var !=0) */ int auto_start_disabled=FALSE; /* if TRUE, don't start new client for hub having the autostart flag set and without client */ int start_and_quit_enabled=FALSE; /* if TRUE, the GUI ends as soon as the -u or -g flag was processed */ int (*nickname_sort_function)(const char*, const char *)=strcmp; /* sensitivity of nickname sorting: button default value is OFF, we use strcmp */ char *use_this_hub_address=NULL; char *use_this_dchuburl=NULL; char *use_this_profile=NULL; /********************************************/ /* set the periodic call rate of a function */ /*************************************************************/ /* if new_rate=0, a current running periodic call is removed */ /*************************************************************/ void set_periodic_function_call_rate(guint32 *rate, guint *handle, GtkFunction function_to_call, gpointer xtra_data_to_send_to_function, guint32 new_rate) { if(new_rate==0) { /* disable periodic call */ if(*handle!=0) { gtk_timeout_remove(*handle); *handle=0; } *rate=0; } else { /* set a periodic call */ if(*rate!=new_rate) { /* at a different speed of the current one */ if(*handle!=0) gtk_timeout_remove(*handle); *rate=new_rate; *handle=gtk_timeout_add(new_rate, function_to_call, xtra_data_to_send_to_function); } } } /*******************************************************/ /* the following vars are used to manage I/O with dctc */ /*******************************************************/ DCTC_COM *current_dctc=NULL; GdkColor light_red, white, black, light_grey, green, light_orange; GdkColor greyDD,greyEE; static struct { unsigned int r,v,b; GdkColor *ptr; }alloc_color[]={ {0xffff,0x0,0x0,&light_red}, {0xffff,0xffff,0xffff,&white}, {0,0,0,&black}, {0xacac,0xacac,0xacac,&light_grey}, {0x0,0xffff,0x0,&green}, {0xffff,0xe7e7,0x8080,&light_orange}, {0xdddd,0xdddd,0xdddd,&greyDD}, {0xeeee,0xeeee,0xeeee,&greyEE}, {0,0,0,NULL} }; GtkStyle *sty_normal=NULL; GtkStyle *sty_hilight=NULL; static GPtrArray *label_blink_list=NULL; gchar **last_started_search=NULL; /* it is an array of gchar * produced by splitting the last entered search pattern */ LMP_ENTRY *unode_lmp=NULL; G_LOCK_DEFINE(unode_lmp); /*********************************/ /* add a label to the blink list */ /*********************************/ void blink_on(char *label_name) { GtkWidget *w; int i; int fnd=0; /* restore original label style */ w=get_widget_by_widget_name(label_name); if(w!=NULL) gtk_widget_set_style(w,sty_hilight); if(label_blink_list==NULL) label_blink_list=g_ptr_array_new(); for(i=0;ilen;i++) { char *t; t=g_ptr_array_index(label_blink_list,i); if((t!=NULL)&&(!strcmp(t,label_name))) { fnd=1; break; } } if(!fnd) { g_ptr_array_add(label_blink_list,strdup(label_name)); } } /**************************************/ /* remove a label from the blink list */ /**************************************/ void blink_off(char *label_name) { GtkWidget *w; int i; /* restore original label style */ w=get_widget_by_widget_name(label_name); if(w!=NULL) gtk_widget_set_style(w,sty_normal); if(label_blink_list!=NULL) { for(i=0;ilen;i++) { char *t; t=g_ptr_array_index(label_blink_list,i); if((t!=NULL)&&(!strcmp(t,label_name))) { g_ptr_array_remove_index_fast(label_blink_list,i); free(t); break; } } } } static gint do_label_blink(gpointer data) { static int status=0; /* 0= current style is normal, 1= current_style is hilight */ int i; if((label_blink_list!=NULL)&&(label_blink_list->len)!=0) { for(i=0;ilen;i++) { GtkWidget *w; w=get_widget_by_widget_name(g_ptr_array_index(label_blink_list,i)); if(w==NULL) continue; if(status==0) gtk_widget_set_style(w,sty_normal); else gtk_widget_set_style(w,sty_hilight); } } status=(status+1)&1; return TRUE; /* timeout again */ } /********************************************************************************************************/ /* Read the old seen hub list stored in .gnome/prog/SeenHubs and save it into the new Berkeley database */ /********************************************************************************************************/ static void convert_gnome_seen_list_to_bdb_seen_list(void) { void *iter; GString *tmp; tmp=g_string_new(""); /* we must get all keys: "/PROGNAME/SeenHubs/" */ /* the value of the keys are to put in buf and to process */ iter=gnome_config_init_iterator("/" PROGNAME "/SeenHubs/"); while(iter!=NULL) { char *dummy; char *buf; dummy=NULL; buf=NULL; iter=gnome_config_iterator_next(iter,&dummy,&buf); if(iter!=NULL) { /* dummy is the key (the hub address), buf is the line returned by hublist */ if((dummy!=NULL)&&(buf!=NULL)) { /* old gnome version of the hub list has a bug, the first byte of the key is missing */ /* we have to recompute a good one */ char *v; v=strchr(buf,'|')+1; tmp=g_string_assign(tmp,v); v=strchr(tmp->str,'|'); tmp=g_string_truncate(tmp,v-tmp->str); /* to ease future usage of values, the key and its value is stored with the trailing '\0' (==C string format)*/ set_key_data(seen_hub_db,tmp->str,tmp->len+1,buf,strlen(buf)+1); } } if(dummy!=NULL) g_free(dummy); if(buf!=NULL) g_free(buf); } gnome_config_clean_section("/" PROGNAME "/SeenHubs/"); gnome_config_sync(); g_string_free(tmp,TRUE); } /*********************************************************/ /* we don't want to receive SIGPIPE, SIGHUP and SIG_CHLD */ /*********************************************************/ static void set_sig(void) { struct sigaction act; sigset_t set; /* ignore SIGPIPE */ /* ignore SIGHUP */ sigemptyset(&set); sigaddset(&set,SIGPIPE); sigaddset(&set,SIGHUP); act.sa_handler=SIG_IGN; act.sa_mask=set; act.sa_flags=SA_RESTART; sigprocmask(SIG_UNBLOCK,&set,NULL); sigaction(SIGPIPE,&act,NULL); sigaction(SIGHUP,&act,NULL); /* handle SIGCHLD */ signal(SIGCHLD, sig_chld); /* Prevents zombies */ } static void start_dctc_client_from_huburl(char *dchub_url,char *profile) { GString *url; char *t; if(strncasecmp(dchub_url,"dchub://",strlen("dchub://"))) { gtk_timeout_add(4000,(void*)gtk_main_quit,NULL); gnome_error_dialog(_("Invalid dchub URL. it must start with dchub://")); gtk_main(); exit(1); } url=g_string_new(dchub_url+strlen("dchub://")); t=strchr(url->str,'/'); if(t!=NULL) { url=g_string_truncate(url,t-url->str); } if(url->len<3) /* 3 is perhaps not even enough to have a valid hostname, I don't know if a domain exists with only 1 letter */ { gtk_timeout_add(4000,(void*)gtk_main_quit,NULL); gnome_error_dialog(_("Invalid dchub URL. The URL is too small to be valid")); gtk_main(); exit(1); } start_a_new_dctc(url->str,0,profile); g_string_free(url,TRUE); } int main (int argc, char *argv[]) { char *path; GdkColormap *colormap; int i; #ifdef ENABLE_NLS bindtextdomain (PACKAGE, PACKAGE_LOCALE_DIR); textdomain (PACKAGE); #endif path=getenv("HOME"); dctc_main_dir=g_string_new(NULL); g_string_sprintf(dctc_main_dir,"%s/.dctc",(path!=NULL)?path:"."); if(access(dctc_main_dir->str,R_OK|W_OK|X_OK)) { if(errno==ENOENT) { if(mkdir(dctc_main_dir->str,0777)) { perror("mkdir"); fprintf(stderr,"Unable to create %s, abort.\n",dctc_main_dir->str); exit(1); } } else { fprintf(stderr,"You have no access rights on %s, abort.\n",dctc_main_dir->str); exit(1); } } dctc_dir=g_string_new(NULL); g_string_sprintf(dctc_dir,"%s/running",dctc_main_dir->str); if(access(dctc_dir->str,R_OK|W_OK|X_OK)) { if(errno==ENOENT) { if(mkdir(dctc_dir->str,0777)) { perror("mkdir"); fprintf(stderr,"Unable to create %s, abort.\n",dctc_dir->str); exit(1); } } else { fprintf(stderr,"You have no access rights on %s, abort.\n",dctc_dir->str); exit(1); } } dctc_active_client_file=g_string_new(NULL); g_string_sprintf(dctc_active_client_file,"%s/gstatus",dctc_main_dir->str); /* this socket is used to send data to DCTC UDP communication socket, it is not bind to anything */ local_udp_socket=socket(AF_UNIX,SOCK_DGRAM,0); { GString *tmp; /* create uaddr_ready file */ tmp=g_string_new(dctc_main_dir->str); g_string_sprintfa(tmp,"/unode.%d",sizeof(UNODE_DATA)); unode_lmp=lmp_new(tmp->str,sizeof(UNODE_DATA)); if(unode_lmp==NULL) { fprintf(stderr,"unable to create %s\n",tmp->str); g_string_free(tmp,TRUE); exit(1); } g_string_free(tmp,TRUE); } { struct poptOption start_options[]={ /* -s (auto_start_disabled) */ {"autostart",'s',POPT_ARG_NONE,&auto_start_disabled,0,_("Disable auto-start of DCTC clients"),NULL}, /* -h hub_address (address of a hub to connect to) */ {"hubaddress",'h',POPT_ARG_STRING,&use_this_hub_address,0,_("Start a new DCTC client for the given hub address"),NULL}, /* -u dchub_url (dchub://address of a hub to connect to) */ {"dchuburl",'u',POPT_ARG_STRING,&use_this_dchuburl,0,_("Start a new DCTC client for the given dchub URL"),NULL}, /* -p profilename (profile to use for the -g flag) */ {"profile",'p',POPT_ARG_STRING,&use_this_profile,0,_("Profile to use for the hub specified with the -g flag (mandatory if -g or -u is used"),NULL}, /* -e (start_and_quit_enabled) */ {"exit",'e',POPT_ARG_NONE,&start_and_quit_enabled,0,_("Quit the GUI immediatly. This option is useful only if -h or -u is used"),NULL}, {NULL, '\0', 0, NULL, 0, NULL, NULL } }; gnome_init_with_popt_table ("dc_gui", VERSION, argc, argv, start_options,0,NULL); } if( ((use_this_hub_address!=NULL) || (use_this_dchuburl!=NULL)) && (use_this_profile==NULL) ) { gtk_timeout_add(4000,(void*)gtk_main_quit,NULL); gnome_error_dialog(_("You must specify a profile to use using -p flag if you use either -h or -u flag")); gtk_main(); exit(1); } if(use_this_dchuburl!=NULL) { start_dctc_client_from_huburl(use_this_dchuburl,use_this_profile); } else if(use_this_hub_address!=NULL) { /* too easy to program it :) */ start_a_new_dctc(use_this_hub_address,0,use_this_profile); } if(start_and_quit_enabled==TRUE) { /* the option -a (--saq) allows a GUI to start a DCTC client (using -h or -u) and immediatly leaves */ /* to avoid to have as many GUI as DCTC client. */ exit(0); } set_sig(); /* * The following code was added by Glade to create one of each component * (except popup menus), just so that you see something after building * the project. Delete any components that you don't want shown initially. */ main_window = create_app1 (); gui_full_restore(main_window,NULL); gtk_widget_realize(main_window); #if 0 gnome_window_icon_set_from_file(GTK_WINDOW(main_window),"icon.xpm"); #else { static GdkPixmap *win_pix=NULL; static GdkBitmap *win_bit=NULL; win_pix=gdk_pixmap_create_from_xpm_d(main_window->window,&win_bit,NULL,dcgui_xpm); gdk_window_set_icon_name (main_window->window, "DCgui " VERSION); gdk_window_set_icon(main_window->window,NULL,win_pix,win_bit); } #endif gtk_widget_show (main_window); dl_popup=create_dl_popup_menu (); ul_popup=create_ul_popup_menu (); q_popup=create_q_popup_menu (); user_popup=create_user_popup_menu (); start_dl_popup=create_start_dl_popup_menu (); gdl_popup=create_gdl_popup_menu (); uaddr_popup=create_uaddr_popup_menu (); done_popup=create_done_popup_menu (); /* preallocate some useful colors */ colormap=gdk_window_get_colormap(main_window->window); i=0; while(alloc_color[i].ptr!=NULL) { alloc_color[i].ptr->red=(guint16)alloc_color[i].r; alloc_color[i].ptr->green=(guint16)alloc_color[i].v; alloc_color[i].ptr->blue=(guint16)alloc_color[i].b; /* Allocate color */ gdk_color_alloc (colormap, alloc_color[i].ptr); i++; } /* fill running hub clist */ fill_recent_hub_clist(); fill_running_hub_clist(); fix_pref_window(); convert_old_bookmark_to_new_bookmark_format(); reload_bookmark(); init_clist(); do_berkeley_init(); convert_gnome_seen_list_to_bdb_seen_list(); gtk_widget_show(get_widget_by_widget_name("bookmark_button")); gtk_widget_hide(get_widget_by_widget_name("delete_selected_bookmark_button")); gtk_widget_hide(get_widget_by_widget_name("start_dctc_selected_hub_button")); gtk_widget_hide(get_widget_by_widget_name("hide_search_user_button")); gtk_widget_hide(get_widget_by_widget_name("user_search_vbox")); /* misc style used by labels */ sty_normal=gtk_style_copy(gtk_widget_get_style(get_widget_by_widget_name("private_chat_page"))); sty_hilight=gtk_style_copy(sty_normal); sty_hilight->fg[GTK_STATE_NORMAL]=green; /* start periodic task */ gtk_timeout_add(500,do_label_blink,NULL); set_periodic_function_call_rate(&running_client_list_refresh_rate,&running_client_list_refresh_rate_gta, running_client_list_periodic_refresh,NULL, 1000*gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(get_widget_by_widget_name("running_client_list_refresh_rate_spinbutton"))) ); set_periodic_function_call_rate(&favorite_client_autostart_check_rate,&favorite_client_autostart_check_rate_gta, favorite_client_periodic_autostart,NULL, 1000*gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(get_widget_by_widget_name("favorite_client_autostart_check_rate_spinbutton"))) ); gtk_main (); do_berkeley_exit(); return 0; }