From owner-freebsd-questions@FreeBSD.ORG Wed Dec 15 16:37:14 2004 Return-Path: Delivered-To: freebsd-questions@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 58C1116A4CE for ; Wed, 15 Dec 2004 16:37:14 +0000 (GMT) Received: from server.absolute-media.de (server.absolute-media.de [213.239.231.9]) by mx1.FreeBSD.org (Postfix) with ESMTP id 29E7E43D5A for ; Wed, 15 Dec 2004 16:37:13 +0000 (GMT) (envelope-from NKoch@demig.de) Received: from localhost (unknown [127.0.0.1]) by server.absolute-media.de (Postfix) with ESMTP id 7987128E65 for ; Wed, 15 Dec 2004 17:33:12 +0100 (CET) Received: from server.absolute-media.de ([127.0.0.1]) by localhost (server [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 06733-09 for ; Wed, 15 Dec 2004 17:33:11 +0100 (CET) Received: from mailhost.demig (p50929B42.dip0.t-ipconnect.de [80.146.155.66]) by server.absolute-media.de (Postfix) with ESMTP id 9FBC828B32 for ; Wed, 15 Dec 2004 17:33:11 +0100 (CET) Received: from ws-ew-3 (ws-ew-3 [192.168.1.72]) by mailhost.demig (8.13.1/8.12.11) with SMTP id iBFGY1VI041516 for ; Wed, 15 Dec 2004 17:34:02 +0100 (CET) (envelope-from NKoch@demig.de) From: "Norbert Koch" To: Date: Wed, 15 Dec 2004 17:34:01 +0100 Message-ID: <000001c4e2c3$e22397a0$4801a8c0@ws-ew-3.W2KDEMIG> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook 8.5, Build 4.71.2173.0 Importance: Normal X-MimeOLE: Produced By Microsoft MimeOLE V4.72.2120.0 X-Virus-Scanned: by amavisd-new at absolute-media.de Subject: using two keyboards at the same time X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 15 Dec 2004 16:37:14 -0000 Hello. I know, the syscons driver does not allow to have two keyboards attached at the same time. So my idea was to have a userland application which polls the keyboard(s) currently _not_ attached to syscons using select(2) or poll(2). >From reading the source code under /sys/dev/kbd I thought this should work. I made this simple test: I attached syscons to /dev/kbd1 and ran "cat /dev/kbd0". As expected I saw characters coming from both keyboards. Then I wrote a program to do the selecting and switching. Well, it does not work. Select never returns. Does anyone have an idea? May be I just made some stupid mistake. Thank you. >-------------------------------------------- #include #include #include #include #include #include #include #include #include #include #define MAX_DEVICES 5 #define TEST #define STR(x) #x #define XSTR(x) STR (x) static void usage (void) { fprintf (stderr, "usage: autosw [ -D ] [ -d ] [ [ -f ] ... ]\n" " -D : do not detach\n" " -d : enable debug output\n" " -f : specify keyboard device (up to " XSTR (MAX_DEVICES) ")\n" " if no keyboard devices specified\n" " /dev/kbd0 and /dev/kbd1 are polled\n"); exit (1); } /* * borrowed from /usr/src/usr.sbin/kbdcontrol/kbdcontrol.c */ static int set_keyboard_fd (int fd) { keyboard_info_t info; if (ioctl (fd, KDGKBINFO, & info) == -1) { close (fd); return -1; }; ioctl (fd, CONS_RELKBD, 0); close (fd); if (ioctl (0, CONS_SETKBD, info.kb_index) == -1) { return -1; }; return 0; } static int set_keyboard (char * device) { int fd; fd = open (device, O_RDONLY); if (fd < 0) { return -1; }; return set_keyboard_fd (fd); } int main (int argc, char ** argv) { char * devices[MAX_DEVICES]; fd_set ifds, ofds; int ch, i, fd, maxfd, no_devices = 0, debug = 0, detach = 1, detached = 0; struct stat sb; while ((ch = getopt (argc, argv, "Ddf:h")) != -1) { switch (ch) { case 'D': detach = 0; break; case 'd': ++ debug; break; case 'f': if (no_devices >= MAX_DEVICES) { fprintf (stderr, "too many devices\n"); exit (1); }; if (stat (optarg, & sb) < 0) { fprintf (stderr, "cannot stat %s: %s\n", optarg, strerror (errno)); exit (1); }; if ((sb.st_mode & S_IFCHR) == 0) { fprintf (stderr, "not a character device: %s\n", optarg); exit (1); }; devices[no_devices ++] = strdup (optarg); continue; case 'h': case '?': default: usage (); } }; /* * no devices specified, use default */ if (no_devices == 0) { devices[0] = "/dev/kbd0"; devices[1] = "/dev/kbd1"; no_devices = 2; if (debug) { fprintf (stderr, "using default devices\n"); }; }; /* * switch syscons to first keyboard */ #ifndef TEST for (i = -1; ++ i < no_devices;) #else for (i = 1; i == 1; ++ i) #endif { if (set_keyboard (devices[i]) == 0) { if (debug) { fprintf (stderr, "selecting keyboard %s\n", devices[i]); }; break; } }; for (;;) { /* * try to open all devices for select */ FD_ZERO (& ifds); maxfd = -1; #ifndef TEST for (i = -1; ++ i < no_devices;) #else for (i = 0; i == 0; ++ i) #endif { fd = open (devices[i], O_RDONLY|O_NONBLOCK); if (fd >= 0) { if (debug) { fprintf (stderr, "polling %s", devices[i]); }; if (debug >= 2) { fprintf (stderr, " fd=%u", fd); }; if (debug) { fprintf (stderr, "\n"); }; FD_SET (fd, & ifds); if (fd > maxfd) { maxfd = fd; } } }; if (maxfd < 0) { fprintf (stderr, "could not open any device\n"); exit (1); }; if (detach && ! detached && ! debug) { daemon (0, 0); detached = 1; }; ofds = ifds; if (debug >= 2) { fprintf (stderr, "polling maxfd=%u\n", maxfd); }; /* ***** !!! never returns !!! */ if (select (maxfd, & ofds, NULL, NULL, NULL) == -1) { exit (0); }; if (debug) { fprintf (stderr, "polled successfully\n"); }; /* * find keyboard where select returned some activity */ for (fd = -1; ++ fd < maxfd; ++ fd) { if (FD_ISSET (fd, & ofds)) { if (debug) { fprintf (stderr, "switching keyboard\n"); }; if (debug >= 2) { fprintf (stderr, " fd=%u", fd); }; if (debug) { fprintf (stderr, "\n"); }; /* * switch to keyboard with activity */ set_keyboard_fd (fd); FD_ZERO (& ofds); } else if (FD_ISSET (fd, & ifds)) { if (debug >= 2) { fprintf (stderr, "closing fd=%u\n", fd); }; close (fd); } } } }