mirror of
https://github.com/Tha14/toxic.git
synced 2024-11-22 21:33:02 +01:00
Lots of bug fixes and general code cleanup
This commit is contained in:
parent
92d76c7f99
commit
11701d22a1
@ -93,7 +93,7 @@ int complete_line(ToxWindow *self, const void *list, int n_items, int size)
|
|||||||
{
|
{
|
||||||
ChatContext *ctx = self->chatwin;
|
ChatContext *ctx = self->chatwin;
|
||||||
|
|
||||||
if (ctx->pos <= 0 || ctx->len <= 0 || ctx->len >= MAX_STR_SIZE || size > MAX_STR_SIZE)
|
if (ctx->pos <= 0 || ctx->len <= 0 || ctx->pos > ctx->len || ctx->len >= MAX_STR_SIZE || size > MAX_STR_SIZE)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
const char *L = (char *) list;
|
const char *L = (char *) list;
|
||||||
@ -136,7 +136,7 @@ int complete_line(ToxWindow *self, const void *list, int n_items, int size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string_is_empty(sub)) {
|
if (!sub[0]) {
|
||||||
free(sub);
|
free(sub);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -185,7 +185,7 @@ int complete_line(ToxWindow *self, const void *list, int n_items, int size)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
char tmpend[MAX_STR_SIZE];
|
char tmpend[MAX_STR_SIZE];
|
||||||
strcpy(tmpend, &ubuf[ctx->pos]);
|
snprintf(tmpend, sizeof(tmpend), "%s", &ubuf[ctx->pos]);
|
||||||
strcpy(&ubuf[strt], match);
|
strcpy(&ubuf[strt], match);
|
||||||
strcpy(&ubuf[strt + m_len], endchrs);
|
strcpy(&ubuf[strt + m_len], endchrs);
|
||||||
strcpy(&ubuf[strt + m_len + n_endchrs], tmpend);
|
strcpy(&ubuf[strt + m_len + n_endchrs], tmpend);
|
||||||
@ -193,7 +193,7 @@ int complete_line(ToxWindow *self, const void *list, int n_items, int size)
|
|||||||
/* convert to widechar and copy back to original buf */
|
/* convert to widechar and copy back to original buf */
|
||||||
wchar_t newbuf[MAX_STR_SIZE];
|
wchar_t newbuf[MAX_STR_SIZE];
|
||||||
|
|
||||||
if (mbs_to_wcs_buf(newbuf, ubuf, MAX_STR_SIZE) == -1)
|
if (mbs_to_wcs_buf(newbuf, ubuf, sizeof(newbuf) / sizeof(wchar_t)) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
wcscpy(ctx->line, newbuf);
|
wcscpy(ctx->line, newbuf);
|
||||||
@ -218,7 +218,7 @@ static void complt_home_dir(ToxWindow *self, char *path, int pathsize, const cha
|
|||||||
|
|
||||||
wchar_t wline[MAX_STR_SIZE];
|
wchar_t wline[MAX_STR_SIZE];
|
||||||
|
|
||||||
if (mbs_to_wcs_buf(wline, newline, sizeof(wline)) == -1)
|
if (mbs_to_wcs_buf(wline, newline, sizeof(wline) / sizeof(wchar_t)) == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int newlen = wcslen(wline);
|
int newlen = wcslen(wline);
|
||||||
@ -261,10 +261,10 @@ int dir_match(ToxWindow *self, Tox *m, const wchar_t *line, const wchar_t *cmd)
|
|||||||
} else if (!si && b_path[0] != '/') { /* look for matches in pwd */
|
} else if (!si && b_path[0] != '/') { /* look for matches in pwd */
|
||||||
char tmp[MAX_STR_SIZE];
|
char tmp[MAX_STR_SIZE];
|
||||||
snprintf(tmp, sizeof(tmp), ".%s", b_path);
|
snprintf(tmp, sizeof(tmp), ".%s", b_path);
|
||||||
strcpy(b_path, tmp);
|
snprintf(b_path, sizeof(b_path), "%s", tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(b_name, &b_path[si + 1]);
|
snprintf(b_name, sizeof(b_name), "%s", &b_path[si + 1]);
|
||||||
b_path[si + 1] = '\0';
|
b_path[si + 1] = '\0';
|
||||||
int b_name_len = strlen(b_name);
|
int b_name_len = strlen(b_name);
|
||||||
DIR *dp = opendir(b_path);
|
DIR *dp = opendir(b_path);
|
||||||
|
@ -541,7 +541,7 @@ static void chat_onFileRecv(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_
|
|||||||
snprintf(file_path, sizeof(file_path), "%s", filename);
|
snprintf(file_path, sizeof(file_path), "%s", filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path_len >= sizeof(ft->file_path) || name_length >= sizeof(ft->file_name)) {
|
if (path_len >= sizeof(file_path) || path_len >= sizeof(ft->file_path) || name_length >= sizeof(ft->file_name)) {
|
||||||
tox_file_control(m, friendnum, filenum, TOX_FILE_CONTROL_CANCEL, NULL);
|
tox_file_control(m, friendnum, filenum, TOX_FILE_CONTROL_CANCEL, NULL);
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer faield: File path too long.");
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer faield: File path too long.");
|
||||||
return;
|
return;
|
||||||
@ -937,7 +937,7 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
|
|||||||
|
|
||||||
if (diff != -1) {
|
if (diff != -1) {
|
||||||
if (x + diff > x2 - 1) {
|
if (x + diff > x2 - 1) {
|
||||||
int wlen = wcswidth(ctx->line, sizeof(ctx->line));
|
int wlen = MAX(0, wcswidth(ctx->line, sizeof(ctx->line) / sizeof(wchar_t)));
|
||||||
ctx->start = wlen < x2 ? 0 : wlen - x2 + 1;
|
ctx->start = wlen < x2 ? 0 : wlen - x2 + 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1091,7 +1091,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
|
|||||||
int y, x;
|
int y, x;
|
||||||
getyx(self->window, y, x);
|
getyx(self->window, y, x);
|
||||||
(void) x;
|
(void) x;
|
||||||
int new_x = ctx->start ? x2 - 1 : wcswidth(ctx->line, ctx->pos);
|
int new_x = ctx->start ? x2 - 1 : MAX(0, wcswidth(ctx->line, ctx->pos));
|
||||||
wmove(self->window, y + 1, new_x);
|
wmove(self->window, y + 1, new_x);
|
||||||
|
|
||||||
wrefresh(self->window);
|
wrefresh(self->window);
|
||||||
|
18
src/dns.c
18
src/dns.c
@ -234,12 +234,16 @@ static int parse_dns_response(ToxWindow *self, u_char *answer, int ans_len, char
|
|||||||
and the domain in dombuf.
|
and the domain in dombuf.
|
||||||
|
|
||||||
return length of username on success, -1 on failure */
|
return length of username on success, -1 on failure */
|
||||||
static int parse_addr(const char *addr, char *namebuf, char *dombuf)
|
static int parse_addr(const char *addr, char *namebuf, size_t namebuf_sz, char *dombuf, size_t dombuf_sz)
|
||||||
{
|
{
|
||||||
char tmpaddr[MAX_STR_SIZE];
|
if (strlen(addr) >= MAX_STR_SIZE)
|
||||||
char *tmpname, *tmpdom;
|
return -1;
|
||||||
|
|
||||||
strcpy(tmpaddr, addr);
|
char tmpaddr[MAX_STR_SIZE];
|
||||||
|
char *tmpname = NULL;
|
||||||
|
char *tmpdom = NULL;
|
||||||
|
|
||||||
|
snprintf(tmpaddr, sizeof(tmpaddr), "%s", addr);
|
||||||
tmpname = strtok(tmpaddr, "@");
|
tmpname = strtok(tmpaddr, "@");
|
||||||
tmpdom = strtok(NULL, "");
|
tmpdom = strtok(NULL, "");
|
||||||
|
|
||||||
@ -247,8 +251,8 @@ static int parse_addr(const char *addr, char *namebuf, char *dombuf)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
str_to_lower(tmpdom);
|
str_to_lower(tmpdom);
|
||||||
strcpy(namebuf, tmpname);
|
snprintf(namebuf, namebuf_sz, "%s", tmpname);
|
||||||
strcpy(dombuf, tmpdom);
|
snprintf(dombuf, dombuf_sz, "%s", tmpdom);
|
||||||
|
|
||||||
return strlen(namebuf);
|
return strlen(namebuf);
|
||||||
}
|
}
|
||||||
@ -295,7 +299,7 @@ void *dns3_lookup_thread(void *data)
|
|||||||
char inputdomain[MAX_STR_SIZE];
|
char inputdomain[MAX_STR_SIZE];
|
||||||
char name[MAX_STR_SIZE];
|
char name[MAX_STR_SIZE];
|
||||||
|
|
||||||
int namelen = parse_addr(t_data.addr, name, inputdomain);
|
int namelen = parse_addr(t_data.addr, name, sizeof(name), inputdomain, sizeof(inputdomain));
|
||||||
|
|
||||||
if (namelen == -1) {
|
if (namelen == -1) {
|
||||||
dns_error(self, "Must be a Tox ID or an address in the form username@domain");
|
dns_error(self, "Must be a Tox ID or an address in the form username@domain");
|
||||||
|
@ -285,7 +285,7 @@ void close_file_transfer(ToxWindow *self, Tox *m, struct FileTransfer *ft, int C
|
|||||||
tox_file_control(m, ft->friendnum, ft->filenum, (TOX_FILE_CONTROL) CTRL, NULL);
|
tox_file_control(m, ft->friendnum, ft->filenum, (TOX_FILE_CONTROL) CTRL, NULL);
|
||||||
|
|
||||||
if (message && self) {
|
if (message && self) {
|
||||||
if (self->active_box != -1)
|
if (self->active_box != -1 && sound_type != silent)
|
||||||
box_notify2(self, sound_type, NT_NOFOCUS | NT_WNDALERT_2, self->active_box, "%s", message);
|
box_notify2(self, sound_type, NT_NOFOCUS | NT_WNDALERT_2, self->active_box, "%s", message);
|
||||||
else
|
else
|
||||||
box_notify(self, sound_type, NT_NOFOCUS | NT_WNDALERT_2, &self->active_box, self->name, "%s", message);
|
box_notify(self, sound_type, NT_NOFOCUS | NT_WNDALERT_2, &self->active_box, self->name, "%s", message);
|
||||||
|
@ -139,8 +139,10 @@ static int save_blocklist(char *path)
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
for (i = 0; i < Blocked.max_idx; ++i) {
|
for (i = 0; i < Blocked.max_idx; ++i) {
|
||||||
if (count > Blocked.num_blocked)
|
if (count > Blocked.num_blocked) {
|
||||||
goto on_error;
|
free(data);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (Blocked.list[i].active) {
|
if (Blocked.list[i].active) {
|
||||||
BlockedFriend tmp;
|
BlockedFriend tmp;
|
||||||
@ -161,19 +163,20 @@ static int save_blocklist(char *path)
|
|||||||
|
|
||||||
FILE *fp = fopen(path, "wb");
|
FILE *fp = fopen(path, "wb");
|
||||||
|
|
||||||
if (fp == NULL)
|
if (fp == NULL) {
|
||||||
goto on_error;
|
free(data);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (fwrite(data, len, 1, fp) != 1)
|
if (fwrite(data, len, 1, fp) != 1) {
|
||||||
goto on_error;
|
fclose(fp);
|
||||||
|
free(data);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
free(data);
|
free(data);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
on_error:
|
|
||||||
free(data);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sort_blocklist_index(void);
|
static void sort_blocklist_index(void);
|
||||||
@ -221,9 +224,10 @@ int load_blocklist(char *path)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < num; ++i) {
|
for (i = 0; i < num; ++i) {
|
||||||
|
BlockedFriend tmp;
|
||||||
|
memset(&tmp, 0, sizeof(BlockedFriend));
|
||||||
memset(&Blocked.list[i], 0, sizeof(BlockedFriend));
|
memset(&Blocked.list[i], 0, sizeof(BlockedFriend));
|
||||||
|
|
||||||
BlockedFriend tmp;
|
|
||||||
memcpy(&tmp, data + i * sizeof(BlockedFriend), sizeof(BlockedFriend));
|
memcpy(&tmp, data + i * sizeof(BlockedFriend), sizeof(BlockedFriend));
|
||||||
Blocked.list[i].active = true;
|
Blocked.list[i].active = true;
|
||||||
Blocked.list[i].num = i;
|
Blocked.list[i].num = i;
|
||||||
|
@ -249,19 +249,22 @@ void cmd_connect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)
|
|||||||
|
|
||||||
const char *ip = argv[1];
|
const char *ip = argv[1];
|
||||||
const char *port = argv[2];
|
const char *port = argv[2];
|
||||||
const char *key = argv[3];
|
const char *ascii_key = argv[3];
|
||||||
|
|
||||||
if (atoi(port) == 0) {
|
if (atoi(port) == 0) {
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid port.");
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid port.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *binary_string = hex_string_to_bin(key);
|
char key_binary[TOX_PUBLIC_KEY_SIZE * 2 + 1];
|
||||||
|
if (hex_string_to_bin(ascii_key, strlen(ascii_key), key_binary, TOX_PUBLIC_KEY_SIZE) == -1) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid key.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
TOX_ERR_BOOTSTRAP err;
|
TOX_ERR_BOOTSTRAP err;
|
||||||
tox_bootstrap(m, ip, atoi(port), (uint8_t *) binary_string, &err);
|
tox_bootstrap(m, ip, atoi(port), (uint8_t *) key_binary, &err);
|
||||||
tox_add_tcp_relay(m, ip, atoi(port), (uint8_t *) binary_string, &err);
|
tox_add_tcp_relay(m, ip, atoi(port), (uint8_t *) key_binary, &err);
|
||||||
free(binary_string);
|
|
||||||
|
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case TOX_ERR_BOOTSTRAP_BAD_HOST:
|
case TOX_ERR_BOOTSTRAP_BAD_HOST:
|
||||||
|
@ -593,7 +593,7 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
|
|||||||
|
|
||||||
if (diff != -1) {
|
if (diff != -1) {
|
||||||
if (x + diff > x2 - 1) {
|
if (x + diff > x2 - 1) {
|
||||||
int wlen = wcswidth(ctx->line, sizeof(ctx->line));
|
int wlen = MAX(0, wcswidth(ctx->line, sizeof(ctx->line) / sizeof(wchar_t)));
|
||||||
ctx->start = wlen < x2 ? 0 : wlen - x2 + 1;
|
ctx->start = wlen < x2 ? 0 : wlen - x2 + 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -698,7 +698,7 @@ static void groupchat_onDraw(ToxWindow *self, Tox *m)
|
|||||||
int y, x;
|
int y, x;
|
||||||
getyx(self->window, y, x);
|
getyx(self->window, y, x);
|
||||||
(void) x;
|
(void) x;
|
||||||
int new_x = ctx->start ? x2 - 1 : wcswidth(ctx->line, ctx->pos);
|
int new_x = ctx->start ? x2 - 1 : MAX(0, wcswidth(ctx->line, ctx->pos));
|
||||||
wmove(self->window, y + 1, new_x);
|
wmove(self->window, y + 1, new_x);
|
||||||
|
|
||||||
wrefresh(self->window);
|
wrefresh(self->window);
|
||||||
@ -795,66 +795,66 @@ static int group_audio_close_out_device(int groupnum)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int group_audio_write(int peernum, int groupnum, const int16_t *pcm, unsigned int samples, uint8_t channels,
|
// static int group_audio_write(int peernum, int groupnum, const int16_t *pcm, unsigned int samples, uint8_t channels,
|
||||||
unsigned int sample_rate)
|
// unsigned int sample_rate)
|
||||||
{
|
// {
|
||||||
if (!pcm)
|
// if (!pcm)
|
||||||
return -1;
|
// return -1;
|
||||||
|
|
||||||
if (channels == 0 || channels > 2)
|
// if (channels == 0 || channels > 2)
|
||||||
return -2;
|
// return -2;
|
||||||
|
|
||||||
ALuint bufid;
|
// ALuint bufid;
|
||||||
ALint processed = 0, queued = 0;
|
// ALint processed = 0, queued = 0;
|
||||||
|
|
||||||
alGetSourcei(groupchats[groupnum].audio.source, AL_BUFFERS_PROCESSED, &processed);
|
// alGetSourcei(groupchats[groupnum].audio.source, AL_BUFFERS_PROCESSED, &processed);
|
||||||
alGetSourcei(groupchats[groupnum].audio.source, AL_BUFFERS_QUEUED, &queued);
|
// alGetSourcei(groupchats[groupnum].audio.source, AL_BUFFERS_QUEUED, &queued);
|
||||||
fprintf(stderr, "source: %d, queued: %d, processed: %d\n", groupchats[groupnum].audio.source, queued, processed);
|
// fprintf(stderr, "source: %d, queued: %d, processed: %d\n", groupchats[groupnum].audio.source, queued, processed);
|
||||||
|
|
||||||
if (processed) {
|
// if (processed) {
|
||||||
ALuint bufids[processed];
|
// ALuint bufids[processed];
|
||||||
alSourceUnqueueBuffers(groupchats[groupnum].audio.source, processed, bufids);
|
// alSourceUnqueueBuffers(groupchats[groupnum].audio.source, processed, bufids);
|
||||||
alDeleteBuffers(processed - 1, bufids + 1);
|
// alDeleteBuffers(processed - 1, bufids + 1);
|
||||||
bufid = bufids[0];
|
// bufid = bufids[0];
|
||||||
} else if (queued < 16) {
|
// } else if (queued < 16) {
|
||||||
alGenBuffers(1, &bufid);
|
// alGenBuffers(1, &bufid);
|
||||||
} else {
|
// } else {
|
||||||
return -3;
|
// return -3;
|
||||||
}
|
// }
|
||||||
|
|
||||||
int length = samples * channels * sizeof(int16_t);
|
// int length = samples * channels * sizeof(int16_t);
|
||||||
|
|
||||||
alBufferData(bufid, (channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, pcm, length, sample_rate);
|
// alBufferData(bufid, (channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, pcm, length, sample_rate);
|
||||||
alSourceQueueBuffers(groupchats[groupnum].audio.source, 1, &bufid);
|
// alSourceQueueBuffers(groupchats[groupnum].audio.source, 1, &bufid);
|
||||||
|
|
||||||
ALint state;
|
// ALint state;
|
||||||
alGetSourcei(groupchats[groupnum].audio.source, AL_SOURCE_STATE, &state);
|
// alGetSourcei(groupchats[groupnum].audio.source, AL_SOURCE_STATE, &state);
|
||||||
|
|
||||||
if (state != AL_PLAYING)
|
// if (state != AL_PLAYING)
|
||||||
alSourcePlay(groupchats[groupnum].audio.source);
|
// alSourcePlay(groupchats[groupnum].audio.source);
|
||||||
|
|
||||||
return 0;
|
// return 0;
|
||||||
}
|
// }
|
||||||
|
|
||||||
static void groupchat_onWriteDevice(ToxWindow *self, Tox *m, int groupnum, int peernum, const int16_t *pcm,
|
static void groupchat_onWriteDevice(ToxWindow *self, Tox *m, int groupnum, int peernum, const int16_t *pcm,
|
||||||
unsigned int samples, uint8_t channels, unsigned int sample_rate)
|
unsigned int samples, uint8_t channels, unsigned int sample_rate)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (groupnum != self->num)
|
// if (groupnum != self->num)
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
if (peernum < 0)
|
// if (peernum < 0)
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
if (groupchats[groupnum].audio.dvhandle == NULL)
|
// if (groupchats[groupnum].audio.dvhandle == NULL)
|
||||||
fprintf(stderr, "dvhandle is null)\n");
|
// fprintf(stderr, "dvhandle is null)\n");
|
||||||
|
|
||||||
if (groupchats[groupnum].audio.dvctx == NULL)
|
// if (groupchats[groupnum].audio.dvctx == NULL)
|
||||||
fprintf(stderr, "ctx is null\n");
|
// fprintf(stderr, "ctx is null\n");
|
||||||
|
|
||||||
int ret = group_audio_write(peernum, groupnum, pcm, samples, channels, sample_rate);
|
// int ret = group_audio_write(peernum, groupnum, pcm, samples, channels, sample_rate);
|
||||||
fprintf(stderr, "write: %d\n", ret);
|
// fprintf(stderr, "write: %d\n", ret);
|
||||||
}
|
}
|
||||||
#endif /* AUDIO */
|
#endif /* AUDIO */
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ static void input_yank(ToxWindow *self, int x, int mx_x)
|
|||||||
|
|
||||||
if (x + yank_cols >= mx_x) {
|
if (x + yank_cols >= mx_x) {
|
||||||
int rmdr = MAX(0, (x + yank_cols) - mx_x);
|
int rmdr = MAX(0, (x + yank_cols) - mx_x);
|
||||||
int s_len = wcswidth(&ctx->line[ctx->start], rmdr);
|
int s_len = MAX(0, wcswidth(&ctx->line[ctx->start], rmdr));
|
||||||
ctx->start += s_len + 1;
|
ctx->start += s_len + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,7 +137,7 @@ static void input_mv_end(ToxWindow *self, int y, int mx_x)
|
|||||||
|
|
||||||
ctx->pos = ctx->len;
|
ctx->pos = ctx->len;
|
||||||
|
|
||||||
int wlen = wcswidth(ctx->line, sizeof(ctx->line));
|
int wlen = MAX(0, wcswidth(ctx->line, sizeof(ctx->line) / sizeof(wchar_t)));
|
||||||
ctx->start = MAX(0, 1 + (mx_x * (wlen / mx_x) - mx_x) + (wlen % mx_x));
|
ctx->start = MAX(0, 1 + (mx_x * (wlen / mx_x) - mx_x) + (wlen % mx_x));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,7 +196,7 @@ static void input_history(ToxWindow *self, wint_t key, int mx_x)
|
|||||||
ChatContext *ctx = self->chatwin;
|
ChatContext *ctx = self->chatwin;
|
||||||
|
|
||||||
fetch_hist_item(ctx, key);
|
fetch_hist_item(ctx, key);
|
||||||
int wlen = wcswidth(ctx->line, sizeof(ctx->line));
|
int wlen = MAX(0, wcswidth(ctx->line, sizeof(ctx->line) / sizeof(wchar_t)));
|
||||||
ctx->start = wlen < mx_x ? 0 : wlen - mx_x + 1;
|
ctx->start = wlen < mx_x ? 0 : wlen - mx_x + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,6 +133,9 @@ static struct line_info *line_info_ret_queue(struct history *hst)
|
|||||||
void line_info_add(ToxWindow *self, const char *timestr, const char *name1, const char *name2, uint8_t type,
|
void line_info_add(ToxWindow *self, const char *timestr, const char *name1, const char *name2, uint8_t type,
|
||||||
uint8_t bold, uint8_t colour, const char *msg, ...)
|
uint8_t bold, uint8_t colour, const char *msg, ...)
|
||||||
{
|
{
|
||||||
|
if (!self)
|
||||||
|
return;
|
||||||
|
|
||||||
struct history *hst = self->chatwin->hst;
|
struct history *hst = self->chatwin->hst;
|
||||||
|
|
||||||
if (hst->queue_sz >= MAX_LINE_INFO_QUEUE)
|
if (hst->queue_sz >= MAX_LINE_INFO_QUEUE)
|
||||||
|
@ -179,7 +179,7 @@ void load_chat_history(ToxWindow *self, struct chatlog *log)
|
|||||||
if (sz <= 0)
|
if (sz <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char *hstbuf = malloc(sz);
|
char *hstbuf = malloc(sz + 1);
|
||||||
|
|
||||||
if (hstbuf == NULL)
|
if (hstbuf == NULL)
|
||||||
exit_toxic_err("failed in load_chat_history", FATALERR_MEMORY);
|
exit_toxic_err("failed in load_chat_history", FATALERR_MEMORY);
|
||||||
@ -196,6 +196,8 @@ void load_chat_history(ToxWindow *self, struct chatlog *log)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hstbuf[sz] = '\0';
|
||||||
|
|
||||||
/* Number of history lines to load: must not be larger than MAX_LINE_INFO_QUEUE - 2 */
|
/* Number of history lines to load: must not be larger than MAX_LINE_INFO_QUEUE - 2 */
|
||||||
int L = MIN(MAX_LINE_INFO_QUEUE - 2, user_settings->history_size);
|
int L = MIN(MAX_LINE_INFO_QUEUE - 2, user_settings->history_size);
|
||||||
int start, count = 0;
|
int start, count = 0;
|
||||||
|
@ -109,22 +109,27 @@ void get_elapsed_time_str(char *buf, int bufsize, uint64_t secs)
|
|||||||
snprintf(buf, bufsize, "%ld:%.2ld:%.2ld", hours, minutes, seconds);
|
snprintf(buf, bufsize, "%ld:%.2ld:%.2ld", hours, minutes, seconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *hex_string_to_bin(const char *hex_string)
|
/*
|
||||||
|
* Converts a hexidecimal string of length hex_len to binary format and puts the result in output.
|
||||||
|
* output_size must be exactly half of hex_len.
|
||||||
|
*
|
||||||
|
* Returns 0 on success.
|
||||||
|
* Returns -1 on failure.
|
||||||
|
*/
|
||||||
|
int hex_string_to_bin(const char *hex_string, size_t hex_len, char *output, size_t output_size)
|
||||||
{
|
{
|
||||||
size_t len = strlen(hex_string);
|
if (output_size == 0 || hex_len != output_size * 2)
|
||||||
char *val = malloc(len);
|
return -1;
|
||||||
|
|
||||||
if (val == NULL)
|
for (size_t i = 0; i < output_size; ++i) {
|
||||||
exit_toxic_err("failed in hex_string_to_bin", FATALERR_MEMORY);
|
sscanf(hex_string, "%2hhx", &output[i]);
|
||||||
|
hex_string += 2;
|
||||||
|
}
|
||||||
|
|
||||||
size_t i;
|
return 0;
|
||||||
|
|
||||||
for (i = 0; i < len; ++i, hex_string += 2)
|
|
||||||
sscanf(hex_string, "%2hhx", &val[i]);
|
|
||||||
|
|
||||||
return val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int hex_string_to_bytes(char *buf, int size, const char *keystr)
|
int hex_string_to_bytes(char *buf, int size, const char *keystr)
|
||||||
{
|
{
|
||||||
if (size % 2 != 0)
|
if (size % 2 != 0)
|
||||||
@ -147,6 +152,9 @@ int hex_string_to_bytes(char *buf, int size, const char *keystr)
|
|||||||
/* Returns 1 if the string is empty, 0 otherwise */
|
/* Returns 1 if the string is empty, 0 otherwise */
|
||||||
int string_is_empty(const char *string)
|
int string_is_empty(const char *string)
|
||||||
{
|
{
|
||||||
|
if (!string)
|
||||||
|
return true;
|
||||||
|
|
||||||
return string[0] == '\0';
|
return string[0] == '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,8 +41,14 @@
|
|||||||
|
|
||||||
void hst_to_net(uint8_t *num, uint16_t numbytes);
|
void hst_to_net(uint8_t *num, uint16_t numbytes);
|
||||||
|
|
||||||
/* convert a hex string to binary */
|
/*
|
||||||
char *hex_string_to_bin(const char *hex_string);
|
* Converts a hexidecimal string of length hex_len to binary format and puts the result in output.
|
||||||
|
* output_size must be exactly half of hex_len.
|
||||||
|
*
|
||||||
|
* Returns 0 on success.
|
||||||
|
* Returns -1 on failure.
|
||||||
|
*/
|
||||||
|
int hex_string_to_bin(const char *hex_string, size_t hex_len, char *output, size_t output_size);
|
||||||
|
|
||||||
/* convert a hex string to bytes. returns 0 on success, -1 on failure */
|
/* convert a hex string to bytes. returns 0 on success, -1 on failure */
|
||||||
int hex_string_to_bytes(char *buf, int size, const char *keystr);
|
int hex_string_to_bytes(char *buf, int size, const char *keystr);
|
||||||
|
24
src/notify.c
24
src/notify.c
@ -90,7 +90,7 @@ struct _ActiveNotifications {
|
|||||||
#ifdef BOX_NOTIFY
|
#ifdef BOX_NOTIFY
|
||||||
NotifyNotification* box;
|
NotifyNotification* box;
|
||||||
char messages[MAX_BOX_MSG_LEN + 1][MAX_BOX_MSG_LEN + 1];
|
char messages[MAX_BOX_MSG_LEN + 1][MAX_BOX_MSG_LEN + 1];
|
||||||
char title[24];
|
char title[64];
|
||||||
size_t size;
|
size_t size;
|
||||||
time_t n_timeout;
|
time_t n_timeout;
|
||||||
#endif
|
#endif
|
||||||
@ -153,25 +153,26 @@ bool is_playing(int source)
|
|||||||
static bool device_opened = false;
|
static bool device_opened = false;
|
||||||
time_t last_opened_update = 0;
|
time_t last_opened_update = 0;
|
||||||
|
|
||||||
bool m_open_device()
|
/* Opens primary device. Returns true on succe*/
|
||||||
|
void m_open_device()
|
||||||
{
|
{
|
||||||
last_opened_update = get_unix_time();
|
last_opened_update = get_unix_time();
|
||||||
|
|
||||||
if (device_opened) return true;
|
if (device_opened) return;
|
||||||
|
|
||||||
/* Blah error check */
|
/* Blah error check */
|
||||||
open_primary_device(output, &Control.device_idx, 48000, 20, 1);
|
open_primary_device(output, &Control.device_idx, 48000, 20, 1);
|
||||||
|
|
||||||
return (device_opened = true);
|
device_opened = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool m_close_device()
|
void m_close_device()
|
||||||
{
|
{
|
||||||
if (!device_opened) return true;
|
if (!device_opened) return;
|
||||||
|
|
||||||
close_device(output, Control.device_idx);
|
close_device(output, Control.device_idx);
|
||||||
|
|
||||||
return !(device_opened = false);
|
device_opened = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Terminate all sounds but wait for them to finish first */
|
/* Terminate all sounds but wait for them to finish first */
|
||||||
@ -598,9 +599,12 @@ int box_notify(ToxWindow* self, Notification notif, uint64_t flags, int* id_indi
|
|||||||
actives[id].id_indicator = id_indicator;
|
actives[id].id_indicator = id_indicator;
|
||||||
if (id_indicator) *id_indicator = id;
|
if (id_indicator) *id_indicator = id;
|
||||||
}
|
}
|
||||||
#endif
|
#else
|
||||||
|
if (id == -1)
|
||||||
|
return -1;
|
||||||
|
#endif /* SOUND_NOTIFY */
|
||||||
|
|
||||||
strncpy(actives[id].title, title, 24);
|
snprintf(actives[id].title, sizeof(actives[id].title), "%s", title);
|
||||||
if (strlen(title) > 23) strcpy(actives[id].title + 20, "...");
|
if (strlen(title) > 23) strcpy(actives[id].title + 20, "...");
|
||||||
|
|
||||||
va_list __ARGS__; va_start (__ARGS__, format);
|
va_list __ARGS__; va_start (__ARGS__, format);
|
||||||
@ -699,7 +703,7 @@ int box_silent_notify(ToxWindow* self, uint64_t flags, int* id_indicator, const
|
|||||||
*id_indicator = id;
|
*id_indicator = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(actives[id].title, title, 24);
|
snprintf(actives[id].title, sizeof(actives[id].title), "%s", title);
|
||||||
if (strlen(title) > 23) strcpy(actives[id].title + 20, "...");
|
if (strlen(title) > 23) strcpy(actives[id].title + 20, "...");
|
||||||
|
|
||||||
va_list __ARGS__; va_start (__ARGS__, format);
|
va_list __ARGS__; va_start (__ARGS__, format);
|
||||||
|
@ -212,7 +212,7 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
|
|||||||
|
|
||||||
if (diff != -1) {
|
if (diff != -1) {
|
||||||
if (x + diff > x2 - 1) {
|
if (x + diff > x2 - 1) {
|
||||||
int wlen = wcswidth(ctx->line, sizeof(ctx->line));
|
int wlen = MAX(0, wcswidth(ctx->line, sizeof(ctx->line) / sizeof(wchar_t)));
|
||||||
ctx->start = wlen < x2 ? 0 : wlen - x2 + 1;
|
ctx->start = wlen < x2 ? 0 : wlen - x2 + 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -330,7 +330,7 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
|
|||||||
getyx(self->window, y, x);
|
getyx(self->window, y, x);
|
||||||
(void) x;
|
(void) x;
|
||||||
|
|
||||||
int new_x = ctx->start ? x2 - 1 : wcswidth(ctx->line, ctx->pos);
|
int new_x = ctx->start ? x2 - 1 : MAX(0, wcswidth(ctx->line, ctx->pos));
|
||||||
wmove(self->window, y + 1, new_x);
|
wmove(self->window, y + 1, new_x);
|
||||||
|
|
||||||
wrefresh(self->window);
|
wrefresh(self->window);
|
||||||
|
@ -41,6 +41,7 @@ typedef struct {
|
|||||||
} FriendRequests;
|
} FriendRequests;
|
||||||
|
|
||||||
ToxWindow new_prompt(void);
|
ToxWindow new_prompt(void);
|
||||||
|
|
||||||
void prep_prompt_win(void);
|
void prep_prompt_win(void);
|
||||||
void prompt_init_statusbar(ToxWindow *self, Tox *m);
|
void prompt_init_statusbar(ToxWindow *self, Tox *m);
|
||||||
void prompt_update_nick(ToxWindow *prompt, const char *nick);
|
void prompt_update_nick(ToxWindow *prompt, const char *nick);
|
||||||
|
@ -167,6 +167,10 @@ static int detect_gnu_screen ()
|
|||||||
|
|
||||||
free (dyn_buffer);
|
free (dyn_buffer);
|
||||||
dyn_buffer = NULL;
|
dyn_buffer = NULL;
|
||||||
|
|
||||||
|
if (strlen(socket_path) + strlen(PATH_SEP_S) + strlen(socket_name) >= sizeof(mplex_data))
|
||||||
|
goto nomplex;
|
||||||
|
|
||||||
strcpy (mplex_data, socket_path);
|
strcpy (mplex_data, socket_path);
|
||||||
strcat (mplex_data, PATH_SEP_S);
|
strcat (mplex_data, PATH_SEP_S);
|
||||||
strcat (mplex_data, socket_name);
|
strcat (mplex_data, socket_name);
|
||||||
@ -181,6 +185,8 @@ nomplex:
|
|||||||
pclose (session_info_stream);
|
pclose (session_info_stream);
|
||||||
if (dyn_buffer)
|
if (dyn_buffer)
|
||||||
free (dyn_buffer);
|
free (dyn_buffer);
|
||||||
|
if (socket_path)
|
||||||
|
free(socket_path);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,7 +202,7 @@ static int detect_tmux ()
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* store the session number string for later use */
|
/* store the session number string for later use */
|
||||||
strcpy (mplex_data, pos + 1);
|
snprintf (mplex_data, sizeof(mplex_data), "%s", pos + 1);
|
||||||
mplex = MPLEX_TMUX;
|
mplex = MPLEX_TMUX;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
51
src/toxic.c
51
src/toxic.c
@ -77,6 +77,9 @@ char *DATA_FILE = NULL;
|
|||||||
char *BLOCK_FILE = NULL;
|
char *BLOCK_FILE = NULL;
|
||||||
ToxWindow *prompt = NULL;
|
ToxWindow *prompt = NULL;
|
||||||
|
|
||||||
|
#define DATANAME "data"
|
||||||
|
#define BLOCKNAME "data-blocklist"
|
||||||
|
|
||||||
#define AUTOSAVE_FREQ 60
|
#define AUTOSAVE_FREQ 60
|
||||||
#define MIN_PASSWORD_LEN 6
|
#define MIN_PASSWORD_LEN 6
|
||||||
#define MAX_PASSWORD_LEN 64
|
#define MAX_PASSWORD_LEN 64
|
||||||
@ -119,6 +122,24 @@ static void init_signal_catchers(void)
|
|||||||
signal(SIGSEGV, catch_SIGSEGV);
|
signal(SIGSEGV, catch_SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free_global_data(void)
|
||||||
|
{
|
||||||
|
if (DATA_FILE) {
|
||||||
|
free(DATA_FILE);
|
||||||
|
DATA_FILE = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BLOCK_FILE) {
|
||||||
|
free(BLOCK_FILE);
|
||||||
|
BLOCK_FILE = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user_settings) {
|
||||||
|
free(user_settings);
|
||||||
|
user_settings = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void exit_toxic_success(Tox *m)
|
void exit_toxic_success(Tox *m)
|
||||||
{
|
{
|
||||||
store_data(m, DATA_FILE);
|
store_data(m, DATA_FILE);
|
||||||
@ -131,10 +152,7 @@ void exit_toxic_success(Tox *m)
|
|||||||
terminate_audio();
|
terminate_audio();
|
||||||
#endif /* AUDIO */
|
#endif /* AUDIO */
|
||||||
|
|
||||||
free(DATA_FILE);
|
free_global_data();
|
||||||
free(BLOCK_FILE);
|
|
||||||
free(user_settings);
|
|
||||||
|
|
||||||
tox_kill(m);
|
tox_kill(m);
|
||||||
endwin();
|
endwin();
|
||||||
|
|
||||||
@ -150,6 +168,7 @@ void exit_toxic_success(Tox *m)
|
|||||||
|
|
||||||
void exit_toxic_err(const char *errmsg, int errcode)
|
void exit_toxic_err(const char *errmsg, int errcode)
|
||||||
{
|
{
|
||||||
|
free_global_data();
|
||||||
freopen("/dev/tty", "w", stderr);
|
freopen("/dev/tty", "w", stderr);
|
||||||
endwin();
|
endwin();
|
||||||
fprintf(stderr, "Toxic session aborted with error code %d (%s)\n", errcode, errmsg);
|
fprintf(stderr, "Toxic session aborted with error code %d (%s)\n", errcode, errmsg);
|
||||||
@ -289,9 +308,11 @@ static int load_nodelist(const char *filename)
|
|||||||
toxNodes.nodes[toxNodes.lines][NODELEN - 1] = 0;
|
toxNodes.nodes[toxNodes.lines][NODELEN - 1] = 0;
|
||||||
toxNodes.ports[toxNodes.lines] = atoi(port);
|
toxNodes.ports[toxNodes.lines] = atoi(port);
|
||||||
|
|
||||||
char *key_binary = hex_string_to_bin(key_ascii);
|
char key_binary[TOX_PUBLIC_KEY_SIZE + 2 + 1];
|
||||||
|
if (hex_string_to_bin(key_ascii, strlen(key_ascii), key_binary, TOX_PUBLIC_KEY_SIZE) == -1)
|
||||||
|
continue;
|
||||||
|
|
||||||
memcpy(toxNodes.keys[toxNodes.lines], key_binary, TOX_PUBLIC_KEY_SIZE);
|
memcpy(toxNodes.keys[toxNodes.lines], key_binary, TOX_PUBLIC_KEY_SIZE);
|
||||||
free(key_binary);
|
|
||||||
|
|
||||||
toxNodes.lines++;
|
toxNodes.lines++;
|
||||||
}
|
}
|
||||||
@ -933,10 +954,22 @@ static void parse_args(int argc, char *argv[])
|
|||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
arg_opts.use_custom_data = 1;
|
arg_opts.use_custom_data = 1;
|
||||||
DATA_FILE = strdup(optarg);
|
|
||||||
|
if (DATA_FILE)
|
||||||
|
free(DATA_FILE);
|
||||||
|
|
||||||
|
if (BLOCK_FILE)
|
||||||
|
free(BLOCK_FILE);
|
||||||
|
|
||||||
|
DATA_FILE = malloc(strlen(optarg) + 1);
|
||||||
|
strcpy(DATA_FILE, optarg);
|
||||||
|
|
||||||
|
if (DATA_FILE == NULL)
|
||||||
|
exit_toxic_err("failed in parse_args", FATALERR_MEMORY);
|
||||||
|
|
||||||
BLOCK_FILE = malloc(strlen(optarg) + strlen("-blocklist") + 1);
|
BLOCK_FILE = malloc(strlen(optarg) + strlen("-blocklist") + 1);
|
||||||
|
|
||||||
if (DATA_FILE == NULL || BLOCK_FILE == NULL)
|
if (BLOCK_FILE == NULL)
|
||||||
exit_toxic_err("failed in parse_args", FATALERR_MEMORY);
|
exit_toxic_err("failed in parse_args", FATALERR_MEMORY);
|
||||||
|
|
||||||
strcpy(BLOCK_FILE, optarg);
|
strcpy(BLOCK_FILE, optarg);
|
||||||
@ -1007,8 +1040,6 @@ static void parse_args(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DATANAME "data"
|
|
||||||
#define BLOCKNAME "data-blocklist"
|
|
||||||
static int init_default_data_files(void)
|
static int init_default_data_files(void)
|
||||||
{
|
{
|
||||||
if (arg_opts.use_custom_data)
|
if (arg_opts.use_custom_data)
|
||||||
|
@ -568,7 +568,7 @@ ToxWindow *get_window_ptr(int i)
|
|||||||
{
|
{
|
||||||
ToxWindow *toxwin = NULL;
|
ToxWindow *toxwin = NULL;
|
||||||
|
|
||||||
if (i >= 0 && i <= MAX_WINDOWS_NUM && windows[i].active)
|
if (i >= 0 && i < MAX_WINDOWS_NUM && windows[i].active)
|
||||||
toxwin = &windows[i];
|
toxwin = &windows[i];
|
||||||
|
|
||||||
return toxwin;
|
return toxwin;
|
||||||
@ -595,7 +595,7 @@ void kill_all_windows(Tox *m)
|
|||||||
if (windows[i].is_chat)
|
if (windows[i].is_chat)
|
||||||
kill_chat_window(&windows[i], m);
|
kill_chat_window(&windows[i], m);
|
||||||
else if (windows[i].is_groupchat)
|
else if (windows[i].is_groupchat)
|
||||||
close_groupchat(&windows[i], m, i);
|
close_groupchat(&windows[i], m, windows[i].num);
|
||||||
}
|
}
|
||||||
|
|
||||||
kill_prompt_window(prompt);
|
kill_prompt_window(prompt);
|
||||||
|
110
src/xtra.c
110
src/xtra.c
@ -72,24 +72,24 @@ Property read_property(Window s, Atom p)
|
|||||||
unsigned long read_num;
|
unsigned long read_num;
|
||||||
unsigned long left_bytes;
|
unsigned long left_bytes;
|
||||||
unsigned char *data = NULL;
|
unsigned char *data = NULL;
|
||||||
|
|
||||||
int read_bytes = 1024;
|
int read_bytes = 1024;
|
||||||
|
|
||||||
/* Keep trying to read the property until there are no bytes unread */
|
/* Keep trying to read the property until there are no bytes unread */
|
||||||
do {
|
do {
|
||||||
if (data) XFree(data);
|
if (data) XFree(data);
|
||||||
|
|
||||||
XGetWindowProperty(Xtra.display, s,
|
XGetWindowProperty(Xtra.display, s,
|
||||||
p, 0,
|
p, 0,
|
||||||
read_bytes,
|
read_bytes,
|
||||||
False, AnyPropertyType,
|
False, AnyPropertyType,
|
||||||
&read_type, &read_format,
|
&read_type, &read_format,
|
||||||
&read_num, &left_bytes,
|
&read_num, &left_bytes,
|
||||||
&data);
|
&data);
|
||||||
|
|
||||||
read_bytes *= 2;
|
read_bytes *= 2;
|
||||||
} while (left_bytes != 0);
|
} while (left_bytes != 0);
|
||||||
|
|
||||||
Property property = {data, read_format, read_num, read_type};
|
Property property = {data, read_format, read_num, read_type};
|
||||||
return property;
|
return property;
|
||||||
}
|
}
|
||||||
@ -107,7 +107,7 @@ Atom get_dnd_type(long *a, int l)
|
|||||||
static void handle_xdnd_enter(XClientMessageEvent* e)
|
static void handle_xdnd_enter(XClientMessageEvent* e)
|
||||||
{
|
{
|
||||||
Xtra.handling_version = (e->data.l[1] >> 24);
|
Xtra.handling_version = (e->data.l[1] >> 24);
|
||||||
|
|
||||||
if ((e->data.l[1] & 1)) {
|
if ((e->data.l[1] & 1)) {
|
||||||
// Fetch the list of possible conversions
|
// Fetch the list of possible conversions
|
||||||
Property p = read_property(e->data.l[0], XdndTypeList);
|
Property p = read_property(e->data.l[0], XdndTypeList);
|
||||||
@ -120,7 +120,7 @@ static void handle_xdnd_enter(XClientMessageEvent* e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void handle_xdnd_position(XClientMessageEvent* e)
|
static void handle_xdnd_position(XClientMessageEvent* e)
|
||||||
{
|
{
|
||||||
XEvent ev = {
|
XEvent ev = {
|
||||||
.xclient = {
|
.xclient = {
|
||||||
.type = ClientMessage,
|
.type = ClientMessage,
|
||||||
@ -130,15 +130,15 @@ static void handle_xdnd_position(XClientMessageEvent* e)
|
|||||||
.format = 32,
|
.format = 32,
|
||||||
.data = {
|
.data = {
|
||||||
.l = {
|
.l = {
|
||||||
Xtra.proxy_window,
|
Xtra.proxy_window,
|
||||||
(Xtra.expecting_type != XtraNil),
|
(Xtra.expecting_type != XtraNil),
|
||||||
0, 0,
|
0, 0,
|
||||||
XdndActionCopy
|
XdndActionCopy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
XSendEvent(Xtra.display, e->data.l[0], False, NoEventMask, &ev);
|
XSendEvent(Xtra.display, e->data.l[0], False, NoEventMask, &ev);
|
||||||
XFlush(Xtra.display);
|
XFlush(Xtra.display);
|
||||||
}
|
}
|
||||||
@ -159,7 +159,7 @@ static void handle_xdnd_drop(XClientMessageEvent* e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
XSendEvent(Xtra.display, e->data.l[0], False, NoEventMask, &ev);
|
XSendEvent(Xtra.display, e->data.l[0], False, NoEventMask, &ev);
|
||||||
} else {
|
} else {
|
||||||
Xtra.source_window = e->data.l[0];
|
Xtra.source_window = e->data.l[0];
|
||||||
@ -188,57 +188,57 @@ static void handle_xdnd_selection(XSelectionEvent* e)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
XSendEvent(Xtra.display, Xtra.source_window, False, NoEventMask, &ev);
|
XSendEvent(Xtra.display, Xtra.source_window, False, NoEventMask, &ev);
|
||||||
|
|
||||||
Property p = read_property(Xtra.proxy_window, XdndSelection);
|
Property p = read_property(Xtra.proxy_window, XdndSelection);
|
||||||
DropType dt;
|
DropType dt;
|
||||||
|
|
||||||
if (strcmp(XGetAtomName(Xtra.display, p.read_type), "text/uri-list") == 0)
|
if (strcmp(XGetAtomName(Xtra.display, p.read_type), "text/uri-list") == 0)
|
||||||
dt = DT_file_list;
|
dt = DT_file_list;
|
||||||
else /* text/uri-list */
|
else /* text/uri-list */
|
||||||
dt = DT_plain;
|
dt = DT_plain;
|
||||||
|
|
||||||
|
|
||||||
/* Call callback for every entry */
|
/* Call callback for every entry */
|
||||||
if (Xtra.on_drop && p.read_num)
|
if (Xtra.on_drop && p.read_num)
|
||||||
{
|
{
|
||||||
char *sptr;
|
char *sptr;
|
||||||
char *str = strtok_r((char *) p.data, "\n\r", &sptr);
|
char *str = strtok_r((char *) p.data, "\n\r", &sptr);
|
||||||
|
|
||||||
if (str) Xtra.on_drop(str, dt);
|
if (str) Xtra.on_drop(str, dt);
|
||||||
while ((str = strtok_r(NULL, "\n\r", &sptr)))
|
while ((str = strtok_r(NULL, "\n\r", &sptr)))
|
||||||
Xtra.on_drop(str, dt);
|
Xtra.on_drop(str, dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.data) XFree(p.data);
|
if (p.data) XFree(p.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *event_loop(void* p)
|
void *event_loop(void* p)
|
||||||
{
|
{
|
||||||
/* Handle events like a real nigga */
|
/* Handle events like a real nigga */
|
||||||
|
|
||||||
(void) p; /* DINDUNOTHIN */
|
(void) p; /* DINDUNOTHIN */
|
||||||
|
|
||||||
XEvent event;
|
XEvent event;
|
||||||
int pending;
|
int pending;
|
||||||
|
|
||||||
while (Xtra.display)
|
while (Xtra.display)
|
||||||
{
|
{
|
||||||
/* NEEDMOEVENTSFODEMPROGRAMS */
|
/* NEEDMOEVENTSFODEMPROGRAMS */
|
||||||
|
|
||||||
XLockDisplay(Xtra.display);
|
XLockDisplay(Xtra.display);
|
||||||
if((pending = XPending(Xtra.display))) XNextEvent(Xtra.display, &event);
|
if((pending = XPending(Xtra.display))) XNextEvent(Xtra.display, &event);
|
||||||
|
|
||||||
if (!pending)
|
if (!pending)
|
||||||
{
|
{
|
||||||
XUnlockDisplay(Xtra.display);
|
XUnlockDisplay(Xtra.display);
|
||||||
usleep(10000);
|
usleep(10000);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.type == ClientMessage)
|
if (event.type == ClientMessage)
|
||||||
{
|
{
|
||||||
Atom type = event.xclient.message_type;
|
Atom type = event.xclient.message_type;
|
||||||
|
|
||||||
if (type == XdndEnter) handle_xdnd_enter(&event.xclient);
|
if (type == XdndEnter) handle_xdnd_enter(&event.xclient);
|
||||||
else if (type == XdndPosition) handle_xdnd_position(&event.xclient);
|
else if (type == XdndPosition) handle_xdnd_position(&event.xclient);
|
||||||
else if (type == XdndDrop) handle_xdnd_drop(&event.xclient);
|
else if (type == XdndDrop) handle_xdnd_drop(&event.xclient);
|
||||||
@ -247,11 +247,11 @@ void *event_loop(void* p)
|
|||||||
else if (event.type == SelectionNotify) handle_xdnd_selection(&event.xselection);
|
else if (event.type == SelectionNotify) handle_xdnd_selection(&event.xselection);
|
||||||
/* AINNOBODYCANHANDLEDEMEVENTS*/
|
/* AINNOBODYCANHANDLEDEMEVENTS*/
|
||||||
else XSendEvent(Xtra.display, Xtra.terminal_window, 0, 0, &event);
|
else XSendEvent(Xtra.display, Xtra.terminal_window, 0, 0, &event);
|
||||||
|
|
||||||
XUnlockDisplay(Xtra.display);
|
XUnlockDisplay(Xtra.display);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Actual XTRA termination
|
/* Actual XTRA termination
|
||||||
* Please call xtra_terminate() at exit
|
* Please call xtra_terminate() at exit
|
||||||
* otherwise HEWUSAGUDBOI happens
|
* otherwise HEWUSAGUDBOI happens
|
||||||
*/
|
*/
|
||||||
@ -262,23 +262,23 @@ void *event_loop(void* p)
|
|||||||
int init_xtra(drop_callback d)
|
int init_xtra(drop_callback d)
|
||||||
{
|
{
|
||||||
memset(&Xtra, 0, sizeof(Xtra));
|
memset(&Xtra, 0, sizeof(Xtra));
|
||||||
|
|
||||||
if (!d) return -1;
|
if (!d) return -1;
|
||||||
else Xtra.on_drop = d;
|
else Xtra.on_drop = d;
|
||||||
|
|
||||||
XInitThreads();
|
XInitThreads();
|
||||||
if ( !(Xtra.display = XOpenDisplay(NULL))) return -1;
|
if ( !(Xtra.display = XOpenDisplay(NULL))) return -1;
|
||||||
|
|
||||||
Xtra.terminal_window = focused_window_id();
|
Xtra.terminal_window = focused_window_id();
|
||||||
|
|
||||||
{
|
{
|
||||||
/* Create an invisible window which will act as proxy for the DnD operation. */
|
/* Create an invisible window which will act as proxy for the DnD operation. */
|
||||||
XSetWindowAttributes attr = {0};
|
XSetWindowAttributes attr = {0};
|
||||||
attr.event_mask = EnterWindowMask |
|
attr.event_mask = EnterWindowMask |
|
||||||
LeaveWindowMask |
|
LeaveWindowMask |
|
||||||
ButtonMotionMask |
|
ButtonMotionMask |
|
||||||
ButtonPressMask |
|
ButtonPressMask |
|
||||||
ButtonReleaseMask |
|
ButtonReleaseMask |
|
||||||
ResizeRedirectMask;
|
ResizeRedirectMask;
|
||||||
|
|
||||||
attr.do_not_propagate_mask = NoEventMask;
|
attr.do_not_propagate_mask = NoEventMask;
|
||||||
@ -286,14 +286,14 @@ int init_xtra(drop_callback d)
|
|||||||
Window root;
|
Window root;
|
||||||
int x, y;
|
int x, y;
|
||||||
unsigned int wht, hht, b, d;
|
unsigned int wht, hht, b, d;
|
||||||
|
|
||||||
/* Since we cannot capture resize events for parent window we will have to create
|
/* Since we cannot capture resize events for parent window we will have to create
|
||||||
* this window to have maximum size as defined in root window
|
* this window to have maximum size as defined in root window
|
||||||
*/
|
*/
|
||||||
XGetGeometry(Xtra.display,
|
XGetGeometry(Xtra.display,
|
||||||
XDefaultRootWindow(Xtra.display),
|
XDefaultRootWindow(Xtra.display),
|
||||||
&root, &x, &y, &wht, &hht, &b, &d);
|
&root, &x, &y, &wht, &hht, &b, &d);
|
||||||
|
|
||||||
if (! (Xtra.proxy_window = XCreateWindow
|
if (! (Xtra.proxy_window = XCreateWindow
|
||||||
(Xtra.display, Xtra.terminal_window, /* Parent */
|
(Xtra.display, Xtra.terminal_window, /* Parent */
|
||||||
0, 0, /* Position */
|
0, 0, /* Position */
|
||||||
@ -306,7 +306,7 @@ int init_xtra(drop_callback d)
|
|||||||
&attr)) ) /* Attributes for value mask */
|
&attr)) ) /* Attributes for value mask */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XMapWindow(Xtra.display, Xtra.proxy_window); /* Show window (sandwich) */
|
XMapWindow(Xtra.display, Xtra.proxy_window); /* Show window (sandwich) */
|
||||||
XLowerWindow(Xtra.display, Xtra.proxy_window); /* Don't interfere with parent lmao */
|
XLowerWindow(Xtra.display, Xtra.proxy_window); /* Don't interfere with parent lmao */
|
||||||
|
|
||||||
@ -321,7 +321,7 @@ int init_xtra(drop_callback d)
|
|||||||
XdndTypeList = XInternAtom(Xtra.display, "XdndTypeList", False);
|
XdndTypeList = XInternAtom(Xtra.display, "XdndTypeList", False);
|
||||||
XdndActionCopy = XInternAtom(Xtra.display, "XdndActionCopy", False);
|
XdndActionCopy = XInternAtom(Xtra.display, "XdndActionCopy", False);
|
||||||
XdndFinished = XInternAtom(Xtra.display, "XdndFinished", False);
|
XdndFinished = XInternAtom(Xtra.display, "XdndFinished", False);
|
||||||
|
|
||||||
/* Inform my nigga windows that we are aware of dnd */
|
/* Inform my nigga windows that we are aware of dnd */
|
||||||
Atom XdndVersion = 3;
|
Atom XdndVersion = 3;
|
||||||
XChangeProperty(Xtra.display,
|
XChangeProperty(Xtra.display,
|
||||||
@ -331,18 +331,20 @@ int init_xtra(drop_callback d)
|
|||||||
32,
|
32,
|
||||||
PropModeReplace,
|
PropModeReplace,
|
||||||
(unsigned char*)&XdndVersion, 1);
|
(unsigned char*)&XdndVersion, 1);
|
||||||
|
|
||||||
pthread_t id;
|
pthread_t id;
|
||||||
pthread_create(&id, NULL, event_loop, NULL);
|
if (pthread_create(&id, NULL, event_loop, NULL) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
pthread_detach(id);
|
pthread_detach(id);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void terminate_xtra()
|
void terminate_xtra()
|
||||||
{
|
{
|
||||||
if (!Xtra.display) return;
|
if (!Xtra.display) return;
|
||||||
|
|
||||||
XEvent terminate = {
|
XEvent terminate = {
|
||||||
.xclient = {
|
.xclient = {
|
||||||
.type = ClientMessage,
|
.type = ClientMessage,
|
||||||
@ -350,19 +352,19 @@ void terminate_xtra()
|
|||||||
.message_type = XtraTerminate,
|
.message_type = XtraTerminate,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
XLockDisplay(Xtra.display);
|
XLockDisplay(Xtra.display);
|
||||||
XDeleteProperty(Xtra.display, Xtra.proxy_window, XdndAware);
|
XDeleteProperty(Xtra.display, Xtra.proxy_window, XdndAware);
|
||||||
XSendEvent(Xtra.display, Xtra.proxy_window, 0, NoEventMask, &terminate);
|
XSendEvent(Xtra.display, Xtra.proxy_window, 0, NoEventMask, &terminate);
|
||||||
XUnlockDisplay(Xtra.display);
|
XUnlockDisplay(Xtra.display);
|
||||||
|
|
||||||
while (Xtra.display); /* Wait for termination */
|
while (Xtra.display); /* Wait for termination */
|
||||||
}
|
}
|
||||||
|
|
||||||
long unsigned int focused_window_id()
|
long unsigned int focused_window_id()
|
||||||
{
|
{
|
||||||
if (!Xtra.display) return 0;
|
if (!Xtra.display) return 0;
|
||||||
|
|
||||||
Window focus;
|
Window focus;
|
||||||
int revert;
|
int revert;
|
||||||
XLockDisplay(Xtra.display);
|
XLockDisplay(Xtra.display);
|
||||||
|
Loading…
Reference in New Issue
Block a user