void uifliplist_update_menus(int from_unit, int to_unit) { /* Yick, allocate dynamically */ static ui_menu_entry_t flipmenu[NUM_DRIVES][FLIPLIST_MENU_LIMIT]; static struct cb_data_t cb_data[NUM_DRIVES][sizeof(cbd_enum_t)]; char *image = NULL, *t0 = NULL, *t1 = NULL, *t2 = NULL, *t3 = NULL; char *t4 = NULL, *t5 = NULL; void *fl_iterator; int i, drive, true_emu, fliplist_start = 0; ui_callback_t callback = NULL; resources_get_int("DriveTrueEmulation", &true_emu); for (drive = from_unit - 8; (drive <= to_unit - 8) && (drive < NUM_DRIVES); drive++) { i = 0; t0 = t1 = t2 = t3 = t4 = t5 = NULL; memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t)); t0 = lib_msprintf(_("Attach #%d"), drive + 8); flipmenu[drive][i].string = t0; flipmenu[drive][i].type = UI_MENU_TYPE_NORMAL; flipmenu[drive][i].callback = (ui_callback_t)attach_disk; flipmenu[drive][i].callback_data = (ui_callback_data_t)(long)(drive + 8); i++; memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t)); t5 = lib_msprintf(_("Detach #%d"), drive + 8); flipmenu[drive][i].string = t5; flipmenu[drive][i].type = UI_MENU_TYPE_NORMAL; flipmenu[drive][i].callback = (ui_callback_t)detach_disk; flipmenu[drive][i].callback_data = (ui_callback_data_t)(long)(drive + 8); i++; /* drivesettings */ memcpy(&flipmenu[drive][i], (const char *)ui_drive_options_submenu, sizeof(ui_menu_entry_t)); i++; /* Write protext UI controll */ memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t)); flipmenu[drive][i].string = _("Read-only"); flipmenu[drive][i].type = UI_MENU_TYPE_TICK; switch (drive) { case 0: callback = (ui_callback_t)toggle_AttachDevice8Readonly; break; case 1: callback = (ui_callback_t)toggle_AttachDevice9Readonly; break; case 2: callback = (ui_callback_t)toggle_AttachDevice10Readonly; break; case 3: callback = (ui_callback_t)toggle_AttachDevice11Readonly; break; } flipmenu[drive][i].callback = callback; i++; fliplist_start = i; /* if we take the goto don't free anything */ /* don't update menu deeply when drive has not been enabled or nothing has been attached */ if (true_emu) { if (!((1 << drive) & enabled_drives)) { goto update_menu; } } else { if (drive_get_disk_drive_type(drive) == DRIVE_TYPE_NONE) { goto update_menu; } } memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t)); flipmenu[drive][i].string = "--"; flipmenu[drive][i].type = UI_MENU_TYPE_SEPARATOR; i++; memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t)); util_fname_split(fliplist_get_next(drive + 8), NULL, &image); if (image) { t1 = util_concat(_("Next: "), image, NULL); } else { t1 = util_concat(_("Next: "), "<", _("empty"), ">", NULL); } flipmenu[drive][i].string = t1; flipmenu[drive][i].type = UI_MENU_TYPE_NORMAL; flipmenu[drive][i].callback = (ui_callback_t)attach_from_fliplist; cb_data[drive][CBD_NEXT].unit = drive + 8; cb_data[drive][CBD_NEXT].data = 1; flipmenu[drive][i].callback_data = (ui_callback_data_t)&(cb_data[drive][CBD_NEXT]); lib_free(image); image = NULL; i++; memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t)); util_fname_split(fliplist_get_prev(drive + 8), NULL, &image); if (image) { t2 = util_concat(_("Previous: "), image, NULL); } else { t2 = util_concat(_("Previous: "), "<", _("empty"), ">", NULL); } flipmenu[drive][i].string = t2; flipmenu[drive][i].type = UI_MENU_TYPE_NORMAL; flipmenu[drive][i].callback = (ui_callback_t)attach_from_fliplist; cb_data[drive][CBD_PREV].unit = drive + 8; cb_data[drive][CBD_PREV].data = 0; flipmenu[drive][i].callback_data = (ui_callback_data_t)&(cb_data[drive][CBD_PREV]); lib_free(image); image = NULL; i++; memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t)); util_fname_split(last_attached_images[drive], NULL, &image); if (image[0]) { t3 = util_concat(_("Add: "), image, NULL); flipmenu[drive][i].string = t3; flipmenu[drive][i].type = UI_MENU_TYPE_NORMAL; flipmenu[drive][i].callback = (ui_callback_t)add2fliplist2; cb_data[drive][CBD_ADD].unit = drive + 8; cb_data[drive][CBD_ADD].data = (long) last_attached_images[drive]; flipmenu[drive][i].callback_data = (ui_callback_data_t)&(cb_data[drive][CBD_ADD]); i++; } lib_free(image); image = NULL; memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t)); util_fname_split(last_attached_images[drive], NULL, &image); if (image[0]) { t4 = util_concat(_("Remove: "), image, NULL); flipmenu[drive][i].string = t4; flipmenu[drive][i].type = UI_MENU_TYPE_NORMAL; flipmenu[drive][i].callback = (ui_callback_t)remove_from_fliplist2; cb_data[drive][CBD_REMOVE].unit = drive + 8; cb_data[drive][CBD_REMOVE].data = (long) last_attached_images[drive]; flipmenu[drive][i].callback_data = (ui_callback_data_t)&(cb_data[drive][CBD_REMOVE]); i++; } lib_free(image); image = NULL; memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t)); flipmenu[drive][i].string = "--"; flipmenu[drive][i].type = UI_MENU_TYPE_SEPARATOR; i++; /* Now collect current fliplist */ fl_iterator = fliplist_init_iterate(drive + 8); fliplist_start = i; while (fl_iterator) { memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t)); util_fname_split(fliplist_get_image(fl_iterator), NULL, &image); flipmenu[drive][i].string = util_concat(NO_TRANS, image, NULL); flipmenu[drive][i].type = UI_MENU_TYPE_NORMAL; flipmenu[drive][i].callback = (ui_callback_t)attach_from_fliplist2; flipmenu[drive][i].callback_data = (ui_callback_data_t)fl_iterator; fl_iterator = fliplist_next_iterate(drive + 8); lib_free(image); image = NULL; i++; if (i >= (FLIPLIST_MENU_LIMIT - 1)) { /* the end delimitor must fit */ log_warning(LOG_DEFAULT, "Number of fliplist menu entries exceeded. Cutting after %d entries.", i); break; } } update_menu: /* make sure the menu is well terminated */ memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t)); ui_destroy_drive_menu(drive); ui_set_drive_menu(drive, flipmenu[drive]); lib_free(t0); lib_free(t1); lib_free(t2); lib_free(t3); lib_free(t4); lib_free(t5); while (fliplist_start < i) { lib_free(flipmenu[drive][fliplist_start].string); flipmenu[drive][fliplist_start].string = NULL; fliplist_start++; } } /* Update the checkmarks */ ui_menu_update_all(); }
void uifliplist_update_menus(int from_unit, int to_unit) { /* Yick, allocate dynamically */ static ui_menu_entry_t flipmenu[NUM_DRIVES][FLIPLIST_MENU_LIMIT]; static struct cb_data_t cb_data[NUM_DRIVES][sizeof(cbd_enum_t)]; char *image = NULL, *t0 = NULL, *t1 = NULL, *t2 = NULL, *t3 = NULL; char *t4 = NULL, *t5 = NULL, *dir; void *fl_iterator; int i, drive, true_emu, fliplist_start = 0; static int name_count = 0; char *menuname; resources_get_int("DriveTrueEmulation", &true_emu); for (drive = from_unit - 8; (drive <= to_unit - 8) && (drive < NUM_DRIVES); drive++) { i = 0; t0 = t1 = t2 = t3 = t4 = t5 = NULL; memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t)); t0 = lib_msprintf(_("Attach #%d"), drive + 8); flipmenu[drive][i].string = t0; flipmenu[drive][i].callback = (ui_callback_t)attach_disk; flipmenu[drive][i].callback_data = (ui_callback_data_t)(drive + 8); i++; memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t)); t5 = lib_msprintf(_("Detach #%d"), drive + 8); flipmenu[drive][i].string = t5; flipmenu[drive][i].callback = (ui_callback_t)detach_disk; flipmenu[drive][i].callback_data = (ui_callback_data_t)(drive + 8); i++; #ifdef USE_GNOMEUI /* drivesettings */ /* this won't work so far for Xaw, because the checkmarks aren't updated when a menu is destroyed, as the flipmenu is dynamically regenerated; The Gnome code is already fixed. */ memcpy(&flipmenu[drive][i], (const char *)ui_drive_options_submenu, sizeof(ui_menu_entry_t)); i++; /* Write protext UI controll */ memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t)); flipmenu[drive][i].string = _("*Write Protect"); if (drive == 0) flipmenu[drive][i].callback = G_CALLBACK(toggle_AttachDevice8Readonly); else flipmenu[drive][i].callback = G_CALLBACK(toggle_AttachDevice9Readonly); i++; #endif fliplist_start = i; /* if we take the goto don't free anythin */ /* don't update menu deeply when drive has not been enabled or nothing has been attached */ if (true_emu) { if (!((1 << drive) & enabled_drives)) goto update_menu; } else { if (strcmp(last_attached_images[drive], "") == 0) goto update_menu; } memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t)); flipmenu[drive][i].string = "--"; i++; memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t)); util_fname_split(fliplist_get_next(drive + 8), &dir, &image); t1 = util_concat(_("Next: "), image ? image : _("<empty>"), NULL); flipmenu[drive][i].string = t1; flipmenu[drive][i].callback = (ui_callback_t)attach_from_fliplist; cb_data[drive][CBD_NEXT].unit = drive + 8; cb_data[drive][CBD_NEXT].data = 1; flipmenu[drive][i].callback_data = (ui_callback_data_t)&(cb_data[drive][CBD_NEXT]); if (dir) lib_free(dir); if (image) lib_free(image); i++; memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t)); util_fname_split(fliplist_get_prev(drive + 8), &dir, &image); t2 = util_concat(_("Previous: "), image ? image : _("<empty>"), NULL); flipmenu[drive][i].string = t2; flipmenu[drive][i].callback = (ui_callback_t)attach_from_fliplist; cb_data[drive][CBD_PREV].unit = drive + 8; cb_data[drive][CBD_PREV].data = 0; flipmenu[drive][i].callback_data = (ui_callback_data_t)&(cb_data[drive][CBD_PREV]); if (dir) lib_free(dir); if (image) lib_free(image); i++; memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t)); util_fname_split(last_attached_images[drive], &dir, &image); t3 = util_concat(_("Add: "), image, NULL); flipmenu[drive][i].string = t3; flipmenu[drive][i].callback = (ui_callback_t)add2fliplist2; cb_data[drive][CBD_ADD].unit = drive + 8; cb_data[drive][CBD_ADD].data = (long) last_attached_images[drive]; flipmenu[drive][i].callback_data = (ui_callback_data_t)&(cb_data[drive][CBD_ADD]); if (dir) lib_free(dir); if (image) lib_free(image); i++; memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t)); util_fname_split(last_attached_images[drive], &dir, &image); t4 = util_concat(_("Remove: "), image, NULL); flipmenu[drive][i].string = t4; flipmenu[drive][i].callback = (ui_callback_t)remove_from_fliplist2; cb_data[drive][CBD_REMOVE].unit = drive + 8; cb_data[drive][CBD_REMOVE].data = (long) last_attached_images[drive]; flipmenu[drive][i].callback_data = (ui_callback_data_t)&(cb_data[drive][CBD_REMOVE]); if (dir) lib_free(dir); if (image) lib_free(image); i++; memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t)); flipmenu[drive][i].string = "--"; i++; /* Now collect current fliplist */ fl_iterator = fliplist_init_iterate(drive + 8); fliplist_start = i; while (fl_iterator) { memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t)); util_fname_split(fliplist_get_image(fl_iterator), &dir, &image); flipmenu[drive][i].string = util_concat(NO_TRANS, image, NULL); flipmenu[drive][i].callback = (ui_callback_t)attach_from_fliplist2; flipmenu[drive][i].callback_data = (ui_callback_data_t)fl_iterator; fl_iterator = fliplist_next_iterate(drive + 8); if (dir) lib_free(dir); if (image) lib_free(image); i++; if (i >= (FLIPLIST_MENU_LIMIT - 1)) { /* the end delimitor must fit */ log_warning(LOG_DEFAULT, "Number of fliplist menu entries exceeded." "Cutting after %d entries.", i); break; } } update_menu: /* make sure the menu is well terminated */ memset(&(flipmenu[drive][i]), 0, sizeof(ui_menu_entry_t)); menuname = lib_msprintf("LeftDrive%iMenu%i", drive + 8, name_count); #ifdef USE_GNOMEUI ui_destroy_drive_menu(drive); ui_set_drive_menu(drive, flipmenu[drive]); #else /* ugly ... */ if (drive == 0) { ui_destroy_drive8_menu(); /* FIXME: Make sure the widget is really destroyed! */ ui_set_drive8_menu(ui_menu_create(menuname /*"LeftDrive8Menu"*/, flipmenu[drive], NULL)); } else { ui_destroy_drive9_menu(); /* FIXME: Make sure the widget is really destroyed! */ ui_set_drive9_menu(ui_menu_create(menuname /*"LeftDrive9Menu"*/, flipmenu[drive], NULL)); } #endif lib_free(menuname); if (t0) lib_free(t0); if (t1) lib_free(t1); if (t2) lib_free(t2); if (t3) lib_free(t3); if (t4) lib_free(t4); if (t5) lib_free(t5); while (fliplist_start < i) { if (flipmenu[drive][fliplist_start].string) lib_free(flipmenu[drive][fliplist_start].string); fliplist_start++; } } }
/** \brief Fill in a menu with controls for fliplist control. * * Fliplist controls are placed at the end of a menu, after a * separator. Any previously-existing fliplist controls within the * menu will be removed. * * \param menu The menu to be edited. * \param unit The drive unit (8-11) that this menu * will control. * \param separator_count The number of menu separators in the * part of the menu that does not involve * the fliplist. */ void ui_populate_fliplist_menu(GtkWidget *menu, int unit, int separator_count) { const char *fliplist_string; GtkWidget *menu_item; GList *children = gtk_container_get_children(GTK_CONTAINER(menu)); GList *child_iter = g_list_first(children); int separators_so_far = 0; while (child_iter) { if (GTK_IS_SEPARATOR_MENU_ITEM(child_iter->data)) { ++separators_so_far; } if (separators_so_far > separator_count) { gtk_container_remove(GTK_CONTAINER(menu), child_iter->data); } child_iter = child_iter->next; } g_list_free(children); /* Fliplist controls in GTK2/GNOME are next/previous and then the * full list of entries within it. For GTK3 we only show these if * the fliplist isn't empty for this drive. */ /* TODO: Add/Remove current image to/from fliplist should really * be here too. */ fliplist_string = fliplist_get_next(unit); if (fliplist_string) { char buf[128]; char *basename = NULL; fliplist_t fliplist_iterator; int index; gtk_container_add(GTK_CONTAINER(menu), gtk_separator_menu_item_new()); util_fname_split(fliplist_string, NULL, &basename); snprintf(buf, 128, "Next: %s", basename ? basename : fliplist_string); lib_free(basename); basename = NULL; buf[127] = 0; menu_item = gtk_menu_item_new_with_label(buf); g_signal_connect(menu_item, "activate", G_CALLBACK(ui_fliplist_next_cb), GINT_TO_POINTER(unit)); gtk_container_add(GTK_CONTAINER(menu), menu_item); fliplist_string = fliplist_get_prev(unit); if (fliplist_string) { util_fname_split(fliplist_string, NULL, &basename); snprintf(buf, 128, "Previous: %s", basename ? basename : fliplist_string); lib_free(basename); basename = NULL; buf[127] = 0; menu_item = gtk_menu_item_new_with_label(buf); g_signal_connect(menu_item, "activate", G_CALLBACK(ui_fliplist_prev_cb), GINT_TO_POINTER(unit)); gtk_container_add(GTK_CONTAINER(menu), menu_item); } gtk_container_add(GTK_CONTAINER(menu), gtk_separator_menu_item_new()); fliplist_iterator = fliplist_init_iterate(unit); index = 0; while (fliplist_iterator) { fliplist_string = fliplist_get_image(fliplist_iterator); util_fname_split(fliplist_string, NULL, &basename); menu_item = gtk_menu_item_new_with_label(basename ? basename : fliplist_string); lib_free(basename); basename = NULL; g_signal_connect(menu_item, "activate", G_CALLBACK(ui_fliplist_select_cb), GINT_TO_POINTER(unit+(index << 8))); gtk_container_add(GTK_CONTAINER(menu), menu_item); fliplist_iterator = fliplist_next_iterate(unit); ++index; } } }