1 #include "utf8.c"
2
3 /* originally lifted from the clipboard code in tui, take a shmif
4 * context and a message then split message over as many events as
5 * needed, respecting utf8 alignment */
shmif_msgchunk(struct arcan_shmif_cont * c,const char * msg,size_t len)6 static void shmif_msgchunk(
7 struct arcan_shmif_cont* c, const char* msg, size_t len)
8 {
9 if (!c || !msg || !len)
10 return;
11
12 arcan_event msgev = {
13 .category = EVENT_EXTERNAL,
14 .ext.kind = ARCAN_EVENT(MESSAGE)
15 };
16
17 uint32_t state = 0, codepoint = 0;
18 const char* outs = msg;
19 size_t maxlen = sizeof(msgev.ext.message.data) - 1;
20
21 /* utf8- point aligned against block size */
22 while (len > maxlen){
23 size_t i, lastok = 0;
24 state = 0;
25 for (i = 0; i <= maxlen - 1; i++){
26 if (UTF8_ACCEPT == utf8_decode(&state, &codepoint, (uint8_t)(msg[i])))
27 lastok = i;
28
29 if (i != lastok){
30 if (0 == i)
31 return;
32 }
33 }
34
35 memcpy(msgev.ext.message.data, outs, lastok);
36 msgev.ext.message.data[lastok] = '\0';
37 len -= lastok;
38 outs += lastok;
39
40 if (len)
41 msgev.ext.message.multipart = 1;
42 else
43 msgev.ext.message.multipart = 0;
44
45 arcan_shmif_enqueue(c, &msgev);
46 }
47
48 /* flush remaining */
49 if (len){
50 snprintf((char*)msgev.ext.message.data, maxlen, "%s", outs);
51 msgev.ext.message.multipart = 0;
52 arcan_shmif_enqueue(c, &msgev);
53 }
54 }
55