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;
}
Exemple #2
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
}
Exemple #3
0
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;
}
Exemple #4
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);
}
Exemple #7
0
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);
}
Exemple #9
0
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);
}
Exemple #10
0
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;
}
Exemple #11
0
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);
    }
}
Exemple #14
0
//--------------------------
//
// ( ) 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;
}
Exemple #15
0
char*
ui_get_save_filename( const char *title )
{
  return run_dialog( title, GTK_FILE_CHOOSER_ACTION_SAVE );
}
Exemple #16
0
char*
ui_get_open_filename( const char *title )
{
  return run_dialog( title, GTK_FILE_CHOOSER_ACTION_OPEN );
}
Exemple #17
0
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 );
}
Exemple #19
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 );
}