1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-11-26 14:53:26 +01:00

Add localization system (gettext)

This commit is contained in:
Ansa89 2015-05-25 16:38:52 +02:00 committed by cnhenry
parent a455c80a1f
commit 0a2ad23c15
36 changed files with 5493 additions and 395 deletions

View File

@ -3,6 +3,10 @@
* [OS X Notes](#deps_osx) * [OS X Notes](#deps_osx)
* [Compiling](#compiling) * [Compiling](#compiling)
* [Documentation](#docs) * [Documentation](#docs)
* [Translating](#langs)
* [Create new translation 1: PO file](#new_lang_1)
* [Create new translation 2: MO file](#new_lang_2)
* [Update existing translation](#upd_lang)
* [Notes](#notes) * [Notes](#notes)
* [Compilation variables](#comp_vars) * [Compilation variables](#comp_vars)
* [Packaging](#packaging) * [Packaging](#packaging)
@ -20,20 +24,23 @@
| [OpenALUT](http://openal.org) | SOUND NOTIFICATIONS | libalut-dev | | [OpenALUT](http://openal.org) | SOUND NOTIFICATIONS | libalut-dev |
| [LibNotify](https://developer.gnome.org/libnotify) | DESKTOP NOTIFICATIONS | libnotify-dev | | [LibNotify](https://developer.gnome.org/libnotify) | DESKTOP NOTIFICATIONS | libnotify-dev |
| [AsciiDoc](http://asciidoc.org/index.html) | DOCUMENTATION<sup>1</sup> | asciidoc | | [AsciiDoc](http://asciidoc.org/index.html) | DOCUMENTATION<sup>1</sup> | asciidoc |
<sup>1</sup>: see [Documentation](#docs) | [Gettext](https://www.gnu.org/software/gettext) | LOCALIZATION<sup>2</sup> | gettext |
<sup>1</sup>: see [Documentation](#docs)<br />
<sup>2</sup>: see [Translating](#langs)
<a name="deps_osx" /> <a name="deps_osx" />
#### OS X Notes #### OS X Notes
Using [Homebrew](http://brew.sh): Using [Homebrew](http://brew.sh):
``` ```
brew install openal-soft freealut libconfig brew install openal-soft freealut libconfig gettext
brew install https://raw.githubusercontent.com/Tox/homebrew-tox/master/Formula/libtoxcore.rb brew install https://raw.githubusercontent.com/Tox/homebrew-tox/master/Formula/libtoxcore.rb
brew install https://raw.githubusercontent.com/Homebrew/homebrew-x11/master/libnotify.rb brew install https://raw.githubusercontent.com/Homebrew/homebrew-x11/master/libnotify.rb
brew link gettext
``` ```
You can omit `libnotify` if you intend to build without desktop notifications enabled. You can omit `libnotify` if you intend to build without desktop notifications enabled.
<a name="Compiling"> <a name="compiling">
## Compiling ## Compiling
``` ```
make PREFIX="/where/to/install" make PREFIX="/where/to/install"
@ -46,6 +53,45 @@ Run `make doc` in the build directory after editing the asciidoc files to regene
**NOTE FOR DEVELOPERS**: asciidoc files and generated manpages will need to be commited together.<br /> **NOTE FOR DEVELOPERS**: asciidoc files and generated manpages will need to be commited together.<br />
**NOTE FOR EVERYONE**: [asciidoc](http://asciidoc.org/index.html) (and this step) is only required for regenerating manpages when you modify them. **NOTE FOR EVERYONE**: [asciidoc](http://asciidoc.org/index.html) (and this step) is only required for regenerating manpages when you modify them.
<a name="langs" />
## Translating
Toxic uses gettext to localize some strings in various languages.<br />
These notes are for people who want help translating toxic in new languages (or improve an existing translation).<br />
The following example shows how to create/update german translation (de).
<a name="new_lang_1" />
#### Create new translation 1: PO file
To start a new translation, you can use the [provided script](translations/tools/create_po.sh):
```
cd toxic-src/translations/tools
./create_po.sh
Insert locale to create (for example "en"): de
Created de.po.
```
Now you can proceed to translate `toxic-src/translations/de.po`.
<a name="new_lang_2" />
#### Create new translation 2: MO file
When you fully translated the PO file, you are ready to create the MO (Machine Object) file.<br />
Again you can use the [provided script](translations/tools/create_mo.sh) to achieve this:
```
cd toxic-src/translations/tools
./create_mo.sh
Insert locale (for example "en"): de
```
<a name="upd_lang" />
#### Update existing translation
When the toxic sources are updated, you probably need to update your translation as well.<br />
To do so use the [provided script](translations/tools/update_po.sh) to update the PO file:
```
cd toxic-src/translations/tools
./update_po.sh
Insert locale to update (for example "en"): de
..................................... done.
```
Then you need to translate new/changed strings and after you fully updated the PO file, create the MO file as described [above](#new_lang_2).
<a name="notes" /> <a name="notes" />
## Notes ## Notes
@ -58,6 +104,7 @@ Run `make doc` in the build directory after editing the asciidoc files to regene
* `DISABLE_AV=1` → build toxic without audio call support * `DISABLE_AV=1` → build toxic without audio call support
* `DISABLE_SOUND_NOTIFY=1` → build toxic without sound notifications support * `DISABLE_SOUND_NOTIFY=1` → build toxic without sound notifications support
* `DISABLE_DESKTOP_NOTIFY=1` → build toxic without desktop notifications support * `DISABLE_DESKTOP_NOTIFY=1` → build toxic without desktop notifications support
* `DISABLE_LOCALIZATION=1` → build toxic without localization support
<a name="packaging" /> <a name="packaging" />
#### Packaging #### Packaging

View File

@ -24,6 +24,12 @@ ifneq ($(DESK_NOTIFY), disabled)
-include $(CHECKS_DIR)/desktop_notifications.mk -include $(CHECKS_DIR)/desktop_notifications.mk
endif endif
# Check if we want build localization support
LOCALIZATION = $(shell if [ -z "$(DISABLE_LOCALIZATION)" ] || [ "$(DISABLE_LOCALIZATION)" = "0" ] ; then echo enabled ; else echo disabled ; fi)
ifneq ($(LOCALIZATION), enabled)
CFLAGS += -DNO_GETTEXT
endif
# Check if we can build Toxic # Check if we can build Toxic
CHECK_LIBS = $(shell pkg-config --exists $(LIBS) || echo -n "error") CHECK_LIBS = $(shell pkg-config --exists $(LIBS) || echo -n "error")
ifneq ($(CHECK_LIBS), error) ifneq ($(CHECK_LIBS), error)

View File

@ -13,6 +13,7 @@ DOC_DIR = $(BASE_DIR)/doc
SRC_DIR = $(BASE_DIR)/src SRC_DIR = $(BASE_DIR)/src
SND_DIR = $(BASE_DIR)/sounds SND_DIR = $(BASE_DIR)/sounds
MISC_DIR = $(BASE_DIR)/misc MISC_DIR = $(BASE_DIR)/misc
TRANSLATIONS_DIR = $(BASE_DIR)/translations
# Project files # Project files
MANFILES = toxic.1 toxic.conf.5 MANFILES = toxic.1 toxic.conf.5
@ -22,9 +23,13 @@ SNDFILES = ToxicContactOnline.wav ToxicContactOffline.wav ToxicError.wav
SNDFILES += ToxicRecvMessage.wav ToxicOutgoingCall.wav ToxicIncomingCall.wav SNDFILES += ToxicRecvMessage.wav ToxicOutgoingCall.wav ToxicIncomingCall.wav
SNDFILES += ToxicTransferComplete.wav ToxicTransferStart.wav SNDFILES += ToxicTransferComplete.wav ToxicTransferStart.wav
# Available languages (sorted alphabetically)
LANGS = en it
# Install directories # Install directories
PREFIX = /usr/local PREFIX = /usr/local
BINDIR = $(PREFIX)/bin BINDIR = $(PREFIX)/bin
DATADIR = $(PREFIX)/share/toxic DATADIR = $(PREFIX)/share/toxic
MANDIR = $(PREFIX)/share/man MANDIR = $(PREFIX)/share/man
APPDIR = $(PREFIX)/share/applications APPDIR = $(PREFIX)/share/applications
LOCALEDIR = ${PREFIX}/share/locale

View File

@ -8,3 +8,9 @@ LIBS := $(filter-out ncursesw, $(LIBS))
# OS X ships a usable, recent version of ncurses, but calls it ncurses not ncursesw. # OS X ships a usable, recent version of ncurses, but calls it ncurses not ncursesw.
LDFLAGS += -lncurses -lalut -ltoxav -ltoxcore -ltoxdns -lresolv -lconfig -ltoxencryptsave -g LDFLAGS += -lncurses -lalut -ltoxav -ltoxcore -ltoxdns -lresolv -lconfig -ltoxencryptsave -g
CFLAGS += -I/usr/local/opt/freealut/include/AL -I/usr/local/opt/glib/include/glib-2.0 -g CFLAGS += -I/usr/local/opt/freealut/include/AL -I/usr/local/opt/glib/include/glib-2.0 -g
# Check if we want build localization support
LOCALIZATION = $(shell if [ -z "$(DISABLE_LOCALIZATION)" ] || [ "$(DISABLE_LOCALIZATION)" = "0" ] ; then echo enabled ; else echo disabled ; fi)
ifneq ($(LOCALIZATION), disabled)
LDFLAGS += -lintl
endif

View File

@ -14,6 +14,7 @@ help:
@echo " DISABLE_AV: Set to \"1\" to force building without audio call support" @echo " DISABLE_AV: Set to \"1\" to force building without audio call support"
@echo " DISABLE_SOUND_NOTIFY: Set to \"1\" to force building without sound notification support" @echo " DISABLE_SOUND_NOTIFY: Set to \"1\" to force building without sound notification support"
@echo " DISABLE_DESKTOP_NOTIFY: Set to \"1\" to force building without desktop notifications support" @echo " DISABLE_DESKTOP_NOTIFY: Set to \"1\" to force building without desktop notifications support"
@echo " DISABLE_LOCALIZATION: Set to \"1\" to force building without localization support"
@echo " USER_CFLAGS: Add custom flags to default CFLAGS" @echo " USER_CFLAGS: Add custom flags to default CFLAGS"
@echo " USER_LDFLAGS: Add custom flags to default LDFLAGS" @echo " USER_LDFLAGS: Add custom flags to default LDFLAGS"
@echo " PREFIX: Specify a prefix directory for binaries, data files,... (default is \"$(abspath $(PREFIX))\")" @echo " PREFIX: Specify a prefix directory for binaries, data files,... (default is \"$(abspath $(PREFIX))\")"

View File

@ -8,6 +8,17 @@ install: $(BUILD_DIR)/toxic
@mkdir -p $(abspath $(DESTDIR)/$(APPDIR)) @mkdir -p $(abspath $(DESTDIR)/$(APPDIR))
@install -m 0644 $(MISC_DIR)/$(DESKFILE) $(abspath $(DESTDIR)/$(APPDIR)/$(DESKFILE)) @install -m 0644 $(MISC_DIR)/$(DESKFILE) $(abspath $(DESTDIR)/$(APPDIR)/$(DESKFILE))
@if [ -z "$(DISABLE_LOCALIZATION)" -o "$(DISABLE_LOCALIZATION)" = "0" ]; then \
echo "Installing translations" ; \
for i in $(LANGS) ; do \
if [ ! -e $(TRANSLATIONS_DIR)/$$i.mo ]; then \
continue ; \
fi ; \
mkdir -p $(abspath $(DESTDIR)/$(LOCALEDIR)/$$i/LC_MESSAGES) ; \
install -m 0644 $(TRANSLATIONS_DIR)/$$i.mo $(abspath $(DESTDIR)/$(LOCALEDIR)/$$i/LC_MESSAGES/toxic.mo) ; \
done ; \
fi
@echo "Installing data files" @echo "Installing data files"
@mkdir -p $(abspath $(DESTDIR)/$(DATADIR)) @mkdir -p $(abspath $(DESTDIR)/$(DATADIR))
@for f in $(DATAFILES) ; do \ @for f in $(DATAFILES) ; do \

View File

@ -37,6 +37,12 @@
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#ifdef NO_GETTEXT
#define gettext(A) (A)
#else
#include <libintl.h>
#endif
#ifdef __APPLE__ #ifdef __APPLE__
#include <OpenAL/al.h> #include <OpenAL/al.h>
#include <OpenAL/alc.h> #include <OpenAL/alc.h>
@ -237,7 +243,7 @@ int start_transmission(ToxWindow *self, Call *call)
if ( register_device_callback(self->num, call->in_idx, if ( register_device_callback(self->num, call->in_idx,
read_device_callback, &self->num, true) != de_None) read_device_callback, &self->num, true) != de_None)
/* Set VAD as true for all; TODO: Make it more dynamic */ /* Set VAD as true for all; TODO: Make it more dynamic */
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to register input handler!"); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Failed to register input handler!"));
if ( open_primary_device(output, &call->out_idx, if ( open_primary_device(output, &call->out_idx,
CallContrl.audio_sample_rate, CallContrl.audio_frame_duration, CallContrl.audio_channels) != de_None ) { CallContrl.audio_sample_rate, CallContrl.audio_frame_duration, CallContrl.audio_channels) != de_None ) {
@ -559,8 +565,7 @@ void cmd_call(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
goto on_error; goto on_error;
} }
self->is_call = call_running; line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Calling... idx: %d"), self->call_idx);
callback_recv_ringing(CallContrl.av, self->num, &CallContrl);
return; return;
on_error: on_error:
@ -689,8 +694,8 @@ void cmd_list_devices(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*
const char *error_str; const char *error_str;
if ( argc != 1 ) { if ( argc != 1 ) {
if ( argc < 1 ) error_str = "Type must be specified!"; if ( argc < 1 ) error_str = gettext("Type must be specified!");
else error_str = "Only one argument allowed!"; else error_str = gettext("Only one argument allowed!");
goto on_error; goto on_error;
} }
@ -704,7 +709,7 @@ void cmd_list_devices(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*
type = output; type = output;
else { else {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid type: %s", argv[1]); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid type: %s"), argv[1]);
return; return;
} }
@ -721,9 +726,9 @@ void cmd_change_device(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (
const char *error_str; const char *error_str;
if ( argc != 2 ) { if ( argc != 2 ) {
if ( argc < 1 ) error_str = "Type must be specified!"; if ( argc < 1 ) error_str = gettext("Type must be specified!");
else if ( argc < 2 ) error_str = "Must have id!"; else if ( argc < 2 ) error_str = gettext("Must have id!");
else error_str = "Only two arguments allowed!"; else error_str = gettext("Only two arguments allowed!");
goto on_error; goto on_error;
} }
@ -737,7 +742,7 @@ void cmd_change_device(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (
type = output; type = output;
else { else {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid type: %s", argv[1]); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid type: %s"), argv[1]);
return; return;
} }
@ -746,12 +751,12 @@ void cmd_change_device(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (
long int selection = strtol(argv[2], &end, 10); long int selection = strtol(argv[2], &end, 10);
if ( *end ) { if ( *end ) {
error_str = "Invalid input"; error_str = gettext("Invalid input");
goto on_error; goto on_error;
} }
if ( set_primary_device(type, selection) == de_InvalidSelection ) { if ( set_primary_device(type, selection) == de_InvalidSelection ) {
error_str="Invalid selection!"; error_str=gettext("Invalid selection!");
goto on_error; goto on_error;
} }
@ -765,9 +770,9 @@ void cmd_ccur_device(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*a
const char *error_str; const char *error_str;
if ( argc != 2 ) { if ( argc != 2 ) {
if ( argc < 1 ) error_str = "Type must be specified!"; if ( argc < 1 ) error_str = gettext("Type must be specified!");
else if ( argc < 2 ) error_str = "Must have id!"; else if ( argc < 2 ) error_str = gettext("Must have id!");
else error_str = "Only two arguments allowed!"; else error_str = gettext("Only two arguments allowed!");
goto on_error; goto on_error;
} }
@ -781,7 +786,7 @@ void cmd_ccur_device(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*a
type = output; type = output;
else { else {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid type: %s", argv[1]); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid type: %s"), argv[1]);
return; return;
} }
@ -790,12 +795,12 @@ void cmd_ccur_device(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*a
long int selection = strtol(argv[2], &end, 10); long int selection = strtol(argv[2], &end, 10);
if ( *end ) { if ( *end ) {
error_str = "Invalid input"; error_str = gettext("Invalid input");
goto on_error; goto on_error;
} }
if ( selection_valid(type, selection) == de_InvalidSelection ) { if ( selection_valid(type, selection) == de_InvalidSelection ) {
error_str="Invalid selection!"; error_str=gettext("Invalid selection!");
goto on_error; goto on_error;
} }
@ -836,8 +841,8 @@ void cmd_mute(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
const char *error_str; const char *error_str;
if ( argc != 1 ) { if ( argc != 1 ) {
if ( argc < 1 ) error_str = "Type must be specified!"; if ( argc < 1 ) error_str = gettext("Type must be specified!");
else error_str = "Only two arguments allowed!"; else error_str = gettext("Only two arguments allowed!");
goto on_error; goto on_error;
} }
@ -851,7 +856,7 @@ void cmd_mute(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
type = output; type = output;
else { else {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid type: %s", argv[1]); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid type: %s"), argv[1]);
return; return;
} }
@ -882,8 +887,8 @@ void cmd_sense(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[M
const char *error_str; const char *error_str;
if ( argc != 1 ) { if ( argc != 1 ) {
if ( argc < 1 ) error_str = "Must have value!"; if ( argc < 1 ) error_str = gettext("Must have value!");
else error_str = "Only two arguments allowed!"; else error_str = gettext("Only two arguments allowed!");
goto on_error; goto on_error;
} }
@ -892,7 +897,7 @@ void cmd_sense(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[M
float value = strtof(argv[1], &end); float value = strtof(argv[1], &end);
if ( *end ) { if ( *end ) {
error_str = "Invalid input"; error_str = gettext("Invalid input");
goto on_error; goto on_error;
} }

View File

@ -24,6 +24,12 @@
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#ifdef NO_GETTEXT
#define gettext(A) (A)
#else
#include <libintl.h>
#endif
#ifdef __APPLE__ #ifdef __APPLE__
#include <sys/types.h> #include <sys/types.h>
#include <sys/dir.h> #include <sys/dir.h>
@ -117,7 +123,7 @@ int complete_line(ToxWindow *self, const void *list, int n_items, int size)
char *sub = malloc(strlen(ubuf) + 1); char *sub = malloc(strlen(ubuf) + 1);
if (sub == NULL) if (sub == NULL)
exit_toxic_err("failed in complete_line", FATALERR_MEMORY); exit_toxic_err(gettext("failed in complete_line"), FATALERR_MEMORY);
if (!s && !dir_search) { if (!s && !dir_search) {
strcpy(sub, tmp); strcpy(sub, tmp);

View File

@ -24,6 +24,12 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#ifdef NO_GETTEXT
#define gettext(A) (A)
#else
#include <libintl.h>
#endif
#include "misc_tools.h" #include "misc_tools.h"
#include "file_transfers.h" #include "file_transfers.h"
#include "friendlist.h" #include "friendlist.h"
@ -59,7 +65,7 @@ int avatar_send(Tox *m, uint32_t friendnum)
return 0; return 0;
if (err != TOX_ERR_FILE_SEND_OK) { if (err != TOX_ERR_FILE_SEND_OK) {
fprintf(stderr, "tox_file_send failed for friendnumber %d (error %d)\n", friendnum, err); fprintf(stderr, gettext("tox_file_send failed for friendnumber %d (error %d)\n"), friendnum, err);
return -1; return -1;
} }
@ -203,7 +209,7 @@ void on_avatar_chunk_request(Tox *m, struct FileTransfer *ft, uint64_t position,
tox_file_send_chunk(m, ft->friendnum, ft->filenum, position, send_data, send_length, &err); tox_file_send_chunk(m, ft->friendnum, ft->filenum, position, send_data, send_length, &err);
if (err != TOX_ERR_FILE_SEND_CHUNK_OK) if (err != TOX_ERR_FILE_SEND_CHUNK_OK)
fprintf(stderr, "tox_file_send_chunk failed in avatar callback (error %d)\n", err); fprintf(stderr, gettext("tox_file_send_chunk failed in avatar callback (error %d)\n"), err);
ft->position += send_length; ft->position += send_length;
} }

View File

@ -31,6 +31,12 @@
#include <assert.h> #include <assert.h>
#include <limits.h> #include <limits.h>
#ifdef NO_GETTEXT
#define gettext(A) (A)
#else
#include <libintl.h>
#endif
#include "toxic.h" #include "toxic.h"
#include "windows.h" #include "windows.h"
#include "execute.h" #include "execute.h"
@ -47,6 +53,9 @@
#include "notify.h" #include "notify.h"
#include "message_queue.h" #include "message_queue.h"
#define YES_STR gettext("yes")
#define NO_STR gettext("no")
#ifdef AUDIO #ifdef AUDIO
#include "audio_call.h" #include "audio_call.h"
#endif /* AUDIO */ #endif /* AUDIO */
@ -211,7 +220,7 @@ static void chat_onConnectionChange(ToxWindow *self, Tox *m, uint32_t num, TOX_C
? tox_friend_get_typing(m, num, NULL) : false; ? tox_friend_get_typing(m, num, NULL) : false;
chat_resume_file_transfers(m, num); chat_resume_file_transfers(m, num);
msg = "has come online"; msg = gettext("has come online");
line_info_add(self, timefrmt, nick, NULL, CONNECTION, 0, GREEN, msg); line_info_add(self, timefrmt, nick, NULL, CONNECTION, 0, GREEN, msg);
write_to_log(msg, nick, ctx->log, true); write_to_log(msg, nick, ctx->log, true);
} else if (connection_status == TOX_CONNECTION_NONE) { } else if (connection_status == TOX_CONNECTION_NONE) {
@ -222,7 +231,7 @@ static void chat_onConnectionChange(ToxWindow *self, Tox *m, uint32_t num, TOX_C
chat_stop_file_senders(m, num); chat_stop_file_senders(m, num);
msg = "has gone offline"; msg = gettext("has gone offline");
line_info_add(self, timefrmt, nick, NULL, DISCONNECTION, 0, RED, msg); line_info_add(self, timefrmt, nick, NULL, DISCONNECTION, 0, RED, msg);
write_to_log(msg, nick, ctx->log, true); write_to_log(msg, nick, ctx->log, true);
} }
@ -307,21 +316,21 @@ static void chat_onFileChunkRequest(ToxWindow *self, Tox *m, uint32_t friendnum,
char msg[MAX_STR_SIZE]; char msg[MAX_STR_SIZE];
if (length == 0) { if (length == 0) {
snprintf(msg, sizeof(msg), "File '%s' successfully sent.", ft->file_name); snprintf(msg, sizeof(msg), gettext("File '%s' successfully sent."), ft->file_name);
print_progress_bar(self, ft->bps, 100.0, ft->line_id); print_progress_bar(self, ft->bps, 100.0, ft->line_id);
close_file_transfer(self, m, ft, -1, msg, transfer_completed); close_file_transfer(self, m, ft, -1, msg, transfer_completed);
return; return;
} }
if (ft->file == NULL) { if (ft->file == NULL) {
snprintf(msg, sizeof(msg), "File transfer for '%s' failed: Null file pointer.", ft->file_name); snprintf(msg, sizeof(msg), gettext("File transfer for '%s' failed: Null file pointer."), ft->file_name);
close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error); close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error);
return; return;
} }
if (ft->position != position) { if (ft->position != position) {
if (fseek(ft->file, position, SEEK_SET) == -1) { if (fseek(ft->file, position, SEEK_SET) == -1) {
snprintf(msg, sizeof(msg), "File transfer for '%s' failed: Seek fail.", ft->file_name); snprintf(msg, sizeof(msg), gettext("File transfer for '%s' failed: Seek fail."), ft->file_name);
close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error); close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error);
return; return;
} }
@ -333,7 +342,7 @@ static void chat_onFileChunkRequest(ToxWindow *self, Tox *m, uint32_t friendnum,
size_t send_length = fread(send_data, 1, sizeof(send_data), ft->file); size_t send_length = fread(send_data, 1, sizeof(send_data), ft->file);
if (send_length != length) { if (send_length != length) {
snprintf(msg, sizeof(msg), "File transfer for '%s' failed: Read fail.", ft->file_name); snprintf(msg, sizeof(msg), gettext("File transfer for '%s' failed: Read fail."), ft->file_name);
close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error); close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error);
return; return;
} }
@ -342,7 +351,7 @@ static void chat_onFileChunkRequest(ToxWindow *self, Tox *m, uint32_t friendnum,
tox_file_send_chunk(m, ft->friendnum, ft->filenum, position, send_data, send_length, &err); tox_file_send_chunk(m, ft->friendnum, ft->filenum, position, send_data, send_length, &err);
if (err != TOX_ERR_FILE_SEND_CHUNK_OK) if (err != TOX_ERR_FILE_SEND_CHUNK_OK)
fprintf(stderr, "tox_file_send_chunk failed in chat callback (error %d)\n", err); fprintf(stderr, gettext("tox_file_send_chunk failed in chat callback (error %d)\n"), err);
ft->position += send_length; ft->position += send_length;
ft->bps += send_length; ft->bps += send_length;
@ -365,20 +374,20 @@ static void chat_onFileRecvChunk(ToxWindow *self, Tox *m, uint32_t friendnum, ui
char msg[MAX_STR_SIZE]; char msg[MAX_STR_SIZE];
if (length == 0) { if (length == 0) {
snprintf(msg, sizeof(msg), "File '%s' successfully received.", ft->file_name); snprintf(msg, sizeof(msg), gettext("File '%s' successfully received."), ft->file_name);
print_progress_bar(self, ft->bps, 100.0, ft->line_id); print_progress_bar(self, ft->bps, 100.0, ft->line_id);
close_file_transfer(self, m, ft, -1, msg, transfer_completed); close_file_transfer(self, m, ft, -1, msg, transfer_completed);
return; return;
} }
if (ft->file == NULL) { if (ft->file == NULL) {
snprintf(msg, sizeof(msg), "File transfer for '%s' failed: Invalid file pointer.", ft->file_name); snprintf(msg, sizeof(msg), gettext("File transfer for '%s' failed: Invalid file pointer."), ft->file_name);
close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error); close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error);
return; return;
} }
if (fwrite(data, length, 1, ft->file) != 1) { if (fwrite(data, length, 1, ft->file) != 1) {
snprintf(msg, sizeof(msg), "File transfer for '%s' failed: Write fail.", ft->file_name); snprintf(msg, sizeof(msg), gettext("File transfer for '%s' failed: Write fail."), ft->file_name);
close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error); close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error);
return; return;
} }
@ -404,7 +413,7 @@ static void chat_onFileControl(ToxWindow *self, Tox *m, uint32_t friendnum, uint
/* transfer is accepted */ /* transfer is accepted */
if (ft->state == FILE_TRANSFER_PENDING) { if (ft->state == FILE_TRANSFER_PENDING) {
ft->state = FILE_TRANSFER_STARTED; ft->state = FILE_TRANSFER_STARTED;
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer [%d] for '%s' accepted.", line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File transfer [%d] for '%s' accepted."),
ft->index, ft->file_name); ft->index, ft->file_name);
char progline[MAX_STR_SIZE]; char progline[MAX_STR_SIZE];
prep_prog_line(progline); prep_prog_line(progline);
@ -422,7 +431,7 @@ static void chat_onFileControl(ToxWindow *self, Tox *m, uint32_t friendnum, uint
break; break;
case TOX_FILE_CONTROL_CANCEL: case TOX_FILE_CONTROL_CANCEL:
snprintf(msg, sizeof(msg), "File transfer for '%s' was aborted.", ft->file_name); snprintf(msg, sizeof(msg), gettext("File transfer for '%s' was aborted."), ft->file_name);
close_file_transfer(self, m, ft, -1, msg, notif_error); close_file_transfer(self, m, ft, -1, msg, notif_error);
break; break;
} }
@ -438,13 +447,13 @@ static void chat_onFileRecv(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_
if (!ft) { if (!ft) {
tox_file_control(m, friendnum, filenum, TOX_FILE_CONTROL_CANCEL, NULL); tox_file_control(m, friendnum, filenum, TOX_FILE_CONTROL_CANCEL, NULL);
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: Too many concurrent file transfers."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File transfer failed: Too many concurrent file transfers."));
return; return;
} }
char sizestr[32]; char sizestr[32];
bytes_convert_str(sizestr, sizeof(sizestr), file_size); bytes_convert_str(sizestr, sizeof(sizestr), file_size);
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer request for '%s' (%s)", filename, sizestr); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File transfer request for '%s' (%s)"), filename, sizestr);
char file_path[MAX_STR_SIZE]; char file_path[MAX_STR_SIZE];
size_t path_len = name_length; size_t path_len = name_length;
@ -459,7 +468,7 @@ static void chat_onFileRecv(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_
if (path_len >= sizeof(ft->file_path) || name_length >= sizeof(ft->file_name)) { if (path_len >= sizeof(ft->file_path) || name_length >= sizeof(ft->file_name)) {
tox_file_control(m, friendnum, filenum, TOX_FILE_CONTROL_CANCEL, NULL); tox_file_control(m, friendnum, filenum, TOX_FILE_CONTROL_CANCEL, NULL);
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer faield: File path too long."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File transfer faield: File path too long."));
return; return;
} }
@ -485,12 +494,12 @@ static void chat_onFileRecv(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_
if (count > 999) { if (count > 999) {
tox_file_control(m, friendnum, filenum, TOX_FILE_CONTROL_CANCEL, NULL); tox_file_control(m, friendnum, filenum, TOX_FILE_CONTROL_CANCEL, NULL);
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: invalid file path."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File transfer failed: invalid file path."));
return; return;
} }
} }
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Type '/savefile %d' to accept the file transfer.", ft->index); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Type '%s %d' to accept the file transfer."), "/savefile", ft->index);
ft->state = FILE_TRANSFER_PENDING; ft->state = FILE_TRANSFER_PENDING;
ft->direction = FILE_TRANSFER_RECV; ft->direction = FILE_TRANSFER_RECV;
@ -503,10 +512,10 @@ static void chat_onFileRecv(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_
if (self->active_box != -1) if (self->active_box != -1)
box_notify2(self, transfer_pending, NT_WNDALERT_0 | NT_NOFOCUS, self->active_box, box_notify2(self, transfer_pending, NT_WNDALERT_0 | NT_NOFOCUS, self->active_box,
"Incoming file: %s", filename ); gettext("Incoming file: %s"), filename );
else else
box_notify(self, transfer_pending, NT_WNDALERT_0 | NT_NOFOCUS, &self->active_box, self->name, box_notify(self, transfer_pending, NT_WNDALERT_0 | NT_NOFOCUS, &self->active_box, self->name,
"Incoming file: %s", filename ); gettext("Incoming file: %s"), filename );
} }
static void chat_onGroupInvite(ToxWindow *self, Tox *m, int32_t friendnumber, uint8_t type, const char *group_pub_key, static void chat_onGroupInvite(ToxWindow *self, Tox *m, int32_t friendnumber, uint8_t type, const char *group_pub_key,
@ -521,7 +530,7 @@ static void chat_onGroupInvite(ToxWindow *self, Tox *m, int32_t friendnumber, ui
char *k = malloc(length); char *k = malloc(length);
if (k == NULL) if (k == NULL)
exit_toxic_err("Failed in chat_onGroupInvite", FATALERR_MEMORY); exit_toxic_err(gettext("Failed in chat_onGroupInvite"), FATALERR_MEMORY);
memcpy(k, group_pub_key, length); memcpy(k, group_pub_key, length);
Friends.list[friendnumber].group_invite.key = k; Friends.list[friendnumber].group_invite.key = k;
@ -535,12 +544,12 @@ static void chat_onGroupInvite(ToxWindow *self, Tox *m, int32_t friendnumber, ui
get_nick_truncate(m, name, friendnumber); get_nick_truncate(m, name, friendnumber);
if (self->active_box != -1) if (self->active_box != -1)
box_silent_notify2(self, NT_WNDALERT_2 | NT_NOFOCUS, self->active_box, "invites you to join group chat"); box_silent_notify2(self, NT_WNDALERT_2 | NT_NOFOCUS, self->active_box, gettext("invites you to join group chat"));
else else
box_silent_notify(self, NT_WNDALERT_2 | NT_NOFOCUS, &self->active_box, name, "invites you to join group chat"); box_silent_notify(self, NT_WNDALERT_2 | NT_NOFOCUS, &self->active_box, name, gettext("invites you to join group chat"));
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s has invited you to a group chat.", name); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("%s has invited you to a group chat."), name);
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Type \"/join\" to join the chat."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Type \"%s\" to join the chat."), "/join");
} }
/* AV Stuff */ /* AV Stuff */
@ -560,9 +569,9 @@ void chat_onInvite (ToxWindow *self, ToxAV *av, uint32_t friend_number, int stat
sound_notify(self, call_incoming, NT_LOOP, &self->ringing_sound); sound_notify(self, call_incoming, NT_LOOP, &self->ringing_sound);
if (self->active_box != -1) if (self->active_box != -1)
box_silent_notify2(self, NT_NOFOCUS | NT_WNDALERT_0, self->active_box, "Incoming audio call!"); box_silent_notify2(self, NT_NOFOCUS | NT_WNDALERT_0, self->active_box, gettext("Incoming audio call!"));
else else
box_silent_notify(self, NT_NOFOCUS | NT_WNDALERT_0, &self->active_box, self->name, "Incoming audio call!"); box_silent_notify(self, NT_NOFOCUS | NT_WNDALERT_0, &self->active_box, self->name, gettext("Incoming audio call!"));
} }
void chat_onRinging (ToxWindow *self, ToxAV *av, uint32_t friend_number, int state) void chat_onRinging (ToxWindow *self, ToxAV *av, uint32_t friend_number, int state)
@ -570,7 +579,7 @@ void chat_onRinging (ToxWindow *self, ToxAV *av, uint32_t friend_number, int sta
if (!self || !self->is_call || self->num != friend_number) if (!self || !self->is_call || self->num != friend_number)
return; return;
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Ringing...type \"/hangup\" to cancel it."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Ringing...type \"%s\" to cancel it."), "/hangup");
#ifdef SOUND_NOTIFY #ifdef SOUND_NOTIFY
if (self->ringing_sound == -1) if (self->ringing_sound == -1)
@ -630,7 +639,8 @@ void chat_onStart (ToxWindow *self, ToxAV *av, uint32_t friend_number, int state
self->is_call = true; self->is_call = true;
init_infobox(self); init_infobox(self);
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Call started! Type: \"/hangup\" to end it.");
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Call started! Type: \"%s\" to end it."), "/hangup");
#ifdef SOUND_NOTIFY #ifdef SOUND_NOTIFY
stop_sound(self->ringing_sound); stop_sound(self->ringing_sound);
@ -755,31 +765,31 @@ static void draw_infobox(ToxWindow *self)
infobox->lastupdate = curtime; infobox->lastupdate = curtime;
const char *in_is_muted = infobox->in_is_muted ? "yes" : "no"; const char *in_is_muted = infobox->in_is_muted ? YES_STR : NO_STR;
const char *out_is_muted = infobox->out_is_muted ? "yes" : "no"; const char *out_is_muted = infobox->out_is_muted ? YES_STR : NO_STR;
wmove(infobox->win, 1, 1); wmove(infobox->win, 1, 1);
wattron(infobox->win, COLOR_PAIR(RED) | A_BOLD); wattron(infobox->win, COLOR_PAIR(RED) | A_BOLD);
wprintw(infobox->win, " Call Active\n"); wprintw(infobox->win, gettext(" Call Active\n"));
wattroff(infobox->win, COLOR_PAIR(RED) | A_BOLD); wattroff(infobox->win, COLOR_PAIR(RED) | A_BOLD);
wattron(infobox->win, A_BOLD); wattron(infobox->win, A_BOLD);
wprintw(infobox->win, " Duration: "); wprintw(infobox->win, gettext(" Duration: "));
wattroff(infobox->win, A_BOLD); wattroff(infobox->win, A_BOLD);
wprintw(infobox->win, "%s\n", infobox->timestr); wprintw(infobox->win, "%s\n", infobox->timestr);
wattron(infobox->win, A_BOLD); wattron(infobox->win, A_BOLD);
wprintw(infobox->win, " In muted: "); wprintw(infobox->win, gettext(" In muted: "));
wattroff(infobox->win, A_BOLD); wattroff(infobox->win, A_BOLD);
wprintw(infobox->win, "%s\n", in_is_muted); wprintw(infobox->win, "%s\n", in_is_muted);
wattron(infobox->win, A_BOLD); wattron(infobox->win, A_BOLD);
wprintw(infobox->win, " Out muted: "); wprintw(infobox->win, gettext(" Out muted: "));
wattroff(infobox->win, A_BOLD); wattroff(infobox->win, A_BOLD);
wprintw(infobox->win, "%s\n", out_is_muted); wprintw(infobox->win, "%s\n", out_is_muted);
wattron(infobox->win, A_BOLD); wattron(infobox->win, A_BOLD);
wprintw(infobox->win, " VAD level: "); wprintw(infobox->win, gettext(" VAD level: "));
wattroff(infobox->win, A_BOLD); wattroff(infobox->win, A_BOLD);
wprintw(infobox->win, "%.2f\n", infobox->vad_lvl); wprintw(infobox->win, "%.2f\n", infobox->vad_lvl);
@ -1071,7 +1081,7 @@ static void chat_onInit(ToxWindow *self, Tox *m)
ctx->cqueue = calloc(1, sizeof(struct chat_queue)); ctx->cqueue = calloc(1, sizeof(struct chat_queue));
if (ctx->log == NULL || ctx->hst == NULL || ctx->cqueue == NULL) if (ctx->log == NULL || ctx->hst == NULL || ctx->cqueue == NULL)
exit_toxic_err("failed in chat_onInit", FATALERR_MEMORY); exit_toxic_err(gettext("failed in chat_onInit"), FATALERR_MEMORY);
line_info_init(ctx->hst); line_info_init(ctx->hst);
@ -1143,7 +1153,7 @@ ToxWindow new_chat(Tox *m, uint32_t friendnum)
Help *help = calloc(1, sizeof(Help)); Help *help = calloc(1, sizeof(Help));
if (stb == NULL || chatwin == NULL || help == NULL) if (stb == NULL || chatwin == NULL || help == NULL)
exit_toxic_err("failed in new_chat", FATALERR_MEMORY); exit_toxic_err(gettext("failed in new_chat"), FATALERR_MEMORY);
ret.chatwin = chatwin; ret.chatwin = chatwin;
ret.stb = stb; ret.stb = stb;

View File

@ -23,6 +23,12 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#ifdef NO_GETTEXT
#define gettext(A) (A)
#else
#include <libintl.h>
#endif
#include "toxic.h" #include "toxic.h"
#include "windows.h" #include "windows.h"
#include "misc_tools.h" #include "misc_tools.h"
@ -39,7 +45,7 @@ extern FriendsList Friends;
void cmd_cancelfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_cancelfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{ {
if (argc < 2) { if (argc < 2) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Requires type in|out and the file ID."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Requires type %s and the file ID."), "in|out");
return; return;
} }
@ -48,7 +54,7 @@ void cmd_cancelfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*ar
int idx = atoi(argv[2]); int idx = atoi(argv[2]);
if (idx >= MAX_FILES || idx < 0) { if (idx >= MAX_FILES || idx < 0) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file ID."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid file ID."));
return; return;
} }
@ -60,50 +66,50 @@ void cmd_cancelfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*ar
} else if (strcasecmp(inoutstr, "out") == 0) { } else if (strcasecmp(inoutstr, "out") == 0) {
ft = get_file_transfer_struct_index(self->num, idx, FILE_TRANSFER_SEND); ft = get_file_transfer_struct_index(self->num, idx, FILE_TRANSFER_SEND);
} else { } else {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Type must be 'in' or 'out'."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Type must be '%s' or '%s'."), "in", "out");
return; return;
} }
if (!ft) { if (!ft) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file ID."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid file ID."));
return; return;
} }
if (ft->state == FILE_TRANSFER_INACTIVE) { if (ft->state == FILE_TRANSFER_INACTIVE) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file ID."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid file ID."));
return; return;
} }
snprintf(msg, sizeof(msg), "File transfer for '%s' aborted.", ft->file_name); snprintf(msg, sizeof(msg), gettext("File transfer for '%s' aborted."), ft->file_name);
close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, silent); close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, silent);
} }
void cmd_groupinvite(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_groupinvite(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{ {
if (argc < 1) { if (argc < 1) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group number required."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Group number required."));
return; return;
} }
int groupnum = atoi(argv[1]); int groupnum = atoi(argv[1]);
if (groupnum == 0 && strcmp(argv[1], "0")) { /* atoi returns 0 value on invalid input */ if (groupnum == 0 && strcmp(argv[1], "0")) { /* atoi returns 0 value on invalid input */
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid group number."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid group number."));
return; return;
} }
if (tox_invite_friend(m, self->num, groupnum) == -1) { if (tox_invite_friend(m, self->num, groupnum) == -1) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to invite contact to group."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Failed to invite contact to group."));
return; return;
} }
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invited contact to Group %d.", groupnum); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invited contact to Group %d."), groupnum);
} }
void cmd_join_group(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_join_group(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{ {
if (get_num_active_windows() >= MAX_WINDOWS_NUM) { if (get_num_active_windows() >= MAX_WINDOWS_NUM) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, " * Warning: Too many windows are open."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, gettext(" * Warning: Too many windows are open."));
return; return;
} }
@ -112,7 +118,7 @@ void cmd_join_group(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*ar
uint8_t type = Friends.list[self->num].group_invite.type; uint8_t type = Friends.list[self->num].group_invite.type;
if (!Friends.list[self->num].group_invite.pending) { if (!Friends.list[self->num].group_invite.pending) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending group chat invite."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("No pending group chat invite."));
return; return;
} }
@ -127,12 +133,12 @@ void cmd_join_group(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*ar
#endif*/ #endif*/
if (groupnum == -1) { if (groupnum == -1) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group chat instance failed to initialize."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Group chat instance failed to initialize."));
return; return;
} }
if (init_groupchat_win(prompt, m, groupnum, type) == -1) { if (init_groupchat_win(prompt, m, groupnum, type) == -1) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group chat window failed to initialize."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Group chat window failed to initialize."));
tox_del_groupchat(m, groupnum); tox_del_groupchat(m, groupnum);
return; return;
} }
@ -142,31 +148,31 @@ void cmd_join_group(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*ar
void cmd_savefile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_savefile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{ {
if (argc < 1) { if (argc < 1) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File ID required."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File ID required."));
return; return;
} }
int idx = atoi(argv[1]); int idx = atoi(argv[1]);
if ((idx == 0 && strcmp(argv[1], "0")) || idx >= MAX_FILES) { if ((idx == 0 && strcmp(argv[1], "0")) || idx >= MAX_FILES) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending file transfers with that ID."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("No pending file transfers with that ID."));
return; return;
} }
struct FileTransfer *ft = get_file_transfer_struct_index(self->num, idx, FILE_TRANSFER_RECV); struct FileTransfer *ft = get_file_transfer_struct_index(self->num, idx, FILE_TRANSFER_RECV);
if (!ft) { if (!ft) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending file transfers with that ID."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("No pending file transfers with that ID."));
return; return;
} }
if (ft->state != FILE_TRANSFER_PENDING) { if (ft->state != FILE_TRANSFER_PENDING) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending file transfers with that ID."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("No pending file transfers with that ID."));
return; return;
} }
if ((ft->file = fopen(ft->file_path, "a")) == NULL) { if ((ft->file = fopen(ft->file_path, "a")) == NULL) {
const char *msg = "File transfer failed: Invalid file path."; const char *msg = gettext("File transfer failed: Invalid file path.");
close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error); close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, notif_error);
return; return;
} }
@ -177,7 +183,7 @@ void cmd_savefile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
if (err != TOX_ERR_FILE_CONTROL_OK) if (err != TOX_ERR_FILE_CONTROL_OK)
goto on_recv_error; goto on_recv_error;
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Saving file [%d] as: '%s'", idx, ft->file_path); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Saving file [%d] as: '%s'"), idx, ft->file_path);
/* prep progress bar line */ /* prep progress bar line */
char progline[MAX_STR_SIZE]; char progline[MAX_STR_SIZE];
@ -192,23 +198,23 @@ void cmd_savefile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
on_recv_error: on_recv_error:
switch (err) { switch (err) {
case TOX_ERR_FILE_CONTROL_FRIEND_NOT_FOUND: case TOX_ERR_FILE_CONTROL_FRIEND_NOT_FOUND:
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: Friend not found."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File transfer failed: Friend not found."));
return; return;
case TOX_ERR_FILE_CONTROL_FRIEND_NOT_CONNECTED: case TOX_ERR_FILE_CONTROL_FRIEND_NOT_CONNECTED:
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: Friend is not online."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File transfer failed: Friend is not online."));
return; return;
case TOX_ERR_FILE_CONTROL_NOT_FOUND: case TOX_ERR_FILE_CONTROL_NOT_FOUND:
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: Invalid filenumber."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File transfer failed: Invalid filenumber."));
return; return;
case TOX_ERR_FILE_CONTROL_SENDQ: case TOX_ERR_FILE_CONTROL_SENDQ:
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed: Connection error."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File transfer failed: Connection error."));
return; return;
default: default:
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed (error %d)\n", err); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File transfer failed (error %d)\n"), err);
return; return;
} }
} }
@ -218,12 +224,12 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
const char *errmsg = NULL; const char *errmsg = NULL;
if (argc < 1) { if (argc < 1) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File path required."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File path required."));
return; return;
} }
if (argv[1][0] != '\"') { if (argv[1][0] != '\"') {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File path must be enclosed in quotes."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File path must be enclosed in quotes."));
return; return;
} }
@ -234,21 +240,21 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
path[path_len] = '\0'; path[path_len] = '\0';
if (path_len >= MAX_STR_SIZE) { if (path_len >= MAX_STR_SIZE) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File path exceeds character limit."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File path exceeds character limit."));
return; return;
} }
FILE *file_to_send = fopen(path, "r"); FILE *file_to_send = fopen(path, "r");
if (file_to_send == NULL) { if (file_to_send == NULL) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File not found."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("File not found."));
return; return;
} }
off_t filesize = file_size(path); off_t filesize = file_size(path);
if (filesize == 0) { if (filesize == 0) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid file."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid file."));
fclose(file_to_send); fclose(file_to_send);
return; return;
} }
@ -281,30 +287,30 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
char sizestr[32]; char sizestr[32];
bytes_convert_str(sizestr, sizeof(sizestr), filesize); bytes_convert_str(sizestr, sizeof(sizestr), filesize);
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Sending file [%d]: '%s' (%s)", filenum, file_name, sizestr); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Sending file [%d]: '%s' (%s)"), filenum, file_name, sizestr);
return; return;
on_send_error: on_send_error:
switch (err) { switch (err) {
case TOX_ERR_FILE_SEND_FRIEND_NOT_FOUND: case TOX_ERR_FILE_SEND_FRIEND_NOT_FOUND:
errmsg = "File transfer failed: Invalid friend."; errmsg = gettext("File transfer failed: Invalid friend.");
break; break;
case TOX_ERR_FILE_SEND_FRIEND_NOT_CONNECTED: case TOX_ERR_FILE_SEND_FRIEND_NOT_CONNECTED:
errmsg = "File transfer failed: Friend is offline."; errmsg = gettext("File transfer failed: Friend is offline.");
break; break;
case TOX_ERR_FILE_SEND_NAME_TOO_LONG: case TOX_ERR_FILE_SEND_NAME_TOO_LONG:
errmsg = "File transfer failed: Filename is too long."; errmsg = gettext("File transfer failed: Filename is too long.");
break; break;
case TOX_ERR_FILE_SEND_TOO_MANY: case TOX_ERR_FILE_SEND_TOO_MANY:
errmsg = "File transfer failed: Too many concurrent file transfers."; errmsg = gettext("File transfer failed: Too many concurrent file transfers.");
break; break;
default: default:
errmsg = "File transfer failed."; errmsg = gettext("File transfer failed.");
break; break;
} }

View File

@ -29,6 +29,12 @@
#include <unistd.h> #include <unistd.h>
#include <pwd.h> #include <pwd.h>
#ifdef NO_GETTEXT
#define gettext(A) (A)
#else
#include <libintl.h>
#endif
#include "toxic.h" #include "toxic.h"
#include "configdir.h" #include "configdir.h"
@ -116,7 +122,7 @@ int create_user_config_dirs(char *path)
char *logpath = malloc(strlen(path) + strlen(LOGDIR) + 1); char *logpath = malloc(strlen(path) + strlen(LOGDIR) + 1);
if (fullpath == NULL || logpath == NULL) if (fullpath == NULL || logpath == NULL)
exit_toxic_err("failed in load_data_structures", FATALERR_MEMORY); exit_toxic_err(gettext("failed in load_data_structures"), FATALERR_MEMORY);
strcpy(fullpath, path); strcpy(fullpath, path);
strcat(fullpath, CONFIGDIR); strcat(fullpath, CONFIGDIR);

View File

@ -26,6 +26,12 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <resolv.h> #include <resolv.h>
#ifdef NO_GETTEXT
#define gettext(A) (A)
#else
#include <libintl.h>
#endif
#ifdef __APPLE__ #ifdef __APPLE__
#include <arpa/nameser_compat.h> #include <arpa/nameser_compat.h>
#else #else
@ -146,7 +152,7 @@ static int load_dns_domainlist(const char *path)
static int dns_error(ToxWindow *self, const char *errmsg) static int dns_error(ToxWindow *self, const char *errmsg)
{ {
pthread_mutex_lock(&Winthread.lock); pthread_mutex_lock(&Winthread.lock);
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "User lookup failed: %s", errmsg); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("User lookup failed: %s"), errmsg);
pthread_mutex_unlock(&Winthread.lock); pthread_mutex_unlock(&Winthread.lock);
return -1; return -1;
@ -172,18 +178,18 @@ static int parse_dns_response(ToxWindow *self, u_char *answer, int ans_len, char
int len = dn_expand(answer, ans_end, ans_pt, exp_ans, sizeof(exp_ans)); int len = dn_expand(answer, ans_end, ans_pt, exp_ans, sizeof(exp_ans));
if (len == -1) if (len == -1)
return dns_error(self, "dn_expand failed."); return dns_error(self, gettext("dn_expand failed."));
ans_pt += len; ans_pt += len;
if (ans_pt > ans_end - 4) if (ans_pt > ans_end - 4)
return dns_error(self, "DNS reply was too short."); return dns_error(self, gettext("DNS reply was too short."));
int type; int type;
GETSHORT(type, ans_pt); GETSHORT(type, ans_pt);
if (type != T_TXT) if (type != T_TXT)
return dns_error(self, "Broken DNS reply."); return dns_error(self, gettext("Broken DNS reply."));
ans_pt += INT16SZ; /* class */ ans_pt += INT16SZ; /* class */
@ -195,12 +201,12 @@ static int parse_dns_response(ToxWindow *self, u_char *answer, int ans_len, char
len = dn_expand(answer, ans_end, ans_pt, exp_ans, sizeof(exp_ans)); len = dn_expand(answer, ans_end, ans_pt, exp_ans, sizeof(exp_ans));
if (len == -1) if (len == -1)
return dns_error(self, "Second dn_expand failed."); return dns_error(self, gettext("Second dn_expand failed."));
ans_pt += len; ans_pt += len;
if (ans_pt > ans_end - 10) if (ans_pt > ans_end - 10)
return dns_error(self, "DNS reply was too short."); return dns_error(self, gettext("DNS reply was too short."));
GETSHORT(type, ans_pt); GETSHORT(type, ans_pt);
ans_pt += INT16SZ; ans_pt += INT16SZ;
@ -208,20 +214,20 @@ static int parse_dns_response(ToxWindow *self, u_char *answer, int ans_len, char
GETSHORT(size, ans_pt); GETSHORT(size, ans_pt);
if (ans_pt + size < answer || ans_pt + size > ans_end) if (ans_pt + size < answer || ans_pt + size > ans_end)
return dns_error(self, "RR overflow."); return dns_error(self, gettext("RR overflow."));
} while (type == T_CNAME); } while (type == T_CNAME);
if (type != T_TXT) if (type != T_TXT)
return dns_error(self, "DNS response failed."); return dns_error(self, gettext("DNS response failed."));
uint32_t txt_len = *ans_pt; uint32_t txt_len = *ans_pt;
if (!size || txt_len >= size || !txt_len) if (!size || txt_len >= size || !txt_len)
return dns_error(self, "No record found."); return dns_error(self, gettext("No record found."));
if (txt_len > MAX_DNS_REQST_SIZE) if (txt_len > MAX_DNS_REQST_SIZE)
return dns_error(self, "Invalid DNS response."); return dns_error(self, gettext("Invalid DNS response."));
ans_pt++; ans_pt++;
ans_pt[txt_len] = '\0'; ans_pt[txt_len] = '\0';
@ -298,7 +304,7 @@ void *dns3_lookup_thread(void *data)
int namelen = parse_addr(t_data.addr, name, inputdomain); int namelen = parse_addr(t_data.addr, name, inputdomain);
if (namelen == -1) { if (namelen == -1) {
dns_error(self, "Must be a Tox ID or an address in the form username@domain"); dns_error(self, gettext("Must be a Tox ID or an address in the form username@domain"));
killdns_thread(NULL); killdns_thread(NULL);
} }
@ -308,14 +314,14 @@ void *dns3_lookup_thread(void *data)
int match = get_domain_match(DNS_pubkey, domain, inputdomain); int match = get_domain_match(DNS_pubkey, domain, inputdomain);
if (match == -1) { if (match == -1) {
dns_error(self, "Domain not found."); dns_error(self, gettext("Domain not found."));
killdns_thread(NULL); killdns_thread(NULL);
} }
void *dns_obj = tox_dns3_new((uint8_t *) DNS_pubkey); void *dns_obj = tox_dns3_new((uint8_t *) DNS_pubkey);
if (dns_obj == NULL) { if (dns_obj == NULL) {
dns_error(self, "Core failed to create DNS object."); dns_error(self, gettext("Core failed to create DNS object."));
killdns_thread(NULL); killdns_thread(NULL);
} }
@ -326,7 +332,7 @@ void *dns3_lookup_thread(void *data)
(uint8_t *) name, namelen); (uint8_t *) name, namelen);
if (str_len == -1) { if (str_len == -1) {
dns_error(self, "Core failed to generate DNS3 string."); dns_error(self, gettext("Core failed to generate DNS3 string."));
killdns_thread(dns_obj); killdns_thread(dns_obj);
} }
@ -340,7 +346,7 @@ void *dns3_lookup_thread(void *data)
int ans_len = res_query(d_string, C_IN, T_TXT, answer, sizeof(answer)); int ans_len = res_query(d_string, C_IN, T_TXT, answer, sizeof(answer));
if (ans_len <= 0) { if (ans_len <= 0) {
dns_error(self, "DNS query failed."); dns_error(self, gettext("DNS query failed."));
killdns_thread(dns_obj); killdns_thread(dns_obj);
} }
@ -355,7 +361,7 @@ void *dns3_lookup_thread(void *data)
/* extract the encrypted ID from TXT response */ /* extract the encrypted ID from TXT response */
if (strncmp(ans_id, TOX_DNS3_TXT_PREFIX, prfx_len) != 0) { if (strncmp(ans_id, TOX_DNS3_TXT_PREFIX, prfx_len) != 0) {
dns_error(self, "Bad DNS3 TXT response."); dns_error(self, gettext("Bad DNS3 TXT response."));
killdns_thread(dns_obj); killdns_thread(dns_obj);
} }
@ -363,7 +369,7 @@ void *dns3_lookup_thread(void *data)
if (tox_decrypt_dns3_TXT(dns_obj, (uint8_t *) t_data.id_bin, (uint8_t *) encrypted_id, if (tox_decrypt_dns3_TXT(dns_obj, (uint8_t *) t_data.id_bin, (uint8_t *) encrypted_id,
strlen(encrypted_id), request_id) == -1) { strlen(encrypted_id), request_id) == -1) {
dns_error(self, "Core failed to decrypt DNS response."); dns_error(self, gettext("Core failed to decrypt DNS response."));
killdns_thread(dns_obj); killdns_thread(dns_obj);
} }
@ -379,12 +385,12 @@ void *dns3_lookup_thread(void *data)
void dns3_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, const char *msg) void dns3_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, const char *msg)
{ {
if (arg_opts.proxy_type != TOX_PROXY_TYPE_NONE && arg_opts.force_tcp) { if (arg_opts.proxy_type != TOX_PROXY_TYPE_NONE && arg_opts.force_tcp) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "DNS lookups are disabled."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("DNS lookups are disabled."));
return; return;
} }
if (t_data.busy) { if (t_data.busy) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Please wait for previous user lookup to finish."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Please wait for previous user lookup to finish."));
return; return;
} }
@ -394,7 +400,7 @@ void dns3_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr,
int ret = load_dns_domainlist(path); int ret = load_dns_domainlist(path);
if (ret < 0) { if (ret < 0) {
const char *errmsg = "DNS server list failed to load with error code %d. Falling back to hard-coded list."; const char *errmsg = gettext("DNS server list failed to load with error code %d. Falling back to hard-coded list.");
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg, ret); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg, ret);
} }
} }
@ -407,20 +413,20 @@ void dns3_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr,
t_data.busy = 1; t_data.busy = 1;
if (pthread_attr_init(&dns_thread.attr) != 0) { if (pthread_attr_init(&dns_thread.attr) != 0) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "Error: DNS thread attr failed to init"); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, gettext("Error: DNS thread attr failed to init"));
memset(&t_data, 0, sizeof(struct thread_data)); memset(&t_data, 0, sizeof(struct thread_data));
return; return;
} }
if (pthread_attr_setdetachstate(&dns_thread.attr, PTHREAD_CREATE_DETACHED) != 0) { if (pthread_attr_setdetachstate(&dns_thread.attr, PTHREAD_CREATE_DETACHED) != 0) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "Error: DNS thread attr failed to set"); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, gettext("Error: DNS thread attr failed to set"));
pthread_attr_destroy(&dns_thread.attr); pthread_attr_destroy(&dns_thread.attr);
memset(&t_data, 0, sizeof(struct thread_data)); memset(&t_data, 0, sizeof(struct thread_data));
return; return;
} }
if (pthread_create(&dns_thread.tid, &dns_thread.attr, dns3_lookup_thread, NULL) != 0) { if (pthread_create(&dns_thread.tid, &dns_thread.attr, dns3_lookup_thread, NULL) != 0) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "Error: DNS thread failed to init"); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, gettext("Error: DNS thread failed to init"));
pthread_attr_destroy(&dns_thread.attr); pthread_attr_destroy(&dns_thread.attr);
memset(&t_data, 0, sizeof(struct thread_data)); memset(&t_data, 0, sizeof(struct thread_data));
return; return;

View File

@ -24,6 +24,12 @@
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#ifdef NO_GETTEXT
#define gettext(A) (A)
#else
#include <libintl.h>
#endif
#include "toxic.h" #include "toxic.h"
#include "windows.h" #include "windows.h"
#include "execute.h" #include "execute.h"
@ -98,7 +104,7 @@ static int parse_command(WINDOW *w, ToxWindow *self, const char *input, char (*a
char *cmd = strdup(input); char *cmd = strdup(input);
if (cmd == NULL) if (cmd == NULL)
exit_toxic_err("failed in parse_command", FATALERR_MEMORY); exit_toxic_err(gettext("failed in parse_command"), FATALERR_MEMORY);
int num_args = 0; int num_args = 0;
int i = 0; /* index of last char in an argument */ int i = 0; /* index of last char in an argument */
@ -112,7 +118,7 @@ static int parse_command(WINDOW *w, ToxWindow *self, const char *input, char (*a
i = char_find(1, cmd, '\"'); i = char_find(1, cmd, '\"');
if (cmd[i] == '\0') { if (cmd[i] == '\0') {
const char *errmsg = "Invalid argument. Did you forget a closing \"?"; const char *errmsg = gettext("Invalid argument. Did you forget a closing \"?");
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg);
free(cmd); free(cmd);
return -1; return -1;
@ -183,5 +189,5 @@ void execute(WINDOW *w, ToxWindow *self, Tox *m, const char *input, int mode)
if (do_command(w, self, m, num_args, global_commands, args) == 0) if (do_command(w, self, m, num_args, global_commands, args) == 0)
return; return;
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid command."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid command."));
} }

View File

@ -26,6 +26,12 @@
#include <time.h> #include <time.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#ifdef NO_GETTEXT
#define gettext(A) (A)
#else
#include <libintl.h>
#endif
#include <tox/tox.h> #include <tox/tox.h>
#include "toxic.h" #include "toxic.h"
@ -84,7 +90,7 @@ static void realloc_friends(int n)
uint32_t *f_idx = realloc(Friends.index, n * sizeof(uint32_t)); uint32_t *f_idx = realloc(Friends.index, n * sizeof(uint32_t));
if (f == NULL || f_idx == NULL) if (f == NULL || f_idx == NULL)
exit_toxic_err("failed in realloc_friends", FATALERR_MEMORY); exit_toxic_err(gettext("failed in realloc_friends"), FATALERR_MEMORY);
Friends.list = f; Friends.list = f;
Friends.index = f_idx; Friends.index = f_idx;
@ -104,7 +110,7 @@ static void realloc_blocklist(int n)
uint32_t *b_idx = realloc(Blocked.index, n * sizeof(uint32_t)); uint32_t *b_idx = realloc(Blocked.index, n * sizeof(uint32_t));
if (b == NULL || b_idx == NULL) if (b == NULL || b_idx == NULL)
exit_toxic_err("failed in realloc_blocklist", FATALERR_MEMORY); exit_toxic_err(gettext("failed in realloc_blocklist"), FATALERR_MEMORY);
Blocked.list = b; Blocked.list = b;
Blocked.index = b_idx; Blocked.index = b_idx;
@ -132,7 +138,7 @@ static int save_blocklist(char *path)
char *data = malloc(len); char *data = malloc(len);
if (data == NULL) if (data == NULL)
exit_toxic_err("Failed in save_blocklist", FATALERR_MEMORY); exit_toxic_err(gettext("Failed in save_blocklist"), FATALERR_MEMORY);
int i; int i;
@ -199,7 +205,7 @@ int load_blocklist(char *path)
if (data == NULL) { if (data == NULL) {
fclose(fp); fclose(fp);
exit_toxic_err("Failed in load_blocklist", FATALERR_MEMORY); exit_toxic_err(gettext("Failed in load_blocklist"), FATALERR_MEMORY);
} }
if (fread(data, len, 1, fp) != 1) { if (fread(data, len, 1, fp) != 1) {
@ -322,7 +328,7 @@ static void friendlist_onMessage(ToxWindow *self, Tox *m, uint32_t num, TOX_MESS
get_time_str(timefrmt, sizeof(timefrmt)); get_time_str(timefrmt, sizeof(timefrmt));
line_info_add(prompt, timefrmt, nick, NULL, IN_MSG, 0, 0, "%s", str); line_info_add(prompt, timefrmt, nick, NULL, IN_MSG, 0, 0, "%s", str);
line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, "* Warning: Too many windows are open."); line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, gettext("* Warning: Too many windows are open."));
sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL); sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL);
} }
@ -337,7 +343,7 @@ static void friendlist_onConnectionChange(ToxWindow *self, Tox *m, uint32_t num,
++Friends.num_online; ++Friends.num_online;
if (avatar_send(m, num) == -1) if (avatar_send(m, num) == -1)
fprintf(stderr, "avatar_send failed for friend %d\n", num); fprintf(stderr, gettext("avatar_send failed for friend %d\n"), num);
} }
Friends.list[num].connection_status = connection_status; Friends.list[num].connection_status = connection_status;
@ -412,7 +418,7 @@ void friendlist_onFriendAdded(ToxWindow *self, Tox *m, uint32_t num, bool sort)
tox_friend_get_public_key(m, num, (uint8_t *) Friends.list[i].pub_key, &pkerr); tox_friend_get_public_key(m, num, (uint8_t *) Friends.list[i].pub_key, &pkerr);
if (pkerr != TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK) if (pkerr != TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK)
fprintf(stderr, "tox_friend_get_public_key failed (error %d)\n", pkerr); fprintf(stderr, gettext("tox_friend_get_public_key failed (error %d)\n"), pkerr);
TOX_ERR_FRIEND_GET_LAST_ONLINE loerr; TOX_ERR_FRIEND_GET_LAST_ONLINE loerr;
uint64_t t = tox_friend_get_last_online(m, num, &loerr); uint64_t t = tox_friend_get_last_online(m, num, &loerr);
@ -491,7 +497,7 @@ static void friendlist_onFileRecv(ToxWindow *self, Tox *m, uint32_t num, uint32_
get_nick_truncate(m, nick, num); get_nick_truncate(m, nick, num);
line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED,
"* File transfer from %s failed: too many windows are open.", nick); gettext("* File transfer from %s failed: too many windows are open."), nick);
sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL); sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL);
} }
@ -514,7 +520,7 @@ static void friendlist_onGroupInvite(ToxWindow *self, Tox *m, int32_t num, uint8
get_nick_truncate(m, nick, num); get_nick_truncate(m, nick, num);
line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED,
"* Group chat invite from %s failed: too many windows are open.", nick); gettext("* Group chat invite from %s failed: too many windows are open."), nick);
sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL); sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL);
} }
@ -537,7 +543,7 @@ static void delete_friend(Tox *m, uint32_t f_num)
{ {
TOX_ERR_FRIEND_DELETE err; TOX_ERR_FRIEND_DELETE err;
if (tox_friend_delete(m, f_num, &err) != true) { if (tox_friend_delete(m, f_num, &err) != true) {
fprintf(stderr, "tox_friend_delete failed with error %d\n", err); fprintf(stderr, gettext("tox_friend_delete failed with error %d\n"), err);
return; return;
} }
@ -617,7 +623,7 @@ static void draw_del_popup(void)
wattroff(PendingDelete.popup, A_BOLD); wattroff(PendingDelete.popup, A_BOLD);
wmove(PendingDelete.popup, 1, 1); wmove(PendingDelete.popup, 1, 1);
wprintw(PendingDelete.popup, "Delete contact "); wprintw(PendingDelete.popup, gettext("Delete contact "));
wattron(PendingDelete.popup, A_BOLD); wattron(PendingDelete.popup, A_BOLD);
if (blocklist_view == 0) if (blocklist_view == 0)
@ -698,7 +704,7 @@ static void unblock_friend(Tox *m, uint32_t bnum)
uint32_t friendnum = tox_friend_add_norequest(m, (uint8_t *) Blocked.list[bnum].pub_key, &err); uint32_t friendnum = tox_friend_add_norequest(m, (uint8_t *) Blocked.list[bnum].pub_key, &err);
if (err != TOX_ERR_FRIEND_ADD_OK) { if (err != TOX_ERR_FRIEND_ADD_OK) {
line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to unblock friend (error %d)\n", err); line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Failed to unblock friend (error %d)\n"), err);
return; return;
} }
@ -757,7 +763,7 @@ static void friendlist_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
Friends.list[f].chatwin = add_window(m, new_chat(m, Friends.list[f].num)); Friends.list[f].chatwin = add_window(m, new_chat(m, Friends.list[f].num));
set_active_window(Friends.list[f].chatwin); set_active_window(Friends.list[f].chatwin);
} else { } else {
const char *msg = "* Warning: Too many windows are open."; const char *msg = gettext("* Warning: Too many windows are open.");
line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, msg); line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, msg);
sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL); sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL);
} }
@ -794,7 +800,7 @@ static void friendlist_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
static void blocklist_onDraw(ToxWindow *self, Tox *m, int y2, int x2) static void blocklist_onDraw(ToxWindow *self, Tox *m, int y2, int x2)
{ {
wattron(self->window, A_BOLD); wattron(self->window, A_BOLD);
wprintw(self->window, " Blocked: "); wprintw(self->window, gettext(" Blocked: "));
wattroff(self->window, A_BOLD); wattroff(self->window, A_BOLD);
wprintw(self->window, "%d\n\n", Blocked.num_blocked); wprintw(self->window, "%d\n\n", Blocked.num_blocked);
@ -846,7 +852,7 @@ static void blocklist_onDraw(ToxWindow *self, Tox *m, int y2, int x2)
wmove(self->window, y2 - 1, 1); wmove(self->window, y2 - 1, 1);
wattron(self->window, A_BOLD); wattron(self->window, A_BOLD);
wprintw(self->window, "Key: "); wprintw(self->window, gettext("Key: "));
wattroff(self->window, A_BOLD); wattroff(self->window, A_BOLD);
int i; int i;
@ -872,11 +878,11 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
bool fix_statuses = x2 != self->x; /* true if window max x value has changed */ bool fix_statuses = x2 != self->x; /* true if window max x value has changed */
wattron(self->window, COLOR_PAIR(CYAN)); wattron(self->window, COLOR_PAIR(CYAN));
wprintw(self->window, " Press the"); wprintw(self->window, gettext(" Press the"));
wattron(self->window, A_BOLD); wattron(self->window, A_BOLD);
wprintw(self->window, " h "); wprintw(self->window, " h ");
wattroff(self->window, A_BOLD); wattroff(self->window, A_BOLD);
wprintw(self->window, "key for help\n\n"); wprintw(self->window, gettext("key for help\n\n"));
wattroff(self->window, COLOR_PAIR(CYAN)); wattroff(self->window, COLOR_PAIR(CYAN));
if (blocklist_view == 1) { if (blocklist_view == 1) {
@ -888,7 +894,7 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
struct tm cur_loc_tm = *localtime((const time_t *) &cur_time); struct tm cur_loc_tm = *localtime((const time_t *) &cur_time);
wattron(self->window, A_BOLD); wattron(self->window, A_BOLD);
wprintw(self->window, " Online: "); wprintw(self->window, gettext(" Online: "));
wattroff(self->window, A_BOLD); wattroff(self->window, A_BOLD);
wprintw(self->window, "%d/%d \n\n", Friends.num_online, Friends.num_friends); wprintw(self->window, "%d/%d \n\n", Friends.num_online, Friends.num_friends);
@ -1002,19 +1008,19 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
switch (day_dist) { switch (day_dist) {
case 0: case 0:
wprintw(self->window, " Last seen: Today %s\n", hourmin); wprintw(self->window, gettext(" Last seen: Today %s\n"), hourmin);
break; break;
case 1: case 1:
wprintw(self->window, " Last seen: Yesterday %s\n", hourmin); wprintw(self->window, gettext(" Last seen: Yesterday %s\n"), hourmin);
break; break;
default: default:
wprintw(self->window, " Last seen: %d days ago\n", day_dist); wprintw(self->window, gettext(" Last seen: %d days ago\n"), day_dist);
break; break;
} }
} else { } else {
wprintw(self->window, " Last seen: Never\n"); wprintw(self->window, gettext(" Last seen: Never\n"));
} }
} }
} }
@ -1026,7 +1032,7 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
wmove(self->window, y2 - 1, 1); wmove(self->window, y2 - 1, 1);
wattron(self->window, A_BOLD); wattron(self->window, A_BOLD);
wprintw(self->window, "Key: "); wprintw(self->window, gettext("Key: "));
wattroff(self->window, A_BOLD); wattroff(self->window, A_BOLD);
int i; int i;
@ -1066,7 +1072,7 @@ static void friendlist_onAV(ToxWindow *self, ToxAV *av, uint32_t friend_number,
get_nick_truncate(m, nick, Friends.list[friend_number].num); get_nick_truncate(m, nick, Friends.list[friend_number].num);
line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Audio action from: %s!", nick); line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Audio action from: %s!", nick);
const char *errmsg = "* Warning: Too many windows are open."; const char *errmsg = gettext("* Warning: Too many windows are open.");
line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, errmsg); line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, errmsg);
sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL); sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL);
@ -1116,9 +1122,9 @@ ToxWindow new_friendlist(void)
Help *help = calloc(1, sizeof(Help)); Help *help = calloc(1, sizeof(Help));
if (help == NULL) if (help == NULL)
exit_toxic_err("failed in new_friendlist", FATALERR_MEMORY); exit_toxic_err(gettext("failed in new_friendlist"), FATALERR_MEMORY);
ret.help = help; ret.help = help;
strcpy(ret.name, "contacts"); strcpy(ret.name, gettext("contacts"));
return ret; return ret;
} }

View File

@ -24,6 +24,12 @@
#include <string.h> #include <string.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#ifdef NO_GETTEXT
#define gettext(A) (A)
#else
#include <libintl.h>
#endif
#include "toxic.h" #include "toxic.h"
#include "windows.h" #include "windows.h"
#include "misc_tools.h" #include "misc_tools.h"
@ -46,19 +52,19 @@ extern FriendRequests FrndRequests;
void cmd_accept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_accept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{ {
if (argc < 1) { if (argc < 1) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Request ID required."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Request ID required."));
return; return;
} }
int req = atoi(argv[1]); int req = atoi(argv[1]);
if ((req == 0 && strcmp(argv[1], "0")) || req < 0 || req > MAX_FRIEND_REQUESTS) { if ((req == 0 && strcmp(argv[1], "0")) || req < 0 || req > MAX_FRIEND_REQUESTS) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending friend request with that ID."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("No pending friend request with that ID."));
return; return;
} }
if (!FrndRequests.request[req].active) { if (!FrndRequests.request[req].active) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending friend request with that ID."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("No pending friend request with that ID."));
return; return;
} }
@ -66,10 +72,10 @@ void cmd_accept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
uint32_t friendnum = tox_friend_add_norequest(m, FrndRequests.request[req].key, &err); uint32_t friendnum = tox_friend_add_norequest(m, FrndRequests.request[req].key, &err);
if (err != TOX_ERR_FRIEND_ADD_OK) { if (err != TOX_ERR_FRIEND_ADD_OK) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to add friend (error %d\n)", err); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Failed to add friend (error %d)\n"), err);
return; return;
} else { } else {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Friend request accepted."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Friend request accepted."));
on_friendadded(m, friendnum, true); on_friendadded(m, friendnum, true);
} }
@ -96,42 +102,42 @@ void cmd_add_helper(ToxWindow *self, Tox *m, const char *id_bin, const char *msg
switch (err) { switch (err) {
case TOX_ERR_FRIEND_ADD_TOO_LONG: case TOX_ERR_FRIEND_ADD_TOO_LONG:
errmsg = "Message is too long."; errmsg = gettext("Message is too long.");
break; break;
case TOX_ERR_FRIEND_ADD_NO_MESSAGE: case TOX_ERR_FRIEND_ADD_NO_MESSAGE:
errmsg = "Please add a message to your request."; errmsg = gettext("Please add a message to your request.");
break; break;
case TOX_ERR_FRIEND_ADD_OWN_KEY: case TOX_ERR_FRIEND_ADD_OWN_KEY:
errmsg = "That appears to be your own ID."; errmsg = gettext("That appears to be your own ID.");
break; break;
case TOX_ERR_FRIEND_ADD_ALREADY_SENT: case TOX_ERR_FRIEND_ADD_ALREADY_SENT:
errmsg = "Friend request has already been sent."; errmsg = gettext("Friend request has already been sent.");
break; break;
case TOX_ERR_FRIEND_ADD_BAD_CHECKSUM: case TOX_ERR_FRIEND_ADD_BAD_CHECKSUM:
errmsg = "Bad checksum in address."; errmsg = gettext("Bad checksum in address.");
break; break;
case TOX_ERR_FRIEND_ADD_SET_NEW_NOSPAM: case TOX_ERR_FRIEND_ADD_SET_NEW_NOSPAM:
errmsg = "Nospam was different."; errmsg = gettext("Nospam was different.");
break; break;
case TOX_ERR_FRIEND_ADD_MALLOC: case TOX_ERR_FRIEND_ADD_MALLOC:
errmsg = "Core memory allocation failed."; errmsg = gettext("Core memory allocation failed.");
break; break;
case TOX_ERR_FRIEND_ADD_OK: case TOX_ERR_FRIEND_ADD_OK:
errmsg = "Friend request sent."; errmsg = gettext("Friend request sent.");
on_friendadded(m, f_num, true); on_friendadded(m, f_num, true);
break; break;
case TOX_ERR_FRIEND_ADD_NULL: case TOX_ERR_FRIEND_ADD_NULL:
/* fallthrough */ /* fallthrough */
default: default:
errmsg = "Faile to add friend: Unknown error."; errmsg = gettext("Failed to add friend: Unknown error.");
break; break;
} }
@ -141,7 +147,7 @@ void cmd_add_helper(ToxWindow *self, Tox *m, const char *id_bin, const char *msg
void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{ {
if (argc < 1) { if (argc < 1) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Tox ID or address required."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Tox ID or address required."));
return; return;
} }
@ -150,7 +156,7 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
if (argc > 1) { if (argc > 1) {
if (argv[2][0] != '\"') { if (argv[2][0] != '\"') {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Message must be enclosed in quotes."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Message must be enclosed in quotes."));
return; return;
} }
@ -166,7 +172,7 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
size_t n_len = tox_self_get_name_size(m); size_t n_len = tox_self_get_name_size(m);
selfname[n_len] = '\0'; selfname[n_len] = '\0';
snprintf(msg, sizeof(msg), "Hello, my name is %s. Care to Tox?", selfname); snprintf(msg, sizeof(msg), gettext("Hello, my name is %s. Care to Tox?"), selfname);
} }
char id_bin[TOX_ADDRESS_SIZE] = {0}; char id_bin[TOX_ADDRESS_SIZE] = {0};
@ -184,7 +190,7 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
xx[2] = '\0'; xx[2] = '\0';
if (sscanf(xx, "%02x", &x) != 1) { if (sscanf(xx, "%02x", &x) != 1) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid Tox ID."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid Tox ID."));
return; return;
} }
@ -201,12 +207,12 @@ void cmd_avatar(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
{ {
if (argc < 2 || strlen(argv[1]) < 3) { if (argc < 2 || strlen(argv[1]) < 3) {
avatar_unset(m); avatar_unset(m);
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Avatar is not set."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Avatar is not set."));
return; return;
} }
if (argv[1][0] != '\"') { if (argv[1][0] != '\"') {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Path must be enclosed in quotes."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Path must be enclosed in quotes."));
return; return;
} }
@ -216,7 +222,7 @@ void cmd_avatar(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
int len = strlen(path) - 1; int len = strlen(path) - 1;
if (len <= 0) { if (len <= 0) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid path."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid path."));
return; return;
} }
@ -226,12 +232,12 @@ void cmd_avatar(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
if (avatar_set(m, path, len) == -1) { if (avatar_set(m, path, len) == -1) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0,
"Failed to set avatar. Avatars must be in PNG format and may not exceed %d bytes.", gettext("Failed to set avatar. Avatars must be in PNG format and may not exceed %d bytes."),
MAX_AVATAR_FILE_SIZE); MAX_AVATAR_FILE_SIZE);
return; return;
} }
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Avatar set to '%s'", filename); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Avatar set to '%s'"), filename);
} }
void cmd_clear(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_clear(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
@ -243,7 +249,7 @@ void cmd_clear(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[M
void cmd_connect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_connect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{ {
if (argc != 3) { if (argc != 3) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Require: <ip> <port> <key>"); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Require: <ip> <port> <key>"));
return; return;
} }
@ -252,7 +258,7 @@ void cmd_connect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)
const char *key = argv[3]; const char *key = argv[3];
if (atoi(port) == 0) { if (atoi(port) == 0) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid port."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid port."));
return; return;
} }
@ -265,15 +271,15 @@ void cmd_connect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)
switch (err) { switch (err) {
case TOX_ERR_BOOTSTRAP_BAD_HOST: case TOX_ERR_BOOTSTRAP_BAD_HOST:
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Bootstrap failed: Invalid IP."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Bootstrap failed: Invalid IP."));
break; break;
case TOX_ERR_BOOTSTRAP_BAD_PORT: case TOX_ERR_BOOTSTRAP_BAD_PORT:
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Bootstrap failed: Invalid port."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Bootstrap failed: Invalid port."));
break; break;
case TOX_ERR_BOOTSTRAP_NULL: case TOX_ERR_BOOTSTRAP_NULL:
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Bootstrap failed."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Bootstrap failed."));
break; break;
default: default:
break; break;
@ -283,19 +289,19 @@ void cmd_connect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)
void cmd_decline(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_decline(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{ {
if (argc < 1) { if (argc < 1) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Request ID required."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Request ID required."));
return; return;
} }
int req = atoi(argv[1]); int req = atoi(argv[1]);
if ((req == 0 && strcmp(argv[1], "0")) || req < 0 || req > MAX_FRIEND_REQUESTS) { if ((req == 0 && strcmp(argv[1], "0")) || req < 0 || req > MAX_FRIEND_REQUESTS) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending friend request with that ID."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("No pending friend request with that ID."));
return; return;
} }
if (!FrndRequests.request[req].active) { if (!FrndRequests.request[req].active) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending friend request with that ID."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("No pending friend request with that ID."));
return; return;
} }
@ -315,12 +321,12 @@ void cmd_decline(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)
void cmd_groupchat(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_groupchat(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{ {
if (get_num_active_windows() >= MAX_WINDOWS_NUM) { if (get_num_active_windows() >= MAX_WINDOWS_NUM) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, " * Warning: Too many windows are open."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, gettext(" * Warning: Too many windows are open."));
return; return;
} }
if (argc < 1) { if (argc < 1) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Please specify group type: text | audio"); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Please specify group type: %s"), "text|audio");
return; return;
} }
@ -331,7 +337,7 @@ void cmd_groupchat(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*arg
else if (!strcasecmp(argv[1], "text")) else if (!strcasecmp(argv[1], "text"))
type = TOX_GROUPCHAT_TYPE_TEXT; type = TOX_GROUPCHAT_TYPE_TEXT;
else { else {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Valid group types are: text | audio"); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Valid group types are: %s"), "text|audio");
return; return;
} }
@ -345,17 +351,17 @@ void cmd_groupchat(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*arg
#endif*/ #endif*/
if (groupnum == -1) { if (groupnum == -1) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group chat instance failed to initialize."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Group chat instance failed to initialize."));
return; return;
} }
if (init_groupchat_win(prompt, m, groupnum, type) == -1) { if (init_groupchat_win(prompt, m, groupnum, type) == -1) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group chat window failed to initialize."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Group chat window failed to initialize."));
tox_del_groupchat(m, groupnum); tox_del_groupchat(m, groupnum);
return; return;
} }
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group chat [%d] created.", groupnum); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Group chat [%d] created."), groupnum);
} }
void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
@ -365,9 +371,9 @@ void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
if (argc == 0) { if (argc == 0) {
if (log->log_on) if (log->log_on)
msg = "Logging for this window is ON. Type \"/log off\" to disable."; msg = gettext("Logging for this window is ON. Type \"/log off\" to disable.");
else else
msg = "Logging for this window is OFF. Type \"/log on\" to enable."; msg = gettext("Logging for this window is OFF. Type \"/log on\" to enable.");
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg);
return; return;
@ -388,7 +394,7 @@ void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
log_enable(self->name, myid, NULL, log, LOG_GROUP); log_enable(self->name, myid, NULL, log, LOG_GROUP);
} }
msg = "Logging enabled"; msg = gettext("Logging enabled");
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg);
return; return;
} else if (!strcmp(swch, "0") || !strcmp(swch, "off")) { } else if (!strcmp(swch, "0") || !strcmp(swch, "off")) {
@ -397,13 +403,13 @@ void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
log_disable(log); log_disable(log);
msg = "Logging disabled"; msg = gettext("Logging disabled");
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg);
return; return;
} }
msg = "Invalid option. Use \"/log on\" and \"/log off\" to toggle logging."; msg = gettext("Invalid option. Use \"%s\" to toggle logging.");
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg, "/log on|off");
} }
void cmd_myid(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_myid(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
@ -426,7 +432,7 @@ void cmd_myid(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
void cmd_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{ {
if (argc < 1) { if (argc < 1) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Input required."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Input required."));
return; return;
} }
@ -443,7 +449,7 @@ void cmd_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
} }
if (!valid_nick(nick)) { if (!valid_nick(nick)) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid name."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Invalid name."));
return; return;
} }
@ -459,12 +465,12 @@ void cmd_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
void cmd_note(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_note(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{ {
if (argc < 1) { if (argc < 1) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Input required."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Input required."));
return; return;
} }
if (argv[1][0] != '\"') { if (argv[1][0] != '\"') {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Note must be enclosed in quotes."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Note must be enclosed in quotes."));
return; return;
} }
@ -490,7 +496,7 @@ void cmd_quit(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
void cmd_requests(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_requests(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{ {
if (FrndRequests.num_requests == 0) { if (FrndRequests.num_requests == 0) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending friend requests."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("No pending friend requests."));
return; return;
} }
@ -527,8 +533,8 @@ void cmd_status(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
if (argc >= 2) { if (argc >= 2) {
have_note = true; have_note = true;
} else if (argc < 1) { } else if (argc < 1) {
errmsg = "Require a status. Statuses are: online, busy and away."; errmsg = gettext("Require a status. Statuses are: %s.");
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg, "online|busy|away");
goto finish; goto finish;
} }
@ -542,8 +548,8 @@ void cmd_status(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
else if (!strcasecmp(status_str, "busy")) else if (!strcasecmp(status_str, "busy"))
status = TOX_USER_STATUS_BUSY; status = TOX_USER_STATUS_BUSY;
else { else {
errmsg = "Invalid status. Valid statuses are: online, busy and away."; errmsg = gettext("Invalid status. Valid statuses are: %s.");
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg, "online|busy|away");
goto finish; goto finish;
} }
@ -552,7 +558,7 @@ void cmd_status(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
if (have_note) { if (have_note) {
if (argv[2][0] != '\"') { if (argv[2][0] != '\"') {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Note must be enclosed in quotes."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Note must be enclosed in quotes."));
goto finish; goto finish;
} }

View File

@ -22,6 +22,12 @@
#include <string.h> #include <string.h>
#ifdef NO_GETTEXT
#define gettext(A) (A)
#else
#include <libintl.h>
#endif
#include "toxic.h" #include "toxic.h"
#include "windows.h" #include "windows.h"
#include "line_info.h" #include "line_info.h"
@ -37,16 +43,16 @@ void cmd_set_title(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*arg
if (tlen != -1) { if (tlen != -1) {
title[tlen] = '\0'; title[tlen] = '\0';
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Title is set to: %s", title); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Title is set to: %s"), title);
} else { } else {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Title is not set"); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Title is not set"));
} }
return; return;
} }
if (argv[1][0] != '\"') { if (argv[1][0] != '\"') {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Title must be enclosed in quotes."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Title must be enclosed in quotes."));
return; return;
} }
@ -56,7 +62,7 @@ void cmd_set_title(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*arg
title[len] = '\0'; title[len] = '\0';
if (tox_group_set_title(m, self->num, (uint8_t *) title, len) != 0) { if (tox_group_set_title(m, self->num, (uint8_t *) title, len) != 0) {
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set title."); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Failed to set title."));
return; return;
} }
@ -71,9 +77,9 @@ void cmd_set_title(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*arg
size_t sn_len = tox_self_get_name_size(m); size_t sn_len = tox_self_get_name_size(m);
selfnick[sn_len] = '\0'; selfnick[sn_len] = '\0';
line_info_add(self, timefrmt, selfnick, NULL, NAME_CHANGE, 0, 0, " set the group title to: %s", title); line_info_add(self, timefrmt, selfnick, NULL, NAME_CHANGE, 0, 0, gettext(" set the group title to: %s"), title);
char tmp_event[MAX_STR_SIZE]; char tmp_event[MAX_STR_SIZE];
snprintf(tmp_event, sizeof(tmp_event), "set title to %s", title); snprintf(tmp_event, sizeof(tmp_event), gettext("set title to %s"), title);
write_to_log(tmp_event, selfnick, self->chatwin->log, true); write_to_log(tmp_event, selfnick, self->chatwin->log, true);
} }

View File

@ -31,6 +31,12 @@
#include <wchar.h> #include <wchar.h>
#include <unistd.h> #include <unistd.h>
#ifdef NO_GETTEXT
#define gettext(A) (A)
#else
#include <libintl.h>
#endif
#ifdef AUDIO #ifdef AUDIO
#ifdef __APPLE__ #ifdef __APPLE__
#include <OpenAL/al.h> #include <OpenAL/al.h>
@ -134,7 +140,7 @@ int init_groupchat_win(ToxWindow *prompt, Tox *m, int groupnum, uint8_t type)
if (groupchats[i].peer_names == NULL || groupchats[i].oldpeer_names == NULL if (groupchats[i].peer_names == NULL || groupchats[i].oldpeer_names == NULL
|| groupchats[i].peer_name_lengths == NULL || groupchats[i].oldpeer_name_lengths == NULL) || groupchats[i].peer_name_lengths == NULL || groupchats[i].oldpeer_name_lengths == NULL)
exit_toxic_err("failed in init_groupchat_win", FATALERR_MEMORY); exit_toxic_err(gettext("failed in init_groupchat_win"), FATALERR_MEMORY);
memcpy(&groupchats[i].oldpeer_names[0], UNKNOWN_NAME, sizeof(UNKNOWN_NAME)); memcpy(&groupchats[i].oldpeer_names[0], UNKNOWN_NAME, sizeof(UNKNOWN_NAME));
groupchats[i].oldpeer_name_lengths[0] = (uint16_t) strlen(UNKNOWN_NAME); groupchats[i].oldpeer_name_lengths[0] = (uint16_t) strlen(UNKNOWN_NAME);
@ -142,7 +148,7 @@ int init_groupchat_win(ToxWindow *prompt, Tox *m, int groupnum, uint8_t type)
#ifdef AUDIO #ifdef AUDIO
if (type == TOX_GROUPCHAT_TYPE_AV) if (type == TOX_GROUPCHAT_TYPE_AV)
if (group_audio_open_out_device(i) == -1) if (group_audio_open_out_device(i) == -1)
fprintf(stderr, "Group Audio failed to init\n"); fprintf(stderr, gettext("Group Audio failed to init\n"));
#endif /* AUDIO */ #endif /* AUDIO */
set_active_window(groupchats[i].chatwin); set_active_window(groupchats[i].chatwin);
@ -328,10 +334,10 @@ static void groupchat_onGroupTitleChange(ToxWindow *self, Tox *m, int groupnum,
char nick[TOX_MAX_NAME_LENGTH]; char nick[TOX_MAX_NAME_LENGTH];
get_group_nick_truncate(m, nick, peernum, groupnum); get_group_nick_truncate(m, nick, peernum, groupnum);
line_info_add(self, timefrmt, nick, NULL, NAME_CHANGE, 0, 0, " set the group title to: %s", title); line_info_add(self, timefrmt, nick, NULL, NAME_CHANGE, 0, 0, gettext(" set the group title to: %s"), title);
char tmp_event[MAX_STR_SIZE]; char tmp_event[MAX_STR_SIZE];
snprintf(tmp_event, sizeof(tmp_event), "set title to %s", title); snprintf(tmp_event, sizeof(tmp_event), gettext("set title to %s"), title);
write_to_log(tmp_event, nick, ctx->log, true); write_to_log(tmp_event, nick, ctx->log, true);
} }
@ -353,7 +359,7 @@ static void copy_peernames(int gnum, uint8_t peerlist[][TOX_MAX_NAME_LENGTH], ui
if (groupchats[gnum].peer_names == NULL || groupchats[gnum].oldpeer_names == NULL if (groupchats[gnum].peer_names == NULL || groupchats[gnum].oldpeer_names == NULL
|| groupchats[gnum].peer_name_lengths == NULL || groupchats[gnum].oldpeer_name_lengths == NULL) { || groupchats[gnum].peer_name_lengths == NULL || groupchats[gnum].oldpeer_name_lengths == NULL) {
exit_toxic_err("failed in copy_peernames", FATALERR_MEMORY); exit_toxic_err(gettext("failed in copy_peernames"), FATALERR_MEMORY);
} }
uint16_t u_len = strlen(UNKNOWN_NAME); uint16_t u_len = strlen(UNKNOWN_NAME);
@ -410,7 +416,7 @@ void *group_add_wait(void *data)
pthread_mutex_unlock(&Winthread.lock); pthread_mutex_unlock(&Winthread.lock);
} }
const char *event = "has joined the room"; const char *event = gettext("has joined the room");
char timefrmt[TIME_STR_SIZE]; char timefrmt[TIME_STR_SIZE];
get_time_str(timefrmt, sizeof(timefrmt)); get_time_str(timefrmt, sizeof(timefrmt));
@ -508,7 +514,7 @@ static void groupchat_onGroupNamelistChange(ToxWindow *self, Tox *m, int groupnu
break; break;
case TOX_CHAT_CHANGE_PEER_DEL: case TOX_CHAT_CHANGE_PEER_DEL:
event = "has left the room"; event = gettext("has left the room");
line_info_add(self, timefrmt, (char *) oldpeername, NULL, DISCONNECTION, 0, RED, event); line_info_add(self, timefrmt, (char *) oldpeername, NULL, DISCONNECTION, 0, RED, event);
if (groupchats[self->num].side_pos > 0) if (groupchats[self->num].side_pos > 0)
@ -525,11 +531,11 @@ static void groupchat_onGroupNamelistChange(ToxWindow *self, Tox *m, int groupnu
if (strcmp((char *) oldpeername, DEFAULT_TOX_NAME) == 0) if (strcmp((char *) oldpeername, DEFAULT_TOX_NAME) == 0)
return; return;
event = " is now known as "; event = gettext(" is now known as ");
line_info_add(self, timefrmt, (char *) oldpeername, (char *) peername, NAME_CHANGE, 0, 0, event); line_info_add(self, timefrmt, (char *) oldpeername, (char *) peername, NAME_CHANGE, 0, 0, event);
char tmp_event[TOXIC_MAX_NAME_LENGTH * 2 + 32]; char tmp_event[TOXIC_MAX_NAME_LENGTH * 2 + 32];
snprintf(tmp_event, sizeof(tmp_event), "is now known as %s", (char *) peername); snprintf(tmp_event, sizeof(tmp_event), gettext("is now known as %s"), (char *) peername);
write_to_log(tmp_event, (char *) oldpeername, ctx->log, true); write_to_log(tmp_event, (char *) oldpeername, ctx->log, true);
break; break;
} }
@ -540,12 +546,12 @@ static void groupchat_onGroupNamelistChange(ToxWindow *self, Tox *m, int groupnu
static void send_group_action(ToxWindow *self, ChatContext *ctx, Tox *m, char *action) static void send_group_action(ToxWindow *self, ChatContext *ctx, Tox *m, char *action)
{ {
if (action == NULL) { if (action == NULL) {
wprintw(ctx->history, "Invalid syntax.\n"); wprintw(ctx->history, gettext("Invalid syntax.\n"));
return; return;
} }
if (tox_group_action_send(m, self->num, (uint8_t *) action, strlen(action)) == -1) { if (tox_group_action_send(m, self->num, (uint8_t *) action, strlen(action)) == -1) {
const char *errmsg = " * Failed to send action."; const char *errmsg = gettext(" * Failed to send action.");
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, errmsg); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, errmsg);
} }
} }
@ -632,7 +638,7 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
} }
} else if (!string_is_empty(line)) { } else if (!string_is_empty(line)) {
if (tox_group_message_send(m, self->num, (uint8_t *) line, strlen(line)) == -1) { if (tox_group_message_send(m, self->num, (uint8_t *) line, strlen(line)) == -1) {
const char *errmsg = " * Failed to send message."; const char *errmsg = gettext(" * Failed to send message.");
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, errmsg); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, errmsg);
} }
} }
@ -669,7 +675,7 @@ static void groupchat_onDraw(ToxWindow *self, Tox *m)
wmove(ctx->sidebar, 0, 1); wmove(ctx->sidebar, 0, 1);
wattron(ctx->sidebar, A_BOLD); wattron(ctx->sidebar, A_BOLD);
wprintw(ctx->sidebar, "Peers: %d\n", num_peers); wprintw(ctx->sidebar, gettext("Peers: %d\n"), num_peers);
wattroff(ctx->sidebar, A_BOLD); wattroff(ctx->sidebar, A_BOLD);
mvwaddch(ctx->sidebar, 1, 0, ACS_LTEE); mvwaddch(ctx->sidebar, 1, 0, ACS_LTEE);
@ -719,7 +725,7 @@ static void groupchat_onInit(ToxWindow *self, Tox *m)
ctx->log = calloc(1, sizeof(struct chatlog)); ctx->log = calloc(1, sizeof(struct chatlog));
if (ctx->log == NULL || ctx->hst == NULL) if (ctx->log == NULL || ctx->hst == NULL)
exit_toxic_err("failed in groupchat_onInit", FATALERR_MEMORY); exit_toxic_err(gettext("failed in groupchat_onInit"), FATALERR_MEMORY);
line_info_init(ctx->hst); line_info_init(ctx->hst);
@ -804,7 +810,7 @@ static int group_audio_write(int peernum, int groupnum, const int16_t *pcm, unsi
alGetSourcei(groupchats[groupnum].audio.source, AL_BUFFERS_PROCESSED, &processed); alGetSourcei(groupchats[groupnum].audio.source, AL_BUFFERS_PROCESSED, &processed);
alGetSourcei(groupchats[groupnum].audio.source, AL_BUFFERS_QUEUED, &queued); alGetSourcei(groupchats[groupnum].audio.source, AL_BUFFERS_QUEUED, &queued);
fprintf(stderr, "source: %d, queued: %d, processed: %d\n", groupchats[groupnum].audio.source, queued, processed); fprintf(stderr, gettext("source: %d, queued: %d, processed: %d\n"), groupchats[groupnum].audio.source, queued, processed);
if (processed) { if (processed) {
ALuint bufids[processed]; ALuint bufids[processed];
@ -843,13 +849,13 @@ static void groupchat_onWriteDevice(ToxWindow *self, Tox *m, int groupnum, int p
return; return;
if (groupchats[groupnum].audio.dvhandle == NULL) if (groupchats[groupnum].audio.dvhandle == NULL)
fprintf(stderr, "dvhandle is null)\n"); fprintf(stderr, gettext("dvhandle is null)\n"));
if (groupchats[groupnum].audio.dvctx == NULL) if (groupchats[groupnum].audio.dvctx == NULL)
fprintf(stderr, "ctx is null\n"); fprintf(stderr, gettext("ctx is null\n"));
int ret = group_audio_write(peernum, groupnum, pcm, samples, channels, sample_rate); int ret = group_audio_write(peernum, groupnum, pcm, samples, channels, sample_rate);
fprintf(stderr, "write: %d\n", ret); fprintf(stderr, gettext("write: %d\n"), ret);
} }
#endif /* AUDIO */ #endif /* AUDIO */
@ -873,13 +879,13 @@ ToxWindow new_group_chat(Tox *m, int groupnum)
ret.onWriteDevice = &groupchat_onWriteDevice; ret.onWriteDevice = &groupchat_onWriteDevice;
#endif #endif
snprintf(ret.name, sizeof(ret.name), "Group %d", groupnum); snprintf(ret.name, sizeof(ret.name), gettext("Group %d"), groupnum);
ChatContext *chatwin = calloc(1, sizeof(ChatContext)); ChatContext *chatwin = calloc(1, sizeof(ChatContext));
Help *help = calloc(1, sizeof(Help)); Help *help = calloc(1, sizeof(Help));
if (chatwin == NULL || help == NULL) if (chatwin == NULL || help == NULL)
exit_toxic_err("failed in new_group_chat", FATALERR_MEMORY); exit_toxic_err(gettext("failed in new_group_chat"), FATALERR_MEMORY);
ret.chatwin = chatwin; ret.chatwin = chatwin;
ret.help = help; ret.help = help;

View File

@ -22,6 +22,12 @@
#include <string.h> #include <string.h>
#ifdef NO_GETTEXT
#define gettext(A) (A)
#else
#include <libintl.h>
#endif
#include "windows.h" #include "windows.h"
#include "toxic.h" #include "toxic.h"
#include "help.h" #include "help.h"
@ -139,32 +145,50 @@ static void help_draw_global(ToxWindow *self)
wmove(win, 1, 1); wmove(win, 1, 1);
wattron(win, A_BOLD | COLOR_PAIR(RED)); wattron(win, A_BOLD | COLOR_PAIR(RED));
wprintw(win, "Global Commands:\n"); wprintw(win, gettext("Global Commands:\n"));
wattroff(win, A_BOLD | COLOR_PAIR(RED)); wattroff(win, A_BOLD | COLOR_PAIR(RED));
wprintw(win, " /add <addr> <msg> : Add contact with optional message\n"); wprintw(win, " /add <ToxID> <msg> : ");
wprintw(win, " /accept <id> : Accept friend request\n"); wprintw(win, gettext("Add contact with optional message\n"));
wprintw(win, " /avatar <path> : Set an avatar (leave path empty to unset)\n"); wprintw(win, " /accept <id> : ");
wprintw(win, " /decline <id> : Decline friend request\n"); wprintw(win, gettext("Accept friend request\n"));
wprintw(win, " /requests : List pending friend requests\n"); wprintw(win, " /avatar <path> : ");
wprintw(win, " /connect <ip> <port> <key> : Manually connect to a DHT node\n"); wprintw(win, gettext("Set an avatar (leave path empty to unset)\n"));
wprintw(win, " /status <type> <msg> : Set status with optional note\n"); wprintw(win, " /decline <id> : ");
wprintw(win, " /note <msg> : Set a personal note\n"); wprintw(win, gettext("Decline friend request\n"));
wprintw(win, " /nick <nick> : Set your nickname\n"); wprintw(win, " /requests : ");
wprintw(win, " /log <on> or <off> : Enable/disable logging\n"); wprintw(win, gettext("List pending friend requests\n"));
wprintw(win, " /group <type> : Create a group chat where type: text | audio\n"); wprintw(win, " /connect <ip> <port> <key> : ");
wprintw(win, " /myid : Print your Tox ID\n"); wprintw(win, gettext("Manually connect to a DHT node\n"));
wprintw(win, " /clear : Clear window history\n"); wprintw(win, " /status <type> <msg> : ");
wprintw(win, " /close : Close the current chat window\n"); wprintw(win, gettext("Set status with optional note\n"));
wprintw(win, " /quit or /exit : Exit Toxic\n"); wprintw(win, " /note <msg> : ");
wprintw(win, gettext("Set a personal note\n"));
wprintw(win, " /nick <nick> : ");
wprintw(win, gettext("Set your nickname\n"));
wprintw(win, " /log <on> or <off> : ");
wprintw(win, gettext("Enable/disable logging\n"));
wprintw(win, " /group <type> : ");
wprintw(win, gettext("Create a group chat where type: text | audio\n"));
wprintw(win, " /myid : ");
wprintw(win, gettext("Print your Tox ID\n"));
wprintw(win, " /clear : ");
wprintw(win, gettext("Clear window history\n"));
wprintw(win, " /close : ");
wprintw(win, gettext("Close the current chat window\n"));
wprintw(win, " /quit or /exit : ");
wprintw(win, gettext("Exit Toxic\n"));
#ifdef AUDIO #ifdef AUDIO
wattron(win, A_BOLD); wattron(win, A_BOLD);
wprintw(win, "\n Audio:\n"); wprintw(win, gettext("\n Audio:\n"));
wattroff(win, A_BOLD); wattroff(win, A_BOLD);
wprintw(win, " /lsdev <type> : List devices where type: in|out\n"); wprintw(win, " /lsdev <type> : ");
wprintw(win, " /sdev <type> <id> : Set active device\n"); wprintw(win, gettext("List devices where type:"));
wprintw(win, " in|out\n");
wprintw(win, " /sdev <type> <id> : ");
wprintw(win, gettext("Set active device\n"));
#endif /* AUDIO */ #endif /* AUDIO */
help_draw_bottom_menu(win); help_draw_bottom_menu(win);
@ -180,27 +204,40 @@ static void help_draw_chat(ToxWindow *self)
wmove(win, 1, 1); wmove(win, 1, 1);
wattron(win, A_BOLD | COLOR_PAIR(RED)); wattron(win, A_BOLD | COLOR_PAIR(RED));
wprintw(win, "Chat Commands:\n"); wprintw(win, gettext("Chat Commands:\n"));
wattroff(win, A_BOLD | COLOR_PAIR(RED)); wattroff(win, A_BOLD | COLOR_PAIR(RED));
wprintw(win, " /invite <n> : Invite contact to a group chat\n"); wprintw(win, " /invite <n> : ");
wprintw(win, " /join : Join a pending group chat\n"); wprintw(win, gettext("Invite contact to a group chat\n"));
wprintw(win, " /sendfile <path> : Send a file\n"); wprintw(win, " /join : ");
wprintw(win, " /savefile <id> : Receive a file\n"); wprintw(win, gettext("Join a pending group chat\n"));
wprintw(win, " /cancel <type> <id> : Cancel file transfer where type: in|out\n"); wprintw(win, " /sendfile <path> : ");
wprintw(win, gettext("Send a file\n"));
wprintw(win, " /savefile <id> : ");
wprintw(win, gettext("Receive a file\n"));
wprintw(win, " /cancel <type> <id> : ");
wprintw(win, gettext("Cancel file transfer where type:"));
wprintw(win, " in|out\n");
#ifdef AUDIO #ifdef AUDIO
wattron(win, A_BOLD); wattron(win, A_BOLD);
wprintw(win, "\n Audio:\n"); wprintw(win, gettext("\n Audio:\n"));
wattroff(win, A_BOLD); wattroff(win, A_BOLD);
wprintw(win, " /call : Audio call\n"); wprintw(win, " /call : ");
wprintw(win, " /answer : Answer incoming call\n"); wprintw(win, gettext("Audio call\n"));
wprintw(win, " /reject : Reject incoming call\n"); wprintw(win, " /answer : ");
wprintw(win, " /hangup : Hangup active call\n"); wprintw(win, gettext("Answer incoming call\n"));
wprintw(win, " /sdev <type> <id> : Change active device\n"); wprintw(win, " /reject : ");
wprintw(win, " /mute <type> : Mute active device if in call\n"); wprintw(win, gettext("Reject incoming call\n"));
wprintw(win, " /sense <n> : VAD sensitivity threshold\n"); wprintw(win, " /hangup : ");
wprintw(win, gettext("Hangup active call\n"));
wprintw(win, " /sdev <type> <id> : ");
wprintw(win, gettext("Change active device\n"));
wprintw(win, " /mute <type> : ");
wprintw(win, gettext("Mute active device if in call\n"));
wprintw(win, " /sense <n> : ");
wprintw(win, gettext("VAD sensitivity threshold\n"));
#endif /* AUDIO */ #endif /* AUDIO */
help_draw_bottom_menu(win); help_draw_bottom_menu(win);
@ -216,16 +253,22 @@ static void help_draw_keys(ToxWindow *self)
wmove(win, 1, 1); wmove(win, 1, 1);
wattron(win, A_BOLD | COLOR_PAIR(RED)); wattron(win, A_BOLD | COLOR_PAIR(RED));
wprintw(win, "Key bindings:\n"); wprintw(win, gettext("Key bindings:\n"));
wattroff(win, A_BOLD | COLOR_PAIR(RED)); wattroff(win, A_BOLD | COLOR_PAIR(RED));
wprintw(win, " Ctrl+O and Ctrl+P : Navigate through the tabs\n"); wprintw(win, " Ctrl+O -- Ctrl+P : ");
wprintw(win, " Page Up and Page Down : Scroll window history one line\n"); wprintw(win, gettext("Navigate through the tabs\n"));
wprintw(win, " Ctrl+F and Ctrl+V : Scroll window history half a page\n"); wprintw(win, " Page Up -- Page Down : ");
wprintw(win, " Ctrl+H : Move to the bottom of window history\n"); wprintw(win, gettext("Scroll window history one line\n"));
wprintw(win, " Ctrl+[ and Ctrl+] : Scroll peer list in groupchats\n"); wprintw(win, " Ctrl+F -- Ctrl+V : ");
wprintw(win, " Ctrl+B : Toggle the groupchat peerlist\n\n"); wprintw(win, gettext("Scroll window history half a page\n"));
wprintw(win, " (Note: Custom keybindings override these defaults.)\n\n"); wprintw(win, " Ctrl+H : ");
wprintw(win, gettext("Move to the bottom of window history\n"));
wprintw(win, " Ctrl+[ -- Ctrl+] : ");
wprintw(win, gettext("Scroll peer list in groupchats\n"));
wprintw(win, " Ctrl+B : ");
wprintw(win, gettext("Toggle the groupchat peerlist\n\n"));
wprintw(win, gettext(" (Note: Custom keybindings override these defaults.)\n\n"));
help_draw_bottom_menu(win); help_draw_bottom_menu(win);
@ -240,10 +283,11 @@ static void help_draw_group(ToxWindow *self)
wmove(win, 1, 1); wmove(win, 1, 1);
wattron(win, A_BOLD | COLOR_PAIR(RED)); wattron(win, A_BOLD | COLOR_PAIR(RED));
wprintw(win, "Group commands:\n"); wprintw(win, gettext("Group commands:\n"));
wattroff(win, A_BOLD | COLOR_PAIR(RED)); wattroff(win, A_BOLD | COLOR_PAIR(RED));
wprintw(win, " /title <msg> : Set group title (show current title if no msg)\n\n"); wprintw(win, " /title <msg> : ");
wprintw(win, gettext("Set group title (show current title if no msg)\n\n"));
help_draw_bottom_menu(win); help_draw_bottom_menu(win);
@ -258,14 +302,15 @@ static void help_draw_contacts(ToxWindow *self)
wmove(win, 1, 1); wmove(win, 1, 1);
wattron(win, A_BOLD | COLOR_PAIR(RED)); wattron(win, A_BOLD | COLOR_PAIR(RED));
wprintw(win, "Friendlist controls:\n"); wprintw(win, gettext("Friendlist controls:\n"));
wattroff(win, A_BOLD | COLOR_PAIR(RED)); wattroff(win, A_BOLD | COLOR_PAIR(RED));
wprintw(win, " Up and Down arrows : Scroll through list\n"); wprintw(win, gettext(" Up and Down arrows : Scroll through list\n"));
wprintw(win, " Right and Left arrows : Switch between friendlist and blocked list\n"); wprintw(win, gettext(" Right and Left arrows : Switch between friendlist and blocked list\n"));
wprintw(win, " Enter : Open a chat window with selected contact\n"); wprintw(win, gettext(" Enter : Open a chat window with selected contact\n"));
wprintw(win, " Delete : Permanently delete a contact\n"); wprintw(win, gettext(" Delete : Permanently delete a contact\n"));
wprintw(win, " B : Block or unblock a contact\n"); wprintw(win, " B : ");
wprintw(win, gettext("Block or unblock a contact\n"));
help_draw_bottom_menu(win); help_draw_bottom_menu(win);

View File

@ -25,6 +25,12 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdarg.h> #include <stdarg.h>
#ifdef NO_GETTEXT
#define gettext(A) (A)
#else
#include <libintl.h>
#endif
#include "toxic.h" #include "toxic.h"
#include "windows.h" #include "windows.h"
#include "line_info.h" #include "line_info.h"
@ -41,7 +47,7 @@ void line_info_init(struct history *hst)
hst->line_root = calloc(1, sizeof(struct line_info)); hst->line_root = calloc(1, sizeof(struct line_info));
if (hst->line_root == NULL) if (hst->line_root == NULL)
exit_toxic_err("failed in line_info_init", FATALERR_MEMORY); exit_toxic_err(gettext("failed in line_info_init"), FATALERR_MEMORY);
hst->line_start = hst->line_root; hst->line_start = hst->line_root;
hst->line_end = hst->line_start; hst->line_end = hst->line_start;
@ -141,7 +147,7 @@ void line_info_add(ToxWindow *self, const char *timestr, const char *name1, cons
struct line_info *new_line = calloc(1, sizeof(struct line_info)); struct line_info *new_line = calloc(1, sizeof(struct line_info));
if (new_line == NULL) if (new_line == NULL)
exit_toxic_err("failed in line_info_add", FATALERR_MEMORY); exit_toxic_err(gettext("failed in line_info_add"), FATALERR_MEMORY);
char frmt_msg[MAX_LINE_INFO_MSG_SIZE] = {0}; char frmt_msg[MAX_LINE_INFO_MSG_SIZE] = {0};

View File

@ -25,6 +25,12 @@
#include <time.h> #include <time.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifdef NO_GETTEXT
#define gettext(A) (A)
#else
#include <libintl.h>
#endif
#include "configdir.h" #include "configdir.h"
#include "toxic.h" #include "toxic.h"
#include "windows.h" #include "windows.h"
@ -180,17 +186,17 @@ void load_chat_history(ToxWindow *self, struct chatlog *log)
char *hstbuf = malloc(sz); char *hstbuf = malloc(sz);
if (hstbuf == NULL) if (hstbuf == NULL)
exit_toxic_err("failed in load_chat_history", FATALERR_MEMORY); exit_toxic_err(gettext("failed in load_chat_history"), FATALERR_MEMORY);
if (fseek(log->file, 0L, SEEK_SET) == -1) { if (fseek(log->file, 0L, SEEK_SET) == -1) {
free(hstbuf); free(hstbuf);
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, " * Failed to read log file"); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, gettext(" * Failed to read log file"));
return; return;
} }
if (fread(hstbuf, sz, 1, log->file) != 1) { if (fread(hstbuf, sz, 1, log->file) != 1) {
free(hstbuf); free(hstbuf);
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, " * Failed to read log file"); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, gettext(" * Failed to read log file"));
return; return;
} }

View File

@ -22,6 +22,12 @@
#include <stdlib.h> #include <stdlib.h>
#ifdef NO_GETTEXT
#define gettext(A) (A)
#else
#include <libintl.h>
#endif
#include "toxic.h" #include "toxic.h"
#include "windows.h" #include "windows.h"
#include "message_queue.h" #include "message_queue.h"
@ -47,7 +53,7 @@ void cqueue_add(struct chat_queue *q, const char *msg, size_t len, uint8_t type,
struct cqueue_msg *new_m = malloc(sizeof(struct cqueue_msg)); struct cqueue_msg *new_m = malloc(sizeof(struct cqueue_msg));
if (new_m == NULL) if (new_m == NULL)
exit_toxic_err("failed in cqueue_message", FATALERR_MEMORY); exit_toxic_err(gettext("failed in cqueue_message"), FATALERR_MEMORY);
snprintf(new_m->message, sizeof(new_m->message), "%s", msg); snprintf(new_m->message, sizeof(new_m->message), "%s", msg);
new_m->len = len; new_m->len = len;

View File

@ -28,6 +28,12 @@
#include <dirent.h> #include <dirent.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifdef NO_GETTEXT
#define gettext(A) (A)
#else
#include <libintl.h>
#endif
#include "toxic.h" #include "toxic.h"
#include "windows.h" #include "windows.h"
#include "misc_tools.h" #include "misc_tools.h"
@ -231,7 +237,7 @@ size_t get_file_name(char *namebuf, size_t bufsize, const char *pathname)
char *path = strdup(pathname); char *path = strdup(pathname);
if (path == NULL) if (path == NULL)
exit_toxic_err("failed in get_file_name", FATALERR_MEMORY); exit_toxic_err(gettext("failed in get_file_name"), FATALERR_MEMORY);
while (len >= 0 && pathname[len] == '/') while (len >= 0 && pathname[len] == '/')
path[len--] = '\0'; path[len--] = '\0';
@ -239,7 +245,7 @@ size_t get_file_name(char *namebuf, size_t bufsize, const char *pathname)
char *finalname = strdup(path); char *finalname = strdup(path);
if (finalname == NULL) if (finalname == NULL)
exit_toxic_err("failed in get_file_name", FATALERR_MEMORY); exit_toxic_err(gettext("failed in get_file_name"), FATALERR_MEMORY);
const char *basenm = strrchr(path, '/'); const char *basenm = strrchr(path, '/');

View File

@ -28,6 +28,12 @@
#include <string.h> #include <string.h>
#include <wchar.h> #include <wchar.h>
#ifdef NO_GETTEXT
#define gettext(A) (A)
#else
#include <libintl.h>
#endif
#include "toxic.h" #include "toxic.h"
#include "windows.h" #include "windows.h"
#include "prompt.h" #include "prompt.h"
@ -130,7 +136,7 @@ void prompt_update_statusmessage(ToxWindow *prompt, Tox *m, const char *statusms
tox_self_set_status_message(m, (uint8_t *) statusmsg, len, &err); tox_self_set_status_message(m, (uint8_t *) statusmsg, len, &err);
if (err != TOX_ERR_SET_INFO_OK) if (err != TOX_ERR_SET_INFO_OK)
line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set note (error %d)\n", err); line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Failed to set note (error %d)\n"), err);
} }
/* Updates own status in prompt statusbar */ /* Updates own status in prompt statusbar */
@ -262,19 +268,19 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
if (statusbar->connection != TOX_CONNECTION_NONE) { if (statusbar->connection != TOX_CONNECTION_NONE) {
int colour = MAGENTA; int colour = MAGENTA;
const char *status_text = "ERROR"; const char *status_text = gettext("ERROR");
switch (statusbar->status) { switch (statusbar->status) {
case TOX_USER_STATUS_NONE: case TOX_USER_STATUS_NONE:
status_text = "Online"; status_text = gettext("Online");
colour = GREEN; colour = GREEN;
break; break;
case TOX_USER_STATUS_AWAY: case TOX_USER_STATUS_AWAY:
status_text = "Away"; status_text = gettext("Away");
colour = YELLOW; colour = YELLOW;
break; break;
case TOX_USER_STATUS_BUSY: case TOX_USER_STATUS_BUSY:
status_text = "Busy"; status_text = gettext("Busy");
colour = RED; colour = RED;
break; break;
} }
@ -287,7 +293,7 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
wprintw(statusbar->topline, " %s", statusbar->nick); wprintw(statusbar->topline, " %s", statusbar->nick);
wattroff(statusbar->topline, A_BOLD); wattroff(statusbar->topline, A_BOLD);
} else { } else {
wprintw(statusbar->topline, " [Offline]"); wprintw(statusbar->topline, gettext(" [Offline]"));
wattron(statusbar->topline, A_BOLD); wattron(statusbar->topline, A_BOLD);
wprintw(statusbar->topline, " %s", statusbar->nick); wprintw(statusbar->topline, " %s", statusbar->nick);
wattroff(statusbar->topline, A_BOLD); wattroff(statusbar->topline, A_BOLD);
@ -351,28 +357,28 @@ static void prompt_onConnectionChange(ToxWindow *self, Tox *m, uint32_t friendnu
const char *msg; const char *msg;
if (connection_status != TOX_CONNECTION_NONE && Friends.list[friendnum].connection_status == TOX_CONNECTION_NONE) { if (connection_status != TOX_CONNECTION_NONE && Friends.list[friendnum].connection_status == TOX_CONNECTION_NONE) {
msg = "has come online"; msg = gettext("has come online");
line_info_add(self, timefrmt, nick, NULL, CONNECTION, 0, GREEN, msg); line_info_add(self, timefrmt, nick, NULL, CONNECTION, 0, GREEN, msg);
write_to_log(msg, nick, ctx->log, true); write_to_log(msg, nick, ctx->log, true);
if (self->active_box != -1) if (self->active_box != -1)
box_notify2(self, user_log_in, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, self->active_box, box_notify2(self, user_log_in, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, self->active_box,
"%s has come online", nick ); gettext("%s has come online"), nick );
else else
box_notify(self, user_log_in, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, &self->active_box, box_notify(self, user_log_in, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, &self->active_box,
"Toxic", "%s has come online", nick ); "Toxic", gettext("%s has come online"), nick );
} }
else if (connection_status == TOX_CONNECTION_NONE) { else if (connection_status == TOX_CONNECTION_NONE) {
msg = "has gone offline"; msg = gettext("has gone offline");
line_info_add(self, timefrmt, nick, NULL, DISCONNECTION, 0, RED, msg); line_info_add(self, timefrmt, nick, NULL, DISCONNECTION, 0, RED, msg);
write_to_log(msg, nick, ctx->log, true); write_to_log(msg, nick, ctx->log, true);
if (self->active_box != -1) if (self->active_box != -1)
box_notify2(self, user_log_out, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, self->active_box, box_notify2(self, user_log_out, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, self->active_box,
"%s has gone offline", nick ); gettext("%s has gone offline"), nick );
else else
box_notify(self, user_log_out, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, &self->active_box, box_notify(self, user_log_out, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, &self->active_box,
"Toxic", "%s has gone offline", nick ); "Toxic", gettext("%s has gone offline"), nick );
} }
} }
@ -383,18 +389,18 @@ static void prompt_onFriendRequest(ToxWindow *self, Tox *m, const char *key, con
char timefrmt[TIME_STR_SIZE]; char timefrmt[TIME_STR_SIZE];
get_time_str(timefrmt, sizeof(timefrmt)); get_time_str(timefrmt, sizeof(timefrmt));
line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 0, 0, "Friend request with the message '%s'", data); line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 0, 0, gettext("Friend request with the message '%s'"), data);
write_to_log("Friend request with the message '%s'", "", ctx->log, true); write_to_log(gettext("Friend request with the message '%s'"), "", ctx->log, true);
int n = add_friend_request(key, data); int n = add_friend_request(key, data);
if (n == -1) { if (n == -1) {
const char *errmsg = "Friend request queue is full. Discarding request."; const char *errmsg = gettext("Friend request queue is full. Discarding request.");
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg);
return; return;
} }
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Type \"/accept %d\" or \"/decline %d\"", n, n); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Type \"%s %d\" or \"%s %d\""), "/accept", n, "/decline", n);
sound_notify(self, generic_message, NT_WNDALERT_1 | NT_NOTIFWND, NULL); sound_notify(self, generic_message, NT_WNDALERT_1 | NT_NOTIFWND, NULL);
} }
@ -423,8 +429,8 @@ void prompt_init_statusbar(ToxWindow *self, Tox *m)
nick[n_len] = '\0'; nick[n_len] = '\0';
statusmsg[s_len] = '\0'; statusmsg[s_len] = '\0';
if (s_len == 0 || !strncmp(statusmsg, "Toxing on Toxic", strlen("Toxing on Toxic"))) { if (s_len == 0 || !strncmp(statusmsg, gettext("Toxing on Toxic"), strlen(gettext("Toxing on Toxic")))) {
snprintf(statusmsg, sizeof(statusmsg), "Toxing on Toxic"); snprintf(statusmsg, sizeof(statusmsg), gettext("Toxing on Toxic"));
s_len = strlen(statusmsg); s_len = strlen(statusmsg);
statusmsg[s_len] = '\0'; statusmsg[s_len] = '\0';
} }
@ -446,10 +452,10 @@ static void print_welcome_msg(ToxWindow *self)
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 1, BLUE, " |_| \\___/_/\\_\\___\\____| v." TOXICVER); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 1, BLUE, " |_| \\___/_/\\_\\___\\____| v." TOXICVER);
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, ""); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "");
const char *msg = "Welcome to Toxic, a free, open source Tox-based instant messenging client."; const char *msg = gettext("Welcome to Toxic, a free, open source Tox-based instant messenging client.");
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 1, CYAN, msg);
msg = "Type \"/help\" for assistance. Further help may be found via the man page.";
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 1, CYAN, msg); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 1, CYAN, msg);
msg = gettext("Type \"%s\" for assistance. Further help may be found via the man page.");
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 1, CYAN, msg, "/help");
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, ""); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "");
} }
@ -467,7 +473,7 @@ static void prompt_onInit(ToxWindow *self, Tox *m)
ctx->hst = calloc(1, sizeof(struct history)); ctx->hst = calloc(1, sizeof(struct history));
if (ctx->log == NULL || ctx->hst == NULL) if (ctx->log == NULL || ctx->hst == NULL)
exit_toxic_err("failed in prompt_onInit", FATALERR_MEMORY); exit_toxic_err(gettext("failed in prompt_onInit"), FATALERR_MEMORY);
line_info_init(ctx->hst); line_info_init(ctx->hst);
@ -505,7 +511,7 @@ ToxWindow new_prompt(void)
Help *help = calloc(1, sizeof(Help)); Help *help = calloc(1, sizeof(Help));
if (stb == NULL || chatwin == NULL || help == NULL) if (stb == NULL || chatwin == NULL || help == NULL)
exit_toxic_err("failed in new_prompt", FATALERR_MEMORY); exit_toxic_err(gettext("failed in new_prompt"), FATALERR_MEMORY);
ret.chatwin = chatwin; ret.chatwin = chatwin;
ret.stb = stb; ret.stb = stb;

View File

@ -40,6 +40,12 @@
#include <limits.h> #include <limits.h>
#include <termios.h> #include <termios.h>
#ifdef NO_GETTEXT
#define gettext(A) (A)
#else
#include <libintl.h>
#endif
#include <tox/tox.h> #include <tox/tox.h>
#include <tox/toxencryptsave.h> #include <tox/toxencryptsave.h>
@ -103,7 +109,7 @@ static void catch_SIGSEGV(int sig)
{ {
freopen("/dev/tty", "w", stderr); // make sure stderr is enabled since we may have disabled it freopen("/dev/tty", "w", stderr); // make sure stderr is enabled since we may have disabled it
endwin(); endwin();
fprintf(stderr, "Caught SIGSEGV: Aborting toxic session.\n"); fprintf(stderr, gettext("Caught SIGSEGV: Aborting toxic session.\n"));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -152,7 +158,7 @@ void exit_toxic_err(const char *errmsg, int errcode)
{ {
freopen("/dev/tty", "w", stderr); freopen("/dev/tty", "w", stderr);
endwin(); endwin();
fprintf(stderr, "Toxic session aborted with error code %d (%s)\n", errcode, errmsg); fprintf(stderr, gettext("Toxic session aborted with error code %d (%s)\n"), errcode, errmsg);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -162,12 +168,16 @@ static void init_term(void)
if (!arg_opts.default_locale) { if (!arg_opts.default_locale) {
if (setlocale(LC_ALL, "") == NULL) if (setlocale(LC_ALL, "") == NULL)
exit_toxic_err("Could not set your locale, please check your locale settings or " exit_toxic_err(gettext("Could not set your locale, please check your locale settings or "
"disable unicode support with the -d flag.", FATALERR_LOCALE_NOT_SET); "disable unicode support with the -d flag."), FATALERR_LOCALE_NOT_SET);
} }
#endif #endif
#ifndef NO_GETTEXT
textdomain("toxic");
#endif
initscr(); initscr();
cbreak(); cbreak();
keypad(stdscr, 1); keypad(stdscr, 1);
@ -218,12 +228,12 @@ static void queue_init_message(const char *msg, ...)
char **new_msgs = realloc(init_messages.msgs, sizeof(char *) * init_messages.num); char **new_msgs = realloc(init_messages.msgs, sizeof(char *) * init_messages.num);
if (new_msgs == NULL) if (new_msgs == NULL)
exit_toxic_err("Failed in queue_init_message", FATALERR_MEMORY); exit_toxic_err(gettext("Failed in queue_init_message"), FATALERR_MEMORY);
new_msgs[i] = malloc(MAX_STR_SIZE); new_msgs[i] = malloc(MAX_STR_SIZE);
if (new_msgs[i] == NULL) if (new_msgs[i] == NULL)
exit_toxic_err("Failed in queue_init_message", FATALERR_MEMORY); exit_toxic_err(gettext("Failed in queue_init_message"), FATALERR_MEMORY);
snprintf(new_msgs[i], MAX_STR_SIZE, "%s", frmt_msg); snprintf(new_msgs[i], MAX_STR_SIZE, "%s", frmt_msg);
init_messages.msgs = new_msgs; init_messages.msgs = new_msgs;
@ -315,14 +325,14 @@ int init_connection_helper(Tox *m, int line)
tox_bootstrap(m, toxNodes.nodes[line], toxNodes.ports[line], (uint8_t *) toxNodes.keys[line], &err); tox_bootstrap(m, toxNodes.nodes[line], toxNodes.ports[line], (uint8_t *) toxNodes.keys[line], &err);
if (err != TOX_ERR_BOOTSTRAP_OK) { if (err != TOX_ERR_BOOTSTRAP_OK) {
fprintf(stderr, "Failed to bootstrap %s:%d\n", toxNodes.nodes[line], toxNodes.ports[line]); fprintf(stderr, gettext("Failed to bootstrap %s:%d\n"), toxNodes.nodes[line], toxNodes.ports[line]);
return -1; return -1;
} }
tox_add_tcp_relay(m, toxNodes.nodes[line], toxNodes.ports[line], (uint8_t *) toxNodes.keys[line], &err); tox_add_tcp_relay(m, toxNodes.nodes[line], toxNodes.ports[line], (uint8_t *) toxNodes.keys[line], &err);
if (err != TOX_ERR_BOOTSTRAP_OK) { if (err != TOX_ERR_BOOTSTRAP_OK) {
fprintf(stderr, "Failed to add TCP relay %s:%d\n", toxNodes.nodes[line], toxNodes.ports[line]); fprintf(stderr, gettext("Failed to add TCP relay %s:%d\n"), toxNodes.nodes[line], toxNodes.ports[line]);
return -1; return -1;
} }
@ -453,7 +463,7 @@ static void first_time_encrypt(const char *msg)
bool valid_password = false; bool valid_password = false;
char passconfirm[MAX_PASSWORD_LEN + 1] = {0}; char passconfirm[MAX_PASSWORD_LEN + 1] = {0};
printf("Enter a new password (must be at least %d characters) ", MIN_PASSWORD_LEN); printf(gettext("Enter a new password (must be at least %d characters) "), MIN_PASSWORD_LEN);
while (valid_password == false) { while (valid_password == false) {
len = password_prompt(user_password.pass, sizeof(user_password.pass)); len = password_prompt(user_password.pass, sizeof(user_password.pass));
@ -463,12 +473,12 @@ static void first_time_encrypt(const char *msg)
exit(0); exit(0);
if (string_is_empty(passconfirm) && (len < MIN_PASSWORD_LEN || len > MAX_PASSWORD_LEN)) { if (string_is_empty(passconfirm) && (len < MIN_PASSWORD_LEN || len > MAX_PASSWORD_LEN)) {
printf("Password must be between %d and %d characters long. ", MIN_PASSWORD_LEN, MAX_PASSWORD_LEN); printf(gettext("Password must be between %d and %d characters long. "), MIN_PASSWORD_LEN, MAX_PASSWORD_LEN);
continue; continue;
} }
if (string_is_empty(passconfirm)) { if (string_is_empty(passconfirm)) {
printf("Enter password again "); printf(gettext("Enter password again "));
snprintf(passconfirm, sizeof(passconfirm), "%s", user_password.pass); snprintf(passconfirm, sizeof(passconfirm), "%s", user_password.pass);
continue; continue;
} }
@ -476,14 +486,14 @@ static void first_time_encrypt(const char *msg)
if (strcmp(user_password.pass, passconfirm) != 0) { if (strcmp(user_password.pass, passconfirm) != 0) {
memset(passconfirm, 0, sizeof(passconfirm)); memset(passconfirm, 0, sizeof(passconfirm));
memset(user_password.pass, 0, sizeof(user_password.pass)); memset(user_password.pass, 0, sizeof(user_password.pass));
printf("Passwords don't match. Try again. "); printf(gettext("Passwords don't match. Try again. "));
continue; continue;
} }
valid_password = true; valid_password = true;
} }
queue_init_message("Data file '%s' is encrypted", DATA_FILE); queue_init_message(gettext("Data file '%s' is encrypted"), DATA_FILE);
memset(passconfirm, 0, sizeof(passconfirm)); memset(passconfirm, 0, sizeof(passconfirm));
user_password.data_is_encrypted = true; user_password.data_is_encrypted = true;
} }
@ -520,7 +530,7 @@ int store_data(Tox *m, const char *path)
(uint8_t *) enc_data, &err); (uint8_t *) enc_data, &err);
if (err != TOX_ERR_ENCRYPTION_OK) { if (err != TOX_ERR_ENCRYPTION_OK) {
fprintf(stderr, "tox_pass_encrypt() failed with error %d\n", err); fprintf(stderr, gettext("tox_pass_encrypt() failed with error %d\n"), err);
fclose(fp); fclose(fp);
return -1; return -1;
} }
@ -571,7 +581,7 @@ static void init_tox_options(struct Tox_Options *tox_opts)
tox_opts->proxy_type = arg_opts.proxy_type; tox_opts->proxy_type = arg_opts.proxy_type;
if (!tox_opts->ipv6_enabled) if (!tox_opts->ipv6_enabled)
queue_init_message("Forcing IPv4 connection"); queue_init_message(gettext("Forcing IPv4 connection"));
if (tox_opts->proxy_type != TOX_PROXY_TYPE_NONE) { if (tox_opts->proxy_type != TOX_PROXY_TYPE_NONE) {
tox_opts->proxy_port = arg_opts.proxy_port; tox_opts->proxy_port = arg_opts.proxy_port;
@ -579,16 +589,16 @@ static void init_tox_options(struct Tox_Options *tox_opts)
const char *ps = tox_opts->proxy_type == TOX_PROXY_TYPE_SOCKS5 ? "SOCKS5" : "HTTP"; const char *ps = tox_opts->proxy_type == TOX_PROXY_TYPE_SOCKS5 ? "SOCKS5" : "HTTP";
char tmp[48]; char tmp[48];
snprintf(tmp, sizeof(tmp), "Using %s proxy %s : %d", ps, arg_opts.proxy_address, arg_opts.proxy_port); snprintf(tmp, sizeof(tmp), gettext("Using %s proxy %s : %d"), ps, arg_opts.proxy_address, arg_opts.proxy_port);
queue_init_message("%s", tmp); queue_init_message("%s", tmp);
} }
if (!tox_opts->udp_enabled) { if (!tox_opts->udp_enabled) {
queue_init_message("UDP disabled"); queue_init_message(gettext("UDP disabled"));
} else if (tox_opts->proxy_type != TOX_PROXY_TYPE_NONE) { } else if (tox_opts->proxy_type != TOX_PROXY_TYPE_NONE) {
const char *msg = "WARNING: Using a proxy without disabling UDP may leak your real IP address."; const char *msg = gettext("WARNING: Using a proxy without disabling UDP may leak your real IP address.");
queue_init_message("%s", msg); queue_init_message("%s", msg);
msg = "Use the -t option to disable UDP."; msg = gettext("Use the -t option to disable UDP.");
queue_init_message("%s", msg); queue_init_message("%s", msg);
} }
} }
@ -607,14 +617,14 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, TOX_ERR_NEW
if (len == 0) { if (len == 0) {
fclose(fp); fclose(fp);
exit_toxic_err("failed in load_toxic", FATALERR_FILEOP); exit_toxic_err(gettext("failed in load_toxic"), FATALERR_FILEOP);
} }
char data[len]; char data[len];
if (fread(data, sizeof(data), 1, fp) != 1) { if (fread(data, sizeof(data), 1, fp) != 1) {
fclose(fp); fclose(fp);
exit_toxic_err("failed in load_toxic", FATALERR_FILEOP); exit_toxic_err(gettext("failed in load_toxic"), FATALERR_FILEOP);
} }
bool is_encrypted = tox_is_data_encrypted((uint8_t *) data); bool is_encrypted = tox_is_data_encrypted((uint8_t *) data);
@ -622,13 +632,13 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, TOX_ERR_NEW
/* attempt to encrypt an already encrypted data file */ /* attempt to encrypt an already encrypted data file */
if (arg_opts.encrypt_data && is_encrypted) { if (arg_opts.encrypt_data && is_encrypted) {
fclose(fp); fclose(fp);
exit_toxic_err("failed in load_toxic", FATALERR_ENCRYPT); exit_toxic_err(gettext("failed in load_toxic"), FATALERR_ENCRYPT);
} }
if (arg_opts.unencrypt_data && is_encrypted) if (arg_opts.unencrypt_data && is_encrypted)
queue_init_message("Data file '%s' has been unencrypted", data_path); queue_init_message(gettext("Data file '%s' has been unencrypted"), data_path);
else if (arg_opts.unencrypt_data) else if (arg_opts.unencrypt_data)
queue_init_message("Warning: passed --unencrypt-data option with unencrypted data file '%s'", data_path); queue_init_message(gettext("Warning: passed --unencrypt-data option with unencrypted data file '%s'"), data_path);
if (is_encrypted) { if (is_encrypted) {
if (!arg_opts.unencrypt_data) if (!arg_opts.unencrypt_data)
@ -636,7 +646,7 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, TOX_ERR_NEW
size_t pwlen = 0; size_t pwlen = 0;
system("clear"); // TODO: is this portable? system("clear"); // TODO: is this portable?
printf("Enter password (q to quit) "); printf(gettext("Enter password (\"%s\" to quit) "), "q");
size_t plain_len = len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; size_t plain_len = len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
char plain[plain_len]; char plain[plain_len];
@ -653,7 +663,7 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, TOX_ERR_NEW
if (pwlen < MIN_PASSWORD_LEN) { if (pwlen < MIN_PASSWORD_LEN) {
system("clear"); system("clear");
sleep(1); sleep(1);
printf("Invalid password. Try again. "); printf(gettext("Invalid password. Try again. "));
continue; continue;
} }
@ -677,10 +687,10 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, TOX_ERR_NEW
} else if (pwerr == TOX_ERR_DECRYPTION_FAILED) { } else if (pwerr == TOX_ERR_DECRYPTION_FAILED) {
system("clear"); system("clear");
sleep(1); sleep(1);
printf("Invalid password. Try again. "); printf(gettext("Invalid password. Try again. "));
} else { } else {
fclose(fp); fclose(fp);
exit_toxic_err("tox_pass_decrypt() failed", pwerr); exit_toxic_err(gettext("tox_pass_decrypt() failed"), pwerr);
} }
} }
} else { /* data is not encrypted */ } else { /* data is not encrypted */
@ -699,7 +709,7 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, TOX_ERR_NEW
fclose(fp); fclose(fp);
} else { /* Data file does not/should not exist */ } else { /* Data file does not/should not exist */
if (file_exists(data_path)) if (file_exists(data_path))
exit_toxic_err("failed in load_toxic", FATALERR_FILEOP); exit_toxic_err(gettext("failed in load_toxic"), FATALERR_FILEOP);
tox_opts->savedata_type = TOX_SAVEDATA_TYPE_NONE; tox_opts->savedata_type = TOX_SAVEDATA_TYPE_NONE;
@ -709,7 +719,7 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, TOX_ERR_NEW
return NULL; return NULL;
if (store_data(m, data_path) == -1) if (store_data(m, data_path) == -1)
exit_toxic_err("failed in load_toxic", FATALERR_FILEOP); exit_toxic_err(gettext("failed in load_toxic"), FATALERR_FILEOP);
} }
return m; return m;
@ -724,23 +734,23 @@ static Tox *load_toxic(char *data_path)
Tox *m = load_tox(data_path, &tox_opts, &new_err); Tox *m = load_tox(data_path, &tox_opts, &new_err);
if (new_err == TOX_ERR_NEW_PORT_ALLOC && tox_opts.ipv6_enabled) { if (new_err == TOX_ERR_NEW_PORT_ALLOC && tox_opts.ipv6_enabled) {
queue_init_message("Falling back to ipv4"); queue_init_message(gettext("Falling back to ipv4"));
tox_opts.ipv6_enabled = false; tox_opts.ipv6_enabled = false;
m = load_tox(data_path, &tox_opts, &new_err); m = load_tox(data_path, &tox_opts, &new_err);
} }
if (!m) if (!m)
exit_toxic_err("tox_new returned fatal error", new_err); exit_toxic_err(gettext("tox_new returned fatal error"), new_err);
if (new_err != TOX_ERR_NEW_OK) if (new_err != TOX_ERR_NEW_OK)
queue_init_message("tox_new returned non-fatal error %d", new_err); queue_init_message(gettext("tox_new returned non-fatal error %d"), new_err);
init_tox_callbacks(m); init_tox_callbacks(m);
load_friendlist(m); load_friendlist(m);
load_blocklist(BLOCK_FILE); load_blocklist(BLOCK_FILE);
if (tox_self_get_name_size(m) == 0) if (tox_self_get_name_size(m) == 0)
tox_self_set_name(m, (uint8_t *) "Toxic User", strlen("Toxic User"), NULL); tox_self_set_name(m, (uint8_t *) gettext("Toxic User"), strlen(gettext("Toxic User")), NULL);
return m; return m;
} }
@ -766,7 +776,7 @@ static void do_bootstrap(Tox *m)
conn_err = init_connection(m); conn_err = init_connection(m);
if (conn_err != 0) if (conn_err != 0)
line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Auto-connect failed with error code %d", conn_err); line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, gettext("Auto-connect failed with error code %d"), conn_err);
} }
static void do_toxic(Tox *m, ToxWindow *prompt) static void do_toxic(Tox *m, ToxWindow *prompt)
@ -847,21 +857,35 @@ void *thread_audio(void *data)
static void print_usage(void) static void print_usage(void)
{ {
fprintf(stderr, "usage: toxic [OPTION] [FILE ...]\n"); fprintf(stderr, gettext("usage: toxic [OPTION] [FILE ...]\n"));
fprintf(stderr, " -4, --ipv4 Force IPv4 connection\n"); fprintf(stderr, " -4, --ipv4 ");
fprintf(stderr, " -b, --debug Enable stderr for debugging\n"); fprintf(stderr, gettext("Force IPv4 connection\n"));
fprintf(stderr, " -c, --config Use specified config file\n"); fprintf(stderr, " -b, --debug ");
fprintf(stderr, " -d, --default-locale Use default POSIX locale\n"); fprintf(stderr, gettext("Enable stderr for debugging\n"));
fprintf(stderr, " -e, --encrypt-data Encrypt an unencrypted data file\n"); fprintf(stderr, " -c, --config ");
fprintf(stderr, " -f, --file Use specified data file\n"); fprintf(stderr, gettext("Use specified config file\n"));
fprintf(stderr, " -h, --help Show this message and exit\n"); fprintf(stderr, " -d, --default-locale ");
fprintf(stderr, " -n, --nodes Use specified DHTnodes file\n"); fprintf(stderr, gettext("Use default POSIX locale\n"));
fprintf(stderr, " -o, --noconnect Do not connect to the DHT network\n"); fprintf(stderr, " -e, --encrypt-data ");
fprintf(stderr, " -p, --SOCKS5-proxy Use SOCKS5 proxy: Requires [IP] [port]\n"); fprintf(stderr, gettext("Encrypt an unencrypted data file\n"));
fprintf(stderr, " -P, --HTTP-proxy Use HTTP proxy: Requires [IP] [port]\n"); fprintf(stderr, " -f, --file ");
fprintf(stderr, " -r, --dnslist Use specified DNSservers file\n"); fprintf(stderr, gettext("Use specified data file\n"));
fprintf(stderr, " -t, --force-tcp Force TCP connection (use this with proxies)\n"); fprintf(stderr, " -h, --help ");
fprintf(stderr, " -u, --unencrypt-data Unencrypt an encrypted data file\n"); fprintf(stderr, gettext("Show this message and exit\n"));
fprintf(stderr, " -n, --nodes ");
fprintf(stderr, gettext("Use specified DHTnodes file\n"));
fprintf(stderr, " -o, --noconnect ");
fprintf(stderr, gettext("Do not connect to the DHT network\n"));
fprintf(stderr, " -p, --SOCKS5-proxy ");
fprintf(stderr, gettext("Use SOCKS5 proxy: Requires [IP] [port]\n"));
fprintf(stderr, " -P, --HTTP-proxy ");
fprintf(stderr, gettext("Use HTTP proxy: Requires [IP] [port]\n"));
fprintf(stderr, " -r, --dnslist ");
fprintf(stderr, gettext("Use specified DNSservers file\n"));
fprintf(stderr, " -t, --force-tcp ");
fprintf(stderr, gettext("Force TCP connection (use this with proxies)\n"));
fprintf(stderr, " -u, --unencrypt-data ");
fprintf(stderr, gettext("Unencrypt an encrypted data file\n"));
} }
static void set_default_opts(void) static void set_default_opts(void)
@ -905,20 +929,20 @@ static void parse_args(int argc, char *argv[])
case 'b': case 'b':
arg_opts.debug = 1; arg_opts.debug = 1;
queue_init_message("stderr enabled"); queue_init_message(gettext("stderr enabled"));
break; break;
case 'c': case 'c':
snprintf(arg_opts.config_path, sizeof(arg_opts.config_path), "%s", optarg); snprintf(arg_opts.config_path, sizeof(arg_opts.config_path), "%s", optarg);
if (!file_exists(arg_opts.config_path)) if (!file_exists(arg_opts.config_path))
queue_init_message("Config file not found"); queue_init_message(gettext("Config file not found"));
break; break;
case 'd': case 'd':
arg_opts.default_locale = 1; arg_opts.default_locale = 1;
queue_init_message("Using default POSIX locale"); queue_init_message(gettext("Using default POSIX locale"));
break; break;
case 'e': case 'e':
@ -931,12 +955,12 @@ static void parse_args(int argc, char *argv[])
BLOCK_FILE = malloc(strlen(optarg) + strlen("-blocklist") + 1); BLOCK_FILE = malloc(strlen(optarg) + strlen("-blocklist") + 1);
if (DATA_FILE == NULL || BLOCK_FILE == NULL) if (DATA_FILE == NULL || BLOCK_FILE == NULL)
exit_toxic_err("failed in parse_args", FATALERR_MEMORY); exit_toxic_err(gettext("failed in parse_args"), FATALERR_MEMORY);
strcpy(BLOCK_FILE, optarg); strcpy(BLOCK_FILE, optarg);
strcat(BLOCK_FILE, "-blocklist"); strcat(BLOCK_FILE, "-blocklist");
queue_init_message("Using '%s' data file", DATA_FILE); queue_init_message(gettext("Using '%s' data file"), DATA_FILE);
break; break;
@ -944,13 +968,13 @@ static void parse_args(int argc, char *argv[])
snprintf(arg_opts.nodes_path, sizeof(arg_opts.nodes_path), "%s", optarg); snprintf(arg_opts.nodes_path, sizeof(arg_opts.nodes_path), "%s", optarg);
if (!file_exists(arg_opts.nodes_path)) if (!file_exists(arg_opts.nodes_path))
queue_init_message("DHTnodes file not found"); queue_init_message(gettext("DHTnodes file not found"));
break; break;
case 'o': case 'o':
arg_opts.no_connect = 1; arg_opts.no_connect = 1;
queue_init_message("DHT disabled"); queue_init_message(gettext("DHT disabled"));
break; break;
case 'p': case 'p':
@ -958,7 +982,7 @@ static void parse_args(int argc, char *argv[])
snprintf(arg_opts.proxy_address, sizeof(arg_opts.proxy_address), "%s", optarg); snprintf(arg_opts.proxy_address, sizeof(arg_opts.proxy_address), "%s", optarg);
if (++optind > argc || argv[optind-1][0] == '-') if (++optind > argc || argv[optind-1][0] == '-')
exit_toxic_err("Proxy error", FATALERR_PROXY); exit_toxic_err(gettext("Proxy error"), FATALERR_PROXY);
arg_opts.proxy_port = (uint16_t) atoi(argv[optind-1]); arg_opts.proxy_port = (uint16_t) atoi(argv[optind-1]);
break; break;
@ -968,7 +992,7 @@ static void parse_args(int argc, char *argv[])
snprintf(arg_opts.proxy_address, sizeof(arg_opts.proxy_address), "%s", optarg); snprintf(arg_opts.proxy_address, sizeof(arg_opts.proxy_address), "%s", optarg);
if (++optind > argc || argv[optind-1][0] == '-') if (++optind > argc || argv[optind-1][0] == '-')
exit_toxic_err("Proxy error", FATALERR_PROXY); exit_toxic_err(gettext("Proxy error"), FATALERR_PROXY);
arg_opts.proxy_port = (uint16_t) atoi(argv[optind-1]); arg_opts.proxy_port = (uint16_t) atoi(argv[optind-1]);
break; break;
@ -977,7 +1001,7 @@ static void parse_args(int argc, char *argv[])
snprintf(arg_opts.dns_path, sizeof(arg_opts.dns_path), "%s", optarg); snprintf(arg_opts.dns_path, sizeof(arg_opts.dns_path), "%s", optarg);
if (!file_exists(arg_opts.dns_path)) if (!file_exists(arg_opts.dns_path))
queue_init_message("DNSservers file not found"); queue_init_message(gettext("DNSservers file not found"));
break; break;
@ -1012,13 +1036,13 @@ static int init_default_data_files(void)
BLOCK_FILE = strdup(BLOCKNAME); BLOCK_FILE = strdup(BLOCKNAME);
if (DATA_FILE == NULL || BLOCK_FILE == NULL) if (DATA_FILE == NULL || BLOCK_FILE == NULL)
exit_toxic_err("failed in load_data_structures", FATALERR_MEMORY); exit_toxic_err(gettext("failed in load_data_structures"), FATALERR_MEMORY);
} else { } else {
DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(DATANAME) + 1); DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(DATANAME) + 1);
BLOCK_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(BLOCKNAME) + 1); BLOCK_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(BLOCKNAME) + 1);
if (DATA_FILE == NULL || BLOCK_FILE == NULL) if (DATA_FILE == NULL || BLOCK_FILE == NULL)
exit_toxic_err("failed in load_data_structures", FATALERR_MEMORY); exit_toxic_err(gettext("failed in load_data_structures"), FATALERR_MEMORY);
strcpy(DATA_FILE, user_config_dir); strcpy(DATA_FILE, user_config_dir);
strcat(DATA_FILE, CONFIGDIR); strcat(DATA_FILE, CONFIGDIR);
@ -1074,7 +1098,7 @@ int main(int argc, char *argv[])
if (arg_opts.encrypt_data && arg_opts.unencrypt_data) { if (arg_opts.encrypt_data && arg_opts.unencrypt_data) {
arg_opts.encrypt_data = 0; arg_opts.encrypt_data = 0;
arg_opts.unencrypt_data = 0; arg_opts.unencrypt_data = 0;
queue_init_message("Warning: Using --unencrypt-data and --encrypt-data simultaneously has no effect"); queue_init_message(gettext("Warning: Using \"%s\" and \"%s\" simultaneously has no effect"), "--unencrypt-data", "--encrypt-data");
} }
/* Make sure all written files are read/writeable only by the current user. */ /* Make sure all written files are read/writeable only by the current user. */
@ -1087,23 +1111,23 @@ int main(int argc, char *argv[])
last_bootstrap_time = get_unix_time(); last_bootstrap_time = get_unix_time();
if (!datafile_exists && !arg_opts.unencrypt_data) if (!datafile_exists && !arg_opts.unencrypt_data)
first_time_encrypt("Creating new data file. Would you like to encrypt it? Y/n (q to quit)"); first_time_encrypt(gettext("Creating new data file. Would you like to encrypt it? Y/n (q to quit)"));
else if (arg_opts.encrypt_data) else if (arg_opts.encrypt_data)
first_time_encrypt("Encrypt existing data file? Y/n (q to quit)"); first_time_encrypt(gettext("Encrypt existing data file? Y/n (q to quit)"));
/* init user_settings struct and load settings from conf file */ /* init user_settings struct and load settings from conf file */
user_settings = calloc(1, sizeof(struct user_settings)); user_settings = calloc(1, sizeof(struct user_settings));
if (user_settings == NULL) if (user_settings == NULL)
exit_toxic_err("failed in main", FATALERR_MEMORY); exit_toxic_err(gettext("failed in main"), FATALERR_MEMORY);
const char *p = arg_opts.config_path[0] ? arg_opts.config_path : NULL; const char *p = arg_opts.config_path[0] ? arg_opts.config_path : NULL;
int settings_err = settings_load(user_settings, p); int settings_err = settings_load(user_settings, p);
#ifdef X11 #ifdef X11
if (init_xtra(DnD_callback) == -1) if (init_xtra(DnD_callback) == -1)
queue_init_message("X failed to initialize"); queue_init_message(gettext("X failed to initialize"));
#endif #endif
Tox *m = load_toxic(DATA_FILE); Tox *m = load_toxic(DATA_FILE);
@ -1119,14 +1143,14 @@ int main(int argc, char *argv[])
/* thread for ncurses stuff */ /* thread for ncurses stuff */
if (pthread_mutex_init(&Winthread.lock, NULL) != 0) if (pthread_mutex_init(&Winthread.lock, NULL) != 0)
exit_toxic_err("failed in main", FATALERR_MUTEX_INIT); exit_toxic_err(gettext("failed in main"), FATALERR_MUTEX_INIT);
if (pthread_create(&Winthread.tid, NULL, thread_winref, (void *) m) != 0) if (pthread_create(&Winthread.tid, NULL, thread_winref, (void *) m) != 0)
exit_toxic_err("failed in main", FATALERR_THREAD_CREATE); exit_toxic_err(gettext("failed in main"), FATALERR_THREAD_CREATE);
/* thread for message queue */ /* thread for message queue */
if (pthread_create(&cqueue_thread.tid, NULL, thread_cqueue, (void *) m) != 0) if (pthread_create(&cqueue_thread.tid, NULL, thread_cqueue, (void *) m) != 0)
exit_toxic_err("failed in main", FATALERR_THREAD_CREATE); exit_toxic_err(gettext("failed in main"), FATALERR_THREAD_CREATE);
#ifdef AUDIO #ifdef AUDIO
@ -1134,14 +1158,14 @@ int main(int argc, char *argv[])
/* audio thread */ /* audio thread */
if (pthread_create(&audio_thread.tid, NULL, thread_audio, (void *) av) != 0) if (pthread_create(&audio_thread.tid, NULL, thread_audio, (void *) av) != 0)
exit_toxic_err("failed in main", FATALERR_THREAD_CREATE); exit_toxic_err(gettext("failed in main"), FATALERR_THREAD_CREATE);
set_primary_device(input, user_settings->audio_in_dev); set_primary_device(input, user_settings->audio_in_dev);
set_primary_device(output, user_settings->audio_out_dev); set_primary_device(output, user_settings->audio_out_dev);
#elif SOUND_NOTIFY #elif SOUND_NOTIFY
if ( init_devices() == de_InternalError ) if ( init_devices() == de_InternalError )
queue_init_message("Failed to init audio devices"); queue_init_message(gettext("Failed to init audio devices"));
#endif /* AUDIO */ #endif /* AUDIO */
@ -1150,16 +1174,16 @@ int main(int argc, char *argv[])
const char *msg; const char *msg;
if (config_err) { if (config_err) {
msg = "Unable to determine configuration directory. Defaulting to 'data' for data file..."; msg = gettext("Unable to determine configuration directory. Defaulting to 'data' for data file...");
queue_init_message("%s", msg); queue_init_message("%s", msg);
} }
if (settings_err == -1) if (settings_err == -1)
queue_init_message("Failed to load user settings"); queue_init_message(gettext("Failed to load user settings"));
/* screen/tmux auto-away timer */ /* screen/tmux auto-away timer */
if (init_mplex_away_timer(m) == -1) if (init_mplex_away_timer(m) == -1)
queue_init_message("Failed to init mplex auto-away."); queue_init_message(gettext("Failed to init mplex auto-away."));
print_init_messages(prompt); print_init_messages(prompt);
cleanup_init_messages(); cleanup_init_messages();
@ -1182,7 +1206,7 @@ int main(int argc, char *argv[])
if (timed_out(last_save, cur_time, AUTOSAVE_FREQ)) { if (timed_out(last_save, cur_time, AUTOSAVE_FREQ)) {
pthread_mutex_lock(&Winthread.lock); pthread_mutex_lock(&Winthread.lock);
if (store_data(m, DATA_FILE) != 0) if (store_data(m, DATA_FILE) != 0)
line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, "WARNING: Failed to save to data file"); line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, gettext("WARNING: Failed to save to data file"));
pthread_mutex_unlock(&Winthread.lock); pthread_mutex_unlock(&Winthread.lock);
last_save = cur_time; last_save = cur_time;

View File

@ -40,8 +40,8 @@
#include <tox/tox.h> #include <tox/tox.h>
#define UNKNOWN_NAME "Anonymous" #define UNKNOWN_NAME gettext("Anonymous")
#define DEFAULT_TOX_NAME "Tox User" /* should always be the same as toxcore's default name */ #define DEFAULT_TOX_NAME gettext("Tox User") /* should always be the same as toxcore's default name */
#define MAX_STR_SIZE TOX_MAX_MESSAGE_LENGTH /* must be >= TOX_MAX_MESSAGE_LENGTH */ #define MAX_STR_SIZE TOX_MAX_MESSAGE_LENGTH /* must be >= TOX_MAX_MESSAGE_LENGTH */
#define MAX_CMDNAME_SIZE 64 #define MAX_CMDNAME_SIZE 64

View File

@ -25,6 +25,12 @@
#include <pthread.h> #include <pthread.h>
#include <ctype.h> #include <ctype.h>
#ifdef NO_GETTEXT
#define gettext(A) (A)
#else
#include <libintl.h>
#endif
#include "friendlist.h" #include "friendlist.h"
#include "prompt.h" #include "prompt.h"
#include "toxic.h" #include "toxic.h"
@ -359,7 +365,7 @@ void set_next_window(int ch)
return; return;
if (active_window == inf) /* infinite loop check */ if (active_window == inf) /* infinite loop check */
exit_toxic_err("failed in set_next_window", FATALERR_INFLOOP); exit_toxic_err(gettext("failed in set_next_window"), FATALERR_INFLOOP);
} }
} }
@ -381,7 +387,7 @@ ToxWindow *init_windows(Tox *m)
int n_prompt = add_window(m, new_prompt()); int n_prompt = add_window(m, new_prompt());
if (n_prompt == -1 || add_window(m, new_friendlist()) == -1) if (n_prompt == -1 || add_window(m, new_friendlist()) == -1)
exit_toxic_err("failed in init_windows", FATALERR_WININIT); exit_toxic_err(gettext("failed in init_windows"), FATALERR_WININIT);
prompt = &windows[n_prompt]; prompt = &windows[n_prompt];
active_window = prompt; active_window = prompt;

BIN
translations/en.mo Normal file

Binary file not shown.

1602
translations/en.po Normal file

File diff suppressed because it is too large Load Diff

BIN
translations/it.mo Normal file

Binary file not shown.

1602
translations/it.po Normal file

File diff suppressed because it is too large Load Diff

19
translations/tools/create_mo.sh Executable file
View File

@ -0,0 +1,19 @@
#!/bin/bash
cd $(dirname $0)
loc="$1"
while [ -z "$1" -a -z "$loc" ]; do
echo -n "Insert locale (for example \"en\"): "
read loc
done
cd ..
if [ ! -e "$loc.po" ]; then
echo "File \"$loc.po\" not found"
echo "The translation file must exist"
exit 1
else
msgfmt -c -o $loc.mo $loc.po
fi

22
translations/tools/create_po.sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/bash
cd $(dirname $0)
loc="$1"
while [ -z "$1" -a -z "$loc" ]; do
echo -n "Insert locale to create (for example \"en\"): "
read loc
done
cd ..
if [ -e "$loc.po" ]; then
echo "File \"$loc.po\" found"
echo "The translation file must not exist"
exit 1
else
msginit --no-translator -l $loc -o $loc.po -i toxic.pot
v=$(grep TOXIC_VERSION ../cfg/global_vars.mk | head -1 | cut -d "=" -f 2 | tr -d " ")
sed -e '1,5{/^#/d;}' $loc.po > $loc.po.tmp && mv $loc.po.tmp $loc.po
sed -e 's/.*Project-Id-Version:.*/"Project-Id-Version: Toxic '"$v"'\\n"/' $loc.po > $loc.po.tmp && mv $loc.po.tmp $loc.po
fi

19
translations/tools/update_po.sh Executable file
View File

@ -0,0 +1,19 @@
#!/bin/bash
cd $(dirname $0)
loc="$1"
while [ -z "$1" -a -z "$loc" ]; do
echo -n "Insert locale to update (for example \"en\"): "
read loc
done
cd ..
if [ ! -e "$loc.po" ]; then
echo "File \"$loc.po\" not found"
echo "The translation file must exist"
exit 1
else
msgmerge -U --backup=none --previous $loc.po toxic.pot
fi

View File

@ -0,0 +1,4 @@
#!/bin/bash
cd $(dirname $0)/..
xgettext -d toxic -o toxic.pot ../src/*

1574
translations/toxic.pot Normal file

File diff suppressed because it is too large Load Diff