fullscreen.c
字号:
/* * GQview * (C) 2004 John Ellis * * Author: John Ellis * * This software is released under the GNU General Public License (GNU GPL). * Please read the included file COPYING for more information. * This software comes with no warranty of any kind, use at your own risk! */#include "gqview.h"#include "fullscreen.h"#include "image.h"#include "ui_fileops.h"#include "ui_menu.h"#include "ui_misc.h"enum { FULLSCREEN_CURSOR_HIDDEN = 1 << 0, FULLSCREEN_CURSOR_NORMAL = 1 << 1, FULLSCREEN_CURSOR_BUSY = 1 << 2};/* *---------------------------------------------------------------------------- * full screen functions *---------------------------------------------------------------------------- */static void clear_mouse_cursor(GtkWidget *widget, gint state){ if (!widget->window) return; if (state & FULLSCREEN_CURSOR_BUSY) { GdkCursor *cursor; cursor = gdk_cursor_new(GDK_WATCH); gdk_window_set_cursor (widget->window, cursor); gdk_cursor_unref(cursor); } else if (state & FULLSCREEN_CURSOR_NORMAL) { gdk_window_set_cursor (widget->window, NULL); } else { GdkCursor *cursor; GdkPixmap *p; p = gdk_bitmap_create_from_data(widget->window, "\0\0\0", 1, 1); cursor = gdk_cursor_new_from_pixmap(p, p, &widget->style->fg[GTK_STATE_ACTIVE], &widget->style->bg[GTK_STATE_ACTIVE], 0, 0); gdk_window_set_cursor (widget->window, cursor); gdk_cursor_unref(cursor); g_object_unref(p); }}static gint fullscreen_hide_mouse_cb(gpointer data){ FullScreenData *fs = data; if (fs->hide_mouse_id == -1) return FALSE; fs->cursor_state &= ~FULLSCREEN_CURSOR_NORMAL; if (!(fs->cursor_state & FULLSCREEN_CURSOR_BUSY)) clear_mouse_cursor(fs->window, fs->cursor_state); fs->hide_mouse_id = -1; return FALSE;}static void fullscreen_hide_mouse_disable(FullScreenData *fs){ if (fs->hide_mouse_id != -1) { g_source_remove(fs->hide_mouse_id); fs->hide_mouse_id = -1; }}static void fullscreen_hide_mouse_reset(FullScreenData *fs){ fullscreen_hide_mouse_disable(fs); fs->hide_mouse_id = g_timeout_add(FULL_SCREEN_HIDE_MOUSE_DELAY, fullscreen_hide_mouse_cb, fs);}static gint fullscreen_mouse_moved(GtkWidget *widget, GdkEventButton *bevent, gpointer data){ FullScreenData *fs = data; if (!(fs->cursor_state & FULLSCREEN_CURSOR_NORMAL)) { fs->cursor_state |= FULLSCREEN_CURSOR_NORMAL; if (!(fs->cursor_state & FULLSCREEN_CURSOR_BUSY)) clear_mouse_cursor(fs->window, fs->cursor_state); } fullscreen_hide_mouse_reset(fs); return FALSE;}static void fullscreen_busy_mouse_disable(FullScreenData *fs){ if (fs->busy_mouse_id != -1) { g_source_remove(fs->busy_mouse_id); fs->busy_mouse_id = -1; }}static void fullscreen_mouse_set_busy(FullScreenData *fs, gint busy){ fullscreen_busy_mouse_disable(fs); if ((fs->cursor_state & FULLSCREEN_CURSOR_BUSY) == (busy)) return; if (busy) { fs->cursor_state |= FULLSCREEN_CURSOR_BUSY; } else { fs->cursor_state &= ~FULLSCREEN_CURSOR_BUSY; } clear_mouse_cursor(fs->window, fs->cursor_state);}static gboolean fullscreen_mouse_set_busy_cb(gpointer data){ FullScreenData *fs = data; fs->busy_mouse_id = -1; fullscreen_mouse_set_busy(fs, TRUE); return FALSE;}static void fullscreen_mouse_set_busy_idle(FullScreenData *fs){ if (fs->busy_mouse_id == -1) { fs->busy_mouse_id = g_timeout_add(FULL_SCREEN_BUSY_MOUSE_DELAY, fullscreen_mouse_set_busy_cb, fs); }}static void fullscreen_image_update_cb(ImageWindow *imd, gpointer data){ FullScreenData *fs = data; if (fs->imd->il && fs->imd->il->pixbuf != image_get_pixbuf(fs->imd)) { fullscreen_mouse_set_busy_idle(fs); }}static void fullscreen_image_complete_cb(ImageWindow *imd, gint preload, gpointer data){ FullScreenData *fs = data; if (!preload) fullscreen_mouse_set_busy(fs, FALSE);}#define XSCREENSAVER_BINARY "xscreensaver-command"#define XSCREENSAVER_COMMAND "xscreensaver-command -deactivate >&- 2>&- &"static void fullscreen_saver_deactivate(void){ static gint checked = FALSE; static gint found = FALSE; if (!checked) { checked = TRUE; found = file_in_path(XSCREENSAVER_BINARY); } if (found) { system (XSCREENSAVER_COMMAND); }}static gboolean fullscreen_saver_block_cb(gpointer data){ if (fullscreen_disable_saver) { fullscreen_saver_deactivate(); } return TRUE;}static gint fullscreen_delete_cb(GtkWidget *widget, GdkEventAny *event, gpointer data){ FullScreenData *fs = data; fullscreen_stop(fs); return TRUE;}FullScreenData *fullscreen_start(GtkWidget *window, ImageWindow *imd, void (*stop_func)(FullScreenData *, gpointer), gpointer stop_data){ FullScreenData *fs; GdkScreen *screen; gint same; gint x, y; gint w, h; GdkGeometry geometry; if (!window || !imd) return NULL; fs = g_new0(FullScreenData, 1); fs->hide_mouse_id = -1; fs->busy_mouse_id = -1; fs->cursor_state = FULLSCREEN_CURSOR_HIDDEN; fs->normal_window = window; fs->normal_imd = imd; fs->stop_func = stop_func; fs->stop_data = stop_data; if (debug) printf("full screen requests screen %d\n", fullscreen_screen); fullscreen_prefs_get_geometry(fullscreen_screen, window, &x, &y, &w, &h, &screen, &same); fs->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_wmclass(GTK_WINDOW(fs->window), "fullscreen", "GQview"); /* this requests no decorations, if you still have them complain to the window manager author(s) */ gtk_window_set_decorated(GTK_WINDOW(fs->window), FALSE); if (fullscreen_screen < 0) { /* If we want control of the window size and position this is not what we want. * GQview needs control of which monitor(s) to use for full screen. */ gtk_window_fullscreen(GTK_WINDOW(fs->window)); } else if (fullscreen_above) { /* request to be above other windows */ gtk_window_set_keep_above(GTK_WINDOW(fs->window), TRUE); } gtk_window_set_resizable(GTK_WINDOW(fs->window), FALSE); gtk_window_set_screen(GTK_WINDOW(fs->window), screen); gtk_container_set_border_width(GTK_CONTAINER(fs->window), 0); g_signal_connect(G_OBJECT(fs->window), "delete_event", G_CALLBACK(fullscreen_delete_cb), fs); gtk_window_set_title(GTK_WINDOW(fs->window), _("GQview full screen")); geometry.min_width = w; geometry.min_height = h; geometry.max_width = w; geometry.max_height = h; geometry.base_width = w; geometry.base_height = h; geometry.win_gravity = GDK_GRAVITY_STATIC; /* By setting USER_POS and USER_SIZE, most window managers will * not request positioning of the full screen window (for example twm). * * In addition, setting gravity to STATIC will result in the * decorations of twm to not effect the requested window position, * the decorations will simply be off screen, except in multi monitor setups :-/ */ gtk_window_set_geometry_hints(GTK_WINDOW(fs->window), fs->window, &geometry, GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE | GDK_HINT_BASE_SIZE | GDK_HINT_WIN_GRAVITY | GDK_HINT_USER_POS); gtk_window_set_default_size(GTK_WINDOW(fs->window), w, h); gtk_window_move(GTK_WINDOW(fs->window), x, y); fs->imd = image_new(FALSE); gtk_container_add(GTK_CONTAINER(fs->window), fs->imd->widget); /* set background to black */ if (BLACK_BACKGROUND) { image_background_set_black(fs->imd, TRUE); } image_set_delay_flip(fs->imd, fullscreen_clean_flip); image_auto_refresh(fs->imd, fs->normal_imd->auto_refresh_interval); if (fullscreen_clean_flip) { image_set_update_func(fs->imd, fullscreen_image_update_cb, fs); image_set_complete_func(fs->imd, fullscreen_image_complete_cb, fs); } gtk_widget_show(fs->imd->widget); image_change_from_image(fs->imd, fs->normal_imd); gtk_widget_show(fs->window); /* for hiding the mouse */ g_signal_connect(G_OBJECT(fs->imd->pr), "motion_notify_event", G_CALLBACK(fullscreen_mouse_moved), fs); clear_mouse_cursor(fs->window, fs->cursor_state); /* set timer to block screen saver */ fs->saver_block_id = g_timeout_add(60 * 1000, fullscreen_saver_block_cb, fs); /* hide normal window * FIXME: properly restore this window on show */#ifdef HIDE_WINDOW_IN_FULLSCREEN gtk_widget_hide(fs->normal_window);#endif image_change_path(fs->normal_imd, NULL, image_zoom_get(fs->normal_imd)); return fs;}void fullscreen_stop(FullScreenData *fs){ if (!fs) return; g_source_remove(fs->saver_block_id); fullscreen_hide_mouse_disable(fs); fullscreen_busy_mouse_disable(fs);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -