mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-06-10 17:00:18 +00:00
Compare commits
1 Commits
windows-ta
...
notificati
| Author | SHA1 | Date | |
|---|---|---|---|
| 99f02cd8e1 |
@@ -19,7 +19,6 @@ libgmodule_dep = dependency('gmodule-2.0')
|
||||
libcanberra_dep = dependency('libcanberra', version: '>= 0.22',
|
||||
required: get_option('libcanberra'))
|
||||
dbus_dep = dependency('gio-2.0', required: get_option('dbus'))
|
||||
libsecret_dep = dependency('libsecret-1', required: false)
|
||||
|
||||
global_deps = []
|
||||
if cc.get_id() == 'msvc'
|
||||
@@ -41,7 +40,6 @@ config_h.set10('ENABLE_NLS', true)
|
||||
config_h.set('USE_OPENSSL', libssl_dep.found())
|
||||
config_h.set('USE_LIBCANBERRA', libcanberra_dep.found())
|
||||
config_h.set('USE_DBUS', dbus_dep.found())
|
||||
config_h.set('HAVE_LIBSECRET', libsecret_dep.found())
|
||||
config_h.set('USE_PLUGIN', get_option('plugin'))
|
||||
config_h.set('USE_GTK_FRONTEND', get_option('gtk-frontend'))
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
<ClInclude Include="public_suffix_data.h" />
|
||||
<ClInclude Include="server.h" />
|
||||
<ClInclude Include="servlist.h" />
|
||||
<ClInclude Include="secretstore.h" />
|
||||
<ClInclude Include="ssl.h" />
|
||||
<ClInclude Include="scram.h" />
|
||||
<ClInclude Include="sysinfo\sysinfo.h" />
|
||||
@@ -69,7 +68,6 @@
|
||||
<ClCompile Include="proto-irc.c" />
|
||||
<ClCompile Include="server.c" />
|
||||
<ClCompile Include="servlist.c" />
|
||||
<ClCompile Include="secretstore.c" />
|
||||
<ClCompile Include="ssl.c" />
|
||||
<ClCompile Include="scram.c" />
|
||||
<ClCompile Include="sts.c" />
|
||||
|
||||
@@ -74,9 +74,6 @@
|
||||
<ClInclude Include="servlist.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="secretstore.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ssl.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -181,9 +178,6 @@
|
||||
<ClCompile Include="servlist.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="secretstore.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ssl.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
||||
@@ -304,24 +304,29 @@ dcc_check_timeouts (void)
|
||||
static int
|
||||
dcc_lookup_proxy (char *host, struct sockaddr_in *addr)
|
||||
{
|
||||
struct hostent *h;
|
||||
static char *cache_host = NULL;
|
||||
static guint32 cache_addr;
|
||||
|
||||
/* too lazy to thread this, so we cache results */
|
||||
if (cache_host)
|
||||
{
|
||||
if (strcmp (host, cache_host) == 0)
|
||||
{
|
||||
addr->sin_addr.s_addr = cache_addr;
|
||||
memcpy (&addr->sin_addr, &cache_addr, 4);
|
||||
return TRUE;
|
||||
}
|
||||
g_free (cache_host);
|
||||
cache_host = NULL;
|
||||
}
|
||||
|
||||
if (net_lookup_ipv4 (host, &addr->sin_addr.s_addr))
|
||||
h = gethostbyname (host);
|
||||
if (h != NULL && h->h_length == 4 && h->h_addr_list[0] != NULL)
|
||||
{
|
||||
cache_addr = addr->sin_addr.s_addr;
|
||||
memcpy (&addr->sin_addr, h->h_addr_list[0], 4);
|
||||
memcpy (&cache_addr, h->h_addr_list[0], 4);
|
||||
cache_host = g_strdup (host);
|
||||
/* cppcheck-suppress memleak */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1609,14 +1614,25 @@ dcc_accept (GIOChannel *source, GIOCondition condition, struct DCC *dcc)
|
||||
}
|
||||
|
||||
guint32
|
||||
dcc_get_my_address (session *sess)
|
||||
dcc_get_my_address (session *sess) /* the address we'll tell the other person */
|
||||
{
|
||||
struct hostent *dns_query;
|
||||
guint32 addr = 0;
|
||||
|
||||
if (prefs.hex_dcc_ip_from_server && sess->server->dcc_ip)
|
||||
addr = sess->server->dcc_ip;
|
||||
else if (prefs.hex_dcc_ip[0])
|
||||
net_lookup_ipv4 ((const char *) prefs.hex_dcc_ip, &addr);
|
||||
{
|
||||
dns_query = gethostbyname ((const char *) prefs.hex_dcc_ip);
|
||||
|
||||
if (dns_query != NULL &&
|
||||
dns_query->h_length == 4 &&
|
||||
dns_query->h_addr_list[0] != NULL)
|
||||
{
|
||||
/*we're offered at least one IPv4 address: we take the first*/
|
||||
addr = *((guint32*) dns_query->h_addr_list[0]);
|
||||
}
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#include "ignore.h"
|
||||
#include "fe.h"
|
||||
#include "modes.h"
|
||||
#include "network.h"
|
||||
#include "notify.h"
|
||||
#include "outbound.h"
|
||||
#include "inbound.h"
|
||||
@@ -1477,13 +1476,14 @@ inbound_uback (server *serv, const message_tags_data *tags_data)
|
||||
void
|
||||
inbound_foundip (session *sess, char *ip, const message_tags_data *tags_data)
|
||||
{
|
||||
struct in_addr addr;
|
||||
struct hostent *HostAddr;
|
||||
|
||||
if (net_lookup_ipv4 (ip, &addr.s_addr))
|
||||
HostAddr = gethostbyname (ip);
|
||||
if (HostAddr)
|
||||
{
|
||||
sess->server->dcc_ip = addr.s_addr;
|
||||
sess->server->dcc_ip = ((struct in_addr *) HostAddr->h_addr_list[0])->s_addr;
|
||||
EMIT_SIGNAL_TIMESTAMP (XP_TE_FOUNDIP, sess->server->server_session,
|
||||
inet_ntoa (addr),
|
||||
inet_ntoa (*((struct in_addr *) HostAddr->h_addr_list[0])),
|
||||
NULL, NULL, NULL, 0, tags_data->timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,8 +27,6 @@ common_sources = [
|
||||
'util.c'
|
||||
]
|
||||
|
||||
secretstore_sources = files('secretstore.c')
|
||||
|
||||
common_sysinfo_deps = []
|
||||
libarchive_dep = dependency('libarchive', required: host_machine.system() != 'windows')
|
||||
|
||||
@@ -40,9 +38,6 @@ common_deps = [
|
||||
if libarchive_dep.found()
|
||||
common_deps += libarchive_dep
|
||||
endif
|
||||
if libsecret_dep.found()
|
||||
common_deps += libsecret_dep
|
||||
endif
|
||||
|
||||
common_includes = [
|
||||
config_h_include,
|
||||
@@ -132,7 +127,7 @@ if get_option('plugin')
|
||||
endif
|
||||
|
||||
zoitechat_common = static_library('zoitechatcommon',
|
||||
sources: [textevents, public_suffix_data] + marshal + common_sources + secretstore_sources,
|
||||
sources: [textevents, public_suffix_data] + marshal + common_sources,
|
||||
include_directories: config_h_include,
|
||||
dependencies: common_deps + common_sysinfo_deps,
|
||||
c_args: common_cflags,
|
||||
|
||||
@@ -96,30 +96,6 @@ net_ip (uint32_t addr)
|
||||
return inet_ntoa (ia);
|
||||
}
|
||||
|
||||
int
|
||||
net_lookup_ipv4 (const char *hostname, uint32_t *addr)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *res;
|
||||
struct sockaddr_in *sin;
|
||||
int ret;
|
||||
|
||||
memset (&hints, 0, sizeof (hints));
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags = AI_ADDRCONFIG;
|
||||
|
||||
ret = getaddrinfo (hostname, NULL, &hints, &res);
|
||||
if (ret != 0)
|
||||
return FALSE;
|
||||
|
||||
sin = (struct sockaddr_in *) res->ai_addr;
|
||||
*addr = sin->sin_addr.s_addr;
|
||||
freeaddrinfo (res);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
net_store_destroy (netstore * ns)
|
||||
{
|
||||
|
||||
@@ -39,7 +39,6 @@ int net_connect (netstore *ns, int sok4, int sok6, int *sok_return);
|
||||
char *net_resolve (netstore *ns, char *hostname, int port, char **real_host);
|
||||
void net_bind (netstore *tobindto, int sok4, int sok6);
|
||||
char *net_ip (uint32_t addr);
|
||||
int net_lookup_ipv4 (const char *hostname, uint32_t *addr);
|
||||
void net_sockets (int *sok4, int *sok6);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1213,6 +1213,8 @@ zoitechat_get_info (zoitechat_plugin *ph, const char *id)
|
||||
|
||||
case 0x4889ba9b: /* password */
|
||||
case 0x438fdf9: /* nickserv */
|
||||
if (sess->server->network)
|
||||
return ((ircnet *)sess->server->network)->pass;
|
||||
return NULL;
|
||||
|
||||
case 0xca022f43: /* server */
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
#include "zoitechat.h"
|
||||
#include "cfgfiles.h"
|
||||
#include "secretstore.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <wincred.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBSECRET
|
||||
#include <libsecret/secret.h>
|
||||
#endif
|
||||
|
||||
static char *secretstore_target (const char *network_name)
|
||||
{
|
||||
return g_strdup_printf ("zoitechat/network/%s", network_name ? network_name : "default");
|
||||
}
|
||||
|
||||
int secretstore_is_keyring_available (void)
|
||||
{
|
||||
#ifdef WIN32
|
||||
return TRUE;
|
||||
#elif defined(HAVE_LIBSECRET)
|
||||
return TRUE;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
char *secretstore_get_network_password (const char *network_name)
|
||||
{
|
||||
char *target;
|
||||
target = secretstore_target (network_name);
|
||||
#ifdef WIN32
|
||||
{
|
||||
PCREDENTIALA cred = NULL;
|
||||
char *ret = NULL;
|
||||
if (CredReadA (target, CRED_TYPE_GENERIC, 0, &cred))
|
||||
{
|
||||
ret = g_strndup ((const char *) cred->CredentialBlob, cred->CredentialBlobSize);
|
||||
CredFree (cred);
|
||||
}
|
||||
g_free (target);
|
||||
return ret;
|
||||
}
|
||||
#elif defined(HAVE_LIBSECRET)
|
||||
{
|
||||
static const SecretSchema schema = {
|
||||
"net.zoite.ZoiteChat.Network", SECRET_SCHEMA_NONE,
|
||||
{
|
||||
{ "network", SECRET_SCHEMA_ATTRIBUTE_STRING },
|
||||
{ NULL, 0 },
|
||||
}
|
||||
};
|
||||
char *ret = secret_password_lookup_sync (&schema, NULL, NULL, "network", target, NULL);
|
||||
g_free (target);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
g_free (target);
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
int secretstore_set_network_password (const char *network_name, const char *password)
|
||||
{
|
||||
char *target;
|
||||
target = secretstore_target (network_name);
|
||||
#ifdef WIN32
|
||||
{
|
||||
CREDENTIALA cred;
|
||||
memset (&cred, 0, sizeof (cred));
|
||||
cred.Type = CRED_TYPE_GENERIC;
|
||||
cred.TargetName = target;
|
||||
cred.CredentialBlobSize = (DWORD) strlen (password);
|
||||
cred.CredentialBlob = (LPBYTE) password;
|
||||
cred.Persist = CRED_PERSIST_LOCAL_MACHINE;
|
||||
cred.UserName = "zoitechat";
|
||||
if (!CredWriteA (&cred, 0))
|
||||
{
|
||||
g_free (target);
|
||||
return FALSE;
|
||||
}
|
||||
g_free (target);
|
||||
return TRUE;
|
||||
}
|
||||
#elif defined(HAVE_LIBSECRET)
|
||||
{
|
||||
static const SecretSchema schema = {
|
||||
"net.zoite.ZoiteChat.Network", SECRET_SCHEMA_NONE,
|
||||
{
|
||||
{ "network", SECRET_SCHEMA_ATTRIBUTE_STRING },
|
||||
{ NULL, 0 },
|
||||
}
|
||||
};
|
||||
gboolean ok = secret_password_store_sync (&schema, SECRET_COLLECTION_DEFAULT,
|
||||
"ZoiteChat network password", password, NULL, NULL, "network", target, NULL);
|
||||
g_free (target);
|
||||
return ok;
|
||||
}
|
||||
#else
|
||||
g_free (target);
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
int secretstore_delete_network_password (const char *network_name)
|
||||
{
|
||||
char *target;
|
||||
target = secretstore_target (network_name);
|
||||
#ifdef WIN32
|
||||
{
|
||||
gboolean ok = CredDeleteA (target, CRED_TYPE_GENERIC, 0);
|
||||
g_free (target);
|
||||
return ok;
|
||||
}
|
||||
#elif defined(HAVE_LIBSECRET)
|
||||
{
|
||||
static const SecretSchema schema = {
|
||||
"net.zoite.ZoiteChat.Network", SECRET_SCHEMA_NONE,
|
||||
{
|
||||
{ "network", SECRET_SCHEMA_ATTRIBUTE_STRING },
|
||||
{ NULL, 0 },
|
||||
}
|
||||
};
|
||||
gboolean ok = secret_password_clear_sync (&schema, NULL, NULL, "network", target, NULL);
|
||||
g_free (target);
|
||||
return ok;
|
||||
}
|
||||
#else
|
||||
g_free (target);
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
int secretstore_require_unlock (const char *network_name)
|
||||
{
|
||||
#ifdef WIN32
|
||||
return TRUE;
|
||||
#elif defined(HAVE_LIBSECRET)
|
||||
{
|
||||
static const SecretSchema schema = {
|
||||
"net.zoite.ZoiteChat.Network", SECRET_SCHEMA_NONE,
|
||||
{
|
||||
{ "network", SECRET_SCHEMA_ATTRIBUTE_STRING },
|
||||
{ NULL, 0 },
|
||||
}
|
||||
};
|
||||
char *target;
|
||||
char *password;
|
||||
GError *error = NULL;
|
||||
target = secretstore_target (network_name);
|
||||
password = secret_password_lookup_sync (&schema, NULL, &error, "network", target, NULL);
|
||||
g_free (target);
|
||||
if (password)
|
||||
{
|
||||
memset (password, 0, strlen (password));
|
||||
g_free (password);
|
||||
return TRUE;
|
||||
}
|
||||
if (error)
|
||||
{
|
||||
g_error_free (error);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
#ifndef ZOITECHAT_SECRETSTORE_H
|
||||
#define ZOITECHAT_SECRETSTORE_H
|
||||
|
||||
char *secretstore_get_network_password (const char *network_name);
|
||||
int secretstore_set_network_password (const char *network_name, const char *password);
|
||||
int secretstore_delete_network_password (const char *network_name);
|
||||
int secretstore_is_keyring_available (void);
|
||||
int secretstore_require_unlock (const char *network_name);
|
||||
|
||||
#endif
|
||||
@@ -881,7 +881,7 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv)
|
||||
if (prefs.hex_net_auto_reconnectonfail)
|
||||
auto_reconnect (serv, FALSE, -1);
|
||||
break;
|
||||
case '3': /* resolver finished */
|
||||
case '3': /* gethostbyname finished */
|
||||
waitline2 (source, host, sizeof host);
|
||||
waitline2 (source, ip, sizeof ip);
|
||||
waitline2 (source, outbuf, sizeof outbuf);
|
||||
@@ -932,7 +932,7 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv)
|
||||
waitline2 (source, tbuf, sizeof tbuf);
|
||||
prefs.local_ip = inet_addr (tbuf);
|
||||
break;
|
||||
case '7': /* prefs.hex_net_bind_host resolve failed */
|
||||
case '7': /* gethostbyname (prefs.hex_net_bind_host) failed */
|
||||
sprintf (outbuf,
|
||||
_("Cannot resolve hostname %s\nCheck your IP Settings!\n"),
|
||||
prefs.hex_net_bind_host);
|
||||
|
||||
@@ -33,152 +33,9 @@
|
||||
#include "text.h"
|
||||
#include "util.h" /* token_foreach */
|
||||
#include "zoitechatc.h"
|
||||
#include "secretstore.h"
|
||||
|
||||
#include "servlist.h"
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
#endif
|
||||
|
||||
char *
|
||||
servlist_password_encrypt_for_storage (const char *pass)
|
||||
{
|
||||
gchar *material;
|
||||
unsigned char salt[16];
|
||||
unsigned char iv[16];
|
||||
unsigned char key[32];
|
||||
unsigned char *ciphertext;
|
||||
int outlen1;
|
||||
int outlen2;
|
||||
int inlen;
|
||||
int cipherlen;
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
char *b64;
|
||||
char *ret;
|
||||
if (!pass || !*pass)
|
||||
return NULL;
|
||||
#ifdef USE_OPENSSL
|
||||
if (RAND_bytes (salt, sizeof (salt)) != 1 || RAND_bytes (iv, sizeof (iv)) != 1)
|
||||
return NULL;
|
||||
material = g_strdup_printf ("%s|%s", g_get_user_name (), get_xdir ());
|
||||
if (!PKCS5_PBKDF2_HMAC (material, -1, salt, sizeof (salt), 300000, EVP_sha256 (), sizeof (key), key))
|
||||
{
|
||||
g_free (material);
|
||||
return NULL;
|
||||
}
|
||||
g_free (material);
|
||||
inlen = (int) strlen (pass);
|
||||
ciphertext = g_malloc (inlen + EVP_MAX_BLOCK_LENGTH);
|
||||
ctx = EVP_CIPHER_CTX_new ();
|
||||
if (!ctx)
|
||||
{
|
||||
memset (key, 0, sizeof (key));
|
||||
g_free (ciphertext);
|
||||
return NULL;
|
||||
}
|
||||
if (EVP_EncryptInit_ex (ctx, EVP_aes_256_cbc (), NULL, key, iv) != 1 ||
|
||||
EVP_EncryptUpdate (ctx, ciphertext, &outlen1, (const unsigned char *) pass, inlen) != 1 ||
|
||||
EVP_EncryptFinal_ex (ctx, ciphertext + outlen1, &outlen2) != 1)
|
||||
{
|
||||
EVP_CIPHER_CTX_free (ctx);
|
||||
memset (key, 0, sizeof (key));
|
||||
g_free (ciphertext);
|
||||
return NULL;
|
||||
}
|
||||
EVP_CIPHER_CTX_free (ctx);
|
||||
cipherlen = outlen1 + outlen2;
|
||||
{
|
||||
gsize payload_len = sizeof (salt) + sizeof (iv) + (gsize) cipherlen;
|
||||
unsigned char *payload = g_malloc (payload_len);
|
||||
memcpy (payload, salt, sizeof (salt));
|
||||
memcpy (payload + sizeof (salt), iv, sizeof (iv));
|
||||
memcpy (payload + sizeof (salt) + sizeof (iv), ciphertext, cipherlen);
|
||||
b64 = g_base64_encode (payload, payload_len);
|
||||
memset (payload, 0, payload_len);
|
||||
g_free (payload);
|
||||
}
|
||||
memset (key, 0, sizeof (key));
|
||||
memset (ciphertext, 0, inlen + EVP_MAX_BLOCK_LENGTH);
|
||||
g_free (ciphertext);
|
||||
#else
|
||||
b64 = g_base64_encode ((const guchar *) pass, strlen (pass));
|
||||
#endif
|
||||
ret = g_strdup_printf ("enc:%s", b64);
|
||||
g_free (b64);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
servlist_password_is_encrypted (const char *pass)
|
||||
{
|
||||
return pass && g_str_has_prefix (pass, "enc:");
|
||||
}
|
||||
|
||||
char *
|
||||
servlist_password_decrypt_for_storage (const char *enc)
|
||||
{
|
||||
guchar *raw;
|
||||
gsize len;
|
||||
char *ret;
|
||||
if (!enc || !*enc)
|
||||
return NULL;
|
||||
if (!g_str_has_prefix (enc, "enc:"))
|
||||
return g_strdup (enc);
|
||||
raw = g_base64_decode (enc + 4, &len);
|
||||
#ifdef USE_OPENSSL
|
||||
if (len <= 32)
|
||||
{
|
||||
g_free (raw);
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
unsigned char *salt = raw;
|
||||
unsigned char *iv = raw + 16;
|
||||
unsigned char *ciphertext = raw + 32;
|
||||
int cipherlen = (int) (len - 32);
|
||||
unsigned char key[32];
|
||||
gchar *material = g_strdup_printf ("%s|%s", g_get_user_name (), get_xdir ());
|
||||
unsigned char *plaintext = g_malloc ((gsize) cipherlen + 1);
|
||||
int outlen1;
|
||||
int outlen2;
|
||||
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new ();
|
||||
if (!ctx || !PKCS5_PBKDF2_HMAC (material, -1, salt, 16, 300000, EVP_sha256 (), sizeof (key), key))
|
||||
{
|
||||
g_free (material);
|
||||
if (ctx)
|
||||
EVP_CIPHER_CTX_free (ctx);
|
||||
g_free (plaintext);
|
||||
g_free (raw);
|
||||
return NULL;
|
||||
}
|
||||
g_free (material);
|
||||
if (EVP_DecryptInit_ex (ctx, EVP_aes_256_cbc (), NULL, key, iv) != 1 ||
|
||||
EVP_DecryptUpdate (ctx, plaintext, &outlen1, ciphertext, cipherlen) != 1 ||
|
||||
EVP_DecryptFinal_ex (ctx, plaintext + outlen1, &outlen2) != 1)
|
||||
{
|
||||
EVP_CIPHER_CTX_free (ctx);
|
||||
memset (key, 0, sizeof (key));
|
||||
memset (plaintext, 0, (gsize) cipherlen + 1);
|
||||
g_free (plaintext);
|
||||
g_free (raw);
|
||||
return NULL;
|
||||
}
|
||||
EVP_CIPHER_CTX_free (ctx);
|
||||
memset (key, 0, sizeof (key));
|
||||
plaintext[outlen1 + outlen2] = 0;
|
||||
ret = g_strdup ((const char *) plaintext);
|
||||
memset (plaintext, 0, (gsize) cipherlen + 1);
|
||||
g_free (plaintext);
|
||||
}
|
||||
#else
|
||||
ret = g_strndup ((const char *) raw, len);
|
||||
#endif
|
||||
g_free (raw);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
struct defaultserver
|
||||
{
|
||||
@@ -487,29 +344,10 @@ servlist_connect (session *sess, ircnet *net, gboolean join)
|
||||
}
|
||||
|
||||
serv->password[0] = 0;
|
||||
if ((net->flags & FLAG_USE_KEYRING) && net->name)
|
||||
|
||||
if (net->pass)
|
||||
{
|
||||
char *stored_pass = secretstore_get_network_password (net->name);
|
||||
if (stored_pass && *stored_pass)
|
||||
{
|
||||
safe_strcpy (serv->password, stored_pass, sizeof (serv->password));
|
||||
}
|
||||
if (stored_pass)
|
||||
{
|
||||
memset (stored_pass, 0, strlen (stored_pass));
|
||||
g_free (stored_pass);
|
||||
}
|
||||
}
|
||||
else if (net->pass)
|
||||
{
|
||||
char *plain = servlist_password_decrypt_for_storage (net->pass);
|
||||
if (plain && *plain)
|
||||
safe_strcpy (serv->password, plain, sizeof (serv->password));
|
||||
if (plain)
|
||||
{
|
||||
memset (plain, 0, strlen (plain));
|
||||
g_free (plain);
|
||||
}
|
||||
safe_strcpy (serv->password, net->pass, sizeof (serv->password));
|
||||
}
|
||||
|
||||
if (net->flags & FLAG_USE_GLOBAL)
|
||||
@@ -1144,6 +982,24 @@ servlist_load (void)
|
||||
*
|
||||
* Should be removed at some point.
|
||||
*/
|
||||
case 'A':
|
||||
if (!net->pass)
|
||||
{
|
||||
net->pass = g_strdup (buf + 2);
|
||||
if (!net->logintype)
|
||||
{
|
||||
net->logintype = LOGIN_SASL;
|
||||
}
|
||||
}
|
||||
case 'B':
|
||||
if (!net->pass)
|
||||
{
|
||||
net->pass = g_strdup (buf + 2);
|
||||
if (!net->logintype)
|
||||
{
|
||||
net->logintype = LOGIN_NICKSERV;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (buf[0] == 'N')
|
||||
|
||||
@@ -62,8 +62,7 @@ extern GSList *network_list;
|
||||
#define FLAG_USE_PROXY 16
|
||||
#define FLAG_ALLOW_INVALID 32
|
||||
#define FLAG_FAVORITE 64
|
||||
#define FLAG_USE_KEYRING 128
|
||||
#define FLAG_COUNT 8
|
||||
#define FLAG_COUNT 7
|
||||
|
||||
/* Login methods. Use server password by default - if we had a NickServ password, it'd be set to 2 already by servlist_load() */
|
||||
#define LOGIN_DEFAULT_REAL LOGIN_PASS /* this is to set the default login method for unknown servers */
|
||||
@@ -125,8 +124,5 @@ favchannel *servlist_favchan_copy (favchannel *fav);
|
||||
GSList *servlist_favchan_listadd (GSList *chanlist, char *channel, char *key);
|
||||
|
||||
gboolean joinlist_is_in_list (server *serv, char *channel);
|
||||
char *servlist_password_encrypt_for_storage (const char *pass);
|
||||
char *servlist_password_decrypt_for_storage (const char *pass);
|
||||
gboolean servlist_password_is_encrypted (const char *pass);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include <windows.h>
|
||||
#include <dwmapi.h>
|
||||
#include <glib/gwin32.h>
|
||||
#include "../../win32/appusermodelid.h"
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@@ -141,7 +140,7 @@ win32_set_appusermodelid (void)
|
||||
if (!set_appid)
|
||||
return;
|
||||
|
||||
set_appid (ZOITECHAT_APPUSERMODELIDW);
|
||||
set_appid (L"ZoiteChat.Desktop.Notify");
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(ArchiveLibDir);$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>$(DepLibs);$(ZoiteChatLib)common.lib;wbemuuid.lib;dwmapi.lib;ole32.lib;uuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>$(DepLibs);$(ZoiteChatLib)common.lib;wbemuuid.lib;dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
@@ -872,10 +872,6 @@ fe_set_title (session *sess)
|
||||
|
||||
static void
|
||||
mg_topicbar_update_height (GtkWidget *topic);
|
||||
static void
|
||||
mg_topicbar_queue_relayout (GtkWidget *topic);
|
||||
static void
|
||||
mg_queue_window_relayout (GtkWidget *window);
|
||||
|
||||
static session *
|
||||
mg_session_from_window (GtkWidget *wid)
|
||||
@@ -895,57 +891,6 @@ mg_session_from_window (GtkWidget *wid)
|
||||
return current_sess;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
mg_window_relayout_idle_cb (gpointer userdata)
|
||||
{
|
||||
GtkWidget *window = GTK_WIDGET (userdata);
|
||||
session *sess;
|
||||
|
||||
g_object_set_data (G_OBJECT (window), "mg-window-relayout-source", NULL);
|
||||
|
||||
sess = mg_session_from_window (window);
|
||||
if (sess && sess->gui)
|
||||
{
|
||||
if (GTK_IS_WIDGET (sess->gui->topic_entry))
|
||||
mg_topicbar_queue_relayout (sess->gui->topic_entry);
|
||||
|
||||
if (GTK_IS_XTEXT (sess->gui->xtext))
|
||||
{
|
||||
gtk_xtext_refresh (GTK_XTEXT (sess->gui->xtext));
|
||||
gtk_widget_queue_resize (sess->gui->xtext);
|
||||
gtk_widget_queue_draw (sess->gui->xtext);
|
||||
}
|
||||
|
||||
if (GTK_IS_WIDGET (sess->gui->window))
|
||||
{
|
||||
gtk_widget_queue_resize (sess->gui->window);
|
||||
gtk_widget_queue_draw (sess->gui->window);
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (window);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
mg_queue_window_relayout (GtkWidget *window)
|
||||
{
|
||||
guint source_id;
|
||||
|
||||
if (!window || !GTK_IS_WIDGET (window))
|
||||
return;
|
||||
|
||||
if (g_object_get_data (G_OBJECT (window), "mg-window-relayout-source") != NULL)
|
||||
return;
|
||||
|
||||
source_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
|
||||
mg_window_relayout_idle_cb,
|
||||
g_object_ref (window),
|
||||
NULL);
|
||||
g_object_set_data (G_OBJECT (window), "mg-window-relayout-source",
|
||||
GUINT_TO_POINTER (source_id));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
mg_windowstate_cb (GtkWindow *wid, GdkEventWindowState *event, gpointer userdata)
|
||||
{
|
||||
@@ -994,18 +939,24 @@ mg_windowstate_cb (GtkWindow *wid, GdkEventWindowState *event, gpointer userdata
|
||||
}
|
||||
|
||||
sess = mg_session_from_window (GTK_WIDGET (wid));
|
||||
if (sess && sess->gui && GTK_IS_WIDGET (sess->gui->topic_entry))
|
||||
{
|
||||
mg_topicbar_update_height (sess->gui->topic_entry);
|
||||
gtk_widget_queue_draw (sess->gui->topic_entry);
|
||||
}
|
||||
if (sess && sess->gui && GTK_IS_XTEXT (sess->gui->xtext))
|
||||
{
|
||||
gtk_xtext_refresh (GTK_XTEXT (sess->gui->xtext));
|
||||
gtk_widget_queue_draw (sess->gui->xtext);
|
||||
}
|
||||
if (sess && sess->gui && GTK_IS_WIDGET (sess->gui->window))
|
||||
mg_queue_window_relayout (sess->gui->window);
|
||||
else
|
||||
mg_queue_window_relayout (GTK_WIDGET (wid));
|
||||
gtk_widget_queue_draw (sess->gui->window);
|
||||
|
||||
if (current_sess && current_sess->gui)
|
||||
menu_set_fullscreen (current_sess->gui, prefs.hex_gui_win_fullscreen);
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
if (event->changed_mask &
|
||||
(GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN))
|
||||
mg_win32_allow_autohide_taskbar (wid, event);
|
||||
mg_win32_allow_autohide_taskbar (wid, event);
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
@@ -1099,10 +1050,21 @@ mg_configure_cb (GtkWidget *wid, GdkEventConfigure *event, session *sess)
|
||||
}
|
||||
|
||||
target_sess = mg_session_from_window (wid);
|
||||
if (target_sess && target_sess->gui && GTK_IS_WIDGET (target_sess->gui->window))
|
||||
mg_queue_window_relayout (target_sess->gui->window);
|
||||
else
|
||||
mg_queue_window_relayout (wid);
|
||||
if (target_sess && target_sess->gui)
|
||||
{
|
||||
if (GTK_IS_WIDGET (target_sess->gui->topic_entry))
|
||||
{
|
||||
mg_topicbar_update_height (target_sess->gui->topic_entry);
|
||||
gtk_widget_queue_draw (target_sess->gui->topic_entry);
|
||||
}
|
||||
if (GTK_IS_XTEXT (target_sess->gui->xtext))
|
||||
{
|
||||
gtk_xtext_refresh (GTK_XTEXT (target_sess->gui->xtext));
|
||||
gtk_widget_queue_draw (target_sess->gui->xtext);
|
||||
}
|
||||
if (GTK_IS_WIDGET (target_sess->gui->window))
|
||||
gtk_widget_queue_draw (target_sess->gui->window);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -3149,51 +3111,33 @@ mg_create_dialogbuttons (GtkWidget *box)
|
||||
static void
|
||||
mg_topicbar_update_height (GtkWidget *topic)
|
||||
{
|
||||
GtkWidget *parent;
|
||||
GtkWidget *grandparent;
|
||||
GtkWidget *scroller;
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter start;
|
||||
GtkTextIter end;
|
||||
GtkTextView *view;
|
||||
PangoLayout *layout;
|
||||
char *text;
|
||||
int width;
|
||||
int line_height;
|
||||
int line_count;
|
||||
int target_height;
|
||||
int margin_left;
|
||||
int margin_right;
|
||||
int margin_top;
|
||||
int margin_bottom;
|
||||
int old_height;
|
||||
PangoContext *context;
|
||||
PangoFontMetrics *metrics;
|
||||
|
||||
if (!topic || !GTK_IS_TEXT_VIEW (topic))
|
||||
return;
|
||||
|
||||
view = GTK_TEXT_VIEW (topic);
|
||||
parent = gtk_widget_get_parent (topic);
|
||||
grandparent = parent ? gtk_widget_get_parent (parent) : NULL;
|
||||
scroller = gtk_widget_get_parent (topic);
|
||||
|
||||
margin_left = gtk_text_view_get_left_margin (view);
|
||||
margin_right = gtk_text_view_get_right_margin (view);
|
||||
margin_top = gtk_text_view_get_top_margin (view);
|
||||
margin_bottom = gtk_text_view_get_bottom_margin (view);
|
||||
|
||||
buffer = gtk_text_view_get_buffer (view);
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (topic));
|
||||
gtk_text_buffer_get_bounds (buffer, &start, &end);
|
||||
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
|
||||
layout = gtk_widget_create_pango_layout (topic, text && text[0] ? text : " ");
|
||||
g_free (text);
|
||||
|
||||
width = gtk_widget_get_allocated_width (topic);
|
||||
if (width <= 1 && parent)
|
||||
width = gtk_widget_get_allocated_width (parent);
|
||||
width -= margin_left + margin_right;
|
||||
if (width < 1)
|
||||
width = 1;
|
||||
pango_layout_set_width (layout, width * PANGO_SCALE);
|
||||
width = gtk_widget_get_allocated_width (topic) - 8;
|
||||
if (width > 0)
|
||||
pango_layout_set_width (layout, width * PANGO_SCALE);
|
||||
pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
|
||||
|
||||
context = gtk_widget_get_pango_context (topic);
|
||||
@@ -3205,95 +3149,44 @@ mg_topicbar_update_height (GtkWidget *topic)
|
||||
pango_font_metrics_unref (metrics);
|
||||
if (line_height <= 0)
|
||||
line_height = 16;
|
||||
|
||||
line_count = pango_layout_get_line_count (layout);
|
||||
if (line_count <= 0)
|
||||
line_count = 1;
|
||||
target_height = line_height * line_count;
|
||||
if (target_height < line_height)
|
||||
target_height = line_height;
|
||||
|
||||
target_height = (line_height * line_count) + margin_top + margin_bottom;
|
||||
if (target_height < line_height + margin_top + margin_bottom)
|
||||
target_height = line_height + margin_top + margin_bottom;
|
||||
|
||||
old_height = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (topic),
|
||||
"mg-topicbar-target-height"));
|
||||
if (old_height != target_height)
|
||||
gtk_widget_set_size_request (topic, -1, target_height);
|
||||
if (scroller && GTK_IS_SCROLLED_WINDOW (scroller))
|
||||
{
|
||||
g_object_set_data (G_OBJECT (topic), "mg-topicbar-target-height",
|
||||
GINT_TO_POINTER (target_height));
|
||||
gtk_widget_set_size_request (topic, -1, target_height);
|
||||
|
||||
if (parent && GTK_IS_SCROLLED_WINDOW (parent))
|
||||
{
|
||||
gtk_scrolled_window_set_max_content_height (GTK_SCROLLED_WINDOW (parent), -1);
|
||||
gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (parent), -1);
|
||||
gtk_scrolled_window_set_max_content_height (GTK_SCROLLED_WINDOW (parent), target_height);
|
||||
gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (parent), target_height);
|
||||
gtk_widget_set_size_request (parent, -1, target_height);
|
||||
}
|
||||
gtk_scrolled_window_set_max_content_height (GTK_SCROLLED_WINDOW (scroller), -1);
|
||||
gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (scroller), -1);
|
||||
gtk_scrolled_window_set_max_content_height (GTK_SCROLLED_WINDOW (scroller), target_height);
|
||||
gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (scroller), target_height);
|
||||
gtk_widget_set_size_request (scroller, -1, target_height);
|
||||
gtk_widget_queue_resize (scroller);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_queue_resize (topic);
|
||||
}
|
||||
|
||||
gtk_widget_queue_resize (topic);
|
||||
if (parent)
|
||||
gtk_widget_queue_resize (parent);
|
||||
if (grandparent)
|
||||
gtk_widget_queue_resize (grandparent);
|
||||
gtk_widget_queue_draw (topic);
|
||||
g_object_unref (layout);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
mg_topicbar_relayout_idle_cb (gpointer userdata)
|
||||
{
|
||||
GtkWidget *topic = GTK_WIDGET (userdata);
|
||||
|
||||
g_object_set_data (G_OBJECT (topic), "mg-topicbar-relayout-source", NULL);
|
||||
mg_topicbar_update_height (topic);
|
||||
g_object_unref (topic);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
mg_topicbar_queue_relayout (GtkWidget *topic)
|
||||
{
|
||||
guint source_id;
|
||||
|
||||
if (!topic || !GTK_IS_TEXT_VIEW (topic))
|
||||
return;
|
||||
|
||||
if (g_object_get_data (G_OBJECT (topic), "mg-topicbar-relayout-source") != NULL)
|
||||
return;
|
||||
|
||||
source_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
|
||||
mg_topicbar_relayout_idle_cb,
|
||||
g_object_ref (topic),
|
||||
NULL);
|
||||
g_object_set_data (G_OBJECT (topic), "mg-topicbar-relayout-source",
|
||||
GUINT_TO_POINTER (source_id));
|
||||
}
|
||||
|
||||
static void
|
||||
mg_topicbar_buffer_changed_cb (GtkTextBuffer *buffer, gpointer userdata)
|
||||
{
|
||||
(void) buffer;
|
||||
mg_topicbar_queue_relayout (GTK_WIDGET (userdata));
|
||||
mg_topicbar_update_height (GTK_WIDGET (userdata));
|
||||
}
|
||||
|
||||
static void
|
||||
mg_topicbar_size_allocate_cb (GtkWidget *widget, GtkAllocation *allocation, gpointer userdata)
|
||||
{
|
||||
int old_width;
|
||||
|
||||
(void) allocation;
|
||||
(void) userdata;
|
||||
|
||||
old_width = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
|
||||
"mg-topicbar-allocated-width"));
|
||||
if (allocation->width == old_width)
|
||||
return;
|
||||
|
||||
g_object_set_data (G_OBJECT (widget), "mg-topicbar-allocated-width",
|
||||
GINT_TO_POINTER (allocation->width));
|
||||
mg_topicbar_queue_relayout (widget);
|
||||
mg_topicbar_update_height (widget);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -3578,7 +3471,7 @@ mg_create_infoframe (GtkWidget *box)
|
||||
|
||||
frame = gtk_frame_new (0);
|
||||
gtk_frame_set_shadow_type ((GtkFrame*)frame, GTK_SHADOW_OUT);
|
||||
gtk_box_pack_start (GTK_BOX (box), frame, TRUE, TRUE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (box), frame, FALSE, TRUE, 0);
|
||||
|
||||
hbox = mg_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 0);
|
||||
gtk_container_add (GTK_CONTAINER (frame), hbox);
|
||||
@@ -3599,7 +3492,7 @@ mg_create_meters (session_gui *gui, GtkWidget *parent_box)
|
||||
|
||||
if ((prefs.hex_gui_lagometer & 2) || (prefs.hex_gui_throttlemeter & 2))
|
||||
{
|
||||
infbox = mg_box_new (GTK_ORIENTATION_HORIZONTAL, TRUE, 0);
|
||||
infbox = mg_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (box), infbox, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -91,9 +91,6 @@ zoitechat_gtk_ldflags = []
|
||||
if host_machine.system() == 'windows'
|
||||
zoitechat_gtk_sources += 'notifications/notification-windows.c'
|
||||
zoitechat_gtk_deps += cc.find_library('dwmapi', required: true)
|
||||
zoitechat_gtk_deps += cc.find_library('shell32', required: true)
|
||||
zoitechat_gtk_deps += cc.find_library('ole32', required: true)
|
||||
zoitechat_gtk_deps += cc.find_library('uuid', required: true)
|
||||
zoitechat_theme_deps += cc.find_library('dwmapi', required: true)
|
||||
|
||||
else
|
||||
|
||||
@@ -75,7 +75,7 @@ notification_backend_show (const char *title, const char *text)
|
||||
"Notify",
|
||||
g_variant_builder_end (¶ms),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
1000,
|
||||
-1,
|
||||
NULL,
|
||||
(GAsyncReadyCallback)on_notify_ready,
|
||||
NULL);
|
||||
@@ -108,7 +108,7 @@ notification_backend_init (const char **error)
|
||||
"GetCapabilities",
|
||||
NULL,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
30,
|
||||
1000,
|
||||
NULL,
|
||||
&err);
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#include <roapi.h>
|
||||
#include <windows.ui.notifications.h>
|
||||
#include "../../../win32/appusermodelid.h"
|
||||
|
||||
using namespace Windows::UI::Notifications;
|
||||
using namespace Windows::Data::Xml::Dom;
|
||||
@@ -85,20 +84,13 @@ extern "C"
|
||||
__declspec (dllexport) int
|
||||
notification_backend_init (const char **error)
|
||||
{
|
||||
if (FAILED (Windows::Foundation::Initialize (RO_INIT_SINGLETHREADED)))
|
||||
{
|
||||
*error = "Error initializing Windows::Foundation.";
|
||||
return 0;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (!notifier)
|
||||
notifier = ToastNotificationManager::CreateToastNotifier (ZOITECHAT_APPUSERMODELIDW);
|
||||
notifier = ToastNotificationManager::CreateToastNotifier (L"ZoiteChat.Desktop.Notify");
|
||||
}
|
||||
catch (Platform::Exception ^ ex)
|
||||
{
|
||||
Windows::Foundation::Uninitialize ();
|
||||
static char exc_message[1024];
|
||||
std::string tmp = narrow(std::wstring(ex->Message->Data()));
|
||||
if (SUCCEEDED(StringCchPrintfA(exc_message, _countof(exc_message), "Error (0x%x): %s", ex->HResult, tmp.c_str())))
|
||||
@@ -109,11 +101,16 @@ extern "C"
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
Windows::Foundation::Uninitialize ();
|
||||
*error = "Generic c++ exception.";
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (FAILED (Windows::Foundation::Initialize (RO_INIT_SINGLETHREADED)))
|
||||
{
|
||||
*error = "Error initializing Windows::Foundation.";
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,12 +32,6 @@
|
||||
#include "gtkutil.h"
|
||||
|
||||
#include <gio/gio.h>
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
#include <shobjidl.h>
|
||||
#include <gdk/gdkwin32.h>
|
||||
#endif
|
||||
#if defined(GTK_DISABLE_DEPRECATED)
|
||||
typedef struct _GtkStatusIcon GtkStatusIcon;
|
||||
#endif
|
||||
@@ -123,7 +117,6 @@ gboolean gtk_status_icon_is_embedded (GtkStatusIcon *status_icon);
|
||||
|
||||
void tray_apply_setup (void);
|
||||
static gboolean tray_menu_try_restore (void);
|
||||
static gboolean tray_toggle_visibility_from_input (gboolean force_hide, gboolean direct_input);
|
||||
static void tray_cleanup (void);
|
||||
static void tray_init (void);
|
||||
static void tray_set_icon_state (TrayIcon icon, TrayIconState state);
|
||||
@@ -132,7 +125,6 @@ static void tray_menu_notify_cb (GObject *tray, GParamSpec *pspec, gpointer user
|
||||
static void tray_update_toggle_item_label (void);
|
||||
static gboolean tray_window_state_cb (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata);
|
||||
static void tray_window_visibility_cb (GtkWidget *widget, gpointer userdata);
|
||||
static WinStatus tray_get_window_status (void);
|
||||
static void tray_toggle_item_destroy_cb (GtkWidget *widget, gpointer userdata);
|
||||
#if HAVE_APPINDICATOR_BACKEND
|
||||
static void tray_menu_show_cb (GtkWidget *menu, gpointer userdata) G_GNUC_UNUSED;
|
||||
@@ -157,16 +149,6 @@ static GtkWidget *tray_menu;
|
||||
#if !HAVE_APPINDICATOR_BACKEND
|
||||
static GtkStatusIcon *tray_status_icon;
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
static HWND tray_win32_hwnd;
|
||||
static HICON tray_win32_icon;
|
||||
static HICON tray_win32_overlay_icon;
|
||||
static ITaskbarList3 *tray_win32_taskbar;
|
||||
static gboolean tray_win32_active;
|
||||
static UINT tray_win32_taskbar_created;
|
||||
static const UINT tray_win32_callback_msg = WM_APP + 42;
|
||||
static const GUID tray_win32_guid = { 0xf79ad3d9, 0xc92f, 0x49eb, { 0x9d, 0xd2, 0xe1, 0xad, 0xad, 0xa8, 0x1c, 0xd3 } };
|
||||
#endif
|
||||
static gboolean tray_backend_active = FALSE;
|
||||
|
||||
static gint flash_tag;
|
||||
@@ -528,447 +510,6 @@ tray_status_icon_init (void)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
static HICON
|
||||
tray_win32_pixbuf_to_hicon (GdkPixbuf *pixbuf)
|
||||
{
|
||||
BITMAPV5HEADER bi;
|
||||
ICONINFO ii;
|
||||
HBITMAP color;
|
||||
HBITMAP mask;
|
||||
HDC dc;
|
||||
HICON icon;
|
||||
guchar *pixels;
|
||||
guchar *src;
|
||||
guchar *dst;
|
||||
void *bits;
|
||||
int width;
|
||||
int height;
|
||||
int rowstride;
|
||||
int channels;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
if (!pixbuf)
|
||||
return NULL;
|
||||
|
||||
width = gdk_pixbuf_get_width (pixbuf);
|
||||
height = gdk_pixbuf_get_height (pixbuf);
|
||||
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
channels = gdk_pixbuf_get_n_channels (pixbuf);
|
||||
pixels = gdk_pixbuf_get_pixels (pixbuf);
|
||||
|
||||
ZeroMemory (&bi, sizeof (bi));
|
||||
bi.bV5Size = sizeof (bi);
|
||||
bi.bV5Width = width;
|
||||
bi.bV5Height = -height;
|
||||
bi.bV5Planes = 1;
|
||||
bi.bV5BitCount = 32;
|
||||
bi.bV5Compression = BI_BITFIELDS;
|
||||
bi.bV5RedMask = 0x00ff0000;
|
||||
bi.bV5GreenMask = 0x0000ff00;
|
||||
bi.bV5BlueMask = 0x000000ff;
|
||||
bi.bV5AlphaMask = 0xff000000;
|
||||
|
||||
dc = GetDC (NULL);
|
||||
color = CreateDIBSection (dc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, &bits, NULL, 0);
|
||||
ReleaseDC (NULL, dc);
|
||||
if (!color)
|
||||
return NULL;
|
||||
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
src = pixels + y * rowstride;
|
||||
dst = (guchar *)bits + y * width * 4;
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
guchar alpha = channels >= 4 ? src[3] : 255;
|
||||
dst[0] = src[2] * alpha / 255;
|
||||
dst[1] = src[1] * alpha / 255;
|
||||
dst[2] = src[0] * alpha / 255;
|
||||
dst[3] = alpha;
|
||||
src += channels;
|
||||
dst += 4;
|
||||
}
|
||||
}
|
||||
|
||||
mask = CreateBitmap (width, height, 1, 1, NULL);
|
||||
if (!mask)
|
||||
{
|
||||
DeleteObject (color);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZeroMemory (&ii, sizeof (ii));
|
||||
ii.fIcon = TRUE;
|
||||
ii.hbmColor = color;
|
||||
ii.hbmMask = mask;
|
||||
icon = CreateIconIndirect (&ii);
|
||||
DeleteObject (mask);
|
||||
DeleteObject (color);
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
static HWND
|
||||
tray_win32_get_main_hwnd (void)
|
||||
{
|
||||
GtkWindow *win;
|
||||
GdkWindow *gdk_window;
|
||||
|
||||
win = GTK_WINDOW (zoitechat_get_info (ph, "gtkwin_ptr"));
|
||||
if (!win)
|
||||
return NULL;
|
||||
|
||||
gdk_window = gtk_widget_get_window (GTK_WIDGET (win));
|
||||
if (!gdk_window)
|
||||
return NULL;
|
||||
|
||||
return gdk_win32_window_get_handle (gdk_window);
|
||||
}
|
||||
|
||||
static ITaskbarList3 *
|
||||
tray_win32_get_taskbar (void)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (tray_win32_taskbar)
|
||||
return tray_win32_taskbar;
|
||||
|
||||
hr = CoCreateInstance (&CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_ITaskbarList3, (void **)&tray_win32_taskbar);
|
||||
if (FAILED (hr))
|
||||
return NULL;
|
||||
|
||||
hr = tray_win32_taskbar->lpVtbl->HrInit (tray_win32_taskbar);
|
||||
if (FAILED (hr))
|
||||
{
|
||||
tray_win32_taskbar->lpVtbl->Release (tray_win32_taskbar);
|
||||
tray_win32_taskbar = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return tray_win32_taskbar;
|
||||
}
|
||||
|
||||
static void
|
||||
tray_win32_release_attention (void)
|
||||
{
|
||||
if (tray_win32_overlay_icon)
|
||||
{
|
||||
DestroyIcon (tray_win32_overlay_icon);
|
||||
tray_win32_overlay_icon = NULL;
|
||||
}
|
||||
|
||||
if (tray_win32_taskbar)
|
||||
{
|
||||
tray_win32_taskbar->lpVtbl->Release (tray_win32_taskbar);
|
||||
tray_win32_taskbar = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tray_win32_clear_attention (void)
|
||||
{
|
||||
FLASHWINFO flash;
|
||||
ITaskbarList3 *taskbar;
|
||||
HWND hwnd;
|
||||
|
||||
hwnd = tray_win32_get_main_hwnd ();
|
||||
if (!hwnd)
|
||||
return;
|
||||
|
||||
ZeroMemory (&flash, sizeof (flash));
|
||||
flash.cbSize = sizeof (flash);
|
||||
flash.hwnd = hwnd;
|
||||
flash.dwFlags = FLASHW_STOP;
|
||||
FlashWindowEx (&flash);
|
||||
|
||||
taskbar = tray_win32_get_taskbar ();
|
||||
if (taskbar)
|
||||
taskbar->lpVtbl->SetOverlayIcon (taskbar, hwnd, NULL, L"");
|
||||
|
||||
if (tray_win32_overlay_icon)
|
||||
{
|
||||
DestroyIcon (tray_win32_overlay_icon);
|
||||
tray_win32_overlay_icon = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tray_win32_set_attention (TrayIcon icon)
|
||||
{
|
||||
FLASHWINFO flash;
|
||||
ITaskbarList3 *taskbar;
|
||||
HICON hicon;
|
||||
HWND hwnd;
|
||||
|
||||
if (tray_get_window_status () == WS_FOCUSED)
|
||||
return;
|
||||
|
||||
hwnd = tray_win32_get_main_hwnd ();
|
||||
if (!hwnd)
|
||||
return;
|
||||
|
||||
ZeroMemory (&flash, sizeof (flash));
|
||||
flash.cbSize = sizeof (flash);
|
||||
flash.hwnd = hwnd;
|
||||
flash.dwFlags = FLASHW_TRAY | FLASHW_TIMERNOFG;
|
||||
FlashWindowEx (&flash);
|
||||
|
||||
taskbar = tray_win32_get_taskbar ();
|
||||
if (!taskbar)
|
||||
return;
|
||||
|
||||
hicon = tray_win32_pixbuf_to_hicon (icon);
|
||||
if (!hicon)
|
||||
return;
|
||||
|
||||
if (SUCCEEDED (taskbar->lpVtbl->SetOverlayIcon (taskbar, hwnd, hicon, L"")))
|
||||
{
|
||||
if (tray_win32_overlay_icon)
|
||||
DestroyIcon (tray_win32_overlay_icon);
|
||||
tray_win32_overlay_icon = hicon;
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroyIcon (hicon);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tray_win32_init_data (NOTIFYICONDATAW *nid)
|
||||
{
|
||||
ZeroMemory (nid, sizeof (*nid));
|
||||
nid->cbSize = sizeof (*nid);
|
||||
nid->hWnd = tray_win32_hwnd;
|
||||
nid->uID = 1;
|
||||
nid->uFlags = NIF_GUID;
|
||||
nid->guidItem = tray_win32_guid;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
tray_win32_add (void)
|
||||
{
|
||||
NOTIFYICONDATAW nid;
|
||||
|
||||
tray_win32_init_data (&nid);
|
||||
nid.uFlags |= NIF_MESSAGE | NIF_ICON | NIF_TIP;
|
||||
nid.uCallbackMessage = tray_win32_callback_msg;
|
||||
nid.hIcon = tray_win32_icon;
|
||||
wcsncpy (nid.szTip, L"ZoiteChat", G_N_ELEMENTS (nid.szTip) - 1);
|
||||
|
||||
if (!Shell_NotifyIconW (NIM_ADD, &nid))
|
||||
return FALSE;
|
||||
|
||||
tray_win32_init_data (&nid);
|
||||
nid.uVersion = NOTIFYICON_VERSION_4;
|
||||
Shell_NotifyIconW (NIM_SETVERSION, &nid);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
tray_win32_set_icon (TrayIcon icon)
|
||||
{
|
||||
NOTIFYICONDATAW nid;
|
||||
HICON hicon;
|
||||
|
||||
if (!tray_win32_active)
|
||||
return;
|
||||
|
||||
hicon = tray_win32_pixbuf_to_hicon (icon);
|
||||
if (!hicon)
|
||||
return;
|
||||
|
||||
tray_win32_init_data (&nid);
|
||||
nid.uFlags |= NIF_ICON;
|
||||
nid.hIcon = hicon;
|
||||
if (Shell_NotifyIconW (NIM_MODIFY, &nid))
|
||||
{
|
||||
if (tray_win32_icon)
|
||||
DestroyIcon (tray_win32_icon);
|
||||
tray_win32_icon = hicon;
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroyIcon (hicon);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tray_win32_set_tooltip (const char *text)
|
||||
{
|
||||
NOTIFYICONDATAW nid;
|
||||
wchar_t *wide;
|
||||
|
||||
if (!tray_win32_active)
|
||||
return;
|
||||
|
||||
wide = g_utf8_to_utf16 (text ? text : "", -1, NULL, NULL, NULL);
|
||||
tray_win32_init_data (&nid);
|
||||
nid.uFlags |= NIF_TIP;
|
||||
if (wide)
|
||||
{
|
||||
wcsncpy (nid.szTip, wide, G_N_ELEMENTS (nid.szTip) - 1);
|
||||
g_free (wide);
|
||||
}
|
||||
Shell_NotifyIconW (NIM_MODIFY, &nid);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
tray_win32_is_embedded (void)
|
||||
{
|
||||
return tray_win32_active;
|
||||
}
|
||||
|
||||
static void
|
||||
tray_win32_cleanup (void)
|
||||
{
|
||||
NOTIFYICONDATAW nid;
|
||||
|
||||
if (tray_win32_active)
|
||||
{
|
||||
tray_win32_init_data (&nid);
|
||||
Shell_NotifyIconW (NIM_DELETE, &nid);
|
||||
tray_win32_active = FALSE;
|
||||
}
|
||||
|
||||
if (tray_win32_icon)
|
||||
{
|
||||
DestroyIcon (tray_win32_icon);
|
||||
tray_win32_icon = NULL;
|
||||
}
|
||||
|
||||
tray_win32_release_attention ();
|
||||
|
||||
if (tray_win32_hwnd)
|
||||
{
|
||||
DestroyWindow (tray_win32_hwnd);
|
||||
tray_win32_hwnd = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK
|
||||
tray_win32_wndproc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
(void)wparam;
|
||||
|
||||
if (msg == tray_win32_taskbar_created && tray_win32_icon)
|
||||
{
|
||||
tray_win32_add ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (msg == tray_win32_callback_msg)
|
||||
{
|
||||
switch (LOWORD (lparam))
|
||||
{
|
||||
case NIN_SELECT:
|
||||
case NIN_KEYSELECT:
|
||||
case WM_LBUTTONUP:
|
||||
tray_menu_restore_cb (NULL, NULL);
|
||||
return 0;
|
||||
case WM_CONTEXTMENU:
|
||||
case WM_RBUTTONUP:
|
||||
SetForegroundWindow (hwnd);
|
||||
tray_menu_cb (NULL, 3, GetTickCount (), NULL);
|
||||
PostMessage (hwnd, WM_NULL, 0, 0);
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProcW (hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
tray_win32_init (void)
|
||||
{
|
||||
WNDCLASSW wc;
|
||||
|
||||
tray_win32_taskbar_created = RegisterWindowMessageW (L"TaskbarCreated");
|
||||
tray_win32_icon = tray_win32_pixbuf_to_hicon (ICON_NORMAL);
|
||||
if (!tray_win32_icon)
|
||||
return FALSE;
|
||||
|
||||
ZeroMemory (&wc, sizeof (wc));
|
||||
wc.lpfnWndProc = tray_win32_wndproc;
|
||||
wc.hInstance = GetModuleHandleW (NULL);
|
||||
wc.lpszClassName = L"ZoiteChatTrayWindow";
|
||||
RegisterClassW (&wc);
|
||||
|
||||
tray_win32_hwnd = CreateWindowExW (0, wc.lpszClassName, L"", 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, wc.hInstance, NULL);
|
||||
if (!tray_win32_hwnd)
|
||||
{
|
||||
tray_win32_cleanup ();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!tray_win32_add ())
|
||||
{
|
||||
tray_win32_cleanup ();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
tray_win32_active = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
tray_win32_or_status_icon_init (void)
|
||||
{
|
||||
if (tray_win32_init ())
|
||||
return TRUE;
|
||||
|
||||
return tray_status_icon_init ();
|
||||
}
|
||||
|
||||
static void
|
||||
tray_win32_or_status_icon_set_icon (TrayIcon icon)
|
||||
{
|
||||
if (tray_win32_active)
|
||||
tray_win32_set_icon (icon);
|
||||
else
|
||||
tray_status_icon_set_icon (icon);
|
||||
}
|
||||
|
||||
static void
|
||||
tray_win32_or_status_icon_set_tooltip (const char *text)
|
||||
{
|
||||
if (tray_win32_active)
|
||||
tray_win32_set_tooltip (text);
|
||||
else
|
||||
tray_status_icon_set_tooltip (text);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
tray_win32_or_status_icon_is_embedded (void)
|
||||
{
|
||||
if (tray_win32_active)
|
||||
return tray_win32_is_embedded ();
|
||||
|
||||
return tray_status_icon_is_embedded ();
|
||||
}
|
||||
|
||||
static void
|
||||
tray_win32_or_status_icon_cleanup (void)
|
||||
{
|
||||
if (tray_win32_active || tray_win32_hwnd || tray_win32_icon)
|
||||
tray_win32_cleanup ();
|
||||
else
|
||||
tray_status_icon_cleanup ();
|
||||
}
|
||||
|
||||
static const TrayBackendOps tray_backend_ops = {
|
||||
tray_win32_or_status_icon_init,
|
||||
tray_win32_or_status_icon_set_icon,
|
||||
tray_win32_or_status_icon_set_tooltip,
|
||||
tray_win32_or_status_icon_is_embedded,
|
||||
tray_win32_or_status_icon_cleanup
|
||||
};
|
||||
#else
|
||||
static const TrayBackendOps tray_backend_ops = {
|
||||
tray_status_icon_init,
|
||||
tray_status_icon_set_icon,
|
||||
@@ -977,7 +518,6 @@ static const TrayBackendOps tray_backend_ops = {
|
||||
tray_status_icon_cleanup
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
tray_backend_init (void)
|
||||
@@ -1157,10 +697,6 @@ tray_stop_flash (void)
|
||||
flash_tag = 0;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
tray_win32_clear_attention ();
|
||||
#endif
|
||||
|
||||
if (tray_backend_active)
|
||||
{
|
||||
tray_set_icon_state (ICON_NORMAL, TRAY_ICON_NORMAL);
|
||||
@@ -1311,8 +847,8 @@ fe_tray_set_file (const char *filename)
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
tray_toggle_visibility_from_input (gboolean force_hide, gboolean direct_input)
|
||||
gboolean
|
||||
tray_toggle_visibility (gboolean force_hide)
|
||||
{
|
||||
static int x, y;
|
||||
static GdkScreen *screen;
|
||||
@@ -1354,29 +890,9 @@ tray_toggle_visibility_from_input (gboolean force_hide, gboolean direct_input)
|
||||
gtk_window_maximize (win);
|
||||
if (fullscreen)
|
||||
gtk_window_fullscreen (win);
|
||||
#ifdef WIN32
|
||||
{
|
||||
GdkWindow *gdk_window;
|
||||
HWND hwnd = NULL;
|
||||
|
||||
gdk_window = gtk_widget_get_window (GTK_WIDGET (win));
|
||||
if (gdk_window)
|
||||
hwnd = gdk_win32_window_get_handle (gdk_window);
|
||||
|
||||
if (hwnd && IsIconic (hwnd))
|
||||
ShowWindow (hwnd, SW_RESTORE);
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (win));
|
||||
gtk_window_present (win);
|
||||
|
||||
if (direct_input && hwnd)
|
||||
SetForegroundWindow (hwnd);
|
||||
}
|
||||
#else
|
||||
gtk_widget_show (GTK_WIDGET (win));
|
||||
gtk_window_deiconify (win);
|
||||
gtk_window_present (win);
|
||||
#endif
|
||||
}
|
||||
|
||||
tray_update_toggle_item_label ();
|
||||
@@ -1384,19 +900,13 @@ tray_toggle_visibility_from_input (gboolean force_hide, gboolean direct_input)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
tray_toggle_visibility (gboolean force_hide)
|
||||
{
|
||||
return tray_toggle_visibility_from_input (force_hide, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
tray_menu_restore_cb (GtkWidget *item, gpointer userdata)
|
||||
{
|
||||
(void)item;
|
||||
(void)userdata;
|
||||
|
||||
tray_toggle_visibility_from_input (FALSE, TRUE);
|
||||
tray_toggle_visibility (FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1532,11 +1042,7 @@ tray_menu_destroy (GtkWidget *menu, gpointer userdata)
|
||||
if (G_IS_OBJECT (menu))
|
||||
g_object_unref (menu);
|
||||
#ifdef WIN32
|
||||
if (tray_menu_timer)
|
||||
{
|
||||
g_source_remove (tray_menu_timer);
|
||||
tray_menu_timer = 0;
|
||||
}
|
||||
g_source_remove (tray_menu_timer);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@@ -1777,9 +1283,6 @@ tray_hilight_cb (char *word[], void *userdata)
|
||||
if (prefs.hex_input_tray_hilight)
|
||||
{
|
||||
tray_set_flash (ICON_HILIGHT, TRAY_ICON_HIGHLIGHT);
|
||||
#ifdef WIN32
|
||||
tray_win32_set_attention (ICON_HILIGHT);
|
||||
#endif
|
||||
|
||||
/* FIXME: hides any previous private messages */
|
||||
tray_hilight_count++;
|
||||
@@ -1831,9 +1334,6 @@ tray_priv (char *from, char *text)
|
||||
if (prefs.hex_input_tray_priv)
|
||||
{
|
||||
tray_set_flash (ICON_MSG, TRAY_ICON_MESSAGE);
|
||||
#ifdef WIN32
|
||||
tray_win32_set_attention (ICON_MSG);
|
||||
#endif
|
||||
|
||||
tray_priv_count++;
|
||||
if (tray_priv_count == 1)
|
||||
@@ -1905,9 +1405,6 @@ tray_cleanup (void)
|
||||
|
||||
if (tray_backend_active)
|
||||
tray_backend_cleanup ();
|
||||
#ifdef WIN32
|
||||
tray_win32_release_attention ();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1920,7 +1417,7 @@ tray_apply_setup (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
#if HAVE_APPINDICATOR_BACKEND || defined(WIN32)
|
||||
#if HAVE_APPINDICATOR_BACKEND
|
||||
if (prefs.hex_gui_tray)
|
||||
tray_init ();
|
||||
#else
|
||||
@@ -1974,7 +1471,7 @@ tray_plugin_init (zoitechat_plugin *plugin_handle, char **plugin_name,
|
||||
G_CALLBACK (tray_window_visibility_cb), NULL);
|
||||
}
|
||||
|
||||
#if HAVE_APPINDICATOR_BACKEND || defined(WIN32)
|
||||
#if HAVE_APPINDICATOR_BACKEND
|
||||
if (prefs.hex_gui_tray)
|
||||
#else
|
||||
if (prefs.hex_gui_tray && gtkutil_tray_icon_supported (window))
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "../common/servlist.h"
|
||||
#include "../common/cfgfiles.h"
|
||||
#include "../common/fe.h"
|
||||
#include "../common/secretstore.h"
|
||||
#include "../common/util.h"
|
||||
|
||||
#include "fe-gtk.h"
|
||||
@@ -86,12 +85,6 @@ static GtkWidget *edit_entry_nick2;
|
||||
static GtkWidget *edit_entry_user;
|
||||
static GtkWidget *edit_entry_real;
|
||||
static GtkWidget *edit_entry_pass;
|
||||
static GtkWidget *edit_check_show_pass;
|
||||
static GtkWidget *edit_check_use_keyring;
|
||||
static GtkWidget *edit_button_encrypt_pass;
|
||||
static GtkWidget *edit_button_import_pass;
|
||||
static int edit_pass_changed;
|
||||
static char *edit_loaded_password;
|
||||
static GtkWidget *edit_label_nick;
|
||||
static GtkWidget *edit_label_nick2;
|
||||
static GtkWidget *edit_label_real;
|
||||
@@ -110,168 +103,6 @@ static session *servlist_sess;
|
||||
|
||||
static void servlist_network_row_cb (GtkTreeSelection *sel, gpointer user_data);
|
||||
static GtkWidget *servlist_open_edit (GtkWidget *parent, ircnet *net);
|
||||
static void servlist_password_changed_cb (GtkEditable *editable, gpointer userdata);
|
||||
|
||||
static void
|
||||
servlist_update_password_tools (ircnet *net)
|
||||
{
|
||||
gboolean has_local;
|
||||
gboolean use_keyring;
|
||||
|
||||
if (!edit_button_encrypt_pass || !edit_button_import_pass)
|
||||
return;
|
||||
|
||||
use_keyring = net && (net->flags & FLAG_USE_KEYRING);
|
||||
has_local = net && net->pass && *net->pass && !use_keyring && !edit_pass_changed;
|
||||
gtk_widget_set_sensitive (edit_button_encrypt_pass, has_local && !servlist_password_is_encrypted (net->pass));
|
||||
gtk_widget_set_sensitive (edit_button_import_pass, has_local);
|
||||
}
|
||||
|
||||
static void
|
||||
servlist_entry_set_text_silent (GtkWidget *entry, const char *text)
|
||||
{
|
||||
g_signal_handlers_block_by_func (G_OBJECT (entry), G_CALLBACK (servlist_password_changed_cb), NULL);
|
||||
gtk_entry_set_text (GTK_ENTRY (entry), text);
|
||||
g_signal_handlers_unblock_by_func (G_OBJECT (entry), G_CALLBACK (servlist_password_changed_cb), NULL);
|
||||
}
|
||||
|
||||
static char *
|
||||
servlist_display_password (ircnet *net)
|
||||
{
|
||||
if (!net)
|
||||
return NULL;
|
||||
if (edit_pass_changed)
|
||||
return g_strdup (gtk_entry_get_text (GTK_ENTRY (edit_entry_pass)));
|
||||
if (edit_loaded_password)
|
||||
return g_strdup (edit_loaded_password);
|
||||
if (net->flags & FLAG_USE_KEYRING)
|
||||
return secretstore_get_network_password (net->name);
|
||||
return servlist_password_decrypt_for_storage (net->pass);
|
||||
}
|
||||
|
||||
static void
|
||||
servlist_toggle_show_password_cb (GtkToggleButton *toggle, gpointer userdata)
|
||||
{
|
||||
if (gtk_toggle_button_get_active (toggle))
|
||||
{
|
||||
char *password = servlist_display_password (selected_net);
|
||||
if (password)
|
||||
{
|
||||
if (edit_loaded_password)
|
||||
{
|
||||
memset (edit_loaded_password, 0, strlen (edit_loaded_password));
|
||||
g_free (edit_loaded_password);
|
||||
}
|
||||
edit_loaded_password = g_strdup (password);
|
||||
servlist_entry_set_text_silent (userdata, password);
|
||||
memset (password, 0, strlen (password));
|
||||
g_free (password);
|
||||
}
|
||||
gtk_entry_set_visibility (GTK_ENTRY (userdata), TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_entry_set_visibility (GTK_ENTRY (userdata), FALSE);
|
||||
if (edit_loaded_password && !edit_pass_changed)
|
||||
servlist_entry_set_text_silent (userdata, "***");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
servlist_toggle_keyring_cb (GtkToggleButton *toggle, gpointer userdata)
|
||||
{
|
||||
servlist_update_password_tools (selected_net);
|
||||
}
|
||||
|
||||
static void
|
||||
servlist_password_changed_cb (GtkEditable *editable, gpointer userdata)
|
||||
{
|
||||
edit_pass_changed = 1;
|
||||
if (edit_loaded_password && strcmp (gtk_entry_get_text (GTK_ENTRY (editable)), "***"))
|
||||
{
|
||||
memset (edit_loaded_password, 0, strlen (edit_loaded_password));
|
||||
g_free (edit_loaded_password);
|
||||
edit_loaded_password = NULL;
|
||||
}
|
||||
servlist_update_password_tools (selected_net);
|
||||
}
|
||||
|
||||
static void
|
||||
servlist_encrypt_password_cb (GtkWidget *button, gpointer userdata)
|
||||
{
|
||||
ircnet *net = userdata;
|
||||
char *plain;
|
||||
char *enc;
|
||||
|
||||
if (!net || (net->flags & FLAG_USE_KEYRING) || !net->pass || servlist_password_is_encrypted (net->pass))
|
||||
return;
|
||||
|
||||
plain = servlist_password_decrypt_for_storage (net->pass);
|
||||
if (!plain || !*plain)
|
||||
{
|
||||
if (plain)
|
||||
{
|
||||
memset (plain, 0, strlen (plain));
|
||||
g_free (plain);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
enc = servlist_password_encrypt_for_storage (plain);
|
||||
memset (plain, 0, strlen (plain));
|
||||
g_free (plain);
|
||||
if (!enc)
|
||||
{
|
||||
fe_message (_("Could not encrypt this password."), FE_MSG_WARN);
|
||||
return;
|
||||
}
|
||||
|
||||
g_free (net->pass);
|
||||
net->pass = enc;
|
||||
servlist_save ();
|
||||
servlist_update_password_tools (net);
|
||||
}
|
||||
|
||||
static void
|
||||
servlist_import_password_cb (GtkWidget *button, gpointer userdata)
|
||||
{
|
||||
ircnet *net = userdata;
|
||||
char *plain;
|
||||
|
||||
if (!net || !net->name || (net->flags & FLAG_USE_KEYRING) || !net->pass || !*net->pass)
|
||||
return;
|
||||
|
||||
plain = servlist_password_decrypt_for_storage (net->pass);
|
||||
if (!plain || !*plain)
|
||||
{
|
||||
if (plain)
|
||||
{
|
||||
memset (plain, 0, strlen (plain));
|
||||
g_free (plain);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!secretstore_set_network_password (net->name, plain))
|
||||
{
|
||||
memset (plain, 0, strlen (plain));
|
||||
g_free (plain);
|
||||
fe_message (_("Could not move this password into the system keyring."), FE_MSG_WARN);
|
||||
return;
|
||||
}
|
||||
|
||||
memset (plain, 0, strlen (plain));
|
||||
g_free (plain);
|
||||
g_free (net->pass);
|
||||
net->pass = NULL;
|
||||
net->flags |= FLAG_USE_KEYRING;
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (edit_check_use_keyring), TRUE);
|
||||
servlist_entry_set_text_silent (edit_entry_pass, "***");
|
||||
edit_pass_changed = 0;
|
||||
servlist_save ();
|
||||
servlist_update_password_tools (net);
|
||||
}
|
||||
|
||||
static char *
|
||||
servlist_get_cert_file (ircnet *net)
|
||||
@@ -1247,79 +1078,14 @@ servlist_update_from_entry (char **str, GtkWidget *entry)
|
||||
*str = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
|
||||
}
|
||||
|
||||
static char *
|
||||
servlist_edit_current_password (ircnet *net)
|
||||
{
|
||||
if (!net)
|
||||
return NULL;
|
||||
if (net->flags & FLAG_USE_KEYRING)
|
||||
return secretstore_get_network_password (net->name);
|
||||
return servlist_password_decrypt_for_storage (net->pass);
|
||||
}
|
||||
|
||||
static void
|
||||
servlist_edit_update (ircnet *net)
|
||||
{
|
||||
gboolean use_keyring;
|
||||
gboolean keyring_changed;
|
||||
char *password = NULL;
|
||||
servlist_update_from_entry (&net->nick, edit_entry_nick);
|
||||
servlist_update_from_entry (&net->nick2, edit_entry_nick2);
|
||||
servlist_update_from_entry (&net->user, edit_entry_user);
|
||||
servlist_update_from_entry (&net->real, edit_entry_real);
|
||||
if (net && net->name)
|
||||
{
|
||||
use_keyring = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (edit_check_use_keyring));
|
||||
keyring_changed = !!(net->flags & FLAG_USE_KEYRING) != !!use_keyring;
|
||||
if (!edit_pass_changed && !keyring_changed)
|
||||
return;
|
||||
if (edit_pass_changed)
|
||||
password = g_strdup (gtk_entry_get_text (GTK_ENTRY (edit_entry_pass)));
|
||||
else
|
||||
password = servlist_edit_current_password (net);
|
||||
if (use_keyring)
|
||||
{
|
||||
if (password && *password)
|
||||
{
|
||||
if (!secretstore_set_network_password (net->name, password))
|
||||
{
|
||||
fe_message (_("No system keyring is available. ZoiteChat can save this password using local encrypted fallback storage, but it is less protected than your desktop keyring."), FE_MSG_WARN);
|
||||
memset (password, 0, strlen (password));
|
||||
g_free (password);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
secretstore_delete_network_password (net->name);
|
||||
net->flags |= FLAG_USE_KEYRING;
|
||||
g_free (net->pass);
|
||||
net->pass = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *enc = NULL;
|
||||
if (password && *password)
|
||||
{
|
||||
enc = servlist_password_encrypt_for_storage (password);
|
||||
if (!enc)
|
||||
{
|
||||
fe_message (_("Could not encrypt this password."), FE_MSG_WARN);
|
||||
memset (password, 0, strlen (password));
|
||||
g_free (password);
|
||||
return;
|
||||
}
|
||||
}
|
||||
secretstore_delete_network_password (net->name);
|
||||
net->flags &= ~FLAG_USE_KEYRING;
|
||||
g_free (net->pass);
|
||||
net->pass = enc;
|
||||
}
|
||||
if (password)
|
||||
{
|
||||
memset (password, 0, strlen (password));
|
||||
g_free (password);
|
||||
}
|
||||
}
|
||||
servlist_update_from_entry (&net->pass, edit_entry_pass);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1327,19 +1093,9 @@ servlist_edit_close_cb (GtkWidget *button, gpointer userdata)
|
||||
{
|
||||
if (selected_net)
|
||||
servlist_edit_update (selected_net);
|
||||
if (edit_loaded_password)
|
||||
{
|
||||
memset (edit_loaded_password, 0, strlen (edit_loaded_password));
|
||||
g_free (edit_loaded_password);
|
||||
edit_loaded_password = NULL;
|
||||
}
|
||||
|
||||
gtk_widget_destroy (edit_win);
|
||||
edit_win = NULL;
|
||||
edit_entry_pass = NULL;
|
||||
edit_check_show_pass = NULL;
|
||||
edit_button_encrypt_pass = NULL;
|
||||
edit_button_import_pass = NULL;
|
||||
}
|
||||
|
||||
static gint
|
||||
@@ -1370,10 +1126,6 @@ servlist_edit_cb (GtkWidget *but, gpointer none)
|
||||
{
|
||||
if (!servlist_has_selection (GTK_TREE_VIEW (networks_tree)))
|
||||
return;
|
||||
if (!selected_net || !selected_net->name)
|
||||
return;
|
||||
if ((selected_net->flags & FLAG_USE_KEYRING) && !secretstore_require_unlock (selected_net->name))
|
||||
return;
|
||||
|
||||
edit_win = servlist_open_edit (serverlist_win, selected_net);
|
||||
gtkutil_set_icon (edit_win);
|
||||
@@ -2565,7 +2317,7 @@ servlist_open_edit (GtkWidget *parent, ircnet *net)
|
||||
|
||||
|
||||
/* Checkboxes and entries */
|
||||
table3 = gtkutil_grid_new (17, 2, FALSE);
|
||||
table3 = gtkutil_grid_new (14, 2, FALSE);
|
||||
gtk_box_pack_start (GTK_BOX (vbox5), table3, FALSE, FALSE, 0);
|
||||
gtk_grid_set_row_spacing (GTK_GRID (table3), 2);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (table3), 8);
|
||||
@@ -2584,97 +2336,38 @@ servlist_open_edit (GtkWidget *parent, ircnet *net)
|
||||
#endif
|
||||
servlist_create_check (1, net->flags & FLAG_USE_GLOBAL, table3, 5, 0, _("Use global user information"));
|
||||
|
||||
edit_check_use_keyring = gtk_check_button_new_with_mnemonic (_("Use system keyring"));
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (edit_check_use_keyring), net->flags & FLAG_USE_KEYRING);
|
||||
servlist_table_attach (table3, edit_check_use_keyring, 0, 2, 6, 7,
|
||||
FALSE, FALSE,
|
||||
SERVLIST_ALIGN_START, SERVLIST_ALIGN_CENTER,
|
||||
SERVLIST_X_PADDING, SERVLIST_Y_PADDING);
|
||||
g_signal_connect (G_OBJECT (edit_check_use_keyring), "toggled",
|
||||
G_CALLBACK (servlist_toggle_keyring_cb), NULL);
|
||||
|
||||
edit_entry_nick = servlist_create_entry (table3, _("_Nick name:"), 7, net->nick, &edit_label_nick, 0);
|
||||
edit_entry_nick2 = servlist_create_entry (table3, _("Second choice:"), 8, net->nick2, &edit_label_nick2, 0);
|
||||
edit_entry_real = servlist_create_entry (table3, _("Rea_l name:"), 9, net->real, &edit_label_real, 0);
|
||||
edit_entry_user = servlist_create_entry (table3, _("_User name:"), 10, net->user, &edit_label_user, 0);
|
||||
edit_entry_nick = servlist_create_entry (table3, _("_Nick name:"), 6, net->nick, &edit_label_nick, 0);
|
||||
edit_entry_nick2 = servlist_create_entry (table3, _("Second choice:"), 7, net->nick2, &edit_label_nick2, 0);
|
||||
edit_entry_real = servlist_create_entry (table3, _("Rea_l name:"), 8, net->real, &edit_label_real, 0);
|
||||
edit_entry_user = servlist_create_entry (table3, _("_User name:"), 9, net->user, &edit_label_user, 0);
|
||||
|
||||
label_logintype = gtk_label_new (_("Login method:"));
|
||||
servlist_table_attach (table3, label_logintype, 0, 1, 11, 12,
|
||||
servlist_table_attach (table3, label_logintype, 0, 1, 10, 11,
|
||||
FALSE, FALSE,
|
||||
SERVLIST_ALIGN_START, SERVLIST_ALIGN_CENTER,
|
||||
SERVLIST_X_PADDING, SERVLIST_Y_PADDING);
|
||||
gtk_widget_set_halign (label_logintype, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (label_logintype, GTK_ALIGN_CENTER);
|
||||
combobox_logintypes = servlist_create_logintypecombo (notebook);
|
||||
servlist_table_attach (table3, combobox_logintypes, 1, 2, 11, 12,
|
||||
servlist_table_attach (table3, combobox_logintypes, 1, 2, 10, 11,
|
||||
FALSE, FALSE,
|
||||
SERVLIST_ALIGN_FILL, SERVLIST_ALIGN_FILL,
|
||||
4, 2);
|
||||
|
||||
edit_entry_pass = servlist_create_entry (table3, _("Password:"), 12, NULL, 0, _("Password used for login. If in doubt, leave blank."));
|
||||
if (edit_loaded_password)
|
||||
{
|
||||
memset (edit_loaded_password, 0, strlen (edit_loaded_password));
|
||||
g_free (edit_loaded_password);
|
||||
edit_loaded_password = NULL;
|
||||
}
|
||||
edit_pass_changed = 0;
|
||||
g_signal_connect (G_OBJECT (edit_entry_pass), "changed",
|
||||
G_CALLBACK (servlist_password_changed_cb), NULL);
|
||||
if (net->flags & FLAG_USE_KEYRING)
|
||||
{
|
||||
char *stored = secretstore_get_network_password (net->name);
|
||||
if (stored && *stored)
|
||||
{
|
||||
edit_loaded_password = g_strdup (stored);
|
||||
servlist_entry_set_text_silent (edit_entry_pass, "***");
|
||||
}
|
||||
if (stored)
|
||||
{
|
||||
memset (stored, 0, strlen (stored));
|
||||
g_free (stored);
|
||||
}
|
||||
}
|
||||
else if (net->pass && *net->pass)
|
||||
{
|
||||
servlist_entry_set_text_silent (edit_entry_pass, "***");
|
||||
}
|
||||
edit_pass_changed = 0;
|
||||
edit_entry_pass = servlist_create_entry (table3, _("Password:"), 11, net->pass, 0, _("Password used for login. If in doubt, leave blank."));
|
||||
gtk_entry_set_visibility (GTK_ENTRY (edit_entry_pass), FALSE);
|
||||
if (selected_net && selected_net->logintype == LOGIN_SASLEXTERNAL)
|
||||
gtk_widget_set_sensitive (edit_entry_pass, FALSE);
|
||||
edit_check_show_pass = gtk_check_button_new_with_mnemonic (_("Show password"));
|
||||
servlist_table_attach (table3, edit_check_show_pass, 0, 2, 13, 14,
|
||||
FALSE, FALSE,
|
||||
SERVLIST_ALIGN_START, SERVLIST_ALIGN_CENTER,
|
||||
4, 2);
|
||||
g_signal_connect (G_OBJECT (edit_check_show_pass), "toggled",
|
||||
G_CALLBACK (servlist_toggle_show_password_cb), edit_entry_pass);
|
||||
|
||||
edit_button_encrypt_pass = gtk_button_new_with_mnemonic (_("Encrypt saved password"));
|
||||
servlist_table_attach (table3, edit_button_encrypt_pass, 0, 1, 14, 15,
|
||||
FALSE, FALSE,
|
||||
SERVLIST_ALIGN_START, SERVLIST_ALIGN_CENTER,
|
||||
SERVLIST_X_PADDING, SERVLIST_Y_PADDING);
|
||||
g_signal_connect (G_OBJECT (edit_button_encrypt_pass), "clicked",
|
||||
G_CALLBACK (servlist_encrypt_password_cb), net);
|
||||
edit_button_import_pass = gtk_button_new_with_mnemonic (_("Move password to keyring"));
|
||||
servlist_table_attach (table3, edit_button_import_pass, 1, 2, 14, 15,
|
||||
FALSE, FALSE,
|
||||
SERVLIST_ALIGN_START, SERVLIST_ALIGN_CENTER,
|
||||
4, 2);
|
||||
g_signal_connect (G_OBJECT (edit_button_import_pass), "clicked",
|
||||
G_CALLBACK (servlist_import_password_cb), net);
|
||||
|
||||
label34 = gtk_label_new (_("Character set:"));
|
||||
servlist_table_attach (table3, label34, 0, 1, 15, 16,
|
||||
servlist_table_attach (table3, label34, 0, 1, 12, 13,
|
||||
FALSE, FALSE,
|
||||
SERVLIST_ALIGN_START, SERVLIST_ALIGN_CENTER,
|
||||
SERVLIST_X_PADDING, SERVLIST_Y_PADDING);
|
||||
gtk_widget_set_halign (label34, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (label34, GTK_ALIGN_CENTER);
|
||||
comboboxentry_charset = servlist_create_charsetcombo ();
|
||||
servlist_table_attach (table3, comboboxentry_charset, 1, 2, 15, 16,
|
||||
servlist_table_attach (table3, comboboxentry_charset, 1, 2, 12, 13,
|
||||
FALSE, FALSE,
|
||||
SERVLIST_ALIGN_FILL, SERVLIST_ALIGN_FILL,
|
||||
4, 2);
|
||||
@@ -2700,7 +2393,7 @@ servlist_open_edit (GtkWidget *parent, ircnet *net)
|
||||
G_CALLBACK (servlist_delete_client_cert_cb), net);
|
||||
gtk_box_pack_start (GTK_BOX (hbox_cert_buttons), edit_button_cert_delete, FALSE, FALSE, 0);
|
||||
|
||||
servlist_table_attach (table3, hbox_cert_buttons, 0, 2, 16, 17,
|
||||
servlist_table_attach (table3, hbox_cert_buttons, 0, 2, 13, 14,
|
||||
FALSE, FALSE,
|
||||
SERVLIST_ALIGN_START, SERVLIST_ALIGN_CENTER,
|
||||
SERVLIST_X_PADDING, SERVLIST_Y_PADDING);
|
||||
@@ -2724,8 +2417,6 @@ servlist_open_edit (GtkWidget *parent, ircnet *net)
|
||||
{
|
||||
servlist_toggle_global_user (FALSE);
|
||||
}
|
||||
servlist_toggle_keyring_cb (GTK_TOGGLE_BUTTON (edit_check_use_keyring), NULL);
|
||||
servlist_update_password_tools (net);
|
||||
|
||||
gtk_widget_grab_focus (button10);
|
||||
gtk_widget_grab_default (button10);
|
||||
|
||||
@@ -107,23 +107,12 @@ theme_manager_reset_mode_colors (unsigned int mode, gboolean *palette_changed)
|
||||
*palette_changed = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
theme_runtime_clear_gtk_mapped_custom_tokens (void)
|
||||
{
|
||||
}
|
||||
|
||||
gboolean
|
||||
theme_manager_save_preferences (void)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
theme_manager_apply_to_window (GtkWidget *window)
|
||||
{
|
||||
(void)window;
|
||||
}
|
||||
|
||||
void
|
||||
theme_manager_dispatch_changed (ThemeChangedReason reasons)
|
||||
{
|
||||
|
||||
@@ -88,15 +88,9 @@ theme_application_apply_toplevel_theme (gboolean dark)
|
||||
gboolean
|
||||
theme_application_apply_mode (unsigned int mode, gboolean *palette_changed)
|
||||
{
|
||||
static gboolean runtime_loaded = FALSE;
|
||||
gboolean dark;
|
||||
|
||||
if (!runtime_loaded)
|
||||
{
|
||||
theme_runtime_load ();
|
||||
runtime_loaded = TRUE;
|
||||
}
|
||||
|
||||
theme_runtime_load ();
|
||||
dark = theme_runtime_apply_mode (mode, palette_changed);
|
||||
theme_application_apply_toplevel_theme (dark);
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include "theme-gtk3.h"
|
||||
#include "theme-manager.h"
|
||||
#include "theme-preferences.h"
|
||||
#include "theme-runtime.h"
|
||||
|
||||
extern void load_text_events (void);
|
||||
|
||||
@@ -1418,56 +1417,17 @@ theme_preferences_gtk3_sync_remove_state (theme_preferences_ui *ui)
|
||||
gtk_widget_set_sensitive (ui->gtk3_remove, source == ZOITECHAT_GTK3_THEME_SOURCE_USER);
|
||||
}
|
||||
|
||||
static void
|
||||
theme_preferences_gtk3_sync_runtime_palette (theme_preferences_ui *ui)
|
||||
{
|
||||
ThemeWidgetStyleValues style_values;
|
||||
GtkWidget *style_source = NULL;
|
||||
|
||||
if (ui && ui->parent)
|
||||
style_source = GTK_WIDGET (ui->parent);
|
||||
else if (ui && ui->gtk3_combo)
|
||||
style_source = ui->gtk3_combo;
|
||||
|
||||
theme_runtime_clear_gtk_mapped_custom_tokens ();
|
||||
|
||||
theme_get_widget_style_values_for_widget (style_source, &style_values);
|
||||
|
||||
theme_preferences_staged_set_color (THEME_TOKEN_TEXT_FOREGROUND,
|
||||
&style_values.foreground,
|
||||
NULL,
|
||||
TRUE);
|
||||
theme_preferences_staged_set_color (THEME_TOKEN_TEXT_BACKGROUND,
|
||||
&style_values.background,
|
||||
NULL,
|
||||
TRUE);
|
||||
theme_preferences_staged_set_color (THEME_TOKEN_SELECTION_FOREGROUND,
|
||||
&style_values.selection_foreground,
|
||||
NULL,
|
||||
TRUE);
|
||||
theme_preferences_staged_set_color (THEME_TOKEN_SELECTION_BACKGROUND,
|
||||
&style_values.selection_background,
|
||||
NULL,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
theme_preferences_gtk3_apply_and_refresh (theme_preferences_ui *ui, GError **error)
|
||||
theme_preferences_gtk3_apply_and_refresh (GError **error)
|
||||
{
|
||||
if (!theme_gtk3_apply_current (error))
|
||||
return FALSE;
|
||||
|
||||
if (ui && ui->parent)
|
||||
theme_manager_apply_to_window (GTK_WIDGET (ui->parent));
|
||||
|
||||
theme_preferences_gtk3_sync_runtime_palette (ui);
|
||||
|
||||
theme_manager_dispatch_changed (THEME_CHANGED_REASON_THEME_PACK |
|
||||
THEME_CHANGED_REASON_PALETTE |
|
||||
THEME_CHANGED_REASON_WIDGET_STYLE |
|
||||
THEME_CHANGED_REASON_USERLIST |
|
||||
THEME_CHANGED_REASON_MODE);
|
||||
return TRUE;
|
||||
if (!theme_gtk3_apply_current (error))
|
||||
return FALSE;
|
||||
theme_manager_dispatch_changed (THEME_CHANGED_REASON_THEME_PACK |
|
||||
THEME_CHANGED_REASON_PALETTE |
|
||||
THEME_CHANGED_REASON_WIDGET_STYLE |
|
||||
THEME_CHANGED_REASON_USERLIST |
|
||||
THEME_CHANGED_REASON_MODE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1503,7 +1463,7 @@ theme_preferences_gtk3_changed_cb (GtkComboBox *combo, gpointer user_data)
|
||||
ui->setup_prefs->hex_gui_gtk3_variant = prefs.hex_gui_gtk3_variant;
|
||||
}
|
||||
|
||||
if (selection_changed && !theme_preferences_gtk3_apply_and_refresh (ui, &error))
|
||||
if (selection_changed && !theme_preferences_gtk3_apply_and_refresh (&error))
|
||||
{
|
||||
theme_preferences_show_message (ui, GTK_MESSAGE_ERROR,
|
||||
error ? error->message : _("Failed to apply GTK3 theme."));
|
||||
@@ -1592,7 +1552,7 @@ theme_preferences_populate_gtk3 (theme_preferences_ui *ui)
|
||||
g_free (final_id);
|
||||
}
|
||||
|
||||
if (should_apply && !theme_preferences_gtk3_apply_and_refresh (ui, &error))
|
||||
if (should_apply && !theme_preferences_gtk3_apply_and_refresh (&error))
|
||||
{
|
||||
theme_preferences_show_message (ui, GTK_MESSAGE_ERROR,
|
||||
error ? error->message : _("Failed to apply GTK3 theme."));
|
||||
|
||||
@@ -410,20 +410,6 @@ theme_runtime_reset_mode_colors (gboolean dark_mode)
|
||||
dark_mode_active = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
theme_runtime_clear_gtk_mapped_custom_tokens (void)
|
||||
{
|
||||
light_custom_tokens[THEME_TOKEN_TEXT_FOREGROUND] = FALSE;
|
||||
light_custom_tokens[THEME_TOKEN_TEXT_BACKGROUND] = FALSE;
|
||||
light_custom_tokens[THEME_TOKEN_SELECTION_FOREGROUND] = FALSE;
|
||||
light_custom_tokens[THEME_TOKEN_SELECTION_BACKGROUND] = FALSE;
|
||||
|
||||
dark_custom_tokens[THEME_TOKEN_TEXT_FOREGROUND] = FALSE;
|
||||
dark_custom_tokens[THEME_TOKEN_TEXT_BACKGROUND] = FALSE;
|
||||
dark_custom_tokens[THEME_TOKEN_SELECTION_FOREGROUND] = FALSE;
|
||||
dark_custom_tokens[THEME_TOKEN_SELECTION_BACKGROUND] = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
theme_runtime_load (void)
|
||||
{
|
||||
|
||||
@@ -47,7 +47,6 @@ gboolean theme_runtime_apply_dark_mode (gboolean enable);
|
||||
void theme_runtime_user_set_color (ThemeSemanticToken token, const GdkRGBA *col);
|
||||
void theme_runtime_dark_set_color (ThemeSemanticToken token, const GdkRGBA *col);
|
||||
void theme_runtime_reset_mode_colors (gboolean dark_mode);
|
||||
void theme_runtime_clear_gtk_mapped_custom_tokens (void);
|
||||
gboolean theme_runtime_get_color (ThemeSemanticToken token, GdkRGBA *out_rgba);
|
||||
gboolean theme_runtime_mode_has_user_colors (gboolean dark_mode);
|
||||
void theme_runtime_get_widget_style_values (ThemeWidgetStyleValues *out_values);
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
#define ZOITECHAT_APPUSERMODELID "ZoiteChat.Desktop.Notify"
|
||||
#ifdef _WIN32
|
||||
#define ZOITECHAT_APPUSERMODELIDW L"ZoiteChat.Desktop.Notify"
|
||||
#endif
|
||||
@@ -1,6 +1,5 @@
|
||||
#define APPNAM "ZoiteChat"
|
||||
#define APPVER "<#= [string]::Join('.', $versionParts) #>"
|
||||
#include "..\appusermodelid.h"
|
||||
; These are defined by our installer project at build time
|
||||
;#define APPARCH "x64"
|
||||
;#define PROJECTDIR "C:\...\zoitechat\win32\installer\"
|
||||
@@ -77,14 +76,11 @@ Root: HKCR; Subkey: "irc"; ValueType: string; ValueName: "URL Protocol"; ValueDa
|
||||
Root: HKCR; Subkey: "irc\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\zoitechat.exe,0"; Flags: uninsdeletevalue; Tasks: not portable
|
||||
Root: HKCR; Subkey: "irc\shell"; ValueType: string; ValueName: ""; ValueData: "open"; Flags: uninsdeletevalue; Tasks: not portable
|
||||
Root: HKCR; Subkey: "irc\shell\open\command"; ValueType: string; ValueName: ""; ValueData: "{app}\zoitechat.exe --url=""%1"""; Flags: uninsdeletevalue; Tasks: not portable
|
||||
Root: HKCR; Subkey: "irc\Application"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#ZOITECHAT_APPUSERMODELID}"; Flags: uninsdeletevalue; Tasks: not portable
|
||||
Root: HKCR; Subkey: ".zct"; ValueType: string; ValueName: ""; ValueData: "ZoiteChat.Theme"; Flags: uninsdeletevalue; Tasks: not portable
|
||||
Root: HKCR; Subkey: ".hct"; ValueType: string; ValueName: ""; ValueData: "ZoiteChat.Theme"; Flags: uninsdeletevalue; Tasks: not portable
|
||||
Root: HKCR; Subkey: "ZoiteChat.Theme"; ValueType: string; ValueName: ""; ValueData: "ZoiteChat Theme"; Flags: uninsdeletekey; Tasks: not portable
|
||||
Root: HKCR; Subkey: "ZoiteChat.Theme\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\zoitechat.exe,0"; Flags: uninsdeletevalue; Tasks: not portable
|
||||
Root: HKCR; Subkey: "ZoiteChat.Theme\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\zoitechat.exe"" ""%1"""; Flags: uninsdeletevalue; Tasks: not portable
|
||||
Root: HKCR; Subkey: "ZoiteChat.Theme\Application"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#ZOITECHAT_APPUSERMODELID}"; Flags: uninsdeletevalue; Tasks: not portable
|
||||
Root: HKCR; Subkey: "Applications\zoitechat.exe\Application"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#ZOITECHAT_APPUSERMODELID}"; Flags: uninsdeletevalue; Tasks: not portable
|
||||
|
||||
[Run]
|
||||
Filename: "{app}\zoitechat.exe"; Description: "Run ZoiteChat after closing the Wizard"; Flags: nowait postinstall skipifsilent
|
||||
@@ -192,15 +188,15 @@ Source: "zoitechat.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: lib
|
||||
Source: "zoitechat-text.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: xctext
|
||||
|
||||
[Icons]
|
||||
Name: "{group}\ZoiteChat"; Filename: "{app}\zoitechat.exe"; AppUserModelID: "{#ZOITECHAT_APPUSERMODELID}"; Tasks: not portable; Check: not WizardNoIcons
|
||||
Name: "{group}\ZoiteChat Safe Mode"; Filename: "{app}\zoitechat.exe"; Parameters: "--no-auto --no-plugins"; AppUserModelID: "{#ZOITECHAT_APPUSERMODELID}"; Tasks: not portable; Check: not WizardNoIcons
|
||||
Name: "{group}\ZoiteChat ChangeLog"; Filename: "{app}\changelog.url"; IconFilename: "{sys}\shell32.dll"; IconIndex: 165; AppUserModelID: "{#ZOITECHAT_APPUSERMODELID}"; Tasks: not portable; Check: not WizardNoIcons
|
||||
Name: "{group}\ZoiteChat ReadMe"; Filename: "{app}\readme.url"; IconFilename: "{sys}\shell32.dll"; IconIndex: 23; AppUserModelID: "{#ZOITECHAT_APPUSERMODELID}"; Tasks: not portable; Check: not WizardNoIcons
|
||||
Name: "{group}\ZoiteChat Config Folder"; Filename: "%APPDATA%\ZoiteChat\"; AppUserModelID: "{#ZOITECHAT_APPUSERMODELID}"; Tasks: not portable; Check: not WizardNoIcons
|
||||
Name: "{group}\ZoiteChat-Text"; Filename: "{app}\zoitechat-text.exe"; AppUserModelID: "{#ZOITECHAT_APPUSERMODELID}"; Components: xctext; Tasks: not portable; Check: not WizardNoIcons
|
||||
Name: "{group}\Uninstall ZoiteChat"; Filename: "{uninstallexe}"; AppUserModelID: "{#ZOITECHAT_APPUSERMODELID}"; Tasks: not portable; Check: not WizardNoIcons
|
||||
Name: "{commondesktop}\ZoiteChat"; Filename: "{app}\zoitechat.exe"; AppUserModelID: "{#ZOITECHAT_APPUSERMODELID}"; Components: icons\desktopicon; Tasks: not portable
|
||||
Name: "{commonappdata}\Microsoft\Internet Explorer\Quick Launch\ZoiteChat"; Filename: "{app}\zoitechat.exe"; AppUserModelID: "{#ZOITECHAT_APPUSERMODELID}"; Components: icons\quicklaunchicon; Tasks: not portable
|
||||
Name: "{group}\ZoiteChat"; Filename: "{app}\zoitechat.exe"; AppUserModelID: "ZoiteChat.Desktop.Notify"; Tasks: not portable; Check: not WizardNoIcons
|
||||
Name: "{group}\ZoiteChat Safe Mode"; Filename: "{app}\zoitechat.exe"; Parameters: "--no-auto --no-plugins"; Tasks: not portable; Check: not WizardNoIcons
|
||||
Name: "{group}\ZoiteChat ChangeLog"; Filename: "{app}\changelog.url"; IconFilename: "{sys}\shell32.dll"; IconIndex: 165; Tasks: not portable; Check: not WizardNoIcons
|
||||
Name: "{group}\ZoiteChat ReadMe"; Filename: "{app}\readme.url"; IconFilename: "{sys}\shell32.dll"; IconIndex: 23; Tasks: not portable; Check: not WizardNoIcons
|
||||
Name: "{group}\ZoiteChat Config Folder"; Filename: "%APPDATA%\ZoiteChat\"; Tasks: not portable; Check: not WizardNoIcons
|
||||
Name: "{group}\ZoiteChat-Text"; Filename: "{app}\zoitechat-text.exe"; Components: xctext; Tasks: not portable; Check: not WizardNoIcons
|
||||
Name: "{group}\Uninstall ZoiteChat"; Filename: "{uninstallexe}"; Tasks: not portable; Check: not WizardNoIcons
|
||||
Name: "{commondesktop}\ZoiteChat"; Filename: "{app}\zoitechat.exe"; AppUserModelID: "ZoiteChat.Desktop.Notify"; Components: icons\desktopicon; Tasks: not portable
|
||||
Name: "{commonappdata}\Microsoft\Internet Explorer\Quick Launch\ZoiteChat"; Filename: "{app}\zoitechat.exe"; Components: icons\quicklaunchicon; Tasks: not portable
|
||||
|
||||
[Messages]
|
||||
BeveledLabel= {#APPNAM}
|
||||
|
||||
@@ -128,7 +128,7 @@
|
||||
|
||||
<ArchiveDefs Condition="'$(ArchiveLib)'=='archive_static.lib' or '$(ArchiveLib)'=='libarchive_static.lib'">LIBARCHIVE_STATIC</ArchiveDefs>
|
||||
|
||||
<DepLibs>$(Gtk3Lib);$(Gdk3Lib);wininet.lib;winmm.lib;ws2_32.lib;advapi32.lib;atk-1.0.lib;gio-2.0.lib;gdk_pixbuf-2.0.lib;pangowin32-1.0.lib;pangocairo-1.0.lib;pango-1.0.lib;cairo.lib;gobject-2.0.lib;gmodule-2.0.lib;glib-2.0.lib;$(IntlLib);$(IconvLib);$(ZlibLib);$(Xml2Lib);$(JpegLib);$(PngLib);$(ArchiveLib);$(OpenSslLibs)</DepLibs>
|
||||
<DepLibs>$(Gtk3Lib);$(Gdk3Lib);wininet.lib;winmm.lib;ws2_32.lib;atk-1.0.lib;gio-2.0.lib;gdk_pixbuf-2.0.lib;pangowin32-1.0.lib;pangocairo-1.0.lib;pango-1.0.lib;cairo.lib;gobject-2.0.lib;gmodule-2.0.lib;glib-2.0.lib;$(IntlLib);$(IconvLib);$(ZlibLib);$(Xml2Lib);$(JpegLib);$(PngLib);$(ArchiveLib);$(OpenSslLibs)</DepLibs>
|
||||
|
||||
<DataDir>$(SolutionDir)..\data\\</DataDir>
|
||||
<ZoiteChatBuild>$(SolutionDir)..\..\zoitechat-build</ZoiteChatBuild>
|
||||
|
||||
Reference in New Issue
Block a user