- add an animated tray icon for the GTK2 version (patch by Jochen Baier)
git-svn-id: http://svn.code.sf.net/p/xqf/code/trunk@622 d2ac09be-c843-0410-8b1f-f8a84130e0ec
This commit is contained in:
parent
61322fbd01
commit
28d7d5fb82
@ -3,6 +3,7 @@ Jun 19, 2004: Ludwig Nussel <l-n@users.sourceforge.net>
|
||||
all servers. Today's qstat cvs version required.
|
||||
- add gametypes for World of Padman Q3A mod
|
||||
- add support for Jedi Academy (wine game, patch by Steffen Pankratz)
|
||||
- add an animated tray icon for the GTK2 version (patch by Jochen Baier)
|
||||
|
||||
Jun 06, 2004: Ludwig Nussel <l-n@users.sourceforge.net>
|
||||
- update Danish translation (Morten Brix Pedersen)
|
||||
|
@ -48,7 +48,7 @@ if test "x$USE_GTK2" != "xno"; then
|
||||
OLD_GTK_SUPPORT="-DGTK_ENABLE_BROKEN=1"
|
||||
AC_SUBST(OLD_GTK_SUPPORT)
|
||||
|
||||
pkg_modules="gtk+-2.0 >= 2.0.0"
|
||||
pkg_modules="gtk+-2.0 >= 2.0.0 gdk-pixbuf-xlib-2.0"
|
||||
PKG_CHECK_MODULES(PACKAGE, [$pkg_modules])
|
||||
AC_SUBST(PACKAGE_CFLAGS)
|
||||
AC_SUBST(PACKAGE_LIBS)
|
||||
@ -195,6 +195,7 @@ AC_CONFIG_FILES([
|
||||
docs/Makefile
|
||||
pixmaps/Makefile
|
||||
pixmaps/flags/Makefile
|
||||
pixmaps/trayicon/Makefile
|
||||
xqf.spec
|
||||
po/Makefile.in
|
||||
])
|
||||
|
@ -1,4 +1,4 @@
|
||||
SUBDIRS = flags
|
||||
SUBDIRS = flags trayicon
|
||||
|
||||
EXTRA_DIST = $(splash_DATA) $(icon_DATA)
|
||||
|
||||
|
4
xqf/pixmaps/trayicon/Makefile.am
Normal file
4
xqf/pixmaps/trayicon/Makefile.am
Normal file
@ -0,0 +1,4 @@
|
||||
EXTRA_DIST = $(tray_DATA)
|
||||
|
||||
traydir = $(pkgdatadir)/default/trayicon
|
||||
tray_DATA = $(wildcard *.png) $(wildcard *.ani)
|
BIN
xqf/pixmaps/trayicon/around_frame_1.png
Normal file
BIN
xqf/pixmaps/trayicon/around_frame_1.png
Normal file
Binary file not shown.
BIN
xqf/pixmaps/trayicon/around_frame_2.png
Normal file
BIN
xqf/pixmaps/trayicon/around_frame_2.png
Normal file
Binary file not shown.
BIN
xqf/pixmaps/trayicon/around_frame_3.png
Normal file
BIN
xqf/pixmaps/trayicon/around_frame_3.png
Normal file
Binary file not shown.
BIN
xqf/pixmaps/trayicon/around_frame_4.png
Normal file
BIN
xqf/pixmaps/trayicon/around_frame_4.png
Normal file
Binary file not shown.
5
xqf/pixmaps/trayicon/busy.ani
Normal file
5
xqf/pixmaps/trayicon/busy.ani
Normal file
@ -0,0 +1,5 @@
|
||||
around_frame_1.png 8
|
||||
around_frame_2.png 8
|
||||
around_frame_3.png 8
|
||||
around_frame_4.png 8
|
||||
|
BIN
xqf/pixmaps/trayicon/frame_basic.png
Normal file
BIN
xqf/pixmaps/trayicon/frame_basic.png
Normal file
Binary file not shown.
16
xqf/pixmaps/trayicon/ready.ani
Normal file
16
xqf/pixmaps/trayicon/ready.ani
Normal file
@ -0,0 +1,16 @@
|
||||
red_frame_4_4.png 50
|
||||
frame_basic.png 50
|
||||
red_frame_4_4.png 50
|
||||
frame_basic.png 50
|
||||
red_frame_4_4.png 50
|
||||
frame_basic.png 50
|
||||
red_frame_4_4.png 50
|
||||
frame_basic.png 50
|
||||
red_frame_4_4.png 50
|
||||
frame_basic.png 50
|
||||
red_frame_4_4.png 6000
|
||||
red_frame_3_4.png 6000
|
||||
red_frame_2_4.png 6000
|
||||
red_frame_1_4.png 6000
|
||||
frame_basic.png 1
|
||||
|
BIN
xqf/pixmaps/trayicon/red_frame_4_4.png
Normal file
BIN
xqf/pixmaps/trayicon/red_frame_4_4.png
Normal file
Binary file not shown.
@ -57,6 +57,7 @@ srv-list.c \
|
||||
srv-prop.c \
|
||||
stat.c \
|
||||
statistics.c \
|
||||
trayicon.c \
|
||||
utils.c \
|
||||
xqf.c \
|
||||
xqf-ui.c \
|
||||
@ -98,6 +99,7 @@ srv-list.h \
|
||||
srv-prop.h \
|
||||
stat.h \
|
||||
statistics.h \
|
||||
trayicon.h \
|
||||
utils.h \
|
||||
xqf-ui.h \
|
||||
xqf.h \
|
||||
|
@ -101,6 +101,7 @@ int default_save_plrinfo;
|
||||
int default_auto_favorites;
|
||||
int default_show_splash;
|
||||
int default_auto_maps;
|
||||
int default_show_tray_icon;
|
||||
int default_toolbar_style;
|
||||
int default_toolbar_tips;
|
||||
int default_refresh_sorts;
|
||||
@ -170,6 +171,7 @@ static GtkWidget *save_plrinfo_check_button;
|
||||
static GtkWidget *auto_favorites_check_button;
|
||||
static GtkWidget *show_splash_button;
|
||||
static GtkWidget *auto_maps_check_button;
|
||||
static GtkWidget *tray_icon_check_button;
|
||||
static GtkWidget *show_hostnames_check_button;
|
||||
static GtkWidget *show_defport_check_button;
|
||||
static GtkWidget *toolbar_style_radio_buttons[3];
|
||||
@ -941,6 +943,12 @@ static void get_new_defaults (void) {
|
||||
if (i != default_auto_maps)
|
||||
config_set_bool ("search maps", default_auto_maps = i);
|
||||
|
||||
#ifdef USE_GTK2
|
||||
i = GTK_TOGGLE_BUTTON (tray_icon_check_button)->active;
|
||||
if (i != default_show_tray_icon)
|
||||
config_set_bool ("showtray", default_show_tray_icon = i);
|
||||
#endif
|
||||
|
||||
config_pop_prefix ();
|
||||
|
||||
/* QStat */
|
||||
@ -3922,6 +3930,23 @@ static GtkWidget *general_options_page (void) {
|
||||
|
||||
gtk_widget_show (hbox);
|
||||
|
||||
#ifdef USE_GTK2
|
||||
/*Tray icon*/
|
||||
hbox = gtk_hbox_new (FALSE, 4);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
|
||||
|
||||
|
||||
tray_icon_check_button = gtk_check_button_new_with_label (_("Minimize to system tray"));
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tray_icon_check_button), default_show_tray_icon);
|
||||
|
||||
gtk_tooltips_set_tip (tooltips, tray_icon_check_button,
|
||||
_("Enable xqf tray icon. You need to restart xqf to take effect !"), NULL);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (hbox), tray_icon_check_button, FALSE, FALSE, 0);
|
||||
gtk_widget_show (tray_icon_check_button);
|
||||
gtk_widget_show (hbox);
|
||||
#endif
|
||||
|
||||
gtk_widget_show (vbox);
|
||||
|
||||
gtk_widget_show (frame);
|
||||
@ -5030,6 +5055,7 @@ int prefs_load (void) {
|
||||
default_auto_favorites = config_get_bool ("refresh favorites=false");
|
||||
default_show_splash = config_get_bool ("splash screen=true");
|
||||
default_auto_maps = config_get_bool ("search maps=false");
|
||||
default_show_tray_icon = config_get_bool ("showtray=false");
|
||||
|
||||
config_pop_prefix ();
|
||||
|
||||
@ -5319,4 +5345,3 @@ static void file_dialog(const char *title, GtkSignalFunc ok_callback, enum serve
|
||||
|
||||
gtk_widget_show(file_selector);
|
||||
}
|
||||
|
||||
|
@ -88,6 +88,7 @@ extern int default_save_srvinfo;
|
||||
extern int default_save_plrinfo;
|
||||
extern int default_auto_favorites;
|
||||
extern int default_show_splash;
|
||||
extern int default_show_tray_icon;
|
||||
extern int default_always_resolve;
|
||||
extern int default_toolbar_style;
|
||||
extern int default_toolbar_tips;
|
||||
@ -126,5 +127,3 @@ extern void free_user_info (void);
|
||||
extern int prefs_load (void);
|
||||
|
||||
#endif /* __PREF_H__ */
|
||||
|
||||
|
||||
|
@ -495,6 +495,19 @@ GSList *server_clist_selected_servers (void) {
|
||||
return list;
|
||||
}
|
||||
|
||||
GSList *server_clist_get_n_servers (int amount) {
|
||||
GSList *list = NULL;
|
||||
struct server *server;
|
||||
int row;
|
||||
|
||||
for (row = 0; (row < server_clist->rows && row < amount) ; row++) {
|
||||
server = (struct server *) gtk_clist_get_row_data (server_clist, row);
|
||||
list = server_list_prepend (list, server);
|
||||
}
|
||||
|
||||
return g_slist_reverse (list);
|
||||
}
|
||||
|
||||
/*
|
||||
server_clist_all_servers -- Return all servers that are in the server
|
||||
clist widget. It returns a new list. Note that the prepend function
|
||||
|
@ -38,6 +38,7 @@ extern int server_clist_refresh_server (struct server *s);
|
||||
extern void server_clist_select_one (int row);
|
||||
extern GSList *server_clist_selected_servers (void);
|
||||
extern GSList *server_clist_all_servers (void);
|
||||
extern GSList *server_clist_get_n_servers (int amount);
|
||||
|
||||
extern void server_clist_selection_visible (void);
|
||||
|
||||
|
926
xqf/src/trayicon.c
Normal file
926
xqf/src/trayicon.c
Normal file
@ -0,0 +1,926 @@
|
||||
/* XQF - Quake server browser and launcher
|
||||
*
|
||||
* 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
|
||||
.*
|
||||
.*
|
||||
.* trayicon.c:
|
||||
.*
|
||||
* Copyright (C) Jochen Baier <email@jochen-baier.de>
|
||||
.*
|
||||
.* based on:
|
||||
.*
|
||||
.* eggtrayicon.c api
|
||||
.*
|
||||
* Copyright (C) Anders Carlsson <andersca@gnu.org>
|
||||
.*
|
||||
.* magic transparent KDE icon:
|
||||
.*
|
||||
.* Copyright (C) Jochen Baier <email@jochen-baier.de>
|
||||
.*
|
||||
*/
|
||||
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "gnuconfig.h"
|
||||
|
||||
#ifndef USE_GTK2
|
||||
/*dummy functions for gtk 1.x, this avoid a lot ifdef´s*/
|
||||
void tray_init (GtkWidget * window) {/**/};
|
||||
void tray_delete_event_hook (void) {/**/};
|
||||
void tray_icon_set_tooltip (gchar *tip) {/**/};
|
||||
void tray_icon_stop_animation (void) {/**/};
|
||||
void tray_icon_start_animation (void) {/**/};
|
||||
extern void tray_done (void) {/**/};
|
||||
extern gboolean tray_icon_work(void) {return FALSE;};
|
||||
#else
|
||||
|
||||
#include <stdio.h>
|
||||
#include <gtk/gtkplug.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <string.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <gdk-pixbuf-xlib/gdk-pixbuf-xlib.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "i18n.h"
|
||||
#include "pref.h"
|
||||
#include "xqf.h"
|
||||
#include "debug.h"
|
||||
#include "loadpixmap.h"
|
||||
#include "srv-list.h"
|
||||
#include "source.h"
|
||||
|
||||
#define SYSTEM_TRAY_REQUEST_DOCK 0
|
||||
#define SYSTEM_TRAY_BEGIN_MESSAGE 1
|
||||
#define SYSTEM_TRAY_CANCEL_MESSAGE 2
|
||||
|
||||
#define EGG_TYPE_TRAY_ICON (egg_tray_icon_get_type ())
|
||||
#define EGG_TRAY_ICON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_TRAY_ICON, EggTrayIcon))
|
||||
#define EGG_TRAY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_TRAY_ICON, EggTrayIconClass))
|
||||
#define EGG_IS_TRAY_ICON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_TRAY_ICON))
|
||||
#define EGG_IS_TRAY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_TRAY_ICON))
|
||||
#define EGG_TRAY_ICON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_TRAY_ICON, EggTrayIconClass))
|
||||
|
||||
#define EVENT_REFRESH 2
|
||||
#define EVENT_UPDATE 3
|
||||
#define N_SERVER 100
|
||||
#define ANI_TIME 10
|
||||
|
||||
static const char kde_window_manger[]="KWin";
|
||||
|
||||
typedef struct _EggTrayIcon EggTrayIcon;
|
||||
typedef struct _EggTrayIconClass EggTrayIconClass;
|
||||
|
||||
struct _EggTrayIcon
|
||||
{
|
||||
GtkPlug parent_instance;
|
||||
guint stamp;
|
||||
Atom selection_atom;
|
||||
Atom manager_atom;
|
||||
Atom system_tray_opcode_atom;
|
||||
Window manager_window;
|
||||
GtkWidget *box;
|
||||
GtkWidget *background;
|
||||
GtkWidget *image;
|
||||
GdkPixbuf *default_pix;
|
||||
gboolean ready;
|
||||
};
|
||||
|
||||
struct _EggTrayIconClass
|
||||
{
|
||||
GtkPlugClass parent_class;
|
||||
};
|
||||
|
||||
GType egg_tray_icon_get_type (void);
|
||||
static GtkPlugClass *parent_class = NULL;
|
||||
|
||||
EggTrayIcon *egg_tray_icon_new (const gchar *name, GdkPixbuf *pix);
|
||||
guint egg_tray_icon_send_message (EggTrayIcon *icon, gint timeout, const char *message, gint len);
|
||||
void egg_tray_icon_cancel_message (EggTrayIcon *icon, guint id);
|
||||
static void egg_tray_icon_init (EggTrayIcon *icon);
|
||||
static void egg_tray_icon_class_init (EggTrayIconClass *klass);
|
||||
static void egg_tray_icon_unrealize (GtkWidget *widget);
|
||||
static void egg_tray_icon_update_manager_window (EggTrayIcon *icon);
|
||||
GdkPixbuf *kde_dock_background(EggTrayIcon *icon);
|
||||
|
||||
GtkTooltips *tray_icon_tips = NULL;
|
||||
EggTrayIcon *tray_icon = NULL;
|
||||
|
||||
GdkPixbuf *frame_basic;
|
||||
|
||||
GtkWidget *menu = NULL;
|
||||
GtkWidget *refresh_item;
|
||||
GtkWidget *update_item;
|
||||
GtkWidget *stop_item;
|
||||
GtkWidget *show_item;
|
||||
GtkWidget *hide_item;
|
||||
GtkWidget *exit_item;
|
||||
|
||||
typedef struct _frame frame;
|
||||
|
||||
struct _frame
|
||||
{
|
||||
GdkPixbuf *pix;
|
||||
gint delay;
|
||||
};
|
||||
|
||||
typedef struct _animation animation;
|
||||
|
||||
struct _animation
|
||||
{
|
||||
GArray *array;
|
||||
frame current_frame;
|
||||
gint frame_counter;
|
||||
gint time_counter;
|
||||
gboolean loop;
|
||||
};
|
||||
|
||||
static animation *busy_ani;
|
||||
static animation *ready_ani;
|
||||
|
||||
static GtkWidget *window; /* copy of the main window */
|
||||
static gint x_pos = 50;
|
||||
static gint y_pos = 50;
|
||||
|
||||
static gboolean animation_running = FALSE;
|
||||
static gboolean refresh_update=FALSE;
|
||||
|
||||
static gint animation_timer=0;
|
||||
static gint animation_callback (gpointer nothing);
|
||||
|
||||
gboolean tray_icon_work(void)
|
||||
{
|
||||
if (!tray_icon)
|
||||
return FALSE;
|
||||
|
||||
return tray_icon->ready;
|
||||
}
|
||||
|
||||
/*user close main window-> hide it*/
|
||||
void tray_delete_event_hook(void)
|
||||
{
|
||||
gtk_window_get_position(GTK_WINDOW(window), &x_pos, &y_pos);
|
||||
gtk_widget_hide(window);
|
||||
}
|
||||
|
||||
void show_main_window_call(GtkWidget * button, void *data)
|
||||
{
|
||||
static gboolean first_call = TRUE;
|
||||
|
||||
if (first_call) {
|
||||
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
|
||||
gtk_widget_show(window);
|
||||
first_call = FALSE;
|
||||
} else {
|
||||
gtk_window_move(GTK_WINDOW(window), x_pos, y_pos);
|
||||
gtk_widget_show(window);
|
||||
}
|
||||
}
|
||||
|
||||
void hide_main_window_call(GtkWidget * button, void *data)
|
||||
{
|
||||
gtk_window_get_position(GTK_WINDOW(window), &x_pos, &y_pos);
|
||||
gtk_widget_hide(window);
|
||||
}
|
||||
|
||||
void exit_call(GtkWidget * button, void *data)
|
||||
{
|
||||
gtk_widget_destroy(GTK_WIDGET(tray_icon));
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
void set_menu_sens(void)
|
||||
{
|
||||
gtk_widget_set_sensitive (show_item, !GTK_WIDGET_VISIBLE(window));
|
||||
gtk_widget_set_sensitive (hide_item, GTK_WIDGET_VISIBLE(window));
|
||||
gtk_widget_set_sensitive (stop_item, refresh_update);
|
||||
}
|
||||
|
||||
static void
|
||||
tray_icon_pressed(GtkWidget * button, GdkEventButton * event, EggTrayIcon * icon)
|
||||
{
|
||||
|
||||
/*right click */
|
||||
if (event->button == 1) {
|
||||
if (GTK_WIDGET_VISIBLE(window)) {
|
||||
gtk_window_get_position(GTK_WINDOW(window), &x_pos, &y_pos);
|
||||
gtk_widget_hide(window);
|
||||
} else {
|
||||
show_main_window_call(NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*left click */
|
||||
if (event->button == 3) {
|
||||
|
||||
set_menu_sens ();
|
||||
|
||||
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0,
|
||||
gtk_get_current_event_time());
|
||||
}
|
||||
}
|
||||
|
||||
void tray_icon_set_tooltip(gchar * tip)
|
||||
{
|
||||
if (!tray_icon || !tray_icon->ready )
|
||||
return;
|
||||
|
||||
if(!tray_icon_tips)
|
||||
tray_icon_tips = gtk_tooltips_new();
|
||||
|
||||
gtk_tooltips_set_tip(GTK_TOOLTIPS(tray_icon_tips),
|
||||
GTK_WIDGET(tray_icon), tip, tip);
|
||||
}
|
||||
|
||||
static gint animation_callback(gpointer _ani)
|
||||
{
|
||||
animation *ani= _ani;
|
||||
|
||||
if (ani->frame_counter==0 && ani->time_counter==0) {
|
||||
ani->current_frame=g_array_index (ani->array, frame, ani->frame_counter);
|
||||
gtk_image_set_from_pixbuf(GTK_IMAGE(tray_icon->image), ani->current_frame.pix);
|
||||
}
|
||||
|
||||
if (ani->time_counter < ani->current_frame.delay) {
|
||||
ani->time_counter++;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (ani->frame_counter == ani->array->len-1) {
|
||||
ani->frame_counter= 0;
|
||||
ani->time_counter =0;
|
||||
|
||||
if (ani->loop) {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
animation_running=FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
ani->frame_counter++;
|
||||
ani->current_frame=g_array_index (ani->array, frame, ani->frame_counter);
|
||||
gtk_image_set_from_pixbuf(GTK_IMAGE(tray_icon->image), ani->current_frame.pix);
|
||||
ani->time_counter=0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void tray_icon_start_animation(void)
|
||||
{
|
||||
|
||||
if (!tray_icon_work())
|
||||
return;
|
||||
|
||||
refresh_update=TRUE;
|
||||
|
||||
if (animation_running) {
|
||||
if (animation_timer) g_source_remove(animation_timer);
|
||||
}
|
||||
|
||||
busy_ani->frame_counter = 0;
|
||||
busy_ani->time_counter = 0;
|
||||
|
||||
animation_timer = g_timeout_add(ANI_TIME, (GtkFunction) animation_callback, busy_ani);
|
||||
animation_running = TRUE;
|
||||
}
|
||||
|
||||
void tray_icon_stop_animation(void)
|
||||
{
|
||||
if (!tray_icon_work())
|
||||
return;
|
||||
|
||||
refresh_update=FALSE;
|
||||
set_menu_sens ();
|
||||
|
||||
if (animation_running) {
|
||||
if (animation_timer)
|
||||
g_source_remove(animation_timer);
|
||||
|
||||
ready_ani->frame_counter = 0;
|
||||
ready_ani->time_counter = 0;
|
||||
|
||||
animation_timer = g_timeout_add(ANI_TIME, (GtkFunction) animation_callback, ready_ani);
|
||||
}
|
||||
}
|
||||
|
||||
static animation *tray_icon_load_animation (gchar *name, gboolean loop)
|
||||
{
|
||||
|
||||
gint i=0;
|
||||
gint line_number=0;
|
||||
gboolean eof=FALSE;
|
||||
gchar *ani_file;
|
||||
gchar *content;
|
||||
gchar *begin;
|
||||
gchar *line;
|
||||
gchar *png_start;
|
||||
gchar *delay_string=NULL;
|
||||
gchar *png_filename;
|
||||
|
||||
animation *ani;
|
||||
frame tmp_frame;
|
||||
|
||||
if(!name) return NULL;
|
||||
|
||||
{
|
||||
char* tmp = g_strconcat("trayicon", G_DIR_SEPARATOR_S, name, NULL);
|
||||
ani_file = find_pixmap_directory(tmp);
|
||||
g_free(tmp);
|
||||
}
|
||||
|
||||
if(!ani_file || !g_file_get_contents (ani_file, &content, NULL, NULL))
|
||||
{
|
||||
xqf_warning("Could not load animation file '%s'", name);
|
||||
g_free(ani_file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ani=g_new(animation, 1);
|
||||
ani->array = g_array_new (FALSE, FALSE, sizeof (frame));
|
||||
ani->frame_counter = 0;
|
||||
ani->time_counter = 0;
|
||||
ani->loop = loop;
|
||||
|
||||
begin=content;
|
||||
|
||||
while (!eof) {
|
||||
|
||||
if ((content[i] == '\n') || (content[i] == '\0') ) {
|
||||
|
||||
if ( content[i-1] != '\n') {
|
||||
|
||||
line_number++;
|
||||
|
||||
do {
|
||||
|
||||
line= g_strndup (begin, &content[i]-begin);
|
||||
if (strlen (line) <= 1) {
|
||||
xqf_warning (_("Error in file: %s line: %d\n"), ani_file, line_number);
|
||||
break;
|
||||
}
|
||||
|
||||
png_start =g_strrstr (line, ".png");
|
||||
if (!png_start) {
|
||||
xqf_warning (_("Error in file: %s line: %d\n"), ani_file, line_number);
|
||||
break;
|
||||
}
|
||||
|
||||
delay_string=g_strdup (png_start+4);
|
||||
g_strstrip(delay_string);
|
||||
|
||||
if (strlen (delay_string) < 1) {
|
||||
xqf_warning (_("Error in file: %s line: %d\n"), ani_file, line_number);
|
||||
break;
|
||||
}
|
||||
|
||||
tmp_frame.delay= strtol(delay_string, NULL, 10);
|
||||
if (tmp_frame.delay== 0) {
|
||||
xqf_warning (_("Error in file: %s line: %d\n"), ani_file, line_number);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tmp_frame.delay != 1)
|
||||
tmp_frame.delay=tmp_frame.delay / 2;
|
||||
|
||||
*(png_start+4)=0; /*cut anything behind ".png" */
|
||||
|
||||
png_filename= g_strconcat(PACKAGE_DATA_DIR, G_DIR_SEPARATOR_S,"default",
|
||||
G_DIR_SEPARATOR_S, "trayicon", G_DIR_SEPARATOR_S, line, NULL);
|
||||
|
||||
tmp_frame.pix = load_pixmap_as_pixbuf (png_filename);
|
||||
if (tmp_frame.pix == NULL) {
|
||||
xqf_warning (_("Error in file: %s line: %d\n"), ani_file, line_number);
|
||||
break;
|
||||
}
|
||||
|
||||
if (png_filename)
|
||||
g_free (png_filename);
|
||||
|
||||
g_array_append_val (ani->array, tmp_frame);
|
||||
|
||||
} while (0);
|
||||
|
||||
if (line)
|
||||
g_free(line);
|
||||
if (delay_string)
|
||||
g_free(delay_string);
|
||||
|
||||
}
|
||||
|
||||
if (content[i] == '\0' || (content[i] == '\n' && content[i+1] == '\0' ))
|
||||
eof=TRUE;
|
||||
else
|
||||
begin=&content[i]+1;
|
||||
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (content)
|
||||
g_free(content);
|
||||
if (ani_file)
|
||||
g_free(ani_file);
|
||||
|
||||
return ani;
|
||||
}
|
||||
|
||||
void tray_create_menu (void)
|
||||
{
|
||||
|
||||
GtkWidget *separator1 = NULL;
|
||||
|
||||
menu = gtk_menu_new();
|
||||
|
||||
refresh_item = gtk_menu_item_new_with_label(_("Refresh"));
|
||||
g_signal_connect(G_OBJECT(refresh_item), "activate",
|
||||
G_CALLBACK(refresh_n_server), GINT_TO_POINTER(N_SERVER));
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(menu), refresh_item);
|
||||
|
||||
update_item= gtk_menu_item_new_with_label(_("Update"));
|
||||
g_signal_connect(G_OBJECT(update_item), "activate",
|
||||
G_CALLBACK(update_source_callback), NULL);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(menu), update_item);
|
||||
|
||||
stop_item = gtk_menu_item_new_with_label(_("Stop"));
|
||||
g_signal_connect(G_OBJECT(stop_item), "activate",
|
||||
G_CALLBACK(stop_callback), NULL);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(menu), stop_item);
|
||||
|
||||
separator1 = gtk_menu_item_new();
|
||||
gtk_widget_show(separator1);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(menu), separator1);
|
||||
gtk_widget_set_sensitive(separator1, FALSE);
|
||||
|
||||
show_item = gtk_menu_item_new_with_label(_("Show"));
|
||||
g_signal_connect(G_OBJECT(show_item), "activate",
|
||||
G_CALLBACK(show_main_window_call), NULL);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(menu), show_item);
|
||||
|
||||
hide_item= gtk_menu_item_new_with_label(_("Hide"));
|
||||
g_signal_connect(G_OBJECT(hide_item), "activate",
|
||||
G_CALLBACK(hide_main_window_call), NULL);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(menu), hide_item);
|
||||
|
||||
exit_item = gtk_menu_item_new_with_label(_("Exit"));
|
||||
g_signal_connect(G_OBJECT(exit_item), "activate",
|
||||
G_CALLBACK(exit_call), NULL);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(menu), exit_item);
|
||||
|
||||
gtk_widget_show_all(menu);
|
||||
}
|
||||
|
||||
void tray_init(GtkWidget * main_window)
|
||||
{
|
||||
gdk_pixbuf_xlib_init (GDK_DISPLAY(), DefaultScreen (GDK_DISPLAY()));
|
||||
|
||||
/* local copy */
|
||||
window = main_window;
|
||||
|
||||
gtk_window_get_position(GTK_WINDOW(window), &x_pos, &y_pos);
|
||||
|
||||
tray_create_menu();
|
||||
|
||||
busy_ani = tray_icon_load_animation ("busy.ani", TRUE);
|
||||
ready_ani = tray_icon_load_animation("ready.ani", FALSE);
|
||||
|
||||
frame_basic = load_pixmap_as_pixbuf("trayicon/frame_basic.png");
|
||||
|
||||
if(frame_basic)
|
||||
tray_icon = egg_tray_icon_new ("xqf", frame_basic);
|
||||
|
||||
if (tray_icon && tray_icon->ready)
|
||||
{
|
||||
g_signal_connect(tray_icon, "button_press_event",
|
||||
G_CALLBACK(tray_icon_pressed),tray_icon);
|
||||
|
||||
gtk_widget_hide(window);
|
||||
}
|
||||
else
|
||||
gtk_widget_show(window);
|
||||
}
|
||||
|
||||
void tray_done (void)
|
||||
{
|
||||
if (busy_ani)
|
||||
{
|
||||
if (busy_ani->array)
|
||||
g_array_free (busy_ani->array, TRUE);
|
||||
|
||||
if (ready_ani->array)
|
||||
g_array_free (ready_ani->array, TRUE);
|
||||
|
||||
g_free(busy_ani);
|
||||
}
|
||||
|
||||
g_free(ready_ani);
|
||||
|
||||
//FIXME
|
||||
//if (tray_icon)
|
||||
//gtk_widget_destroy(GTK_WIDGET(tray_icon));
|
||||
}
|
||||
|
||||
/*eggtrayicon stuff*/
|
||||
GType
|
||||
egg_tray_icon_get_type (void)
|
||||
{
|
||||
static GType our_type = 0;
|
||||
|
||||
our_type = g_type_from_name ("EggTrayIcon");
|
||||
|
||||
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);
|
||||
}
|
||||
else if (parent_class == NULL) {
|
||||
/* we're reheating the old class from a previous instance - engage ugly hack =( */
|
||||
egg_tray_icon_class_init ((EggTrayIconClass *)g_type_class_peek (our_type));
|
||||
}
|
||||
|
||||
return our_type;
|
||||
}
|
||||
|
||||
static void
|
||||
egg_tray_icon_init (EggTrayIcon *icon)
|
||||
{
|
||||
icon->stamp = 1;
|
||||
gtk_widget_add_events (GTK_WIDGET (icon), GDK_PROPERTY_CHANGE_MASK);
|
||||
}
|
||||
|
||||
static void
|
||||
egg_tray_icon_class_init (EggTrayIconClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
widget_class->unrealize = egg_tray_icon_unrealize;
|
||||
}
|
||||
|
||||
static GdkFilterReturn
|
||||
egg_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 == DestroyNotify)
|
||||
{
|
||||
egg_tray_icon_update_manager_window (icon);
|
||||
}
|
||||
}
|
||||
|
||||
return GDK_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
egg_tray_icon_unrealize (GtkWidget *widget)
|
||||
{
|
||||
EggTrayIcon *icon = EGG_TRAY_ICON (widget);
|
||||
GdkWindow *root_window=NULL;
|
||||
|
||||
if (icon->manager_window != None)
|
||||
{
|
||||
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 void
|
||||
egg_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;
|
||||
|
||||
gdk_error_trap_push ();
|
||||
XSendEvent (display,
|
||||
icon->manager_window, False, NoEventMask, (XEvent *)&ev);
|
||||
XSync (display, False);
|
||||
gdk_error_trap_pop ();
|
||||
|
||||
icon->ready=TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
egg_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);
|
||||
}
|
||||
|
||||
/*from gdk-pixbuf-xlib-drawabel.c*/
|
||||
static gboolean
|
||||
xlib_window_is_viewable (Window w)
|
||||
{
|
||||
XWindowAttributes wa;
|
||||
|
||||
while (w != 0) {
|
||||
Window parent, root, *children;
|
||||
int nchildren;
|
||||
|
||||
XGetWindowAttributes (GDK_DISPLAY(), w, &wa);
|
||||
|
||||
if (wa.map_state != IsViewable) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!XQueryTree (GDK_DISPLAY(), w, &root,
|
||||
&parent, &children, &nchildren))
|
||||
return FALSE;
|
||||
|
||||
if (nchildren > 0)
|
||||
XFree (children);
|
||||
|
||||
if ((parent == root) || (w == root))
|
||||
return TRUE;
|
||||
|
||||
w = parent;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean kde_dock (EggTrayIcon *icon)
|
||||
{
|
||||
|
||||
Window win;
|
||||
Window data;
|
||||
Atom kde_tray_atom = XInternAtom (GDK_DISPLAY(), "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False);
|
||||
Atom kde_dock_atom = XInternAtom (GDK_DISPLAY(), "KWM_DOCKWINDOW", False); //KDE 2 support not tested
|
||||
|
||||
win = GDK_WINDOW_XID (GTK_WIDGET (icon)->window);
|
||||
|
||||
XSetWindowBackgroundPixmap(GDK_DISPLAY(), win, ParentRelative);
|
||||
|
||||
data = 1;
|
||||
XChangeProperty (GDK_DISPLAY(), win, kde_dock_atom, XA_WINDOW, 32,
|
||||
PropModeReplace, (unsigned char *)&data, 1);
|
||||
data = GDK_WINDOW_XID (window->window);
|
||||
XChangeProperty (GDK_DISPLAY(), win, kde_tray_atom, XA_WINDOW, 32,
|
||||
PropModeReplace, (unsigned char *)&data, 1);
|
||||
|
||||
XMapWindow (GDK_DISPLAY(), win);
|
||||
XFlush (GDK_DISPLAY());
|
||||
|
||||
return (xlib_window_is_viewable(win));
|
||||
}
|
||||
|
||||
GdkPixbuf *kde_dock_background(EggTrayIcon *icon)
|
||||
{
|
||||
|
||||
Window win;
|
||||
XWindowAttributes wa;
|
||||
GdkPixbuf *background;
|
||||
|
||||
win = GDK_WINDOW_XID (GTK_WIDGET (icon)->window);
|
||||
XGetWindowAttributes (GDK_DISPLAY(),win, &wa);
|
||||
|
||||
background=gdk_pixbuf_xlib_get_from_drawable (NULL, win, 0, NULL,
|
||||
0, 0, 0, 0, wa.width, wa.height);
|
||||
|
||||
return background;
|
||||
}
|
||||
|
||||
static void
|
||||
egg_tray_icon_update_manager_window (EggTrayIcon *icon)
|
||||
{
|
||||
|
||||
static GdkPixbuf *background_pixbuf;
|
||||
const gchar *window_manager=NULL;
|
||||
|
||||
if (icon->manager_window != None) {
|
||||
GdkWindow *gdkwin;
|
||||
gdkwin = gdk_window_lookup (icon->manager_window);
|
||||
gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon);
|
||||
}
|
||||
|
||||
XGrabServer (GDK_DISPLAY());
|
||||
|
||||
icon->manager_window = XGetSelectionOwner (GDK_DISPLAY(),
|
||||
icon->selection_atom);
|
||||
|
||||
if (icon->manager_window != None)
|
||||
XSelectInput (GDK_DISPLAY(), icon->manager_window, StructureNotifyMask);
|
||||
|
||||
XUngrabServer (GDK_DISPLAY());
|
||||
XFlush (GDK_DISPLAY());
|
||||
|
||||
if (icon->manager_window == None)
|
||||
return;
|
||||
|
||||
window_manager=gdk_x11_screen_get_window_manager_name (gdk_screen_get_default());
|
||||
|
||||
if ( !g_ascii_strcasecmp(window_manager, kde_window_manger) && kde_dock (icon)) {
|
||||
|
||||
if ((background_pixbuf=kde_dock_background(icon)) !=NULL) {
|
||||
|
||||
icon->box= gtk_fixed_new ();
|
||||
gtk_fixed_set_has_window(GTK_FIXED (icon->box),TRUE);
|
||||
gtk_container_add(GTK_CONTAINER(icon), icon->box);
|
||||
|
||||
icon->image=gtk_image_new ();
|
||||
gtk_image_set_from_pixbuf(GTK_IMAGE(icon->image), icon->default_pix);
|
||||
|
||||
icon->background =gtk_image_new ();
|
||||
gtk_image_set_from_pixbuf(GTK_IMAGE(icon->background), background_pixbuf);
|
||||
|
||||
gtk_fixed_put (GTK_FIXED (icon->box), GTK_WIDGET(icon->background), 0, 0);
|
||||
gtk_fixed_put (GTK_FIXED (icon->box), GTK_WIDGET(icon->image), 0, 0);
|
||||
|
||||
gtk_widget_show (icon->background);
|
||||
gtk_widget_show (icon->image);
|
||||
gtk_widget_show(icon->box);
|
||||
|
||||
icon->ready=TRUE;
|
||||
}
|
||||
} else {
|
||||
|
||||
icon->box=gtk_event_box_new ();
|
||||
gtk_container_add(GTK_CONTAINER(icon), icon->box);
|
||||
|
||||
icon->image=gtk_image_new ();
|
||||
gtk_image_set_from_pixbuf(GTK_IMAGE(icon->image),icon->default_pix);
|
||||
gtk_container_add(GTK_CONTAINER(icon->box), icon->image);
|
||||
|
||||
gtk_widget_show (icon->image);
|
||||
gtk_widget_show(icon->box);
|
||||
|
||||
GdkWindow *gdkwin;
|
||||
|
||||
gdkwin = gdk_window_lookup (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);
|
||||
}
|
||||
}
|
||||
|
||||
EggTrayIcon *
|
||||
egg_tray_icon_new (const char *name, GdkPixbuf *pix)
|
||||
{
|
||||
EggTrayIcon *icon;
|
||||
char buffer[256];
|
||||
GdkWindow *root_window;
|
||||
Screen *xscreen=DefaultScreenOfDisplay (GDK_DISPLAY());
|
||||
|
||||
g_return_val_if_fail (pix!= NULL, NULL);
|
||||
|
||||
icon = g_object_new (EGG_TYPE_TRAY_ICON, NULL);
|
||||
gtk_window_set_title (GTK_WINDOW (icon), name);
|
||||
|
||||
gtk_plug_construct (GTK_PLUG (icon), 0);
|
||||
gtk_widget_realize (GTK_WIDGET (icon));
|
||||
|
||||
icon->ready=FALSE;
|
||||
icon->default_pix=pix;
|
||||
|
||||
/* Now see if there's a manager window around */
|
||||
g_snprintf (buffer, sizeof (buffer), "_NET_SYSTEM_TRAY_S%d",
|
||||
XScreenNumberOfScreen (xscreen));
|
||||
|
||||
icon->selection_atom = XInternAtom (DisplayOfScreen (xscreen),
|
||||
buffer, False);
|
||||
|
||||
icon->manager_atom = XInternAtom (DisplayOfScreen (xscreen),
|
||||
"MANAGER", False);
|
||||
|
||||
icon->system_tray_opcode_atom = XInternAtom (DisplayOfScreen (xscreen),
|
||||
"_NET_SYSTEM_TRAY_OPCODE", False);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (icon));
|
||||
egg_tray_icon_update_manager_window (icon);
|
||||
root_window = gdk_window_lookup (gdk_x11_get_default_root_xwindow ());
|
||||
|
||||
/* Add a root window filter so that we get changes on MANAGER */
|
||||
gdk_window_add_filter (root_window, egg_tray_icon_manager_filter, icon);
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
guint
|
||||
egg_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();
|
||||
|
||||
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 (GDK_DISPLAY(),
|
||||
icon->manager_window, False, StructureNotifyMask, (XEvent *)&ev);
|
||||
XSync (GDK_DISPLAY(), False);
|
||||
}
|
||||
gdk_error_trap_pop ();
|
||||
|
||||
return stamp;
|
||||
}
|
||||
|
||||
void
|
||||
egg_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);
|
||||
}
|
||||
|
||||
#endif /*GTK 2*/
|
48
xqf/src/trayicon.h
Normal file
48
xqf/src/trayicon.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* XQF - Quake server browser and launcher
|
||||
*
|
||||
* 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
|
||||
.*
|
||||
.*
|
||||
.* trayicon.c:
|
||||
.*
|
||||
* Copyright (C) Jochen Baier <email@jochen-baier.de>
|
||||
.*
|
||||
.* based on:
|
||||
.*
|
||||
.* eggtrayicon.c api
|
||||
.*
|
||||
* Copyright (C) Anders Carlsson <andersca@gnu.org>
|
||||
.*
|
||||
.* magic transparent KDE icon:
|
||||
.*
|
||||
.* Copyright (C) Jochen Baier <email@jochen-baier.de>
|
||||
.*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _system_tray_h_
|
||||
#define _system_tray_h_
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
extern void tray_init (GtkWidget * window) ;
|
||||
extern void tray_done (void);
|
||||
extern void tray_delete_event_hook (void);
|
||||
extern void tray_icon_set_tooltip (gchar *tip);
|
||||
extern gboolean tray_icon_work(void);
|
||||
extern void tray_icon_stop_animation (void);
|
||||
extern void tray_icon_start_animation (void);
|
||||
|
||||
#endif /*_system_tray_h_*/
|
@ -34,6 +34,7 @@
|
||||
#include "sort.h"
|
||||
#include "pref.h"
|
||||
#include "debug.h"
|
||||
#include "trayicon.h"
|
||||
|
||||
static GSList *xqf_windows = NULL;
|
||||
static GtkWidget *target_window = NULL;
|
||||
@ -128,13 +129,22 @@ void print_status (GtkWidget *sbar, char *fmt, ...) {
|
||||
|
||||
gtk_statusbar_pop (GTK_STATUSBAR (sbar), context_id);
|
||||
gtk_statusbar_push (GTK_STATUSBAR (sbar), context_id, buf);
|
||||
|
||||
if (default_show_tray_icon)
|
||||
tray_icon_set_tooltip(buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int window_delete_event_callback (GtkWidget *widget, gpointer data) {
|
||||
target_window = widget;
|
||||
gtk_widget_destroy ((GtkWidget *) (xqf_windows->data));
|
||||
|
||||
if (default_show_tray_icon && tray_icon_work()) {
|
||||
tray_delete_event_hook();
|
||||
}
|
||||
else {
|
||||
target_window = widget;
|
||||
gtk_widget_destroy ((GtkWidget *) (xqf_windows->data));
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -844,5 +854,3 @@ GtkWidget *create_server_type_menu (enum server_type active_type,
|
||||
|
||||
return option_menu;
|
||||
}
|
||||
|
||||
|
||||
|
@ -81,6 +81,7 @@
|
||||
#include "redial.h"
|
||||
#include "splash.h"
|
||||
#include "loadpixmap.h"
|
||||
#include "trayicon.h"
|
||||
|
||||
#ifdef USE_GEOIP
|
||||
#include "country-filter.h"
|
||||
@ -961,6 +962,8 @@ static void stat_lists_state_handler (struct stat_job *job,
|
||||
|
||||
case STAT_UPDATE_SOURCE:
|
||||
progress_bar_str = _("Updating lists...");
|
||||
if (default_show_tray_icon)
|
||||
tray_icon_start_animation ();
|
||||
break;
|
||||
|
||||
case STAT_RESOLVE_NAMES:
|
||||
@ -969,6 +972,8 @@ static void stat_lists_state_handler (struct stat_job *job,
|
||||
|
||||
case STAT_REFRESH_SERVERS:
|
||||
progress_bar_str = _("Refreshing: %d/%d");
|
||||
if (default_show_tray_icon)
|
||||
tray_icon_start_animation ();
|
||||
break;
|
||||
|
||||
case STAT_RESOLVE_HOSTS:
|
||||
@ -1001,6 +1006,8 @@ static void stat_lists_close_handler (struct stat_job *job, int killed) {
|
||||
print_status (main_status_bar, _("Waiting to redial server(s)..."));
|
||||
else
|
||||
*/
|
||||
|
||||
tray_icon_stop_animation ();
|
||||
print_status (main_status_bar, _("Done."));
|
||||
|
||||
progress_bar_reset (main_progress_bar);
|
||||
@ -1494,7 +1501,7 @@ static int srvinf_clist_compare_func (GtkCList *clist,
|
||||
}
|
||||
|
||||
|
||||
static void update_source_callback (GtkWidget *widget, gpointer data) {
|
||||
void update_source_callback (GtkWidget *widget, gpointer data) {
|
||||
GSList *masters = NULL;
|
||||
GSList *servers = NULL;
|
||||
GSList *uservers = NULL;
|
||||
@ -1554,8 +1561,24 @@ static void refresh_callback (GtkWidget *widget, gpointer data) {
|
||||
}
|
||||
}
|
||||
|
||||
void refresh_n_server (GtkWidget * button, gpointer *data)
|
||||
{
|
||||
GSList *list;
|
||||
gint number;
|
||||
|
||||
static void stop_callback (GtkWidget *widget, gpointer data) {
|
||||
if (stat_process)
|
||||
return;
|
||||
|
||||
event_type = EVENT_REFRESH;
|
||||
number=GPOINTER_TO_INT(data);
|
||||
|
||||
list = server_clist_get_n_servers(number);
|
||||
|
||||
if (list)
|
||||
stat_lists(NULL, NULL, list, NULL);
|
||||
}
|
||||
|
||||
void stop_callback (GtkWidget *widget, gpointer data) {
|
||||
|
||||
event_type = 0; // To prevent sound from stopped action from playing
|
||||
|
||||
@ -3584,8 +3607,6 @@ void create_main_window (void) {
|
||||
|
||||
window_set_icon(main_window);
|
||||
|
||||
gtk_widget_show (main_window);
|
||||
|
||||
gtk_window_add_accel_group (GTK_WINDOW (main_window), accel_group);
|
||||
gtk_accel_group_unref (accel_group);
|
||||
|
||||
@ -3595,7 +3616,6 @@ void create_main_window (void) {
|
||||
gtk_tooltips_enable(tooltips);
|
||||
else
|
||||
gtk_tooltips_disable(tooltips);
|
||||
|
||||
}
|
||||
|
||||
void play_sound (const char *sound, const int override)
|
||||
@ -3898,6 +3918,11 @@ int main (int argc, char *argv[]) {
|
||||
|
||||
create_main_window ();
|
||||
|
||||
if (default_show_tray_icon)
|
||||
tray_init(main_window);
|
||||
else
|
||||
gtk_widget_show (main_window);
|
||||
|
||||
source_ctree_select_source (favorites);
|
||||
filter_menu_activate_current();
|
||||
|
||||
@ -3912,10 +3937,15 @@ int main (int argc, char *argv[]) {
|
||||
|
||||
debug(1,"startup time %ds", time(NULL)-xqf_start_time);
|
||||
|
||||
tray_icon_set_tooltip(_("nothing yet..."));
|
||||
|
||||
gtk_main ();
|
||||
|
||||
play_sound(sound_xqf_quit, 0);
|
||||
|
||||
if (default_show_tray_icon)
|
||||
tray_done();
|
||||
|
||||
unregister_window (main_window);
|
||||
main_window = NULL;
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <arpa/inet.h> /* struct in_addr */
|
||||
#include <time.h> /* time_t */
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib.h>
|
||||
|
||||
#define RC_DIR ".qf"
|
||||
@ -277,5 +278,8 @@ extern int event_type;
|
||||
extern int dontlaunch;
|
||||
|
||||
extern void refresh_source_list (void);
|
||||
extern void update_source_callback (GtkWidget *widget, gpointer data);
|
||||
extern void refresh_n_server(GtkWidget * button, gpointer *data);
|
||||
extern void stop_callback (GtkWidget *widget, gpointer data);
|
||||
|
||||
#endif /* __XQF_H__ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user