sunInit.c revision 85d6961b
1/* $Xorg: sunInit.c,v 1.4 2000/08/17 19:48:29 cpqbld Exp $ */
2/*
3 * sunInit.c --
4 *	Initialization functions for screen/keyboard/mouse, etc.
5 *
6 * Copyright 1987 by the Regents of the University of California
7 *
8 * Permission to use, copy, modify, and distribute this
9 * software and its documentation for any purpose and without
10 * fee is hereby granted, provided that the above copyright
11 * notice appear in all copies.  The University of California
12 * makes no representations about the suitability of this
13 * software for any purpose.  It is provided "as is" without
14 * express or implied warranty.
15 *
16 *
17 */
18/* $XFree86: xc/programs/Xserver/hw/sun/sunInit.c,v 3.14 2004/06/02 22:43:00 dawes Exp $ */
19
20/************************************************************
21Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
22
23                    All Rights Reserved
24
25Permission  to  use,  copy,  modify,  and  distribute   this
26software  and  its documentation for any purpose and without
27fee is hereby granted, provided that the above copyright no-
28tice  appear  in all copies and that both that copyright no-
29tice and this permission notice appear in  supporting  docu-
30mentation,  and  that the names of Sun or The Open Group
31not be used in advertising or publicity pertaining to
32distribution  of  the software  without specific prior
33written permission. Sun and The Open Group make no
34representations about the suitability of this software for
35any purpose. It is provided "as is" without any express or
36implied warranty.
37
38SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO  THIS  SOFTWARE,
39INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
40NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE  LI-
41ABLE  FOR  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
42ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,  DATA  OR
43PROFITS,  WHETHER  IN  AN  ACTION OF CONTRACT, NEGLIGENCE OR
44OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
45THE USE OR PERFORMANCE OF THIS SOFTWARE.
46
47*******************************************************/
48
49#include    "sun.h"
50#include    "gcstruct.h"
51#include    "mi.h"
52#include    "fb.h"
53
54/* default log file paths */
55#ifndef DEFAULT_LOGDIR
56#define DEFAULT_LOGDIR "/var/log"
57#endif
58#ifndef DEFAULT_LOGPREFIX
59#define DEFAULT_LOGPREFIX "Xsun."
60#endif
61
62/* maximum pixmap depth */
63#ifndef SUNMAXDEPTH
64#define SUNMAXDEPTH 8
65#endif
66
67#ifdef i386 /* { */
68#define BW2I NULL
69#else /* }{ */
70#define BW2I sunBW2Init
71#endif /* } */
72
73#ifdef LOWMEMFTPT
74#undef  BW2I
75#define BW2I NULL
76#endif /* ifdef LOWMEMFTPT */
77
78#if SUNMAXDEPTH == 1 /* { */
79#define CG2I NULL
80#define CG3I NULL
81#define CG4I NULL
82#define CG6I NULL
83#define CG8I NULL
84#define TCXI NULL
85#else /* }{ */
86#define CG3I sunCG3Init
87#if defined(i386) || defined(__bsdi__) /* { */
88#define CG2I NULL
89#define CG4I NULL
90#else /* }{ */
91#ifdef INCLUDE_CG2_HEADER
92#define CG2I sunCG2Init
93#endif /* INCLUDE_CG2_HEADER */
94#define CG4I sunCG4Init
95#endif /* } */
96#ifdef FBTYPE_SUNFAST_COLOR /* { */
97#define CG6I sunCG6Init
98#else /* }{ */
99#define CG6I NULL
100#endif /* } */
101#ifdef XFBTYPE_TCX  /* { */
102#define TCXI sunTCXInit
103#else /* }{ */
104#define TCXI NULL
105#endif /* } */
106#if SUNMAXDEPTH > 8 /* { */
107#ifdef FBTYPE_MEMCOLOR /* { */
108#define CG8I sunCG8Init
109#else /* }{ */
110#define CG8I NULL
111#endif /* } */
112#else /* }{ */
113#define CG8I NULL
114#endif /* } */
115
116#endif /* } */
117
118static int OpenFrameBuffer(char *, int);
119static void SigIOHandler(int);
120static char** GetDeviceList(int, char **);
121static void getKbdType(void);
122
123#if SUNMAXDEPTH == 32
124static Bool sunCfbCreateGC(GCPtr);
125static void sunCfbGetSpans(DrawablePtr, int, DDXPointPtr, int *, int, char *);
126static void sunCfbGetImage(DrawablePtr, int,int, int, int, unsigned int, unsigned long, char *);
127#endif /* SUNMAXDEPTH == 32 */
128
129static Bool	sunDevsInited = FALSE;
130
131EventList *sunEvents = NULL;
132
133Bool sunSwapLkeys = FALSE;
134Bool sunDebug = FALSE;
135char *sunDeviceList = NULL;
136Bool sunForceMono = FALSE;
137Bool sunFlipPixels = FALSE;
138Bool sunFbInfo = FALSE;
139Bool sunCG4Frob = FALSE;
140Bool sunNoGX = FALSE;
141
142sunKbdPrivRec sunKbdPriv = {
143    -1,		/* fd */
144    -1,		/* type */
145    -1,		/* layout */
146    0,		/* click */
147    (Leds)0,	/* leds */
148};
149
150sunPtrPrivRec sunPtrPriv = {
151    -1,		/* fd */
152    0		/* Current button state */
153};
154
155/*
156 * The name member in the following table corresponds to the
157 * FBTYPE_* macros defined in /usr/include/sun/fbio.h file
158 */
159sunFbDataRec sunFbData[XFBTYPE_LASTPLUSONE] = {
160  { NULL, "SUN1BW        (bw1)" },
161  { NULL, "SUN1COLOR     (cg1)" },
162  { BW2I, "SUN2BW        (bw2)" },
163#ifdef INCLUDE_CG2_HEADER
164  { CG2I, "SUN2COLOR     (cg2)" },
165#else
166  { NULL, "SUN2COLOR     (cg2)" },
167#endif /* INCLUDE_CG2_HEADER */
168  { NULL, "SUN2GP        (gp1/gp2)" },
169  { NULL, "SUN5COLOR     (cg5/386i accel)" },
170  { CG3I, "SUN3COLOR     (cg3)" },
171  { CG8I, "MEMCOLOR      (cg8)" },
172  { CG4I, "SUN4COLOR     (cg4)" },
173  { NULL, "NOTSUN1" },
174  { NULL, "NOTSUN2" },
175  { NULL, "NOTSUN3" }
176#ifndef i386 /* { */
177 ,{ CG6I, "SUNFAST_COLOR (cg6/gx)" },
178  { NULL, "SUNROP_COLOR  (cg9)" },
179  { NULL, "SUNFB_VIDEO" },
180  { NULL, "SUNGIFB" },
181  { NULL, "SUNPLAS" },
182#ifdef FBTYPE_SUNGP3
183  { NULL, "SUNGP3        (cg12/gs)" },
184#endif
185#ifdef FBTYPE_SUNGT
186  { NULL, "SUNGT         (gt)" },
187#endif
188#ifdef FBTYPE_SUNLEO
189  { NULL, "SUNLEO        (zx)" },
190#endif
191#ifdef FBTYPE_MDICOLOR
192  { NULL, "MDICOLOR      (cgfourteen)" },
193#endif
194#ifdef XFBTYPE_TCX
195  { TCXI, "TCX           (tcx)" },
196#endif
197#endif /* } */
198};
199
200/*
201 * a list of devices to try if there is no environment or command
202 * line list of devices
203 */
204#if SUNMAXDEPTH == 1 /* { */
205static char *fallbackList[] = {
206    BWTWO0DEV, BWTWO1DEV, BWTWO2DEV
207};
208#else /* }{ */
209static char *fallbackList[] = {
210#ifndef i386 /* { */
211    CGTWO0DEV, CGTWO1DEV, CGTWO2DEV,
212#if (MAXSCREENS == 4)
213    CGTWO3DEV,
214#endif
215#endif /* } */
216    CGTHREE0DEV,
217#ifndef i386 /* { */
218    CGTHREE1DEV, CGTHREE2DEV,
219#if (MAXSCREENS == 4)
220    CGTHREE3DEV,
221#endif
222#endif /* } */
223#ifdef FBTYPE_SUNFAST_COLOR /* { */
224    CGSIX0DEV, CGSIX1DEV, CGSIX2DEV,
225#if (MAXSCREENS == 4)
226    CGSIX3DEV,
227#endif
228#endif /* } */
229#ifndef i386 /* { */
230    CGFOUR0DEV, BWTWO0DEV, BWTWO1DEV, BWTWO2DEV,
231#if (MAXSCREENS == 4)
232    BWTWO3DEV,
233#endif
234#endif /* } */
235#if SUNMAXDEPTH > 8 /* { */
236    CGEIGHT0DEV,
237#if 0
238#ifdef XFBTYPE_TCX
239    TCX0DEV,
240#endif
241#endif
242#endif /* } */
243    "/dev/fb"
244};
245#endif /* } */
246
247#define FALLBACK_LIST_LEN sizeof fallbackList / sizeof fallbackList[0]
248
249fbFd sunFbs[MAXSCREENS];
250
251static PixmapFormatRec	formats[] = {
252    { 1, 1, BITMAP_SCANLINE_PAD	} /* 1-bit deep */
253#if SUNMAXDEPTH > 1
254    ,{ 8, 8, BITMAP_SCANLINE_PAD} /* 8-bit deep */
255#if SUNMAXDEPTH > 8
256    ,{ 12, 24, BITMAP_SCANLINE_PAD } /* 12-bit deep */
257    ,{ 24, 32, BITMAP_SCANLINE_PAD } /* 24-bit deep */
258#endif
259#endif
260};
261#define NUMFORMATS	(sizeof formats)/(sizeof formats[0])
262
263/*
264 * OpenFrameBuffer --
265 *	Open a frame buffer according to several rules.
266 *	Find the device to use by looking in the sunFbData table,
267 *	an XDEVICE envariable, a -dev switch or using /dev/fb if trying
268 *	to open screen 0 and all else has failed.
269 *
270 * Results:
271 *	The fd of the framebuffer.
272 */
273static int
274OpenFrameBuffer(
275    char		*device,	/* e.g. "/dev/cgtwo0" */
276    int			screen    	/* what screen am I going to be */
277)
278{
279    int			ret = TRUE;
280    struct fbgattr	*fbattr;
281    static int		devFbUsed;
282
283    sunFbs[screen].fd = -1;
284    if (strcmp (device, "/dev/fb") == 0 && devFbUsed)
285	return FALSE;
286    if (access (device, R_OK | W_OK) == -1)
287	return FALSE;
288    if ((sunFbs[screen].fd = open(device, O_RDWR, 0)) == -1)
289	ret = FALSE;
290    else {
291	fbattr = (struct fbgattr *) xalloc (sizeof (struct fbgattr));
292	if (ioctl(sunFbs[screen].fd, FBIOGATTR, fbattr) == -1) {
293	    /*
294		This is probably a bwtwo; the $64,000 question is:
295		is it the mono plane of a cgfour, or is it really a
296		real bwtwo?  If there is only a cgfour in the box or
297		only a bwtwo in the box, then it isn't a problem.  If
298		it's a 3/60, which has a bwtwo on the mother board *and*
299		a cgfour, then things get tricky because there's no way
300		to tell if the bwtwo is really being emulated by the cgfour.
301	    */
302	    xfree (fbattr);
303	    fbattr = NULL;
304	    if (ioctl(sunFbs[screen].fd, FBIOGTYPE, &sunFbs[screen].info) == -1) {
305		Error("unable to get frame buffer attributes");
306		(void) close(sunFbs[screen].fd);
307		sunFbs[screen].fd = -1;
308		return FALSE;
309	    }
310	}
311	if (ret) {
312	    int verb = 1;
313
314	    if (sunFbInfo)
315		verb = -1;
316
317	    devFbUsed = TRUE;
318	    if (fbattr) {
319		if (fbattr->fbtype.fb_type >= XFBTYPE_LASTPLUSONE) {
320		    ErrorF ("%s is an unknown framebuffer type\n", device);
321		    (void) close(sunFbs[screen].fd);
322		    sunFbs[screen].fd = -1;
323		    return FALSE;
324		}
325		sunFbs[screen].info = fbattr->fbtype;
326	    }
327	    sunFbs[screen].fbPriv = (pointer) fbattr;
328	    if (fbattr && !sunFbData[fbattr->fbtype.fb_type].init) {
329		int _i;
330		ret = FALSE;
331		for (_i = 0; _i < FB_ATTR_NEMUTYPES; _i++) {
332		    if (sunFbData[fbattr->emu_types[_i]].init) {
333			sunFbs[screen].info.fb_type = fbattr->emu_types[_i];
334			ret = TRUE;
335			LogMessageVerb(X_INFO, verb, "%s is emulating a %s\n",
336			    device, sunFbData[fbattr->fbtype.fb_type].name);
337			break;
338		    }
339		}
340	    }
341	    LogMessageVerb(X_INFO, verb, "%s is really a %s\n", device,
342		sunFbData[fbattr ? fbattr->fbtype.fb_type : sunFbs[screen].info.fb_type].name);
343	}
344    }
345    if (!ret)
346	sunFbs[screen].fd = -1;
347    return ret;
348}
349
350/*-
351 *-----------------------------------------------------------------------
352 * SigIOHandler --
353 *	Signal handler for SIGIO - input is available.
354 *
355 * Results:
356 *	sunSigIO is set - ProcessInputEvents() will be called soon.
357 *
358 * Side Effects:
359 *	None
360 *
361 *-----------------------------------------------------------------------
362 */
363/*ARGSUSED*/
364static void
365SigIOHandler(int sig)
366{
367    int olderrno = errno;
368    sunEnqueueEvents ();
369    errno = olderrno;
370}
371
372/*-
373 *-----------------------------------------------------------------------
374 * sunNonBlockConsoleOff --
375 *	Turn non-blocking mode on the console off, so you don't get logged
376 *	out when the server exits.
377 *
378 * Results:
379 *	None.
380 *
381 * Side Effects:
382 *	None.
383 *
384 *-----------------------------------------------------------------------
385 */
386void
387sunNonBlockConsoleOff(
388#if defined(SVR4) || defined(CSRG_BASED)
389    void
390#else
391    char* arg
392#endif
393)
394{
395    register int i;
396
397    i = fcntl(2, F_GETFL, 0);
398    if (i >= 0)
399	(void) fcntl(2, F_SETFL, i & ~FNDELAY);
400}
401
402static char**
403GetDeviceList(int argc, char **argv)
404{
405    int		i;
406    char	*envList = NULL;
407    char	*cmdList = sunDeviceList;
408    char	**deviceList = (char **)NULL;
409
410    if (!cmdList)
411	envList = getenv ("XDEVICE");
412
413    if (cmdList || envList) {
414	char	*_tmpa;
415	char	*_tmpb;
416	int	_i1;
417	deviceList = (char **) xalloc ((MAXSCREENS + 1) * sizeof (char *));
418	_tmpa = (cmdList) ? cmdList : envList;
419	for (_i1 = 0; _i1 < MAXSCREENS; _i1++) {
420	    _tmpb = strtok (_tmpa, ":");
421	    if (_tmpb)
422		deviceList[_i1] = _tmpb;
423	    else
424		deviceList[_i1] = NULL;
425	    _tmpa = NULL;
426	}
427	deviceList[MAXSCREENS] = NULL;
428    }
429    if (!deviceList) {
430	/* no environment and no cmdline, so default */
431	deviceList =
432	    (char **) xalloc ((FALLBACK_LIST_LEN + 1) * sizeof (char *));
433	for (i = 0; i < FALLBACK_LIST_LEN; i++)
434	    deviceList[i] = fallbackList[i];
435	deviceList[FALLBACK_LIST_LEN] = NULL;
436    }
437    return deviceList;
438}
439
440static void
441getKbdType(void)
442{
443/*
444 * The Sun 386i has system include files that preclude this pre SunOS 4.1
445 * test for the presence of a type 4 keyboard however it really doesn't
446 * matter since no 386i has ever been shipped with a type 3 keyboard.
447 * SunOS 4.1 no longer needs this kludge.
448 */
449#if !defined(i386) && !defined(KIOCGKEY)
450#define TYPE4KEYBOARDOVERRIDE
451#endif
452
453    int ii;
454
455    for (ii = 0; ii < 3; ii++) {
456	sunKbdWait();
457	(void) ioctl (sunKbdPriv.fd, KIOCTYPE, &sunKbdPriv.type);
458#ifdef TYPE4KEYBOARDOVERRIDE
459	/*
460	 * Magic. Look for a key which is non-existent on a real type
461	 * 3 keyboard but does exist on a type 4 keyboard.
462	 */
463	if (sunKbdPriv.type == KB_SUN3) {
464	    struct kiockeymap key;
465
466	    key.kio_tablemask = 0;
467	    key.kio_station = 118;
468	    if (ioctl(sunKbdPriv.fd, KIOCGKEY, &key) == -1) {
469		Error( "ioctl KIOCGKEY" );
470		FatalError("Can't KIOCGKEY on fd %d\n", sunKbdPriv.fd);
471	    }
472	    if (key.kio_entry != HOLE)
473		sunKbdPriv.type = KB_SUN4;
474	}
475#endif
476	switch (sunKbdPriv.type) {
477	case KB_SUN2:
478	case KB_SUN3:
479	case KB_SUN4: return;
480	default:
481	    sunChangeKbdTranslation(sunKbdPriv.fd, FALSE);
482	    continue;
483	}
484    }
485    FatalError ("Unsupported keyboard type %d\n", sunKbdPriv.type);
486}
487
488void
489OsVendorInit(void)
490{
491    static int inited;
492    if (!inited) {
493	const char *logfile;
494	char *lf;
495#ifndef i386
496	struct rlimit rl;
497
498	/*
499	 * one per client, one per screen, one per listen endpoint,
500	 * keyboard, mouse, and stderr
501	 */
502	int maxfds = MAXCLIENTS + MAXSCREENS + 5;
503
504	if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
505	    rl.rlim_cur = maxfds < rl.rlim_max ? maxfds : rl.rlim_max;
506	    (void) setrlimit (RLIMIT_NOFILE, &rl);
507	}
508#endif
509
510#define LOGSUFFIX ".log"
511#define LOGOLDSUFFIX ".old"
512
513	logfile = DEFAULT_LOGDIR "/" DEFAULT_LOGPREFIX;
514	if (asprintf(&lf, "%s%%s" LOGSUFFIX, logfile) == -1)
515	    FatalError("Cannot allocate space for the log file name\n");
516	LogInit(lf, LOGOLDSUFFIX);
517
518#undef LOGSUFFIX
519#undef LOGOLDSUFFIX
520
521	free(lf);
522
523	sunKbdPriv.fd = open ("/dev/kbd", O_RDWR, 0);
524	if (sunKbdPriv.fd < 0)
525	    FatalError ("Cannot open /dev/kbd, error %d\n", errno);
526	sunPtrPriv.fd = open ("/dev/mouse", O_RDWR, 0);
527	if (sunPtrPriv.fd < 0)
528	    FatalError ("Cannot open /dev/mouse, error %d\n", errno);
529	getKbdType ();
530	switch (sunKbdPriv.type) {
531	case KB_SUN2:
532	case KB_SUN3:
533	    LogMessage(X_INFO, "Sun type %d Keyboard\n", sunKbdPriv.type);
534	    break;
535	case KB_SUN4:
536#define LAYOUT_US5	33
537	    (void) ioctl (sunKbdPriv.fd, KIOCLAYOUT, &sunKbdPriv.layout);
538	    if (sunKbdPriv.layout < 0 ||
539		sunKbdPriv.layout > sunMaxLayout ||
540		sunType4KeyMaps[sunKbdPriv.layout] == NULL)
541		FatalError ("Unsupported keyboard type 4 layout %d\n",
542			    sunKbdPriv.layout);
543	    sunKeySyms[KB_SUN4].map = sunType4KeyMaps[sunKbdPriv.layout];
544	    LogMessage(X_INFO, "Sun type %d Keyboard, layout %d\n",
545		sunKbdPriv.layout >= LAYOUT_US5 ? 5 : 4, sunKbdPriv.layout);
546	    break;
547	default:
548	    LogMessage(X_INFO, "Unknown keyboard type\n");
549	    break;
550        }
551	inited = 1;
552    }
553}
554
555void
556OsVendorFatalError(void)
557{
558}
559
560/*-
561 *-----------------------------------------------------------------------
562 * InitOutput --
563 *	Initialize screenInfo for all actually accessible framebuffers.
564 *	The
565 *
566 * Results:
567 *	screenInfo init proc field set
568 *
569 * Side Effects:
570 *	None
571 *
572 *-----------------------------------------------------------------------
573 */
574
575void
576InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
577{
578    int     	i, scr;
579    int		nonBlockConsole = 0;
580    char	**devList;
581    static int	setup_on_exit = 0;
582
583    if (!monitorResolution)
584	monitorResolution = 90;
585    if (RunFromSigStopParent)
586	nonBlockConsole = 1;
587    if (sunDebug)
588	nonBlockConsole = 0;
589
590    /*
591     *	Writes to /dev/console can block - causing an
592     *	excess of error messages to hang the server in
593     *	deadlock.  So.......
594     */
595    if (nonBlockConsole) {
596	if (!setup_on_exit) {
597#if defined(SVR4) || defined(CSRG_BASED)
598	    if (atexit(sunNonBlockConsoleOff))
599#else
600	    if (on_exit(sunNonBlockConsoleOff, (char *)0))
601#endif
602		ErrorF("InitOutput: can't register NBIO exit handler\n");
603
604	    setup_on_exit = 1;
605	}
606	i = fcntl(2, F_GETFL, 0);
607	if (i >= 0)
608	    i = fcntl(2, F_SETFL, i | FNDELAY);
609	if (i < 0) {
610	    Error("fcntl");
611	    ErrorF("InitOutput: can't put stderr in non-block mode\n");
612	}
613    }
614    pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
615    pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
616    pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
617    pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
618
619    pScreenInfo->numPixmapFormats = NUMFORMATS;
620    for (i=0; i< NUMFORMATS; i++)
621        pScreenInfo->formats[i] = formats[i];
622    if (!sunDevsInited) {
623	/* first time ever */
624	for (scr = 0; scr < MAXSCREENS; scr++)
625	    sunFbs[scr].fd = -1;
626	devList = GetDeviceList (argc, argv);
627	for (i = 0, scr = 0; devList[i] != NULL && scr < MAXSCREENS; i++)
628	    if (OpenFrameBuffer (devList[i], scr))
629		scr++;
630	sunDevsInited = TRUE;
631	xfree (devList);
632    }
633    for (scr = 0; scr < MAXSCREENS; scr++)
634	if (sunFbs[scr].fd != -1)
635	    (void) AddScreen (sunFbData[sunFbs[scr].info.fb_type].init,
636			      argc, argv);
637    (void) OsSignal(SIGWINCH, SIG_IGN);
638}
639
640/*-
641 *-----------------------------------------------------------------------
642 * InitInput --
643 *	Initialize all supported input devices...what else is there
644 *	besides pointer and keyboard?
645 *
646 * Results:
647 *	None.
648 *
649 * Side Effects:
650 *	Two DeviceRec's are allocated and registered as the system pointer
651 *	and keyboard devices.
652 *
653 *-----------------------------------------------------------------------
654 */
655void
656InitInput(int argc, char **argv)
657{
658    int rc;
659
660    rc = AllocDevicePair(serverClient, "sun",
661			 &sunPointerDevice, &sunKeyboardDevice,
662			 sunMouseProc, sunKbdProc, FALSE);
663    if (rc != Success)
664	FatalError("Failed to init sun default input devices.\n");
665
666    GetEventList(&sunEvents);
667
668    (void)mieqInit();
669#define SET_FLOW(fd) fcntl(fd, F_SETFL, FNDELAY | FASYNC)
670#ifdef SVR4
671    (void) OsSignal(SIGPOLL, SigIOHandler);
672#define WANT_SIGNALS(fd) ioctl(fd, I_SETSIG, S_INPUT | S_HIPRI)
673#else
674    (void) OsSignal(SIGIO, SigIOHandler);
675#define WANT_SIGNALS(fd) fcntl(fd, F_SETOWN, getpid())
676#endif
677    if (sunKbdPriv.fd >= 0) {
678	if (SET_FLOW(sunKbdPriv.fd) == -1 || WANT_SIGNALS(sunKbdPriv.fd) == -1) {
679	    (void) close (sunKbdPriv.fd);
680	    sunKbdPriv.fd = -1;
681	    FatalError("Async kbd I/O failed in InitInput");
682	}
683    }
684    if (sunPtrPriv.fd >= 0) {
685	if (SET_FLOW(sunPtrPriv.fd) == -1 || WANT_SIGNALS(sunPtrPriv.fd) == -1) {
686	    (void) close (sunPtrPriv.fd);
687	    sunPtrPriv.fd = -1;
688	    FatalError("Async mouse I/O failed in InitInput");
689	}
690    }
691}
692
693void
694CloseInput(void)
695{
696}
697
698#if SUNMAXDEPTH == 8
699
700Bool
701sunCfbSetupScreen(
702    ScreenPtr pScreen,
703    pointer pbits,		/* pointer to screen bitmap */
704    int xsize,			/* in pixels */
705    int ysize,			/* in pixels */
706    int dpix,			/* dots per inch */
707    int dpiy,			/* dots per inch */
708    int width,			/* pixel width of frame buffer */
709    int	bpp			/* bits per pixel of root */
710)
711{
712    return fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy,
713			 width, bpp);
714}
715
716Bool
717sunCfbFinishScreenInit(
718    ScreenPtr pScreen,
719    pointer pbits,		/* pointer to screen bitmap */
720    int xsize,			/* in pixels */
721    int ysize,			/* in pixels */
722    int dpix,			/* dots per inch */
723    int dpiy,			/* dots per inch */
724    int width,			/* pixel width of frame buffer */
725    int bpp			/* bits per pixel of root */
726)
727{
728    return fbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy,
729			      width, bpp);
730}
731
732Bool
733sunCfbScreenInit(
734    ScreenPtr pScreen,
735    pointer pbits,		/* pointer to screen bitmap */
736    int xsize,			/* in pixels */
737    int ysize,			/* in pixels */
738    int dpix,			/* dots per inch */
739    int dpiy,			/* dots per inch */
740    int width,			/* pixel width of frame buffer */
741    int bpp			/* bits per pixel of root */
742)
743{
744    return fbScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp);
745}
746
747#else /* SUNMAXDEPTH != 8 */
748#if SUNMAXDEPTH == 32
749
750static Bool
751sunCfbCreateGC(GCPtr pGC)
752{
753    return fbCreateGC (pGC);
754}
755
756static void
757sunCfbGetSpans(
758    DrawablePtr		pDrawable,	/* drawable from which to get bits */
759    int			wMax,		/* largest value of all *pwidths */
760    DDXPointPtr		ppt,		/* points to start copying from */
761    int			*pwidth,	/* list of number of bits to copy */
762    int			nspans,		/* number of scanlines to copy */
763    char		*pdstStart	/* where to put the bits */
764)
765{
766    fbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
767}
768
769static void
770sunCfbGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, unsigned int format, unsigned long planeMask, char *pdstLine)
771{
772    fbGetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
773}
774
775Bool
776sunCfbSetupScreen(
777    ScreenPtr pScreen,
778    pointer pbits,		/* pointer to screen bitmap */
779    int xsize,			/* in pixels */
780    int ysize,			/* in pixels */
781    int dpix,			/* dots per inch */
782    int dpiy,			/* dots per inch */
783    int width,			/* pixel width of frame buffer */
784    int	bpp			/* bits per pixel of root */
785)
786{
787    int ret;
788
789    ret = fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp);
790    pScreen->CreateGC = sunCfbCreateGC;
791    pScreen->GetImage = sunCfbGetImage;
792    pScreen->GetSpans = sunCfbGetSpans;
793    return ret;
794}
795
796/* Adapt cfb logic */
797
798Bool
799sunCfbFinishScreenInit(
800    ScreenPtr pScreen,
801    pointer pbits,		/* pointer to screen bitmap */
802    int xsize,			/* in pixels */
803    int ysize,			/* in pixels */
804    int dpix,			/* dots per inch */
805    int dpiy,			/* dots per inch */
806    int width,			/* pixel width of frame buffer */
807    int bpp
808)
809{
810    VisualPtr	visuals;
811    int		nvisuals;
812    DepthPtr	depths;
813    int		ndepths;
814    VisualID	defaultVisual;
815    int		rootdepth = 0;
816
817    if (!fbInitVisuals(&visuals, &depths, &nvisuals, &ndepths,
818		       &rootdepth, &defaultVisual, 1 << (bpp - 1), 8))
819	return FALSE;
820    if (! miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
821			rootdepth, ndepths, depths,
822			defaultVisual, nvisuals, visuals))
823	return FALSE;
824    pScreen->CloseScreen = fbCloseScreen;
825    return TRUE;
826}
827
828
829Bool
830sunCfbScreenInit(
831    ScreenPtr pScreen,
832    pointer pbits,		/* pointer to screen bitmap */
833    int xsize,			/* in pixels */
834    int ysize,			/* in pixels */
835    int dpix,			/* dots per inch */
836    int dpiy,			/* dots per inch */
837    int width,			/* pixel width of frame buffer */
838    int bpp
839)
840{
841    if (!sunCfbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy,
842			   width, bpp))
843	return FALSE;
844    return sunCfbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix,
845				  dpiy, width, bpp);
846}
847
848#endif  /* SUNMAXDEPTH == 32 */
849#endif  /* SUNMAXDEPTH */
850