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

📄 eggtrayicon.c

📁 Linux系统下著名的个人防火墙
💻 C
字号:
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- *//* eggtrayicon.c * Copyright (C) 2002 Anders Carlsson <andersca@gnu.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#include <config.h>#include <string.h>#include <libintl.h>#include "eggtrayicon.h"#include <gdk/gdkx.h>#include <X11/Xatom.h>#ifndef EGG_COMPILATION#ifndef _#define _(x) dgettext (GETTEXT_PACKAGE, x)#define N_(x) x#endif#else#define _(x) x#define N_(x) x#endif#define SYSTEM_TRAY_REQUEST_DOCK    0#define SYSTEM_TRAY_BEGIN_MESSAGE   1#define SYSTEM_TRAY_CANCEL_MESSAGE  2#define SYSTEM_TRAY_ORIENTATION_HORZ 0#define SYSTEM_TRAY_ORIENTATION_VERT 1enum {  PROP_0,  PROP_ORIENTATION};         static GtkPlugClass *parent_class = NULL;static void egg_tray_icon_init (EggTrayIcon *icon);static void egg_tray_icon_class_init (EggTrayIconClass *klass);static void egg_tray_icon_get_property (GObject    *object,					guint       prop_id,					GValue     *value,					GParamSpec *pspec);static void egg_tray_icon_realize   (GtkWidget *widget);static void egg_tray_icon_unrealize (GtkWidget *widget);static void egg_tray_icon_update_manager_window (EggTrayIcon *icon);GTypeegg_tray_icon_get_type (void){  static GType our_type = 0;  if (our_type == 0)    {      static const GTypeInfo our_info =      {	sizeof (EggTrayIconClass),	(GBaseInitFunc) NULL,	(GBaseFinalizeFunc) NULL,	(GClassInitFunc) egg_tray_icon_class_init,	NULL, /* class_finalize */	NULL, /* class_data */	sizeof (EggTrayIcon),	0,    /* n_preallocs */	(GInstanceInitFunc) egg_tray_icon_init      };      our_type = g_type_register_static (GTK_TYPE_PLUG, "EggTrayIcon", &our_info, 0);    }  return our_type;}static voidegg_tray_icon_init (EggTrayIcon *icon){  icon->stamp = 1;  icon->orientation = GTK_ORIENTATION_HORIZONTAL;    gtk_widget_add_events (GTK_WIDGET (icon), GDK_PROPERTY_CHANGE_MASK);}static voidegg_tray_icon_class_init (EggTrayIconClass *klass){  GObjectClass *gobject_class = (GObjectClass *)klass;  GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;  parent_class = g_type_class_peek_parent (klass);  gobject_class->get_property = egg_tray_icon_get_property;  widget_class->realize   = egg_tray_icon_realize;  widget_class->unrealize = egg_tray_icon_unrealize;  g_object_class_install_property (gobject_class,				   PROP_ORIENTATION,				   g_param_spec_enum ("orientation",						      _("Orientation"),						      _("The orientation of the tray."),						      GTK_TYPE_ORIENTATION,						      GTK_ORIENTATION_HORIZONTAL,						      G_PARAM_READABLE));}static voidegg_tray_icon_get_property (GObject    *object,			    guint       prop_id,			    GValue     *value,			    GParamSpec *pspec){  EggTrayIcon *icon = EGG_TRAY_ICON (object);  switch (prop_id)    {    case PROP_ORIENTATION:      g_value_set_enum (value, icon->orientation);      break;    default:      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);      break;    }}static voidegg_tray_icon_get_orientation_property (EggTrayIcon *icon){  Display *xdisplay;  Atom type;  int format;  union {	gulong *prop;	guchar *prop_ch;  } prop = { NULL };  gulong nitems;  gulong bytes_after;  int error, result;  g_assert (icon->manager_window != None);    xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));  gdk_error_trap_push ();  type = None;  result = XGetWindowProperty (xdisplay,			       icon->manager_window,			       icon->orientation_atom,			       0, G_MAXLONG, FALSE,			       XA_CARDINAL,			       &type, &format, &nitems,			       &bytes_after, &(prop.prop_ch));  error = gdk_error_trap_pop ();  if (error || result != Success)    return;  if (type == XA_CARDINAL)    {      GtkOrientation orientation;      orientation = (prop.prop [0] == SYSTEM_TRAY_ORIENTATION_HORZ) ?					GTK_ORIENTATION_HORIZONTAL :					GTK_ORIENTATION_VERTICAL;      if (icon->orientation != orientation)	{	  icon->orientation = orientation;	  g_object_notify (G_OBJECT (icon), "orientation");	}    }  if (prop.prop)    XFree (prop.prop);}static GdkFilterReturnegg_tray_icon_manager_filter (GdkXEvent *xevent, GdkEvent *event, gpointer user_data){  EggTrayIcon *icon = user_data;  XEvent *xev = (XEvent *)xevent;  if (xev->xany.type == ClientMessage &&      xev->xclient.message_type == icon->manager_atom &&      xev->xclient.data.l[1] == icon->selection_atom)    {      egg_tray_icon_update_manager_window (icon);    }  else if (xev->xany.window == icon->manager_window)    {      if (xev->xany.type == PropertyNotify &&	  xev->xproperty.atom == icon->orientation_atom)	{	  egg_tray_icon_get_orientation_property (icon);	}      if (xev->xany.type == DestroyNotify)	{	  egg_tray_icon_update_manager_window (icon);	}    }    return GDK_FILTER_CONTINUE;}static voidegg_tray_icon_unrealize (GtkWidget *widget){  EggTrayIcon *icon = EGG_TRAY_ICON (widget);  GdkWindow *root_window;  if (icon->manager_window != None)    {      GdkWindow *gdkwin;      gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (widget),                                              icon->manager_window);      gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon);    }  root_window = gdk_screen_get_root_window (gtk_widget_get_screen (widget));  gdk_window_remove_filter (root_window, egg_tray_icon_manager_filter, icon);  if (GTK_WIDGET_CLASS (parent_class)->unrealize)    (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);}static voidegg_tray_icon_send_manager_message (EggTrayIcon *icon,				    long         message,				    Window       window,				    long         data1,				    long         data2,				    long         data3){  XClientMessageEvent ev;  Display *display;    ev.type = ClientMessage;  ev.window = window;  ev.message_type = icon->system_tray_opcode_atom;  ev.format = 32;  ev.data.l[0] = gdk_x11_get_server_time (GTK_WIDGET (icon)->window);  ev.data.l[1] = message;  ev.data.l[2] = data1;  ev.data.l[3] = data2;  ev.data.l[4] = data3;  display = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));    gdk_error_trap_push ();  XSendEvent (display,	      icon->manager_window, False, NoEventMask, (XEvent *)&ev);  XSync (display, False);  gdk_error_trap_pop ();}static voidegg_tray_icon_send_dock_request (EggTrayIcon *icon){  egg_tray_icon_send_manager_message (icon,				      SYSTEM_TRAY_REQUEST_DOCK,				      icon->manager_window,				      gtk_plug_get_id (GTK_PLUG (icon)),				      0, 0);}static voidegg_tray_icon_update_manager_window (EggTrayIcon *icon){  Display *xdisplay;    xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));    if (icon->manager_window != None)    {      GdkWindow *gdkwin;      gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)),					      icon->manager_window);            gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon);    }    XGrabServer (xdisplay);    icon->manager_window = XGetSelectionOwner (xdisplay,					     icon->selection_atom);  if (icon->manager_window != None)    XSelectInput (xdisplay,		  icon->manager_window, StructureNotifyMask|PropertyChangeMask);  XUngrabServer (xdisplay);  XFlush (xdisplay);    if (icon->manager_window != None)    {      GdkWindow *gdkwin;      gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)),					      icon->manager_window);            gdk_window_add_filter (gdkwin, egg_tray_icon_manager_filter, icon);      /* Send a request that we'd like to dock */      egg_tray_icon_send_dock_request (icon);      egg_tray_icon_get_orientation_property (icon);    }}static voidegg_tray_icon_realize (GtkWidget *widget){  EggTrayIcon *icon = EGG_TRAY_ICON (widget);  GdkScreen *screen;  GdkDisplay *display;  Display *xdisplay;  char buffer[256];  GdkWindow *root_window;  if (GTK_WIDGET_CLASS (parent_class)->realize)    GTK_WIDGET_CLASS (parent_class)->realize (widget);  screen = gtk_widget_get_screen (widget);  display = gdk_screen_get_display (screen);  xdisplay = gdk_x11_display_get_xdisplay (display);  /* Now see if there's a manager window around */  g_snprintf (buffer, sizeof (buffer),	      "_NET_SYSTEM_TRAY_S%d",	      gdk_screen_get_number (screen));  icon->selection_atom = XInternAtom (xdisplay, buffer, False);    icon->manager_atom = XInternAtom (xdisplay, "MANAGER", False);    icon->system_tray_opcode_atom = XInternAtom (xdisplay,						   "_NET_SYSTEM_TRAY_OPCODE",						   False);  icon->orientation_atom = XInternAtom (xdisplay,					"_NET_SYSTEM_TRAY_ORIENTATION",					False);  egg_tray_icon_update_manager_window (icon);  root_window = gdk_screen_get_root_window (screen);    /* Add a root window filter so that we get changes on MANAGER */  gdk_window_add_filter (root_window,			 egg_tray_icon_manager_filter, icon);}EggTrayIcon *egg_tray_icon_new_for_screen (GdkScreen *screen, const char *name){  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);  return g_object_new (EGG_TYPE_TRAY_ICON, "screen", screen, "title", name, NULL);}EggTrayIcon*egg_tray_icon_new (const gchar *name){  return g_object_new (EGG_TYPE_TRAY_ICON, "title", name, NULL);}guintegg_tray_icon_send_message (EggTrayIcon *icon,			    gint         timeout,			    const gchar *message,			    gint         len){  guint stamp;    g_return_val_if_fail (EGG_IS_TRAY_ICON (icon), 0);  g_return_val_if_fail (timeout >= 0, 0);  g_return_val_if_fail (message != NULL, 0);		       if (icon->manager_window == None)    return 0;  if (len < 0)    len = strlen (message);  stamp = icon->stamp++;    /* Get ready to send the message */  egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_BEGIN_MESSAGE,				      (Window)gtk_plug_get_id (GTK_PLUG (icon)),				      timeout, len, stamp);  /* Now to send the actual message */  gdk_error_trap_push ();  while (len > 0)    {      XClientMessageEvent ev;      Display *xdisplay;      xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));            ev.type = ClientMessage;      ev.window = (Window)gtk_plug_get_id (GTK_PLUG (icon));      ev.format = 8;      ev.message_type = XInternAtom (xdisplay,				     "_NET_SYSTEM_TRAY_MESSAGE_DATA", False);      if (len > 20)	{	  memcpy (&ev.data, message, 20);	  len -= 20;	  message += 20;	}      else	{	  memcpy (&ev.data, message, len);	  len = 0;	}      XSendEvent (xdisplay,		  icon->manager_window, False, StructureNotifyMask, (XEvent *)&ev);      XSync (xdisplay, False);    }  gdk_error_trap_pop ();  return stamp;}voidegg_tray_icon_cancel_message (EggTrayIcon *icon,			      guint        id){  g_return_if_fail (EGG_IS_TRAY_ICON (icon));  g_return_if_fail (id > 0);    egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_CANCEL_MESSAGE,				      (Window)gtk_plug_get_id (GTK_PLUG (icon)),				      id, 0, 0);}GtkOrientationegg_tray_icon_get_orientation (EggTrayIcon *icon){  g_return_val_if_fail (EGG_IS_TRAY_ICON (icon), GTK_ORIENTATION_HORIZONTAL);  return icon->orientation;}

⌨️ 快捷键说明

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