rufus/src/localization.h

174 lines
5.2 KiB
C

/*
* Rufus: The Reliable USB Formatting Utility
* Localization functions, a.k.a. "Everybody is doing it wrong but me!"
* Copyright © 2013-2016 Pete Batard <pete@akeo.ie>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include <stddef.h>
#pragma once
// Number of concurrent localization messages (i.e. messages we can concurrently
// reference at the same time). Must be a power of 2.
#define LOC_MESSAGE_NB 32
#define LOC_MESSAGE_SIZE 2048
#define LOC_HTAB_SIZE 1031 // Using a prime speeds up the hash table init
// Attributes that can be set by a translation
#define LOC_RIGHT_TO_LEFT 0x00000001
#define LOC_NEEDS_UPDATE 0x00000002
#define MSG_RTF 0x10000000
#define MSG_MASK 0x0FFFFFFF
#define luprint(msg) uprintf("%s(%d): " msg "\n", loc_filename, loc_line_nr)
#define luprintf(msg, ...) uprintf("%s(%d): " msg "\n", loc_filename, loc_line_nr, __VA_ARGS__)
/*
* List handling functions (stolen from libusb)
* NB: offsetof() requires '#include <stddef.h>'
*/
struct list_head {
struct list_head *prev, *next;
};
/* Get an entry from the list
* ptr - the address of this list_head element in "type"
* type - the data type that contains "member"
* member - the list_head element in "type"
*/
#define list_entry(ptr, type, member) \
((type *)((uintptr_t)(ptr) - (uintptr_t)offsetof(type, member)))
/* Get each entry from a list
* pos - A structure pointer has a "member" element
* head - list head
* member - the list_head element in "pos"
* type - the type of the first parameter
*/
#define list_for_each_entry(pos, head, type, member) \
for (pos = list_entry((head)->next, type, member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, type, member))
#define list_for_each_entry_safe(pos, n, head, type, member) \
for (pos = list_entry((head)->next, type, member), \
n = list_entry(pos->member.next, type, member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, type, member))
#define list_empty(entry) ((entry)->next == (entry))
static __inline void list_init(struct list_head *entry)
{
entry->prev = entry->next = entry;
}
static __inline void list_add(struct list_head *entry, struct list_head *head)
{
entry->next = head->next;
entry->prev = head;
head->next->prev = entry;
head->next = entry;
}
static __inline void list_add_tail(struct list_head *entry,
struct list_head *head)
{
entry->next = head;
entry->prev = head->prev;
head->prev->next = entry;
head->prev = entry;
}
static __inline void list_del(struct list_head *entry)
{
entry->next->prev = entry->prev;
entry->prev->next = entry->next;
entry->next = entry->prev = NULL;
}
// Commands that take a control ID *MUST* be at the top
// The last command with a control ID *MUST* be LC_TEXT
enum loc_command_type {
LC_GROUP,
LC_TEXT, // Delimits commands that take a Control ID and commands that don't
LC_VERSION,
LC_LOCALE,
LC_BASE,
LC_FONT,
LC_ATTRIBUTES,
};
typedef struct loc_cmd_struct {
uint8_t command;
uint8_t unum_size;
uint16_t line_nr;
int ctrl_id; // Also used as the attributes mask
int32_t num[2];
uint32_t* unum;
char* txt[2];
struct list_head list;
} loc_cmd;
typedef struct loc_parse_struct {
char c;
enum loc_command_type cmd;
char* arg_type;
} loc_parse;
typedef struct loc_control_id_struct {
const char* name;
const int id;
} loc_control_id;
typedef struct loc_dlg_list_struct {
const int dlg_id;
HWND hDlg;
struct list_head list;
} loc_dlg_list;
extern const loc_parse parse_cmd[7];
extern struct list_head locale_list;
extern char *default_msg_table[], *current_msg_table[], **msg_table;
extern int loc_line_nr;
extern char *loc_filename, *embedded_loc_filename;
extern BOOL en_msg_mode;
void free_loc_cmd(loc_cmd* lcmd);
BOOL dispatch_loc_cmd(loc_cmd* lcmd);
void _init_localization(BOOL reinit);
void _exit_localization(BOOL reinit);
#define init_localization() _init_localization(FALSE)
#define exit_localization() _exit_localization(FALSE)
#define reinit_localization() do {_exit_localization(TRUE); _init_localization(TRUE);} while(0)
void apply_localization(int dlg_id, HWND hDlg);
void reset_localization(int dlg_id);
void free_dialog_list(void);
char* lmprintf(uint32_t msg_id, ...);
BOOL get_supported_locales(const char* filename);
BOOL get_loc_data_file(const char* filename, loc_cmd* lcmd);
void free_locale_list(void);
loc_cmd* get_locale_from_lcid(int lcid, BOOL fallback);
loc_cmd* get_locale_from_name(char* locale_name, BOOL fallback);
void toggle_default_locale(void);
const char* get_name_from_id(int id);
WORD get_language_id(loc_cmd* lcmd);