/* Copyright (C) 2001-2002 Kenichi Suto * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define _GLOBAL #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef HAVE_GETOPT_LONG #include #endif #include "defs.h" #include "global.h" #include #include #include #include "eb.h" #include "dictheading.h" #include "dicttext.h" #include "dictgroup.h" #include "weblist.h" #include "pixmap.h" #include "selection.h" #include "preference.h" #include "dialog.h" #define DEFAULT_WINDOW_WIDTH 670 #define DEFAULT_WINDOW_HEIGHT 440 static gboolean style_set=FALSE; static pthread_t server_tid=(pthread_t)-1; static guint signal_remote_command = 0; static gint conn; static gchar sock_name[512]; extern GtkWidget *dict_scroll; extern GtkWidget *note_tree; void exit_program( GtkWidget *widget, gpointer data ) { if(pthread_self() == server_tid) pthread_exit(0); ebook_end(); gdk_window_get_root_origin(window->window, &window_x, &window_y); window_width = window->allocation.width; window_height = window->allocation.height; tree_width = note_tree->allocation.width; tree_height = note_tree->allocation.height; save_preference(); gtk_main_quit (); if(server_tid != (pthread_t)-1) pthread_cancel(server_tid); close(conn); unlink(sock_name); // pthread_kill(server_tid, SIGKILL); pthread_join(server_tid, NULL); exit(0); } static void delete_event( GtkWidget *widget, GdkEvent *event, gpointer data ) { exit_program(widget, data); } static void sig_handler(int sig){ gint status; //g_print("(%d) signal %d received\n", getpid(), sig); switch(sig){ case SIGCHLD: wait(&status); if(WEXITSTATUS(status) == 100){ warning(_("Failed to execute command. Please check setting.")); } break; case SIGTERM: case SIGINT: exit_program(NULL, NULL); break; default: break; } } static void style_set_event( GtkWidget *widget, GdkEvent *event, gpointer data ) { style_set = TRUE; } static void draw_event( GtkWidget *widget, GdkEvent *event, gpointer data ) { gint save_row; gchar *text=NULL; if(style_set == FALSE) return; save_row = current_row; clear_tree(tree_root); current_row = save_row; show_result_tree(); if(current_position.page >= 0){ text = ebook_get_text(current_book_info, current_position.page, current_position.offset); show_text(current_book_info, text); free(text); } else { show_about(); } style_set = FALSE; } gboolean perform_shortcut(GdkEventKey *event); static gint window_key_event(GtkWidget *widget, GdkEventKey *event){ // g_print("window_key_event\n"); if(perform_shortcut(event) == TRUE){ gtk_signal_emit_stop_by_name(GTK_OBJECT(window), "key_press_event"); } if(ebook_search_method() != SEARCH_METHOD_MULTI) gtk_window_set_focus(GTK_WINDOW(window), word_entry); return(FALSE); } gint g_argc; gchar *g_argv[16]; static void remote_command_old( GtkWidget *widget, gpointer data ) { gboolean selection=FALSE; gboolean popup=FALSE; gboolean iconify=FALSE; gboolean raise=FALSE; gboolean save_popup; gint i; gint c; gchar word[512]; Window xwindow; int option_index = 0; static struct option long_options[] = { {"selection", 0, 0, 's'}, {"popup", 0, 0, 'p'}, {"raise", 0, 0, 'r'}, {"iconify", 0, 0, 'i'}, {0, 0, 0, 0} }; /* g_print("g_argc = %d\n", g_argc); for(i=0;iwindow); xwindow = GDK_WINDOW_XWINDOW(window->window); XIconifyWindow(GDK_DISPLAY (), xwindow, DefaultScreen (GDK_DISPLAY ())); } if (raise) { g_print("Raise\n"); // gdk_window_hide(window->window); gtk_widget_grab_focus(window); gdk_window_raise(window->window); // gdk_window_show(window->window); // gtk_window_activate_focus(GTK_WINDOW(window)); /* xwindow = GDK_WINDOW_XWINDOW(window->window); XRaiseWindow(GDK_DISPLAY (), xwindow); */ } if(strlen(word) != 0){ g_print("Searching %s\n", word); gtk_entry_set_text(GTK_ENTRY(word_entry), word); start_search(); } } extern GtkWidget *popup; static void remote_command( GtkWidget *widget, gpointer data ) { gboolean bpopup=FALSE; gint i; gchar word[512]; if(strcmp(g_argv[1], "--search") == 0){ word[0] = '\0'; for(i=2; i < g_argc ; i ++){ strcat(word, g_argv[i]); strcat(word, " "); } if(strlen(word) != 0){ g_print("Searching %s\n", word); gtk_entry_set_text(GTK_ENTRY(word_entry), word); start_search(); } } else if((strcmp(g_argv[1], "--selection") == 0) || (strcmp(g_argv[1], "--popup") == 0)) { if(strcmp(g_argv[1], "--popup") == 0) bpopup = TRUE; g_print("Searching selection\n"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_popup), bpopup); bshow_popup = bpopup; copy_clipboard(NULL); return; } else if(strcmp(g_argv[1], "--close-popup") == 0){ if(popup != NULL) gtk_signal_emit_by_name(GTK_OBJECT (popup), // "delete_event"); "close_popup"); gtk_signal_emit_by_name(GTK_OBJECT (popup), "redraw"); } } static void *server_thread(void *arg) { gint count=0; gchar buff[256]; int len, read_len; gchar *p; gint i; gint state; struct sockaddr_un address; int sock; size_t addrLength; signal(SIGCHLD, SIG_DFL); // signal(SIGINT, SIG_DFL); signal(SIGTERM, SIG_DFL); signal(SIGPIPE, SIG_DFL); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &state); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &state); if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { perror("socket"); _exit(1); } /* Remove any preexisting socket (or other file) */ address.sun_family = AF_UNIX; /* Unix domain socket */ // strcpy(address.sun_path, "./sample-socket"); sprintf(sock_name, "%s/.remote-sock", package_dir); strcpy(address.sun_path, sock_name); unlink(sock_name); /* The total length of the address includes the sun_family element */ #ifndef HAVE_GETOPT_LONG addrLength = sizeof(address.sun_len) + sizeof(address.sun_family) + strlen(address.sun_path) + 1; address.sun_len = addrLength; #else addrLength = sizeof(address.sun_family) + strlen(address.sun_path); #endif if (bind(sock, (struct sockaddr *) &address, addrLength)){ perror("bind"); _exit(1); } if (listen(sock, 5)){ perror("listen"); _exit(1); } sprintf(buff, "remote command %d", count); while ((conn = accept(sock, (struct sockaddr *) &address, &addrLength)) >= 0) { printf("---- getting data\n"); read_len = read(conn, buff, 1); if(read_len != 1){ g_print("Failed to read socket\n"); close(conn); continue; } len = (unsigned char)buff[0]; if(len == 0){ g_print("Data too short\n"); close(conn); continue; } g_print("Receiving %d bytes of data...", len); read_len = read(conn, buff, len); if(read_len != len){ g_print("%d should be %d\n", read_len , len); perror("read"); g_print("Failed to read socket\n"); close(conn); continue; } g_print("done\n"); close(conn); p = buff; g_argc = *p; p ++; for(i=0; iwindow, NULL, ebook_pixmap, ebook_mask); hidden_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); hidden_entry = gtk_entry_new(); gtk_signal_connect (GTK_OBJECT(hidden_entry), "selection_received", GTK_SIGNAL_FUNC (selection_received), NULL); gtk_container_add (GTK_CONTAINER (hidden_window), hidden_entry); show_about(); gtk_selection_owner_set(window, GDK_SELECTION_PRIMARY,GDK_CURRENT_TIME); if(!bshow_menu_bar) hide_menu_bar(); if(!bshow_dict_bar) hide_dict_bar(); if(!bshow_status_bar) hide_status_bar(); if(argc != 1) execute_remote_command(argc, argv); gdk_threads_enter(); gtk_main (); gdk_threads_leave(); ebook_end(); _exit(0); // return(0); }