📄 wmxmms.c
字号:
/* XMMS - Cross-platform multimedia player * Copyright (C) 1998-2002 Peter Alm, Mikael Alm, Olle Hallnas, * Thomas Nilsson and 4Front Technologies * * 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 <gtk/gtk.h>#include <gdk/gdkx.h>#include <X11/Xlib.h>#include <X11/Xatom.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include "xmms/i18n.h"#include "config.h"#include "libxmms/xmmsctrl.h"#include "xmms-dock-master.xpm"#include "getopt.h"typedef struct{ int x, y, width, height, pressed_x, pressed_y, normal_x, normal_y; gboolean focus, pressed; void (*callback) (void);}Button;void action_play(void);void action_pause(void);void action_eject(void);void action_prev(void);void action_next(void);void action_stop(void);Button buttons[] ={ {21, 28, 9, 11, 20, 64, 0, 64, FALSE, FALSE, action_play}, /* PLAY */ {33, 28, 9, 11, 30, 64, 10, 64, FALSE, FALSE, action_pause}, /* PAUSE */ {45, 28, 9, 11, 20, 75, 0, 75, FALSE, FALSE, action_eject}, /* EJECT */ {21, 42, 9, 11, 20, 86, 0, 86, FALSE, FALSE, action_prev}, /* PREV */ {33, 42, 9, 11, 30, 86, 10, 86, FALSE, FALSE, action_next}, /* NEXT */ {45, 42, 9, 11, 30, 75, 10, 75, FALSE, FALSE, action_stop}, /* STOP */};#define NUM_BUTTONS 6GList *button_list;#define VOLSLIDER_X 11#define VOLSLIDER_Y 12#define VOLSLIDER_WIDTH 6#define VOLSLIDER_HEIGHT 40#define SEEKSLIDER_X 21#define SEEKSLIDER_Y 16#define SEEKSLIDER_WIDTH 30#define SEEKSLIDER_HEIGHT 7#define SEEKSLIDER_KNOB_WIDTH 3#define SEEKSLIDER_MAX (SEEKSLIDER_WIDTH - SEEKSLIDER_KNOB_WIDTH)gboolean volslider_dragging = FALSE;int volslider_pos = 0;gboolean seekslider_visible = FALSE, seekslider_dragging = FALSE;int seekslider_pos = -1, seekslider_drag_offset = 0;int timeout_tag = 0;void init(void);GtkWidget *window, *icon_win;GdkPixmap *pixmap, *launch_pixmap;GdkBitmap *mask, *launch_mask;GdkGC *dock_gc;GtkTooltips *tooltips = NULL;int xmms_session = 0;char *xmms_cmd = "xmms";gboolean xmms_running = FALSE;gboolean has_geometry = FALSE, single_click = FALSE, song_title = FALSE;char *icon_name = NULL;int win_x, win_y;GtkTargetEntry drop_types[] ={ {"text/plain", 0, 1}};/* Does anyone know a better way? */extern Window gdk_leader_window;void action_play(void){ xmms_remote_play(xmms_session);}void action_pause(void){ xmms_remote_pause(xmms_session);}void action_eject(void){ xmms_remote_eject(xmms_session);}void action_prev(void){ xmms_remote_playlist_prev(xmms_session);}void action_next(void){ xmms_remote_playlist_next(xmms_session);}void action_stop(void){ xmms_remote_stop(xmms_session);}gboolean inside_region(int mx, int my, int x, int y, int w, int h){ if ((mx >= x && mx < x + w) && (my >= y && my < y + h)) return TRUE; return FALSE;}void real_draw_button(GdkWindow *w, Button *button){ if (button->pressed) gdk_draw_pixmap(w, dock_gc, pixmap, button->pressed_x, button->pressed_y, button->x, button->y, button->width, button->height); else gdk_draw_pixmap(w, dock_gc, pixmap, button->normal_x, button->normal_y, button->x, button->y, button->width, button->height);}void draw_button(Button *button){ real_draw_button(window->window, button); real_draw_button(icon_win->window, button);}void draw_buttons(GList *list){ for (; list; list = g_list_next(list)) draw_button(list->data);}void real_draw_volslider(GdkWindow *w){ gdk_draw_pixmap(w, dock_gc, pixmap, 48, 65, VOLSLIDER_X, VOLSLIDER_Y, VOLSLIDER_WIDTH, VOLSLIDER_HEIGHT); gdk_draw_pixmap(w, dock_gc, pixmap, 42, 65 + VOLSLIDER_HEIGHT - volslider_pos, VOLSLIDER_X, VOLSLIDER_Y + VOLSLIDER_HEIGHT - volslider_pos, VOLSLIDER_WIDTH, volslider_pos);}void draw_volslider(void){ real_draw_volslider(window->window); real_draw_volslider(icon_win->window);}void real_draw_seekslider(GdkWindow *w){ int slider_x; if (seekslider_visible) { gdk_draw_pixmap(w, dock_gc, pixmap, 2, 114, 19, 12, 35, 14); if (seekslider_pos < SEEKSLIDER_MAX / 3) slider_x = 44; else if (seekslider_pos < (SEEKSLIDER_MAX * 2) / 3) slider_x = 47; else slider_x = 50; gdk_draw_pixmap(w, dock_gc, pixmap, slider_x, 112, SEEKSLIDER_X + seekslider_pos, SEEKSLIDER_Y, 3, SEEKSLIDER_HEIGHT); } else gdk_draw_pixmap(w, dock_gc, pixmap, 2, 100, 19, 12, 35, 14);}void draw_seekslider(void){ real_draw_seekslider(window->window); real_draw_seekslider(icon_win->window);}void redraw_window(void){ if (xmms_running) { gdk_draw_pixmap(window->window, dock_gc, pixmap, 0, 0, 0, 0, 64, 64); gdk_draw_pixmap(icon_win->window, dock_gc, pixmap, 0, 0, 0, 0, 64, 64); draw_buttons(button_list); draw_volslider(); draw_seekslider(); } else { gdk_draw_pixmap(window->window, dock_gc, launch_pixmap, 0, 0, 0, 0, 64, 64); gdk_draw_pixmap(icon_win->window, dock_gc, launch_pixmap, 0, 0, 0, 0, 64, 64); }}void expose_cb(GtkWidget *w, GdkEventExpose *event, gpointer data){ redraw_window();}void button_press_cb(GtkWidget *w, GdkEventButton *event, gpointer data){ GList *node; Button *btn; int pos; char *cmd; if (xmms_running) { if (event->button == 2) { if(xmms_remote_is_pl_win(xmms_session)) xmms_remote_pl_win_toggle(xmms_session, 0); else xmms_remote_pl_win_toggle(xmms_session, 1); } else if (event->button == 3) { if(xmms_remote_is_main_win(xmms_session)) xmms_remote_main_win_toggle(xmms_session, 0); else xmms_remote_main_win_toggle(xmms_session, 1); } else if (event->button == 4 || event->button == 5) { if (event->button == 4) volslider_pos += 3; else volslider_pos -= 3; if (volslider_pos < 0) volslider_pos = 0; if (volslider_pos > VOLSLIDER_HEIGHT) volslider_pos = VOLSLIDER_HEIGHT; xmms_remote_set_main_volume(xmms_session, (volslider_pos * 100) / VOLSLIDER_HEIGHT); draw_volslider(); } } if (event->button != 1) return; if (xmms_running) { for (node = button_list; node; node = g_list_next(node)) { btn = node->data; if (inside_region(event->x, event->y, btn->x, btn->y, btn->width, btn->height)) { btn->focus = TRUE; btn->pressed = TRUE; draw_button(btn); } } if (inside_region(event->x, event->y, VOLSLIDER_X, VOLSLIDER_Y, VOLSLIDER_WIDTH, VOLSLIDER_HEIGHT)) { volslider_pos = VOLSLIDER_HEIGHT - (event->y - VOLSLIDER_Y); xmms_remote_set_main_volume(xmms_session, (volslider_pos * 100) / VOLSLIDER_HEIGHT); draw_volslider(); volslider_dragging = TRUE; } if (inside_region(event->x, event->y, SEEKSLIDER_X, SEEKSLIDER_Y, SEEKSLIDER_WIDTH, SEEKSLIDER_HEIGHT) && seekslider_visible) { pos = event->x - SEEKSLIDER_X; if (pos >= seekslider_pos && pos < seekslider_pos + SEEKSLIDER_KNOB_WIDTH) seekslider_drag_offset = pos - seekslider_pos; else { seekslider_drag_offset = 1; seekslider_pos = pos - seekslider_drag_offset; if (seekslider_pos < 0) seekslider_pos = 0; if (seekslider_pos > SEEKSLIDER_MAX) seekslider_pos = SEEKSLIDER_MAX; } draw_seekslider(); seekslider_dragging = TRUE; } } else if ((!single_click && event->type == GDK_2BUTTON_PRESS) || (single_click && event->type == GDK_BUTTON_PRESS)) { cmd = g_strconcat(xmms_cmd, " &", NULL); system(cmd); g_free(cmd); }}void button_release_cb(GtkWidget *w, GdkEventButton *event, gpointer data){ GList *node; Button *btn; int len; if (event->button != 1) return; for (node = button_list; node; node = g_list_next(node)) { btn = node->data; if (btn->pressed) { btn->focus = FALSE; btn->pressed = FALSE; draw_button(btn); if (btn->callback) btn->callback(); } } volslider_dragging = FALSE; if (seekslider_dragging) { len = xmms_remote_get_playlist_time(xmms_session, xmms_remote_get_playlist_pos(xmms_session)); xmms_remote_jump_to_time(xmms_session, (seekslider_pos * len) / SEEKSLIDER_MAX); seekslider_dragging = FALSE; }}void motion_notify_cb(GtkWidget *w, GdkEventMotion *event, gpointer data){ GList *node; Button *btn; gboolean inside; for (node = button_list; node; node = g_list_next(node)) { btn = node->data; if (btn->focus) { inside = inside_region(event->x, event->y, btn->x, btn->y, btn->width, btn->height); if ((inside && !btn->pressed) || (!inside && btn->pressed)) { btn->pressed = inside; draw_button(btn); } } } if (volslider_dragging) { volslider_pos = VOLSLIDER_HEIGHT - (event->y - VOLSLIDER_Y); if (volslider_pos < 0) volslider_pos = 0; if (volslider_pos > VOLSLIDER_HEIGHT) volslider_pos = VOLSLIDER_HEIGHT; xmms_remote_set_main_volume(xmms_session, (volslider_pos * 100) / VOLSLIDER_HEIGHT); draw_volslider(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -