1 /*
2  * A wandering box test that deals with dirty rectangles
3  */
4 
5 #include <stdlib.h>
6 #include <stdint.h>
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <stdbool.h>
10 
11 #include <arcan_shmif.h>
12 
13 static size_t box_x;
14 static size_t box_y;
15 static bool reset = true;
16 
17 static shmif_pixel bgcol = SHMIF_RGBA(32, 32, 32, 255);
18 static shmif_pixel boxcol = SHMIF_RGBA(64, 128, 64, 255);
19 
draw_box_px(shmif_pixel * px,size_t pitch,size_t max_w,size_t max_h,size_t x,size_t y,size_t w,size_t h,shmif_pixel col)20 static bool draw_box_px(
21 shmif_pixel* px, size_t pitch, size_t max_w, size_t max_h,
22 size_t x, size_t y, size_t w, size_t h, shmif_pixel col)
23 {
24 	if (x >= max_w || y >= max_h)
25 		return false;
26 
27 	int ux = x + w > max_w ? max_w : x + w;
28 	int uy = y + h > max_h ? max_h : y + h;
29 
30 	for (int cy = y; cy < uy; cy++)
31 		for (int cx = x; cx < ux; cx++)
32 			px[ cy * pitch + cx ] = col;
33 
34 	return true;
35 }
36 
draw_box(struct arcan_shmif_cont * c,size_t x,size_t y,int w,int h,shmif_pixel col)37 static bool draw_box(struct arcan_shmif_cont* c,
38 	size_t x, size_t y, int w, int h, shmif_pixel col)
39 {
40 	return draw_box_px(c->vidp, c->pitch, c->w, c->h, x, y, w, h, col);
41 }
42 
run_frame(struct arcan_shmif_cont * c)43 void run_frame(struct arcan_shmif_cont* c)
44 {
45 	draw_box(c, box_x, box_y, 32, 32, bgcol);
46 	c->dirty.x1 = box_x;
47 	c->dirty.y1 = box_y;
48 	c->dirty.x2 = box_x + 32 + 8;
49 	c->dirty.y2 = box_y + 32 + 8;
50 
51 	box_x += 8;
52 	box_y += 8;
53 
54 	if (box_x >= c->w){
55 		box_x = random() % (c->w - 32);
56 		reset = true;
57 	}
58 
59 	if (box_y >= c->h){
60 		box_y = random() % (c->h - 32);
61 		reset = true;
62 	}
63 
64 	if (reset){
65 		c->dirty.x1 = 0;
66 		c->dirty.y1 = 0;
67 		c->dirty.x2 = c->w;
68 		c->dirty.y2 = c->h;
69 		bgcol = SHMIF_RGBA(32 + random() % 224, 64 + random() % 196, 32 + random() % 224, 0xff);
70 		draw_box(c, 0, 0, c->w, c->h, bgcol);
71 		reset = false;
72 	}
73 
74 	draw_box(c, box_x, box_y, 32, 32, boxcol);
75 
76 	arcan_shmif_signal(c, SHMIF_SIGVID);
77 }
78 
main(int argc,char ** argv)79 int main(int argc, char** argv)
80 {
81 	struct arcan_shmif_cont cont = arcan_shmif_open(
82 		SEGID_APPLICATION, SHMIF_ACQUIRE_FATALFAIL, NULL);
83 
84 /* event- frame clock + dirty updates */
85 	cont.hints = SHMIF_RHINT_SUBREGION | SHMIF_RHINT_IGNORE_ALPHA | SHMIF_RHINT_VSIGNAL_EV;
86 	draw_box(&cont, cont.w, cont.h, 32, 32, boxcol);
87 
88 /* enable the hints and send contents */
89 	arcan_shmif_resize(&cont, cont.w, cont.h);
90 	arcan_shmif_signal(&cont, SHMIF_SIGVID);
91 
92 	struct arcan_event ev;
93 	while (arcan_shmif_wait(&cont, &ev)){
94 		switch (ev.tgt.kind){
95 		case TARGET_COMMAND_EXIT:
96 			goto out;
97 		break;
98 		case TARGET_COMMAND_DISPLAYHINT:
99 			if (ev.tgt.ioevs[0].iv > 32 && ev.tgt.ioevs[1].iv > 32){
100 				arcan_shmif_resize(&cont, ev.tgt.ioevs[0].iv, ev.tgt.ioevs[1].iv);
101 				reset = true;
102 				run_frame(&cont);
103 			}
104 		break;
105 		case TARGET_COMMAND_RESET:
106 			reset = true;
107 			run_frame(&cont);
108 		break;
109 		case TARGET_COMMAND_STEPFRAME:
110 			run_frame(&cont);
111 		break;
112 
113 		default:
114 		break;
115 		}
116 	}
117 out:
118 	return EXIT_SUCCESS;
119 }
120