📄 commonapp.cpp
字号:
HXEntry* entry = NULL; gchar* escaped_value_str; entry = (HXEntry*)prefs_iter->data; value = hx_entry_get_value(entry); escaped_value_str = strdup_and_escape(hx_value_get_string(value)); line = g_strdup_printf("%s=%s\n", hx_entry_get_key(entry), escaped_value_str); g_free(escaped_value_str); result = hxcommon_channel_write(chan, line); g_free(line); g_return_if_fail(result); prefs_iter = g_slist_next(prefs_iter); } if(window) { hxwindow_save_preferences(window, chan); } g_io_channel_shutdown(chan, TRUE, &error);}voidhxcommon_load_preferences(HXMainWindow* window){ GIOChannel* chan; const gchar* home; gchar* filename; GIOStatus status; GError* error = NULL; gchar* line; HXValue* value; gboolean override_open_audio_pref = TRUE; gchar* favorite_title = NULL; gint favorite_index_title = -1; enum SectionNameType { HELIX_SECTION = 0, RECENT_URLS_SECTION = 1, PLAYER_SECTION = 2, FAVORITES_SECTION = 3, SIGN_IN_SECTION = 4 } section_name; const gchar* section_labels[] = { "helix", "recent_urls", "player", "favorites", "signin" }; // If no section name, assume helix section section_name = HELIX_SECTION; home = g_get_home_dir(); g_return_if_fail(home != NULL); filename = g_strdup_printf("%s/%s", home, HXPLAYER_RC); chan = g_io_channel_new_file(filename, "r", &error); g_free(filename); if(error) { if(error->code != G_FILE_ERROR_NOENT) { g_warning(error->message); } g_error_free(error); error = NULL; return; } if(!chan) { /* File does not exist */ return; }#ifdef G_OS_UNIX /* Set permissions to readable/writable only by user */ fchmod(g_io_channel_unix_get_fd(chan), S_IREAD | S_IWRITE);#endif /* Force line termination to '\n' only. Otherwise, the '\r' in some of the plugin handler preferences confuse us. */ g_io_channel_set_line_term(chan, "\n", 1); for(;;) { status = g_io_channel_read_line(chan, &line, NULL, NULL, &error); if(error) { g_warning(error->message); g_error_free(error); error = NULL; break; } if(status == G_IO_STATUS_EOF) { break; } else if(status == G_IO_STATUS_AGAIN || !line) { continue; } else if(status != G_IO_STATUS_NORMAL) { g_warning("Error reading config file"); break; } if(line[0] == '[') { gchar* section; gchar* pos; /* We have a new section */ if((pos = strchr(line, ']'))) { guint i; *pos = '\0'; section = line + 1; section_name = HELIX_SECTION; // default to helix for(i = 0; i < sizeof(section_labels) / sizeof(*section_labels); i++) { if(strcmp(section, section_labels[i]) == 0) { section_name = (enum SectionNameType)i; break; } } } } else { // Parse the line gchar* key = line; gchar* value_str = strchr(line, '='); if(key && value_str) { gchar* pos; gchar* unescaped_value_str = NULL; // terminate the key *value_str++ = '\0'; // get rid of the trailing newline on the value pos = strchr(value_str, '\n'); if(pos) { *pos = '\0'; } switch(section_name) { case HELIX_SECTION: /* Add it to the player */ unescaped_value_str = strdup_and_unescape(value_str); value = hx_value_new(HX_VALUE_STRING); hx_value_set_string(value, unescaped_value_str); hx_prefs_set_entry(key, value); hx_value_free(value); g_free(unescaped_value_str); if(strcmp(key, "OpenAudioDeviceOnPlayback") == 0) { override_open_audio_pref = FALSE; } break; case RECENT_URLS_SECTION: if(window) { if(strncmp(key, "url", 3) == 0) { hxwindow_recent_urls_append(window, value_str); } } break; case PLAYER_SECTION: if(window) { GValue value; memset(&value, 0, sizeof(value)); g_value_init(&value, G_TYPE_STRING); g_value_set_string(&value, value_str); hxwindow_set_property(window, key, &value); g_value_unset(&value); } break; case FAVORITES_SECTION: if(window) { const gint favorite_title_len = sizeof("favorite_title") - 1; const gint favorite_url_len = sizeof("favorite_url") - 1; if(strncmp(key, "favorite_title", favorite_title_len) == 0) { gchar* pos; pos = key + favorite_title_len; favorite_index_title = -1; sscanf(pos, "%d", &favorite_index_title); g_free(favorite_title); favorite_title = g_strdup(value_str); } else if(strncmp(key, "favorite_url", sizeof("favorite_url") - 1) == 0) { gint favorite_index_url = -1; gchar* pos; pos = key + favorite_url_len; sscanf(pos, "%d", &favorite_index_url); if(favorite_title && favorite_index_url == favorite_index_title) { hxwindow_favorite_add(window, favorite_title, value_str); g_free(favorite_title); favorite_title = NULL; favorite_index_title = -1; favorite_index_url = -1; } else { g_warning("Parse error reading favorites"); } } else { g_warning("Parse error reading favorites"); } } break;#ifdef HELIX_FEATURE_RP_SIGN_IN case SIGN_IN_SECTION: if(window) { hxwindow_set_sign_in_property(window, key, value_str); } break; #endif default: break; } } } g_free(line); } g_io_channel_shutdown(chan, TRUE, &error); if(override_open_audio_pref) { /* Open the audio device on startup instead of playback. This gives us the ability to read the volume properly on startup */ value = hx_value_new(HX_VALUE_STRING); hx_value_set_string(value, "0"); hx_prefs_set_entry("OpenAudioDeviceOnPlayback", value); hx_value_free(value); }}voidhxcommon_reset_player(void){ gchar* filename; const gchar* home; gtk_main_quit(); // Request that we quit g_hxcommon_app.restart_on_quit = TRUE; g_hxcommon_app.save_preferences = FALSE; home = g_get_home_dir(); filename = g_strdup_printf("%s/%s", home, HXPLAYER_RC); unlink(filename); g_free(filename);}/* main * ==== * These functions support the setup of the app in main(); */static voidparse_command_line(HXCommandLineOptions* cmd, int* pargc, char*** pargv){ /* XXXRGG: This function will mix up the order of arguments. This could conceivably be a problem with some options... */ int c; int option_index = 0; char** argv; int argc; GList* unknown_options = NULL; GList* iter; // XXXRGG: gdb resolves &optind incorrectly. Use a pointer to look // at its value (gdb 5.3.90_2003-08-01-cvs-debian): // int* _optind = &optind;#ifdef _GNU_SOURCE /* suppress errors */ opterr = 0;#endif argv = *pargv; argc = *pargc; /* Command line options */ memset(cmd, 0, sizeof(*cmd)); cmd->run_embedded = FALSE; cmd->command_fd = -1; cmd->callbacks_fd = -1; cmd->is_remote_command = FALSE; cmd->fullscreen = FALSE; cmd->quit_on_done = FALSE; // Location is not set in this function. We set it once gtk // and glib have swallowed the args they want from the command line. cmd->location = NULL; for(;;) {#ifdef _GNU_SOURCE static struct option long_options[] = { /* name has_arg flag val */ { "embedded", 1, 0, 'e' }, // argument is xid { "callbacks", 1, 0, 'c' }, { "remote", 0, 0, 'r' }, { "help", 0, 0, 'h' }, { "fullscreen", 0, 0, 'f' }, { "quit", 0, 0, 'q' }, { "new", 0, 0, 'n' }, { 0, 0, 0, 0 }, }; c = getopt_long(argc, argv, "c:e:fhnqr", long_options, &option_index);#else c = getopt(argc, argv, "c:e:hnr");#endif if(c == -1) { break; } switch(c) { case ':': /* Missing a value for an option */ break; case 'r': /* tbd: implement remote commands */ cmd->is_remote_command = TRUE; break; case 'e': if(!sscanf(optarg, "%d", &cmd->command_fd)) { g_error(_("Invalid arguement to --embedded: %s"), optarg); } cmd->run_embedded = TRUE; break; case 'c': if(!sscanf(optarg, "%d", &cmd->callbacks_fd)) { g_error(_("Invalid arguement to --callbacks: %s"), optarg); } break; case 'h': printf(_( "Usage: hxwindow [OPTION]... [FILE]\n" "\n" " -r, --remote Send a running player a command\n" " -h, --help Display this message\n" " -e, --embedded FD Run player in embedded mode, receive commands on descriptor FD\n" " -c, --callbacks FD Use with --embedded, receive callbacks on descriptor FD\n" " -f, --fullscreen Run the player in fullscreen mode on startup\n" " -n, --new Open in new player (do not reuse a running player\n" " -q, --quit Quit when playback is completed (used in conjunction with a URL\n" "\n" "https://player.helixcommunity.org\n" )); exit(EXIT_SUCCESS); break; case 'f': cmd->fullscreen = TRUE; break; case 'n': cmd->open_in_new_player = TRUE; break; case 'q': cmd->quit_on_done = TRUE; break; case '?': { gchar* option = argv[optind - 1]; unknown_options = g_list_append(unknown_options, option); if(optind < argc) { if(argv[optind][0] != '-') { /* Looks like this option has an argument with it. Add it to our list so that they stay in order*/ optind++; option = argv[optind - 1]; unknown_options = g_list_append(unknown_options, option); } } break; } default: g_assert(FALSE); break; } } /* Update argv/c to point to the remaining options */ argc = 1; iter = unknown_options; while(iter) { argv[argc++] = (char*)iter->data; iter = g_list_next(iter); } while(optind < *pargc) { argv[argc++] = argv[optind++]; } *pargc = argc; g_list_free(unknown_options);}static gbooleanlocate_resources(const char *argv0){ /* Find our resources */ gboolean found = FALSE; gchar* test_file = APP_NAME_SHORT "/logo.png"; gchar* resolved_argv0 = NULL; /* The following if's can be rearranged to change the desired search order */ if(!found) { /* Try $HELIX_LIBS/share */ char* helix_libs = getenv("HELIX_LIBS"); if(helix_libs) { gchar* test_file_path = g_strdup_printf("%s/share/%s", helix_libs, test_file); if(g_file_test(test_file_path, G_FILE_TEST_EXISTS)) { g_hxcommon_app.package_data_dir = g_strdup(helix_libs); g_hxcommon_app.package = g_strdup("share"); found = TRUE; } g_free(test_file_path); } } if(!found) { /* Try the path provided at compilation time */ gchar* package_path = g_strdup_printf("%s/%s/%s", PACKAGE_DATA_DIR, PACKAGE, test_file); if(g_file_test(package_path, G_FILE_TEST_EXISTS)) { g_hxcommon_app.package_data_dir = g_strdup(PACKAGE_DATA_DIR); g_hxcommon_app.package = g_strdup(PACKAGE); found = TRUE; } g_free(package_path); } if(!found) { /* The following functions require argv0 to be an absolute path */ if(g_path_is_absolute(argv0)) { resolved_argv0 = g_strdup(argv0); } else { resolved_argv0 = g_find_program_in_path(argv0); } } #ifdef G_OS_UNIX if(!found) { /* If argv[0] is a symbolic link, resolve it and try that directory */ char* resolved_exec_filename; gchar* resolved_exec_path; gchar* resource_test_filename;#ifdef _GNU_SOURCE /* canonicalize_file_name is more intelligent than realpath, so use it if it's available. */ resolved_exec_filename = canonicalize_file_name(resolved_argv0);#else char buf[PATH_MAX+1] = ""; resolved_exec_filename = realpath(resolved_argv0, buf);#endif if(resolved_exec_filename) { resolved_exec_path = dirname(resolved_exec_filename); resource_test_filename = g_strdup_printf("%s/share/%s", resolved_exec_path, test_file); if(g_file_test(resource_test_filename, G_FILE_TEST_EXISTS))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -