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 #include <sys/types.h>
24 
25 #include "brightoninternals.h"
26 #include "brightonX11.h"
27 
28 static float opacity = 1.0;
29 
30 /*
31  * Much of this could do with a rework to make it more generic, at the moment
32  * a lot of the key handlers are very bespoke.
33  */
34 
35 extern void brightonKeyInput(brightonWindow *, int, int);
36 extern void brightonControlKeyInput(brightonWindow *, int, int);
37 extern void brightonShiftKeyInput(brightonWindow *, int, int, int);
38 extern void brightonControlShiftKeyInput(brightonWindow *, int, int, int);
39 extern void printColorCacheStats(brightonWindow *);
40 
41 /*
42  * TOOK THIS OUT BY POPULAR DEMAND
43  */
44 //extern int brightonMenu();
45 
46 int
brightonKeyPress(brightonWindow * bwin,brightonEvent * event)47 brightonKeyPress(brightonWindow *bwin, brightonEvent *event)
48 {
49 	brightonIResource *panel;
50 
51 	if (bwin->flags & BRIGHTON_DEBUG)
52 		printf("brightonKeyPress(%i)\n", event->key);
53 
54 	if ((event->key == 'p') && (event->flags & BRIGHTON_MOD_CONTROL))
55 	{
56 		brightonXpmWrite(bwin, "/tmp/brighton.xpm");
57 		printColorCacheStats(bwin);
58 	}
59 
60 	/*
61 	 * All of the following up to the dispatch is for the top layer opacity, it
62 	 * could go into a separate file?
63 	 *
64 	 * T should just be a toggle between totally opaque and the current
65 	 * setting. There are a few other keys that are natively interpreted for
66 	 * rather trivial reasons before being passed through to the GUI. These
67 	 * implicit mappings should be dropped.
68 	 */
69 	if ((event->key == 't') && (event->flags & BRIGHTON_MOD_CONTROL))
70 	{
71 		float hold;
72 
73 		hold = bwin->opacity;
74 		bwin->opacity = opacity;
75 		opacity = hold;
76 		brightonFinalRender(bwin, 0, 0, bwin->width, bwin->height);
77 	} else if ((event->key == 'o') && (event->flags & BRIGHTON_MOD_CONTROL)) {
78 		/*
79 		 * 'O' should be to make more opaque, 'o' more transparent. This is not
80 		 * as * trivial as it seems since the shift key is always a separate
81 		 * event.
82 		 */
83 		if (event->flags & BRIGHTON_MOD_SHIFT)
84 		{
85 			if (bwin->opacity == 1.0f)
86 				bwin->opacity = 0.2f;
87 			else if ((bwin->opacity += 0.1f) > 1.0f)
88 				bwin->opacity = 1.0f;
89 			brightonFinalRender(bwin, 0, 0, bwin->width, bwin->height);
90 		} else {
91 			if (bwin->opacity <= 0.21f)
92 				bwin->opacity = 1.0f;
93 			else if ((bwin->opacity -= 0.2f) < 0.2f)
94 				bwin->opacity = 0.2f;
95 			brightonFinalRender(bwin, 0, 0, bwin->width, bwin->height);
96 		}
97 	}
98 
99 	/*
100 	 * We now want to look to see if the request needs to be dispatched to any
101 	 * devices. This means 'if the mouse is within any device then pass the key
102 	 * event to that device.
103 	 */
104 	if ((bwin->flags & BRIGHTON_DEV_ACTIVE) && (bwin->activepanel != 0))
105 	{
106 		bwin->activepanel->configure(bwin, bwin->activepanel, event);
107 	} else if ((panel = brightonPanelLocator(bwin, event->x, event->y))
108 		> (brightonIResource *) NULL)
109 	{
110 		if (panel->configure)
111 			panel->configure(bwin, panel, event);
112 	}
113 
114 	/*
115 	 * Finally, as this is a key press event I want to pass it through to the
116 	 * midi library. This is a rather ugly hack to have a more useful keyboard
117 	 * mapping. We should only really do this from the keyboard panel, but that
118 	 * if for later study.
119 	 */
120 	if ((event->flags & BRIGHTON_MOD_CONTROL)
121 		&& (event->flags & BRIGHTON_MOD_SHIFT))
122 		brightonControlShiftKeyInput(bwin, event->key, 1, event->flags);
123 	else if (event->flags & BRIGHTON_MOD_CONTROL)
124 		brightonControlKeyInput(bwin, event->key, 1);
125 	else if (event->flags & BRIGHTON_MOD_SHIFT)
126 		brightonShiftKeyInput(bwin, event->key, 1, event->flags);
127 	else
128 		brightonKeyInput(bwin, event->key, 1);
129 
130 	return(0);
131 }
132 
133 int
brightonKeyRelease(brightonWindow * bwin,brightonEvent * event)134 brightonKeyRelease(brightonWindow *bwin, brightonEvent *event)
135 {
136 	brightonIResource *panel;
137 
138 	if (bwin->flags & BRIGHTON_DEBUG)
139 		printf("brightonKeyRelease(%i)\n", event->key);
140 
141 	if ((bwin->flags & BRIGHTON_DEV_ACTIVE) && (bwin->activepanel != 0))
142 		bwin->activepanel->configure(bwin, bwin->activepanel, event);
143 	else if ((panel = brightonPanelLocator(bwin, event->x, event->y))
144 		> (brightonIResource *) NULL)
145 	{
146 		if (panel->configure)
147 			panel->configure(bwin, panel, event);
148 	}
149 
150 	if (~event->flags & BRIGHTON_MOD_CONTROL)
151 		brightonKeyInput(bwin, event->key, 0);
152 
153 	return(0);
154 }
155 
156 int
brightonButtonPress(brightonWindow * bwin,brightonEvent * event)157 brightonButtonPress(brightonWindow *bwin, brightonEvent *event)
158 {
159 	if (bwin->flags & BRIGHTON_DEBUG)
160 		printf("brightonButtonPress(%i)\n", event->key);
161 
162 	/*
163 	 * TOOK THIS OUT BY POPULAR DEMAND
164 	if (event->key == BRIGHTON_BUTTON3) {
165 			brightonMenu(bwin, event->x, event->y, 100, 200);
166 		return(0);
167 	}
168 	 */
169 
170 	/*
171 	 * We need to determine which device is under the selection, and force
172 	 * statefull delivery of events to that device for further motion.
173 	 */
174 	bwin->activepanel = 0;
175 
176 	if ((bwin->activepanel = brightonPanelLocator(bwin, event->x, event->y))
177 		> (brightonIResource *) NULL)
178 	{
179 		bwin->flags |= BRIGHTON_DEV_ACTIVE;
180 
181 		event->command = BRIGHTON_BUTTONPRESS;
182 
183 		if (bwin->activepanel->configure)
184 			bwin->activepanel->configure(bwin, bwin->activepanel, event);
185 	} else
186 		bwin->flags &= ~BRIGHTON_DEV_ACTIVE;
187 	return(0);
188 }
189 
190 int
brightonButtonRelease(brightonWindow * bwin,brightonEvent * event)191 brightonButtonRelease(brightonWindow *bwin, brightonEvent *event)
192 {
193 	if (bwin->flags & BRIGHTON_DEBUG)
194 	{
195 		if ((bwin) && (bwin->activepanel))
196 			printf("brightonButtonRelease(%p, %p, %p)\n",
197 				bwin,
198 				bwin->activepanel,
199 				bwin->activepanel->configure);
200 	}
201 
202 	event->command = BRIGHTON_BUTTONRELEASE;
203 
204 	/*
205 	 * TOOK THIS OUT BY POPULAR DEMAND
206 	if (event->key == BRIGHTON_BUTTON3) {
207 			brightonMenu(bwin, event->x, event->y, 100, 200);
208 		return(0);
209 	}
210 	 */
211 
212 	/*if (bwin->activepanel && bwin->activepanel->configure) */
213 	if ((bwin->flags & BRIGHTON_DEV_ACTIVE) && (bwin->activepanel != 0))
214 		bwin->activepanel->configure(bwin, bwin->activepanel, event);
215 
216 	bwin->flags &= ~BRIGHTON_DEV_ACTIVE;
217 	bwin->activepanel = 0;
218 	return(0);
219 }
220 
221 int
brightonMotionNotify(brightonWindow * bwin,brightonEvent * event)222 brightonMotionNotify(brightonWindow *bwin, brightonEvent *event)
223 {
224 	if ((bwin->flags & BRIGHTON_DEV_ACTIVE) && (bwin->activepanel != 0))
225 	{
226 		if (bwin->activepanel->configure)
227 			bwin->activepanel->configure(bwin, bwin->activepanel, event);
228 	}
229 	return(0);
230 }
231 
232 static void
brightonFillRatios(brightonWindow * win)233 brightonFillRatios(brightonWindow *win)
234 {
235 	float wfact, hfact;
236 
237 	wfact = ((float) win->display->width) * 0.95
238 		/ ((float) win->template->width);
239 	hfact = ((float) win->display->height) * 0.95
240 		/ ((float) win->template->height);
241 
242 	if (hfact > wfact) {
243 		win->maxw = win->display->width * 0.95;
244 		win->minw = win->template->width;
245 		win->minh = win->template->height;
246 		win->maxh = win->template->height * wfact;
247 	} else {
248 		win->maxh = win->display->height * 0.95;
249 		win->minw = win->template->width;
250 		win->minh = win->template->height;
251 		win->maxw = win->template->width * hfact;
252 	}
253 }
254 
255 int
brightonEnterNotify(brightonWindow * bwin,brightonEvent * event)256 brightonEnterNotify(brightonWindow *bwin, brightonEvent *event)
257 {
258 	if (bwin->flags & BRIGHTON_DEBUG)
259 		printf("brightonEnterNotify()\n");
260 
261 #if (BRIGHTON_HAS_ZOOM == 1)
262 	if (bwin->flags & BRIGHTON_AUTOZOOM)
263 	{
264 		if (bwin->flags & BRIGHTON_DEBUG)
265 			printf("AutoZoom\n");
266 
267 		// Make sure we are initted
268 		if ((bwin->minh == 0) || (bwin->maxh == 0))
269 			brightonFillRatios(bwin);
270 
271 		bwin->display->flags |= BRIGHTON_ANTIALIAS_5;
272 
273 		brightonRequestResize(bwin,
274 			bwin->template->width,
275 			bwin->template->height);
276 
277 		if (bwin->flags & BRIGHTON_SET_RAISE)
278 			BRaiseWindow(bwin->display, bwin);
279 	} else
280 #endif
281 	if (~bwin->flags & BRIGHTON_NO_ASPECT) {
282 		float aspect = ((float) bwin->width) / bwin->height;
283 
284 	    if ((aspect / bwin->aspect < 0.98) || ((aspect / bwin->aspect) > 1.02))
285 		{
286 			/* Ratio has changed */
287 			if (bwin->flags & _BRIGHTON_SET_HEIGHT) {
288 				if ((bwin->height * bwin->aspect)
289 					< ((brightonDisplay *) bwin->display)->width)
290 					bwin->width = bwin->height * bwin->aspect;
291 				else {
292 					bwin->width =
293 						((brightonDisplay *) bwin->display)->width - 10;
294 					bwin->height = bwin->width / bwin->aspect;
295 				}
296 			} else {
297 				if ((bwin->width / bwin->aspect)
298 					< ((brightonDisplay *) bwin->display)->height)
299 					bwin->height = bwin->width / bwin->aspect;
300 				else {
301 					bwin->height =
302 						((brightonDisplay *) bwin->display)->height - 10;
303 					bwin->width = bwin->height * bwin->aspect;
304 				}
305 			}
306 
307 			if (bwin->flags & BRIGHTON_DEBUG)
308 				printf("changed aspect ratio: %f %i %i\n",
309 					aspect, bwin->width, bwin->height);
310 
311 			BResizeWindow(bwin->display, bwin, bwin->width, bwin->height);
312 			brightonWorldChanged(bwin, bwin->width, bwin->height);
313 		}
314 	}
315 
316 	bwin->flags &= ~_BRIGHTON_SET_HEIGHT;
317 
318 	if (bwin->flags & BRIGHTON_EXITING)
319 	{
320 		BAutoRepeat(bwin->display, 1);
321 		return(0);
322 	}
323 
324 	BAutoRepeat(bwin->display, 0);
325 
326 	return(0);
327 }
328 
329 int
brightonLeaveNotify(brightonWindow * bwin,brightonEvent * event)330 brightonLeaveNotify(brightonWindow *bwin, brightonEvent *event)
331 {
332 	if (bwin->flags & BRIGHTON_DEBUG)
333 		printf("brightonLeaveNotify()\n");
334 
335 #if (BRIGHTON_HAS_ZOOM == 1)
336 	if (bwin->flags & BRIGHTON_AUTOZOOM)
337 	{
338 		if (bwin->flags & BRIGHTON_DEBUG)
339 			printf("AutoZoom\n");
340 
341 		// Make sure we are initted
342 		if ((bwin->minh == 0) || (bwin->maxh == 0))
343 			brightonFillRatios(bwin);
344 
345 		// Flip the window size
346 		brightonRequestResize(bwin, bwin->minw, bwin->minh);
347 
348 		if (bwin->flags & BRIGHTON_SET_LOWER)
349 			BLowerWindow(bwin->display, bwin);
350 	} else
351 #endif
352 	if (~bwin->flags & BRIGHTON_NO_ASPECT) {
353 		float aspect = ((float) bwin->width) / bwin->height;
354 
355 	    if ((aspect / bwin->aspect < 0.98) || ((aspect / bwin->aspect) > 1.02))
356 		{
357 			/* Ratio has changed */
358 			if (bwin->flags & _BRIGHTON_SET_HEIGHT) {
359 				if ((bwin->height * bwin->aspect)
360 					< ((brightonDisplay *) bwin->display)->width)
361 					bwin->width = bwin->height * bwin->aspect;
362 				else {
363 					bwin->width =
364 						((brightonDisplay *) bwin->display)->width - 10;
365 					bwin->height = bwin->width / bwin->aspect;
366 				}
367 			} else {
368 				if ((bwin->width / bwin->aspect)
369 					< ((brightonDisplay *) bwin->display)->height)
370 					bwin->height = bwin->width / bwin->aspect;
371 				else {
372 					bwin->height =
373 						((brightonDisplay *) bwin->display)->height - 10;
374 					bwin->width = bwin->height * bwin->aspect;
375 				}
376 			}
377 
378 			if (bwin->flags & BRIGHTON_DEBUG)
379 				printf("changed aspect ratio: %f %i %i\n",
380 					aspect, bwin->width, bwin->height);
381 
382 			BResizeWindow(bwin->display, bwin, bwin->width, bwin->height);
383 			brightonWorldChanged(bwin, bwin->width, bwin->height);
384 		}
385 	}
386 
387 	bwin->flags &= ~_BRIGHTON_SET_HEIGHT;
388 
389 	BAutoRepeat(bwin->display, 1);
390 	return(0);
391 }
392 
393 int
brightonFocusIn(brightonWindow * bwin,brightonEvent * event)394 brightonFocusIn(brightonWindow *bwin, brightonEvent *event)
395 {
396 	if (bwin->flags & BRIGHTON_DEBUG)
397 		printf("brightonFocusIn()\n");
398 
399 	brightonEnterNotify(bwin, event);
400 
401 	return(0);
402 }
403 
404 int
brightonFocusOut(brightonWindow * bwin,brightonEvent * event)405 brightonFocusOut(brightonWindow *bwin, brightonEvent *event)
406 {
407 	if (bwin->flags & BRIGHTON_DEBUG)
408 		printf("brightonFocusOut()\n");
409 
410 	brightonLeaveNotify(bwin, event);
411 
412 	return(0);
413 }
414 
415 int
brightonKeymapNotify(brightonWindow * bwin,brightonEvent * event)416 brightonKeymapNotify(brightonWindow *bwin, brightonEvent *event)
417 {
418 	if (bwin->flags & BRIGHTON_DEBUG)
419 		printf("brightonKeymapNotify()\n");
420 	return(0);
421 }
422 
423 int
brightonExpose(brightonWindow * bwin,brightonEvent * event)424 brightonExpose(brightonWindow *bwin, brightonEvent *event)
425 {
426 	if (bwin->flags & BRIGHTON_DEBUG)
427 		printf("brightonExpose(%i %i %i %i)\n",
428 			event->x, event->y, event->w, event->h);
429 
430 	BCopyArea(bwin->display,
431 		event->x, event->y, event->w, event->h, event->x, event->y);
432 	return(0);
433 }
434 
435 int
brightonGraphicsExpose(brightonWindow * bwin,brightonEvent * event)436 brightonGraphicsExpose(brightonWindow *bwin, brightonEvent *event)
437 {
438 	if (bwin->flags & BRIGHTON_DEBUG)
439 		printf("brightonGraphicsExpose()\n");
440 	return(0);
441 }
442 
443 int
brightonNoExpose(brightonWindow * bwin,brightonEvent * event)444 brightonNoExpose(brightonWindow *bwin, brightonEvent *event)
445 {
446 	if (bwin->flags & BRIGHTON_DEBUG)
447 		printf("brightonNoExpose()\n");
448 	return(0);
449 }
450 
451 int
brightonVisibilityNotify(brightonWindow * bwin,brightonEvent * event)452 brightonVisibilityNotify(brightonWindow *bwin, brightonEvent *event)
453 {
454 	if (bwin->flags & BRIGHTON_DEBUG)
455 		printf("brightonVisibilityNotify()\n");
456 	return(0);
457 }
458 
459 int
brightonCreateNotify(brightonWindow * bwin,brightonEvent * event)460 brightonCreateNotify(brightonWindow *bwin, brightonEvent *event)
461 {
462 	if (bwin->flags & BRIGHTON_DEBUG)
463 		printf("brightonCreateNotify()\n");
464 	return(0);
465 }
466 
467 int
brightonDestroyNotify(brightonWindow * bwin,brightonEvent * event)468 brightonDestroyNotify(brightonWindow *bwin, brightonEvent *event)
469 {
470 	/*
471 	 * Counter intuitive, we do nothing here. The process gets a SIGPIPE and
472 	 * the GUI intercepts this to request the engine to terminate the algo
473 	 * represented by this GUI. Engine will terminate when all algos have
474 	 * finished.
475 	 */
476 	if (bwin->flags & BRIGHTON_DEBUG)
477 		printf("brightonDestroyNotify()\n");
478 	return(0);
479 }
480 
481 int
brightonUnmapNotify(brightonWindow * bwin,brightonEvent * event)482 brightonUnmapNotify(brightonWindow *bwin, brightonEvent *event)
483 {
484 	if (bwin->flags & BRIGHTON_DEBUG)
485 		printf("brightonUnmapNotify()\n");
486 	return(0);
487 }
488 
489 int
brightonMapNotify(brightonWindow * bwin,brightonEvent * event)490 brightonMapNotify(brightonWindow *bwin, brightonEvent *event)
491 {
492 	if (bwin->flags & BRIGHTON_DEBUG)
493 		printf("brightonMapNotify()\n");
494 	return(0);
495 }
496 
497 int
brightonMapRequest(brightonWindow * bwin,brightonEvent * event)498 brightonMapRequest(brightonWindow *bwin, brightonEvent *event)
499 {
500 	if (bwin->flags & BRIGHTON_DEBUG)
501 		printf("brightonMapRequest()\n");
502 	return(0);
503 }
504 
505 int
brightonReparentNotify(brightonWindow * bwin,brightonEvent * event)506 brightonReparentNotify(brightonWindow *bwin, brightonEvent *event)
507 {
508 	if (bwin->flags & BRIGHTON_DEBUG)
509 		printf("brightonReparentNotify()\n");
510 	return(0);
511 }
512 
513 int
brightonConfigureNotify(brightonWindow * bwin,brightonEvent * event)514 brightonConfigureNotify(brightonWindow *bwin, brightonEvent *event)
515 {
516 	if (bwin->flags & BRIGHTON_DEBUG)
517 		printf("brightonConfigureNotify(%i, %i, %i, %i)\n",
518 			event->x, event->y, event->w, event->h);
519 
520 	if (bwin->flags & BRIGHTON_SET_SIZE)
521 	{
522 		bwin->flags &= ~BRIGHTON_SET_SIZE;
523 		return(0);
524 	}
525 
526 	if ((bwin->width != event->w) || (bwin->height != event->h))
527 		brightonWorldChanged(bwin, event->w, event->h);
528 
529 	/* This is wrong. */
530 //	if ((bwin->width != event->w) || (bwin->height != event->h))
531 //		BResizeWindow(bwin->display, bwin, bwin->width, bwin->height);
532 
533 	return(0);
534 }
535 
536 int
brightonConfigureRequest(brightonWindow * bwin,brightonEvent * event)537 brightonConfigureRequest(brightonWindow *bwin, brightonEvent *event)
538 {
539 	if (bwin->flags & BRIGHTON_DEBUG)
540 		printf("brightonConfigureRequest()\n");
541 	return(0);
542 }
543 
544 int
brightonGravityNotify(brightonWindow * bwin,brightonEvent * event)545 brightonGravityNotify(brightonWindow *bwin, brightonEvent *event)
546 {
547 	if (bwin->flags & BRIGHTON_DEBUG)
548 		printf("brightonGravityNotify()\n");
549 	return(0);
550 }
551 
552 int
brightonRequestResize(brightonWindow * bwin,int w,int h)553 brightonRequestResize(brightonWindow *bwin, int w, int h)
554 {
555 	if (bwin->flags & BRIGHTON_DEBUG)
556 		printf("brightonResizeRequest(%i, %i)\n", w, h);
557 
558 	if ((bwin->width != w) || (bwin->height != h))
559 	{
560 		if ((bwin->width < w) && (bwin->flags & BRIGHTON_SET_RAISE))
561 			BRaiseWindow(bwin->display, bwin);
562 
563 		/*
564 		 * Our size has changed. We need to re-render the background, and then
565 		 * repaint it.
566 		 */
567 		BResizeWindow(bwin->display, bwin, w, h);
568 		brightonWorldChanged(bwin, w, h);
569 	}
570 	return(0);
571 }
572 
573 int
brightonResizeRequest(brightonWindow * bwin,brightonEvent * event)574 brightonResizeRequest(brightonWindow *bwin, brightonEvent *event)
575 {
576 	if (bwin->flags & BRIGHTON_DEBUG)
577 		printf("brightonResizeRequest(%i, %i)\n", event->w, event->h);
578 
579 	if ((bwin->width != event->w) || (bwin->height != event->h))
580 	{
581 		/*
582 		 * Our size has changed. We need to re-render the background, and then
583 		 * repaint it.
584 		 */
585 		brightonWorldChanged(bwin, event->w, event->h);
586 
587 /*
588 		if ((bwin->width != event->w) || (bwin->height != event->h))
589 			BResizeWindow(bwin->display, bwin->win, bwin->width, bwin->height);
590 */
591 	}
592 	return(0);
593 }
594 
595 int
brightonCirculateNotify(brightonWindow * bwin,brightonEvent * event)596 brightonCirculateNotify(brightonWindow *bwin, brightonEvent *event)
597 {
598 	if (bwin->flags & BRIGHTON_DEBUG)
599 		printf("brightonCirculateNotify()\n");
600 	return(0);
601 }
602 
603 int
brightonCirculateRequest(brightonWindow * bwin,brightonEvent * event)604 brightonCirculateRequest(brightonWindow *bwin, brightonEvent *event)
605 {
606 	if (bwin->flags & BRIGHTON_DEBUG)
607 		printf("brightonCirculateRequest()\n");
608 	return(0);
609 }
610 
611 int
brightonPropertyNotify(brightonWindow * bwin,brightonEvent * event)612 brightonPropertyNotify(brightonWindow *bwin, brightonEvent *event)
613 {
614 	if (bwin->flags & BRIGHTON_DEBUG)
615 		printf("brightonPropertyNotify()\n");
616 	return(0);
617 }
618 
619 int
brightonSelectionClear(brightonWindow * bwin,brightonEvent * event)620 brightonSelectionClear(brightonWindow *bwin, brightonEvent *event)
621 {
622 	if (bwin->flags & BRIGHTON_DEBUG)
623 		printf("brightonSelectionClear()\n");
624 	return(0);
625 }
626 
627 int
brightonSelectionRequest(brightonWindow * bwin,brightonEvent * event)628 brightonSelectionRequest(brightonWindow *bwin, brightonEvent *event)
629 {
630 	if (bwin->flags & BRIGHTON_DEBUG)
631 		printf("brightonSelectionRequest()\n");
632 	return(0);
633 }
634 
635 int
brightonSelectionNotify(brightonWindow * bwin,brightonEvent * event)636 brightonSelectionNotify(brightonWindow *bwin, brightonEvent *event)
637 {
638 	if (bwin->flags & BRIGHTON_DEBUG)
639 		printf("brightonSelectionNotify()\n");
640 	return(0);
641 }
642 
643 int
brightonColormapNotify(brightonWindow * bwin,brightonEvent * event)644 brightonColormapNotify(brightonWindow *bwin, brightonEvent *event)
645 {
646 	if (bwin->flags & BRIGHTON_DEBUG)
647 		printf("brightonColormapNotify()\n");
648 	return(0);
649 }
650 
651 int
brightonClientMessage(brightonWindow * bwin,brightonEvent * event)652 brightonClientMessage(brightonWindow *bwin, brightonEvent *event)
653 {
654 	if (bwin->flags & BRIGHTON_DEBUG)
655 		printf("brightonClientMessage()\n");
656 	return(0);
657 }
658 
659 int
brightonMappingNotify(brightonWindow * bwin,brightonEvent * event)660 brightonMappingNotify(brightonWindow *bwin, brightonEvent *event)
661 {
662 	if (bwin->flags & BRIGHTON_DEBUG)
663 		printf("brightonMappingNotify()\n");
664 	return(0);
665 }
666 
667 int
brightonNullHandler(brightonWindow * bwin,brightonEvent * event)668 brightonNullHandler(brightonWindow *bwin, brightonEvent *event)
669 {
670 	if (bwin->flags & BRIGHTON_DEBUG)
671 		printf("brightonNullHandler()\n");
672 	return(0);
673 }
674 
675 typedef int (*eventRoutine)(brightonWindow *, brightonEvent *);
676 
677 /*
678  * Check out the bEvent from the library, it can mask some events that are
679  * considered "not important", but actually may be.
680  */
681 eventRoutine defaultHandlers[BLASTEvent] = {
682 	brightonNullHandler,
683 	brightonNullHandler,
684 	brightonKeyPress,
685 	brightonKeyRelease,
686 	brightonButtonPress,
687 	brightonButtonRelease,
688 	brightonMotionNotify,
689 	brightonEnterNotify,
690 	brightonLeaveNotify,
691 	brightonFocusIn,
692 	brightonFocusOut,
693 	brightonKeymapNotify,
694 	brightonExpose,
695 	brightonGraphicsExpose,
696 	brightonNoExpose,
697 	brightonVisibilityNotify,
698 	brightonCreateNotify,
699 	brightonDestroyNotify,
700 	brightonUnmapNotify,
701 	brightonMapNotify,
702 	brightonMapRequest,
703 	brightonReparentNotify,
704 	brightonConfigureNotify,
705 	brightonConfigureRequest,
706 	brightonGravityNotify,
707 	brightonResizeRequest,
708 	brightonCirculateNotify,
709 	brightonCirculateRequest,
710 	brightonPropertyNotify,
711 	brightonSelectionClear,
712 	brightonSelectionRequest,
713 	brightonSelectionNotify,
714 	brightonColormapNotify,
715 	brightonClientMessage,
716 	brightonMappingNotify
717 };
718 
brightonInitDefHandlers(brightonWindow * bwin)719 void brightonInitDefHandlers(brightonWindow *bwin)
720 {
721 	int i;
722 
723 	for (i = 0; i < BLASTEvent; i++)
724 		bwin->callbacks[i] = defaultHandlers[i];
725 }
726 
727 void
brightonOldEventLoop(brightonDisplay ** dlist)728 brightonOldEventLoop(brightonDisplay **dlist)
729 {
730 	brightonDisplay *display;
731 	brightonEvent event;
732 	brightonWindow *bwin = (*dlist)->bwin;
733 
734 	while (1) {
735 		/*
736 		 * BNextEvent will block due to it using XNextEvent. This makes the
737 		 * use of other functions rather difficult. Will rework this to use
738 		 * XCheckMaskEvent which will not block.
739 		 *
740 		 *	while (1) {
741 		 *		foreach (win) {
742 		 * 			BCheckMaskEvent(bwin, &event);
743 		 *		}
744 		 *	}
745 		 *
746 		 * We need this since the MIDI routines also need to be checked, so we
747 		 * will select on the ALSA SEQ port looking for controller changes so
748 		 * that they can modify the GUI display.
749 		 */
750 		BNextEvent(bwin->display, &event);
751 
752 		if (event.command == BRIGHTON_NONE)
753 			continue;
754 
755 		/*
756 		 * This may need to be changed to a semaphore, but I am hoping all GUI
757 		 * activity can occupy a single thread only.
758 		 */
759 		bwin->flags |= BRIGHTON_BUSY;
760 
761 		/*
762 		 * Look for the right window.
763 		 */
764 		display = *dlist;
765 
766 		while (display != 0)
767 		{
768 			if (event.wid == ((brightonWindow *) display->bwin)->win)
769 				break;
770 
771 			if ((event.type == BRIGHTON_DESTROY)
772 				&& (((brightonWindow *) display->bwin)->parentwin == event.wid))
773 				break;
774 
775 			display = display->next;
776 		}
777 
778 		if ((display == 0 || (event.type < 0) || (event.type >= BLASTEvent)))
779 			continue;
780 
781 		((brightonWindow *) display->bwin)->callbacks[event.type]
782 			(display->bwin, &event);
783 
784 		bwin->flags &= ~BRIGHTON_BUSY;
785 	}
786 }
787 
788 int
brightonEventLoop(brightonDisplay ** dlist)789 brightonEventLoop(brightonDisplay **dlist)
790 {
791 	brightonDisplay *display;
792 	brightonEvent event;
793 	brightonWindow *bwin = (*dlist)->bwin;
794 
795 /*	while (1) { */
796 		/*
797 		 * BNextEvent will block due to it using XNextEvent. This makes the
798 		 * use of other functions rather difficult. Will rework this to use
799 		 * XCheckMaskEvent which will not block.
800 		 *
801 		 *	while (1) {
802 		 *		foreach (win) {
803 		 * 			BCheckMaskEvent(bwin, &event);
804 		 *		}
805 		 *	}
806 		 *
807 		 * We need this since the MIDI routines also need to be checked, so we
808 		 * will select on the ALSA SEQ port looking for controller changes so
809 		 * that they can modify the GUI display.
810 		 */
811 		while (BNextEvent(bwin->display, &event) > 0)
812 		{
813 			if (event.command == BRIGHTON_NONE)
814 				continue;
815 
816 			/*
817 			 * This may need to be changed to a semaphore, but I am hoping all
818 			 * GUI activity can occupy a single thread only.
819 			 */
820 			bwin->flags |= BRIGHTON_BUSY;
821 
822 			/*
823 			 * Look for the right window.
824 			 */
825 			display = *dlist;
826 
827 			while (display != 0)
828 			{
829 				if (event.wid == ((brightonWindow *) display->bwin)->win)
830 					break;
831 
832 				if ((event.type == BRIGHTON_DESTROY)
833 					&& (((brightonWindow *) display->bwin)->parentwin
834 						== event.wid))
835 					break;
836 
837 				display = display->next;
838 			}
839 
840 			if ((display == 0 || (event.type < 0)
841 				|| (event.type >= BLASTEvent)))
842 				continue;
843 
844 			((brightonWindow *) display->bwin)->callbacks[event.type]
845 				(display->bwin, &event);
846 
847 			bwin->flags &= ~BRIGHTON_BUSY;
848 
849 			/*
850 			 * Configure events are typically big resizes which are long events.
851 			 * If we handle all of them (they come in buckets) at once it is
852 			 * possible the engine will detect GUI failure from active sense
853 			 */
854 			if (event.command == BRIGHTON_CONFIGURE)
855 				return(1);
856 		}
857 
858 		/*
859 		 * This will now become a select on the ALSA SEQ socket looking for
860 		 * MIDI events. Not certain how they will be linked into the GUI at
861 		 * the moment. For now this is just a sleep until the ALSA SEQ interface
862 		 * registration code has been finalised.
863 		 *
864 		 * What we will be looking for are events on a MIDI channel, we will
865 		 * look for that MIDI channel in our window lists. We want to respond
866 		 * to key events and reflect that in the GUI optionally, but not send
867 		 * the key events since the engine will handle all those. We also want
868 		 * to look for controller values and have some configurable method to
869 		 * link those to our controls. Now this linkage will be done via the
870 		 * GUI, preferably, with the <Control><Middle Mouse><MIDI CC # motion>.
871 		 * Since the GUI handles this then we can dispatch events to another
872 		 * module that does the linkage. Need to be able to save and retrieve
873 		 * configurations - <Control><Middle> will go to this module, and all
874 		 * MIDI controller events as well, and it will make the linkage and
875 		 * dispatch the events.
876 		 * We should try and have a vkeydb type X event keymap.
877 		 */
878 /*		usleep(10000); */
879 /*	} */
880 	return(0);
881 }
882 
883