Bug Summary

File:hw/xfree86/common/xf86Events.c
Location:line 711, column 21
Description:Access to field 'next' results in a dereference of a null pointer (loaded from variable 'p')

Annotated Source Code

1/*
2 * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Thomas Roell not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Thomas Roell makes no representations
11 * about the suitability of this software for any purpose. It is provided
12 * "as is" without express or implied warranty.
13 *
14 * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 *
22 */
23/*
24 * Copyright (c) 1994-2003 by The XFree86 Project, Inc.
25 *
26 * Permission is hereby granted, free of charge, to any person obtaining a
27 * copy of this software and associated documentation files (the "Software"),
28 * to deal in the Software without restriction, including without limitation
29 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
30 * and/or sell copies of the Software, and to permit persons to whom the
31 * Software is furnished to do so, subject to the following conditions:
32 *
33 * The above copyright notice and this permission notice shall be included in
34 * all copies or substantial portions of the Software.
35 *
36 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
37 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
38 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
39 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
40 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
41 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
42 * OTHER DEALINGS IN THE SOFTWARE.
43 *
44 * Except as contained in this notice, the name of the copyright holder(s)
45 * and author(s) shall not be used in advertising or otherwise to promote
46 * the sale, use or other dealings in this Software without prior written
47 * authorization from the copyright holder(s) and author(s).
48 */
49
50/* [JCH-96/01/21] Extended std reverse map to four buttons. */
51
52#ifdef HAVE_XORG_CONFIG_H1
53#include <xorg-config.h>
54#endif
55
56#include <X11/X.h>
57#include <X11/Xpoll.h>
58#include <X11/Xproto.h>
59#include <X11/Xatom.h>
60#include "misc.h"
61#include "xf86.h"
62#include "xf86Priv.h"
63#define XF86_OS_PRIVS
64#include "xf86_OSlib.h"
65#include <X11/keysym.h>
66
67#ifdef XFreeXDGA1
68#include "dgaproc.h"
69#endif
70
71#include <X11/extensions/XI.h>
72#include <X11/extensions/XIproto.h>
73#include "inputstr.h"
74#include "xf86Xinput.h"
75
76#include "mi.h"
77#include "mipointer.h"
78
79#include "xkbsrv.h"
80#include "xkbstr.h"
81
82#ifdef DPMSExtension1
83#include <X11/extensions/dpmsconst.h>
84#include "dpmsproc.h"
85#endif
86
87#include "xf86platformBus.h"
88#include "systemd-logind.h"
89
90/*
91 * This is a toggling variable:
92 * FALSE = No VT switching keys have been pressed last time around
93 * TRUE = Possible VT switch Pending
94 * (DWH - 12/2/93)
95 *
96 * This has been generalised to work with Linux and *BSD+syscons (DHD)
97 */
98
99Bool VTSwitchEnabled = TRUE1; /* Allows run-time disabling for
100 *BSD and for avoiding VT
101 switches when using the DRI
102 automatic full screen mode.*/
103
104extern fd_set EnabledDevices;
105
106#ifdef XF86PM
107extern void (*xf86OSPMClose) (void);
108#endif
109
110static void xf86VTSwitch(void);
111
112/*
113 * Allow arbitrary drivers or other XFree86 code to register with our main
114 * Wakeup handler.
115 */
116typedef struct x_IHRec {
117 int fd;
118 InputHandlerProc ihproc;
119 void *data;
120 Bool enabled;
121 Bool is_input;
122 struct x_IHRec *next;
123} IHRec, *IHPtr;
124
125static IHPtr InputHandlers = NULL((void*)0);
126
127Bool
128LegalModifier(unsigned int key, DeviceIntPtr pDev)
129{
130 return TRUE1;
131}
132
133/*
134 * TimeSinceLastInputEvent --
135 * Function used for screensaver purposes by the os module. Returns the
136 * time in milliseconds since there last was any input.
137 */
138int
139TimeSinceLastInputEvent(void)
140{
141 if (xf86Info.lastEventTime == 0) {
142 xf86Info.lastEventTime = GetTimeInMillis();
143 }
144 return GetTimeInMillis() - xf86Info.lastEventTime;
145}
146
147/*
148 * SetTimeSinceLastInputEvent --
149 * Set the lastEventTime to now.
150 */
151void
152SetTimeSinceLastInputEvent(void)
153{
154 xf86Info.lastEventTime = GetTimeInMillis();
155}
156
157/*
158 * ProcessInputEvents --
159 * Retrieve all waiting input events and pass them to DIX in their
160 * correct chronological order. Only reads from the system pointer
161 * and keyboard.
162 */
163void
164ProcessInputEvents(void)
165{
166 int x, y;
167
168 mieqProcessInputEvents();
169
170 /* FIXME: This is a problem if we have multiple pointers */
171 miPointerGetPosition(inputInfo.pointer, &x, &y);
172
173 xf86SetViewport(xf86Info.currentScreen, x, y);
174}
175
176/*
177 * Handle keyboard events that cause some kind of "action"
178 * (i.e., server termination, video mode changes, VT switches, etc.)
179 */
180void
181xf86ProcessActionEvent(ActionEvent action, void *arg)
182{
183 DebugF("ProcessActionEvent(%d,%p)\n", (int) action, arg);
184 switch (action) {
185 case ACTION_TERMINATE:
186 if (!xf86Info.dontZap) {
187 xf86Msg(X_INFO, "Server zapped. Shutting down.\n");
188#ifdef XFreeXDGA1
189 DGAShutdown();
190#endif
191 GiveUp(0);
192 }
193 break;
194 case ACTION_NEXT_MODE:
195 if (!xf86Info.dontZoom)
196 xf86ZoomViewport(xf86Info.currentScreen, 1);
197 break;
198 case ACTION_PREV_MODE:
199 if (!xf86Info.dontZoom)
200 xf86ZoomViewport(xf86Info.currentScreen, -1);
201 break;
202 case ACTION_SWITCHSCREEN:
203 if (VTSwitchEnabled && !xf86Info.dontVTSwitch && arg) {
204 int vtno = *((int *) arg);
205
206 if (vtno != xf86Info.vtno) {
207 if (!xf86VTActivate(vtno)) {
208 ErrorF("Failed to switch from vt%02d to vt%02d: %s\n",
209 xf86Info.vtno, vtno, strerror(errno(*__error())));
210 }
211 }
212 }
213 break;
214 case ACTION_SWITCHSCREEN_NEXT:
215 if (VTSwitchEnabled && !xf86Info.dontVTSwitch) {
216 if (!xf86VTActivate(xf86Info.vtno + 1)) {
217 /* If first try failed, assume this is the last VT and
218 * try wrapping around to the first vt.
219 */
220 if (!xf86VTActivate(1)) {
221 ErrorF("Failed to switch from vt%02d to next vt: %s\n",
222 xf86Info.vtno, strerror(errno(*__error())));
223 }
224 }
225 }
226 break;
227 case ACTION_SWITCHSCREEN_PREV:
228 if (VTSwitchEnabled && !xf86Info.dontVTSwitch && xf86Info.vtno > 0) {
229 if (!xf86VTActivate(xf86Info.vtno - 1)) {
230 /* Don't know what the maximum VT is, so can't wrap around */
231 ErrorF("Failed to switch from vt%02d to previous vt: %s\n",
232 xf86Info.vtno, strerror(errno(*__error())));
233 }
234 }
235 break;
236 default:
237 break;
238 }
239}
240
241/*
242 * xf86Wakeup --
243 * Os wakeup handler.
244 */
245
246/* ARGSUSED */
247void
248xf86Wakeup(void *blockData, int err, void *pReadmask)
249{
250 fd_set *LastSelectMask = (fd_set *) pReadmask;
251 fd_set devicesWithInput;
252 InputInfoPtr pInfo;
253
254 if (err >= 0) {
255
256 XFD_ANDSET(&devicesWithInput, LastSelectMask, &EnabledDevices){ int __i__; for (__i__ = 0; __i__ < ((((1024) % ((sizeof(
__int32_t) * 8))) == 0) ? ((1024) / ((sizeof(__int32_t) * 8))
) : (((1024) / ((sizeof(__int32_t) * 8))) + 1)); __i__++) (((
(&devicesWithInput))->fds_bits))[__i__] = ((((((LastSelectMask
))->fds_bits))[__i__]) & (((((&EnabledDevices))->
fds_bits))[__i__])); }
;
257 if (XFD_ANYSET(&devicesWithInput)((((((1024) % ((sizeof(__int32_t) * 8))) == 0) ? ((1024) / ((
sizeof(__int32_t) * 8))) : (((1024) / ((sizeof(__int32_t) * 8
))) + 1)) > 0 && ((((&devicesWithInput)->fds_bits
))[0])) || (((((1024) % ((sizeof(__int32_t) * 8))) == 0) ? ((
1024) / ((sizeof(__int32_t) * 8))) : (((1024) / ((sizeof(__int32_t
) * 8))) + 1)) > 1 && ((((&devicesWithInput)->
fds_bits))[1])) || (((((1024) % ((sizeof(__int32_t) * 8))) ==
0) ? ((1024) / ((sizeof(__int32_t) * 8))) : (((1024) / ((sizeof
(__int32_t) * 8))) + 1)) > 2 && ((((&devicesWithInput
)->fds_bits))[2])) || (((((1024) % ((sizeof(__int32_t) * 8
))) == 0) ? ((1024) / ((sizeof(__int32_t) * 8))) : (((1024) /
((sizeof(__int32_t) * 8))) + 1)) > 3 && ((((&
devicesWithInput)->fds_bits))[3])) || (((((1024) % ((sizeof
(__int32_t) * 8))) == 0) ? ((1024) / ((sizeof(__int32_t) * 8)
)) : (((1024) / ((sizeof(__int32_t) * 8))) + 1)) > 4 &&
((((&devicesWithInput)->fds_bits))[4])) || (((((1024)
% ((sizeof(__int32_t) * 8))) == 0) ? ((1024) / ((sizeof(__int32_t
) * 8))) : (((1024) / ((sizeof(__int32_t) * 8))) + 1)) > 5
&& ((((&devicesWithInput)->fds_bits))[5])) ||
(((((1024) % ((sizeof(__int32_t) * 8))) == 0) ? ((1024) / ((
sizeof(__int32_t) * 8))) : (((1024) / ((sizeof(__int32_t) * 8
))) + 1)) > 6 && ((((&devicesWithInput)->fds_bits
))[6])) || (((((1024) % ((sizeof(__int32_t) * 8))) == 0) ? ((
1024) / ((sizeof(__int32_t) * 8))) : (((1024) / ((sizeof(__int32_t
) * 8))) + 1)) > 7 && ((((&devicesWithInput)->
fds_bits))[7])) || (((((1024) % ((sizeof(__int32_t) * 8))) ==
0) ? ((1024) / ((sizeof(__int32_t) * 8))) : (((1024) / ((sizeof
(__int32_t) * 8))) + 1)) > 8 && ((((&devicesWithInput
)->fds_bits))[8])) || (((((1024) % ((sizeof(__int32_t) * 8
))) == 0) ? ((1024) / ((sizeof(__int32_t) * 8))) : (((1024) /
((sizeof(__int32_t) * 8))) + 1)) > 9 && ((((&
devicesWithInput)->fds_bits))[9])) || (((((1024) % ((sizeof
(__int32_t) * 8))) == 0) ? ((1024) / ((sizeof(__int32_t) * 8)
)) : (((1024) / ((sizeof(__int32_t) * 8))) + 1)) > 10 &&
((((&devicesWithInput)->fds_bits))[10])) || (((((1024
) % ((sizeof(__int32_t) * 8))) == 0) ? ((1024) / ((sizeof(__int32_t
) * 8))) : (((1024) / ((sizeof(__int32_t) * 8))) + 1)) > 11
&& ((((&devicesWithInput)->fds_bits))[11])) ||
(((((1024) % ((sizeof(__int32_t) * 8))) == 0) ? ((1024) / ((
sizeof(__int32_t) * 8))) : (((1024) / ((sizeof(__int32_t) * 8
))) + 1)) > 12 && ((((&devicesWithInput)->fds_bits
))[12])) || (((((1024) % ((sizeof(__int32_t) * 8))) == 0) ? (
(1024) / ((sizeof(__int32_t) * 8))) : (((1024) / ((sizeof(__int32_t
) * 8))) + 1)) > 13 && ((((&devicesWithInput)->
fds_bits))[13])) || (((((1024) % ((sizeof(__int32_t) * 8))) ==
0) ? ((1024) / ((sizeof(__int32_t) * 8))) : (((1024) / ((sizeof
(__int32_t) * 8))) + 1)) > 14 && ((((&devicesWithInput
)->fds_bits))[14])) || (((((1024) % ((sizeof(__int32_t) * 8
))) == 0) ? ((1024) / ((sizeof(__int32_t) * 8))) : (((1024) /
((sizeof(__int32_t) * 8))) + 1)) > 15 && ((((&
devicesWithInput)->fds_bits))[15])))
) {
258 pInfo = xf86InputDevs;
259 while (pInfo) {
260 if (pInfo->read_input && pInfo->fd >= 0 &&
261 (FD_ISSET(pInfo->fd, &devicesWithInput)__darwin_fd_isset((pInfo->fd), (&devicesWithInput)) != 0)) {
262 input_lock();
263
264 /*
265 * Remove the descriptior from the set because more than one
266 * device may share the same file descriptor.
267 */
268 FD_CLR(pInfo->fd, &devicesWithInput)do { int __fd = (pInfo->fd); ((&devicesWithInput)->
fds_bits[(unsigned long)__fd/(sizeof(__int32_t) * 8)] &= ~
((__int32_t)(1<<((unsigned long)__fd % (sizeof(__int32_t
) * 8))))); } while(0)
;
269
270 pInfo->read_input(pInfo);
271 input_unlock();
272 }
273 pInfo = pInfo->next;
274 }
275 }
276 }
277
278 if (err >= 0) { /* we don't want the handlers called if select() */
279 IHPtr ih, ih_tmp; /* returned with an error condition, do we? */
280
281 nt_list_for_each_entry_safe(ih, ih_tmp, InputHandlers, next)for (ih = InputHandlers, ih_tmp = (ih) ? (ih)->next : ((void
*)0); ih; ih = ih_tmp, ih_tmp = (ih_tmp) ? (ih_tmp)->next:
((void*)0))
{
282 if (ih->enabled && ih->fd >= 0 && ih->ihproc &&
283 (FD_ISSET(ih->fd, ((fd_set *) pReadmask))__darwin_fd_isset((ih->fd), (((fd_set *) pReadmask))) != 0)) {
284 ih->ihproc(ih->fd, ih->data);
285 }
286 }
287 }
288
289 if (xf86VTSwitchPending())
290 xf86VTSwitch();
291}
292
293/*
294 * xf86ReadInput --
295 * input thread handler
296 */
297
298static void
299xf86ReadInput(int fd, int ready, void *closure)
300{
301 InputInfoPtr pInfo = closure;
302
303 pInfo->read_input(pInfo);
304}
305
306/*
307 * xf86AddEnabledDevice --
308 *
309 */
310void
311xf86AddEnabledDevice(InputInfoPtr pInfo)
312{
313 InputThreadRegisterDev(pInfo->fd, xf86ReadInput, pInfo);
314}
315
316/*
317 * xf86RemoveEnabledDevice --
318 *
319 */
320void
321xf86RemoveEnabledDevice(InputInfoPtr pInfo)
322{
323 InputThreadUnregisterDev(pInfo->fd);
324}
325
326static int *xf86SignalIntercept = NULL((void*)0);
327
328void
329xf86InterceptSignals(int *signo)
330{
331 if ((xf86SignalIntercept = signo))
332 *signo = -1;
333}
334
335static void (*xf86SigIllHandler) (void) = NULL((void*)0);
336
337void
338xf86InterceptSigIll(void (*sigillhandler) (void))
339{
340 xf86SigIllHandler = sigillhandler;
341}
342
343/*
344 * xf86SigWrapper --
345 * Catch unexpected signals and exit or continue cleanly.
346 */
347int
348xf86SigWrapper(int signo)
349{
350 if ((signo == SIGILL4) && xf86SigIllHandler) {
351 (*xf86SigIllHandler) ();
352 return 0; /* continue */
353 }
354
355 if (xf86SignalIntercept && (*xf86SignalIntercept < 0)) {
356 *xf86SignalIntercept = signo;
357 return 0; /* continue */
358 }
359
360 xf86Info.caughtSignal = TRUE1;
361 return 1; /* abort */
362}
363
364/*
365 * xf86PrintBacktrace --
366 * Print a stack backtrace for debugging purposes.
367 */
368void
369xf86PrintBacktrace(void)
370{
371 xorg_backtrace();
372}
373
374static void
375xf86ReleaseKeys(DeviceIntPtr pDev)
376{
377 KeyClassPtr keyc;
378 int i;
379
380 if (!pDev || !pDev->key)
381 return;
382
383 keyc = pDev->key;
384
385 /*
386 * Hmm... here is the biggest hack of every time !
387 * It may be possible that a switch-vt procedure has finished BEFORE
388 * you released all keys neccessary to do this. That peculiar behavior
389 * can fool the X-server pretty much, cause it assumes that some keys
390 * were not released. TWM may stuck alsmost completly....
391 * OK, what we are doing here is after returning from the vt-switch
392 * exeplicitely unrelease all keyboard keys before the input-devices
393 * are reenabled.
394 */
395
396 for (i = keyc->xkbInfo->desc->min_key_code;
397 i < keyc->xkbInfo->desc->max_key_code; i++) {
398 if (key_is_down(pDev, i, KEY_POSTED2)) {
399 input_lock();
400 QueueKeyboardEvents(pDev, KeyRelease3, i);
401 input_unlock();
402 }
403 }
404}
405
406void
407xf86DisableInputDeviceForVTSwitch(InputInfoPtr pInfo)
408{
409 if (!pInfo->dev)
410 return;
411
412 if (!pInfo->dev->enabled)
413 pInfo->flags |= XI86_DEVICE_DISABLED0x10;
414
415 xf86ReleaseKeys(pInfo->dev);
416 ProcessInputEvents();
417 DisableDevice(pInfo->dev, TRUE1);
418}
419
420void
421xf86EnableInputDeviceForVTSwitch(InputInfoPtr pInfo)
422{
423 if (pInfo->dev && (pInfo->flags & XI86_DEVICE_DISABLED0x10) == 0)
424 EnableDevice(pInfo->dev, TRUE1);
425 pInfo->flags &= ~XI86_DEVICE_DISABLED0x10;
426}
427
428/*
429 * xf86UpdateHasVTProperty --
430 * Update a flag property on the root window to say whether the server VT
431 * is currently the active one as some clients need to know this.
432 */
433static void
434xf86UpdateHasVTProperty(Bool hasVT)
435{
436 Atom property_name;
437 int32_t value = hasVT ? 1 : 0;
438 int i;
439
440 property_name = MakeAtom(HAS_VT_ATOM_NAME"XFree86_has_VT", sizeof(HAS_VT_ATOM_NAME"XFree86_has_VT") - 1,
441 FALSE0);
442 if (property_name == BAD_RESOURCE0xe0000000)
443 FatalError("Failed to retrieve \"HAS_VT\" atom\n");
444 for (i = 0; i < xf86NumScreens; i++) {
445 dixChangeWindowProperty(serverClient,
446 xf86ScrnToScreen(xf86Screens[i])->root,
447 property_name, XA_INTEGER((Atom) 19), 32,
448 PropModeReplace0, 1, &value, TRUE1);
449 }
450}
451
452void
453xf86VTLeave(void)
454{
455 int i;
456 InputInfoPtr pInfo;
457 IHPtr ih;
458
459 DebugF("xf86VTSwitch: Leaving, xf86Exiting is %s\n",
460 BOOLTOSTRING((dispatchException & DE_TERMINATE) ? TRUE : FALSE));
461#ifdef DPMSExtension1
462 if (DPMSPowerLevel != DPMSModeOn0)
463 DPMSSet(serverClient, DPMSModeOn0);
464#endif
465 for (i = 0; i < xf86NumScreens; i++) {
466 if (!(dispatchException & DE_TERMINATE2))
467 if (xf86Screens[i]->EnableDisableFBAccess)
468 (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], FALSE0);
469 }
470
471 /*
472 * Keep the order: Disable Device > LeaveVT
473 * EnterVT > EnableDevice
474 */
475 for (ih = InputHandlers; ih; ih = ih->next) {
476 if (ih->is_input)
477 xf86DisableInputHandler(ih);
478 else
479 xf86DisableGeneralHandler(ih);
480 }
481 for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next)
482 xf86DisableInputDeviceForVTSwitch(pInfo);
483
484 input_lock();
485 for (i = 0; i < xf86NumScreens; i++)
486 xf86Screens[i]->LeaveVT(xf86Screens[i]);
487 for (i = 0; i < xf86NumGPUScreens; i++)
488 xf86GPUScreens[i]->LeaveVT(xf86GPUScreens[i]);
489
490 xf86AccessLeave(); /* We need this here, otherwise */
491
492 if (!xf86VTSwitchAway())
493 goto switch_failed;
494
495#ifdef XF86PM
496 if (xf86OSPMClose)
497 xf86OSPMClose();
498 xf86OSPMClose = NULL((void*)0);
499#endif
500
501 for (i = 0; i < xf86NumScreens; i++) {
502 /*
503 * zero all access functions to
504 * trap calls when switched away.
505 */
506 xf86Screens[i]->vtSema = FALSE0;
507 }
508 if (xorgHWAccess)
509 xf86DisableIO();
510
511 xf86UpdateHasVTProperty(FALSE0);
512
513 return;
514
515switch_failed:
516 DebugF("xf86VTSwitch: Leave failed\n");
517 xf86AccessEnter();
518 for (i = 0; i < xf86NumScreens; i++) {
519 if (!xf86Screens[i]->EnterVT(xf86Screens[i]))
520 FatalError("EnterVT failed for screen %d\n", i);
521 }
522 for (i = 0; i < xf86NumGPUScreens; i++) {
523 if (!xf86GPUScreens[i]->EnterVT(xf86GPUScreens[i]))
524 FatalError("EnterVT failed for gpu screen %d\n", i);
525 }
526 if (!(dispatchException & DE_TERMINATE2)) {
527 for (i = 0; i < xf86NumScreens; i++) {
528 if (xf86Screens[i]->EnableDisableFBAccess)
529 (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], TRUE1);
530 }
531 }
532 dixSaveScreens(serverClient, SCREEN_SAVER_FORCER2, ScreenSaverReset0);
533
534 for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next)
535 xf86EnableInputDeviceForVTSwitch(pInfo);
536 for (ih = InputHandlers; ih; ih = ih->next) {
537 if (ih->is_input)
538 xf86EnableInputHandler(ih);
539 else
540 xf86EnableGeneralHandler(ih);
541 }
542 input_unlock();
543}
544
545void
546xf86VTEnter(void)
547{
548 int i;
549 InputInfoPtr pInfo;
550 IHPtr ih;
551
552 DebugF("xf86VTSwitch: Entering\n");
553 if (!xf86VTSwitchTo())
554 return;
555
556#ifdef XF86PM
557 xf86OSPMClose = xf86OSPMOpen();
558#endif
559
560 if (xorgHWAccess)
561 xf86EnableIO();
562 xf86AccessEnter();
563 for (i = 0; i < xf86NumScreens; i++) {
564 xf86Screens[i]->vtSema = TRUE1;
565 if (!xf86Screens[i]->EnterVT(xf86Screens[i]))
566 FatalError("EnterVT failed for screen %d\n", i);
567 }
568 for (i = 0; i < xf86NumGPUScreens; i++) {
569 xf86GPUScreens[i]->vtSema = TRUE1;
570 if (!xf86GPUScreens[i]->EnterVT(xf86GPUScreens[i]))
571 FatalError("EnterVT failed for gpu screen %d\n", i);
572 }
573 for (i = 0; i < xf86NumScreens; i++) {
574 if (xf86Screens[i]->EnableDisableFBAccess)
575 (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], TRUE1);
576 }
577
578 /* Turn screen saver off when switching back */
579 dixSaveScreens(serverClient, SCREEN_SAVER_FORCER2, ScreenSaverReset0);
580
581 for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next) {
582 /* Devices with server managed fds get enabled on logind resume */
583 if (!(pInfo->flags & XI86_SERVER_FD0x20))
584 xf86EnableInputDeviceForVTSwitch(pInfo);
585 }
586
587 for (ih = InputHandlers; ih; ih = ih->next) {
588 if (ih->is_input)
589 xf86EnableInputHandler(ih);
590 else
591 xf86EnableGeneralHandler(ih);
592 }
593#ifdef XSERVER_PLATFORM_BUS
594 /* check for any new output devices */
595 xf86platformVTProbe();
596#endif
597
598 xf86UpdateHasVTProperty(TRUE1);
599
600 input_unlock();
601}
602
603/*
604 * xf86VTSwitch --
605 * Handle requests for switching the vt.
606 */
607static void
608xf86VTSwitch(void)
609{
610 DebugF("xf86VTSwitch()\n");
611
612#ifdef XFreeXDGA1
613 if (!DGAVTSwitch())
614 return;
615#endif
616
617 /*
618 * Since all screens are currently all in the same state it is sufficient
619 * check the first. This might change in future.
620 *
621 * VTLeave is always handled here (VT_PROCESS guarantees this is safe),
622 * if we use systemd_logind xf86VTEnter() gets called by systemd-logind.c
623 * once it has resumed all drm nodes.
624 */
625 if (xf86VTOwner())
626 xf86VTLeave();
627 else if (!systemd_logind_controls_session()0)
628 xf86VTEnter();
629}
630
631/* Input handler registration */
632
633static void *
634addInputHandler(int fd, InputHandlerProc proc, void *data)
635{
636 IHPtr ih;
637
638 if (fd < 0 || !proc)
639 return NULL((void*)0);
640
641 ih = calloc(sizeof(*ih), 1);
642 if (!ih)
643 return NULL((void*)0);
644
645 ih->fd = fd;
646 ih->ihproc = proc;
647 ih->data = data;
648 ih->enabled = TRUE1;
649
650 ih->next = InputHandlers;
651 InputHandlers = ih;
652
653 return ih;
654}
655
656void *
657xf86AddInputHandler(int fd, InputHandlerProc proc, void *data)
658{
659 IHPtr ih = addInputHandler(fd, proc, data);
660
661 if (ih) {
662 AddEnabledDevice(fd);
663 ih->is_input = TRUE1;
664 }
665 return ih;
666}
667
668void *
669xf86AddGeneralHandler(int fd, InputHandlerProc proc, void *data)
670{
671 IHPtr ih = addInputHandler(fd, proc, data);
672
673 if (ih)
674 AddGeneralSocket(fd);
675 return ih;
676}
677
678/**
679 * Set the handler for the console's fd. Replaces (and returns) the previous
680 * handler or NULL, whichever appropriate.
681 * proc may be NULL if the server should not handle events on the console.
682 */
683InputHandlerProc
684xf86SetConsoleHandler(InputHandlerProc proc, void *data)
685{
686 static IHPtr handler = NULL((void*)0);
687 InputHandlerProc old_proc = NULL((void*)0);
688
689 if (handler) {
690 old_proc = handler->ihproc;
691 xf86RemoveGeneralHandler(handler);
692 }
693
694 handler = xf86AddGeneralHandler(xf86Info.consoleFd, proc, data);
695
696 return old_proc;
697}
698
699static void
700removeInputHandler(IHPtr ih)
701{
702 IHPtr p;
703
704 if (ih == InputHandlers)
5
Assuming 'ih' is not equal to 'InputHandlers'
6
Taking false branch
705 InputHandlers = ih->next;
706 else {
707 p = InputHandlers;
7
Value assigned to 'p'
708 while (p && p->next != ih)
8
Assuming pointer value is null
709 p = p->next;
710 if (ih)
9
Taking true branch
711 p->next = ih->next;
10
Access to field 'next' results in a dereference of a null pointer (loaded from variable 'p')
712 }
713 free(ih);
714}
715
716int
717xf86RemoveInputHandler(void *handler)
718{
719 IHPtr ih;
720 int fd;
721
722 if (!handler)
723 return -1;
724
725 ih = handler;
726 fd = ih->fd;
727
728 if (ih->fd >= 0)
729 RemoveEnabledDevice(ih->fd);
730 removeInputHandler(ih);
731
732 return fd;
733}
734
735int
736xf86RemoveGeneralHandler(void *handler)
737{
738 IHPtr ih;
739 int fd;
740
741 if (!handler)
1
Assuming 'handler' is non-null
2
Taking false branch
742 return -1;
743
744 ih = handler;
745 fd = ih->fd;
746
747 if (ih->fd >= 0)
3
Taking false branch
748 RemoveGeneralSocket(ih->fd);
749 removeInputHandler(ih);
4
Calling 'removeInputHandler'
750
751 return fd;
752}
753
754void
755xf86DisableInputHandler(void *handler)
756{
757 IHPtr ih;
758
759 if (!handler)
760 return;
761
762 ih = handler;
763 ih->enabled = FALSE0;
764 if (ih->fd >= 0)
765 RemoveEnabledDevice(ih->fd);
766}
767
768void
769xf86DisableGeneralHandler(void *handler)
770{
771 IHPtr ih;
772
773 if (!handler)
774 return;
775
776 ih = handler;
777 ih->enabled = FALSE0;
778 if (ih->fd >= 0)
779 RemoveGeneralSocket(ih->fd);
780}
781
782void
783xf86EnableInputHandler(void *handler)
784{
785 IHPtr ih;
786
787 if (!handler)
788 return;
789
790 ih = handler;
791 ih->enabled = TRUE1;
792 if (ih->fd >= 0)
793 AddEnabledDevice(ih->fd);
794}
795
796void
797xf86EnableGeneralHandler(void *handler)
798{
799 IHPtr ih;
800
801 if (!handler)
802 return;
803
804 ih = handler;
805 ih->enabled = TRUE1;
806 if (ih->fd >= 0)
807 AddGeneralSocket(ih->fd);
808}
809
810/*
811 * As used currently by the DRI, the return value is ignored.
812 */
813Bool
814xf86EnableVTSwitch(Bool new)
815{
816 static Bool def = TRUE1;
817 Bool old;
818
819 old = VTSwitchEnabled;
820 if (!new) {
821 /* Disable VT switching */
822 def = VTSwitchEnabled;
823 VTSwitchEnabled = FALSE0;
824 }
825 else {
826 /* Restore VT switching to default */
827 VTSwitchEnabled = def;
828 }
829 return old;
830}
831
832void
833DDXRingBell(int volume, int pitch, int duration)
834{
835 xf86OSRingBell(volume, pitch, duration);
836}
837
838Bool
839xf86VTOwner(void)
840{
841 /* at system startup xf86Screens[0] won't be set - but we will own the VT */
842 if (xf86NumScreens == 0)
843 return TRUE1;
844 return xf86Screens[0]->vtSema;
845}