~ubuntu-branches/ubuntu/maverick/vice/maverick

« back to all changes in this revision

Viewing changes to src/arch/unix/uifliplist.c

  • Committer: Bazaar Package Importer
  • Author(s): Zed Pobre
  • Date: 2005-02-01 11:30:26 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20050201113026-3eyakzsmmheclvjg
Tags: 1.16-1
* New upstream version
* Fixes crash on 64-bit architectures (closes: #287640)
* x128 working again (closes: #286767)
* Works fine with /dev/dsp in use (not in the main changelog, but tested
  on my local machine as working).  Presumably, this also takes care of
  the issue with dsp being held.  I'm not sure if this is because I'm
  testing it on a 2.6 kernel now -- if you are still having problems
  with /dev/dsp, please reopen the bugs. (closes: #152952, #207942)
* Don't kill Makefile.in on clean

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * uifliplist.c
 
3
 *
 
4
 * Written by
 
5
 *  Martin Pottendorfer <Martin.Pottendorfer@aut.alcatel.at>
 
6
 *  Andreas Boose <viceteam@t-online.de>
 
7
 *
 
8
 * This file is part of VICE, the Versatile Commodore Emulator.
 
9
 * See README for copyright notice.
 
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; either version 2 of the License, or
 
14
 *  (at your option) any later version.
 
15
 *
 
16
 *  This program is distributed in the hope that it will be useful,
 
17
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
18
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
19
 *  GNU General Public License for more details.
 
20
 *
 
21
 *  You should have received a copy of the GNU General Public License
 
22
 *  along with this program; if not, write to the Free Software
 
23
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 
24
 *  02111-1307  USA.
 
25
 *
 
26
 */
 
27
 
 
28
#include "vice.h"
 
29
 
 
30
#include <stdio.h>
 
31
#include <stdlib.h>
 
32
#include <string.h>
 
33
 
 
34
#include "attach.h"
 
35
#include "fliplist.h"
 
36
#include "lib.h"
 
37
#include "log.h"
 
38
#include "resources.h"
 
39
#include "uifliplist.h"
 
40
#include "uidrive.h"
 
41
#include "uimenu.h"
 
42
#include "util.h"
 
43
#include "vsync.h"
 
44
 
 
45
 
 
46
struct cb_data_t {
 
47
    int unit;
 
48
    long data;                  /* should be enough for a pointer */
 
49
};
 
50
 
 
51
typedef enum {
 
52
    CBD_NEXT, CBD_PREV, CBD_ADD, CBD_REMOVE
 
53
} cbd_enum_t;
 
54
 
 
55
 
 
56
extern char last_attached_images[NUM_DRIVES][256];
 
57
extern ui_drive_enable_t enabled_drives;
 
58
extern UI_CALLBACK(attach_disk);
 
59
extern UI_CALLBACK(detach_disk);
 
60
 
 
61
static UI_CALLBACK(attach_from_fliplist3)
 
62
{
 
63
    fliplist_attach_head(8, (int)UI_MENU_CB_PARAM);
 
64
}
 
65
 
 
66
static UI_CALLBACK(add2fliplist)
 
67
{
 
68
    fliplist_add_image(8);
 
69
    uifliplist_update_menus(8, 8);
 
70
}
 
71
 
 
72
static UI_CALLBACK(remove_from_fliplist)
 
73
{
 
74
    fliplist_remove(8, NULL);
 
75
    uifliplist_update_menus(8, 8);
 
76
}
 
77
 
 
78
static char *load_save_fliplist_last_dir = NULL;
 
79
 
 
80
static UI_CALLBACK(load_save_fliplist)
 
81
{
 
82
    char *filename, *title;
 
83
    int what = (int)UI_MENU_CB_PARAM;
 
84
    ui_button_t button;
 
85
 
 
86
    vsync_suspend_speed_eval();
 
87
    title = util_concat(what ? _("Load ") : _("Save"), _("Fliplist File"),
 
88
                        NULL);
 
89
    filename = ui_select_file(title, NULL, 0, False,
 
90
                              load_save_fliplist_last_dir, "*.vfl",
 
91
                              &button, True, NULL);
 
92
    lib_free(title);
 
93
    switch (button) {
 
94
      case UI_BUTTON_OK:
 
95
        if (what) {
 
96
            if (fliplist_load_list((unsigned int)-1, filename, 0) == 0)
 
97
                ui_message(_("Successfully read `%s'."), filename);
 
98
            else
 
99
                ui_error(_("Error reading `%s'."), filename);
 
100
        } else {
 
101
            if (fliplist_save_list((unsigned int)-1, filename) == 0)
 
102
                ui_message(_("Successfully wrote `%s'."), filename);
 
103
            else
 
104
                ui_error(_("Error writing `%s'."), filename);
 
105
        }
 
106
        if (load_save_fliplist_last_dir)
 
107
            lib_free(load_save_fliplist_last_dir);
 
108
        util_fname_split(filename, &load_save_fliplist_last_dir, NULL);
 
109
        break;
 
110
      default:
 
111
        break;
 
112
    }
 
113
 
 
114
}
 
115
 
 
116
ui_menu_entry_t fliplist_submenu[] = {
 
117
    { N_("Add current image (Unit 8)"),
 
118
      (ui_callback_t)add2fliplist, (ui_callback_data_t)0, NULL,
 
119
      XK_i, UI_HOTMOD_META },
 
120
    { N_("Remove current image (Unit 8)"),
 
121
      (ui_callback_t)remove_from_fliplist, (ui_callback_data_t)0, NULL,
 
122
      XK_k, UI_HOTMOD_META },
 
123
    { N_("Attach next image (Unit 8)"),
 
124
      (ui_callback_t)attach_from_fliplist3, (ui_callback_data_t)1, NULL,
 
125
      XK_n, UI_HOTMOD_META },
 
126
    { N_("Attach previous image (Unit 8)"),
 
127
      (ui_callback_t)attach_from_fliplist3, (ui_callback_data_t)0, NULL,
 
128
      XK_N, UI_HOTMOD_META },
 
129
    { N_("Load fliplist file"),
 
130
      (ui_callback_t)load_save_fliplist, (ui_callback_data_t)1, NULL },
 
131
    { N_("Save fliplist file"),
 
132
      (ui_callback_t)load_save_fliplist, (ui_callback_data_t)0, NULL },
 
133
    { NULL }
 
134
};
 
135
 
 
136
static UI_CALLBACK(attach_from_fliplist2)
 
137
{
 
138
    file_system_attach_disk(fliplist_get_unit((void *)UI_MENU_CB_PARAM),
 
139
                            fliplist_get_image((void *)UI_MENU_CB_PARAM));
 
140
}
 
141
 
 
142
static UI_CALLBACK(remove_from_fliplist2)
 
143
{
 
144
    fliplist_remove(((struct cb_data_t *)UI_MENU_CB_PARAM)->unit,
 
145
                    (char *) ((struct cb_data_t *)UI_MENU_CB_PARAM)->data);
 
146
    uifliplist_update_menus(((struct cb_data_t *)UI_MENU_CB_PARAM)->unit,
 
147
                            ((struct cb_data_t *)UI_MENU_CB_PARAM)->unit);
 
148
}
 
149
 
 
150
static UI_CALLBACK(add2fliplist2)
 
151
{
 
152
    fliplist_set_current(((struct cb_data_t *)UI_MENU_CB_PARAM)->unit,
 
153
                         (char *) ((struct cb_data_t *)UI_MENU_CB_PARAM)->data);
 
154
    fliplist_add_image(((struct cb_data_t *)UI_MENU_CB_PARAM)->unit);
 
155
    uifliplist_update_menus(((struct cb_data_t *)UI_MENU_CB_PARAM)->unit,
 
156
                            ((struct cb_data_t *)UI_MENU_CB_PARAM)->unit);
 
157
}
 
158
 
 
159
static UI_CALLBACK(attach_from_fliplist)
 
160
{
 
161
    fliplist_attach_head(((struct cb_data_t *)UI_MENU_CB_PARAM)->unit,
 
162
                         (int) ((struct cb_data_t *)UI_MENU_CB_PARAM)->data);
 
163
}
 
164
 
 
165
#ifdef USE_GNOMEUI
 
166
UI_MENU_DEFINE_TOGGLE(AttachDevice8Readonly)
 
167
UI_MENU_DEFINE_TOGGLE(AttachDevice9Readonly)
 
168
#endif
 
169
 
 
170
#define FLIPLIST_MENU_LIMIT 256
 
171
void uifliplist_update_menus(int from_unit, int to_unit)
 
172
{
 
173
    /* Yick, allocate dynamically */
 
174
    static ui_menu_entry_t flipmenu[NUM_DRIVES][FLIPLIST_MENU_LIMIT];
 
175
    static struct cb_data_t cb_data[NUM_DRIVES][sizeof(cbd_enum_t)];
 
176
 
 
177
    char *image = NULL, *t0 = NULL, *t1 = NULL, *t2 = NULL, *t3 = NULL;
 
178
    char *t4 = NULL, *t5 = NULL, *dir;
 
179
    void *fl_iterator;
 
180
    int i, drive, true_emu, fliplist_start = 0;
 
181
    static int name_count = 0;
 
182
    char *menuname;
 
183
 
 
184
    resources_get_value("DriveTrueEmulation", (void *)&true_emu);
 
185
 
 
186
    for (drive = from_unit - 8;
 
187
        (drive <= to_unit - 8) && (drive < NUM_DRIVES);
 
188
        drive++) {
 
189
 
 
190
        i = 0;
 
191
        t0 = t1 = t2 = t3 = t4 = t5 = NULL;
 
192
 
 
193
        memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t));
 
194
        t0 = lib_msprintf(_("Attach #%d"), drive + 8);
 
195
        flipmenu[drive][i].string = t0;
 
196
        flipmenu[drive][i].callback = (ui_callback_t)attach_disk;
 
197
        flipmenu[drive][i].callback_data = (ui_callback_data_t)(drive + 8);
 
198
        i++;
 
199
 
 
200
        memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t));
 
201
        t5 = lib_msprintf(_("Detach #%d"), drive + 8);
 
202
        flipmenu[drive][i].string = t5;
 
203
        flipmenu[drive][i].callback = (ui_callback_t)detach_disk;
 
204
        flipmenu[drive][i].callback_data = (ui_callback_data_t)(drive + 8);
 
205
        i++;
 
206
 
 
207
#ifdef USE_GNOMEUI
 
208
        /* drivesettings */
 
209
        /* this won't work so far for Xaw, because the checkmarks
 
210
           aren't updated when a menu is destroyed, as the flipmenu is
 
211
           dynamically regenerated; The Gnome code is already fixed. */
 
212
        memcpy(&flipmenu[drive][i], (const char *)ui_drive_options_submenu,
 
213
               sizeof(ui_menu_entry_t));
 
214
        i++;
 
215
        /* Write protext UI controll */
 
216
        memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t));
 
217
        flipmenu[drive][i].string = _("*Write Protect");
 
218
        if (drive == 0)
 
219
            flipmenu[drive][i].callback = toggle_AttachDevice8Readonly;
 
220
        else
 
221
            flipmenu[drive][i].callback = toggle_AttachDevice9Readonly;
 
222
        i++;
 
223
#endif
 
224
 
 
225
        fliplist_start = i;     /* if we take the goto don't free anythin */
 
226
 
 
227
        /* don't update menu deeply when drive has not been enabled
 
228
           or nothing has been attached */
 
229
        if (true_emu) {
 
230
            if (!((1 << drive) & enabled_drives))
 
231
                goto update_menu;
 
232
        } else {
 
233
            if (strcmp(last_attached_images[drive], "") == 0)
 
234
                goto update_menu;
 
235
        }
 
236
 
 
237
        memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t));
 
238
        flipmenu[drive][i].string = "--";
 
239
        i++;
 
240
 
 
241
        memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t));
 
242
        util_fname_split(fliplist_get_next(drive + 8), &dir, &image);
 
243
        t1 = util_concat(_("Next: "), image ? image : _("<empty>"), NULL);
 
244
        flipmenu[drive][i].string = t1;
 
245
        flipmenu[drive][i].callback = (ui_callback_t)attach_from_fliplist;
 
246
        cb_data[drive][CBD_NEXT].unit = drive + 8;
 
247
        cb_data[drive][CBD_NEXT].data = 1;
 
248
        flipmenu[drive][i].callback_data =
 
249
            (ui_callback_data_t)&(cb_data[drive][CBD_NEXT]);
 
250
        if (dir)
 
251
            lib_free(dir);
 
252
        if (image)
 
253
            lib_free(image);
 
254
        i++;
 
255
 
 
256
        memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t));
 
257
        util_fname_split(fliplist_get_prev(drive + 8), &dir, &image);
 
258
        t2 = util_concat(_("Previous: "), image ? image : _("<empty>"), NULL);
 
259
        flipmenu[drive][i].string = t2;
 
260
        flipmenu[drive][i].callback = (ui_callback_t)attach_from_fliplist;
 
261
        cb_data[drive][CBD_PREV].unit = drive + 8;
 
262
        cb_data[drive][CBD_PREV].data = 0;
 
263
        flipmenu[drive][i].callback_data =
 
264
            (ui_callback_data_t)&(cb_data[drive][CBD_PREV]);
 
265
        if (dir)
 
266
            lib_free(dir);
 
267
        if (image)
 
268
            lib_free(image);
 
269
        i++;
 
270
 
 
271
        memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t));
 
272
        util_fname_split(last_attached_images[drive], &dir, &image);
 
273
        t3 = util_concat(_("Add: "), image, NULL);
 
274
        flipmenu[drive][i].string = t3;
 
275
        flipmenu[drive][i].callback = (ui_callback_t)add2fliplist2;
 
276
        cb_data[drive][CBD_ADD].unit = drive + 8;
 
277
        cb_data[drive][CBD_ADD].data = (long) last_attached_images[drive];
 
278
        flipmenu[drive][i].callback_data =
 
279
            (ui_callback_data_t)&(cb_data[drive][CBD_ADD]);
 
280
        if (dir)
 
281
            lib_free(dir);
 
282
        if (image)
 
283
            lib_free(image);
 
284
        i++;
 
285
 
 
286
        memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t));
 
287
        util_fname_split(last_attached_images[drive], &dir, &image);
 
288
        t4 = util_concat(_("Remove: "), image, NULL);
 
289
        flipmenu[drive][i].string = t4;
 
290
        flipmenu[drive][i].callback = (ui_callback_t)remove_from_fliplist2;
 
291
        cb_data[drive][CBD_REMOVE].unit = drive + 8;
 
292
        cb_data[drive][CBD_REMOVE].data = (long) last_attached_images[drive];
 
293
        flipmenu[drive][i].callback_data =
 
294
            (ui_callback_data_t)&(cb_data[drive][CBD_REMOVE]);
 
295
        if (dir)
 
296
            lib_free(dir);
 
297
        if (image)
 
298
            lib_free(image);
 
299
        i++;
 
300
 
 
301
        memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t));
 
302
        flipmenu[drive][i].string = "--";
 
303
        i++;
 
304
 
 
305
        /* Now collect current fliplist */
 
306
        fl_iterator = fliplist_init_iterate(drive + 8);
 
307
        fliplist_start = i;
 
308
        while (fl_iterator) {
 
309
            memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t));
 
310
            util_fname_split(fliplist_get_image(fl_iterator), &dir, &image);
 
311
            flipmenu[drive][i].string = util_concat(NO_TRANS, image, NULL);
 
312
            flipmenu[drive][i].callback =
 
313
                (ui_callback_t)attach_from_fliplist2;
 
314
            flipmenu[drive][i].callback_data =
 
315
                (ui_callback_data_t)fl_iterator;
 
316
 
 
317
            fl_iterator = fliplist_next_iterate(drive + 8);
 
318
            if (dir)
 
319
                lib_free(dir);
 
320
            if (image)
 
321
                lib_free(image);
 
322
            i++;
 
323
            if (i >= (FLIPLIST_MENU_LIMIT - 1)) {
 
324
                /* the end delimitor must fit */
 
325
                log_warning(LOG_DEFAULT,
 
326
                            "Number of fliplist menu entries exceeded."
 
327
                            "Cutting after %d entries.", i);
 
328
                break;
 
329
            }
 
330
        }
 
331
 
 
332
    update_menu:
 
333
        /* make sure the menu is well terminated */
 
334
        memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t));
 
335
 
 
336
        menuname = lib_msprintf("LeftDrive%iMenu%i", drive + 8, name_count);
 
337
 
 
338
#ifdef USE_GNOMEUI
 
339
        ui_destroy_drive_menu(drive);
 
340
        ui_set_drive_menu(drive, ui_menu_create(menuname,
 
341
                                                flipmenu[drive], NULL));
 
342
#else
 
343
        /* ugly ... */
 
344
        if (drive == 0) {
 
345
            ui_destroy_drive8_menu();
 
346
            /* FIXME: Make sure the widget is really destroyed! */
 
347
            ui_set_drive8_menu(ui_menu_create(menuname /*"LeftDrive8Menu"*/,
 
348
                                              flipmenu[drive], NULL));
 
349
        } else {
 
350
            ui_destroy_drive9_menu();
 
351
            /* FIXME: Make sure the widget is really destroyed! */
 
352
            ui_set_drive9_menu(ui_menu_create(menuname /*"LeftDrive9Menu"*/,
 
353
                                              flipmenu[drive], NULL));
 
354
        }
 
355
#endif
 
356
 
 
357
        lib_free(menuname);
 
358
 
 
359
        if (t0)
 
360
            lib_free(t0);
 
361
        if (t1)
 
362
            lib_free(t1);
 
363
        if (t2)
 
364
            lib_free(t2);
 
365
        if (t3)
 
366
            lib_free(t3);
 
367
        if (t4)
 
368
            lib_free(t4);
 
369
        if (t5)
 
370
            lib_free(t5);
 
371
        while (fliplist_start < i) {
 
372
            if (flipmenu[drive][fliplist_start].string)
 
373
                lib_free(flipmenu[drive][fliplist_start].string);
 
374
            fliplist_start++;
 
375
        }
 
376
    }
 
377
}
 
378
 
 
379
void uifliplist_shutdown(void)
 
380
{
 
381
    lib_free(load_save_fliplist_last_dir);
 
382
}
 
383