#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "globals.hpp" #include "system.h" #include "video.hpp" #include "dos.h" #include "macs.hpp" #include "image.hpp" #include "palette.hpp" #include "jmalloc.hpp" image *screen=NULL; static ulong *frame_buffer=NULL; uchar current_background=0; typedef struct { int input; int output; } keymap_t; static float xs; static float ys; Display *display; static Colormap x_cmap; Window mainwin; static GC x_gc; static Visual *my_visual; static XVisualInfo *x_visinfo=0; //static XImage *x_image; static int x_screen; static int oktodraw = 0; static unsigned char *framebuffer=0; static int verbose=0; static short *jcspace=0; static int doGLX; static int glX_errorBase, glX_eventBase; static GLXContext glX_context; static int glX_scaled=0; static GLfloat glX_scale_width; static GLfloat glX_scale_height; static int config_notify=0; static int config_notify_width; static int config_notify_height; int win_xres,win_yres; void PickVisual() { int attribList1[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_GREEN_SIZE, 8, None }; int attribList2[] = { GLX_RGBA, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, None }; doGLX = glXQueryExtension(display, &glX_errorBase, &glX_eventBase); if (!doGLX) { printf("OpenGL not supported\n"); exit(0); } x_visinfo = glXChooseVisual(display, x_screen, attribList1); if (!x_visinfo) x_visinfo = glXChooseVisual(display, x_screen, attribList2); else printf("double-buffered\n"); if (!x_visinfo) { printf("Could not chose an RGB visual. Use X version.\n"); exit(0); } else printf("single-buffered\n"); my_visual = x_visinfo->visual; } // ======================================================================== // makes a null cursor // ======================================================================== static Cursor CreateNullCursor(Display *display, Window root) { Pixmap cursormask; XGCValues xgc; GC gc; XColor dummycolour; Cursor cursor; cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/); xgc.function = GXclear; gc = XCreateGC(display, cursormask, GCFunction, &xgc); XFillRectangle(display, cursormask, gc, 0, 0, 1, 1); dummycolour.pixel = 0; dummycolour.red = 0; dummycolour.flags = 04; cursor = XCreatePixmapCursor(display, cursormask, cursormask, &dummycolour,&dummycolour, 0,0); XFreePixmap(display,cursormask); XFreeGC(display,gc); return cursor; } void CreateWindow(void) { // setup attributes for main window int attribmask = CWEventMask | CWColormap | CWBorderPixel; XSetWindowAttributes attribs; Colormap tmpcmap; tmpcmap = XCreateColormap(display, XRootWindow(display, x_visinfo->screen), my_visual, AllocNone); attribs.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask | ExposureMask; attribs.border_pixel = 0; attribs.colormap = tmpcmap; // create the main window mainwin = XCreateWindow(display, XRootWindow(display, x_visinfo->screen), 0, 0, // x, y win_xres+1, win_yres+1, 0, // borderwidth x_visinfo->depth, InputOutput, my_visual, attribmask, &attribs ); XFreeColormap(display, tmpcmap); } int *lookup24=NULL; void palette::load() { int intensity; int color; int r, g, b; lookup24 = (int *)jmalloc(256*4,"24 bit palette lookup"); for (color = 0 ; color < 256 ; color++) { r = (int)red(color)<<24; g = (int)green(color)<<16; b = (int)blue(color)<<8; lookup24[color] = r + g + b; } } void palette::load_nice() { load(); } void image::make_page(short wid, short hi, unsigned char *page_buffer) { if (special && !special->static_mem) { data=(uchar *)jmalloc(wid*hi,"image data\n"); if (page_buffer) memcpy(data,page_buffer,wid*hi); } else if (page_buffer) data=page_buffer; else data=(uchar *)jmalloc(wid*hi,"image data"); } void image::delete_page() { if (!special || !special->static_mem) jfree(data); } void reset_frame() { glViewport(0, 0, win_xres+1, win_yres+1); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, xres+1, 0, yres+1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); xs=(float)(win_xres+1)/(xres+1); ys=(float)(win_yres+1)/(yres+1); if (xs!=1.0 || ys!=1.0) printf("Pixel scaling -> %lfx%lf\n",xs,ys); glPixelZoom(xs,ys); // top to bottom pixel lines glRasterPos2i(0,0); } void Scaled_f(void) { config_notify = 1; glX_scaled = 1; } void UnScaled_f(void) { config_notify = 1; glX_scaled = 0; } void set_mode(int mode, int argc, char **argv) { // Cmd_AddCommand("glx_scaled", Scaled_f); // Cmd_AddCommand("glx_unscaled", UnScaled_f); /****************************** Open DISPLAY *************************/ char display_name[100]; // get the default display name from the enviroment variable DISPLAY char *ds_name=getenv("DISPLAY"); if (!ds_name) ds_name="unix:0.0"; strcpy(display_name,ds_name); display=XOpenDisplay(display_name); if (!display) { printf("Cound not connect to X server named '%s'\n",display_name); exit(1); } x_screen = DefaultScreen(display); win_xres=640; win_yres=400; int i; for (i=1;iwidth()*(long)im->height()); // ulong *page=frame_buffer+y*(xres+1)+x; ulong *page=frame_buffer; uchar *sl=im->scan_line(y1)+x1; int skip=im->width()-(x2-x1+1); int frame_skip=(xres+1)-(x2-x1+1); for (y=y1;y<=y2;y++) { for (x=x1;x<=x2;x++) *(page++)=lookup24[*(sl++)]; sl+=skip; // page+=frame_skip; } refresh_frame_buffer(x,y,x+(x2-x1),y+(y2-y1)); } void put_image(image *im, int x, int y) { put_part(im,x,y,0,0,im->width()-1,im->height()-1); } void update_dirty(image *im, int xoff, int yoff) { int count; dirty_rect *dr,*q; CHECK(im->special); // make sure the image has the ablity to contain dirty areas if (im->special->keep_dirt==0) put_image(im,0,0); else { count=im->special->dirties.number_nodes(); if (!count) return; // if nothing to update, return (linked_node *) dr=im->special->dirties.first(); while (count>0) { put_part(im,dr->dx1+xoff,dr->dy1+yoff,dr->dx1,dr->dy1,dr->dx2,dr->dy2); q=dr; (linked_node *)dr=dr->next(); im->special->dirties.unlink((linked_node *)q); delete q; count--; } } }