summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data.c95
-rw-r--r--data.h38
-rw-r--r--gtk.c39
-rw-r--r--gui.h13
-rw-r--r--limox.c19
-rw-r--r--limox.h5
6 files changed, 133 insertions, 76 deletions
diff --git a/data.c b/data.c
index c0a0592..afa4616 100644
--- a/data.c
+++ b/data.c
@@ -5,36 +5,34 @@
#include <stdio.h>
#include "gui.h"
+#include "data.h"
-// https://www.rfc-editor.org/rfc/rfc6121#section-2.1.2.5
-typedef enum {
- SUB_NONE,
- SUB_TO,
- SUB_FROM,
- SUB_BOTH
-} subscription_t;
+static roster_item_t* roster = NULL;
-typedef struct _roster_item_t {
- const char* name;
- const char* jid;
- subscription_t sub;
- void* widget; // the roster item in the contact list view
- void* page_widget; // the chat page corresponding to this roster item
- struct _roster_item_t* next;
-} roster_item_t;
+void data_add_roster_item(const char* jid, const char* subscription,
+ const char* name) {
-// the RAM-stored data payload
-static roster_item_t* roster = NULL;
+ // FIXME check if roster item already exists and handle updates
+ // allocate datastructures
+ roster_item_t* item = malloc(sizeof(roster_item_t));
+ chat_t* chat = malloc(sizeof(chat_t));
-void add_roster_item(const char* jid, const char* subscription, const char* name) {
+ // initialize chat
+ chat->messages = NULL;
+ gui_add_chat_widget(chat);
- // parse roster item
- roster_item_t* item = malloc(sizeof(roster_item_t));
- item->name = name;
- item->jid = jid;
+ // initialize roster item
+ if (name == NULL) {
+ item->name = NULL;
+ } else {
+ item->name = malloc(sizeof(char)*strlen(name));
+ strcpy(item->name, name);
+ }
+ item->jid = malloc(sizeof(char)*strlen(jid));
+ strcpy(item->jid, jid);
if (strcmp(subscription, "none") == 0) {
item->sub = SUB_NONE;
} else if (strcmp(subscription, "to") == 0) {
@@ -47,7 +45,9 @@ void add_roster_item(const char* jid, const char* subscription, const char* name
printf("Invalid subscription '%s'!\n", subscription);
return;
}
+ item->chat = chat;
item->next = NULL;
+ gui_add_roster_item_widget(item);
// add item to roster datastructure
if (roster == NULL) {
@@ -59,29 +59,40 @@ void add_roster_item(const char* jid, const char* subscription, const char* name
current->next = item;
}
- // notify GUI
- item->widget = gui_add_roster_item(jid, subscription, name);
- item->page_widget = gui_add_chat();
-
}
-void* data_get_chat_page(void* roster_item_widget) {
-
- if (roster == NULL) {
- printf("Empty roster!\n");
- exit(1);
- } else {
- roster_item_t* current = roster;
- while (1) {
- if (current->widget == roster_item_widget) {
- return current->page_widget;
- }
- if (current->next == NULL) {
- printf("Could not find matching roster item!\n");
- exit(1);
- }
- current = current->next;
+void data_add_incoming_message(const char* sender_jid, const char* content) {
+
+ // find correct chat
+ chat_t* chat = NULL;
+ roster_item_t* i;
+ int bare_len; // length of bare JID
+ for (i = roster; i != NULL; i=i->next) {
+ bare_len = strlen(i->jid);
+ if (strncmp(i->jid, sender_jid, bare_len) == 0) {
+ chat = i->chat;
+ break;
}
}
+ if (chat == NULL) {
+ printf("Could not find chat for message from '%s'!\n", sender_jid);
+ return;
+ }
+
+ // initialize message_t
+ message_t* msg = malloc(sizeof(message_t));
+ msg->sender_jid = malloc(sizeof(char)*strlen(sender_jid));
+ strcpy(msg->sender_jid, sender_jid);
+ msg->content = malloc(sizeof(char)*strlen(content));
+ strcpy(msg->content, content);
+ msg->next = NULL;
+ gui_add_message_widget(msg, i->chat);
+
+ // find pointer to next message of chat
+ message_t* m;
+ for (m = chat->messages; m != NULL; m=m->next);
+
+ // append message to chat
+ m = msg;
}
diff --git a/data.h b/data.h
index 6fabbe6..6b6e936 100644
--- a/data.h
+++ b/data.h
@@ -1,2 +1,36 @@
-void add_roster_item(const char* jid, const char* subscription, const char* name);
-void* data_get_chat_page(void* roster_item_widget);
+#ifndef DATA_H
+#define DATA_H
+
+// https://www.rfc-editor.org/rfc/rfc6121#section-2.1.2.5
+typedef enum {
+ SUB_NONE,
+ SUB_TO,
+ SUB_FROM,
+ SUB_BOTH
+} subscription_t;
+
+typedef struct _message_t {
+ char* content;
+ char* sender_jid;
+ struct _message_t* next;
+ void* widget;
+} message_t;
+
+typedef struct _chat_t {
+ message_t* messages;
+ void* widget;
+} chat_t;
+
+typedef struct _roster_item_t {
+ char* name; // could be NULL
+ char* jid;
+ subscription_t sub;
+ chat_t* chat;
+ struct _roster_item_t* next;
+ void* widget;
+} roster_item_t;
+
+void data_add_roster_item(const char* jid, const char* subscription,
+ const char* name);
+void data_add_incoming_message(const char* sender_jid, const char* content);
+#endif
diff --git a/gtk.c b/gtk.c
index c84534c..9813531 100644
--- a/gtk.c
+++ b/gtk.c
@@ -185,7 +185,7 @@ static void to_roster(void) {
}
-void* gui_add_chat(void) {
+void gui_add_chat_widget(chat_t* chat) {
// create chat page (GtkBox) and add it to the stack
GtkWidget* chat_layout_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 20);
@@ -206,6 +206,9 @@ void* gui_add_chat(void) {
gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scrolled),
chat_content_box);
+ // save widget pointer
+ chat->widget = (void*)chat_content_box;
+
// create and add text input field
GtkWidget* text_entry = gtk_entry_new();
gtk_box_append(GTK_BOX(chat_layout_box), text_entry);
@@ -216,44 +219,46 @@ void* gui_add_chat(void) {
//g_signal_connect_swapped(send_button, "clicked", G_CALLBACK(send_message),
// chat); // TODO
- // return chat page as void pointer for future reference
- return (void*)chat_layout_box;
-
}
-void gui_add_message(const char* sender_jid, const char* content) {
+void gui_add_message_widget(message_t* message, chat_t* chat) {
- printf("Received from %s:\n%s\n", sender_jid, content);
+ // TODO
+ printf("Received from %s:\n%s\n", message->sender_jid, message->content);
}
-static void to_chat(GtkWidget* roster_item_widget) {
+static void to_chat(chat_t* chat) {
- GtkWidget* chat_page = data_get_chat_page((void*)roster_item_widget);
+ //GtkWidget* chat_page = data_get_chat_page((void*)roster_item_widget);
+ GtkWidget* chat_page = chat->widget; // initialize as a far child
+ for (int i=0; i<3; i++) { // and then jump three levels up
+ chat_page = gtk_widget_get_parent(chat_page);
+ }
gtk_stack_set_visible_child(GTK_STACK(stack), chat_page);
}
-void* gui_add_roster_item(const char* jid, const char* sub, const char* name) {
+void gui_add_roster_item_widget(roster_item_t* item) {
// print debug message
- if (name) {
- printf("roster item: %s, %s, sub:%s\n", name, jid, sub);
+ if (item->name) {
+ printf("roster item: %s, %s, sub:%d\n", item->name, item->jid,
+ item->sub);
} else {
- printf("roster item: (no name), %s, sub:%s\n", jid, sub);
+ printf("roster item: (no name), %s, sub:%d\n", item->jid, item->sub);
}
// create widget for roster item
GtkWidget* roster_item_widget;
- if (name == NULL || strcmp(name, "") == 0) {
- roster_item_widget = gtk_button_new_with_label(name);
+ if (item->name == NULL || strcmp(item->name, "") == 0) {
+ roster_item_widget = gtk_button_new_with_label(item->jid);
} else {
- roster_item_widget = gtk_button_new_with_label(jid);
+ roster_item_widget = gtk_button_new_with_label(item->name);
}
// add roster item widget to roster page
gtk_box_append(GTK_BOX(roster_content_box), roster_item_widget);
g_signal_connect_swapped(roster_item_widget, "clicked", G_CALLBACK(to_chat),
- roster_item_widget);
+ item->chat);
- return (void*)roster_item_widget;
}
diff --git a/gui.h b/gui.h
index db1fe31..9bcbb1d 100644
--- a/gui.h
+++ b/gui.h
@@ -1,3 +1,8 @@
+#ifndef GUI_H
+#define GUI_H
+
+#include "data.h"
+
// interface for main.c
void gui_run(void);
@@ -6,6 +11,8 @@ void gui_connected(char* jid, char* password);
void gui_disconnected(void);
void gui_suspended(void);
void gui_resumed(void);
-void* gui_add_chat(void);
-void gui_add_message(const char* sender_jid, const char* content);
-void* gui_add_roster_item(const char* jid, const char* sub, const char* name);
+void gui_add_roster_item_widget(roster_item_t* item);
+void gui_add_chat_widget(chat_t* chat);
+void gui_add_message_widget(message_t* message, chat_t* chat);
+
+#endif
diff --git a/limox.c b/limox.c
index 5bdaa7b..6c84971 100644
--- a/limox.c
+++ b/limox.c
@@ -40,19 +40,16 @@ static xmpp_sm_state_t* sm_state;
static int message_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza,
void *userdata) {
- // local variables
- xmpp_stanza_t* body;
- const char* content;
-
- body = xmpp_stanza_get_child_by_name(stanza, "body");
+ xmpp_stanza_t* body = xmpp_stanza_get_child_by_name(stanza, "body");
if (body == NULL) {
printf("DEBUG: Got message stanza of type char without body!\n");
return 1;
}
- content = xmpp_stanza_get_text(body);
+ const char* content = xmpp_stanza_get_text(body);
+ const char* sender = xmpp_stanza_get_from(stanza);
- gui_add_message(xmpp_stanza_get_from(stanza), content);
+ data_add_incoming_message(sender, content);
return 1;
}
@@ -60,16 +57,14 @@ static int message_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza,
static int roster_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza,
void *userdata) {
- printf("DEBUG: Received roster.\n");
-
// iterate over roster result
xmpp_stanza_t* query = xmpp_stanza_get_child_by_name(stanza, "query");
for (xmpp_stanza_t* item = xmpp_stanza_get_children(query); item;
item = xmpp_stanza_get_next(item)) {
- add_roster_item(xmpp_stanza_get_attribute(item, "jid"),
- xmpp_stanza_get_attribute(item, "subscription"),
- xmpp_stanza_get_attribute(item, "name"));
+ data_add_roster_item(xmpp_stanza_get_attribute(item, "jid"),
+ xmpp_stanza_get_attribute(item, "subscription"),
+ xmpp_stanza_get_attribute(item, "name"));
}
return 1;
diff --git a/limox.h b/limox.h
index 90a3b76..4f2d8c1 100644
--- a/limox.h
+++ b/limox.h
@@ -1,3 +1,6 @@
+#ifndef LIMOX_H
+#define LIMOX_H
+
// life cycle / event loop related functions
void limox_init(void); // initialize limox
void limox_run_once(void); // process event loop for a short amount of time
@@ -6,3 +9,5 @@ void limox_quit(void); // disconnect and clean up
// interface for the GUI implementation
void limox_connect(const char* jid, const char* password);
void limox_disconnect(void);
+
+#endif