revert: restore pre-upstream-merge baseline (tree of 3b673150b)
All checks were successful
CI Code / Check spelling (pull_request) Successful in 18s
CI Code / Check coding style (pull_request) Successful in 30s
CI Code / Linux (ubuntu) (pull_request) Successful in 4m51s
CI Code / Linux (debian) (pull_request) Successful in 6m59s
CI Code / Linux (arch) (pull_request) Successful in 10m12s
CI Code / Code Coverage (pull_request) Successful in 6m44s

Roll the tree back to the pre-merge tip 3b673150b, undoing the upstream sync merge 72f4f186d (303 files) and the 13 post-merge commits layered on top of it.

Purpose: restore the last pre-sync baseline so the reported OMEMO/OTR encryption regressions can be reproduced against a known-good state and the upstream sync ruled in or out as the cause. Nothing is dropped from history; the merge and every post-merge commit remain reachable and can be cherry-picked back selectively.

Baseline:     3b673150b chore(chatlog): disable background message file logging (stage 1)

Undoes merge: 72f4f186d merge: sync upstream profanity-im/profanity
This commit is contained in:
2026-06-29 12:17:01 +03:00
parent ca92d29179
commit f9e184eda7
311 changed files with 9908 additions and 11285 deletions

View File

@@ -65,7 +65,7 @@ buffer_create(void)
return new_buff;
}
unsigned int
int
buffer_size(ProfBuff buffer)
{
return g_slist_length(buffer->entries);
@@ -137,7 +137,7 @@ buffer_remove_entry_by_id(ProfBuff buffer, const char* const id)
}
void
buffer_remove_entry(ProfBuff buffer, unsigned int entry)
buffer_remove_entry(ProfBuff buffer, int entry)
{
GSList* node = g_slist_nth(buffer->entries, entry);
if (node == NULL) {
@@ -169,7 +169,7 @@ buffer_mark_received(ProfBuff buffer, const char* const id)
}
ProfBuffEntry*
buffer_get_entry(ProfBuff buffer, unsigned int entry)
buffer_get_entry(ProfBuff buffer, int entry)
{
GSList* node = g_slist_nth(buffer->entries, entry);
if (node == NULL) {
@@ -197,7 +197,7 @@ static ProfBuffEntry*
_create_entry(const char* show_char, int pad_indent, GDateTime* time, int flags, theme_item_t theme_item, const char* const display_from, const char* const from_jid, const char* const message, DeliveryReceipt* receipt, const char* const id, int y_start_pos, int y_end_pos)
{
assert(time != NULL);
ProfBuffEntry* e = g_new0(ProfBuffEntry, 1);
ProfBuffEntry* e = malloc(sizeof(struct prof_buff_entry_t));
e->show_char = STRDUP_OR_NULL(show_char);
e->pad_indent = pad_indent;
e->flags = flags;

View File

@@ -3,9 +3,35 @@
* vim: expandtab:ts=4:sts=4:sw=4
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
* Copyright (C) 2019 - 2026 Michael Vetter <jubalh@iodoru.org>
* Copyright (C) 2019 - 2025 Michael Vetter <jubalh@iodoru.org>
*
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
*/
#ifndef UI_BUFFER_H
@@ -55,9 +81,9 @@ void buffer_free(ProfBuff buffer);
void buffer_append(ProfBuff buffer, const char* show_char, int pad_indent, GDateTime* time, int flags, theme_item_t theme_item, const char* const display_from, const char* const barejid, const char* const message, DeliveryReceipt* receipt, const char* const id, int y_start_pos, int y_end_pos);
void buffer_prepend(ProfBuff buffer, const char* show_char, int pad_indent, GDateTime* time, int flags, theme_item_t theme_item, const char* const display_from, const char* const barejid, const char* const message, DeliveryReceipt* receipt, const char* const id, int y_start_pos, int y_end_pos);
void buffer_remove_entry_by_id(ProfBuff buffer, const char* const id);
void buffer_remove_entry(ProfBuff buffer, unsigned int entry);
unsigned int buffer_size(ProfBuff buffer);
ProfBuffEntry* buffer_get_entry(ProfBuff buffer, unsigned int entry);
void buffer_remove_entry(ProfBuff buffer, int entry);
int buffer_size(ProfBuff buffer);
ProfBuffEntry* buffer_get_entry(ProfBuff buffer, int entry);
ProfBuffEntry* buffer_get_entry_by_id(ProfBuff buffer, const char* const id);
gboolean buffer_mark_received(ProfBuff buffer, const char* const id);

View File

@@ -3,9 +3,35 @@
* vim: expandtab:ts=4:sts=4:sw=4
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
* Copyright (C) 2019 - 2026 Michael Vetter <jubalh@iodoru.org>
* Copyright (C) 2019 - 2025 Michael Vetter <jubalh@iodoru.org>
*
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
*/
#include "config.h"
@@ -327,7 +353,7 @@ chatwin_incoming_msg(ProfChatWin* chatwin, ProfMessage* message, gboolean win_cr
cons_show_incoming_message(display_name, num, chatwin->unread, window);
if (prefs_get_boolean(PREF_FLASH)) {
ui_flash();
flash();
}
chatwin->unread++;
@@ -364,7 +390,7 @@ chatwin_incoming_msg(ProfChatWin* chatwin, ProfMessage* message, gboolean win_cr
wins_add_quotes_ac(window, message->plain, FALSE);
if (prefs_get_boolean(PREF_BEEP)) {
ui_beep();
beep();
}
}
@@ -393,8 +419,7 @@ chatwin_outgoing_msg(ProfChatWin* chatwin, const char* const message, const char
const char* display_message = plugin_message ?: message;
if (request_receipt && id) {
auto_gchar gchar* outgoing_str = prefs_get_string(PREF_OUTGOING_STAMP);
win_print_outgoing_with_receipt((ProfWin*)chatwin, enc_char, outgoing_str, display_message, id, replace_id);
win_print_outgoing_with_receipt((ProfWin*)chatwin, enc_char, "me", display_message, id, replace_id);
} else {
win_print_outgoing((ProfWin*)chatwin, enc_char, id, replace_id, display_message);
}
@@ -425,15 +450,7 @@ chatwin_outgoing_carbon(ProfChatWin* chatwin, ProfMessage* message)
ProfWin* window = (ProfWin*)chatwin;
char* old_plain = message->plain;
auto_char char* plugin_msg = plugins_pre_chat_message_display(message->from_jid->barejid, message->from_jid->resourcepart, message->plain);
if (plugin_msg)
message->plain = plugin_msg;
win_print_outgoing(window, enc_char, message->id, message->replace_id, message->plain);
message->plain = old_plain;
int num = wins_get_num(window);
status_bar_active(num, WIN_CHAT, chatwin->barejid);
}

View File

@@ -4,7 +4,33 @@
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#include "config.h"

View File

@@ -3,9 +3,35 @@
* vim: expandtab:ts=4:sts=4:sw=4
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
* Copyright (C) 2019 - 2026 Michael Vetter <jubalh@iodoru.org>
* Copyright (C) 2019 - 2025 Michael Vetter <jubalh@iodoru.org>
*
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
*/
#include "config.h"
@@ -64,13 +90,6 @@ cons_show(const char* const msg, ...)
va_end(arg);
}
#define cons_show_if_set(fmt, elmnt) \
do { \
if (elmnt) { \
cons_show(fmt, elmnt); \
} \
} while (0)
void
cons_show_padded(int pad, const char* const msg, ...)
{
@@ -91,12 +110,9 @@ cons_show_help(const char* const cmd, CommandHelp* help)
cons_show("");
win_println(console, THEME_HELP_HEADER, "-", "%s", &cmd[1]);
win_print(console, THEME_HELP_HEADER, "-", "");
size_t i;
size_t cmd_len = strlen(cmd);
if (cmd_len > 0) {
for (i = 0; i < cmd_len - 1; i++) {
win_append(console, THEME_HELP_HEADER, "-");
}
int i;
for (i = 0; i < strlen(cmd) - 1; i++) {
win_append(console, THEME_HELP_HEADER, "-");
}
win_appendln(console, THEME_HELP_HEADER, "");
cons_show("");
@@ -108,7 +124,7 @@ cons_show_help(const char* const cmd, CommandHelp* help)
win_println(console, THEME_HELP_HEADER, "-", "Description");
win_println(console, THEME_DEFAULT, "-", "%s", help->desc);
size_t maxlen = 0;
int maxlen = 0;
for (i = 0; help->args[i][0] != NULL; i++) {
if (strlen(help->args[i][0]) > maxlen)
maxlen = strlen(help->args[i][0]);
@@ -118,7 +134,7 @@ cons_show_help(const char* const cmd, CommandHelp* help)
cons_show("");
win_println(console, THEME_HELP_HEADER, "-", "Arguments");
for (i = 0; help->args[i][0] != NULL; i++) {
win_println_indent(console, (int)(maxlen + 3), "%-*s: %s", (int)(maxlen + 1), help->args[i][0], help->args[i][1]);
win_println_indent(console, maxlen + 3, "%-*s: %s", maxlen + 1, help->args[i][0], help->args[i][1]);
}
}
@@ -162,8 +178,8 @@ cons_show_tlscert_summary(const TLSCertificate* cert)
return;
}
cons_show("Subject : %s", cert->subject.commonname);
cons_show("Issuer : %s", cert->issuer.commonname);
cons_show("Subject : %s", cert->subject_commonname);
cons_show("Issuer : %s", cert->issuer_commonname);
cons_show("Fingerprint : %s", cert->fingerprint);
}
@@ -176,39 +192,75 @@ cons_show_tlscert(const TLSCertificate* cert)
cons_show("Certificate:");
cons_show(" Version : %d", cert->version);
cons_show(" Subject:");
cons_show_if_set(" Common name : %s", cert->subject.commonname);
cons_show_if_set(" Distinguished name : %s", cert->subject.distinguishedname);
cons_show_if_set(" Organisation : %s", cert->subject.organisation);
cons_show_if_set(" Organisation unit : %s", cert->subject.organisation_unit);
cons_show_if_set(" Email : %s", cert->subject.email);
cons_show_if_set(" State : %s", cert->subject.state);
cons_show_if_set(" Country : %s", cert->subject.country);
cons_show_if_set(" Serial number : %s", cert->subject.serialnumber);
if (cert->subject_commonname) {
cons_show(" Common name : %s", cert->subject_commonname);
}
if (cert->subject_distinguishedname) {
cons_show(" Distinguished name : %s", cert->subject_distinguishedname);
}
if (cert->subject_organisation) {
cons_show(" Organisation : %s", cert->subject_organisation);
}
if (cert->subject_organisation_unit) {
cons_show(" Organisation unit : %s", cert->subject_organisation_unit);
}
if (cert->subject_email) {
cons_show(" Email : %s", cert->subject_email);
}
if (cert->subject_state) {
cons_show(" State : %s", cert->subject_state);
}
if (cert->subject_country) {
cons_show(" Country : %s", cert->subject_country);
}
if (cert->subject_serialnumber) {
cons_show(" Serial number : %s", cert->subject_serialnumber);
}
cons_show(" Issuer:");
cons_show_if_set(" Common name : %s", cert->issuer.commonname);
cons_show_if_set(" Distinguished name : %s", cert->issuer.distinguishedname);
cons_show_if_set(" Organisation : %s", cert->issuer.organisation);
cons_show_if_set(" Organisation unit : %s", cert->issuer.organisation_unit);
cons_show_if_set(" Email : %s", cert->issuer.email);
cons_show_if_set(" State : %s", cert->issuer.state);
cons_show_if_set(" Country : %s", cert->issuer.country);
cons_show_if_set(" Serial number : %s", cert->issuer.serialnumber);
if (cert->issuer_commonname) {
cons_show(" Common name : %s", cert->issuer_commonname);
}
if (cert->issuer_distinguishedname) {
cons_show(" Distinguished name : %s", cert->issuer_distinguishedname);
}
if (cert->issuer_organisation) {
cons_show(" Organisation : %s", cert->issuer_organisation);
}
if (cert->issuer_organisation_unit) {
cons_show(" Organisation unit : %s", cert->issuer_organisation_unit);
}
if (cert->issuer_email) {
cons_show(" Email : %s", cert->issuer_email);
}
if (cert->issuer_state) {
cons_show(" State : %s", cert->issuer_state);
}
if (cert->issuer_country) {
cons_show(" Country : %s", cert->issuer_country);
}
if (cert->issuer_serialnumber) {
cons_show(" Serial number : %s", cert->issuer_serialnumber);
}
cons_show_if_set(" Serial number : %s", cert->serialnumber);
cons_show(" Version : %d", cert->version);
cons_show_if_set(" Key algorithm : %s", cert->key_alg);
cons_show_if_set(" Signature algorithm : %s", cert->signature_alg);
if (cert->serialnumber) {
cons_show(" Serial number : %s", cert->serialnumber);
}
cons_show_if_set(" Validity Start : %s", cert->notbefore);
cons_show_if_set(" Validity End : %s", cert->notafter);
if (cert->key_alg) {
cons_show(" Key algorithm : %s", cert->key_alg);
}
if (cert->signature_alg) {
cons_show(" Signature algorithm : %s", cert->signature_alg);
}
cons_show_if_set(" Fingerprint SHA1 : %s", cert->fingerprint_sha1);
cons_show_if_set(" Fingerprint SHA256 : %s", cert->fingerprint_sha256);
cons_show_if_set(" Pubkey Fingerprint : %s", cert->pubkey_fingerprint);
cons_show(" Start : %s", cert->notbefore);
cons_show(" End : %s", cert->notafter);
cons_show(" Fingerprint : %s", cert->fingerprint);
}
void
@@ -365,7 +417,7 @@ cons_check_version(gboolean not_available_msg)
gboolean relase_valid = g_regex_match_simple("^\\d+\\.\\d+\\.\\d+$", latest_release, 0, 0);
if (relase_valid) {
if (release_is_new(PACKAGE_VERSION, latest_release)) {
if (release_is_new(latest_release)) {
win_println(console, THEME_DEFAULT, "-", "A new version of Profanity is available: %s", latest_release);
win_println(console, THEME_DEFAULT, "-", "Check <https://profanity-im.github.io> for details.");
win_println(console, THEME_DEFAULT, "-", "");
@@ -418,7 +470,7 @@ cons_show_wins(gboolean unread)
GSList* curr = window_strings;
while (curr) {
if (g_strstr_len(curr->data, strlen(curr->data), " unread") != NULL) {
if (g_strstr_len((char*)curr->data, strlen((char*)curr->data), " unread") != NULL) {
win_println(console, THEME_CMD_WINS_UNREAD, "-", "%s", (char*)curr->data);
} else {
win_println(console, THEME_DEFAULT, "-", "%s", (char*)curr->data);
@@ -431,7 +483,7 @@ cons_show_wins(gboolean unread)
}
void
cons_show_wins_attention(void)
cons_show_wins_attention()
{
ProfWin* console = wins_get_console();
cons_show("");
@@ -439,7 +491,7 @@ cons_show_wins_attention(void)
GSList* curr = window_strings;
while (curr) {
if (g_strstr_len(curr->data, strlen(curr->data), " unread") != NULL) {
if (g_strstr_len((char*)curr->data, strlen((char*)curr->data), " unread") != NULL) {
win_println(console, THEME_CMD_WINS_UNREAD, "-", "%s", (char*)curr->data);
} else {
win_println(console, THEME_DEFAULT, "-", "%s", (char*)curr->data);
@@ -793,7 +845,7 @@ cons_show_qrcode(const char* const text)
static const size_t ZOOM_SIZE = 10;
QRcode* qrcode = QRcode_encodeString(text, 0, QR_ECLEVEL_L, QR_MODE_8, 1);
size_t width = (qrcode->width * ZOOM_SIZE);
int width = (qrcode->width * ZOOM_SIZE);
unsigned char* data = qrcode->data;
ProfWin* console = wins_get_console();
@@ -805,7 +857,7 @@ cons_show_qrcode(const char* const text)
return;
}
for (size_t i = 0; i < width + 2 * ZOOM_SIZE; i += ZOOM_SIZE) {
for (int i = 0; i < width + 2 * ZOOM_SIZE; i += ZOOM_SIZE) {
strcat(pad, "\u2588\u2588");
}
@@ -1266,21 +1318,6 @@ cons_splash_setting(void)
cons_show("Splash screen (/splash) : OFF");
}
void
cons_spellcheck_setting(void)
{
#ifdef HAVE_SPELLCHECK
if (prefs_get_boolean(PREF_SPELLCHECK_ENABLE)) {
auto_gchar gchar* lang = prefs_get_string(PREF_SPELLCHECK_LANG);
cons_show("Spellcheck (/spellcheck) : ON (%s)", lang);
} else {
cons_show("Spellcheck (/spellcheck) : OFF");
}
#else
cons_show("Spellcheck (/spellcheck) : built without spellcheck support");
#endif
}
void
cons_occupants_setting(void)
{
@@ -1304,7 +1341,7 @@ cons_occupants_setting(void)
else
cons_show("Occupants wrap (/occupants) : OFF");
auto_gchar gchar* occupants_ch = prefs_get_occupants_char();
auto_char char* occupants_ch = prefs_get_occupants_char();
if (occupants_ch) {
cons_show("Occupants char (/occupants) : %s", occupants_ch);
} else {
@@ -1317,7 +1354,7 @@ cons_occupants_setting(void)
int size = prefs_get_occupants_size();
cons_show("Occupants size (/occupants) : %d", size);
auto_gchar gchar* header_ch = prefs_get_occupants_header_char();
auto_char char* header_ch = prefs_get_occupants_header_char();
if (header_ch) {
cons_show("Occupants header char (/occupants) : %s", header_ch);
} else {
@@ -1434,42 +1471,42 @@ cons_roster_setting(void)
else
cons_show("Roster offline (/roster) : hide");
auto_gchar gchar* header_ch = prefs_get_roster_header_char();
auto_char char* header_ch = prefs_get_roster_header_char();
if (header_ch) {
cons_show("Roster header char (/roster) : %s", header_ch);
} else {
cons_show("Roster header char (/roster) : none");
}
auto_gchar gchar* contact_ch = prefs_get_roster_contact_char();
auto_char char* contact_ch = prefs_get_roster_contact_char();
if (contact_ch) {
cons_show("Roster contact char (/roster) : %s", contact_ch);
} else {
cons_show("Roster contact char (/roster) : none");
}
auto_gchar gchar* resource_ch = prefs_get_roster_resource_char();
auto_char char* resource_ch = prefs_get_roster_resource_char();
if (resource_ch) {
cons_show("Roster resource char (/roster) : %s", resource_ch);
} else {
cons_show("Roster resource char (/roster) : none");
}
auto_gchar gchar* room_ch = prefs_get_roster_room_char();
auto_char char* room_ch = prefs_get_roster_room_char();
if (room_ch) {
cons_show("Roster room char (/roster) : %s", room_ch);
} else {
cons_show("Roster room char (/roster) : none");
}
auto_gchar gchar* room_priv_ch = prefs_get_roster_room_private_char();
auto_char char* room_priv_ch = prefs_get_roster_room_private_char();
if (room_priv_ch) {
cons_show("Roster room private char (/roster) : %s", room_priv_ch);
} else {
cons_show("Roster room private char (/roster) : none");
}
auto_gchar gchar* private_ch = prefs_get_roster_private_char();
auto_char char* private_ch = prefs_get_roster_private_char();
if (private_ch) {
cons_show("Roster private char (/roster) : %s", private_ch);
} else {
@@ -1600,7 +1637,6 @@ cons_show_ui_prefs(void)
cons_beep_setting();
cons_flash_setting();
cons_splash_setting();
cons_spellcheck_setting();
cons_winpos_setting();
cons_wrap_setting();
cons_time_setting();
@@ -1703,11 +1739,6 @@ cons_notify_setting(void)
else
cons_show("Subscription requests (/notify sub) : OFF");
if (prefs_get_boolean(PREF_AUTOPING_WARNING))
cons_show("Autoping warning (/autoping warning): ON");
else
cons_show("Autoping warning (/autoping warning): OFF");
gint remind_period = prefs_get_notify_remind();
if (remind_period == 0) {
cons_show("Reminder period (/notify remind) : OFF");
@@ -2008,26 +2039,21 @@ cons_autoping_setting(void)
{
gint autoping_interval = prefs_get_autoping();
if (autoping_interval == 0) {
cons_show("Autoping interval (/autoping) : OFF");
cons_show("Autoping interval (/autoping) : OFF");
} else if (autoping_interval == 1) {
cons_show("Autoping interval (/autoping) : 1 second");
cons_show("Autoping interval (/autoping) : 1 second");
} else {
cons_show("Autoping interval (/autoping) : %d seconds", autoping_interval);
cons_show("Autoping interval (/autoping) : %d seconds", autoping_interval);
}
gint autoping_timeout = prefs_get_autoping_timeout();
if (autoping_timeout == 0) {
cons_show("Autoping timeout (/autoping) : OFF");
cons_show("Autoping timeout (/autoping) : OFF");
} else if (autoping_timeout == 1) {
cons_show("Autoping timeout (/autoping) : 1 second");
cons_show("Autoping timeout (/autoping) : 1 second");
} else {
cons_show("Autoping timeout (/autoping) : %d seconds", autoping_timeout);
cons_show("Autoping timeout (/autoping) : %d seconds", autoping_timeout);
}
if (prefs_get_boolean(PREF_AUTOPING_WARNING))
cons_show("Autoping warning (/autoping warning): ON");
else
cons_show("Autoping warning (/autoping warning): OFF");
}
void
@@ -2352,7 +2378,6 @@ cons_help(void)
cons_show_padded(pad, "/help commands ui : List commands for manipulating the user interface.");
cons_show_padded(pad, "/help commands plugins : List plugin commands.");
cons_show_padded(pad, "/help [command] : Detailed help on a specific command.");
cons_show_padded(pad, "/[command]? : Shortcut to get detailed help on a specific command.");
cons_show_padded(pad, "/help navigation : How to navigate around Profanity.");
cons_show("");
@@ -2469,123 +2494,137 @@ cons_get_string(ProfConsoleWin* conswin)
return g_strdup("Console");
}
static void
_cons_theme_bar_prop(ProfWin* console, theme_item_t theme, char* prop)
void
_cons_theme_bar_prop(theme_item_t theme, char* prop)
{
auto_gchar gchar* propstr = g_strdup_printf("%-24s", prop);
win_print(console, THEME_TEXT, "-", "%s", propstr);
ProfWin* console = wins_get_console();
auto_gchar gchar* setting = theme_get_string(prop);
win_append(console, theme, "%s", setting);
GString* propstr = g_string_new(" ");
g_string_append_printf(propstr, "%-24s", prop);
win_print(console, THEME_TEXT, "-", "%s", propstr->str);
g_string_free(propstr, TRUE);
GString* valstr = g_string_new(" ");
char* setting = theme_get_string(prop);
g_string_append_printf(valstr, "%s ", setting);
theme_free_string(setting);
win_append(console, theme, "%s", valstr->str);
win_appendln(console, THEME_TEXT, "");
g_string_free(valstr, TRUE);
}
static void
_cons_theme_prop(ProfWin* console, theme_item_t theme, char* prop)
void
_cons_theme_prop(theme_item_t theme, char* prop)
{
auto_gchar gchar* propstr = g_strdup_printf("%-24s", prop);
win_print(console, THEME_TEXT, "-", "%s", propstr);
ProfWin* console = wins_get_console();
auto_gchar gchar* setting = theme_get_string(prop);
win_appendln(console, theme, "%s", setting);
GString* propstr = g_string_new(" ");
g_string_append_printf(propstr, "%-24s", prop);
win_print(console, THEME_TEXT, "-", "%s", propstr->str);
g_string_free(propstr, TRUE);
GString* valstr = g_string_new("");
char* setting = theme_get_string(prop);
g_string_append_printf(valstr, "%s", setting);
theme_free_string(setting);
win_appendln(console, theme, "%s", valstr->str);
g_string_free(valstr, TRUE);
}
void
cons_theme_properties(void)
{
ProfWin* console = wins_get_console();
cons_show("Current colours:");
_cons_theme_bar_prop(console, THEME_TITLE_TEXT, "titlebar.text");
_cons_theme_bar_prop(console, THEME_TITLE_BRACKET, "titlebar.brackets");
_cons_theme_bar_prop(THEME_TITLE_TEXT, "titlebar.text");
_cons_theme_bar_prop(THEME_TITLE_BRACKET, "titlebar.brackets");
_cons_theme_bar_prop(console, THEME_TITLE_SCROLLED, "titlebar.scrolled");
_cons_theme_bar_prop(THEME_TITLE_SCROLLED, "titlebar.scrolled");
_cons_theme_bar_prop(console, THEME_TITLE_UNENCRYPTED, "titlebar.unencrypted");
_cons_theme_bar_prop(console, THEME_TITLE_ENCRYPTED, "titlebar.encrypted");
_cons_theme_bar_prop(console, THEME_TITLE_UNTRUSTED, "titlebar.untrusted");
_cons_theme_bar_prop(console, THEME_TITLE_TRUSTED, "titlebar.trusted");
_cons_theme_bar_prop(THEME_TITLE_UNENCRYPTED, "titlebar.unencrypted");
_cons_theme_bar_prop(THEME_TITLE_ENCRYPTED, "titlebar.encrypted");
_cons_theme_bar_prop(THEME_TITLE_UNTRUSTED, "titlebar.untrusted");
_cons_theme_bar_prop(THEME_TITLE_TRUSTED, "titlebar.trusted");
_cons_theme_bar_prop(console, THEME_TITLE_CHAT, "titlebar.chat");
_cons_theme_bar_prop(console, THEME_TITLE_ONLINE, "titlebar.online");
_cons_theme_bar_prop(console, THEME_TITLE_AWAY, "titlebar.away");
_cons_theme_bar_prop(console, THEME_TITLE_XA, "titlebar.xa");
_cons_theme_bar_prop(console, THEME_TITLE_DND, "titlebar.dnd");
_cons_theme_bar_prop(console, THEME_TITLE_OFFLINE, "titlebar.offline");
_cons_theme_bar_prop(THEME_TITLE_CHAT, "titlebar.chat");
_cons_theme_bar_prop(THEME_TITLE_ONLINE, "titlebar.online");
_cons_theme_bar_prop(THEME_TITLE_AWAY, "titlebar.away");
_cons_theme_bar_prop(THEME_TITLE_XA, "titlebar.xa");
_cons_theme_bar_prop(THEME_TITLE_DND, "titlebar.dnd");
_cons_theme_bar_prop(THEME_TITLE_OFFLINE, "titlebar.offline");
_cons_theme_bar_prop(console, THEME_STATUS_TEXT, "statusbar.text");
_cons_theme_bar_prop(console, THEME_STATUS_BRACKET, "statusbar.brackets");
_cons_theme_bar_prop(console, THEME_STATUS_ACTIVE, "statusbar.active");
_cons_theme_bar_prop(console, THEME_STATUS_CURRENT, "statusbar.current");
_cons_theme_bar_prop(console, THEME_STATUS_NEW, "statusbar.new");
_cons_theme_bar_prop(console, THEME_STATUS_TIME, "statusbar.time");
_cons_theme_bar_prop(THEME_STATUS_TEXT, "statusbar.text");
_cons_theme_bar_prop(THEME_STATUS_BRACKET, "statusbar.brackets");
_cons_theme_bar_prop(THEME_STATUS_ACTIVE, "statusbar.active");
_cons_theme_bar_prop(THEME_STATUS_CURRENT, "statusbar.current");
_cons_theme_bar_prop(THEME_STATUS_NEW, "statusbar.new");
_cons_theme_bar_prop(THEME_STATUS_TIME, "statusbar.time");
_cons_theme_prop(console, THEME_TIME, "main.time");
_cons_theme_prop(console, THEME_TEXT, "main.text");
_cons_theme_prop(console, THEME_SPLASH, "main.splash");
_cons_theme_prop(console, THEME_ERROR, "error");
_cons_theme_prop(console, THEME_OTR_STARTED_TRUSTED, "otr.started.trusted");
_cons_theme_prop(console, THEME_OTR_STARTED_UNTRUSTED, "otr.started.untrusted");
_cons_theme_prop(console, THEME_OTR_ENDED, "otr.ended");
_cons_theme_prop(console, THEME_OTR_TRUSTED, "otr.trusted");
_cons_theme_prop(console, THEME_OTR_UNTRUSTED, "otr.untrusted");
_cons_theme_prop(THEME_TIME, "main.time");
_cons_theme_prop(THEME_TEXT, "main.text");
_cons_theme_prop(THEME_SPLASH, "main.splash");
_cons_theme_prop(THEME_ERROR, "error");
_cons_theme_prop(THEME_OTR_STARTED_TRUSTED, "otr.started.trusted");
_cons_theme_prop(THEME_OTR_STARTED_UNTRUSTED, "otr.started.untrusted");
_cons_theme_prop(THEME_OTR_ENDED, "otr.ended");
_cons_theme_prop(THEME_OTR_TRUSTED, "otr.trusted");
_cons_theme_prop(THEME_OTR_UNTRUSTED, "otr.untrusted");
_cons_theme_prop(console, THEME_ME, "me");
_cons_theme_prop(console, THEME_TEXT_ME, "main.text.me");
_cons_theme_prop(console, THEME_THEM, "them");
_cons_theme_prop(console, THEME_TEXT_THEM, "main.text.them");
_cons_theme_prop(console, THEME_TEXT_HISTORY, "main.text.history");
_cons_theme_prop(THEME_ME, "me");
_cons_theme_prop(THEME_TEXT_ME, "main.text.me");
_cons_theme_prop(THEME_THEM, "them");
_cons_theme_prop(THEME_TEXT_THEM, "main.text.them");
_cons_theme_prop(THEME_TEXT_HISTORY, "main.text.history");
_cons_theme_prop(console, THEME_CHAT, "chat");
_cons_theme_prop(console, THEME_ONLINE, "online");
_cons_theme_prop(console, THEME_AWAY, "away");
_cons_theme_prop(console, THEME_XA, "xa");
_cons_theme_prop(console, THEME_DND, "dnd");
_cons_theme_prop(console, THEME_OFFLINE, "offline");
_cons_theme_prop(console, THEME_SUBSCRIBED, "subscribed");
_cons_theme_prop(console, THEME_UNSUBSCRIBED, "unsubscribed");
_cons_theme_prop(THEME_CHAT, "chat");
_cons_theme_prop(THEME_ONLINE, "online");
_cons_theme_prop(THEME_AWAY, "away");
_cons_theme_prop(THEME_XA, "xa");
_cons_theme_prop(THEME_DND, "dnd");
_cons_theme_prop(THEME_OFFLINE, "offline");
_cons_theme_prop(THEME_SUBSCRIBED, "subscribed");
_cons_theme_prop(THEME_UNSUBSCRIBED, "unsubscribed");
_cons_theme_prop(console, THEME_INCOMING, "incoming");
_cons_theme_prop(console, THEME_MENTION, "mention");
_cons_theme_prop(console, THEME_TRIGGER, "trigger");
_cons_theme_prop(console, THEME_TYPING, "typing");
_cons_theme_prop(console, THEME_GONE, "gone");
_cons_theme_prop(THEME_INCOMING, "incoming");
_cons_theme_prop(THEME_MENTION, "mention");
_cons_theme_prop(THEME_TRIGGER, "trigger");
_cons_theme_prop(THEME_TYPING, "typing");
_cons_theme_prop(THEME_GONE, "gone");
_cons_theme_prop(console, THEME_ROOMINFO, "roominfo");
_cons_theme_prop(console, THEME_ROOMMENTION, "roommention");
_cons_theme_prop(console, THEME_ROOMMENTION_TERM, "roommention.term");
_cons_theme_prop(console, THEME_ROOMTRIGGER, "roomtrigger");
_cons_theme_prop(console, THEME_ROOMTRIGGER_TERM, "roomtrigger.term");
_cons_theme_prop(THEME_ROOMINFO, "roominfo");
_cons_theme_prop(THEME_ROOMMENTION, "roommention");
_cons_theme_prop(THEME_ROOMMENTION_TERM, "roommention.term");
_cons_theme_prop(THEME_ROOMTRIGGER, "roomtrigger");
_cons_theme_prop(THEME_ROOMTRIGGER_TERM, "roomtrigger.term");
_cons_theme_prop(console, THEME_ROSTER_HEADER, "roster.header");
_cons_theme_prop(console, THEME_ROSTER_CHAT, "roster.chat");
_cons_theme_prop(console, THEME_ROSTER_ONLINE, "roster.online");
_cons_theme_prop(console, THEME_ROSTER_AWAY, "roster.away");
_cons_theme_prop(console, THEME_ROSTER_XA, "roster.xa");
_cons_theme_prop(console, THEME_ROSTER_DND, "roster.dnd");
_cons_theme_prop(console, THEME_ROSTER_OFFLINE, "roster.offline");
_cons_theme_prop(console, THEME_ROSTER_CHAT_ACTIVE, "roster.chat.active");
_cons_theme_prop(console, THEME_ROSTER_ONLINE_ACTIVE, "roster.online.active");
_cons_theme_prop(console, THEME_ROSTER_AWAY_ACTIVE, "roster.away.active");
_cons_theme_prop(console, THEME_ROSTER_XA_ACTIVE, "roster.xa.active");
_cons_theme_prop(console, THEME_ROSTER_DND_ACTIVE, "roster.dnd.active");
_cons_theme_prop(console, THEME_ROSTER_OFFLINE_ACTIVE, "roster.offline.active");
_cons_theme_prop(console, THEME_ROSTER_CHAT_UNREAD, "roster.chat.unread");
_cons_theme_prop(console, THEME_ROSTER_ONLINE_UNREAD, "roster.online.unread");
_cons_theme_prop(console, THEME_ROSTER_AWAY_UNREAD, "roster.away.unread");
_cons_theme_prop(console, THEME_ROSTER_XA_UNREAD, "roster.xa.unread");
_cons_theme_prop(console, THEME_ROSTER_DND_UNREAD, "roster.dnd.unread");
_cons_theme_prop(console, THEME_ROSTER_OFFLINE_UNREAD, "roster.offline.unread");
_cons_theme_prop(console, THEME_ROSTER_ROOM, "roster.room");
_cons_theme_prop(console, THEME_ROSTER_ROOM_UNREAD, "roster.room.unread");
_cons_theme_prop(console, THEME_ROSTER_ROOM_TRIGGER, "roster.room.trigger");
_cons_theme_prop(console, THEME_ROSTER_ROOM_MENTION, "roster.room.mention");
_cons_theme_prop(THEME_ROSTER_HEADER, "roster.header");
_cons_theme_prop(THEME_ROSTER_CHAT, "roster.chat");
_cons_theme_prop(THEME_ROSTER_ONLINE, "roster.online");
_cons_theme_prop(THEME_ROSTER_AWAY, "roster.away");
_cons_theme_prop(THEME_ROSTER_XA, "roster.xa");
_cons_theme_prop(THEME_ROSTER_DND, "roster.dnd");
_cons_theme_prop(THEME_ROSTER_OFFLINE, "roster.offline");
_cons_theme_prop(THEME_ROSTER_CHAT_ACTIVE, "roster.chat.active");
_cons_theme_prop(THEME_ROSTER_ONLINE_ACTIVE, "roster.online.active");
_cons_theme_prop(THEME_ROSTER_AWAY_ACTIVE, "roster.away.active");
_cons_theme_prop(THEME_ROSTER_XA_ACTIVE, "roster.xa.active");
_cons_theme_prop(THEME_ROSTER_DND_ACTIVE, "roster.dnd.active");
_cons_theme_prop(THEME_ROSTER_OFFLINE_ACTIVE, "roster.offline.active");
_cons_theme_prop(THEME_ROSTER_CHAT_UNREAD, "roster.chat.unread");
_cons_theme_prop(THEME_ROSTER_ONLINE_UNREAD, "roster.online.unread");
_cons_theme_prop(THEME_ROSTER_AWAY_UNREAD, "roster.away.unread");
_cons_theme_prop(THEME_ROSTER_XA_UNREAD, "roster.xa.unread");
_cons_theme_prop(THEME_ROSTER_DND_UNREAD, "roster.dnd.unread");
_cons_theme_prop(THEME_ROSTER_OFFLINE_UNREAD, "roster.offline.unread");
_cons_theme_prop(THEME_ROSTER_ROOM, "roster.room");
_cons_theme_prop(THEME_ROSTER_ROOM_UNREAD, "roster.room.unread");
_cons_theme_prop(THEME_ROSTER_ROOM_TRIGGER, "roster.room.trigger");
_cons_theme_prop(THEME_ROSTER_ROOM_MENTION, "roster.room.mention");
_cons_theme_prop(console, THEME_OCCUPANTS_HEADER, "occupants.header");
_cons_theme_prop(THEME_OCCUPANTS_HEADER, "occupants.header");
_cons_theme_prop(console, THEME_RECEIPT_SENT, "receipt.sent");
_cons_theme_prop(THEME_RECEIPT_SENT, "receipt.sent");
_cons_theme_prop(console, THEME_INPUT_TEXT, "input.text");
_cons_theme_prop(console, THEME_INPUT_MISSPELLED, "input.misspelled");
_cons_theme_prop(THEME_INPUT_TEXT, "input.text");
cons_show("");
}
@@ -2747,7 +2786,7 @@ cons_show_bookmarks_ignore(gchar** list, gsize len)
cons_show("");
cons_show("Ignored bookmarks:");
for (gsize i = 0; i < len; i++) {
for (int i = 0; i < len; i++) {
win_print(console, THEME_DEFAULT, "-", " %s", list[i]);
win_newline(console);
}
@@ -2800,15 +2839,13 @@ cons_strophe_setting(void)
}
}
cons_show("XEP-0198 Stream-Management : %s", sm_setting);
auto_gchar gchar* verbosity = prefs_get_string(PREF_STROPHE_VERBOSITY);
cons_show("libstrophe Verbosity : %s", verbosity);
cons_show("libstrophe Verbosity : %s", prefs_get_string(PREF_STROPHE_VERBOSITY));
}
void
cons_privacy_setting(void)
{
auto_gchar gchar* dblog = prefs_get_string(PREF_DBLOG);
cons_show("Database logging : %s", dblog);
cons_show("Database logging : %s", prefs_get_string(PREF_DBLOG));
if (prefs_get_boolean(PREF_HISTORY)) {
cons_show("Chat history (/history) : ON");

View File

@@ -4,7 +4,33 @@
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#include "config.h"
@@ -54,7 +80,6 @@
static int inp_size;
static gboolean perform_resize = FALSE;
static gboolean ui_suspended = FALSE;
static GTimer* ui_idle_time;
static WINDOW* main_scr;
@@ -64,14 +89,6 @@ static Display* display;
static void _ui_draw_term_title(void);
// Fail-safe gate: authoritative flag (doesn't depend on isendwin staying
// TRUE), plus the regular endwin check for shutdown.
static gboolean
_ui_redraw_suspended(void)
{
return ui_suspended || isendwin();
}
static void
_ui_close(void)
{
@@ -129,10 +146,6 @@ ui_sigwinch_handler(int sig)
void
ui_update(void)
{
if (_ui_redraw_suspended()) {
return;
}
ProfWin* current = wins_get_current();
if (current->layout->paged == 0) {
win_move_to_end(current);
@@ -146,7 +159,7 @@ ui_update(void)
title_bar_update_virtual();
status_bar_draw();
inp_put_back();
prof_doupdate();
doupdate();
if (perform_resize) {
perform_resize = FALSE;
@@ -174,7 +187,7 @@ ui_get_idle_time(void)
// if no libxss or xss idle time failed, use profanity idle time
#endif
gdouble seconds_elapsed = g_timer_elapsed(ui_idle_time, NULL);
unsigned long ms_elapsed = (unsigned long)(seconds_elapsed * 1000.0);
unsigned long ms_elapsed = seconds_elapsed * 1000.0;
return ms_elapsed;
}
@@ -184,56 +197,9 @@ ui_reset_idle_time(void)
g_timer_start(ui_idle_time);
}
void
ui_suspend(void)
{
inp_suspend();
// Flush before flipping the flag (prof_doupdate skips while suspended).
prof_doupdate();
ui_suspended = TRUE;
endwin();
}
void
ui_resume(void)
{
ui_suspended = FALSE;
clearok(stdscr, TRUE); // ncurses can't see vim's screen clobber
refresh();
inp_resume();
}
void
ui_beep(void)
{
if (!isendwin()) {
beep();
}
}
void
ui_flash(void)
{
if (!isendwin()) {
flash();
}
}
void
prof_doupdate(void)
{
if (!_ui_redraw_suspended()) {
doupdate();
}
}
void
ui_resize(void)
{
if (_ui_redraw_suspended()) {
return;
}
struct winsize w;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
erase();
@@ -252,10 +218,6 @@ ui_resize(void)
void
ui_redraw(void)
{
if (_ui_redraw_suspended()) {
return;
}
title_bar_resize();
wins_resize_all();
status_bar_resize();
@@ -399,7 +361,7 @@ void
ui_handle_login_account_success(ProfAccount* account, gboolean secured)
{
if (account->theme) {
if (theme_load(account->theme, FALSE)) {
if (theme_load(account->theme, false)) {
ui_load_colours();
if (prefs_get_boolean(PREF_ROSTER)) {
ui_show_roster();

View File

@@ -4,7 +4,33 @@
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#define _XOPEN_SOURCE_EXTENDED
@@ -50,7 +76,6 @@
#include "xmpp/roster_list.h"
#include "xmpp/chat_state.h"
#include "tools/editor.h"
#include "tools/spellcheck.h"
static WINDOW* inp_win;
static int pad_start = 0;
@@ -65,7 +90,6 @@ static fd_set fds;
static int r;
static char* inp_line = NULL;
static gboolean get_password = FALSE;
static gboolean is_suspended = FALSE;
static void _inp_win_update_virtual(void);
static int _inp_edited(const wint_t ch);
@@ -180,16 +204,6 @@ _inp_slashguard_check(void)
char*
inp_readline(void)
{
// UI is suspended
if (is_suspended || isendwin()) {
// Mirror the normal-path unlock so workers aren't starved
// for the whole editor session.
pthread_mutex_unlock(&lock);
g_usleep(100000); // 100ms
pthread_mutex_lock(&lock);
return NULL;
}
p_rl_timeout.tv_sec = inp_timeout / 1000;
p_rl_timeout.tv_usec = inp_timeout % 1000 * 1000;
FD_ZERO(&fds);
@@ -290,22 +304,6 @@ inp_close(void)
discard = NULL;
}
void
inp_suspend(void)
{
is_suspended = TRUE;
rl_callback_handler_remove();
rl_deprep_terminal();
}
void
inp_resume(void)
{
is_suspended = FALSE;
rl_callback_handler_install(NULL, _inp_rl_linehandler);
rl_prep_terminal(0);
}
char*
inp_get_line(void)
{
@@ -315,13 +313,11 @@ inp_get_line(void)
werase(inp_win);
wmove(inp_win, 0, 0);
_inp_win_update_virtual();
prof_doupdate();
doupdate();
char* line = NULL;
while (!line) {
line = inp_readline();
ui_update();
while (g_main_context_iteration(NULL, FALSE)) // non-blocking; bounded by ready sources
;
}
status_bar_clear_prompt();
return line;
@@ -344,14 +340,12 @@ inp_get_password(void)
werase(inp_win);
wmove(inp_win, 0, 0);
_inp_win_update_virtual();
prof_doupdate();
doupdate();
char* password = NULL;
get_password = TRUE;
while (!password) {
password = inp_readline();
ui_update();
while (g_main_context_iteration(NULL, FALSE)) // non-blocking; bounded by ready sources
;
}
get_password = FALSE;
status_bar_clear_prompt();
@@ -386,17 +380,12 @@ _inp_write(char* line, int offset)
getyx(inp_win, y, x);
col += x;
gboolean do_spell = prefs_get_boolean(PREF_SPELLCHECK_ENABLE) && (line[0] != '/');
for (size_t i = 0; line[i] != '\0'; i++) {
char* c = &line[i];
char retc[PROF_MB_CUR_MAX] = { 0 };
size_t ch_len = mbrlen(c, MB_CUR_MAX, NULL);
// ch_len == 0 means mbrlen consumed the null wide character;
// skipping it here keeps `i += ch_len - 1` below from
// underflowing to SIZE_MAX.
if ((ch_len == (size_t)-2) || (ch_len == (size_t)-1) || ch_len == 0) {
if ((ch_len == (size_t)-2) || (ch_len == (size_t)-1)) {
waddch(inp_win, ' ');
continue;
}
@@ -404,7 +393,7 @@ _inp_write(char* line, int offset)
if (line[i] == '\n') {
c = retc;
ch_len = wctomb(retc, L'\u23ce'); /* return symbol */
if (ch_len == (size_t)-1) { /* not representable */
if (ch_len == -1) { /* not representable */
retc[0] = '\\';
ch_len = 1;
}
@@ -412,62 +401,14 @@ _inp_write(char* line, int offset)
i += ch_len - 1;
}
if (do_spell) {
gunichar uc = g_utf8_get_char(c);
if (g_unichar_isalnum(uc) || uc == '\'') {
// start of a word
size_t start = i - (ch_len - 1);
size_t end = start + ch_len;
while (line[end] != '\0') {
size_t next_ch_len = mbrlen(&line[end], MB_CUR_MAX, NULL);
// ch_len == 0 means embedded NUL — stop, otherwise
// `end += next_ch_len` loops forever.
if (next_ch_len == (size_t)-2 || next_ch_len == (size_t)-1 || next_ch_len == 0)
break;
gunichar next_uc = g_utf8_get_char(&line[end]);
if (!g_unichar_isalnum(next_uc) && next_uc != '\'')
break;
end += next_ch_len;
}
auto_gchar gchar* word = g_strndup(&line[start], end - start);
gboolean misspelled = spellcheck_is_misspelled(word);
if (misspelled) {
wattron(inp_win, theme_attrs(THEME_INPUT_MISSPELLED));
}
// add the word
size_t word_pos = start;
while (word_pos < end) {
size_t cur_ch_len = mbrlen(&line[word_pos], MB_CUR_MAX, NULL);
// Defensive: invalid or zero-length step would loop
// forever; advance one byte and continue.
if (cur_ch_len == (size_t)-2 || cur_ch_len == (size_t)-1 || cur_ch_len == 0) {
word_pos++;
continue;
}
waddnstr(inp_win, &line[word_pos], (int)cur_ch_len);
word_pos += cur_ch_len;
}
if (misspelled) {
wattroff(inp_win, theme_attrs(THEME_INPUT_MISSPELLED));
}
i = end - 1;
continue;
}
}
waddnstr(inp_win, c, (int)ch_len);
waddnstr(inp_win, c, ch_len);
}
wmove(inp_win, 0, col);
_inp_win_handle_scroll();
_inp_win_update_virtual();
prof_doupdate();
doupdate();
}
static int
@@ -513,13 +454,11 @@ _inp_offset_to_col(char* str, int offset)
while (i < offset && str[i] != '\0') {
gunichar uni = g_utf8_get_char(&str[i]);
size_t ch_len = mbrlen(&str[i], MB_CUR_MAX, NULL);
// ch_len == 0 (embedded NUL) would freeze the loop on the same
// byte; treat it like an invalid step.
if ((ch_len == (size_t)-2) || (ch_len == (size_t)-1) || ch_len == 0) {
if ((ch_len == (size_t)-2) || (ch_len == (size_t)-1)) {
i++;
continue;
}
i += (int)ch_len;
i += ch_len;
col++;
if (g_unichar_iswide(uni)) {
col++;
@@ -1066,16 +1005,6 @@ _inp_rl_down_arrow_handler(int count, int key)
return 0;
}
static void
_editor_finished_cb(gchar* message, void* user_data)
{
if (message) {
rl_replace_line(message, 0);
rl_point = rl_end;
rl_forced_update_display();
}
}
static int
_inp_rl_send_to_editor(int count, int key)
{
@@ -1083,7 +1012,9 @@ _inp_rl_send_to_editor(int count, int key)
return 0;
}
launch_editor(rl_line_buffer, _editor_finished_cb, NULL);
auto_gchar gchar* message = NULL;
get_message_from_editor_async(rl_line_buffer);
return 0;
}

View File

@@ -4,7 +4,33 @@
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#ifndef UI_INPUTWIN_H
@@ -18,8 +44,6 @@ void create_input_window(void);
void inp_close(void);
void inp_win_resize(void);
void inp_put_back(void);
void inp_suspend(void);
void inp_resume(void);
char* inp_get_password(void);
char* inp_get_line(void);
void inp_set_line(const char* const new_line);

View File

@@ -3,9 +3,35 @@
* vim: expandtab:ts=4:sts=4:sw=4
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
* Copyright (C) 2019 - 2026 Michael Vetter <jubalh@iodoru.org>
* Copyright (C) 2019 - 2025 Michael Vetter <jubalh@iodoru.org>
*
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
*/
#include "config.h"
@@ -382,7 +408,7 @@ _mucwin_print_mention(ProfWin* window, const char* const message, const char* co
auto_gchar gchar* mynick_str = g_utf8_substring(message, pos, pos + mynick_len);
win_append_highlight(window, THEME_ROOMMENTION_TERM, "%s", mynick_str);
last_pos = pos + (int)mynick_len;
last_pos = pos + mynick_len;
curr = g_slist_next(curr);
}
@@ -400,8 +426,8 @@ _mucwin_print_mention(ProfWin* window, const char* const message, const char* co
gint
_cmp_trigger_weight(gconstpointer a, gconstpointer b)
{
size_t alen = strlen((char*)a);
size_t blen = strlen((char*)b);
int alen = strlen((char*)a);
int blen = strlen((char*)b);
if (alen > blen)
return -1;
@@ -438,10 +464,10 @@ _mucwin_print_triggers(ProfWin* window, const char* const message, GList* trigge
}
// found, replace vars if earlier than previous
int trigger_pos = (int)(trigger_ptr - message_lower);
int trigger_pos = trigger_ptr - message_lower;
if (first_trigger_pos == -1 || trigger_pos < first_trigger_pos) {
first_trigger_pos = trigger_pos;
first_trigger_len = (int)strlen(trigger_lower);
first_trigger_len = strlen(trigger_lower);
}
curr = g_list_next(curr);
@@ -471,7 +497,7 @@ _mucwin_print_triggers(ProfWin* window, const char* const message, GList* trigge
}
trigger_section[i] = '\0';
if (first_trigger_pos + first_trigger_len < (int)strlen(message)) {
if (first_trigger_pos + first_trigger_len < strlen(message)) {
win_append_highlight(window, THEME_ROOMTRIGGER_TERM, "%s", trigger_section);
_mucwin_print_triggers(window, &message[first_trigger_pos + first_trigger_len], triggers);
} else {

View File

@@ -4,7 +4,33 @@
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#include "config.h"
@@ -26,9 +52,6 @@
#include "config/preferences.h"
#include "ui/ui.h"
#include "ui/window_list.h"
#ifdef HAVE_GTK
#include "ui/tray.h"
#endif
#include "xmpp/xmpp.h"
#include "xmpp/muc.h"
@@ -57,11 +80,6 @@ _notifier_uninit(void)
static void
_notify(const char* const message, int timeout, const char* const category)
{
#ifdef HAVE_GTK
if (!tray_gtk_ready()) {
return;
}
#endif
log_debug("Attempting notification: %s", message);
if (notify_is_initted()) {
log_debug("Reinitialising libnotify");
@@ -79,13 +97,14 @@ _notify(const char* const message, int timeout, const char* const category)
notify_notification_set_category(notification, category);
notify_notification_set_urgency(notification, NOTIFY_URGENCY_NORMAL);
auto_gerror GError* error = NULL;
GError* error = NULL;
gboolean notify_success = notify_notification_show(notification, &error);
if (!notify_success) {
log_error("Error sending desktop notification:");
log_error(" -> Message : %s", message);
log_error(" -> Error : %s", PROF_GERROR_MESSAGE(error));
log_error(" -> Error : %s", error->message);
g_error_free(error);
} else {
log_debug("Notification sent.");
}

View File

@@ -3,9 +3,35 @@
* vim: expandtab:ts=4:sts=4:sw=4
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
* Copyright (C) 2019 - 2026 Michael Vetter <jubalh@iodoru.org>
* Copyright (C) 2019 - 2025 Michael Vetter <jubalh@iodoru.org>
*
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
*/
#include "config.h"

View File

@@ -4,7 +4,33 @@
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#include "config.h"
@@ -57,7 +83,7 @@ privwin_incoming_msg(ProfPrivateWin* privatewin, ProfMessage* message)
privatewin->unread++;
if (prefs_get_boolean(PREF_FLASH)) {
ui_flash();
flash();
}
}
@@ -65,7 +91,7 @@ privwin_incoming_msg(ProfPrivateWin* privatewin, ProfMessage* message)
wins_add_quotes_ac(window, message->plain, TRUE);
if (prefs_get_boolean(PREF_BEEP)) {
ui_beep();
beep();
}
if (notify) {

View File

@@ -3,9 +3,35 @@
* vim: expandtab:ts=4:sts=4:sw=4
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
* Copyright (C) 2019 - 2026 Michael Vetter <jubalh@iodoru.org>
* Copyright (C) 2019 - 2025 Michael Vetter <jubalh@iodoru.org>
*
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
*/
#include "config.h"
@@ -552,7 +578,7 @@ _rosterwin_resources(ProfLayoutSplit* layout, PContact contact, int current_inde
g_string_append(msg, " ");
this_indent--;
}
auto_gchar gchar* ch = prefs_get_roster_resource_char();
auto_char char* ch = prefs_get_roster_resource_char();
if (ch) {
g_string_append_printf(msg, "%s", ch);
}

View File

@@ -4,7 +4,33 @@
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#include "config.h"

View File

@@ -4,7 +4,33 @@
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
int screen_titlebar_row(void);

View File

@@ -3,9 +3,35 @@
* vim: expandtab:ts=4:sts=4:sw=4
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
* Copyright (C) 2019 - 2026 Michael Vetter <jubalh@iodoru.org>
* Copyright (C) 2019 - 2025 Michael Vetter <jubalh@iodoru.org>
*
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
*/
#include "config.h"
@@ -48,27 +74,25 @@ typedef struct _status_bar_t
char* prompt;
char* fulljid;
GHashTable* tabs;
guint current_tab;
int current_tab;
} StatusBar;
static GTimeZone* tz;
static StatusBar* statusbar;
static WINDOW* statusbar_win;
#define CONSOLE_TAB_ID 10 // Console tab ID in status bar hash table
void _get_range_bounds(guint* start, guint* end, gboolean is_static);
static guint _status_bar_draw_time(guint pos);
static guint _status_bar_draw_maintext(guint pos);
static guint _status_bar_draw_dbbackend(guint pos);
static guint _status_bar_draw_bracket(gboolean current, guint pos, const char* ch);
static guint _status_bar_draw_extended_tabs(guint pos, gboolean prefix, guint start, guint end, gboolean is_static);
static guint _status_bar_draw_tab(StatusBarTab* tab, guint pos, guint num, gboolean include_brackets);
static guint _status_bar_draw_tabs(guint pos);
void _get_range_bounds(int* start, int* end, gboolean is_static);
static int _status_bar_draw_time(int pos);
static int _status_bar_draw_maintext(int pos);
static int _status_bar_draw_dbbackend(int pos);
static int _status_bar_draw_bracket(gboolean current, int pos, const char* ch);
static int _status_bar_draw_extended_tabs(int pos, gboolean prefix, int start, int end, gboolean is_static);
static int _status_bar_draw_tab(StatusBarTab* tab, int pos, int num, gboolean include_brackets);
static int _status_bar_draw_tabs(int pos);
static void _destroy_tab(StatusBarTab* tab);
static guint _tabs_width(guint start, guint end);
static guint _count_digits(guint number);
static guint _count_digits_in_range(guint start, guint end);
static int _tabs_width(int start, int end);
static unsigned int _count_digits(int number);
static unsigned int _count_digits_in_range(int start, int end);
static char* _display_name(StatusBarTab* tab);
static gboolean _tabmode_is_actlist(void);
@@ -77,12 +101,12 @@ status_bar_init(void)
{
tz = g_time_zone_new_local();
statusbar = g_new0(StatusBar, 1);
statusbar = malloc(sizeof(StatusBar));
statusbar->time = NULL;
statusbar->prompt = NULL;
statusbar->fulljid = NULL;
statusbar->tabs = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)_destroy_tab);
StatusBarTab* console = g_new0(StatusBarTab, 1);
StatusBarTab* console = calloc(1, sizeof(StatusBarTab));
console->window_type = WIN_CONSOLE;
console->identifier = strdup("console");
console->display_name = NULL;
@@ -156,10 +180,10 @@ status_bar_set_all_inactive(void)
}
void
status_bar_current(guint i)
status_bar_current(int i)
{
if (i == 0) {
statusbar->current_tab = CONSOLE_TAB_ID;
statusbar->current_tab = 10;
} else {
statusbar->current_tab = i;
}
@@ -170,7 +194,12 @@ status_bar_current(guint i)
void
status_bar_inactive(const int win)
{
g_hash_table_remove(statusbar->tabs, GINT_TO_POINTER((win == 0) ? CONSOLE_TAB_ID : win));
int true_win = win;
if (true_win == 0) {
true_win = 10;
}
g_hash_table_remove(statusbar->tabs, GINT_TO_POINTER(true_win));
status_bar_draw();
}
@@ -178,7 +207,9 @@ status_bar_inactive(const int win)
void
_create_tab(const int win, win_type_t wintype, char* identifier, gboolean highlight)
{
StatusBarTab* tab = g_new0(StatusBarTab, 1);
int true_win = win == 0 ? 10 : win;
StatusBarTab* tab = malloc(sizeof(StatusBarTab));
tab->identifier = strdup(identifier);
tab->highlight = highlight;
tab->window_type = wintype;
@@ -207,7 +238,7 @@ _create_tab(const int win, win_type_t wintype, char* identifier, gboolean highli
}
}
g_hash_table_replace(statusbar->tabs, GINT_TO_POINTER((win == 0) ? CONSOLE_TAB_ID : win), tab);
g_hash_table_replace(statusbar->tabs, GINT_TO_POINTER(true_win), tab);
status_bar_draw();
}
@@ -279,8 +310,8 @@ status_bar_draw(void)
werase(statusbar_win);
wbkgd(statusbar_win, theme_attrs(THEME_STATUS_TEXT));
guint max_tabs = prefs_get_statusbartabs();
guint pos = 1;
gint max_tabs = prefs_get_statusbartabs();
int pos = 1;
pos = _status_bar_draw_time(pos);
pos = _status_bar_draw_maintext(pos);
@@ -292,27 +323,24 @@ status_bar_draw(void)
inp_put_back();
}
static guint
_status_bar_draw_tabs(guint pos)
static int
_status_bar_draw_tabs(int pos)
{
auto_gchar gchar* tabmode = prefs_get_string(PREF_STATUSBAR_TABMODE);
if (g_strcmp0(tabmode, "actlist") != 0) {
guint start, end;
int start, end;
gboolean is_static = g_strcmp0(tabmode, "dynamic") != 0;
_get_range_bounds(&start, &end, is_static);
guint tabs_w = _tabs_width(start, end);
int max_x = getmaxx(stdscr);
if (max_x > 0 && (guint)max_x > tabs_w) {
pos = (guint)max_x - tabs_w;
} else {
pos = getmaxx(stdscr) - _tabs_width(start, end);
if (pos < 0) {
pos = 0;
}
pos = _status_bar_draw_extended_tabs(pos, TRUE, start, end, is_static);
for (guint i = start; i <= end; i++) {
for (int i = start; i <= end; i++) {
StatusBarTab* tab = g_hash_table_lookup(statusbar->tabs, GINT_TO_POINTER(i));
if (tab) {
pos = _status_bar_draw_tab(tab, pos, i, TRUE);
@@ -360,9 +388,9 @@ _status_bar_draw_tabs(guint pos)
static gboolean
_has_new_msgs_beyond_range_on_side(gboolean left_side, int display_tabs_start, int display_tabs_end)
{
guint max_tabs = prefs_get_statusbartabs();
gint max_tabs = prefs_get_statusbartabs();
int tabs_count = g_hash_table_size(statusbar->tabs);
if ((guint)tabs_count <= max_tabs) {
if (tabs_count <= max_tabs) {
return FALSE;
}
@@ -379,10 +407,10 @@ _has_new_msgs_beyond_range_on_side(gboolean left_side, int display_tabs_start, i
return FALSE;
}
static guint
_status_bar_draw_extended_tabs(guint pos, gboolean prefix, guint start, guint end, gboolean is_static)
static int
_status_bar_draw_extended_tabs(int pos, gboolean prefix, int start, int end, gboolean is_static)
{
guint max_tabs = prefs_get_statusbartabs();
gint max_tabs = prefs_get_statusbartabs();
if (max_tabs == 0) {
return pos;
}
@@ -395,9 +423,7 @@ _status_bar_draw_extended_tabs(guint pos, gboolean prefix, guint start, guint en
if (prefix && start < 2) {
return pos;
}
// Guard against underflow when opened_tabs == 0 (reachable if the
// earlier `opened_tabs <= max_tabs` early-return no longer holds).
if (!prefix && end >= opened_tabs) {
if (!prefix && end > opened_tabs - 1) {
return pos;
}
gboolean is_current = is_static && statusbar->current_tab > max_tabs;
@@ -423,8 +449,8 @@ _status_bar_draw_extended_tabs(guint pos, gboolean prefix, guint start, guint en
return pos;
}
static guint
_status_bar_draw_tab(StatusBarTab* tab, guint pos, guint num, gboolean include_brackets)
static int
_status_bar_draw_tab(StatusBarTab* tab, int pos, int num, gboolean include_brackets)
{
gboolean is_current = num == statusbar->current_tab;
@@ -472,8 +498,8 @@ _status_bar_draw_tab(StatusBarTab* tab, guint pos, guint num, gboolean include_b
return pos;
}
static guint
_status_bar_draw_bracket(gboolean current, guint pos, const char* ch)
static int
_status_bar_draw_bracket(gboolean current, int pos, const char* ch)
{
int bracket_attrs = theme_attrs(THEME_STATUS_BRACKET);
wattron(statusbar_win, bracket_attrs);
@@ -488,8 +514,8 @@ _status_bar_draw_bracket(gboolean current, guint pos, const char* ch)
return pos;
}
static guint
_status_bar_draw_time(guint pos)
static int
_status_bar_draw_time(int pos)
{
auto_gchar gchar* time_pref = prefs_get_string(PREF_TIME_STATUSBAR);
if (g_strcmp0(time_pref, "off") == 0) {
@@ -509,7 +535,7 @@ _status_bar_draw_time(guint pos)
int bracket_attrs = theme_attrs(THEME_STATUS_BRACKET);
int time_attrs = theme_attrs(THEME_STATUS_TIME);
guint len = (guint)strlen(statusbar->time);
size_t len = strlen(statusbar->time);
wattron(statusbar_win, bracket_attrs);
mvwaddch(statusbar_win, 0, pos, '[');
pos++;
@@ -533,8 +559,8 @@ _tabmode_is_actlist(void)
return g_strcmp0(tabmode, "actlist") == 0;
}
static guint
_status_bar_draw_maintext(guint pos)
static int
_status_bar_draw_maintext(int pos)
{
const char* maintext = NULL;
auto_jid Jid* jidp = NULL;
@@ -580,8 +606,8 @@ _status_bar_draw_maintext(guint pos)
return pos;
}
static guint
_status_bar_draw_dbbackend(guint pos)
static int
_status_bar_draw_dbbackend(int pos)
{
if (!prefs_get_boolean(PREF_STATUSBAR_SHOW_DBBACKEND))
return pos;
@@ -607,20 +633,20 @@ _destroy_tab(StatusBarTab* tab)
}
}
static guint
_tabs_width(guint start, guint end)
static int
_tabs_width(int start, int end)
{
gboolean show_number = prefs_get_boolean(PREF_STATUSBAR_SHOW_NUMBER);
gboolean show_name = prefs_get_boolean(PREF_STATUSBAR_SHOW_NAME);
gboolean show_read = prefs_get_boolean(PREF_STATUSBAR_SHOW_READ);
guint max_tabs = prefs_get_statusbartabs();
gint max_tabs = prefs_get_statusbartabs();
guint opened_tabs = g_hash_table_size(statusbar->tabs);
int width = start < 2 ? 1 : 4;
width += (end < opened_tabs) ? 3 : 0;
width += end > opened_tabs - 1 ? 0 : 3;
if (show_name && show_number) {
for (guint i = start; i <= end; i++) {
for (int i = start; i <= end; i++) {
StatusBarTab* tab = g_hash_table_lookup(statusbar->tabs, GINT_TO_POINTER(i));
if (tab) {
gboolean is_current = i == statusbar->current_tab;
@@ -637,7 +663,7 @@ _tabs_width(guint start, guint end)
}
if (show_name && !show_number) {
for (guint i = start; i <= end; i++) {
for (int i = start; i <= end; i++) {
StatusBarTab* tab = g_hash_table_lookup(statusbar->tabs, GINT_TO_POINTER(i));
if (tab) {
gboolean is_current = i == statusbar->current_tab;
@@ -713,7 +739,7 @@ _display_name(StatusBarTab* tab)
}
void
_get_range_bounds(guint* start, guint* end, gboolean is_static)
_get_range_bounds(int* start, int* end, gboolean is_static)
{
int current_tab = statusbar->current_tab;
gint display_range = prefs_get_statusbartabs();
@@ -736,10 +762,12 @@ _get_range_bounds(guint* start, guint* end, gboolean is_static)
}
// Counts amount of digits in a number
static guint
_count_digits(guint number)
static unsigned int
_count_digits(int number)
{
guint digits_count = 0;
unsigned int digits_count = 0;
if (number < 0)
number = -number;
do {
number /= 10;
@@ -751,11 +779,12 @@ _count_digits(guint number)
// Counts the total number of digits in a range of numbers, inclusive.
// Example: _count_digits_in_range(2, 3) returns 2, _count_digits_in_range(2, 922) returns 2657
static guint
_count_digits_in_range(guint start, guint end)
static unsigned int
_count_digits_in_range(int start, int end)
{
guint total_digits = 0;
for (guint i = start; i <= end; i++) {
int total_digits = 0;
for (int i = start; i <= end; i++) {
total_digits += _count_digits(i);
}

View File

@@ -4,7 +4,33 @@
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#ifndef UI_STATUSBAR_H
@@ -18,6 +44,6 @@ void status_bar_set_prompt(const char* const prompt);
void status_bar_clear_prompt(void);
void status_bar_set_fulljid(const char* const fulljid);
void status_bar_clear_fulljid(void);
void status_bar_current(guint i);
void status_bar_current(int i);
#endif

View File

@@ -3,9 +3,35 @@
* vim: expandtab:ts=4:sts=4:sw=4
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
* Copyright (C) 2019 - 2026 Michael Vetter <jubalh@iodoru.org>
* Copyright (C) 2019 - 2025 Michael Vetter <jubalh@iodoru.org>
*
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
*/
#include <stdlib.h>
@@ -24,9 +50,6 @@
#include "ui/window_list.h"
#include "ui/window.h"
#include "ui/screen.h"
#ifdef HAVE_OMEMO
#include "omemo/omemo.h"
#endif
#include "xmpp/roster_list.h"
#include "xmpp/chat_session.h"
@@ -46,24 +69,6 @@ static void _show_privacy(ProfChatWin* chatwin);
static void _show_muc_privacy(ProfMucWin* mucwin);
static void _show_scrolled(ProfWin* current);
static void _show_attention(ProfWin* current, gboolean attention);
static void _show_trust_indicator(gboolean trusted, int bracket_attrs, int trusted_attrs, int untrusted_attrs);
static inline void
_wprintw_withattr(WINDOW* w, const char* text, int attrs)
{
wattron(w, attrs);
wprintw(w, "%s", text);
wattroff(w, attrs);
}
static void
_show_trust_indicator(gboolean trusted, int bracket_attrs, int trusted_attrs, int untrusted_attrs)
{
wprintw(win, " ");
_wprintw_withattr(win, "[", bracket_attrs);
_wprintw_withattr(win, trusted ? "trusted" : "untrusted", trusted ? trusted_attrs : untrusted_attrs);
_wprintw_withattr(win, "]", bracket_attrs);
}
void
create_title_bar(void)
@@ -225,7 +230,7 @@ _title_bar_draw(void)
auto_gchar gchar* title = win_get_title(current);
mvwprintw(win, 0, 0, " %s", title);
pos = (int)strlen(title) + 1;
pos = strlen(title) + 1;
// presence is written from the right side
// calculate it first so we have a maxposition
@@ -438,10 +443,6 @@ _show_muc_privacy(ProfMucWin* mucwin)
{
int bracket_attrs = theme_attrs(THEME_TITLE_BRACKET);
int encrypted_attrs = theme_attrs(THEME_TITLE_ENCRYPTED);
#ifdef HAVE_OMEMO
int trusted_attrs = theme_attrs(THEME_TITLE_TRUSTED);
int untrusted_attrs = theme_attrs(THEME_TITLE_UNTRUSTED);
#endif
if (mucwin->is_omemo) {
wprintw(win, " ");
@@ -455,10 +456,6 @@ _show_muc_privacy(ProfMucWin* mucwin)
wprintw(win, "]");
wattroff(win, bracket_attrs);
#ifdef HAVE_OMEMO
_show_trust_indicator(mucwin->omemo_trusted, bracket_attrs, trusted_attrs, untrusted_attrs);
#endif
return;
}
@@ -525,7 +522,29 @@ _show_privacy(ProfChatWin* chatwin)
wattron(win, bracket_attrs);
wprintw(win, "]");
wattroff(win, bracket_attrs);
_show_trust_indicator(chatwin->otr_is_trusted, bracket_attrs, trusted_attrs, untrusted_attrs);
if (chatwin->otr_is_trusted) {
wprintw(win, " ");
wattron(win, bracket_attrs);
wprintw(win, "[");
wattroff(win, bracket_attrs);
wattron(win, trusted_attrs);
wprintw(win, "trusted");
wattroff(win, trusted_attrs);
wattron(win, bracket_attrs);
wprintw(win, "]");
wattroff(win, bracket_attrs);
} else {
wprintw(win, " ");
wattron(win, bracket_attrs);
wprintw(win, "[");
wattroff(win, bracket_attrs);
wattron(win, untrusted_attrs);
wprintw(win, "untrusted");
wattroff(win, untrusted_attrs);
wattron(win, bracket_attrs);
wprintw(win, "]");
wattroff(win, bracket_attrs);
}
return;
}
@@ -566,10 +585,6 @@ _show_privacy(ProfChatWin* chatwin)
wprintw(win, "]");
wattroff(win, bracket_attrs);
#ifdef HAVE_OMEMO
_show_trust_indicator(chatwin->omemo_trusted, bracket_attrs, trusted_attrs, untrusted_attrs);
#endif
return;
}
@@ -601,7 +616,7 @@ _show_contact_presence(ProfChatWin* chatwin, int pos, int maxpos)
}
if (resource && prefs_get_boolean(PREF_RESOURCE_TITLE)) {
int needed = (int)strlen(resource) + 1;
int needed = strlen(resource) + 1;
if (pos + needed < maxpos) {
wprintw(win, "/");
wprintw(win, "%s", resource);

View File

@@ -4,14 +4,38 @@
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#ifndef UI_TITLEBAR_H
#define UI_TITLEBAR_H
#include "glib.h"
void create_title_bar(void);
void free_title_bar(void);
void title_bar_update_virtual(void);

View File

@@ -4,7 +4,33 @@
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#include "config.h"
@@ -21,11 +47,6 @@
#include "ui/tray.h"
#include "ui/window_list.h"
#if defined(GDK_WINDOWING_X11) && defined(HAVE_XEXITHANDLER)
#include <gdk/gdkx.h>
#include <X11/Xlib.h>
#endif
static gboolean gtk_ready = FALSE;
static GtkStatusIcon* prof_tray = NULL;
static GString* icon_filename = NULL;
@@ -34,21 +55,6 @@ static gint unread_messages;
static gboolean shutting_down;
static guint timer;
#if defined(GDK_WINDOWING_X11) && defined(HAVE_XEXITHANDLER)
static void
_x_io_error_handler(Display* display, void* user_data)
{
log_warning("Error: X Server connection lost.");
gtk_ready = FALSE;
}
static int
_x_io_handler(Display* display)
{
return 0;
}
#endif
/*
* Get icons from installation share folder or (if defined) .locale user's folder
*
@@ -75,7 +81,7 @@ _get_icons(void)
auto_gchar gchar* icons_dir_s = files_get_config_path(DIR_ICONS);
icons_dir = g_string_new(icons_dir_s);
auto_gerror GError* err = NULL;
GError* err = NULL;
if (!g_file_test(icons_dir->str, G_FILE_TEST_IS_DIR)) {
return;
@@ -103,7 +109,8 @@ _get_icons(void)
}
g_string_free(name, TRUE);
} else {
log_error("Unable to open dir: %s", PROF_GERROR_MESSAGE(err));
log_error("Unable to open dir: %s", err->message);
g_error_free(err);
}
g_dir_close(dir);
g_string_free(icons_dir, TRUE);
@@ -118,7 +125,7 @@ _get_icons(void)
gboolean
_tray_change_icon(gpointer data)
{
if (shutting_down || !gtk_ready) {
if (shutting_down) {
return FALSE;
}
@@ -171,14 +178,6 @@ tray_init(void)
return;
}
#if defined(GDK_WINDOWING_X11) && defined(HAVE_XEXITHANDLER)
GdkDisplay* display = gdk_display_get_default();
if (GDK_IS_X11_DISPLAY(display)) {
XSetIOErrorExitHandler(GDK_DISPLAY_XDISPLAY(display), _x_io_error_handler, NULL);
XSetIOErrorHandler(_x_io_handler);
}
#endif
if (prefs_get_boolean(PREF_TRAY)) {
log_debug("Building GTK icon");
tray_enable();
@@ -195,18 +194,9 @@ tray_update(void)
}
}
gboolean
tray_gtk_ready(void)
{
return gtk_ready;
}
void
tray_set_timer(int interval)
{
if (!gtk_ready) {
return;
}
if (timer) {
g_source_remove(timer);
}
@@ -223,9 +213,6 @@ tray_set_timer(int interval)
void
tray_enable(void)
{
if (!gtk_ready) {
return;
}
prof_tray = gtk_status_icon_new_from_file(icon_filename->str);
shutting_down = FALSE;
_tray_change_icon(NULL);

View File

@@ -4,17 +4,41 @@
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#ifndef UI_TRAY_H
#define UI_TRAY_H
#ifdef HAVE_GTK
#include <glib.h>
void tray_init(void);
void tray_update(void);
gboolean tray_gtk_ready(void);
void tray_enable(void);
void tray_disable(void);

View File

@@ -3,9 +3,35 @@
* vim: expandtab:ts=4:sts=4:sw=4
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
* Copyright (C) 2019 - 2026 Michael Vetter <jubalh@iodoru.org>
* Copyright (C) 2019 - 2025 Michael Vetter <jubalh@iodoru.org>
*
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
*/
#ifndef UI_UI_H
@@ -26,26 +52,19 @@
#include "otr/otr.h"
#endif
#define NO_ME 1
#define NO_DATE 2
#define NO_EOL 4
#define NO_COLOUR_FROM 8
#define NO_COLOUR_DATE 16
#define UNTRUSTED 32
#define ENTRY_COMPLETED 64
#define ENTRY_ERROR 128
#define NO_ME 1
#define NO_DATE 2
#define NO_EOL 4
#define NO_COLOUR_FROM 8
#define NO_COLOUR_DATE 16
#define UNTRUSTED 32
// core UI
void ui_init(void);
void ui_suspend(void);
void ui_resume(void);
void ui_load_colours(void);
void ui_update(void);
void ui_redraw(void);
void ui_resize(void);
// doupdate() wrapper that skips when the UI is suspended. Use this instead
// of raw doupdate() to avoid the per-site whitelist class of bug.
void prof_doupdate(void);
void ui_focus_win(ProfWin* window);
void ui_sigwinch_handler(int sig);
void ui_handle_otr_error(const char* const barejid, const char* const message);
@@ -87,8 +106,6 @@ void ui_handle_recipient_error(const char* const recipient, const char* const er
void ui_handle_error(const char* const err_msg);
void ui_clear_win_title(void);
void ui_goodbye_title(void);
void ui_beep(void);
void ui_flash(void);
void ui_handle_room_configuration_form_error(const char* const roomjid, const char* const message);
void ui_handle_room_config_submit_result(const char* const roomjid);
void ui_handle_room_config_submit_result_error(const char* const roomjid, const char* const message);
@@ -256,7 +273,7 @@ void cons_show_contacts(GSList* list);
void cons_show_roster(GSList* list);
void cons_show_roster_group(const char* const group, GSList* list);
void cons_show_wins(gboolean unread);
void cons_show_wins_attention(void);
void cons_show_wins_attention();
gchar* cons_get_string(ProfConsoleWin* conswin);
void cons_show_status(const char* const barejid);
void cons_show_info(PContact pcontact);
@@ -296,7 +313,6 @@ void cons_console_setting(void);
void cons_flash_setting(void);
void cons_tray_setting(void);
void cons_splash_setting(void);
void cons_spellcheck_setting(void);
void cons_titlebar_setting(void);
void cons_vercheck_setting(void);
void cons_occupants_setting(void);

View File

@@ -4,7 +4,33 @@
*
* Copyright (C) 2022 Marouane L. <techmetx11@disroot.org>
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#include "ui/ui.h"

View File

@@ -4,7 +4,33 @@
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#ifndef UI_WIN_TYPES_H
@@ -136,7 +162,6 @@ typedef struct prof_win_t
ProfLayout* layout;
Autocomplete urls_ac;
Autocomplete quotes_ac;
GHashTable* warned_jids;
} ProfWin;
typedef struct prof_console_win_t
@@ -155,7 +180,6 @@ typedef struct prof_chat_win_t
gboolean pgp_send;
gboolean pgp_recv;
gboolean is_omemo;
gboolean omemo_trusted;
gboolean is_ox; // XEP-0373: OpenPGP for XMPP
char* resource_override;
gboolean history_shown;
@@ -181,7 +205,6 @@ typedef struct prof_muc_win_t
gboolean showjid;
gboolean showoffline;
gboolean is_omemo;
gboolean omemo_trusted;
unsigned long memcheck;
char* enctext;
char* message_char;

View File

@@ -3,18 +3,41 @@
* vim: expandtab:ts=4:sts=4:sw=4
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
* Copyright (C) 2019 - 2026 Michael Vetter <jubalh@iodoru.org>
* Copyright (C) 2019 - 2025 Michael Vetter <jubalh@iodoru.org>
*
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
*/
#include "config.h"
#include "database.h"
#include "ui/win_types.h"
#include "ui/window_list.h"
#ifdef HAVE_OMEMO
#include "omemo/omemo.h"
#endif
#include <stdlib.h>
#include <string.h>
@@ -42,46 +65,6 @@
#include "xmpp/roster_list.h"
#include "ai/ai_client.h"
static const int PAD_MIN_HEIGHT = 100;
static const int PAD_DEAD_SPACE_LIMIT = 2000; // reclaim once the pad holds this much dead space (cursor past live buffer); size-independent, so it never fires while scrolling
static gboolean _in_redraw = FALSE;
static void
_win_ensure_pad_capacity(ProfWin* window, WINDOW* win, int lines_needed)
{
if (!win) {
return;
}
int cur_height = getmaxy(win);
int cur_width = getmaxx(win);
if (lines_needed >= cur_height - 1) {
// redraw to reclaim dead pad space (cursor far past live buffer, e.g. a long
// append-only session); dead space never accrues while scrolling, only here
int dead = window ? getcury(win) - window->layout->buffer->lines : 0;
if (window && dead > PAD_DEAD_SPACE_LIMIT && !_in_redraw) {
win_redraw(window);
} else {
// resize to required lines + some buffer for next messages
int new_height = lines_needed + 100;
wresize(win, new_height, cur_width);
}
}
}
// upper-bound estimate of rows a message body occupies (hard newlines + soft-wrap), to reserve pad space before printing so a tall message isn't clipped (a clipped height desyncs the scroll offset)
static int
_win_estimated_lines(WINDOW* win, const char* const message, int indent, int pad_indent)
{
int usable = MAX(1, getmaxx(win) - (indent + pad_indent));
int newlines = 0;
for (const char* p = message; *p; p++) {
if (*p == '\n') {
newlines++;
}
}
return newlines + utf8_display_len(message) / usable + 2;
}
static const char* LOADING_MESSAGE = "Loading older messages…";
static const char* CONS_WIN_TITLE = "CProof. Type /help for help information.";
static const char* XML_WIN_TITLE = "XML Console";
@@ -92,7 +75,7 @@ static void
_win_printf(ProfWin* window, const char* show_char, int pad_indent, GDateTime* timestamp, int flags, theme_item_t theme_item, const char* const display_from, const char* const from_jid, const char* const message_id, const char* const message, ...);
static void _win_print_internal(ProfWin* window, const char* show_char, int pad_indent, GDateTime* time,
int flags, theme_item_t theme_item, const char* const from, const char* const message, DeliveryReceipt* receipt);
static void _win_print_wrapped(WINDOW* win, const char* const message, int indent, int pad_indent);
static void _win_print_wrapped(WINDOW* win, const char* const message, size_t indent, int pad_indent);
// Helper: clamp a subwindow width to a sane range [1, cols-1] if possible
static int
@@ -128,9 +111,9 @@ _win_create_simple_layout(void)
{
int cols = getmaxx(stdscr);
ProfLayoutSimple* layout = g_new0(ProfLayoutSimple, 1);
ProfLayoutSimple* layout = malloc(sizeof(ProfLayoutSimple));
layout->base.type = LAYOUT_SIMPLE;
layout->base.win = newpad(PAD_MIN_HEIGHT, cols);
layout->base.win = newpad(PAD_SIZE, cols);
wbkgd(layout->base.win, theme_attrs(THEME_TEXT));
layout->base.buffer = buffer_create();
layout->base.y_pos = 0;
@@ -146,9 +129,9 @@ _win_create_split_layout(void)
{
int cols = getmaxx(stdscr);
ProfLayoutSplit* layout = g_new0(ProfLayoutSplit, 1);
ProfLayoutSplit* layout = malloc(sizeof(ProfLayoutSplit));
layout->base.type = LAYOUT_SPLIT;
layout->base.win = newpad(PAD_MIN_HEIGHT, cols);
layout->base.win = newpad(PAD_SIZE, cols);
wbkgd(layout->base.win, theme_attrs(THEME_TEXT));
layout->base.buffer = buffer_create();
layout->base.y_pos = 0;
@@ -165,7 +148,7 @@ _win_create_split_layout(void)
ProfWin*
win_create_console(void)
{
ProfConsoleWin* new_win = g_new0(ProfConsoleWin, 1);
ProfConsoleWin* new_win = malloc(sizeof(ProfConsoleWin));
new_win->window.type = WIN_CONSOLE;
new_win->window.scroll_state = WIN_SCROLL_INNER;
new_win->window.layout = _win_create_split_layout();
@@ -176,7 +159,8 @@ win_create_console(void)
ProfWin*
win_create_chat(const char* const barejid)
{
ProfChatWin* new_win = g_new0(ProfChatWin, 1);
assert(barejid != NULL);
ProfChatWin* new_win = malloc(sizeof(ProfChatWin));
new_win->window.type = WIN_CHAT;
new_win->window.scroll_state = WIN_SCROLL_INNER;
new_win->window.layout = _win_create_simple_layout();
@@ -188,9 +172,6 @@ win_create_chat(const char* const barejid)
new_win->pgp_recv = FALSE;
new_win->pgp_send = FALSE;
new_win->is_omemo = FALSE;
#ifdef HAVE_OMEMO
new_win->omemo_trusted = omemo_is_jid_trusted(barejid);
#endif
new_win->is_ox = FALSE;
new_win->history_shown = FALSE;
new_win->unread = 0;
@@ -210,22 +191,23 @@ win_create_chat(const char* const barejid)
ProfWin*
win_create_muc(const char* const roomjid)
{
ProfMucWin* new_win = g_new0(ProfMucWin, 1);
assert(roomjid != NULL);
ProfMucWin* new_win = malloc(sizeof(ProfMucWin));
int cols = getmaxx(stdscr);
new_win->window.type = WIN_MUC;
new_win->window.scroll_state = WIN_SCROLL_INNER;
ProfLayoutSplit* layout = g_new0(ProfLayoutSplit, 1);
ProfLayoutSplit* layout = malloc(sizeof(ProfLayoutSplit));
layout->base.type = LAYOUT_SPLIT;
if (prefs_get_boolean(PREF_OCCUPANTS)) {
int subwin_cols = win_occpuants_cols();
layout->base.win = newpad(PAD_MIN_HEIGHT, cols - subwin_cols);
layout->base.win = newpad(PAD_SIZE, cols - subwin_cols);
wbkgd(layout->base.win, theme_attrs(THEME_TEXT));
layout->subwin = newpad(PAD_MIN_HEIGHT, subwin_cols);
layout->subwin = newpad(PAD_SIZE, subwin_cols);
wbkgd(layout->subwin, theme_attrs(THEME_TEXT));
} else {
layout->base.win = newpad(PAD_MIN_HEIGHT, (cols));
layout->base.win = newpad(PAD_SIZE, (cols));
wbkgd(layout->base.win, theme_attrs(THEME_TEXT));
layout->subwin = NULL;
}
@@ -256,9 +238,6 @@ win_create_muc(const char* const roomjid)
new_win->enctext = NULL;
new_win->message_char = NULL;
new_win->is_omemo = FALSE;
#ifdef HAVE_OMEMO
new_win->omemo_trusted = omemo_is_jid_trusted(roomjid);
#endif
new_win->last_message = NULL;
new_win->last_msg_id = NULL;
new_win->has_attention = FALSE;
@@ -271,7 +250,9 @@ win_create_muc(const char* const roomjid)
ProfWin*
win_create_config(const char* const roomjid, DataForm* form, ProfConfWinCallback submit, ProfConfWinCallback cancel, const void* userdata)
{
ProfConfWin* new_win = g_new0(ProfConfWin, 1);
assert(roomjid != NULL);
assert(form != NULL);
ProfConfWin* new_win = malloc(sizeof(ProfConfWin));
new_win->window.type = WIN_CONFIG;
new_win->window.scroll_state = WIN_SCROLL_INNER;
new_win->window.layout = _win_create_simple_layout();
@@ -289,7 +270,8 @@ win_create_config(const char* const roomjid, DataForm* form, ProfConfWinCallback
ProfWin*
win_create_private(const char* const fulljid)
{
ProfPrivateWin* new_win = g_new0(ProfPrivateWin, 1);
assert(fulljid != NULL);
ProfPrivateWin* new_win = malloc(sizeof(ProfPrivateWin));
new_win->window.type = WIN_PRIVATE;
new_win->window.scroll_state = WIN_SCROLL_INNER;
new_win->window.layout = _win_create_simple_layout();
@@ -306,7 +288,7 @@ win_create_private(const char* const fulljid)
ProfWin*
win_create_xmlconsole(void)
{
ProfXMLWin* new_win = g_new0(ProfXMLWin, 1);
ProfXMLWin* new_win = malloc(sizeof(ProfXMLWin));
new_win->window.type = WIN_XML;
new_win->window.scroll_state = WIN_SCROLL_INNER;
new_win->window.layout = _win_create_simple_layout();
@@ -319,7 +301,9 @@ win_create_xmlconsole(void)
ProfWin*
win_create_plugin(const char* const plugin_name, const char* const tag)
{
ProfPluginWin* new_win = g_new0(ProfPluginWin, 1);
assert(plugin_name != NULL);
assert(tag != NULL);
ProfPluginWin* new_win = malloc(sizeof(ProfPluginWin));
new_win->window.type = WIN_PLUGIN;
new_win->window.scroll_state = WIN_SCROLL_INNER;
new_win->window.layout = _win_create_simple_layout();
@@ -335,7 +319,8 @@ win_create_plugin(const char* const plugin_name, const char* const tag)
ProfWin*
win_create_vcard(vCard* vcard)
{
ProfVcardWin* new_win = g_new0(ProfVcardWin, 1);
assert(vcard != NULL);
ProfVcardWin* new_win = malloc(sizeof(ProfVcardWin));
new_win->window.type = WIN_VCARD;
new_win->window.scroll_state = WIN_SCROLL_INNER;
new_win->window.layout = _win_create_simple_layout();
@@ -601,11 +586,11 @@ win_hide_subwin(ProfWin* window)
layout->subwin = NULL;
layout->sub_y_pos = 0;
int cols = getmaxx(stdscr);
wresize(layout->base.win, PAD_MIN_HEIGHT, cols);
wresize(layout->base.win, PAD_SIZE, cols);
win_redraw(window);
} else {
int cols = getmaxx(stdscr);
wresize(window->layout->win, PAD_MIN_HEIGHT, cols);
wresize(window->layout->win, PAD_SIZE, cols);
win_redraw(window);
}
}
@@ -627,14 +612,27 @@ win_show_subwin(ProfWin* window)
}
ProfLayoutSplit* layout = (ProfLayoutSplit*)window->layout;
/* Free a previous pad if win_show_subwin was called twice in a row
* without an intervening win_hide_subwin. */
// If a subwindow already exists (e.g. repeated call), destroy it to avoid leaks
if (layout->subwin) {
delwin(layout->subwin);
layout->subwin = NULL;
}
// Ensure minimum width to avoid creating a zero-width pad
if (subwin_cols <= 0) {
subwin_cols = 1;
}
layout->subwin = newpad(PAD_SIZE, subwin_cols);
if (layout->subwin == NULL) {
// Failed to allocate subwindow; keep base window resized to full width
log_error("Failed to create subwindow pad (cols=%d)", subwin_cols);
wresize(layout->base.win, PAD_SIZE, cols);
win_redraw(window);
return;
}
layout->subwin = newpad(PAD_MIN_HEIGHT, subwin_cols);
wbkgd(layout->subwin, theme_attrs(THEME_TEXT));
wresize(layout->base.win, PAD_MIN_HEIGHT, cols - subwin_cols);
wresize(layout->base.win, PAD_SIZE, cols - subwin_cols);
win_redraw(window);
}
@@ -654,10 +652,6 @@ win_free(ProfWin* window)
}
free(window->layout);
if (window->warned_jids) {
g_hash_table_destroy(window->warned_jids);
}
switch (window->type) {
case WIN_CHAT:
{
@@ -721,44 +715,6 @@ win_free(ProfWin* window)
free(window);
}
gboolean
win_warn_needed(ProfWin* window, const char* const type, const char* const jid)
{
if (!window || !type || !jid) {
return TRUE;
}
if (!window->warned_jids) {
return TRUE;
}
auto_gchar gchar* key = g_strdup_printf("%s:%s", type, jid);
return !g_hash_table_contains(window->warned_jids, key);
}
void
win_warn_sent(ProfWin* window, const char* const type, const char* const jid)
{
if (!window || !type || !jid) {
return;
}
if (!window->warned_jids) {
window->warned_jids = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
}
gchar* key = g_strdup_printf("%s:%s", type, jid);
g_hash_table_insert(window->warned_jids, key, GINT_TO_POINTER(1));
}
void
win_clear_warned_jids(ProfWin* window)
{
if (window && window->warned_jids) {
g_hash_table_remove_all(window->warned_jids);
}
}
void
win_page_up(ProfWin* window, int scroll_size)
{
@@ -855,7 +811,7 @@ win_page_down(ProfWin* window, int scroll_size)
GDateTime* now = g_date_time_new_now_local();
ProfBuffEntry* last_entry = buffer_get_entry(window->layout->buffer, bf_size - 1);
auto_gchar gchar* start = g_date_time_format_iso8601(last_entry->time);
auto_gchar gchar* end_date = prof_date_time_format_iso8601(NULL);
auto_gchar gchar* end_date = g_date_time_format_iso8601(now);
db_history_result_t db_response = chatwin_db_history((ProfChatWin*)window, start, end_date, FALSE);
if (db_response == DB_RESPONSE_EMPTY)
*scroll_state = WIN_SCROLL_REACHED_BOTTOM;
@@ -978,9 +934,9 @@ win_resize(ProfWin* window)
subwin_cols = win_occpuants_cols();
}
wbkgd(layout->base.win, theme_attrs(THEME_TEXT));
wresize(layout->base.win, PAD_MIN_HEIGHT, cols - subwin_cols);
wresize(layout->base.win, PAD_SIZE, cols - subwin_cols);
wbkgd(layout->subwin, theme_attrs(THEME_TEXT));
wresize(layout->subwin, PAD_MIN_HEIGHT, subwin_cols);
wresize(layout->subwin, PAD_SIZE, subwin_cols);
if (window->type == WIN_CONSOLE) {
rosterwin_roster();
} else if (window->type == WIN_MUC) {
@@ -990,11 +946,11 @@ win_resize(ProfWin* window)
}
} else {
wbkgd(layout->base.win, theme_attrs(THEME_TEXT));
wresize(layout->base.win, PAD_MIN_HEIGHT, cols);
wresize(layout->base.win, PAD_SIZE, cols);
}
} else {
wbkgd(window->layout->win, theme_attrs(THEME_TEXT));
wresize(window->layout->win, PAD_MIN_HEIGHT, cols);
wresize(window->layout->win, PAD_SIZE, cols);
}
win_redraw(window);
@@ -1122,11 +1078,11 @@ win_show_contact(ProfWin* window, PContact contact)
GTimeSpan span = g_date_time_difference(now, last_activity);
g_date_time_unref(now);
int hours = (int)(span / G_TIME_SPAN_HOUR);
int hours = span / G_TIME_SPAN_HOUR;
span = span - hours * G_TIME_SPAN_HOUR;
int minutes = (int)(span / G_TIME_SPAN_MINUTE);
int minutes = span / G_TIME_SPAN_MINUTE;
span = span - minutes * G_TIME_SPAN_MINUTE;
int seconds = (int)(span / G_TIME_SPAN_SECOND);
int seconds = span / G_TIME_SPAN_SECOND;
if (hours > 0) {
win_append(window, presence_colour, ", idle %dh%dm%ds", hours, minutes, seconds);
@@ -1247,11 +1203,11 @@ win_show_info(ProfWin* window, PContact contact)
GDateTime* now = g_date_time_new_now_local();
GTimeSpan span = g_date_time_difference(now, last_activity);
int hours = (int)(span / G_TIME_SPAN_HOUR);
int hours = span / G_TIME_SPAN_HOUR;
span = span - hours * G_TIME_SPAN_HOUR;
int minutes = (int)(span / G_TIME_SPAN_MINUTE);
int minutes = span / G_TIME_SPAN_MINUTE;
span = span - minutes * G_TIME_SPAN_MINUTE;
int seconds = (int)(span / G_TIME_SPAN_SECOND);
int seconds = span / G_TIME_SPAN_SECOND;
if (hours > 0) {
win_println(window, THEME_DEFAULT, "-", "Last activity: %dh%dm%ds", hours, minutes, seconds);
@@ -1787,7 +1743,7 @@ win_appendln_highlight(ProfWin* window, theme_item_t theme_item, const char* con
void
win_print_http_transfer(ProfWin* window, const char* const message, char* id)
{
win_print_status_with_id(window, message, id, THEME_DEFAULT, 0);
win_print_outgoing_with_receipt(window, "!", NULL, message, id, NULL);
}
void
@@ -1795,7 +1751,7 @@ win_print_outgoing_with_receipt(ProfWin* window, const char* show_char, const ch
{
GDateTime* time = g_date_time_new_now_local();
DeliveryReceipt* receipt = g_new0(struct delivery_receipt_t, 1);
DeliveryReceipt* receipt = malloc(sizeof(struct delivery_receipt_t));
receipt->received = FALSE;
const char* myjid = connection_get_fulljid();
@@ -1836,33 +1792,6 @@ win_update_entry_message(ProfWin* window, const char* const id, const char* cons
}
}
void
win_update_entry(ProfWin* window, const char* const id, const char* const message, theme_item_t theme_item, int flags)
{
if (window->type == WIN_CONSOLE)
return;
ProfBuffEntry* entry = buffer_get_entry_by_id(window->layout->buffer, id);
if (entry) {
if (message) {
free(entry->message);
entry->message = strdup(message);
}
entry->theme_item = theme_item;
entry->flags |= flags;
win_redraw(window);
}
}
void
win_print_status_with_id(ProfWin* window, const char* const message, char* id, theme_item_t theme_item, int flags)
{
GDateTime* time = g_date_time_new_now_local();
int y_start_pos = getcury(window->layout->win);
_win_print_internal(window, "!", 0, time, flags, theme_item, NULL, message, NULL);
buffer_append(window->layout->buffer, "!", 0, time, flags, theme_item, NULL, NULL, message, NULL, id, y_start_pos, getcury(window->layout->win));
g_date_time_unref(time);
}
void
win_remove_entry_message(ProfWin* window, const char* const id)
{
@@ -1922,7 +1851,7 @@ _win_print_internal(ProfWin* window, const char* show_char, int pad_indent, GDat
gboolean me_message = FALSE;
int offset = 0;
int colour = theme_attrs(THEME_ME);
int indent = 0;
size_t indent = 0;
auto_gchar gchar* time_pref = NULL;
switch (window->type) {
@@ -1955,7 +1884,7 @@ _win_print_internal(ProfWin* window, const char* show_char, int pad_indent, GDat
assert(date_fmt != NULL);
if (strlen(date_fmt) != 0) {
indent = 3 + (int)strlen(date_fmt);
indent = 3 + strlen(date_fmt);
}
if ((flags & NO_DATE) == 0) {
@@ -2016,8 +1945,6 @@ _win_print_internal(ProfWin* window, const char* show_char, int pad_indent, GDat
}
}
_win_ensure_pad_capacity(window, window->layout->win, getcury(window->layout->win) + _win_estimated_lines(window->layout->win, message + offset, indent, pad_indent));
if (prefs_get_boolean(PREF_WRAP)) {
_win_print_wrapped(window->layout->win, message + offset, indent, pad_indent);
} else {
@@ -2051,11 +1978,11 @@ _win_indent(WINDOW* win, int size)
}
static void
_win_print_wrapped(WINDOW* win, const char* const message, int indent, int pad_indent)
_win_print_wrapped(WINDOW* win, const char* const message, size_t indent, int pad_indent)
{
int starty = getcury(win);
int wordi = 0;
auto_gchar gchar* word = g_malloc(strlen(message) + 1);
auto_char char* word = malloc(strlen(message) + 1);
gchar* curr_ch = g_utf8_offset_to_pointer(message, 0);
@@ -2078,12 +2005,11 @@ _win_print_wrapped(WINDOW* win, const char* const message, int indent, int pad_i
int wordlen = 0;
while (*curr_ch != ' ' && *curr_ch != '\n' && *curr_ch != '\0') {
size_t ch_len = mbrlen(curr_ch, MB_CUR_MAX, NULL);
// 0 / invalid step: advance one byte to avoid spinning.
if ((ch_len == (size_t)-2) || (ch_len == (size_t)-1) || ch_len == 0) {
if ((ch_len == (size_t)-2) || (ch_len == (size_t)-1)) {
curr_ch++;
continue;
}
size_t offset = 0;
int offset = 0;
while (offset < ch_len) {
word[wordi++] = curr_ch[offset++];
}
@@ -2168,7 +2094,6 @@ _win_print_wrapped(WINDOW* win, const char* const message, int indent, int pad_i
void
win_print_trackbar(ProfWin* window)
{
_win_ensure_pad_capacity(window, window->layout->win, getcury(window->layout->win));
int cols = getmaxx(window->layout->win);
wbkgdset(window->layout->win, theme_attrs(THEME_TRACKBAR));
@@ -2184,21 +2109,12 @@ win_print_trackbar(ProfWin* window)
void
win_redraw(ProfWin* window)
{
unsigned int size = buffer_size(window->layout->buffer);
_in_redraw = TRUE;
// size the pad to fit the whole buffer (plus headroom) and erase it
int cols = getmaxx(window->layout->win);
int needed = window->layout->buffer->lines + 100;
wresize(window->layout->win, MAX(needed, PAD_MIN_HEIGHT), cols);
int size = buffer_size(window->layout->buffer);
werase(window->layout->win);
for (unsigned int i = 0; i < size; i++) {
for (int i = 0; i < size; i++) {
ProfBuffEntry* e = buffer_get_entry(window->layout->buffer, i);
// check if we need more space before printing
_win_ensure_pad_capacity(window, window->layout->win, getcury(window->layout->win));
e->y_start_pos = getcury(window->layout->win);
if (e->display_from == NULL && e->message && e->message[0] == '-') {
// just an indicator to print the trackbar/separator not the actual message
@@ -2213,8 +2129,6 @@ win_redraw(ProfWin* window)
e->_lines = e->y_end_pos - e->y_start_pos;
window->layout->buffer->lines += e->_lines;
}
_in_redraw = FALSE;
}
void
@@ -2349,7 +2263,6 @@ win_toggle_attention(ProfWin* window)
void
win_sub_print(WINDOW* win, char* msg, gboolean newline, gboolean wrap, int indent)
{
_win_ensure_pad_capacity(NULL, win, getcury(win));
int maxx = getmaxx(win);
int curx = getcurx(win);
int cury = getcury(win);
@@ -2438,11 +2351,11 @@ win_handle_command_exec_result_note(ProfWin* window, const char* const type, con
void
win_insert_last_read_position_marker(ProfWin* window, char* id)
{
unsigned int size = buffer_size(window->layout->buffer);
int size = buffer_size(window->layout->buffer);
// TODO: this is somewhat costly. We should improve this later.
// check if we already have a separator present
for (unsigned int i = 0; i < size; i++) {
for (int i = 0; i < size; i++) {
ProfBuffEntry* e = buffer_get_entry(window->layout->buffer, i);
// if yes, don't print a new one

View File

@@ -3,9 +3,35 @@
* vim: expandtab:ts=4:sts=4:sw=4
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
* Copyright (C) 2019 - 2026 Michael Vetter <jubalh@iodoru.org>
* Copyright (C) 2019 - 2025 Michael Vetter <jubalh@iodoru.org>
*
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
*/
#ifndef UI_WINDOW_H
@@ -59,15 +85,9 @@ void win_sub_print(WINDOW* win, char* msg, gboolean newline, gboolean wrap, int
void win_sub_newline_lazy(WINDOW* win);
void win_mark_received(ProfWin* window, const char* const id);
void win_update_entry_message(ProfWin* window, const char* const id, const char* const message);
void win_update_entry(ProfWin* window, const char* const id, const char* const message, theme_item_t theme_item, int flags);
void win_print_status_with_id(ProfWin* window, const char* const message, char* id, theme_item_t theme_item, int flags);
gboolean win_has_active_subwin(ProfWin* window);
gboolean win_warn_needed(ProfWin* window, const char* const type, const char* const jid);
void win_warn_sent(ProfWin* window, const char* const type, const char* const jid);
void win_clear_warned_jids(ProfWin* window);
void win_page_up(ProfWin* window, int scroll_size);
void win_page_down(ProfWin* window, int scroll_size);
void win_sub_page_down(ProfWin* window);

View File

@@ -3,9 +3,35 @@
* vim: expandtab:ts=4:sts=4:sw=4
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
* Copyright (C) 2019 - 2026 Michael Vetter <jubalh@iodoru.org>
* Copyright (C) 2019 - 2025 Michael Vetter <jubalh@iodoru.org>
*
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
*/
#include "config.h"
@@ -1030,31 +1056,6 @@ _wins_get_next_available_num(GList* used)
}
}
void
wins_omemo_trust_changed(const char* const jid)
{
GList* curr = values;
while (curr) {
ProfWin* window = curr->data;
if (window->type == WIN_CHAT) {
ProfChatWin* chatwin = (ProfChatWin*)window;
if (jid == NULL || strcmp(chatwin->barejid, jid) == 0) {
#ifdef HAVE_OMEMO
chatwin->omemo_trusted = omemo_is_jid_trusted(chatwin->barejid);
#endif
}
} else if (window->type == WIN_MUC) {
ProfMucWin* mucwin = (ProfMucWin*)window;
if (jid == NULL || strcmp(mucwin->roomjid, jid) == 0) {
#ifdef HAVE_OMEMO
mucwin->omemo_trusted = omemo_is_jid_trusted(mucwin->roomjid);
#endif
}
}
curr = g_list_next(curr);
}
}
gboolean
wins_tidy(void)
{

View File

@@ -4,7 +4,33 @@
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#ifndef UI_WINDOW_LIST_H
@@ -63,7 +89,6 @@ GSList* wins_get_chat_recipients(void);
GSList* wins_get_prune_wins(void);
void wins_lost_connection(void);
void wins_reestablished_connection(void);
void wins_omemo_trust_changed(const char* const jid);
gboolean wins_tidy(void);
GSList* wins_create_summary(gboolean unread);
GSList* wins_create_summary_attention();

View File

@@ -4,7 +4,33 @@
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
*
* SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
*/
#include "config.h"