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