📄 skin.c
字号:
/* XMMS - Cross-platform multimedia player * Copyright (C) 1998-2002 Peter Alm, Mikael Alm, Olle Hallnas, * Thomas Nilsson and 4Front Technologies * Copyright (C) 1999-2002 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 "xmms.h"#include "defskin/main.xpm"#include "defskin/cbuttons.xpm"#include "defskin/titlebar.xpm"#include "defskin/shufrep.xpm"#include "defskin/text.xpm"#include "defskin/volume.xpm"#include "defskin/monoster.xpm"#include "defskin/playpaus.xpm"#include "defskin/nums_ex.xpm"#include "defskin/posbar.xpm"#include "defskin/pledit.xpm"#include "defskin/eqmain.xpm"#include "defskin/eq_ex.xpm"#include <ctype.h>#ifndef HAVE_MKDTEMPchar* mkdtemp(char* path);#endifSkin *skin;static int skin_current_num;static const gint skin_default_viscolor[24][3] ={ {9,34,53}, {10,18,26}, {0,54,108}, {0,58,116}, {0,62,124}, {0,66,132}, {0,70,140}, {0,74,148}, {0,78,156}, {0,82,164}, {0,86,172}, {0,92,184}, {0,98,196}, {0,104,208}, {0,110,220}, {0,116,232}, {0,122,244}, {0,128,255}, {0,128,255}, {0,104,208}, {0,80,160}, {0,56,112}, {0,32,64}, {200, 200, 200}};static void setup_skin_masks(void){ if (cfg.show_wm_decorations) return; if (cfg.player_visible) { gtk_widget_shape_combine_mask(mainwin, skin_get_mask(SKIN_MASK_MAIN, cfg.doublesize, cfg.player_shaded), 0, 0); } gtk_widget_shape_combine_mask(equalizerwin, skin_get_mask(SKIN_MASK_EQ, EQUALIZER_DOUBLESIZE, cfg.equalizer_shaded), 0, 0);}static GdkBitmap *create_default_mask(GdkWindow * parent, gint w, gint h){ GdkBitmap *ret; GdkGC *gc; GdkColor pattern; ret = gdk_pixmap_new(parent, w, h, 1); gc = gdk_gc_new(ret); pattern.pixel = 1; gdk_gc_set_foreground(gc, &pattern); gdk_draw_rectangle(ret, gc, TRUE, 0, 0, w, h); gdk_gc_destroy(gc); return ret;}static void load_def_pixmap(SkinPixmap *skinpixmap, gchar **skindata){ skinpixmap->def_pixmap = gdk_pixmap_create_from_xpm_d(mainwin->window, NULL, NULL, skindata); gdk_window_get_size(skinpixmap->def_pixmap, &skinpixmap->width, &skinpixmap->height);}static void skin_query_color(GdkColormap *cm, GdkColor *c){ XColor xc = {0}; xc.pixel = c->pixel; XQueryColor(GDK_COLORMAP_XDISPLAY(cm), GDK_COLORMAP_XCOLORMAP(cm), &xc); c->red = xc.red; c->green = xc.green; c->blue = xc.blue;}static glong skin_calc_luminance(GdkColor *c){ return (0.212671 * c->red + 0.715160 * c->green + 0.072169 * c->blue);}static void skin_get_textcolors(GdkPixmap *text, GdkColor *bgc, GdkColor *fgc){ /* * Try to extract reasonable background and foreground colors * from the font pixmap */ GdkImage *gi; GdkColormap *cm; int i; if (text == NULL) return; /* Get the first line of text */ gi = gdk_image_get(text, 0, 0, 152, 6); cm = gdk_window_get_colormap(playlistwin->window); for (i = 0; i < 6; i ++) { GdkColor c; gint x; glong d, max_d; /* Get a pixel from the middle of the space character */ bgc[i].pixel = gdk_image_get_pixel(gi, 151, i); skin_query_color(cm, &bgc[i]); max_d = 0; for (x = 1; x < 150; x ++) { c.pixel = gdk_image_get_pixel(gi, x, i); skin_query_color(cm, &c); d = labs(skin_calc_luminance(&c) - skin_calc_luminance(&bgc[i])); if (d > max_d) { memcpy(&fgc[i], &c, sizeof(GdkColor)); max_d = d; } } } gdk_image_destroy(gi);}void init_skins(void){ gint i; skin = (Skin *) g_malloc0(sizeof (Skin)); load_def_pixmap(&skin->main, skin_main); load_def_pixmap(&skin->cbuttons, skin_cbuttons); load_def_pixmap(&skin->titlebar, skin_titlebar); load_def_pixmap(&skin->shufrep, skin_shufrep); load_def_pixmap(&skin->text, skin_text); skin_get_textcolors(skin->text.def_pixmap, skin->def_textbg, skin->def_textfg); load_def_pixmap(&skin->volume, skin_volume); load_def_pixmap(&skin->balance, skin_volume); load_def_pixmap(&skin->monostereo, skin_monoster); load_def_pixmap(&skin->playpause, skin_playpaus); load_def_pixmap(&skin->numbers, skin_nums_ex); load_def_pixmap(&skin->posbar, skin_posbar); load_def_pixmap(&skin->pledit, skin_pledit); load_def_pixmap(&skin->eqmain, skin_eqmain); load_def_pixmap(&skin->eq_ex, skin_eq_ex); skin->def_pledit_normal.red = 0x2400; skin->def_pledit_normal.green = 0x9900; skin->def_pledit_normal.blue = 0xffff; gdk_color_alloc(gdk_window_get_colormap(playlistwin->window), &skin->def_pledit_normal); skin->def_pledit_current.red = 0xffff; skin->def_pledit_current.green = 0xee00; skin->def_pledit_current.blue = 0xffff; gdk_color_alloc(gdk_window_get_colormap(playlistwin->window), &skin->def_pledit_current); skin->def_pledit_normalbg.red = 0x0A00; skin->def_pledit_normalbg.green = 0x1200; skin->def_pledit_normalbg.blue = 0x0A00; gdk_color_alloc(gdk_window_get_colormap(playlistwin->window), &skin->def_pledit_normalbg); skin->def_pledit_selectedbg.red = 0x0A00; skin->def_pledit_selectedbg.green = 0x1200; skin->def_pledit_selectedbg.blue = 0x4A00; gdk_color_alloc(gdk_window_get_colormap(playlistwin->window), &skin->def_pledit_selectedbg); for (i = 0; i < 24; i++) { skin->vis_color[i][0] = skin_default_viscolor[i][0]; skin->vis_color[i][1] = skin_default_viscolor[i][1]; skin->vis_color[i][2] = skin_default_viscolor[i][2]; } skin->def_mask = create_default_mask(mainwin->window, 275, 116); skin->def_mask_ds = create_default_mask(mainwin->window, 550, 232); skin->def_mask_shade = create_default_mask(mainwin->window, 275, 14); skin->def_mask_shade_ds = create_default_mask(mainwin->window, 550, 28); setup_skin_masks(); create_skin_window();}static guint hex_chars_to_int(gchar c, gchar d){ /* * Converts a value in the range 0x00-0xFF * to a integer in the range 0-65535 */ gchar str[3]; str[0] = c; str[1] = d; str[2] = '\0'; return (CLAMP(strtol(str, NULL, 16), 0, 255) * 256);}GdkColor *load_skin_color(const gchar * path, const gchar * file, const gchar * section, const gchar * key){ gchar *filename, *value; GdkColor *color = NULL; filename = find_file_recursively(path, file); if (filename) { value = read_ini_string(filename, section, key); if (value) { gchar *ptr = value; gint len; color = g_malloc0(sizeof (GdkColor)); g_strchug(g_strchomp(value)); if (value[0] == '#') ptr++; len = strlen(ptr); /* * The handling of incomplete values is done this way * to maximize winamp compatibility */ if (len >= 6) { color->red = hex_chars_to_int(*ptr, *(ptr + 1)); ptr += 2; } if (len >= 4) { color->green = hex_chars_to_int(*ptr, *(ptr + 1)); ptr += 2; } if (len >= 2) color->blue = hex_chars_to_int(*ptr, *(ptr + 1)); gdk_color_alloc(gdk_window_get_colormap(playlistwin->window), color); g_free(value); } g_free(filename); } return color;}static void load_skin_pixmap(SkinPixmap *skinpixmap, const gchar * path, const gchar * file){ char *filename; gint w, h; filename = find_file_recursively(path, file); if (!filename) return; skinpixmap->pixmap = read_bmp(filename); g_free(filename); if (!skinpixmap->pixmap) return; gdk_window_get_size(skinpixmap->pixmap, &w, &h); skinpixmap->current_width = MIN(w, skinpixmap->width); skinpixmap->current_height = MIN(h, skinpixmap->height);}GdkBitmap *skin_create_transparent_mask(const gchar * path, const gchar * file, const gchar * section, GdkWindow * window, gint width, gint height, gboolean doublesize){ gchar *filename; GdkBitmap *mask = NULL; GdkGC *gc = NULL; GdkColor pattern; GdkPoint *gpoints; gboolean created_mask = FALSE; GArray *num, *point; gint i, j, k; if (!path) return NULL; filename = find_file_recursively(path, file); if (!filename) return NULL; if ((num = read_ini_array(filename, section, "NumPoints")) == NULL) { g_free(filename); return NULL; } if ((point = read_ini_array(filename, section, "PointList")) == NULL) { g_array_free(num, TRUE); g_free(filename); return NULL; } mask = gdk_pixmap_new(window, width, height, 1); gc = gdk_gc_new(mask); pattern.pixel = 0; gdk_gc_set_foreground(gc, &pattern); gdk_draw_rectangle(mask, gc, TRUE, 0, 0, width, height); pattern.pixel = 1; gdk_gc_set_foreground(gc, &pattern); j = 0; for (i = 0; i < num->len; i++) { if ((point->len - j) >= (g_array_index(num, gint, i) * 2)) { created_mask = TRUE; gpoints = g_malloc(g_array_index(num, gint, i) * sizeof (GdkPoint)); for (k = 0; k < g_array_index(num, gint, i); k++) { gpoints[k].x = g_array_index(point, gint, j + k * 2) * (1 + doublesize); gpoints[k].y = g_array_index(point, gint, j + k * 2 + 1) * (1 + doublesize); } j += k * 2; gdk_draw_polygon(mask, gc, TRUE, gpoints, g_array_index(num, gint, i)); g_free(gpoints); } } g_array_free(num, TRUE); g_array_free(point, TRUE); g_free(filename); if (!created_mask) gdk_draw_rectangle(mask, gc, TRUE, 0, 0, width, height); gdk_gc_destroy(gc); return mask;}void load_skin_viscolor(const gchar * path, const gchar * file){ FILE *f; gint i, c; gchar line[256], *filename; GArray *a; for (i = 0; i < 24; i++) { skin->vis_color[i][0] = skin_default_viscolor[i][0]; skin->vis_color[i][1] = skin_default_viscolor[i][1]; skin->vis_color[i][2] = skin_default_viscolor[i][2]; } filename = find_file_recursively(path, file); if (!filename) return; if ((f = fopen(filename, "r")) == NULL) { g_free(filename); return; } for (i = 0; i < 24; i++) { if (fgets(line, 255, f)) { a = string_to_garray(line); if (a->len > 2) { for (c = 0; c < 3; c++) skin->vis_color[i][c] = g_array_index(a, gint, c); } g_array_free(a, TRUE); } else break; } fclose(f); g_free(filename);}static void skin_numbers_generate_dash(SkinPixmap *numbers){ GdkGC *gc; GdkPixmap *pixmap; if (numbers->pixmap == NULL || numbers->current_width < 99) return; gc = gdk_gc_new(numbers->pixmap); pixmap = gdk_pixmap_new(mainwin->window, 108, numbers->current_height, gdk_rgb_get_visual()->depth); skin_draw_pixmap(pixmap, gc, SKIN_NUMBERS, 0, 0, 0, 0, 99, 13); skin_draw_pixmap(pixmap, gc, SKIN_NUMBERS, 90, 0, 99, 0, 9, 13); skin_draw_pixmap(pixmap, gc, SKIN_NUMBERS, 20, 6, 101, 6, 5, 1); gdk_gc_unref(gc); gdk_pixmap_unref(numbers->pixmap); numbers->pixmap = pixmap; numbers->current_width = 108;}static void skin_free_pixmap(SkinPixmap *p){ if (p->pixmap) gdk_pixmap_unref(p->pixmap); p->pixmap = NULL;}void free_skin(void){ gint i; skin_free_pixmap(&skin->main); skin_free_pixmap(&skin->cbuttons); skin_free_pixmap(&skin->titlebar);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -