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