comparison src/skins/ui_vis.c @ 2579:8fba3fbf1a0f

add vis and svis
author Tomasz Mon <desowin@gmail.com>
date Mon, 19 May 2008 18:05:54 +0200
parents
children c9e40418a74c
comparison
equal deleted inserted replaced
2574:8da9705862e5 2579:8fba3fbf1a0f
1 /*
2 * Audacious - a cross-platform multimedia player
3 * Copyright (c) 2007 Audacious development team.
4 *
5 * Based on:
6 * BMP - Cross-platform multimedia player
7 * Copyright (C) 2003-2004 BMP development team.
8 * XMMS:
9 * Copyright (C) 1998-2003 XMMS development team.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; under version 3 of the License.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses>.
22 *
23 * The Audacious team does not consider modular code linking to
24 * Audacious or using our public API to be a derived work.
25 */
26
27 #include "ui_skin.h"
28 #include "ui_vis.h"
29 #include "util.h"
30 #include <audacious/plugin.h>
31
32 static const gfloat vis_afalloff_speeds[] = { 0.34, 0.5, 1.0, 1.3, 1.6 };
33 static const gfloat vis_pfalloff_speeds[] = { 1.2, 1.3, 1.4, 1.5, 1.6 };
34 static const gint vis_redraw_delays[] = { 1, 2, 4, 8 };
35 static const guint8 vis_scope_colors[] =
36 { 21, 21, 20, 20, 19, 19, 18, 19, 19, 20, 20, 21, 21 };
37 static guchar voiceprint_data[76*16];
38
39 enum {
40 DOUBLED,
41 LAST_SIGNAL
42 };
43
44 static void ui_vis_class_init (UiVisClass *klass);
45 static void ui_vis_init (UiVis *vis);
46 static void ui_vis_destroy (GtkObject *object);
47 static void ui_vis_realize (GtkWidget *widget);
48 static void ui_vis_unrealize (GtkWidget *widget);
49 static void ui_vis_map (GtkWidget *widget);
50 static void ui_vis_unmap (GtkWidget *widget);
51 static void ui_vis_size_request (GtkWidget *widget, GtkRequisition *requisition);
52 static void ui_vis_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
53 static gboolean ui_vis_expose (GtkWidget *widget, GdkEventExpose *event);
54 static void ui_vis_toggle_scaled (UiVis *vis);
55
56 static GtkWidgetClass *parent_class = NULL;
57 static guint vis_signals[LAST_SIGNAL] = { 0 };
58
59 GType ui_vis_get_type() {
60 static GType vis_type = 0;
61 if (!vis_type) {
62 static const GTypeInfo vis_info = {
63 sizeof (UiVisClass),
64 NULL,
65 NULL,
66 (GClassInitFunc) ui_vis_class_init,
67 NULL,
68 NULL,
69 sizeof (UiVis),
70 0,
71 (GInstanceInitFunc) ui_vis_init,
72 };
73 vis_type = g_type_register_static (GTK_TYPE_WIDGET, "UiVis", &vis_info, 0);
74 }
75
76 return vis_type;
77 }
78
79 static void ui_vis_class_init(UiVisClass *klass) {
80 GtkObjectClass *object_class;
81 GtkWidgetClass *widget_class;
82
83 object_class = (GtkObjectClass*) klass;
84 widget_class = (GtkWidgetClass*) klass;
85 parent_class = gtk_type_class (gtk_widget_get_type ());
86
87 object_class->destroy = ui_vis_destroy;
88
89 widget_class->realize = ui_vis_realize;
90 widget_class->unrealize = ui_vis_unrealize;
91 widget_class->map = ui_vis_map;
92 widget_class->unmap = ui_vis_unmap;
93 widget_class->expose_event = ui_vis_expose;
94 widget_class->size_request = ui_vis_size_request;
95 widget_class->size_allocate = ui_vis_size_allocate;
96
97 klass->doubled = ui_vis_toggle_scaled;
98
99 vis_signals[DOUBLED] =
100 g_signal_new ("toggle-scaled", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
101 G_STRUCT_OFFSET (UiVisClass, doubled), NULL, NULL,
102 gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
103 }
104
105 static void ui_vis_init(UiVis *vis) {
106 memset(voiceprint_data, 0, 16*76);
107 }
108
109 GtkWidget* ui_vis_new(GtkWidget *fixed, gint x, gint y, gint width) {
110 UiVis *vis = g_object_new (ui_vis_get_type (), NULL);
111
112 vis->x = x;
113 vis->y = y;
114
115 vis->width = width;
116 vis->height = 16;
117
118 vis->fixed = fixed;
119 vis->scaled = FALSE;
120
121 vis->visible_window = TRUE;
122 vis->event_window = NULL;
123
124 gtk_fixed_put(GTK_FIXED(vis->fixed), GTK_WIDGET(vis), vis->x, vis->y);
125
126 return GTK_WIDGET(vis);
127 }
128
129 static void ui_vis_destroy(GtkObject *object) {
130 UiVis *vis;
131
132 g_return_if_fail (object != NULL);
133 g_return_if_fail (UI_IS_VIS (object));
134
135 vis = UI_VIS (object);
136
137 if (GTK_OBJECT_CLASS (parent_class)->destroy)
138 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
139 }
140
141 static void ui_vis_realize(GtkWidget *widget) {
142 UiVis *vis;
143 GdkWindowAttr attributes;
144 gint attributes_mask;
145
146 g_return_if_fail (widget != NULL);
147 g_return_if_fail (UI_IS_VIS(widget));
148
149 GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
150 vis = UI_VIS(widget);
151
152 attributes.x = widget->allocation.x;
153 attributes.y = widget->allocation.y;
154 attributes.width = widget->allocation.width;
155 attributes.height = widget->allocation.height;
156 attributes.window_type = GDK_WINDOW_CHILD;
157 attributes.event_mask = gtk_widget_get_events(widget);
158 attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
159
160 if (vis->visible_window)
161 {
162 attributes.visual = gtk_widget_get_visual(widget);
163 attributes.colormap = gtk_widget_get_colormap(widget);
164 attributes.wclass = GDK_INPUT_OUTPUT;
165 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
166 widget->window = gdk_window_new(widget->parent->window, &attributes, attributes_mask);
167 GTK_WIDGET_UNSET_FLAGS(widget, GTK_NO_WINDOW);
168 gdk_window_set_user_data(widget->window, widget);
169 }
170 else
171 {
172 widget->window = gtk_widget_get_parent_window (widget);
173 g_object_ref (widget->window);
174
175 attributes.wclass = GDK_INPUT_ONLY;
176 attributes_mask = GDK_WA_X | GDK_WA_Y;
177 vis->event_window = gdk_window_new (widget->window, &attributes, attributes_mask);
178 GTK_WIDGET_SET_FLAGS (widget, GTK_NO_WINDOW);
179 gdk_window_set_user_data(vis->event_window, widget);
180 }
181
182 widget->style = gtk_style_attach(widget->style, widget->window);
183 }
184
185 static void ui_vis_unrealize(GtkWidget *widget) {
186 UiVis *vis;
187 vis = UI_VIS(widget);
188
189 if ( vis->event_window != NULL )
190 {
191 gdk_window_set_user_data( vis->event_window , NULL );
192 gdk_window_destroy( vis->event_window );
193 vis->event_window = NULL;
194 }
195
196 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
197 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
198 }
199
200 static void ui_vis_map(GtkWidget *widget)
201 {
202 UiVis *vis;
203 vis = UI_VIS(widget);
204
205 if (vis->event_window != NULL)
206 gdk_window_show (vis->event_window);
207
208 if (GTK_WIDGET_CLASS (parent_class)->map)
209 (* GTK_WIDGET_CLASS (parent_class)->map) (widget);
210 }
211
212 static void ui_vis_unmap (GtkWidget *widget)
213 {
214 UiVis *vis;
215 vis = UI_VIS(widget);
216
217 if (vis->event_window != NULL)
218 gdk_window_hide (vis->event_window);
219
220 if (GTK_WIDGET_CLASS (parent_class)->unmap)
221 (* GTK_WIDGET_CLASS (parent_class)->unmap) (widget);
222 }
223
224 static void ui_vis_size_request(GtkWidget *widget, GtkRequisition *requisition) {
225 UiVis *vis = UI_VIS(widget);
226
227 requisition->width = vis->width*(vis->scaled ? aud_cfg->scale_factor : 1);
228 requisition->height = vis->height*(vis->scaled ? aud_cfg->scale_factor : 1);
229 }
230
231 static void ui_vis_size_allocate(GtkWidget *widget, GtkAllocation *allocation) {
232 UiVis *vis = UI_VIS (widget);
233
234 widget->allocation = *allocation;
235 widget->allocation.x *= (vis->scaled ? aud_cfg->scale_factor : 1);
236 widget->allocation.y *= (vis->scaled ? aud_cfg->scale_factor : 1);
237 if (GTK_WIDGET_REALIZED (widget))
238 {
239 if (vis->event_window != NULL)
240 gdk_window_move_resize(vis->event_window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
241 else
242 gdk_window_move_resize(widget->window, widget->allocation.x, widget->allocation.y, allocation->width, allocation->height);
243 }
244
245 vis->x = widget->allocation.x/(vis->scaled ? aud_cfg->scale_factor : 1);
246 vis->y = widget->allocation.y/(vis->scaled ? aud_cfg->scale_factor : 1);
247 }
248
249 static gboolean ui_vis_expose(GtkWidget *widget, GdkEventExpose *event) {
250 g_return_val_if_fail (widget != NULL, FALSE);
251 g_return_val_if_fail (UI_IS_VIS (widget), FALSE);
252 g_return_val_if_fail (event != NULL, FALSE);
253
254 UiVis *vis = UI_VIS (widget);
255
256 gint x, y, n, h = 0, h2;
257 gfloat delta;
258 guchar skin_col[2][3];
259 guchar vis_color[24][3];
260 guchar vis_voice_color[256][3], voice_c[3];
261 guchar rgb_data[76 * 16 * 3 * 2 * 2], *ptr, c;
262 guint32 colors[24];
263 GdkColor *fgc, *bgc;
264 GdkRgbCmap *cmap;
265
266 if (!GTK_WIDGET_VISIBLE(widget))
267 return FALSE;
268
269 if (!vis->visible_window)
270 return FALSE;
271
272 skin_get_viscolor(aud_active_skin, vis_color);
273 for (y = 0; y < 24; y++) {
274 colors[y] =
275 vis_color[y][0] << 16 | vis_color[y][1] << 8 | vis_color[y][2];
276 }
277 cmap = gdk_rgb_cmap_new(colors, 24);
278
279 if (!vis->scaled) {
280 if(aud_cfg->vis_type == VIS_VOICEPRINT /*&& aud_cfg->voiceprint_mode != VOICEPRINT_NORMAL*/){
281 memset(rgb_data, 0, 76 * 16 * 3);
282 }
283 else{
284 memset(rgb_data, 0, 76 * 16);
285 for (y = 1; y < 16; y += 2) {
286 ptr = rgb_data + (y * 76);
287 for (x = 0; x < 76; x += 2, ptr += 2)
288 *ptr = 1;
289 }
290 }
291 }
292 else{
293 if(aud_cfg->vis_type == VIS_VOICEPRINT /*&& aud_cfg->voiceprint_mode != VOICEPRINT_NORMAL*/){
294 memset(rgb_data, 0, 3 * 4 * 16 * 76);
295 }
296 else{
297 memset(rgb_data, 0, (guint)(76 * aud_cfg->scale_factor) * 32);
298 for (y = 1; y < 16; y += 2) {
299 ptr = rgb_data + (y * (guint)(76 * 4 * aud_cfg->scale_factor));
300 for (x = 0; x < 76; x += 2, ptr += 4) {
301 *ptr = 1;
302 *(ptr + 1) = 1;
303 *(ptr + (guint)(76 * aud_cfg->scale_factor)) = 1;
304 *(ptr + (guint)(76 * aud_cfg->scale_factor)+1) = 1;
305 }
306 }
307 }
308 }
309 if (aud_cfg->vis_type == VIS_ANALYZER) {
310 for (x = 0; x < 75; x++) {
311 if (aud_cfg->analyzer_type == ANALYZER_BARS && (x % 4) == 0)
312 h = vis->data[x >> 2];
313 else if (aud_cfg->analyzer_type == ANALYZER_LINES)
314 h = vis->data[x];
315 if (h && (aud_cfg->analyzer_type == ANALYZER_LINES ||
316 (x % 4) != 3)) {
317 if (!vis->scaled) {
318 ptr = rgb_data + ((16 - h) * 76) + x;
319 switch (aud_cfg->analyzer_mode) {
320 case ANALYZER_NORMAL:
321 for (y = 0; y < h; y++, ptr += 76)
322 *ptr = 18 - h + y;
323 break;
324 case ANALYZER_FIRE:
325 for (y = 0; y < h; y++, ptr += 76)
326 *ptr = y + 2;
327 break;
328 case ANALYZER_VLINES:
329 for (y = 0; y < h; y++, ptr += 76)
330 *ptr = 18 - h;
331 break;
332 }
333 }
334 else{
335 ptr = rgb_data + ((16 - h) * (guint)(76 * 4 * aud_cfg->scale_factor)) + (guint)(x * aud_cfg->scale_factor);
336 switch (aud_cfg->analyzer_mode) {
337 case ANALYZER_NORMAL:
338 for (y = 0; y < h; y++, ptr += (guint)(76 * 4 * aud_cfg->scale_factor)) {
339 *ptr = 18 - h + y;
340 *(ptr + 1) = 18 - h + y;
341 *(ptr + (guint)(76 * aud_cfg->scale_factor)) = 18 - h + y;
342 *(ptr + (guint)(76 * aud_cfg->scale_factor)+1) = 18 - h + y;
343 }
344 break;
345 case ANALYZER_FIRE:
346 for (y = 0; y < h; y++, ptr += (guint)(76 * 4 * aud_cfg->scale_factor)) {
347 *ptr = y + 2;
348 *(ptr + 1) = y + 2;
349 *(ptr + (guint)(76 * aud_cfg->scale_factor)) = y + 2;
350 *(ptr + (guint)(76 * aud_cfg->scale_factor)+1) = y + 2;
351 }
352 break;
353 case ANALYZER_VLINES:
354 for (y = 0; y < h; y++, ptr += (guint)(76 * 4 * aud_cfg->scale_factor)) {
355 *ptr = 18 - h;
356 *(ptr + 1) = 18 - h;
357 *(ptr + (guint)(76 * aud_cfg->scale_factor)) = 18 - h;
358 *(ptr + (guint)(76 * aud_cfg->scale_factor)+1) = 18 - h;
359 }
360
361 break;
362 }
363 }
364 }
365 }
366 if (aud_cfg->analyzer_peaks) {
367 for (x = 0; x < 75; x++) {
368 if (aud_cfg->analyzer_type == ANALYZER_BARS && (x % 4) == 0)
369 h = vis->peak[x >> 2];
370 else if (aud_cfg->analyzer_type == ANALYZER_LINES)
371 h = vis->peak[x];
372 if (h && (aud_cfg->analyzer_type == ANALYZER_LINES || (x % 4) != 3)){
373
374 if (!vis->scaled) {
375 rgb_data[(16 - h) * 76 + x] = 23;
376 }
377 else{
378 ptr = rgb_data + (16 - h) * (guint)(76 * 4 * aud_cfg->scale_factor) + (guint)(x * aud_cfg->scale_factor);
379 *ptr = 23;
380 *(ptr + 1) = 23;
381 *(ptr + (guint)(76 * aud_cfg->scale_factor)) = 23;
382 *(ptr + (guint)(76 * aud_cfg->scale_factor)+1) = 23;
383 }
384 }
385 }
386 }
387 }
388 else if (aud_cfg->vis_type == VIS_VOICEPRINT) {
389 if(!audacious_drct_get_paused() && audacious_drct_get_playing()){/*Don't scroll when it's paused or stopped*/
390 for (y = 0; y < 16; y ++)
391 for (x = 75; x > 0; x--)
392 voiceprint_data[x + y * 76] = voiceprint_data[x-1+y*76];
393 for(y=0;y<16;y++)
394 voiceprint_data[y * 76] = vis->data[y];
395 }
396 if(audacious_drct_get_playing()){ /*Only draw the data if we're playing*/
397 if(aud_cfg->voiceprint_mode == VOICEPRINT_NORMAL){
398 /* Create color gradient from the skin's background- and foreground color*/
399 fgc = skin_get_color(aud_active_skin, SKIN_TEXTFG);
400 bgc = skin_get_color(aud_active_skin, SKIN_TEXTBG);
401 skin_col[0][0] = fgc->red >> 8;
402 skin_col[0][1] = fgc->green >> 8;
403 skin_col[0][2] = fgc->blue >> 8;
404 skin_col[1][0] = bgc->red >> 8;
405 skin_col[1][1] = bgc->green >> 8;
406 skin_col[1][2] = bgc->blue >> 8;
407 for(n=0;n<3;n++){
408 for(x=0;x<256;x++){
409 if(skin_col[0][n] > skin_col[1][n]){
410 delta = (gfloat)(skin_col[0][n] - skin_col[1][n]) / 256.0;
411 vis_voice_color[x][n] = skin_col[1][n] + (gfloat)(delta * x);
412 }
413 else if(skin_col[0][n] == skin_col[1][n]){
414 vis_voice_color[x][n] = skin_col[0][n];
415 }
416 else{
417 delta = (gfloat)(skin_col[1][n] - skin_col[0][n]) / 256.0;
418 vis_voice_color[x][n] = skin_col[1][n] - (gfloat)(delta * x);
419 }
420 }
421 }
422 }
423 for (y = 0; y < 16; y ++){
424 for (x = 0; x < 76; x++){
425 guint8 d = voiceprint_data[x + y*76];
426
427 if(aud_cfg->voiceprint_mode == VOICEPRINT_NORMAL){
428 voice_c[0] = vis_voice_color[d][0];
429 voice_c[1] = vis_voice_color[d][1];
430 voice_c[2] = vis_voice_color[d][2];
431 }
432 else if(aud_cfg->voiceprint_mode == VOICEPRINT_FIRE){
433 voice_c[0] = d < 64 ? (d * 2) : 255;
434 voice_c[1] = d < 64 ? 0 : (d < 128 ? (d-64) * 2 : 255);
435 voice_c[2] = d < 128 ? 0 : (d-128) * 2;
436 /* Test for black->blue->green->red. Isn't pretty, though...
437 voice_c[0] = d > 192 ? (d - 192) << 2 : 0;
438 voice_c[1] = d > 64 ? (d < 128 ? (d - 64) << 2 : (d < 192 ? (192 - d) << 2 : 0)) : 0;
439 voice_c[2] = d < 64 ? d << 2 : (d < 128 ? (128 - d) << 2 : 0);
440 */
441 }
442 else if(aud_cfg->voiceprint_mode == VOICEPRINT_ICE){
443 voice_c[0] = d;
444 voice_c[1] = d < 128 ? d * 2 : 255;
445 voice_c[2] = d < 64 ? d * 4 : 255;
446 }
447 if(!vis->scaled){
448 for(n=0;n<3;n++)
449 rgb_data[x * 3 + y * 76*3+n] = voice_c[n];
450 }
451 else{
452 ptr = rgb_data + (guint)(x * 3 * aud_cfg->scale_factor) + (guint) (y * 76 * 3 * aud_cfg->scale_factor);
453 for(n=0;n<3;n++)
454 {
455 *(ptr + n) = voice_c[n];
456 *(ptr + n + 3) = voice_c[n];
457 *(ptr + (guint)(n + 76 * aud_cfg->scale_factor * 3)) = voice_c[n];
458 *(ptr + (guint)(n + 3 + 76 * aud_cfg->scale_factor * 3)) = voice_c[n];
459 }
460 }
461 }
462 }
463 }
464 }
465 if (aud_cfg->vis_type == VIS_SCOPE) {
466 for (x = 0; x < 75; x++) {
467 switch (aud_cfg->scope_mode) {
468 case SCOPE_DOT:
469 h = vis->data[x];
470 if (!vis->scaled) {
471 ptr = rgb_data + ((14 - h) * 76) + x;
472 *ptr = vis_scope_colors[h + 1];
473 }else{
474 ptr = rgb_data + ((14 - h) * (guint)(76 * 4 * aud_cfg->scale_factor)) + (guint)(x * aud_cfg->scale_factor);
475 *ptr = vis_scope_colors[h + 1];
476 *(ptr + 1) = vis_scope_colors[h + 1];
477 *(ptr + (guint)(76 * aud_cfg->scale_factor)) = vis_scope_colors[h + 1];
478 *(ptr + (guint)(76 * aud_cfg->scale_factor)+1) = vis_scope_colors[h + 1];
479 }
480 break;
481 case SCOPE_LINE:
482 if (x != 74) {
483 h = 14 - vis->data[x];
484 h2 = 14 - vis->data[x + 1];
485 if (h > h2) {
486 y = h;
487 h = h2;
488 h2 = y;
489 }
490 if (!vis->scaled) {
491 ptr = rgb_data + (h * 76) + x;
492 for (y = h; y <= h2; y++, ptr += 76)
493 *ptr = vis_scope_colors[y - 2];
494 }
495 else{
496 ptr = rgb_data + (h * (guint)(76 * 4 * aud_cfg->scale_factor)) + (guint)(x * aud_cfg->scale_factor);
497 for (y = h; y <= h2; y++, ptr += (guint)(76 * 4 * aud_cfg->scale_factor)) {
498 *ptr = vis_scope_colors[y - 2];
499 *(ptr + 1) = vis_scope_colors[y - 2];
500 *(ptr + (guint)(76 * aud_cfg->scale_factor)) = vis_scope_colors[y - 2];
501 *(ptr + (guint)(76 * aud_cfg->scale_factor)+1) = vis_scope_colors[y - 2];
502 }
503 }
504 }
505 else {
506 h = 14 - vis->data[x];
507 if (!vis->scaled) {
508 ptr = rgb_data + (h * 76) + x;
509 *ptr = vis_scope_colors[h + 1];
510 }else{
511 ptr = rgb_data + (h * (guint)(76 * 4 * aud_cfg->scale_factor)) + (guint)(x * aud_cfg->scale_factor);
512 *ptr = vis_scope_colors[h + 1];
513 *(ptr + 1) = vis_scope_colors[h + 1];
514 *(ptr + (guint)(76 * aud_cfg->scale_factor)) = vis_scope_colors[h + 1];
515 *(ptr + (guint)(76 * aud_cfg->scale_factor)+1) = vis_scope_colors[h + 1];
516 }
517 }
518 break;
519 case SCOPE_SOLID:
520 h = 14 - vis->data[x];
521 h2 = 8;
522 c = vis_scope_colors[(gint) vis->data[x]];
523 if (h > h2) {
524 y = h;
525 h = h2;
526 h2 = y;
527 }
528 if (!vis->scaled) {
529 ptr = rgb_data + (h * 76) + x;
530 for (y = h; y <= h2; y++, ptr += 76)
531 *ptr = c;
532 }else{
533 ptr = rgb_data + (h * (guint)(76 * 4 * aud_cfg->scale_factor)) + (guint)(x * aud_cfg->scale_factor);
534 for (y = h; y <= h2; y++, ptr += (guint)(76 * 4 * aud_cfg->scale_factor)) {
535 *ptr = c;
536 *(ptr + 1) = c;
537 *(ptr + (guint)(76 * aud_cfg->scale_factor)) = c;
538 *(ptr + (guint)(76 * aud_cfg->scale_factor)+1) = c;
539 }
540 }
541 break;
542 }
543 }
544 }
545
546 GdkPixmap *obj = NULL;
547 GdkGC *gc;
548 obj = gdk_pixmap_new(NULL, vis->width*(vis->scaled ? aud_cfg->scale_factor : 1), vis->height*(vis->scaled ? aud_cfg->scale_factor : 1), gdk_rgb_get_visual()->depth);
549 gc = gdk_gc_new(obj);
550
551 if (!vis->scaled) {
552 if (aud_cfg->vis_type == VIS_VOICEPRINT) {
553 gdk_draw_rgb_image(obj, gc, 0, 0, vis->width, vis->height,
554 GDK_RGB_DITHER_NORMAL, (guchar *) rgb_data,
555 76 * 3);
556 } else {
557 gdk_draw_indexed_image(obj, gc, 0, 0, vis->width, vis->height,
558 GDK_RGB_DITHER_NORMAL, (guchar *) rgb_data,
559 76 , cmap);
560 }
561 } else {
562 if (aud_cfg->vis_type == VIS_VOICEPRINT) {
563 gdk_draw_rgb_image(obj, gc, 0 << 1, 0 << 1,
564 vis->width << 1, vis->height << 1,
565 GDK_RGB_DITHER_NONE, (guchar *) rgb_data,
566 76 * 2 * 3);
567 } else {
568 gdk_draw_indexed_image(obj, gc, 0 << 1, 0 << 1,
569 vis->width << 1, vis->height << 1,
570 GDK_RGB_DITHER_NONE, (guchar *) rgb_data,
571 76 * 2 , cmap);
572 }
573 }
574
575 gdk_draw_drawable (widget->window, gc, obj, 0, 0, 0, 0,
576 vis->width*(vis->scaled ? aud_cfg->scale_factor : 1), vis->height*(vis->scaled ? aud_cfg->scale_factor : 1));
577 g_object_unref(obj);
578 g_object_unref(gc);
579 gdk_rgb_cmap_free(cmap);
580 return FALSE;
581 }
582
583 static void ui_vis_toggle_scaled(UiVis *vis) {
584 GtkWidget *widget = GTK_WIDGET (vis);
585 vis->scaled = !vis->scaled;
586
587 gtk_widget_set_size_request(widget, vis->width*(vis->scaled ? aud_cfg->scale_factor : 1), vis->height*(vis->scaled ? aud_cfg->scale_factor : 1));
588
589 gtk_widget_queue_draw(GTK_WIDGET(vis));
590 }
591
592 void ui_vis_draw_pixel(GtkWidget *widget, guchar* texture, gint x, gint y, guint8 colour) {
593 UiVis *vis = UI_VIS (widget);
594 if (vis->scaled){
595 texture[y * 76 + x] = colour;
596 texture[y * 76 + x + 1] = colour;
597 texture[y * 76 * 4 + x] = colour;
598 texture[y * 76 * 4 + x + 1] = colour;
599 } else {
600 texture[y * 76 + x] = colour;
601 }
602 }
603
604 void ui_vis_set_visible(GtkWidget *widget, gboolean window_is_visible)
605 {
606 UiVis *vis;
607 gboolean widget_is_visible;
608
609 g_return_if_fail(UI_IS_VIS(widget));
610
611 vis = UI_VIS (widget);
612 widget_is_visible = GTK_WIDGET_VISIBLE(widget);
613
614 vis->visible_window = window_is_visible;
615
616 if (GTK_WIDGET_REALIZED (widget))
617 {
618 if ( widget_is_visible )
619 gtk_widget_hide(widget);
620
621 gtk_widget_unrealize(widget);
622 gtk_widget_realize(widget);
623
624 if ( widget_is_visible )
625 gtk_widget_show(widget);
626 }
627
628 if (widget_is_visible)
629 gtk_widget_queue_resize(widget);
630 }
631
632 void ui_vis_clear_data(GtkWidget *widget) {
633 gint i;
634 UiVis *vis = UI_VIS (widget);
635
636 memset(voiceprint_data, 0, 16*76);
637 for (i = 0; i < 75; i++) {
638 vis->data[i] = (aud_cfg->vis_type == VIS_SCOPE) ? 6 : 0;
639 vis->peak[i] = 0;
640 }
641 }
642
643 void ui_vis_timeout_func(GtkWidget *widget, guchar * data) {
644 UiVis *vis = UI_VIS (widget);
645 static GTimer *timer = NULL;
646 gulong micros = 9999999;
647 gboolean falloff = FALSE;
648 gint i;
649
650 if (!timer) {
651 timer = g_timer_new();
652 g_timer_start(timer);
653 }
654 else {
655 g_timer_elapsed(timer, &micros);
656 if (micros > 14000)
657 g_timer_reset(timer);
658 }
659 if (aud_cfg->vis_type == VIS_ANALYZER) {
660 if (micros > 14000)
661 falloff = TRUE;
662 if (data || falloff) {
663 for (i = 0; i < 75; i++) {
664 if (data && data[i] > vis->data[i]) {
665 vis->data[i] = data[i];
666 if (vis->data[i] > vis->peak[i]) {
667 vis->peak[i] = vis->data[i];
668 vis->peak_speed[i] = 0.01;
669
670 }
671 else if (vis->peak[i] > 0.0) {
672 vis->peak[i] -= vis->peak_speed[i];
673 vis->peak_speed[i] *=
674 vis_pfalloff_speeds[aud_cfg->peaks_falloff];
675 if (vis->peak[i] < vis->data[i])
676 vis->peak[i] = vis->data[i];
677 if (vis->peak[i] < 0.0)
678 vis->peak[i] = 0.0;
679 }
680 }
681 else if (falloff) {
682 if (vis->data[i] > 0.0) {
683 vis->data[i] -=
684 vis_afalloff_speeds[aud_cfg->analyzer_falloff];
685 if (vis->data[i] < 0.0)
686 vis->data[i] = 0.0;
687 }
688 if (vis->peak[i] > 0.0) {
689 vis->peak[i] -= vis->peak_speed[i];
690 vis->peak_speed[i] *=
691 vis_pfalloff_speeds[aud_cfg->peaks_falloff];
692 if (vis->peak[i] < vis->data[i])
693 vis->peak[i] = vis->data[i];
694 if (vis->peak[i] < 0.0)
695 vis->peak[i] = 0.0;
696 }
697 }
698 }
699 }
700 }
701 else if (aud_cfg->vis_type == VIS_VOICEPRINT && data){
702 for(i = 0; i < 16; i++)
703 {
704 vis->data[i] = data[15 - i];
705 }
706 }
707 else if (data) {
708 for (i = 0; i < 75; i++)
709 vis->data[i] = data[i];
710 }
711
712 if (micros > 14000) {
713 if (!vis->refresh_delay) {
714 gtk_widget_queue_draw(widget);
715 vis->refresh_delay = vis_redraw_delays[aud_cfg->vis_refresh];
716 }
717 vis->refresh_delay--;
718 }
719 }