00001 00002 #ifdef HAVE_CONFIG_H 00003 #include <config.h> 00004 #endif 00005 00006 #include <stdarg.h> 00007 #include <gtk/gtk.h> 00008 #include <gdk/gdk.h> 00009 #ifndef WIN32 00010 #include <gdk/gdkx.h> 00011 #endif 00012 #include <gdk/gdkkeysyms.h> 00013 00014 #ifdef HAVE_STDLIB_H 00015 #include <stdlib.h> 00016 #endif 00017 00018 #ifdef HAVE_STRING_H 00019 #include <string.h> 00020 #endif 00021 00022 #ifdef HAVE_UNISTD_H 00023 #include <unistd.h> 00024 #endif 00025 00026 typedef struct { 00027 GtkWidget *topbox; 00028 GtkWidget *textbox; 00029 const char *title; 00030 } TextBoxCache; 00031 00032 static TextBoxCache *textbox_cache = 0; 00033 static int textbox_cache_size = 0; 00034 static int textbox_cache_max = 0; 00035 00036 static void 00037 log_close_cb (GtkWidget * widget, gpointer data) 00038 { 00039 TextBoxCache *tbc = textbox_cache + (int)data; 00040 gtk_widget_destroy (tbc->topbox); 00041 g_free ((char *)tbc->title); 00042 tbc->title = 0; 00043 } 00044 00045 static void 00046 log_clear_cb (GtkWidget * widget, gpointer data) 00047 { 00048 TextBoxCache *tbc = textbox_cache + (int)data; 00049 clear_textbox (tbc->textbox); 00050 } 00051 00052 static void 00053 log_destroy_cb (GtkWidget * widget, gpointer data) 00054 { 00055 TextBoxCache *tbc = textbox_cache + (int)data; 00056 g_free ((char *)tbc->title); 00057 tbc->title = 0; 00058 } 00059 00060 GtkWidget * 00061 get_textbox (const char *title) 00062 { 00063 GtkWidget *scrolled, *view, *log_window, *vbox, *hbox, *button; 00064 GtkTextBuffer *buffer; 00065 int i; 00066 00067 for (i=0; i<textbox_cache_size; i++) 00068 if (textbox_cache[i].title 00069 && strcmp (title, textbox_cache[i].title) == 0) 00070 return textbox_cache[i].textbox; 00071 00072 for (i=0; i<textbox_cache_size; i++) 00073 if (textbox_cache[i].title == 0) 00074 break; 00075 00076 if (i == textbox_cache_size) 00077 { 00078 if (textbox_cache_size >= textbox_cache_max) 00079 { 00080 textbox_cache_max += 10; 00081 textbox_cache = (TextBoxCache *) realloc (textbox_cache, textbox_cache_max * sizeof (TextBoxCache)); 00082 } 00083 textbox_cache_size ++; 00084 } 00085 00086 textbox_cache[i].title = g_strdup (title); 00087 00088 00089 00090 log_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); 00091 g_signal_connect (G_OBJECT (log_window), "destroy", 00092 G_CALLBACK (log_destroy_cb), (void *)i); 00093 gtk_window_set_title (GTK_WINDOW (log_window), title); 00094 gtk_window_set_wmclass (GTK_WINDOW (log_window), "gerbv_log", "gerbv"); 00095 gtk_window_set_default_size (GTK_WINDOW (log_window), 400, 300); 00096 00097 vbox = gtk_vbox_new (FALSE, 0); 00098 gtk_container_set_border_width (GTK_CONTAINER (vbox), 6); 00099 gtk_container_add (GTK_CONTAINER (log_window), vbox); 00100 00101 00102 00103 scrolled = gtk_scrolled_window_new (NULL, NULL); 00104 gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0); 00105 00106 view = gtk_text_view_new (); 00107 gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE); 00108 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); 00109 gtk_text_buffer_create_tag (buffer, "heading", 00110 "weight", PANGO_WEIGHT_BOLD, 00111 "size", 14 * PANGO_SCALE, NULL); 00112 gtk_text_buffer_create_tag (buffer, "italic", 00113 "style", PANGO_STYLE_ITALIC, NULL); 00114 gtk_text_buffer_create_tag (buffer, "bold", 00115 "weight", PANGO_WEIGHT_BOLD, NULL); 00116 gtk_text_buffer_create_tag (buffer, "center", 00117 "justification", GTK_JUSTIFY_CENTER, NULL); 00118 gtk_text_buffer_create_tag (buffer, "underline", 00119 "underline", PANGO_UNDERLINE_SINGLE, NULL); 00120 00121 gtk_container_add (GTK_CONTAINER (scrolled), view); 00122 00123 00124 hbox = gtk_hbutton_box_new (); 00125 gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_END); 00126 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); 00127 00128 button = gtk_button_new_from_stock (GTK_STOCK_CLEAR); 00129 g_signal_connect (G_OBJECT (button), "clicked", 00130 G_CALLBACK (log_clear_cb), (void *)i); 00131 gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); 00132 00133 button = gtk_button_new_from_stock (GTK_STOCK_CLOSE); 00134 g_signal_connect (G_OBJECT (button), "clicked", 00135 G_CALLBACK (log_close_cb), (void *)i); 00136 gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); 00137 00138 gtk_widget_realize (log_window); 00139 gtk_widget_set_uposition (GTK_WIDGET (log_window), 10, 10); 00140 gtk_widget_show_all (log_window); 00141 00142 00143 textbox_cache[i].topbox = log_window; 00144 textbox_cache[i].textbox = view; 00145 00146 return view; 00147 } 00148 00149 void 00150 clear_textbox (GtkWidget *view) 00151 { 00152 GtkTextBuffer *buffer; 00153 00154 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); 00155 gtk_text_buffer_set_text (buffer, "", 0); 00156 } 00157 00158 static char *buf = 0; 00159 static int bufsz = 0; 00160 00161 void 00162 tb_printf (GtkWidget *view, const char *fmt, ...) 00163 { 00164 GtkTextIter iter; 00165 GtkTextBuffer *buffer; 00166 GtkTextMark *mark; 00167 va_list args, args2; 00168 int needed; 00169 00170 va_start (args, fmt); 00171 needed = g_printf_string_upper_bound (fmt, args); 00172 00173 if (bufsz < needed+1) 00174 { 00175 bufsz = needed + 10; 00176 buf = realloc (buf, bufsz); 00177 } 00178 00179 g_vsnprintf (buf, bufsz, fmt, args); 00180 00181 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); 00182 gtk_text_buffer_get_end_iter (buffer, &iter); 00183 00184 gtk_text_buffer_insert (buffer, &iter, buf, -1); 00185 00186 mark = gtk_text_buffer_create_mark (buffer, NULL, &iter, FALSE); 00187 gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view), mark, 00188 0, TRUE, 0.0, 1.0); 00189 gtk_text_buffer_delete_mark (buffer, mark); 00190 }