159a1f54aStsutsui/* $NetBSD: x68kKbd.c,v 1.19 2025/06/22 22:33:49 tsutsui Exp $ */
2ba64b02eStsutsui/*-------------------------------------------------------------------------
3ba64b02eStsutsui * Copyright (c) 1996 Yasushi Yamasaki
4ba64b02eStsutsui * All rights reserved.
5ba64b02eStsutsui *
6ba64b02eStsutsui * Redistribution and use in source and binary forms, with or without
7ba64b02eStsutsui * modification, are permitted provided that the following conditions
8ba64b02eStsutsui * are met:
9ba64b02eStsutsui * 1. Redistributions of source code must retain the above copyright
10ba64b02eStsutsui *    notice, this list of conditions and the following disclaimer.
11ba64b02eStsutsui * 2. Redistributions in binary form must reproduce the above copyright
12ba64b02eStsutsui *    notice, this list of conditions and the following disclaimer in the
13ba64b02eStsutsui *    documentation and/or other materials provided with the distribution.
14ba64b02eStsutsui *
15ba64b02eStsutsui * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16ba64b02eStsutsui * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17ba64b02eStsutsui * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18ba64b02eStsutsui * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19ba64b02eStsutsui * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20ba64b02eStsutsui * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21ba64b02eStsutsui * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22ba64b02eStsutsui * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23ba64b02eStsutsui * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24ba64b02eStsutsui * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25ba64b02eStsutsui *-----------------------------------------------------------------------*/
26ba64b02eStsutsui
27ba64b02eStsutsui/*-
28ba64b02eStsutsui * Copyright (c) 1987 by the Regents of the University of California
29ba64b02eStsutsui *
30ba64b02eStsutsui * Permission to use, copy, modify, and distribute this
31ba64b02eStsutsui * software and its documentation for any purpose and without
32ba64b02eStsutsui * fee is hereby granted, provided that the above copyright
33ba64b02eStsutsui * notice appear in all copies.  The University of California
34ba64b02eStsutsui * makes no representations about the suitability of this
35ba64b02eStsutsui * software for any purpose.  It is provided "as is" without
36ba64b02eStsutsui * express or implied warranty.
37ba64b02eStsutsui */
38ba64b02eStsutsui
39ba64b02eStsutsui/************************************************************
40ba64b02eStsutsuiCopyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
41ba64b02eStsutsui
42ba64b02eStsutsui                    All Rights Reserved
43ba64b02eStsutsui
44ba64b02eStsutsuiPermission  to  use,  copy,  modify,  and  distribute   this
45ba64b02eStsutsuisoftware  and  its documentation for any purpose and without
46ba64b02eStsutsuifee is hereby granted, provided that the above copyright no-
47ba64b02eStsutsuitice  appear  in all copies and that both that copyright no-
48ba64b02eStsutsuitice and this permission notice appear in  supporting  docu-
49ba64b02eStsutsuimentation,  and  that the names of Sun or X Consortium
50ab290810Stsutsuinot be used in advertising or publicity pertaining to
51ab290810Stsutsuidistribution  of  the software  without specific prior
52ab290810Stsutsuiwritten permission. Sun and X Consortium make no
53ab290810Stsutsuirepresentations about the suitability of this software for
54ab290810Stsutsuiany purpose. It is provided "as is" without any express or
55ba64b02eStsutsuiimplied warranty.
56ba64b02eStsutsui
57ba64b02eStsutsuiSUN DISCLAIMS ALL WARRANTIES WITH REGARD TO  THIS  SOFTWARE,
58ba64b02eStsutsuiINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
59ba64b02eStsutsuiNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE  LI-
60ba64b02eStsutsuiABLE  FOR  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
61ba64b02eStsutsuiANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,  DATA  OR
62ba64b02eStsutsuiPROFITS,  WHETHER  IN  AN  ACTION OF CONTRACT, NEGLIGENCE OR
63ba64b02eStsutsuiOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
64ba64b02eStsutsuiTHE USE OR PERFORMANCE OF THIS SOFTWARE.
65ba64b02eStsutsui
66ba64b02eStsutsui********************************************************/
67ba64b02eStsutsui
68ba64b02eStsutsui#include "x68k.h"
69ba64b02eStsutsui#include "mi.h"
70ba64b02eStsutsui
71ba64b02eStsutsui#include <X11/X.h>
72ba64b02eStsutsui#include <X11/Xproto.h>
73ba64b02eStsutsui#include <X11/keysym.h>
74ba64b02eStsutsui#include "screenint.h"
75ba64b02eStsutsui#include "inputstr.h"
76909daefdSmrg#include "eventstr.h"
77ba64b02eStsutsui#include "misc.h"
78ba64b02eStsutsui#include "scrnintstr.h"
79ba64b02eStsutsui#include "servermd.h"
80ba64b02eStsutsui
81ba64b02eStsutsui#include <X11/extensions/XKB.h>
82ba64b02eStsutsui#include "xkbsrv.h"
83ba64b02eStsutsui
84ba64b02eStsutsui#define MIN_KEYCODE     7       /* necessary to avoid the mouse buttons */
85ba64b02eStsutsui#define MAX_KEYCODE     255     /* limited by the protocol */
86ba64b02eStsutsui
879decb2cdStsutsuitypedef struct _X68kKbdPriv {
889decb2cdStsutsui    int type;
899decb2cdStsutsui    int fd;
909decb2cdStsutsui    Leds leds;
9162918564Stsutsui    Firm_event evbuf[X68K_MAXEVENTS];
929decb2cdStsutsui} X68kKbdPriv, *X68kKbdPrivPtr;
939decb2cdStsutsui
94ba64b02eStsutsuiDeviceIntPtr x68kKeyboardDevice = NULL;
95ba64b02eStsutsui
9645f60b5bStsutsuistatic void x68kKbdEvents(int, int, void *);
97ba64b02eStsutsuistatic void x68kInitModMap(KeySymsRec *, CARD8 *);
98ba64b02eStsutsuistatic void x68kInitKbdNames(XkbRMLVOSet *, X68kKbdPrivPtr);
9962918564Stsutsuistatic int x68kKbdGetEvents(DeviceIntPtr);
10045f60b5bStsutsuistatic void x68kKbdEnqueueEvent(DeviceIntPtr, Firm_event *);
101ba64b02eStsutsuistatic void x68kKbdRingBell(DeviceIntPtr, int, int);
1025ca846b1Stsutsuistatic void x68kKbdBell(int, DeviceIntPtr, void *, int);
103ba64b02eStsutsuistatic void x68kKbdCtrl(DeviceIntPtr, KeybdCtrl *);
1049b65525fStsutsuistatic void x68kSetLeds(X68kKbdPrivPtr, uint8_t);
105ba64b02eStsutsui
10645f60b5bStsutsui/*------------------------------------------------------------------------
10745f60b5bStsutsui * x68kKbdEvents --
10845f60b5bStsutsui *	When registered polled keyboard input event handler is invoked,
10945f60b5bStsutsui *	read device events and enqueue them using the mi event queue.
11045f60b5bStsutsui * Results:
11145f60b5bStsutsui *	None.
11245f60b5bStsutsui *
11345f60b5bStsutsui *----------------------------------------------------------------------*/
11472502d70Stsutsuistatic void
11545f60b5bStsutsuix68kKbdEvents(int fd, int ready, void *data)
11672502d70Stsutsui{
11762918564Stsutsui    int i, numEvents;
11845f60b5bStsutsui    DeviceIntPtr device = (DeviceIntPtr)data;
11962918564Stsutsui    DevicePtr pKeyboard = &device->public;
12062918564Stsutsui    X68kKbdPrivPtr pPriv = pKeyboard->devicePrivate;
12145f60b5bStsutsui
12245f60b5bStsutsui    input_lock();
12345f60b5bStsutsui
12445f60b5bStsutsui    do {
12562918564Stsutsui	numEvents = x68kKbdGetEvents(device);
12645f60b5bStsutsui	for (i = 0; i < numEvents; i++) {
12762918564Stsutsui	    x68kKbdEnqueueEvent(device, &pPriv->evbuf[i]);
12845f60b5bStsutsui	}
12962918564Stsutsui    } while (numEvents == X68K_MAXEVENTS);
13045f60b5bStsutsui
13145f60b5bStsutsui    input_unlock();
13272502d70Stsutsui}
13372502d70Stsutsui
134ba64b02eStsutsui/*------------------------------------------------------------------------
135ba64b02eStsutsui * x68kKbdProc --
136ba64b02eStsutsui *	Handle the initialization, etc. of a keyboard.
137ba64b02eStsutsui *
138ba64b02eStsutsui * Results:
139ba64b02eStsutsui *	None.
140ba64b02eStsutsui *
141ba64b02eStsutsui *----------------------------------------------------------------------*/
142ba64b02eStsutsuiint
143b0c54374Stsutsuix68kKbdProc(DeviceIntPtr device,	/* Keyboard to manipulate */
144b0c54374Stsutsui            int what)			/* What to do to it */
145ba64b02eStsutsui{
146b0c54374Stsutsui    DevicePtr pKeyboard = &device->public;
1474ff7d041Stsutsui    X68kKbdPrivPtr pPriv;
148ba64b02eStsutsui    CARD8 x68kModMap[MAP_LENGTH];
149ba64b02eStsutsui    int mode;
150ba64b02eStsutsui    XkbRMLVOSet rmlvo;
151ab290810Stsutsui
152ba64b02eStsutsui    switch (what) {
153ba64b02eStsutsui        case DEVICE_INIT:
1549decb2cdStsutsui            pPriv = malloc(sizeof(*pPriv));
1559decb2cdStsutsui            if (pPriv == NULL) {
1569decb2cdStsutsui                LogMessage(X_ERROR,
1579decb2cdStsutsui                    "Cannot allocate private data for keyboard\n");
1589decb2cdStsutsui                return !Success;
1599decb2cdStsutsui            }
1609decb2cdStsutsui            pPriv->fd = open("/dev/kbd", O_RDONLY | O_NONBLOCK);
1619decb2cdStsutsui            if (pPriv->fd == -1) {
1629decb2cdStsutsui                LogMessage(X_ERROR, "Can't open keyboard device\n");
163ba64b02eStsutsui                return !Success;
164ba64b02eStsutsui            }
1659decb2cdStsutsui            pPriv->type = x68kGetKbdType();
1669decb2cdStsutsui            pPriv->leds = 0;
1674ff7d041Stsutsui            pKeyboard->devicePrivate = pPriv;
168ba64b02eStsutsui            pKeyboard->on = FALSE;
169ba64b02eStsutsui            x68kInitModMap(x68kKeySyms, x68kModMap);
170ba64b02eStsutsui
1714ff7d041Stsutsui            x68kInitKbdNames(&rmlvo, pPriv);
172ba64b02eStsutsui#if 0 /* XXX How should we setup XKB maps for non PS/2 keyboard!? */
173b0c54374Stsutsui            InitKeyboardDeviceStruct(device, &rmlvo,
174ba64b02eStsutsui                                     x68kKbdBell, x68kKbdCtrl);
175ba64b02eStsutsui#else
176b0c54374Stsutsui            InitKeyboardDeviceStruct(device, NULL,
177ba64b02eStsutsui                                     x68kKbdBell, x68kKbdCtrl);
178b0c54374Stsutsui	    XkbApplyMappingChange(device, x68kKeySyms,
179ba64b02eStsutsui		x68kKeySyms->minKeyCode,
180ba64b02eStsutsui		x68kKeySyms->maxKeyCode - x68kKeySyms->minKeyCode + 1,
181ba64b02eStsutsui		x68kModMap, serverClient);
182ba64b02eStsutsui#endif
183ba64b02eStsutsui            break;
184ba64b02eStsutsui
185ba64b02eStsutsui        case DEVICE_ON:
1864ff7d041Stsutsui            pPriv = (X68kKbdPrivPtr)pKeyboard->devicePrivate;
187ba64b02eStsutsui            mode = 1;
1884ff7d041Stsutsui            if (ioctl(pPriv->fd, KIOCSDIRECT, &mode) == -1) {
1894ff7d041Stsutsui                LogMessage(X_ERROR, "Failed to set keyboard direct mode\n");
190ba64b02eStsutsui                return !Success;
191ba64b02eStsutsui            }
1924ff7d041Stsutsui	    x68kSetLeds(pPriv, (uint8_t)pPriv->leds);
1934ff7d041Stsutsui            SetNotifyFd(pPriv->fd, x68kKbdEvents, X_NOTIFY_READ, device);
194ba64b02eStsutsui            pKeyboard->on = TRUE;
195ba64b02eStsutsui            break;
196ba64b02eStsutsui
197ba64b02eStsutsui        case DEVICE_OFF:
1984ff7d041Stsutsui            pPriv = (X68kKbdPrivPtr)pKeyboard->devicePrivate;
1994ff7d041Stsutsui            RemoveNotifyFd(pPriv->fd);
200ba64b02eStsutsui            pKeyboard->on = FALSE;
201ba64b02eStsutsui            break;
2022aa2a51fStsutsui
2039decb2cdStsutsui        case DEVICE_CLOSE:
2049decb2cdStsutsui            pPriv = (X68kKbdPrivPtr)pKeyboard->devicePrivate;
2059decb2cdStsutsui            close(pPriv->fd);
2069decb2cdStsutsui            free(pPriv);
2079decb2cdStsutsui            break;
2089decb2cdStsutsui
2092aa2a51fStsutsui        case DEVICE_ABORT:
2102aa2a51fStsutsui            break;
211ba64b02eStsutsui    }
212ba64b02eStsutsui    return Success;
213ba64b02eStsutsui}
214ba64b02eStsutsui
215ba64b02eStsutsui/*-------------------------------------------------------------------------
216ba64b02eStsutsui * function "x68kInitModMap"
217ba64b02eStsutsui *
218ba64b02eStsutsui *  purpose:  initialize modmap with keysym table
219ba64b02eStsutsui *  argument: (KeySymsRec *)x68kKeySyms : keysym table
220ba64b02eStsutsui *            (CARD8 *)x68kModMap       : result
221ba64b02eStsutsui *  returns:  nothing
222ba64b02eStsutsui *-----------------------------------------------------------------------*/
223ba64b02eStsutsuistatic void
224ba64b02eStsutsuix68kInitModMap(KeySymsRec *KeySyms, CARD8 *x68kModMap)
225ba64b02eStsutsui{
226ba64b02eStsutsui    int i;
227ab290810Stsutsui
228ba64b02eStsutsui    for (i = 0; i < MAP_LENGTH; i++)
229ba64b02eStsutsui        x68kModMap[i] = NoSymbol;
230ba64b02eStsutsui    if (KeySyms->minKeyCode < MIN_KEYCODE) {
231ba64b02eStsutsui        KeySyms->minKeyCode += MIN_KEYCODE;
232ba64b02eStsutsui        KeySyms->maxKeyCode += MIN_KEYCODE;
233ba64b02eStsutsui    }
234ba64b02eStsutsui    if (KeySyms->maxKeyCode > MAX_KEYCODE)
235bd299232Stsutsui        KeySyms->maxKeyCode = MAX_KEYCODE;
236ba64b02eStsutsui    for (i = KeySyms->minKeyCode;
237ba64b02eStsutsui         i < KeySyms->maxKeyCode; i++) {
238ba64b02eStsutsui        switch (KeySyms->map[(i-KeySyms->minKeyCode)*4]) {
239ba64b02eStsutsui            case XK_Shift_L:
240ba64b02eStsutsui            case XK_Shift_R:
241ba64b02eStsutsui                x68kModMap[i] = ShiftMask;
242ba64b02eStsutsui                break;
243ba64b02eStsutsui            case XK_Control_L:
244ba64b02eStsutsui            case XK_Control_R:
245ba64b02eStsutsui                x68kModMap[i] = ControlMask;
246ba64b02eStsutsui                break;
247ba64b02eStsutsui            case XK_Alt_L:
248ba64b02eStsutsui            case XK_Alt_R:
249ba64b02eStsutsui                x68kModMap[i] = Mod1Mask;
250ba64b02eStsutsui                break;
251ba64b02eStsutsui            case XK_Meta_L:
252ba64b02eStsutsui            case XK_Meta_R:
253ba64b02eStsutsui                x68kModMap[i] = Mod2Mask;
254ba64b02eStsutsui                break;
255ba64b02eStsutsui            case XK_Caps_Lock:
256ba64b02eStsutsui                x68kModMap[i] = LockMask;
257ba64b02eStsutsui                break;
258ba64b02eStsutsui        }
259ba64b02eStsutsui    }
260ba64b02eStsutsui}
261ba64b02eStsutsui
262ba64b02eStsutsui/*-------------------------------------------------------------------------
263ba64b02eStsutsui * function "x68kInitKbdNames"
264ba64b02eStsutsui *
265ba64b02eStsutsui *  purpose:  store xkb database names
266ba64b02eStsutsui *  argument: (XkbRMLVOSet *)rmlvo
267ba64b02eStsutsui *            (X68kKbdPrivPtr)pKbd
268ba64b02eStsutsui *  returns:  nothing
269ba64b02eStsutsui *-----------------------------------------------------------------------*/
270ba64b02eStsutsuistatic void
271ba64b02eStsutsuix68kInitKbdNames(XkbRMLVOSet *rmlvo, X68kKbdPrivPtr pKbd)
272ba64b02eStsutsui{
273ba64b02eStsutsui#if 0 /* XXX How should we setup XKB maps for non PS/2 keyboard!? */
274ba64b02eStsutsui    rmlvo->rules = "base";
275ba64b02eStsutsui    rmlvo->model = "x68k";
276ba64b02eStsutsui    switch (pKbd->type) {
277ba64b02eStsutsui    case X68K_KB_STANDARD:
278ba64b02eStsutsui        rmlvo->layout = "jp(standard)";
279ba64b02eStsutsui        break;
280ba64b02eStsutsui    case X68K_KB_ASCII:
281ba64b02eStsutsui        rmlvo->layout = "jp(ascii)";
282ba64b02eStsutsui        break;
283ba64b02eStsutsui    }
284ba64b02eStsutsui    rmlvo->variant = "basic";
285ba64b02eStsutsui    rmlvo->options = "";
286ba64b02eStsutsui#else
287ba64b02eStsutsui    rmlvo->rules = "base";
288ba64b02eStsutsui    rmlvo->model = NULL;
289ba64b02eStsutsui    rmlvo->layout = NULL;
290ba64b02eStsutsui    rmlvo->variant = NULL;
291ba64b02eStsutsui    rmlvo->options = NULL;
292ba64b02eStsutsui#endif
293ba64b02eStsutsui}
294ab290810Stsutsui
295ba64b02eStsutsui/*-
296ba64b02eStsutsui *-----------------------------------------------------------------------
297ba64b02eStsutsui * x68kKbdGetEvents --
298ba64b02eStsutsui *	Return the events waiting in the wings for the given keyboard.
299ba64b02eStsutsui *
300ba64b02eStsutsui * Results:
30162918564Stsutsui *	Update Firm_event buffer in DeviceIntPtr if events are received.
30262918564Stsutsui *	Return the number of received Firm_events in the buffer.
303ba64b02eStsutsui *
304ba64b02eStsutsui * Side Effects:
305ba64b02eStsutsui *	None.
306ba64b02eStsutsui *-----------------------------------------------------------------------
307ba64b02eStsutsui */
30862918564Stsutsuistatic int
30962918564Stsutsuix68kKbdGetEvents(DeviceIntPtr device)
310ba64b02eStsutsui{
31162918564Stsutsui    DevicePtr pKeyboard = &device->public;
31262918564Stsutsui    X68kKbdPrivPtr pPriv = pKeyboard->devicePrivate;
313ab290810Stsutsui    int nBytes;		/* number of bytes of events available. */
31462918564Stsutsui    int NumEvents = 0;
315ba64b02eStsutsui
31662918564Stsutsui    nBytes = read(pPriv->fd, pPriv->evbuf, sizeof(pPriv->evbuf));
31762918564Stsutsui    if (nBytes == -1) {
31862918564Stsutsui	if (errno != EWOULDBLOCK) {
31962918564Stsutsui	    LogMessage(X_ERROR, "Unexpected error on reading keyboard\n");
32062918564Stsutsui	    FatalError("Could not read the keyboard");
321ba64b02eStsutsui	}
322ba64b02eStsutsui    } else {
32362918564Stsutsui	NumEvents = nBytes / sizeof(pPriv->evbuf[0]);
324ba64b02eStsutsui    }
32562918564Stsutsui    return NumEvents;
326ba64b02eStsutsui}
327ba64b02eStsutsui
328ba64b02eStsutsui/*-
329ba64b02eStsutsui *-----------------------------------------------------------------------
330ba64b02eStsutsui * x68kKbdEnqueueEvent --
331ba64b02eStsutsui *
332ba64b02eStsutsui *-----------------------------------------------------------------------
333ba64b02eStsutsui */
33445f60b5bStsutsuistatic void
335b0c54374Stsutsuix68kKbdEnqueueEvent(DeviceIntPtr device, Firm_event *fe)
336ba64b02eStsutsui{
337ba64b02eStsutsui    BYTE		keycode;
338ba64b02eStsutsui    int			type;
339ba64b02eStsutsui
340ba64b02eStsutsui    type = ((fe->value == VKEY_UP) ? KeyRelease : KeyPress);
341ba64b02eStsutsui    keycode = (fe->id & 0x7f) + MIN_KEYCODE;
342b0c54374Stsutsui    QueueKeyboardEvents(device, type, keycode);
343ba64b02eStsutsui}
344ba64b02eStsutsui
345ba64b02eStsutsui/*-
346ba64b02eStsutsui *-----------------------------------------------------------------------
347ba64b02eStsutsui * x68kKbdBell --
348ba64b02eStsutsui *	Ring the terminal/keyboard bell
349ba64b02eStsutsui *
350ba64b02eStsutsui * Results:
351ba64b02eStsutsui *	Ring the keyboard bell for an amount of time proportional to
352ba64b02eStsutsui *	"loudness."
353ba64b02eStsutsui *
354ba64b02eStsutsui * Side Effects:
355ba64b02eStsutsui *	None, really...
356ba64b02eStsutsui *
357ba64b02eStsutsui *-----------------------------------------------------------------------
358ba64b02eStsutsui */
359ba64b02eStsutsui
360ba64b02eStsutsuistatic void
361b0c54374Stsutsuix68kKbdRingBell(DeviceIntPtr device, int volume, int duration)
362ba64b02eStsutsui{
363ab290810Stsutsui    int		    kbdCmd;	/* Command to give keyboard */
364b0c54374Stsutsui    X68kKbdPrivPtr  pPriv = (X68kKbdPrivPtr)device->public.devicePrivate;
365ab290810Stsutsui
366ba64b02eStsutsui    if (volume == 0)
367ab290810Stsutsui	return;
368ba64b02eStsutsui
369ba64b02eStsutsui    kbdCmd = KBD_CMD_BELL;
370ba64b02eStsutsui    if (ioctl (pPriv->fd, KIOCCMD, &kbdCmd) == -1) {
3719c576acfStsutsui	ErrorF("Failed to activate bell\n");
372ba64b02eStsutsui	return;
373ba64b02eStsutsui    }
374ba64b02eStsutsui    usleep (duration * 1000);
375ba64b02eStsutsui    kbdCmd = KBD_CMD_NOBELL;
376ba64b02eStsutsui    if (ioctl (pPriv->fd, KIOCCMD, &kbdCmd) == -1)
3779c576acfStsutsui	ErrorF("Failed to deactivate bell\n");
378ba64b02eStsutsui}
379ba64b02eStsutsui
380ba64b02eStsutsuistatic void
381b0c54374Stsutsuix68kKbdBell(int volume, DeviceIntPtr device, void *ctrl, int unused)
382ba64b02eStsutsui{
383ba64b02eStsutsui    KeybdCtrl*      kctrl = (KeybdCtrl*) ctrl;
384ab290810Stsutsui
385ba64b02eStsutsui    if (kctrl->bell == 0)
386ab290810Stsutsui	return;
387ba64b02eStsutsui
388b0c54374Stsutsui    x68kKbdRingBell(device, volume, kctrl->bell_duration);
389ba64b02eStsutsui}
390ba64b02eStsutsui
391ba64b02eStsutsuivoid
392ba64b02eStsutsuiDDXRingBell(int volume, int pitch, int duration)
393ba64b02eStsutsui{
39459a1f54aStsutsui    DeviceIntPtr device;
39559a1f54aStsutsui    DevicePtr pKeyboard;
39659a1f54aStsutsui
39759a1f54aStsutsui    device = x68kKeyboardDevice;
39859a1f54aStsutsui    if (device != NULL) {
39959a1f54aStsutsui	pKeyboard = &device->public;
40059a1f54aStsutsui	if (pKeyboard->on) {
40159a1f54aStsutsui	    x68kKbdRingBell(device, volume, duration);
40259a1f54aStsutsui	}
40359a1f54aStsutsui    }
404ba64b02eStsutsui}
405ba64b02eStsutsui
406ba64b02eStsutsui/*-
407ba64b02eStsutsui *-----------------------------------------------------------------------
408ba64b02eStsutsui * x68kKbdCtrl --
409ba64b02eStsutsui *	Alter some of the keyboard control parameters
410ba64b02eStsutsui *
411ba64b02eStsutsui * Results:
412ba64b02eStsutsui *	None.
413ba64b02eStsutsui *
414ba64b02eStsutsui * Side Effects:
415ba64b02eStsutsui *	Some...
416ba64b02eStsutsui *
417ba64b02eStsutsui *-----------------------------------------------------------------------
418ba64b02eStsutsui */
419ba64b02eStsutsui#define	XKB_LED_ZENKAKU		0x40
420ba64b02eStsutsui#define	XKB_LED_HIRAGANA	0x20
421ba64b02eStsutsui#define	XKB_LED_INSERT		0x10
422ba64b02eStsutsui#define	XKB_LED_CAPS_LOCK	0x08
423ba64b02eStsutsui#define	XKB_LED_CODE_INPUT	0x04
424ba64b02eStsutsui#define	XKB_LED_ROMAJI		0x02
425ba64b02eStsutsui#define	XKB_LED_KANA_LOCK	0x01
426ba64b02eStsutsui
427ba64b02eStsutsuistatic void
428b0c54374Stsutsuix68kKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl)
429ba64b02eStsutsui{
430b0c54374Stsutsui    X68kKbdPrivPtr pPriv = (X68kKbdPrivPtr)device->public.devicePrivate;
431ba64b02eStsutsui
432ba64b02eStsutsui    if (pPriv->leds != ctrl->leds) {
4339b65525fStsutsui        x68kSetLeds(pPriv, (uint8_t)ctrl->leds);
434ba64b02eStsutsui	pPriv->leds = ctrl->leds;
435ba64b02eStsutsui    }
436ba64b02eStsutsui}
437ba64b02eStsutsui
438ba64b02eStsutsui/*-------------------------------------------------------------------------
439ba64b02eStsutsui * function "x68kSetLeds"
440ba64b02eStsutsui *
441ba64b02eStsutsui *  purpose:  set keyboard leds to specified state
442ba64b02eStsutsui *  argument: (X68kKbdPrivPtr)pPriv
4439b65525fStsutsui *            (uint8_t)data;
444ba64b02eStsutsui *  returns:  nothing
445ba64b02eStsutsui *-----------------------------------------------------------------------*/
446ba64b02eStsutsuistatic void
4479b65525fStsutsuix68kSetLeds(X68kKbdPrivPtr pPriv, uint8_t data)
448ba64b02eStsutsui{
449ba64b02eStsutsui    /* bit sequence of led indicator in xkb and hardware are same */
450ba64b02eStsutsui    if (ioctl(pPriv->fd, KIOCSLED, &data) == -1)
4519c576acfStsutsui        ErrorF("Failed to set keyboard lights\n");
452ab290810Stsutsui}
453ba64b02eStsutsui
454ba64b02eStsutsui/* EOF x68kKbd.c */
455