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