Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 450156
Collapse All | Expand All

(-)a/core/src/common.h (+4 lines)
Lines 34-39 Link Here
34
	#define PATH_PROC	FBSPLASH_DIR"/proc"
34
	#define PATH_PROC	FBSPLASH_DIR"/proc"
35
#endif
35
#endif
36
36
37
/* Maximum number of keyboard connected to a machine.
38
 * The number is big (8) to be on the safe side */
39
#define MAX_KBDS 8
40
37
/* Useful short-named types */
41
/* Useful short-named types */
38
typedef u_int8_t	u8;
42
typedef u_int8_t	u8;
39
typedef u_int16_t	u16;
43
typedef u_int16_t	u16;
(-)a/core/src/daemon.c (-41 / +71 lines)
Lines 20-25 Link Here
20
#include <sys/ioctl.h>
20
#include <sys/ioctl.h>
21
#include <sys/wait.h>
21
#include <sys/wait.h>
22
#include <sys/mman.h>
22
#include <sys/mman.h>
23
#include <sys/select.h>
23
#include <pthread.h>
24
#include <pthread.h>
24
#include <errno.h>
25
#include <errno.h>
25
#include <dirent.h>
26
#include <dirent.h>
Lines 29-34 Link Here
29
#include "common.h"
30
#include "common.h"
30
#include "daemon.h"
31
#include "daemon.h"
31
32
33
#define EV_BUF_SIZE 8
34
32
/* Threading structures */
35
/* Threading structures */
33
pthread_mutex_t mtx_tty = PTHREAD_MUTEX_INITIALIZER;
36
pthread_mutex_t mtx_tty = PTHREAD_MUTEX_INITIALIZER;
34
pthread_mutex_t mtx_paint = PTHREAD_MUTEX_INITIALIZER;
37
pthread_mutex_t mtx_paint = PTHREAD_MUTEX_INITIALIZER;
Lines 41-47 Link Here
41
int ctty = CTTY_VERBOSE;
44
int ctty = CTTY_VERBOSE;
42
45
43
/* File descriptors */
46
/* File descriptors */
44
int fd_evdev = -1;
47
int fd_evdevs[MAX_KBDS];
48
int evdev_count = 0;
45
#ifdef CONFIG_GPM
49
#ifdef CONFIG_GPM
46
int fd_gpm = -1;
50
int fd_gpm = -1;
47
#endif
51
#endif
Lines 51-57 Link Here
51
55
52
/* Misc settings */
56
/* Misc settings */
53
char *notify[2];
57
char *notify[2];
54
char *evdev = NULL;
55
58
56
/* Service list */
59
/* Service list */
57
list svcs = { NULL, NULL };
60
list svcs = { NULL, NULL };
Lines 400-455 Link Here
400
	}
403
	}
401
}
404
}
402
405
406
__u16 get_ev_key_pressed(int fd_evdev, int ev_buf_size, 
407
		struct input_event *ev_buf) {
408
	size_t rb;
409
	int i;
410
	rb = read(fd_evdev, ev_buf, sizeof(struct input_event) * ev_buf_size);
411
	if (rb < (int) sizeof(struct input_event))
412
		return 0;
413
414
	for (i = 0; i < (int) (rb / sizeof(struct input_event)); i++) {
415
		if (ev_buf[i].type != EV_KEY || ev_buf[i].value != 0)
416
			continue;
417
		return ev_buf[i].code;
418
	}	
419
}
420
403
/*
421
/*
404
 * Event device monitor thread.
422
 * Event device monitor thread.
405
 */
423
 */
406
void* thf_switch_evdev(void *unused)
424
void* thf_switch_evdev(void *unused)
407
{
425
{
408
	int i, h, oldstate;
426
	int i, h, oldstate, nfds, retval, fd_evdev;
409
	size_t rb;
427
	fd_set rfds;
410
	struct input_event ev[8];
428
	struct input_event ev_buf[EV_BUF_SIZE];
429
	__u16 key_pressed = 0;
411
430
412
	while (1) {
431
	while (1) {
413
		rb = read(fd_evdev, ev, sizeof(struct input_event)*8);
432
		nfds = 0, fd_evdev = -1;		
414
		if (rb < (int) sizeof(struct input_event))
433
		FD_ZERO(&rfds);
415
			continue;
434
		for (i = 0;i < evdev_count;i++) {
435
			FD_SET(fd_evdevs[i], &rfds);
436
			nfds = max(nfds, fd_evdevs[i]);
437
		}
416
438
417
		for (i = 0; i < (int) (rb / sizeof(struct input_event)); i++) {
439
		nfds++;
418
			if (ev[i].type != EV_KEY || ev[i].value != 0)
419
				continue;
420
440
421
			switch (ev[i].code) {
441
		retval = select(nfds, &rfds, NULL, NULL, NULL);
422
			case KEY_F2:
442
		if (retval == -1)
423
				pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
443
			perror("select()");
424
				pthread_mutex_lock(&mtx_paint);
444
		else if (retval) {
425
				if (ctty == CTTY_SILENT) {
445
			for (i = 0;i < evdev_count;i++) {
426
					h = config.tty_v;
446
				if (FD_ISSET(fd_evdevs[i], &rfds)) {
427
				} else {
447
					fd_evdev = fd_evdevs[i];
428
					h = config.tty_s;
448
					break;
429
				}
449
				}
430
				pthread_mutex_unlock(&mtx_paint);
450
			}
431
				pthread_setcancelstate(oldstate, NULL);
451
			key_pressed = get_ev_key_pressed(fd_evdev, EV_BUF_SIZE, ev_buf);
452
			if (key_pressed == -1)
453
				continue;
454
			switch (key_pressed) {
455
				case KEY_F2:
456
					pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
457
					pthread_mutex_lock(&mtx_paint);
458
					h = (ctty == CTTY_SILENT) ? config.tty_v : config.tty_s;
459
					pthread_mutex_unlock(&mtx_paint);
460
					pthread_setcancelstate(oldstate, NULL);
461
462
					/* Switch to the new tty. This ioctl has to be done on
463
					 * the silent tty. Sometimes init will mess with the
464
					 * settings of the verbose console which will prevent
465
					 * console switching from working properly.
466
					 *
467
					 * Don't worry about fd_tty[config.tty_s] 
468
					 * not being protected by a mutex -- 
469
					 * this thread is always killed before any changes
470
					 * are made to fd_tty[config.tty_s].
471
					 */
472
					ioctl(fd_tty[config.tty_s], VT_ACTIVATE, h);
473
					break;
432
474
433
				/* Switch to the new tty. This ioctl has to be done on
475
				case KEY_F3:
434
				 * the silent tty. Sometimes init will mess with the
476
					config.textbox_visible = !config.textbox_visible;
435
				 * settings of the verbose console which will prevent
477
					invalidate_textbox(theme, config.textbox_visible);
436
				 * console switching from working properly.
478
					cmd_paint(NULL);
437
				 *
479
					break;
438
				 * Don't worry about fd_tty[config.tty_s] not being protected by a
439
				 * mutex -- this thread is always killed before any changes
440
				 * are made to fd_tty[config.tty_s].
441
				 */
442
				ioctl(fd_tty[config.tty_s], VT_ACTIVATE, h);
443
				break;
444
445
			case KEY_F3:
446
				config.textbox_visible = !config.textbox_visible;
447
				invalidate_textbox(theme, config.textbox_visible);
448
				cmd_paint(NULL);
449
				break;
450
			}
480
			}
451
		}
481
		} /* end of else if (retval) */
452
	}
482
	} /* end of while(1) */
453
483
454
	pthread_exit(NULL);
484
	pthread_exit(NULL);
455
}
485
}
Lines 519-525 Link Here
519
549
520
	/* Do we have to start a monitor thread? */
550
	/* Do we have to start a monitor thread? */
521
	if (update & UPD_MON) {
551
	if (update & UPD_MON) {
522
		if (fd_evdev != -1) {
552
		if (evdev_count >= 0) {
523
			if (pthread_create(&th_switchmon, NULL, &thf_switch_evdev, NULL)) {
553
			if (pthread_create(&th_switchmon, NULL, &thf_switch_evdev, NULL)) {
524
				iprint(MSG_ERROR, "Evdev monitor thread creation failed.\n");
554
				iprint(MSG_ERROR, "Evdev monitor thread creation failed.\n");
525
				exit(3);
555
				exit(3);
(-)a/core/src/daemon.h (-4 / +4 lines)
Lines 40-52 Link Here
40
extern int fd_tty_s, fd_tty1, fd_tty0;
40
extern int fd_tty_s, fd_tty1, fd_tty0;
41
41
42
/*
42
/*
43
 * Event device on which the daemon listens for F2 keypresses.
43
 * Event devices on which the daemon listens for F2 keypresses.
44
 * The proper device has to be detected by an external program and
44
 * The proper devices have to be detected by an external program and
45
 * then enabled by sending an appropriate command to the splash
45
 * then enabled by sending an appropriate command to the splash
46
 * daemon.
46
 * daemon.
47
 */
47
 */
48
extern int fd_evdev;
48
extern int fd_evdevs[];
49
extern char *evdev;
49
extern int evdev_count;
50
50
51
#ifdef CONFIG_GPM
51
#ifdef CONFIG_GPM
52
#include <gpm.h>
52
#include <gpm.h>
(-)a/core/src/daemon_cmd.c (-12 / +29 lines)
Lines 239-256 Link Here
239
 */
239
 */
240
int cmd_set_event_dev(void **args)
240
int cmd_set_event_dev(void **args)
241
{
241
{
242
	if (evdev)
242
	char *evdevs;
243
		free(evdev);
243
	char *evdev;
244
244
	int i, j, fd_evdev = -1;
245
	evdev = strdup(args[0]);
246
245
247
	pthread_cancel(th_switchmon);
246
	pthread_cancel(th_switchmon);
247
	for (i = 0;i < evdev_count;i++) {
248
		close(fd_evdevs[i]);
249
	}
250
	evdevs = strdup(args[1]);
251
	evdev_count = *(int*)args[0];	
252
	j = 0;
253
	for (i = 0;i < evdev_count;i++, evdevs = NULL) {
254
		evdev = strtok(evdevs, ",");
255
		fd_evdev = open(evdev, O_RDONLY);
256
		if (fd_evdev != -1) {
257
			fd_evdevs[j] = fd_evdev;
258
			j++;
259
		} else {
260
			perror("failed to open event device");
261
		}
262
	}
263
	if (j == 0) { /* all input devices failed to open */
264
		evdev_count = -1;
265
		free(evdevs);
266
		return -1;
267
	}
248
268
249
	if (fd_evdev != -1)
269
	evdev_count = j;
250
		close(fd_evdev);
270
	free(evdevs);
251
252
	fd_evdev = open(evdev, O_RDONLY);
253
254
	switchmon_start(UPD_MON, config.tty_s);
271
	switchmon_start(UPD_MON, config.tty_s);
255
272
256
	return 0;
273
	return 0;
Lines 524-531 Link Here
524
541
525
	{	.cmd = "set event dev",
542
	{	.cmd = "set event dev",
526
		.handler = cmd_set_event_dev,
543
		.handler = cmd_set_event_dev,
527
		.args = 1,
544
		.args = 2,
528
		.specs = "s"
545
		.specs = "ds"
529
	},
546
	},
530
547
531
	{	.cmd = "set message",
548
	{	.cmd = "set message",
Lines 628-634 Link Here
628
					continue;
645
					continue;
629
646
630
				for (j = 0; j < known_cmds[i].args; j++) {
647
				for (j = 0; j < known_cmds[i].args; j++) {
631
					for (; buf[k] == ' '; buf[k] = 0, k++);
648
					for (; buf[k] == ' '; buf[k] = '\0', k++);
632
					if (!buf[k]) {
649
					if (!buf[k]) {
633
						args[j] = NULL;
650
						args[j] = NULL;
634
						continue;
651
						continue;
(-)a/core/src/libfbsplash.c (-13 / +42 lines)
Lines 588-593 Link Here
588
	return -1;
588
	return -1;
589
}
589
}
590
590
591
#define EVDV_BUF_LEN 128 
592
591
/**
593
/**
592
 * Try to set the event device for the splash daemon.
594
 * Try to set the event device for the splash daemon.
593
 *
595
 *
Lines 595-604 Link Here
595
 */
597
 */
596
int fbsplash_set_evdev(void)
598
int fbsplash_set_evdev(void)
597
{
599
{
598
	char buf[128];
600
	char buf[EVDV_BUF_LEN];
601
	char evdev_devs[EVDV_BUF_LEN * MAX_KBDS];
599
	FILE *fp;
602
	FILE *fp;
600
	int i, j;
603
	int i, j;
601
604
	int kbd_count;
605
	int max_chars, chars_left, dev_path_len;
606
	char dev_path[] = PATH_DEV "/input/";
607
	dev_path_len = strlen(dev_path);
602
	char *evdev_cmds[] = {
608
	char *evdev_cmds[] = {
603
		"/bin/grep -Hsi keyboard " PATH_SYS "/class/input/input*/name | /bin/sed -e 's#.*input\\([0-9]*\\)/name.*#event\\1#'",
609
		"/bin/grep -Hsi keyboard " PATH_SYS "/class/input/input*/name | /bin/sed -e 's#.*input\\([0-9]*\\)/name.*#event\\1#'",
604
		"/bin/grep -Hsi keyboard " PATH_SYS "/class/input/event*/device/driver/description | /bin/grep -o 'event[0-9]\\+'",
610
		"/bin/grep -Hsi keyboard " PATH_SYS "/class/input/event*/device/driver/description | /bin/grep -o 'event[0-9]\\+'",
Lines 608-629 Link Here
608
614
609
	/* Try to activate the event device interface so that F2 can
615
	/* Try to activate the event device interface so that F2 can
610
	 * be used to switch from verbose to silent. */
616
	 * be used to switch from verbose to silent. */
611
	buf[0] = 0;
617
	buf[0] = '\0';
612
	for (i = 0; i < sizeof(evdev_cmds)/sizeof(char*); i++) {
618
	kbd_count = 0;
619
	max_chars = sizeof(evdev_devs) / sizeof(char*);
620
	chars_left = max_chars - 1;
621
	evdev_devs[0] = '\0';
622
	for (i = 0; i < sizeof(evdev_cmds) / sizeof(char*); i++) {
613
		fp = popen(evdev_cmds[i], "r");
623
		fp = popen(evdev_cmds[i], "r");
614
		if (fp) {
624
		if (fp) {
615
			fgets(buf, 128, fp);
625
			while (fgets(buf, 128, fp) && kbd_count < MAX_KBDS) {
616
			if ((j = strlen(buf)) > 0) {
626
				if ((j = strlen(buf)) > 0) {
617
				if (buf[j-1] == '\n')
627
					if (buf[j-1] == '\n')
618
					buf[j-1] = 0;
628
						buf[j-1] = ',';
619
				break;
629
					if (chars_left < (j + dev_path_len)) {
630
						break;
631
					}
632
					kbd_count++;
633
					strncat(evdev_devs, dev_path, chars_left);
634
					chars_left -= dev_path_len;
635
					strncat(evdev_devs, buf, chars_left);
636
					chars_left -= j;
637
				}
638
			}
639
			/* replace the last ',' with '\n' */
640
			if (chars_left > 0 && evdev_devs[0] != '\0') {
641
				j = strlen(evdev_devs);
642
				if (j > 2) {
643
					evdev_devs[j - 1] = '\n';
644
				}
620
			}
645
			}
621
			pclose(fp);
646
			pclose(fp);
622
		}
647
		}
648
		if (kbd_count > 0) 
649
			break;
623
	}
650
	}
624
651
625
	if (buf[0] != 0) {
652
	if (evdev_devs[0] != '\0') {
626
		fbsplash_send("set event dev " PATH_DEV "/input/%s\n", buf);
653
		fbsplash_send("set event dev %d %s", kbd_count, evdev_devs);
627
		return 0;
654
		return 0;
628
	} else {
655
	} else {
629
		return -1;
656
		return -1;
Lines 661-666 Link Here
661
	return 0;
688
	return 0;
662
}
689
}
663
690
691
#define MAX_CMD 2048
692
664
/**
693
/**
665
 * Send stuff to the splash daemon using the splash FIFO.
694
 * Send stuff to the splash daemon using the splash FIFO.
666
 *
695
 *
Lines 668-674 Link Here
668
 */
697
 */
669
int fbsplash_send(const char *fmt, ...)
698
int fbsplash_send(const char *fmt, ...)
670
{
699
{
671
	char cmd[256];
700
	char cmd[MAX_CMD];
672
	va_list ap;
701
	va_list ap;
673
702
674
	if (!fp_fifo) {
703
	if (!fp_fifo) {
Lines 690-696 Link Here
690
	}
719
	}
691
720
692
	va_start(ap, fmt);
721
	va_start(ap, fmt);
693
	vsnprintf(cmd, 256, fmt, ap);
722
	vsnprintf(cmd, MAX_CMD, fmt, ap);
694
	va_end(ap);
723
	va_end(ap);
695
724
696
	fprintf(fp_fifo, cmd);
725
	fprintf(fp_fifo, cmd);

Return to bug 450156