📄 vid_sunx.c
字号:
int size;
int key;
int minsize = getpagesize();
int frm;
// if (d_pzbuffer)
// Z_Free(mainzone, d_pzbuffer); // 2001-09-20 Enhanced zone handling by Maddes
d_pzbuffer = Hunk_HighAllocName(vid.width*vid.height*sizeof(*d_pzbuffer),"zbuff");
for (frm=0 ; frm<2 ; frm++)
{
// free up old frame buffer memory
if (x_framebuffer[frm])
{
XShmDetach(x_disp, &x_shminfo[frm]);
free(x_framebuffer[frm]);
shmdt(x_shminfo[frm].shmaddr);
}
// create the image
x_framebuffer[frm] = XShmCreateImage( x_disp,
x_vis,
x_visinfo->depth,
ZPixmap,
0,
&x_shminfo[frm],
vid.width,
vid.height );
// grab shared memory
size = x_framebuffer[frm]->bytes_per_line
* x_framebuffer[frm]->height;
if (size < minsize)
Sys_Error("VID: Window must use at least %d bytes\n", minsize);
key = random();
x_shminfo[frm].shmid = shmget((key_t)key, size, IPC_CREAT|0777);
if (x_shminfo[frm].shmid==-1)
Sys_Error("VID: Could not get any shared memory\n");
// attach to the shared memory segment
x_shminfo[frm].shmaddr =
(void *) shmat(x_shminfo[frm].shmid, 0, 0);
printf("VID: shared memory id=%d, addr=0x%x\n", x_shminfo[frm].shmid,
(int) x_shminfo[frm].shmaddr);
x_framebuffer[frm]->data = x_shminfo[frm].shmaddr;
// get the X server to attach to it
if (!XShmAttach(x_disp, &x_shminfo[frm]))
Sys_Error("VID: XShmAttach() failed\n");
XSync(x_disp, 0);
shmctl(x_shminfo[frm].shmid, IPC_RMID, 0);
}
}
void VID_MenuDraw( void )
{
qpic_t *p;
char *ptr;
int i, j, column, row, dup;
char temp[100];
p = Draw_CachePic ("gfx/vidmodes.lmp");
M_DrawPic ( (320-p->width)/2, 4, p);
M_Print (4*8, 36 + MAX_COLUMN_SIZE * 8 + 8, "Video mode switching unavailable");
M_Print (9*8, 36 + MAX_COLUMN_SIZE * 8 + 8*6, "Press any key...");
}
void VID_MenuKey( int key ) { M_Menu_Options_f (); }
// Called at startup to set up translation tables, takes 256 8 bit RGB values
// the palette data will go away after the call, so it must be copied off if
// the video driver will need it again
byte surfcache[1024*1024];
//
// VID_SetWindowTitle - set the window and icon titles
//
void VID_SetWindowTitle( Window win, char *pszName )
{
XTextProperty textprop;
XWMHints *wmHints;
// Setup ICCCM properties
textprop.value = (unsigned char *)pszName;
textprop.encoding = XA_STRING;
textprop.format = 8;
textprop.nitems = strlen(pszName);
wmHints = XAllocWMHints();
wmHints->initial_state = NormalState;
wmHints->flags = StateHint;
XSetWMProperties( x_disp, win, &textprop, &textprop,
// Only put WM_COMMAND property on first window.
com_argv, com_argc, NULL, NULL, NULL );
XFree( wmHints );
aWMDelete = XInternAtom( x_disp, "WM_DELETE_WINDOW", False );
XSetWMProtocols( x_disp, win, &aWMDelete, 1 );
}
//
// VID_FullScreen - open the window in full screen mode
//
qboolean VID_FullScreen( Window win )
{
MotifWmHints hints;
XWindowChanges changes;
aHints = XInternAtom( x_disp, "_MOTIF_WM_HINTS", 0 );
if (aHints == None)
{
Con_Printf( "Could not intern X atom for _MOTIF_WM_HINTS." );
return( false );
}
hints.flags = MWM_HINTS_DECORATIONS;
hints.decorations = 0; // Absolutely no decorations.
XChangeProperty( x_disp, win, aHints, aHints, 32, PropModeReplace, (unsigned char *)&hints, 4 );
changes.x = 0;
changes.y = 0;
changes.width = x_screen_width;
changes.height = x_screen_height;
changes.stack_mode = TopIf;
XConfigureWindow( x_disp, win, CWX | CWY | CWWidth | CWHeight | CWStackMode, &changes);
return( true );
}
// 2001-09-18 New cvar system by Maddes (Init) start
/*
===================
VID_Init_Cvars
===================
*/
void VID_Init_Cvars (void)
{
}
// 2001-09-18 New cvar system by Maddes (Init) end
void VID_Init (unsigned char *palette)
{
int pnum, i;
XVisualInfo template;
int num_visuals;
int template_mask;
Cmd_AddCommand ("gamma", VID_Gamma_f);
for (i=0 ; i<256 ; i++)
vid_gamma[i] = i;
vid.width = 320;
vid.height = 200;
vid.aspect = 1.0;
vid.numpages = 2;
vid.colormap = host_colormap;
vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
//vid.cbits = VID_CBITS;
//vid.grades = VID_GRADES;
srandom(getpid());
verbose=COM_CheckParm("-verbose");
// open the display
x_disp = XOpenDisplay(0);
if (!x_disp)
{
if (getenv("DISPLAY"))
Sys_Error("VID: Could not open display [%s]\n",
getenv("DISPLAY"));
else
Sys_Error("VID: Could not open local display\n");
}
x_screen = XDefaultScreen( x_disp );
x_screen_width = WidthOfScreen( ScreenOfDisplay( x_disp, x_screen ) );
x_screen_height = HeightOfScreen( ScreenOfDisplay( x_disp, x_screen ) );
x_center_width = x_screen_width/2;
x_center_height = x_screen_height/2;
Con_Printf( "Using screen %d: %dx%d\n", x_screen, x_screen_width, x_screen_height );
x_root_win = XRootWindow( x_disp, x_screen );
// catch signals so i can turn on auto-repeat
// we never run full-screen, so no auto-repeat nukage
if (0)
{
struct sigaction sa;
sigaction(SIGINT, 0, &sa);
sa.sa_handler = TragicDeath;
sigaction(SIGINT, &sa, 0);
sigaction(SIGTERM, &sa, 0);
}
//XAutoRepeatOff(x_disp);
// for debugging only
// XSynchronize(x_disp, True);
// check for command-line window size
if ((pnum=COM_CheckParm("-winsize")))
{
if (pnum >= com_argc-2)
Sys_Error("VID: -winsize <width> <height>\n");
vid.width = Q_atoi(com_argv[pnum+1]);
vid.height = Q_atoi(com_argv[pnum+2]);
if (!vid.width || !vid.height)
Sys_Error("VID: Bad window width/height\n");
}
template_mask = 0;
// specify a visual id
if ((pnum=COM_CheckParm("-visualid")))
{
if (pnum >= com_argc-1)
Sys_Error("VID: -visualid <id#>\n");
template.visualid = Q_atoi(com_argv[pnum+1]);
template_mask = VisualIDMask;
}
// If not specified, use default visual
else
{
int screen;
screen = XDefaultScreen(x_disp);
template.visualid =
XVisualIDFromVisual(XDefaultVisual(x_disp, screen));
template_mask = VisualIDMask;
}
// pick a visual- warn if more than one was available
x_visinfo = XGetVisualInfo(x_disp, template_mask, &template, &num_visuals);
if (num_visuals > 1)
{
printf("Found more than one visual id at depth %d:\n", template.depth);
for (i=0 ; i<num_visuals ; i++)
printf(" -visualid %d\n", (int)(x_visinfo[i].visualid));
}
else if (num_visuals == 0)
{
if (template_mask == VisualIDMask)
Sys_Error("VID: Bad visual id %d\n", template.visualid);
else
Sys_Error("VID: No visuals at depth %d\n", template.depth);
}
if (verbose)
{
printf("Using visualid %d:\n", (int)(x_visinfo->visualid));
printf(" class %d\n", x_visinfo->class);
printf(" screen %d\n", x_visinfo->screen);
printf(" depth %d\n", x_visinfo->depth);
printf(" red_mask 0x%x\n", (int)(x_visinfo->red_mask));
printf(" green_mask 0x%x\n", (int)(x_visinfo->green_mask));
printf(" blue_mask 0x%x\n", (int)(x_visinfo->blue_mask));
printf(" colormap_size %d\n", x_visinfo->colormap_size);
printf(" bits_per_rgb %d\n", x_visinfo->bits_per_rgb);
}
x_vis = x_visinfo->visual;
// setup attributes for main window
{
int attribmask = CWEventMask | CWColormap | CWBorderPixel;
XSetWindowAttributes attribs;
Colormap tmpcmap;
tmpcmap = XCreateColormap(x_disp, XRootWindow(x_disp,
x_visinfo->screen), x_vis, AllocNone);
attribs.event_mask = x_std_event_mask;
attribs.border_pixel = 0;
attribs.colormap = tmpcmap;
// create the main window
x_win = XCreateWindow( x_disp,
XRootWindow(x_disp, x_visinfo->screen),
0, 0, // x, y
vid.width, vid.height,
0, // borderwidth
x_visinfo->depth,
InputOutput,
x_vis,
attribmask,
&attribs );
if (x_visinfo->class != TrueColor)
XFreeColormap(x_disp, tmpcmap);
}
if (x_visinfo->depth == 8)
{
// create and upload the palette
if (x_visinfo->class == PseudoColor)
{
x_cmap = XCreateColormap(x_disp, x_win, x_vis, AllocAll);
VID_SetPalette(palette);
XSetWindowColormap(x_disp, x_win, x_cmap);
}
}
VID_SetWindowTitle( x_win, "Quake" );
// create the GC
{
XGCValues xgcvalues;
int valuemask = GCGraphicsExposures;
xgcvalues.graphics_exposures = False;
x_gc = XCreateGC(x_disp, x_win, valuemask, &xgcvalues );
}
// map the window
XMapWindow(x_disp, x_win);
// wait for first exposure event
{
XEvent event;
do
{
XNextEvent(x_disp, &event);
if (event.type == Expose && !event.xexpose.count)
oktodraw = true;
} while (!oktodraw);
}
// now safe to draw
// even if MITSHM is available, make sure it's a local connection
if (XShmQueryExtension(x_disp))
{
char *displayname;
doShm = true;
displayname = (char *) getenv("DISPLAY");
if (displayname)
{
char *d = displayname;
while (*d && (*d != ':')) d++;
if (*d) *d = 0;
if (!(!strcasecmp(displayname, "unix") || !*displayname))
doShm = false;
}
}
if (doShm)
{
x_shmeventtype = XShmGetEventBase(x_disp) + ShmCompletion;
ResetSharedFrameBuffers();
}
else
ResetFrameBuffer();
current_framebuffer = 0;
vid.rowbytes = x_framebuffer[0]->bytes_per_line;
vid.buffer = x_framebuffer[0]->data;
vid.conbuffer = x_framebuffer[0]->data;
vid.conrowbytes = vid.rowbytes;
vid.conwidth = vid.width;
vid.conheight = vid.height;
vid.maxwarpwidth = WARP_WIDTH;
vid.maxwarpheight = WARP_HEIGHT;
D_InitCaches (surfcache, sizeof(surfcache));
// XSynchronize(x_disp, False);
vid_menudrawfn = VID_MenuDraw;
vid_menukeyfn = VID_MenuKey;
}
void VID_ShiftPalette(unsigned char *p)
{
VID_SetPalette(p);
}
void VID_SetPalette(unsigned char *palette)
{
int i;
XColor colors[256];
for(i=0;i<256;i++) {
st2d_8to16table[i]= xlib_rgb16(palette[i*3], palette[i*3+1],palette[i*3+2]);
st2d_8to24table[i]= xlib_rgb24(palette[i*3], palette[i*3+1],palette[i*3+2]);
}
if (x_visinfo->class == PseudoColor && x_visinfo->depth == 8)
{
if (palette != current_palette)
memcpy(current_palette, palette, 768);
for (i=0 ; i<256 ; i++)
{
colors[i].pixel = i;
colors[i].flags = DoRed|DoGreen|DoBlue;
colors[i].red = vid_gamma[palette[i*3]] * 257;
colors[i].green = vid_gamma[palette[i*3+1]] * 257;
colors[i].blue = vid_gamma[palette[i*3+2]] * 257;
}
XStoreColors(x_disp, x_cmap, colors, 256);
}
}
// Called at shutdown
void VID_Shutdown (void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -