~ubuntu-branches/ubuntu/hoary/kdemultimedia/hoary

« back to all changes in this revision

Viewing changes to kmidi/TIMIDITY/gtk_i.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Schulze
  • Date: 2003-01-22 15:00:51 UTC
  • Revision ID: james.westby@ubuntu.com-20030122150051-uihwkdoxf15mi1tn
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
    TiMidity++ -- MIDI to WAVE converter and player
 
4
    Copyright (C) 1999 Masanao Izumo <mo@goice.co.jp>
 
5
    Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
 
6
 
 
7
    This program 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 of the License, or
 
10
    (at your option) any later version.
 
11
 
 
12
    This program is distributed in the hope that it will be useful,
 
13
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
    GNU General Public License for more details.
 
16
 
 
17
    You should have received a copy of the GNU General Public License
 
18
    along with this program; if not, write to the Free Software
 
19
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
20
 
 
21
    gtk_i.c - Glenn Trigg 29 Oct 1998
 
22
 
 
23
*/
 
24
#ifdef IA_GTK
 
25
 
 
26
#include <string.h>
 
27
#ifdef HAVE_GLOB_H
 
28
#include <glob.h>
 
29
#endif
 
30
#include <gtk/gtk.h>
 
31
 
 
32
#include "config.h"
 
33
#include "common.h"
 
34
#include "instrum.h"
 
35
#include "playmidi.h"
 
36
#include "output.h"
 
37
#include "controls.h"
 
38
#include "ctl.h"
 
39
 
 
40
#include "pixmaps/playpaus.xpm"
 
41
#include "pixmaps/prevtrk.xpm"
 
42
#include "pixmaps/nexttrk.xpm"
 
43
#include "pixmaps/rew.xpm"
 
44
#include "pixmaps/ff.xpm"
 
45
#include "pixmaps/restart.xpm"
 
46
#include "pixmaps/quit.xpm"
 
47
#include "pixmaps/quiet.xpm"
 
48
#include "pixmaps/loud.xpm"
 
49
#include "pixmaps/open.xpm"
 
50
#include "pixmaps/keyup.xpm"
 
51
#include "pixmaps/keydown.xpm"
 
52
#include "pixmaps/slow.xpm"
 
53
#include "pixmaps/fast.xpm"
 
54
#include "pixmaps/timidity.xpm"
 
55
 
 
56
#define GTK_CHANGE_VOLUME       MOTIF_CHANGE_VOLUME
 
57
#define GTK_CHANGE_LOCATOR      MOTIF_CHANGE_LOCATOR
 
58
#define GTK_QUIT                MOTIF_QUIT
 
59
#define GTK_PLAY_FILE           MOTIF_PLAY_FILE
 
60
#define GTK_NEXT                MOTIF_NEXT
 
61
#define GTK_PREV                MOTIF_PREV
 
62
#define GTK_RESTART             MOTIF_RESTART
 
63
#define GTK_FWD                 MOTIF_FWD
 
64
#define GTK_RWD                 MOTIF_RWD
 
65
#define GTK_PAUSE               MOTIF_PAUSE
 
66
#define GTK_KEYUP               MOTIF_KEYUP
 
67
#define GTK_KEYDOWN             MOTIF_KEYDOWN
 
68
#define GTK_SLOWER              MOTIF_SLOWER
 
69
#define GTK_FASTER              MOTIF_FASTER
 
70
#define GTK_TOGGLE_DRUMS        MOTIF_TOGGLE_DRUMS
 
71
 
 
72
static GtkWidget *create_menubar(void);
 
73
static GtkWidget *create_button_with_pixmap(GtkWidget *, const gchar **, gint, const gchar *);
 
74
static GtkWidget *create_pixmap_label(GtkWidget *, const gchar **);
 
75
static gint delete_event(GtkWidget *, GdkEvent *, gpointer);
 
76
static void destroy (GtkWidget *, gpointer);
 
77
static GtkTooltips *create_yellow_tooltips(void);
 
78
static void handle_input(gpointer, gint, GdkInputCondition);
 
79
static void generic_cb(GtkWidget *, gpointer);
 
80
static void generic_scale_cb(GtkAdjustment *, gpointer);
 
81
static void open_file_cb(GtkWidget *, gpointer);
 
82
static void playlist_cb(GtkWidget *, guint);
 
83
static void playlist_op(GtkWidget *, guint);
 
84
static void file_list_cb(GtkWidget *, gint, gint, GdkEventButton *, gpointer);
 
85
static void clear_all_cb(GtkWidget *, gpointer);
 
86
static void filer_cb(GtkWidget *, gpointer);
 
87
static void tt_toggle_cb(GtkWidget *, gpointer);
 
88
static void locate_update_cb(GtkWidget *, GdkEventButton *, gpointer);
 
89
static void my_adjustment_set_value(GtkAdjustment *, gint);
 
90
static void set_icon_pixmap(GtkWidget *, const gchar **);
 
91
 
 
92
static GtkWidget *window, *clist, *text, *vol_scale, *locator;
 
93
static GtkWidget *filesel = NULL, *plfilesel = NULL;
 
94
static GtkWidget *tot_lbl, *cnt_lbl, *auto_next, *ttshow;
 
95
static GtkTooltips *ttip;
 
96
static int file_number_to_play; /* Number of the file we're playing in the list */
 
97
static int max_sec, is_quitting = 0, locating = 0, local_adjust = 0;
 
98
 
 
99
static GtkItemFactoryEntry ife[] = {
 
100
    {(gchar *)"/File/Open", (gchar *)"<control>O", open_file_cb, 0, NULL},
 
101
    {(gchar *)"/File/sep", NULL, NULL, 0, (gchar *)"<Separator>"},
 
102
    {(gchar *)"/File/Load Playlist", (gchar *)"<control>L", playlist_cb,
 
103
     'l', NULL},
 
104
    {(gchar *)"/File/Save Playlist", (gchar *)"<control>S", playlist_cb,
 
105
     's', NULL},
 
106
    {(gchar *)"/File/sep", NULL, NULL, 0, (gchar *)"<Separator>"},
 
107
    {(gchar *)"/File/Quit", (gchar *)"<control>Q", generic_cb, GTK_QUIT, NULL},
 
108
    {(gchar *)"/Options/Auto next", (gchar *)"<control>A", NULL, 0, (gchar *)"<CheckItem>"},
 
109
    {(gchar *)"/Options/Show tooltips", (gchar *)"<control>T", tt_toggle_cb, 0, (gchar *)"<CheckItem>"},
 
110
    {(gchar *)"/Options/Clear All", (gchar *)"<control>C", clear_all_cb, 0, NULL}
 
111
};
 
112
 
 
113
void Launch_Gtk_Process(int pipe_number);
 
114
 
 
115
/*----------------------------------------------------------------------*/
 
116
 
 
117
static void
 
118
generic_cb(GtkWidget *widget, gpointer data)
 
119
{
 
120
    pipe_int_write((int)data);
 
121
    if((int)data == GTK_PAUSE) {
 
122
        gtk_label_set(GTK_LABEL(cnt_lbl), "Pause");
 
123
    }
 
124
}
 
125
 
 
126
static void
 
127
tt_toggle_cb(GtkWidget *widget, gpointer data)
 
128
{
 
129
    if( GTK_CHECK_MENU_ITEM(ttshow)->active ) {
 
130
        gtk_tooltips_enable(ttip);
 
131
    }
 
132
    else {
 
133
        gtk_tooltips_disable(ttip);
 
134
    }
 
135
}
 
136
 
 
137
static void
 
138
open_file_cb(GtkWidget *widget, gpointer data)
 
139
{
 
140
    if( ! filesel ) {
 
141
        filesel = gtk_file_selection_new("Open File");
 
142
        gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(filesel));
 
143
 
 
144
        gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(filesel)->ok_button),
 
145
                           "clicked",
 
146
                           GTK_SIGNAL_FUNC (filer_cb), (gpointer)1);
 
147
        gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(filesel)->cancel_button),
 
148
                           "clicked",
 
149
                           GTK_SIGNAL_FUNC (filer_cb), (gpointer)0);
 
150
    }
 
151
 
 
152
    gtk_widget_show(GTK_WIDGET(filesel));
 
153
}
 
154
 
 
155
static void
 
156
filer_cb(GtkWidget *widget, gpointer data)
 
157
{
 
158
    gchar *filenames[2];
 
159
#ifdef GLOB_BRACE
 
160
    int i;
 
161
    gchar *patt;
 
162
    glob_t pglob;
 
163
 
 
164
    if((int)data == 1) {
 
165
        patt = gtk_file_selection_get_filename(GTK_FILE_SELECTION(filesel));
 
166
        if(glob(patt, GLOB_BRACE|GLOB_NOMAGIC|GLOB_TILDE, NULL, &pglob))
 
167
            return;
 
168
        for( i = 0; i < pglob.gl_pathc; i++) {
 
169
            filenames[0] = pglob.gl_pathv[i];
 
170
            filenames[1] = NULL;
 
171
            gtk_clist_append(GTK_CLIST(clist), filenames);
 
172
        }
 
173
        globfree(&pglob);
 
174
    }
 
175
#else
 
176
    if((int)data == 1) {
 
177
        filenames[0] = gtk_file_selection_get_filename(GTK_FILE_SELECTION(filesel));
 
178
        filenames[1] = NULL;
 
179
        gtk_clist_append(GTK_CLIST(clist), filenames);
 
180
    }
 
181
#endif
 
182
    gtk_widget_hide(filesel);
 
183
    gtk_clist_columns_autosize(GTK_CLIST(clist));
 
184
}
 
185
 
 
186
static void
 
187
generic_scale_cb(GtkAdjustment *adj, gpointer data)
 
188
{
 
189
    if(local_adjust)
 
190
        return;
 
191
 
 
192
    pipe_int_write((int)data);
 
193
 
 
194
    /* This is a bit of a hack as the volume scale (a GtkVScale) seems
 
195
       to have it's minimum at the top which is counter-intuitive. */
 
196
    if((int)data == GTK_CHANGE_VOLUME) {
 
197
        pipe_int_write(MAX_AMPLIFICATION - adj->value);
 
198
    }
 
199
    else {
 
200
        pipe_int_write((int)adj->value*100);
 
201
    }
 
202
}
 
203
 
 
204
static void
 
205
file_list_cb(GtkWidget *widget, gint row, gint column,
 
206
             GdkEventButton *event, gpointer data)
 
207
{
 
208
    gint        retval;
 
209
    gchar       *fname;
 
210
 
 
211
    if(event && (event->button == 3)) {
 
212
        if(event->type == GDK_2BUTTON_PRESS) {
 
213
            gtk_clist_remove(GTK_CLIST(clist), row);
 
214
        }
 
215
        else {
 
216
            return;
 
217
        }
 
218
    }
 
219
    retval = gtk_clist_get_text(GTK_CLIST(widget), row, 0, &fname);
 
220
    if(retval) {
 
221
        pipe_int_write(GTK_PLAY_FILE);
 
222
        pipe_string_write(fname);
 
223
        file_number_to_play=row;
 
224
    }
 
225
}
 
226
 
 
227
static void
 
228
playlist_cb(GtkWidget *widget, guint data)
 
229
{
 
230
    gchar       *pldir, *plpatt;
 
231
 
 
232
    if( ! plfilesel ) {
 
233
        plfilesel = gtk_file_selection_new("");
 
234
        gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(plfilesel));
 
235
 
 
236
#ifdef orig_tplus
 
237
        pldir = g_getenv("TIMIDITY_PLAYLIST_DIR");
 
238
#else
 
239
        pldir = g_getenv("HOME");
 
240
        pldir = g_strconcat(pldir, "/.kde/share/apps/kmidi", NULL);
 
241
#endif
 
242
        if(pldir != NULL) {
 
243
#ifdef orig_tplus
 
244
            plpatt = g_strconcat(pldir, "/*.tpl", NULL);
 
245
#else
 
246
            plpatt = g_strconcat(pldir, "/*.plist", NULL);
 
247
#endif
 
248
            gtk_file_selection_set_filename(GTK_FILE_SELECTION(plfilesel),
 
249
                                            plpatt);
 
250
            g_free(plpatt);
 
251
        }
 
252
 
 
253
        gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(plfilesel)->ok_button),
 
254
                           "clicked",
 
255
                           GTK_SIGNAL_FUNC (playlist_op), (gpointer)1);
 
256
        gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(plfilesel)->cancel_button),
 
257
                           "clicked",
 
258
                           GTK_SIGNAL_FUNC (playlist_op), NULL);
 
259
    }
 
260
 
 
261
    gtk_window_set_title(GTK_WINDOW(plfilesel), ((char)data == 'l')?
 
262
                         "Load Playlist":
 
263
                         "Save Playlist");
 
264
    gtk_object_set_user_data(GTK_OBJECT(plfilesel), (gpointer)data);
 
265
#ifdef orig_tplus
 
266
    gtk_file_selection_complete(GTK_FILE_SELECTION(plfilesel), "*.tpl");
 
267
#else
 
268
    gtk_file_selection_complete(GTK_FILE_SELECTION(plfilesel), "*.plist");
 
269
#endif
 
270
 
 
271
    gtk_widget_show(plfilesel);
 
272
} /* playlist_cb */
 
273
 
 
274
static void
 
275
playlist_op(GtkWidget *widget, guint data)
 
276
{
 
277
    int         i;
 
278
    gchar       *filename[2], action, *rowdata, fname[BUFSIZ], *tmp;
 
279
    FILE        *plfp;
 
280
 
 
281
    gtk_widget_hide(plfilesel);
 
282
 
 
283
    if(!data)
 
284
        return;
 
285
 
 
286
    action = (gchar)(int)gtk_object_get_user_data(GTK_OBJECT(plfilesel));
 
287
    filename[0] = gtk_file_selection_get_filename(GTK_FILE_SELECTION(plfilesel));
 
288
 
 
289
    if(action == 'l') {
 
290
        if((plfp = fopen(filename[0], "r")) == NULL) {
 
291
            g_error("Can't open %s for reading.", filename[0]);
 
292
            return;
 
293
        }
 
294
        while(fgets(fname, BUFSIZ, plfp) != NULL) {
 
295
            if(fname[strlen(fname) - 1] == '\n')
 
296
                fname[strlen(fname) - 1] = '\0';
 
297
            filename[0] = fname;
 
298
            filename[1] = NULL;
 
299
            gtk_clist_append(GTK_CLIST(clist), filename);
 
300
        }
 
301
        fclose(plfp);
 
302
        gtk_clist_columns_autosize(GTK_CLIST(clist));
 
303
    }
 
304
    else if(action == 's') {
 
305
        if((plfp = fopen(filename[0], "w")) == NULL) {
 
306
            g_error("Can't open %s for writing.", filename[0]);
 
307
            return;
 
308
        }
 
309
        for(i = 0; i < GTK_CLIST(clist)->rows; i++) {
 
310
            gtk_clist_get_text(GTK_CLIST(clist), i, 0, &rowdata);
 
311
            /* Make sure we have an absolute path. */
 
312
            if(*rowdata != '/') {
 
313
                tmp = g_get_current_dir();
 
314
                rowdata = g_strconcat(tmp, "/", rowdata, NULL);
 
315
                fprintf(plfp, "%s\n", rowdata);
 
316
                g_free(rowdata);
 
317
                g_free(tmp);
 
318
            }
 
319
            else {
 
320
                fprintf(plfp, "%s\n", rowdata);
 
321
            }
 
322
        }
 
323
        fclose(plfp);
 
324
    }
 
325
    else {
 
326
        g_error("Invalid playlist action!.");
 
327
    }
 
328
} /* playlist_op */
 
329
 
 
330
static void
 
331
clear_all_cb(GtkWidget *widget, gpointer data)
 
332
{
 
333
    gtk_clist_clear(GTK_CLIST(clist));
 
334
} /* clear_all_cb */
 
335
 
 
336
static gint
 
337
delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
 
338
{
 
339
    return (FALSE);
 
340
}
 
341
 
 
342
static void
 
343
destroy (GtkWidget *widget, gpointer data)
 
344
{
 
345
    is_quitting = 1;
 
346
    pipe_int_write(GTK_QUIT);
 
347
}
 
348
 
 
349
static void
 
350
locate_update_cb (GtkWidget *widget, GdkEventButton *ev, gpointer data)
 
351
{
 
352
    if( (ev->button == 1) || (ev->button == 2)) {
 
353
        if( ev->type == GDK_BUTTON_RELEASE ) {
 
354
            locating = 0;
 
355
        }
 
356
        else {
 
357
            locating = 1;
 
358
        }
 
359
    }
 
360
}
 
361
 
 
362
static void
 
363
my_adjustment_set_value(GtkAdjustment *adj, gint value)
 
364
{
 
365
    local_adjust = 1;
 
366
    gtk_adjustment_set_value(adj, (gfloat)value);
 
367
    local_adjust = 0;
 
368
}
 
369
 
 
370
void
 
371
Launch_Gtk_Process(int pipe_number)
 
372
{
 
373
    int argc = 0;
 
374
    GtkWidget *button, *mbar, *swin;
 
375
    GtkWidget *table, *align, *handlebox;
 
376
    GtkWidget *vbox, *hbox, *vscrollbar, *vbox2;
 
377
    GtkObject *adj;
 
378
 
 
379
    /* enable locale */
 
380
    gtk_set_locale ();
 
381
 
 
382
    gtk_init (&argc, NULL);
 
383
 
 
384
    ttip = create_yellow_tooltips();
 
385
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 
386
    gtk_widget_set_name(window, "TiMidity");
 
387
    gtk_window_set_title(GTK_WINDOW(window), "TiMidity - MIDI Player");
 
388
    gtk_window_set_wmclass(GTK_WINDOW(window), "timidity", "TiMidity");
 
389
 
 
390
    gtk_signal_connect(GTK_OBJECT(window), "delete_event",
 
391
                       GTK_SIGNAL_FUNC (delete_event), NULL);
 
392
 
 
393
    gtk_signal_connect(GTK_OBJECT(window), "destroy",
 
394
                       GTK_SIGNAL_FUNC (destroy), NULL);
 
395
 
 
396
    vbox = gtk_vbox_new(FALSE, 0);
 
397
    gtk_container_add(GTK_CONTAINER(window), vbox);
 
398
 
 
399
    mbar = create_menubar();
 
400
    gtk_box_pack_start(GTK_BOX(vbox), mbar, FALSE, FALSE, 0);
 
401
 
 
402
    hbox = gtk_hbox_new(FALSE, 0);
 
403
    gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 4);
 
404
    gtk_widget_show(hbox);
 
405
 
 
406
    text = gtk_text_new(NULL, NULL);
 
407
    gtk_widget_show(text);
 
408
    gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4);
 
409
    vscrollbar = gtk_vscrollbar_new(GTK_TEXT(text)->vadj);
 
410
    gtk_box_pack_start(GTK_BOX(hbox), vscrollbar, FALSE, FALSE, 4);
 
411
    gtk_widget_show (vscrollbar);
 
412
 
 
413
    hbox = gtk_hbox_new(FALSE, 4);
 
414
    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 4);
 
415
    gtk_widget_show(hbox);
 
416
 
 
417
    adj = gtk_adjustment_new(0., 0., 100., 1., 20., 0.);
 
418
    locator = gtk_hscale_new(GTK_ADJUSTMENT(adj));
 
419
    gtk_scale_set_draw_value(GTK_SCALE(locator), TRUE);
 
420
    gtk_signal_connect(GTK_OBJECT(adj), "value_changed",
 
421
                        GTK_SIGNAL_FUNC(generic_scale_cb),
 
422
                        (gpointer)GTK_CHANGE_LOCATOR);
 
423
    gtk_signal_connect(GTK_OBJECT(locator), "button_press_event",
 
424
                        GTK_SIGNAL_FUNC(locate_update_cb),
 
425
                        NULL);
 
426
    gtk_signal_connect(GTK_OBJECT(locator), "button_release_event",
 
427
                        GTK_SIGNAL_FUNC(locate_update_cb),
 
428
                        NULL);
 
429
    gtk_range_set_update_policy(GTK_RANGE(locator),
 
430
                                GTK_UPDATE_DISCONTINUOUS);
 
431
    gtk_scale_set_digits(GTK_SCALE(locator), 0);
 
432
    gtk_widget_show(locator);
 
433
    gtk_box_pack_start(GTK_BOX(hbox), locator, TRUE, TRUE, 4);
 
434
 
 
435
    align = gtk_alignment_new(0., 1., 1., 0.);
 
436
    gtk_widget_show(align);
 
437
    cnt_lbl = gtk_label_new("00:00");
 
438
    gtk_widget_show(cnt_lbl);
 
439
    gtk_container_add(GTK_CONTAINER(align), cnt_lbl);
 
440
    gtk_box_pack_start(GTK_BOX(hbox), align, FALSE, TRUE, 0);
 
441
 
 
442
    align = gtk_alignment_new(0., 1., 1., 0.);
 
443
    gtk_widget_show(align);
 
444
    tot_lbl = gtk_label_new("/00:00");
 
445
    gtk_widget_show(tot_lbl);
 
446
    gtk_container_add(GTK_CONTAINER(align), tot_lbl);
 
447
    gtk_box_pack_start(GTK_BOX(hbox), align, FALSE, TRUE, 0);
 
448
 
 
449
    hbox = gtk_hbox_new(FALSE, 4);
 
450
    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 4);
 
451
 
 
452
    swin = gtk_scrolled_window_new(NULL, NULL);
 
453
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
 
454
                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
455
    clist = gtk_clist_new(1);
 
456
    gtk_container_add(GTK_CONTAINER(swin), clist);
 
457
    gtk_widget_show(swin);
 
458
    gtk_widget_show(clist);
 
459
    gtk_widget_set_usize(clist, 200, 10);
 
460
    gtk_clist_set_reorderable(GTK_CLIST(clist), TRUE);
 
461
    gtk_clist_set_button_actions(GTK_CLIST(clist), 0, GTK_BUTTON_SELECTS);
 
462
    gtk_clist_set_button_actions(GTK_CLIST(clist), 1, GTK_BUTTON_DRAGS);
 
463
    gtk_clist_set_button_actions(GTK_CLIST(clist), 2, GTK_BUTTON_SELECTS);
 
464
    gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_SINGLE);
 
465
    gtk_clist_set_column_auto_resize(GTK_CLIST(clist), 1, TRUE);
 
466
    gtk_signal_connect(GTK_OBJECT(clist), "select_row",
 
467
                       GTK_SIGNAL_FUNC(file_list_cb), NULL);
 
468
 
 
469
    gtk_box_pack_start(GTK_BOX(hbox), swin, TRUE, TRUE, 0);
 
470
 
 
471
    vbox2 = gtk_vbox_new(FALSE, 0);
 
472
    gtk_box_pack_start(GTK_BOX(hbox), vbox2, TRUE, FALSE, 0);
 
473
    gtk_widget_show(vbox2);
 
474
 
 
475
    /* This is so the pixmap creation works properly. */
 
476
    gtk_widget_realize(window);
 
477
    set_icon_pixmap(window, timidity_xpm);
 
478
 
 
479
    gtk_box_pack_start(GTK_BOX(vbox2),
 
480
                       create_pixmap_label(window, loud_xpm),
 
481
                       FALSE, FALSE, 0);
 
482
 
 
483
    adj = gtk_adjustment_new(30., 0., (gfloat)MAX_AMPLIFICATION, 1., 20., 0.);
 
484
    vol_scale = gtk_vscale_new(GTK_ADJUSTMENT(adj));
 
485
    gtk_scale_set_draw_value(GTK_SCALE(vol_scale), FALSE);
 
486
    gtk_signal_connect (GTK_OBJECT(adj), "value_changed",
 
487
                        GTK_SIGNAL_FUNC(generic_scale_cb),
 
488
                        (gpointer)GTK_CHANGE_VOLUME);
 
489
    gtk_range_set_update_policy(GTK_RANGE(vol_scale),
 
490
                                GTK_UPDATE_DELAYED);
 
491
    gtk_widget_show(vol_scale);
 
492
    gtk_tooltips_set_tip(ttip, vol_scale, "Volume control", NULL);
 
493
 
 
494
    gtk_box_pack_start(GTK_BOX(vbox2), vol_scale, TRUE, TRUE, 0);
 
495
 
 
496
    gtk_box_pack_start(GTK_BOX(vbox2),
 
497
                       create_pixmap_label(window, quiet_xpm),
 
498
                       FALSE, FALSE, 0);
 
499
 
 
500
    handlebox = gtk_handle_box_new();
 
501
    gtk_box_pack_start(GTK_BOX(hbox), handlebox, FALSE, FALSE, 0);
 
502
 
 
503
    table = gtk_table_new(7, 2, TRUE);
 
504
    gtk_container_add(GTK_CONTAINER(handlebox), table);
 
505
 
 
506
    button = create_button_with_pixmap(window, playpaus_xpm, GTK_PAUSE,
 
507
                                       "Play/Pause");
 
508
    gtk_table_attach_defaults(GTK_TABLE(table), button,
 
509
                              0, 2, 0, 1);
 
510
 
 
511
    button = create_button_with_pixmap(window, prevtrk_xpm, GTK_PREV,
 
512
                                       "Previous file");
 
513
    gtk_table_attach_defaults(GTK_TABLE(table), button,
 
514
                              0, 1, 1, 2);
 
515
 
 
516
    button = create_button_with_pixmap(window, nexttrk_xpm, GTK_NEXT,
 
517
                                       "Next file");
 
518
    gtk_table_attach_defaults(GTK_TABLE(table), button,
 
519
                              1, 2, 1, 2);
 
520
 
 
521
    button = create_button_with_pixmap(window, rew_xpm, GTK_RWD,
 
522
                                       "Rewind");
 
523
    gtk_table_attach_defaults(GTK_TABLE(table), button,
 
524
                              0, 1, 2, 3);
 
525
 
 
526
    button = create_button_with_pixmap(window, ff_xpm, GTK_FWD,
 
527
                                       "Fast forward");
 
528
    gtk_table_attach_defaults(GTK_TABLE(table), button,
 
529
                              1, 2, 2, 3);
 
530
 
 
531
    button = create_button_with_pixmap(window, keydown_xpm, GTK_KEYDOWN,
 
532
                                       "Lower pitch");
 
533
    gtk_table_attach_defaults(GTK_TABLE(table), button,
 
534
                              0, 1, 3, 4);
 
535
 
 
536
    button = create_button_with_pixmap(window, keyup_xpm, GTK_KEYUP,
 
537
                                       "Raise pitch");
 
538
    gtk_table_attach_defaults(GTK_TABLE(table), button,
 
539
                              1, 2, 3, 4);
 
540
 
 
541
    button = create_button_with_pixmap(window, slow_xpm, GTK_SLOWER,
 
542
                                       "Decrease tempo");
 
543
    gtk_table_attach_defaults(GTK_TABLE(table), button,
 
544
                              0, 1, 4, 5);
 
545
 
 
546
    button = create_button_with_pixmap(window, fast_xpm, GTK_FASTER,
 
547
                                       "Increase tempo");
 
548
    gtk_table_attach_defaults(GTK_TABLE(table), button,
 
549
                              1, 2, 4, 5);
 
550
 
 
551
    button = create_button_with_pixmap(window, restart_xpm, GTK_RESTART,
 
552
                                       "Restart");
 
553
    gtk_table_attach_defaults(GTK_TABLE(table), button,
 
554
                              0, 1, 5, 6);
 
555
 
 
556
    button = create_button_with_pixmap(window, open_xpm, 0,
 
557
                                       "Open");
 
558
    gtk_signal_disconnect_by_func(GTK_OBJECT(button), generic_cb, 0);
 
559
    gtk_signal_connect(GTK_OBJECT(button), "clicked",
 
560
                              GTK_SIGNAL_FUNC(open_file_cb), 0);
 
561
    gtk_table_attach_defaults(GTK_TABLE(table), button,
 
562
                              1, 2, 5, 6);
 
563
 
 
564
    button = create_button_with_pixmap(window, quit_xpm, GTK_QUIT,
 
565
                                       "Quit");
 
566
    gtk_table_attach_defaults(GTK_TABLE(table), button,
 
567
                              0, 2, 6, 7);
 
568
 
 
569
    gtk_widget_show(hbox);
 
570
    gtk_widget_show(vbox);
 
571
    gtk_widget_show(table);
 
572
    gtk_widget_show(handlebox);
 
573
    gtk_widget_show(window);
 
574
 
 
575
    gdk_input_add(pipe_number, GDK_INPUT_READ, handle_input, NULL);
 
576
 
 
577
pipe_int_write(GTK_CHANGE_VOLUME);
 
578
pipe_int_write(40);
 
579
 
 
580
    gtk_main();
 
581
}
 
582
 
 
583
static GtkWidget *
 
584
create_button_with_pixmap(GtkWidget *window, const gchar **bits, gint data, const gchar *thelp)
 
585
{
 
586
    GtkWidget   *pw, *button;
 
587
    GdkPixmap   *pixmap;
 
588
    GdkBitmap   *mask;
 
589
    GtkStyle    *style;
 
590
 
 
591
    style = gtk_widget_get_style(window);
 
592
    pixmap = gdk_pixmap_create_from_xpm_d(window->window,
 
593
                                          &mask,
 
594
                                          &style->bg[GTK_STATE_NORMAL],
 
595
                                          (gchar **)bits);
 
596
    pw = gtk_pixmap_new(pixmap, mask);
 
597
    gtk_widget_show(pw);
 
598
 
 
599
    button = gtk_button_new();
 
600
    gtk_container_add(GTK_CONTAINER(button), pw);
 
601
    gtk_signal_connect(GTK_OBJECT(button), "clicked",
 
602
                              GTK_SIGNAL_FUNC(generic_cb),
 
603
                              (gpointer)data);
 
604
    gtk_widget_show(button);
 
605
    gtk_tooltips_set_tip(ttip, button, thelp, NULL);
 
606
 
 
607
    return button;
 
608
}
 
609
 
 
610
static GtkWidget *
 
611
create_pixmap_label(GtkWidget *window, const gchar **bits)
 
612
{
 
613
    GtkWidget   *pw;
 
614
    GdkPixmap   *pixmap;
 
615
    GdkBitmap   *mask;
 
616
    GtkStyle    *style;
 
617
 
 
618
    style = gtk_widget_get_style(window);
 
619
    pixmap = gdk_pixmap_create_from_xpm_d(window->window,
 
620
                                          &mask,
 
621
                                          &style->bg[GTK_STATE_NORMAL],
 
622
                                          (gchar **)bits);
 
623
    pw = gtk_pixmap_new(pixmap, mask);
 
624
    gtk_widget_show(pw);
 
625
 
 
626
    return pw;
 
627
}
 
628
 
 
629
static void
 
630
set_icon_pixmap(GtkWidget *window, const gchar **bits)
 
631
{
 
632
    GdkPixmap   *pixmap;
 
633
    GdkBitmap   *mask;
 
634
    GtkStyle    *style;
 
635
 
 
636
    style = gtk_widget_get_style(window);
 
637
    pixmap = gdk_pixmap_create_from_xpm_d(window->window,
 
638
                                          &mask,
 
639
                                          &style->bg[GTK_STATE_NORMAL],
 
640
                                          (gchar **)bits);
 
641
    gdk_window_set_icon(window->window, NULL, pixmap, mask);
 
642
    gdk_window_set_icon_name(window->window, (gchar *)"TiMidity");
 
643
}
 
644
 
 
645
static GtkWidget *
 
646
create_menubar(void)
 
647
{
 
648
    GtkItemFactory      *ifactory;
 
649
    GtkAccelGroup       *ag;
 
650
 
 
651
    ag = gtk_accel_group_get_default();
 
652
    ifactory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<Main>", ag);
 
653
    gtk_item_factory_create_items(ifactory,
 
654
                                  sizeof(ife) / sizeof(GtkItemFactoryEntry),
 
655
                                  ife, NULL);
 
656
    gtk_widget_show(ifactory->widget);
 
657
 
 
658
    auto_next = gtk_item_factory_get_widget(ifactory, "/Options/Auto next");
 
659
    gtk_check_menu_item_set_state(GTK_CHECK_MENU_ITEM(auto_next), TRUE);
 
660
    ttshow = gtk_item_factory_get_widget(ifactory, "/Options/Show tooltips");
 
661
    gtk_check_menu_item_set_state(GTK_CHECK_MENU_ITEM(ttshow), TRUE);
 
662
 
 
663
    return ifactory->widget;
 
664
}
 
665
 
 
666
/* Following function curtesy of the gtk mailing list. */
 
667
 
 
668
static GtkTooltips *
 
669
create_yellow_tooltips()
 
670
{
 
671
    GdkColor    *t_back;
 
672
    GtkTooltips *tip;
 
673
 
 
674
    t_back = (GdkColor*)g_malloc( sizeof(GdkColor));
 
675
 
 
676
    /* First create a default Tooltip */
 
677
    tip = gtk_tooltips_new();
 
678
 
 
679
    /* Try to get the colors */
 
680
    if ( gdk_color_parse("linen", t_back)){
 
681
        if(gdk_colormap_alloc_color(gdk_colormap_get_system(),
 
682
                                    t_back,
 
683
                                    FALSE, TRUE)) {
 
684
            gtk_tooltips_set_colors(tip, t_back, NULL);
 
685
        }
 
686
    }
 
687
 
 
688
    return tip;
 
689
}
 
690
 
 
691
/* Receive DATA sent by the application on the pipe     */
 
692
 
 
693
static void
 
694
handle_input(gpointer client_data, gint source, GdkInputCondition ic)
 
695
{
 
696
    int message;
 
697
 
 
698
    pipe_int_read(&message);
 
699
 
 
700
    switch (message) {
 
701
    case REFRESH_MESSAGE:
 
702
        g_warning("REFRESH MESSAGE IS OBSOLETE !!!");
 
703
        break;
 
704
 
 
705
    case TOTALTIME_MESSAGE:
 
706
        {
 
707
            int cseconds;
 
708
            int minutes,seconds;
 
709
            char local_string[20];
 
710
            GtkObject *adj;
 
711
 
 
712
            pipe_int_read(&cseconds);
 
713
 
 
714
            seconds=cseconds/100;
 
715
            minutes=seconds/60;
 
716
            seconds-=minutes*60;
 
717
            sprintf(local_string,"/ %i:%02i",minutes,seconds);
 
718
            gtk_label_set(GTK_LABEL(tot_lbl), local_string);
 
719
 
 
720
            /* Readjust the time scale */
 
721
            max_sec=cseconds/100;
 
722
            adj = gtk_adjustment_new(0., 0., (gfloat)max_sec,
 
723
                                     1., 10., 0.);
 
724
            gtk_signal_connect(GTK_OBJECT(adj), "value_changed",
 
725
                               GTK_SIGNAL_FUNC(generic_scale_cb),
 
726
                               (gpointer)GTK_CHANGE_LOCATOR);
 
727
            gtk_range_set_adjustment(GTK_RANGE(locator),
 
728
                                     GTK_ADJUSTMENT(adj));
 
729
        }
 
730
        break;
 
731
 
 
732
    case MASTERVOL_MESSAGE:
 
733
        {
 
734
            int volume;
 
735
            GtkAdjustment *adj;
 
736
 
 
737
            pipe_int_read(&volume);
 
738
            adj = gtk_range_get_adjustment(GTK_RANGE(vol_scale));
 
739
            my_adjustment_set_value(adj, MAX_AMPLIFICATION - volume);
 
740
        }
 
741
        break;
 
742
 
 
743
    case FILENAME_MESSAGE:
 
744
        {
 
745
            char filename[255], title[255];
 
746
            char *pc;
 
747
            int i;
 
748
 
 
749
            pipe_string_read(filename);
 
750
 
 
751
            /* Extract basename of the file */
 
752
            pc = strrchr(filename, '/');
 
753
            if (pc == NULL)
 
754
                pc = filename;
 
755
            else
 
756
                pc++;
 
757
 
 
758
            sprintf(title, "Timidity 0.3i - %s", pc);
 
759
            gtk_window_set_title(GTK_WINDOW(window), title);
 
760
 
 
761
            /* Clear the text area. */
 
762
            gtk_text_freeze(GTK_TEXT(text));
 
763
            gtk_text_set_point(GTK_TEXT(text), 0);
 
764
            gtk_text_forward_delete(GTK_TEXT(text),
 
765
                                    gtk_text_get_length(GTK_TEXT(text)));
 
766
            gtk_text_thaw(GTK_TEXT(text));
 
767
        }
 
768
        break;
 
769
 
 
770
    case FILE_LIST_MESSAGE:
 
771
        {
 
772
            gchar filename[255], *fnames[2];
 
773
            gint i, number_of_files, row;
 
774
 
 
775
            /* reset the playing list : play from the start */
 
776
            file_number_to_play = -1;
 
777
 
 
778
            pipe_int_read(&number_of_files);
 
779
            for (i = 0; i < number_of_files; i++)
 
780
            {
 
781
                pipe_string_read(filename);
 
782
                fnames[0] = filename;
 
783
                fnames[1] = NULL;
 
784
                row = gtk_clist_append(GTK_CLIST(clist), fnames);
 
785
            }
 
786
            gtk_clist_columns_autosize(GTK_CLIST(clist));
 
787
        }
 
788
        break;
 
789
 
 
790
    case NEXT_FILE_MESSAGE:
 
791
    case PREV_FILE_MESSAGE:
 
792
    case TUNE_END_MESSAGE:
 
793
        {
 
794
            int nbfile;
 
795
 
 
796
            /* When a file ends, launch next if auto_next toggle */
 
797
            if ( (message==TUNE_END_MESSAGE) &&
 
798
                 !GTK_CHECK_MENU_ITEM(auto_next)->active )
 
799
                return;
 
800
 
 
801
            /* Total number of file to play in the list */
 
802
            nbfile = GTK_CLIST(clist)->rows;
 
803
 
 
804
            if (message == PREV_FILE_MESSAGE)
 
805
                file_number_to_play--;
 
806
            else
 
807
                file_number_to_play++;
 
808
 
 
809
            /* Do nothing if requested file is before first one */
 
810
            if (file_number_to_play < 0) {
 
811
                file_number_to_play = 0;
 
812
                return;
 
813
            }
 
814
 
 
815
            /* Stop after playing the last file */
 
816
            if (file_number_to_play >= nbfile) {
 
817
                file_number_to_play = nbfile - 1;
 
818
                return;
 
819
            }
 
820
 
 
821
            if(gtk_clist_row_is_visible(GTK_CLIST(clist),
 
822
                                        file_number_to_play) !=
 
823
               GTK_VISIBILITY_FULL) {
 
824
                gtk_clist_moveto(GTK_CLIST(clist), file_number_to_play,
 
825
                                 -1, 1.0, 0.0);
 
826
            }
 
827
            gtk_clist_select_row(GTK_CLIST(clist), file_number_to_play, 0);
 
828
        }
 
829
        break;
 
830
 
 
831
    case CURTIME_MESSAGE:
 
832
        {
 
833
            int         cseconds, seconds, minutes;
 
834
            int         nbvoice;
 
835
            char        local_string[20];
 
836
 
 
837
            pipe_int_read(&cseconds);
 
838
            pipe_int_read(&nbvoice);
 
839
 
 
840
            if( is_quitting )
 
841
                return;
 
842
 
 
843
            seconds = cseconds / 100;
 
844
            minutes=seconds/60;
 
845
 
 
846
            sprintf(local_string,"%2d:%02d", minutes, (int)(seconds % 60));
 
847
 
 
848
            gtk_label_set(GTK_LABEL(cnt_lbl), local_string);
 
849
 
 
850
            /* Readjust the time scale if not dragging the scale */
 
851
            if( !locating && (seconds <= max_sec)) {
 
852
                GtkAdjustment *adj;
 
853
 
 
854
                adj = gtk_range_get_adjustment(GTK_RANGE(locator));
 
855
                my_adjustment_set_value(adj, (gfloat)seconds);
 
856
            }
 
857
        }
 
858
        break;
 
859
 
 
860
    case NOTE_MESSAGE:
 
861
        {
 
862
            int channel;
 
863
            int note;
 
864
 
 
865
            pipe_int_read(&channel);
 
866
            pipe_int_read(&note);
 
867
            /* g_warning("NOTE chn%i %i", channel, note); */
 
868
        }
 
869
        break;
 
870
 
 
871
    case PROGRAM_MESSAGE:
 
872
        {
 
873
            int channel;
 
874
            int pgm;
 
875
            char progname[100];
 
876
 
 
877
            pipe_int_read(&channel);
 
878
            pipe_int_read(&pgm);
 
879
            pipe_string_read(progname);
 
880
            /* g_warning("NOTE chn%i %i", channel, pgm); */
 
881
        }
 
882
        break;
 
883
 
 
884
    case VOLUME_MESSAGE:
 
885
        {
 
886
            int channel;
 
887
            int volume;
 
888
 
 
889
            pipe_int_read(&channel);
 
890
            pipe_int_read(&volume);
 
891
            /* g_warning("VOLUME= chn%i %i", channel, volume); */
 
892
        }
 
893
        break;
 
894
 
 
895
 
 
896
    case EXPRESSION_MESSAGE:
 
897
        {
 
898
            int channel;
 
899
            int express;
 
900
 
 
901
            pipe_int_read(&channel);
 
902
            pipe_int_read(&express);
 
903
            /* g_warning("EXPRESSION= chn%i %i", channel, express); */
 
904
        }
 
905
        break;
 
906
 
 
907
    case PANNING_MESSAGE:
 
908
        {
 
909
            int channel;
 
910
            int pan;
 
911
 
 
912
            pipe_int_read(&channel);
 
913
            pipe_int_read(&pan);
 
914
            /* g_warning("PANNING= chn%i %i", channel, pan); */
 
915
        }
 
916
        break;
 
917
 
 
918
    case SUSTAIN_MESSAGE:
 
919
        {
 
920
            int channel;
 
921
            int sust;
 
922
 
 
923
            pipe_int_read(&channel);
 
924
            pipe_int_read(&sust);
 
925
            /* g_warning("SUSTAIN= chn%i %i", channel, sust); */
 
926
        }
 
927
        break;
 
928
 
 
929
    case PITCH_MESSAGE:
 
930
        {
 
931
            int channel;
 
932
            int bend;
 
933
 
 
934
            pipe_int_read(&channel);
 
935
            pipe_int_read(&bend);
 
936
            /* g_warning("PITCH BEND= chn%i %i", channel, bend); */
 
937
        }
 
938
        break;
 
939
 
 
940
    case RESET_MESSAGE:
 
941
        /* g_warning("RESET_MESSAGE"); */
 
942
        break;
 
943
 
 
944
    case CLOSE_MESSAGE:
 
945
        gtk_exit(0);
 
946
        break;
 
947
 
 
948
    case CMSG_MESSAGE:
 
949
        {
 
950
            int type;
 
951
            int message_time, futuretilda;
 
952
            char message[1000];
 
953
            static int tildaflag = 0;
 
954
 
 
955
            pipe_int_read(&type);
 
956
            if (type == CMSG_LYRIC) {
 
957
                        pipe_int_read(&message_time);
 
958
            }
 
959
            pipe_string_read(message);
 
960
 
 
961
            if (message[0] == '~') futuretilda = 1;
 
962
            else futuretilda = 0;
 
963
 
 
964
            if (!tildaflag || message[futuretilda] == '\0')
 
965
              gtk_text_insert(GTK_TEXT(text), NULL, NULL, NULL, "\n", 1);
 
966
 
 
967
            if (message[futuretilda] != '\0')
 
968
            gtk_text_insert(GTK_TEXT(text), NULL, NULL, NULL, message + futuretilda, -1);
 
969
 
 
970
            tildaflag = futuretilda;
 
971
        }
 
972
        break;
 
973
 
 
974
    case CMSG_ERROR:
 
975
        {
 
976
            char strmessage[2024];
 
977
            pipe_string_read(strmessage);
 
978
        }
 
979
        break;
 
980
#if 0
 
981
    case LYRIC_MESSAGE:
 
982
        {
 
983
            char message[1000];
 
984
 
 
985
            pipe_string_read(message);
 
986
 
 
987
            gtk_text_insert(GTK_TEXT(text), NULL, NULL, NULL,
 
988
                            message, -1);
 
989
        }
 
990
        break;
 
991
#endif
 
992
    default:
 
993
        g_warning("UNKNOWN Gtk+ MESSAGE %i", message);
 
994
    }
 
995
}
 
996
#endif /* IA_GTK */