📄 winops-x11.c
字号:
/* GKrellM| Copyright (C) 1999-2006 Bill Wilson|| Author: Bill Wilson billw@gkrellm.net| Latest versions might be found at: http://gkrellm.net|| This program is free software which I release under the GNU General Public| License. You may redistribute and/or modify this program under the terms| of that 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. Version 2 is in the| COPYRIGHT file in the top level directory of this distribution.| | To get a copy of the GNU General Puplic License, write to the Free Software| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include "gkrellm.h"#include "gkrellm-private.h"#include <errno.h>#if !defined(F_TLOCK)#include <sys/file.h>#endif#include <pwd.h>#include <sys/types.h>#include <gdk/gdkx.h>#include <X11/Xmd.h>#include <X11/SM/SMlib.h>#include <X11/Xatom.h>#define _NET_WM_STATE_REMOVE 0#define _NET_WM_STATE_ADD 1#define _NET_WM_STATE_TOGGLE 2static Pixmap root_xpixmap = None;static GdkGC *trans_gc;static gchar *client_id;voidgkrellm_winop_reset(void) { root_xpixmap = None; }static voidcb_smc_save_yourself(SmcConn smc_conn, SmPointer client_data, gint save_type, gboolean shutdown, gint interact_style, gboolean fast) { gkrellm_save_all(); SmcSaveYourselfDone(smc_conn, True); }static voidcb_smc_die(SmcConn smc_conn, SmPointer client_data) { SmcCloseConnection(smc_conn, 0, NULL); gtk_main_quit(); }static voidcb_smc_save_complete(SmcConn smc_conn, SmPointer client_data) { }static voidcb_smc_shutdown_cancelled(SmcConn smc_conn, SmPointer client_data) { }static voidcb_ice_connection_messages(IceConn ice_connection, gint source, GdkInputCondition condition) { IceProcessMessages(ice_connection, NULL, NULL); }static voidsmc_connect(gint argc, gchar **argv) { SmProp userid, program, restart, restart_style, clone, pid, *props[6]; SmPropValue userid_val, pid_val, restart_style_val; CARD8 restartstyle; SmcCallbacks *callbacks; SmcConn smc_connection; IceConn ice_connection; struct passwd *pwd; uid_t uid; gchar error_string[256], pid_str[16], userid_string[256]; gulong mask; gint i, j; /* Session manager callbacks */ callbacks = g_new0(SmcCallbacks, 1); callbacks->save_yourself.callback = cb_smc_save_yourself; callbacks->die.callback = cb_smc_die; callbacks->save_complete.callback = cb_smc_save_complete; callbacks->shutdown_cancelled.callback = cb_smc_shutdown_cancelled; mask = SmcSaveYourselfProcMask | SmcDieProcMask | SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask; smc_connection = SmcOpenConnection(NULL /* SESSION_MANAGER env variable */, NULL /* share ICE connection */, SmProtoMajor, SmProtoMinor, mask, callbacks, _GK.session_id, &client_id, sizeof(error_string), error_string); g_free(callbacks); if (!smc_connection) return; gdk_set_sm_client_id(client_id); /* Session manager properties - 4 are required. */ userid.name = SmUserID; userid.type = SmARRAY8; userid.num_vals = 1; userid.vals = &userid_val; uid = getuid(); if ((pwd = getpwuid(uid)) != NULL) snprintf(userid_string, sizeof(userid_string), "%s", pwd->pw_name); else snprintf(userid_string, sizeof(userid_string), "%d", uid); userid_val.value = userid_string; userid_val.length = strlen(userid_string); pid.name = SmProcessID; pid.type = SmARRAY8; pid.num_vals = 1; pid.vals = &pid_val; sprintf(pid_str, "%i", getpid()); pid_val.value = (SmPointer) pid_str; pid_val.length = strlen(pid_str); restart.name = SmRestartCommand; restart.type = SmLISTofARRAY8; restart.vals = g_new0(SmPropValue, argc + 2); j = 0; for (i = 0; i < argc; ++i) { if ( strcmp(argv[i], "--sm-client-id") ) { restart.vals[j].value = (SmPointer) argv[i]; restart.vals[j++].length = strlen(argv[i]); } else i++; } restart.vals[j].value = (SmPointer) "--sm-client-id"; restart.vals[j++].length = strlen("--sm-client-id"); restart.vals[j].value = (SmPointer) client_id; restart.vals[j++].length = strlen(client_id); restart.num_vals = j; restartstyle = SmRestartImmediately; restart_style.name = SmRestartStyleHint; restart_style.type = SmCARD8; restart_style.num_vals = 1; restart_style.vals = &restart_style_val; restart_style_val.value = (SmPointer) &restartstyle; restart_style_val.length = 1; clone.name = SmCloneCommand; clone.type = SmLISTofARRAY8; clone.vals = restart.vals; clone.num_vals = restart.num_vals - 2; program.name = SmProgram; program.type = SmARRAY8; program.vals = restart.vals; program.num_vals = 1; props[0] = &program; props[1] = &userid; props[2] = &restart; props[3] = &clone; props[4] = &pid;#if 0 /* Make this an option? */ props[5] = &restart_style; SmcSetProperties(smc_connection, 6, props);#else SmcSetProperties(smc_connection, 5, props);#endif g_free(restart.vals); ice_connection = SmcGetIceConnection(smc_connection); gdk_input_add(IceConnectionNumber(ice_connection), GDK_INPUT_READ, (GdkInputFunction) cb_ice_connection_messages, ice_connection); }static voidnet_wm_state(gchar *hint, gboolean state) { XEvent xev; xev.type = ClientMessage; xev.xclient.type = ClientMessage; xev.xclient.window = GDK_WINDOW_XWINDOW(gkrellm_get_top_window()->window); xev.xclient.message_type = gdk_x11_get_xatom_by_name("_NET_WM_STATE"); xev.xclient.format = 32; xev.xclient.data.l[0] = state ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; xev.xclient.data.l[1] = gdk_x11_get_xatom_by_name(hint); xev.xclient.data.l[2] = 0; XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), False, SubstructureNotifyMask, &xev); }voidgkrellm_winop_state_skip_taskbar(gboolean state) { if (!_GK.is_dock_type) net_wm_state("_NET_WM_STATE_SKIP_TASKBAR", state); }voidgkrellm_winop_state_skip_pager(gboolean state) { if (!_GK.is_dock_type) net_wm_state("_NET_WM_STATE_SKIP_PAGER", state); }voidgkrellm_winop_state_above(gboolean state) { net_wm_state("_NET_WM_STATE_ABOVE", state); /* Apparently KDE 3.1.0 and possibly below does not implement * _NET_WM_STATE_ABOVE but _NET_WM_STATE_STAYS_ON_TOP that implies * approximately the same thing */ net_wm_state("_NET_WM_STATE_STAYS_ON_TOP", state); }voidgkrellm_winop_state_below(gboolean state) { net_wm_state("_NET_WM_STATE_BELOW", state); }static FILE *f_lock;static gboolean_gkrellm_get_lock(void) { gchar *lock_dir, *lock_file, *display, *s; gchar buf[32]; snprintf(buf, sizeof(buf), "LCK..%d", (gint) getuid());#if defined(F_TLOCK) lock_dir = "/var/lock/gkrellm"; if (!g_file_test(lock_dir, G_FILE_TEST_IS_DIR)) mkdir(lock_dir, 0755); lock_file = gkrellm_make_config_file_name(lock_dir, buf); display = XDisplayName(NULL); if (display) { s = g_strconcat(lock_file, "_", display, NULL); g_free(lock_file); lock_file = s; } f_lock = fopen(lock_file, "w+"); /* buffering does not apply here */ g_free(lock_file); if ( f_lock && lockf(fileno(f_lock), F_TLOCK, 0) != 0 && errno == EAGAIN ) return FALSE; if (f_lock) { fprintf(f_lock, "%10d\n", (gint) getpid()); fflush(f_lock); }#endif return TRUE; }enum { STRUT_LEFT = 0, STRUT_RIGHT = 1, STRUT_TOP = 2, STRUT_BOTTOM = 3, STRUT_LEFT_START = 4, STRUT_LEFT_END = 5, STRUT_RIGHT_START = 6, STRUT_RIGHT_END = 7, STRUT_TOP_START = 8, STRUT_TOP_END = 9, STRUT_BOTTOM_START = 10, STRUT_BOTTOM_END = 11 };static Atom net_wm_strut_partial = None;static Atom net_wm_strut = None;voidgkrellm_winop_update_struts(void) { gulong struts[12] = { 0, }; Display *display; Window window; gint width; gint height; if (!_GK.is_dock_type) return; display = GDK_WINDOW_XDISPLAY(gkrellm_get_top_window()->window); window = GDK_WINDOW_XWINDOW(gkrellm_get_top_window()->window); if (net_wm_strut_partial == None) { net_wm_strut_partial = XInternAtom(display, "_NET_WM_STRUT_PARTIAL", False); } if (net_wm_strut == None) { net_wm_strut = XInternAtom(display, "_NET_WM_STRUT", False); } gtk_window_get_size(GTK_WINDOW(gkrellm_get_top_window()), &width, &height); if (_GK.x_position == 0) { struts[STRUT_LEFT] = width; struts[STRUT_LEFT_START] = _GK.y_position; struts[STRUT_LEFT_END] = _GK.y_position + height; } else if (_GK.x_position == _GK.w_display - width) { struts[STRUT_RIGHT] = width; struts[STRUT_RIGHT_START] = _GK.y_position; struts[STRUT_RIGHT_END] = _GK.y_position + height; } gdk_error_trap_push(); XChangeProperty (display, window, net_wm_strut, XA_CARDINAL, 32, PropModeReplace, (guchar *) &struts, 4); XChangeProperty (display, window, net_wm_strut_partial, XA_CARDINAL, 32, PropModeReplace, (guchar *) &struts, 12); gdk_error_trap_pop(); }voidgkrellm_winop_options(gint argc, gchar **argv) { Display *display; Window window; Atom atoms[4]; gint n = 0; if ( !_GK.allow_multiple_instances_real && !_GK.force_host_config && !_gkrellm_get_lock() ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -