1 #ifndef MESSAGES_H 2 #define MESSAGES_H 3 4 #include "ui/panel.h" 5 6 #include <stdint.h> 7 #include <time.h> 8 #include <pthread.h> 9 10 extern pthread_mutex_t messages_lock; 11 12 typedef struct native_image NATIVE_IMAGE; 13 14 typedef enum UTOX_MSG_TYPE { 15 MSG_TYPE_NULL, 16 /* MSG_TEXT must start here */ 17 MSG_TYPE_TEXT, 18 MSG_TYPE_ACTION_TEXT, 19 MSG_TYPE_NOTICE, 20 MSG_TYPE_NOTICE_DAY_CHANGE, // Separated so I can localize this later! 21 /* MSG_TEXT should end here */ 22 // MSG_TYPE_OTHER, // Unused, expect to separate MSG_TEXT type 23 MSG_TYPE_IMAGE, 24 // MSG_TYPE_IMAGE_HISTORY, 25 MSG_TYPE_FILE, 26 // MSG_TYPE_FILE_HISTORY, 27 // MSG_TYPE_CALL_ACTIVE, 28 // MSG_TYPE_CALL_HISTORY, 29 } UTOX_MSG_TYPE; 30 31 typedef struct { 32 char *author; 33 uint16_t author_length; 34 35 uint16_t length; 36 char *msg; 37 } MSG_TEXT; 38 39 typedef struct { 40 char *author; 41 uint16_t author_length; 42 43 uint16_t length; 44 char *msg; 45 46 uint32_t author_id; 47 uint32_t author_color; 48 } MSG_GROUP; 49 50 typedef struct { 51 uint32_t w, h; 52 bool zoom; 53 double position; 54 NATIVE_IMAGE *image; 55 } MSG_IMG; 56 57 typedef struct msg_file { 58 uint8_t file_status; 59 uint32_t file_number; 60 61 char *name; 62 size_t name_length; 63 64 // Location on disk 65 uint8_t *path; 66 size_t path_length; 67 // In memory pointer 68 uint8_t *data; 69 size_t data_size; 70 71 uint32_t speed; 72 uint64_t size, progress; 73 bool inline_png; 74 } MSG_FILE; 75 76 /* Generic Message type */ 77 typedef struct msg_header { 78 UTOX_MSG_TYPE msg_type; 79 80 // true, if we're the author, false, if someone else. 81 bool our_msg; 82 83 uint32_t height; 84 time_t time; 85 86 87 uint64_t disk_offset; 88 89 uint32_t receipt; 90 time_t receipt_time; 91 92 union { 93 MSG_TEXT txt; 94 MSG_TEXT action; 95 MSG_TEXT notice; 96 MSG_TEXT notice_day; 97 98 MSG_GROUP grp; 99 100 MSG_IMG img; 101 102 MSG_FILE ft; 103 } via; 104 } MSG_HEADER; 105 106 // Type for indexing into MSG_DATA->data array of messages 107 typedef struct messages { 108 PANEL panel; 109 110 // false for Friendchat, true for Groupchat. 111 bool is_groupchat; 112 // Tox friendnumber/groupnumber 113 uint32_t id; 114 int height, width; 115 116 // Position and length of an URL in the message under the mouse, 117 // if present. cursor_over_uri == UINT16_MAX if there's none. 118 uint32_t cursor_over_uri, urllen; 119 120 // Was the url pressed by the mouse. 121 uint32_t cursor_down_uri; 122 123 uint32_t cursor_over_msg, cursor_over_position, cursor_down_msg, cursor_down_position; 124 uint32_t sel_start_msg, sel_end_msg, sel_start_position, sel_end_position; 125 // true if we're in the middle of selection operation 126 // (mousedown without mouseup yet). 127 bool selecting_text; 128 bool cursor_over_time; 129 130 // Number of messages in data array. 131 uint32_t number; 132 // Number of extra to speedup realloc. 133 int8_t extra; 134 135 // Pointers at various message structs, at most MAX_BACKLOG_MESSAGES. 136 MSG_HEADER **data; 137 138 // Field for preserving position of text scroll 139 double scroll; 140 } MESSAGES; 141 142 uint32_t message_add_group(MESSAGES *m, MSG_HEADER *msg); 143 144 uint32_t message_add_type_text(MESSAGES *m, bool auth, const char *msgtxt, uint16_t length, bool log, bool send); 145 uint32_t message_add_type_action(MESSAGES *m, bool auth, const char *msgtxt, uint16_t length, bool log, bool send); 146 uint32_t message_add_type_notice(MESSAGES *m, const char *msgtxt, uint16_t length, bool log); 147 uint32_t message_add_type_image(MESSAGES *m, bool auth, NATIVE_IMAGE *img, uint16_t width, uint16_t height, bool log); 148 149 MSG_HEADER *message_add_type_file(MESSAGES *m, uint32_t file_number, bool incoming, bool image, uint8_t status, 150 const uint8_t *name, size_t name_size, size_t target_size, size_t current_size); 151 // Returns true if data was logged. 152 bool message_log_to_disk(MESSAGES *m, MSG_HEADER *msg); 153 // Returns true if data was read from log. 154 bool messages_read_from_log(uint32_t friend_number); 155 156 void messages_send_from_queue(MESSAGES *m, uint32_t friend_number); 157 void messages_clear_receipt(MESSAGES *m, uint32_t receipt_number); 158 159 /** Formats all messages from self and friends, and then call draw functions 160 * to write them to the UI. 161 * 162 * accepts: messages struct *pointer, int x,y positions, int width,height 163 */ 164 void messages_draw(PANEL *panel, int x, int y, int width, int height); 165 166 bool messages_mmove(PANEL *panel, int px, int py, int width, int height, int mx, int my, int dx, int dy); 167 bool messages_mdown(PANEL *panel); 168 bool messages_dclick(PANEL *panel, bool triclick); 169 bool messages_mright(PANEL *panel); 170 bool messages_mwheel(PANEL *panel, int height, double d, bool smooth); 171 // Always returns false. 172 bool messages_mup(PANEL *panel); 173 bool messages_mleave(PANEL *m); 174 // Relay keypress to message panel. 175 // Returns bool indicating whether a redraw is needed or not. 176 bool messages_char(uint32_t ch); 177 int messages_selection(PANEL *panel, char *buffer, uint32_t len, bool names); 178 179 void messages_updateheight(MESSAGES *m, int width); 180 181 182 void messages_init(MESSAGES *m, uint32_t friend_number); 183 void message_free(MSG_HEADER *msg); 184 void messages_clear_all(MESSAGES *m); 185 186 #endif 187