Found in "gnokii-working" directory, some November-patches version
[gnokii.git] / xgnokii / xgnokii_sms.c
index b310434..185cc3b 100644 (file)
@@ -1,7 +1,5 @@
 /*
 
-  $Id$
-
   X G N O K I I
 
   A Linux/Unix GUI for Nokia mobile phones.
@@ -10,6 +8,9 @@
 
   Released under the terms of the GNU GPL, see file COPYING for more details.
 
+  Last modification: Sun Apr 30 2000
+  Modified by Jan Derfinak
+
 */
 #include <unistd.h>
 #include <locale.h>
@@ -46,6 +47,7 @@ typedef struct {
   gint  validity;
   gint  class;
   gchar sender[GSM_MAX_SENDER_LENGTH + 1];
+  gchar destination[GSM_MAX_DESTINATION_LENGTH + 1];
 } MessagePointers;
 
 typedef struct {
@@ -209,9 +211,9 @@ static void InsertInboxElement (gpointer d, gpointer userData)
 {
   GSM_SMSMessage *data = (GSM_SMSMessage *) d;
   MessagePointers *msgPtrs;
-  SMS_DateTime *dt;
+  GSM_DateTime *dt;
 
-  if (data->Type == SMS_Deliver || data->Type == SMS_Delivery_Report)
+  if (data->Type == GST_MT || data->Type == GST_DR)
   {
 /*    if (data->Type == GST_MT && data->UDHType == GSM_ConcatenatedMessages)
     {
@@ -230,7 +232,7 @@ static void InsertInboxElement (gpointer d, gpointer userData)
     {
       gchar *row[4];
 
-      if (data->Type == SMS_Delivery_Report)
+      if (data->Type == GST_DR)
       {
         row[0] = g_strdup (_("report"));
         dt = &(data->SMSCTime);
@@ -256,19 +258,20 @@ static void InsertInboxElement (gpointer d, gpointer userData)
                                   dt->Day, dt->Month, dt->Year,
                                   dt->Hour, dt->Minute, dt->Second);
 
-      row[2] = GUI_GetName (data->RemoteNumber.number);
+      row[2] = GUI_GetName (data->Sender);
       if (row[2] == NULL)
-        row[2] = data->RemoteNumber.number;
+        row[2] = data->Sender;
       row[3] = data->MessageText;
 
       gtk_clist_append (GTK_CLIST (SMS.smsClist), row);
       msgPtrs = (MessagePointers *) g_malloc (sizeof (MessagePointers));
       msgPtrs->count = msgPtrs->number = 1;
-      msgPtrs->validity = data->Validity.u.Relative;
-      //      msgPtrs->class = data->Class;
-      strcpy (msgPtrs->sender, data->RemoteNumber.number);
+      msgPtrs->validity = data->Validity;
+      msgPtrs->class = data->Class;
+      strcpy (msgPtrs->sender, data->Sender);
+      msgPtrs->destination[0]='\0';
       msgPtrs->msgPtr = (gint *) g_malloc (sizeof (gint));
-      *(msgPtrs->msgPtr) = (int)data->Number;
+      *(msgPtrs->msgPtr) = data->MessageNumber;
       gtk_clist_set_row_data_full (GTK_CLIST (SMS.smsClist), SMS.row_i++,
                                    msgPtrs, DestroyMsgPtrs);
       g_free (row[0]);
@@ -281,8 +284,8 @@ static void InsertInboxElement (gpointer d, gpointer userData)
 static inline void RefreshInbox (void)
 {
   gtk_clist_freeze (GTK_CLIST (SMS.smsClist));
-
   gtk_clist_clear (GTK_CLIST (SMS.smsClist));
+  gtk_clist_set_column_title(GTK_CLIST (SMS.smsClist), 2/*column*/, _("Sender"));
 
   SMS.row_i = 0;
   g_slist_foreach (phoneMonitor.sms.messages, InsertInboxElement, (gpointer) NULL);
@@ -297,7 +300,7 @@ static void InsertOutboxElement (gpointer d, gpointer userData)
   GSM_SMSMessage *data = (GSM_SMSMessage *) d;
   MessagePointers *msgPtrs;
 
-  if (data->Type == SMS_Submit)
+  if (data->Type == GST_MO)
   {
     gchar *row[4];
 
@@ -306,17 +309,23 @@ static void InsertOutboxElement (gpointer d, gpointer userData)
     else
       row[0] = g_strdup (_("unsent"));
 
-    row[1] = row[2] = g_strdup ("");
+    row[1] = g_strdup ("");    /* time */
+
+    row[2] = GUI_GetName (data->Destination);
+    if (row[2] == NULL)
+      row[2] = data->Destination;
+
     row[3] = data->MessageText;
 
     gtk_clist_append( GTK_CLIST (SMS.smsClist), row);
     msgPtrs = (MessagePointers *) g_malloc (sizeof (MessagePointers));
     msgPtrs->count = msgPtrs->number = 1;
-    msgPtrs->validity = data->Validity.u.Relative;
-    //    msgPtrs->class = data->Class;
-    strcpy (msgPtrs->sender, data->RemoteNumber.number);
+    msgPtrs->validity = data->Validity;
+    msgPtrs->class = data->Class;
+    msgPtrs->sender[0]='\0';
+    strcpy (msgPtrs->destination, data->Destination);
     msgPtrs->msgPtr = (gint *) g_malloc (sizeof (gint));
-    *(msgPtrs->msgPtr) = (int)data->Number;
+    *(msgPtrs->msgPtr) = data->MessageNumber;
     gtk_clist_set_row_data_full (GTK_CLIST (SMS.smsClist), SMS.row_i++,
                                  msgPtrs, DestroyMsgPtrs);
     g_free (row[0]);
@@ -329,6 +338,7 @@ static inline void RefreshOutbox (void)
 {
   gtk_clist_freeze (GTK_CLIST (SMS.smsClist));
   gtk_clist_clear (GTK_CLIST (SMS.smsClist));
+  gtk_clist_set_column_title(GTK_CLIST (SMS.smsClist), 2/*column*/, _("Destination"));
 
   SMS.row_i = 0;
   g_slist_foreach (phoneMonitor.sms.messages, InsertOutboxElement, (gpointer) NULL);
@@ -372,7 +382,7 @@ static void ClickEntry (GtkWidget      *clist,
   gtk_text_forward_delete (GTK_TEXT (SMS.smsText), gtk_text_get_length (GTK_TEXT (SMS.smsText)));
 
   gtk_text_insert (GTK_TEXT (SMS.smsText), NULL, &(SMS.colour), NULL,
-                   _("From: "), -1);
+                   (SMS.currentBox ? _("To: ") : _("From: ")), -1);
   gtk_clist_get_text (GTK_CLIST (clist), row, 2, &buf);
   gtk_text_insert (GTK_TEXT (SMS.smsText), NULL, &(SMS.smsText->style->black), NULL,
                    buf, -1);
@@ -422,15 +432,13 @@ static void OkDeleteSMSDialog (GtkWidget *widget, gpointer data)
     sel = sel->next;
     for (count = 0; count < ((MessagePointers *) gtk_clist_get_row_data (GTK_CLIST (SMS.smsClist), row))->count; count++)
     {
-      int number;
       message = (GSM_SMSMessage *) g_malloc (sizeof (GSM_SMSMessage));
-      number = *(((MessagePointers *) gtk_clist_get_row_data (GTK_CLIST (SMS.smsClist), row))->msgPtr + count);
-      if (number == -1)
+      message->Location = *(((MessagePointers *) gtk_clist_get_row_data (GTK_CLIST (SMS.smsClist), row))->msgPtr + count);
+      if (message->Location == -1)
       {
         g_free (message);
         continue;
       }
-      message->Number = number;
       message->MemoryType = GMT_SM;
 
       e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent));
@@ -900,6 +908,7 @@ static void ShowSelectContactsDialog (void)
                       GTK_SIGNAL_FUNC (CancelSelectContactDialog), (gpointer) r);
 }
 
+typedef gint (*SaveSendSMSCore_func)(GSM_SMSMessage *sms);
 
 static gint SendSMSCore (GSM_SMSMessage *sms)
 {
@@ -917,7 +926,7 @@ static gint SendSMSCore (GSM_SMSMessage *sms)
 
 #ifdef XDEBUG
   g_print ("Address: %s\nText: %s\nDelivery report: %d\nSMS Center: %d\n",
-           sms->RemoteNumber.number,
+           sms->Destination,
            sms->MessageText,
            GTK_TOGGLE_BUTTON (sendSMS.report)->active,
            sendSMS.center);
@@ -929,30 +938,73 @@ static gint SendSMSCore (GSM_SMSMessage *sms)
   if (error != GE_SMSSENDOK)
   {
     gchar *buf = g_strdup_printf (_("SMS send to %s failed\n(error=%d)"),
-                                  sms->RemoteNumber.number, error);
+                                  sms->Destination, error);
     gtk_label_set_text (GTK_LABEL(errorDialog.text), buf);
     gtk_widget_show (errorDialog.dialog);
     g_free (buf);
   }
   else
-    g_print ("Message sent to: %s\n", sms->RemoteNumber.number);
+    g_print ("Message sent to: %s\n", sms->Destination);
 
   return (error);
 }
 
+static gint SaveSMSCore (GSM_SMSMessage *sms)
+{
+  GSM_Error error;
+  PhoneEvent *e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent));
+  D_SMSMessage *m = (D_SMSMessage *) g_malloc (sizeof (D_SMSMessage));
+  
+  /* FIXME: Give user a choice of choosing target memory type, currently
+   * we implicitely always force SIM storage.
+   */
+  sms->MemoryType = GMT_SM;
+  
+  m->sms = sms;
+  e->event = Event_SaveSMSMessage;
+  e->data = m;
+  GUI_InsertEvent (e);
+  pthread_mutex_lock (&saveSMSMutex);
+  pthread_cond_wait (&saveSMSCond, &saveSMSMutex);
+  pthread_mutex_unlock (&saveSMSMutex);
+
+#ifdef XDEBUG
+  g_print ("Address: %s\nText: %s\nDelivery report: %d\nSMS Center: %d\n",
+           sms->Destination,
+           sms->MessageText,
+           GTK_TOGGLE_BUTTON (sendSMS.report)->active,
+           sendSMS.center);
+#endif
+
+  error = m->status;
+  g_free (m);
 
-static void SendSMS (void)
+  if (error != GE_NONE)
+  {
+    gchar *buf = g_strdup_printf (_("SMS save of message to %s failed\n(error=%d)"),
+                                  sms->Destination, error);
+    gtk_label_set_text (GTK_LABEL(errorDialog.text), buf);
+    gtk_widget_show (errorDialog.dialog);
+    g_free (buf);
+  }
+  else
+    g_print ("Message saved, destination to: %s\n", sms->Destination);
+
+  return (error);
+}
+
+static void SaveSendSMS (SaveSendSMSCore_func corefunc)
 {
   GSM_SMSMessage sms;
   AddressPar aps;
-  char udh[256];
   GSList *r;
   gchar *text, *number;
   gchar **addresses;
   gchar *buf;
-  gint offset, nr_msg, l;
+  gint l;
   gint longSMS;
-  register gint i = 0, j;
+  register gint i = 0;
+  GSM_Deconcatenate_state SMS_Deconcatenate_state;
 
   if (CheckAddressMain ())
   {
@@ -984,119 +1036,39 @@ static void SendSMS (void)
     sms.MessageCenter.No = 0;
 
     if (GTK_TOGGLE_BUTTON (sendSMS.report)->active)
-      sms.Report = true;
+      sms.Type = GST_DR;
     else
-      sms.Report = false;
-    sms.Type = SMS_Submit;
-
-    sms.DCS.Type = SMS_GeneralDataCoding;
-    sms.DCS.u.General.Compressed = false;
-    sms.DCS.u.General.Alphabet = SMS_DefaultAlphabet;
-    sms.DCS.u.General.Class = 0;
-    sms.MessageCenter.No = 1;
-    sms.Validity.VPF = SMS_RelativeFormat;
-    sms.Validity.u.Relative = sms.MessageCenter.Validity; /* 4320 minutes == 72 hours */
-    sms.UDH_No = 0;
-
-    strncpy (sms.RemoteNumber.number, number, GSM_MAX_DESTINATION_LENGTH + 1);
-    sms.RemoteNumber.number[GSM_MAX_DESTINATION_LENGTH] = '\0';
-
-    if (l > GSM_MAX_SMS_LENGTH)
-    {
-      if (longSMS)
-      {
-        sms.UDH[0].Type = SMS_ConcatenatedMessages;
-        nr_msg = ((l - 1) / 153) + 1;
-        udh[0] = 0x05; // UDH length
-        udh[1] = 0x00; // concatenated messages (IEI)
-        udh[2] = 0x03; // IEI data length
-        udh[3] = 0x01; // reference number
-        udh[4] = nr_msg;       // number of messages
-        udh[5] = 0x00; // message reference number
-        offset = 6;
-
-        for (j = 0; j < nr_msg; j++)
-        {
-          udh[5] = j + 1;
-
-          memcpy(sms.MessageText,udh,offset);
-          strncpy (sms.MessageText+offset, text + (j * 153), 153);
-          sms.MessageText[153] = '\0';
-
-          buf = g_strdup_printf (_("Sending SMS to %s (%d/%d) ...\n"),
-                                 sms.RemoteNumber.number, j + 1, nr_msg);
-          gtk_label_set_text (GTK_LABEL (infoDialog.text), buf);
-          gtk_widget_show_now (infoDialog.dialog);
-          g_free (buf);
-          GUI_Refresh ();
-
-          if (SendSMSCore (&sms) != GE_SMSSENDOK)
-          {
-            gtk_widget_hide (infoDialog.dialog);
-            GUI_Refresh ();
-            break;
-          }
-
-          gtk_widget_hide (infoDialog.dialog);
-          GUI_Refresh ();
-
-          sleep (1);
-        }
-      }
-      else
-      {
-        sms.UDH_Length = 0;
-        nr_msg = ((l - 1) / 153) + 1;
-        if (nr_msg > 99) // We have place only for 99 messages in header.
-          nr_msg = 99;
-        for (j = 0; j < nr_msg; j++)
-        {
-          gchar header[8];
+      sms.Type = GST_MO;
 
-          g_snprintf (header, 8, "%2d/%-2d: ", j + 1, nr_msg);
-          header[7] = '\0';
+    sms.Class = -1;
+    sms.Compression = false;
+    sms.EightBit = false;
+    sms.Validity = sms.MessageCenter.Validity;
+    sms.UDHPresent = false;
 
-          strcpy (sms.MessageText, header);
-          strncat (sms.MessageText, text + (j * 153), 153);
-          sms.MessageText[160] = '\0';
+    strncpy (sms.Destination, number, GSM_MAX_DESTINATION_LENGTH + 1);
+    sms.Destination[GSM_MAX_DESTINATION_LENGTH] = '\0';
 
-          buf = g_strdup_printf (_("Sending SMS to %s (%d/%d) ...\n"),
-                                 sms.RemoteNumber.number, j + 1, nr_msg);
-          gtk_label_set_text (GTK_LABEL (infoDialog.text), buf);
-          gtk_widget_show_now (infoDialog.dialog);
-          g_free (buf);
-          GUI_Refresh ();
+    buf = g_strdup_printf ((corefunc==SendSMSCore ? _("Sending SMS to %s ...\n") : _("Saving SMS to %s ...\n")),
+           sms.Destination);
+    gtk_label_set_text (GTK_LABEL (infoDialog.text), buf);
+    gtk_widget_show_now (infoDialog.dialog);
+    g_free (buf);
+    GUI_Refresh ();
 
-          if (SendSMSCore (&sms) != GE_SMSSENDOK)
-          {
-            gtk_widget_hide (infoDialog.dialog);
-            GUI_Refresh ();
-            break;
-          }
+    SMS_Deconcatenate_state.first=true;
+    while (SMS_Deconcatenate(&SMS_Deconcatenate_state,&sms,text,l,longSMS)) {
 
-          gtk_widget_hide (infoDialog.dialog);
-          GUI_Refresh ();
+           (void) (*corefunc)(&sms);   /* errors ignored, ugh */
 
-          sleep (1);
-        }
-      }
+           /* Here the sleep have no meaning.
+            * If it is required by some backend phone driver, it should be done THERE!
+            */
+           /* sleep(1); */
     }
-    else
-    {
-      sms.UDH_Length = 0;
-      strncpy (sms.MessageText, text, GSM_MAX_SMS_LENGTH + 1);
-      sms.MessageText[GSM_MAX_SMS_LENGTH] = '\0';
 
-      buf = g_strdup_printf (_("Sending SMS to %s ...\n"), sms.RemoteNumber.number);
-      gtk_label_set_text (GTK_LABEL (infoDialog.text), buf);
-      gtk_widget_show_now (infoDialog.dialog);
-      g_free (buf);
-      GUI_Refresh ();
-
-      (void) SendSMSCore (&sms);
-      gtk_widget_hide (infoDialog.dialog);
-      GUI_Refresh ();
-    }
+    gtk_widget_hide (infoDialog.dialog);
+    GUI_Refresh ();
 
     i++;
   }
@@ -1106,11 +1078,20 @@ static void SendSMS (void)
   g_free (text);
 }
 
+static void SendSMS (void)
+{
+  SaveSendSMS(SendSMSCore);
+}
+
+static void SaveSMS (void)
+{
+  SaveSendSMS(SaveSMSCore);
+}
 
 static GtkItemFactoryEntry send_menu_items[] = {
   { NULL,              NULL,           NULL,           0, "<Branch>"},
   { NULL,              "<control>X",   SendSMS,        0, NULL},
-  { NULL,              "<control>S",   NULL,           0, NULL},
+  { NULL,              "<control>S",   SaveSMS,        0, NULL},
   { NULL,              NULL,           NULL,           0, "<Separator>"},
   { NULL,              "<control>N",   CheckAddress,   0, NULL},
   { NULL,              "<control>C",   ShowSelectContactsDialog, 0, NULL},
@@ -1196,7 +1177,7 @@ static void CreateSMSSendWindow (void)
   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("Save message to outbox"), NULL,
                            NewPixmap(Send_xpm, GUI_SMSWindow->window,
                            &GUI_SMSWindow->style->bg[GTK_STATE_NORMAL]),
-                           (GtkSignalFunc) NULL, NULL);
+                           (GtkSignalFunc) SaveSMS, NULL);
 
   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
 
@@ -1366,7 +1347,7 @@ static void ForwardSMS (void)
 /*
 static inline gint CompareSMSMessageLocation (gconstpointer a, gconstpointer b)
 {
-  return !(((GSM_SMSMessage *) a)->Number == ((GSM_SMSMessage *) b)->Number);
+  return !(((GSM_SMSMessage *) a)->Location == ((GSM_SMSMessage *) b)->Location);
 }
 */
 
@@ -1376,6 +1357,7 @@ static void ReplySMS (void)
   gchar *buf;
 //  GSList *r;
 //  GSM_SMSMessage msg;
+  MessagePointers *msgPtrs;
 
   if (GTK_CLIST (SMS.smsClist)->selection == NULL)
     return;
@@ -1398,14 +1380,20 @@ static void ReplySMS (void)
 
   gtk_text_thaw (GTK_TEXT (sendSMS.smsSendText));
 
-  //msg.Number = *(((MessagePointers *) gtk_clist_get_row_data(GTK_CLIST (SMS.smsClist),
+  //msg.Location = *(((MessagePointers *) gtk_clist_get_row_data(GTK_CLIST (SMS.smsClist),
   //               GPOINTER_TO_INT (GTK_CLIST (SMS.smsClist)->selection->data)))->msgPtr);
 
   //r = g_slist_find_custom (SMS.messages, &msg, CompareSMSMessageLocation);
   //if (r)
-  gtk_entry_set_text (GTK_ENTRY (sendSMS.addr),
-                      ((MessagePointers *) gtk_clist_get_row_data(GTK_CLIST (SMS.smsClist),
-                      GPOINTER_TO_INT (GTK_CLIST (SMS.smsClist)->selection->data)))->sender);
+  msgPtrs = ((MessagePointers *) gtk_clist_get_row_data(GTK_CLIST (SMS.smsClist),
+               GPOINTER_TO_INT (GTK_CLIST (SMS.smsClist)->selection->data)));
+
+  /* We don't have GSM_SMSMessageType stored in MessagePointers so we just
+   * look at both the "sender" and "destination", shouldn't matter.
+   * Anyway to "Reply" to Outbox message is a bit weird, the icon/menu should
+   * be automatically changed when switched to the Outbox mode. Not my business.
+   */
+  gtk_entry_set_text (GTK_ENTRY (sendSMS.addr), (msgPtrs->sender[0] ? msgPtrs->sender : msgPtrs->destination));
 
   CheckAddressMain ();
   RefreshSMSStatus ();