3 * Mesa 3-D graphics library
6 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 /* Minimal swrast-based dri loadable driver.
30 * -- Use malloced (rather than framebuffer) memory for backbuffer
31 * -- 32bpp is hardwared -- fix
34 * -- No mechanism for cliprects or resize notification --
35 * assumes this is a fullscreen device.
36 * -- No locking -- assumes this is the only driver accessing this
38 * -- Doesn't (yet) make use of any acceleration or other interfaces
39 * provided by fb. Would be entirely happy working against any
40 * fullscreen interface.
41 * -- HOWEVER: only a small number of pixelformats are supported, and
42 * the mechanism for choosing between them makes some assumptions
43 * that may not be valid everywhere.
55 #include <sys/ioctl.h>
57 #include <sys/types.h>
63 #include "GL/miniglx.h" /* window-system-specific */
64 #include "miniglxP.h" /* window-system-specific */
65 #include "dri_util.h" /* window-system-specific-ish */
68 #include "extensions.h"
71 #include "texformat.h"
74 #include "array_cache/acache.h"
75 #include "swrast/swrast.h"
76 #include "swrast_setup/swrast_setup.h"
78 #include "tnl/t_context.h"
79 #include "tnl/t_pipeline.h"
80 #include "drivers/common/driverfuncs.h"
85 GLcontext
*glCtx
; /* Mesa context */
88 __DRIcontextPrivate
*context
;
89 __DRIscreenPrivate
*screen
;
90 __DRIdrawablePrivate
*drawable
; /* drawable bound to this ctx */
92 } fbContext
, *fbContextPtr
;
95 #define FB_CONTEXT(ctx) ((fbContextPtr)(ctx->DriverCtx))
98 static const GLubyte
*
99 get_string(GLcontext
*ctx
, GLenum pname
)
104 return (const GLubyte
*) "Mesa dumb framebuffer";
112 update_state( GLcontext
*ctx
, GLuint new_state
)
114 /* not much to do here - pass it on */
115 _swrast_InvalidateState( ctx
, new_state
);
116 _swsetup_InvalidateState( ctx
, new_state
);
117 _ac_InvalidateState( ctx
, new_state
);
118 _tnl_InvalidateState( ctx
, new_state
);
123 * Called by ctx->Driver.GetBufferSize from in core Mesa to query the
124 * current framebuffer size.
127 get_buffer_size( GLframebuffer
*buffer
, GLuint
*width
, GLuint
*height
)
129 GET_CURRENT_CONTEXT(ctx
);
130 fbContextPtr fbmesa
= FB_CONTEXT(ctx
);
132 *width
= fbmesa
->dri
.drawable
->w
;
133 *height
= fbmesa
->dri
.drawable
->h
;
137 /* specifies the buffer for swrast span rendering/reading */
139 set_buffer( GLcontext
*ctx
, GLframebuffer
*buffer
, GLuint bufferBit
)
141 fbContextPtr fbdevctx
= FB_CONTEXT(ctx
);
142 __DRIdrawablePrivate
*dPriv
= fbdevctx
->dri
.drawable
;
144 /* What a twisted mess of private structs
146 assert(buffer
== dPriv
->driverPrivate
);
151 dPriv
->currentBuffer
= dPriv
->frontBuffer
;
154 dPriv
->currentBuffer
= dPriv
->backBuffer
;
157 /* This happens a lot if the client renders to the frontbuffer */
158 if (0) _mesa_problem(ctx
, "bad bufferBit in set_buffer()");
164 init_core_functions( struct dd_function_table
*functions
)
166 functions
->GetString
= get_string
;
167 functions
->UpdateState
= update_state
;
168 functions
->ResizeBuffers
= _swrast_alloc_buffers
;
169 functions
->GetBufferSize
= get_buffer_size
;
171 functions
->Clear
= _swrast_Clear
; /* could accelerate with blits */
176 * Generate code for span functions.
180 #define NAME(PREFIX) PREFIX##_B8G8R8
182 const fbContextPtr fbdevctx = FB_CONTEXT(ctx); \
183 __DRIdrawablePrivate *dPriv = fbdevctx->dri.drawable;
184 #define INIT_PIXEL_PTR(P, X, Y) \
185 GLubyte *P = (GLubyte *)dPriv->currentBuffer + (Y) * dPriv->currentPitch + (X) * 3
186 #define INC_PIXEL_PTR(P) P += 3
187 #define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
188 P[0] = B; P[1] = G; P[2] = R
189 #define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
190 P[0] = B; P[1] = G; P[2] = R
191 #define FETCH_RGBA_PIXEL(R, G, B, A, P) \
192 R = P[2]; G = P[1]; B = P[0]; A = CHAN_MAX
194 #include "swrast/s_spantemp.h"
198 #define NAME(PREFIX) PREFIX##_B8G8R8A8
200 const fbContextPtr fbdevctx = FB_CONTEXT(ctx); \
201 __DRIdrawablePrivate *dPriv = fbdevctx->dri.drawable;
202 #define INIT_PIXEL_PTR(P, X, Y) \
203 GLubyte *P = (GLubyte *)dPriv->currentBuffer + (Y) * dPriv->currentPitch + (X) * 4;
204 #define INC_PIXEL_PTR(P) P += 4
205 #define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
206 P[0] = B; P[1] = G; P[2] = R; P[3] = 255
207 #define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
208 P[0] = B; P[1] = G; P[2] = R; P[3] = A
209 #define FETCH_RGBA_PIXEL(R, G, B, A, P) \
210 R = P[2]; G = P[1]; B = P[0]; A = P[3]
212 #include "swrast/s_spantemp.h"
215 /* 16-bit BGR (XXX implement dithering someday) */
216 #define NAME(PREFIX) PREFIX##_B5G6R5
218 const fbContextPtr fbdevctx = FB_CONTEXT(ctx); \
219 __DRIdrawablePrivate *dPriv = fbdevctx->dri.drawable;
220 #define INIT_PIXEL_PTR(P, X, Y) \
221 GLushort *P = (GLushort *) ((char *)dPriv->currentBuffer + (Y) * dPriv->currentPitch + (X) * 2)
222 #define INC_PIXEL_PTR(P) P += 1
223 #define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
224 *P = ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) )
225 #define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
226 *P = ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) )
227 #define FETCH_RGBA_PIXEL(R, G, B, A, P) \
228 R = ( (((*P) >> 8) & 0xf8) | (((*P) >> 11) & 0x7) ); \
229 G = ( (((*P) >> 3) & 0xfc) | (((*P) >> 5) & 0x3) ); \
230 B = ( (((*P) << 3) & 0xf8) | (((*P) ) & 0x7) ); \
233 #include "swrast/s_spantemp.h"
236 /* 15-bit BGR (XXX implement dithering someday) */
237 #define NAME(PREFIX) PREFIX##_B5G5R5
239 const fbContextPtr fbdevctx = FB_CONTEXT(ctx); \
240 __DRIdrawablePrivate *dPriv = fbdevctx->dri.drawable;
241 #define INIT_PIXEL_PTR(P, X, Y) \
242 GLushort *P = (GLushort *) ((char *)dPriv->currentBuffer + (Y) * dPriv->currentPitch + (X) * 2)
243 #define INC_PIXEL_PTR(P) P += 1
244 #define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
245 *P = ( (((R) & 0xf8) << 7) | (((G) & 0xf8) << 2) | ((B) >> 3) )
246 #define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
247 *P = ( (((R) & 0xf8) << 7) | (((G) & 0xf8) << 2) | ((B) >> 3) )
248 #define FETCH_RGBA_PIXEL(R, G, B, A, P) \
249 R = ( (((*P) >> 7) & 0xf8) | (((*P) >> 10) & 0x7) ); \
250 G = ( (((*P) >> 2) & 0xf8) | (((*P) >> 5) & 0x7) ); \
251 B = ( (((*P) << 3) & 0xf8) | (((*P) ) & 0x7) ); \
254 #include "swrast/s_spantemp.h"
257 /* 8-bit color index */
258 #define NAME(PREFIX) PREFIX##_CI8
260 const fbContextPtr fbdevctx = FB_CONTEXT(ctx); \
261 __DRIdrawablePrivate *dPriv = fbdevctx->dri.drawable;
262 #define INIT_PIXEL_PTR(P, X, Y) \
263 GLubyte *P = (GLubyte *)dPriv->currentBuffer + (Y) * dPriv->currentPitch + (X)
264 #define INC_PIXEL_PTR(P) P += 1
265 #define STORE_CI_PIXEL(P, CI) \
267 #define FETCH_CI_PIXEL(CI, P) \
270 #include "swrast/s_spantemp.h"
274 /* Initialize the driver specific screen private data.
277 fbInitDriver( __DRIscreenPrivate
*sPriv
)
279 sPriv
->private = NULL
;
284 fbDestroyScreen( __DRIscreenPrivate
*sPriv
)
288 /* Create the device specific context.
291 fbCreateContext( const __GLcontextModes
*glVisual
,
292 __DRIcontextPrivate
*driContextPriv
,
293 void *sharedContextPrivate
)
296 GLcontext
*ctx
, *shareCtx
;
297 struct dd_function_table functions
;
300 assert(driContextPriv
);
302 /* Allocate the Fb context */
303 fbmesa
= (fbContextPtr
) CALLOC( sizeof(*fbmesa
) );
307 /* Init default driver functions then plug in our FBdev-specific functions
309 _mesa_init_driver_functions(&functions
);
310 init_core_functions(&functions
);
312 /* Allocate the Mesa context */
313 if (sharedContextPrivate
)
314 shareCtx
= ((fbContextPtr
) sharedContextPrivate
)->glCtx
;
318 ctx
= fbmesa
->glCtx
= _mesa_create_context(glVisual
, shareCtx
,
319 &functions
, (void *) fbmesa
);
320 if (!fbmesa
->glCtx
) {
324 driContextPriv
->driverPrivate
= fbmesa
;
326 /* Create module contexts */
327 _swrast_CreateContext( ctx
);
328 _ac_CreateContext( ctx
);
329 _tnl_CreateContext( ctx
);
330 _swsetup_CreateContext( ctx
);
331 _swsetup_Wakeup( ctx
);
334 /* swrast init -- need to verify these tests - I just plucked the
335 * numbers out of the air. (KW)
338 struct swrast_device_driver
*swdd
;
339 swdd
= _swrast_GetDeviceDriverReference( ctx
);
340 swdd
->SetBuffer
= set_buffer
;
341 if (!glVisual
->rgbMode
) {
342 swdd
->WriteCI32Span
= write_index32_span_CI8
;
343 swdd
->WriteCI8Span
= write_index8_span_CI8
;
344 swdd
->WriteMonoCISpan
= write_monoindex_span_CI8
;
345 swdd
->WriteCI32Pixels
= write_index_pixels_CI8
;
346 swdd
->WriteMonoCIPixels
= write_monoindex_pixels_CI8
;
347 swdd
->ReadCI32Span
= read_index_span_CI8
;
348 swdd
->ReadCI32Pixels
= read_index_pixels_CI8
;
350 else if (glVisual
->rgbBits
== 24 &&
351 glVisual
->alphaBits
== 0) {
352 swdd
->WriteRGBASpan
= write_rgba_span_B8G8R8
;
353 swdd
->WriteRGBSpan
= write_rgb_span_B8G8R8
;
354 swdd
->WriteMonoRGBASpan
= write_monorgba_span_B8G8R8
;
355 swdd
->WriteRGBAPixels
= write_rgba_pixels_B8G8R8
;
356 swdd
->WriteMonoRGBAPixels
= write_monorgba_pixels_B8G8R8
;
357 swdd
->ReadRGBASpan
= read_rgba_span_B8G8R8
;
358 swdd
->ReadRGBAPixels
= read_rgba_pixels_B8G8R8
;
360 else if (glVisual
->rgbBits
== 32 &&
361 glVisual
->alphaBits
== 8) {
362 swdd
->WriteRGBASpan
= write_rgba_span_B8G8R8A8
;
363 swdd
->WriteRGBSpan
= write_rgb_span_B8G8R8A8
;
364 swdd
->WriteMonoRGBASpan
= write_monorgba_span_B8G8R8A8
;
365 swdd
->WriteRGBAPixels
= write_rgba_pixels_B8G8R8A8
;
366 swdd
->WriteMonoRGBAPixels
= write_monorgba_pixels_B8G8R8A8
;
367 swdd
->ReadRGBASpan
= read_rgba_span_B8G8R8A8
;
368 swdd
->ReadRGBAPixels
= read_rgba_pixels_B8G8R8A8
;
370 else if (glVisual
->rgbBits
== 16 &&
371 glVisual
->alphaBits
== 0) {
372 swdd
->WriteRGBASpan
= write_rgba_span_B5G6R5
;
373 swdd
->WriteRGBSpan
= write_rgb_span_B5G6R5
;
374 swdd
->WriteMonoRGBASpan
= write_monorgba_span_B5G6R5
;
375 swdd
->WriteRGBAPixels
= write_rgba_pixels_B5G6R5
;
376 swdd
->WriteMonoRGBAPixels
= write_monorgba_pixels_B5G6R5
;
377 swdd
->ReadRGBASpan
= read_rgba_span_B5G6R5
;
378 swdd
->ReadRGBAPixels
= read_rgba_pixels_B5G6R5
;
380 else if (glVisual
->rgbBits
== 15 &&
381 glVisual
->alphaBits
== 0) {
382 swdd
->WriteRGBASpan
= write_rgba_span_B5G5R5
;
383 swdd
->WriteRGBSpan
= write_rgb_span_B5G5R5
;
384 swdd
->WriteMonoRGBASpan
= write_monorgba_span_B5G5R5
;
385 swdd
->WriteRGBAPixels
= write_rgba_pixels_B5G5R5
;
386 swdd
->WriteMonoRGBAPixels
= write_monorgba_pixels_B5G5R5
;
387 swdd
->ReadRGBASpan
= read_rgba_span_B5G5R5
;
388 swdd
->ReadRGBAPixels
= read_rgba_pixels_B5G5R5
;
391 _mesa_printf("bad pixelformat rgb %d alpha %d\n",
393 glVisual
->alphaBits
);
397 /* use default TCL pipeline */
399 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
400 tnl
->Driver
.RunPipeline
= _tnl_run_pipeline
;
403 _mesa_enable_sw_extensions(ctx
);
410 fbDestroyContext( __DRIcontextPrivate
*driContextPriv
)
412 GET_CURRENT_CONTEXT(ctx
);
413 fbContextPtr fbmesa
= (fbContextPtr
) driContextPriv
->driverPrivate
;
414 fbContextPtr current
= ctx
? FB_CONTEXT(ctx
) : NULL
;
416 /* check if we're deleting the currently bound context */
417 if (fbmesa
== current
) {
418 _mesa_make_current2(NULL
, NULL
, NULL
);
421 /* Free fb context resources */
423 _swsetup_DestroyContext( fbmesa
->glCtx
);
424 _tnl_DestroyContext( fbmesa
->glCtx
);
425 _ac_DestroyContext( fbmesa
->glCtx
);
426 _swrast_DestroyContext( fbmesa
->glCtx
);
428 /* free the Mesa context */
429 fbmesa
->glCtx
->DriverCtx
= NULL
;
430 _mesa_destroy_context( fbmesa
->glCtx
);
437 /* Create and initialize the Mesa and driver specific pixmap buffer
441 fbCreateBuffer( __DRIscreenPrivate
*driScrnPriv
,
442 __DRIdrawablePrivate
*driDrawPriv
,
443 const __GLcontextModes
*mesaVis
,
447 return GL_FALSE
; /* not implemented */
450 const GLboolean swDepth
= mesaVis
->depthBits
> 0;
451 const GLboolean swAlpha
= mesaVis
->alphaBits
> 0;
452 const GLboolean swAccum
= mesaVis
->accumRedBits
> 0;
453 const GLboolean swStencil
= mesaVis
->stencilBits
> 0;
454 driDrawPriv
->driverPrivate
= (void *)
455 _mesa_create_framebuffer( mesaVis
,
461 if (!driDrawPriv
->driverPrivate
)
464 /* Replace the framebuffer back buffer with a malloc'ed one --
467 if (driDrawPriv
->backBuffer
)
468 driDrawPriv
->backBuffer
= malloc(driDrawPriv
->currentPitch
* driDrawPriv
->h
);
476 fbDestroyBuffer(__DRIdrawablePrivate
*driDrawPriv
)
478 _mesa_destroy_framebuffer((GLframebuffer
*) (driDrawPriv
->driverPrivate
));
479 free(driDrawPriv
->backBuffer
);
484 /* If the backbuffer is on a videocard, this is extraordinarily slow!
487 fbSwapBuffers( __DRIdrawablePrivate
*dPriv
)
490 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
493 fbmesa
= (fbContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
495 if (ctx
->Visual
.doubleBufferMode
) {
498 char *tmp
= malloc( dPriv
->currentPitch
);
500 _mesa_notifySwapBuffers( ctx
); /* flush pending rendering comands */
502 ASSERT(dPriv
->frontBuffer
);
503 ASSERT(dPriv
->backBuffer
);
506 for (i
= 0 ; i
< dPriv
->h
; i
++ ) {
507 memcpy( tmp
, (char *)dPriv
->frontBuffer
+ offset
, dPriv
->currentPitch
);
508 memcpy( (char *)dPriv
->backBuffer
+ offset
, tmp
, dPriv
->currentPitch
);
509 offset
+= dPriv
->currentPitch
;
516 /* XXX this shouldn't be an error but we can't handle it for now */
517 _mesa_problem(NULL
, "fbSwapBuffers: drawable has no context!\n");
522 /* Force the context `c' to be the current context and associate with it
526 fbMakeCurrent( __DRIcontextPrivate
*driContextPriv
,
527 __DRIdrawablePrivate
*driDrawPriv
,
528 __DRIdrawablePrivate
*driReadPriv
)
530 if ( driContextPriv
) {
531 fbContextPtr newFbCtx
=
532 (fbContextPtr
) driContextPriv
->driverPrivate
;
534 newFbCtx
->dri
.drawable
= driDrawPriv
;
536 _mesa_make_current2( newFbCtx
->glCtx
,
537 (GLframebuffer
*) driDrawPriv
->driverPrivate
,
538 (GLframebuffer
*) driReadPriv
->driverPrivate
);
540 if ( !newFbCtx
->glCtx
->Viewport
.Width
) {
541 _mesa_set_viewport( newFbCtx
->glCtx
, 0, 0,
542 driDrawPriv
->w
, driDrawPriv
->h
);
545 _mesa_make_current( 0, 0 );
552 /* Force the context `c' to be unbound from its buffer.
555 fbUnbindContext( __DRIcontextPrivate
*driContextPriv
)
561 fbOpenCloseFullScreen( __DRIcontextPrivate
*driContextPriv
)
566 static struct __DriverAPIRec fbAPI
= {
576 fbOpenCloseFullScreen
,
577 fbOpenCloseFullScreen
582 __driRegisterExtensions( void )
588 * This is the bootstrap function for the driver.
589 * The __driCreateScreen name is the symbol that libGL.so fetches.
590 * Return: pointer to a __DRIscreenPrivate.
593 __driCreateScreen(struct DRIDriverRec
*driver
,
594 struct DRIDriverContextRec
*driverContext
)
596 __DRIscreenPrivate
*psp
;
597 psp
= __driUtilCreateScreenNoDRM(driver
, driverContext
, &fbAPI
);
604 * \brief Establish the set of modes available for the display.
606 * \param ctx display handle.
607 * \param numModes will receive the number of supported modes.
608 * \param modes will point to the list of supported modes.
610 * \return one on success, or zero on failure.
612 * Allocates a single visual and fills it with information according to the
613 * display bit depth. Supports only 16 and 32 bpp bit depths, aborting
616 const __GLcontextModes __glModes
[] = {
618 /* 32 bit, RGBA Depth=24 Stencil=8 */
619 {.rgbMode
= GL_TRUE
, .colorIndexMode
= GL_FALSE
, .doubleBufferMode
= GL_TRUE
, .stereoMode
= GL_FALSE
,
620 .haveAccumBuffer
= GL_FALSE
, .haveDepthBuffer
= GL_TRUE
, .haveStencilBuffer
= GL_TRUE
,
621 .redBits
= 8, .greenBits
= 8, .blueBits
= 8, .alphaBits
= 8,
622 .redMask
= 0xff0000, .greenMask
= 0xff00, .blueMask
= 0xff, .alphaMask
= 0xff000000,
623 .rgbBits
= 32, .indexBits
= 0,
624 .accumRedBits
= 0, .accumGreenBits
= 0, .accumBlueBits
= 0, .accumAlphaBits
= 0,
625 .depthBits
= 24, .stencilBits
= 8,
626 .numAuxBuffers
= 0, .level
= 0, .pixmapMode
= GL_FALSE
, },
628 /* 16 bit, RGB Depth=16 */
629 {.rgbMode
= GL_TRUE
, .colorIndexMode
= GL_FALSE
, .doubleBufferMode
= GL_TRUE
, .stereoMode
= GL_FALSE
,
630 .haveAccumBuffer
= GL_FALSE
, .haveDepthBuffer
= GL_TRUE
, .haveStencilBuffer
= GL_FALSE
,
631 .redBits
= 5, .greenBits
= 6, .blueBits
= 5, .alphaBits
= 0,
632 .redMask
= 0xf800, .greenMask
= 0x07e0, .blueMask
= 0x001f, .alphaMask
= 0x0,
633 .rgbBits
= 16, .indexBits
= 0,
634 .accumRedBits
= 0, .accumGreenBits
= 0, .accumBlueBits
= 0, .accumAlphaBits
= 0,
635 .depthBits
= 16, .stencilBits
= 0,
636 .numAuxBuffers
= 0, .level
= 0, .pixmapMode
= GL_FALSE
, },
641 __driInitScreenModes( const DRIDriverContext
*ctx
,
642 int *numModes
, const __GLcontextModes
**modes
)
644 *numModes
= sizeof(__glModes
)/sizeof(__GLcontextModes
*);
645 *modes
= &__glModes
[0];
652 __driValidateMode(const DRIDriverContext
*ctx
)
657 /* HACK - for now, put this here... */
658 /* Alpha - this may need to be a variable to handle UP1x00 vs TITAN */
659 #if defined(__alpha__)
660 # define DRM_PAGE_SIZE 8192
661 #elif defined(__ia64__)
662 # define DRM_PAGE_SIZE getpagesize()
664 # define DRM_PAGE_SIZE 4096
669 __driInitFBDev( struct DRIDriverContextRec
*ctx
)
672 ctx
->shared
.hFrameBuffer
= ctx
->FBStart
;
673 ctx
->shared
.fbSize
= ctx
->FBSize
;
674 ctx
->shared
.hSAREA
= 0xB37D;
675 ctx
->shared
.SAREASize
= DRM_PAGE_SIZE
;
676 id
= shmget(ctx
->shared
.hSAREA
, ctx
->shared
.SAREASize
, IPC_CREAT
| IPC_EXCL
| S_IRUSR
| S_IWUSR
);
678 /* segment will already exist if previous server segfaulted */
679 id
= shmget(ctx
->shared
.hSAREA
, ctx
->shared
.SAREASize
, 0);
681 fprintf(stderr
, "fb: shmget failed\n");
685 ctx
->pSAREA
= shmat(id
, NULL
, 0);
686 if (ctx
->pSAREA
== (void *)-1) {
687 fprintf(stderr
, "fb: shmat failed\n");
690 memset(ctx
->pSAREA
, 0, DRM_PAGE_SIZE
);
695 __driHaltFBDev( struct DRIDriverContextRec
*ctx
)
701 struct DRIDriverRec __driDriver
= {
702 __driInitScreenModes
,