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
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
 ==============================
 
+ o Testing
+
+
 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);
-  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);
+  }
 }
 
 /* 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 (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);
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;
+  unsigned char *message = NULL;
   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 (!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,
-                                  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, 
@@ -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(message);
 }
 
 /* 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;
+  unsigned char *message = NULL;
   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 (!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,
-                                  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, 
@@ -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(message);
 }
 
 /* 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;
+  unsigned char *message = NULL;
   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 (!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,
-                                  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, 
@@ -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(message);
 }
 
 /* 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, 
-                                  NULL, 0, msg, strlen(msg), TRUE);
+                                  NULL, SILC_MESSAGE_FLAG_UTF8,
+                                  msg, strlen(msg), TRUE);
 }
 
 typedef struct {
@@ -119,7 +120,8 @@ static void silc_send_msg_clients(SilcClient client,
     }
 
     /* 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);
   }
@@ -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, 
-                                  clients[0], 0, msg, strlen(msg), TRUE);
+                                  clients[0], SILC_MESSAGE_FLAG_UTF8,
+                                  msg, strlen(msg), TRUE);
 }
 
 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)
 {
+  char *message = NULL;
+  int len;
+
   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)
-    silc_send_channel(server, target, msg);
+    silc_send_channel(server, target, message ? message : msg);
   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)
@@ -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);
@@ -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);
+bool silc_term_utf8(void);
 
 #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.
 
-  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
 
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) */
-#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 */