1 
2 /*
3  *  Diverse Bristol audio routines.
4  *  Copyright (c) by Nick Copeland <nickycopeland@hotmail.com> 1996,2012
5  *
6  *
7  *   This program is free software; you can redistribute it and/or modify
8  *   it under the terms of the GNU General Public License as published by
9  *   the Free Software Foundation; either version 3 of the License, or
10  *   (at your option) any later version.
11  *
12  *   This program is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with this program; if not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #include <stdio.h>
23 
24 #include "brightoninternals.h"
25 
26 extern void cleanout(brightonWindow *);
27 
28 brightonDisplay *dlist = 0;
29 
30 brightonWindow *
brightonInterface(brightonApp * app,int quality,int library,int aa,float aad,int gs,int x,int y)31 brightonInterface(brightonApp *app, int quality, int library, int aa, float aad,
32 int gs, int x, int y)
33 {
34 	brightonDisplay *display;
35 
36 	/*
37 	 * Connect to the display.
38 	 */
39 #ifdef BRIGHTON_HAS_X11
40 	if (app->flags & BRIGHTON_WINDOW)
41 	{
42 		printf("brightonInterface(cli)\n");
43 		display = brightonOpenDisplay("cli");
44 		display->flags |= _BRIGHTON_WINDOW;
45 	} else if ((display = brightonOpenDisplay(NULL)) == 0) {
46 		printf("brightonInterface() failed\n");
47 		return(0);
48 	}
49 #else
50 	app->flags |= BRIGHTON_WINDOW;
51 	printf("brightonInterface(cli)\n");
52 	display = brightonOpenDisplay("cli");
53 	display->flags |= _BRIGHTON_WINDOW;
54 #endif
55 	/*
56 	 * Link it into our list.
57 	 */
58 	display->next = dlist;
59 	if (dlist)
60 		dlist->last = display;
61 	dlist = display;
62 
63 	/* This should be made into an option and needs to be stuffed early */
64 	if ((library != 0) && (display->flags & BRIGHTON_BIMAGE))
65 		display->flags |= BRIGHTON_BIMAGE;
66 	else
67 		display->flags &= ~BRIGHTON_BIMAGE;
68 
69 	if (aa & BRIGHTON_LIB_DEBUG)
70 	{
71 		printf("libbrighton debuging enabled\n");
72 		display->flags |= BRIGHTON_LIB_DEBUG;
73 	}
74 	aa &= ~BRIGHTON_LIB_DEBUG;
75 
76 	switch (aa) {
77 		case 1:
78 			display->flags |= BRIGHTON_ANTIALIAS_1;
79 			break;
80 		case 2:
81 			display->flags |= BRIGHTON_ANTIALIAS_2;
82 			break;
83 		case 3:
84 			display->flags |= BRIGHTON_ANTIALIAS_3;
85 			break;
86 		case 4:
87 			display->flags |= BRIGHTON_ANTIALIAS_4;
88 			break;
89 		case 5:
90 			display->flags |= BRIGHTON_ANTIALIAS_5;
91 			break;
92 	};
93 
94 printf("brighton %p %i %i\n", app, app->width, app->height);
95 	/*
96 	 * Request a new toplevel window for this app.
97 	 */
98 	if ((display->bwin = brightonCreateWindow(display,
99 		app,
100 		BRIGHTON_CMAP_SIZE,
101 		BRIGHTON_DEFAULT_ICON,
102 		quality, gs, x, y)))
103 	{
104 		if (display->flags & BRIGHTON_LIB_DEBUG)
105 			display->bwin->flags |= BRIGHTON_DEBUG;
106 
107 		if ((display->bwin->quality = quality) < 2)
108 			display->bwin->quality = 2;
109 		else if (display->bwin->quality > 8)
110 			display->bwin->quality = 8;
111 
112 		if (app->init)
113 			app->init(display->bwin);
114 
115 		((brightonWindow *) display->bwin)->display = display;
116 
117 		/*
118 		 * Map its panels and devices. Devices can be menus as well.
119 		 */
120 		brightonCreateInterface((brightonWindow *) display->bwin, app);
121 
122 		display->bwin->antialias = aad;
123 
124 		/*brightonEventLoop(&dlist); */
125 
126 		return(display->bwin);
127 	}
128 
129 	return(0);
130 }
131 
132 int
brightonEventMgr()133 brightonEventMgr()
134 {
135 	return(brightonEventLoop(&dlist));
136 }
137 
138 int
brightonRemoveInterface(brightonWindow * bwin)139 brightonRemoveInterface(brightonWindow *bwin)
140 {
141 	brightonDisplay *d;
142 
143 printf("brightonRemoveInterface(%p)\n", bwin);
144 
145 	bwin->flags |= BRIGHTON_EXITING;
146 
147 	if ((d = brightonFindDisplay(dlist, (brightonDisplay *) bwin->display))
148 		== 0)
149 		return(0);
150 
151 	if (bwin->template->destroy != 0)
152 		bwin->template->destroy(bwin);
153 
154 	BAutoRepeat(bwin->display, 1);
155 	brightonDestroyInterface(bwin);
156 
157 	/*
158 	 * Unlink the display
159 	 */
160 	if (d->next)
161 		d->next->last = d->last;
162 
163 	if (d->last)
164 		d->last->next = d->next;
165 	else
166 		dlist = d->next;
167 
168 	if (dlist == 0)
169 	{
170 		brightonDestroyWindow(bwin);
171 		cleanout(bwin);
172 	}
173 
174 	/*
175 	 * Remove window and its contents.
176 	 */
177 	brightonDestroyWindow(bwin);
178 
179 	return(0);
180 }
181 
182 /*
183  * This will cover a bit of code will cover the timing for double click. It
184  * will be tested here and should eventually go into the brighton library.
185  *
186  * First open a 'double click handle', send events that need to be checked,
187  * and close the handle when no longer required. Closing is actually not
188  * trivial here if we do not have a destroy routine.
189  */
190 #include <sys/time.h>
191 
192 #define DC_TIMERS 128
193 struct {
194 	struct timeval time;
195 	int timeout;
196 } dc_timers[DC_TIMERS];
197 
198 int
brightonGetDCTimer(int timeout)199 brightonGetDCTimer(int timeout)
200 {
201 	int dcth;
202 
203 	for (dcth = 0; dcth < DC_TIMERS; dcth++)
204 		if (dc_timers[dcth].timeout == 0)
205 		{
206 			dc_timers[dcth].time.tv_sec = timeout / 1000000;
207 			dc_timers[dcth].time.tv_usec = timeout % 1000000;
208 //			dc_timers[dcth].time.tv_usec = 0;
209 			dc_timers[dcth].timeout = timeout;
210 			return(dcth);
211 		}
212 	return(0);
213 }
214 
215 void
brightonFreeDCTimerHandle(int dcth)216 brightonFreeDCTimerHandle(int dcth)
217 {
218 	dc_timers[dcth].time.tv_sec = 0;
219 }
220 
221 int
brightonDoubleClick(int dcth)222 brightonDoubleClick(int dcth)
223 {
224 	struct timeval current;
225 	int delta_uS;
226 
227 	if ((dcth < 0) || (dcth >= DC_TIMERS))
228 		return(0);
229 
230 	gettimeofday(&current, NULL);
231 
232 	if ((current.tv_sec - dc_timers[dcth].time.tv_sec) > 1)
233 	{
234 		/* Not a double click */
235 		dc_timers[dcth].time.tv_sec = current.tv_sec;
236 		dc_timers[dcth].time.tv_usec = current.tv_usec;
237 
238 		return(0);
239 	}
240 
241 	/*
242 	 * So now build a delta of the time of the two clicks and see if it is
243 	 * within the limit of the timer.
244 	 */
245 	if (current.tv_sec == dc_timers[dcth].time.tv_sec)
246 		delta_uS = current.tv_usec - dc_timers[dcth].time.tv_usec;
247 	else
248 		delta_uS = current.tv_usec + (1000000 - dc_timers[dcth].time.tv_usec);
249 
250 	if (delta_uS < dc_timers[dcth].timeout)
251 		return(1);
252 
253 	dc_timers[dcth].time.tv_sec = current.tv_sec;
254 	dc_timers[dcth].time.tv_usec = current.tv_usec;
255 
256 	return(0);
257 }
258 
259 /*
260  * End of double click timer code.
261  */
262 
263