int os_safe_replace(const char *target, const char *from, const char *backup) { wchar_t *wtarget = NULL; wchar_t *wfrom = NULL; wchar_t *wbackup = NULL; int code = -1; if (!target || !from) return -1; if (!os_utf8_to_wcs_ptr(target, 0, &wtarget)) return -1; if (!os_utf8_to_wcs_ptr(from, 0, &wfrom)) goto fail; if (backup && !os_utf8_to_wcs_ptr(backup, 0, &wbackup)) goto fail; if (ReplaceFileW(wtarget, wfrom, wbackup, 0, NULL, NULL)) { code = 0; } else if (GetLastError() == ERROR_FILE_NOT_FOUND) { code = MoveFileExW(wfrom, wtarget, MOVEFILE_REPLACE_EXISTING) ? 0 : -1; } fail: bfree(wtarget); bfree(wfrom); bfree(wbackup); return code; }
os_dir_t os_opendir(const char *path) { struct dstr path_str = {0}; struct os_dir *dir = NULL; WIN32_FIND_DATA wfd; HANDLE handle; wchar_t *w_path; dstr_copy(&path_str, path); dstr_cat(&path_str, "/*.*"); if (os_utf8_to_wcs_ptr(path_str.array, path_str.len, &w_path) > 0) { handle = FindFirstFileW(w_path, &wfd); if (handle != INVALID_HANDLE_VALUE) { dir = bzalloc(sizeof(struct os_dir)); dir->handle = handle; dir->first = true; dir->wfd = wfd; } bfree(w_path); } dstr_free(&path_str); return dir; }
void BrowserManager::Impl::SendKeyClick(int browserIdentifier, const struct obs_key_event *event, bool keyUp) { ExecuteOnBrowser(browserIdentifier, [&](CefRefPtr<CefBrowser> b) { CefKeyEvent e; e.windows_key_code = event->native_vkey; e.native_key_code = 0; e.type = keyUp ? KEYEVENT_KEYUP : KEYEVENT_RAWKEYDOWN; if (event->text) { char16 *characters; os_utf8_to_wcs_ptr(event->text, 0, &characters); if (characters) { e.character = characters[0]; bfree(characters); } } //e.native_key_code = event->native_vkey; e.modifiers = event->modifiers; b->GetHost()->SendKeyEvent(e); if (event->text && !keyUp) { e.type = KEYEVENT_CHAR; // Figure out why this works e.windows_key_code = e.character; e.character = 0; b->GetHost()->SendKeyEvent(e); } }); }
void *os_dlopen(const char *path) { struct dstr dll_name; wchar_t *wpath; wchar_t *wpath_slash; HMODULE h_library = NULL; if (!path) return NULL; dstr_init_copy(&dll_name, path); dstr_replace(&dll_name, "\\", "/"); if (!dstr_find(&dll_name, ".dll")) dstr_cat(&dll_name, ".dll"); os_utf8_to_wcs_ptr(dll_name.array, 0, &wpath); /* to make module dependency issues easier to deal with, allow * dynamically loaded libraries on windows to search for dependent * libraries that are within the library's own directory */ wpath_slash = wcsrchr(wpath, L'/'); if (wpath_slash) { *wpath_slash = 0; SetDllDirectoryW(wpath); *wpath_slash = L'/'; } h_library = LoadLibraryW(wpath); bfree(wpath); dstr_free(&dll_name); if (wpath_slash) SetDllDirectoryW(NULL); if (!h_library) { DWORD error = GetLastError(); char *message = NULL; FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (LPSTR)&message, 0, NULL); blog(LOG_INFO, "LoadLibrary failed for '%s': %s (%lu)", path, message, error); if (message) LocalFree(message); } return h_library; }
int os_copyfile(const char *file_in, const char *file_out) { wchar_t *file_in_utf16 = NULL; wchar_t *file_out_utf16 = NULL; int code = -1; if (!os_utf8_to_wcs_ptr(file_in, 0, &file_in_utf16)) { return -1; } if (!os_utf8_to_wcs_ptr(file_out, 0, &file_out_utf16)) { goto error; } code = CopyFileW(file_in_utf16, file_out_utf16, true) ? 0 : -1; error: bfree(file_in_utf16); bfree(file_out_utf16); return code; }
uint64_t os_get_free_disk_space(const char *dir) { wchar_t *wdir = NULL; if (!os_utf8_to_wcs_ptr(dir, 0, &wdir)) return 0; ULARGE_INTEGER free; bool success = !!GetDiskFreeSpaceExW(wdir, &free, NULL, NULL); bfree(wdir); return success ? free.QuadPart : 0; }
size_t os_utf8_to_mbs_ptr(const char *str, size_t len, char **pstr) { wchar_t *wstr = NULL; char *dst = NULL; size_t wlen = os_utf8_to_wcs_ptr(str, len, &wstr); size_t out_len = os_wcs_to_mbs_ptr(wstr, wlen, &dst); bfree(wstr); *pstr = dst; return out_len; }
int os_rename(const char *old_path, const char *new_path) { wchar_t *old_path_utf16 = NULL; wchar_t *new_path_utf16 = NULL; int code = -1; if (!os_utf8_to_wcs_ptr(old_path, 0, &old_path_utf16)) { return -1; } if (!os_utf8_to_wcs_ptr(new_path, 0, &new_path_utf16)) { goto error; } code = MoveFileExW(old_path_utf16, new_path_utf16, MOVEFILE_REPLACE_EXISTING) ? 0 : -1; error: bfree(old_path_utf16); bfree(new_path_utf16); return code; }
static inline bool create_proccess(const char *cmd_line, HANDLE stdin_handle, HANDLE stdout_handle, HANDLE *process) { PROCESS_INFORMATION pi = {0}; wchar_t *cmd_line_w = NULL; STARTUPINFOW si = {0}; bool success = false; struct dstr root_dir; wchar_t *root_dir_w = NULL; dstr_init(&root_dir); biliobs_get_root_path(&root_dir); si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES; si.hStdInput = stdin_handle; si.hStdOutput = stdout_handle; os_utf8_to_wcs_ptr(cmd_line, 0, &cmd_line_w); os_utf8_to_wcs_ptr(root_dir.array, 0, &root_dir_w); if (cmd_line_w && root_dir_w) { success = !!CreateProcessW(NULL, cmd_line_w, NULL, NULL, true, CREATE_NO_WINDOW, NULL, root_dir_w, &si, &pi); if (success) { *process = pi.hProcess; CloseHandle(pi.hThread); } } if( cmd_line_w ){ bfree(cmd_line_w); cmd_line_w = NULL; } if (root_dir_w){ bfree(root_dir_w); root_dir_w = NULL; } return success; }
FILE *os_fopen(const char *path, const char *mode) { #ifdef _WIN32 wchar_t *wpath = NULL; FILE *file = NULL; os_utf8_to_wcs_ptr(path, 0, &wpath); file = os_wfopen(wpath, mode); bfree(wpath); return file; #else return fopen(path, mode); #endif }
int os_unlink(const char *path) { wchar_t *w_path; bool success; os_utf8_to_wcs_ptr(path, 0, &w_path); if (!w_path) return -1; success = !!DeleteFileW(w_path); bfree(w_path); return success ? 0 : -1; }
int os_rmdir(const char *path) { wchar_t *w_path; bool success; os_utf8_to_wcs_ptr(path, 0, &w_path); if (!w_path) return -1; success = !!RemoveDirectoryW(w_path); bfree(w_path); return success ? 0 : -1; }
int os_chdir(const char *path) { wchar_t *path_w = NULL; size_t size; int ret; size = os_utf8_to_wcs_ptr(path, 0, &path_w); if (!path_w) return -1; ret = SetCurrentDirectoryW(path_w) ? 0 : -1; bfree(path_w); return ret; }
bool os_file_exists(const char *path) { WIN32_FIND_DATAW wfd; HANDLE hFind; wchar_t *path_utf16; if (!os_utf8_to_wcs_ptr(path, 0, &path_utf16)) return false; hFind = FindFirstFileW(path_utf16, &wfd); if (hFind != INVALID_HANDLE_VALUE) FindClose(hFind); bfree(path_utf16); return hFind != INVALID_HANDLE_VALUE; }
int os_mkdir(const char *path) { wchar_t *path_utf16; BOOL success; if (!os_utf8_to_wcs_ptr(path, 0, &path_utf16)) return MKDIR_ERROR; success = CreateDirectory(path_utf16, NULL); bfree(path_utf16); if (!success) return (GetLastError() == ERROR_ALREADY_EXISTS) ? MKDIR_EXISTS : MKDIR_ERROR; return MKDIR_SUCCESS; }
FILE *os_wfopen(const wchar_t *path, const char *mode) { FILE *file; #ifdef _MSC_VER wchar_t *wcs_mode; os_utf8_to_wcs_ptr(mode, 0, &wcs_mode); file = _wfopen(path, wcs_mode); bfree(wcs_mode); #else char *mbs_path; os_wcs_to_utf8_ptr(path, 0, &mbs_path); file = fopen(mbs_path, mode); bfree(mbs_path); #endif return file; }
int os_glob(const char *pattern, int flags, os_glob_t *pglob) { DARRAY(struct os_globent) files; HANDLE handle; WIN32_FIND_DATA wfd; int ret = -1; os_glob_t out = NULL; wchar_t *w_path; da_init(files); if (os_utf8_to_wcs_ptr(pattern, 0, &w_path) > 0) { handle = FindFirstFileW(w_path, &wfd); if (handle != INVALID_HANDLE_VALUE) { do { struct os_globent ent = {0}; make_globent(&ent, &wfd, pattern); if (ent.path) da_push_back(files, &ent); } while (FindNextFile(handle, &wfd)); FindClose(handle); *pglob = bmalloc(sizeof(**pglob)); (*pglob)->gl_pathc = files.num; (*pglob)->gl_pathv = files.array; ret = 0; } bfree(w_path); } if (ret != 0) *pglob = NULL; UNUSED_PARAMETER(flags); return ret; }
void *os_dlopen(const char *path) { struct dstr dll_name; wchar_t *wpath; HMODULE h_library = NULL; if (!path) return NULL; dstr_init_copy(&dll_name, path); if (!dstr_find(&dll_name, ".dll")) dstr_cat(&dll_name, ".dll"); os_utf8_to_wcs_ptr(dll_name.array, 0, &wpath); h_library = LoadLibraryW(wpath); bfree(wpath); dstr_free(&dll_name); if (!h_library) blog(LOG_INFO, "LoadLibrary failed for '%s', error: %u", path, GetLastError()); return h_library; }
wchar_t *dstr_to_wcs(const struct dstr *str) { wchar_t *dst; os_utf8_to_wcs_ptr(str->array, str->len, &dst); return dst; }
static void ft2_source_update(void *data, obs_data_t settings) { struct ft2_source *srcdata = data; obs_data_t font_obj = obs_data_get_obj(settings, "font"); bool vbuf_needs_update = false; bool word_wrap = false; uint32_t color[2]; uint32_t custom_width = 0; const char *font_name = obs_data_get_string(font_obj, "face"); const char *font_style = obs_data_get_string(font_obj, "style"); uint16_t font_size = (uint16_t)obs_data_get_int(font_obj, "size"); uint32_t font_flags = (uint32_t)obs_data_get_int(font_obj, "flags"); if (!font_obj) return; srcdata->drop_shadow = obs_data_get_bool(settings, "drop_shadow"); srcdata->outline_text = obs_data_get_bool(settings, "outline"); word_wrap = obs_data_get_bool(settings, "word_wrap"); color[0] = (uint32_t)obs_data_get_int(settings, "color1"); color[1] = (uint32_t)obs_data_get_int(settings, "color2"); custom_width = (uint32_t)obs_data_get_int(settings, "custom_width"); if (custom_width >= 100) { if (custom_width != srcdata->custom_width) { srcdata->custom_width = custom_width; vbuf_needs_update = true; } } else { if (srcdata->custom_width >= 100) vbuf_needs_update = true; srcdata->custom_width = 0; } if (word_wrap != srcdata->word_wrap) { srcdata->word_wrap = word_wrap; vbuf_needs_update = true; } if (color[0] != srcdata->color[0] || color[1] != srcdata->color[1]) { srcdata->color[0] = color[0]; srcdata->color[1] = color[1]; vbuf_needs_update = true; } bool from_file = obs_data_get_bool(settings, "from_file"); bool chat_log_mode = obs_data_get_bool(settings, "log_mode"); srcdata->log_mode = chat_log_mode; if (ft2_lib == NULL) goto error; if (srcdata->draw_effect == NULL) { char *effect_file = NULL; char *error_string = NULL; effect_file = obs_module_file("text_default.effect"); if (effect_file) { obs_enter_graphics(); srcdata->draw_effect = gs_effect_create_from_file( effect_file, &error_string); obs_leave_graphics(); bfree(effect_file); if (error_string != NULL) bfree(error_string); } } if (srcdata->font_size != font_size || srcdata->from_file != from_file) vbuf_needs_update = true; srcdata->file_load_failed = false; srcdata->from_file = from_file; if (srcdata->font_name != NULL) { if (strcmp(font_name, srcdata->font_name) == 0 && strcmp(font_style, srcdata->font_style) == 0 && font_flags == srcdata->font_flags && font_size == srcdata->font_size) goto skip_font_load; bfree(srcdata->font_name); bfree(srcdata->font_style); srcdata->font_name = NULL; srcdata->font_style = NULL; srcdata->max_h = 0; } srcdata->font_name = bstrdup(font_name); srcdata->font_style = bstrdup(font_style); srcdata->font_size = font_size; srcdata->font_flags = font_flags; if (!init_font(srcdata) || srcdata->font_face == NULL) { blog(LOG_WARNING, "FT2-text: Failed to load font %s", srcdata->font_name); goto error; } else { FT_Set_Pixel_Sizes(srcdata->font_face, 0, srcdata->font_size); FT_Select_Charmap(srcdata->font_face, FT_ENCODING_UNICODE); } if (srcdata->texbuf != NULL) { bfree(srcdata->texbuf); srcdata->texbuf = NULL; } srcdata->texbuf = bzalloc(texbuf_w * texbuf_h * 4); if (srcdata->font_face) cache_standard_glyphs(srcdata); skip_font_load:; if (from_file) { const char *tmp = obs_data_get_string(settings, "text_file"); if (!tmp || !*tmp) { blog(LOG_WARNING, "FT2-text: Failed to open %s for reading", tmp); goto error; } if (srcdata->text_file != NULL && strcmp(srcdata->text_file, tmp) == 0 && !vbuf_needs_update) goto error; bfree(srcdata->text_file); srcdata->text_file = bstrdup(tmp); if (chat_log_mode) read_from_end(srcdata, tmp); else load_text_from_file(srcdata, tmp); srcdata->last_checked = os_gettime_ns(); } else { const char *tmp = obs_data_get_string(settings, "text"); if (!tmp || !*tmp) goto error; if (srcdata->text != NULL) { bfree(srcdata->text); srcdata->text = NULL; } os_utf8_to_wcs_ptr(tmp, strlen(tmp), &srcdata->text); } if (srcdata->font_face) { cache_glyphs(srcdata, srcdata->text); set_up_vertex_buffer(srcdata); } error: obs_data_release(font_obj); }