@@ -8,11 +8,67 @@ You should have received a copy of the CC0 Public Domain Dedication along with t
88#include <SDL.h>
99#include <SDL_image.h>
1010#include <SDL_ttf.h>
11-
1211#include <SDL_rotozoom.h>
12+ #include <SDL_timer.h>
1313
14- #include <getopt.h>
14+ #include <stdio.h>
15+ #include <stdlib.h>
1516#include <string.h>
17+ #include <getopt.h>
18+
19+ #define LENGTH 2048
20+
21+ SDL_TimerID HB_Timer_ID = 0 ;
22+
23+ Uint32 delay = 5000 ; /* in ms = 10^(-3) sec! */
24+
25+ char * sPWD = (char * )0 ;
26+ char * sAPPID = (char * )0 ;
27+
28+ char tmp [LENGTH ];
29+
30+ int popen_gets ()
31+ {
32+ int k = LENGTH ; int kk ; char * p = tmp ; FILE * fp ;
33+
34+ fp = popen (tmp , "r" );
35+
36+ if (fp == NULL )
37+ return (-1 ); /* printf("Failed to run command\n" ); */
38+
39+ while (fgets (p , k , fp ) != NULL )
40+ {
41+ kk = strnlen (p , k );
42+ p = p + kk ;
43+ k = k - kk ;
44+ }
45+
46+ return (pclose (fp ));
47+ }
48+
49+ const char * HB_CMDs [] =
50+ {
51+ "hb_init" ,
52+ "hb_ping" ,
53+ "hb_done"
54+ };
55+
56+ int HB (int cmd , int d )
57+ {
58+ int r ;
59+
60+ r = snprintf (tmp , LENGTH , "/bin/bash %s/hb.sh %s %d" , sPWD , HB_CMDs [cmd ], d );
61+ r = popen_gets ();
62+
63+ if ( (cmd == 2 ) || (r < 0 ))
64+ return (d );
65+
66+ r = atoi (tmp );
67+
68+ return (r );
69+ }
70+
71+
1672
1773static TTF_Font * font ;
1874
@@ -73,26 +129,30 @@ int handle_corner(int w, int h, int x, int y, int r2, int c)
73129 return r2 > d2 ;
74130}
75131
76- void handle_events (SDL_Surface * screen , SDL_Rect * rects , char * * apps , int num , char corners [4 ][2048 ], int r2 )
132+ int handle_events (SDL_Surface * screen , SDL_Rect * rects , char * * apps , int num , char corners [4 ][2048 ], int r2 )
77133{
78134 static int mouse_x = 0 ;
79135 static int mouse_y = 0 ;
80136 int button = 0 ;
81137 SDL_Event event ;
138+
82139 while (SDL_PollEvent (& event )) {
83140 switch (event .type ) {
84141 case SDL_KEYDOWN :
85- switch (event .key .keysym .sym ) {
142+ {
143+
144+ switch (event .key .keysym .sym )
145+ {
86146 case SDLK_q :
87- exit (1 );
88- break ;
147+ return (2 ); break ;
89148 case SDLK_ESCAPE :
90- exit (1 );
91- break ;
149+ return (2 ); break ;
92150 default :
93151 break ;
94152 }
95153 break ;
154+ }
155+
96156 case SDL_MOUSEMOTION :
97157 mouse_x = event .motion .x ;
98158 mouse_y = event .motion .y ;
@@ -107,34 +167,41 @@ void handle_events(SDL_Surface *screen, SDL_Rect *rects, char **apps, int num, c
107167 }
108168 break ;
109169 case SDL_QUIT :
110- TTF_CloseFont (font );
170+ {
171+ return (1 ); break ;
172+ }
111173
112- TTF_Quit ();
113- SDL_Quit ();
114174
115- exit (1 );
116- break ;
175+ case SDL_USEREVENT :
176+ {
177+ /* and now we can call the function we wanted to call in the timer
178+ but couldn't because of the multithreading problems */
179+ void (* p ) (Uint32 * ) = event .user .data1 ; p (event .user .data2 );
180+ break ;
181+ }
117182 default :
118183 break ;
119184 }
120185 }
186+
121187 if (!button )
122- return ;
188+ return ( 0 ) ;
123189
124190 for (int i = 0 ; i < 4 ; i ++ ) {
125191 if (* corners [i ] && handle_corner (screen -> w , screen -> h , mouse_x , mouse_y , r2 , i )) {
126192 fputs (corners [i ], stdout );
127- exit ( 0 );
193+ return ( 1 );
128194 }
129195 }
130196
131197 for (int i = 0 ; i < num ; i ++ ) {
132198 if (rects [i ].x <= mouse_x && mouse_x < (rects [i ].x + rects [i ].w ) && rects [i ].y <= mouse_y && mouse_y < (rects [i ].y + rects [i ].h )) {
133199 fputs (apps [i ], stdout );
134- exit ( 0 );
200+ return ( 1 );
135201 }
136202 }
137-
203+
204+ return (0 );
138205}
139206
140207SDL_Cursor * empty_cursor ()
@@ -151,6 +218,9 @@ char *fn = "FreeMonoBold.ttf"; // default font
151218
152219void init (int argc , char * * argv )
153220{
221+ sPWD = getenv ("PWD" );
222+ sAPPID = getenv ("APP_ID" ); /* use HB? */
223+
154224 for (;;) {
155225 switch (getopt (argc , argv , "hct:d:p:f:" )) {
156226 case 'h' :
@@ -185,8 +255,6 @@ void init(int argc, char **argv)
185255 }
186256}
187257
188- #define LENGTH 2048
189-
190258int check_corner (char * out , char * in , char * which )
191259{
192260 if (in != strstr (in , which ))
@@ -209,6 +277,37 @@ int check_corner(char *out, char *in, char *which)
209277 return 1 ;
210278}
211279
280+ void HB_PingPong (Uint32 * param )
281+ {
282+ int d = (((* param ) + 500 ) / 1000 ); /* millisec -> sec?!*/
283+ int ret = HB (1 , d );
284+ (void )ret ;
285+ }
286+
287+
288+ /* with the same code as before: */
289+ Uint32 my_callbackfunc (Uint32 interval , void * param )
290+ {
291+ SDL_Event event ;
292+ SDL_UserEvent userevent ;
293+
294+ /* In this example, our callback pushes a function
295+ * into the queue, and causes our callback to be called again at the
296+ * same interval: */
297+
298+ userevent .type = SDL_USEREVENT ;
299+ userevent .code = 0 ;
300+ userevent .data1 = & HB_PingPong ;
301+ userevent .data2 = param ;
302+
303+ event .type = SDL_USEREVENT ;
304+ event .user = userevent ;
305+
306+ SDL_PushEvent (& event );
307+ return (interval );
308+ }
309+
310+
212311int main (int argc , char * * argv )
213312{
214313 init (argc , argv );
@@ -292,7 +391,18 @@ int main(int argc, char **argv)
292391 num ++ ;
293392 }
294393
295- SDL_Init (SDL_INIT_VIDEO );
394+ Uint32 flags = SDL_INIT_VIDEO ;
395+
396+ if ( sAPPID != NULL )
397+ flags = flags | SDL_INIT_TIMER ;
398+
399+ if (SDL_Init (flags ) != 0 )
400+ {
401+ fprintf (stderr , "\nUnable to initialize SDL: %s\n" , SDL_GetError () );
402+ return 1 ;
403+ }
404+
405+ /* atexit(SDL_Quit); */
296406
297407 if (TTF_Init () == -1 )
298408 {
@@ -492,15 +602,40 @@ int main(int argc, char **argv)
492602 }
493603
494604 SDL_Flip (screen );
605+
606+ if ( sAPPID != NULL )
607+ {
608+ /* Start the timer; the callback below will be executed after the delay */
609+ HB_Timer_ID = SDL_AddTimer (delay , my_callbackfunc , & delay );
610+ }
611+
495612
613+ int ret ;
496614 for (;;) {
497615 if (timeout && (int )SDL_GetTicks () > (timeout * 1000 )) {
498616 fputs (to_cmd , stdout );
499617 exit (0 );
500618 }
501619 SDL_Delay (100 );
502- handle_events (screen , rects , apps , num , corners , r2 );
620+
621+ if ( (ret = handle_events (screen , rects , apps , num , corners , r2 )) > 0 )
622+ break ;
503623 }
504- return 0 ;
624+
625+ if ( HB_Timer_ID != 0 )
626+ SDL_RemoveTimer (HB_Timer_ID );
627+
628+ TTF_CloseFont (font );
629+
630+ TTF_Quit ();
631+
632+ HB (2 , 0 );
633+
634+ SDL_Quit ();
635+
636+ if (ret == 1 )
637+ return 0 ;
638+
639+ return 1 ;
505640}
506641
0 commit comments