📄 ui_dga.c
字号:
#include "aconfig.h"#ifdef DGA_DRIVER#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>#include <X11/Xlib.h>#include <X11/Xutil.h>#include <X11/keysym.h>#include <X11/keysymdef.h>#include <X11/extensions/xf86dga.h>#include <X11/extensions/xf86vmode.h>#include <ui.h>#include <xmenu.h>#include <xerror.h>#include "ui.h"#include "xio.h"#include <cursor.h>#include <misc-f.h>#define MOUSEWIDTH 16#define MOUSEHEIGHT 16/* Mouse */static int mouseX, mouseY, oldmouseX, oldmouseY;static CONST char *mousepointer = mouse_pointer_data;static char *storeddata = NULL;static unsigned int mousebuttons = 0;static CONST char *defmode = "320x200";static char *defdisplay = NULL;static int first_time = 1;struct ui_driver DGA_driver;static XF86VidModeModeInfo *mode;static int current;static Display *display;static Window window;static char *buffers[2];static int linewidth;static void DGA_uninitialise (void);static struct{ int screen; Visual *visual; int depth; unsigned char *addr; int grabbed_keybd; int grabbed_mouse; char *base_addr; int linewidth; int width; int height; int bank_size; int ram_size; Colormap cmap; unsigned int *pixels; XF86VidModeModeInfo orig_mode; XF86VidModeModeInfo *mode; int orig_viewport_x; int orig_viewport_y; int vidmode_changed; int modecount; XF86VidModeModeInfo **modes;}xf86ctx ={ -1, NULL, -1, NULL, 0, 0, NULL, -1, -1, -1, -1, -1, 0, NULL, { }, 0, 0, 0};static char *store (char *data, int depth, int lpitch, int width, int height, int xpos, int ypos){ int d = depth / 8; char *store = malloc (d * MOUSEWIDTH * MOUSEHEIGHT); int y; if (xpos + MOUSEWIDTH > width) xpos = width - MOUSEWIDTH; if (ypos + MOUSEHEIGHT > height) ypos = height - MOUSEHEIGHT; if (xpos < 0) xpos = 0; if (ypos < 0) ypos = 0; for (y = 0; y < MOUSEHEIGHT; y++) memcpy (store + d * MOUSEWIDTH * y, data + xpos * d + (ypos + y) * lpitch, MOUSEWIDTH * d); return store;}static voidrestore (char *data, char *store, int depth, int lpitch, int width, int height, int xpos, int ypos){ int y; int d = depth / 8; if (xpos + MOUSEWIDTH > width) xpos = width - MOUSEWIDTH; if (ypos + MOUSEHEIGHT > height) ypos = height - MOUSEHEIGHT; if (xpos < 0) xpos = 0; if (ypos < 0) ypos = 0; for (y = 0; y < MOUSEHEIGHT; y++) memcpy (data + xpos * d + (ypos + y) * lpitch, store + d * MOUSEWIDTH * y, MOUSEWIDTH * d);}static voiddrawmouse (char *data, CONST char *mouse, int depth, int lpitch, int width, int height, int xpos, int ypos){ int x, y, z, c; int d = depth / 8; for (y = 0; y < MOUSEWIDTH; y++) for (x = 0; x < MOUSEWIDTH; x++) if (mouse[x + MOUSEWIDTH * y] && x + xpos > 0 && (x + xpos) < width && y + ypos > 0 && y + ypos < height) { c = mouse[x + MOUSEWIDTH * y] == 2 ? (d == 1 ? 1 : 255) : 0; for (z = 0; z < d; z++) data[z + d * (x + xpos) + (y + ypos) * lpitch] = c; }}static char **names;static menudialog uih_resizedialog[] = { DIALOGCHOICE ("Mode", NULL, 0), {NULL}};static menudialog *DGA_resizedialog (struct uih_context *c){ int i; for (i = 0; i < xf86ctx.modecount; i++) { if (xf86ctx.modes[i]->hdisplay == xf86ctx.width && xf86ctx.modes[i]->vdisplay == xf86ctx.height) break; } if (i == xf86ctx.modecount) i = 0; uih_resizedialog[0].defint = i; uih_resizedialog[0].defstr = (char *) names; return uih_resizedialog;}static voidDGA_resize (struct uih_context *c, int p){ static char s[256]; sprintf (s, "%ix%i", xf86ctx.modes[p]->hdisplay, xf86ctx.modes[p]->vdisplay); defmode = s; ui_call_resize ();}static CONST menuitem menuitems[] = { MENUCDIALOG ("ui", "=", "Resize", "resize", 0, DGA_resize, DGA_resizedialog),};static intDGA_getmodeinfo (XF86VidModeModeInfo * modeinfo){ XF86VidModeModeLine modeline; int dotclock; Bool err; err = XF86VidModeGetModeLine (display, xf86ctx.screen, &dotclock, &modeline); modeinfo->dotclock = dotclock; modeinfo->hdisplay = modeline.hdisplay; modeinfo->hsyncstart = modeline.hsyncstart; modeinfo->hsyncend = modeline.hsyncend; modeinfo->htotal = modeline.htotal; modeinfo->vdisplay = modeline.vdisplay; modeinfo->vsyncstart = modeline.vsyncstart; modeinfo->vsyncend = modeline.vsyncend; modeinfo->vtotal = modeline.vtotal; modeinfo->flags = modeline.flags; modeinfo->privsize = modeline.privsize; modeinfo->private = modeline.private; return err;}static voidDGA_setpalette (ui_palette pal, int start, int end){ int i; for (i = start; i < end; i++) { XColor color; color.pixel = i; color.flags = DoRed | DoBlue | DoGreen; color.red = pal[i - start][0] * 256; color.green = pal[i - start][1] * 256; color.blue = pal[i - start][2] * 256; XStoreColor (display, xf86ctx.cmap, &color); } XF86DGAInstallColormap (display, xf86ctx.screen, xf86ctx.cmap);}static voidDGA_print (int x, int y, CONST char *text){}static voidDGA_display (void){ int i; if (storeddata) free (storeddata), storeddata = NULL; storeddata = store (buffers[current], xf86ctx.depth, linewidth, xf86ctx.width, xf86ctx.height, mouseX, mouseY); drawmouse (buffers[current], mousepointer, xf86ctx.depth, linewidth, xf86ctx.width, xf86ctx.height, mouseX, mouseY); for (i = 0; i < xf86ctx.height; i++) { memcpy (xf86ctx.base_addr + xf86ctx.linewidth * i * xf86ctx.depth / 8, buffers[current] + linewidth * i, linewidth); } restore (buffers[current], storeddata, xf86ctx.depth, linewidth, xf86ctx.width, xf86ctx.height, mouseX, mouseY); oldmouseX = mouseX; oldmouseY = mouseY;#if 0 sleep (1); exit (1);#endif}static voidDGA_flip_buffers (void){ current ^= 1;}static voidDGA_free_buffers (char *b1, char *b2){ free (buffers[0]); free (buffers[1]);}static intDGA_alloc_buffers (char **b1, char **b2){ buffers[0] = malloc (linewidth * xf86ctx.height * xf86ctx.depth / 8); current = 0; if (buffers[0] == NULL) { x_error ("Couldn't alloc enough memory\n"); return 0; } buffers[1] = malloc (linewidth * xf86ctx.height * xf86ctx.depth / 8); if (buffers[1] == NULL) { free (buffers[0]); x_error ("Couldn't alloc enough memory\n"); return 0; } *b1 = buffers[0]; *b2 = buffers[1]; XSync (display, 0); return linewidth; /* bytes per scanline */}static voidDGA_vidmode_restoremode (Display * disp){ XF86VidModeSwitchToMode (disp, xf86ctx.screen, &xf86ctx.orig_mode); XF86VidModeSetViewPort (disp, xf86ctx.screen, xf86ctx.orig_viewport_x, xf86ctx.orig_viewport_y); /* 'Mach64-hack': restores screen when screwed up */ XF86VidModeSwitchMode (disp, xf86ctx.screen, -1); XF86VidModeSwitchMode (disp, xf86ctx.screen, 1);/**************************************************/ XSync (disp, False);}static intDGA_vidmode_setup_mode_restore (void){ Display *disp; int status; pid_t pid; if (!DGA_getmodeinfo (&xf86ctx.orig_mode)) { x_error ("XF86VidModeGetModeLine failed\n"); return 1; } if (!XF86VidModeGetViewPort (display, xf86ctx.screen, &xf86ctx.orig_viewport_x, &xf86ctx.orig_viewport_y)) { x_error ("XF86VidModeGetViewPort failed\n"); return 1; } pid = fork (); if (pid > 0) { waitpid (pid, &status, 0); disp = XOpenDisplay (defdisplay); DGA_vidmode_restoremode (disp); XCloseDisplay (disp); _exit (!WIFEXITED (status)); } if (pid < 0) { perror ("fork"); return 1; } return 0;}static XF86VidModeModeInfo *DGA_findmode (void){ int mindist = 65536 * 30000; int width = 640, height = 480; int i; XF86VidModeModeInfo *best = NULL; if (sscanf (defmode, "%ix%i", &width, &height) < 2) return NULL; for (i = 0; i < xf86ctx.modecount; i++) { int dist; dist = (width - xf86ctx.modes[i]->hdisplay) * (width - xf86ctx.modes[i]->hdisplay) + (height - xf86ctx.modes[i]->vdisplay) * (height - xf86ctx.modes[i]->vdisplay); if (dist < mindist) mindist = dist, best = xf86ctx.modes[i]; } return best;}static voidDGA_getsize (int *w, int *h){ window = RootWindow (display, xf86ctx.screen); DGA_driver.rmask = xf86ctx.visual->red_mask; DGA_driver.gmask = xf86ctx.visual->green_mask; DGA_driver.bmask = xf86ctx.visual->blue_mask; XF86DGADirectVideo (display, xf86ctx.screen, 0); if (xf86ctx.cmap) { XFreeColormap (display, xf86ctx.cmap); xf86ctx.cmap = 0; } switch (xf86ctx.depth) { case 8: xf86ctx.cmap = XCreateColormap (display, window, xf86ctx.visual, AllocAll); if (xf86ctx.visual->class != PseudoColor) { DGA_uninitialise (); x_fatalerror ("Only pseudocolor visual supported on 256 color cards\n"); } DGA_driver.imagetype = UI_C256; break; case 15: case 16: DGA_driver.imagetype = UI_TRUECOLOR16; break; case 24: DGA_driver.imagetype = UI_TRUECOLOR24; break; case 32: DGA_driver.imagetype = UI_TRUECOLOR; break; default: { DGA_uninitialise (); x_fatalerror ("Unsupported visual!\n"); } } xf86ctx.addr = (unsigned char *) xf86ctx.base_addr; mode = DGA_findmode (); if (mode) { /*xf86_dga_setup_graphics (bestmode); */ xf86ctx.vidmode_changed = 1; xf86ctx.mode = mode; } else xf86ctx.mode = &xf86ctx.orig_mode; *w = xf86ctx.width = xf86ctx.mode->hdisplay; *h = xf86ctx.height = xf86ctx.mode->vdisplay; linewidth = ((xf86ctx.width * (xf86ctx.depth / 8)) + 63) & ~63; if (first_time) { if (DGA_vidmode_setup_mode_restore ()) { DGA_uninitialise (); exit (1); } } if (!XF86VidModeSwitchToMode (display, xf86ctx.screen, xf86ctx.mode)) { DGA_uninitialise (); x_fatalerror ("XF86VidModeSwitchToMode failed\n"); } xf86ctx.vidmode_changed = 1; if (!XF86DGASetViewPort (display, xf86ctx.screen, 0, 0)) { DGA_uninitialise (); x_fatalerror ("XF86DGASetViewPort failed\n"); } if (!xf86ctx.grabbed_keybd) { if (XGrabKeyboard (display, window, True, GrabModeAsync, GrabModeAsync, CurrentTime)) { DGA_uninitialise ();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -