⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hints.c

📁 xmms-1.2.10.tar.gz学习使用的就下吧
💻 C
字号:
/*  XMMS - Cross-platform multimedia player *  Copyright (C) 1998-2003  Peter Alm, Mikael Alm, Olle Hallnas, *                           Thomas Nilsson and 4Front Technologies *  Copyright (C) 1999-2004  Haavard Kvaalen * *  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. */#include <X11/Xlib.h>#include <X11/Xmd.h>#include <X11/Xatom.h>#include <gdk/gdkx.h>#include <gdk/gdkprivate.h>#include "xmms.h"/* flags for the window layer */typedef enum{	WIN_LAYER_DESKTOP = 0,	WIN_LAYER_BELOW = 2,	WIN_LAYER_NORMAL = 4,	WIN_LAYER_ONTOP = 6,	WIN_LAYER_DOCK = 8,	WIN_LAYER_ABOVE_DOCK = 10}WinLayer;#define WIN_STATE_STICKY		(1 << 0)#define WIN_HINTS_SKIP_WINLIST		(1 << 1) /* not in win list */#define WIN_HINTS_SKIP_TASKBAR		(1 << 2) /* not on taskbar */#define _NET_WM_STATE_REMOVE   0#define _NET_WM_STATE_ADD      1#define _NET_WM_STATE_TOGGLE   2#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT      0#define _NET_WM_MOVERESIZE_SIZE_TOP          1#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT     2#define _NET_WM_MOVERESIZE_SIZE_RIGHT        3#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT  4#define _NET_WM_MOVERESIZE_SIZE_BOTTOM       5#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT   6#define _NET_WM_MOVERESIZE_SIZE_LEFT         7#define _NET_WM_MOVERESIZE_MOVE              8static void (*set_always_func)(GtkWidget *, gboolean);static void (*set_sticky_func)(GtkWidget *, gboolean);static void (*set_skip_taskbar_func)(GtkWidget *);static void (*move_resize_func)(GtkWidget *, int, int, gboolean);void hint_set_skip_winlist(GtkWidget *window){	if (set_skip_taskbar_func)		set_skip_taskbar_func(window);}void hint_set_always(gboolean always){	if (set_always_func)	{		set_always_func(mainwin, always);		set_always_func(equalizerwin, always);		set_always_func(playlistwin, always);	}}gboolean hint_always_on_top_available(void){	return !!set_always_func;}void hint_set_sticky(gboolean sticky){	if (set_sticky_func)	{		set_sticky_func(mainwin, sticky);		set_sticky_func(equalizerwin, sticky);		set_sticky_func(playlistwin, sticky);	}}gboolean hint_move_resize_available(void){	return 0;}void hint_move_resize(GtkWidget *window, int x, int y, gboolean move){	move_resize_func(window, x, y, move);}static void gnome_wm_set_skip_taskbar(GtkWidget *widget){	long data[1];	Atom xa_win_hints = gdk_atom_intern("_WIN_HINTS", FALSE);	data[0] = WIN_HINTS_SKIP_TASKBAR;	XChangeProperty(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(widget->window),			xa_win_hints, XA_CARDINAL, 32,			PropModeReplace, (unsigned char *) data, 1);}static void gnome_wm_set_window_always(GtkWidget * window, gboolean always){	XEvent xev;	long layer = WIN_LAYER_ONTOP;	Atom xa_win_layer = gdk_atom_intern("_WIN_LAYER", FALSE);	if (always == FALSE)		layer = WIN_LAYER_NORMAL;	if (GTK_WIDGET_MAPPED(window))	{		xev.type = ClientMessage;		xev.xclient.type = ClientMessage;		xev.xclient.window = GDK_WINDOW_XWINDOW(window->window);		xev.xclient.message_type = xa_win_layer;		xev.xclient.format = 32;		xev.xclient.data.l[0] = layer;		XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), False,			   SubstructureNotifyMask, &xev);	}	else	{		long data[1];		data[0] = layer;		XChangeProperty(GDK_DISPLAY(),				GDK_WINDOW_XWINDOW(window->window),				xa_win_layer, XA_CARDINAL, 32, PropModeReplace,				(unsigned char *) data,	1);	}}static void gnome_wm_set_window_sticky(GtkWidget * window, gboolean sticky){	XEvent xev;	long state = 0;	Atom xa_win_state = gdk_atom_intern("_WIN_STATE", FALSE);	if (sticky)		state = WIN_STATE_STICKY;	if (GTK_WIDGET_MAPPED(window))	{		xev.type = ClientMessage;		xev.xclient.type = ClientMessage;		xev.xclient.window = GDK_WINDOW_XWINDOW(window->window);		xev.xclient.message_type = xa_win_state;		xev.xclient.format = 32;		xev.xclient.data.l[0] = WIN_STATE_STICKY;		xev.xclient.data.l[1] = state;		XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), False,			   SubstructureNotifyMask, &xev);	}	else	{		long data[2];		data[0] = state;		XChangeProperty(GDK_DISPLAY(),				GDK_WINDOW_XWINDOW(window->window),				xa_win_state, XA_CARDINAL, 32, PropModeReplace,				(unsigned char *) data, 1);	}}static gboolean gnome_wm_found(void){	Atom r_type, support_check;	int r_format, p;	unsigned long count, bytes_remain;	unsigned char *prop = NULL, *prop2 = NULL;	gboolean ret = FALSE;	gdk_error_trap_push();	support_check = gdk_atom_intern("_WIN_SUPPORTING_WM_CHECK", FALSE);		p = XGetWindowProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(), support_check,			       0, 1, False, XA_CARDINAL, &r_type, &r_format,			       &count, &bytes_remain, &prop);	if (p == Success && prop && r_type == XA_CARDINAL &&	    r_format == 32 && count == 1)	{		Window n = *(long *) prop;		p = XGetWindowProperty(GDK_DISPLAY(), n, support_check, 0, 1,				       False, XA_CARDINAL, &r_type, &r_format,				       &count, &bytes_remain, &prop2);		if (p == Success && prop2 && r_type == XA_CARDINAL &&		    r_format == 32 && count == 1)			ret = TRUE;	}	if (prop)		XFree(prop);	if (prop2)		XFree(prop2);	if (gdk_error_trap_pop())		return FALSE;	return ret;}static gboolean net_wm_found(void){	Atom r_type, support_check;	int r_format,  p;	unsigned long count, bytes_remain;	unsigned char *prop = NULL, *prop2 = NULL;	gboolean ret = FALSE;	gdk_error_trap_push();	support_check = gdk_atom_intern("_NET_SUPPORTING_WM_CHECK", FALSE);	p = XGetWindowProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(), support_check,			       0, 1, False, XA_WINDOW, &r_type, &r_format,			       &count, &bytes_remain, &prop);	if (p == Success && prop && r_type == XA_WINDOW &&	    r_format == 32 && count == 1)	{		Window n = *(Window *) prop;		p = XGetWindowProperty(GDK_DISPLAY(), n, support_check, 0, 1,				       False, XA_WINDOW, &r_type, &r_format,				       &count, &bytes_remain, &prop2);			if (p == Success && prop2 && *prop2 == *prop &&		    r_type == XA_WINDOW && r_format == 32 && count == 1)			ret = TRUE;	}	if (prop)		XFree(prop);	if (prop2)		XFree(prop2);	if (gdk_error_trap_pop())		return FALSE;	return ret;}static void net_wm_set_property(GtkWidget * window, char *atom, gboolean state){	XEvent xev;	int set = _NET_WM_STATE_ADD;	Atom type, property;	if (state == FALSE)		set = _NET_WM_STATE_REMOVE;	type = gdk_atom_intern("_NET_WM_STATE", FALSE);	property = gdk_atom_intern(atom, FALSE);	xev.type = ClientMessage;	xev.xclient.type = ClientMessage;	xev.xclient.window = GDK_WINDOW_XWINDOW(window->window);	xev.xclient.message_type = type;	xev.xclient.format = 32;	xev.xclient.data.l[0] = set;	xev.xclient.data.l[1] = property;	xev.xclient.data.l[2] = 0;		XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), False,		   SubstructureNotifyMask, &xev);}static void net_wm_set_desktop(GtkWidget * window, gboolean all){	XEvent xev;	guint32 current_desktop = 0;	if (!all)	{		int r_format,  p;		unsigned long count, bytes_remain;		unsigned char* prop;		Atom r_type;		Atom current = gdk_atom_intern("_NET_WM_DESKTOP", FALSE);		p = XGetWindowProperty(GDK_DISPLAY(),				       GDK_WINDOW_XWINDOW(window->window), current,				       0, 1, False, XA_CARDINAL, &r_type, &r_format,				       &count, &bytes_remain, &prop);		if (p == Success && prop && r_type == XA_CARDINAL &&		    r_format == 32 && count == 1)		{			current_desktop = *(long*)prop;			XFree(prop);			if (current_desktop != 0xffffffff)				/*				 * We don't want to move the window if				 * it isn't sticky				 */				return;		}		current = gdk_atom_intern("_NET_CURRENT_DESKTOP", FALSE);		p = XGetWindowProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(), current,				       0, 1, False, XA_CARDINAL, &r_type, &r_format,				       &count, &bytes_remain, &prop);		if (p == Success && prop && r_type == XA_CARDINAL &&		    r_format == 32 && count == 1)		{			current_desktop = *(long*)prop;			XFree(prop);		}	}	else		current_desktop = 0xffffffff;	xev.type = ClientMessage;	xev.xclient.type = ClientMessage;	xev.xclient.window = GDK_WINDOW_XWINDOW(window->window);	xev.xclient.message_type = gdk_atom_intern("_NET_WM_DESKTOP", FALSE);	xev.xclient.format = 32;	xev.xclient.data.l[0] = current_desktop;		XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), False,		   SubstructureNotifyMask, &xev);}static void net_wm_set_window_always(GtkWidget * window, gboolean always){	net_wm_set_property(window, "_NET_WM_STATE_STAYS_ON_TOP", always);}static void net_wm_set_window_above(GtkWidget * window, gboolean always){	net_wm_set_property(window, "_NET_WM_STATE_ABOVE", always);}static void net_wm_set_skip_taskbar(GtkWidget * window){	net_wm_set_property(window, "_NET_WM_STATE_SKIP_TASKBAR", TRUE);}static void net_wm_move_resize(GtkWidget *window, int x, int y, gboolean move){	XEvent xev;	int dir;	Atom type;	if (move)		dir = _NET_WM_MOVERESIZE_MOVE;	else		dir = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT;	gdk_pointer_ungrab(GDK_CURRENT_TIME);	type = gdk_atom_intern("_NET_WM_MOVERESIZE", FALSE);	xev.type = ClientMessage;	xev.xclient.type = ClientMessage;	xev.xclient.window = GDK_WINDOW_XWINDOW(window->window);	xev.xclient.message_type = type;	xev.xclient.format = 32;	xev.xclient.data.l[0] = x;	xev.xclient.data.l[1] = y;	xev.xclient.data.l[2] = dir;	xev.xclient.data.l[3] = 1;    /* button */			XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), False,		   SubstructureNotifyMask, &xev);}			       static gboolean find_atom(Atom *atoms, int n, const char *name){	Atom a = gdk_atom_intern(name, FALSE);	int i;	for (i = 0; i < n; i++)		if (a == atoms[i])			return TRUE;	return FALSE;}static gboolean get_supported_atoms(Atom **atoms, unsigned long *natoms, const char *name){	Atom supported = gdk_atom_intern(name, FALSE), r_type;	unsigned long bremain;	int r_format, p;	*atoms = NULL;	gdk_error_trap_push();	p = XGetWindowProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(), supported,			       0, 1000, False, XA_ATOM, &r_type, &r_format,			       natoms, &bremain, (unsigned char **) atoms);	if (gdk_error_trap_pop() || p != Success || r_type != XA_ATOM ||	    *natoms == 0 || *atoms == NULL)		return FALSE;	return TRUE;}static void net_wm_check_features(void){	Atom *atoms;	unsigned long n_atoms;	if (!get_supported_atoms(&atoms, &n_atoms, "_NET_SUPPORTED"))		return;	if (find_atom(atoms, n_atoms, "_NET_WM_STATE"))	{		if (!set_always_func &&		    find_atom(atoms, n_atoms, "_NET_WM_STATE_ABOVE"))			set_always_func = net_wm_set_window_above;		if (!set_always_func &&		    find_atom(atoms, n_atoms, "_NET_WM_STATE_STAYS_ON_TOP"))			set_always_func = net_wm_set_window_always;		if (!set_sticky_func &&		    find_atom(atoms, n_atoms, "_NET_WM_DESKTOP"))			set_sticky_func = net_wm_set_desktop;		if (!set_skip_taskbar_func &&		    find_atom(atoms, n_atoms, "_NET_WM_STATE_SKIP_TASKBAR"))			set_skip_taskbar_func = net_wm_set_skip_taskbar;	}	if (find_atom(atoms, n_atoms, "_NET_WM_MOVERESIZE"))		move_resize_func = net_wm_move_resize;	XFree(atoms);}static void gnome_wm_check_features(void){	Atom *atoms;	unsigned long n_atoms;	if (!get_supported_atoms(&atoms, &n_atoms, "_WIN_PROTOCOLS"))		return;	if (!set_always_func &&	    find_atom(atoms, n_atoms, "_WIN_LAYER"))		set_always_func = gnome_wm_set_window_always;	if (!set_sticky_func &&	    find_atom(atoms, n_atoms, "_WIN_STATE"))		set_sticky_func = gnome_wm_set_window_sticky;	if (!set_skip_taskbar_func &&	    find_atom(atoms, n_atoms, "_WIN_HINTS"))		set_skip_taskbar_func = gnome_wm_set_skip_taskbar;	XFree(atoms);}void check_wm_hints(void){	if (net_wm_found())		net_wm_check_features();	if (gnome_wm_found())		gnome_wm_check_features();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -