Mercurial > hg > forks > pwpunix
view pwplib/X11.c @ 50:e2b6a35bcb0c
Remove usage of malloc.h; Other misc cleanups.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 24 May 2010 08:48:18 +0300 |
parents | c60e531d19cd |
children |
line wrap: on
line source
/*** HEADERS **********************************************/ #include "config.h" #ifdef DRIVE_X11 #include "pwplib.h" #include <string.h> #include <stdlib.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #ifdef DRIVE_X11SHM # include <sys/ipc.h> # include <sys/shm.h> # include <X11/extensions/XShm.h> #endif #define PWP_XWINNAME "pwplib" #define BUFFSIZE(w,h,d) ( (((d)+7)>>3) *(w)*(h)) /*** INTERNAL DRIVER DATA *********************************/ struct { u8*buf; int bufw,bufh,bufd,bpvl; Display *disp; Visual *vis; GC gc; int win,scr,rootw,dummyw; XImage *im; char*winname; Colormap cmap; XColor cols[256]; #ifdef DRIVE_X11SHM XShmSegmentInfo ssi; #endif struct{ int w,h; }savedmode; struct{ int useXShm; }opt; u32 lookup[256]; }pwp_X11; /*** SMALL API FUNX ****************************************/ void pwp_X11_setpalette(int*pal,int colorcount) { int*p=pal,i;XColor*c=pwp_X11.cols; for(i=colorcount;i;i--){ c->red=(*p++<<8); c->green=(*p++<<8); c->blue=(*p++<<8); c++; } XStoreColors(pwp_X11.disp,pwp_X11.cmap,pwp_X11.cols,colorcount); XSync(pwp_X11.disp,False); } void pwp_X11_blit() { if(!pwp_X11.opt.useXShm) { /**** if((pwp_X11.opt.interlaced)||(pwp_X11.opt.halvescans)) { int y1=(frame&1)<<pwp_X11.opt.halvescans,y=0, dy1=(1<<(pwp_X11.opt.interlaced+pwp_X11.opt.halvescans)); for(;y<oxl.buf.vh;y++){ XPutImage(pwp_X11.disp,pwp_X11.win,pwp_X11.gc,pwp_X11.im, 0,y,0,y1,pwp_X11.bufw,1); y1+=dy1; } frame+=pwp_X11.opt.interlaced; }else ****/ XPutImage(pwp_X11.disp,pwp_X11.win,pwp_X11.gc,pwp_X11.im, 0,0,0,0,pwp_X11.bufw,pwp_X11.bufh); } else XShmPutImage( pwp_X11.disp,pwp_X11.win,pwp_X11.gc,pwp_X11.im, 0,0,0,0,pwp_X11.bufw,pwp_X11.bufh,False); XSync(pwp_X11.disp,False); } int pwp_X11_testquit() { XEvent e; if((XCheckMaskEvent(pwp_X11.disp,KeyPressMask|KeyReleaseMask,&e)==True) ||(XEventsQueued(pwp_X11.disp,QueuedAlready)==True)) return 1;else return 0; } /*** WINDOW SETUP FUNX *************************************/ void pwp_X11_getcolormap() { int i=0; pwp_X11.cmap=XCreateColormap(pwp_X11.disp,pwp_X11.rootw,pwp_X11.vis,AllocAll); for(;i<256;i++){ pwp_X11.cols[i].flags=DoRed|DoGreen|DoBlue; pwp_X11.cols[i].pixel=i;pwp_X11.cols[i].pad=0; } } void pwp_X11_openwindow() { XSetWindowAttributes att; Pixmap empty;XColor black={0,0,0,0,0,0}; /* empty cursor */ empty=XCreatePixmap(pwp_X11.disp,pwp_X11.rootw,1,1,1); att.cursor= XCreatePixmapCursor(pwp_X11.disp,empty,empty,&black,&black,0,0); att.override_redirect=False; /* create window */ att.backing_store=NotUseful; att.colormap=pwp_X11.cmap; pwp_X11.win=XCreateWindow( pwp_X11.disp,pwp_X11.rootw, 0,0,pwp_X11.bufw,pwp_X11.bufh,0, pwp_X11.bufd, InputOutput, pwp_X11.vis, CWBackingStore|CWCursor|CWOverrideRedirect |((pwp_X11.bufd==8)?CWColormap:0) ,&att); /* some hints&props */ {XSizeHints shints; shints.min_width= shints.max_width= pwp_X11.bufw; shints.min_height=shints.max_height=pwp_X11.bufh; shints.flags=PMinSize+PMaxSize; XSetStandardProperties( pwp_X11.disp,pwp_X11.win, PWP_XWINNAME,PWP_XWINNAME, None,NULL,0, &shints); } /* and draw the window */ XMapWindow(pwp_X11.disp,pwp_X11.win); /* hook keypress */ XSelectInput(pwp_X11.disp,pwp_X11.win,KeyPress|KeyRelease); /* blank */ /* if(pwp_X11.opt.halvescans) { XFillRectangle(pwp_X11.disp,pwp_X11.win, pwp_X11.gc,0,0,pwp_X11.bufw,pwp_X11.bufh); } .. not yet*/ /* ok ok */ /* {XEvent e; XMaskEvent(pwp_X11.disp,KeyPressMask|KeyReleaseMask,&e);} */ XSync(pwp_X11.disp,False); } /*** DISPLAY SETUP FUNX **************************************/ int pwp_X11_testdepth(int depth) { Screen*s=ScreenOfDisplay(pwp_X11.disp,pwp_X11.scr); Depth*d=s->depths;int i=0; #ifdef DEBUG fprintf(stderr,"testing for depth %i\n",depth); #endif for(;i<s->ndepths;i++) if(d[i].depth==depth)return 1; return 0; } #ifdef DRIVE_X11SHM int pwp_X11_ready_XShm() { pwp_X11.im=XShmCreateImage( pwp_X11.disp,pwp_X11.vis,pwp_X11.bufd, ZPixmap, NULL,&pwp_X11.ssi, pwp_X11.bufw,pwp_X11.bufh ); if(pwp_X11.im==NULL)return 0; pwp_X11.bufh=pwp_X11.im->height; pwp_X11.bufw=pwp_X11.im->width; pwp_X11.bpvl=pwp_X11.im->bytes_per_line; pwp_X11.ssi.shmid=shmget(IPC_PRIVATE, pwp_X11.im->bytes_per_line*pwp_X11.im->height, IPC_CREAT|0777); if(pwp_X11.ssi.shmid<0){ XDestroyImage(pwp_X11.im);return 0;} pwp_X11.im->data=pwp_X11.buf=pwp_X11.ssi.shmaddr= shmat(pwp_X11.ssi.shmid,0,0); if(pwp_X11.ssi.shmaddr==(void*)-1){ XDestroyImage(pwp_X11.im);return 0;} pwp_X11.ssi.readOnly=False; /* XSetErrorHandler. Ei tänne */ XShmAttach(pwp_X11.disp,&pwp_X11.ssi); XSync(pwp_X11.disp,False); shmctl(pwp_X11.ssi.shmid,IPC_RMID,0); return 1; } #endif void pwp_X11_close() { #ifdef DRIVE_X11SHM if(pwp_X11.opt.useXShm){ XShmDetach(pwp_X11.disp,&pwp_X11.ssi); shmdt(pwp_X11.ssi.shmaddr);} #endif XDestroyImage(pwp_X11.im); XDestroyWindow(pwp_X11.disp,pwp_X11.win); } int pwp_X11_ready() { /* color depth */ if(!pwp_X11_testdepth(pwp_X11.bufd)) { if(pwp_X11_testdepth(8)) pwp_X11.bufd=8;else if(pwp_X11_testdepth(16))pwp_X11.bufd=16;else if(pwp_X11_testdepth(15))pwp_X11.bufd=15;else { pwpwrite("No suitable depth available (8/15/16 bpp)\n"); return 0; } } if(pwp_X11.bufd==8)pwp_X11_getcolormap(); pwp_X11_openwindow(); pwplib_regdestr(pwp_X11_close); /* shared memory buffer */ #ifdef DRIVE_X11SHM if(pwp_X11.opt.useXShm){ pwp_X11.opt.useXShm=XShmQueryExtension(pwp_X11.disp); /* tarkista myös versiosta pixmaps==true */ if(pwp_X11.opt.useXShm) if(pwp_X11_ready_XShm())return; else{ pwp_X11.opt.useXShm=0; fprintf(stderr,"no xshm\n");} } #endif /* noxshm */ fprintf(stderr, "X11_buf: %d x %d x %d, videobuf = %d x %d, malloc: %d\n", pwp_X11.bufw,pwp_X11.bufh,pwp_X11.bufd, pwplib.videobuf.width,pwplib.videobuf.height, BUFFSIZE(pwp_X11.bufw,pwp_X11.bufh,pwp_X11.bufd)); pwp_X11.buf=malloc(BUFFSIZE(pwp_X11.bufw,pwp_X11.bufh,pwp_X11.bufd)); pwp_X11.im=XCreateImage( pwp_X11.disp,pwp_X11.vis, pwp_X11.bufd,ZPixmap, 0,pwp_X11.buf, pwp_X11.bufw,pwp_X11.bufh, 32,BUFFSIZE(1,pwp_X11.bufw,pwp_X11.bufd)); pwp_X11.bpvl=pwp_X11.im->bytes_per_line; /* ? */ return 1; } /* pwp_X11.opt.useXShm=!findarg(argc,argv,"-noxshm"); pwp_X11.opt.fullscreen=findarg(argc,argv,"-full"); */ /**************************************************************************/ void pwp_X11_dump_rast_4x4() { u32*d = (u32*)pwp_X11.buf; int x,y,j=0; u8*ss=(u8*)pwplib.videobuf.d; for(y=pwplib.videobuf.height*2;y;y--) { u8*s=ss; for(x=pwplib.videobuf.width;x;x--) { *d++=pwp_X11.lookup[*s++]; } j=(j+1)&1; if(!j) { ss+=pwplib.videobuf.width; } } pwp_X11_blit(); } /**********/ void rast2rgb(int n,int muller,int*r,int*g,int*b) { int fg=n&15,bg=(n>>4)&15; const char rgb[16*3] = { 0,0,0, 0,0,9, 0,9,0, 0,9,9, 9,0,0, 9,0,9, 9,9,0, 9,9,9, 6,6,6, 0,0,15, 0,15,0, 0,15,15, 15,0,0, 15,0,15, 15,15,0, 15,15,15 }; *r = (muller * (rgb[bg*3+0]*2 + rgb[fg*3+0]))/45; *g = (muller * (rgb[bg*3+1]*2 + rgb[fg*3+1]))/45; *b = (muller * (rgb[bg*3+2]*2 + rgb[fg*3+2]))/45; } void pwp_X11_init_8bpp() { int pal[256*3]; int i=0; for(;i<256;i++) { rast2rgb(i,255,pal+i*3,pal+i*3+1,pal+i*3+2); pwp_X11.lookup[i]=(i|(i<<8)|(i<<16)|(i<<24)); } pwp_X11_setpalette(pal,256); pwplib.dump_rast = pwp_X11_dump_rast_4x4; } int pwp_X11_init() { if(!(pwp_X11.disp=XOpenDisplay(NULL))) { pwpwrite("* no X11 available - trying tty\n"); return 0; } pwp_X11.scr=DefaultScreen(pwp_X11.disp); pwp_X11.rootw=DefaultRootWindow(pwp_X11.disp); pwp_X11.gc=DefaultGC(pwp_X11.disp,pwp_X11.scr); pwp_X11.vis=DefaultVisual(pwp_X11.disp,pwp_X11.scr); /* pwp_X11.opt.halvescans = 0; pwp_X11.opt.interlace = 0; */ /****/ pwp_X11.bufw = 640; pwp_X11.bufh = 480; pwplib.videobuf.width = 640/4; pwplib.videobuf.height = 480/4; pwp_X11.opt.useXShm = 0; /****/ if(!pwp_X11_ready()) return 0; if(pwp_X11.bufd==8) pwp_X11_init_8bpp(); else { pwpwrite("* no 8bpp available\n"); return 0; } pwpwrite("* X11\n"); return 1; } #endif