(file) Return to xf86Io.c CVS log (file) (dir) Up to [XFree86 CVS] / xc / programs / Xserver / hw / xfree86 / common

  1 dawes 3.57 /* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86Io.c,v 3.56 2003/11/03 05:11:02 tsi Exp $ */
  2 dawes 3.5  /*
  3 dawes 1.1   * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
  4             *
  5             * Permission to use, copy, modify, distribute, and sell this software and its
  6             * documentation for any purpose is hereby granted without fee, provided that
  7             * the above copyright notice appear in all copies and that both that
  8             * copyright notice and this permission notice appear in supporting
  9             * documentation, and that the name of Thomas Roell not be used in
 10             * advertising or publicity pertaining to distribution of the software without
 11             * specific, written prior permission.  Thomas Roell makes no representations
 12             * about the suitability of this software for any purpose.  It is provided
 13             * "as is" without express or implied warranty.
 14             *
 15             * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 16             * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 17             * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 18             * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 19             * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 20             * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 21             * PERFORMANCE OF THIS SOFTWARE.
 22             *
 23             */
 24 dawes 3.54 /*
 25             * Copyright (c) 1992-2003 by The XFree86 Project, Inc.
 26 dawes 3.57  * All rights reserved.
 27 dawes 3.54  *
 28 dawes 3.57  * Permission is hereby granted, free of charge, to any person obtaining
 29             * a copy of this software and associated documentation files (the
 30             * "Software"), to deal in the Software without restriction, including
 31             * without limitation the rights to use, copy, modify, merge, publish,
 32             * distribute, sublicense, and/or sell copies of the Software, and to
 33             * permit persons to whom the Software is furnished to do so, subject
 34             * to the following conditions:
 35 dawes 3.54  *
 36 dawes 3.57  *   1.  Redistributions of source code must retain the above copyright
 37             *       notice, this list of conditions, and the following disclaimer.
 38 dawes 3.54  *
 39 dawes 3.57  *   2.  Redistributions in binary form must reproduce the above copyright
 40             *       notice, this list of conditions and the following disclaimer
 41             *       in the documentation and/or other materials provided with the
 42             *       distribution, and in the same place and form as other copyright,
 43             *       license and disclaimer information.
 44 dawes 3.54  *
 45 dawes 3.57  *   3.  The end-user documentation included with the redistribution,
 46             *       if any, must include the following acknowledgment: "This product
 47             *       includes software developed by The XFree86 Project, Inc
 48             *       (http://www.xfree86.org/) and its contributors", in the same
 49             *       place and form as other third-party acknowledgments.  Alternately,
 50             *       this acknowledgment may appear in the software itself, in the
 51             *       same form and location as other such third-party acknowledgments.
 52             *
 53             *   4.  Except as contained in this notice, the name of The XFree86
 54             *       Project, Inc shall not be used in advertising or otherwise to
 55             *       promote the sale, use or other dealings in this Software without
 56             *       prior written authorization from The XFree86 Project, Inc.
 57             *
 58             * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 59             * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 60             * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 61             * IN NO EVENT SHALL THE XFREE86 PROJECT, INC OR ITS CONTRIBUTORS BE
 62             * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 63             * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 64             * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 65             * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 66 dawes 3.57  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 67             * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 68             * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 69 dawes 3.54  */
 70            
 71 dawes 3.27 /* $XConsortium: xf86Io.c /main/27 1996/10/19 17:58:55 kaleb $ */
 72 dawes 1.1  
 73            #define NEED_EVENTS
 74            #include "X.h"
 75            #include "Xproto.h"
 76            #include "inputstr.h"
 77            #include "scrnintstr.h"
 78            
 79            #include "compiler.h"
 80            
 81 dawes 3.35 #include "xf86.h"
 82            #include "xf86Priv.h"
 83            #define XF86_OS_PRIVS
 84 dawes 1.1  #include "xf86_OSlib.h"
 85 dawes 3.35 #include "mipointer.h"
 86 dawes 1.1  
 87 dawes 3.22 #ifdef XINPUT
 88            #include "xf86Xinput.h"
 89 dawes 3.35 #include "XIproto.h"
 90            #include "exevents.h"
 91 dawes 3.22 #endif
 92            
 93 dawes 3.11 #ifdef XKB
 94 dawes 3.12 #include <X11/extensions/XKB.h>
 95            #include <X11/extensions/XKBstr.h>
 96            #include <X11/extensions/XKBsrv.h>
 97 dawes 3.11 #endif
 98            
 99 dawes 3.6  unsigned int xf86InitialCaps = 0;
100            unsigned int xf86InitialNum = 0;
101            unsigned int xf86InitialScroll = 0;
102 dawes 1.1  
103            #include "atKeynames.h"
104            
105            /*
106             * xf86KbdBell --
107             *	Ring the terminal/keyboard bell for an amount of time proportional to
108             *      "loudness".
109             */
110            
111            void
112            xf86KbdBell(percent, pKeyboard, ctrl, unused)
113                 int           percent;          /* Percentage of full volume */
114                 DeviceIntPtr  pKeyboard;        /* Keyboard to ring */
115                 pointer	   ctrl;	
116                 int	   unused;	
117            {
118              xf86SoundKbdBell(percent, xf86Info.bell_pitch, xf86Info.bell_duration);
119            }
120            
121            void
122 dawes 3.51 xf86UpdateKbdLeds()
123            {
124              int leds = 0;
125              if (xf86Info.capsLock) leds |= XLED1;
126              if (xf86Info.numLock)  leds |= XLED2;
127              if (xf86Info.scrollLock || xf86Info.modeSwitchLock) leds |= XLED3;
128              if (xf86Info.composeLock) leds |= XLED4;
129              xf86Info.leds = (xf86Info.leds & xf86Info.xleds) | (leds & ~xf86Info.xleds);
130              xf86KbdLeds();
131            }
132            
133            void
134 dawes 1.1  xf86KbdLeds ()
135            {
136 dawes 3.51   int leds, real_leds = 0;
137            
138 herrb 3.55 #if defined (__sparc__) && defined(__linux__)
139 dawes 3.51   static int kbdSun = -1;
140              if (kbdSun == -1) {
141              if ((xf86Info.xkbmodel && !strcmp(xf86Info.xkbmodel, "sun")) ||
142                  (xf86Info.xkbrules && !strcmp(xf86Info.xkbrules, "sun")))
143                  kbdSun = 1;
144              else
145                  kbdSun = 0;
146              }
147              if (kbdSun) {
148                 if (xf86Info.leds & 0x08) real_leds |= XLED1;
149                 if (xf86Info.leds & 0x04) real_leds |= XLED3;
150                 if (xf86Info.leds & 0x02) real_leds |= XLED4;
151                 if (xf86Info.leds & 0x01) real_leds |= XLED2;
152                 leds = real_leds;
153                 real_leds = 0;
154              } else {
155                 leds = xf86Info.leds;
156 dawes 3.14   }
157 dawes 3.52 #else
158              leds = xf86Info.leds;
159 dawes 3.51 #endif /* defined (__sparc__) */
160 dawes 3.52 
161 dawes 3.51 #ifdef LED_CAP
162              if (leds & XLED1)  real_leds |= LED_CAP;
163              if (leds & XLED2)  real_leds |= LED_NUM;
164              if (leds & XLED3)  real_leds |= LED_SCR;
165            #ifdef LED_COMP
166              if (leds & XLED4)  real_leds |= LED_COMP;
167            #else
168              if (leds & XLED4)  real_leds |= LED_SCR;
169 dawes 3.14 #endif
170 dawes 3.51 #endif
171              xf86SetKbdLeds(real_leds);
172 tsi   3.56   (void)leds;
173 dawes 1.1  }
174            
175            /*
176             * xf86KbdCtrl --
177             *      Alter some of the keyboard control parameters. All special protocol
178             *      values are handled by dix (ProgChangeKeyboardControl)
179             */
180            
181            void
182            xf86KbdCtrl (pKeyboard, ctrl)
183                 DevicePtr     pKeyboard;        /* Keyboard to alter */
184                 KeybdCtrl     *ctrl;
185            {
186 dawes 3.51   int leds;
187 dawes 1.1    xf86Info.bell_pitch    = ctrl->bell_pitch;
188              xf86Info.bell_duration = ctrl->bell_duration;
189              xf86Info.autoRepeat    = ctrl->autoRepeat;
190            
191              xf86Info.composeLock   = (ctrl->leds & XCOMP) ? TRUE : FALSE;
192            
193 dawes 3.51   leds = (ctrl->leds & ~(XCAPS | XNUM | XSCR));
194            #ifdef XKB
195              if (noXkbExtension) {
196            #endif
197                  xf86Info.leds = (leds & xf86Info.xleds)|(xf86Info.leds & ~xf86Info.xleds);
198            #ifdef XKB
199              } else {
200                  xf86Info.leds = leds;
201              }
202            #endif
203            
204 dawes 1.1    xf86KbdLeds();
205            }
206            
207            /*
208             * xf86InitKBD --
209 dawes 3.51  *      Reinitialize the keyboard. Only set Lockkeys according to ours leds.
210 dawes 1.1   *      Depress all other keys.
211             */
212            
213            void
214            xf86InitKBD(init)
215            Bool init;
216            {
217 dawes 3.10   char            leds = 0, rad;
218 dawes 1.1    unsigned int    i;
219              xEvent          kevent;
220 dawes 3.16   DeviceIntPtr    pKeyboard = xf86Info.pKeyboard;
221              KeyClassRec     *keyc = xf86Info.pKeyboard->key;
222 dawes 1.1    KeySym          *map = keyc->curKeySyms.map;
223            
224              kevent.u.keyButtonPointer.time = GetTimeInMillis();
225              kevent.u.keyButtonPointer.rootX = 0;
226              kevent.u.keyButtonPointer.rootY = 0;
227            
228              /*
229               * Hmm... here is the biggest hack of every time !
230               * It may be possible that a switch-vt procedure has finished BEFORE
231               * you released all keys neccessary to do this. That peculiar behavior
232               * can fool the X-server pretty much, cause it assumes that some keys
233               * were not released. TWM may stuck alsmost completly....
234               * OK, what we are doing here is after returning from the vt-switch
235               * exeplicitely unrelease all keyboard keys before the input-devices
236               * are reenabled.
237               */
238 dawes 3.1    for (i = keyc->curKeySyms.minKeyCode, map = keyc->curKeySyms.map;
239                   i < keyc->curKeySyms.maxKeyCode;
240                   i++, map += keyc->curKeySyms.mapWidth)
241 dawes 1.1      if (KeyPressed(i))
242                  {
243 dawes 3.1          switch (*map) {
244            	/* Don't release the lock keys */
245                    case XK_Caps_Lock:
246                    case XK_Shift_Lock:
247                    case XK_Num_Lock:
248                    case XK_Scroll_Lock:
249                    case XK_Kana_Lock:
250            	  break;
251                    default:
252            	  kevent.u.u.detail = i;
253            	  kevent.u.u.type = KeyRelease;
254 dawes 3.16 	  (* pKeyboard->public.processInputProc)(&kevent, pKeyboard, 1);
255 dawes 3.1          }
256 dawes 1.1        }
257              
258              xf86Info.scanPrefix      = 0;
259            
260              if (init)
261                {
262                  /*
263                   * we must deal here with the fact, that on some cases the numlock or
264                   * capslock key are enabled BEFORE the server is started up. So look
265                   * here at the state on the according LEDS to determine whether a
266 dawes 3.9         * lock-key is already set.
267 dawes 1.1         */
268            
269                  xf86Info.capsLock        = FALSE;
270                  xf86Info.numLock         = FALSE;
271                  xf86Info.scrollLock      = FALSE;
272                  xf86Info.modeSwitchLock  = FALSE;
273                  xf86Info.composeLock     = FALSE;
274                
275            #ifdef LED_CAP
276 dawes 3.10 #ifdef INHERIT_LOCK_STATE
277 dawes 1.1        leds = xf86Info.leds;
278            
279 dawes 3.1        for (i = keyc->curKeySyms.minKeyCode, map = keyc->curKeySyms.map;
280 dawes 1.1             i < keyc->curKeySyms.maxKeyCode;
281                       i++, map += keyc->curKeySyms.mapWidth)
282            
283                    switch(*map) {
284            
285                    case XK_Caps_Lock:
286                    case XK_Shift_Lock:
287                      if (leds & LED_CAP) 
288            	    {
289 dawes 3.6  	      xf86InitialCaps = i;
290 dawes 1.1  	      xf86Info.capsLock = TRUE;
291            	    }
292                      break;
293            
294                    case XK_Num_Lock:
295                      if (leds & LED_NUM)
296            	    {
297 dawes 3.6  	      xf86InitialNum = i;
298 dawes 1.1  	      xf86Info.numLock = TRUE;
299            	    }
300                      break;
301            
302                    case XK_Scroll_Lock:
303                    case XK_Kana_Lock:
304                      if (leds & LED_SCR)
305            	    {
306 dawes 3.6  	      xf86InitialScroll = i;
307 dawes 1.1  	      xf86Info.scrollLock = TRUE;
308            	    }
309                      break;
310                    }
311 dawes 3.10 #endif /* INHERIT_LOCK_STATE */
312 dawes 3.15       xf86SetKbdLeds(leds);
313 dawes 1.1  #endif /* LED_CAP */
314 tsi   3.56       (void)leds;
315 dawes 1.1  
316                  if      (xf86Info.kbdDelay <= 375) rad = 0x00;
317                  else if (xf86Info.kbdDelay <= 625) rad = 0x20;
318                  else if (xf86Info.kbdDelay <= 875) rad = 0x40;
319                  else                               rad = 0x60;
320                
321                  if      (xf86Info.kbdRate <=  2)   rad |= 0x1F;
322                  else if (xf86Info.kbdRate >= 30)   rad |= 0x00;
323                  else                               rad |= ((58 / xf86Info.kbdRate) - 2);
324                
325                  xf86SetKbdRepeat(rad);
326                }
327            }
328            
329            /*
330             * xf86KbdProc --
331             *	Handle the initialization, etc. of a keyboard.
332             */
333            
334            int
335            xf86KbdProc (pKeyboard, what)
336 dawes 3.16      DeviceIntPtr pKeyboard;	/* Keyboard to manipulate */
337 dawes 1.1       int       what;	    	/* What to do to it */
338            {
339              KeySymsRec           keySyms;
340              CARD8                modMap[MAP_LENGTH];
341              int                  kbdFd;
342            
343              switch (what) {
344            
345              case DEVICE_INIT:
346                /*
347                 * First open and find the current state of the keyboard.
348                 */
349            
350                xf86KbdInit();
351            
352                xf86KbdGetMapping(&keySyms, modMap);
353                
354 dawes 3.15 
355            #ifndef XKB
356 dawes 1.1      defaultKeyboardControl.leds = xf86GetKbdLeds();
357 dawes 3.15 #else
358                defaultKeyboardControl.leds = 0;
359            #endif
360 dawes 1.1  
361                /*
362                 * Perform final initialization of the system private keyboard
363                 * structure and fill in various slots in the device record
364                 * itself which couldn't be filled in before.
365                 */
366            
367 dawes 3.16     pKeyboard->public.on = FALSE;
368 dawes 1.1  
369 dawes 3.12 #ifdef XKB
370                if (noXkbExtension) {
371            #endif
372 dawes 3.16     InitKeyboardDeviceStruct((DevicePtr)xf86Info.pKeyboard,
373 dawes 1.1  			     &keySyms,
374            			     modMap,
375            			     xf86KbdBell,
376            			     (KbdCtrlProcPtr)xf86KbdCtrl);
377 dawes 3.12 #ifdef XKB
378                } else {
379 dawes 3.53  	XkbComponentNamesRec	names;
380            	XkbDescPtr		desc;
381            	Bool			foundTerminate = FALSE;
382            	int			keyc;
383 dawes 3.17 	if (XkbInitialMap) {
384            	    if ((xf86Info.xkbkeymap = strchr(XkbInitialMap, '/')) != NULL)
385            		xf86Info.xkbkeymap++;
386            	    else
387            		xf86Info.xkbkeymap = XkbInitialMap;
388            	}
389            	if (xf86Info.xkbkeymap) {
390            	    names.keymap = xf86Info.xkbkeymap;
391            	    names.keycodes = NULL;
392            	    names.types = NULL;
393            	    names.compat = NULL;
394            	    names.symbols = NULL;
395            	    names.geometry = NULL;
396            	} else {
397            	    names.keymap = NULL;
398            	    names.keycodes = xf86Info.xkbkeycodes;
399            	    names.types = xf86Info.xkbtypes;
400            	    names.compat = xf86Info.xkbcompat;
401            	    names.symbols = xf86Info.xkbsymbols;
402            	    names.geometry = xf86Info.xkbgeometry;
403            	}
404 dawes 3.26 	if ((xf86Info.xkbkeymap || xf86Info.xkbcomponents_specified)
405            	   && (xf86Info.xkbmodel == NULL || xf86Info.xkblayout == NULL)) {
406            		xf86Info.xkbrules = NULL;
407            	}
408            	XkbSetRulesDflts(xf86Info.xkbrules, xf86Info.xkbmodel,
409            			 xf86Info.xkblayout, xf86Info.xkbvariant,
410            			 xf86Info.xkboptions);
411 eich  3.47 	
412 dawes 3.16 	XkbInitKeyboardDeviceStruct(pKeyboard, 
413 dawes 3.12 				    &names,
414            				    &keySyms, 
415            				    modMap, 
416            				    xf86KbdBell,
417            				    (KbdCtrlProcPtr)xf86KbdCtrl);
418 dawes 3.53 
419            	/* Search keymap for Terminate action */
420            	desc  = pKeyboard->key->xkbInfo->desc;
421            	for (keyc = desc->min_key_code; keyc <= desc->max_key_code; keyc++) {
422            	    int i;
423            	    for (i = 1; i <= XkbKeyNumActions(desc, keyc); i++) {
424            		if (XkbKeyAction(desc, keyc, i)
425            		  && XkbKeyAction(desc, keyc, i)->type == XkbSA_Terminate) {
426            		    foundTerminate = TRUE;
427            		    goto searchdone;
428            		}
429            	    }
430              	}
431            searchdone:
432            	xf86Info.ActionKeyBindingsSet = foundTerminate;
433            	if (!foundTerminate)
434            	    xf86Msg(X_INFO, "Server_Terminate keybinding not found\n");
435 dawes 3.12     }
436            #endif
437 dawes 1.1      
438                xf86InitKBD(TRUE);
439                break;
440                
441              case DEVICE_ON:
442                /*
443                 * Set the keyboard into "direct" mode and turn on
444                 * event translation.
445                 */
446            
447                kbdFd = xf86KbdOn();
448 dawes 3.17     /*
449                 * Discard any pending input after a VT switch to prevent the server
450                 * passing on parts of the VT switch sequence.
451                 */
452 dawes 3.18     sleep(1);
453 herrb 3.48 #if defined(WSCONS_SUPPORT)
454                if (xf86Info.consType != WSCONS) {
455            #endif
456            	if (kbdFd != -1) {
457            		char buf[16];
458            		read(kbdFd, buf, 16);
459                	}
460            #if defined(WSCONS_SUPPORT)
461 dawes 3.17     }
462 herrb 3.48 #endif
463 dawes 1.1  
464 dawes 3.49 #if !defined(__UNIXOS2__) /* Under EMX, keyboard cannot be select()'ed */
465 dawes 1.1      if (kbdFd != -1)
466                  AddEnabledDevice(kbdFd);
467 dawes 3.49 #endif  /* __UNIXOS2__ */
468 dawes 1.1  
469 dawes 3.16     pKeyboard->public.on = TRUE;
470 dawes 1.1      xf86InitKBD(FALSE);
471                break;
472                
473              case DEVICE_CLOSE:
474              case DEVICE_OFF:
475                /*
476                 * Restore original keyboard directness and translation.
477                 */
478            
479                kbdFd = xf86KbdOff();
480            
481                if (kbdFd != -1)
482                  RemoveEnabledDevice(kbdFd);
483            
484 dawes 3.16     pKeyboard->public.on = FALSE;
485 dawes 1.1      break;
486            
487              }
488              return (Success);
489            }
490            
491 tsi   3.42 #if defined(DDXTIME) && !defined(QNX4)
492 dawes 1.1  /*
493             * These are getting tossed in here until I can think of where
494             * they really belong
495             */
496 eich  3.45 #define HALFMONTH ((unsigned long) 1<<31)
497 dawes 1.1  CARD32
498            GetTimeInMillis()
499            {
500                struct timeval  tp;
501 eich  3.45     register CARD32 val;
502 eich  3.50     register INT32 diff;
503 eich  3.45     static CARD32 oldval = 0;
504 eich  3.50     static CARD32 time = 0;
505 dawes 1.1  
506                gettimeofday(&tp, 0);
507 eich  3.50     val = (tp.tv_sec * 1000) + (tp.tv_usec / 1000);
508                if (oldval) {
509            	diff = val - oldval;
510            	if (diff > 0)
511            	    time += diff;
512 eich  3.45     }
513                oldval = val;
514 eich  3.50 
515                return time;
516 dawes 1.1  }
517 tsi   3.42 #endif /* DDXTIME && !QNX4 */
518 dawes 1.1  

Powered by
ViewCVS 0.9.2