home *** CD-ROM | disk | FTP | other *** search
- /* $Header: pegIo.c,v 1.4 89/10/10 10:29:30 rws Exp $ */
- /***********************************************************
- Portions modified by Tektronix, Inc. Copyright 1987 Tektronix, Inc.
-
- Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
- and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
-
- All Rights Reserved
-
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted,
- provided that the above copyright notice appear in all copies and that
- both that copyright notice and this permission notice appear in
- supporting documentation, and that the names of Digital or MIT not be
- used in advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- SOFTWARE.
-
- ******************************************************************/
- #include "X.h"
- #define NEED_EVENTS
- #include "Xproto.h"
- #include "inputstr.h"
- #include "miscstruct.h"
- #include "scrnintstr.h"
- #include "cursorstr.h"
- #include "pixmap.h"
- #include "windowstr.h"
- #include "regionstr.h"
- #include "resource.h"
-
- #include "mi.h"
-
- #ifdef UTEK
- #include <box/keyboard.h>
- #endif /* UTEK */
-
- #ifdef UTEKV
- #include "redwing/keyboard.h"
- #endif /* UTEKV */
-
- #include "peg.h"
-
- static void pegChangePointerControl();
- static void pegChangeKeyboardControl();
- static void xtlChangeKeyboardControl();
- static void pegBell();
- static void xtlBell();
- extern int errno;
- extern InitInfo pegInfo;
-
- Bool
- pegSaveScreen(pScreen, on)
- ScreenPtr pScreen;
- int on;
-
- {
- switch (on) {
- case SCREEN_SAVER_FORCER:
- case SCREEN_SAVER_OFF:
- pegInfo.screenIsSaved = SCREEN_SAVER_OFF;
- DisplayOn();
- break;
- case SCREEN_SAVER_ON:
- default:
- pegInfo.screenIsSaved = SCREEN_SAVER_ON;
- DisplayOff();
- break;
- }
-
- return TRUE;
- }
-
-
- /*
- * This routine is needed by a os/4.2 routine to implement screensaver. It is
- * not documented in ddx.doc
- */
- TimeSinceLastInputEvent()
- {
- return (pegInfo.dsp->ds_ltime - pegInfo.dsp->ds_lastevent);
- }
-
- int
- pegGetMotionEvents()
- {
- return 0;
- }
-
- int
- pegMouseProc(pDev, onoff, argc, argv)
- DevicePtr pDev;
- int onoff;
- int argc;
- char **argv;
- {
- BYTE map[8];
- SvcCursorXY upperLeft, lowerRight;
-
- debug4(("MouseProc(0x%x,%d,%d,0x%x)\n", pDev, onoff, argc, argv));
-
- switch (onoff)
- {
- case DEVICE_INIT:
- pegInfo.pPointer = pDev;
- pDev->devicePrivate = (pointer) pegInfo.queue;
- /*
- * Mouse button map so that the leftmost mouse button comes out as
- * 1, middle as 2 and the rightmost button as 3. Any thing else
- * comes out as 0 (the driver only gives us one button at a
- * time).
- */
- map[0] = map[1] = map[2] = map[3] = map[4] = map[5] = map[6] =
- map[7] = 0;
- map[Button_L] = 1;
- map[Button_M] = 2;
- map[Button_R] = 3;
- InitPointerDeviceStruct(pegInfo.pPointer,
- map,
- 8,
- pegGetMotionEvents,
- pegChangePointerControl,
- 0);
- #ifndef XPEG_TANDEM
- SetInputCheck(&pegInfo.queue->head, &pegInfo.queue->tail);
- #endif /* XPEG_TANDEM */
-
- /*
- * Turn on driver. Enable the mouse.
- */
- SetCursorMode(0);
- MousePanOn(); /* this is only effective on a 4405 anyway */
- JoyPanOff(); /* if there is panning... we do it */
- upperLeft.x = upperLeft.y = 0;
- lowerRight.x = pegInfo.scrWidth - 1;
- lowerRight.y = pegInfo.scrHeight - 1;
- SetCursorBounds(&upperLeft, &lowerRight);
-
- break;
- case DEVICE_ON:
- pDev->on = TRUE;
- AddEnabledDevice(pegInfo.eventFd);
- CursorEnable();
-
- /*
- * XXX - the driver has not issued an event yet, so the time of the
- * last event is 0, and the time returned by
- * TimeSinceLastInputEvent() will be very large, and
- * WaitForSomething() will compute a negative
- * time for select(), and select will return with an error... ad
- * infinitum. The bug in WaitForSomething should really be fixed.
- * 2/10/87 Todd B.
- */
- pegInfo.dsp->ds_lastevent = pegInfo.dsp->ds_ltime;
-
- break;
- case DEVICE_OFF:
- pDev->on = FALSE;
- RemoveEnabledDevice(pegInfo.eventFd);
- CursorDisable();
- break;
- case DEVICE_CLOSE:
- break;
- }
- return Success;
-
- }
-
- /*
- * These are the "main row" keys. These are repeatable.
- */
- static char mainrow_PEG[] = {
- KBBackSpace,KBTab, KBLineFeed, KBReturn,
- KBSpaceBar, KBQuote, KBComma, KBHyphon,
- KBPeriod, KBSlash, KB0, KB1,
- KB2, KB3, KB4, KB5,
- KB6, KB7, KB8, KB9,
- KBSemiColon,KBEqual, KBA, KBB,
- KBC, KBD, KBE, KBF,
- KBG, KBH, KBI, KBJ,
- KBK, KBL, KBM, KBN,
- KBO, KBP, KBQ, KBR,
- KBS, KBT, KBU, KBV,
- KBW, KBX, KBY, KBZ,
- KBBraceL, KBBackSlash,KBBraceR, KBBar,
- KBRubOut, KBJoyRight, KBJoyUp, KBJoyLeft,
- KBJoyDown
- };
- static char mainrow_XTL[] = {
- KEY_BackSpace,KEY_Tab, KEY_Linefeed, KEY_Return,
- KEY_Space, KEY_Quote, KEY_Comma, KEY_Minus,
- KEY_Period, KEY_Slash, KEY_0, KEY_1,
- KEY_2, KEY_3, KEY_4, KEY_5,
- KEY_6, KEY_7, KEY_8, KEY_9,
- KEY_SemiColon,KEY_Equal, KEY_a, KEY_b,
- KEY_c, KEY_d, KEY_e, KEY_f,
- KEY_g, KEY_h, KEY_i, KEY_j,
- KEY_k, KEY_l, KEY_m, KEY_n,
- KEY_o, KEY_p, KEY_q, KEY_r,
- KEY_s, KEY_t, KEY_u, KEY_v,
- KEY_w, KEY_x, KEY_y, KEY_z,
- KEY_LBrace, KEY_VertBar, KEY_RBrace, KEY_Tilde,
- KEY_RubOut, KEY_Cursor_R, KEY_Cursor_U, KEY_Cursor_L,
- KEY_Cursor_D
- };
-
- int
- pegKeybdProc(pDev, onoff, argc, argv)
- DevicePtr pDev;
- int onoff;
- int argc;
- char **argv;
- {
- KeySymsRec keySyms;
- CARD8 modMap[MAP_LENGTH];
- int i;
-
- switch (onoff)
- {
- case DEVICE_INIT:
- pegInfo.pKeyboard = pDev;
- pDev->devicePrivate = (pointer) pegInfo.queue;
- #ifdef UTEK
- if (KEYIDSTYLE(pegInfo.softp) == KB_STYLE_VT200)
- #endif /* UTEK */
- #ifdef UTEKV
- if (KEYIDSTYLE(pegInfo.dsp) == KB_STYLE_VT200)
- #endif /* UTEKV */
- {
- /* XTL style */
- gfbXTLKBMappings(&keySyms, modMap);
- InitKeyboardDeviceStruct(
- pegInfo.pKeyboard, &keySyms, modMap, xtlBell,
- xtlChangeKeyboardControl);
- for (i=0; i<sizeof(mainrow_XTL); i++) {
- MakeRawKeyRepeatable(mainrow_XTL[ i ]);
- }
- }
- #ifdef UTEK
- else if (KEYIDSTYLE(pegInfo.softp) == KB_STYLE_YELLOW_JACKET)
- #endif /* UTEK */
- #ifdef UTEKV
- else if (KEYIDSTYLE(pegInfo.dsp) == KB_STYLE_YELLOW_JACKET)
- #endif /* UTEKV */
- {
- /* 4207 YELLOW JACKET style */
- GetPEGKBMappings(&keySyms, modMap);
- InitKeyboardDeviceStruct(
- pegInfo.pKeyboard, &keySyms, modMap, xtlBell,
- pegChangeKeyboardControl);
- for (i=0; i<sizeof(mainrow_XTL); i++) {
- MakeRawKeyRepeatable(mainrow_XTL[ i ]);
- }
- } else {
- /* default to Pegasus style */
- GetPEGKBMappings(&keySyms, modMap);
- InitKeyboardDeviceStruct(
- pegInfo.pKeyboard, &keySyms, modMap, pegBell,
- pegChangeKeyboardControl);
- for (i=0; i<sizeof(mainrow_PEG); i++) {
- MakeRawKeyRepeatable(mainrow_PEG[ i ]);
- }
- }
- Xfree((pointer)keySyms.map);
- ((DeviceIntPtr)pDev)->kbdfeed->ctrl.autoRepeat = True;
- break;
- case DEVICE_ON:
- pDev->on = TRUE;
- AddEnabledDevice(pegInfo.eventFd);
- break;
- case DEVICE_OFF:
- pDev->on = FALSE;
- /* RemoveEnabledDevice(pegInfo.eventFd); */
- break;
- case DEVICE_CLOSE:
- break;
- }
- return Success;
- }
-
- static void
- pegChangeKeyboardControl(pDevice, ctrl)
- DevicePtr pDevice;
- KeybdCtrl *ctrl;
- {
- /* ctrl->click: not possible */
-
- /* ctrl->bell: the DIX layer handles the base volume for the bell */
-
- /* ctrl->bell_pitch: can't set now */
-
- /* ctrl->bell_duration: as far as I can tell, you can't set this */
-
- /* ctrl->leds: We have only one LED, but it is owned by ddx... */
-
- /* ctrl->autoRepeat: We need do nothing here... dix maintains this */
-
- /* ctrl->autoRepeats: Force on the joypad, if necessary */
- if (pegInfo.kv.panEnabled) {
- MakeRawKeyRepeatable(KBJoyLeft);
- MakeRawKeyRepeatable(KBJoyRight);
- MakeRawKeyRepeatable(KBJoyUp);
- MakeRawKeyRepeatable(KBJoyDown);
- }
- }
-
-
- /*
- * NAME
- * setXTLBellVolume - Set bell volume on XTL Keyboard
- *
- * SYNOPSIS
- */
- static void
- setXTLBellVolume(volume)
- int volume; /* in: volume (0-100) */
- /*
- * DESCRIPTION
- * This routines sets the bell volume level on the XTL
- * Keyboard.
- *
- * RETURNS
- * None
- */
- {
- assert(volume >= 0 && volume <= 100);
-
- if (pegInfo.bells.fd < 0) {
- /*
- * Unable to open /dev/bell
- */
- return;
- }
-
- /*
- * XTL keyboard has only 3 distinct bell volumes.
- * Volume is a value between 0 and 100 with 100 being loudest.
- */
- if ( volume < 34 ) {
- /*
- * Make ioctl() call to /dev/bell to set bell volume to SOFT
- */
- if (ioctl(pegInfo.bells.fd, BELL_KEYBD_BELL_ON_SOFT, (char*)0) == -1) {
- #ifdef XDEBUG
- ErrorF("ioctl() returns error %d for BELL_KEYBD_BELL_ON_SOFT\n",
- errno);
- #endif /* XDEBUG */
- }
- } else if (volume < 68 ) {
- /*
- * Make ioctl() call to /dev/bell to set bell volume to MEDIUM
- */
- if (ioctl(pegInfo.bells.fd, BELL_KEYBD_BELL_ON_MED, (char*)0) == -1) {
- #ifdef XDEBUG
- ErrorF("ioctl() returns error %d for BELL_KEYBD_BELL_ON_MED\n",
- errno);
- #endif /* XDEBUG */
- }
- } else {
- /*
- * Make ioctl() call to /dev/bell to set bell volume to LOUD
- */
- if (ioctl(pegInfo.bells.fd, BELL_KEYBD_BELL_ON_LOUD, (char*)0) == -1) {
- #ifdef XDEBUG
- ErrorF("ioctl() returns error %d for BELL_KEYBD_BELL_ON_LOUD\n",
- errno);
- #endif /* XDEBUG */
- }
- }
- }
-
-
-
- /*
- * NAME
- * xtlChangeKeyboardControl - Changes Keyboard Controls
- * for XTL keyboard
- *
- * SYNOPSIS
- */
- static void
- xtlChangeKeyboardControl(pDevice, pKbCtrl)
- DevicePtr pDevice; /* in: pointer to keyboard device */
- KeybdCtrl *pKbCtrl; /* in: pointer to kb control structure */
- /*
- * DESCRIPTION
- * Changes keyboard control as specified in the KeybdCtrl
- * structure (i.e., autorepeat, keyclick volume, bell
- * volume, bell duration, LEDs.
- *
- * RETURNS
- * None
- *
- */
- {
- int lbval = 0; /* low-byte value for bell duration ioctl */
-
- /*
- * pKbCtrl->autoRepeat: We need do nothing here... dix maintains this
- */
-
- /*
- * pKbCtrl->autoRepeats: Force on the joypad, if necessary
- */
- if (pegInfo.kv.panEnabled) {
- MakeRawKeyRepeatable(KEY_Cursor_R);
- MakeRawKeyRepeatable(KEY_Cursor_U);
- MakeRawKeyRepeatable(KEY_Cursor_L);
- MakeRawKeyRepeatable(KEY_Cursor_D);
- }
-
- /*
- * pKbCtrl->click:
- */
- if (pegInfo.bells.fd > 0 && 0 <= pKbCtrl->click && pKbCtrl->click <= 100) {
- if (pKbCtrl->click == 0) {
- /*
- * Make ioctl() call to /dev/bell to:
- * Turn KeyClick OFF
- */
- if (ioctl(pegInfo.bells.fd, BELL_KEYBD_CLICK_OFF, (char*)0) == -1) {
- #ifdef XDEBUG
- ErrorF("ioctl() returns error %d for BELL_KEYBD_CLICK_OFF\n",
- errno);
- #endif /* XDEBUG */
- }
- } else if (pKbCtrl->click < 34) {
- /*
- * Make ioctl() call to /dev/bell to:
- * Set KeyClick volume to SOFT
- */
- if (ioctl(pegInfo.bells.fd, BELL_KEYBD_CLICK_ON_SOFT, (char*)0)
- == -1) {
- #ifdef XDEBUG
- ErrorF("ioctl() returns error %d for BELL_KEYBD_CLICK_ON_SOFT\n",
- errno);
- #endif /* XDEBUG */
- }
- } else if (pKbCtrl->click < 68) {
- /*
- * Make ioctl() call to /dev/bell to:
- * Set KeyClick volume to MEDIUM
- */
- if (ioctl(pegInfo.bells.fd, BELL_KEYBD_CLICK_ON_MED, (char*)0)
- == -1) {
- #ifdef XDEBUG
- ErrorF("ioctl() returns error %d for BELL_KEYBD_CLICK_ON_MED\n",
- errno);
- #endif /* XDEBUG */
- }
- } else if (pKbCtrl->click <= 100) {
- /*
- * Make ioctl() call to /dev/bell to:
- * Set KeyClick volume to LOUD
- */
- if (ioctl(pegInfo.bells.fd, BELL_KEYBD_CLICK_ON_LOUD, (char*)0)
- == -1) {
- #ifdef XDEBUG
- ErrorF("ioctl() returns error %d for BELL_KEYBD_CLICK_ON_LOUD\n",
- errno);
- #endif /* XDEBUG */
- }
- }
- }
-
- /*
- * pKbCtrl->bell:
- * The DIX layer handles the base volume for the bell, however, ...
- * the DIX stored base volume level is applied only with a call
- * to xtlBell(). Ringing of the bell through any other means
- * (e.g., echo "^G") would result in a volume as set by the
- * last xtlBell() call. Therefore, we set the base volume here!
- */
- setXTLBellVolume(pKbCtrl->bell);
-
- /*
- * pKbCtrl->bell_pitch:
- * not possible on XTL keyboard.
- */
-
- /*
- * pKbCtrl->bell_duration:
- *
- * The Kernel stores the bell duration that is set via ioctl().
- *
- * For the XTL keyboard, the duration (pKbCtrl->bell_duration) is
- * established by the low-order byte (lbval) of the "RING BELL" command
- * (4X hex) and equals the decimal value of lbval times 40 milliseconds
- * (pKbCtrl->bell_duration=lbval*40 msec).
- * If the bell_duration >= 0 then convert to an lbval.
- * Note that if duration <= 0 then the command 40 (Key Click 2.5 msec) will
- * be executed.
- */
-
- if (pegInfo.bells.fd > 0) {
- /*
- * Was able to open /dev/xdev
- */
- if (pKbCtrl->bell_duration > (0xf * 40)) {
- lbval = 0xf;
- } else if (pKbCtrl->bell_duration > 0) {
- lbval = (int)(pKbCtrl->bell_duration/40) & 0xf;
- }
- if (ioctl(pegInfo.bells.fd, BELL_KEYBD_BELL_DURATION_SET,
- (char *)(&lbval)) == -1 ) {
- #ifdef XDEBUG
- ErrorF("ioctl() returns error %d for BELL_KEYBD_BELL_DURATION_SET\n",
- errno);
- #endif /* XDEBUG */
- }
- }
-
- /*
- * pKbCtrl->leds:
- *
- * The XTL keyboard has 3 LEDs that are worth manipulating; these are
- * name X LED #
- * ---------- -------
- * Hold Screen = LED 1
- * Compose = LED 2
- * Wait = LED 3
- * Tek = LED 4
- * Xmt = LED 5
- * Rcv = LED 6
- * The Lock LED is reserved to be used by the system to indicate when the
- * Lock key is considered on.
- */
-
- if (pegInfo.eventFd > 0) {
- /*
- * Was able to open /dev/xdev
- */
-
- /*
- * HOLD SCREEN
- */
-
- if (pKbCtrl->leds & 0x1) {
- if (ioctl(pegInfo.eventFd, KEYBD_HOLD_LED_ON, (char*)0) == -1) {
- #ifdef XDEBUG
- ErrorF("ioctl() returns error %d for KEYBD_HOLD_LED_ON\n", errno);
- #endif /* XDEBUG */
- }
- } else {
- if (ioctl(pegInfo.eventFd, KEYBD_HOLD_LED_OFF, (char*)0) == -1) {
- #ifdef XDEBUG
- ErrorF("ioctl() returns error %d for KEYBD_HOLD_LED_OFF\n", errno);
- #endif /* XDEBUG */
- }
- }
-
- /*
- * COMPOSE
- */
- if (pKbCtrl->leds & 0x2) {
- if (ioctl(pegInfo.eventFd, KEYBD_COMPOSE_LED_ON, (char*)0) == -1) {
- #ifdef XDEBUG
- ErrorF("ioctl() returns error %d for KEYBD_COMPOSE_LED_ON\n", errno);
- #endif /* XDEBUG */
- }
- } else {
- if (ioctl(pegInfo.eventFd, KEYBD_COMPOSE_LED_OFF, (char*)0) == -1) {
- #ifdef XDEBUG
- ErrorF("ioctl() returns error %d for KEYBD_COMPOSE_LED_OFF\n", errno);
- #endif /* XDEBUG */
- }
- }
-
- /*
- * WAIT
- */
- if (pKbCtrl->leds & 0x4) {
- if (ioctl(pegInfo.eventFd, KEYBD_WAIT_LED_ON, (char*)0) == -1) {
- #ifdef XDEBUG
- ErrorF("ioctl() returns error %d for KEYBD_WAIT_LED_ON\n", errno);
- #endif /* XDEBUG */
- }
- } else {
- if (ioctl(pegInfo.eventFd, KEYBD_WAIT_LED_OFF, (char*)0)) {
- #ifdef XDEBUG
- ErrorF("ioctl() returns error %d for KEYBD_WAIT_LED_OFF\n", errno);
- #endif /* XDEBUG */
- }
- }
-
- /*
- * TEK
- */
- if (pKbCtrl->leds & 0x8) {
- if (ioctl(pegInfo.eventFd, KEYBD_TEK_LED_ON, (char*)0) == -1) {
- #ifdef XDEBUG
- ErrorF("ioctl() returns error %d for KEYBD_TEK_LED_ON\n", errno);
- #endif /* XDEBUG */
- }
- } else {
- if (ioctl(pegInfo.eventFd, KEYBD_TEK_LED_OFF, (char*)0) == -1) {
- #ifdef XDEBUG
- ErrorF("ioctl() returns error %d for KEYBD_TEK_LED_OFF\n", errno);
- #endif /* XDEBUG */
- }
- }
-
- /*
- * XMT
- */
- if (pKbCtrl->leds & 0x10) {
- if (ioctl(pegInfo.eventFd, KEYBD_XMT_LED_ON, (char*)0) == -1) {
- #ifdef XDEBUG
- ErrorF("ioctl() returns error %d for KEYBD_XMT_LED_ON\n", errno);
- #endif /* XDEBUG */
- }
- } else {
- if (ioctl(pegInfo.eventFd, KEYBD_XMT_LED_OFF, (char*)0) == -1) {
- #ifdef XDEBUG
- ErrorF("ioctl() returns error %d for KEYBD_XMT_LED_OFF\n", errno);
- #endif /* XDEBUG */
- }
- }
-
- /*
- * RCV
- */
- if (pKbCtrl->leds & 0x20) {
- if (ioctl(pegInfo.eventFd, KEYBD_RCV_LED_ON, (char*)0) == -1) {
- #ifdef XDEBUG
- ErrorF("ioctl() returns error %d for KEYBD_RCV_LED_ON\n", errno);
- #endif /* XDEBUG */
-
- }
- } else {
- if (ioctl(pegInfo.eventFd, KEYBD_RCV_LED_OFF, (char*)0) == -1) {
- #ifdef XDEBUG
- ErrorF("ioctl() returns error %d for KEYBD_RCV_LED_OFF\n", errno);
- #endif /* XDEBUG */
- }
- }
- }
- }
-
- static void
- pegBell(loud, pDevice)
- int loud;
- DevicePtr pDevice;
- {
- int i;
-
- assert(loud >= 0 && loud <= 100);
-
- /*
- * We have only 8 distinct bell volumes, named 0-7
- */
- i = loud / 14;
-
- if (pegInfo.bells.fd > 0 && pegInfo.bells.len[ i ])
- write(pegInfo.bells.fd,
- pegInfo.bells.str[ i ],
- pegInfo.bells.len[ i ]);
- }
-
- /*
- * NAME
- * xtlBell - ring bell on XTL Keyboard
- *
- * SYNOPSIS
- */
- static void
- xtlBell(volume, pDevice)
- int volume; /* in: volume (0-100) */
- DevicePtr pDevice; /* in: ptr to keyboard device */
- /*
- * DESCRIPTION
- * This routines sets the bell volume level then rings
- * the bell. DIX has already applied the base volume
- * level to the client requested adjustment level.
- *
- * RETURNS
- * None
- */
- {
- assert(volume >= 0 && volume <= 100);
-
- if (pegInfo.bells.fd < 0) {
- /*
- * Unable to open /dev/bell
- */
- return;
- }
-
- /*
- * Set the XTL keyboard volume before ringing bell.
- */
- setXTLBellVolume(volume);
-
- /*
- * Finally, RING THE BELL!!
- */
- write(pegInfo.bells.fd, "", 0);
-
- /*
- * Reset the XTL keyboard volume to base volume.
- */
- volume = ((DeviceIntPtr)pDevice)->kbdfeed->ctrl.bell;
- setXTLBellVolume(volume);
- }
-
- static void
- pegChangePointerControl(pDevice, ctrl)
- DevicePtr pDevice;
- PtrCtrl *ctrl;
- {
- SvcCursorSpeed new;
- int acceleration;
-
- if (!(new.multiplier = ctrl->num / ctrl->den))
- new.multiplier = 1; /* watch for den > num */
- new.threshold = ctrl->threshold;
- new.divisor = 1;
- if (SetCursorSpeed(&new) < 0)
- Error("SetCursorSpeed");
- }
-
-
- Bool
- pegSetCursorPosition( pScr, newx, newy, generateEvent)
- ScreenPtr pScr;
- int newx;
- int newy;
- Bool generateEvent;
- {
- xEvent motion;
- int xlimit, ylimit;
- SvcCursorXY new;
- static Bool firstTime = True;
-
- if (firstTime) {
- #ifdef UTEK
- if (CPU_BOARD(pegInfo.softp) == HC_CPU_4405PLUS) {
- debug4(("first-time cursor position shifted from (%d,%d) to ",
- newx, newy));
- newx = SCREEN_X(pegInfo.softp) / 2;
- newy = SCREEN_Y(pegInfo.softp) / 2;
- }
- #endif /* UTEK */
- firstTime = False;
- }
- xlimit = pegInfo.scrWidth-1;
- ylimit = pegInfo.scrHeight-1;
- new.x = newx;
- new.y = newy;
-
- /*
- * Insure the position is still visible
- */
- if (new.x < 0)
- new.x = 0;
- else if (new.x > xlimit)
- new.x = xlimit;
-
- if (new.y < 0)
- new.y = 0;
- else if (new.y > ylimit)
- new.y = ylimit;
-
- debug4(("SetCursorPosition(%d,%d)-->(%d,%d), %sgenerate an event\n",
- newx, newy, new.x, new.y, generateEvent ? "" : "don't"));
- #ifdef XTESTEXT1
- LastMousePosition.x = new.x;
- LastMousePosition.y = new.y;
- #endif /* XTESTEXT1 */
- /*
- * Use ioctl to move cursor without causing an event to get
- * generated. If this OS does not have this ioctl, just use
- * SetCursorPoint which may or may not actually generate an event
- */
- if (ioctl(pegInfo.eventFd, CE_NEW_MOUSE_POSITION_NO_EVT,
- (char *)(&new)) == -1) {
-
- if (SetCursorPoint(&new) < 0)
- Error("SetCursorPoint");
- }
- /*
- * XXX - these don't get updated 'till the next vertical sync, so
- * we could force them here. But we don't because that suppresses an
- * event being generated (very useful because of the 4405 hack above).
- *
- * pegInfo.dsp->ds_x = new.x;
- * pegInfo.dsp->ds_y = new.y;
- */
-
- if (generateEvent)
- {
- if (pegInfo.queue->head != pegInfo.queue->tail)
- ProcessInputEvents();
- motion.u.keyButtonPointer.rootX = newx;
- motion.u.keyButtonPointer.rootY = newy;
- motion.u.keyButtonPointer.time = pegInfo.lastEventTime;
- motion.u.u.type = MotionNotify;
- (*pegInfo.pPointer->processInputProc) (&motion, pegInfo.pPointer, 1);
- }
-
- return TRUE;
- }
-
- /*
- * NAME
- * pegRecolorCursor - Change cursor color
- *
- * SYNOPSIS
- */
- void
- pegRecolorCursor( pScr, pCurs, displayed)
- ScreenPtr pScr;
- CursorPtr pCurs;
- Bool displayed; /* TRUE if this cursor is currently displayed */
- /*
- * DESCRIPTION
- * Dix is telling us that the colors in the pCurs structure
- * have changed. Since we are not storing color info in the
- * devPrivate field of pCurs we do not need to update that
- * structure. We must change the color of the current
- * cursor if parameter "displayed" is TRUE.
- *
- * RETURNS
- * None
- *
- */
- {
- /*
- * Calling DisplayCursor does a little more work than is necessary but
- * makes the process simpler to code. All we really need to do is call
- * SetCursorColor.
- */
- if (displayed)
- (* pScr->DisplayCursor)( pScr, pCurs);
-
- }
-
- Bool
- pegDisplayCursor(pScr, pCurs)
- ScreenPtr pScr;
- CursorPtr pCurs;
- {
- SvcCursorFormPtr new;
- SvcCursorColor colors;
-
- #ifdef XDEBUG
- if (xflg_debug & 0x10) {
- x_debug("DisplayCursor %dX%d, hot=(%d,%d)\n",
- pCurs->width, pCurs->height,
- pCurs->xhot, pCurs->yhot);
- x_debug("cursor colors=<%x %x %x><%x %x %x>\n",
- pCurs->foreRed,
- pCurs->foreGreen,
- pCurs->foreBlue,
- pCurs->backRed,
- pCurs->backGreen,
- pCurs->backBlue);
- }
- #endif /* XDEBUG */
-
- if (pegInfo.depth == 1) {
- unsigned short r, g, b;
-
- /*
- * We are assuming here that if depth is one (-mono option or a
- * 4316/4406+), then there is only one visual: the 0th one for the
- * screen. Otherwise we must call the screen ListInstalledColormaps()
- * and lookup the visual associated with it.
- */
- r = pCurs->foreRed;
- g = pCurs->foreGreen;
- b = pCurs->foreBlue;
- (*pScr->ResolveColor)(&r, &g, &b, &pScr->visuals[0]);
- colors.redFore = r;
- colors.greenFore = g;
- colors.blueFore = b;
-
- r = pCurs->backRed;
- g = pCurs->backGreen;
- b = pCurs->backBlue;
- (*pScr->ResolveColor)(&r, &g, &b, &pScr->visuals[0]);
- colors.redBack = r;
- colors.greenBack = g;
- colors.blueBack = b;
- } else {
- #ifdef NOTDEF
- if (!FGammaCorrectionDisabled) {
- DisplayLookUpGammaCorrectedColor(
- (unsigned short) pCurs->foreRed,
- (unsigned short) pCurs->foreGreen,
- (unsigned short) pCurs->foreBlue,
- &colors.redFore,
- &colors.greenFore,
- &colors.blueFore);
- DisplayLookUpGammaCorrectedColor(
- (unsigned short) pCurs->backRed,
- (unsigned short) pCurs->backGreen,
- (unsigned short) pCurs->backBlue,
- &colors.redBack,
- &colors.greenBack,
- &colors.blueBack);
- }
- else
- #endif
- {
- colors.redFore = (short) pCurs->foreRed;
- colors.greenFore = (short) pCurs->foreGreen;
- colors.blueFore = (short) pCurs->foreBlue;
- colors.redBack = (short) pCurs->backRed;
- colors.greenBack = (short) pCurs->backGreen;
- colors.blueBack = (short) pCurs->backBlue;
- }
- }
- if (SetCursorColor(&colors) < 0)
- Error("SetCursorColor");
-
- /*
- * load the cursor
- */
- new = (SvcCursorFormPtr) pCurs->devPriv[pScr->myNum];
- new->xoff = pCurs->bits->xhot;
- new->yoff = pCurs->bits->yhot;
- if (SetCursorSourceAndMask(new))
- Error("SetCursorSourceAndMask");
- }
-
- void
- pegPointerNonInterestBox( pScr, pBox)
- ScreenPtr pScr;
- BoxPtr pBox;
- {
-
- debug5(("PointerNonInterestBox: Box = x1 %d y1 %d x2 %d y2 %d\n",
- pBox->x1, pBox->y1, pBox->x2, pBox->y2));
- pegInfo.dsp->ds_box.bottom = pBox->y2;
- pegInfo.dsp->ds_box.top = pBox->y1;
- pegInfo.dsp->ds_box.left = pBox->x1;
- pegInfo.dsp->ds_box.right = pBox->x2;
- }
-
- void
- pegConstrainCursor( pScr, pBox)
- ScreenPtr pScr;
- BoxPtr pBox;
- {
- SvcCursorXY upperLeft, lowerRight;
-
- debug4(("ConstrainCursor(0x%x)@(%d,%d),(%d,%d)\n", pScr,
- pBox->x1, pBox->y1, pBox->x2, pBox->y2));
-
- pegInfo.constraintBox = *pBox;
- #ifdef XPEG_TANDEM
- if (!pegTandem)
- #endif /* XPEG_TANDEM */
- {
- upperLeft.x = pBox->x1;
- upperLeft.y = pBox->y1;
- lowerRight.x = pBox->x2;
- lowerRight.y = pBox->y2;
- SetCursorBounds(&upperLeft, &lowerRight);
- }
- }
-
- void
- pegCursorLimits( pScr, pCurs, pHotBox, pTopLeftBox)
- ScreenPtr pScr;
- CursorPtr pCurs;
- BoxPtr pHotBox;
- BoxPtr pTopLeftBox; /* return value */
- {
- pTopLeftBox->x1 = max( pHotBox->x1, 0);
- pTopLeftBox->y1 = max( pHotBox->y1, 0);
- pTopLeftBox->x2 = min( pHotBox->x2, pegInfo.width);
- pTopLeftBox->y2 = min( pHotBox->y2, pegInfo.height);
- }
-
- /*
- * Copy data in (pegasus) bitmap format to fill a 64 x 64 bitmap.
- * Pad with zeros.
- */
- static void
- CopyCursorImage(src, dest, width, height)
- long *src, *dest;
- int width, height;
- {
- int x, y;
- long edgeMask;
-
- /*
- * We know pegasus bitmaps have four bytes per scanline if width <= 32,
- * eight bytes per scanline if 32 < width <= SvcCursorSize (64).
- * Set all unused bits to zero, only mask when needed.
- */
- if (width < 32) {
- edgeMask = 0xffffffff << (32 - width);
- for (y = 0; y < height; y++) {
- *dest++ = src[y] & edgeMask;
- *dest++ = 0;
- }
- } else if (width == 32) {
- for (y = 0; y < height; y++) {
- *dest++ = src[y];
- *dest++ = 0;
- }
- } else if (width < SvcCursorSize) {
- edgeMask = 0xffffffff << (SvcCursorSize - width);
- for (y = 0; y < 2 * height; y += 2) {
- *dest++ = src[y];
- *dest++ = src[y+1] & edgeMask;
- }
- } else {
- for (y = 0; y < 2 * height; y += 2) {
- *dest++ = src[y];
- *dest++ = src[y+1];
- }
- }
- /* zero the remaining lines */
- for (y = height; y < SvcCursorSize; y++) {
- *dest++ = 0;
- *dest++ = 0;
- }
- }
-
- Bool
- pegRealizeCursor( pScr, pCurs)
- ScreenPtr pScr;
- CursorPtr pCurs; /* a SERVER-DEPENDENT cursor */
- {
- SvcCursorForm *data;
-
- data = (SvcCursorForm *)Xalloc(sizeof(SvcCursorForm));
- if (!data)
- return(FALSE);
-
- if (pCurs->bits->height < SvcCursorSize
- || pCurs->bits->width < SvcCursorSize) {
- data->src = (unsigned long *)Xalloc(SvcCursorDataSize * sizeof(long));
- data->mask = (unsigned long *)Xalloc(SvcCursorDataSize * sizeof(long));
- if (!data->src || !data->mask)
- return(FALSE);
- CopyCursorImage((long *)pCurs->bits->source, data->src,
- pCurs->bits->width, pCurs->bits->height);
- CopyCursorImage((long *)pCurs->bits->mask, data->mask,
- pCurs->bits->width, pCurs->bits->height);
- } else {
- data->src = (unsigned long *)pCurs->bits->source;
- data->mask = (unsigned long *)pCurs->bits->mask;
- }
-
- pCurs->devPriv[pScr->myNum] = (pointer)data;
-
- return(TRUE); /* Failure can happen only in Xalloc() */
- }
-
- Bool
- pegUnrealizeCursor( pScr, pCurs)
- ScreenPtr pScr;
- CursorPtr pCurs;
- {
- SvcCursorForm *data = (SvcCursorForm *)pCurs->devPriv[pScr->myNum];
-
- if (data->src != (unsigned long *)pCurs->bits->source) {
- Xfree(data->src);
- Xfree(data->mask);
- }
- Xfree(data);
-
- return(TRUE);
- }
-
- /*
- * NAME
- * pegQueryBestSize - return best sizes for cursor and patterns
- *
- * SYNOPSIS
- */
- void
- pegQueryBestSize(class, pwidth, pheight)
- int class; /* in: CursorShape, TileShape, or StippleShape */
- short *pwidth; /* in/out: width */
- short *pheight; /* in/out: height */
- /*
- * DESCRIPTION
- * Return best sizes for cursors, tiles, and stiples in
- * response to client requests. For CursorShape, return
- * the maximum width and height for cursors that we can
- * handle. For TileShape and StippleShape, start with the
- * suggested values in *pwidth and *pheight and modify them
- * in place to be optimal values that are greater than or
- * equal to the suggested values.
- *
- * RETURNS
- * None
- *
- */
- {
-
- switch(class) {
- case CursorShape:
- *pwidth = SvcCursorSize;
- *pheight = SvcCursorSize;
- break;
-
- /*
- * Return nearest, multiple of 32 not less than width
- * Do nothing for height
- */
- case TileShape:
- case StippleShape:
- if (*pwidth <= 32)
- *pwidth = 32;
- else
- *pwidth = (*pwidth + 31) & ~0x1f;
-
- /* We don't care what height they use */
- break;
- }
- }
-