~ubuntu-branches/ubuntu/hardy/gnomad2/hardy

« back to all changes in this revision

Viewing changes to src/player.c

  • Committer: Bazaar Package Importer
  • Author(s): Shaun Jackman
  • Date: 2004-10-25 10:24:21 UTC
  • Revision ID: james.westby@ubuntu.com-20041025102421-hnnl6uzlkutcibvi
Tags: upstream-2.5.0
ImportĀ upstreamĀ versionĀ 2.5.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* player.c
 
2
   Player window for jukebox file playing
 
3
   Copyright (C) 2001 Linus Walleij
 
4
 
 
5
This file is part of the GNOMAD package.
 
6
 
 
7
GNOMAD is free software; you can redistribute it and/or modify
 
8
it under the terms of the GNU General Public License as published by
 
9
the Free Software Foundation; either version 2, or (at your option)
 
10
any later version.
 
11
 
 
12
You should have received a copy of the GNU General Public License
 
13
along with GNOMAD; see the file COPYING.  If not, write to
 
14
the Free Software Foundation, 59 Temple Place - Suite 330,
 
15
Boston, MA 02111-1307, USA. 
 
16
 
 
17
*/
 
18
 
 
19
#include "common.h"
 
20
#include "player.h"
 
21
#include "jukebox.h"
 
22
 
 
23
typedef struct {
 
24
  guint16 effect;
 
25
  gint16 min;
 
26
  gint16 max;
 
27
} eax_adjust_props_t;
 
28
 
 
29
static gboolean playing = FALSE;
 
30
 
 
31
/* option values */
 
32
static void patch_changed (gpointer combo,
 
33
                           gpointer data)
 
34
{
 
35
  guint effect = GPOINTER_TO_UINT(data);
 
36
#if ! GTK_CHECK_VERSION(2,4,0)
 
37
  guint patch = gtk_option_menu_get_history(GTK_OPTION_MENU(combo));
 
38
#else
 
39
  guint patch = gtk_combo_box_get_active(GTK_COMBO_BOX(combo));
 
40
#endif
 
41
  
 
42
  if (playing) {
 
43
    // Wire scalevalue to 0
 
44
    g_print("Selecting patch %d for effect %04X\n", patch, effect);
 
45
    jukebox_adjust_eax(effect, patch, 0);
 
46
  }
 
47
}
 
48
 
 
49
 
 
50
/* options = name -> value -> name -> value -> ... */
 
51
/* This code for GTK+ 2.3 / 2.4 and up */
 
52
#if GTK_CHECK_VERSION(2,4,0)
 
53
static GtkWidget *create_patch_menu(guint16 effect,
 
54
                                    GSList *patches,
 
55
                                    GCallback callback_function,
 
56
                                    guint default_patch)
 
57
{
 
58
  GtkWidget *combo_box;
 
59
  GSList *tmplist = patches;
 
60
  guint mr_effect = (guint) effect;
 
61
 
 
62
  // Create a combo box
 
63
  combo_box = gtk_combo_box_new_text();
 
64
  // Then use gtk_combo_box_get_active() for numbering
 
65
  // Add rows to the combo box
 
66
  while (tmplist) {
 
67
    gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), tmplist->data);
 
68
    tmplist = tmplist->next;
 
69
  }
 
70
  gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), default_patch);
 
71
  g_signal_connect(GTK_OBJECT(combo_box),
 
72
                   "changed",
 
73
                   G_CALLBACK(callback_function),
 
74
                   GUINT_TO_POINTER(mr_effect));
 
75
  gtk_widget_show(combo_box);
 
76
 
 
77
  // Free memory used by list
 
78
  tmplist = patches;
 
79
  while (tmplist != NULL) {
 
80
    g_free(tmplist->data);
 
81
    tmplist = tmplist->next;
 
82
  }
 
83
  g_slist_free(patches);
 
84
  return combo_box;
 
85
}
 
86
#else
 
87
/* options = name -> value -> name -> value -> ... */
 
88
static GtkWidget *create_patch_menu(guint16 effect,
 
89
                                    GSList *patches,
 
90
                                    GCallback callback_function,
 
91
                                    guint default_patch)
 
92
{
 
93
  GtkWidget *option_menu;
 
94
  GtkWidget *menu;
 
95
  GtkWidget *menu_item;
 
96
  GSList *group = NULL;
 
97
  GSList *tmplist = patches;
 
98
  guint i;
 
99
  guint mr_effect = (guint) effect;
 
100
 
 
101
  // Create an option menu
 
102
  option_menu = gtk_option_menu_new();
 
103
  menu = gtk_menu_new();
 
104
  // Add rows to the menu
 
105
  i = 0;
 
106
  while (tmplist) {
 
107
    menu_item = gtk_radio_menu_item_new_with_label(group, tmplist->data);
 
108
    if (i == default_patch) {
 
109
      gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item), TRUE);
 
110
    }
 
111
    group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menu_item));
 
112
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
 
113
    gtk_widget_show(menu_item);
 
114
    tmplist = tmplist->next;
 
115
    i++;
 
116
  }
 
117
  g_signal_connect(GTK_OBJECT(option_menu),
 
118
                   "changed",
 
119
                   G_CALLBACK(callback_function),
 
120
                   GUINT_TO_POINTER(mr_effect));
 
121
  gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu);
 
122
  gtk_option_menu_set_history (GTK_OPTION_MENU (option_menu), default_patch);
 
123
  gtk_widget_show(option_menu);
 
124
  // Free memory used by list
 
125
  tmplist = patches;
 
126
  while (tmplist != NULL) {
 
127
    g_free(tmplist->data);
 
128
    tmplist = tmplist->next;
 
129
  }
 
130
  g_slist_free(patches);
 
131
  return option_menu;
 
132
}
 
133
#endif
 
134
 
 
135
void prevbutton_click ( GtkButton *button,
 
136
                        gpointer data )
 
137
{
 
138
  if (playing)
 
139
    jukebox_previous();
 
140
}
 
141
 
 
142
void nextbutton_click ( GtkButton *button,
 
143
                        gpointer data )
 
144
{
 
145
  if (playing)
 
146
    jukebox_next(FALSE);
 
147
}
 
148
 
 
149
void stop_playing ( GtkButton *button,
 
150
                    gpointer data )
 
151
{
 
152
  if (playing) {
 
153
    cancel_jukebox_operation = TRUE;
 
154
    playing = FALSE;
 
155
  }
 
156
}
 
157
 
 
158
static void adjust_scalevalue (GtkAdjustment *adj,
 
159
                               gpointer data)
 
160
{
 
161
  eax_adjust_props_t *adjprops = (eax_adjust_props_t *) data;
 
162
  // gint16 scalevalue = adjprops->max+1 - ((gint16) adj->value);
 
163
  gint16 scalevalue = (gint16) adj->value;
 
164
 
 
165
  if (playing) {
 
166
    g_print("Setting scalevalue for effect %04X to %d\n", 
 
167
            adjprops->effect, scalevalue);
 
168
    jukebox_adjust_eax(adjprops->effect, 0, scalevalue);
 
169
  }
 
170
}
 
171
 
 
172
static void close_scalevalue (gpointer data,
 
173
                              GClosure *closure)
 
174
{
 
175
  eax_adjust_props_t *adjprops = (eax_adjust_props_t *) data;
 
176
 
 
177
  g_print("Destroying adjprops for %04X\n", adjprops->effect);
 
178
  g_free(adjprops);
 
179
}
 
180
 
 
181
static GtkWidget *create_adjustment_control(guint16 effect,
 
182
                                            gint16 min,
 
183
                                            gint16 max,
 
184
                                            gint16 current)
 
185
{
 
186
  GtkObject *adjustment;
 
187
  GtkWidget *vscale;
 
188
  eax_adjust_props_t *adjprops;
 
189
 
 
190
  adjprops = (eax_adjust_props_t *) g_malloc(sizeof(eax_adjust_props_t)); 
 
191
  adjprops->effect = effect;
 
192
  adjprops->min = min;
 
193
  adjprops->max = max;
 
194
 
 
195
  /*
 
196
  adjustment = gtk_adjustment_new ((gfloat) max+1 - current,
 
197
                                   (gfloat) min,
 
198
                                   (gfloat) max+1,
 
199
                                   1.0, 1.0, 1.0);
 
200
  */
 
201
 
 
202
  adjustment = gtk_adjustment_new ((gfloat) current,
 
203
                                   (gfloat) min,
 
204
                                   (gfloat) max+1,
 
205
                                   1.0, 1.0, 1.0);
 
206
 
 
207
  vscale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
 
208
  g_signal_connect_data(GTK_OBJECT(adjustment),
 
209
                        "value_changed",
 
210
                        G_CALLBACK(adjust_scalevalue),
 
211
                        adjprops,
 
212
                        close_scalevalue,
 
213
                        0);
 
214
  gtk_widget_set_usize (GTK_WIDGET (vscale), 20, 120);
 
215
  gtk_range_set_update_policy (GTK_RANGE (vscale),
 
216
                               GTK_UPDATE_CONTINUOUS);
 
217
  gtk_range_set_inverted (GTK_RANGE(vscale), TRUE);
 
218
  gtk_scale_set_draw_value (GTK_SCALE(vscale), TRUE);
 
219
  gtk_scale_set_digits (GTK_SCALE(vscale), 0);
 
220
  return vscale;
 
221
}
 
222
 
 
223
 
 
224
static void toggle_onoff (GtkCheckButton *toggle,
 
225
                          gpointer data)
 
226
{
 
227
  gboolean togglestatus;
 
228
  guint16 onoff;
 
229
  guint effect = GPOINTER_TO_UINT(data);
 
230
  
 
231
  togglestatus = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle));
 
232
  if (togglestatus)
 
233
    onoff = 1;
 
234
  else
 
235
    onoff = 0;
 
236
  if (playing) {
 
237
    // Wire scalevalue to 0
 
238
    jukebox_adjust_eax(effect, onoff, 0);
 
239
  } 
 
240
}
 
241
 
 
242
 
 
243
static GtkWidget *get_eax_controls()
 
244
{
 
245
  njb_eax_t *eax;
 
246
  GtkWidget *hbox;
 
247
  GtkWidget *group_box = NULL;
 
248
  GtkWidget *label;
 
249
  GtkWidget *checkbox;
 
250
  GtkWidget *vbox;
 
251
  GtkWidget *vscale;
 
252
  guint16 lastgroup = 0xFFFF;
 
253
#define HORIZONTAL 0x00
 
254
#define VERTICAL   0x01
 
255
  u_int8_t last_direction = HORIZONTAL;
 
256
 
 
257
  // Stuff all EAX stuff into this frame
 
258
  hbox = gtk_hbox_new(FALSE, 5);
 
259
 
 
260
  jukebox_reset_get_eax();
 
261
  
 
262
  while ((eax = jukebox_get_eax()) != NULL) {
 
263
    // FIXME: reset all exclusive effects when an exclusive is selected.
 
264
    // Eax group has its own box
 
265
    if (lastgroup != eax->group) {
 
266
      if (group_box != NULL) {
 
267
        // pack previous frame
 
268
        gtk_box_pack_start(GTK_BOX(hbox), group_box, TRUE, TRUE, 0);
 
269
        gtk_widget_show(group_box);
 
270
      }
 
271
      // If this groups consists of scalevalues (we are guessing
 
272
      // that the first group member speaks for the rest), then create
 
273
      // a hbox, else (for patches etc) create a hbox.
 
274
      if (eax->scaleable != 0x00) {
 
275
        group_box = gtk_hbox_new(FALSE, 0);
 
276
        last_direction = HORIZONTAL;
 
277
      } else {
 
278
        group_box = gtk_vbox_new(FALSE, 0);
 
279
        last_direction = VERTICAL;
 
280
      }
 
281
    }
 
282
    // Then each effect with it's label is stuffed in a vbox
 
283
    vbox = gtk_vbox_new(FALSE, 0);
 
284
    // onoff values
 
285
    if (eax->selectable != 0x00 &&
 
286
        eax->min_selectionvalue == 0x00 &&
 
287
        eax->max_selectionvalue == 0x01) {
 
288
      guint effect = (guint) eax->number;
 
289
 
 
290
      checkbox = gtk_check_button_new_with_label(eax->name);
 
291
      if (eax->current_selectionvalue != 0x00) {
 
292
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbox), TRUE);
 
293
      }
 
294
      g_signal_connect(GTK_OBJECT(checkbox),
 
295
                       "toggled",
 
296
                       G_CALLBACK(toggle_onoff),
 
297
                       GUINT_TO_POINTER(effect));
 
298
      gtk_box_pack_start(GTK_BOX(vbox), checkbox, TRUE, TRUE, 0);
 
299
    } else {
 
300
      // All non-onoff effects need a label too.
 
301
      label = gtk_label_new(eax->name);
 
302
      gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.0f);
 
303
      gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
 
304
      // Patch value combobox
 
305
      if (eax->selectable != 0x00) {
 
306
        guint i;
 
307
        GSList *names = NULL;
 
308
        
 
309
        for(i = 0; i < eax->max_selectionvalue - eax->min_selectionvalue + 1; i++) {
 
310
          names = g_slist_append(names, g_strdup(eax->selection_names[i]));
 
311
        }
 
312
        GtkWidget *patches = create_patch_menu(eax->number,
 
313
                                               names,
 
314
                                               GTK_SIGNAL_FUNC(patch_changed),
 
315
                                               eax->current_selectionvalue);
 
316
        gtk_box_pack_start(GTK_BOX(vbox), patches, TRUE, TRUE, 0);
 
317
      }
 
318
      // Scale value slider
 
319
      if (eax->scaleable != 0x00) {
 
320
        GtkWidget *slider;
 
321
        
 
322
        g_print("Scalevalue %s, min %d, max %d, current %d\n",
 
323
                eax->name, eax->min_scalevalue, eax->max_scalevalue,
 
324
                eax->current_scalevalue);
 
325
        slider = create_adjustment_control(eax->number,
 
326
                                           eax->min_scalevalue,
 
327
                                           eax->max_scalevalue,
 
328
                                           eax->current_scalevalue);
 
329
        gtk_box_pack_start(GTK_BOX(vbox), slider, TRUE, TRUE, 0);
 
330
        gtk_widget_show(slider);
 
331
      }
 
332
    }
 
333
    gtk_box_pack_start(GTK_BOX(group_box), vbox, TRUE, TRUE, 0);
 
334
    gtk_widget_show(vbox);
 
335
    lastgroup = eax->group;
 
336
    jukebox_destroy_eax(eax);
 
337
  }
 
338
 
 
339
  // Pack the last group box
 
340
  gtk_box_pack_start(GTK_BOX(hbox), group_box, TRUE, TRUE, 0);
 
341
  gtk_widget_show(group_box);
 
342
  
 
343
  return hbox;
 
344
}
 
345
 
 
346
/* Creates a complicated player window */
 
347
void create_player_window(GList *metalist)
 
348
{
 
349
  static play_thread_arg_t play_thread_args;
 
350
  GtkWidget *label1, *label2, *label3, *dialog, *button, *separator;
 
351
  GtkWidget *label, *arrow;
 
352
  GtkWidget *hscale, *eax_controls;
 
353
  GtkWidget *hbox, *hbox2, *hbox3, *vbox;
 
354
  GtkObject *adj;
 
355
 
 
356
  play_thread_args.metalist = metalist;
 
357
  dialog = gtk_dialog_new();
 
358
  gtk_window_set_title (GTK_WINDOW (dialog), (_("Playing tracks on the jukebox")));
 
359
  gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 5);
 
360
  gtk_box_set_homogeneous (GTK_BOX (GTK_DIALOG (dialog)->action_area), TRUE);
 
361
  gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
 
362
 
 
363
  label1 = gtk_label_new(_("Playing:"));
 
364
  label2 = gtk_label_new("");
 
365
  /* value, lower, upper, step_increment, page_increment, page_size */
 
366
  /* Note that the page_size value only makes a difference for
 
367
   * scrollbar widgets, and the highest value you'll get is actually
 
368
   * (upper - page_size). */
 
369
  adj = gtk_adjustment_new (0.0, 0.0, 101.0, 0.1, 1.0, 1.0);
 
370
  hscale = gtk_hscale_new (GTK_ADJUSTMENT (adj));
 
371
  gtk_widget_set_sensitive(hscale, FALSE);
 
372
  gtk_widget_set_usize (GTK_WIDGET (hscale), 200, 30);
 
373
  gtk_range_set_update_policy (GTK_RANGE (hscale),
 
374
                               GTK_UPDATE_CONTINUOUS);
 
375
  gtk_scale_set_digits (GTK_SCALE(hscale), 1);
 
376
  gtk_scale_set_value_pos (GTK_SCALE(hscale), GTK_POS_TOP);
 
377
  gtk_scale_set_draw_value (GTK_SCALE(hscale), FALSE);
 
378
  gtk_widget_show (hscale);
 
379
  button = gtk_button_new_with_label(_("STOP"));
 
380
  GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
 
381
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), button,
 
382
                      FALSE, FALSE, 0);
 
383
  g_signal_connect_object(GTK_OBJECT(button),
 
384
                          "clicked",
 
385
                          G_CALLBACK(stop_playing),
 
386
                          NULL,
 
387
                          0);
 
388
  g_signal_connect_object(GTK_OBJECT(dialog),
 
389
                          "delete_event",
 
390
                          G_CALLBACK(stop_playing),
 
391
                          NULL, // GTK_OBJECT(dialog) ???
 
392
                          0);
 
393
  hbox = gtk_hbox_new(FALSE, 5);
 
394
  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 0);
 
395
  vbox = gtk_vbox_new(FALSE, 0);
 
396
  gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
 
397
  separator = gtk_hseparator_new ();
 
398
  gtk_box_pack_start(GTK_BOX(vbox), separator, TRUE, TRUE, 0);
 
399
  gtk_box_pack_start(GTK_BOX(vbox), label1, TRUE, TRUE, 0);
 
400
  gtk_box_pack_start(GTK_BOX(vbox), label2, TRUE, TRUE, 0);
 
401
 
 
402
  /* Manouver panel */
 
403
  hbox2 = gtk_hbox_new(FALSE, 0);
 
404
 
 
405
  button = gtk_button_new();
 
406
  hbox3 = gtk_hbox_new(FALSE, 0);
 
407
  arrow = gtk_arrow_new(GTK_ARROW_LEFT, GTK_SHADOW_NONE);
 
408
  gtk_box_pack_start(GTK_BOX(hbox3), arrow, TRUE, TRUE, 0);
 
409
  label = gtk_label_new(_("PREV"));
 
410
  gtk_box_pack_start(GTK_BOX(hbox3), label, TRUE, TRUE, 0);
 
411
  gtk_widget_show(arrow);
 
412
  gtk_container_add(GTK_CONTAINER(button), hbox3);
 
413
  g_signal_connect_object(GTK_OBJECT(button),
 
414
                          "clicked",
 
415
                          G_CALLBACK(prevbutton_click),
 
416
                          NULL,
 
417
                          0);
 
418
  gtk_box_pack_start(GTK_BOX(hbox2), button, FALSE, TRUE, 0);
 
419
  GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
 
420
  label3 = gtk_label_new("00:00:00");
 
421
  gtk_box_pack_start(GTK_BOX(hbox2), label3, TRUE, TRUE, 0);
 
422
  button = gtk_button_new();
 
423
  hbox3 = gtk_hbox_new(FALSE, 0);
 
424
  label = gtk_label_new(_("NEXT"));
 
425
  gtk_box_pack_start(GTK_BOX(hbox3), label, TRUE, TRUE, 0);
 
426
  arrow = gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
 
427
  gtk_box_pack_start(GTK_BOX(hbox3), arrow, TRUE, TRUE, 0);
 
428
  gtk_widget_show(arrow);
 
429
  gtk_container_add(GTK_CONTAINER(button), hbox3);
 
430
  g_signal_connect_object(GTK_OBJECT(button),
 
431
                          "clicked",
 
432
                          G_CALLBACK(nextbutton_click),
 
433
                          NULL,
 
434
                          0);
 
435
  gtk_box_pack_start(GTK_BOX(hbox2), button, FALSE, TRUE, 0);
 
436
  GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
 
437
  gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, TRUE, 0);
 
438
 
 
439
  separator = gtk_hseparator_new ();
 
440
  gtk_box_pack_start(GTK_BOX(vbox), separator, TRUE, TRUE, 0);
 
441
  gtk_box_pack_start(GTK_BOX(vbox), hscale, TRUE, TRUE, 0);
 
442
  eax_controls = get_eax_controls();
 
443
  gtk_box_pack_start(GTK_BOX(hbox), eax_controls, TRUE, TRUE, 0);
 
444
 
 
445
  /* Get all settings from jukebox */
 
446
  gtk_widget_show_all(dialog);
 
447
 
 
448
  play_thread_args.songlabel = label2;
 
449
  play_thread_args.timelabel = label3;
 
450
  play_thread_args.adj = adj;
 
451
  play_thread_args.dialog = dialog;
 
452
  
 
453
  cancel_jukebox_operation = FALSE;
 
454
  g_thread_create(play_thread,(gpointer) &play_thread_args, FALSE, NULL);
 
455
  playing = TRUE;
 
456
}
 
457
 
 
458
/* Plays a certain playlist with ID plid */
 
459
void play_playlist(guint plid)
 
460
{
 
461
  GList *playlist;
 
462
 
 
463
  /* Get the playlist from the jukebox */
 
464
  playlist = jukebox_get_playlist_for_play(plid);
 
465
  if (playlist != NULL)
 
466
    create_player_window(playlist);
 
467
}