Added SILC_MESSAGE_FLAG_UTF8 and implemented it. All messages
authorPekka Riikonen <priikone@silcnet.org>
Sun, 16 Jun 2002 09:38:09 +0000 (09:38 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sun, 16 Jun 2002 09:38:09 +0000 (09:38 +0000)
sent in Irssi SILC client are now UTF-8 encoded.  Will be
automatically decoded when received if terminal does not support
UTF-8.

CHANGES
TODO
apps/irssi/src/silc/core/client_ops.c
apps/irssi/src/silc/core/silc-channels.c
apps/irssi/src/silc/core/silc-servers.c
apps/irssi/src/silc/core/silc-servers.h
doc/draft-riikonen-silc-pp-06.nroff
lib/silccore/silcchannel.h

diff --git a/CHANGES b/CHANGES
index 64943042eba94e8cb83f1bfdc82e47868b940974..21346a55b4eb73939e329f23717bc3f52b274774 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,14 @@
+Sun Jun 16 11:49:45 EEST 2002 Pekka Riikonen <priikone@silcnet.org>
+
+       * Added SILC_MESSAGE_FLAG_UTF8 to the protocol specs and the
+         core library, and implemented it.  All textual messages SHOULD
+         use this flag and the message MUST be UTF-8 encoded.
+         All text messages sent by Irssi SILC client are now UTF-8
+         encoded (regardless whether the terminal supports UTF-8 or not).
+         Affected files are lib/silccore/silcchannel.h,
+         irssi/src/silc/core/silc-servers.c, silc-channels.c and
+         client_ops.c.
+
 Sat Jun 15 18:23:39 EEST 2002 Pekka Riikonen <priikone@silcnet.org>
 
        * Added lots of new statistics updating that was missing from
 Sat Jun 15 18:23:39 EEST 2002 Pekka Riikonen <priikone@silcnet.org>
 
        * Added lots of new statistics updating that was missing from
diff --git a/TODO b/TODO
index c09bd0be9bdd3c22f8d9d53a2b7711f03c08615a..b8cc7a4f4604042c1a3696b5d679a4fff78cd384 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,6 +1,9 @@
 TODO/bugs in Irssi SILC client
 ==============================
 
 TODO/bugs in Irssi SILC client
 ==============================
 
+ o Testing
+
+
 TODO/bugs In SILC Client Library
 ================================
 
 TODO/bugs In SILC Client Library
 ================================
 
index 7d53788f836631bc349bdb2ccf5d9dc89b0e946a..1651b20058013e9760f1e049164e7f39f1f5209f 100644 (file)
@@ -174,11 +174,32 @@ void silc_channel_message(SilcClient client, SilcClientConnection conn,
     printformat_module("fe-common/silc", server, channel->channel_name,
                       MSGLEVEL_NOTICES, SILCTXT_CHANNEL_NOTICE, 
                        nick == NULL ? "[<unknown>]" : nick->nick, message);
     printformat_module("fe-common/silc", server, channel->channel_name,
                       MSGLEVEL_NOTICES, SILCTXT_CHANNEL_NOTICE, 
                        nick == NULL ? "[<unknown>]" : nick->nick, message);
-  else
+  else {
+    if (flags & SILC_MESSAGE_FLAG_UTF8 && !silc_term_utf8()) {
+      char tmp[256], *cp, *dm = NULL;
+
+      memset(tmp, 0, sizeof(tmp));
+      cp = tmp;
+      if (message_len > sizeof(tmp) - 1) {
+       dm = silc_calloc(message_len + 1, sizeof(*dm));
+       cp = dm;
+      }
+
+      silc_utf8_decode(message, message_len, SILC_STRING_ASCII,
+                      cp, message_len);
+      signal_emit("message public", 6, server, cp,
+                 nick == NULL ? "[<unknown>]" : nick->nick,
+                 nick == NULL ? "" : nick->host == NULL ? "" : nick->host,
+                 chanrec->name, nick);
+      silc_free(dm);
+      return;
+    }
+
     signal_emit("message public", 6, server, message,
                nick == NULL ? "[<unknown>]" : nick->nick,
                nick == NULL ? "" : nick->host == NULL ? "" : nick->host,
                chanrec->name, nick);
     signal_emit("message public", 6, server, message,
                nick == NULL ? "[<unknown>]" : nick->nick,
                nick == NULL ? "" : nick->host == NULL ? "" : nick->host,
                chanrec->name, nick);
+  }
 }
 
 /* Private message to the client. The `sender' is the nickname of the
 }
 
 /* Private message to the client. The `sender' is the nickname of the
@@ -227,6 +248,25 @@ void silc_private_message(SilcClient client, SilcClientConnection conn,
   if (!message)
     return;
 
   if (!message)
     return;
 
+  if (flags & SILC_MESSAGE_FLAG_UTF8 && !silc_term_utf8()) {
+    char tmp[256], *cp, *dm = NULL;
+
+    memset(tmp, 0, sizeof(tmp));
+    cp = tmp;
+    if (message_len > sizeof(tmp) - 1) {
+      dm = silc_calloc(message_len + 1, sizeof(*dm));
+      cp = dm;
+    }
+
+    silc_utf8_decode(message, message_len, SILC_STRING_ASCII,
+                    cp, message_len);
+    signal_emit("message private", 4, server, cp,
+               sender->nickname ? sender->nickname : "[<unknown>]",
+               sender->username ? userhost : NULL);
+    silc_free(dm);
+    return;
+  }
+
   signal_emit("message private", 4, server, message,
              sender->nickname ? sender->nickname : "[<unknown>]",
              sender->username ? userhost : NULL);
   signal_emit("message private", 4, server, message,
              sender->nickname ? sender->nickname : "[<unknown>]",
              sender->username ? userhost : NULL);
index 3aab164ed7b2f5d7e9580f7473516b5a8201e3da..38cd2bcc448069101d0dd6dcde65406ffe982053 100644 (file)
@@ -173,6 +173,7 @@ static void command_me(const char *data, SILC_SERVER_REC *server,
   SILC_CHANNEL_REC *chanrec;
   char *tmpcmd = "ME", *tmp;
   SilcUInt32 argc = 0;
   SILC_CHANNEL_REC *chanrec;
   char *tmpcmd = "ME", *tmp;
   SilcUInt32 argc = 0;
+  unsigned char *message = NULL;
   unsigned char **argv;
   SilcUInt32 *argv_lens, *argv_types;
   int i;
   unsigned char **argv;
   SilcUInt32 *argv_lens, *argv_types;
   int i;
@@ -198,11 +199,21 @@ static void command_me(const char *data, SILC_SERVER_REC *server,
   if (chanrec == NULL) 
     cmd_return_error(CMDERR_CHAN_NOT_FOUND);
 
   if (chanrec == NULL) 
     cmd_return_error(CMDERR_CHAN_NOT_FOUND);
 
+  if (!silc_term_utf8()) {
+    int len = silc_utf8_encoded_len(argv[1], argv_lens[1], SILC_STRING_ASCII);
+    message = silc_calloc(len + 1, sizeof(*message));
+    g_return_if_fail(message != NULL);
+    silc_utf8_encode(argv[1], argv_lens[1], SILC_STRING_ASCII, message, len);
+  }
+
   /* Send the action message */
   silc_client_send_channel_message(silc_client, server->conn, 
                                   chanrec->entry, NULL,
   /* Send the action message */
   silc_client_send_channel_message(silc_client, server->conn, 
                                   chanrec->entry, NULL,
-                                  SILC_MESSAGE_FLAG_ACTION, 
-                                  argv[1], argv_lens[1], TRUE);
+                                  SILC_MESSAGE_FLAG_ACTION |
+                                  SILC_MESSAGE_FLAG_UTF8,
+                                  message ? message : argv[1],
+                                  message ? strlen(message) : argv_lens[1],
+                                  TRUE);
 
   printformat_module("fe-common/silc", server, chanrec->entry->channel_name,
                     MSGLEVEL_ACTIONS, SILCTXT_CHANNEL_OWNACTION, 
 
   printformat_module("fe-common/silc", server, chanrec->entry->channel_name,
                     MSGLEVEL_ACTIONS, SILCTXT_CHANNEL_OWNACTION, 
@@ -212,6 +223,7 @@ static void command_me(const char *data, SILC_SERVER_REC *server,
     silc_free(argv[i]);
   silc_free(argv_lens);
   silc_free(argv_types);
     silc_free(argv[i]);
   silc_free(argv_lens);
   silc_free(argv_types);
+  silc_free(message);
 }
 
 /* ACTION local command. Same as ME but takes the channel as mandatory
 }
 
 /* ACTION local command. Same as ME but takes the channel as mandatory
@@ -223,6 +235,7 @@ static void command_action(const char *data, SILC_SERVER_REC *server,
   SILC_CHANNEL_REC *chanrec;
   char *tmpcmd = "ME", *tmp;
   SilcUInt32 argc = 0;
   SILC_CHANNEL_REC *chanrec;
   char *tmpcmd = "ME", *tmp;
   SilcUInt32 argc = 0;
+  unsigned char *message = NULL;
   unsigned char **argv;
   SilcUInt32 *argv_lens, *argv_types;
   int i;
   unsigned char **argv;
   SilcUInt32 *argv_lens, *argv_types;
   int i;
@@ -247,11 +260,21 @@ static void command_action(const char *data, SILC_SERVER_REC *server,
   if (chanrec == NULL) 
     cmd_return_error(CMDERR_CHAN_NOT_FOUND);
 
   if (chanrec == NULL) 
     cmd_return_error(CMDERR_CHAN_NOT_FOUND);
 
+  if (!silc_term_utf8()) {
+    int len = silc_utf8_encoded_len(argv[2], argv_lens[2], SILC_STRING_ASCII);
+    message = silc_calloc(len + 1, sizeof(*message));
+    g_return_if_fail(message != NULL);
+    silc_utf8_encode(argv[2], argv_lens[2], SILC_STRING_ASCII, message, len);
+  }
+
   /* Send the action message */
   silc_client_send_channel_message(silc_client, server->conn, 
                                   chanrec->entry, NULL,
   /* Send the action message */
   silc_client_send_channel_message(silc_client, server->conn, 
                                   chanrec->entry, NULL,
-                                  SILC_MESSAGE_FLAG_ACTION, 
-                                  argv[2], argv_lens[2], TRUE);
+                                  SILC_MESSAGE_FLAG_ACTION |
+                                  SILC_MESSAGE_FLAG_UTF8,
+                                  message ? message : argv[2],
+                                  message ? strlen(message) : argv_lens[2],
+                                  TRUE);
 
   printformat_module("fe-common/silc", server, chanrec->entry->channel_name,
                     MSGLEVEL_ACTIONS, SILCTXT_CHANNEL_OWNACTION, 
 
   printformat_module("fe-common/silc", server, chanrec->entry->channel_name,
                     MSGLEVEL_ACTIONS, SILCTXT_CHANNEL_OWNACTION, 
@@ -261,6 +284,7 @@ static void command_action(const char *data, SILC_SERVER_REC *server,
     silc_free(argv[i]);
   silc_free(argv_lens);
   silc_free(argv_types);
     silc_free(argv[i]);
   silc_free(argv_lens);
   silc_free(argv_types);
+  silc_free(message);
 }
 
 /* NOTICE local command. */
 }
 
 /* NOTICE local command. */
@@ -271,6 +295,7 @@ static void command_notice(const char *data, SILC_SERVER_REC *server,
   SILC_CHANNEL_REC *chanrec;
   char *tmpcmd = "ME", *tmp;
   SilcUInt32 argc = 0;
   SILC_CHANNEL_REC *chanrec;
   char *tmpcmd = "ME", *tmp;
   SilcUInt32 argc = 0;
+  unsigned char *message = NULL;
   unsigned char **argv;
   SilcUInt32 *argv_lens, *argv_types;
   int i;
   unsigned char **argv;
   SilcUInt32 *argv_lens, *argv_types;
   int i;
@@ -295,11 +320,21 @@ static void command_notice(const char *data, SILC_SERVER_REC *server,
   if (chanrec == NULL) 
     cmd_return_error(CMDERR_CHAN_NOT_FOUND);
 
   if (chanrec == NULL) 
     cmd_return_error(CMDERR_CHAN_NOT_FOUND);
 
+  if (!silc_term_utf8()) {
+    int len = silc_utf8_encoded_len(argv[1], argv_lens[1], SILC_STRING_ASCII);
+    message = silc_calloc(len + 1, sizeof(*message));
+    g_return_if_fail(message != NULL);
+    silc_utf8_encode(argv[1], argv_lens[1], SILC_STRING_ASCII, message, len);
+  }
+
   /* Send the action message */
   silc_client_send_channel_message(silc_client, server->conn, 
                                   chanrec->entry, NULL,
   /* Send the action message */
   silc_client_send_channel_message(silc_client, server->conn, 
                                   chanrec->entry, NULL,
-                                  SILC_MESSAGE_FLAG_NOTICE, 
-                                  argv[1], argv_lens[1], TRUE);
+                                  SILC_MESSAGE_FLAG_NOTICE |
+                                  SILC_MESSAGE_FLAG_UTF8,
+                                  message ? message : argv[1],
+                                  message ? strlen(message) : argv_lens[1],
+                                  TRUE);
 
   printformat_module("fe-common/silc", server, chanrec->entry->channel_name,
                     MSGLEVEL_NOTICES, SILCTXT_CHANNEL_OWNNOTICE, 
 
   printformat_module("fe-common/silc", server, chanrec->entry->channel_name,
                     MSGLEVEL_NOTICES, SILCTXT_CHANNEL_OWNNOTICE, 
@@ -309,6 +344,7 @@ static void command_notice(const char *data, SILC_SERVER_REC *server,
     silc_free(argv[i]);
   silc_free(argv_lens);
   silc_free(argv_types);
     silc_free(argv[i]);
   silc_free(argv_lens);
   silc_free(argv_types);
+  silc_free(message);
 }
 
 /* AWAY local command.  Sends UMODE command that sets the SILC_UMODE_GONE
 }
 
 /* AWAY local command.  Sends UMODE command that sets the SILC_UMODE_GONE
index 089242715af34577d97b104ab85617306431be38..ae34c5c70806033c6c42adc0b82a09631fc49ae0 100644 (file)
@@ -62,7 +62,8 @@ static void silc_send_channel(SILC_SERVER_REC *server,
   }
 
   silc_client_send_channel_message(silc_client, server->conn, rec->entry, 
   }
 
   silc_client_send_channel_message(silc_client, server->conn, rec->entry, 
-                                  NULL, 0, msg, strlen(msg), TRUE);
+                                  NULL, SILC_MESSAGE_FLAG_UTF8,
+                                  msg, strlen(msg), TRUE);
 }
 
 typedef struct {
 }
 
 typedef struct {
@@ -119,7 +120,8 @@ static void silc_send_msg_clients(SilcClient client,
     }
 
     /* Send the private message */
     }
 
     /* Send the private message */
-    silc_client_send_private_message(client, conn, target, 0,
+    silc_client_send_private_message(client, conn, target, 
+                                    SILC_MESSAGE_FLAG_UTF8,
                                     rec->msg, strlen(rec->msg),
                                     TRUE);
   }
                                     rec->msg, strlen(rec->msg),
                                     TRUE);
   }
@@ -162,7 +164,8 @@ static void silc_send_msg(SILC_SERVER_REC *server, char *nick, char *msg)
   /* Send the private message directly */
   silc_free(nickname);
   silc_client_send_private_message(silc_client, server->conn, 
   /* Send the private message directly */
   silc_free(nickname);
   silc_client_send_private_message(silc_client, server->conn, 
-                                  clients[0], 0, msg, strlen(msg), TRUE);
+                                  clients[0], SILC_MESSAGE_FLAG_UTF8,
+                                  msg, strlen(msg), TRUE);
 }
 
 static int isnickflag_func(char flag)
 }
 
 static int isnickflag_func(char flag)
@@ -183,14 +186,26 @@ const char *get_nick_flags(void)
 static void send_message(SILC_SERVER_REC *server, char *target,
                         char *msg, int target_type)
 {
 static void send_message(SILC_SERVER_REC *server, char *target,
                         char *msg, int target_type)
 {
+  char *message = NULL;
+  int len;
+
   g_return_if_fail(server != NULL);
   g_return_if_fail(target != NULL);
   g_return_if_fail(msg != NULL);
 
   g_return_if_fail(server != NULL);
   g_return_if_fail(target != NULL);
   g_return_if_fail(msg != NULL);
 
+  if (!silc_term_utf8()) {
+    len = silc_utf8_encoded_len(msg, strlen(msg), SILC_STRING_ASCII);
+    message = silc_calloc(len + 1, sizeof(*message));
+    g_return_if_fail(message != NULL);
+    silc_utf8_encode(msg, strlen(msg), SILC_STRING_ASCII, message, len);
+  }
+
   if (target_type == SEND_TARGET_CHANNEL)
   if (target_type == SEND_TARGET_CHANNEL)
-    silc_send_channel(server, target, msg);
+    silc_send_channel(server, target, message ? message : msg);
   else
   else
-    silc_send_msg(server, target, msg);
+    silc_send_msg(server, target, message ? message : msg);
+
+  silc_free(message);
 }
 
 static void sig_connected(SILC_SERVER_REC *server)
 }
 
 static void sig_connected(SILC_SERVER_REC *server)
@@ -253,8 +268,7 @@ static void sig_disconnected(SILC_SERVER_REC *server)
   }
 }
 
   }
 }
 
-SILC_SERVER_REC *silc_server_connect(SILC_SERVER_CONNECT_REC *conn)
-{
+SILC_SERVER_REC *silc_server_connect(SILC_SERVER_CONNECT_REC *conn){
   SILC_SERVER_REC *server;
 
   g_return_val_if_fail(IS_SILC_SERVER_CONNECT(conn), NULL);
   SILC_SERVER_REC *server;
 
   g_return_val_if_fail(IS_SILC_SERVER_CONNECT(conn), NULL);
@@ -952,3 +966,13 @@ void silc_server_free_ftp(SILC_SERVER_REC *server,
     }
   }
 }
     }
   }
 }
+
+bool silc_term_utf8(void)
+{
+  const char *str;
+  str = settings_get_str("term_type");
+  if (str)
+    if (g_strcasecmp(str, "utf-8") == 0)
+      return TRUE;
+  return FALSE;
+}
index 965e1f9661b3ba0d7025a05848d4d157b0065d8b..7b319766ee7cfbac09381fc600591e62a1540e56 100644 (file)
@@ -70,5 +70,6 @@ void silc_server_init(void);
 void silc_server_deinit(void);
 void silc_server_free_ftp(SILC_SERVER_REC *server,
                          SilcClientEntry client_entry);
 void silc_server_deinit(void);
 void silc_server_free_ftp(SILC_SERVER_REC *server,
                          SilcClientEntry client_entry);
+bool silc_term_utf8(void);
 
 #endif
 
 #endif
index e66c6a4e262f82ab65485e0e28b6551b1778de6b..5a7d7edfeb20d774b56adada490abb3061a9d9a5 100644 (file)
@@ -1720,7 +1720,14 @@ o Message Flags (2 bytes) - Includes the Message Flags of
           document should define how this flag is interpreted
           and define any associated payloads.
 
           document should define how this flag is interpreted
           and define any associated payloads.
 
-  0x0100 - 0x0800 RESERVED
+  0x0100  SILC_MESSAGE_FLAG_UTF8
+
+          This flag indicates that the message is UTF-8 encoded
+          textual message.  When sending text messages this
+          flag SHOULD be used.  When this flag is used the text
+          sent as message MUST be UTF-8 encoded.
+
+  0x0200 - 0x0800 RESERVED
 
           Reserved for future flags
 
 
           Reserved for future flags
 
index 788ef384cbfdbf6216eb17c0faf793e53a7a85f4..fa471a4263e41986c73e3fa0e6ba9e63afcb46bf 100644 (file)
@@ -104,17 +104,18 @@ typedef struct SilcChannelKeyPayloadStruct *SilcChannelKeyPayload;
 typedef SilcUInt16 SilcMessageFlags;
 
 /* The message flags (shared by both channel and private messages) */
 typedef SilcUInt16 SilcMessageFlags;
 
 /* The message flags (shared by both channel and private messages) */
-#define SILC_MESSAGE_FLAG_NONE        0x0000
-#define SILC_MESSAGE_FLAG_AUTOREPLY   0x0001
-#define SILC_MESSAGE_FLAG_NOREPLY     0x0002
-#define SILC_MESSAGE_FLAG_ACTION      0x0004
-#define SILC_MESSAGE_FLAG_NOTICE      0x0008
-#define SILC_MESSAGE_FLAG_REQUEST     0x0010
-#define SILC_MESSAGE_FLAG_SIGNED      0x0020
-#define SILC_MESSAGE_FLAG_REPLY       0x0040
-#define SILC_MESSAGE_FLAG_DATA        0x0080
-#define SILC_MESSAGE_FLAG_RESERVED    0x0100 /* to 0x0800 */
-#define SILC_MESSAGE_FLAG_PRIVATE     0x1000 /* to 0x8000 */
+#define SILC_MESSAGE_FLAG_NONE        0x0000      /* No flags */
+#define SILC_MESSAGE_FLAG_AUTOREPLY   0x0001     /* Automatically replied */
+#define SILC_MESSAGE_FLAG_NOREPLY     0x0002     /* Send no reply to this */
+#define SILC_MESSAGE_FLAG_ACTION      0x0004     /* Action message */
+#define SILC_MESSAGE_FLAG_NOTICE      0x0008     /* Notice message */
+#define SILC_MESSAGE_FLAG_REQUEST     0x0010     /* A request */
+#define SILC_MESSAGE_FLAG_SIGNED      0x0020     /* Message is signed */
+#define SILC_MESSAGE_FLAG_REPLY       0x0040     /* A reply */
+#define SILC_MESSAGE_FLAG_DATA        0x0080     /* MIME object */
+#define SILC_MESSAGE_FLAG_UTF8        0x0100     /* UTF-8 string */
+#define SILC_MESSAGE_FLAG_RESERVED    0x0200     /* to 0x0800 */
+#define SILC_MESSAGE_FLAG_PRIVATE     0x1000     /* to 0x8000 */
 /***/
 
 /* Prototypes */
 /***/
 
 /* Prototypes */