Bug Summary

File:hw/xfree86/common/xf86Events.c
Location:line 716, 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,%x)\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 OsBlockSIGIO();
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 OsReleaseSIGIO();
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 * xf86SigioReadInput --
295 * signal handler for the SIGIO signal.
296 */
297static void
298xf86SigioReadInput(int fd, void *closure)
299{
300 int errno_save = errno(*__error());
301 InputInfoPtr pInfo = closure;
302
303 pInfo->read_input(pInfo);
304
305 errno(*__error()) = errno_save;
306}
307
308/*
309 * xf86AddEnabledDevice --
310 *
311 */
312void
313xf86AddEnabledDevice(InputInfoPtr pInfo)
314{
315 if (!xf86InstallSIGIOHandler(pInfo->fd, xf86SigioReadInput, pInfo)) {
316 AddEnabledDevice(pInfo->fd);
317 }
318}
319
320/*
321 * xf86RemoveEnabledDevice --
322 *
323 */
324void
325xf86RemoveEnabledDevice(InputInfoPtr pInfo)
326{
327 if (!xf86RemoveSIGIOHandler(pInfo->fd)) {
328 RemoveEnabledDevice(pInfo->fd);
329 }
330}
331
332static int *xf86SignalIntercept = NULL((void*)0);
333
334void
335xf86InterceptSignals(int *signo)
336{
337 if ((xf86SignalIntercept = signo))
338 *signo = -1;
339}
340
341static void (*xf86SigIllHandler) (void) = NULL((void*)0);
342
343void
344xf86InterceptSigIll(void (*sigillhandler) (void))
345{
346 xf86SigIllHandler = sigillhandler;
347}
348
349/*
350 * xf86SigWrapper --
351 * Catch unexpected signals and exit or continue cleanly.
352 */
353int
354xf86SigWrapper(int signo)
355{
356 if ((signo == SIGILL4) && xf86SigIllHandler) {
357 (*xf86SigIllHandler) ();
358 return 0; /* continue */
359 }
360
361 if (xf86SignalIntercept && (*xf86SignalIntercept < 0)) {
362 *xf86SignalIntercept = signo;
363 return 0; /* continue */
364 }
365
366 xf86Info.caughtSignal = TRUE1;
367 return 1; /* abort */
368}
369
370/*
371 * xf86PrintBacktrace --
372 * Print a stack backtrace for debugging purposes.
373 */
374void
375xf86PrintBacktrace(void)
376{
377 xorg_backtrace();
378}
379
380static void
381xf86ReleaseKeys(DeviceIntPtr pDev)
382{
383 KeyClassPtr keyc;
384 int i;
385
386 if (!pDev || !pDev->key)
387 return;
388
389 keyc = pDev->key;
390
391 /*
392 * Hmm... here is the biggest hack of every time !
393 * It may be possible that a switch-vt procedure has finished BEFORE
394 * you released all keys neccessary to do this. That peculiar behavior
395 * can fool the X-server pretty much, cause it assumes that some keys
396 * were not released. TWM may stuck alsmost completly....
397 * OK, what we are doing here is after returning from the vt-switch
398 * exeplicitely unrelease all keyboard keys before the input-devices
399 * are reenabled.
400 */
401
402 for (i = keyc->xkbInfo->desc->min_key_code;
403 i < keyc->xkbInfo->desc->max_key_code; i++) {
404 if (key_is_down(pDev, i, KEY_POSTED2)) {
405 OsBlockSIGIO();
406 QueueKeyboardEvents(pDev, KeyRelease3, i, NULL((void*)0));
407 OsReleaseSIGIO();
408 }
409 }
410}
411
412void
413xf86DisableInputDeviceForVTSwitch(InputInfoPtr pInfo)
414{
415 if (!pInfo->dev)
416 return;
417
418 if (!pInfo->dev->enabled)
419 pInfo->flags |= XI86_DEVICE_DISABLED0x10;
420
421 xf86ReleaseKeys(pInfo->dev);
422 ProcessInputEvents();
423 DisableDevice(pInfo->dev, TRUE1);
424}
425
426void
427xf86EnableInputDeviceForVTSwitch(InputInfoPtr pInfo)
428{
429 if (pInfo->dev && (pInfo->flags & XI86_DEVICE_DISABLED0x10) == 0)
430 EnableDevice(pInfo->dev, TRUE1);
431 pInfo->flags &= ~XI86_DEVICE_DISABLED0x10;
432}
433
434/*
435 * xf86UpdateHasVTProperty --
436 * Update a flag property on the root window to say whether the server VT
437 * is currently the active one as some clients need to know this.
438 */
439static void
440xf86UpdateHasVTProperty(Bool hasVT)
441{
442 Atom property_name;
443 int32_t value = hasVT ? 1 : 0;
444 int i;
445
446 property_name = MakeAtom(HAS_VT_ATOM_NAME"XFree86_has_VT", sizeof(HAS_VT_ATOM_NAME"XFree86_has_VT") - 1,
447 FALSE0);
448 if (property_name == BAD_RESOURCE0xe0000000)
449 FatalError("Failed to retrieve \"HAS_VT\" atom\n");
450 for (i = 0; i < xf86NumScreens; i++) {
451 ChangeWindowProperty(xf86ScrnToScreen(xf86Screens[i])->root,
452 property_name, XA_INTEGER((Atom) 19), 32,
453 PropModeReplace0, 1, &value, TRUE1);
454 }
455}
456
457void
458xf86VTLeave(void)
459{
460 int i;
461 InputInfoPtr pInfo;
462 IHPtr ih;
463
464 DebugF("xf86VTSwitch: Leaving, xf86Exiting is %s\n",
465 BOOLTOSTRING((dispatchException & DE_TERMINATE) ? TRUE : FALSE));
466#ifdef DPMSExtension1
467 if (DPMSPowerLevel != DPMSModeOn0)
468 DPMSSet(serverClient, DPMSModeOn0);
469#endif
470 for (i = 0; i < xf86NumScreens; i++) {
471 if (!(dispatchException & DE_TERMINATE2))
472 if (xf86Screens[i]->EnableDisableFBAccess)
473 (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], FALSE0);
474 }
475
476 /*
477 * Keep the order: Disable Device > LeaveVT
478 * EnterVT > EnableDevice
479 */
480 for (ih = InputHandlers; ih; ih = ih->next) {
481 if (ih->is_input)
482 xf86DisableInputHandler(ih);
483 else
484 xf86DisableGeneralHandler(ih);
485 }
486 for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next)
487 xf86DisableInputDeviceForVTSwitch(pInfo);
488
489 OsBlockSIGIO();
490 for (i = 0; i < xf86NumScreens; i++)
491 xf86Screens[i]->LeaveVT(xf86Screens[i]);
492 for (i = 0; i < xf86NumGPUScreens; i++)
493 xf86GPUScreens[i]->LeaveVT(xf86GPUScreens[i]);
494
495 xf86AccessLeave(); /* We need this here, otherwise */
496
497 if (!xf86VTSwitchAway())
498 goto switch_failed;
499
500#ifdef XF86PM
501 if (xf86OSPMClose)
502 xf86OSPMClose();
503 xf86OSPMClose = NULL((void*)0);
504#endif
505
506 for (i = 0; i < xf86NumScreens; i++) {
507 /*
508 * zero all access functions to
509 * trap calls when switched away.
510 */
511 xf86Screens[i]->vtSema = FALSE0;
512 }
513 if (xorgHWAccess)
514 xf86DisableIO();
515
516 xf86UpdateHasVTProperty(FALSE0);
517
518 return;
519
520switch_failed:
521 DebugF("xf86VTSwitch: Leave failed\n");
522 xf86AccessEnter();
523 for (i = 0; i < xf86NumScreens; i++) {
524 if (!xf86Screens[i]->EnterVT(xf86Screens[i]))
525 FatalError("EnterVT failed for screen %d\n", i);
526 }
527 for (i = 0; i < xf86NumGPUScreens; i++) {
528 if (!xf86GPUScreens[i]->EnterVT(xf86GPUScreens[i]))
529 FatalError("EnterVT failed for gpu screen %d\n", i);
530 }
531 if (!(dispatchException & DE_TERMINATE2)) {
532 for (i = 0; i < xf86NumScreens; i++) {
533 if (xf86Screens[i]->EnableDisableFBAccess)
534 (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], TRUE1);
535 }
536 }
537 dixSaveScreens(serverClient, SCREEN_SAVER_FORCER2, ScreenSaverReset0);
538
539 for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next)
540 xf86EnableInputDeviceForVTSwitch(pInfo);
541 for (ih = InputHandlers; ih; ih = ih->next) {
542 if (ih->is_input)
543 xf86EnableInputHandler(ih);
544 else
545 xf86EnableGeneralHandler(ih);
546 }
547 OsReleaseSIGIO();
548}
549
550void
551xf86VTEnter(void)
552{
553 int i;
554 InputInfoPtr pInfo;
555 IHPtr ih;
556
557 DebugF("xf86VTSwitch: Entering\n");
558 if (!xf86VTSwitchTo())
559 return;
560
561#ifdef XF86PM
562 xf86OSPMClose = xf86OSPMOpen();
563#endif
564
565 if (xorgHWAccess)
566 xf86EnableIO();
567 xf86AccessEnter();
568 for (i = 0; i < xf86NumScreens; i++) {
569 xf86Screens[i]->vtSema = TRUE1;
570 if (!xf86Screens[i]->EnterVT(xf86Screens[i]))
571 FatalError("EnterVT failed for screen %d\n", i);
572 }
573 for (i = 0; i < xf86NumGPUScreens; i++) {
574 xf86GPUScreens[i]->vtSema = TRUE1;
575 if (!xf86GPUScreens[i]->EnterVT(xf86GPUScreens[i]))
576 FatalError("EnterVT failed for gpu screen %d\n", i);
577 }
578 for (i = 0; i < xf86NumScreens; i++) {
579 if (xf86Screens[i]->EnableDisableFBAccess)
580 (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], TRUE1);
581 }
582
583 /* Turn screen saver off when switching back */
584 dixSaveScreens(serverClient, SCREEN_SAVER_FORCER2, ScreenSaverReset0);
585
586 for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next) {
587 /* Devices with server managed fds get enabled on logind resume */
588 if (!(pInfo->flags & XI86_SERVER_FD0x20))
589 xf86EnableInputDeviceForVTSwitch(pInfo);
590 }
591
592 for (ih = InputHandlers; ih; ih = ih->next) {
593 if (ih->is_input)
594 xf86EnableInputHandler(ih);
595 else
596 xf86EnableGeneralHandler(ih);
597 }
598#ifdef XSERVER_PLATFORM_BUS
599 /* check for any new output devices */
600 xf86platformVTProbe();
601#endif
602
603 xf86UpdateHasVTProperty(TRUE1);
604
605 OsReleaseSIGIO();
606}
607
608/*
609 * xf86VTSwitch --
610 * Handle requests for switching the vt.
611 */
612static void
613xf86VTSwitch(void)
614{
615 DebugF("xf86VTSwitch()\n");
616
617#ifdef XFreeXDGA1
618 if (!DGAVTSwitch())
619 return;
620#endif
621
622 /*
623 * Since all screens are currently all in the same state it is sufficient
624 * check the first. This might change in future.
625 *
626 * VTLeave is always handled here (VT_PROCESS guarantees this is safe),
627 * if we use systemd_logind xf86VTEnter() gets called by systemd-logind.c
628 * once it has resumed all drm nodes.
629 */
630 if (xf86VTOwner())
631 xf86VTLeave();
632 else if (!systemd_logind_controls_session()0)
633 xf86VTEnter();
634}
635
636/* Input handler registration */
637
638static void *
639addInputHandler(int fd, InputHandlerProc proc, void *data)
640{
641 IHPtr ih;
642
643 if (fd < 0 || !proc)
644 return NULL((void*)0);
645
646 ih = calloc(sizeof(*ih), 1);
647 if (!ih)
648 return NULL((void*)0);
649
650 ih->fd = fd;
651 ih->ihproc = proc;
652 ih->data = data;
653 ih->enabled = TRUE1;
654
655 ih->next = InputHandlers;
656 InputHandlers = ih;
657
658 return ih;
659}
660
661void *
662xf86AddInputHandler(int fd, InputHandlerProc proc, void *data)
663{
664 IHPtr ih = addInputHandler(fd, proc, data);
665
666 if (ih) {
667 AddEnabledDevice(fd);
668 ih->is_input = TRUE1;
669 }
670 return ih;
671}
672
673void *
674xf86AddGeneralHandler(int fd, InputHandlerProc proc, void *data)
675{
676 IHPtr ih = addInputHandler(fd, proc, data);
677
678 if (ih)
679 AddGeneralSocket(fd);
680 return ih;
681}
682
683/**
684 * Set the handler for the console's fd. Replaces (and returns) the previous
685 * handler or NULL, whichever appropriate.
686 * proc may be NULL if the server should not handle events on the console.
687 */
688InputHandlerProc
689xf86SetConsoleHandler(InputHandlerProc proc, void *data)
690{
691 static IHPtr handler = NULL((void*)0);
692 InputHandlerProc old_proc = NULL((void*)0);
693
694 if (handler) {
695 old_proc = handler->ihproc;
696 xf86RemoveGeneralHandler(handler);
697 }
698
699 handler = xf86AddGeneralHandler(xf86Info.consoleFd, proc, data);
700
701 return old_proc;
702}
703
704static void
705removeInputHandler(IHPtr ih)
706{
707 IHPtr p;
708
709 if (ih == InputHandlers)
5
Assuming 'ih' is not equal to 'InputHandlers'
6
Taking false branch
710 InputHandlers = ih->next;
711 else {
712 p = InputHandlers;
7
Value assigned to 'p'
713 while (p && p->next != ih)
8
Assuming pointer value is null
714 p = p->next;
715 if (ih)
9
Taking true branch
716 p->next = ih->next;
10
Access to field 'next' results in a dereference of a null pointer (loaded from variable 'p')
717 }
718 free(ih);
719}
720
721int
722xf86RemoveInputHandler(void *handler)
723{
724 IHPtr ih;
725 int fd;
726
727 if (!handler)
728 return -1;
729
730 ih = handler;
731 fd = ih->fd;
732
733 if (ih->fd >= 0)
734 RemoveEnabledDevice(ih->fd);
735 removeInputHandler(ih);
736
737 return fd;
738}
739
740int
741xf86RemoveGeneralHandler(void *handler)
742{
743 IHPtr ih;
744 int fd;
745
746 if (!handler)
1
Assuming 'handler' is non-null
2
Taking false branch
747 return -1;
748
749 ih = handler;
750 fd = ih->fd;
751
752 if (ih->fd >= 0)
3
Taking false branch
753 RemoveGeneralSocket(ih->fd);
754 removeInputHandler(ih);
4
Calling 'removeInputHandler'
755
756 return fd;
757}
758
759void
760xf86DisableInputHandler(void *handler)
761{
762 IHPtr ih;
763
764 if (!handler)
765 return;
766
767 ih = handler;
768 ih->enabled = FALSE0;
769 if (ih->fd >= 0)
770 RemoveEnabledDevice(ih->fd);
771}
772
773void
774xf86DisableGeneralHandler(void *handler)
775{
776 IHPtr ih;
777
778 if (!handler)
779 return;
780
781 ih = handler;
782 ih->enabled = FALSE0;
783 if (ih->fd >= 0)
784 RemoveGeneralSocket(ih->fd);
785}
786
787void
788xf86EnableInputHandler(void *handler)
789{
790 IHPtr ih;
791
792 if (!handler)
793 return;
794
795 ih = handler;
796 ih->enabled = TRUE1;
797 if (ih->fd >= 0)
798 AddEnabledDevice(ih->fd);
799}
800
801void
802xf86EnableGeneralHandler(void *handler)
803{
804 IHPtr ih;
805
806 if (!handler)
807 return;
808
809 ih = handler;
810 ih->enabled = TRUE1;
811 if (ih->fd >= 0)
812 AddGeneralSocket(ih->fd);
813}
814
815/*
816 * As used currently by the DRI, the return value is ignored.
817 */
818Bool
819xf86EnableVTSwitch(Bool new)
820{
821 static Bool def = TRUE1;
822 Bool old;
823
824 old = VTSwitchEnabled;
825 if (!new) {
826 /* Disable VT switching */
827 def = VTSwitchEnabled;
828 VTSwitchEnabled = FALSE0;
829 }
830 else {
831 /* Restore VT switching to default */
832 VTSwitchEnabled = def;
833 }
834 return old;
835}
836
837void
838DDXRingBell(int volume, int pitch, int duration)
839{
840 xf86OSRingBell(volume, pitch, duration);
841}
842
843Bool
844xf86VTOwner(void)
845{
846 /* at system startup xf86Screens[0] won't be set - but we will own the VT */
847 if (xf86NumScreens == 0)
848 return TRUE1;
849 return xf86Screens[0]->vtSema;
850}