int xf86_dga2_init(void) { int i,j ; xf86ctx.screen = DefaultScreen(display); if(!XDGAQueryVersion(display, &i, &j)) fprintf(stderr,"XDGAQueryVersion failed\n"); else if (i < 2) fprintf(stderr,"This driver requires DGA 2.0 or newer\n"); else if(!XDGAQueryExtension(display, &i, &j)) fprintf(stderr,"XDGAQueryExtension failed\n"); else { /* Dumping core while DirectVideo is active causes an X-server freeze with kernel 2.6, so don't dump core! */ struct rlimit limit = { 0, 0 }; if(setrlimit(RLIMIT_CORE, &limit)) perror("rlimit"); else if(!XDGAOpenFramebuffer(display,xf86ctx.screen)) fprintf(stderr,"XDGAOpenFramebuffer failed\n"); else return SYSDEP_DISPLAY_FULLSCREEN|SYSDEP_DISPLAY_EFFECTS; } fprintf(stderr,"Use of DGA-modes is disabled\n"); return 0; }
Bool XF86DGAQueryVersion( Display* dpy, int* majorVersion, int* minorVersion ){ return XDGAQueryVersion(dpy, majorVersion, minorVersion); }
static int vinit( video_module_t *module ) { int n, i, major, minor, mcount, nodga; int (*old_ehandler)(Display*, XErrorEvent*); Display *dis = x11.disp; XDGAMode *mm; video_desc_t *m; memset( &dga, 0, sizeof(dga) ); if( !x11.connected || get_bool_res("enable_xdga_video")!=1 ) return 1; nodga = !XDGAQueryExtension(dis, &dga.ev_base, &dga.err_base); old_ehandler = XSetErrorHandler( dga_error_handler ); nodga = nodga || !XDGAQueryVersion(dis, &major, &minor); XSetErrorHandler( old_ehandler ); if( nodga ) { printm("X11 DGA is not available\n"); return 1; } if( major < MIN_MAJOR || (major == MIN_MAJOR && minor < MIN_MINOR) ) { printm("Xserver is running DGA %d.%d (%d.%d is required)\n", major, minor, MIN_MAJOR, MIN_MINOR ); return 1; } printm("Running X11 DGA %d.%d\n\n", major, minor ); if( !(mm=XDGAQueryModes(dis, x11.screen, &mcount)) ) { printm("XDGAQueryModes failed\n"); return 1; } m = calloc( mcount, sizeof(video_desc_t) ); for( n=0, i=0; i<mcount; i++ ) { int j, skip = 0; char *s; for( j=0; (s=get_str_res_ind("xdga_modes", 0, j)); j++ ) { skip = 1; if( i == strtol(s,NULL,0) ) break; } if( mm[i].visualClass != DirectColor /*&& mm[i].visualClass != PseudoColor*/ ) skip = 1; if( mm[i].bitsPerPixel == 24 || mm[i].depth == 16 || mm[i].depth != x11.xdepth ) skip = 1; if( s ) skip = 0; printm(" %c Mode %d: \"%s\": %dx%d %2d (%dx%d) %.2f Hz %04x %d %d\n", skip ? ' ' : '*', mm[i].num, mm[i].name, mm[i].imageWidth, mm[i].imageHeight, mm[i].depth, mm[i].pixmapWidth, mm[i].pixmapHeight, mm[i].verticalRefresh, /*mm[i].viewportWidth, mm[i].viewportHeight, */ mm[i].flags, mm[i].bytesPerScanline, mm[i].visualClass ); if( skip ) continue; /* add mode */ m[n].offs = 0; /* fixme! */ m[n].rowbytes = mm[i].bytesPerScanline; m[n].w = mm[i].viewportWidth; m[n].h = mm[i].viewportHeight; m[n].depth = mm[i].depth; m[n].refresh = (mm[i].verticalRefresh * 65536) + 0.5; m[n].module_data = (void*)mm[i].num; m[n].next = NULL; if( n>0 ) m[n-1].next = &m[n]; n++; } printm("\n"); xdga_module.modes = &m[0]; XFree( mm ); add_key_actions( xdga_keys, sizeof(xdga_keys) ); dga.initialized = 1; return 0; }
/* _xdga2_gfxdrv_init_drv: * Initializes driver and creates screen bitmap. */ static BITMAP *_xdga2_private_gfxdrv_init_drv(GFX_DRIVER *drv, int w, int h, int vw, int vh, int depth, int accel) { int dga_error_base, dga_major_version, dga_minor_version; int mode, mask, red_shift = 0, green_shift = 0, blue_shift = 0; long input_mask; char tmp1[128], tmp2[128]; BITMAP *bmp; /* This is just to test if the system driver has been installed properly */ if (_xwin.window == None) return NULL; /* Test that display is local. */ if (!_xdga2_private_display_is_local()) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("This driver needs local display")); return NULL; } /* Choose convenient size. */ if ((w == 0) && (h == 0)) { w = 640; h = 480; } if ((w < 80) || (h < 80) || (w > 4096) || (h > 4096)) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported screen size")); return NULL; } if (vw < w) vw = w; if (vh < h) vh = h; if (1 #ifdef ALLEGRO_COLOR8 && (depth != 8) #endif #ifdef ALLEGRO_COLOR16 && (depth != 15) && (depth != 16) #endif #ifdef ALLEGRO_COLOR24 && (depth != 24) #endif #ifdef ALLEGRO_COLOR32 && (depth != 32) #endif ) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported color depth")); return NULL; } /* Checks presence of DGA extension */ if (!XDGAQueryExtension(_xwin.display, &dga_event_base, &dga_error_base) || !XDGAQueryVersion(_xwin.display, &dga_major_version, &dga_minor_version)) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("DGA extension is not supported")); return NULL; } /* Works only with DGA 2.0 or newer */ if (dga_major_version < 2) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("DGA 2.0 or newer is required")); return NULL; } /* Attempts to access the framebuffer */ if (!XDGAOpenFramebuffer(_xwin.display, _xwin.screen)) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not open framebuffer")); return NULL; } /* Finds suitable video mode number */ mode = _xdga2_find_mode(w, h, vw, vh, depth); if (!mode) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Resolution not supported")); return NULL; } /* Sets DGA video mode */ dga_device = XDGASetMode(_xwin.display, _xwin.screen, mode); if (dga_device == NULL) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not switch to DGA mode")); return NULL; } _xwin.in_dga_mode = 2; _set_current_refresh_rate(dga_device->mode.verticalRefresh); set_display_switch_mode(SWITCH_NONE); /* Installs DGA color map */ if (_dga_cmap) { XFreeColormap(_xwin.display, _dga_cmap); _dga_cmap = 0; } if ((dga_device->mode.visualClass == PseudoColor) || (dga_device->mode.visualClass == GrayScale) || (dga_device->mode.visualClass == DirectColor)) _dga_cmap = XDGACreateColormap(_xwin.display, _xwin.screen, dga_device, AllocAll); else _dga_cmap = XDGACreateColormap(_xwin.display, _xwin.screen, dga_device, AllocNone); XDGAInstallColormap(_xwin.display, _xwin.screen, _dga_cmap); /* Sets up direct color shifts */ if (depth != 8) { for (mask = dga_device->mode.redMask, red_shift = 0; (mask & 1) == 0; mask >>= 1, red_shift++); for (mask = dga_device->mode.greenMask, green_shift = 0; (mask & 1) == 0; mask >>= 1, green_shift++); for (mask = dga_device->mode.blueMask, blue_shift = 0; (mask & 1) == 0; mask >>= 1, blue_shift++); } switch (depth) { case 15: _rgb_r_shift_15 = red_shift; _rgb_g_shift_15 = green_shift; _rgb_b_shift_15 = blue_shift; break; case 16: _rgb_r_shift_16 = red_shift; _rgb_g_shift_16 = green_shift; _rgb_b_shift_16 = blue_shift; break; case 24: _rgb_r_shift_24 = red_shift; _rgb_g_shift_24 = green_shift; _rgb_b_shift_24 = blue_shift; break; case 32: _rgb_r_shift_32 = red_shift; _rgb_g_shift_32 = green_shift; _rgb_b_shift_32 = blue_shift; break; } /* Enables input */ XSync(_xwin.display, True); input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask; XDGASelectInput(_xwin.display, _xwin.screen, input_mask); if (_xwin_keyboard_focused) { (*_xwin_keyboard_focused)(FALSE, 0); keyboard_got_focus = TRUE; } _mouse_on = TRUE; /* Creates screen bitmap */ drv->linear = TRUE; bmp = _make_bitmap(dga_device->mode.imageWidth, dga_device->mode.imageHeight, (uintptr_t)dga_device->data, drv, depth, dga_device->mode.bytesPerScanline); if (!bmp) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Not enough memory")); return NULL; } drv->w = bmp->cr = w; drv->h = bmp->cb = h; drv->vid_mem = dga_device->mode.imageWidth * dga_device->mode.imageHeight * BYTES_PER_PIXEL(depth); if (accel) { /* Hardware acceleration has been requested */ /* Updates line switcher to accommodate framebuffer synchronization */ #ifdef ALLEGRO_NO_ASM bmp->write_bank = _xdga2_write_line; bmp->read_bank = _xdga2_write_line; #else bmp->write_bank = _xdga2_write_line_asm; bmp->read_bank = _xdga2_write_line_asm; #endif _screen_vtable.acquire = _xdga2_acquire; /* Checks for hardware acceleration support */ if (dga_device->mode.flags & XDGASolidFillRect) { /* XDGAFillRectangle is available */ _orig_hline = _screen_vtable.hline; _orig_vline = _screen_vtable.vline; _orig_rectfill = _screen_vtable.rectfill; _screen_vtable.hline = _xaccel_hline; _screen_vtable.vline = _xaccel_vline; _screen_vtable.rectfill = _xaccel_rectfill; _screen_vtable.clear_to_color = _xaccel_clear_to_color; gfx_capabilities |= (GFX_HW_HLINE | GFX_HW_FILL); } if (dga_device->mode.flags & XDGABlitRect) { /* XDGACopyArea is available */ _screen_vtable.blit_to_self = _xaccel_blit_to_self; _screen_vtable.blit_to_self_forward = _xaccel_blit_to_self; _screen_vtable.blit_to_self_backward = _xaccel_blit_to_self; gfx_capabilities |= GFX_HW_VRAM_BLIT; } if (dga_device->mode.flags & XDGABlitTransRect) { /* XDGACopyTransparentArea is available */ _orig_draw_sprite = _screen_vtable.draw_sprite; _orig_masked_blit = _screen_vtable.masked_blit; _screen_vtable.masked_blit = _xaccel_masked_blit; _screen_vtable.draw_sprite = _xaccel_draw_sprite; if (_screen_vtable.color_depth == 8) _screen_vtable.draw_256_sprite = _xaccel_draw_sprite; gfx_capabilities |= GFX_HW_VRAM_BLIT_MASKED; } RESYNC(); } /* Checks for triple buffering */ if (dga_device->mode.viewportFlags & XDGAFlipRetrace) gfx_capabilities |= GFX_CAN_TRIPLE_BUFFER; /* Sets up driver description */ uszprintf(_xdga2_driver_desc, sizeof(_xdga2_driver_desc), uconvert_ascii("X-Windows DGA 2.0 graphics%s", tmp1), uconvert_ascii(accel ? (gfx_capabilities ? " (accelerated)" : "") : " (software only)", tmp2)); drv->desc = _xdga2_driver_desc; return bmp; }