📄 utility.c
字号:
/*** Sinek (Media Player)** Copyright (c) 2001-2002 Gurer Ozen**** This code is free software; you can redistribute it and/or** modify it under the terms of the GNU General Public License.**** utility functions*/#include "common.h"#include <stdarg.h>struct window{ int (*builder)(GtkWidget **win); int flags; GtkWidget *win;};const GtkTargetEntry dnd_types[] ={ { "text/plain", 0, 0 }, { "text/uri-list", 0, 0 }, { "STRING", 0, 0 },};static GList *windows = NULL;static void wm_map_cb(GtkWidget *win, struct window *w);static void wm_unmap_cb(GtkWidget *win, struct window *w);static void wm_dnd_receive(GtkWidget *w, GdkDragContext *con, gint x, gint y, GtkSelectionData *sdata, guint info, guint time, gpointer udata);static gint wm_key_cb(GtkWidget *win, GdkEventKey *ev, struct window *w);static gint wm_button_cb(GtkWidget *win, GdkEventButton *ev, struct window *w);static gint wm_delete_cb(GtkWidget *win, GdkEvent *ev, struct window *w);static gint wm_destroy_cb(GtkWidget *win, struct window *w);struct fsel_struct{ GtkWidget *win; void (*callback)(char *filename);};static void fsel_ok(GtkWidget *w, struct fsel_struct *fsel);static void fsel_cancel(GtkWidget *w, struct fsel_struct *fsel);static gint fsel_delete(GtkWidget *w, GdkEvent *ev, struct fsel_struct *fsel);void add_tooltip(GtkWidget *w, char *tip){ static GtkTooltips *tips = NULL; if(NULL == tips) tips = gtk_tooltips_new(); gtk_tooltips_set_tip(tips, w, tip, NULL);}void sort_list(GtkListStore *list, gint col, GCompareDataFunc func, gpointer data){ GArray *ar; GtkTreeIter iter; gpointer item; gboolean go; int i, len; len = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(list), NULL); ar = g_array_sized_new(FALSE, FALSE, sizeof(gpointer), len); go = gtk_tree_model_get_iter_root(GTK_TREE_MODEL(list), &iter); while(go) { gtk_tree_model_get(GTK_TREE_MODEL(list), &iter, col, &item, -1); g_array_append_val(ar, item); go = gtk_tree_model_iter_next(GTK_TREE_MODEL(list), &iter); } gtk_list_store_clear(list); g_array_sort_with_data(ar, func, data); i = 0; while(i < len) { gtk_list_store_append(list, &iter); item = g_array_index(ar, gpointer, i); gtk_list_store_set(list, &iter, col, (gpointer)item, -1); i++; } g_array_free(ar, FALSE);}static void cb_url(GtkButton *but, const char *url){ int pid, argc; char *argv[5], buf3[1024]; sprintf(buf3, "openURL(%s)", url); argv[0] = "mozilla"; argv[1] = "-remote"; argv[2] = buf3; argc = 3; pid = fork(); if(pid == -1) return; if(pid == 0) { execvp(argv[0], argv); _exit(0); } else { return; }}GtkWidget *create_url(const char *url){ static char buf[512]; GdkColor uri_color[2] = {{0, 0, 0, 0xffff}, {0, 0xffff, 0, 0}}; gboolean success[2]; GdkColormap *cmap; GtkWidget *box, *but, *lab; int i; box = gtk_hbox_new(FALSE, 0); gtk_widget_show(box); sprintf(buf, " %s ", url); but = gtk_button_new_with_label(buf); gtk_widget_show(but); gtk_box_pack_start(GTK_BOX(box), but, TRUE, FALSE, 0); gtk_button_set_relief(GTK_BUTTON(but), GTK_RELIEF_NONE); buf[0] = ' '; for(i = 1; i <= strlen(url); i++) buf[i] = '_'; buf[i] = ' '; gtk_label_set_pattern(GTK_LABEL(GTK_BIN(but)->child), buf);// cmap = gdk_colormap_get_system(); gdk_colormap_alloc_colors(cmap, uri_color, 2, FALSE, TRUE, success); if (success[0] == TRUE && success[1] == TRUE) { lab = GTK_BIN(but)->child; gtk_widget_modify_fg(lab, GTK_STATE_NORMAL, &uri_color[0]); gtk_widget_modify_fg(lab, GTK_STATE_ACTIVE, &uri_color[1]); gtk_widget_modify_fg(lab, GTK_STATE_PRELIGHT, &uri_color[0]); } else g_warning("about_create(): color allocation failed.\n");// g_signal_connect(G_OBJECT(but), "clicked", G_CALLBACK(cb_url), (gpointer)url); return box;}static void button_cb(GtkWidget *w, cmd_type data){ execute_cmd(data);}GtkWidget *create_pix_button(const gchar *stock_id, cmd_type cmd, char *tip){ GtkWidget *but, *icon; but = gtk_button_new(); gtk_widget_show(but); icon = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_BUTTON); gtk_widget_show(icon); gtk_container_add(GTK_CONTAINER(but), icon); g_signal_connect(G_OBJECT(but), "clicked", G_CALLBACK(button_cb), (gpointer)cmd); if(tip) add_tooltip(but, tip); return but;}void update_pix_toggle(GtkWidget *w){ const gchar *stock_id; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) stock_id = g_object_get_data(G_OBJECT(w), "on"); else stock_id = g_object_get_data(G_OBJECT(w), "off"); gtk_image_set_from_stock(GTK_IMAGE(GTK_BIN(w)->child), stock_id, GTK_ICON_SIZE_BUTTON); gtk_widget_show(GTK_BIN(w)->child); }static void toggle_cb(GtkWidget *w, cmd_type cmd){ if(sinek.signal_fake) return; execute_cmd(cmd); update_pix_toggle(w);}GtkWidget *create_pix_toggle(const gchar *stock_id_on, const gchar *stock_id_off, int is_on, cmd_type cmd, char *tip){ GtkWidget *tog, *icon; tog = gtk_toggle_button_new(); gtk_widget_show(tog); g_object_set_data(G_OBJECT(tog), "on", (gpointer)stock_id_on); g_object_set_data(G_OBJECT(tog), "off", (gpointer)stock_id_off); if(is_on) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tog), TRUE); icon = gtk_image_new(); gtk_widget_show(icon); gtk_container_add(GTK_CONTAINER(tog), icon); update_pix_toggle(tog); g_signal_connect(G_OBJECT(tog), "toggled", G_CALLBACK(toggle_cb), (gpointer)cmd); add_tooltip(tog, tip); return tog;}static void wm_setup_callbacks(struct window *w){ GtkWidget *win = w->win; int flags = w->flags; g_signal_connect(G_OBJECT(win), "map", G_CALLBACK(wm_map_cb), (gpointer)w); g_signal_connect(G_OBJECT(win), "unmap", G_CALLBACK(wm_unmap_cb), (gpointer)w); if(flags & WM_KEYS) g_signal_connect(G_OBJECT(win), "key_press_event", G_CALLBACK(wm_key_cb), (gpointer)w); if(flags & WM_MENU || flags & WM_VOLUME) g_signal_connect(G_OBJECT(win), "button_press_event", G_CALLBACK(wm_button_cb), (gpointer)w); if(flags & WM_AUTOHIDE) g_signal_connect(G_OBJECT(win), "delete_event", G_CALLBACK(wm_delete_cb), (gpointer)w); if(flags & WM_DND) { g_signal_connect(G_OBJECT(win), "drag-data-received", G_CALLBACK(wm_dnd_receive), NULL); gtk_drag_dest_set(win, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, dnd_types, 3, GDK_ACTION_COPY | GDK_ACTION_MOVE); } g_signal_connect(G_OBJECT(win), "destroy", G_CALLBACK(wm_destroy_cb), (gpointer)w);}static struct window *wm_setup(int (*builder)(GtkWidget **win)){ struct window *w; GList *item; for(item = g_list_first(windows); item; item = g_list_next(item)) { w = item->data; if(w->builder == builder) return(w); } w = malloc(sizeof(struct window)); w->flags = builder(&w->win); w->builder = builder; windows = g_list_append(windows, w); wm_setup_callbacks(w); return w;}void wm_manage(GtkWidget *win, int flags){ struct window *w; w = malloc(sizeof(struct window)); w->win = win; w->flags = flags; w->builder = NULL; windows = g_list_append(windows, w); wm_setup_callbacks(w);}void wm_build(int (*builder)(GtkWidget **win)){ wm_setup(builder);}void wm_show(int (*builder)(GtkWidget **win)){ struct window *w; w = wm_setup(builder); gtk_window_present(GTK_WINDOW(w->win));}void wm_toggle(int (*builder)(GtkWidget **win)){ struct window *w; w = wm_setup(builder); if(GTK_WIDGET_VISIBLE(w->win)) gtk_widget_hide(w->win); else gtk_window_present(GTK_WINDOW(w->win));}static void wm_map_cb(GtkWidget *win, struct window *w){ sinek.nr_mapped++; if(w->flags & WM_MENU || w->flags & WM_VOLUME) { gtk_widget_add_events(w->win, GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK); } video_lift(w->win);}static void wm_unmap_cb(GtkWidget *win, struct window *w){ sinek.nr_mapped--; if(0 == sinek.nr_mapped) gtk_main_quit();}static void wm_dnd_receive(GtkWidget *w, GdkDragContext *con, gint x, gint y, GtkSelectionData *sdata, guint info, guint time, gpointer udata){ char *t; if(sdata->data) { t = (char *)sdata->data; strtok(t, "\r"); if(strncmp(t, "file:///", 8) == 0) t += 7; if(strncmp(t, "file:/", 6) == 0) t += 5; video_play(t); }}static gint wm_key_cb(GtkWidget *win, GdkEventKey *ev, struct window *w){ GtkWidget *wid; wid = gtk_window_get_focus(GTK_WINDOW(w->win)); if(GTK_IS_ENTRY(wid) || GTK_IS_TEXT_VIEW(wid)) return FALSE; return key_handle(ev->keyval, ev->state);}static gint wm_button_cb(GtkWidget *win, GdkEventButton *ev, struct window *w){ if(ev->button == 3 && w->flags & WM_MENU) popup_pop(ev->time); else if(ev->button == 4 && w->flags & WM_VOLUME) audio_slide_volume(5); else if(ev->button == 5 && w->flags & WM_VOLUME) audio_slide_volume(-5); else return FALSE; return TRUE;}static gint wm_delete_cb(GtkWidget *win, GdkEvent *ev, struct window *w){ gtk_widget_hide(win); return TRUE;} static gint wm_destroy_cb(GtkWidget *win, struct window *w){ windows = g_list_remove(windows, w); free(w); sinek.nr_mapped--; if(0 == sinek.nr_mapped) gtk_main_quit(); return FALSE;}void wm_relayer_all(void){ GList *item; GtkWidget *win; for(item = g_list_first(windows); item; item = g_list_next(item)) { win = ((struct window *)item->data)->win; if(GTK_WIDGET_REALIZED(win)) video_lift(win); }}void wm_show_all(void){ GList *item; struct window *w; for(item = g_list_first(windows); item; item = g_list_next(item)) { w = (struct window *)item->data; if(w->flags & 4096) { gtk_widget_show(w->win); w->flags &= ~4096; } }}void wm_hide_all(void){ GList *item; struct window *w; for(item = g_list_first(windows); item; item = g_list_next(item)) { w = (struct window *)item->data; if(GTK_WIDGET_MAPPED(w->win)) { gtk_widget_hide(w->win); w->flags |= 4096; } }}void select_file(void (*func)(char *filename), char *title){ struct fsel_struct *fsel; GtkWidget *win, *b; fsel = malloc(sizeof(struct fsel_struct)); fsel->callback = func; win = gtk_file_selection_new(title); fsel->win = win; gtk_container_set_border_width(GTK_CONTAINER(win), 10); b = GTK_FILE_SELECTION(win)->ok_button; g_signal_connect(G_OBJECT(b), "clicked", G_CALLBACK(fsel_ok), fsel); b = GTK_FILE_SELECTION(win)->cancel_button; g_signal_connect(G_OBJECT(b), "clicked", G_CALLBACK(fsel_cancel), fsel); g_signal_connect(G_OBJECT(win), "delete_event", G_CALLBACK(fsel_delete), fsel); wm_manage(win, 0); gtk_widget_show(win);}static void fsel_ok(GtkWidget *w, struct fsel_struct *fsel){ char *file; file = (char *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(fsel->win)); fsel->callback(file); gtk_widget_destroy(fsel->win); free(fsel);}static void fsel_cancel(GtkWidget *w, struct fsel_struct *fsel){ gtk_widget_destroy(fsel->win); free(fsel);}static gint fsel_delete(GtkWidget *w, GdkEvent *ev, struct fsel_struct *fsel){ free(fsel); return FALSE;}static void warning_response_cb(GtkWidget *w, gint response, gpointer data){ char *msg; msg = g_object_get_data(G_OBJECT(w), "msg"); g_free(msg); gtk_widget_destroy(w);}void warning(char *fmt, ...){ GtkWidget *w; va_list ap; char *msg; va_start(ap, fmt); msg = g_strdup_vprintf(fmt, ap); va_end(ap); w = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, msg); gtk_window_set_title(GTK_WINDOW(w), _("Sinek Warning")); gtk_window_set_position(GTK_WINDOW(w), GTK_WIN_POS_CENTER); g_signal_connect(G_OBJECT(w), "response", G_CALLBACK(warning_response_cb), NULL); g_object_set_data(G_OBJECT(w), "msg", msg); wm_manage(w, WM_MENU); gtk_widget_show(w);}static gboolean freq_add_file(GtkTreeModel *model, GtkTreePath *treepath, GtkTreeIter *iter, GtkFileSelection *fs){ gchar *path, *name, *filename; gtk_label_get(GTK_LABEL(gtk_bin_get_child(GTK_BIN(fs->history_pulldown))), &path); gtk_tree_model_get(model, iter, 0, &name, -1); filename = g_build_filename(path, name, NULL); pl_append(filename); g_free(filename); return FALSE;}static void freq_add_selected(GtkWidget *w, GtkFileSelection *fs){ GtkTreeSelection *sel; sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(fs->file_list)); gtk_tree_selection_selected_foreach(sel, (GtkTreeSelectionForeachFunc)freq_add_file, (gpointer)fs);}static void freq_add_all(GtkWidget *w, GtkFileSelection *fs){ GtkTreeModel *model; model = gtk_tree_view_get_model(GTK_TREE_VIEW(fs->file_list)); gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc)freq_add_file, (gpointer)fs);}static void freq_ok(GtkWidget *w, GtkFileSelection *fs){ gchar *file, *tmp, *path; int mode; mode = (int)g_object_get_data(G_OBJECT(fs), "mode"); if(mode) freq_add_selected(w, fs); else { file = (char *)gtk_file_selection_get_filename(fs); if(file) video_play(file); } gtk_label_get(GTK_LABEL(gtk_bin_get_child(GTK_BIN(fs->history_pulldown))), &tmp); path = g_strconcat(tmp, G_DIR_SEPARATOR_S, NULL); media->conf->update_string(media->conf, "sinek.last_dir", path); g_free(path); gtk_widget_hide(GTK_WIDGET(fs));}void file_request(gboolean for_playlist){ static GtkWidget *browse_win = NULL; GtkWidget *freq, *box, *b; char *path; if(browse_win) goto out; path = media->conf->register_string(media->conf, "sinek.last_dir", "", NULL, NULL, NULL, NULL); freq = gtk_file_selection_new(_("Select Video File")); gtk_container_set_border_width(GTK_CONTAINER(freq), 10); gtk_window_set_wmclass(GTK_WINDOW(freq), "filesel", "sinek"); gtk_file_selection_set_select_multiple(GTK_FILE_SELECTION(freq), TRUE); if(path && *path != 0) gtk_file_selection_set_filename(GTK_FILE_SELECTION(freq), path); b = GTK_FILE_SELECTION(freq)->ok_button; gtk_widget_show(b); GTK_WIDGET_SET_FLAGS(b, GTK_CAN_DEFAULT); g_signal_connect(G_OBJECT(b), "clicked", G_CALLBACK(freq_ok), freq); b = GTK_FILE_SELECTION(freq)->cancel_button; gtk_widget_show(b); GTK_WIDGET_SET_FLAGS(b, GTK_CAN_DEFAULT); g_signal_connect_swapped(G_OBJECT(b), "clicked", G_CALLBACK(gtk_widget_hide), GTK_OBJECT(freq)); box = gtk_hbutton_box_new(); gtk_widget_show(box); gtk_box_pack_end(GTK_BOX(GTK_FILE_SELECTION(freq)->action_area), box, TRUE, TRUE, 0); gtk_button_box_set_layout(GTK_BUTTON_BOX(box), GTK_BUTTONBOX_END); gtk_box_set_spacing(GTK_BOX(box), 5); b = gtk_button_new_with_label(_("Add selected files")); gtk_widget_show(b); gtk_box_pack_start(GTK_BOX(box), b, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(b), "clicked", G_CALLBACK(freq_add_selected), freq); b = gtk_button_new_with_label(_("Add all files in directory")); gtk_widget_show(b); gtk_box_pack_start(GTK_BOX(box), b, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(b), "clicked", G_CALLBACK(freq_add_all), freq); g_signal_connect_swapped(G_OBJECT(freq), "delete_event", G_CALLBACK(gtk_widget_hide), GTK_OBJECT(freq)); browse_win = freq; wm_manage(freq, 0);out: g_object_set_data(G_OBJECT(browse_win), "mode", (gpointer)for_playlist); gtk_window_present(GTK_WINDOW(browse_win));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -