bool ro_gui_iconbar_click(wimp_pointer *pointer) { int key_down = 0; nsurl *url; nserror error; switch (pointer->buttons) { case wimp_CLICK_SELECT: if (nsoption_charp(homepage_url) != NULL) { error = nsurl_create(nsoption_charp(homepage_url), &url); } else { error = nsurl_create(NETSURF_HOMEPAGE, &url); } /* create an initial browser window */ if (error == NSERROR_OK) { error = browser_window_create(BW_CREATE_HISTORY, url, NULL, NULL, NULL); nsurl_unref(url); } if (error != NSERROR_OK) { warn_user(messages_get_errorcode(error), 0); } break; case wimp_CLICK_ADJUST: xosbyte1(osbyte_SCAN_KEYBOARD, 0 ^ 0x80, 0, &key_down); if (key_down == 0) ro_gui_hotlist_open(); break; } return true; }
/** * Convert a string encoded in the system local encoding to UTF-8 * * \param string The string to convert * \param len The length (in bytes) of the string, or 0 * \param result Pointer to location in which to store result * \return An nserror code */ nserror utf8_from_local_encoding(const char *string, size_t len, char **result) { os_error *error; int alphabet, i, num_specials = 0, result_alloc; #define SPECIAL_CHUNK_SIZE 255 size_t off, prev_off, cur_off; char *temp; const char *enc; nserror err; assert(string && result); /* get length, if necessary */ if (len == 0) len = strlen(string); /* read system alphabet */ error = xosbyte1(osbyte_ALPHABET_NUMBER, 127, 0, &alphabet); if (error) alphabet = territory_ALPHABET_LATIN1; /* UTF-8 -> simply copy string */ if (alphabet == 111 /* UTF-8 */) { temp = strndup(string, len); if (!temp) return NSERROR_NOMEM; *result = temp; return NSERROR_OK; } /* get encoding name */ enc = (alphabet <= CONT_ENC_END ? localencodings[alphabet - 100] : (alphabet == 120 ? localencodings[CONT_ENC_END - 100 + 1] : localencodings[0])); /* create output buffer (oversized) */ result_alloc = (len * 4) + (3 * SPECIAL_CHUNK_SIZE) + 1; *(result) = malloc(result_alloc); if (!(*result)) return NSERROR_NOMEM; *(*result) = '\0'; prev_off = 0; cur_off = 0; /* Iterate over string, converting input between unconvertable * characters and inserting appropriate output for characters * that iconv can't handle. */ for (off = 0; off < len; off++) { if (string[off] < 0x80 || string[off] > 0x9f) continue; for (i = 0; i != NOF_ELEMENTS(special_chars); i++) { if (string[off] != special_chars[i].local) continue; /* 0 length has a special meaning to utf8_from_enc */ if (off - prev_off > 0) { err = utf8_from_enc(string + prev_off, enc, off - prev_off, &temp, NULL); if (err != NSERROR_OK) { assert(err != NSERROR_BAD_ENCODING); LOG("utf8_from_enc failed"); free(*result); return NSERROR_NOMEM; } strcat((*result) + cur_off, temp); cur_off += strlen(temp); free(temp); } strcat((*result) + cur_off, special_chars[i].utf); cur_off += special_chars[i].len; prev_off = off + 1; num_specials++; if (num_specials % SPECIAL_CHUNK_SIZE == SPECIAL_CHUNK_SIZE - 1) { char *temp = realloc((*result), result_alloc + (3 * SPECIAL_CHUNK_SIZE)); if (!temp) { free(*result); return NSERROR_NOMEM; } *result = temp; result_alloc += (3 * SPECIAL_CHUNK_SIZE); } } } /* handle last chunk * NB. 0 length has a special meaning to utf8_from_enc */ if (prev_off < len) { err = utf8_from_enc(string + prev_off, enc, len - prev_off, &temp, NULL); if (err != NSERROR_OK) { assert(err != NSERROR_BAD_ENCODING); LOG("utf8_from_enc failed"); free(*result); return NSERROR_NOMEM; } strcat((*result) + cur_off, temp); cur_off += strlen(temp); free(temp); } /* and copy into more reasonably-sized buffer */ temp = realloc((*result), cur_off + 1); if (!temp) { LOG("realloc failed"); free(*result); return NSERROR_NOMEM; } *result = temp; return NSERROR_OK; }
/** * Convert a UTF-8 encoded string into the system local encoding * * \param string The string to convert * \param len The length (in bytes) of the string, or 0 * \param result Pointer to location in which to store result * \return An nserror code */ nserror utf8_to_local_encoding(const char *string, size_t len, char **result) { os_error *error; int alphabet, i; size_t off, prev_off; char *temp, *cur_pos; const char *enc; nserror err; assert(string); assert(result); /* get length, if necessary */ if (len == 0) len = strlen(string); /* read system alphabet */ error = xosbyte1(osbyte_ALPHABET_NUMBER, 127, 0, &alphabet); if (error) alphabet = territory_ALPHABET_LATIN1; /* UTF-8 -> simply copy string */ if (alphabet == 111 /* UTF-8 */) { *result = strndup(string, len); return NSERROR_OK; } /* get encoding name */ enc = (alphabet <= CONT_ENC_END ? localencodings[alphabet - 100] : (alphabet == 120 ? localencodings[CONT_ENC_END - 100 + 1] : localencodings[0])); /* create output buffer */ *(result) = malloc(len + 1); if (!(*result)) return NSERROR_NOMEM; *(*result) = '\0'; prev_off = 0; cur_pos = (*result); /* Iterate over string, converting input between unconvertable * characters and inserting appropriate output for characters * that iconv can't handle. */ for (off = 0; off < len; off = utf8_next(string, len, off)) { if (string[off] != 0xE2 && string[off] != 0xC5 && string[off] != 0xEF) continue; for (i = 0; i != NOF_ELEMENTS(special_chars); i++) { if (strncmp(string + off, special_chars[i].utf, special_chars[i].len) != 0) continue; /* 0 length has a special meaning to utf8_to_enc */ if (off - prev_off > 0) { err = utf8_to_enc(string + prev_off, enc, off - prev_off, &temp); if (err != NSERROR_OK) { assert(err != NSERROR_BAD_ENCODING); free(*result); return NSERROR_NOMEM; } strcat(cur_pos, temp); cur_pos += strlen(temp); free(temp); } *cur_pos = special_chars[i].local; *(++cur_pos) = '\0'; prev_off = off + special_chars[i].len; } } /* handle last chunk * NB. 0 length has a special meaning to utf8_to_enc */ if (prev_off < len) { err = utf8_to_enc(string + prev_off, enc, len - prev_off, &temp); if (err != NSERROR_OK) { assert(err != NSERROR_BAD_ENCODING); free(*result); return NSERROR_NOMEM; } strcat(cur_pos, temp); free(temp); } return NSERROR_OK; }
/** * Translate a menu's textual content into the system local encoding * * \param menu The menu to translate * \return false if out of memory, true otherwise */ bool ro_gui_menu_translate(struct menu_definition *menu) { os_error *error; int alphabet; struct menu_definition_entry *entry; char *translated; nserror err; /* read current alphabet */ error = xosbyte1(osbyte_ALPHABET_NUMBER, 127, 0, &alphabet); if (error) { LOG(("failed reading alphabet: 0x%x: %s", error->errnum, error->errmess)); /* assume Latin1 */ alphabet = territory_ALPHABET_LATIN1; } if (menu->current_encoding == alphabet) /* menu text is already in the correct encoding */ return true; /* translate root menu title text */ free(menu->menu->title_data.indirected_text.text); err = utf8_to_local_encoding(messages_get(menu->title_key), 0, &translated); if (err != NSERROR_OK) { assert(err != NSERROR_BAD_ENCODING); LOG(("utf8_to_enc failed")); return false; } /* and fill in WIMP menu field */ menu->menu->title_data.indirected_text.text = translated; /* now the menu entries */ for (entry = menu->entries; entry; entry = entry->next) { wimp_menu *submenu = entry->menu_entry->sub_menu; /* tranlate menu entry text */ free(entry->menu_entry->data.indirected_text.text); err = utf8_to_local_encoding(messages_get(entry->entry_key), 0, &translated); if (err != NSERROR_OK) { assert(err != NSERROR_BAD_ENCODING); LOG(("utf8_to_enc failed")); return false; } /* fill in WIMP menu fields */ entry->menu_entry->data.indirected_text.text = translated; entry->menu_entry->data.indirected_text.validation = (char *) -1; entry->menu_entry->data.indirected_text.size = strlen(translated); /* child menu title - this is the same as the text of * the parent menu entry, so just copy the pointer */ if (submenu != wimp_NO_SUB_MENU && IS_MENU(submenu)) { submenu->title_data.indirected_text.text = translated; } } /* finally, set the current encoding of the menu */ menu->current_encoding = alphabet; return true; }