sun_kbd.c revision ee3138f1
1ee3138f1Smrg/*
2ee3138f1Smrg * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
3ee3138f1Smrg * Copyright 1993 by David Dawes <dawes@XFree86.org>
4ee3138f1Smrg * Copyright 1999 by David Holland <davidh@iquest.net)
5ee3138f1Smrg *
6ee3138f1Smrg * Permission to use, copy, modify, distribute, and sell this software and its
7ee3138f1Smrg * documentation for any purpose is hereby granted without fee, provided that
8ee3138f1Smrg * the above copyright notice appear in all copies and that both that copyright
9ee3138f1Smrg * notice and this permission notice appear in supporting documentation, and
10ee3138f1Smrg * that the names of Thomas Roell, David Dawes, and David Holland not be used
11ee3138f1Smrg * in advertising or publicity pertaining to distribution of the software
12ee3138f1Smrg * without specific, written prior permission.  Thomas Roell, David Dawes, and
13ee3138f1Smrg * David Holland make no representations about the suitability of this software
14ee3138f1Smrg * for any purpose.  It is provided "as is" without express or implied
15ee3138f1Smrg * warranty.
16ee3138f1Smrg *
17ee3138f1Smrg * THOMAS ROELL, DAVID DAWES, AND DAVID HOLLAND DISCLAIM ALL WARRANTIES WITH
18ee3138f1Smrg * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
19ee3138f1Smrg * AND FITNESS.  IN NO EVENT SHALL THOMAS ROELL, DAVID DAWES, OR DAVID HOLLAND
20ee3138f1Smrg * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21ee3138f1Smrg * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
22ee3138f1Smrg * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
23ee3138f1Smrg * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24ee3138f1Smrg */
25ee3138f1Smrg/* Copyright 2004-2007 Sun Microsystems, Inc.  All rights reserved.
26ee3138f1Smrg *
27ee3138f1Smrg * Permission is hereby granted, free of charge, to any person obtaining a
28ee3138f1Smrg * copy of this software and associated documentation files (the
29ee3138f1Smrg * "Software"), to deal in the Software without restriction, including
30ee3138f1Smrg * without limitation the rights to use, copy, modify, merge, publish,
31ee3138f1Smrg * distribute, and/or sell copies of the Software, and to permit persons
32ee3138f1Smrg * to whom the Software is furnished to do so, provided that the above
33ee3138f1Smrg * copyright notice(s) and this permission notice appear in all copies of
34ee3138f1Smrg * the Software and that both the above copyright notice(s) and this
35ee3138f1Smrg * permission notice appear in supporting documentation.
36ee3138f1Smrg *
37ee3138f1Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
38ee3138f1Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
39ee3138f1Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
40ee3138f1Smrg * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
41ee3138f1Smrg * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
42ee3138f1Smrg * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
43ee3138f1Smrg * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
44ee3138f1Smrg * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
45ee3138f1Smrg * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
46ee3138f1Smrg *
47ee3138f1Smrg * Except as contained in this notice, the name of a copyright holder
48ee3138f1Smrg * shall not be used in advertising or otherwise to promote the sale, use
49ee3138f1Smrg * or other dealings in this Software without prior written authorization
50ee3138f1Smrg * of the copyright holder.
51ee3138f1Smrg */
52ee3138f1Smrg
53ee3138f1Smrg#ifdef HAVE_CONFIG_H
54ee3138f1Smrg#include "config.h"
55ee3138f1Smrg#endif
56ee3138f1Smrg
57ee3138f1Smrg#include "xf86.h"
58ee3138f1Smrg#include "xf86Priv.h"
59ee3138f1Smrg#include "xf86_OSlib.h"
60ee3138f1Smrg#include "xf86OSKbd.h"
61ee3138f1Smrg#include "sun_kbd.h"
62ee3138f1Smrg
63ee3138f1Smrg#include <sys/stropts.h>
64ee3138f1Smrg#include <sys/vuid_event.h>
65ee3138f1Smrg#include <sys/kbd.h>
66ee3138f1Smrg
67ee3138f1Smrgstatic void
68ee3138f1SmrgsunKbdSetLeds(InputInfoPtr pInfo, int leds)
69ee3138f1Smrg{
70ee3138f1Smrg    int i;
71ee3138f1Smrg
72ee3138f1Smrg    SYSCALL(i = ioctl(pInfo->fd, KIOCSLED, &leds));
73ee3138f1Smrg    if (i < 0) {
74ee3138f1Smrg	xf86Msg(X_ERROR, "%s: Failed to set keyboard LED's: %s\n",
75ee3138f1Smrg                pInfo->name, strerror(errno));
76ee3138f1Smrg    }
77ee3138f1Smrg}
78ee3138f1Smrg
79ee3138f1Smrg
80ee3138f1Smrgstatic int
81ee3138f1SmrgsunKbdGetLeds(InputInfoPtr pInfo)
82ee3138f1Smrg{
83ee3138f1Smrg    int i, leds = 0;
84ee3138f1Smrg
85ee3138f1Smrg    SYSCALL(i = ioctl(pInfo->fd, KIOCGLED, &leds));
86ee3138f1Smrg    if (i < 0) {
87ee3138f1Smrg        xf86Msg(X_ERROR, "%s: Failed to get keyboard LED's: %s\n",
88ee3138f1Smrg                pInfo->name, strerror(errno));
89ee3138f1Smrg    }
90ee3138f1Smrg    return leds;
91ee3138f1Smrg}
92ee3138f1Smrg
93ee3138f1Smrg
94ee3138f1Smrg/*
95ee3138f1Smrg * Save initial keyboard state.  This is called at the start of each server
96ee3138f1Smrg * generation.
97ee3138f1Smrg */
98ee3138f1Smrgstatic int
99ee3138f1SmrgKbdInit(InputInfoPtr pInfo, int what)
100ee3138f1Smrg{
101ee3138f1Smrg    KbdDevPtr pKbd = (KbdDevPtr) pInfo->private;
102ee3138f1Smrg    sunKbdPrivPtr priv = (sunKbdPrivPtr) pKbd->private;
103ee3138f1Smrg    pointer options = pInfo->options;
104ee3138f1Smrg
105ee3138f1Smrg    int	ktype, klayout, i;
106ee3138f1Smrg    const char *ktype_name;
107ee3138f1Smrg
108ee3138f1Smrg    priv->otranslation 	= -1;
109ee3138f1Smrg    priv->odirect 	= -1;
110ee3138f1Smrg
111ee3138f1Smrg    if (options != NULL) {
112ee3138f1Smrg	priv->strmod = xf86SetStrOption(options, "StreamsModule", NULL);
113ee3138f1Smrg    } else {
114ee3138f1Smrg	priv->strmod 		= NULL;
115ee3138f1Smrg    }
116ee3138f1Smrg
117ee3138f1Smrg    if (priv->strmod) {
118ee3138f1Smrg	SYSCALL(i = ioctl(pInfo->fd, I_PUSH, priv->strmod));
119ee3138f1Smrg	if (i < 0) {
120ee3138f1Smrg	    xf86Msg(X_ERROR,
121ee3138f1Smrg		    "%s: cannot push module '%s' onto keyboard device: %s\n",
122ee3138f1Smrg		    pInfo->name, priv->strmod, strerror(errno));
123ee3138f1Smrg	}
124ee3138f1Smrg    }
125ee3138f1Smrg
126ee3138f1Smrg    SYSCALL(i = ioctl(pInfo->fd, KIOCTYPE, &ktype));
127ee3138f1Smrg    if (i < 0) {
128ee3138f1Smrg	xf86Msg(X_ERROR, "%s: Unable to determine keyboard type: %s\n",
129ee3138f1Smrg		pInfo->name, strerror(errno));
130ee3138f1Smrg	return BadImplementation;
131ee3138f1Smrg    }
132ee3138f1Smrg
133ee3138f1Smrg    SYSCALL(i = ioctl(pInfo->fd, KIOCLAYOUT, &klayout));
134ee3138f1Smrg    if (i < 0) {
135ee3138f1Smrg	xf86Msg(X_ERROR, "%s: Unable to determine keyboard layout: %s\n",
136ee3138f1Smrg		pInfo->name, strerror(errno));
137ee3138f1Smrg	return BadImplementation;
138ee3138f1Smrg    }
139ee3138f1Smrg
140ee3138f1Smrg    switch (ktype) {
141ee3138f1Smrg    case KB_SUN3:
142ee3138f1Smrg	ktype_name = "Sun Type 3"; break;
143ee3138f1Smrg    case KB_SUN4:
144ee3138f1Smrg	ktype_name = "Sun Type 4/5/6"; break;
145ee3138f1Smrg    case KB_USB:
146ee3138f1Smrg	ktype_name = "USB"; break;
147ee3138f1Smrg    case KB_PC:
148ee3138f1Smrg	ktype_name = "PC"; break;
149ee3138f1Smrg    default:
150ee3138f1Smrg	ktype_name = "Unknown"; break;
151ee3138f1Smrg    }
152ee3138f1Smrg
153ee3138f1Smrg    xf86Msg(X_PROBED, "%s: Keyboard type: %s (%d)\n",
154ee3138f1Smrg	    pInfo->name, ktype_name, ktype);
155ee3138f1Smrg    xf86Msg(X_PROBED, "%s: Keyboard layout: %d\n", pInfo->name, klayout);
156ee3138f1Smrg
157ee3138f1Smrg    priv->ktype 	= ktype;
158ee3138f1Smrg    priv->oleds 	= sunKbdGetLeds(pInfo);
159ee3138f1Smrg
160ee3138f1Smrg    return Success;
161ee3138f1Smrg}
162ee3138f1Smrg
163ee3138f1Smrg
164ee3138f1Smrgstatic int
165ee3138f1SmrgKbdOn(InputInfoPtr pInfo, int what)
166ee3138f1Smrg{
167ee3138f1Smrg    KbdDevPtr pKbd = (KbdDevPtr) pInfo->private;
168ee3138f1Smrg    sunKbdPrivPtr priv = (sunKbdPrivPtr) pKbd->private;
169ee3138f1Smrg
170ee3138f1Smrg    int	ktrans, kdirect, i;
171ee3138f1Smrg
172ee3138f1Smrg    SYSCALL(i = ioctl(pInfo->fd, KIOCGDIRECT, &kdirect));
173ee3138f1Smrg    if (i < 0) {
174ee3138f1Smrg	xf86Msg(X_ERROR,
175ee3138f1Smrg		"%s: Unable to determine keyboard direct setting: %s\n",
176ee3138f1Smrg		pInfo->name, strerror(errno));
177ee3138f1Smrg	return BadImplementation;
178ee3138f1Smrg    }
179ee3138f1Smrg
180ee3138f1Smrg    priv->odirect = kdirect;
181ee3138f1Smrg    kdirect = 1;
182ee3138f1Smrg
183ee3138f1Smrg    SYSCALL(i = ioctl(pInfo->fd, KIOCSDIRECT, &kdirect));
184ee3138f1Smrg    if (i < 0) {
185ee3138f1Smrg	xf86Msg(X_ERROR, "%s: Failed turning keyboard direct mode on: %s\n",
186ee3138f1Smrg			pInfo->name, strerror(errno));
187ee3138f1Smrg	return BadImplementation;
188ee3138f1Smrg    }
189ee3138f1Smrg
190ee3138f1Smrg    /* Setup translation */
191ee3138f1Smrg
192ee3138f1Smrg    SYSCALL(i = ioctl(pInfo->fd, KIOCGTRANS, &ktrans));
193ee3138f1Smrg    if (i < 0) {
194ee3138f1Smrg	xf86Msg(X_ERROR,
195ee3138f1Smrg		"%s: Unable to determine keyboard translation mode: %s\n",
196ee3138f1Smrg		pInfo->name, strerror(errno));
197ee3138f1Smrg	return BadImplementation;
198ee3138f1Smrg    }
199ee3138f1Smrg
200ee3138f1Smrg    priv->otranslation = ktrans;
201ee3138f1Smrg    ktrans = TR_UNTRANS_EVENT;
202ee3138f1Smrg
203ee3138f1Smrg    SYSCALL(i = ioctl(pInfo->fd, KIOCTRANS, &ktrans));
204ee3138f1Smrg    if (i < 0) {
205ee3138f1Smrg	xf86Msg(X_ERROR, "%s: Failed setting keyboard translation mode: %s\n",
206ee3138f1Smrg			pInfo->name, strerror(errno));
207ee3138f1Smrg	return BadImplementation;
208ee3138f1Smrg    }
209ee3138f1Smrg
210ee3138f1Smrg    return Success;
211ee3138f1Smrg}
212ee3138f1Smrg
213ee3138f1Smrgstatic int
214ee3138f1SmrgKbdOff(InputInfoPtr pInfo, int what)
215ee3138f1Smrg{
216ee3138f1Smrg    KbdDevPtr pKbd = (KbdDevPtr) pInfo->private;
217ee3138f1Smrg    sunKbdPrivPtr priv = (sunKbdPrivPtr) pKbd->private;
218ee3138f1Smrg
219ee3138f1Smrg    int i;
220ee3138f1Smrg
221ee3138f1Smrg    /* restore original state */
222ee3138f1Smrg
223ee3138f1Smrg    sunKbdSetLeds(pInfo, priv->oleds);
224ee3138f1Smrg
225ee3138f1Smrg    if (priv->otranslation != -1) {
226ee3138f1Smrg        SYSCALL(i = ioctl(pInfo->fd, KIOCTRANS, &priv->otranslation));
227ee3138f1Smrg	if (i < 0) {
228ee3138f1Smrg	    xf86Msg(X_ERROR,
229ee3138f1Smrg		    "%s: Unable to restore keyboard translation mode: %s\n",
230ee3138f1Smrg		    pInfo->name, strerror(errno));
231ee3138f1Smrg	    return BadImplementation;
232ee3138f1Smrg	}
233ee3138f1Smrg	priv->otranslation = -1;
234ee3138f1Smrg    }
235ee3138f1Smrg
236ee3138f1Smrg    if (priv->odirect != -1) {
237ee3138f1Smrg        SYSCALL(i = ioctl(pInfo->fd, KIOCSDIRECT, &priv->odirect));
238ee3138f1Smrg	if (i < 0) {
239ee3138f1Smrg	    xf86Msg(X_ERROR,
240ee3138f1Smrg		    "%s: Unable to restore keyboard direct setting: %s\n",
241ee3138f1Smrg		    pInfo->name, strerror(errno));
242ee3138f1Smrg	    return BadImplementation;
243ee3138f1Smrg	}
244ee3138f1Smrg	priv->odirect = -1;
245ee3138f1Smrg    }
246ee3138f1Smrg
247ee3138f1Smrg    if (priv->strmod) {
248ee3138f1Smrg	SYSCALL(i = ioctl(pInfo->fd, I_POP, priv->strmod));
249ee3138f1Smrg	if (i < 0) {
250ee3138f1Smrg            xf86Msg(X_WARNING,
251ee3138f1Smrg		    "%s: cannot pop module '%s' off keyboard device: %s\n",
252ee3138f1Smrg		    pInfo->name, priv->strmod, strerror(errno));
253ee3138f1Smrg	}
254ee3138f1Smrg    }
255ee3138f1Smrg
256ee3138f1Smrg    return Success;
257ee3138f1Smrg}
258ee3138f1Smrg
259ee3138f1Smrg
260ee3138f1Smrgstatic void
261ee3138f1SmrgSoundKbdBell(InputInfoPtr pInfo, int loudness, int pitch, int duration)
262ee3138f1Smrg{
263ee3138f1Smrg    KbdDevPtr pKbd = (KbdDevPtr) pInfo->private;
264ee3138f1Smrg    sunKbdPrivPtr priv = (sunKbdPrivPtr) pKbd->private;
265ee3138f1Smrg
266ee3138f1Smrg    int	kbdCmd, i;
267ee3138f1Smrg#ifdef KIOCMKTONE
268ee3138f1Smrg    int cycles;
269ee3138f1Smrg    int mktonevalue;
270ee3138f1Smrg#endif
271ee3138f1Smrg
272ee3138f1Smrg    if (loudness && pitch)
273ee3138f1Smrg    {
274ee3138f1Smrg#ifdef KIOCMKTONE
275ee3138f1Smrg	if (pitch == 0)
276ee3138f1Smrg	    cycles = UINT16_MAX;
277ee3138f1Smrg	else if (pitch >= UINT16_MAX)
278ee3138f1Smrg	    cycles = 0;
279ee3138f1Smrg	else {
280ee3138f1Smrg	    cycles = (PIT_HZ + pitch / 2) / pitch;
281ee3138f1Smrg	    if (cycles > UINT16_MAX)
282ee3138f1Smrg		cycles = UINT16_MAX;
283ee3138f1Smrg	}
284ee3138f1Smrg
285ee3138f1Smrg	mktonevalue = cycles | (((duration * loudness * 20) / 1000) << 16);
286ee3138f1Smrg
287ee3138f1Smrg	errno = 0;
288ee3138f1Smrg	SYSCALL(i = ioctl (pInfo->fd, KIOCMKTONE, mktonevalue));
289ee3138f1Smrg	if (i == 0)
290ee3138f1Smrg	    return;
291ee3138f1Smrg
292ee3138f1Smrg	if (errno != EINVAL) {
293ee3138f1Smrg	    if (errno != EAGAIN)
294ee3138f1Smrg		xf86Msg(X_ERROR, "%s: Failed to activate bell: %s\n",
295ee3138f1Smrg			pInfo->name, strerror(errno));
296ee3138f1Smrg	    return;
297ee3138f1Smrg	}
298ee3138f1Smrg#endif
299ee3138f1Smrg
300ee3138f1Smrg 	kbdCmd = KBD_CMD_BELL;
301ee3138f1Smrg
302ee3138f1Smrg	SYSCALL(i = ioctl (pInfo->fd, KIOCCMD, &kbdCmd));
303ee3138f1Smrg	if (i < 0) {
304ee3138f1Smrg	    xf86Msg(X_ERROR, "%s: Failed to activate bell: %s\n",
305ee3138f1Smrg                pInfo->name, strerror(errno));
306ee3138f1Smrg	}
307ee3138f1Smrg
308ee3138f1Smrg	usleep(duration * loudness * 20);
309ee3138f1Smrg
310ee3138f1Smrg	kbdCmd = KBD_CMD_NOBELL;
311ee3138f1Smrg	SYSCALL(i = ioctl (pInfo->fd, KIOCCMD, &kbdCmd));
312ee3138f1Smrg	if (i < 0) {
313ee3138f1Smrg	     xf86Msg(X_ERROR, "%s: Failed to deactivate bell: %s\n",
314ee3138f1Smrg                pInfo->name, strerror(errno));
315ee3138f1Smrg	}
316ee3138f1Smrg    }
317ee3138f1Smrg}
318ee3138f1Smrg
319ee3138f1Smrgstatic void
320ee3138f1SmrgSetKbdLeds(InputInfoPtr pInfo, int leds)
321ee3138f1Smrg{
322ee3138f1Smrg    int real_leds = sunKbdGetLeds(pInfo);
323ee3138f1Smrg
324ee3138f1Smrg    real_leds &= ~(LED_CAPS_LOCK | LED_NUM_LOCK | LED_SCROLL_LOCK | LED_COMPOSE);
325ee3138f1Smrg
326ee3138f1Smrg    if (leds & XLED1)  real_leds |= LED_CAPS_LOCK;
327ee3138f1Smrg    if (leds & XLED2)  real_leds |= LED_NUM_LOCK;
328ee3138f1Smrg    if (leds & XLED3)  real_leds |= LED_SCROLL_LOCK;
329ee3138f1Smrg    if (leds & XLED4)  real_leds |= LED_COMPOSE;
330ee3138f1Smrg
331ee3138f1Smrg    sunKbdSetLeds(pInfo, real_leds);
332ee3138f1Smrg}
333ee3138f1Smrg
334ee3138f1Smrgstatic int
335ee3138f1SmrgGetKbdLeds(InputInfoPtr pInfo)
336ee3138f1Smrg{
337ee3138f1Smrg    int leds = 0;
338ee3138f1Smrg    int real_leds = sunKbdGetLeds(pInfo);
339ee3138f1Smrg
340ee3138f1Smrg    if (real_leds & LED_CAPS_LOCK)	leds |= XLED1;
341ee3138f1Smrg    if (real_leds & LED_NUM_LOCK)	leds |= XLED2;
342ee3138f1Smrg    if (real_leds & LED_SCROLL_LOCK)	leds |= XLED3;
343ee3138f1Smrg    if (real_leds & LED_COMPOSE)	leds |= XLED4;
344ee3138f1Smrg
345ee3138f1Smrg    return leds;
346ee3138f1Smrg}
347ee3138f1Smrg
348ee3138f1Smrg/* ARGSUSED0 */
349ee3138f1Smrgstatic void
350ee3138f1SmrgSetKbdRepeat(InputInfoPtr pInfo, char rad)
351ee3138f1Smrg{
352ee3138f1Smrg    /* Nothing to do */
353ee3138f1Smrg}
354ee3138f1Smrg
355ee3138f1Smrgstatic void
356ee3138f1SmrgReadInput(InputInfoPtr pInfo)
357ee3138f1Smrg{
358ee3138f1Smrg    KbdDevPtr pKbd = (KbdDevPtr) pInfo->private;
359ee3138f1Smrg    Firm_event event[64];
360ee3138f1Smrg    int        nBytes, i;
361ee3138f1Smrg
362ee3138f1Smrg    /* I certainly hope its not possible to read partial events */
363ee3138f1Smrg
364ee3138f1Smrg    if ((nBytes = read(pInfo->fd, (char *)event, sizeof(event))) > 0)
365ee3138f1Smrg    {
366ee3138f1Smrg        for (i = 0; i < (nBytes / sizeof(Firm_event)); i++) {
367ee3138f1Smrg	    pKbd->PostEvent(pInfo, event[i].id & 0xFF,
368ee3138f1Smrg			    event[i].value == VKEY_DOWN ? TRUE : FALSE);
369ee3138f1Smrg	}
370ee3138f1Smrg    }
371ee3138f1Smrg}
372ee3138f1Smrg
373ee3138f1Smrgstatic Bool
374ee3138f1SmrgOpenKeyboard(InputInfoPtr pInfo)
375ee3138f1Smrg{
376ee3138f1Smrg    const char *kbdPath = NULL;
377ee3138f1Smrg    const char *defaultKbd = "/dev/kbd";
378ee3138f1Smrg
379ee3138f1Smrg    if (pInfo->options != NULL) {
380ee3138f1Smrg	kbdPath = xf86SetStrOption(pInfo->options, "Device", NULL);
381ee3138f1Smrg    }
382ee3138f1Smrg    if (kbdPath == NULL) {
383ee3138f1Smrg        kbdPath = defaultKbd;
384ee3138f1Smrg    }
385ee3138f1Smrg
386ee3138f1Smrg    pInfo->fd = open(kbdPath, O_RDONLY | O_NONBLOCK);
387ee3138f1Smrg
388ee3138f1Smrg    if (pInfo->fd == -1) {
389ee3138f1Smrg        xf86Msg(X_ERROR, "%s: cannot open \"%s\"\n", pInfo->name, kbdPath);
390ee3138f1Smrg    } else {
391ee3138f1Smrg	xf86MsgVerb(X_INFO, 3, "%s: Opened device \"%s\"\n", pInfo->name,
392ee3138f1Smrg		    kbdPath);
393ee3138f1Smrg    }
394ee3138f1Smrg
395ee3138f1Smrg    if ((kbdPath != NULL) && (kbdPath != defaultKbd)) {
396ee3138f1Smrg	xfree(kbdPath);
397ee3138f1Smrg    }
398ee3138f1Smrg
399ee3138f1Smrg    if (pInfo->fd == -1) {
400ee3138f1Smrg	return FALSE;
401ee3138f1Smrg    } else {
402ee3138f1Smrg	pInfo->read_input = ReadInput;
403ee3138f1Smrg	return TRUE;
404ee3138f1Smrg    }
405ee3138f1Smrg}
406ee3138f1Smrg
407ee3138f1Smrg_X_EXPORT Bool
408ee3138f1Smrgxf86OSKbdPreInit(InputInfoPtr pInfo)
409ee3138f1Smrg{
410ee3138f1Smrg    KbdDevPtr pKbd = pInfo->private;
411ee3138f1Smrg
412ee3138f1Smrg    pKbd->KbdInit       = KbdInit;
413ee3138f1Smrg    pKbd->KbdOn         = KbdOn;
414ee3138f1Smrg    pKbd->KbdOff        = KbdOff;
415ee3138f1Smrg    pKbd->Bell          = SoundKbdBell;
416ee3138f1Smrg    pKbd->SetLeds       = SetKbdLeds;
417ee3138f1Smrg    pKbd->GetLeds       = GetKbdLeds;
418ee3138f1Smrg    pKbd->SetKbdRepeat  = SetKbdRepeat;
419ee3138f1Smrg    pKbd->KbdGetMapping = KbdGetMapping;
420ee3138f1Smrg
421ee3138f1Smrg    pKbd->RemapScanCode = NULL;
422ee3138f1Smrg    pKbd->GetSpecialKey = NULL;
423ee3138f1Smrg    pKbd->SpecialKey    = NULL;
424ee3138f1Smrg
425ee3138f1Smrg    pKbd->OpenKeyboard = OpenKeyboard;
426ee3138f1Smrg
427ee3138f1Smrg    pKbd->vtSwitchSupported = FALSE;
428ee3138f1Smrg    pKbd->CustomKeycodes = FALSE;
429ee3138f1Smrg
430ee3138f1Smrg    pKbd->private = xcalloc(sizeof(sunKbdPrivRec), 1);
431ee3138f1Smrg    if (pKbd->private == NULL) {
432ee3138f1Smrg       xf86Msg(X_ERROR,"can't allocate keyboard OS private data\n");
433ee3138f1Smrg       return FALSE;
434ee3138f1Smrg    } else {
435ee3138f1Smrg	sunKbdPrivPtr priv = (sunKbdPrivPtr) pKbd->private;
436ee3138f1Smrg	priv->otranslation = -1;
437ee3138f1Smrg	priv->odirect = -1;
438ee3138f1Smrg    }
439ee3138f1Smrg
440ee3138f1Smrg    return TRUE;
441ee3138f1Smrg}
442