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