int main (int argc, char **argv) { gint lastentry = 0; guint32 timestamp; const gchar* startup_id = g_getenv ("DESKTOP_STARTUP_ID"); //printf ("startup id is %s\n", startup_id); if (startup_id && (startup_id[0] != '\0')) { gchar **results = g_strsplit (startup_id, "_TIME", 0); while (results[lastentry] != NULL) lastentry++; timestamp = (guint32) g_strtod (results[lastentry - 1], NULL); g_strfreev (results); } else timestamp = GDK_CURRENT_TIME; gdk_init (&argc, &argv); run_dialog (NULL, NULL, timestamp); gdk_notify_startup_complete (); return 0; }
static void on_file_save_button_clicked(GtkButton *button, PropertyDialogElements *e) { #ifdef G_OS_WIN32 gchar *path = win32_show_project_open_dialog(e->dialog, _("Choose Project Filename"), gtk_entry_get_text(GTK_ENTRY(e->file_name)), TRUE, TRUE); if (path != NULL) { gtk_entry_set_text(GTK_ENTRY(e->file_name), path); g_free(path); } #else GtkWidget *dialog; /* initialise the dialog */ dialog = gtk_file_chooser_dialog_new(_("Choose Project Filename"), NULL, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); gtk_widget_set_name(dialog, "GeanyDialogProject"); gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE); gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), TRUE); gtk_window_set_type_hint(GTK_WINDOW(dialog), GDK_WINDOW_TYPE_HINT_DIALOG); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); run_dialog(dialog, e->file_name); #endif }
int main(int argc, char **argv) { set_is_chs(); exec_setup_scripts(); init_TableDir(); load_settings(); load_gtab_list(FALSE); gtk_init(&argc, &argv); #if HIME_i18n_message bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); textdomain(GETTEXT_PACKAGE); #endif g_object_get(gtk_settings_get_default(), "gtk-alternative-button-order", &button_order, NULL); #if 0 // once you invoke hime-setup, the left-right buton tips is disabled save_hime_conf_int(LEFT_RIGHT_BUTTON_TIPS, 0); #endif run_dialog(); gtk_main(); return 0; }
int MCA_folder(MCExecPoint& ep, const char *p_title, const char *p_prompt, const char *p_initial, unsigned int p_options) { if (!MCModeMakeLocalWindows()) { char *t_resolved_initial_path = MCS_resolvepath(p_initial); MCRemoteFolderDialog(ep, p_title, p_prompt, t_resolved_initial_path); if (t_resolved_initial_path != NULL) free(t_resolved_initial_path); return 0; } ////////// GtkWidget *dialog ; dialog = create_open_dialog( p_title == NULL ? p_prompt : p_title, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ); if ( p_initial != NULL ) gtk_file_chooser_set_current_folder ( GTK_FILE_CHOOSER ( dialog ) , MCS_resolvepath(p_initial) ); run_dialog ( dialog, ep) ; close_dialog ( dialog ) ; return (1); }
static void list_box_row_activated (GtkListBox *listbox, GtkListBoxRow *row, CcDateTimePanel *self) { CcDateTimePanelPrivate *priv = self->priv; gchar *widget_name, *found; widget_name = g_strdup (gtk_buildable_get_name (GTK_BUILDABLE (row))); if (!widget_name) return; gtk_list_box_select_row (listbox, NULL); if (!g_strcmp0 (widget_name, "auto-datetime-row")) { toggle_switch (W ("network_time_switch")); } else if (!g_strcmp0 (widget_name, "auto-timezone-row")) { toggle_switch (W ("auto_timezone_switch")); } else if ((found = g_strrstr (widget_name, "button"))) { /* replace "button" with "dialog" */ memcpy (found, "dialog", 6); run_dialog (self, widget_name); } g_free (widget_name); }
static void on_get_secret_configuration_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { ChangePassphraseData *data = user_data; GVariantIter iter; const gchar *type; GVariant *details; GVariant *configuration = NULL; GError *error; configuration = NULL; error = NULL; if (!udisks_block_call_get_secret_configuration_finish (UDISKS_BLOCK (source_object), &configuration, res, &error)) { gdu_utils_show_error (GTK_WINDOW (data->window), _("Error retrieving configuration data"), error); g_error_free (error); change_passphrase_data_free (data); goto out; } g_variant_iter_init (&iter, configuration); while (g_variant_iter_next (&iter, "(&s@a{sv})", &type, &details)) { if (g_strcmp0 (type, "crypttab") == 0) { const gchar *passphrase_contents; data->crypttab_details = g_variant_ref (details); if (g_variant_lookup (details, "passphrase-contents", "^&ay", &passphrase_contents)) { gtk_entry_set_text (GTK_ENTRY (data->existing_passphrase_entry), passphrase_contents); /* Don't focus on the "Existing passphrase" entry */ gtk_editable_select_region (GTK_EDITABLE (data->existing_passphrase_entry), 0, 0); gtk_widget_grab_focus (data->passphrase_entry); run_dialog (data); goto out; } } } gdu_utils_show_error (GTK_WINDOW (data->window), _("/etc/crypttab configuration data is malformed"), NULL); change_passphrase_data_free (data); out: if (configuration != NULL) g_variant_unref (configuration); }
int MCA_file_with_types(MCExecPoint& ep, const char *p_title, const char *p_prompt, char * const p_types[], uint4 p_type_count, const char *p_initial, unsigned int p_options) { if (!MCModeMakeLocalWindows()) { bool t_plural = (p_options & MCA_OPTION_PLURAL) != 0; char *t_resolved_path = MCS_resolvepath(p_initial); char **t_rtypes; if (types_to_remote_types(p_types, p_type_count, t_rtypes)) { MCRemoteFileDialog(ep, p_title, p_prompt, t_rtypes, p_type_count * 2, NULL, t_resolved_path, false, t_plural); MCCStringArrayFree(t_rtypes, p_type_count * 2); } delete t_resolved_path; return 1; } ////////// GtkWidget *dialog ; // Create the file dialog with the correct prompt dialog = create_open_dialog ( p_title == NULL ? p_prompt : p_title, GTK_FILE_CHOOSER_ACTION_OPEN ); // If we have any filters, add them. if ( p_type_count > 0 ) add_dialog_filters ( dialog, p_types , p_type_count ); if ( p_options & MCA_OPTION_PLURAL ) gtk_file_chooser_set_select_multiple ( GTK_FILE_CHOOSER ( dialog ) ,true ); // If we have an initial file/folder then set it. set_initial_file ( dialog, p_initial, G_last_opened_path ) ; // Run the dialog ... this will be replaced with our own loop which will call the REV event handler too. run_dialog ( dialog, ep) ; MCresult -> clear(); MCresult -> copysvalue(get_current_filter_name ( dialog ) ); if (G_last_opened_path != nil) g_free(G_last_opened_path); G_last_opened_path = gtk_file_chooser_get_current_folder ( GTK_FILE_CHOOSER ( dialog ) ) ; // All done, close the dialog. close_dialog ( dialog ) ; return(1); }
static void finish_prepare_screenshot (char *initial_uri, GdkWindow *window, GdkRectangle *rectangle) { ScreenshotDialog *dialog; gboolean include_mask = (!take_window_shot && !take_area_shot); /* always disable window border for full-desktop or selected-area screenshots */ if (!take_window_shot) screenshot = screenshot_get_pixbuf (window, rectangle, include_pointer, FALSE, include_mask); else { screenshot = screenshot_get_pixbuf (window, rectangle, include_pointer, include_border, include_mask); switch (border_effect[0]) { case 's': /* shadow */ screenshot_add_shadow (&screenshot); break; case 'b': /* border */ screenshot_add_border (&screenshot); break; case 'n': /* none */ default: break; } } /* release now the lock, it was acquired when we were finding the window */ screenshot_release_lock (); if (screenshot == NULL) { screenshot_show_error_dialog (NULL, _("Unable to take a screenshot of the current window"), NULL); exit (1); } play_sound_effect (window); dialog = screenshot_dialog_new (screenshot, initial_uri, take_window_shot); g_free (initial_uri); screenshot_save_start (screenshot, save_done_notification, dialog); run_dialog (dialog); }
LRESULT menu_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { switch (msg) { case WM_INITMENUPOPUP: { HMENU hmenu = (HMENU)wparam; struct menu_item* item; MENUINFO mi; mi.cbSize = sizeof(mi); mi.fMask = MIM_MENUDATA; GetMenuInfo(hmenu, &mi); item = (struct menu_item*)mi.dwMenuData; if (item) fill_menu(item); return 0; } break; case WM_MENUCOMMAND: { HMENU hmenu = (HMENU)lparam; struct menu_item* item; MENUITEMINFOW mii; mii.cbSize = sizeof(mii); mii.fMask = MIIM_DATA|MIIM_ID; GetMenuItemInfoW(hmenu, wparam, TRUE, &mii); item = (struct menu_item*)mii.dwItemData; if (item) exec_item(item); else if (mii.wID == MENU_ID_RUN) run_dialog(); destroy_menus(); return 0; } } return DefWindowProcW(hwnd, msg, wparam, lparam); }
enum thing layer_to_board_object_type(struct world *mzx_world) { int dialog_result; struct element *elements[3]; struct dialog di; int object_type = 0; const char *radio_button_strings[] = { "Custom Block", "Custom Floor", "Text" }; // Prevent previous keys from carrying through. force_release_all_keys(); set_context(CTX_BLOCK_TYPE); elements[0] = construct_radio_button(6, 4, radio_button_strings, 3, 12, &object_type); elements[1] = construct_button(5, 11, "OK", 0); elements[2] = construct_button(15, 11, "Cancel", -1); construct_dialog(&di, "Object type", 26, 4, 28, 14, elements, 3, 0); dialog_result = run_dialog(mzx_world, &di); destruct_dialog(&di); pop_context(); // Prevent UI keys from carrying through. force_release_all_keys(); if(dialog_result) return NO_ID; switch(object_type) { case 0: return CUSTOM_BLOCK; case 1: return CUSTOM_FLOOR; case 2: return __TEXT; } return NO_ID; }
static gboolean gwget_ask_download_playlist(GwgetData *gwgetdata) { gchar *msg; gint response; if (g_str_has_suffix(gwgetdata->filename, ".m3u") || g_str_has_suffix(gwgetdata->filename, ".M3U")) { msg = g_strdup_printf( _("The file %s is an MP3 playlist.\nDownload the files that it contains?"), gwgetdata->filename); response = run_dialog(_("Download files in MP3 playlist?"), _(msg), _("No"), _("Yes")); g_free(msg); if (response == GTK_RESPONSE_OK) return TRUE; } return FALSE; }
/** * main: * @argc: * @argv[]: Sent to gtk_init * * Prompt for GnuPG and SSH. Communicates using stdin/stdout. Communication data * is in ini-file structures * * Returns: 0 */ int main (int argc, char *argv[]) { GError *err = NULL; gchar *data; gboolean ret; gsize length; /* Exit on HUP signal */ signal(SIGINT, hup_handler); prepare_logging (); egg_libgcrypt_initialize (); input_data = g_key_file_new (); output_data = g_key_file_new (); gtk_init (&argc, &argv); #ifdef HAVE_LOCALE_H /* internationalisation */ setlocale (LC_ALL, ""); #endif #ifdef HAVE_GETTEXT bindtextdomain (GETTEXT_PACKAGE, MATELOCALEDIR); textdomain (GETTEXT_PACKAGE); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); #endif data = read_all_input (); g_assert (data); if (!data[0]) fatal ("no auth dialog instructions", NULL); ret = g_key_file_load_from_data (input_data, data, strlen (data), G_KEY_FILE_NONE, &err); g_free (data); if (!ret) fatal ("couldn't parse auth dialog instructions", egg_error_message (err)); run_dialog (); /* Cleanup after any key */ if (the_key) { egg_secure_clear (the_key, n_the_key); egg_secure_free (the_key); the_key = NULL; n_the_key = 0; } g_key_file_free (input_data); data = g_key_file_to_data (output_data, &length, &err); g_key_file_free (output_data); if (!data) fatal ("couldn't format auth dialog response: %s", egg_error_message (err)); write_all_output (data, length); g_free (data); return 0; }
void gdu_change_passphrase_dialog_show (GduWindow *window, UDisksObject *object) { ChangePassphraseData *data; data = g_new0 (ChangePassphraseData, 1); data->window = g_object_ref (window); data->object = g_object_ref (object); data->block = udisks_object_get_block (object); g_assert (data->block != NULL); data->encrypted = udisks_object_get_encrypted (object); g_assert (data->encrypted != NULL); data->has_passphrase_in_configuration = has_passphrase_in_configuration (data); data->dialog = GTK_WIDGET (gdu_application_new_widget (gdu_window_get_application (window), "change-passphrase-dialog.ui", "change-passphrase-dialog", &data->builder)); data->infobar_vbox = GTK_WIDGET (gtk_builder_get_object (data->builder, "infobar-vbox")); if (data->has_passphrase_in_configuration) { GtkWidget *infobar; infobar = gdu_utils_create_info_bar (GTK_MESSAGE_INFO, _("Changing the passphrase for this device, will also update the passphrase referenced by the <i>/etc/crypttab</i> file"), NULL); gtk_box_pack_start (GTK_BOX (data->infobar_vbox), infobar, TRUE, TRUE, 0); } data->existing_passphrase_entry = GTK_WIDGET (gtk_builder_get_object (data->builder, "existing-passphrase-entry")); g_signal_connect (data->existing_passphrase_entry, "notify::text", G_CALLBACK (on_property_changed), data); data->passphrase_entry = GTK_WIDGET (gtk_builder_get_object (data->builder, "passphrase-entry")); g_signal_connect (data->passphrase_entry, "notify::text", G_CALLBACK (on_property_changed), data); data->confirm_passphrase_entry = GTK_WIDGET (gtk_builder_get_object (data->builder, "confirm-passphrase-entry")); g_signal_connect (data->confirm_passphrase_entry, "notify::text", G_CALLBACK (on_property_changed), data); data->show_passphrase_checkbutton = GTK_WIDGET (gtk_builder_get_object (data->builder, "show-passphrase-checkbutton")); g_signal_connect (data->show_passphrase_checkbutton, "notify::active", G_CALLBACK (on_property_changed), data); data->passphrase_strengh_box = GTK_WIDGET (gtk_builder_get_object (data->builder, "passphrase-strength-box")); data->passphrase_strengh_widget = gdu_password_strength_widget_new (); gtk_widget_set_tooltip_markup (data->passphrase_strengh_widget, _("The strength of the passphrase")); gtk_box_pack_start (GTK_BOX (data->passphrase_strengh_box), data->passphrase_strengh_widget, TRUE, TRUE, 0); gtk_window_set_transient_for (GTK_WINDOW (data->dialog), GTK_WINDOW (window)); gtk_dialog_set_default_response (GTK_DIALOG (data->dialog), GTK_RESPONSE_OK); populate (data); update (data); /* Retrieve the passphrase from system-level configuration, if applicable */ if (data->has_passphrase_in_configuration) { udisks_block_call_get_secret_configuration (data->block, g_variant_new ("a{sv}", NULL), /* options */ NULL, /* cancellable */ on_get_secret_configuration_cb, data); } else { run_dialog (data); } }
//-------------------------- // // ( ) Copy block // ( ) Copy block (repeated) // ( ) Move block // ( ) Clear block // ( ) Flip block // ( ) Mirror block // ( ) Paint block // ( ) Copy to... // ( ) Copy to... // ( ) Save as MZM // // _OK_ _Cancel_ // //-------------------------- boolean select_block_command(struct world *mzx_world, struct block_info *block, enum editor_mode mode) { int dialog_result; struct element *elements[3]; struct dialog di; int selection = 0; const char *radio_button_strings[] = { "Copy block", "Copy block (repeated)", "Move block", "Clear block", "Flip block", "Mirror block", "Paint block", NULL, NULL, "Save as MZM" }; switch(mode) { default: case EDIT_BOARD: radio_button_strings[7] = "Copy to overlay"; radio_button_strings[8] = "Copy to vlayer"; break; case EDIT_OVERLAY: radio_button_strings[7] = "Copy to board"; radio_button_strings[8] = "Copy to vlayer"; break; case EDIT_VLAYER: radio_button_strings[7] = "Copy to board"; radio_button_strings[8] = "Copy to overlay"; break; } // Prevent previous keys from carrying through. force_release_all_keys(); set_context(CTX_BLOCK_CMD); elements[0] = construct_radio_button(2, 2, radio_button_strings, 10, 21, &selection); elements[1] = construct_button(5, 13, "OK", 0); elements[2] = construct_button(15, 13, "Cancel", -1); construct_dialog(&di, "Choose block command", 26, 3, 29, 16, elements, 3, 0); dialog_result = run_dialog(mzx_world, &di); pop_context(); destruct_dialog(&di); // Prevent UI keys from carrying through. force_release_all_keys(); if(dialog_result) { block->selected = false; return false; } // Translate selection to a real block command. block->selected = true; block->command = BLOCK_CMD_NONE; block->src_mode = mode; block->dest_mode = mode; switch(selection) { case 0: block->command = BLOCK_CMD_COPY; break; case 1: block->command = BLOCK_CMD_COPY_REPEATED; break; case 2: block->command = BLOCK_CMD_MOVE; break; case 3: block->command = BLOCK_CMD_CLEAR; break; case 4: block->command = BLOCK_CMD_FLIP; break; case 5: block->command = BLOCK_CMD_MIRROR; break; case 6: block->command = BLOCK_CMD_PAINT; break; case 7: { block->command = BLOCK_CMD_COPY; switch(mode) { case EDIT_BOARD: block->dest_mode = EDIT_OVERLAY; break; case EDIT_OVERLAY: case EDIT_VLAYER: block->dest_mode = EDIT_BOARD; break; } break; } case 8: { block->command = BLOCK_CMD_COPY; switch(mode) { case EDIT_BOARD: case EDIT_OVERLAY: block->dest_mode = EDIT_VLAYER; break; case EDIT_VLAYER: block->dest_mode = EDIT_OVERLAY; break; } break; } case 9: block->command = BLOCK_CMD_SAVE_MZM; break; } return true; }
char* ui_get_save_filename( const char *title ) { return run_dialog( title, GTK_FILE_CHOOSER_ACTION_SAVE ); }
char* ui_get_open_filename( const char *title ) { return run_dialog( title, GTK_FILE_CHOOSER_ACTION_OPEN ); }
int MCA_ask_file_with_types(MCExecPoint& ep, const char *p_title, const char *p_prompt, char * const p_types[], uint4 p_type_count, const char *p_initial, unsigned int p_options) { if (!MCModeMakeLocalWindows()) { bool t_plural = (p_options & MCA_OPTION_PLURAL) != 0; char *t_resolved_path = MCS_resolvepath(p_initial); char **t_rtypes; if (types_to_remote_types(p_types, p_type_count, t_rtypes)) { MCRemoteFileDialog(ep, p_title, p_prompt, t_rtypes, p_type_count * 2, NULL, t_resolved_path, true, t_plural); MCCStringArrayFree(t_rtypes, p_type_count * 2); } delete t_resolved_path; return 1; } GtkWidget *dialog ; dialog = create_open_dialog( p_title == NULL ? p_prompt : p_title, GTK_FILE_CHOOSER_ACTION_SAVE ); if ( p_type_count > 0 ) add_dialog_filters ( dialog, p_types , p_type_count ); // If we are given an initial if (p_initial != nil) { if (MCS_exists(p_initial, True)) { char *t_path; t_path = MCS_resolvepath(p_initial); gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), t_path); delete t_path; } else { char *t_folder; const char *t_name; if (strchr(p_initial, '/') == NULL) { t_folder = NULL; t_name = p_initial; } else { t_folder = strdup(p_initial); strrchr(t_folder, '/')[0] = '\0'; t_name = strrchr(p_initial, '/') + 1; if (MCS_exists(t_folder, False)) { char *t_new_folder; t_new_folder = MCS_resolvepath(t_folder); delete t_folder; t_folder = t_new_folder; } else t_folder = NULL; } gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), t_folder == NULL ? G_last_saved_path : t_folder); gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), t_name); delete t_folder; } } else { gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), G_last_saved_path); } run_dialog ( dialog, ep) ; MCresult -> clear(); MCresult -> copysvalue(get_current_filter_name ( dialog ) ); if (G_last_saved_path != NULL) g_free(G_last_saved_path); G_last_saved_path = gtk_file_chooser_get_current_folder ( GTK_FILE_CHOOSER ( dialog ) ) ; close_dialog ( dialog ) ; return(1); }
char* ui_get_open_filename( const char *title ) { return run_dialog( title, 0 ); }
static void __check_for_updates(struct world *mzx_world, struct config_info *conf) { int cur_host; char *update_host; bool try_next_host = true; bool ret = false; set_context(CTX_UPDATER); if(conf->update_host_count < 1) { error("No updater hosts defined! Aborting.", 1, 8, 0); goto err_out; } if(!swivel_current_dir(true)) goto err_out; for(cur_host = 0; (cur_host < conf->update_host_count) && try_next_host; cur_host++) { char **list_entries, buffer[LINE_BUF_LEN], *url_base, *value; struct manifest_entry *removed, *replaced, *added, *e; int i = 0, entries = 0, buf_len, result; char update_branch[LINE_BUF_LEN]; const char *version = VERSION; int list_entry_width = 0; enum host_status status; struct host *h = NULL; unsigned int retries; FILE *f; // Acid test: Can we write to this directory? f = fopen_unsafe(UPDATES_TXT, "w+b"); if(!f) { error("Failed to create \"" UPDATES_TXT "\". Check permissions.", 1, 8, 0); goto err_chdir; } update_host = conf->update_hosts[cur_host]; if(!reissue_connection(conf, &h, update_host)) goto err_host_destroy; for(retries = 0; retries < MAX_RETRIES; retries++) { // Grab the file containing the names of the current Stable and Unstable status = host_recv_file(h, "/" UPDATES_TXT, f, "text/plain"); rewind(f); if(status == HOST_SUCCESS) break; if(!reissue_connection(conf, &h, update_host)) goto err_host_destroy; } if(retries == MAX_RETRIES) { snprintf(widget_buf, WIDGET_BUF_LEN, "Failed to download \"" UPDATES_TXT "\" (err=%d).\n", status); widget_buf[WIDGET_BUF_LEN - 1] = 0; error(widget_buf, 1, 8, 0); goto err_host_destroy; } snprintf(update_branch, LINE_BUF_LEN, "Current-%s", conf->update_branch_pin); // Walk this list (of two, hopefully) while(true) { char *m = buffer, *key; value = NULL; // Grab a single line from the manifest if(!fgets(buffer, LINE_BUF_LEN, f)) break; key = strsep(&m, ":\n"); if(!key) break; value = strsep(&m, ":\n"); if(!value) break; if(strcmp(key, update_branch) == 0) break; } fclose(f); unlink(UPDATES_TXT); /* There was no "Current-XXX: Version" found; we cannot proceed with the * update because we cannot compute an update URL below. */ if(!value) { error("Failed to identify applicable update version.", 1, 8, 0); goto err_host_destroy; } /* There's likely to be a space prepended to the version number. * Skip it here. */ if(value[0] == ' ') value++; /* We found the latest update version, but we should check to see if that * matches the version we're already using. The user may choose to receive * "stability" updates for their current major version, or upgrade to the * newest one. */ if(strcmp(value, version) != 0) { struct element *elements[6]; struct dialog di; buf_len = snprintf(widget_buf, WIDGET_BUF_LEN, "A new major version is available (%s)", value); widget_buf[WIDGET_BUF_LEN - 1] = 0; elements[0] = construct_label((55 - buf_len) >> 1, 2, widget_buf); elements[1] = construct_label(2, 4, "You can continue to receive updates for the version\n" "installed (if available), or you can upgrade to the\n" "newest major version (recommended)."); elements[2] = construct_label(2, 8, "If you do not upgrade, this question will be asked\n" "again the next time you run the updater.\n"); elements[3] = construct_button(9, 11, "Upgrade", 0); elements[4] = construct_button(21, 11, "Update Old", 1); elements[5] = construct_button(36, 11, "Cancel", 2); construct_dialog(&di, "New Major Version", 11, 6, 55, 14, elements, 6, 3); result = run_dialog(mzx_world, &di); destruct_dialog(&di); // User pressed Escape, abort all updates if(result < 0 || result == 2) { try_next_host = false; goto err_host_destroy; } // User pressed Upgrade, use new major if(result == 0) version = value; } /* We can now compute a unique URL base for the updater. This will * be composed of a user-selected version and a static platform-archicture * name. */ url_base = cmalloc(LINE_BUF_LEN); snprintf(url_base, LINE_BUF_LEN, "/%s/" PLATFORM, version); debug("Update base URL: %s\n", url_base); /* The call to manifest_get_updates() destroys any existing manifest * file in this directory. Since we still allow user to abort after * this call, and downloading the updates may fail, we copy the * old manifest to a backup location and optionally restore it later. */ if(!backup_original_manifest()) { error("Failed to back up manifest. Check permissions.", 1, 8, 0); try_next_host = false; goto err_free_url_base; } for(retries = 0; retries < MAX_RETRIES; retries++) { bool m_ret; m_hide(); draw_window_box(3, 11, 76, 13, DI_MAIN, DI_DARK, DI_CORNER, 1, 1); write_string("Computing manifest deltas (added, replaced, deleted)..", 13, 12, DI_TEXT, 0); update_screen(); m_ret = manifest_get_updates(h, url_base, &removed, &replaced, &added); clear_screen(32, 7); m_show(); update_screen(); if(m_ret) break; if(!reissue_connection(conf, &h, update_host)) goto err_roll_back_manifest; } if(retries == MAX_RETRIES) { error("Failed to compute update manifests", 1, 8, 0); goto err_roll_back_manifest; } // At this point, we have a successful manifest, so we won't need another host try_next_host = false; if(!removed && !replaced && !added) { struct element *elements[3]; struct dialog di; elements[0] = construct_label(2, 2, "This client is already current."); elements[1] = construct_button(7, 4, "OK", 0); elements[2] = construct_button(13, 4, "Try next host", 1); construct_dialog(&di, "No Updates", 22, 9, 35, 6, elements, 3, 1); result = run_dialog(mzx_world, &di); destruct_dialog(&di); if((result == 1) && (cur_host < conf->update_host_count)) try_next_host = true; goto err_free_update_manifests; } for(e = removed; e; e = e->next, entries++) list_entry_width = MAX(list_entry_width, 2 + (int)strlen(e->name)+1+1); for(e = replaced; e; e = e->next, entries++) list_entry_width = MAX(list_entry_width, 2 + (int)strlen(e->name)+1+1); for(e = added; e; e = e->next, entries++) list_entry_width = MAX(list_entry_width, 2 + (int)strlen(e->name)+1+1); // We don't want the listbox to be too wide list_entry_width = MIN(list_entry_width, 60); list_entries = cmalloc(entries * sizeof(char *)); for(e = removed; e; e = e->next, i++) { list_entries[i] = cmalloc(list_entry_width); snprintf(list_entries[i], list_entry_width, "- %s", e->name); list_entries[i][list_entry_width - 1] = 0; } for(e = replaced; e; e = e->next, i++) { list_entries[i] = cmalloc(list_entry_width); snprintf(list_entries[i], list_entry_width, "* %s", e->name); list_entries[i][list_entry_width - 1] = 0; } for(e = added; e; e = e->next, i++) { list_entries[i] = cmalloc(list_entry_width); snprintf(list_entries[i], list_entry_width, "+ %s", e->name); list_entries[i][list_entry_width - 1] = 0; } draw_window_box(19, 1, 59, 4, DI_MAIN, DI_DARK, DI_CORNER, 1, 1); write_string(" Task Summary ", 33, 1, DI_TITLE, 0); write_string("ESC - Cancel [+] Add [-] Delete", 21, 2, DI_TEXT, 0); write_string("ENTER - Proceed [*] Replace ", 21, 3, DI_TEXT, 0); result = list_menu((const char **)list_entries, list_entry_width, NULL, 0, entries, ((80 - (list_entry_width + 9)) >> 1) + 1, 4); for(i = 0; i < entries; i++) free(list_entries[i]); free(list_entries); clear_screen(32, 7); update_screen(); if(result < 0) goto err_free_update_manifests; /* Defer deletions until we restart; any of these files may still be * in use by this (old) process. Reduce the number of entries by the * number of removed items for the progress meter below. */ for(e = removed; e; e = e->next, entries--) delete_hook(e->name); /* Since the operations for adding and replacing a file are identical, * we modify the replaced list and tack on the added list to the end. * * Either list may be NULL; in the case that `replaced' is NULL, simply * re-assign the `added' pointer. `added' being NULL has no effect. * * Later, we need only free the replaced list (see below). */ if(replaced) { for(e = replaced; e->next; e = e->next) ; e->next = added; } else replaced = added; cancel_update = false; host_set_callbacks(h, NULL, recv_cb, cancel_cb); i = 1; for(e = replaced; e; e = e->next, i++) { for(retries = 0; retries < MAX_RETRIES; retries++) { char name[72]; bool m_ret; if(!check_create_basedir(e->name)) goto err_free_delete_list; final_size = (long)e->size; m_hide(); snprintf(name, 72, "%s (%ldb) [%u/%u]", e->name, final_size, i, entries); meter(name, 0, final_size); update_screen(); m_ret = manifest_entry_download_replace(h, url_base, e, delete_hook); clear_screen(32, 7); m_show(); update_screen(); if(m_ret) break; if(cancel_update) { error("Download was cancelled; update aborted.", 1, 8, 0); goto err_free_delete_list; } if(!reissue_connection(conf, &h, update_host)) goto err_free_delete_list; host_set_callbacks(h, NULL, recv_cb, cancel_cb); } if(retries == MAX_RETRIES) { snprintf(widget_buf, WIDGET_BUF_LEN, "Failed to download \"%s\" (after %d attempts).", e->name, retries); widget_buf[WIDGET_BUF_LEN - 1] = 0; error(widget_buf, 1, 8, 0); goto err_free_delete_list; } } if(delete_list) { f = fopen_unsafe(DELETE_TXT, "wb"); if(!f) { error("Failed to create \"" DELETE_TXT "\". Check permissions.", 1, 8, 0); goto err_free_delete_list; } for(e = delete_list; e; e = e->next) { fprintf(f, "%08x%08x%08x%08x%08x%08x%08x%08x %lu %s\n", e->sha256[0], e->sha256[1], e->sha256[2], e->sha256[3], e->sha256[4], e->sha256[5], e->sha256[6], e->sha256[7], e->size, e->name); } fclose(f); } try_next_host = false; ret = true; err_free_delete_list: manifest_list_free(&delete_list); delete_list = delete_p = NULL; err_free_update_manifests: manifest_list_free(&removed); manifest_list_free(&replaced); err_roll_back_manifest: restore_original_manifest(ret); err_free_url_base: free(url_base); err_host_destroy: host_destroy(h); pop_context(); } //end host for loop err_chdir: swivel_current_dir_back(true); err_out: /* At this point we found updates and we successfully updated * to them. Reload the program with the original argv. */ if(ret) { const void *argv = process_argv; struct element *elements[2]; struct dialog di; elements[0] = construct_label(2, 2, "This client will now attempt to restart itself."); elements[1] = construct_button(23, 4, "OK", 0); construct_dialog(&di, "Update Successful", 14, 9, 51, 6, elements, 2, 1); run_dialog(mzx_world, &di); destruct_dialog(&di); execv(process_argv[0], argv); perror("execv"); error("Attempt to invoke self failed!", 1, 8, 0); return; } }
char* ui_get_save_filename( const char *title ) { return run_dialog( title, 1 ); }