├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README.md
├── android
├── AndroidManifest.xml
├── audio.c
├── freetype.c
├── gl.c
├── main.c
├── main.h
└── res
│ └── drawable
│ └── i.png
├── avatar.c
├── avatar.h
├── button.c
├── button.h
├── cocoa
├── Info.plist
├── MainMenu.xib
├── Makefile
├── cursor.h
├── drawing.m
├── find_static.sh
├── frozen_dmg.tar.bz2
├── grabdesktop.m
├── interaction.m
├── main.h
├── main.m
├── make_dmg.sh
├── make_info_plist.sh
├── objc_main.h
├── utox.iconset
│ ├── icon_128x128.png
│ ├── icon_16x16.png
│ ├── icon_256x256.png
│ ├── icon_32x32.png
│ ├── icon_512x512.png
│ └── icon_512x512@2x.png
└── video.m
├── commands.c
├── commands.h
├── contextmenu.c
├── contextmenu.h
├── dns.c
├── dns.h
├── docs
├── BUILD.md
├── COCOA.md
└── INSTALL.md
├── dropdown.c
├── dropdown.h
├── edit.c
├── edit.h
├── file_transfers.c
├── file_transfers.h
├── friend.c
├── friend.h
├── icons
├── icon.ico
├── icon.rc
├── icon_unread.ico
├── utox-128x128.png
├── utox-14x14.png
├── utox-16x16.png
├── utox-192x192.png
├── utox-22x22.png
├── utox-24x24.png
├── utox-256x256.png
├── utox-32x32.png
├── utox-36x36.png
├── utox-48x48.png
├── utox-512x512.png
├── utox-64x64.png
├── utox-72x72.png
├── utox-96x96.png
└── utox.svg
├── images
├── uTox-win32.png
└── uTox-xlib.png
├── langs
├── bg.h
├── br.h
├── cn.h
├── cs.h
├── da.h
├── de.h
├── en.h
├── es.h
├── fr.h
├── hi.h
├── hu.h
├── it.h
├── ja.h
├── lv.h
├── nl.h
├── no.h
├── pl.h
├── pt.h
├── ro.h
├── ru.h
├── sv.h
├── tr.h
├── tw.h
└── ua.h
├── list.c
├── list.h
├── main.c
├── main.h
├── messages.c
├── messages.h
├── png
├── png.c
└── png.h
├── scrollable.c
├── scrollable.h
├── shared
└── freetype-text.c
├── sized_string.h
├── svg.c
├── svg.h
├── text.c
├── text.h
├── theme.c
├── theme.h
├── theme_tables.h
├── tools
├── android-build.sh
├── cross-compile-windows.sh
└── logs_to_plaintext.c
├── tooltip.c
├── tooltip.h
├── tox.c
├── tox.h
├── tox_av.h
├── tox_bootstrap.h
├── tox_callbacks.h
├── ui.c
├── ui.h
├── ui_buttons.h
├── ui_dropdown.c
├── ui_dropdown.h
├── ui_edits.h
├── ui_i18n.c
├── ui_i18n.h
├── ui_i18n_decls.h
├── unused.h
├── util.c
├── util.h
├── utox.1
├── utox.desktop
├── utox_theme.ini
├── windows
├── audio.c
├── dnd.c
├── example.reg
├── main.7.c
├── main.XP.c
├── main.c
└── main.h
└── xlib
├── audio.c
├── dbus.c
├── event.c
├── freetype.c
├── gtk.c
├── keysym2ucs.c
├── main.c
├── main.h
├── mmenu.c
├── mmenu.h
└── v4l.c
/.gitignore:
--------------------------------------------------------------------------------
1 | *.o
2 | utox
3 | utox.exe
4 | bin/
5 | lib/
6 | debug.keystore
7 | *.dll
8 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # This repository is unmaintained! You can find the new repository here: [GrayHatter/uTox](https://github.com/GrayHatter/utox)
2 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | ## OPTIONS ##
2 | # set to anything else to disable them
3 | DBUS = 1
4 | V4LCONVERT = 1
5 | FILTER_AUDIO = 1
6 | UNITY = 0
7 |
8 | DEPS = fontconfig freetype2 libtoxav libtoxcore
9 | DEPS += openal vpx x11 xext xrender
10 |
11 | ifeq ($(DBUS), 1)
12 | DEPS += dbus-1
13 | endif
14 |
15 | ifeq ($(V4LCONVERT), 1)
16 | DEPS += libv4lconvert
17 | endif
18 |
19 | ifeq ($(FILTER_AUDIO), 1)
20 | DEPS += filteraudio
21 | endif
22 |
23 | ifeq ($(UNITY), 1)
24 | DEPS += messaging-menu unity
25 | endif
26 |
27 | UNAME_S := $(shell uname -s)
28 |
29 | CFLAGS += -g -Wall -Wshadow -pthread -std=gnu99
30 | CFLAGS += $(shell pkg-config --cflags $(DEPS))
31 | LDFLAGS = -pthread -lm
32 | LDFLAGS += $(shell pkg-config --libs $(DEPS))
33 |
34 | ifneq ($(DBUS), 1)
35 | CFLAGS += -DNO_DBUS
36 | endif
37 |
38 | ifneq ($(V4LCONVERT), 1)
39 | CFLAGS += -DNO_V4LCONVERT
40 | endif
41 |
42 | ifeq ($(FILTER_AUDIO), 1)
43 | CFLAGS += -DAUDIO_FILTERING
44 | endif
45 |
46 | ifeq ($(UNITY), 1)
47 | CFLAGS += -DUNITY
48 | endif
49 |
50 | ifeq ($(UNAME_S), Linux)
51 | LDFLAGS += -lresolv -ldl
52 | endif
53 |
54 | DESTDIR ?=
55 | PREFIX ?= /usr/local
56 |
57 | SRC = $(wildcard *.c png/png.c)
58 | OBJ = $(SRC:.c=.o)
59 | GIT_V = $(shell git describe --abbrev=8 --dirty --always --tags)
60 |
61 | all: utox
62 |
63 | utox: $(OBJ)
64 | @echo " LD $@"
65 | @$(CC) $(CFLAGS) -o utox $(OBJ) $(LDFLAGS)
66 |
67 | install: utox
68 | mkdir -p $(DESTDIR)$(PREFIX)/bin
69 | install -m 0755 utox $(DESTDIR)$(PREFIX)/bin/utox
70 |
71 | mkdir -p $(DESTDIR)$(PREFIX)/share/icons/hicolor/14x14/apps
72 | install -m 644 icons/utox-14x14.png $(DESTDIR)$(PREFIX)/share/icons/hicolor/14x14/apps/utox.png
73 | mkdir -p $(DESTDIR)$(PREFIX)/share/icons/hicolor/16x16/apps
74 | install -m 644 icons/utox-16x16.png $(DESTDIR)$(PREFIX)/share/icons/hicolor/16x16/apps/utox.png
75 | mkdir -p $(DESTDIR)$(PREFIX)/share/icons/hicolor/22x22/apps
76 | install -m 644 icons/utox-22x22.png $(DESTDIR)$(PREFIX)/share/icons/hicolor/22x22/apps/utox.png
77 | mkdir -p $(DESTDIR)$(PREFIX)/share/icons/hicolor/24x24/apps
78 | install -m 644 icons/utox-24x24.png $(DESTDIR)$(PREFIX)/share/icons/hicolor/24x24/apps/utox.png
79 | mkdir -p $(DESTDIR)$(PREFIX)/share/icons/hicolor/32x32/apps
80 | install -m 644 icons/utox-32x32.png $(DESTDIR)$(PREFIX)/share/icons/hicolor/32x32/apps/utox.png
81 | mkdir -p $(DESTDIR)$(PREFIX)/share/icons/hicolor/36x36/apps
82 | install -m 644 icons/utox-36x36.png $(DESTDIR)$(PREFIX)/share/icons/hicolor/36x36/apps/utox.png
83 | mkdir -p $(DESTDIR)$(PREFIX)/share/icons/hicolor/48x48/apps
84 | install -m 644 icons/utox-48x48.png $(DESTDIR)$(PREFIX)/share/icons/hicolor/48x48/apps/utox.png
85 | mkdir -p $(DESTDIR)$(PREFIX)/share/icons/hicolor/64x64/apps
86 | install -m 644 icons/utox-64x64.png $(DESTDIR)$(PREFIX)/share/icons/hicolor/64x64/apps/utox.png
87 | mkdir -p $(DESTDIR)$(PREFIX)/share/icons/hicolor/72x72/apps
88 | install -m 644 icons/utox-72x72.png $(DESTDIR)$(PREFIX)/share/icons/hicolor/72x72/apps/utox.png
89 | mkdir -p $(DESTDIR)$(PREFIX)/share/icons/hicolor/96x96/apps
90 | install -m 644 icons/utox-96x96.png $(DESTDIR)$(PREFIX)/share/icons/hicolor/96x96/apps/utox.png
91 | mkdir -p $(DESTDIR)$(PREFIX)/share/icons/hicolor/128x128/apps
92 | install -m 644 icons/utox-128x128.png $(DESTDIR)$(PREFIX)/share/icons/hicolor/128x128/apps/utox.png
93 | mkdir -p $(DESTDIR)$(PREFIX)/share/icons/hicolor/192x192/apps
94 | install -m 644 icons/utox-192x192.png $(DESTDIR)$(PREFIX)/share/icons/hicolor/192x192/apps/utox.png
95 | mkdir -p $(DESTDIR)$(PREFIX)/share/icons/hicolor/256x256/apps
96 | install -m 644 icons/utox-256x256.png $(DESTDIR)$(PREFIX)/share/icons/hicolor/256x256/apps/utox.png
97 | mkdir -p $(DESTDIR)$(PREFIX)/share/icons/hicolor/512x512/apps
98 | install -m 644 icons/utox-512x512.png $(DESTDIR)$(PREFIX)/share/icons/hicolor/512x512/apps/utox.png
99 | mkdir -p $(DESTDIR)$(PREFIX)/share/icons/hicolor/scalable/apps
100 | install -m 644 icons/utox.svg $(DESTDIR)$(PREFIX)/share/icons/hicolor/scalable/apps/utox.svg
101 |
102 | mkdir -p $(DESTDIR)$(PREFIX)/share/applications
103 | install -m 644 utox.desktop $(DESTDIR)$(PREFIX)/share/applications/utox.desktop
104 | if [ "$(UNITY)" -eq "1" ]; then echo "X-MessagingMenu-UsesChatSection=true" >> $(DESTDIR)$(PREFIX)/share/applications/utox.desktop; fi
105 |
106 | mkdir -p $(DESTDIR)$(PREFIX)/share/man/man1
107 | install -m 644 utox.1 $(DESTDIR)$(PREFIX)/share/man/man1/utox.1
108 |
109 | main.o: xlib/main.c xlib/keysym2ucs.c
110 |
111 | .c.o:
112 | @echo " CC $@"
113 | @$(CC) $(CFLAGS) -o $@ -c -DGIT_VERSION=\"$(GIT_V)\" $<
114 |
115 | clean:
116 | rm -f utox *.o png/*.o
117 |
118 | .PHONY: all clean
119 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # This repository is no longer maintained!
2 | # Please report issues or create pull requests here: https://github.com/GrayHatter/utox
3 |
4 |
5 |
6 | # μTox
7 |
8 | Lightweight [Tox](https://github.com/irungentoo/ProjectTox-Core) client.
9 |
10 | * Some things are incomplete and there may be some bugs: feel free to make issues/suggestions
11 |
12 | * Xlib support is mostly complete, but may have some small bugs (no right click menus, lags)
13 |
14 | * Android support is experimental, it lacks important features (accepting/creating file transfers, sending inline images, video)
15 |
16 | * Cocoa (OS X without XQuartz) support is also experimental. Please see [the notes](docs/COCOA.md) before building.
17 |
18 | ## Screenshots
19 |
20 | μTox running on Windows 8
21 |
22 | 
23 |
24 | μTox running on lubuntu:
25 |
26 | 
27 |
28 |
29 | ## Installing
30 |
31 | See [INSTALL.md](docs/INSTALL.md).
32 |
33 | ## Building
34 |
35 | See [BUILD.md](docs/BUILD.md).
36 |
37 | ## Downloads
38 |
39 | [Up to date download links on utox.org](http://utox.org)
40 |
--------------------------------------------------------------------------------
/android/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/android/freetype.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #define PIXELS(x) (((x) + 32) / 64)
5 |
6 | typedef struct
7 | {
8 | uint32_t ucs4;
9 | int16_t x, y;
10 | uint16_t width, height, xadvance, xxxx;
11 | int16_t mx, my;
12 | } GLYPH;
13 |
14 | typedef struct
15 | {
16 | FT_Face face;
17 | uint8_t *fontmap;
18 | uint16_t x, y, my, height;
19 | GLuint texture;
20 | GLYPH *glyphs[128];
21 | } FONT;
22 |
23 | FT_Library ftlib;
24 | FONT font[16], *sfont;
25 |
26 | GLYPH* font_getglyph(FONT *f, uint32_t ch)
27 | {
28 | uint32_t hash = ch % 128;
29 | GLYPH *g = f->glyphs[hash], *s = g;
30 | if(g) {
31 | while(g->ucs4 != ~0) {
32 | if(g->ucs4 == ch) {
33 | return g;
34 | }
35 | g++;
36 | }
37 |
38 | uint32_t count = (uint32_t)(g - s);
39 | g = realloc(s, (count + 2) * sizeof(GLYPH));
40 | if(!g) {
41 | return NULL;
42 | }
43 |
44 | f->glyphs[hash] = g;
45 | g += count;
46 | } else {
47 | g = malloc(sizeof(GLYPH) * 2);
48 | if(!g) {
49 | return NULL;
50 | }
51 |
52 | f->glyphs[hash] = g;
53 | }
54 |
55 | g[1].ucs4 = ~0;
56 | FT_UInt index = FT_Get_Char_Index(f->face, ch);
57 | FT_Load_Glyph(f->face, index, FT_LOAD_RENDER);
58 | FT_GlyphSlotRec *p = f->face->glyph;
59 |
60 | g->ucs4 = ch;
61 | g->x = p->bitmap_left;
62 | g->y = PIXELS(f->face->size->metrics.ascender) - p->bitmap_top;
63 | g->width = p->bitmap.width;
64 | g->height = p->bitmap.rows;
65 | g->xadvance = (p->advance.x + (1 << 5)) >> 6;
66 |
67 | if(f->x + g->width > 512) {
68 | f->x = 0;
69 | f->y = f->my;
70 | }
71 |
72 | g->mx = f->x;
73 | g->my = f->y;
74 |
75 | glBindTexture(GL_TEXTURE_2D, f->texture);
76 | glTexSubImage2D(GL_TEXTURE_2D, 0, f->x, f->y, g->width, g->height, GL_ALPHA, GL_UNSIGNED_BYTE, p->bitmap.buffer);
77 |
78 | f->x += g->width;
79 |
80 | if(f->y + g->height > f->my) {
81 | f->my = f->y + g->height;
82 | }
83 |
84 | return g;
85 | }
86 |
87 | static void initfonts(void)
88 | {
89 | FT_Init_FreeType(&ftlib);
90 | }
91 |
92 | static _Bool font_open(FONT *f, double size, uint8_t weight)
93 | {
94 | FT_New_Face(ftlib, "/system/fonts/Roboto-Regular.ttf", 0, &f->face);
95 | FT_Set_Char_Size(f->face, (size * 64.0 + 0.5), (size * 64.0 + 0.5), 0, 0);
96 |
97 | f->fontmap = malloc(512 * 512);
98 | f->x = 0;
99 | f->y = 0;
100 | f->my = 0;
101 | f->height = 512;
102 |
103 | glGenTextures(1, &f->texture);
104 | glBindTexture(GL_TEXTURE_2D, f->texture);
105 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
106 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
107 | glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512, 512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, f->fontmap);
108 |
109 | return 1;
110 | }
111 |
112 | static void loadfonts(void)
113 | {
114 | #define F(x) (x * SCALE / 2.0)
115 | font_open(&font[FONT_TEXT], F(12.0), 0);
116 |
117 | font_open(&font[FONT_TITLE], F(12.0), 1);
118 |
119 | font_open(&font[FONT_SELF_NAME], F(14.0), 1);
120 | font_open(&font[FONT_STATUS], F(11.0), 0);
121 |
122 | font_open(&font[FONT_LIST_NAME], F(12.0), 0);
123 |
124 | //font_open(&font[FONT_MSG], F(11.0), 2);
125 | //font_open(&font[FONT_MSG_NAME], F(10.0), 2);
126 | font_open(&font[FONT_MISC], F(10.0), 0);
127 | //font_open(&font[FONT_MSG_LINK], F(11.0), 2);
128 | #undef F
129 |
130 | font_small_lineheight = (font[FONT_TEXT].face->size->metrics.height + (1 << 5)) >> 6;
131 | //font_msg_lineheight = (font[FONT_MSG].face->size->metrics.height + (1 << 5)) >> 6;
132 | }
133 |
134 | static void freefonts(void)
135 | {
136 | int i;
137 | for(i = 0; i != countof(font); i++) {
138 | FONT *f = &font[i];
139 | if(f->face) {
140 | FT_Done_Face(f->face);
141 | }
142 |
143 | int j = 0;
144 | for(j = 0; j != countof(f->glyphs); j++) {
145 | GLYPH *g = f->glyphs[j];
146 | if(g) {
147 | /*while(g->ucs4 != ~0) {
148 | if(g->pic) {
149 | XRenderFreePicture(display, g->pic);
150 | }
151 | g++;
152 | }*/
153 |
154 | free(f->glyphs[j]);
155 | f->glyphs[j] = NULL;
156 | }
157 | }
158 | }
159 | }
160 |
161 | static int _drawtext(int x, int xmax, int y, char_t *str, STRING_IDX length)
162 | {
163 | glUniform3fv(k, 1, colorf);
164 | glBindTexture(GL_TEXTURE_2D, sfont->texture);
165 | int c = 0;
166 |
167 | GLYPH *g;
168 | uint8_t len;
169 | uint32_t ch;
170 | while(length) {
171 | len = utf8_len_read(str, &ch);
172 | str += len;
173 | length -= len;
174 |
175 | g = font_getglyph(sfont, ch);
176 | if(g) {
177 | if(x + g->xadvance > xmax) {
178 | x = -x;
179 | break;
180 | }
181 |
182 | if(c == 64) {
183 | glDrawQuads(0, 64);
184 | c = 0;
185 | }
186 |
187 | makeglyph(&quads[c++], x + g->x, y + g->y, g->mx, g->my, g->width, g->height);
188 |
189 | x += g->xadvance;
190 | }
191 | }
192 |
193 | glDrawQuads(0, c);
194 |
195 | return x;
196 | }
197 |
198 | #include "../shared/freetype-text.c"
199 |
200 |
--------------------------------------------------------------------------------
/android/main.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | #include
12 |
13 | #define debug(...) ((void)__android_log_print(ANDROID_LOG_INFO, "utox", __VA_ARGS__))
14 |
15 | #define RGB(r, g, b) ((r) | ((g) << 8) | ((b) << 16))
16 |
17 | #define KEY_BACK 1
18 | #define KEY_RETURN 2
19 | #define KEY_LEFT 3
20 | #define KEY_RIGHT 4
21 | #define KEY_TAB 7
22 | #define KEY_DEL 8
23 | #define KEY_END 9
24 | #define KEY_HOME 10
25 | #define KEY_UP 5
26 | #define KEY_DOWN 6
27 | #define KEY_PAGEUP 11
28 | #define KEY_PAGEDOWN 12
29 |
30 | #define KEY(x) (x)
31 |
32 | // Early include to obtain GLuint.
33 | #include
34 | typedef GLuint UTOX_NATIVE_IMAGE;
35 | #define UTOX_NATIVE_IMAGE_IS_VALID(x) (0 != (x))
36 |
--------------------------------------------------------------------------------
/android/res/drawable/i.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/android/res/drawable/i.png
--------------------------------------------------------------------------------
/avatar.c:
--------------------------------------------------------------------------------
1 | #include "main.h"
2 |
3 | /* gets avatar filepath for given client id string and stores it in dest,
4 | * returns number of chars written */
5 | int get_avatar_location(char_t *dest, const char_t *id)
6 | {
7 | char_t *p = dest + datapath_subdir(dest, AVATAR_DIRECTORY);
8 | memcpy((char *)p, id, TOX_PUBLIC_KEY_SIZE * 2); p += TOX_PUBLIC_KEY_SIZE * 2;
9 | strcpy((char *)p, ".png"); p += sizeof(".png") - 1;
10 |
11 | return p - dest;
12 | }
13 |
14 | /* frees the image of an avatar, does nothing if image is NULL */
15 | void avatar_free_image(AVATAR *avatar)
16 | {
17 | if (avatar->image) {
18 | image_free(avatar->image);
19 | avatar->image = NULL;
20 | }
21 | }
22 |
23 |
24 | int load_avatar(const char_t *id, uint8_t *dest, uint32_t *size_out)
25 | {
26 | char_t path[UTOX_FILE_NAME_LENGTH];
27 | uint32_t size;
28 |
29 | get_avatar_location(path, id);
30 |
31 | uint8_t *avatar_data = file_raw((char *)path, &size);
32 | if (!avatar_data) {
33 | return 0;
34 | }
35 | if (size > UTOX_AVATAR_MAX_DATA_LENGTH) {
36 | free(avatar_data);
37 | debug("Avatars:\t saved avatar file(%s) too large for tox\n", path);
38 | return 0;
39 | }
40 |
41 | memcpy(dest, avatar_data, size);
42 | free(avatar_data);
43 | if (size_out) {
44 | *size_out = size;
45 | }
46 | return 1;
47 | }
48 |
49 | int save_avatar(const char_t *id, const uint8_t *data, uint32_t size)
50 | {
51 | char_t path[UTOX_FILE_NAME_LENGTH];
52 |
53 | get_avatar_location(path, id);
54 |
55 | FILE *file = fopen((char*)path, "wb");
56 | if (file) {
57 | fwrite(data, size, 1, file);
58 | flush_file(file);
59 | fclose(file);
60 | return 1;
61 | } else {
62 | debug("Avatars:\terror opening avatar file (%s) for writing\n", (char *)path);
63 | return 0;
64 | }
65 | }
66 |
67 | int delete_saved_avatar(const char_t *id)
68 | {
69 | char_t path[UTOX_FILE_NAME_LENGTH];
70 |
71 | get_avatar_location(path, id);
72 |
73 | return remove((char *)path);
74 | }
75 |
76 |
77 | int set_avatar(AVATAR *avatar, const uint8_t *data, uint32_t size)
78 | {
79 | if (size > UTOX_AVATAR_MAX_DATA_LENGTH) {
80 | debug("Avatars:\t avatar too large\n");
81 | return 0;
82 | }
83 |
84 | uint16_t w, h;
85 | UTOX_NATIVE_IMAGE *image = png_to_image((UTOX_PNG_IMAGE)data, size, &w, &h, 1);
86 | if(!UTOX_NATIVE_IMAGE_IS_VALID(image)) {
87 | debug("Avatars:\t avatar is invalid\n");
88 | return 0;
89 | } else {
90 |
91 | avatar_free_image(avatar);
92 |
93 | avatar->image = image;
94 | avatar->width = w;
95 | avatar->height = h;
96 | avatar->format = UTOX_AVATAR_FORMAT_PNG;
97 | tox_hash(avatar->hash, data, size);
98 |
99 | return 1;
100 | }
101 | }
102 |
103 | void unset_avatar(AVATAR *avatar)
104 | {
105 | avatar->format = UTOX_AVATAR_FORMAT_NONE;
106 | avatar_free_image(avatar);
107 | }
108 |
109 | /* sets self avatar, see self_set_and_save_avatar */
110 | int self_set_avatar(const uint8_t *data, uint32_t size)
111 | {
112 | if (!set_avatar(&self.avatar, data, size)) {
113 | return 0;
114 | }
115 |
116 | uint8_t *png_data = malloc(size);
117 | memcpy(png_data, data, size);
118 | tox_postmessage(TOX_SETAVATAR, UTOX_AVATAR_FORMAT_PNG, size, png_data);
119 | return 1;
120 | }
121 |
122 | int self_set_and_save_avatar(const uint8_t *data, uint32_t size)
123 | {
124 | if (self_set_avatar(data, size)) {
125 | uint8_t hex_id[TOX_FRIEND_ADDRESS_SIZE * 2];
126 | id_to_string(hex_id, self.id_binary);
127 | save_avatar(hex_id, data, size);
128 | return 1;
129 | } else {
130 | return 0;
131 | }
132 | }
133 |
134 | void self_remove_avatar()
135 | {
136 | unset_avatar(&self.avatar);
137 | uint8_t hex_id[TOX_FRIEND_ADDRESS_SIZE * 2];
138 | id_to_string(hex_id, self.id_binary);
139 | delete_saved_avatar(hex_id);
140 | tox_postmessage(TOX_UNSETAVATAR, 0, 0, NULL);
141 | }
142 |
143 | _Bool avatar_on_friend_online(Tox *tox, uint32_t friend_number){
144 | uint8_t *avatar_data = self.avatar_data;
145 | size_t avatar_size = self.avatar_size;
146 |
147 | outgoing_file_send(tox, friend_number, NULL, avatar_data, avatar_size, TOX_FILE_KIND_AVATAR);
148 | return 1;
149 | }
150 |
151 | int utox_avatar_update_friends(Tox *tox){
152 | uint32_t i, friend_count, error_count = 0;
153 | friend_count = tox_self_get_friend_list_size(tox);
154 | uint32_t friend_loop[friend_count];
155 | tox_self_get_friend_list(tox, friend_loop);
156 |
157 | for(i = 0; i < friend_count; i++){
158 | if (tox_friend_get_connection_status(tox, friend_loop[i], 0)) {
159 | error_count += !avatar_on_friend_online(tox, friend_loop[i]);
160 | }
161 | }
162 |
163 | return error_count;
164 | }
165 |
166 | void utox_incoming_avatar(uint32_t friend_number, uint8_t *avatar, size_t size){
167 | // save avatar and hash to disk
168 |
169 | if(size <= 0){
170 | postmessage(FRIEND_UNSETAVATAR, friend_number, 0, NULL);
171 | } else {
172 | postmessage(FRIEND_SETAVATAR, friend_number, size, avatar);
173 | }
174 | }
175 |
--------------------------------------------------------------------------------
/avatar.h:
--------------------------------------------------------------------------------
1 | /* subdirectory name to save avatars in */
2 | #define AVATAR_DIRECTORY "avatars"
3 |
4 | //TODO: remove
5 | #define UTOX_AVATAR_MAX_DATA_LENGTH (64 * 1024) //NOTE: increasing this above 64k might cause issues.
6 | #define UTOX_AVATAR_FORMAT_NONE 0
7 | #define UTOX_AVATAR_FORMAT_PNG 1
8 |
9 | /* data needed for each avatar in memory */
10 | typedef struct avatar {
11 | uint8_t format; /* one of TOX_AVATAR_FORMAT */
12 | uint8_t hash[TOX_HASH_LENGTH]; /* tox_hash for the png data of this avatar */
13 | UTOX_NATIVE_IMAGE *image; /* converted avatar image to draw */
14 | uint16_t width, height; /* width and height of image (in pixels) */
15 | }AVATAR;
16 |
17 | /* whether user's avatar is set */
18 | #define self_has_avatar() (self.avatar.format != UTOX_AVATAR_FORMAT_NONE)
19 | /* whether friend f's avatar is set, where f is a pointer to a friend struct */
20 | #define friend_has_avatar(f) (f->avatar.format != UTOX_AVATAR_FORMAT_NONE)
21 |
22 | /* gets the avatar location on the disk and puts the result in dest.
23 | * id is the client id string for given client. To get the cid string from a cid, use cid_to_string
24 | * returns the number of chars written
25 | */
26 | int get_avatar_location(char_t *dest, const char_t *id);
27 |
28 | /* loads an avatar from disk and puts the resulting png data in buffer given by dest.
29 | * id is the client id string for given client. To get the cid string from a cid, use cid_to_string
30 | * id should be at least (TOX_PUBLIC_KEY_SIZE * 2) bytes long
31 | * if size_out is not NULL, load_avatar will store the length of the png data there
32 | * on success: returns 1
33 | * on failure: returns 0
34 | * notes: dest should be at least UTOX_AVATAR_MAX_DATA_LENGTH bytes long.
35 | */
36 | int load_avatar(const char_t *id, uint8_t *dest, uint32_t *size_out);
37 |
38 | /* saves avatar png data to disk
39 | * id is cid string(see load_avatar), and size is size of data
40 | * on success: returns 1
41 | * on failure: returns 0
42 | * see also: load_avatar
43 | */
44 | int save_avatar(const char_t *id, const uint8_t *data, uint32_t size);
45 |
46 | /* deletes saved avatar data for given id
47 | * on success: returns 1
48 | * on failure: returns 0
49 | * see also: load_avatar
50 | */
51 | int delete_saved_avatar(const char_t *id);
52 |
53 | /* converts png data given by data to a UTOX_NATIVE_IMAGE and uses that to populate the avatar struct
54 | * avatar is pointer to an avatar struct to store result in. Remains unchanged if function fails.
55 | * data is pointer to png data to convert
56 | * size is size of data
57 | *
58 | * on success: returns 1
59 | * on failure: returns 0
60 | *
61 | * notes: fails if given size is larger than UTOX_AVATAR_MAX_DATA_LENGTH or data is not valid PNG data
62 | */
63 | int set_avatar(AVATAR *avatar, const uint8_t *data, uint32_t size);
64 |
65 | /* unsets an avatar by setting its format to UTOX_AVATAR_FORMAT_NONE and
66 | * freeing its image */
67 | void unset_avatar(AVATAR *avatar);
68 |
69 | /* sets own avatar based on given png data and saves it to disk if successful
70 | * data is png data to set avatar to
71 | * size is size of data
72 | *
73 | * on success: returns 1
74 | * on failure: returns 0
75 | *
76 | * notes: fails if size is too large or data is not a valid png file
77 | */
78 | int self_set_and_save_avatar(const uint8_t *data, uint32_t size);
79 |
80 | /* unsets own avatar and removes it from disk */
81 | void self_remove_avatar();
82 |
83 | /* Call this every time friend_number goes online from the tox_do thread.
84 | *
85 | * return 1 on success.
86 | * return 0 on failure.
87 | */
88 | _Bool avatar_on_friend_online(Tox *tox, uint32_t friend_number);
89 |
90 | /** called once out new avatar is changed to update all of our friends
91 | *
92 | * returns 0 if there were no errors sending the avatars to every online friend.
93 | * returns +1 for each friend we could not send to.
94 | * returns negative if any avatar or friend was left in an unknown state.
95 | */
96 | int utox_avatar_update_friends(Tox *tox);
97 |
98 | /** Colled by incoming file transfers to change the avater.
99 | *
100 | * If size <=0, we'll unset the avatar, else we'll set and update the friend
101 | */
102 | void utox_incoming_avatar(uint32_t friend_number, uint8_t *avatar, size_t size);
103 |
--------------------------------------------------------------------------------
/button.c:
--------------------------------------------------------------------------------
1 | #include "main.h"
2 |
3 | static void calculate_pos_and_width(BUTTON *b, int *x, int *w) {
4 | int old_w = *w;
5 |
6 | // Increase width if needed, so that button text fits.
7 | if(maybe_i18nal_string_is_valid(&b->button_text)) {
8 | STRING* s = maybe_i18nal_string_get(&b->button_text);
9 | int needed_w = textwidth(s->str, s->length) + 6 * SCALE;
10 | if(*w < needed_w) {
11 | *w = needed_w;
12 | }
13 | }
14 |
15 | // Push away from the right border to fit,
16 | // if our panel is right-adjusted.
17 | if(b->panel.x < 0) {
18 | *x -= *w - old_w;
19 | }
20 | }
21 |
22 | void button_draw(BUTTON *b, int x, int y, int width, int height)
23 | {
24 | // Button is hidden
25 | if (b->nodraw)
26 | return;
27 |
28 | // If `update` function is defined, call it on each draw
29 | if (b->update) {
30 | b->update(b);
31 | }
32 |
33 | // Ensure that font is set before calculating position and width.
34 | setfont(FONT_SELF_NAME);
35 |
36 | // Button contents color
37 | uint32_t color_text = b->mousedown ? b->ct2 : (b->mouseover ? b->ct2 : b->ct1);
38 | setcolor(color_text);
39 |
40 | int w = width;
41 | calculate_pos_and_width(b, &x, &w);
42 |
43 | // Button background color
44 | uint32_t color_background = b->mousedown ? b->c3 : (b->mouseover ? b->c2 : b->c1);
45 |
46 | if(b->bm) {
47 | drawalpha(b->bm, x, y, width, height, color_background);
48 | } else {
49 | drawrectw(x, y, w, height, b->disabled ? (b->cd ? b->cd : b->cd) : color_background);
50 |
51 | //setfont(FONT_TEXT_LARGE);
52 | //setcolor(b->mouseover ? 0x222222 : 0x555555);
53 | //drawtext(x + 5, y, b->text, b->text_length);
54 | }
55 |
56 | if(b->bm2) {
57 | int bx = w / 2 - b->bw * SCALE / 2, by = height / 2 - b->bh * SCALE / 2;
58 | drawalpha(b->bm2, x + bx, y + by, b->bw * SCALE, b->bh * SCALE, color_text);
59 | }
60 |
61 | if(maybe_i18nal_string_is_valid(&b->button_text)) {
62 | if(b->bm) {
63 | while(w > width) {
64 | // The text didn't fit into the original width.
65 | // Fill the rest of the new width with the image
66 | // and hope for the best.
67 | drawalpha(b->bm, x - width + w, y, width, height, color_background);
68 | w -= width / 2 + 1;
69 | }
70 | }
71 | STRING* s = maybe_i18nal_string_get(&b->button_text);
72 | drawtext(x + 3 * SCALE, y + SCALE, s->str, s->length);
73 | }
74 | }
75 |
76 | _Bool button_mmove(BUTTON *b, int UNUSED(x), int UNUSED(y), int width, int height, int mx, int my, int UNUSED(dx), int UNUSED(dy))
77 | {
78 | // Ensure that font is set before calculating position and width.
79 | setfont(FONT_SELF_NAME);
80 |
81 | int real_x = 0, real_w = width;
82 | calculate_pos_and_width(b, &real_x, &real_w);
83 |
84 | _Bool mouseover = inrect(mx, my, real_x, 0, real_w, height);
85 | if(mouseover) {
86 | if(!b->disabled) {
87 | cursor = CURSOR_HAND;
88 | }
89 |
90 | if(maybe_i18nal_string_is_valid(&b->tooltip_text)) {
91 | tooltip_new(&b->tooltip_text);
92 | }
93 |
94 | }
95 | if(mouseover != b->mouseover) {
96 | b->mouseover = mouseover;
97 | return 1;
98 | }
99 |
100 | return 0;
101 | }
102 |
103 | _Bool button_mdown(BUTTON *b)
104 | {
105 | if(!b->mousedown && b->mouseover) {
106 | b->mousedown = 1;
107 | return 1;
108 | }
109 |
110 | return 0;
111 | }
112 |
113 | _Bool button_mright(BUTTON *b)
114 | {
115 | if(b->mouseover && b->onright) {
116 | b->onright();
117 | return 1;
118 | }
119 |
120 | return 0;
121 | }
122 |
123 | _Bool button_mwheel(BUTTON *UNUSED(b), int UNUSED(height), double UNUSED(d))
124 | {
125 | return 0;
126 | }
127 |
128 | _Bool button_mup(BUTTON *b)
129 | {
130 | if(b->mousedown) {
131 | if(b->mouseover) {
132 | b->onpress();
133 | }
134 |
135 | b->mousedown = 0;
136 | return 1;
137 | }
138 |
139 | return 0;
140 | }
141 |
142 | _Bool button_mleave(BUTTON *b)
143 | {
144 | if(b->mouseover) {
145 | b->mouseover = 0;
146 | return 1;
147 | }
148 |
149 | return 0;
150 | }
151 |
--------------------------------------------------------------------------------
/button.h:
--------------------------------------------------------------------------------
1 | struct button {
2 | PANEL panel;
3 |
4 | // Button picture id, top-left aligned/centered respectively.
5 | int bm, bm2;
6 |
7 | // Width/height of bm2 picture. Used for centering.
8 | int bw, bh;
9 |
10 | // Background RGB color for bm picture, when Idle/Hovered/Pressed respectively.
11 | uint32_t
12 | c1, // Button normal background colour
13 | c2, // Button hover background colour
14 | c3, // Button active (press) background colour
15 | ct1, // Button contents (text or icon) colour
16 | ct2, // Button contents (text or icon) hover colour
17 | cd;
18 |
19 | MAYBE_I18NAL_STRING button_text;
20 | MAYBE_I18NAL_STRING tooltip_text;
21 |
22 | _Bool mouseover, mousedown, disabled, nodraw;
23 |
24 | void (*onright)(void); // called when right mouse button goes down
25 | void (*onpress)(void);
26 | void (*update)(BUTTON *b);
27 | };
28 |
29 | void button_draw(BUTTON *b, int x, int y, int width, int height);
30 | _Bool button_mmove(BUTTON *b, int x, int y, int width, int height, int mx, int my, int dx, int dy);
31 | _Bool button_mdown(BUTTON *b);
32 | _Bool button_mright(BUTTON *b);
33 | _Bool button_mwheel(BUTTON *b, int height, double d);
34 | _Bool button_mup(BUTTON *b);
35 | _Bool button_mleave(BUTTON *b);
36 |
--------------------------------------------------------------------------------
/cocoa/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | future.$(PRODUCT_NAME:rfc1034identifier)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | LSMinimumSystemVersion
26 | $(MACOSX_DEPLOYMENT_TARGET)
27 | NSHumanReadableCopyright
28 | Copyright © 2015 Tox project. All rights reserved.
29 | NSMainNibFile
30 | MainMenu
31 | NSPrincipalClass
32 | NSApplication
33 |
34 |
35 |
--------------------------------------------------------------------------------
/cocoa/Makefile:
--------------------------------------------------------------------------------
1 | ## OPTIONS ##
2 | # set to anything else to disable them
3 | COCOA = 1
4 | FILTER_AUDIO = 1
5 |
6 | CFLAGS ?= ""
7 | LDFLAGS ?= ""
8 | FRAMEWORKS = -framework AppKit -framework CoreGraphics -framework OpenAL -framework Foundation \
9 | -framework CoreText -framework CoreFoundation -framework AVFoundation \
10 | -framework CoreVideo -framework CoreMedia -framework OpenGL -framework QuartzCore \
11 | -lresolv
12 | DEPS = libtoxcore libtoxav vpx libsodium
13 |
14 | ifeq ($(FILTER_AUDIO), 1)
15 | DEPS += filteraudio
16 | CFLAGS += -DAUDIO_FILTERING
17 | endif
18 |
19 | CFLAGS += -g -Wall -Wshadow -Os
20 | CFLAGS += $(shell pkg-config --cflags $(DEPS))
21 | LDFLAGS += $(FRAMEWORKS)
22 | LDFLAGS += -pthread -lm
23 | LDFLAGS += $(shell pkg-config --libs $(DEPS))
24 |
25 | DESTDIR ?=
26 | PREFIX ?= /usr/local
27 |
28 | SRC = $(wildcard *.c cocoa/*.m)
29 | OBJ = $(SRC:=.o)
30 | GIT_V = $(shell git describe --abbrev=8 --dirty --always --tags)
31 | CFLAGS += -DGIT_VERSION=\"$(GIT_V)\"
32 |
33 | all: utox
34 |
35 | utox: $(OBJ)
36 | @echo " LD $@"
37 | @$(CC) $(CFLAGS) -o utox $(OBJ) $(LDFLAGS)
38 |
39 | utox-static: $(OBJ)
40 | @echo " SL $@"
41 | $(CC) $(CFLAGS) -o utox-static $(OBJ) $(shell cocoa/find_static.sh $(DEPS)) $(FRAMEWORKS)
42 |
43 | utox-MainMenu.nib:
44 | ibtool --compile $@ cocoa/MainMenu.xib
45 |
46 | utox-Info.plist:
47 | sh cocoa/make_info_plist.sh cocoa/Info.plist $@
48 |
49 | utox.icns:
50 | iconutil --convert icns cocoa/utox.iconset -o ./utox.icns
51 |
52 | uTox.app: utox utox-Info.plist utox-MainMenu.nib utox.icns
53 | mkdir -p uTox.app/Contents/MacOS
54 | mkdir -p uTox.app/Contents/Resources
55 | install -m 755 utox uTox.app/Contents/MacOS/utox
56 | install -m 644 utox-Info.plist uTox.app/Contents/Info.plist
57 | install -m 644 utox.icns uTox.app/Contents/Resources/uTox.icns
58 | install -m 644 utox-MainMenu.nib uTox.app/Contents/Resources/MainMenu.nib
59 |
60 | uTox.dmg: utox-static uTox.app
61 | sh cocoa/make_dmg.sh
62 |
63 | %.m.o: %.m
64 | @echo " OBJC $@"
65 | @$(CC) -xobjective-c $(CFLAGS) -o $@ -c $<
66 |
67 | %.c.o: %.c
68 | @echo " CC $@"
69 | @$(CC) -xobjective-c $(CFLAGS) -o $@ -c $<
70 |
71 | clean:
72 | rm -f utox utox-Info.plist utox-MainMenu.nib cocoa/*.o *.o .utox_info_plist.* utox-static uTox.dmg
73 | rm -rf uTox.app utox_dmg.*
74 |
75 | print-%:
76 | @echo $($*)
77 |
78 | .PHONY: all clean
79 |
--------------------------------------------------------------------------------
/cocoa/cursor.h:
--------------------------------------------------------------------------------
1 | #ifndef SCA_CURSOR_H
2 | #define SCA_CURSOR_H
3 |
4 | #import
5 |
6 | static inline CGImageRef create_zoom_cursor(CGFloat scale, BOOL plus) {
7 | CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
8 | CGColorRef black = CGColorCreateGenericRGB(0, 0, 0, 1.0);
9 | CGColorRef white = CGColorCreateGenericRGB(1, 1, 1, 1.0);
10 |
11 | CGContextRef draw = CGBitmapContextCreate(NULL, 16 * scale, 16 * scale, 8, 0, cs, (CGBitmapInfo)kCGImageAlphaPremultipliedLast);
12 | CGColorSpaceRelease(cs);
13 |
14 | CGContextBeginPath(draw);
15 | CGContextMoveToPoint(draw, 2. * scale, 14. * scale);
16 | CGContextAddLineToPoint(draw, 15. * scale, 1. * scale);
17 | //CGContextCloseSubpath(draw);
18 |
19 | CGContextSetStrokeColorWithColor(draw, black);
20 | CGContextSetLineWidth(draw, 3.0 * scale);
21 | CGContextDrawPath(draw, kCGPathStroke);
22 |
23 | CGContextBeginPath(draw);
24 | CGContextAddEllipseInRect(draw, CGRectInset((CGRect){0, 4 * scale, 12 * scale, 12 * scale}, 0.5, 0.5));
25 |
26 | CGContextSetLineWidth(draw, scale);
27 | CGContextSetFillColorWithColor(draw, white);
28 | CGContextDrawPath(draw, kCGPathFillStroke);
29 |
30 | CGContextBeginPath(draw);
31 | CGContextAddRect(draw, (CGRect){3 * scale, 9 * scale, 6 * scale, 2 * scale});
32 |
33 | if (plus)
34 | CGContextAddRect(draw, (CGRect){5 * scale, 7 * scale, 2 * scale, 6 * scale});
35 |
36 | CGContextSetFillColorWithColor(draw, black);
37 | CGContextDrawPath(draw, kCGPathFill);
38 |
39 | CGImageRef glass = CGBitmapContextCreateImage(draw);
40 | CGContextRelease(draw);
41 | CGColorRelease(white);
42 | CGColorRelease(black);
43 | return glass;
44 | }
45 |
46 | static inline NSCursor *create_zoom_in_cursor(void) {
47 | CGImageRef base = create_zoom_cursor(1.0, YES);
48 | CGImageRef base2x = create_zoom_cursor(2.0, YES);
49 |
50 | NSBitmapImageRep *b = [[NSBitmapImageRep alloc] initWithCGImage:base];
51 | NSBitmapImageRep *b2x = [[NSBitmapImageRep alloc] initWithCGImage:base2x];
52 | NSImage *cur = [[NSImage alloc] initWithSize:(CGSize){16, 16}];
53 | [cur addRepresentation:b2x];
54 | b2x.size = (CGSize){16, 16};
55 | [cur addRepresentation:b];
56 |
57 | NSCursor *ret = [[NSCursor alloc] initWithImage:cur hotSpot:(CGPoint){6, 6}];
58 |
59 | [b release];
60 | [b2x release];
61 | [cur release];
62 | CGImageRelease(base);
63 | CGImageRelease(base2x);
64 |
65 | return ret;
66 | }
67 |
68 | static inline NSCursor *create_zoom_out_cursor(void) {
69 | CGImageRef base = create_zoom_cursor(1.0, NO);
70 | CGImageRef base2x = create_zoom_cursor(2.0, NO);
71 |
72 | NSBitmapImageRep *b = [[NSBitmapImageRep alloc] initWithCGImage:base];
73 | NSBitmapImageRep *b2x = [[NSBitmapImageRep alloc] initWithCGImage:base2x];
74 | NSImage *cur = [[NSImage alloc] initWithSize:(CGSize){16, 16}];
75 | [cur addRepresentation:b2x];
76 | b2x.size = (CGSize){16, 16};
77 | [cur addRepresentation:b];
78 |
79 | NSCursor *ret = [[NSCursor alloc] initWithImage:cur hotSpot:(CGPoint){6, 6}];
80 |
81 | [b release];
82 | [b2x release];
83 | [cur release];
84 | CGImageRelease(base);
85 | CGImageRelease(base2x);
86 |
87 | return ret;
88 | }
89 |
90 | #endif
91 |
--------------------------------------------------------------------------------
/cocoa/find_static.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Find .a archives for static linking purposes
3 | # Copyright 2015 Zodiac Labs but you are free
4 | # to reuse anywhere without permission
5 |
6 | unmangle_ldflags() {
7 | for LIBWHAT in $@; do
8 | printf "$(echo $LIBWHAT | sed -e s/-l/lib/g -e s/\$/.a/g) "
9 | done
10 | }
11 |
12 | LDFLAGS=
13 | for LIBRARY in $@; do
14 | SP=$(pkg-config --libs-only-L $LIBRARY | sed s/-L//g)
15 | NLIB=$(unmangle_ldflags $(pkg-config --libs-only-l $LIBRARY))
16 | for ARCHIVE in $NLIB; do
17 | LDFLAGS="$LDFLAGS $(find $SP -name $ARCHIVE | head -n 1)"
18 | done
19 | done
20 |
21 | echo $LDFLAGS | sort | uniq
22 |
--------------------------------------------------------------------------------
/cocoa/frozen_dmg.tar.bz2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/cocoa/frozen_dmg.tar.bz2
--------------------------------------------------------------------------------
/cocoa/main.h:
--------------------------------------------------------------------------------
1 | #ifndef COCOA_MAIN_H
2 | #define COCOA_MAIN_H
3 |
4 | /* Don't put Objective-C declarations here so we don't have to compile
5 | * all of uTox as ObjC. Stuff that requires ObjC available goes in objc_main.h,
6 | * included below. */
7 |
8 | #include
9 |
10 | #include
11 |
12 | #include
13 |
14 | #include
15 |
16 | #include
17 |
18 | #define KEY_BACK kVK_Delete
19 | #define KEY_RETURN kVK_Return
20 | #define KEY_LEFT kVK_LeftArrow
21 | #define KEY_RIGHT kVK_RightArrow
22 | #define KEY_TAB kVK_Tab
23 | #define KEY_LEFT_TAB kVK_ISO_Left_Tab
24 | #define KEY_DEL kVK_ForwardDelete
25 | #define KEY_END kVK_End
26 | #define KEY_HOME kVK_Home
27 | #define KEY_UP kVK_UpArrow
28 | #define KEY_DOWN kVK_DownArrow
29 | #define KEY_PAGEUP kVK_PageUp
30 | #define KEY_PAGEDOWN kVK_PageDown
31 |
32 | #define KEY(k) (k)
33 |
34 | #define RGB(r, g, b) (((r) << 16) | ((g) << 8) | (b))
35 |
36 | void debug(const char *fmt, ...);
37 | typedef struct utox_native_image UTOX_NATIVE_IMAGE;
38 | int UTOX_NATIVE_IMAGE_IS_VALID(UTOX_NATIVE_IMAGE *img);
39 |
40 | #ifdef __OBJC__
41 | #include "objc_main.h"
42 | #endif
43 |
44 | #endif
45 |
--------------------------------------------------------------------------------
/cocoa/make_dmg.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | WORK=$(mktemp -d utox_dmg.XXXXXXX) || exit 1
3 | tar -C $WORK -xjf "cocoa/frozen_dmg.tar.bz2"
4 |
5 | rm $WORK/uTox/uTox.app
6 | cp -r "uTox.app" "$WORK/uTox/uTox.app"
7 | cp -r "utox-static" "$WORK/uTox/uTox.app/Contents/MacOS/utox"
8 | chmod +x "$WORK/uTox/uTox.app/Contents/MacOS/utox"
9 | if [ ".$CODE_SIGN_IDENTITY" = "." ]; then
10 | CODE_SIGN_IDENTITY="-"
11 | fi
12 | codesign -s "$CODE_SIGN_IDENTITY" -fv "$WORK/uTox/uTox.app/Contents/MacOS/utox"
13 | touch $WORK/uTox/.Trash
14 |
15 | hdiutil create -megabytes 32 -srcfolder $WORK/uTox \
16 | -format UDBZ -nospotlight -noanyowners "uTox.dmg"
17 | rm -rf $WORK
--------------------------------------------------------------------------------
/cocoa/make_info_plist.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | TMPFILE=$(mktemp .utox_info_plist.XXXXXXX)
3 | cp $1 $TMPFILE
4 |
5 | plist_set() {
6 | /usr/libexec/PlistBuddy -c "Set :$1 '$2'" $TMPFILE
7 | }
8 |
9 | plist_set CFBundleIdentifier "future.utox"
10 | plist_set CFBundleExecutable "utox"
11 | plist_set LSMinimumSystemVersion "10.7"
12 | plist_set CFBundleName "uTox"
13 | plist_set CFBundleIconFile "uTox"
14 |
15 | mv $TMPFILE "utox-Info.plist"
--------------------------------------------------------------------------------
/cocoa/objc_main.h:
--------------------------------------------------------------------------------
1 | #ifndef uTox_objc_main_h
2 | #define uTox_objc_main_h
3 |
4 | #import
5 | #import
6 | #import
7 |
8 | @class uToxStardustView;
9 | extern CGDirectDisplayID desktop_capture_from;
10 | extern CGRect desktop_capture_rect;
11 | extern CGFloat desktop_capture_scale;
12 | typedef struct {
13 | NSWindow *window;
14 | uToxStardustView *view;
15 | void (*finished_callback)(_Bool, uint64_t, NSWindow *);
16 | } stardust_context_t;
17 | extern stardust_context_t stardust_context;
18 |
19 | void setup_cursors(void);
20 |
21 | #define RELEASE_CHK(func, obj) if ((obj)) \
22 | func((obj));
23 |
24 | //#define HAS_CUSTOM_EDIT_DRAW_IMPLEMENTATION
25 |
26 | #define MAC_OS_AT_LEAST_DO(a, b, c) \
27 | if ([[NSProcessInfo processInfo] respondsToSelector:@selector(isOperatingSystemAtLeastVersion:)] && \
28 | [[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){a, b, c}])
29 | #define AT_LEAST_YOSEMITE_DO MAC_OS_AT_LEAST_DO(10, 10, 0)
30 |
31 | // gotta use the old version checker here
32 | #define AT_LEAST_MAVERICKS_DO if (NSFoundationVersionNumber >= NSFoundationVersionNumber10_9)
33 | #define AT_LEAST_MOUNTAIN_LION_DO if (NSFoundationVersionNumber >= NSFoundationVersionNumber10_8)
34 |
35 | #define NSSTRING_FROM_LOCALIZED(msgid) [[[NSString alloc] initWithBytes:S(msgid) length:SLEN(msgid) encoding:NSUTF8StringEncoding] autorelease]
36 |
37 |
38 | struct utox_native_image {
39 | CGImageRef image;
40 | double scale;
41 | };
42 |
43 | @class uToxView;
44 | @interface uToxAppDelegate : NSResponder {
45 | NSMutableDictionary *devices;
46 | NSMutableDictionary *ironclad;
47 | }
48 | @property (retain) NSWindow *utox_window;
49 | @property (retain) NSMenuItem *nameMenuItem;
50 | @property (retain) NSMenuItem *statusMenuItem;
51 | @property (retain) NSMenu *dockMenu;
52 |
53 | - (uToxView *)mainView;
54 | - (void)soilWindowContents;
55 | @end
56 |
57 | /* Webcam management */
58 |
59 | @interface uToxAppDelegate (VideoDevices)
60 | - (void *)storeVideoDevicesList;
61 | - (AVCaptureDevice *)getCaptureDeviceFromHandle:(void *)handle;
62 | @end
63 |
64 | /* Video call satellite windows */
65 |
66 | @interface uToxAppDelegate (IroncladManager)
67 | - (void)setIroncladWindow:(NSWindow *)w forID:(uint32_t)id;
68 | - (void)releaseIroncladWindowForID:(uint32_t)id;
69 | - (NSWindow *)ironcladWindowForID:(uint32_t)id;
70 | @end
71 |
72 | /* Main UI */
73 |
74 | @interface uToxView : NSView
75 | @end
76 |
77 | @interface uToxView (UserInteraction)
78 | @end
79 |
80 | /* Desktop rectangle selector */
81 |
82 | @interface uToxStardustView : NSView
83 | + (NSWindow *)createWindowOnScreen:(NSScreen *)target;
84 |
85 | @property (strong) NSTextField *instruction;
86 | @property (getter=isVideo) BOOL video;
87 | - (CGRect)getRect;
88 | @end
89 |
90 | /* Video capture */
91 |
92 | @interface uToxAV : NSObject
93 | - (instancetype)initWithHandle:(void *)video_dev_handle NS_DESIGNATED_INITIALIZER;
94 | @end
95 |
96 | @interface uToxIroncladView : NSView
97 | + (NSWindow *)createWindow;
98 |
99 | - (void)displayImage:(uint8_t *)rgba w:(uint16_t)width h:(uint16_t)height;
100 | @end
101 |
102 | #endif
103 |
--------------------------------------------------------------------------------
/cocoa/utox.iconset/icon_128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/cocoa/utox.iconset/icon_128x128.png
--------------------------------------------------------------------------------
/cocoa/utox.iconset/icon_16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/cocoa/utox.iconset/icon_16x16.png
--------------------------------------------------------------------------------
/cocoa/utox.iconset/icon_256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/cocoa/utox.iconset/icon_256x256.png
--------------------------------------------------------------------------------
/cocoa/utox.iconset/icon_32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/cocoa/utox.iconset/icon_32x32.png
--------------------------------------------------------------------------------
/cocoa/utox.iconset/icon_512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/cocoa/utox.iconset/icon_512x512.png
--------------------------------------------------------------------------------
/cocoa/utox.iconset/icon_512x512@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/cocoa/utox.iconset/icon_512x512@2x.png
--------------------------------------------------------------------------------
/commands.c:
--------------------------------------------------------------------------------
1 | #include "main.h"
2 |
3 | STRING_IDX utox_run_command(char_t *string, STRING_IDX string_length, char_t **cmd, char_t **argument, int trusted){
4 | if(trusted == 0){
5 | return 0; /* We don't currently support commands from non-trusted sources, before you run commands from friends
6 | * or elsewhere, you MUST implement error checking better than what exists */
7 | }
8 |
9 | STRING_IDX cmd_length, argument_length;
10 |
11 | if (string[0] == '/') { /* Cool it's a command we support! */
12 | // debug("command found!\n");
13 | uint16_t i;
14 | for (i = 0; i < string_length; ++i) {
15 | if (string[i] == ' ') {
16 | cmd_length = i;
17 | break;
18 | }
19 | }
20 |
21 | ++i;
22 | for (; i < string_length; ++i) {
23 | if (string[i] != ' ') {
24 | argument_length = string_length - i;
25 | *argument = string + i;
26 | break;
27 | }
28 | }
29 |
30 | if(cmd_length){
31 | --cmd_length;
32 | *cmd = string + 1;
33 | }
34 | } else {
35 | // debug("No command found\n"); /* Sad, we don't support this command. */
36 | *argument = string;
37 | cmd = NULL;
38 | return 0;
39 | }
40 |
41 | /* Start accepting actions */
42 | if ((cmd_length == 5) && (memcmp(*cmd, "alias", 5) == 0) && *argument ) {
43 | if(selected_item->item == ITEM_FRIEND) {
44 | FRIEND *f = selected_item->data;
45 | friend_set_alias(f, *argument, argument_length);
46 | cmd_length = -1; /* We'll take care of this, don't return to edit */
47 | }
48 | } else {
49 | // debug("Command unsupported!\n");
50 | }
51 | return cmd_length;
52 | }
53 |
--------------------------------------------------------------------------------
/commands.h:
--------------------------------------------------------------------------------
1 | /** utox_run_command()
2 | *
3 | * takes data string and parses it for a command, if that command is supported, acts on that command, else it simply
4 | * results the processed command and argv.
5 | *
6 | * Returns the remaining string length.
7 | */
8 | STRING_IDX utox_run_command(char_t *string, STRING_IDX string_length, char_t **cmd, char_t **argument, int trusted);
9 |
--------------------------------------------------------------------------------
/contextmenu.c:
--------------------------------------------------------------------------------
1 | #include "main.h"
2 |
3 | static CONTEXTMENU context_menu;
4 |
5 | #define CONTEXT_WIDTH (SCALE * 60)
6 | #define CONTEXT_HEIGHT (SCALE * 12)
7 |
8 | static void calculate_pos_and_width(CONTEXTMENU *b, int *x, int *w) {
9 | uint8_t i;
10 |
11 | *x = b->x;
12 | *w = b->width;
13 |
14 | // Increase width if needed, so that all menu items fit.
15 | for(i = 0; i < b->count; i++) {
16 | STRING *name = b->ondisplay(i, b);
17 | int needed_w = textwidth(name->str, name->length) + 4 * SCALE;
18 | if(*w < needed_w) {
19 | *w = needed_w;
20 | }
21 | }
22 |
23 | // Push away from the right border to fit.
24 | if(*x + *w >= utox_window_width) {
25 | *x -= *w;
26 | }
27 | }
28 |
29 | void contextmenu_draw(void)
30 | {
31 | CONTEXTMENU *b = &context_menu;
32 | if(!b->open) {
33 | return;
34 | }
35 |
36 | int x, w, active_h;
37 | calculate_pos_and_width(b, &x, &w);
38 |
39 | drawrectw(x, b->y, w, b->height, COLOR_MAIN_BACKGROUND);
40 | active_h = b->y + b->over * CONTEXT_HEIGHT;
41 | drawrectw(x, active_h, w, CONTEXT_HEIGHT, COLOR_ACTIVEOPTION_BACKGROUND);
42 |
43 | int i;
44 | for(i = 0; i != b->count; i++) {
45 | // Ensure that font is set before calculating position and width.
46 | STRING *name = b->ondisplay(i, b);
47 | setfont(FONT_TEXT);
48 | setcolor((active_h == b->y + i * CONTEXT_HEIGHT) ? COLOR_ACTIVEOPTION_TEXT : COLOR_MAIN_TEXT);
49 | drawtext(x + SCALE * 2, b->y + SCALE * 2 + i * CONTEXT_HEIGHT, name->str, name->length);
50 | }
51 |
52 | framerect(x, b->y, x + w, b->y + b->height, COLOR_EDGE_ACTIVE);
53 | }
54 |
55 | _Bool contextmenu_mmove(int mx, int my, int UNUSED(dx), int UNUSED(dy))
56 | {
57 | CONTEXTMENU *b = &context_menu;
58 |
59 | if(!b->open) {
60 | return 0;
61 | }
62 |
63 | cursor = CURSOR_NONE;
64 |
65 | // Ensure that font is set before calculating position and width.
66 | setfont(FONT_TEXT);
67 | setcolor(COLOR_MAIN_BACKGROUND);
68 |
69 | int x, w;
70 | calculate_pos_and_width(b, &x, &w);
71 |
72 | _Bool mouseover = inrect(mx, my, x, b->y, w, b->height);
73 | if(!mouseover) {
74 | if(b->over != 0xFF) {
75 | b->over = 0xFF;
76 | return 1;
77 | }
78 | return 0;
79 | }
80 |
81 | uint8_t over = (my - b->y) / CONTEXT_HEIGHT;
82 | if(over >= b->count) {
83 | over = 0xFF;
84 | }
85 |
86 | if(over != b->over) {
87 | b->over = over;
88 | return 1;
89 | }
90 |
91 | return 0;
92 | }
93 |
94 | _Bool contextmenu_mdown(void)
95 | {
96 | CONTEXTMENU *b = &context_menu;
97 |
98 | if(!b->open) {
99 | return 0;
100 | }
101 |
102 | if(b->over != 0xFF) {
103 | b->down = b->over;
104 | } else {
105 | b->open = 0;
106 | }
107 | return 1;
108 | }
109 |
110 | _Bool contextmenu_mup(void)
111 | {
112 | CONTEXTMENU *b = &context_menu;
113 |
114 | if(!b->open) {
115 | return 0;
116 | }
117 |
118 | if(b->over == b->down) {
119 | b->onselect(b->over);
120 | b->open = 0;
121 | return 1;
122 | }
123 |
124 | return 0;
125 | }
126 |
127 | _Bool contextmenu_mleave(void)
128 | {
129 | CONTEXTMENU *b = &context_menu;
130 |
131 | if(!b->open) {
132 | return 0;
133 | }
134 |
135 | if(b->over != 0xFF) {
136 | b->over = 0xFF;
137 | return 1;
138 | }
139 |
140 | return 0;
141 | }
142 |
143 | void contextmenu_new_ex(uint8_t count, void *userdata, void (*onselect)(uint8_t), STRING* (*ondisplay)(uint8_t, const CONTEXTMENU*))
144 | {
145 | CONTEXTMENU *b = &context_menu;
146 |
147 | b->y = mouse.y;
148 | b->height = CONTEXT_HEIGHT * count;
149 | if(b->y + b->height >= utox_window_height) {
150 | b->y -= b->height;
151 | }
152 | b->x = mouse.x;
153 | b->width = CONTEXT_WIDTH;
154 |
155 | b->open = 1;
156 | b->count = count;
157 | b->over = 0xFF;
158 | b->onselect = onselect;
159 | b->ondisplay = ondisplay;
160 | b->userdata = userdata;
161 | }
162 |
163 | static STRING* contextmenu_localized_ondisplay(uint8_t i, const CONTEXTMENU* cm)
164 | {
165 | return SPTRFORLANG(LANG, ((UI_STRING_ID*) cm->userdata)[i]);
166 | }
167 |
168 | void contextmenu_new(uint8_t count, UI_STRING_ID* menu_string_ids, void (*onselect)(uint8_t)) {
169 | contextmenu_new_ex(count, menu_string_ids, onselect, contextmenu_localized_ondisplay);
170 | }
171 |
--------------------------------------------------------------------------------
/contextmenu.h:
--------------------------------------------------------------------------------
1 |
2 | typedef struct contextmenu {
3 | int x, y, width, height;
4 | _Bool open;
5 | uint8_t count, over, down;
6 | void (*onselect)(uint8_t);
7 | STRING* (*ondisplay)(uint8_t, const struct contextmenu*);
8 | void *userdata;
9 | } CONTEXTMENU;
10 |
11 | void contextmenu_draw(void);
12 | _Bool contextmenu_mmove(int mx, int my, int dx, int dy);
13 | _Bool contextmenu_mdown(void);
14 | _Bool contextmenu_mup(void);
15 | _Bool contextmenu_mleave(void);
16 |
17 | void contextmenu_new(uint8_t count, UI_STRING_ID* menu_string_ids, void (*onselect)(uint8_t));
18 | void contextmenu_new_ex(uint8_t count, void *userdata, void (*onselect)(uint8_t), STRING* (*ondisplay)(uint8_t, const CONTEXTMENU*));
19 |
--------------------------------------------------------------------------------
/dns.h:
--------------------------------------------------------------------------------
1 | void dns_request(char_t *name, uint16_t length);
2 |
--------------------------------------------------------------------------------
/docs/BUILD.md:
--------------------------------------------------------------------------------
1 | # Build
2 |
3 | Following are barebone compilation instructions that should get you going. They probably wont work but #tox-dev can
4 | probably help you out if you're nice when you ask.
5 |
6 | If you're looking for it to "just work" you're going to want [these instructions](INSTALL.md) instead.
7 |
8 |
9 | ## Unix Like
10 |
11 | ### Xlib
12 |
13 | The easy way out is:
14 | ```sh
15 | cd uTox/
16 | make
17 | make install
18 | ```
19 |
20 | But if the hard way is more your thing, this might work:
21 | ```clang -o utox *.c png/png.c -g -Wall -Wshadow -pthread -std=gnu99 `pkg-config --libs --cflags fontconfig freetype2 libtoxav libtoxcore openal vpx x11 xext xrender dbus-1 libv4lconvert filteraudio` -pthread -lm -lresolv -ldl```
22 |
23 | or if you built toxcore statically, less likely to work:
24 |
25 | `cc -o uTox.o *.c ./png/png.c -lX11 -lXrender -lXext -ltoxcore -ltoxav -ltoxdns -lopenal -lsodium -lopus -lvpx -lm -pthread -lresolv -ldl -lfilteraudio -lfontconfig -lfreetype -lv4lconvert -I/usr/include/freetype2 -ldbus-1`
26 |
27 | For the build to pass you need to install the following from sources: [filteraudio](https://github.com/irungentoo/filter_audio) [libtoxcore](https://github.com/irungentoo/toxcore)
28 |
29 | For base emoji ids support you need: [base_emoji](https://github.com/irungentoo/base_emoji)
30 |
31 |
32 | ## Windows
33 |
34 | ### Compiling for Windows
35 |
36 | If you have mingw-w64 and a working cygwin enviroment, the build script provided in
37 | tools/ should just work. You must tell it if you want 32 or 64 bit, then the enviroment
38 | you want to use.
39 |
40 | 64bit should be `tools/cross-compile-windows.sh`
41 |
42 | 32bit should be `tools/cross-compile-windows.sh -32`
43 |
44 | Make sure you grab a copy of toxcore, openal, and filter_audio from
45 | https://jenkins.libtoxcore.so/ (Make sure you grab the right bit version.)
46 |
47 | You can also cross compile from unix if that's more your thing; again you'll need mingw-w64 and then just:
48 |
49 | `tools/cross-compile-windows.sh -unix`
50 |
51 | Don't forget to add -32 if you'd rather build the 32bit version.
52 |
53 |
54 | ## OSX
55 | You need XQuartz on 10.8+, no video yet.
56 |
57 | `cc -o uTox.o *.c png/png.c -I/opt/X11/include -L/opt/X11/lib -lX11 -lXrender -lXext -ltoxcore -ltoxav -ltoxdns -framework OpenAL -pthread -lresolv -ldl -lm -lfontconfig -lfreetype -lvpx -I/opt/X11/include/freetype2`
58 |
59 | If you are relying on Homebrew to provide libraries and headers, you can use the following line instead to save you the trouble:
60 |
61 | `cc -o uTox.o *.c png/png.c -L/usr/local/lib -I/usr/local/include -I/opt/X11/include -L/opt/X11/lib -lX11 -lXrender -lXext -ltoxcore -ltoxav -ltoxdns -framework OpenAL -pthread -lresolv -ldl -lm -lfontconfig -lfreetype -lvpx -I/opt/X11/include/freetype2`
62 |
63 |
64 | ## Android
65 |
66 | Requires Android SDK+NDK
67 |
68 | From uTox root folder, using prebuilt static toxcore + freetype libraries (includes in ../include and libs in ../lib), resulting apk is ./tmp/tmp2.apk:
69 |
70 | ### Setup:
71 |
72 | ```bash
73 | mkdir ./tmp
74 | mkdir ./tmp/java
75 | mkdir ./tmp/libs
76 | mkdir ./tmp/libs/armeabi
77 | keytool -genkey -v -keystore ./tmp/debug.keystore -alias $ALIAS -keyalg RSA -keysize 2048 -validity 20000
78 | ```
79 |
80 | ### Compile + Pack APK
81 |
82 | ```bash
83 | arm-linux-androideabi-gcc --sysroot=$NDK_PATH/platforms/android-9/arch-arm/ -I../include/freetype2/ -I../include/ ./*.c ./png/png.c -llog -landroid -lEGL -lGLESv2 -lOpenSLES ../lib/libtoxcore.a ../lib/libtoxdns.a ../lib/libtoxav.a ../lib/libsodium.a ../lib/libopus.a ../lib/libvpx.a ../lib/libfreetype.a -lm -lz -ldl -shared -o ./tmp/libs/armeabi/libn.so
84 | /aapt package -f -M ./android/AndroidManifest.xml -S ./android/res -I $SDK_PATH/platforms/android-10/android.jar -F ./tmp/tmp1.apk -J ./tmp/java
85 | javac -d ./tmp/java ./tmp/java/R.java
86 | dx --dex --output=./tmp/classes.dex ./tmp/java
87 | java -classpath $SDK_PATH/tools/lib/sdklib.jar com.android.sdklib.build.ApkBuilderMain ./tmp/tmp2.apk -u -z ./tmp/tmp1.apk -f ./tmp/classes.dex -nf ./tmp/libs
88 | jarsigner -sigalg SHA1withRSA -digestalg SHA1 -keystore ./tmp/debug.keystore -storepass $PASSWORD ./tmp/tmp2.apk $ALIAS
89 | ```
90 |
91 |
--------------------------------------------------------------------------------
/docs/COCOA.md:
--------------------------------------------------------------------------------
1 | # uTox-cocoa specific notes
2 |
3 | * 10.10 SDK is required to build, but the product should be
4 | compatible back to 10.7.
5 | * Support for Mavericks SDK is TODO (ifdef out 10.10 bits)
6 | * Please make sure your dependencies are built with the lowest
7 | `MACOSX_DEPLOYMENT_TARGET` possible
8 | * The gameplan for 10.6 is to just replace AVFoundation with QTKit
9 | equivalents.
10 | * 32-bit support would be nice too (PowerPC is probably too much)
11 | * Build an OS X .app package by using `make uTox.app`.
12 | * Some features will not work unless you run from a `.app`. These
13 | include desktop notifications and the dock icon (???).
14 | * An Xcode project file is TODO
15 | * It is recommended to define `UTOX_COCOA_BRAVE` while building for
16 | release. It will disable some basic sanity checks which should
17 | always pass if the code is correct.
18 | * You can instruct uTox to use Yosemite blur as a UI element colour
19 | in utox_theme.ini by (not implemented currently)
20 | * When filing issues directly related to uTox-cocoa, please @stal888 in
21 | your issue so I get notified.
22 |
23 | ## How to compile (for yourself)
24 |
25 | ```bash
26 | brew install --HEAD libtoxcore
27 | make -f cocoa/Makefile uTox.app
28 | ```
29 |
30 | Done!
31 |
32 | ## How to compile (for your friend)
33 |
34 | ```bash
35 | brew install --HEAD libtoxcore
36 | make -f cocoa/Makefile uTox.dmg
37 | ```
38 |
39 | Done! (the DMG target builds a statically linked utox binary
40 | for you automatically. It does not depend on anything but system
41 | libraries. Build just the binary with `make -f cocoa/Makefile utox-static`)
42 |
43 | ## Adding to uTox-cocoa
44 |
45 | * Please keep your C straight
--------------------------------------------------------------------------------
/docs/INSTALL.md:
--------------------------------------------------------------------------------
1 | # Install
2 |
3 | The following will help you get μTox installed on your computron/toaster/carrier pigeon. The focus of this guide is to get you running ASAP. And mostly deals with precomplied binaries. If you're looking to contribute (you're the real MVP) you're probably looking for [Building](BUILD.md).
4 |
5 | For any and all of the following, you'll need to have [toxcore](https://github.com/irungentoo/toxcore) installed first.
6 |
7 | - [Unix-like](#unix)
8 | - [OS X](#osx)
9 | - [Windows](#windows)
10 | - [Android](#android)
11 |
12 |
13 | ## Unix-like
14 |
15 | Dependencies:
16 |
17 | ```dbus filter_audio freetype libvpx openal v4l xext xrender```
18 |
19 | 1. First compile:
20 |
21 | ```bash
22 | make all
23 | ```
24 |
25 | 2. Then install:
26 |
27 | ```bash
28 | sudo make install
29 | ```
30 |
31 | If make/install really isn't your thing, you can try some precomplied binaries.
32 | - [amd64](https://jenkins.libtoxcore.so/view/Clients/job/uTox_linux_amd64/) [[.tar.xz]](https://jenkins.libtoxcore.so/view/Clients/job/uTox_linux_amd64/lastSuccessfulBuild/artifact/utox/utox_linux_amd64.tar.xz)
33 | - [i686](https://jenkins.libtoxcore.so/view/Clients/job/uTox_linux_i686/) [[.tar.xz]](https://jenkins.libtoxcore.so/view/Clients/job/uTox_linux_i686/lastSuccessfulBuild/artifact/utox/utox_linux_i686.tar.xz)
34 |
35 | ### Adding a desktop launcher
36 |
37 | Assuming that repository working copy is your current directory.
38 |
39 | 1. Copy `.desktop` entry
40 |
41 | ```bash
42 | sudo cp ./utox.desktop /usr/share/applications/utox.desktop
43 | ```
44 |
45 | 2. Make it executable
46 |
47 | ```bash
48 | sudo chmod +x /usr/share/applications/utox.desktop
49 | ```
50 |
51 | 3. Add an icon
52 |
53 | ```bash
54 | sudo cp ./icons/utox-128x128.png /usr/share/pixmaps/utox.png
55 | ```
56 |
57 | ### Archlinux
58 |
59 | If you're lucky enough to use Archlinux, someone has an AUR package just for you!
60 |
61 | https://aur.archlinux.org/packages/utox-git/
62 |
63 |
64 | ## OS X
65 |
66 | No one is currently providing binaries for OSX yet... Sorry Apple people...
67 |
68 | [I guess I'll try to build it](docs/BUILD.md#OSX).
69 |
70 |
71 | ## Windows
72 |
73 | Installing on windows isn't really a thing yet... you can download the nighties. They should just work.
74 |
75 | - [32-bit](https://jenkins.libtoxcore.so/view/Clients/job/uTox_win32/) [[.zip]](https://jenkins.libtoxcore.so/view/Clients/job/uTox_win32/lastSuccessfulBuild/artifact/utox/utox_win32.zip)
76 | - [64-bit](https://jenkins.libtoxcore.so/view/Clients/job/uTox_win64/) [[.zip]](https://jenkins.libtoxcore.so/view/Clients/job/uTox_win64/lastSuccessfulBuild/artifact/utox/utox_win64.zip)
77 | - [Updater](https://jenkins.libtoxcore.so/view/Clients/job/utox_update_win32/) (32-bit) [[.zip]](https://jenkins.libtoxcore.so/view/Clients/job/utox_update_win32/lastSuccessfulBuild/artifact/utox-updater.zip)
78 |
79 |
80 | ## Android
81 |
82 | μTox on android has been neglected too long, so we're not currently providing binaries.
83 |
84 | # Meta
85 | [Jenkins](https://jenkins.libtoxcore.so) offers automatically compiled binaries. All files below link to the last successful build. [See which changes are in which Jenkins build of uTox](https://jenkins.libtoxcore.so/job/Sync%20uTox/changes).
86 |
--------------------------------------------------------------------------------
/dropdown.h:
--------------------------------------------------------------------------------
1 | // userdata of list-based dropdown consists of these records
2 | typedef struct
3 | {
4 | MAYBE_I18NAL_STRING name;
5 | void *handle;
6 | }DROP_ELEMENT;
7 |
8 | typedef struct dropdown {
9 | PANEL panel;
10 | _Bool mouseover, open;
11 | uint16_t dropcount, selected, over;
12 | void (*onselect)(uint16_t, const struct dropdown*);
13 | STRING* (*ondisplay)(uint16_t, const struct dropdown*);
14 | UI_ELEMENT_STYLE style;
15 | void *userdata;
16 | } DROPDOWN;
17 |
18 | void dropdown_drawactive(void);
19 |
20 | void dropdown_draw(DROPDOWN *b, int x, int y, int width, int height);
21 | _Bool dropdown_mmove(DROPDOWN *b, int x, int y, int width, int height, int mx, int my, int dx, int dy);
22 | _Bool dropdown_mdown(DROPDOWN *b);
23 | _Bool dropdown_mright(DROPDOWN *b);
24 | _Bool dropdown_mwheel(DROPDOWN *b, int height, double d);
25 | _Bool dropdown_mup(DROPDOWN *b);
26 | _Bool dropdown_mleave(DROPDOWN *b);
27 |
28 | STRING* simple_dropdown_ondisplay(uint16_t, const DROPDOWN*);
29 |
30 | STRING* list_dropdown_ondisplay(uint16_t, const DROPDOWN*);
31 | void list_dropdown_add_hardcoded(DROPDOWN*, uint8_t* name, void *handle);
32 | void list_dropdown_add_localized(DROPDOWN*, UI_STRING_ID string_id, void *handle);
33 | void list_dropdown_clear(DROPDOWN*);
34 |
--------------------------------------------------------------------------------
/edit.h:
--------------------------------------------------------------------------------
1 | /*todo: replace windows functions, multiline edits, add missing edit functions (ex: double click to select word)*/
2 |
3 | struct edit_change
4 | {
5 | _Bool remove, padding;
6 | STRING_IDX start, length;
7 | char_t data[0];
8 | };
9 |
10 | struct edit {
11 | PANEL panel;
12 |
13 | _Bool multiline, mouseover, noborder, readonly, select_completely;
14 | STRING_IDX mouseover_char, length, maxlength;
15 | uint16_t width, height;
16 |
17 | uint16_t history_cur, history_length;
18 | EDIT_CHANGE **history;
19 |
20 | SCROLLABLE *scroll;
21 | char_t *data;
22 |
23 | MAYBE_I18NAL_STRING empty_str;
24 | UI_ELEMENT_STYLE style;
25 |
26 | void (*onenter)(EDIT *edit);
27 | void (*onchange)(EDIT *edit);
28 | void (*ontab)(EDIT *edit);
29 | void (*onshifttab)(EDIT *edit);
30 | void (*onlosefocus)(EDIT *edit);
31 | };
32 |
33 | void edit_draw(EDIT *edit, int x, int y, int width, int height);
34 |
35 | _Bool edit_mmove(EDIT *edit, int x, int y, int width, int height, int mx, int my, int dx, int dy);
36 | _Bool edit_mdown(EDIT *edit);
37 | _Bool edit_dclick(EDIT *edit, _Bool triclick);
38 | _Bool edit_mright(EDIT *edit);
39 | _Bool edit_mwheel(EDIT *edit, int height, double d);
40 | _Bool edit_mup(EDIT *edit);
41 | _Bool edit_mleave(EDIT *edit);
42 |
43 | void edit_do(EDIT *edit, STRING_IDX start, STRING_IDX length, _Bool remove);
44 |
45 | void edit_press(void);
46 |
47 | void edit_char(uint32_t ch, _Bool control, uint8_t flags);
48 |
49 | int edit_selection(EDIT *edit, char_t *data, int len);
50 | int edit_copy(char_t *data, int len);
51 | void edit_paste(char_t *data, int len, _Bool select);
52 |
53 | _Bool edit_active(void);
54 | EDIT *edit_get_active(void);
55 |
56 | void edit_resetfocus(void);
57 | void edit_setfocus(EDIT *edit);
58 | void edit_setstr(EDIT *edit, char_t *str, STRING_IDX length);
59 | void edit_setcursorpos(EDIT *edit, STRING_IDX pos);
60 | STRING_IDX edit_getcursorpos(void);
61 |
62 | // set outloc and outlen to the mark range.
63 | // returns 1 if the mark range is valid for the current edit,
64 | // else 0.
65 | // a mark range is valid when *outlen != 0 and there is an active edit.
66 | _Bool edit_getmark(STRING_IDX *outloc, STRING_IDX *outlen);
67 | void edit_setmark(STRING_IDX loc, STRING_IDX len);
68 |
69 | void edit_setselectedrange(STRING_IDX loc, STRING_IDX len);
70 |
--------------------------------------------------------------------------------
/file_transfers.h:
--------------------------------------------------------------------------------
1 | #define MAX_FILE_TRANSFERS 32
2 |
3 | enum UTOX_FILE_TRANSFER_STATUS{
4 | FILE_TRANSFER_STATUS_NONE,
5 | FILE_TRANSFER_STATUS_ACTIVE,
6 | FILE_TRANSFER_STATUS_PAUSED_US,
7 | FILE_TRANSFER_STATUS_PAUSED_BOTH,
8 | FILE_TRANSFER_STATUS_PAUSED_THEM,
9 | FILE_TRANSFER_STATUS_BROKEN,
10 | FILE_TRANSFER_STATUS_COMPLETED,
11 | FILE_TRANSFER_STATUS_KILLED,
12 | };
13 |
14 | typedef struct FILE_TRANSFER {
15 | uint32_t friend_number, file_number;
16 | uint8_t file_id[TOX_FILE_ID_LENGTH];
17 | uint8_t status, resume, kind;
18 | _Bool incoming, in_memory, is_avatar; //, in_tmp_loc;
19 | uint8_t *path, *name; //, *tmp_path;
20 | size_t path_length, name_length; //, tmp_path_length;
21 | uint64_t size, size_transferred;
22 | uint8_t *memory, *avatar;
23 |
24 | /* speed + progress calculations. */
25 | uint32_t speed, num_packets;
26 | uint64_t last_check_time, last_check_transferred;
27 |
28 | FILE *file, *saveinfo;
29 | MSG_FILE *ui_data;
30 | } FILE_TRANSFER;
31 |
32 | void file_transfer_local_control(Tox *tox, uint32_t friend_number, uint32_t file_number, TOX_FILE_CONTROL control);
33 | uint32_t outgoing_file_send(Tox *tox, uint32_t friend_number, uint8_t *path, uint8_t *filename, size_t filename_length, uint32_t kind);
34 |
35 | int utox_file_start_write(uint32_t friend_number, uint32_t file_number, void *filepath);
36 |
37 | void utox_set_callbacks_for_transfer(Tox *tox);
38 | void utox_cleanup_file_transfers(uint32_t friend_number, uint32_t file_number);
39 |
40 | void ft_friend_online(Tox *tox, uint32_t friend_number);
41 | void ft_friend_offline(Tox *tox, uint32_t friend_number);
42 |
43 | void utox_file_save_ftinfo(FILE_TRANSFER *file);
44 | _Bool utox_file_load_ftinfo(FILE_TRANSFER *file);
45 |
--------------------------------------------------------------------------------
/friend.h:
--------------------------------------------------------------------------------
1 | typedef struct friend_meta_data {
2 | size_t alias_length;
3 | uint8_t data[];
4 | } FRIEND_META_DATA;
5 |
6 | typedef struct friend {
7 | _Bool online, typing, notify;
8 | uint8_t calling, status;
9 | int32_t callid;
10 | uint16_t call_width, call_height;
11 |
12 | uint8_t cid[TOX_PUBLIC_KEY_SIZE], tooltip[8];
13 | char_t *name, *alias, *status_message, *typed;
14 | STRING_IDX name_length, alias_length, status_length, typed_length;
15 |
16 | MSG_DATA msg;
17 |
18 | EDIT_CHANGE **edit_history;
19 | uint16_t edit_history_cur, edit_history_length;
20 |
21 | AVATAR avatar;
22 |
23 | uint16_t transfer_count;
24 |
25 | FRIEND_META_DATA metadata;
26 | } FRIEND;
27 |
28 | #define MAX_GROUP_PEERS 256
29 |
30 | typedef struct groupchat {
31 | uint32_t peers;
32 | uint32_t our_peer_number;
33 | uint8_t type;
34 | _Bool audio_calling;
35 | volatile _Bool muted;
36 | STRING_IDX name_length, topic_length, typed_length;
37 | char_t name[128], topic[128]; //static sizes for now
38 | char_t *typed;
39 | char_t *peername[MAX_GROUP_PEERS];
40 | unsigned int source[MAX_GROUP_PEERS];
41 | volatile uint64_t last_recv_audio[MAX_GROUP_PEERS]; /* TODO: thread safety (This should work fine but it isn't very clean.) */
42 |
43 | EDIT_CHANGE **edit_history;
44 | uint16_t edit_history_cur, edit_history_length;
45 |
46 | MSG_DATA msg;
47 | } GROUPCHAT;
48 |
49 | #define friend_id(f) (f - friend)
50 |
51 | void friend_setname(FRIEND *f, char_t *name, STRING_IDX length);
52 | void friend_set_alias(FRIEND *f, char_t *alias, STRING_IDX length);
53 | void friend_addmessage(FRIEND *f, void *data);
54 | void friend_sendimage(FRIEND *f, UTOX_NATIVE_IMAGE *, uint16_t width, uint16_t height, UTOX_PNG_IMAGE, size_t png_size);
55 | void friend_recvimage(FRIEND *f, UTOX_NATIVE_IMAGE *native_image, uint16_t width, uint16_t height);
56 |
57 | void friend_notify(FRIEND *f, char_t *str, STRING_IDX str_length, char_t *msg, STRING_IDX msg_length);
58 | #define friend_notifystr(f, str, msg, mlen) friend_notify(f, (char_t*)str, sizeof(str) - 1, msg, mlen)
59 | void friend_addmessage_notify(FRIEND *f, char_t *data, STRING_IDX length);
60 | void friend_set_typing(FRIEND *f, int typing);
61 |
62 | void friend_addid(uint8_t *id, char_t *msg, STRING_IDX msg_length);
63 | void friend_add(char_t *name, STRING_IDX length, char_t *msg, STRING_IDX msg_length);
64 |
65 | void friend_history_clear(FRIEND *f);
66 |
67 | void friend_free(FRIEND *f);
68 | void group_free(GROUPCHAT *g);
69 |
--------------------------------------------------------------------------------
/icons/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/icons/icon.ico
--------------------------------------------------------------------------------
/icons/icon.rc:
--------------------------------------------------------------------------------
1 | 101 ICON "icon.ico"
2 | 102 ICON "icon_unread.ico"
3 |
--------------------------------------------------------------------------------
/icons/icon_unread.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/icons/icon_unread.ico
--------------------------------------------------------------------------------
/icons/utox-128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/icons/utox-128x128.png
--------------------------------------------------------------------------------
/icons/utox-14x14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/icons/utox-14x14.png
--------------------------------------------------------------------------------
/icons/utox-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/icons/utox-16x16.png
--------------------------------------------------------------------------------
/icons/utox-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/icons/utox-192x192.png
--------------------------------------------------------------------------------
/icons/utox-22x22.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/icons/utox-22x22.png
--------------------------------------------------------------------------------
/icons/utox-24x24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/icons/utox-24x24.png
--------------------------------------------------------------------------------
/icons/utox-256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/icons/utox-256x256.png
--------------------------------------------------------------------------------
/icons/utox-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/icons/utox-32x32.png
--------------------------------------------------------------------------------
/icons/utox-36x36.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/icons/utox-36x36.png
--------------------------------------------------------------------------------
/icons/utox-48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/icons/utox-48x48.png
--------------------------------------------------------------------------------
/icons/utox-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/icons/utox-512x512.png
--------------------------------------------------------------------------------
/icons/utox-64x64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/icons/utox-64x64.png
--------------------------------------------------------------------------------
/icons/utox-72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/icons/utox-72x72.png
--------------------------------------------------------------------------------
/icons/utox-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/icons/utox-96x96.png
--------------------------------------------------------------------------------
/icons/utox.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/images/uTox-win32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/images/uTox-win32.png
--------------------------------------------------------------------------------
/images/uTox-xlib.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/images/uTox-xlib.png
--------------------------------------------------------------------------------
/langs/br.h:
--------------------------------------------------------------------------------
1 | msgid(LANG_NATIVE_NAME)
2 | msgstr("Português brasileiro")
3 |
4 | msgid(LANG_ENGLISH_NAME)
5 | msgstr("Brazilian Portuguese")
6 |
7 | msgid(REQ_SENT)
8 | msgstr("Pedido de amizade enviado. Quando aceito, seu amigo aparecerá online.")
9 |
10 | msgid(REQ_RESOLVE)
11 | msgstr("Resolução de DNS em andamento...")
12 |
13 | msgid(REQ_INVALID_ID)
14 | msgstr("Erro: ID Tox inválido")
15 |
16 | msgid(REQ_EMPTY_ID)
17 | msgstr("Erro: ID Tox não especificado")
18 |
19 | msgid(REQ_LONG_MSG)
20 | msgstr("Erro: Mensagem muito longa")
21 |
22 | msgid(REQ_NO_MSG)
23 | msgstr("Erro: Sem mensagem")
24 |
25 | msgid(REQ_SELF_ID)
26 | msgstr("Erro: Este é seu próprio ID Tox")
27 |
28 | msgid(REQ_ALREADY_FRIENDS)
29 | msgstr("Erro: Este ID Tox já consta na sua lista")
30 |
31 | msgid(REQ_UNKNOWN)
32 | msgstr("Erro: Desconhecido")
33 |
34 | msgid(REQ_BAD_CHECKSUM)
35 | msgstr("Erro: ID Tox Inválido (checksum incorreto)")
36 |
37 | msgid(REQ_BAD_NOSPAM)
38 | msgstr("Erro: ID Tox inválido (código anti-spam incorreto)")
39 |
40 | msgid(REQ_NO_MEMORY)
41 | msgstr("Erro: Sem memória")
42 |
43 | msgid(TRANSFER_NEW)
44 | msgstr("Nova transferência de arquivo")
45 |
46 | msgid(TRANSFER_STARTED)
47 | msgstr("Transferência de arquivo iniciada")
48 |
49 | //msgid(TRANSFER___)
50 | //msgstr("...")
51 |
52 | msgid(TRANSFER_PAUSED)
53 | msgstr("Transferência de arquivo parada")
54 |
55 | msgid(TRANSFER_BROKEN)
56 | msgstr("Arquivo transferido está corrompido")
57 |
58 | msgid(TRANSFER_CANCELLED)
59 | msgstr("Transferência de arquivo cancelada")
60 |
61 | msgid(TRANSFER_COMPLETE)
62 | msgstr("Transferência completa")
63 |
64 | msgid(CALL_CANCELLED)
65 | msgstr("Chamada cancelada")
66 |
67 | msgid(CALL_INVITED)
68 | msgstr("Chamada enviada")
69 |
70 | msgid(CALL_RINGING)
71 | msgstr("Chamando")
72 |
73 | msgid(CALL_STARTED)
74 | msgstr("Chamada iniciada")
75 |
76 | msgid(ADDFRIENDS)
77 | msgstr("Adicionar amigos")
78 |
79 | msgid(TOXID)
80 | msgstr("ID Tox")
81 |
82 | msgid(MESSAGE)
83 | msgstr("Mensagem")
84 |
85 | msgid(SEARCHFRIENDS)
86 | msgstr("Buscar amigo(s)")
87 |
88 | msgid(ADD)
89 | msgstr("Adicionar")
90 |
91 | msgid(SWITCHPROFILE)
92 | msgstr("Trocar perfil")
93 |
94 | msgid(FRIENDREQUEST)
95 | msgstr("Pedidos de amizade")
96 |
97 | msgid(USERSETTINGS)
98 | msgstr("Configurações do usuário")
99 |
100 | msgid(NAME)
101 | msgstr("Nome")
102 |
103 | msgid(STATUSMESSAGE)
104 | msgstr("Mensagem de status")
105 |
106 | msgid(PREVIEW)
107 | msgstr("Pré-visualização")
108 |
109 | msgid(DEVICESELECTION)
110 | msgstr("Dispositivo selecionado")
111 |
112 | msgid(AUDIOINPUTDEVICE)
113 | msgstr("Dispositivo de entrada de áudio")
114 |
115 | msgid(AUDIOOUTPUTDEVICE)
116 | msgstr("Dispositivo de saída de áudio")
117 |
118 | msgid(VIDEOINPUTDEVICE)
119 | msgstr("Dispositivo de entrada de vídeo")
120 |
121 | msgid(OTHERSETTINGS)
122 | msgstr("Outras configurações")
123 |
124 | //msgid(DPI)
125 | //msgstr("DPI")
126 |
127 | msgid(SAVELOCATION)
128 | msgstr("Salvar localização")
129 |
130 | msgid(LANGUAGE)
131 | msgstr("Idioma")
132 |
133 | msgid(NETWORK)
134 | msgstr("Rede")
135 |
136 | //msgid(IPV6)
137 | //msgstr("IPv6:")
138 |
139 | //msgid(UDP)
140 | //msgstr("UDP:")
141 |
142 | //msgid(PROXY)
143 | //msgstr("Proxy (SOCKS 5)")
144 |
145 | msgid(WARNING)
146 | msgstr("Mudar as configurações de rede/proxy te desconectará temporariamente da rede Tox")
147 |
148 | msgid(LOGGING)
149 | msgstr("Logar conversas")
150 |
151 | msgid(IS_TYPING)
152 | msgstr("está digitando...")
153 |
154 | msgid(COPY)
155 | msgstr("Copiar")
156 |
157 | msgid(COPYWITHOUTNAMES)
158 | msgstr("Copiar (sem nomes)")
159 |
160 | msgid(CUT)
161 | msgstr("Cortar")
162 |
163 | msgid(PASTE)
164 | msgstr("Colar")
165 |
166 | msgid(DELETE)
167 | msgstr("Excluir")
168 |
169 | msgid(SELECTALL)
170 | msgstr("Selecionar tudo")
171 |
172 | msgid(REMOVE)
173 | msgstr("Remover")
174 |
175 | msgid(LEAVE)
176 | msgstr("Sair")
177 |
178 | msgid(ACCEPT)
179 | msgstr("Aceitar")
180 |
181 | msgid(IGNORE)
182 | msgstr("Ignorar")
183 |
184 | msgid(CLICKTOSAVE)
185 | msgstr("Clique para salvar")
186 |
187 | msgid(CLICKTOOPEN)
188 | msgstr("Clique para abrir")
189 |
190 | msgid(CANCELLED)
191 | msgstr("Cancelado")
192 |
193 | msgid(DPI_TINY)
194 | msgstr("Pequeno (50%)")
195 |
196 | msgid(DPI_NORMAL)
197 | msgstr("Normal (100%)")
198 |
199 | msgid(DPI_BIG)
200 | msgstr("Grande (150%)")
201 |
202 | msgid(DPI_LARGE)
203 | msgstr("Maior (200%)")
204 |
205 | msgid(DPI_HUGE)
206 | msgstr("Imenso (250%)")
207 |
208 | msgid(CONTACTS_FILTER_ALL)
209 | msgstr("Todos")
210 |
211 | msgid(CONTACTS_FILTER_ONLINE)
212 | msgstr("Online")
213 |
214 | msgid(PROXY_DISABLED)
215 | msgstr("Desabilitado")
216 |
217 | msgid(PROXY_FALLBACK)
218 | msgstr("Apenas se necessário")
219 |
220 | msgid(PROXY_ALWAYS_USE)
221 | msgstr("Sempre usar")
222 |
223 | msgid(NO)
224 | msgstr("Não")
225 |
226 | msgid(YES)
227 | msgstr("Sim")
228 |
229 | msgid(VIDEO_IN_NONE)
230 | msgstr("Nenhum")
231 |
232 | msgid(VIDEO_IN_DESKTOP)
233 | msgstr("Área de trabalho")
234 |
235 | msgid(DEFAULT_FRIEND_REQUEST_MESSAGE)
236 | msgstr("Por favor, aceite este pedido de amizade.")
237 |
238 | msgid(CONTACTS_FILTER_EDIT_HINT)
239 | msgstr("Buscar amigo(s)")
240 |
241 | //msgid(PROXY_EDIT_HINT_IP)
242 | //msgstr("IP")
243 |
244 | msgid(PROXY_EDIT_HINT_PORT)
245 | msgstr("Porta")
246 |
247 | //TODO: Localize or remove.
248 | //msgid(AUDIO_IN_DEFAULT_LOOPBACK)
249 | //msgstr("Default Loopback")
250 |
251 | //TODO: Localize or remove.
252 | //msgid(WINDOW_TITLE_VIDEO_PREVIEW)
253 | //msgstr("Video Preview")
254 |
255 | //TODO: Localize or remove.
256 | //msgid(AUDIONOTIFICATIONS)
257 | //msgstr("Enable Audible Notification (Ringtone)")
258 |
--------------------------------------------------------------------------------
/langs/cn.h:
--------------------------------------------------------------------------------
1 | msgid(LANG_NATIVE_NAME)
2 | msgstr("简体中文")
3 |
4 | msgid(LANG_ENGLISH_NAME)
5 | msgstr("SIMPLIFIED CHINESE")
6 |
7 | msgid(REQ_SENT)
8 | msgstr("添加好友请求已发送。当对方接受请求后将在好友列表中在线。")
9 |
10 | msgid(REQ_RESOLVE)
11 | msgstr("尝试解析DNS名......")
12 |
13 | msgid(REQ_INVALID_ID)
14 | msgstr("错误: 无效的 Tox ID")
15 |
16 | msgid(REQ_EMPTY_ID)
17 | msgstr("错误: 没有指定Tox ID")
18 |
19 | msgid(REQ_LONG_MSG)
20 | msgstr("错误: 消息太长")
21 |
22 | msgid(REQ_NO_MSG)
23 | msgstr("错误: 空消息")
24 |
25 | msgid(REQ_SELF_ID)
26 | msgstr("错误: Tox ID 是你自己的 ID")
27 |
28 | msgid(REQ_ALREADY_FRIENDS)
29 | msgstr("错误: Tox ID 已在好友列表中了")
30 |
31 | msgid(REQ_UNKNOWN)
32 | msgstr("错误: 未知")
33 |
34 | msgid(REQ_BAD_CHECKSUM)
35 | msgstr("错误: 无效的 Tox ID (错误的校验和)")
36 |
37 | msgid(REQ_BAD_NOSPAM)
38 | msgstr("错误: 无效的 Tox ID (错误的nospam值)")
39 |
40 | msgid(REQ_NO_MEMORY)
41 | msgstr("错误: 没内存了")
42 |
43 | msgid(TRANSFER_NEW)
44 | msgstr("新建文件传输任务")
45 |
46 | msgid(TRANSFER_STARTED)
47 | msgstr("文件传输开始")
48 |
49 | //TODO: Same as in English? Localize or remove.
50 | //msgid(TRANSFER___)
51 | //msgstr("...")
52 |
53 | msgid(TRANSFER_PAUSED)
54 | msgstr("文件传输暂停")
55 |
56 | msgid(TRANSFER_BROKEN)
57 | msgstr("文件传输中断")
58 |
59 | msgid(TRANSFER_CANCELLED)
60 | msgstr("文件传输取消")
61 |
62 | msgid(TRANSFER_COMPLETE)
63 | msgstr("文件传输完成")
64 |
65 | msgid(CALL_CANCELLED)
66 | msgstr("呼叫取消")
67 |
68 | msgid(CALL_INVITED)
69 | msgstr("呼叫邀请")
70 |
71 | msgid(CALL_RINGING)
72 | msgstr("呼叫振铃")
73 |
74 | msgid(CALL_STARTED)
75 | msgstr("呼叫开始")
76 |
77 | msgid(ADDFRIENDS)
78 | msgstr("添加好友")
79 |
80 | //TODO: Same as in English? Localize or remove.
81 | //msgid(TOXID)
82 | //msgstr("Tox ID")
83 |
84 | msgid(MESSAGE)
85 | msgstr("消息")
86 |
87 | msgid(SEARCHFRIENDS)
88 | msgstr("搜索好友")
89 |
90 | msgid(ADD)
91 | msgstr("添加")
92 |
93 | msgid(SWITCHPROFILE)
94 | msgstr("切换设置")
95 |
96 | msgid(FRIENDREQUEST)
97 | msgstr("好友呼叫")
98 |
99 | msgid(USERSETTINGS)
100 | msgstr("用户设置")
101 |
102 | msgid(NAME)
103 | msgstr("名字")
104 |
105 | msgid(STATUSMESSAGE)
106 | msgstr("状态消息(签名)")
107 |
108 | msgid(PREVIEW)
109 | msgstr("预览")
110 |
111 | msgid(DEVICESELECTION)
112 | msgstr("设备选择")
113 |
114 | msgid(AUDIOINPUTDEVICE)
115 | msgstr("音频输入设备")
116 |
117 | msgid(AUDIOOUTPUTDEVICE)
118 | msgstr("音频输出设备")
119 |
120 | msgid(VIDEOINPUTDEVICE)
121 | msgstr("视频输入设备")
122 |
123 | msgid(OTHERSETTINGS)
124 | msgstr("其他设置")
125 |
126 | //TODO: Same as in English? Localize or remove.
127 | //msgid(DPI)
128 | //msgstr("DPI")
129 |
130 | //TODO: Same as in English? Localize or remove.
131 | //msgid(SAVELOCATION)
132 | //msgstr("Save Location")
133 |
134 | msgid(LANGUAGE)
135 | msgstr("语言")
136 |
137 | msgid(NETWORK)
138 | msgstr("网络")
139 |
140 | //TODO: Same as in English? Localize or remove.
141 | //msgid(IPV6)
142 | //msgstr("IPv6:")
143 |
144 | //TODO: Same as in English? Localize or remove.
145 | //msgid(UDP)
146 | //msgstr("UDP:")
147 |
148 | msgid(PROXY)
149 | msgstr("代理 (SOCKS 5)")
150 |
151 | msgid(WARNING)
152 | msgstr("修改网络或代理设置将会断开tox网络连接")
153 |
154 | //TODO: Same as in English? Localize or remove.
155 | //msgid(LOGGING)
156 | //msgstr("Logging")
157 |
158 | //TODO: Same as in English? Localize or remove.
159 | //msgid(IS_TYPING)
160 | //msgstr("is typing...")
161 |
162 | msgid(COPY)
163 | msgstr("复制")
164 |
165 | msgid(COPYWITHOUTNAMES)
166 | msgstr("复制 (不带名字)")
167 |
168 | msgid(CUT)
169 | msgstr("剪切")
170 |
171 | msgid(PASTE)
172 | msgstr("粘贴")
173 |
174 | msgid(DELETE)
175 | msgstr("删除")
176 |
177 | msgid(SELECTALL)
178 | msgstr("全选")
179 |
180 | msgid(REMOVE)
181 | msgstr("删除")
182 |
183 | msgid(LEAVE)
184 | msgstr("离开")
185 |
186 | msgid(ACCEPT)
187 | msgstr("接受")
188 |
189 | msgid(IGNORE)
190 | msgstr("忽略")
191 |
192 | msgid(CLICKTOSAVE)
193 | msgstr("点击保存")
194 |
195 | msgid(CLICKTOOPEN)
196 | msgstr("点击打开")
197 |
198 | msgid(CANCELLED)
199 | msgstr("取消")
200 |
201 | //TODO: Localize or remove.
202 | //msgid(DPI_TINY)
203 | //msgstr("Tiny (50%)")
204 |
205 | //TODO: Localize or remove.
206 | //msgid(DPI_NORMAL)
207 | //msgstr("Normal (100%)")
208 |
209 | //TODO: Localize or remove.
210 | //msgid(DPI_BIG)
211 | //msgstr("Big (150%)")
212 |
213 | //TODO: Localize or remove.
214 | //msgid(DPI_LARGE)
215 | //msgstr("Large (200%)")
216 |
217 | //TODO: Localize or remove.
218 | //msgid(DPI_HUGE)
219 | //msgstr("Huge (250%)")
220 |
221 | //TODO: Localize or remove.
222 | //msgid(CONTACTS_FILTER_ALL)
223 | //msgstr("All")
224 |
225 | //TODO: Localize or remove.
226 | //msgid(CONTACTS_FILTER_ONLINE)
227 | //msgstr("Online")
228 |
229 | //TODO: Localize or remove.
230 | //msgid(PROXY_DISABLED)
231 | //msgstr("Disabled")
232 |
233 | //TODO: Localize or remove.
234 | //msgid(PROXY_FALLBACK)
235 | //msgstr("Fallback")
236 |
237 | //TODO: Localize or remove.
238 | //msgid(PROXY_ALWAYS_USE)
239 | //msgstr("Always use")
240 |
241 | //TODO: Localize or remove.
242 | //msgid(NO)
243 | //msgstr("No")
244 |
245 | //TODO: Localize or remove.
246 | //msgid(YES)
247 | //msgstr("Yes")
248 |
249 | //TODO: Localize or remove.
250 | //msgid(VIDEO_IN_NONE)
251 | //msgstr("None")
252 |
253 | //TODO: Localize or remove.
254 | //msgid(VIDEO_IN_DESKTOP)
255 | //msgstr("Desktop")
256 |
257 | //TODO: Localize or remove.
258 | //msgid(DEFAULT_FRIEND_REQUEST_MESSAGE)
259 | //msgstr("Please accept this friend request.")
260 |
261 | //TODO: Localize or remove.
262 | //msgid(CONTACTS_FILTER_EDIT_HINT)
263 | //msgstr("Search friends")
264 |
265 | //TODO: Localize or remove.
266 | //msgid(PROXY_EDIT_HINT_IP)
267 | //msgstr("IP")
268 |
269 | //TODO: Localize or remove.
270 | //msgid(PROXY_EDIT_HINT_PORT)
271 | //msgstr("Port")
272 |
273 | //TODO: Localize or remove.
274 | //msgid(AUDIO_IN_DEFAULT_LOOPBACK)
275 | //msgstr("Default Loopback")
276 |
277 | //TODO: Localize or remove.
278 | //msgid(WINDOW_TITLE_VIDEO_PREVIEW)
279 | //msgstr("Video Preview")
280 |
281 | //TODO: Localize or remove.
282 | //msgid(AUDIONOTIFICATIONS)
283 | //msgstr("Enable Audible Notification (Ringtone)")
284 |
--------------------------------------------------------------------------------
/langs/cs.h:
--------------------------------------------------------------------------------
1 | msgid(LANG_NATIVE_NAME)
2 | msgstr("Čeština")
3 |
4 | msgid(LANG_ENGLISH_NAME)
5 | msgstr("Czech")
6 |
7 | msgid(REQ_SENT)
8 | msgstr("Žádost poslána. Váš kontakt se objeví online, jakmile vaši žádost přijme.")
9 |
10 | msgid(REQ_RESOLVE)
11 | msgstr("Pokus o zjištění DNS jména...")
12 |
13 | msgid(REQ_INVALID_ID)
14 | msgstr("Chyba: Neplatné Tox ID")
15 |
16 | msgid(REQ_EMPTY_ID)
17 | msgstr("Chyba: Tox ID nespecifikováno")
18 |
19 | msgid(REQ_LONG_MSG)
20 | msgstr("Chyba: Zpráva je příliš dlouhá")
21 |
22 | msgid(REQ_NO_MSG)
23 | msgstr("Chyba: Prázdná zpráva")
24 |
25 | msgid(REQ_SELF_ID)
26 | msgstr("Chyba: Tox ID je Vaše ID")
27 |
28 | msgid(REQ_ALREADY_FRIENDS)
29 | msgstr("Chyba: Tox ID je již ve Vašich kontaktech")
30 |
31 | msgid(REQ_UNKNOWN)
32 | msgstr("Chyba: Neznámá")
33 |
34 | msgid(REQ_BAD_CHECKSUM)
35 | msgstr("Chyba: Neplatné Tox ID (kontrolní součet)")
36 |
37 | msgid(REQ_BAD_NOSPAM)
38 | msgstr("Chyba: Neplatné Tox ID (hodnota nospam)")
39 |
40 | msgid(REQ_NO_MEMORY)
41 | msgstr("Chyba: Nedostatek paměti")
42 |
43 | msgid(TRANSFER_NEW)
44 | msgstr("Nový přenos souboru")
45 |
46 | msgid(TRANSFER_STARTED)
47 | msgstr("Přenos souboru začal")
48 |
49 | msgid(TRANSFER___)
50 | msgstr("...")
51 |
52 | msgid(TRANSFER_PAUSED)
53 | msgstr("Přenos souboru pozastaven")
54 |
55 | msgid(TRANSFER_BROKEN)
56 | msgstr("Přenos souboru se nezdařil")
57 |
58 | msgid(TRANSFER_CANCELLED)
59 | msgstr("Přenos souboru zrušen")
60 |
61 | msgid(TRANSFER_COMPLETE)
62 | msgstr("Přenos souboru dokončen")
63 |
64 | msgid(CALL_CANCELLED)
65 | msgstr("Hovor zrušen")
66 |
67 | msgid(CALL_INVITED)
68 | //msgstr("Call invited")
69 |
70 | msgid(CALL_RINGING)
71 | //msgstr("Call ringing")
72 |
73 | msgid(CALL_STARTED)
74 | msgstr("Hovor začal")
75 |
76 | msgid(ADDFRIENDS)
77 | msgstr("Přidat kontakt")
78 |
79 | msgid(TOXID)
80 | msgstr("Tox ID")
81 |
82 | msgid(MESSAGE)
83 | msgstr("Zpráva")
84 |
85 | msgid(SEARCHFRIENDS)
86 | msgstr("Najdi kontakt")
87 |
88 | msgid(ADD)
89 | msgstr("Přidej")
90 |
91 | msgid(SWITCHPROFILE)
92 | msgstr("Přepnout profil")
93 |
94 | msgid(FRIENDREQUEST)
95 | msgstr("Žádost o kontakt")
96 |
97 | msgid(USERSETTINGS)
98 | msgstr("Uživatelské nastavení")
99 |
100 | msgid(NAME)
101 | msgstr("Jméno")
102 |
103 | msgid(STATUSMESSAGE)
104 | msgstr("Status")
105 |
106 | msgid(PREVIEW)
107 | msgstr("Náhled")
108 |
109 | msgid(DEVICESELECTION)
110 | msgstr("Výběr zařízení")
111 |
112 | msgid(AUDIOINPUTDEVICE)
113 | msgstr("Vstupní zvukové zařízení")
114 |
115 | msgid(AUDIOOUTPUTDEVICE)
116 | msgstr("Výstupní zvukové zařízení")
117 |
118 | msgid(VIDEOINPUTDEVICE)
119 | msgstr("Vstupní video zařízení")
120 |
121 | msgid(OTHERSETTINGS)
122 | msgstr("Ostatní nastavení")
123 |
124 | msgid(DPI)
125 | msgstr("DPI")
126 |
127 | msgid(SAVELOCATION)
128 | msgstr("Ulož pozici")
129 |
130 | msgid(LANGUAGE)
131 | msgstr("Jazyk")
132 |
133 | msgid(NETWORK)
134 | msgstr("Síť")
135 |
136 | msgid(IPV6)
137 | msgstr("IPv6:")
138 |
139 | msgid(UDP)
140 | msgstr("UDP:")
141 |
142 | msgid(PROXY)
143 | msgstr("Proxy (SOCKS 5)")
144 |
145 | msgid(WARNING)
146 | msgstr("Změna nastavení sítě/Proxy Vás dočasně odpojí od sítě Tox.")
147 |
148 | msgid(LOGGING)
149 | msgstr("Logování")
150 |
151 | msgid(IS_TYPING)
152 | msgstr("píše...")
153 |
154 | msgid(COPY)
155 | msgstr("Kopírovat")
156 |
157 | msgid(COPYWITHOUTNAMES)
158 | msgstr("Kopírovat (beze jmen)")
159 |
160 | msgid(CUT)
161 | msgstr("Vyjmout")
162 |
163 | msgid(PASTE)
164 | msgstr("Vložit")
165 |
166 | msgid(DELETE)
167 | msgstr("Smazat")
168 |
169 | msgid(SELECTALL)
170 | msgstr("Vybrat vše")
171 |
172 | msgid(REMOVE)
173 | msgstr("Odstranit")
174 |
175 | msgid(LEAVE)
176 | msgstr("Opustit")
177 |
178 | msgid(ACCEPT)
179 | msgstr("Přijmout")
180 |
181 | msgid(IGNORE)
182 | msgstr("Ignorovat")
183 |
184 | msgid(CLICKTOSAVE)
185 | msgstr("Klikni pro uložení")
186 |
187 | msgid(CLICKTOOPEN)
188 | msgstr("Klikni pro otevření")
189 |
190 | msgid(CANCELLED)
191 | msgstr("Zrušeno")
192 |
193 | msgid(DPI_TINY)
194 | msgstr("Malý (50%)")
195 |
196 | msgid(DPI_NORMAL)
197 | msgstr("Normální (100%)")
198 |
199 | msgid(DPI_BIG)
200 | msgstr("Větší (150%)")
201 |
202 | msgid(DPI_LARGE)
203 | msgstr("Velký (200%)")
204 |
205 | msgid(DPI_HUGE)
206 | msgstr("Obrovský (250%)")
207 |
208 | msgid(CONTACTS_FILTER_ALL)
209 | msgstr("Vše")
210 |
211 | msgid(CONTACTS_FILTER_ONLINE)
212 | msgstr("Online")
213 |
214 | msgid(PROXY_DISABLED)
215 | msgstr("Vypnuto")
216 |
217 | msgid(PROXY_FALLBACK)
218 | msgstr("Záložní režim")
219 |
220 | msgid(PROXY_ALWAYS_USE)
221 | msgstr("Použít vždy")
222 |
223 | msgid(NO)
224 | msgstr("Ne")
225 |
226 | msgid(YES)
227 | msgstr("Ano")
228 |
229 | msgid(VIDEO_IN_NONE)
230 | msgstr("Žádné")
231 |
232 | msgid(VIDEO_IN_DESKTOP)
233 | msgstr("Plocha")
234 |
235 | //TODO: Localize or remove.
236 | //msgid(DEFAULT_FRIEND_REQUEST_MESSAGE)
237 | //msgstr("Please accept this friend request.")
238 |
239 | //TODO: Localize or remove.
240 | //msgid(CONTACTS_FILTER_EDIT_HINT)
241 | //msgstr("Search friends")
242 |
243 | //TODO: Localize or remove.
244 | //msgid(PROXY_EDIT_HINT_IP)
245 | //msgstr("IP")
246 |
247 | //TODO: Localize or remove.
248 | //msgid(PROXY_EDIT_HINT_PORT)
249 | //msgstr("Port")
250 |
251 | //TODO: Localize or remove.
252 | //msgid(AUDIO_IN_DEFAULT_LOOPBACK)
253 | //msgstr("Default Loopback")
254 |
255 | //TODO: Localize or remove.
256 | //msgid(WINDOW_TITLE_VIDEO_PREVIEW)
257 | //msgstr("Video Preview")
258 |
259 | //TODO: Localize or remove.
260 | //msgid(AUDIONOTIFICATIONS)
261 | //msgstr("Enable Audible Notification (Ringtone)")
262 |
--------------------------------------------------------------------------------
/langs/da.h:
--------------------------------------------------------------------------------
1 | msgid(LANG_NATIVE_NAME)
2 | msgstr("Dansk")
3 |
4 | msgid(LANG_ENGLISH_NAME)
5 | msgstr("DANISH")
6 |
7 | msgid(REQ_SENT)
8 | msgstr("Venneanmodning sendt. Din ven vil forekomme online når anmodningen er accepteret.")
9 |
10 | msgid(REQ_RESOLVE)
11 | msgstr("Prøver at afkode DNS navn...")
12 |
13 | msgid(REQ_INVALID_ID)
14 | msgstr("Fejl: Ugyldigt Tox ID")
15 |
16 | msgid(REQ_EMPTY_ID)
17 | msgstr("Fejl: Intet Tox ID specificeret")
18 |
19 | msgid(REQ_LONG_MSG)
20 | msgstr("Fejl: Besked er for lang")
21 |
22 | msgid(REQ_NO_MSG)
23 | msgstr("Fejl: Tom besked")
24 |
25 | msgid(REQ_SELF_ID)
26 | msgstr("Fejl: Tox ID er eget ID")
27 |
28 | msgid(REQ_ALREADY_FRIENDS)
29 | msgstr("Fejl: Tox ID er allerede på vennelisten")
30 |
31 | msgid(REQ_UNKNOWN)
32 | msgstr("Fejl: Ukendt")
33 |
34 | msgid(REQ_BAD_CHECKSUM)
35 | msgstr("Fejl: Ugyldigt Tox ID (forkert checksum)")
36 |
37 | msgid(REQ_BAD_NOSPAM)
38 | msgstr("Fejl: Ugyldigt Tox ID (forkert nospam værdi)")
39 |
40 | msgid(REQ_NO_MEMORY)
41 | msgstr("Fejl: Ingen hukommelse")
42 |
43 | msgid(TRANSFER_NEW)
44 | msgstr("Ny filoverførsel")
45 |
46 | msgid(TRANSFER_STARTED)
47 | msgstr("Filoverførsel startet")
48 |
49 | //msgid(TRANSFER___)
50 | //msgstr("...")
51 |
52 | msgid(TRANSFER_PAUSED)
53 | msgstr("Filoverførsel sat på pause")
54 |
55 | msgid(TRANSFER_BROKEN)
56 | msgstr("Filoverførsel fejlede")
57 |
58 | msgid(TRANSFER_CANCELLED)
59 | msgstr("Filoverførsel annulleret")
60 |
61 | msgid(TRANSFER_COMPLETE)
62 | msgstr("Filoverførsel færdig")
63 |
64 | msgid(CALL_CANCELLED)
65 | msgstr("Opkald annulleret")
66 |
67 | msgid(CALL_INVITED)
68 | msgstr("Opkald inviteret")
69 |
70 | msgid(CALL_RINGING)
71 | msgstr("Opkald ringer")
72 |
73 | msgid(CALL_STARTED)
74 | msgstr("Opkald startet")
75 |
76 | msgid(ADDFRIENDS)
77 | msgstr("Tilføj venner")
78 |
79 | //msgid(TOXID)
80 | //msgstr("Tox ID")
81 |
82 | msgid(MESSAGE)
83 | msgstr("Besked")
84 |
85 | msgid(SEARCHFRIENDS)
86 | msgstr("Søg i venner")
87 |
88 | msgid(ADD)
89 | msgstr("Tilføj")
90 |
91 | msgid(SWITCHPROFILE)
92 | msgstr("Skift profil")
93 |
94 | msgid(FRIENDREQUEST)
95 | msgstr("Venneanmodning")
96 |
97 | msgid(USERSETTINGS)
98 | msgstr("Brugerindstillinger")
99 |
100 | msgid(NAME)
101 | msgstr("Navn")
102 |
103 | msgid(STATUSMESSAGE)
104 | msgstr("Status besked")
105 |
106 | msgid(PREVIEW)
107 | msgstr("Eksempel")
108 |
109 | msgid(DEVICESELECTION)
110 | msgstr("Vælg enhed")
111 |
112 | msgid(AUDIOINPUTDEVICE)
113 | msgstr("Lyd input enhed")
114 |
115 | msgid(AUDIOFILTERING)
116 | msgstr("Lyd Filter")
117 |
118 | msgid(AUDIOOUTPUTDEVICE)
119 | msgstr("Lyd output enhed")
120 |
121 | msgid(VIDEOINPUTDEVICE)
122 | msgstr("Video output enhed")
123 |
124 | msgid(OTHERSETTINGS)
125 | msgstr("Andre indstillinger")
126 |
127 | //msgid(DPI)
128 | //msgstr("DPI")
129 |
130 | msgid(SAVELOCATION)
131 | msgstr("Gem område")
132 |
133 | msgid(LANGUAGE)
134 | msgstr("Sprog")
135 |
136 | msgid(NETWORK)
137 | msgstr("Netværk")
138 |
139 | //msgid(IPV6)
140 | //msgstr("IPv6:")
141 |
142 | //msgid(UDP)
143 | //msgstr("UDP:")
144 |
145 | //msgid(PROXY)
146 | //msgstr("Proxy (SOCKS 5)")
147 |
148 | msgid(WARNING)
149 | msgstr("Ændring af Netværk/Proxy indstillinger vil midlertidigt afbryde din forbindelse til Tox netværket")
150 |
151 | msgid(LOGGING)
152 | msgstr("Logger")
153 |
154 | msgid(AUDIONOTIFICATIONS)
155 | msgstr("Aktiver lyd notifikation (Ringetone)")
156 |
157 | msgid(IS_TYPING)
158 | msgstr("skriver...")
159 |
160 | msgid(COPY)
161 | msgstr("Kopier")
162 |
163 | msgid(COPYWITHOUTNAMES)
164 | msgstr("Kopier (ingen navne)")
165 |
166 | msgid(CUT)
167 | msgstr("Klip")
168 |
169 | msgid(PASTE)
170 | msgstr("Indsæt")
171 |
172 | msgid(DELETE)
173 | msgstr("Slet")
174 |
175 | msgid(SELECTALL)
176 | msgstr("Vælg alle")
177 |
178 | msgid(REMOVE)
179 | msgstr("Fjern")
180 |
181 | msgid(LEAVE)
182 | msgstr("Forlad")
183 |
184 | msgid(ACCEPT)
185 | msgstr("Accepter")
186 |
187 | msgid(IGNORE)
188 | msgstr("Ignorer")
189 |
190 | msgid(CLICKTOSAVE)
191 | msgstr("Klik for at gemme")
192 |
193 | msgid(CLICKTOOPEN)
194 | msgstr("Klik for at åbne")
195 |
196 | msgid(CANCELLED)
197 | msgstr("Annulleret")
198 |
199 | msgid(DPI_TINY)
200 | msgstr("Lille (50%)")
201 |
202 | //msgid(DPI_NORMAL)
203 | //msgstr("Normal (100%)")
204 |
205 | msgid(DPI_BIG)
206 | msgstr("Stor (150%)")
207 |
208 | msgid(DPI_LARGE)
209 | msgstr("Kæmpe (200%)")
210 |
211 | msgid(DPI_HUGE)
212 | msgstr("Enorm (250%)")
213 |
214 | msgid(CONTACTS_FILTER_ALL)
215 | msgstr("Alle")
216 |
217 | //msgid(CONTACTS_FILTER_ONLINE)
218 | //msgstr("Online")
219 |
220 | msgid(PROXY_DISABLED)
221 | msgstr("Ikke slået til")
222 |
223 | //msgid(PROXY_FALLBACK)
224 | //msgstr("Fallback")
225 |
226 | msgid(PROXY_ALWAYS_USE)
227 | msgstr("Brug altid")
228 |
229 | msgid(NO)
230 | msgstr("Nej")
231 |
232 | msgid(YES)
233 | msgstr("Ja")
234 |
235 | msgid(VIDEO_IN_NONE)
236 | msgstr("Ingen")
237 |
238 | msgid(VIDEO_IN_DESKTOP)
239 | msgstr("Skrivebord")
240 |
241 | msgid(AUDIO_IN_DEFAULT_LOOPBACK)
242 | msgstr("Standard Loopback")
243 |
244 | msgid(DEFAULT_FRIEND_REQUEST_MESSAGE)
245 | msgstr("Accepter venligst denne venneanmodning.")
246 |
247 | msgid(CONTACTS_FILTER_EDIT_HINT)
248 | msgstr("Find venner")
249 |
250 | //msgid(PROXY_EDIT_HINT_IP)
251 | //msgstr("IP")
252 |
253 | //msgid(PROXY_EDIT_HINT_PORT)
254 | //msgstr("Port")
255 |
256 | msgid(WINDOW_TITLE_VIDEO_PREVIEW)
257 | msgstr("Video prøve")
258 |
259 | //msgid(MUTE)
260 | //msgstr("Mute")
261 |
262 | //msgid(UNMUTE)
263 | //msgstr("Unmute")
264 |
265 | msgid(AVATAR_TOO_LARGE_MAX_SIZE_IS)
266 | msgstr("Avatar er for stor. Maximum Størrelse: ")
267 |
268 | msgid(CANT_FIND_FILE_OR_EMPTY)
269 | msgstr("Kan ikke finde den valgte fil eller også er valgte fil tom.")
270 |
271 | msgid(CLEAR_HISTORY)
272 | msgstr("Slet historie")
273 |
--------------------------------------------------------------------------------
/langs/fr.h:
--------------------------------------------------------------------------------
1 | msgid(LANG_NATIVE_NAME)
2 | msgstr("Français")
3 |
4 | msgid(LANG_ENGLISH_NAME)
5 | msgstr("FRENCH")
6 |
7 | msgid(REQ_SENT)
8 | msgstr("Demande envoyée. Votre ami apparaîtra en ligne quand il acceptera votre demande.")
9 |
10 | msgid(REQ_RESOLVE)
11 | msgstr("Tente de résoudre les noms DNS...")
12 |
13 | msgid(REQ_INVALID_ID)
14 | msgstr("Erreur: Tox ID invalide")
15 |
16 | msgid(REQ_EMPTY_ID)
17 | msgstr("Erreur: Aucun Tox ID")
18 |
19 | msgid(REQ_LONG_MSG)
20 | msgstr("Erreur: Message trop long")
21 |
22 | msgid(REQ_NO_MSG)
23 | msgstr("Erreur: Message vide")
24 |
25 | msgid(REQ_SELF_ID)
26 | msgstr("Erreur: Tox ID est une ID personnel")
27 |
28 | msgid(REQ_ALREADY_FRIENDS)
29 | msgstr("Erreur: Tox ID est déjà dans votre liste d'ami")
30 |
31 | msgid(REQ_UNKNOWN)
32 | msgstr("Erreur: Inconnue")
33 |
34 | msgid(REQ_BAD_CHECKSUM)
35 | msgstr("Erreur: Tox ID invalide (bad checksum)")
36 |
37 | msgid(REQ_BAD_NOSPAM)
38 | msgstr("Erreur: Tox ID invalide (bad nospam value)")
39 |
40 | msgid(REQ_NO_MEMORY)
41 | msgstr("Erreur: Pas de mémoire")
42 |
43 | msgid(TRANSFER_NEW)
44 | msgstr("Nouveau transfert de fichier")
45 |
46 | msgid(TRANSFER_STARTED)
47 | msgstr("Transfert de fichier commencé")
48 |
49 | msgid(TRANSFER_PAUSED)
50 | msgstr("Transfert de fichier en pause")
51 |
52 | msgid(TRANSFER_BROKEN)
53 | msgstr("Transfert de fichier interrompu")
54 |
55 | msgid(TRANSFER_CANCELLED)
56 | msgstr("Transfert de fichier annulé")
57 |
58 | msgid(TRANSFER_COMPLETE)
59 | msgstr("Transfert de fichier complété")
60 |
61 | msgid(CALL_CANCELLED)
62 | msgstr("Appel annulé")
63 |
64 | msgid(CALL_INVITED)
65 | msgstr("Réception d'un appel")
66 |
67 | msgid(CALL_RINGING)
68 | msgstr("Appel en cours")
69 |
70 | msgid(CALL_STARTED)
71 | msgstr("Appel commencé")
72 |
73 | msgid(ADDFRIENDS)
74 | msgstr("Ajouter un ami")
75 |
76 | msgid(SEARCHFRIENDS)
77 | msgstr("Recherche d'ami")
78 |
79 | msgid(ADD)
80 | msgstr("Ajouter")
81 |
82 | msgid(SWITCHPROFILE)
83 | msgstr("Changement de profil")
84 |
85 | msgid(FRIENDREQUEST)
86 | msgstr("Demande d'ami")
87 |
88 | msgid(USERSETTINGS)
89 | msgstr("Paramètre d'utilisateur")
90 |
91 | msgid(NAME)
92 | msgstr("Nom")
93 |
94 | msgid(STATUSMESSAGE)
95 | msgstr("Message d'humeur")
96 |
97 | msgid(PREVIEW)
98 | msgstr("Aperçu")
99 |
100 | msgid(DEVICESELECTION)
101 | msgstr("Sélection des périphériques")
102 |
103 | msgid(AUDIOINPUTDEVICE)
104 | msgstr("Périphérique d'entrée audio")
105 |
106 | msgid(AUDIOFILTERING)
107 | msgstr("Filtre audio")
108 |
109 | msgid(AUDIOOUTPUTDEVICE)
110 | msgstr("Périphérique de sortie audio")
111 |
112 | msgid(VIDEOINPUTDEVICE)
113 | msgstr("Périphérique d'entrée vidéo")
114 |
115 | msgid(OTHERSETTINGS)
116 | msgstr("Autres paramètres")
117 |
118 | msgid(DPI)
119 | msgstr("Taille de la police")
120 |
121 | msgid(SAVELOCATION)
122 | msgstr("Emplacement de sauvegarde")
123 |
124 | msgid(LANGUAGE)
125 | msgstr("Langue")
126 |
127 | msgid(NETWORK)
128 | msgstr("Réseau")
129 |
130 | msgid(WARNING)
131 | msgstr("Modifier les paramètres Réseau/Proxy vous déconnectera du réseau Tox")
132 |
133 | msgid(LOGGING)
134 | msgstr("Historique")
135 |
136 | msgid(AUDIONOTIFICATIONS)
137 | msgstr("Activer les notifications audio (Sonnerie)")
138 |
139 | msgid(IS_TYPING)
140 | msgstr("en train d'écrire...")
141 |
142 | msgid(COPY)
143 | msgstr("Copier")
144 |
145 | msgid(COPYWITHOUTNAMES)
146 | msgstr("Copier (sans les noms)")
147 |
148 | msgid(CUT)
149 | msgstr("Couper")
150 |
151 | msgid(PASTE)
152 | msgstr("Coller")
153 |
154 | msgid(DELETE)
155 | msgstr("Supprimer")
156 |
157 | msgid(SELECTALL)
158 | msgstr("Tout sélectionner")
159 |
160 | msgid(REMOVE)
161 | msgstr("Effacer")
162 |
163 | msgid(LEAVE)
164 | msgstr("Partir")
165 |
166 | msgid(ACCEPT)
167 | msgstr("Accepter")
168 |
169 | msgid(IGNORE)
170 | msgstr("Ignorer")
171 |
172 | msgid(SENDSCREENSHOT)
173 | msgstr("Envoyer une capture d'écran")
174 |
175 | msgid(CLICKTOSAVE)
176 | msgstr("Cliquer pour sauvegarder")
177 |
178 | msgid(CLICKTOOPEN)
179 | msgstr("Cliquer pour ouvrir")
180 |
181 | msgid(CANCELLED)
182 | msgstr("Annulé")
183 |
184 | msgid(DPI_TINY)
185 | msgstr("Petit (50%)")
186 |
187 | msgid(DPI_BIG)
188 | msgstr("Grand (150%)")
189 |
190 | msgid(DPI_HUGE)
191 | msgstr("Très large (250%)")
192 |
193 | msgid(CONTACTS_FILTER_ALL)
194 | msgstr("Tout")
195 |
196 | msgid(CONTACTS_FILTER_ONLINE)
197 | msgstr("En ligne")
198 |
199 | msgid(PROXY_DISABLED)
200 | msgstr("Désactivé")
201 |
202 | msgid(PROXY_FALLBACK)
203 | msgstr("Repli")
204 |
205 | msgid(PROXY_ALWAYS_USE)
206 | msgstr("Toujours utiliser")
207 |
208 | msgid(NO)
209 | msgstr("Non")
210 |
211 | msgid(YES)
212 | msgstr("Oui")
213 |
214 | msgid(VIDEO_IN_NONE)
215 | msgstr("Aucun")
216 |
217 | msgid(VIDEO_IN_DESKTOP)
218 | msgstr("Ecran")
219 |
220 | msgid(DEFAULT_FRIEND_REQUEST_MESSAGE)
221 | msgstr("Veuillez accepter cette requête d'ami.")
222 |
223 | msgid(CONTACTS_FILTER_EDIT_HINT)
224 | msgstr("Recherche d'ami")
225 |
226 | msgid(AUDIO_IN_DEFAULT_LOOPBACK)
227 | msgstr("Par défaut")
228 |
229 | msgid(WINDOW_TITLE_VIDEO_PREVIEW)
230 | msgstr("Aperçu vidéo")
231 |
232 | msgid(MUTE)
233 | msgstr("Muet")
234 |
235 | msgid(UNMUTE)
236 | msgstr("Non muet")
237 |
238 | msgid(AVATAR_TOO_LARGE_MAX_SIZE_IS)
239 | msgstr("Avatar trop grand. Taille maximum : ")
240 |
241 | msgid(CANT_FIND_FILE_OR_EMPTY)
242 | msgstr("Impossible de trouver le fichier sélectionné ou le fichier sélectionné est vide.")
243 |
244 | msgid(CLEAR_HISTORY)
245 | msgstr("Nettoyer l'historique")
246 |
247 | msgid(THEME)
248 | msgstr("Thème")
249 |
250 | msgid(THEME_DEFAULT)
251 | msgstr("Défaut")
252 |
253 | msgid(THEME_LIGHT)
254 | msgstr("Thème clair")
255 |
256 | msgid(THEME_DARK)
257 | msgstr("Thème sombre")
258 |
259 | msgid(THEME_HIGHCONTRAST)
260 | msgstr("Contraste élevé")
261 |
--------------------------------------------------------------------------------
/langs/ja.h:
--------------------------------------------------------------------------------
1 | msgid(LANG_NATIVE_NAME)
2 | msgstr("日本語")
3 |
4 | msgid(LANG_ENGLISH_NAME)
5 | msgstr("JAPANESE")
6 |
7 | msgid(REQ_SENT)
8 | msgstr("フレンド要求が送信されました。要求が承諾されるとオンライン表示になります。")
9 |
10 | msgid(REQ_RESOLVE)
11 | msgstr("DNS解決中")
12 |
13 | msgid(REQ_INVALID_ID)
14 | msgstr("エラー: 無効なTox IDです")
15 |
16 | msgid(REQ_EMPTY_ID)
17 | msgstr("エラー: Tox IDが指定されていません")
18 |
19 | msgid(REQ_LONG_MSG)
20 | msgstr("エラー: メッセージが長すぎます")
21 |
22 | msgid(REQ_NO_MSG)
23 | msgstr("エラー: 空のメッセージ")
24 |
25 | msgid(REQ_SELF_ID)
26 | msgstr("エラー: Tox IDは自身のIDです")
27 |
28 | msgid(REQ_ALREADY_FRIENDS)
29 | msgstr("エラー: Tox IDは既にフレンドリストの中です")
30 |
31 | msgid(REQ_UNKNOWN)
32 | msgstr("エラー: 不明")
33 |
34 | msgid(REQ_BAD_CHECKSUM)
35 | msgstr("エラー: Tox IDは不正です (不正なチェックサム)")
36 |
37 | msgid(REQ_BAD_NOSPAM)
38 | msgstr("エラー: Tox IDは不正です (不正なnospam値)")
39 |
40 | msgid(REQ_NO_MEMORY)
41 | msgstr("エラー: メモリ不足です")
42 |
43 | msgid(TRANSFER_NEW)
44 | msgstr("新しいファイルの転送")
45 |
46 | msgid(TRANSFER_STARTED)
47 | msgstr("ファイルの転送が開始しました")
48 |
49 | //TODO: Same as in English? Localize or remove.
50 | //msgid(TRANSFER___)
51 | //msgstr("...")
52 |
53 | msgid(TRANSFER_PAUSED)
54 | msgstr("ファイルの転送が停止しました")
55 |
56 | msgid(TRANSFER_BROKEN)
57 | msgstr("ファイルの転送が失敗しました")
58 |
59 | msgid(TRANSFER_CANCELLED)
60 | msgstr("ファイルの転送をキャンセルしました")
61 |
62 | msgid(TRANSFER_COMPLETE)
63 | msgstr("ファイルの転送が完了しました")
64 |
65 | msgid(CALL_CANCELLED)
66 | msgstr("通話をキャンセルしました")
67 |
68 | msgid(CALL_INVITED)
69 | msgstr("通話を招待しました")
70 |
71 | msgid(CALL_RINGING)
72 | msgstr("通話が鳴っています")
73 |
74 | msgid(CALL_STARTED)
75 | msgstr("通話を開始しました")
76 |
77 | msgid(ADDFRIENDS)
78 | msgstr("フレンド追加")
79 |
80 | //TODO: Same as in English? Localize or remove.
81 | //msgid(TOXID)
82 | //msgstr("Tox ID")
83 |
84 | msgid(MESSAGE)
85 | msgstr("メッセージ")
86 |
87 | msgid(SEARCHFRIENDS)
88 | msgstr("フレンドの検索")
89 |
90 | msgid(ADD)
91 | msgstr("追加")
92 |
93 | msgid(SWITCHPROFILE)
94 | msgstr("プロファイルを変更")
95 |
96 | msgid(FRIENDREQUEST)
97 | msgstr("フレンド要求")
98 |
99 | msgid(USERSETTINGS)
100 | msgstr("ユーザ設定")
101 |
102 | msgid(NAME)
103 | msgstr("名前")
104 |
105 | msgid(STATUSMESSAGE)
106 | msgstr("状態メッセージ")
107 |
108 | msgid(PREVIEW)
109 | msgstr("プレビュー")
110 |
111 | msgid(DEVICESELECTION)
112 | msgstr("デバイス選択")
113 |
114 | msgid(AUDIOINPUTDEVICE)
115 | msgstr("音声入力デバイス")
116 |
117 | msgid(AUDIOOUTPUTDEVICE)
118 | msgstr("音声出力デバイス")
119 |
120 | msgid(VIDEOINPUTDEVICE)
121 | msgstr("ビデオ入力デバイス")
122 |
123 | msgid(OTHERSETTINGS)
124 | msgstr("他の設定")
125 |
126 | msgid(DPI)
127 | msgstr("解像度")
128 |
129 | msgid(SAVELOCATION)
130 | msgstr("場所の保存")
131 |
132 | msgid(LANGUAGE)
133 | msgstr("言語")
134 |
135 | msgid(NETWORK)
136 | msgstr("ネットワーク")
137 |
138 | //TODO: Same as in English? Localize or remove.
139 | //msgid(IPV6)
140 | //msgstr("IPv6:")
141 |
142 | //TODO: Same as in English? Localize or remove.
143 | //msgid(UDP)
144 | //msgstr("UDP:")
145 |
146 | msgid(PROXY)
147 | msgstr("プロキシ (SOCKS 5)")
148 |
149 | msgid(WARNING)
150 | msgstr("ネットワークやプロキシの設定を変えるとToxネットワークの接続が切断されます")
151 |
152 | msgid(LOGGING)
153 | msgstr("ロギング")
154 |
155 | //TODO: Same as in English? Localize or remove.
156 | //msgid(IS_TYPING)
157 | //msgstr("is typing...")
158 |
159 | msgid(COPY)
160 | msgstr("コピー")
161 |
162 | msgid(COPYWITHOUTNAMES)
163 | msgstr("コピー(名前以外)")
164 |
165 | msgid(CUT)
166 | msgstr("カット")
167 |
168 | msgid(PASTE)
169 | msgstr("ペースト")
170 |
171 | msgid(DELETE)
172 | msgstr("削除")
173 |
174 | msgid(SELECTALL)
175 | msgstr("すべてを選択")
176 |
177 | msgid(REMOVE)
178 | msgstr("削除")
179 |
180 | msgid(LEAVE)
181 | msgstr("退出")
182 |
183 | msgid(ACCEPT)
184 | msgstr("承認")
185 |
186 | msgid(IGNORE)
187 | msgstr("無視する")
188 |
189 | msgid(CLICKTOSAVE)
190 | msgstr("クリックで保存")
191 |
192 | msgid(CLICKTOOPEN)
193 | msgstr("クリックで開く")
194 |
195 | msgid(CANCELLED)
196 | msgstr("キャンセルしました")
197 |
198 | //TODO: Localize or remove.
199 | //msgid(DPI_TINY)
200 | //msgstr("Tiny (50%)")
201 |
202 | //TODO: Localize or remove.
203 | //msgid(DPI_NORMAL)
204 | //msgstr("Normal (100%)")
205 |
206 | //TODO: Localize or remove.
207 | //msgid(DPI_BIG)
208 | //msgstr("Big (150%)")
209 |
210 | //TODO: Localize or remove.
211 | //msgid(DPI_LARGE)
212 | //msgstr("Large (200%)")
213 |
214 | //TODO: Localize or remove.
215 | //msgid(DPI_HUGE)
216 | //msgstr("Huge (250%)")
217 |
218 | //TODO: Localize or remove.
219 | //msgid(CONTACTS_FILTER_ALL)
220 | //msgstr("All")
221 |
222 | //TODO: Localize or remove.
223 | //msgid(CONTACTS_FILTER_ONLINE)
224 | //msgstr("Online")
225 |
226 | //TODO: Localize or remove.
227 | //msgid(PROXY_DISABLED)
228 | //msgstr("Disabled")
229 |
230 | //TODO: Localize or remove.
231 | //msgid(PROXY_FALLBACK)
232 | //msgstr("Fallback")
233 |
234 | //TODO: Localize or remove.
235 | //msgid(PROXY_ALWAYS_USE)
236 | //msgstr("Always use")
237 |
238 | //TODO: Localize or remove.
239 | //msgid(NO)
240 | //msgstr("No")
241 |
242 | //TODO: Localize or remove.
243 | //msgid(YES)
244 | //msgstr("Yes")
245 |
246 | //TODO: Localize or remove.
247 | //msgid(VIDEO_IN_NONE)
248 | //msgstr("None")
249 |
250 | //TODO: Localize or remove.
251 | //msgid(VIDEO_IN_DESKTOP)
252 | //msgstr("Desktop")
253 |
254 | //TODO: Localize or remove.
255 | //msgid(DEFAULT_FRIEND_REQUEST_MESSAGE)
256 | //msgstr("Please accept this friend request.")
257 |
258 | //TODO: Localize or remove.
259 | //msgid(CONTACTS_FILTER_EDIT_HINT)
260 | //msgstr("Search friends")
261 |
262 | //TODO: Localize or remove.
263 | //msgid(PROXY_EDIT_HINT_IP)
264 | //msgstr("IP")
265 |
266 | //TODO: Localize or remove.
267 | //msgid(PROXY_EDIT_HINT_PORT)
268 | //msgstr("Port")
269 |
270 | //TODO: Localize or remove.
271 | //msgid(AUDIO_IN_DEFAULT_LOOPBACK)
272 | //msgstr("Default Loopback")
273 |
274 | //TODO: Localize or remove.
275 | //msgid(WINDOW_TITLE_VIDEO_PREVIEW)
276 | //msgstr("Video Preview")
277 |
278 | //TODO: Localize or remove.
279 | //msgid(AUDIONOTIFICATIONS)
280 | //msgstr("Enable Audible Notification (Ringtone)")
281 |
--------------------------------------------------------------------------------
/langs/lv.h:
--------------------------------------------------------------------------------
1 | msgid(LANG_NATIVE_NAME)
2 | msgstr("Latviešu")
3 |
4 | msgid(LANG_ENGLISH_NAME)
5 | msgstr("LATVIAN")
6 |
7 | msgid(REQ_SENT)
8 | msgstr("Draugu pieprasījums ir nosūtīts. Jūsu draugs parādīsies tiešsaistē kad pieprasījums būs pieņemts.")
9 |
10 | msgid(REQ_RESOLVE)
11 | msgstr("Atrisinājam DNS ierakstus")
12 |
13 | msgid(REQ_INVALID_ID)
14 | msgstr("Kļūda: Nederīgs Tox ID")
15 |
16 | msgid(REQ_EMPTY_ID)
17 | msgstr("Kļūda: No Tox ID specified")
18 |
19 | msgid(REQ_LONG_MSG)
20 | msgstr("Kļūda: Ziņa ir pārāk gara")
21 |
22 | msgid(REQ_NO_MSG)
23 | msgstr("Kļūda: Tukša ziņa")
24 |
25 | msgid(REQ_SELF_ID)
26 | msgstr("Kļūda: Tox ID is self ID")
27 |
28 | msgid(REQ_ALREADY_FRIENDS)
29 | msgstr("Kļūda: Tox ID jau ir draugu sarakstā")
30 |
31 | msgid(REQ_UNKNOWN)
32 | msgstr("Kļūda: Unknown")
33 |
34 | msgid(REQ_BAD_CHECKSUM)
35 | msgstr("Kļūda: Nederīgs Tox ID (bad checksum)")
36 |
37 | msgid(REQ_BAD_NOSPAM)
38 | msgstr("Kļūda: Nederīgs Tox ID (bad nospam value)")
39 |
40 | msgid(REQ_NO_MEMORY)
41 | msgstr("Kļūda: No memory")
42 |
43 | msgid(TRANSFER_NEW)
44 | msgstr("Jauna faila pārsūtīšana")
45 |
46 | msgid(TRANSFER_STARTED)
47 | msgstr("Faila pārsūtīšana sākta")
48 |
49 | msgid(TRANSFER_PAUSED)
50 | msgstr("Faila pārsūtīšana apturēta")
51 |
52 | msgid(TRANSFER_BROKEN)
53 | msgstr("Kļūda faila pārsūtīšanā")
54 |
55 | msgid(TRANSFER_CANCELLED)
56 | msgstr("Faila pārsūtīšana atcelta")
57 |
58 | msgid(TRANSFER_COMPLETE)
59 | msgstr("Faila pārsūtīšana pabeigta")
60 |
61 | msgid(CALL_CANCELLED)
62 | msgstr("Zvans atcelts")
63 |
64 | msgid(CALL_INVITED)
65 | msgstr("Saruna aicinājums")
66 |
67 | msgid(CALL_RINGING)
68 | msgstr("Jums zvana")
69 |
70 | msgid(CALL_STARTED)
71 | msgstr("Zvans uzsākts")
72 |
73 | msgid(ADDFRIENDS)
74 | msgstr("Pievienot draugus")
75 |
76 | msgid(MESSAGE)
77 | msgstr("Ziņa")
78 |
79 | msgid(SEARCHFRIENDS)
80 | msgstr("Meklēt draugus")
81 |
82 | msgid(ADD)
83 | msgstr("Pievienot")
84 |
85 | msgid(SWITCHPROFILE)
86 | msgstr("Mainīt lietotāju")
87 |
88 | msgid(FRIENDREQUEST)
89 | msgstr("Draugu pieprasījums")
90 |
91 | msgid(USERSETTINGS)
92 | msgstr("Lietotāja iestatījumi")
93 |
94 | msgid(NAME)
95 | msgstr("Vārds")
96 |
97 | msgid(STATUSMESSAGE)
98 | msgstr("Statusa ziņojums")
99 |
100 | msgid(PREVIEW)
101 | msgstr("Priekšskatījums")
102 |
103 | msgid(DEVICESELECTION)
104 | msgstr("Ierīču izvēle")
105 |
106 | msgid(AUDIOINPUTDEVICE)
107 | msgstr("Audio ievades ierīce")
108 |
109 | msgid(AUDIOOUTPUTDEVICE)
110 | msgstr("Audio izvades ierīce")
111 |
112 | msgid(VIDEOINPUTDEVICE)
113 | msgstr("Video ievades ierīce")
114 |
115 | msgid(OTHERSETTINGS)
116 | msgstr("Citi iestatījumi")
117 |
118 | msgid(SAVELOCATION)
119 | msgstr("Saglabāt novietojumu")
120 |
121 | msgid(LANGUAGE)
122 | msgstr("Valoda")
123 |
124 | msgid(NETWORK)
125 | msgstr("Tīkls")
126 |
127 | msgid(PROXY)
128 | msgstr("Starpniekserveris (SOCKS 5)")
129 |
130 | msgid(WARNING)
131 | msgstr("Mainot starpniekservera iestatījumus, jūs tiksit īslaicīgi atvienots no Tox tīkla")
132 |
133 | msgid(LOGGING)
134 | msgstr("Žurnāli")
135 |
136 | msgid(IS_TYPING)
137 | msgstr("raksta...")
138 |
139 | msgid(COPY)
140 | msgstr("Kopēt")
141 |
142 | msgid(COPYWITHOUTNAMES)
143 | msgstr("Kopēt (bez vārdiem)")
144 |
145 | msgid(CUT)
146 | msgstr("Izgriezt")
147 |
148 | msgid(PASTE)
149 | msgstr("Ielīmēt")
150 |
151 | msgid(DELETE)
152 | msgstr("Dzēst")
153 |
154 | msgid(SELECTALL)
155 | msgstr("Atlasīt visu")
156 |
157 | msgid(REMOVE)
158 | msgstr("Noņemt")
159 |
160 | msgid(LEAVE)
161 | msgstr("Pamest")
162 |
163 | msgid(ACCEPT)
164 | msgstr("Pieņemt")
165 |
166 | msgid(IGNORE)
167 | msgstr("Ignorēt")
168 |
169 | msgid(CLICKTOSAVE)
170 | msgstr("Spiest, lai saglabātu")
171 |
172 | msgid(CLICKTOOPEN)
173 | msgstr("Spiest, lai atvērtu")
174 |
175 | msgid(CANCELLED)
176 | msgstr("Atcelts")
177 |
178 | msgid(DPI_TINY)
179 | msgstr("Mazs (50%)")
180 |
181 | msgid(DPI_NORMAL)
182 | msgstr("Normāls (100%)")
183 |
184 | msgid(DPI_BIG)
185 | msgstr("Liels (150%)")
186 |
187 | msgid(DPI_LARGE)
188 | msgstr("Ļoti liels (200%)")
189 |
190 | msgid(DPI_HUGE)
191 | msgstr("Milzīgs (250%)")
192 |
193 | msgid(CONTACTS_FILTER_ALL)
194 | msgstr("Viss")
195 |
196 | msgid(CONTACTS_FILTER_ONLINE)
197 | msgstr("Tiešsaistē")
198 |
199 | msgid(PROXY_DISABLED)
200 | msgstr("Atslēgts")
201 |
202 | msgid(PROXY_FALLBACK)
203 | msgstr("Alternatīvs starpniekserveris (fallback)")
204 |
205 | msgid(PROXY_ALWAYS_USE)
206 | msgstr("Vienmēr izmantot")
207 |
208 | msgid(NO)
209 | msgstr("Nē")
210 |
211 | msgid(YES)
212 | msgstr("Jā")
213 |
214 | msgid(VIDEO_IN_NONE)
215 | msgstr("Nav")
216 |
217 | msgid(VIDEO_IN_DESKTOP)
218 | msgstr("Galddators")
219 |
220 | msgid(DEFAULT_FRIEND_REQUEST_MESSAGE)
221 | msgstr("Lūdzu, pieņemiet šo drauga pieprasījumu.")
222 |
223 | msgid(CONTACTS_FILTER_EDIT_HINT)
224 | msgstr("Meklēt draugus")
225 |
226 | msgid(PROXY_EDIT_HINT_PORT)
227 | msgstr("Ports")
228 |
229 | //TODO: Localize or remove.
230 | //msgid(AUDIO_IN_DEFAULT_LOOPBACK)
231 | //msgstr("Default Loopback")
232 |
233 | msgid(WINDOW_TITLE_VIDEO_PREVIEW)
234 | msgstr("Priekšskatījums")
235 |
236 | msgid(AUDIONOTIFICATIONS)
237 | msgstr("Ieslēgt zvana signālu")
238 |
--------------------------------------------------------------------------------
/langs/pl.h:
--------------------------------------------------------------------------------
1 | msgid(LANG_NATIVE_NAME)
2 | msgstr("Polski")
3 |
4 | msgid(LANG_ENGLISH_NAME)
5 | msgstr("POLISH")
6 |
7 | msgid(REQ_SENT)
8 | msgstr("Zapytanie zostało wysłane. Znajomy/a pojawi się online kiedy zaakceptuje zapytanie.")
9 |
10 | msgid(REQ_RESOLVE)
11 | msgstr("Próba rozwiązania nazwy DNS...")
12 |
13 | msgid(REQ_INVALID_ID)
14 | msgstr("Błąd: Niepoprawny Tox ID")
15 |
16 | msgid(REQ_EMPTY_ID)
17 | msgstr("Błąd: Nie podano Tox ID")
18 |
19 | msgid(REQ_LONG_MSG)
20 | msgstr("Błąd: Wiadomość jest zbyt długa")
21 |
22 | msgid(REQ_NO_MSG)
23 | msgstr("Błąd: Pusta wiadomość")
24 |
25 | msgid(REQ_SELF_ID)
26 | msgstr("Błąd: Podany Tox ID jest twoim ID")
27 |
28 | msgid(REQ_ALREADY_FRIENDS)
29 | msgstr("Błąd: Podany Tox ID jest już na liście znajomych")
30 |
31 | msgid(REQ_UNKNOWN)
32 | msgstr("Błąd: Nieznany")
33 |
34 | msgid(REQ_BAD_CHECKSUM)
35 | msgstr("Błąd: Niepoprawny Tox ID (zła suma kontrolna)")
36 |
37 | msgid(REQ_BAD_NOSPAM)
38 | msgstr("Błąd: Niepoprawny Tox ID (zła wartość nospam)")
39 |
40 | msgid(REQ_NO_MEMORY)
41 | msgstr("Błąd: Brak pamięci")
42 |
43 | msgid(TRANSFER_NEW)
44 | msgstr("Nowy transfer pliku")
45 |
46 | msgid(TRANSFER_STARTED)
47 | msgstr("Transfer pliku rozpoczęty")
48 |
49 | //TODO: Same as in English? Localize or remove.
50 | //msgid(TRANSFER___)
51 | //msgstr("...")
52 |
53 | msgid(TRANSFER_PAUSED)
54 | msgstr("Transfer pliku wstrzymany")
55 |
56 | msgid(TRANSFER_BROKEN)
57 | msgstr("Transfer pliku nieudany")
58 |
59 | msgid(TRANSFER_CANCELLED)
60 | msgstr("Transfer pliku anulowany")
61 |
62 | msgid(TRANSFER_COMPLETE)
63 | msgstr("Transfer pliku zakończony")
64 |
65 | msgid(CALL_CANCELLED)
66 | msgstr("Rozmowa anulowana")
67 |
68 | msgid(CALL_INVITED)
69 | msgstr("Rozmowa przychodząca")
70 |
71 | msgid(CALL_RINGING)
72 | msgstr("Nawiązywanie połączenia")
73 |
74 | msgid(CALL_STARTED)
75 | msgstr("Rozmowa rozpoczęta")
76 |
77 | msgid(ADDFRIENDS)
78 | msgstr("Dodaj znajomych")
79 |
80 | //TODO: Same as in English? Localize or remove.
81 | //msgid(TOXID)
82 | //msgstr("Tox ID")
83 |
84 | msgid(MESSAGE)
85 | msgstr("Wiadomość")
86 |
87 | msgid(SEARCHFRIENDS)
88 | msgstr("Znajdź znajomych")
89 |
90 | msgid(ADD)
91 | msgstr("Dodaj")
92 |
93 | msgid(SWITCHPROFILE)
94 | msgstr("Zmień profil")
95 |
96 | msgid(FRIENDREQUEST)
97 | msgstr("Zapytanie do znajomych")
98 |
99 | msgid(USERSETTINGS)
100 | msgstr("Ustawienia użytkownika")
101 |
102 | msgid(NAME)
103 | msgstr("Nick")
104 |
105 | msgid(STATUSMESSAGE)
106 | msgstr("Status")
107 |
108 | msgid(PREVIEW)
109 | msgstr("Podgląd")
110 |
111 | msgid(DEVICESELECTION)
112 | msgstr("Wybór urządzenia")
113 |
114 | msgid(AUDIOINPUTDEVICE)
115 | msgstr("Urządzenie wejściowe audio")
116 |
117 | msgid(AUDIOOUTPUTDEVICE)
118 | msgstr("Urządzenie wyjściowe audio")
119 |
120 | msgid(VIDEOINPUTDEVICE)
121 | msgstr("Urządzenie wejściowe wideo")
122 |
123 | msgid(OTHERSETTINGS)
124 | msgstr("Inne ustawienia")
125 |
126 | //TODO: Same as in English? Localize or remove.
127 | //msgid(DPI)
128 | //msgstr("DPI")
129 |
130 | msgid(SAVELOCATION)
131 | msgstr("Lokalizacja dla zapisu danych")
132 |
133 | msgid(LANGUAGE)
134 | msgstr("Język")
135 |
136 | msgid(NETWORK)
137 | msgstr("Sieć")
138 |
139 | //TODO: Same as in English? Localize or remove.
140 | //msgid(IPV6)
141 | //msgstr("IPv6:")
142 |
143 | //TODO: Same as in English? Localize or remove.
144 | //msgid(UDP)
145 | //msgstr("UDP:")
146 |
147 | //TODO: Same as in English? Localize or remove.
148 | //msgid(PROXY)
149 | //msgstr("Proxy (SOCKS 5)")
150 |
151 | msgid(WARNING)
152 | msgstr("Zmiana ustawień sieci/proxy tymczasowo rozłączy cię z siecią Tox")
153 |
154 | msgid(LOGGING)
155 | msgstr("Historia")
156 |
157 | msgid(IS_TYPING)
158 | msgstr("pisze...")
159 |
160 | msgid(COPY)
161 | msgstr("Kopiuj")
162 |
163 | msgid(COPYWITHOUTNAMES)
164 | msgstr("Kopiuj (bez nicków)")
165 |
166 | msgid(CUT)
167 | msgstr("Wytnij")
168 |
169 | msgid(PASTE)
170 | msgstr("Wklej")
171 |
172 | msgid(DELETE)
173 | msgstr("Usuń")
174 |
175 | msgid(SELECTALL)
176 | msgstr("Zaznacz wszystko")
177 |
178 | msgid(REMOVE)
179 | msgstr("Usuń")
180 |
181 | msgid(LEAVE)
182 | msgstr("Opuść")
183 |
184 | msgid(ACCEPT)
185 | msgstr("Zaakceptuj")
186 |
187 | msgid(IGNORE)
188 | msgstr("Ignoruj")
189 |
190 | msgid(CLICKTOSAVE)
191 | msgstr("Przyciśnij by zapisać")
192 |
193 | msgid(CLICKTOOPEN)
194 | msgstr("Przyciśnij by otworzyć")
195 |
196 | msgid(CANCELLED)
197 | msgstr("Anulowano")
198 |
199 | msgid(DPI_TINY)
200 | msgstr("Małe (50%)")
201 |
202 | msgid(DPI_NORMAL)
203 | msgstr("Normalne (100%)")
204 |
205 | msgid(DPI_BIG)
206 | msgstr("Duże (150%)")
207 |
208 | msgid(DPI_LARGE)
209 | msgstr("Wielkie (200%)")
210 |
211 | msgid(DPI_HUGE)
212 | msgstr("Ogromne (250%)")
213 |
214 | msgid(CONTACTS_FILTER_ALL)
215 | msgstr("Wszyscy")
216 |
217 | //TODO: Localize or remove.
218 | //msgid(CONTACTS_FILTER_ONLINE)
219 | //msgstr("Online")
220 |
221 | msgid(PROXY_DISABLED)
222 | msgstr("Wyłączone")
223 |
224 | msgid(PROXY_FALLBACK)
225 | msgstr("Awaryjnie")
226 |
227 | msgid(PROXY_ALWAYS_USE)
228 | msgstr("Zawsze")
229 |
230 | msgid(NO)
231 | msgstr("Nie")
232 |
233 | msgid(YES)
234 | msgstr("Tak")
235 |
236 | msgid(VIDEO_IN_NONE)
237 | msgstr("Brak")
238 |
239 | msgid(VIDEO_IN_DESKTOP)
240 | msgstr("Ekran")
241 |
242 | //TODO: Localize or remove.
243 | //msgid(DEFAULT_FRIEND_REQUEST_MESSAGE)
244 | //msgstr("Please accept this friend request.")
245 |
246 | //TODO: Localize or remove.
247 | //msgid(CONTACTS_FILTER_EDIT_HINT)
248 | //msgstr("Search friends")
249 |
250 | //TODO: Localize or remove.
251 | //msgid(PROXY_EDIT_HINT_IP)
252 | //msgstr("IP")
253 |
254 | //TODO: Localize or remove.
255 | //msgid(PROXY_EDIT_HINT_PORT)
256 | //msgstr("Port")
257 |
258 | //TODO: Localize or remove.
259 | //msgid(AUDIO_IN_DEFAULT_LOOPBACK)
260 | //msgstr("Default Loopback")
261 |
262 | //TODO: Localize or remove.
263 | //msgid(WINDOW_TITLE_VIDEO_PREVIEW)
264 | //msgstr("Video Preview")
265 |
266 | //TODO: Localize or remove.
267 | //msgid(AUDIONOTIFICATIONS)
268 | //msgstr("Enable Audible Notification (Ringtone)")
269 |
--------------------------------------------------------------------------------
/langs/sv.h:
--------------------------------------------------------------------------------
1 | // Återkommande ord:
2 | // Tox ID
3 | // Vän
4 | // Begäran
5 | // Vänlista
6 | // Ogiltigt
7 |
8 | msgid(LANG_NATIVE_NAME)
9 | msgstr("Svenska")
10 |
11 | msgid(LANG_ENGLISH_NAME)
12 | msgstr("Swedish")
13 |
14 | msgid(REQ_SENT)
15 | msgstr("Vänskapsbegäran skickad. Din vän kommer att visas som online efter att din begäran har accepterats.")
16 |
17 | msgid(REQ_RESOLVE)
18 | msgstr("Försöker att avgöra/utgöra information från DNS namnet...")
19 | //msgstr("Attempting to resolve DNS name...")
20 |
21 | msgid(REQ_INVALID_ID)
22 | msgstr("Fel: Ogiltigt Tox ID")
23 |
24 | msgid(REQ_EMPTY_ID)
25 | msgstr("Fel: Inget Tox ID angivet")
26 |
27 | msgid(REQ_LONG_MSG)
28 | msgstr("Fel: Meddelandet är för långt")
29 |
30 | msgid(REQ_NO_MSG)
31 | msgstr("Fel: Tomt meddelande")
32 |
33 | msgid(REQ_SELF_ID)
34 | msgstr("Fel: Du har angett ditt egna Tox ID")
35 |
36 | msgid(REQ_ALREADY_FRIENDS)
37 | msgstr("Fel: Tox ID är redan i din vänlista")
38 |
39 | msgid(REQ_UNKNOWN)
40 | msgstr("Fel: Okänt")
41 |
42 | msgid(REQ_BAD_CHECKSUM)
43 | msgstr("Fel: Ogiltigt Tox ID (inkorrekt checksumma)")
44 |
45 | msgid(REQ_BAD_NOSPAM)
46 | msgstr("Fel: Ogiltigt Tox ID (inkorrekt nospamvärde)")
47 |
48 | msgid(REQ_NO_MEMORY)
49 | msgstr("Fel: Inget minne")
50 |
51 | msgid(TRANSFER_NEW)
52 | msgstr("Ny filöverföring")
53 |
54 | msgid(TRANSFER_STARTED)
55 | msgstr("Filöverföring påbörjad")
56 |
57 | msgid(TRANSFER___)
58 | msgstr("...")
59 |
60 | msgid(TRANSFER_PAUSED)
61 | msgstr("Filöverföring pausad")
62 |
63 | msgid(TRANSFER_BROKEN)
64 | msgstr("Filöverföring trasig")
65 |
66 | msgid(TRANSFER_CANCELLED)
67 | msgstr("Filöverföring avbruten")
68 |
69 | msgid(TRANSFER_COMPLETE)
70 | msgstr("Filöverföring färdig")
71 |
72 | msgid(CALL_CANCELLED)
73 | msgstr("Samtal avbrutet")
74 |
75 | msgid(CALL_INVITED)
76 | //Osäker på avsikten i meddelandet översättningen
77 | //msgstr("Samtalsinbjudan")
78 | msgstr("Inbjuden till samtal")
79 | //msgstr("Call invited")
80 |
81 | msgid(CALL_RINGING)
82 | msgstr("Samtal ringer")
83 |
84 | msgid(CALL_STARTED)
85 | msgstr("Samtal påbörjat")
86 |
87 | msgid(ADDFRIENDS)
88 | msgstr("Lägg till vänner")
89 |
90 | msgid(TOXID)
91 | msgstr("Tox ID")
92 |
93 | msgid(MESSAGE)
94 | msgstr("Meddelande")
95 |
96 | msgid(SEARCHFRIENDS)
97 | msgstr("Sök vänner")
98 |
99 | msgid(ADD)
100 | msgstr("Lägg till")
101 |
102 | msgid(SWITCHPROFILE)
103 | msgstr("Ändra profil")
104 |
105 | msgid(FRIENDREQUEST)
106 | msgstr("Vänskapsinbjudan")
107 |
108 | msgid(USERSETTINGS)
109 | msgstr("Användarinställning")
110 |
111 | msgid(NAME)
112 | msgstr("Namn")
113 |
114 | msgid(STATUSMESSAGE)
115 | msgstr("Tillståndsmeddelande")
116 |
117 | msgid(PREVIEW)
118 | msgstr("Förhandsvisning")
119 |
120 | msgid(DEVICESELECTION)
121 | msgstr("Hårdvaru (Device) val")
122 |
123 | msgid(AUDIOINPUTDEVICE)
124 | msgstr("Ljudingångshårdvara (Input Device)")
125 |
126 | msgid(AUDIOFILTERING)
127 | msgstr("Filtrera ljud")
128 |
129 | msgid(AUDIOOUTPUTDEVICE)
130 | msgstr("Ljudutgångshårdvara (Output Device)")
131 |
132 | msgid(VIDEOINPUTDEVICE)
133 | msgstr("Bildingångshårdvara (Input Device)")
134 |
135 | msgid(OTHERSETTINGS)
136 | msgstr("Andra inställningar")
137 |
138 | msgid(DPI)
139 | msgstr("DPI")
140 |
141 | msgid(SAVELOCATION)
142 | msgstr("Sparplats")
143 |
144 | msgid(LANGUAGE)
145 | msgstr("Språk")
146 |
147 | msgid(NETWORK)
148 | msgstr("Nätverk")
149 |
150 | msgid(IPV6)
151 | msgstr("IPv6:")
152 |
153 | msgid(UDP)
154 | msgstr("UDP:")
155 |
156 | msgid(PROXY)
157 | msgstr("Proxy (SOCKS 5)")
158 |
159 | msgid(WARNING)
160 | msgstr("Om du ändrar Network/Proxy så kommer du att tillfälligt tappa din anslutning till Toxnätverket")
161 |
162 | msgid(LOGGING)
163 | msgstr("Loggning")
164 |
165 | msgid(AUDIONOTIFICATIONS)
166 | msgstr("Aktivera ljudnotifikationer (ringsignal)")
167 |
168 | msgid(IS_TYPING)
169 | msgstr("skriver...")
170 |
171 | msgid(COPY)
172 | msgstr("Kopiera")
173 |
174 | msgid(COPYWITHOUTNAMES)
175 | msgstr("Kopiera (utan namn)")
176 |
177 | msgid(CUT)
178 | msgstr("Klipp")
179 |
180 | msgid(PASTE)
181 | msgstr("Klistra")
182 |
183 | msgid(DELETE)
184 | msgstr("Tabort")
185 |
186 | msgid(SELECTALL)
187 | msgstr("Välj alla")
188 |
189 | msgid(REMOVE)
190 | msgstr("Tabort")
191 |
192 | msgid(LEAVE)
193 | msgstr("Leave")
194 |
195 | msgid(ACCEPT)
196 | msgstr("Tillåt")
197 |
198 | msgid(IGNORE)
199 | msgstr("Ignorera")
200 |
201 | msgid(CLICKTOSAVE)
202 | msgstr("Klicka för att spara")
203 |
204 | msgid(CLICKTOOPEN)
205 | msgstr("Klicka för att öppna")
206 |
207 | msgid(CANCELLED)
208 | msgstr("Avbruten")
209 |
210 | msgid(DPI_TINY)
211 | msgstr("Liten (50%)")
212 |
213 | msgid(DPI_NORMAL)
214 | msgstr("Normal (100%)")
215 |
216 | msgid(DPI_BIG)
217 | msgstr("Stor (150%)")
218 |
219 | msgid(DPI_LARGE)
220 | msgstr("Större (200%)")
221 |
222 | msgid(DPI_HUGE)
223 | msgstr("Enorm (250%)")
224 |
225 | msgid(CONTACTS_FILTER_ALL)
226 | msgstr("Alla")
227 |
228 | msgid(CONTACTS_FILTER_ONLINE)
229 | msgstr("Online")
230 |
231 | msgid(PROXY_DISABLED)
232 | msgstr("Deaktiverad")
233 |
234 | msgid(PROXY_FALLBACK)
235 | msgstr("Fallback")
236 |
237 | msgid(PROXY_ALWAYS_USE)
238 | msgstr("Använd alltid")
239 |
240 | msgid(NO)
241 | msgstr("Nej")
242 |
243 | msgid(YES)
244 | msgstr("Ja")
245 |
246 | msgid(VIDEO_IN_NONE)
247 | msgstr("Inget")
248 |
249 | msgid(VIDEO_IN_DESKTOP)
250 | msgstr("Skrivbord")
251 |
252 | msgid(AUDIO_IN_DEFAULT_LOOPBACK)
253 | msgstr("Standard Loopback")
254 |
255 | msgid(DEFAULT_FRIEND_REQUEST_MESSAGE)
256 | msgstr("Var god och acceptera min vänskapsbegäran.")
257 |
258 | msgid(CONTACTS_FILTER_EDIT_HINT)
259 | msgstr("Sök vänner")
260 |
261 | msgid(PROXY_EDIT_HINT_IP)
262 | msgstr("IP")
263 |
264 | msgid(PROXY_EDIT_HINT_PORT)
265 | msgstr("Port")
266 |
267 | msgid(WINDOW_TITLE_VIDEO_PREVIEW)
268 | msgstr("Videoförhandsgranskning")
269 |
270 | msgid(MUTE)
271 | msgstr("Tysta")
272 |
273 | msgid(UNMUTE)
274 | msgstr("Avtysta")
275 |
276 |
--------------------------------------------------------------------------------
/langs/tw.h:
--------------------------------------------------------------------------------
1 | msgid(LANG_NATIVE_NAME)
2 | msgstr("繁體中文")
3 |
4 | msgid(LANG_ENGLISH_NAME)
5 | msgstr("TRADITIONAL CHINESE")
6 |
7 | msgid(REQ_SENT)
8 | msgstr("添加好友請求已發送。當對方接受請求後將在好友列表中在線。")
9 |
10 | msgid(REQ_RESOLVE)
11 | msgstr("嘗試解析DNS名......")
12 |
13 | msgid(REQ_INVALID_ID)
14 | msgstr("錯誤: 無效的 Tox ID")
15 |
16 | msgid(REQ_EMPTY_ID)
17 | msgstr("錯誤: 沒有指定Tox ID")
18 |
19 | msgid(REQ_LONG_MSG)
20 | msgstr("錯誤: 消息太長")
21 |
22 | msgid(REQ_NO_MSG)
23 | msgstr("錯誤: 空消息")
24 |
25 | msgid(REQ_SELF_ID)
26 | msgstr("錯誤: Tox ID 是你自己的 ID")
27 |
28 | msgid(REQ_ALREADY_FRIENDS)
29 | msgstr("錯誤: Tox ID 已在好友列表中了")
30 |
31 | msgid(REQ_UNKNOWN)
32 | msgstr("錯誤: 未知")
33 |
34 | msgid(REQ_BAD_CHECKSUM)
35 | msgstr("錯誤: 無效的 Tox ID (錯誤的校驗和)")
36 |
37 | msgid(REQ_BAD_NOSPAM)
38 | msgstr("錯誤: 無效的 Tox ID (錯誤的nospam值)")
39 |
40 | msgid(REQ_NO_MEMORY)
41 | msgstr("錯誤: 沒內存了")
42 |
43 | msgid(TRANSFER_NEW)
44 | msgstr("新建文件傳輸任務")
45 |
46 | msgid(TRANSFER_STARTED)
47 | msgstr("文件傳輸開始")
48 |
49 | //TODO: Same as in English? Localize or remove.
50 | //msgid(TRANSFER___)
51 | //msgstr("...")
52 |
53 | msgid(TRANSFER_PAUSED)
54 | msgstr("文件傳輸暫停")
55 |
56 | msgid(TRANSFER_BROKEN)
57 | msgstr("文件傳輸中斷")
58 |
59 | msgid(TRANSFER_CANCELLED)
60 | msgstr("文件傳輸取消")
61 |
62 | msgid(TRANSFER_COMPLETE)
63 | msgstr("文件傳輸完成")
64 |
65 | msgid(CALL_CANCELLED)
66 | msgstr("呼叫取消")
67 |
68 | msgid(CALL_INVITED)
69 | msgstr("呼叫邀請")
70 |
71 | msgid(CALL_RINGING)
72 | msgstr("呼叫振鈴")
73 |
74 | msgid(CALL_STARTED)
75 | msgstr("呼叫開始")
76 |
77 | msgid(ADDFRIENDS)
78 | msgstr("添加好友")
79 |
80 | //TODO: Same as in English? Localize or remove.
81 | //msgid(TOXID)
82 | //msgstr("Tox ID")
83 |
84 | msgid(MESSAGE)
85 | msgstr("消息")
86 |
87 | msgid(SEARCHFRIENDS)
88 | msgstr("搜索好友")
89 |
90 | msgid(ADD)
91 | msgstr("添加")
92 |
93 | msgid(SWITCHPROFILE)
94 | msgstr("切換設置")
95 |
96 | msgid(FRIENDREQUEST)
97 | msgstr("好友呼叫")
98 |
99 | msgid(USERSETTINGS)
100 | msgstr("用戶設置")
101 |
102 | msgid(NAME)
103 | msgstr("名字")
104 |
105 | msgid(STATUSMESSAGE)
106 | msgstr("狀態消息(簽名)")
107 |
108 | msgid(PREVIEW)
109 | msgstr("預覽")
110 |
111 | msgid(DEVICESELECTION)
112 | msgstr("設備選擇")
113 |
114 | msgid(AUDIOINPUTDEVICE)
115 | msgstr("音頻輸入設備")
116 |
117 | msgid(AUDIOOUTPUTDEVICE)
118 | msgstr("音頻輸出設備")
119 |
120 | msgid(VIDEOINPUTDEVICE)
121 | msgstr("視頻輸入設備")
122 |
123 | msgid(OTHERSETTINGS)
124 | msgstr("其他設置")
125 |
126 | //TODO: Same as in English? Localize or remove.
127 | //msgid(DPI)
128 | //msgstr("DPI")
129 |
130 | //TODO: Same as in English? Localize or remove.
131 | //msgid(SAVELOCATION)
132 | //msgstr("Save Location")
133 |
134 | msgid(LANGUAGE)
135 | msgstr("語言")
136 |
137 | msgid(NETWORK)
138 | msgstr("網絡")
139 |
140 | //TODO: Same as in English? Localize or remove.
141 | //msgid(IPV6)
142 | //msgstr("IPv6:")
143 |
144 | //TODO: Same as in English? Localize or remove.
145 | //msgid(UDP)
146 | //msgstr("UDP:")
147 |
148 | msgid(PROXY)
149 | msgstr("代理 (SOCKS 5)")
150 |
151 | msgid(WARNING)
152 | msgstr("修改網絡或代理設置將會斷開tox網絡連接")
153 |
154 | //TODO: Same as in English? Localize or remove.
155 | //msgid(LOGGING)
156 | //msgstr("Logging")
157 |
158 | //TODO: Same as in English? Localize or remove.
159 | //msgid(IS_TYPING)
160 | //msgstr("is typing...")
161 |
162 | msgid(COPY)
163 | msgstr("複制")
164 |
165 | msgid(COPYWITHOUTNAMES)
166 | msgstr("複制 (不帶名字)")
167 |
168 | msgid(CUT)
169 | msgstr("剪切")
170 |
171 | msgid(PASTE)
172 | msgstr("粘貼")
173 |
174 | msgid(DELETE)
175 | msgstr("刪除")
176 |
177 | msgid(SELECTALL)
178 | msgstr("全選")
179 |
180 | msgid(REMOVE)
181 | msgstr("刪除")
182 |
183 | msgid(LEAVE)
184 | msgstr("離開")
185 |
186 | msgid(ACCEPT)
187 | msgstr("接受")
188 |
189 | msgid(IGNORE)
190 | msgstr("忽略")
191 |
192 | msgid(CLICKTOSAVE)
193 | msgstr("點擊保存")
194 |
195 | msgid(CLICKTOOPEN)
196 | msgstr("點擊打開")
197 |
198 | msgid(CANCELLED)
199 | msgstr("取消")
200 |
201 | //TODO: Localize or remove.
202 | //msgid(DPI_TINY)
203 | //msgstr("Tiny (50%)")
204 |
205 | //TODO: Localize or remove.
206 | //msgid(DPI_NORMAL)
207 | //msgstr("Normal (100%)")
208 |
209 | //TODO: Localize or remove.
210 | //msgid(DPI_BIG)
211 | //msgstr("Big (150%)")
212 |
213 | //TODO: Localize or remove.
214 | //msgid(DPI_LARGE)
215 | //msgstr("Large (200%)")
216 |
217 | //TODO: Localize or remove.
218 | //msgid(DPI_HUGE)
219 | //msgstr("Huge (250%)")
220 |
221 | //TODO: Localize or remove.
222 | //msgid(CONTACTS_FILTER_ALL)
223 | //msgstr("All")
224 |
225 | //TODO: Localize or remove.
226 | //msgid(CONTACTS_FILTER_ONLINE)
227 | //msgstr("Online")
228 |
229 | //TODO: Localize or remove.
230 | //msgid(PROXY_DISABLED)
231 | //msgstr("Disabled")
232 |
233 | //TODO: Localize or remove.
234 | //msgid(PROXY_FALLBACK)
235 | //msgstr("Fallback")
236 |
237 | //TODO: Localize or remove.
238 | //msgid(PROXY_ALWAYS_USE)
239 | //msgstr("Always use")
240 |
241 | //TODO: Localize or remove.
242 | //msgid(NO)
243 | //msgstr("No")
244 |
245 | //TODO: Localize or remove.
246 | //msgid(YES)
247 | //msgstr("Yes")
248 |
249 | //TODO: Localize or remove.
250 | //msgid(VIDEO_IN_NONE)
251 | //msgstr("None")
252 |
253 | //TODO: Localize or remove.
254 | //msgid(VIDEO_IN_DESKTOP)
255 | //msgstr("Desktop")
256 |
257 | //TODO: Localize or remove.
258 | //msgid(DEFAULT_FRIEND_REQUEST_MESSAGE)
259 | //msgstr("Please accept this friend request.")
260 |
261 | //TODO: Localize or remove.
262 | //msgid(CONTACTS_FILTER_EDIT_HINT)
263 | //msgstr("Search friends")
264 |
265 | //TODO: Localize or remove.
266 | //msgid(PROXY_EDIT_HINT_IP)
267 | //msgstr("IP")
268 |
269 | //TODO: Localize or remove.
270 | //msgid(PROXY_EDIT_HINT_PORT)
271 | //msgstr("Port")
272 |
273 | //TODO: Localize or remove.
274 | //msgid(AUDIO_IN_DEFAULT_LOOPBACK)
275 | //msgstr("Default Loopback")
276 |
277 | //TODO: Localize or remove.
278 | //msgid(WINDOW_TITLE_VIDEO_PREVIEW)
279 | //msgstr("Video Preview")
280 |
281 | //TODO: Localize or remove.
282 | //msgid(AUDIONOTIFICATIONS)
283 | //msgstr("Enable Audible Notification (Ringtone)")
284 |
--------------------------------------------------------------------------------
/list.h:
--------------------------------------------------------------------------------
1 | /* list: the contact list
2 | */
3 |
4 |
5 | /* non-exhaustive list of panels we to select from, it's probably better to replace this but I don't know with what. */
6 | enum
7 | {
8 | ITEM_NONE,
9 | ITEM_ADD,
10 | ITEM_SETTINGS,
11 | ITEM_TRANSFER,
12 | ITEM_FRIEND,
13 | ITEM_GROUP,
14 | ITEM_FRIEND_ADD,
15 | };
16 |
17 | typedef struct
18 | {
19 | uint8_t item;
20 | char namestr[15];
21 | void *data;
22 | }ITEM;
23 |
24 | extern ITEM *selected_item;
25 | ITEM *ritem;
26 |
27 | void list_start(void);
28 | void list_addfriend(FRIEND *f);
29 | void list_addfriend2(FRIEND *f, FRIENDREQ *req);
30 | void list_addgroup(GROUPCHAT *g);
31 | void list_addfriendreq(FRIENDREQ *f);
32 | void list_deletesitem(void);
33 | void list_deleteritem(void);
34 |
35 | void list_selectchat(int index);
36 | void list_selectaddfriend(void);
37 | void list_reselect_current(void);
38 | void list_selectsettings(void);
39 | void list_selectswap(void);
40 |
41 | void list_scale(void);
42 |
43 | void list_draw(void *n, int x, int y, int width, int height);
44 | void list_freeall(void);
45 |
46 | _Bool list_mmove(void *n, int x, int y, int width, int height, int mx, int my, int dx, int dy);
47 | _Bool list_mdown(void *n);
48 | _Bool list_mright(void *n);
49 | _Bool list_mwheel(void *n, int height, double d);
50 | _Bool list_mup(void *n);
51 | _Bool list_mleave(void *n);
52 |
--------------------------------------------------------------------------------
/main.c:
--------------------------------------------------------------------------------
1 | #include "main.h"
2 |
3 | /** Change source of main.c if windows or android
4 | * else default to xlib
5 | **/
6 | #ifdef __WIN32__
7 | #include "windows/main.c"
8 | #else
9 | #ifdef __ANDROID__
10 | #include "android/main.c"
11 | #else
12 | #ifdef __OBJC__
13 | // #include "cocoa/main.m"
14 | #else
15 | #include "xlib/main.c"
16 | #endif
17 | #endif
18 | #endif
19 |
--------------------------------------------------------------------------------
/messages.h:
--------------------------------------------------------------------------------
1 |
2 | //Type for indexing into MSG_DATA->data array of messages
3 | typedef uint32_t MSG_IDX;
4 | #define MSG_IDX_MAX (UINT32_MAX)
5 |
6 | typedef struct
7 | {
8 | uint32_t width, height;
9 |
10 | // Tox friendnumber/groupnumber
11 | uint32_t id;
12 |
13 | // Number of messages in data array.
14 | MSG_IDX n;
15 |
16 | // Indices of messages in data array, where text selection starts and ends.
17 | MSG_IDX istart, iend;
18 | // Indices in strings of corresponding messages, where selection starts/ends.
19 | STRING_IDX start, end;
20 |
21 | // Pointers at various message structs, at most MAX_BACKLOG_MESSAGES.
22 | void **data;
23 |
24 | // Field for preserving position of text scroll,
25 | // while this MSG_DATA is inactive.
26 | double scroll;
27 | } MSG_DATA;
28 |
29 | struct messages {
30 | PANEL panel;
31 |
32 | // false for Friendchat, true for Groupchat.
33 | _Bool type;
34 |
35 | // true if we're in the middle of selection operation
36 | // (mousedown without mouseup yet).
37 | _Bool select;
38 |
39 | // Position and length of an URL in the message under the mouse,
40 | // if present. urlover == STRING_IDX_MAX if there's none.
41 | STRING_IDX urlover, urllen;
42 |
43 | // Was the url pressed by the mouse.
44 | _Bool urlmdown;
45 |
46 | uint32_t height, width;
47 |
48 | // Indices of messages, that the mouse is over now/has been
49 | // pressed mousedown over. MSG_IDX_MAX, when the mouse isn't over
50 | // any message/when not in selection mode.
51 | MSG_IDX iover, idown;
52 | // For text messages encodes indices of chars in strings.
53 | // For non-text messages, encodes various logical parts of them.
54 |
55 | // over in file transfers (iover == 1):
56 | // 0 == not hovered
57 | // 1 == hover on the upper transfer button
58 | // 2 == hover on the lower transfer button
59 | // 3 == hover on the rest of the transfer box
60 | uint32_t over, down;
61 |
62 | MSG_DATA *data;
63 | };
64 |
65 | enum {
66 | MSG_TYPE_TEXT,
67 | MSG_TYPE_ACTION_TEXT,
68 | MSG_TYPE_IMAGE,
69 | MSG_TYPE_FILE,
70 | };
71 |
72 | typedef struct {
73 | // true, if we're the author, false, if someone else.
74 | _Bool author;
75 | uint8_t msg_type;
76 |
77 | uint32_t height;
78 | uint32_t time;
79 |
80 | STRING_IDX length;
81 | char_t msg[0];
82 | } MESSAGE;
83 |
84 | typedef struct {
85 | // true, if we're the author, false, if someone else.
86 | _Bool author;
87 | uint8_t msg_type;
88 |
89 | uint32_t height;
90 | uint32_t time;
91 |
92 | uint16_t w, h;
93 | _Bool zoom;
94 | double position;
95 | UTOX_NATIVE_IMAGE *image;
96 | } MSG_IMG;
97 |
98 | typedef struct msg_file {
99 | // true, if we're the author, false, if someone else.
100 | _Bool author;
101 | uint8_t msg_type;
102 |
103 | uint32_t height;
104 | uint32_t time;
105 |
106 | uint32_t speed;
107 | uint32_t filenumber;
108 | uint8_t status, name_length;
109 | uint64_t size, progress;
110 | _Bool inline_png;
111 | uint8_t *path;
112 | uint8_t name[64];
113 | } MSG_FILE;
114 |
115 | struct FILE_TRANSFER;
116 |
117 | /* Called externally to add a message to the queue */
118 | MSG_FILE* message_add_type_file(struct FILE_TRANSFER *file);
119 |
120 | void messages_draw(MESSAGES *m, int x, int y, int width, int height);
121 | _Bool messages_mmove(MESSAGES *m, int x, int y, int width, int height, int mx, int my, int dx, int dy);
122 | _Bool messages_mdown(MESSAGES *m);
123 | _Bool messages_dclick(MESSAGES *m, _Bool triclick);
124 | _Bool messages_mright(MESSAGES *m);
125 | _Bool messages_mwheel(MESSAGES *m, int height, double d);
126 | _Bool messages_mup(MESSAGES *m);
127 | _Bool messages_mleave(MESSAGES *m);
128 |
129 | int messages_selection(MESSAGES *m, void *data, uint32_t len, _Bool names);
130 |
131 | _Bool messages_char(uint32_t ch);
132 |
133 | void messages_updateheight(MESSAGES *m);
134 | void message_updateheight(MESSAGES *m, MESSAGE *msg, MSG_DATA *p);
135 | void message_add(MESSAGES *m, MESSAGE *msg, MSG_DATA *p);
136 | void message_clear(MESSAGES *m, MSG_DATA *p);
137 |
138 | void message_free(MESSAGE *msg);
139 |
--------------------------------------------------------------------------------
/scrollable.c:
--------------------------------------------------------------------------------
1 | #include "main.h"
2 |
3 | void scroll_draw(SCROLLABLE *s, int x, int y, int width, int height)
4 | {
5 | uint32_t c = s->content_height;
6 | uint32_t h = height, m, dy;
7 |
8 | if(h >= c) {
9 | // If h(eight) > c(ontent height), don't draw anything.
10 | return;
11 | } else {
12 | m = (h * h) / c;
13 | double d = (h - m);
14 | dy = (s->d * d) + 0.5;
15 | }
16 |
17 | y += dy;
18 | x += s->x;
19 |
20 | if(!s->left) {
21 | x += width - SCROLL_WIDTH;
22 | }
23 |
24 | drawalpha(BM_SCROLLHALFTOP, x, y, SCROLL_WIDTH, SCROLL_WIDTH / 2, s->color);
25 |
26 | y += SCROLL_WIDTH / 2;
27 | int y2 = y + m - SCROLL_WIDTH;
28 | if(SCROLL_WIDTH > m) {
29 | y2 = y;
30 | }
31 | drawrect(x, y, x + SCROLL_WIDTH, y2, s->color);
32 |
33 | drawalpha(BM_SCROLLHALFBOT, x, y2, SCROLL_WIDTH, SCROLL_WIDTH / 2, s->color);
34 | }
35 |
36 | int scroll_gety(SCROLLABLE *s, int height)
37 | {
38 | int c = s->content_height;
39 |
40 | if(c > height)
41 | {
42 | return (s->d * (double)(c - height)) + 0.5;
43 | }
44 |
45 | return 0;
46 | }
47 |
48 | _Bool scroll_mmove(SCROLLABLE *s, int UNUSED(px), int UNUSED(py), int width, int height, int x, int y, int UNUSED(dx), int dy)
49 | {
50 | _Bool draw = 0;
51 |
52 | _Bool hit = inrect(x, y, s->left ? 0 : (width - SCROLL_WIDTH), 0, SCROLL_WIDTH, height);
53 | if(s->mouseover != hit)
54 | {
55 | s->mouseover = hit;
56 | draw = 1;
57 | }
58 |
59 | s->mouseover2 = inrect(x, y, 0, 0, width, height);
60 |
61 | if(s->mousedown)
62 | {
63 | uint32_t c = s->content_height;
64 | uint32_t h = height;
65 |
66 | if(c > h)
67 | {
68 | uint32_t m = (h * h) / c;
69 | double d = (h - m);
70 |
71 | s->d = ((s->d * d) + (double)dy) / d;
72 |
73 | if(s->d < 0.0)
74 | {
75 | s->d = 0.0;
76 | }
77 | else if(s->d >= 1.0)
78 | {
79 | s->d = 1.0;
80 | }
81 |
82 | draw = 1;
83 | }
84 | }
85 |
86 | return draw;
87 | }
88 |
89 | _Bool scroll_mdown(SCROLLABLE *s)
90 | {
91 | if(s->mouseover)
92 | {
93 | s->mousedown = 1;
94 | return 1;
95 | }
96 |
97 | return 0;
98 | }
99 |
100 | _Bool scroll_mright(SCROLLABLE *UNUSED(s))
101 | {
102 | return 0;
103 | }
104 |
105 | _Bool scroll_mwheel(SCROLLABLE *s, int height, double d)
106 | {
107 | if(s->mouseover2)
108 | {
109 | uint32_t c = s->content_height;
110 | uint32_t h = height;
111 |
112 | if(c > h)
113 | {
114 | uint32_t m = (h * h) / c;
115 | double dd = (h - m);
116 |
117 | s->d -= 16.0 * d / dd;;
118 |
119 | if(s->d < 0.0)
120 | {
121 | s->d = 0.0;
122 | }
123 | else if(s->d >= 1.0)
124 | {
125 | s->d = 1.0;
126 | }
127 |
128 | return 1;
129 | }
130 | }
131 |
132 | return 0;
133 | }
134 |
135 | _Bool scroll_mup(SCROLLABLE *s)
136 | {
137 | if(s->mousedown)
138 | {
139 | s->mousedown = 0;
140 | return 1;
141 | }
142 |
143 | return 0;
144 | }
145 |
146 | _Bool scroll_mleave(SCROLLABLE *s)
147 | {
148 | if(s->mouseover)
149 | {
150 | s->mouseover = 0;
151 | return 1;
152 | }
153 |
154 | s->mouseover2 = 0;
155 |
156 | return 0;
157 | }
158 |
--------------------------------------------------------------------------------
/scrollable.h:
--------------------------------------------------------------------------------
1 |
2 | struct scrollable
3 | {
4 | PANEL panel;
5 |
6 | uint32_t color;
7 | int x;
8 |
9 | double d;
10 | _Bool left, mousedown, mouseover, mouseover2;
11 | int content_height;
12 | };
13 |
14 | void scroll_draw(SCROLLABLE *s, int x, int y, int width, int height);
15 | int scroll_gety(SCROLLABLE *s, int height);
16 |
17 | _Bool scroll_mmove(SCROLLABLE *s, int x, int y, int width, int height, int mx, int my, int dx, int dy);
18 | _Bool scroll_mdown(SCROLLABLE *s);
19 | _Bool scroll_mright(SCROLLABLE *s);
20 | _Bool scroll_mwheel(SCROLLABLE *s, int height, double d);
21 | _Bool scroll_mup(SCROLLABLE *s);
22 | _Bool scroll_mleave(SCROLLABLE *s);
23 |
--------------------------------------------------------------------------------
/shared/freetype-text.c:
--------------------------------------------------------------------------------
1 |
2 | void drawtext(int x, int y, char_t *str, STRING_IDX length)
3 | {
4 | _drawtext(x, INT_MAX, y, str, length);
5 | }
6 |
7 | int drawtext_getwidth(int x, int y, char_t *str, STRING_IDX length)
8 | {
9 | return _drawtext(x, INT_MAX, y, str, length) - x;
10 | }
11 |
12 | void drawtextrange(int x, int xmax, int y, char_t *str, STRING_IDX length)
13 | {
14 | x = _drawtext(x, xmax, y, str, length);
15 | if(x < 0) {
16 | _drawtext(-x, INT_MAX, y, (char_t*)"...", 3);
17 | }
18 | }
19 |
20 | void drawtextwidth(int x, int width, int y, char_t *str, STRING_IDX length)
21 | {
22 | drawtextrange(x, x + width, y, str, length);
23 | }
24 |
25 | void drawtextwidth_right(int x, int width, int y, char_t *str, STRING_IDX length)
26 | {
27 | int w = textwidth(str, length);
28 | if (w < width) {
29 | drawtext(x + width - w, y, str, length);
30 | } else {
31 | drawtextrange(x, x + width, y, str, length);
32 | }
33 | }
34 |
35 | int textwidth(char_t *str, STRING_IDX length)
36 | {
37 | GLYPH *g;
38 | uint8_t len;
39 | uint32_t ch;
40 | int x = 0;
41 | while(length) {
42 | len = utf8_len_read(str, &ch);
43 | str += len;
44 | length -= len;
45 |
46 | g = font_getglyph(sfont, ch);
47 | if(g) {
48 | x += g->xadvance;
49 | }
50 | }
51 | return x;
52 | }
53 |
54 | int textfit(char_t *str, STRING_IDX length, int width)
55 | {
56 | GLYPH *g;
57 | uint8_t len;
58 | uint32_t ch;
59 | int x = 0;
60 |
61 | STRING_IDX i = 0;
62 | while(i != length) {
63 | len = utf8_len_read(str, &ch);
64 | str += len;
65 |
66 | g = font_getglyph(sfont, ch);
67 | if(g) {
68 | x += g->xadvance;
69 | if(x > width) {
70 | return i;
71 | }
72 | }
73 |
74 | i += len;
75 | }
76 |
77 | return length;
78 | }
79 |
80 | int textfit_near(char_t *str, STRING_IDX length, int width)
81 | {
82 | GLYPH *g;
83 | uint8_t len;
84 | uint32_t ch;
85 | int x = 0;
86 |
87 | STRING_IDX i = 0;
88 | while(i != length) {
89 | len = utf8_len_read(str, &ch);
90 | str += len;
91 |
92 | g = font_getglyph(sfont, ch);
93 | if(g) {
94 | x += g->xadvance;
95 | if(x > width) {
96 | return i;
97 | }
98 | }
99 |
100 | i += len;
101 | }
102 |
103 | return length;
104 | }
105 |
106 | void setfont(int id)
107 | {
108 | sfont = &font[id];
109 | }
110 |
111 |
--------------------------------------------------------------------------------
/sized_string.h:
--------------------------------------------------------------------------------
1 |
2 | typedef uint8_t char_t;
3 | // Unsigned integer type for string indices and sizes.
4 | typedef uint16_t STRING_IDX;
5 | #define STRING_IDX_MAX (UINT16_MAX)
6 |
7 | typedef struct {
8 | char_t *str;
9 | STRING_IDX length;
10 | } STRING;
11 |
12 | #define STRING_INIT(x) { .str = (char_t*)x, .length = sizeof(x) - 1 }
13 |
--------------------------------------------------------------------------------
/svg.h:
--------------------------------------------------------------------------------
1 |
2 | #define BM_SCROLLHALF_WIDTH SCROLL_WIDTH
3 | #define BM_SCROLLHALF_HEIGHT (SCROLL_WIDTH / 2)
4 |
5 | #define BM_STATUSAREA_WIDTH (10 * SCALE)
6 | #define BM_STATUSAREA_HEIGHT (20 * SCALE)
7 |
8 | #define _BM_ADD_WIDTH 9
9 | #define BM_ADD_WIDTH (9 * SCALE)
10 | #define BM_STATUS_WIDTH (5 * SCALE)
11 | #define BM_STATUS_NOTIFY_WIDTH (7 * SCALE)
12 | #define BM_NMSG_WIDTH (9 * SCALE)
13 |
14 | #define BM_LBUTTON_WIDTH (26 * SCALE)
15 | #define BM_LBUTTON_HEIGHT (20 * SCALE)
16 |
17 | #define BM_SBUTTON_WIDTH (26 * SCALE)
18 | #define BM_SBUTTON_HEIGHT (10 * SCALE)
19 |
20 | #define BM_FT_WIDTH (125 * SCALE)
21 | #define BM_FT_HEIGHT (26 * SCALE)
22 |
23 | #define BM_FTM_WIDTH (113 * SCALE)
24 |
25 | #define BM_FTB_WIDTH (11 * SCALE)
26 | #define BM_FTB_HEIGHT (12 * SCALE)
27 |
28 | #define BM_CONTACT_WIDTH (20 * SCALE)
29 |
30 | #define _BM_LBICON_WIDTH 11
31 | #define BM_LBICON_WIDTH (11 * SCALE)
32 | #define _BM_LBICON_HEIGHT 10
33 | #define BM_LBICON_HEIGHT (10 * SCALE)
34 |
35 | #define BM_FB_WIDTH (6 * SCALE)
36 | #define BM_FB_HEIGHT (5 * SCALE)
37 |
38 | /* Chat button placements */
39 | #define BM_CHAT_BUTTON_WIDTH (15 * SCALE)
40 | #define BM_CHAT_BUTTON_HEIGHT (15 * SCALE)
41 | #define BM_CHAT_SEND_WIDTH (32 * SCALE)
42 | #define BM_CHAT_SEND_HEIGHT (32 * SCALE)
43 | #define _BM_CHAT_SEND_OVERLAY_WIDTH 20
44 | #define BM_CHAT_SEND_OVERLAY_HEIGHT (20 * SCALE)
45 | #define BM_CHAT_SEND_OVERLAY_WIDTH (20 * SCALE)
46 |
47 | #define _BM_CHAT_WIDTH 10
48 | #define BM_CHAT_WIDTH (10 * SCALE)
49 |
50 | #define _BM_CI_WIDTH 10
51 | #define BM_CI_WIDTH (10 * SCALE)
52 |
53 | void *svg_data;
54 |
55 | _Bool svg_draw(_Bool needmemory);
56 |
--------------------------------------------------------------------------------
/text.h:
--------------------------------------------------------------------------------
1 |
2 | int drawtextmultiline(int x, int right, int y, int top, int bottom, uint16_t lineheight, char_t *data, STRING_IDX length, STRING_IDX h, STRING_IDX hlen, STRING_IDX mark, STRING_IDX marklen, _Bool multiline);
3 | STRING_IDX hittextmultiline(int mx, int right, int my, int height, uint16_t lineheight, char_t *str, STRING_IDX length, _Bool multiline);
4 | int text_height(int right, uint16_t lineheight, char_t *str, STRING_IDX length);
5 |
6 | STRING_IDX text_lineup(int width, int height, STRING_IDX p, uint16_t lineheight, char_t *str, STRING_IDX length, SCROLLABLE *scroll);
7 | STRING_IDX text_linedown(int width, int height, STRING_IDX p, uint16_t lineheight, char_t *str, STRING_IDX length, SCROLLABLE *scroll);
8 |
--------------------------------------------------------------------------------
/theme.h:
--------------------------------------------------------------------------------
1 | enum {
2 | THEME_DEFAULT,
3 | THEME_LIGHT,
4 | THEME_DARK,
5 | THEME_HIGHCONTRAST,
6 | THEME_CUSTOM,
7 | THEME_ZENBURN, // !!!!
8 | // @TODO
9 | // THEME_XRESOURCE
10 | };
11 |
12 | uint32_t COLOR_MAIN_BACKGROUND;
13 | uint32_t COLOR_MAIN_TEXT;
14 | uint32_t COLOR_MAIN_CHATTEXT;
15 | uint32_t COLOR_MAIN_SUBTEXT;
16 | uint32_t COLOR_MAIN_ACTIONTEXT;
17 | uint32_t COLOR_MAIN_QUOTETEXT;
18 | uint32_t COLOR_MAIN_URLTEXT;
19 | uint32_t COLOR_MAIN_HINTTEXT;
20 | uint32_t COLOR_MENU_BACKGROUND;
21 | uint32_t COLOR_MENU_TEXT;
22 | uint32_t COLOR_MENU_SUBTEXT;
23 | uint32_t COLOR_MENU_HOVER_BACKGROUND;
24 | uint32_t COLOR_MENU_ACTIVE_BACKGROUND;
25 | uint32_t COLOR_MENU_ACTIVE_TEXT;
26 | uint32_t COLOR_LIST_BACKGROUND;
27 | uint32_t COLOR_LIST_HOVER_BACKGROUND;
28 | uint32_t COLOR_LIST_TEXT;
29 | uint32_t COLOR_LIST_SUBTEXT;
30 | uint32_t COLOR_AUX_BACKGROUND;
31 | uint32_t COLOR_AUX_EDGE_NORMAL;
32 | uint32_t COLOR_AUX_EDGE_HOVER;
33 | uint32_t COLOR_AUX_EDGE_ACTIVE;
34 | uint32_t COLOR_AUX_TEXT;
35 | uint32_t COLOR_AUX_ACTIVEOPTION_BACKGROUND;
36 | uint32_t COLOR_AUX_ACTIVEOPTION_TEXT;
37 | uint32_t COLOR_GROUP_SELF;
38 | uint32_t COLOR_GROUP_PEER;
39 | uint32_t COLOR_GROUP_AUDIO;
40 | uint32_t COLOR_GROUP_MUTED;
41 | uint32_t COLOR_SELECTION_BACKGROUND;
42 | uint32_t COLOR_SELECTION_TEXT;
43 | uint32_t COLOR_EDGE_NORMAL;
44 | uint32_t COLOR_EDGE_ACTIVE;
45 | uint32_t COLOR_EDGE_HOVER;
46 | uint32_t COLOR_ACTIVEOPTION_BACKGROUND;
47 | uint32_t COLOR_ACTIVEOPTION_TEXT;
48 | uint32_t COLOR_STATUS_ONLINE;
49 | uint32_t COLOR_STATUS_AWAY;
50 | uint32_t COLOR_STATUS_BUSY;
51 | uint32_t COLOR_BUTTON_SUCCESS_BACKGROUND;
52 | uint32_t COLOR_BUTTON_SUCCESS_TEXT;
53 | uint32_t COLOR_BUTTON_SUCCESS_HOVER_BACKGROUND;
54 | uint32_t COLOR_BUTTON_SUCCESS_HOVER_TEXT;
55 | uint32_t COLOR_BUTTON_WARNING_BACKGROUND;
56 | uint32_t COLOR_BUTTON_WARNING_TEXT;
57 | uint32_t COLOR_BUTTON_WARNING_HOVER_BACKGROUND;
58 | uint32_t COLOR_BUTTON_WARNING_HOVER_TEXT;
59 | uint32_t COLOR_BUTTON_DANGER_BACKGROUND;
60 | uint32_t COLOR_BUTTON_DANGER_TEXT;
61 | uint32_t COLOR_BUTTON_DANGER_HOVER_BACKGROUND;
62 | uint32_t COLOR_BUTTON_DANGER_HOVER_TEXT;
63 | uint32_t COLOR_BUTTON_DISABLED_BACKGROUND;
64 | uint32_t COLOR_BUTTON_DISABLED_TEXT;
65 | uint32_t COLOR_BUTTON_DISABLED_HOVER_BACKGROUND;
66 | uint32_t COLOR_BUTTON_DISABLED_TRANSFER;
67 | uint32_t COLOR_BUTTON_INPROGRESS_BACKGROUND;
68 | uint32_t COLOR_BUTTON_INPROGRESS_TEXT;
69 |
70 | void theme_load(char loadtheme);
71 | void read_custom_theme(const char *path);
72 |
73 | uint32_t status_color[4];
74 |
75 | uint32_t theme;
76 |
77 | extern const char *COLOUR_NAME_TABLE[];
78 | extern uint32_t *COLOUR_POINTER_TABLE[];
79 |
--------------------------------------------------------------------------------
/theme_tables.h:
--------------------------------------------------------------------------------
1 | const char *COLOUR_NAME_TABLE[] = {
2 | "MAIN_BACKGROUND",
3 | "MAIN_TEXT",
4 | "MAIN_CHATTEXT",
5 | "MAIN_SUBTEXT",
6 | "MAIN_ACTIONTEXT",
7 | "MAIN_QUOTETEXT",
8 | "MAIN_URLTEXT",
9 | "MAIN_HINTTEXT",
10 |
11 | "MENU_BACKGROUND",
12 | "MENU_TEXT",
13 | "MENU_SUBTEXT",
14 | "MENU_HOVER_BACKGROUND",
15 | "MENU_ACTIVE_BACKGROUND",
16 | "MENU_ACTIVE_TEXT",
17 |
18 | "LIST_BACKGROUND",
19 | "LIST_HOVER_BACKGROUND",
20 | "LIST_TEXT",
21 | "LIST_SUBTEXT",
22 |
23 | "GROUP_SELF",
24 | "GROUP_PEER",
25 | "GROUP_AUDIO",
26 | "GROUP_MUTED",
27 |
28 | "SELECTION_BACKGROUND",
29 | "SELECTION_TEXT",
30 |
31 | "EDGE_NORMAL",
32 | "EDGE_HOVER",
33 | "EDGE_ACTIVE",
34 | "ACTIVEOPTION_BACKGROUND",
35 | "ACTIVEOPTION_TEXT",
36 |
37 | "AUX_BACKGROUND",
38 | "AUX_EDGE_NORMAL",
39 | "AUX_EDGE_HOVER",
40 | "AUX_EDGE_ACTIVE",
41 | "AUX_TEXT",
42 | "AUX_ACTIVEOPTION_BACKGROUND",
43 | "AUX_ACTIVEOPTION_TEXT",
44 |
45 | "STATUS_ONLINE",
46 | "STATUS_AWAY",
47 | "STATUS_BUSY",
48 |
49 | "BUTTON_SUCCESS_BACKGROUND",
50 | "BUTTON_SUCCESS_TEXT",
51 | "BUTTON_SUCCESS_HOVER_BACKGROUND",
52 | "BUTTON_SUCCESS_HOVER_TEXT",
53 | "BUTTON_WARNING_BACKGROUND",
54 | "BUTTON_WARNING_TEXT",
55 | "BUTTON_WARNING_HOVER_BACKGROUND",
56 | "BUTTON_WARNING_HOVER_TEXT",
57 | "BUTTON_DANGER_BACKGROUND",
58 | "BUTTON_DANGER_TEXT",
59 | "BUTTON_DANGER_HOVER_BACKGROUND",
60 | "BUTTON_DANGER_HOVER_TEXT",
61 | "BUTTON_DISABLED_BACKGROUND",
62 | "BUTTON_DISABLED_TEXT",
63 | "BUTTON_DISABLED_TRANSFER",
64 | "BUTTON_INPROGRESS_BACKGROUND",
65 | "BUTTON_INPROGRESS_TEXT",
66 | NULL
67 | };
68 | uint32_t *COLOUR_POINTER_TABLE[] = {
69 | &COLOR_MAIN_BACKGROUND,
70 | &COLOR_MAIN_TEXT,
71 | &COLOR_MAIN_CHATTEXT,
72 | &COLOR_MAIN_SUBTEXT,
73 | &COLOR_MAIN_ACTIONTEXT,
74 | &COLOR_MAIN_QUOTETEXT,
75 | &COLOR_MAIN_URLTEXT,
76 | &COLOR_MAIN_HINTTEXT,
77 |
78 | &COLOR_MENU_BACKGROUND,
79 | &COLOR_MENU_TEXT,
80 | &COLOR_MENU_SUBTEXT,
81 | &COLOR_MENU_HOVER_BACKGROUND,
82 | &COLOR_MENU_ACTIVE_BACKGROUND,
83 | &COLOR_MENU_ACTIVE_TEXT,
84 |
85 | &COLOR_LIST_BACKGROUND,
86 | &COLOR_LIST_HOVER_BACKGROUND,
87 | &COLOR_LIST_TEXT,
88 | &COLOR_LIST_SUBTEXT,
89 |
90 | &COLOR_GROUP_SELF,
91 | &COLOR_GROUP_PEER,
92 | &COLOR_GROUP_AUDIO,
93 | &COLOR_GROUP_MUTED,
94 |
95 | &COLOR_SELECTION_BACKGROUND,
96 | &COLOR_SELECTION_TEXT,
97 |
98 | &COLOR_EDGE_NORMAL,
99 | &COLOR_EDGE_HOVER,
100 | &COLOR_EDGE_ACTIVE,
101 | &COLOR_ACTIVEOPTION_BACKGROUND,
102 | &COLOR_ACTIVEOPTION_TEXT,
103 |
104 | &COLOR_AUX_BACKGROUND,
105 | &COLOR_AUX_EDGE_NORMAL,
106 | &COLOR_AUX_EDGE_HOVER,
107 | &COLOR_AUX_EDGE_ACTIVE ,
108 | &COLOR_AUX_TEXT,
109 | &COLOR_AUX_ACTIVEOPTION_BACKGROUND,
110 | &COLOR_AUX_ACTIVEOPTION_TEXT,
111 |
112 | &COLOR_STATUS_ONLINE,
113 | &COLOR_STATUS_AWAY,
114 | &COLOR_STATUS_BUSY,
115 |
116 | &COLOR_BUTTON_SUCCESS_BACKGROUND,
117 | &COLOR_BUTTON_SUCCESS_TEXT,
118 | &COLOR_BUTTON_SUCCESS_HOVER_BACKGROUND,
119 | &COLOR_BUTTON_SUCCESS_HOVER_TEXT,
120 | &COLOR_BUTTON_WARNING_BACKGROUND,
121 | &COLOR_BUTTON_WARNING_TEXT,
122 | &COLOR_BUTTON_WARNING_HOVER_BACKGROUND,
123 | &COLOR_BUTTON_WARNING_HOVER_TEXT,
124 | &COLOR_BUTTON_DANGER_BACKGROUND,
125 | &COLOR_BUTTON_DANGER_TEXT,
126 | &COLOR_BUTTON_DANGER_HOVER_BACKGROUND,
127 | &COLOR_BUTTON_DANGER_HOVER_TEXT,
128 | &COLOR_BUTTON_DISABLED_BACKGROUND,
129 | &COLOR_BUTTON_DISABLED_TEXT,
130 | &COLOR_BUTTON_DISABLED_TRANSFER,
131 | &COLOR_BUTTON_INPROGRESS_BACKGROUND,
132 | &COLOR_BUTTON_INPROGRESS_TEXT,
133 | NULL
134 | };
135 |
--------------------------------------------------------------------------------
/tools/android-build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Script to cross compile utox for android from linux (and soon windows)
3 | #
4 |
5 |
6 | usage() {
7 | echo "Cross compile script to build uTox for android from a ~unix environment."
8 | echo
9 | echo "Usage: "
10 | echo "cd [utox_root_directory/]"
11 | echo "$0"
12 | echo
13 | echo "Yup, that's it..."
14 | return 0
15 | }
16 |
17 | for arg in "$@"; do
18 | case "$arg" in
19 | *)
20 | usage
21 | exit 1
22 | ;;
23 | esac
24 | done
25 |
26 | export ALIAS=utox
27 |
28 | export ANDROID_NDK_HOME=/opt/android-ndk
29 | mkdir toolchain
30 | cd toolchain
31 | export TOOLCHAIN=$(pwd)
32 | cd ..
33 | "$ANDROID_NDK_HOME/build/tools/make-standalone-toolchain.sh" \
34 | --ndk-dir="$ANDROID_NDK_HOME" \
35 | --toolchain=arm-linux-androideabi-clang3.5 \
36 | --install-dir=$TOOLCHAIN \
37 | --platform=android-9
38 |
39 | export PATH="$TOOLCHAIN/bin:$PATH"
40 | SDK_PATH=/opt/android-sdk
41 | # cd utox
42 |
43 | mkdir ./tmp
44 | mkdir ./tmp/java
45 | mkdir ./tmp/libs
46 | mkdir ./tmp/libs/armeabi
47 |
48 | ls -la ../openal-arm/lib/
49 | OPENAL_BUILD='-I../openal-arm/include ../openal-arm/lib/libopenal.a -lOpenSLES'
50 | NATIVE_AUDIO_BUILD='-DNATIVE_ANDROID_AUDIO -lOpenSLES'
51 |
52 | arm-linux-androideabi-gcc -Wl,--error-unresolved-symbols \
53 | -Wall -Wextra -s \
54 | -I../freetype-arm/include/freetype2/ -I../toxcore-arm/include/ \
55 | ./*.c ./png/png.c -llog -landroid -lEGL -lGLESv2 $OPENAL_BUILD \
56 | ../toxcore-arm/lib/libtoxcore.a ../toxcore-arm/lib/libtoxdns.a ../toxcore-arm/lib/libtoxav.a ../toxcore-arm/lib/libsodium.a \
57 | ../toxcore-arm/lib/libopus.a ../toxcore-arm/lib/libvpx.a ../freetype-arm/lib/libfreetype.a \
58 | -lm -lz -ldl -shared -o ./tmp/libs/armeabi/libn.so
59 |
60 | $SDK_PATH/build-tools/21.1.2/aapt package -f -M ./android/AndroidManifest.xml -S ./android/res \
61 | -I $SDK_PATH/platforms/android-21/android.jar -F ./tmp/tmp1.apk -J ./tmp/java
62 |
63 | javac -d ./tmp/java ./tmp/java/R.java
64 |
65 | $SDK_PATH/build-tools/21.1.2/dx --dex --output=./tmp/classes.dex ./tmp/java
66 |
67 | java -classpath $SDK_PATH/tools/lib/sdklib.jar com.android.sdklib.build.ApkBuilderMain ./tmp/tmp2.apk \
68 | -u -z ./tmp/tmp1.apk -f ./tmp/classes.dex -nf ./tmp/libs
69 |
70 | jarsigner -sigalg SHA1withRSA -digestalg SHA1 -keystore ./debug.keystore -storepass $PASSWORD ./tmp/tmp2.apk $ALIAS
71 |
72 | mv tmp/tmp2.apk ./utox.apk
73 |
74 | rm -r tmp toolchain
75 |
76 |
--------------------------------------------------------------------------------
/tools/cross-compile-windows.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Script to cross compile utox for win64 from a linux host with ming32
3 | #
4 | # Expects build dir to be git root with filter_audio and toxcore libs in ./lib/
5 | #
6 | # TODO: Add support to -t path/to/libtoxcore; -l path/to/openal; -f path/to/filter_audio
7 |
8 | usage() {
9 | echo "Cross compile script to build windows uTox from a ~unix enviroment."
10 | echo
11 | echo "Usage: $0 [32|64] [win|unix] [fast|debug]"
12 | return 0
13 | }
14 |
15 | for arg in "$@"; do
16 | case "$arg" in
17 | 32 | '-32')
18 | arch=32
19 | ;;
20 | 64 | '-64')
21 | arch=64
22 | ;;
23 | 'unix' | '-u')
24 | host=0
25 | ;;
26 | 'win' | '-w')
27 | host=1
28 | ;;
29 | 'fast' | '-f')
30 | fast=1
31 | ;;
32 | 'debug' | '-d')
33 | debug=1
34 | ;;
35 | 'legacy' | '-l')
36 | legacy=1
37 | ;;
38 | *)
39 | usage
40 | exit 1
41 | ;;
42 | esac
43 | done
44 |
45 | # Build Architecture
46 | if [[ $arch == 32 ]]; then
47 | WINDOWS_TOOLCHAIN=i686-w64-mingw32
48 | echo "Building 32bit version of uTox"
49 | elif [[ $arch == 64 ]]; then
50 | WINDOWS_TOOLCHAIN=x86_64-w64-mingw32
51 | echo "Building 64bit version of uTox"
52 | else
53 | WINDOWS_TOOLCHAIN=x86_64-w64-mingw32
54 | echo "Defaulting to 64bit"
55 | fi
56 |
57 | # Build Environment
58 | if [[ $host == 0 ]]; then
59 | MINGW32_LIB_DIR="/usr/$WINDOWS_TOOLCHAIN/lib"
60 | echo "Building from a native Unix environment"
61 | elif [[ $host == 1 ]]; then
62 | MINGW32_LIB_DIR="/usr/$WINDOWS_TOOLCHAIN/sys-root/mingw/lib"
63 | echo "Building from a ~Unix environment within windows"
64 | else
65 | MINGW32_LIB_DIR="/usr/$WINDOWS_TOOLCHAIN/sys-root/mingw/lib"
66 | echo "Defaulting to a ~Unix environment within windows"
67 | fi
68 |
69 | # Other options
70 | if [[ $debug == 1 ]]; then
71 | COMP_OPTs="-g -O0"
72 | echo "Building with debugging info"
73 | elif [[ $fast == 1 ]]; then
74 | COMP_OPTs="-s -O0"
75 | echo "Quick build (without optimizations)"
76 | else
77 | COMP_OPTs="-s -Ofast"
78 | fi
79 |
80 | if [[ $legacy == 1 ]]; then
81 | COMP_OPTs+=" -D __WIN_LEGACY=1"
82 | echo "Compiling for windows XP"
83 | fi
84 |
85 | GIT_V=`git describe --abbrev=8 --dirty --always --tags`
86 | echo -n "Git version: "
87 | git describe --abbrev=8 --dirty --always --tags
88 |
89 | # Build filter_audio
90 | AUDIO_FILTERING_BUILD="-DAUDIO_FILTERING -I ./lib/filter_audio/ ./lib/filter_audio/filter_audio.c \
91 | ./lib/filter_audio/aec/*.c ./lib/filter_audio/agc/*.c ./lib/filter_audio/ns/*.c ./lib/filter_audio/other/*.c \
92 | ./lib/filter_audio/vad/*.c ./lib/filter_audio/zam/*.c"
93 |
94 | # Remove existing
95 | rm utox.exe 2> /dev/null
96 |
97 | # Generate a windows icon
98 | "$WINDOWS_TOOLCHAIN"-windres icons/icon.rc -O coff -o icon.o
99 |
100 | # Compile
101 | "$WINDOWS_TOOLCHAIN"-gcc -o utox.exe $COMP_OPTs -DGIT_VERSION=\"$GIT_V\" -DAL_LIBTYPE_STATIC ./*.c ./png/png.c ./icon.o \
102 | ./lib/toxcore/lib/libtoxcore.a ./lib/toxcore/lib/libtoxdns.a ./lib/toxcore/lib/libtoxav.a \
103 | ./lib/toxcore/lib/libsodium.a $MINGW32_LIB_DIR/libwinpthread.a ./lib/toxcore/lib/libvpx.a ./lib/toxcore/lib/libopus.a \
104 | ./lib/openal/lib/libOpenAL32.a -I ./lib/toxcore/include/ -I ./lib/openal/include/ \
105 | $AUDIO_FILTERING_BUILD \
106 | -std=gnu99 -liphlpapi -lws2_32 -lgdi32 -lmsimg32 -ldnsapi -lcomdlg32 -Wl,-subsystem,windows -lwinmm -lole32 -loleaut32 \
107 | -lstrmiids
108 |
--------------------------------------------------------------------------------
/tools/logs_to_plaintext.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | void* file_raw(char *path, uint32_t *size)
8 | {
9 | FILE *file;
10 | char *data;
11 | int len;
12 |
13 | file = fopen(path, "rb");
14 | if(!file) {
15 | printf("File not found (%s)\n", path);
16 | return NULL;
17 | }
18 |
19 | fseek(file, 0, SEEK_END);
20 | len = ftell(file);
21 | data = malloc(len);
22 | if(!data) {
23 | fclose(file);
24 | return NULL;
25 | }
26 |
27 | fseek(file, 0, SEEK_SET);
28 |
29 | if(fread(data, len, 1, file) != 1) {
30 | printf("Read error (%s)\n", path);
31 | fclose(file);
32 | free(data);
33 | return NULL;
34 | }
35 |
36 | fclose(file);
37 |
38 | printf("Read %u bytes (%s)\n", len, path);
39 |
40 | if(size) {
41 | *size = len;
42 | }
43 | return data;
44 | }
45 |
46 | int main(int argc, char *argv[])
47 | {
48 | uint8_t *in, *p, *end;
49 | uint32_t in_size;
50 | FILE *out;
51 |
52 | if(argc != 3) {
53 | printf("usage: ./a.out \n");
54 | return 0;
55 | }
56 |
57 | in = file_raw(argv[1], &in_size);
58 | if(!in) {
59 | return 0;
60 | }
61 |
62 | out = fopen(argv[2], "w");
63 | if(!out) {
64 | free(in);
65 | return 0;
66 | }
67 |
68 | p = in;
69 | end = in + in_size;
70 |
71 | while(p < end) {
72 | uint64_t time;
73 | uint16_t namelen, length;
74 | time_t rawtime;
75 | char *timestr;
76 |
77 | memcpy(&time, p, 8);
78 | memcpy(&namelen, p + 8, 2);
79 | memcpy(&length, p + 10, 2);
80 | if(p[12]) {
81 | fputs("[Sent]", out);
82 | }
83 | p += 16;
84 |
85 | rawtime = (time_t)time;
86 | timestr = ctime(&rawtime);
87 |
88 | fprintf(out, "[%.*s] %.*s: %.*s\n", strlen(timestr) - 1, timestr, namelen, p, length, p + namelen);
89 | p += length + namelen;
90 | }
91 |
92 | free(in);
93 | fclose(out);
94 | }
95 |
--------------------------------------------------------------------------------
/tooltip.c:
--------------------------------------------------------------------------------
1 | #include "main.h"
2 |
3 | static TOOLTIP tooltip;
4 |
5 | #define TOOLTIP_WIDTH (SCALE * 12)
6 | #define TOOLTIP_HEIGHT (SCALE * 12)
7 | #define TOOLTIP_YOFFSET 12
8 |
9 | static void calculate_pos_and_width(TOOLTIP *b, int *x, int *w) {
10 | *x = b->x;
11 | *w = b->width;
12 |
13 | // Increase width if needed, so that tooltip text fits.
14 | if(maybe_i18nal_string_is_valid(b->tt_text)) {
15 | STRING* s = maybe_i18nal_string_get(b->tt_text);
16 | int needed_w = textwidth(s->str, s->length) + 4 * SCALE;
17 | if(*w < needed_w) {
18 | *w = needed_w;
19 | }
20 | }
21 |
22 | // Push away from the right border to fit.
23 | if(*x + *w >= utox_window_width) {
24 | *x -= *w;
25 | }
26 | }
27 |
28 | volatile _Bool kill_thread;
29 |
30 | void tooltip_reset(void)
31 | {
32 | TOOLTIP *b = &tooltip;
33 |
34 | b->visible = 0;
35 | b->can_show = 0;
36 |
37 | if (b->thread) {
38 | kill_thread = 1;
39 | b->thread = 0;
40 | }
41 | }
42 |
43 | void tooltip_draw(void)
44 | {
45 | TOOLTIP *b = &tooltip;
46 | if(!b->visible) {
47 | return;
48 | }
49 |
50 | // Ensure that font is set before calculating position and width.
51 | setfont(FONT_TEXT);
52 | setcolor(COLOR_MAIN_TEXT);
53 |
54 | int x, w;
55 | calculate_pos_and_width(b, &x, &w);
56 |
57 | drawrectw(x, b->y, w, b->height, COLOR_MAIN_BACKGROUND);
58 |
59 | STRING* s = maybe_i18nal_string_get(b->tt_text);
60 | drawtext(x + SCALE * 2, b->y + SCALE * 2, s->str, s->length);
61 |
62 | framerect(x, b->y, x + w, b->y + b->height, COLOR_EDGE_NORMAL);
63 | }
64 |
65 | _Bool tooltip_mmove(void)
66 | {
67 | TOOLTIP *b = &tooltip;
68 |
69 | b->can_show = 0;
70 |
71 | if(!b->visible) {
72 | return 0;
73 | }
74 |
75 | b->visible = 0;
76 |
77 | if (b->thread) {
78 | kill_thread = 1;
79 | b->thread = 0;
80 | }
81 |
82 | return 1;
83 | }
84 |
85 | _Bool tooltip_mdown(void)
86 | {
87 | TOOLTIP *b = &tooltip;
88 |
89 | b->can_show = 0;
90 | b->mouse_down = 1;
91 | b->visible = 0;
92 |
93 | if (b->thread) {
94 | kill_thread = 1;
95 | b->thread = 0;
96 | }
97 |
98 | return 0;
99 | }
100 |
101 | _Bool tooltip_mup(void)
102 | {
103 | TOOLTIP *b = &tooltip;
104 |
105 | b->can_show = 0;
106 | b->mouse_down = 0;
107 |
108 | if (b->thread) {
109 | kill_thread = 1;
110 | b->thread = 0;
111 | }
112 |
113 | return 0;
114 | }
115 |
116 | void tooltip_show(void)
117 | {
118 |
119 | TOOLTIP *b = &tooltip;
120 |
121 | if (!b->can_show)
122 | return;
123 |
124 | b->y = mouse.y + TOOLTIP_YOFFSET;
125 | b->height = TOOLTIP_HEIGHT;
126 | if(b->y + b->height >= utox_window_height) {
127 | b->y -= (b->height + TOOLTIP_YOFFSET);
128 | }
129 | b->x = mouse.x;
130 | b->width = TOOLTIP_WIDTH;
131 |
132 | b->visible = 1;
133 |
134 | if (b->thread) {
135 | kill_thread = 1;
136 | b->thread = 0;
137 | }
138 |
139 | }
140 |
141 | volatile _Bool reset_time;
142 |
143 | static void tooltip_thread(void *UNUSED(args))
144 | {
145 | uint64_t last_move_time = ~0;
146 | while (1) {
147 | if (kill_thread) {
148 | break;
149 | }
150 |
151 | TOOLTIP *b = &tooltip;
152 | if (reset_time) {
153 | last_move_time = get_time() + 500 * 1000 * 1000;
154 | reset_time = 0;
155 | }
156 |
157 | if (get_time() > last_move_time) {
158 | postmessage(TOOLTIP_SHOW, 0, 0, NULL);
159 | last_move_time = ~0;
160 | }
161 |
162 | yieldcpu(100);
163 | }
164 |
165 | kill_thread = 0;
166 | }
167 |
168 | // This is being called every time the mouse is moving above a button
169 | void tooltip_new(MAYBE_I18NAL_STRING* text)
170 | {
171 | TOOLTIP *b = &tooltip;
172 |
173 | b->can_show = 1;
174 | b->tt_text = text;
175 |
176 | if(b->visible || b->mouse_down) {
177 | return;
178 | }
179 |
180 | if (!b->thread && !kill_thread) {
181 | thread(tooltip_thread, NULL);
182 | b->thread = 1;
183 | }
184 |
185 | reset_time = 1;
186 | }
187 |
188 |
189 |
--------------------------------------------------------------------------------
/tooltip.h:
--------------------------------------------------------------------------------
1 | typedef struct tooltip {
2 | int x, y, width, height;
3 | _Bool visible;
4 |
5 | _Bool can_show;
6 | _Bool mouse_down;
7 | _Bool thread;
8 |
9 | MAYBE_I18NAL_STRING* tt_text;
10 | } TOOLTIP;
11 |
12 | // removes the tooltip, requires a redraw
13 | void tooltip_reset(void);
14 |
15 | void tooltip_draw(void);
16 | _Bool tooltip_mmove(void);
17 | _Bool tooltip_mdown(void);
18 | _Bool tooltip_mup(void);
19 |
20 | void tooltip_show(void);
21 | void tooltip_new(MAYBE_I18NAL_STRING* text);
22 |
23 |
--------------------------------------------------------------------------------
/tox.h:
--------------------------------------------------------------------------------
1 | /* todo: proper system for posting messages to the toxcore thread, comments, better names (?), proper cleanup of a/v and a/v thread*/
2 | /* -proper unpause/pause file transfers, resuming file transfers + what if new file transfer with same id gets created before the main thread receives the message for the old one?
3 | >= GiB file sizes with FILE_*_PROGRESS on 32bit */
4 |
5 | /* details about messages and their (param1, param2, data) values are in the message handlers in tox.c*/
6 |
7 | /* toxcore thread messages (sent from the client thread)
8 | */
9 | enum {
10 | TOX_KILL,
11 |
12 | TOX_SETNAME,
13 | TOX_SETAVATAR,
14 | TOX_UNSETAVATAR,
15 | TOX_SETSTATUSMSG,
16 | TOX_SETSTATUS,
17 | TOX_ADDFRIEND,
18 | TOX_DELFRIEND,
19 | TOX_ACCEPTFRIEND,
20 | TOX_SENDMESSAGE,
21 | TOX_SENDACTION, //10
22 | TOX_SENDMESSAGEGROUP,
23 | TOX_SENDACTIONGROUP,
24 | TOX_SET_TYPING,
25 | TOX_CALL,
26 | TOX_CALL_VIDEO,
27 | TOX_CALL_VIDEO_ON,
28 | TOX_CALL_VIDEO_OFF,
29 | TOX_CANCELCALL,
30 | TOX_ACCEPTCALL,
31 | TOX_HANGUP, //20
32 | TOX_NEWGROUP,
33 | TOX_LEAVEGROUP,
34 | TOX_GROUPINVITE,
35 | TOX_GROUPCHANGETOPIC,
36 | TOX_GROUP_AUDIO_START,
37 | TOX_GROUP_AUDIO_END,
38 |
39 | TOX_SEND_NEW_FILE,
40 | TOX_SEND_NEW_INLINE,
41 | TOX_ACCEPTFILE, //30
42 | TOX_FILE_START_TEMP,
43 | TOX_FILE_INCOMING_RESUME,
44 | TOX_FILE_INCOMING_PAUSE,
45 | TOX_FILE_INCOMING_CANCEL,
46 | TOX_FILE_OUTGOING_RESUME,
47 | TOX_FILE_OUTGOING_PAUSE,
48 | TOX_FILE_OUTGOING_CANCEL,
49 | TOX_FRIEND_ONLINE,
50 | };
51 |
52 | struct TOX_SEND_INLINE_MSG {
53 | size_t image_size;
54 | UTOX_PNG_IMAGE image;
55 | };
56 |
57 | /* toxav thread messages (sent from the client thread)
58 | */
59 | enum
60 | {
61 | AUDIO_KILL,
62 | AUDIO_SET_INPUT,
63 | AUDIO_SET_OUTPUT,
64 | AUDIO_PREVIEW_START,
65 | AUDIO_PREVIEW_END,
66 | AUDIO_CALL_START,
67 | AUDIO_CALL_END,
68 | AUDIO_PLAY_RINGTONE,
69 | AUDIO_STOP_RINGTONE,
70 | GROUP_AUDIO_CALL_START,
71 | GROUP_AUDIO_CALL_END,
72 | };
73 |
74 | enum
75 | {
76 | VIDEO_KILL,
77 | VIDEO_SET,
78 | VIDEO_PREVIEW_START,
79 | VIDEO_PREVIEW_END,
80 | VIDEO_CALL_START,
81 | VIDEO_CALL_END,
82 | };
83 |
84 |
85 | enum
86 | {
87 | TOXAV_KILL,
88 | };
89 | /* client thread messages (recieved by the client thread)
90 | */
91 | enum {
92 | /* general messages */
93 | TOX_DONE,
94 | DHT_CONNECTED,
95 | DNS_RESULT,
96 |
97 | SET_AVATAR,
98 |
99 | SEND_FILES,
100 | SAVE_FILE,
101 | FILE_START_TEMP,
102 | FILE_ABORT_TEMP,
103 |
104 | NEW_AUDIO_IN_DEVICE,
105 | NEW_AUDIO_OUT_DEVICE,
106 | NEW_VIDEO_DEVICE,
107 |
108 | /* friend related */
109 | FRIEND_REQUEST,
110 | FRIEND_ACCEPT,
111 | FRIEND_ADD,
112 | FRIEND_DEL,
113 | FRIEND_MESSAGE,
114 | FRIEND_NAME,
115 | FRIEND_SETAVATAR,
116 | FRIEND_UNSETAVATAR,
117 | FRIEND_STATUS_MESSAGE,
118 | FRIEND_STATUS,
119 | FRIEND_TYPING,
120 | FRIEND_ONLINE,
121 |
122 | /* friend a/v */
123 | FRIEND_CALL_STATUS,
124 | FRIEND_CALL_VIDEO,
125 | FRIEND_CALL_MEDIACHANGE,
126 | FRIEND_CALL_START_VIDEO,
127 | FRIEND_CALL_STOP_VIDEO,
128 | FRIEND_VIDEO_FRAME,
129 | PREVIEW_FRAME,
130 | PREVIEW_FRAME_NEW,
131 |
132 | /* friend file */
133 | FRIEND_FILE_NEW,
134 | FRIEND_FILE_UPDATE,
135 | FRIEND_INLINE_IMAGE,
136 |
137 | /* group */
138 | GROUP_ADD,
139 | GROUP_MESSAGE,
140 | GROUP_PEER_ADD,
141 | GROUP_PEER_DEL,
142 | GROUP_PEER_NAME,
143 | GROUP_TITLE,
144 | GROUP_AUDIO_START,
145 | GROUP_AUDIO_END,
146 | GROUP_UPDATE,
147 |
148 | TOOLTIP_SHOW,
149 | };
150 |
151 | enum
152 | {
153 | CALL_NONE,
154 | CALL_INVITED,
155 | CALL_RINGING,
156 | CALL_OK,
157 | CALL_NONE_VIDEO, //not used
158 | CALL_INVITED_VIDEO,
159 | CALL_RINGING_VIDEO,
160 | CALL_OK_VIDEO,
161 | };
162 | /* toxcore thread
163 | */
164 | void tox_thread(void *args);
165 |
166 | /* send a message to the toxcore thread
167 | */
168 | void tox_postmessage(uint8_t msg, uint32_t param1, uint32_t param2, void *data);
169 |
170 | /* send a message to the audio thread
171 | */
172 | void toxaudio_postmessage(uint8_t msg, uint32_t param1, uint32_t param2, void *data);
173 |
174 | /* send a message to the video thread
175 | */
176 | void toxvideo_postmessage(uint8_t msg, uint32_t param1, uint32_t param2, void *data);
177 |
178 | /* send a message to the toxav thread
179 | */
180 | void toxav_postmessage(uint8_t msg, uint32_t param1, uint32_t param2, void *data);
181 |
182 | /* read a message sent from the toxcore thread (sent with postmessage())
183 | */
184 | void tox_message(uint8_t msg, uint16_t param1, uint16_t param2, void *data);
185 |
186 | void tox_settingschanged(void);
187 |
--------------------------------------------------------------------------------
/ui.h:
--------------------------------------------------------------------------------
1 |
2 | /* draws an image in the style of an avatar at within rect (x,y,targetwidth,targetheight)
3 | * this means: resize the image while keeping proportion so that the dimension(width or height) that has the smallest rational difference to the targetdimension becomes exactly targetdimension, then
4 | * crop the image so it fits in the (x,y,targetwidth,targetheight) rect, and
5 | * set the position if a dimension is too large so it's centered on the middle
6 | *
7 | * first argument is the image to draw, width and height are the width and height of the input image
8 | */
9 | void draw_avatar_image(UTOX_NATIVE_IMAGE *image, int x, int y, uint32_t width, uint32_t height, uint32_t targetwidth, uint32_t targetheight);
10 |
11 | enum
12 | {
13 | PANEL_NONE,
14 | PANEL_MAIN,
15 | PANEL_MESSAGES,
16 | PANEL_LIST,
17 | PANEL_BUTTON,
18 | PANEL_DROPDOWN,
19 | PANEL_EDIT,
20 | PANEL_SCROLLABLE,
21 | };
22 |
23 | typedef enum {
24 | MAIN_STYLE, // white style, used in right side
25 | AUXILIARY_STYLE, // gray style, used on friends side
26 | } UI_ELEMENT_STYLE;
27 |
28 | typedef struct scrollable SCROLLABLE;
29 | typedef struct edit EDIT;
30 | typedef struct panel PANEL;
31 | typedef struct button BUTTON;
32 | typedef struct messages MESSAGES;
33 | struct panel
34 | {
35 | uint8_t type;
36 | _Bool disabled;
37 | int x, y, width, height;
38 | SCROLLABLE *content_scroll;
39 | void (*drawfunc)(int, int, int, int);
40 | PANEL **child;
41 | };
42 |
43 | enum
44 | {
45 | ADDF_NONE,
46 | ADDF_SENT,
47 | ADDF_DISCOVER,
48 | ADDF_BADNAME,
49 | ADDF_NONAME,
50 | ADDF_TOOLONG, //if message length is too long.
51 | ADDF_NOMESSAGE, //if no message (message length must be >= 1 byte).
52 | ADDF_OWNKEY, //if user's own key.
53 | ADDF_ALREADYSENT, //if friend request already sent or already a friend.
54 | ADDF_UNKNOWN, //for unknown error.
55 | ADDF_BADCHECKSUM, //if bad checksum in address.
56 | ADDF_SETNEWNOSPAM, //if the friend was already there but the nospam was different.
57 | ADDF_NOMEM, //if increasing the friend list size fails.
58 | };
59 |
60 | extern PANEL panel_root;
61 | extern PANEL panel_chat, panel_friend_chat, panel_friend_request, panel_group_chat;
62 | extern PANEL panel_overhead, panel_add_friend, panel_settings_master, panel_change_profile;
63 | extern MESSAGES messages_friend, messages_group;
64 | extern EDIT edit_name, edit_status, edit_add_id, edit_add_msg, edit_msg, edit_msg_group, edit_search, edit_proxy_ip, edit_proxy_port;
65 | extern SCROLLABLE scrollbar_roster;
66 | extern BUTTON button_add, button_settings, button_transfer;
67 |
68 | typedef struct {
69 | STRING plain;
70 | UI_STRING_ID i18nal;
71 | } MAYBE_I18NAL_STRING;
72 |
73 | void maybe_i18nal_string_set_plain(MAYBE_I18NAL_STRING*, char_t *str, STRING_IDX length);
74 | void maybe_i18nal_string_set_i18nal(MAYBE_I18NAL_STRING*, UI_STRING_ID);
75 | STRING* maybe_i18nal_string_get(MAYBE_I18NAL_STRING*);
76 | _Bool maybe_i18nal_string_is_valid(MAYBE_I18NAL_STRING*);
77 |
78 | #define DEFAULT_LANG LANG_EN
79 | #define S(x) (ui_gettext(LANG, (STR_##x))->str)
80 | #define SLEN(x) (ui_gettext(LANG, (STR_##x))->length)
81 | #define SPTR(x) (ui_gettext(LANG, (STR_##x)))
82 | #define SPTRFORLANG(l,x) (ui_gettext((l), (x)))
83 | // Application-wide language setting
84 | extern UI_LANG_ID LANG;
85 |
86 | void ui_scale(uint8_t scale);
87 | void ui_size(int width, int height);
88 |
89 | void ui_mouseleave(void);
90 |
91 | void panel_draw(PANEL *p, int x, int y, int width, int height);
92 |
93 | _Bool panel_mmove(PANEL *p, int x, int y, int width, int height, int mx, int my, int dx, int dy);
94 | void panel_mdown(PANEL *p);
95 | _Bool panel_dclick(PANEL *p, _Bool triclick);
96 | _Bool panel_mright(PANEL *p);
97 | _Bool panel_mwheel(PANEL *p, int x, int y, int width, int height, double d);
98 | _Bool panel_mup(PANEL *p);
99 | _Bool panel_mleave(PANEL *p);
100 |
101 | #define GRAY(x) (((x) << 16) | ((x) << 8) | (x))
102 |
103 | #define BLACK 0
104 |
105 | /* search
106 | */
107 |
108 | uint8_t SEARCH;
109 | uint8_t FILTER;
110 | int search_offset[1024];
111 | int search_unset[1024];
112 | char search_data[128];
113 |
114 | /* metrics
115 | */
116 | uint8_t SCALE;
117 |
118 | /* These are the new defines to help align UI elements, the new ones start with either the x_/y_ prefix and the
119 | * _top/_bottom/_left/_right post fix, and should be used to replace the originals whenever possible. If you're able to
120 | * replace an original, please replace all occurrences, and delete the define. */
121 | #define X_SIDEBAR_RIGHT (111 * SCALE)
122 |
123 | #define X_MAIN_LEFT ((111 * SCALE) + 1)
124 |
125 | #define X_ROSTER_LEFT (8 * SCALE)
126 | #define Y_ROSTER_TOP (43 * SCALE)
127 |
128 |
129 | /* side */
130 | #define LIST_X (8 * SCALE)
131 | #define LIST_RIGHT (111 * SCALE)
132 | #define LIST_Y (31 * SCALE)
133 | #define LIST_Y2 (43 * SCALE)
134 | #define LIST_BOTTOM (-18 * SCALE)
135 |
136 |
137 | #define LIST_NAME_X (37 * SCALE)
138 | #define LIST_NAME_Y (6 * SCALE)
139 |
140 | #define LIST_STATUS_X (37 * SCALE)
141 | #define LIST_STATUS_Y (13 * SCALE)
142 |
143 | #define LIST_AVATAR_X (LIST_X + 5 * SCALE / 2)
144 | #define LIST_AVATAR_Y (5 * SCALE / 2)
145 |
146 | #define LIST_BUTTON_Y (-13 * SCALE)
147 |
148 | #define ITEM_HEIGHT (25 * SCALE)
149 |
150 | #define SCROLL_WIDTH (4 * SCALE) //must be divisible by 2
151 |
152 | #define SELF_NAME_X (32 * SCALE)
153 | #define SELF_NAME_Y (8 * SCALE)
154 |
155 | #define SELF_MSG_X (32 * SCALE)
156 | #define SELF_MSG_Y (15 * SCALE)
157 |
158 | #define SELF_AVATAR_X (5 * SCALE)
159 | #define SELF_AVATAR_Y (5 * SCALE)
160 |
161 | #define SELF_STATUS_X (96 * SCALE)
162 | #define SELF_STATUS_Y (5 * SCALE)
163 |
164 | #define MESSAGES_SPACING (SCALE * 2)
165 | #define MESSAGES_X (55 * SCALE)
166 | #define TIME_WIDTH (16 * SCALE)
167 | #define NAME_OFFSET (7 * SCALE)
168 |
169 | #define MESSAGES_BOTTOM (-47 * SCALE)
170 |
171 | #define SEARCH_Y (31 * SCALE) - 1
172 |
173 | /* main */
174 | //#define MAIN_X
175 | //#define MAIN_Y LIST_Y
176 |
177 | /* colors */
178 | #define C_RED RGB(200, 78, 78)
179 | #define C_SCROLL GRAY(209)
180 |
--------------------------------------------------------------------------------
/ui_dropdown.h:
--------------------------------------------------------------------------------
1 | //Simple static dropdowns.
2 | extern DROPDOWN dropdown_dpi, dropdown_language, dropdown_proxy, dropdown_ipv6, dropdown_udp, dropdown_logging, dropdown_audible_notification, dropdown_filter, dropdown_audio_filtering, dropdown_close_to_tray, dropdown_start_in_tray, dropdown_theme, dropdown_auto_startup, dropdown_typing_notes;
3 |
4 | //List-based dropdowns. list_dropdown_* functions are applicable.
5 | extern DROPDOWN dropdown_audio_in, dropdown_audio_out, dropdown_video;
6 |
--------------------------------------------------------------------------------
/ui_i18n.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "sized_string.h"
5 | #include "ui_i18n_decls.h"
6 |
7 | #ifdef msgid
8 | #error "msgid is already defined"
9 | #endif
10 | #ifdef msgstr
11 | #error "msgstr is already defined"
12 | #endif
13 | #ifdef LANG_POSIX_LOCALE
14 | #error "LANG_POSIX_LOCALE is already defined"
15 | #endif
16 | #ifdef LANG_WINDOWS_ID
17 | #error "LANG_WINDOWS_ID is already defined"
18 | #endif
19 | #ifdef LANG_PRIORITY
20 | #error "LANG_PRIORITY is already defined"
21 | #endif
22 |
23 | /***** Parsing localized strings *****/
24 |
25 | #define msgid(x) curr_id = (STR_##x);
26 | #define msgstr(x) \
27 | localized_strings[_LANG_ID][curr_id].str = (uint8_t*)(x); \
28 | localized_strings[_LANG_ID][curr_id].length = sizeof(x) - 1;
29 | #define LANG_WINDOWS_ID(x)
30 | #define LANG_POSIX_LOCALE(x)
31 | #define LANG_PRIORITY(x)
32 |
33 | static STRING canary = STRING_INIT("BUG. PLEASE REPORT.");
34 |
35 | static void init_strings(STRING (*localized_strings)[STRS_MAX+1]) {
36 | UI_LANG_ID i;
37 | UI_STRING_ID j;
38 |
39 | for(i = 0; i <= LANGS_MAX; i++) {
40 | for(j = 0; j <= STRS_MAX; j++) {
41 | localized_strings[i][j] = canary;
42 | }
43 | }
44 |
45 | UI_STRING_ID curr_id = 0;
46 |
47 | #include "ui_i18n.h"
48 |
49 | }
50 |
51 | #undef LANG_PRIORITY
52 | #undef LANG_POSIX_LOCALE
53 | #undef LANG_WINDOWS_ID
54 | #undef msgstr
55 | #undef msgid
56 |
57 | STRING* ui_gettext(UI_LANG_ID lang, UI_STRING_ID string_id) {
58 | static STRING localized_strings[LANGS_MAX+1][STRS_MAX+1];
59 | static int ready = 0;
60 |
61 | if(!ready) {
62 | init_strings(localized_strings);
63 | ready = 1;
64 | }
65 |
66 | if((lang > LANGS_MAX) || (string_id > STRS_MAX)) {
67 | return &canary;
68 | }
69 |
70 | return &localized_strings[lang][string_id];
71 | }
72 |
73 | /***** Parsing detection by POSIX locale *****/
74 |
75 | #define msgid(x)
76 | #define msgstr(x)
77 | #define LANG_WINDOWS_ID(x)
78 | #define LANG_POSIX_LOCALE(x) posix_locales[_LANG_ID] = (x);
79 | #define LANG_PRIORITY(x) priorities[_LANG_ID] = (x);
80 |
81 | static void init_posix_locales(const char* posix_locales[], int8_t priorities[]) {
82 |
83 | #include "ui_i18n.h"
84 |
85 | }
86 |
87 | #undef LANG_PRIORITY
88 | #undef LANG_POSIX_LOCALE
89 | #undef LANG_WINDOWS_ID
90 | #undef msgstr
91 | #undef msgid
92 |
93 | UI_LANG_ID ui_guess_lang_by_posix_locale(const char* locale, UI_LANG_ID deflt) {
94 | static const char* posix_locales[LANGS_MAX+1];
95 | static int8_t priorities[LANGS_MAX+1];
96 | static int ready = 0;
97 |
98 | if(!ready) {
99 | init_posix_locales(posix_locales, priorities);
100 | ready = 1;
101 | }
102 |
103 | UI_LANG_ID i;
104 | UI_LANG_ID found_lang = 0;
105 | int8_t found_prio = INT8_MAX;
106 |
107 | // Try detecting by full prefix match first.
108 | for(i = 0; i <= LANGS_MAX; i++) {
109 | const char* l = posix_locales[i];
110 | if(!l) continue;
111 |
112 | if(strstr(locale, l)) {
113 | if(found_prio > priorities[i]) {
114 | found_lang = i;
115 | found_prio = priorities[i];
116 | }
117 | }
118 | }
119 |
120 | if(found_prio < INT8_MAX) {
121 | return found_lang;
122 | }
123 |
124 | // It appears we haven't found exact language_territory
125 | // match (e.g. zh_TW) for given locale. ,
126 | // Try stripping territory off and search only by language part.
127 | for(i = 0; i <= LANGS_MAX; i++) {
128 | const char* l = posix_locales[i];
129 | if(!l) continue;
130 |
131 | char* sep = strchr(l, '_');
132 | if(!sep) continue;
133 |
134 | if(!strncmp(locale, l, sep-l)) {
135 | if(found_prio > priorities[i]) {
136 | found_lang = i;
137 | found_prio = priorities[i];
138 | }
139 | }
140 | }
141 |
142 | return found_prio < INT8_MAX ? found_lang : deflt;
143 | }
144 |
145 | /***** Parsing detection by Windows language id *****/
146 |
147 | #define msgid(x)
148 | #define msgstr(x)
149 | #define LANG_WINDOWS_ID(x) windows_lang_ids[_LANG_ID] = (x);
150 | #define LANG_POSIX_LOCALE(x)
151 | #define LANG_PRIORITY(x) priorities[_LANG_ID] = (x);
152 |
153 | static void init_windows_lang_ids(uint16_t windows_lang_ids[], int8_t priorities[]) {
154 |
155 | #include "ui_i18n.h"
156 |
157 | }
158 |
159 | #undef LANG_PRIORITY
160 | #undef LANG_POSIX_LOCALE
161 | #undef LANG_WINDOWS_ID
162 | #undef msgstr
163 | #undef msgid
164 |
165 | UI_LANG_ID ui_guess_lang_by_windows_lang_id(uint16_t lang_id, UI_LANG_ID deflt) {
166 | static uint16_t windows_lang_ids[LANGS_MAX+1];
167 | static int8_t priorities[LANGS_MAX+1];
168 | static int ready = 0;
169 |
170 | if(!ready) {
171 | init_windows_lang_ids(windows_lang_ids, priorities);
172 | ready = 1;
173 | }
174 |
175 | UI_LANG_ID i;
176 | UI_LANG_ID found_lang = 0;
177 | int8_t found_prio = INT8_MAX;
178 |
179 | // Try detecting by full match first, including sublanguage part.
180 | for(i = 0; i <= LANGS_MAX; i++) {
181 | uint16_t l = windows_lang_ids[i];
182 | if(!l) continue;
183 |
184 | if(l == lang_id) {
185 | if(found_prio > priorities[i]) {
186 | found_lang = i;
187 | found_prio = priorities[i];
188 | }
189 | }
190 | }
191 |
192 | if(found_prio < INT8_MAX) {
193 | return found_lang;
194 | }
195 |
196 | // It appears we haven't found exact id match.
197 | // Try matching by the lower 8 bits, which contain language family part.
198 | for(i = 0; i <= LANGS_MAX; i++) {
199 | uint16_t l = windows_lang_ids[i];
200 | if(!l) continue;
201 |
202 | if((l&0xFF) == (lang_id&0xFF)) {
203 | if(found_prio > priorities[i]) {
204 | found_lang = i;
205 | found_prio = priorities[i];
206 | }
207 | }
208 | }
209 |
210 | return found_prio < INT8_MAX ? found_lang : deflt;
211 | }
212 |
--------------------------------------------------------------------------------
/ui_i18n_decls.h:
--------------------------------------------------------------------------------
1 | enum {
2 | LANG_BG,
3 | LANG_DE,
4 | LANG_EN,
5 | LANG_ES,
6 | LANG_FR,
7 | LANG_HI, //5
8 | LANG_JA,
9 | LANG_IT,
10 | LANG_LV,
11 | LANG_NL,
12 | LANG_NO, //10
13 | LANG_BR,
14 | LANG_PL,
15 | LANG_RO,
16 | LANG_RU,
17 | LANG_TR, //15
18 | LANG_UA,
19 | LANG_CN,
20 | LANG_TW,
21 | LANG_CS,
22 | LANG_DK,
23 | LANG_SV,
24 | LANG_HU,
25 | LANG_PT,
26 | //Do NOT add new values beyond this point, or alter LANGS_MAX accordingly.
27 | LANGS_MAX = LANG_PT
28 | };
29 |
30 | enum {
31 | //This ensures that all statically initialized to zero UI_STRING_ID vars
32 | //will render as canary "BUG. PLEASE REPORT." strings.
33 | UI_STRING_ID_INVALID = 0,
34 |
35 | STR_REQ_SENT,
36 | STR_REQ_RESOLVE,
37 | STR_REQ_INVALID_ID,
38 | STR_REQ_EMPTY_ID,
39 | STR_REQ_LONG_MSG,
40 | STR_REQ_NO_MSG,
41 | STR_REQ_SELF_ID,
42 | STR_REQ_ALREADY_FRIENDS,
43 | STR_REQ_UNKNOWN,
44 | STR_REQ_BAD_CHECKSUM,
45 | STR_REQ_BAD_NOSPAM,
46 | STR_REQ_NO_MEMORY,
47 |
48 | STR_SEND_FILE,
49 | STR_SAVE_FILE,
50 | STR_WHERE_TO_SAVE_FILE_PROMPT,
51 | STR_SEND_FILE_PROMPT,
52 | STR_SCREEN_CAPTURE_PROMPT,
53 |
54 | STR_TRANSFER_NEW,
55 | STR_TRANSFER_STARTED,
56 | STR_TRANSFER___,
57 | STR_TRANSFER_PAUSED,
58 | STR_TRANSFER_BROKEN,
59 | STR_TRANSFER_CANCELLED,
60 | STR_TRANSFER_COMPLETE,
61 |
62 | STR_CALL_CANCELLED,
63 | STR_CALL_INVITED,
64 | STR_CALL_RINGING,
65 | STR_CALL_STARTED,
66 |
67 | STR_ADDFRIENDS,
68 | STR_TOXID,
69 | STR_MESSAGE,
70 | STR_SEARCHFRIENDS,
71 | STR_ADD, STR_BUTTON_ADD_FRIEND = STR_ADD, STR_BUTTON_ACCEPT_FRIEND = STR_ADD,
72 | STR_CREATEGROUPCHAT,
73 | STR_SWITCHPROFILE,
74 | STR_FRIENDREQUEST,
75 | STR_USERSETTINGS,
76 | STR_NAME,
77 | STR_PROFILE,
78 | STR_STATUSMESSAGE,
79 | STR_PREVIEW,
80 | STR_DEVICESELECTION,
81 | STR_AUDIOINPUTDEVICE,
82 | STR_AUDIOFILTERING,
83 | STR_AUDIOOUTPUTDEVICE,
84 | STR_VIDEOINPUTDEVICE,
85 |
86 | // Setting strings
87 | STR_OTHERSETTINGS,
88 | STR_UI,
89 | STR_USER_INTERFACE,
90 | STR_UTOX_SETTINGS,
91 | STR_NETWORK_SETTINGS,
92 | STR_AUDIO_VIDEO,
93 |
94 | STR_DPI,
95 | STR_SAVELOCATION,
96 | STR_LANGUAGE,
97 | STR_NETWORK,
98 | STR_IPV6,
99 | STR_UDP,
100 | STR_PROXY,
101 | STR_WARNING,
102 | STR_LOGGING,
103 | STR_AUDIONOTIFICATIONS,
104 | STR_RINGTONE,
105 | STR_IS_TYPING,
106 | STR_CLOSE_TO_TRAY,
107 | STR_START_IN_TRAY,
108 | STR_AUTO_STARTUP,
109 |
110 |
111 | // Interact with texts / clipboard
112 | STR_COPY, STR_COPY_TOX_ID = STR_COPY,
113 | STR_COPYWITHOUTNAMES,
114 | STR_COPY_WITH_NAMES,
115 | STR_CUT,
116 | STR_PASTE,
117 | STR_DELETE,
118 | STR_SELECTALL,
119 |
120 | STR_REMOVE,
121 | STR_REMOVE_FRIEND,
122 | STR_REMOVE_GROUP,
123 | STR_LEAVE,
124 | STR_LEAVE_GROUP,
125 | STR_ACCEPT, STR_REQ_ACCEPT = STR_ACCEPT,
126 | STR_CTOPIC, STR_CHANGE_GROUP_TOPIC = STR_CTOPIC,
127 | STR_IGNORE, STR_REQ_DECLINE = STR_IGNORE,
128 |
129 | STR_SENDSCREENSHOT,
130 |
131 | STR_CLICKTOSAVE,
132 | STR_CLICKTOOPEN,
133 | STR_CANCELLED,
134 |
135 | STR_DPI_TINY,
136 | STR_DPI_NORMAL,
137 | STR_DPI_BIG,
138 | STR_DPI_LARGE,
139 | STR_DPI_HUGE,
140 |
141 | STR_CONTACTS_FILTER_ALL,
142 | STR_CONTACTS_FILTER_ONLINE,
143 |
144 | STR_CONTACTS_FILTER_EDIT_HINT,
145 |
146 | STR_PROXY_DISABLED,
147 | STR_PROXY_FALLBACK,
148 | STR_PROXY_ALWAYS_USE,
149 |
150 | STR_PROXY_EDIT_HINT_IP,
151 | STR_PROXY_EDIT_HINT_PORT,
152 |
153 | STR_NO,
154 | STR_YES,
155 | STR_OFF,
156 | STR_ON,
157 |
158 | STR_VIDEO_IN_NONE, STR_AUDIO_IN_NONE = STR_VIDEO_IN_NONE,
159 | STR_VIDEO_IN_DESKTOP,
160 |
161 | STR_AUDIO_IN_DEFAULT_LOOPBACK,
162 | STR_AUDIO_IN_ANDROID,
163 |
164 | STR_DEFAULT_FRIEND_REQUEST_MESSAGE,
165 |
166 | STR_WINDOW_TITLE_VIDEO_PREVIEW,
167 |
168 | STR_MUTE,
169 | STR_UNMUTE,
170 |
171 | STR_SELECT_AVATAR_TITLE,
172 | STR_AVATAR_TOO_LARGE_MAX_SIZE_IS,
173 | STR_CANT_FIND_FILE_OR_EMPTY,
174 |
175 | STR_CLEAR_HISTORY,
176 |
177 | STR_THEME,
178 | STR_THEME_DEFAULT,
179 | STR_THEME_LIGHT,
180 | STR_THEME_DARK,
181 | STR_THEME_HIGHCONTRAST,
182 | STR_THEME_CUSTOM,
183 | STR_THEME_ZENBURN,
184 | STR_SEND_TYPING_NOTIFICATIONS,
185 |
186 | STR_LANG_NATIVE_NAME,
187 | STR_LANG_ENGLISH_NAME,
188 | //Do NOT add new values beyond this point, or alter STRS_MAX accordingly.
189 | STRS_MAX = STR_LANG_ENGLISH_NAME
190 | };
191 |
192 | typedef uint8_t UI_LANG_ID;
193 | typedef uint16_t UI_STRING_ID;
194 |
195 | STRING* ui_gettext(UI_LANG_ID lang, UI_STRING_ID string_id);
196 |
197 | UI_LANG_ID ui_guess_lang_by_posix_locale(const char* locale, UI_LANG_ID deflt);
198 | UI_LANG_ID ui_guess_lang_by_windows_lang_id(uint16_t lang_id, UI_LANG_ID deflt);
199 |
--------------------------------------------------------------------------------
/unused.h:
--------------------------------------------------------------------------------
1 |
2 | //Some libraries define it (yes, I'm looking at you, libvpx).
3 | //Ensure that our definition prevails.
4 | #ifdef UNUSED
5 | # undef UNUSED
6 | #endif
7 |
8 | #ifdef __GNUC__
9 | # define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
10 | #elif defined(__LCLINT__)
11 | # define UNUSED(x) /*@unused@*/ x
12 | #else
13 | # define UNUSED(x) x
14 | #endif
15 |
--------------------------------------------------------------------------------
/util.h:
--------------------------------------------------------------------------------
1 | /*todo: sprint_bytes */
2 |
3 | /* read a whole file from a path,
4 | * on success: returns pointer to data (must be free()'d later), writes size of data to *size if size is not NULL
5 | * on failure: returns NULL
6 | */
7 | void* file_raw(char *path, uint32_t *size);
8 |
9 | /*
10 | * Write *data, of size, to path on disk.
11 | */
12 | void file_write_raw(uint8_t *path, uint8_t *data, size_t size);
13 |
14 | //add null terminator to data
15 | void* file_text(char *path);
16 |
17 | /* returns non-zero if substring is found */
18 | _Bool strstr_case(const char *a, const char *b);
19 |
20 | /* convert tox id to string
21 | * notes: dest must be (TOX_FRIEND_ADDRESS_SIZE * 2) bytes large, src must be TOX_FRIEND_ADDRESS_SIZE bytes large
22 | */
23 | void id_to_string(char_t *dest, char_t *src);
24 |
25 | /* same as id_to_string(), but for TOX_PUBLIC_KEY_SIZE
26 | */
27 | void cid_to_string(char_t *dest, char_t *src);
28 |
29 |
30 | /* same as id_to_string(), but for TOX_FILE_ID_LENGTH
31 | */
32 | void fid_to_string(char_t *dest, char_t *src);
33 |
34 | /* convert tox hash to string,
35 | * notes: dest must be (TOX_HASH_LENGTH * 2) bytes large, src must be TOX_HASH_LENGTH bytes large
36 | */
37 | void hash_to_string(char_t *dest, char_t *src);
38 |
39 | /* convert string to tox id
40 | * on success: returns 1
41 | * on failure: returns 0
42 | * notes: dest must be TOX_FRIEND_ADDRESS_SIZE bytes large, some data may be written to dest even on failure
43 | */
44 | _Bool string_to_id(char_t *dest, char_t *src);
45 |
46 | /* convert number of bytes to human readable string
47 | returns number of characters written
48 | notes: dest should be atleast # characters large
49 | */
50 | int sprint_bytes(uint8_t *dest, unsigned int size, uint64_t bytes);
51 |
52 | /* length of a utf-8 character
53 | returns the size of the character in bytes
54 | returns -1 if the size of the character is greater than len or if the character is invalid
55 | */
56 | uint8_t utf8_len(char_t *data);
57 | /* read the character into ch */
58 | uint8_t utf8_len_read(char_t *data, uint32_t *ch);
59 | /* backwards length */
60 | uint8_t utf8_unlen(char_t *data);
61 |
62 | /* remove invalid characters from utf8 string
63 | * returns the new length after invalid characters have been removed
64 | */
65 | int utf8_validate(const char_t *data, int len);
66 |
67 | /*
68 | */
69 | uint8_t unicode_to_utf8_len(uint32_t ch);
70 | void unicode_to_utf8(uint32_t ch, char_t *dst);
71 |
72 | /* compare first n bytes of s1 and s2, ignoring the case of alpha chars
73 | * match: returns 0
74 | * no match: returns 1
75 | * notes: n must be <= length of s1 and <= length of s2
76 | */
77 | _Bool memcmp_case(const char_t *s1, const char_t *s2, uint32_t n);
78 |
79 | /* replace html entities (<,>,&) with html
80 | */
81 | char_t* tohtml(char_t *str, STRING_IDX len);
82 |
83 | /* color format conversion functions
84 | *
85 | */
86 | void yuv420tobgr(uint16_t width, uint16_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, unsigned int ystride, unsigned int ustride, unsigned int vstride, uint8_t *out);
87 | void yuv422to420(uint8_t *plane_y, uint8_t *plane_u, uint8_t *plane_v, uint8_t *input, uint16_t width, uint16_t height);
88 | void bgrtoyuv420(uint8_t *plane_y, uint8_t *plane_u, uint8_t *plane_v, uint8_t *rgb, uint16_t width, uint16_t height);
89 | void bgrxtoyuv420(uint8_t *plane_y, uint8_t *plane_u, uint8_t *plane_v, uint8_t *rgb, uint16_t width, uint16_t height);
90 |
91 | /*
92 | */
93 | void scale_rgbx_image(uint8_t *old_rgbx, uint16_t old_width, uint16_t old_height, uint8_t *new_rgbx, uint16_t new_width, uint16_t new_height);
94 |
95 | /*
96 | */
97 | UTOX_SAVE* config_load(void);
98 | void config_save(UTOX_SAVE *save);
99 |
100 |
101 | /*
102 | Saves user meta data to disk
103 | */
104 | void utox_write_metadata(FRIEND *f);
105 |
--------------------------------------------------------------------------------
/utox.1:
--------------------------------------------------------------------------------
1 | .TH UTOX "1" "June 2015" "µTox 0.3.2"
2 | .SH NAME
3 | µTox \- Lightweight Tox client
4 |
5 | .SH SYNOPSIS
6 | usage: utox [--portable] [--theme ]
7 | or: utox --version
8 |
9 | .SH DESCRIPTION
10 | µTox is a free software lighweight X.org graphical Tox client.
11 |
12 | µTox can be used for:
13 | * 1-to-1 text IM
14 | * group IM
15 | * audio calls
16 | * video calls
17 | * group audio calls
18 | * desktop sharing
19 | * file transfers
20 |
21 | .SH OPTIONS
22 | .IP "\fB\-\-theme\fP "
23 | Choose a color scheme. Possible options are \fIdefault\fP, \fIdark\fP,
24 | \fIlight\fP, \fIhighcontrast\fP, or \fPzenburn\fP.
25 |
26 | .IP \fB\-\-portable\fP
27 | Run in portable mode.
28 |
29 | .IP \fB\-\-version\fP
30 | Print version and exit.
31 |
32 | .SH CHAT COMMANDS
33 | These commands can be used in the chat window.
34 | .IP "\fB/alias\fP "
35 | Sets selected friend's alias to . It will be displayed instead of that
36 | friend's name.
37 | .IP "\fB/topic\fP "
38 | Changes current groupchat's name/topic to . This command can also be
39 | used to edit the current topic by typing /topic and pressing the tab key.
40 | .IP "\fB/me\fP "
41 | Sends an message/action in the format , for example: Tox User
42 | says hi
43 |
44 | .SH FILES
45 | All files listed below are located in \fB$HOME/.config/tox\fP. If µTox is
46 | running in portable mode, their location will be \fB./tox\fP.
47 | .IP \fBtox_save.tox\fP
48 | \fBtox_save.tox\fP is the file that contains the public/private key pair, name,
49 | status and contacts. It's compatible with other Tox clients.
50 | .IP \fButox_save\fP
51 | \fButox_save\fP is µTox' binary config file, it contains settings such as
52 | language, proxy options, DPI or logging.
53 | .IP \fBavatars\fP
54 | The \fBavatars\fP directory contains other contacts' avatars. Files are named
55 | after contacts' public keys (the first 64 characters of the ID).
56 | .IP "\fB[public key].txt\fP"
57 | Those are friends' chat logs. µTox supports only 1v1 chat logging for now.
58 | .IP "\fB[public key].fmetadata\fP"
59 | Friend metadata file, currently used for storing aliases.
60 | .IP "\fB[public key][file number].ftoutfo\fP"
61 | Current outgoing file transfers' state. Used for resuming transfers across
62 | client restarts.
63 |
64 | .SH CONTRIBUTORS
65 | Please see the list page:
66 | .I https://github.com/notsecure/uTox/graphs/contributors
67 |
68 | .SH BUGS
69 | Please report bugs on
70 | .I https://github.com/notsecure/uTox/issues
71 |
72 | The website for
73 | .B µTox
74 | can be found at
75 | .I http://utox.org/
76 | and source code can be found at
77 | .I https://github.com/notsecure/uTox
78 |
--------------------------------------------------------------------------------
/utox.desktop:
--------------------------------------------------------------------------------
1 | [Desktop Entry]
2 | Version=1.0
3 | Type=Application
4 | Name=uTox
5 | Comment=A lightweight Tox client
6 | TryExec=utox
7 | Exec=utox
8 | Icon=utox
9 | Categories=InstantMessaging;AudioVideo;Network;
10 | Terminal=false
11 | MimeType=x-scheme-handler/tox;
12 |
--------------------------------------------------------------------------------
/utox_theme.ini:
--------------------------------------------------------------------------------
1 | # This is an example uTox theme. Copy it to ~/.config/tox/utox_theme.ini.
2 | # A list of keys is in theme.h, remove COLOR_ from the front.
3 | # Colours specified in hex
4 |
5 | #---- Main chat area ----
6 | COLOR_MAIN_BACKGROUND = FFFFFF
7 | COLOR_MAIN_TEXT = 333333
8 | COLOR_MAIN_CHATTEXT = 000000
9 | COLOR_MAIN_SUBTEXT = 414141
10 | COLOR_MAIN_ACTIONTEXT = 4E4EC8
11 | COLOR_MAIN_QUOTETEXT = 008000
12 | COLOR_MAIN_URLTEXT = 001FFF
13 | COLOR_MAIN_HINTTEXT = 969696
14 |
15 | #---- Friend list header and bottom-left buttons ----
16 | COLOR_MENU_BACKGROUND = 1C1C1C
17 | COLOR_MENU_TEXT = FFFFFF
18 | COLOR_MENU_SUBTEXT = D1D1D1
19 | COLOR_MENU_HOVER_BACKGROUND = 282828
20 | COLOR_MENU_ACTIVE_BACKGROUND = 414141
21 | COLOR_MENU_ACTIVE_TEXT = FFFFFF
22 |
23 | #---- Friend list ----
24 | COLOR_LIST_BACKGROUND = 414141
25 | COLOR_LIST_HOVER_BACKGROUND = 505050
26 | COLOR_LIST_TEXT = FFFFFF
27 | COLOR_LIST_SUBTEXT = D1D1D1
28 |
29 | #---- Groupchat user list and title ----
30 | COLOR_GROUP_SELF = 6BC260
31 | COLOR_GROUP_PEER = 969696
32 | COLOR_GROUP_AUDIO = C84E4E
33 | COLOR_GROUP_MUTED = 4E4EC8
34 |
35 | #---- Text selection ----
36 | COLOR_SELECTION_BACKGROUND = 333333
37 | COLOR_SELECTION_TEXT = FFFFFF
38 |
39 | #---- Inputs, dropdowns & tooltips ----
40 | COLOR_EDGE_NORMAL = C0C0C0
41 | COLOR_EDGE_HOVER = 969696
42 | COLOR_EDGE_ACTIVE = 4EA6EA
43 | COLOR_ACTIVEOPTION_BACKGROUND = D1D1D1
44 | COLOR_ACTIVEOPTION_TEXT = 333333
45 |
46 | #---- Auxiliary style for inputs/dropdowns ("Search friends" bar) ----
47 | COLOR_AUX_BACKGROUND = 313131
48 | COLOR_AUX_EDGE_NORMAL = 313131
49 | COLOR_AUX_EDGE_HOVER = 999999
50 | COLOR_AUX_EDGE_ACTIVE = 1A73B7
51 | COLOR_AUX_TEXT = FFFFFF
52 | COLOR_AUX_ACTIVEOPTION_BACKGROUND = 505050
53 | COLOR_AUX_ACTIVEOPTION_TEXT = FFFFFF
54 |
55 | #---- Status circles ----
56 | COLOR_STATUS_ONLINE = 6BC260
57 | COLOR_STATUS_AWAY = CEBF45
58 | COLOR_STATUS_BUSY = C84E4E
59 |
60 | #---- Buttons ----
61 | COLOR_BUTTON_SUCCESS_BACKGROUND = 6BC260
62 | COLOR_BUTTON_SUCCESS_TEXT = FFFFFF
63 | COLOR_BUTTON_SUCCESS_HOVER_BACKGROUND = 76D56A
64 | COLOR_BUTTON_SUCCESS_HOVER_TEXT = FFFFFF
65 | COLOR_BUTTON_WARNING_BACKGROUND = CEBF45
66 | COLOR_BUTTON_WARNING_TEXT = FFFFFF
67 | COLOR_BUTTON_WARNING_HOVER_BACKGROUND = E3D24C
68 | COLOR_BUTTON_WARNING_HOVER_TEXT = FFFFFF
69 | COLOR_BUTTON_DANGER_BACKGROUND = C84E4E
70 | COLOR_BUTTON_DANGER_TEXT = FFFFFF
71 | COLOR_BUTTON_DANGER_HOVER_BACKGROUND = DC5656
72 | COLOR_BUTTON_DANGER_HOVER_TEXT = FFFFFF
73 | COLOR_BUTTON_DISABLED_BACKGROUND = D1D1D1
74 | COLOR_BUTTON_DISABLED_TEXT = FFFFFF
75 | COLOR_BUTTON_DISABLED_TRANSFER = 414141
76 | COLOR_BUTTON_INPROGRESS_BACKGROUND = 4EA6EA
77 | COLOR_BUTTON_INPROGRESS_TEXT = FFFFFF
78 |
--------------------------------------------------------------------------------
/windows/dnd.c:
--------------------------------------------------------------------------------
1 |
2 | typedef struct {
3 | IDropTarget dt;
4 | LONG ref;
5 | } my_IDropTarget;
6 |
7 | ULONG __stdcall dnd_AddRef(IDropTarget *lpMyObj)
8 | {
9 | my_IDropTarget *p = (void*)lpMyObj;
10 | return InterlockedIncrement(&p->ref);
11 | }
12 |
13 | ULONG __stdcall dnd_Release(IDropTarget *lpMyObj)
14 | {
15 | my_IDropTarget *p = (void*)lpMyObj;
16 | LONG count = InterlockedDecrement(&p->ref);
17 |
18 | if(!count) {
19 | free(lpMyObj->lpVtbl);
20 | free(lpMyObj);
21 | }
22 |
23 | return count;
24 | }
25 |
26 | HRESULT __stdcall dnd_QueryInterface(IDropTarget *lpMyObj, REFIID riid, LPVOID FAR * lppvObj)
27 | {
28 | *lppvObj = NULL;
29 |
30 | // PRINT_GUID (riid);
31 | if (IsEqualIID (riid, &IID_IUnknown) || IsEqualIID (riid, &IID_IDropTarget))
32 | {
33 | dnd_AddRef (lpMyObj);
34 | *lppvObj = lpMyObj;
35 | return S_OK;
36 | }
37 |
38 | return E_NOINTERFACE;
39 | }
40 |
41 | HRESULT __stdcall dnd_DragEnter(IDropTarget *lpMyObj, IDataObject * pDataObject, DWORD grfKeyState, POINTL pt, DWORD * pdwEffect)
42 | {
43 | *pdwEffect = DROPEFFECT_COPY;
44 | return S_OK;
45 | }
46 |
47 | HRESULT __stdcall dnd_DragOver(IDropTarget *lpMyObj, DWORD grfKeyState, POINTL pt, DWORD * pdwEffect)
48 | {
49 | *pdwEffect = DROPEFFECT_COPY;
50 | return S_OK;
51 | }
52 |
53 | HRESULT __stdcall dnd_DragLeave(IDropTarget *lpMyObj)
54 | {
55 | return S_OK;
56 | }
57 |
58 | HRESULT __stdcall dnd_Drop(IDropTarget *lpMyObj, IDataObject * pDataObject, DWORD grfKeyState, POINTL pt, DWORD * pdwEffect)
59 | {
60 | *pdwEffect = DROPEFFECT_COPY;
61 | debug("droppped!\n");
62 |
63 | if(selected_item->item != ITEM_FRIEND) {
64 | return S_OK;
65 | }
66 |
67 | FORMATETC format = {
68 | .cfFormat = CF_HDROP,
69 | .dwAspect = DVASPECT_CONTENT,
70 | .lindex = -1,
71 | .tymed = TYMED_HGLOBAL,
72 | };
73 | STGMEDIUM medium;
74 |
75 | HRESULT r = pDataObject->lpVtbl->GetData(pDataObject, &format, &medium);
76 | if(r == S_OK) {
77 | HDROP h = medium.hGlobal;
78 | int count = DragQueryFile(h, ~0, NULL, 0);
79 | debug("%u files dropped\n", count);
80 | int i;
81 |
82 | char *paths = malloc(count * 256);
83 | if(paths) {
84 | char *p = paths;
85 | for(i = 0; i != count; i++) {
86 | p += DragQueryFile(h, i, p, 256);
87 | *p++ = '\n';
88 | }
89 |
90 | tox_postmessage(TOX_SEND_NEW_FILE, (FRIEND*)selected_item->data - friend, 0xFFFF, paths);
91 | }
92 |
93 | ReleaseStgMedium(&medium);
94 | } else {
95 | debug("itz failed! %lX\n", r);
96 | }
97 |
98 | return S_OK;
99 | }
100 |
101 | static void dnd_init(HWND window)
102 | {
103 | my_IDropTarget *p;
104 | p = malloc(sizeof(my_IDropTarget));
105 | p->dt.lpVtbl = malloc(sizeof(*(p->dt.lpVtbl)));
106 | p->ref = 0;
107 |
108 | p->dt.lpVtbl->QueryInterface = dnd_QueryInterface;
109 | p->dt.lpVtbl->AddRef = dnd_AddRef;
110 | p->dt.lpVtbl->Release = dnd_Release;
111 |
112 | p->dt.lpVtbl->DragEnter = dnd_DragEnter;
113 | p->dt.lpVtbl->DragLeave = dnd_DragLeave;
114 | p->dt.lpVtbl->DragOver = dnd_DragOver;
115 | p->dt.lpVtbl->Drop = dnd_Drop;
116 |
117 | CoLockObjectExternal((struct IUnknown*)p, TRUE, FALSE);
118 |
119 | RegisterDragDrop(window, (IDropTarget*)p);
120 | }
121 |
--------------------------------------------------------------------------------
/windows/example.reg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/notsecure/uTox/f04c40f597a1c3cfaeaea969882bdab5bb442436/windows/example.reg
--------------------------------------------------------------------------------
/windows/main.7.c:
--------------------------------------------------------------------------------
1 | #ifndef _WIN32_WINNT
2 | #define _WIN32_WINNT 0x0600
3 | #endif
4 |
5 | #include
6 |
7 | void launch_at_startup(int is_launch_at_startup){
8 | HKEY hKey;
9 | const wchar_t* run_key_path = L"Software\\Microsoft\\Windows\\CurrentVersion\\Run";
10 | wchar_t path[UTOX_FILE_NAME_LENGTH*2];
11 | uint16_t path_length = 0, ret = 0;
12 | if(is_launch_at_startup == 1){
13 | if(ERROR_SUCCESS == RegOpenKeyW(HKEY_CURRENT_USER, run_key_path, &hKey)){
14 | path_length = GetModuleFileNameW(NULL, path+1, UTOX_FILE_NAME_LENGTH*2);
15 | path[0] = '\"';
16 | path[path_length+1] = '\"';
17 | path[path_length+2] = '\0';
18 | path_length += 2;
19 | ret = RegSetKeyValueW(hKey, NULL, (LPCSTR)(L"uTox"), REG_SZ, path, path_length*2); /*2 bytes per wchar */
20 | if(ret == ERROR_SUCCESS){
21 | debug("Successful auto start addition.\n");
22 | }
23 | RegCloseKey(hKey);
24 | }
25 | }
26 | if(is_launch_at_startup == 0){
27 | if(ERROR_SUCCESS == RegOpenKeyW(HKEY_CURRENT_USER, run_key_path, &hKey)){
28 | ret = RegDeleteKeyValueW(hKey, NULL, L"uTox");
29 | if(ret == ERROR_SUCCESS){
30 | debug("Successful auto start deletion.\n");
31 | }
32 | RegCloseKey(hKey);
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/windows/main.XP.c:
--------------------------------------------------------------------------------
1 | void launch_at_startup(int is_launch_at_startup){
2 | HKEY hKey;
3 | const wchar_t* run_key_path = L"Software\\Microsoft\\Windows\\CurrentVersion\\Run";
4 | wchar_t path[UTOX_FILE_NAME_LENGTH*2];
5 | uint16_t path_length = 0, ret = 0;
6 | if(is_launch_at_startup == 1){
7 | if(ERROR_SUCCESS == RegOpenKeyW(HKEY_CURRENT_USER, run_key_path, &hKey)){
8 | path_length = GetModuleFileNameW(NULL, path+1, UTOX_FILE_NAME_LENGTH*2);
9 | path[0] = '\"';
10 | path[path_length+1] = '\"';
11 | path[path_length+2] = '\0';
12 | path_length += 2;
13 | ret = RegSetValueExW(hKey, L"uTox", NULL, REG_SZ, (uint8_t*)path, path_length*2); /*2 bytes per wchar */
14 | if(ret == ERROR_SUCCESS){
15 | debug("Successful auto start addition.\n");
16 | }
17 | RegCloseKey(hKey);
18 | }
19 | }
20 | if(is_launch_at_startup == 0){
21 | debug("Going to delete auto start key.\n");
22 | if(ERROR_SUCCESS == RegOpenKeyW(HKEY_CURRENT_USER, run_key_path, &hKey)){
23 | debug("Successful key opened.\n");
24 | ret = RegDeleteValueW(hKey, L"uTox");
25 | if(ret == ERROR_SUCCESS){
26 | debug("Successful auto start deletion.\n");
27 | } else {
28 | debug("UN-Successful auto start deletion.\n");
29 | }
30 | RegCloseKey(hKey);
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/windows/main.h:
--------------------------------------------------------------------------------
1 | /** Select the true main.c for legacy XP support.
2 | * else default to xlib
3 | **/
4 | #ifndef __WIN_LEGACY
5 | #undef _WIN32_WINNT
6 | #define _WIN32_WINNT 0x0600
7 | #endif
8 |
9 | #ifndef WINVER
10 | #define WINVER 0x410
11 | #endif
12 |
13 | #undef CLEARTYPE_QUALITY
14 | #define CLEARTYPE_QUALITY 5
15 |
16 | #define STRSAFE_NO_DEPRECATE
17 | #include
18 | #include
19 | #include
20 |
21 | #define KEY_BACK VK_BACK
22 | #define KEY_RETURN VK_RETURN
23 | #define KEY_LEFT VK_LEFT
24 | #define KEY_RIGHT VK_RIGHT
25 | #define KEY_TAB VK_TAB
26 | #define KEY_DEL VK_DELETE
27 | #define KEY_END VK_END
28 | #define KEY_HOME VK_HOME
29 | #define KEY_UP VK_UP
30 | #define KEY_DOWN VK_DOWN
31 | #define KEY_PAGEUP VK_PRIOR
32 | #define KEY_PAGEDOWN VK_NEXT
33 |
34 | #define debug(...) printf(__VA_ARGS__); fflush(stdout)
35 |
36 | #define KEY(x) (x)
37 |
38 | #ifdef __MINGW32__
39 | #define fseeko fseeko64
40 | #define ftello ftello64
41 | #endif
42 |
43 | // internal representation of an image
44 | typedef struct utox_native_image {
45 | HBITMAP bitmap; // 32 bit bitmap containing
46 | // red, green, blue and alpha
47 |
48 | _Bool has_alpha; // whether bitmap has an alpha channel
49 |
50 | // width and height in pixels of the bitmap
51 | uint32_t width, height;
52 |
53 | // width and height in pixels the image should be drawn to
54 | uint32_t scaled_width, scaled_height;
55 |
56 | // stretch mode used when stretching this image, either
57 | // COLORONCOLOR(ugly and fast), or HALFTONE(prettier and slower)
58 | int stretch_mode;
59 |
60 | } UTOX_NATIVE_IMAGE;
61 |
62 | #define UTOX_NATIVE_IMAGE_IS_VALID(x) (NULL != (x))
63 | #define UTOX_NATIVE_IMAGE_HAS_ALPHA(x) (x->has_alpha)
64 |
65 |
66 | #define STRSAFE_NO_DEPRECATE
67 |
68 | #ifdef __CRT__NO_INLINE
69 | #undef __CRT__NO_INLINE
70 | #define DID_UNDEFINE__CRT__NO_INLINE
71 | #include
72 | #ifdef DID_UNDEFINE__CRT__NO_INLINE
73 | #define __CRT__NO_INLINE
74 | #endif
75 | #endif
76 |
77 | #include
78 | #include
79 | #include
80 | #include
81 | #include
82 |
83 | #include
84 | extern const CLSID CLSID_SampleGrabber;
85 | extern const CLSID CLSID_NullRenderer;
86 |
87 | #include
88 | #include
89 | #include
90 |
91 | #include
92 |
93 | #include
94 | #include
95 |
96 | #undef CLEARTYPE_QUALITY
97 | #define CLEARTYPE_QUALITY 5
98 |
99 | #define WM_NOTIFYICON (WM_APP + 0)
100 | #define WM_TOX (WM_APP + 1)
101 |
102 | LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
103 |
104 |
105 | enum {
106 | MENU_TEXTINPUT = 101,
107 | MENU_MESSAGES = 102,
108 | };
109 |
110 | //HBITMAP bitmap[32];
111 | void *bitmap[BM_CI1 + 1];
112 | HFONT font[32];
113 | HCURSOR cursors[8];
114 | HICON my_icon, unread_messages_icon;
115 |
116 | HWND hwnd, capturewnd;
117 | HINSTANCE hinstance;
118 | HDC main_hdc, hdc, hdcMem;
119 | HBRUSH hdc_brush;
120 | HBITMAP hdc_bm;
121 | HWND video_hwnd[MAX_NUM_FRIENDS];
122 |
123 |
124 | //static char save_path[280];
125 |
126 | static _Bool flashing, desktopgrab_video;
127 |
128 |
129 | static _Bool hidden;
130 |
131 | _Bool utox_portable;
132 | char utox_portable_save_path[MAX_PATH];
133 |
134 | //WM_COMMAND
135 | enum
136 | {
137 | TRAY_SHOWHIDE,
138 | TRAY_EXIT,
139 | TRAY_STATUS_AVAILABLE,
140 | TRAY_STATUS_AWAY,
141 | TRAY_STATUS_BUSY,
142 | };
143 |
--------------------------------------------------------------------------------
/xlib/audio.c:
--------------------------------------------------------------------------------
1 |
2 | void audio_detect(void)
3 | {
4 | }
5 |
6 | _Bool audio_init(void *handle)
7 | {
8 | return 0;
9 | }
10 |
11 | _Bool audio_close(void *handle)
12 | {
13 | return 0;
14 | }
15 |
16 | _Bool audio_frame(int16_t *buffer)
17 | {
18 | return 0;
19 | }
20 |
--------------------------------------------------------------------------------
/xlib/dbus.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #define NOTIFY_OBJECT "/org/freedesktop/Notifications"
5 | #define NOTIFY_INTERFACE "org.freedesktop.Notifications"
6 |
7 | static sig_atomic_t done;
8 |
9 | static int notify_build_message(DBusMessage* notify_msg, char *title, char *content, uint8_t *cid)
10 | {
11 | DBusMessageIter args[4];
12 | char *app_name = "uTox";
13 | uint32_t replaces_id = -1;
14 | char_t app_icon_data[UTOX_FILE_NAME_LENGTH];
15 | char *app_icon = "";
16 | int32_t timeout = 5000;
17 | dbus_bool_t m = 0;
18 | char* key = "foo";
19 | int value = 42;
20 |
21 | // Gets the avatar of the user to be displayed in the notification
22 | if(cid != NULL) {
23 | char_t string_cid[TOX_PUBLIC_KEY_SIZE * 2];
24 | cid_to_string(string_cid, cid);
25 | get_avatar_location(app_icon_data, string_cid);
26 | app_icon = (char*) app_icon_data;
27 | }
28 |
29 | dbus_message_iter_init_append(notify_msg, &args[0]);
30 | m |= dbus_message_iter_append_basic(&args[0], DBUS_TYPE_STRING, &app_name);
31 | m |= dbus_message_iter_append_basic(&args[0], DBUS_TYPE_UINT32, &replaces_id);
32 | m |= dbus_message_iter_append_basic(&args[0], DBUS_TYPE_STRING, &app_icon);
33 | m |= dbus_message_iter_append_basic(&args[0], DBUS_TYPE_STRING, &title);
34 | m |= dbus_message_iter_append_basic(&args[0], DBUS_TYPE_STRING, &content);
35 |
36 | m |= dbus_message_iter_open_container(&args[0],DBUS_TYPE_ARRAY,DBUS_TYPE_STRING_AS_STRING,&args[1]);
37 | /*for (i = 0; array[i]; i++ )
38 | m |= dbus_message_iter_append_basic(&args[1], DBUS_TYPE_STRING, &array[i]);*/
39 | m |= dbus_message_iter_close_container(&args[0],&args[1]);
40 |
41 | m |= dbus_message_iter_open_container(&args[0],DBUS_TYPE_ARRAY,"{sv}",&args[1]); /* usually {sv} for dictionaries */
42 | m |= dbus_message_iter_open_container(&args[1],DBUS_TYPE_DICT_ENTRY,NULL,&args[2]);
43 | m |= dbus_message_iter_append_basic(&args[2],DBUS_TYPE_STRING,&key);
44 | m |= dbus_message_iter_open_container(&args[2],DBUS_TYPE_VARIANT,DBUS_TYPE_INT32_AS_STRING,&args[3]);
45 | m |= dbus_message_iter_append_basic(&args[3],DBUS_TYPE_INT32,&value);
46 | m |= dbus_message_iter_close_container(&args[2],&args[3]);
47 | m |= dbus_message_iter_close_container(&args[1],&args[2]);
48 | m |= dbus_message_iter_close_container(&args[0],&args[1]);
49 | m |= dbus_message_iter_append_basic(&args[0], DBUS_TYPE_INT32, &timeout);
50 |
51 | return m;
52 | }
53 |
54 | static void notify_callback(DBusPendingCall* pending, void* user_data)
55 | {
56 | done = 1;
57 | }
58 |
59 | void dbus_notify(char *title, char *content, uint8_t *cid)
60 | {
61 | DBusMessage *msg;
62 | DBusConnection* conn;
63 | DBusError err;
64 | DBusPendingCall* pending;
65 |
66 | dbus_error_init(&err);
67 | conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
68 |
69 | if(dbus_error_is_set(&err)) {
70 | fprintf(stderr, "Connection Error (%s)\n", err.message);
71 | dbus_error_free(&err);
72 | }
73 |
74 | if(!conn) {
75 | return;
76 | }
77 |
78 | msg = dbus_message_new_method_call(NULL, NOTIFY_OBJECT, NOTIFY_INTERFACE, "Notify");
79 |
80 | if(!msg) {
81 | //fprintf(stderr, "Message Null\n");
82 | //exit(1);
83 | return;
84 | }
85 |
86 | dbus_message_set_auto_start(msg, TRUE);
87 | dbus_message_set_destination(msg, NOTIFY_INTERFACE);
88 |
89 | /* append arguments
90 | UINT32 org.freedesktop.Notifications.Notify (STRING app_name, UINT32 replaces_id, STRING app_icon, STRING summary, STRING body, ARRAY actions, DICT hints, INT32 expire_timeout); */
91 |
92 | if(!notify_build_message(msg, title, content, cid)) {
93 | //fprintf(stderr, "Out Of Memory!\n");
94 | return;
95 | }
96 |
97 | dbus_error_init(&err);
98 |
99 | if(!dbus_connection_send_with_reply(conn, msg, &pending, -1)) {
100 | fprintf(stderr, "Sending failed!\n");
101 | exit(1);
102 | }
103 |
104 | if(!dbus_pending_call_set_notify(pending, ¬ify_callback, NULL, NULL)) {
105 | //fprintf(stderr, "Callback failed!");
106 | return;
107 | }
108 |
109 | while(!done) {
110 | dbus_connection_read_write_dispatch(conn, -1);
111 | }
112 |
113 | dbus_message_unref(msg);
114 | dbus_connection_unref(conn);
115 |
116 | return;
117 | }
118 |
--------------------------------------------------------------------------------
/xlib/main.h:
--------------------------------------------------------------------------------
1 |
2 |
3 | #include
4 |
5 | #include
6 |
7 | #ifdef __APPLE__
8 | #include
9 | #else
10 | #include
11 | #endif
12 |
13 | #include
14 |
15 | #include
16 |
17 | #define debug(...) printf(__VA_ARGS__)
18 |
19 | #define RGB(r, g, b) (((r) << 16) | ((g) << 8) | (b))
20 |
21 | #define KEY_BACK XK_BackSpace
22 | #define KEY_RETURN XK_Return
23 | #define KEY_LEFT XK_Left
24 | #define KEY_RIGHT XK_Right
25 | #define KEY_TAB XK_Tab
26 | #define KEY_LEFT_TAB XK_ISO_Left_Tab
27 | #define KEY_DEL XK_Delete
28 | #define KEY_END XK_End
29 | #define KEY_HOME XK_Home
30 | #define KEY_UP XK_Up
31 | #define KEY_DOWN XK_Down
32 | #define KEY_PAGEUP XK_Page_Up
33 | #define KEY_PAGEDOWN XK_Page_Down
34 |
35 | #define KEY(x) (x + 'a' - 'A')
36 |
37 | typedef struct utox_native_image {
38 | // This is really a Picture, but it is just a typedef for XID, and I didn't
39 | // want to clutter namespace with #include for it.
40 | XID rgb;
41 | XID alpha;
42 | } UTOX_NATIVE_IMAGE;
43 |
44 | #define UTOX_NATIVE_IMAGE_IS_VALID(x) (None != (x))
45 | #define UTOX_NATIVE_IMAGE_HAS_ALPHA(x) (None != (x->alpha))
46 |
--------------------------------------------------------------------------------
/xlib/mmenu.c:
--------------------------------------------------------------------------------
1 | MessagingMenuApp *mmapp;
2 | UnityLauncherEntry *launcher;
3 | GMainLoop *mmloop;
4 | _Bool unity_running;
5 |
6 | char_t f_name_data[TOX_MAX_NAME_LENGTH] = "";
7 | char_t f_id_data[TOX_PUBLIC_KEY_SIZE * 2 + 1] = "";
8 | char_t f_id_data_on_minimize[TOX_PUBLIC_KEY_SIZE * 2 + 1] = "";
9 | uint_fast32_t unread_friends = 0;
10 |
11 | // Checks if the current desktop is unity
12 | _Bool is_unity_running()
13 | {
14 | if(strcmp(getenv("XDG_CURRENT_DESKTOP"), "Unity") == 0) {
15 | return 1;
16 | }
17 | else {
18 | return 0;
19 | }
20 | }
21 |
22 | // Runs the main event loop
23 | void run_mmloop()
24 | {
25 | g_main_loop_run(mmloop);
26 | }
27 |
28 | // Function called once the user presses an entry in the MessagingMenu
29 | static void source_activated(MessagingMenuApp *mmapp_, const gchar *source_id, gpointer user_data)
30 | {
31 | // TODO
32 | }
33 |
34 | // Sets the user status in the Messaging Menu
35 | void mm_set_status(int status)
36 | {
37 | switch(status) {
38 |
39 | case 0:
40 | messaging_menu_app_set_status(mmapp, MESSAGING_MENU_STATUS_AVAILABLE);
41 | break;
42 |
43 | case 1:
44 | messaging_menu_app_set_status(mmapp, MESSAGING_MENU_STATUS_AWAY);
45 | break;
46 |
47 | case 2:
48 | messaging_menu_app_set_status(mmapp, MESSAGING_MENU_STATUS_BUSY);
49 | break;
50 | }
51 | }
52 |
53 | // Function called once the user changes its status in the MessagingMenu
54 | static void status_changed(MessagingMenuApp *mmapp_, gint status, gpointer user_data)
55 | {
56 | switch(status) {
57 | case MESSAGING_MENU_STATUS_AVAILABLE:
58 | self.status = 0;
59 | tox_postmessage(TOX_SETSTATUS, 0, 0, NULL);
60 | break;
61 |
62 | case MESSAGING_MENU_STATUS_AWAY:
63 | self.status = 1;
64 | tox_postmessage(TOX_SETSTATUS, 1, 0, NULL);
65 | break;
66 |
67 | case MESSAGING_MENU_STATUS_BUSY:
68 | self.status = 2;
69 | tox_postmessage(TOX_SETSTATUS, 2, 0, NULL);
70 | break;
71 |
72 | default:
73 | self.status = 1;
74 | tox_postmessage(TOX_SETSTATUS, 1, 0, NULL);
75 | break;
76 | }
77 |
78 | drawalpha(BM_ONLINE + status, SELF_STATUS_X + BM_STATUSAREA_WIDTH / 2 - BM_STATUS_WIDTH / 2, SELF_STATUS_Y + BM_STATUSAREA_HEIGHT / 2 - BM_STATUS_WIDTH / 2, BM_STATUS_WIDTH, BM_STATUS_WIDTH, status_color[status]);
79 |
80 | }
81 |
82 | // Registers the app in the Unity Messaging Menu
83 | void mm_register()
84 | {
85 | mmapp = messaging_menu_app_new("utox.desktop");
86 | launcher = unity_launcher_entry_get_for_desktop_id("utox.desktop");
87 | messaging_menu_app_register(mmapp);
88 | g_signal_connect(mmapp, "activate-source", G_CALLBACK (source_activated), NULL);
89 | g_signal_connect(mmapp, "status-changed", G_CALLBACK (status_changed), NULL);
90 | mmloop = g_main_loop_new(NULL, FALSE);
91 | thread(run_mmloop, NULL);
92 | }
93 |
94 | // Unregisters the app from the Unity Messaging Menu
95 | void mm_unregister()
96 | {
97 | messaging_menu_app_unregister(mmapp);
98 | g_object_unref(mmapp);
99 | g_main_loop_unref(mmloop);
100 | }
101 |
102 | // Saves the current user ID when minimized
103 | void mm_save_cid()
104 | {
105 | strcpy((char*)f_id_data_on_minimize, (char*)f_id_data);
106 | }
107 |
108 | // Checks if a user is in the Messaging Menu
109 | _Bool is_in_mm(uint8_t *f_id)
110 | {
111 | if(f_id == NULL) {
112 | strcpy((char*)f_id_data, (char*)f_id_data_on_minimize);
113 | }
114 | else {
115 | cid_to_string(f_id_data, f_id);
116 | f_id_data[TOX_PUBLIC_KEY_SIZE * 2] = '\0';
117 | }
118 |
119 | if(f_id_data[0] != '\0') {
120 | if(messaging_menu_app_has_source(mmapp, (gchar*)f_id_data)) {
121 | return 1;
122 | }
123 | }
124 |
125 | return 0;
126 | }
127 |
128 | // Adds an entry to the MessagingMenu
129 | gboolean add_source()
130 | {
131 | messaging_menu_app_append_source(mmapp, (gchar*)f_id_data, NULL, (gchar*)f_name_data);
132 | messaging_menu_app_draw_attention(mmapp, (gchar*)f_id_data);
133 | unread_friends++;
134 | unity_launcher_entry_set_count(launcher, unread_friends);
135 | if(unread_friends == 1) {
136 | unity_launcher_entry_set_count_visible(launcher, TRUE);
137 | }
138 | return FALSE;
139 | }
140 |
141 | // Adds a new notification to the Messaging Menu.
142 | void mm_notify(char_t *f_name, uint8_t *f_id)
143 | {
144 | if(!is_in_mm(f_id)) {
145 | strncpy((char*)f_name_data, (char*)f_name, TOX_MAX_NAME_LENGTH);
146 | g_idle_add(add_source, NULL);
147 | }
148 | }
149 |
150 | // Removes a source from the MessagingMenu
151 | gboolean remove_source()
152 | {
153 | messaging_menu_app_remove_source(mmapp, (gchar*)f_id_data);
154 | unread_friends--;
155 | unity_launcher_entry_set_count(launcher, unread_friends);
156 | if(unread_friends == 0) {
157 | unity_launcher_entry_set_count_visible(launcher, FALSE);
158 | }
159 | return FALSE;
160 | }
161 |
162 | // Removes a notification from the Messaging Menu.
163 | void mm_rm_entry(uint8_t *f_id)
164 | {
165 | if(is_in_mm(f_id)) {
166 | g_idle_add(remove_source, NULL);
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/xlib/mmenu.h:
--------------------------------------------------------------------------------
1 | /* Function which removes an entry from the messaging menu
2 | * Is called by xlib/{list,event}.c and takes in parameter a friend ID
3 | */
4 | void mm_rm_entry(uint8_t *f_id);
5 |
6 | /* Function which sets the user status in the messaging menu
7 | * Is called by ui_buttons.h
8 | */
9 | void mm_set_status(int status);
10 |
--------------------------------------------------------------------------------