diff options
Diffstat (limited to 'window.c')
-rw-r--r-- | window.c | 906 |
1 files changed, 0 insertions, 906 deletions
diff --git a/window.c b/window.c deleted file mode 100644 index 85d9ffd..0000000 --- a/window.c +++ /dev/null @@ -1,906 +0,0 @@ -#include "3d.h" -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <X11/Xresource.h> -#include <X11/keysymdef.h> -#include <sys/types.h> -#include <sys/shm.h> -#include <X11/extensions/XShm.h> -#include <pthread.h> -#include <unistd.h> -#include <GL/gl.h> -#include <GL/glx.h> -typedef enum { - _3D_REND_X11_SHM, - _3D_REND_X11_OGL, -} _3DaysRenderer; -typedef struct CDrawWindow { - Window window; - Display *disp; - Atom clip3days; - Cursor empty_cursor; - //sz_x and sz_y are the window size - //disp_w/h is the 3Days screen size - int64_t sz_x,sz_y,disp_w,disp_h; - XShmSegmentInfo shm_info; - XImage *shm_image; - GC gc; - XVisualInfo *visual; - GLuint gl_texture; - double gl_left,gl_right; - double gl_top,gl_bottom; - int64_t scaling_enabled; - GLXContext context; - void *texture_address; - pthread_mutex_t pt; - int64_t reso_changed; - _3DaysRenderer renderer_type; -} CDrawWindow; -static void StartInputScanner(); -static CDrawWindow *dw=NULL; -static char *clip_text=NULL; -static void utf8_prop(Display *dpy, XEvent ev); -//See note in NewDrawWindow -static Atom wmclose; -int64_t __3DaysSwapRGB() { - if(dw) - if(dw->renderer_type==_3D_REND_X11_OGL) - return 1; - return 0; -} -static int64_t use_software_rend=0; -// -// Call before window is made -// -void __3DaysSetSoftwareRender(int64_t s) { - use_software_rend=s; -} -void __3DaysEnableScaling(int64_t s) { - //The software scaling is handled by HCRT.BIN - if(dw) - if(dw->renderer_type==_3D_REND_X11_OGL) - dw->scaling_enabled=s; -} -static const GLfloat texcoords[] = -{ - 0, 1, - 1, 1, - 1, 0, - 0, 0, - 0, 1, - 1, 1, - 1, 0, - 0, 0, -}; -CDrawWindow *NewDrawWindow() { - if(!dw) { - atexit(&DrawWindowDel); - XInitThreads(); - dw=TD_MALLOC(sizeof(*dw)); - dw->disp=XOpenDisplay(NULL); - long screen=DefaultScreen(dw->disp); - GLint glxAttribs[] = { - GLX_RGBA, - GLX_DOUBLEBUFFER, - GLX_DEPTH_SIZE, 24, - GLX_STENCIL_SIZE, 8, - GLX_RED_SIZE, 8, - GLX_GREEN_SIZE, 8, - GLX_BLUE_SIZE, 8, - GLX_SAMPLE_BUFFERS, 0, - GLX_SAMPLES, 0, - None - }; - if(use_software_rend) goto software; - dw->visual = glXChooseVisual(dw->disp, screen, glxAttribs); - XSetWindowAttributes windowAttribs; - if(dw->visual) { - dw->renderer_type=_3D_REND_X11_OGL; - windowAttribs.border_pixel = BlackPixel(dw->disp, screen); - windowAttribs.background_pixel = WhitePixel(dw->disp, screen); - windowAttribs.override_redirect = True; - windowAttribs.colormap = XCreateColormap(dw->disp, RootWindow(dw->disp, screen), dw->visual->visual, AllocNone); - windowAttribs.event_mask = ExposureMask; - dw->window = XCreateWindow(dw->disp, RootWindow(dw->disp,screen), 0, 0, 640, 480, 0, dw->visual->depth, InputOutput, dw->visual->visual, CWBackPixel | CWColormap | CWBorderPixel | CWEventMask, &windowAttribs); - XSelectInput(dw->disp,dw->window, - ExposureMask|KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask|ButtonMotionMask|Button3MotionMask|Button4MotionMask|Button5MotionMask|FocusChangeMask|StructureNotifyMask); - dw->context = glXCreateContext(dw->disp, dw->visual, NULL, GL_TRUE); - glXMakeCurrent(dw->disp, dw->window, dw->context); - // Show the window - XSetStandardProperties(dw->disp,dw->window,"3Days",NULL,None,NULL,0,NULL); - XClearWindow(dw->disp, dw->window); - XMapRaised(dw->disp, dw->window); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glGenTextures(1,&dw->gl_texture); - glBindTexture(GL_TEXTURE_2D,dw->gl_texture); - glClientActiveTexture(dw->gl_texture); - glTexCoordPointer(2, GL_FLOAT, 0, texcoords); - glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,640,480,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - } else { - software: - - windowAttribs.border_pixel = BlackPixel(dw->disp, screen); - windowAttribs.background_pixel = WhitePixel(dw->disp, screen); - windowAttribs.override_redirect = True; - windowAttribs.colormap = None; - windowAttribs.event_mask = ExposureMask; - dw->window = XCreateWindow(dw->disp, RootWindow(dw->disp,screen), 0, 0, 640, 480, 0, 24, InputOutput, XDefaultVisual(dw->disp,DefaultScreen(dw->disp)), CWBackPixel | CWColormap | CWBorderPixel | CWEventMask, &windowAttribs); - XSelectInput(dw->disp,dw->window, - ExposureMask|KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask|ButtonMotionMask|Button3MotionMask|Button4MotionMask|Button5MotionMask|FocusChangeMask|StructureNotifyMask); - XSetStandardProperties(dw->disp,dw->window,"3Days",NULL,None,NULL,0,NULL); - XClearWindow(dw->disp, dw->window); - XMapRaised(dw->disp, dw->window); - dw->gc=XCreateGC(dw->disp,dw->window,0,NULL); - dw->renderer_type=_3D_REND_X11_SHM; - dw->shm_image=XShmCreateImage(dw->disp,XDefaultVisual(dw->disp,screen),24,ZPixmap,0,&dw->shm_info,640,480); - dw->shm_info.shmid=shmget(IPC_PRIVATE,640*480*4,IPC_CREAT|0777); - dw->shm_info.readOnly=False; - dw->shm_info.shmaddr=dw->shm_image->data=shmat(dw->shm_info.shmid,0,0); - XShmAttach(dw->disp,&dw->shm_info); - XMapWindow(dw->disp,dw->window); - } - //Make a empty cursor - char data[]={0}; - XColor colors[]={0}; - Pixmap cpm=XCreateBitmapFromData(dw->disp,dw->window,data,1,1); - dw->empty_cursor=XCreatePixmapCursor(dw->disp,cpm,cpm,colors,colors,0,0); - XFreePixmap(dw->disp,cpm); - XDefineCursor(dw->disp,dw->window,dw->empty_cursor); - //https://stackoverflow.com/questions/10792361/how-do-i-gracefully-exit-an-x11-event-loop - //Here's the deal,I dont know why they made X11 like this. - //Send a prayer to the dude who awnsered this question. - wmclose=XInternAtom(dw->disp,"WM_DELETE_WINDOW",False); - XSetWMProtocols(dw->disp,dw->window,&wmclose,1); - dw->disp_h=480; - dw->disp_w=640; - dw->scaling_enabled=1; - pthread_mutex_init(&dw->pt,NULL); - } -} -void DrawWindowUpdate(CDrawWindow *win,int8_t *_colors,int64_t internal_width,int64_t h) { - sigset_t old_set,set; - if(0!=pthread_mutex_trylock(&dw->pt)) - goto ret; - sigemptyset(&set); - sigaddset(&set,SIGUSR2); - sigprocmask(SIG_BLOCK,&set,&old_set); - XLockDisplay(dw->disp); - if(dw->renderer_type==_3D_REND_X11_SHM) { - XShmPutImage(dw->disp,dw->window,dw->gc,dw->shm_image,0,0,0,0,dw->disp_w,dw->disp_h,True); - pthread_mutex_unlock(&dw->pt); - if(dw->reso_changed) { - if(map_get(&TOSLoader,"SetScaleResolution")) { - FFI_CALL_TOS_2(map_get(&TOSLoader,"SetScaleResolution")->data[0].val,dw->sz_x,dw->sz_y); - dw->reso_changed=0; - } - } - } else if(dw->renderer_type==_3D_REND_X11_OGL) { - XEvent e; - pthread_mutex_unlock(&dw->pt); - //I will OpenGL on the main thread - memset(&e,0,sizeof e); - e.type=Expose; - XSendEvent(dw->disp,dw->window,False,0,&e); - } - XFlush(dw->disp); - XUnlockDisplay(dw->disp); - sigprocmask(SIG_SETMASK,&old_set,NULL); - ret:; -} -void DrawWindowDel() { - if(dw) { - if(dw->renderer_type==_3D_REND_X11_SHM) { - XLockDisplay(dw->disp); - XShmDetach(dw->disp,&dw->shm_info); - XDestroyImage(dw->shm_image); - shmdt(dw->shm_info.shmaddr); - shmctl(dw->shm_info.shmid,IPC_RMID,NULL); - XFlush(dw->disp); - if(dw->gc) - XFreeGC(dw->disp,dw->gc); - XDestroyWindow(dw->disp,dw->window); - XCloseDisplay(dw->disp); - TD_FREE(dw); - dw=NULL; - } else { - XLockDisplay(dw->disp); - pthread_mutex_lock(&dw ->pt); - XFlush(dw->disp); - glXDestroyContext(dw->disp,dw->context); - XDestroyWindow(dw->disp,dw->window); - XCloseDisplay(dw->disp); - pthread_mutex_destroy(&dw->pt); - TD_FREE(dw); - dw=NULL; - } - } -} -#define CH_CTRLA 0x01 -#define CH_CTRLB 0x02 -#define CH_CTRLC 0x03 -#define CH_CTRLD 0x04 -#define CH_CTRLE 0x05 -#define CH_CTRLF 0x06 -#define CH_CTRLG 0x07 -#define CH_CTRLH 0x08 -#define CH_CTRLI 0x09 -#define CH_CTRLJ 0x0A -#define CH_CTRLK 0x0B -#define CH_CTRLL 0x0C -#define CH_CTRLM 0x0D -#define CH_CTRLN 0x0E -#define CH_CTRLO 0x0F -#define CH_CTRLP 0x10 -#define CH_CTRLQ 0x11 -#define CH_CTRLR 0x12 -#define CH_CTRLS 0x13 -#define CH_CTRLT 0x14 -#define CH_CTRLU 0x15 -#define CH_CTRLV 0x16 -#define CH_CTRLW 0x17 -#define CH_CTRLX 0x18 -#define CH_CTRLY 0x19 -#define CH_CTRLZ 0x1A -#define CH_CURSOR 0x05 -#define CH_BACKSPACE 0x08 -#define CH_ESC 0x1B -#define CH_SHIFT_ESC 0x1C -#define CH_SHIFT_SPACE 0x1F -#define CH_SPACE 0x20 - - -//Scan code flags -#define SCf_E0_PREFIX 7 -#define SCf_KEY_UP 8 -#define SCf_SHIFT 9 -#define SCf_CTRL 10 -#define SCf_ALT 11 -#define SCf_CAPS 12 -#define SCf_NUM 13 -#define SCf_SCROLL 14 -#define SCf_NEW_KEY 15 -#define SCf_MS_L_DOWN 16 -#define SCf_MS_R_DOWN 17 -#define SCf_DELETE 18 -#define SCf_INS 19 -#define SCf_NO_SHIFT 30 -#define SCf_KEY_DESC 31 -#define SCF_E0_PREFIX (1<<SCf_E0_PREFIX) -#define SCF_KEY_UP (1<<SCf_KEY_UP) -#define SCF_SHIFT (1<<SCf_SHIFT) -#define SCF_CTRL (1<<SCf_CTRL) -#define SCF_ALT (1<<SCf_ALT) -#define SCF_CAPS (1<<SCf_CAPS) -#define SCF_NUM (1<<SCf_NUM) -#define SCF_SCROLL (1<<SCf_SCROLL) -#define SCF_NEW_KEY (1<<SCf_NEW_KEY) -#define SCF_MS_L_DOWN (1<<SCf_MS_L_DOWN) -#define SCF_MS_R_DOWN (1<<SCf_MS_R_DOWN) -#define SCF_DELETE (1<<SCf_DELETE) -#define SCF_INS (1<<SCf_INS) -#define SCF_NO_SHIFT (1<<SCf_NO_SHIFT) -#define SCF_KEY_DESC (1<<SCf_KEY_DESC) - -//TempleOS places a 1 in bit 7 for -//keys with an E0 prefix. -//See \dLK,"::/Doc/CharOverview.DD"\d and \dLK,"KbdHndlr",A="MN:KbdHndlr"\d(). -#define SC_ESC 0x01 -#define SC_BACKSPACE 0x0E -#define SC_TAB 0x0F -#define SC_ENTER 0x1C -#define SC_SHIFT 0x2A -#define SC_CTRL 0x1D -#define SC_ALT 0x38 -#define SC_CAPS 0x3A -#define SC_NUM 0x45 -#define SC_SCROLL 0x46 -#define SC_CURSOR_UP 0x48 -#define SC_CURSOR_DOWN 0x50 -#define SC_CURSOR_LEFT 0x4B -#define SC_CURSOR_RIGHT 0x4D -#define SC_PAGE_UP 0x49 -#define SC_PAGE_DOWN 0x51 -#define SC_HOME 0x47 -#define SC_END 0x4F -#define SC_INS 0x52 -#define SC_DELETE 0x53 -#define SC_F1 0x3B -#define SC_F2 0x3C -#define SC_F3 0x3D -#define SC_F4 0x3E -#define SC_F5 0x3F -#define SC_F6 0x40 -#define SC_F7 0x41 -#define SC_F8 0x42 -#define SC_F9 0x43 -#define SC_F10 0x44 -#define SC_F11 0x57 -#define SC_F12 0x58 -#define SC_PAUSE 0x61 -#define SC_GUI 0xDB -#define SC_PRTSCRN1 0xAA -#define SC_PRTSCRN2 0xB7 - -#define IS_CAPS(x) (x&(KMOD_RSHIFT|KMOD_LSHIFT|KMOD_CAPS)) -//http://www.rohitab.com/discuss/topic/39438-keyboard-driver/ -static char keys[]={ - 0, CH_ESC, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', '\t', 'q', - 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', 0, 'a', 's', 'd', - 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', 'z', 'x', 'c', 'v', 'b', - 'n', 'm', ',', '.', '/', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, '5', 0, '+', 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; -static int64_t K2SC(char ch) { - int64_t i=0; - for(;i!=sizeof(keys)/sizeof(*keys);i++) { - if(keys[i]==ch) return i; - } -} -static int64_t persist_mod=0; -static int32_t __ScanKey(int64_t *ch,int64_t *sc,XEvent *_e) { - XEvent e=*_e; - #define PERSIST_KEY(flag) \ - if(e.type==KeyRelease) { \ - persist_mod&=~(flag); \ - mod&=~(flag); \ - } else \ - mod|=(persist_mod|=(flag)); - int64_t mod=persist_mod,cond,dummy; - static int64_t prev_key_press=-1; - if(!ch) ch=&dummy; - if(!sc) sc=&dummy; - cond=1; - if(cond) { - if(e.type==KeyPress) { - if(prev_key_press==XLookupKeysym(&e,0)) - return -1; - prev_key_press=XLookupKeysym(&e,0); - ent: - *ch=*sc=0; - if(e.xkey.state&ShiftMask) - mod|=SCF_SHIFT; - else - mod|=SCF_NO_SHIFT; - if(e.xkey.state&(ControlMask)) - mod|=SCF_CTRL; - /*if(e.key.keysym.mod&(KMOD_CAPS)) - mod|=SCF_CAPS; - if(e.key.keysym.mod&(KMOD_NUM)) - mod|=SCF_NUM;*/ - /*if(e.key.keysym.mod&KMOD_LGUI) - mod|=SCF_MS_L_DOWN; - if(e.key.keysym.mod&KMOD_RGUI) - mod|=SCF_MS_R_DOWN;*/ - *sc=XLookupKeysym(&e,0); - switch(*sc) { - case XK_space: - return *sc=K2SC(' ')|mod; - case XK_apostrophe: - return *sc=K2SC('\'')|mod; - case XK_comma: - return *sc=K2SC(',')|mod; - case XK_minus: - return *sc=K2SC('-')|mod; - case XK_period: - return *sc=K2SC('.')|mod; - case XK_grave: - return *sc=K2SC('`')|mod; - case XK_slash: - return *sc=K2SC('/')|mod; - case XK_0: - return *sc=K2SC('0')|mod; - case XK_1: - return *sc=K2SC('1')|mod; - case XK_2: - return *sc=K2SC('2')|mod; - case XK_3: - return *sc=K2SC('3')|mod; - case XK_4: - return *sc=K2SC('4')|mod; - case XK_5: - return *sc=K2SC('5')|mod; - case XK_6: - return *sc=K2SC('6')|mod; - case XK_7: - return *sc=K2SC('7')|mod; - case XK_8: - return *sc=K2SC('8')|mod; - case XK_9: - return *sc=K2SC('9')|mod; - case XK_semicolon: - return *sc=K2SC(';')|mod; - case XK_equal: - return *sc=K2SC('=')|mod; - case XK_bracketleft: - return *sc=K2SC('[')|mod; - case XK_bracketright: - return *sc=K2SC(']')|mod; - case XK_backslash: - return *sc=K2SC('\\')|mod; - case XK_q: - return *sc=K2SC('q')|mod; - case XK_w: - return *sc=K2SC('w')|mod; - case XK_e: - return *sc=K2SC('e')|mod; - case XK_r: - return *sc=K2SC('r')|mod; - case XK_t: - return *sc=K2SC('t')|mod; - case XK_y: - return *sc=K2SC('y')|mod; - case XK_u: - return *sc=K2SC('u')|mod; - case XK_i: - return *sc=K2SC('i')|mod; - case XK_o: - return *sc=K2SC('o')|mod; - case XK_p: - return *sc=K2SC('p')|mod; - case XK_a: - return *sc=K2SC('a')|mod; - case XK_s: - return *sc=K2SC('s')|mod; - case XK_d: - return *sc=K2SC('d')|mod; - case XK_f: - return *sc=K2SC('f')|mod; - case XK_g: - return *sc=K2SC('g')|mod; - case XK_h: - return *sc=K2SC('h')|mod; - case XK_j: - return *sc=K2SC('j')|mod; - case XK_k: - return *sc=K2SC('k')|mod; - case XK_l: - return *sc=K2SC('l')|mod; - case XK_z: - return *sc=K2SC('z')|mod; - case XK_x: - return *sc=K2SC('x')|mod; - case XK_c: - return *sc=K2SC('c')|mod; - case XK_v: - return *sc=K2SC('v')|mod; - case XK_b: - return *sc=K2SC('b')|mod; - case XK_n: - return *sc=K2SC('n')|mod; - case XK_m: - return *sc=K2SC('m')|mod; - case XK_Escape: - *sc=mod|SC_ESC; - return 1; - case XK_BackSpace: - *sc=mod|SC_BACKSPACE; - return 1; - case XK_Tab: - *sc=mod|SC_TAB; - return 1; - case XK_Return: - *sc=mod|SC_ENTER; - return 1; - case XK_Shift_L: - case XK_Shift_R: - PERSIST_KEY(SCF_SHIFT); - *sc=mod|SC_SHIFT; - return 1; - case XK_Alt_L: - case XK_Alt_R: - PERSIST_KEY(SCF_ALT); - *sc=mod|SC_ALT; - return 1; - case XK_Control_L: - case XK_Control_R: - PERSIST_KEY(SCF_CTRL); - *sc=mod|SC_CTRL; - return 1; - case XK_Caps_Lock: - PERSIST_KEY(SCF_CAPS); - *sc=mod|SC_CAPS; - return 1; - /* - case SDL_SCANCODE_NUMLOCKCLEAR: - *sc=mod|SC_NUM; - return 1; - */ - case XK_Scroll_Lock: - *sc=mod|SC_SCROLL; - return 1; - case XK_Down: - *sc=mod|SC_CURSOR_DOWN; - return 1; - case XK_Up: - *sc=mod|SC_CURSOR_UP; - return 1; - case XK_Right: - *sc=mod|SC_CURSOR_RIGHT; - return 1; - case XK_Left: - *sc=mod|SC_CURSOR_LEFT; - return 1; - case XK_Page_Down: - *sc=mod|SC_PAGE_DOWN; - return 1; - case XK_Page_Up: - *sc=mod|SC_PAGE_UP; - return 1; - case XK_Home: - *sc=mod|SC_HOME; - return 1; - case XK_End: - *sc=mod|SC_END; - return 1; - case XK_Insert: - *sc=mod|SC_INS; - return 1; - case XK_Delete: - *sc=mod|SC_DELETE; - return 1; - case XK_Super_L: - case XK_Super_R: - *sc=mod|SC_GUI; - return 1; - case XK_Pause: - *sc=mod|SC_PAUSE; - return 1; - case XK_F1...XK_F12: - *sc=mod|(SC_F1+*sc-XK_F1); - return 1; - } - } else if(e.type==KeyRelease) { - prev_key_press=0; - mod|=SCF_KEY_UP; - goto ent; - } - } - return -1; -} -static void (*kb_cb)(); -static void *kb_cb_data; -static int KBCallback(void *d,XEvent *e) { - int64_t c,s; - if(kb_cb&&(-1!=__ScanKey(&c,&s,e))) - FFI_CALL_TOS_2(kb_cb,c,s); - return 0; -} -void SetKBCallback(void *fptr,void *data) { - kb_cb=fptr; - kb_cb_data=data; -} -//x,y,z,(l<<1)|r -static void(*ms_cb)(); -static int MSCallback(void *d,XEvent *e) { - static int64_t x,y,cx,cy; - static int state; - static int z; - if(ms_cb) - switch(e->type) { - case ButtonPress: - x=e->xbutton.x,y=e->xbutton.y; - if(e->xbutton.button==1) - state|=2; - else if(e->xbutton.button==4) - z--; - else if(e->xbutton.button==5) - z++; - else if(e->xbutton.button==3) - state|=1; - goto ent; - case ButtonRelease: - x=e->xbutton.x,y=e->xbutton.y; - if(e->xbutton.button==1) - state&=~2; - else if(e->xbutton.button==3) - state&=~1; - goto ent; - case MotionNotify: - x=e->xmotion.x,y=e->xmotion.y; - ent: - if(dw->renderer_type==_3D_REND_X11_OGL) { - //X11 corantes go from top to bottom - int64_t y2=dw->sz_y-y,x2=x; - //We need to scale out coordnates to the "screen rectangle" - //OpenGL cordnates go from (-1.0,-1.0) to (1.0,1.0) - //Our silly sauce rectangle doesn't take up the whole screen, - //We use (dw->gl_left,dw->gl_bottom),(dw->gl_right,dw->gl_top) - double xd=x2/(double)dw->sz_x*2. -1.; //Make it go from -1 to 1 - double yd=y2/(double)dw->sz_y*2. -1.; //Ditto - if(xd<dw->gl_left) - xd=dw->gl_left; - if(xd>dw->gl_right) - xd=dw->gl_right; - if(yd<dw->gl_top) - yd=dw->gl_top; - if(yd>dw->gl_bottom) - yd=dw->gl_bottom; - yd=(yd-dw->gl_bottom)/(dw->gl_top-dw->gl_bottom); - xd=(xd-dw->gl_left)/(dw->gl_right-dw->gl_left); - y2=480*yd; - x2=640*xd; - FFI_CALL_TOS_4(ms_cb,x2,y2,z,state); - } else - FFI_CALL_TOS_4(ms_cb,x,y,z,state); - } - return 0; -} - -void SetMSCallback(void *fptr) { - ms_cb=fptr; -} -static void utf8_send(char *text,XEvent ev) { - Display *dpy=dw->disp; - XSelectionEvent ssev; - XLockDisplay(dpy); - Atom utf8 = XInternAtom(dpy, "UTF8_STRING", False); - Atom targets=XInternAtom(dw->disp, "TARGETS", False); - Atom atom=XInternAtom(dw->disp, "ATOM", False); - XSelectionRequestEvent *sev; - loop:; - sev=&ev.xselectionrequest; - if(sev->target==targets) { - XChangeProperty( - dpy, - sev->requestor, - sev->property, - atom, - 32, //expects 8/16/32 bits - PropModeReplace, - &utf8, - 1 - ); - goto set; - } else if(sev->target!=utf8||sev->property==None) { - //Oh no - ssev.type=SelectionNotify; - ssev.requestor=sev->requestor; - ssev.selection=sev->selection; - ssev.target=sev->target; - ssev.property=None; - ssev.time=CurrentTime; - XSendEvent(dpy, sev->requestor, True, NoEventMask, (XEvent *)&ssev); - goto end; - } - if(!text) - text=""; - XChangeProperty(dpy, sev->requestor, sev->property, utf8, 8, PropModeReplace, - (unsigned char *)text, strlen(text)); - set: - ssev.type = SelectionNotify; - ssev.requestor = sev->requestor; - ssev.selection = sev->selection; - ssev.target = sev->target; - ssev.property = sev->property; - ssev.time = sev->time; - XSendEvent(dpy, sev->requestor, True, NoEventMask, (XEvent *)&ssev); - end: - XUnlockDisplay(dpy); -} -void SetClipboard(char *text) { - TD_FREE(clip_text); - XLockDisplay(dw->disp); - Atom sel = XInternAtom(dw->disp, "CLIPBOARD", False); - XSetSelectionOwner(dw->disp, sel, dw->window, CurrentTime); - XUnlockDisplay(dw->disp); - clip_text=strdup(text); -} -static void __InputLoop(void *ul,int64_t clip_only) { - XEvent e; - XSelectionEvent *sev; - for(;!*(int64_t*)ul;) { - XNextEvent(dw->disp,&e); - if(e.type==Expose&&dw->renderer_type==_3D_REND_X11_OGL) { - pthread_mutex_lock(&dw->pt); - XWindowAttributes attribs; - XGetWindowAttributes(dw->disp, dw->window, &attribs); - glViewport(0, 0, attribs.width, attribs.height); - glClear(GL_COLOR_BUFFER_BIT); - char *_colors=dw->texture_address; - double sx,sy,ox,oy; - if(dw->scaling_enabled) { - sx=dw->sz_y/480.*640.,sy=dw->sz_y; - if(dw->sz_x<sx) { - sy=dw->sz_x/640.*480.; - sx=dw->sz_x; - } - ox=(dw->sz_x-sx); - oy=(dw->sz_y-sy); - sx=1.-ox/dw->sz_x; - sy=1.-oy/dw->sz_y; - } else { - sx=640./dw->sz_x,sy=480./dw->sz_y; - } - dw->gl_left=-sx; - dw->gl_right=sx; - dw->gl_top=-sy; - dw->gl_bottom=sy; - GLfloat verts[]={ - dw->gl_left,dw->gl_top, - dw->gl_right,dw->gl_top, - dw->gl_right,dw->gl_bottom, - dw->gl_left,dw->gl_bottom - }; - glClear(GL_COLOR_BUFFER_BIT); - glColor4f(0,0,0,0); - glEnable(GL_VERTEX_ARRAY); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D,dw->gl_texture); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD); - glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,640,480,0,GL_RGBA,GL_UNSIGNED_BYTE,_colors); - char triangles[]={ - 0,1,2,0,3,2 - }; - glVertexPointer(2,GL_FLOAT,0,verts); - glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_BYTE,triangles); - glFinish(); - glXSwapBuffers(dw->disp,dw->window); - pthread_mutex_unlock(&dw->pt); - } else if(e.type==ClientMessage) { - if(e.xclient.data.l[0]==wmclose) { - bye: - __ShutdownCores(); - DrawWindowDel(); - exit(0); - } - } else if(e.type==DestroyNotify){ - goto bye; - } else if(e.type==ConfigureNotify&&dw) { - if(dw->sz_x!=e.xconfigure.width||dw->sz_y!=e.xconfigure.height) - dw->reso_changed=1; - dw->sz_x=e.xconfigure.width; - dw->sz_y=e.xconfigure.height; - } else if(e.type==SelectionRequest) { - utf8_send(clip_text,e); - } else if(e.type==SelectionNotify) - utf8_prop(dw->disp,e); - else if(e.type==FocusOut) { - if((persist_mod|SCF_ALT)&&kb_cb) - FFI_CALL_TOS_2(kb_cb,0,SC_ALT|SCF_ALT|SCF_KEY_UP|SCF_NO_SHIFT); - if((persist_mod|SCF_CTRL)&&kb_cb) - FFI_CALL_TOS_2(kb_cb,0,SC_CTRL|SCF_CTRL|SCF_KEY_UP|SCF_NO_SHIFT); - if((persist_mod|SCF_SHIFT)&&kb_cb) - FFI_CALL_TOS_2(kb_cb,0,SC_SHIFT|SCF_SHIFT|SCF_KEY_UP); - if((persist_mod|SCF_CAPS)&&kb_cb) - FFI_CALL_TOS_2(kb_cb,0,SC_CAPS|SCF_NO_SHIFT|SCF_KEY_UP); - persist_mod&=~(SCF_CAPS|SCF_SHIFT|SCF_CTRL|SCF_ALT); - continue; - } - if(kb_cb) - KBCallback(kb_cb_data,&e); - if(ms_cb) - MSCallback(NULL,&e); - } -} -char *ClipboardText() { - XLockDisplay(dw->disp); - char *ret; - Atom sel = XInternAtom(dw->disp, "CLIPBOARD", False); - Window owner = XGetSelectionOwner(dw->disp, sel); - XEvent ev; - if(owner==dw->window) { - ret=strdup(clip_text); - XUnlockDisplay(dw->disp); - return ret; - } - Atom utf8=XInternAtom(dw->disp, "UTF8_STRING", False); - Atom target=XInternAtom(dw->disp, "3DaysCLIP", False); - XConvertSelection(dw->disp, sel, utf8, target, dw->window, - CurrentTime); - TD_FREE(clip_text); - clip_text=NULL; - for(;;) { - XNextEvent(dw->disp,&ev); - if(ev.type==SelectionNotify) { - utf8_prop(dw->disp,ev); - break; - } - } - XUnlockDisplay(dw->disp); - if(!clip_text) - clip_text=strdup(""); - return strdup(clip_text); -} -void InputLoop(void *ul) { - __InputLoop(ul,0); -} -//https://www.google.com/search?q=xlib+clipboard&client=firefox-b-1-e&sxsrf=ALiCzsb9A6kPI8rhFAVztJKwMeVH6WiTJQ%3A1655908750653&ei=jimzYuS0J_6fptQP6pStoAs&ved=0ahUKEwjks_PmpMH4AhX-j4kEHWpKC7QQ4dUDCA0&uact=5&oq=xlib+clipboard&gs_lcp=Cgdnd3Mtd2l6EAMyBggAEB4QFjIGCAAQHhAWMgUIABCGAzIFCAAQhgMyBQgAEIYDMgUIABCGAzoHCAAQRxCwAzoHCAAQsAMQQzoKCAAQ5AIQsAMYAToSCC4QxwEQowIQyAMQsAMQQxgCOgwILhDIAxCwAxBDGAI6BAgjECc6BAgAEEM6CwgAEIAEELEDEIMBOgUIABCABDoICAAQgAQQsQM6CwguEIAEEMcBENEDOgoIABCABBCHAhAUSgQIQRgASgQIRhgBULkCWKMXYIkaaAFwAXgAgAGYA4gB1B2SAQcyLTQuNy4xmAEAoAEByAERwAEB2gEGCAEQARgJ2gEGCAIQARgI&sclient=gws-wiz -static void -utf8_prop(Display *dpy, XEvent ev) -{ - Window w=dw->window; - XLockDisplay(dpy); - Atom sel = XInternAtom(dw->disp, "CLIPBOARD", False); - Atom utf8 = XInternAtom(dw->disp, "UTF8_STRING", False); - Atom target=XInternAtom(dw->disp, "3DaysCLIP", False); - Atom da, incr, type; - int di; - unsigned long size, dul; - unsigned char *prop_ret = NULL; - XGetWindowProperty(dpy, w, target, 0, 0, False, AnyPropertyType, - &type, &di, &dul, &size, &prop_ret); - XFree(prop_ret); - XGetWindowProperty(dpy, w, target, 0, size, False, AnyPropertyType, - &da, &di, &dul, &dul, &prop_ret); - TD_FREE(clip_text); - if(!size) - clip_text=strdup(""); - else - clip_text=strdup(prop_ret); - XFree(prop_ret); - XDeleteProperty(dpy, w, target); - XUnlockDisplay(dpy); -} -//Expected HCRT.BIN to be loaded -void *_3DaysSetResolution(int64_t w,int64_t h) { - if(!dw) return NULL; - if(dw->renderer_type==_3D_REND_X11_SHM) { - XEvent e; - XLockDisplay(dw->disp); - pthread_mutex_lock(&dw->pt); - dw->disp_h=h; - dw->disp_w=w; - XShmDetach(dw->disp,&dw->shm_info); - XDestroyImage(dw->shm_image); - shmdt(dw->shm_info.shmaddr); - shmctl(dw->shm_info.shmid,IPC_RMID,NULL); - memset(&dw->shm_info,0,sizeof(dw->shm_info)); - dw->shm_info.shmid=shmget(IPC_PRIVATE,w*h*4,IPC_CREAT|0777); - dw->shm_info.readOnly=False; - dw->shm_info.shmaddr=shmat(dw->shm_info.shmid,0,0); - XShmAttach(dw->disp,&dw->shm_info); - dw->shm_image=XShmCreateImage(dw->disp,XDefaultVisual(dw->disp,DefaultScreen(dw->disp)),24,ZPixmap,0,&dw->shm_info,w,h); - dw->shm_image->data=dw->shm_info.shmaddr; - //Wait for event to sync with server to avoid nasty stuff(push a dummy event for XSync to not hang for a next event) - memset(&e,0,sizeof e); - e.type=Expose; - XSendEvent(dw->disp,dw->window,False,0,&e); - XSync(dw->disp,False); - pthread_mutex_unlock(&dw->pt); - XUnlockDisplay(dw->disp); - return dw->shm_info.shmaddr; - } else if(dw->renderer_type==_3D_REND_X11_OGL) { - pthread_mutex_lock(&dw->pt); - if(dw->texture_address) - free(dw->texture_address); - dw->texture_address=calloc(w*h,4); - pthread_mutex_unlock(&dw->pt); - return dw->texture_address; - } -} -static void LaunchScaler(void *c) { - void *fp=map_get(&TOSLoader,"ScalerMP")->data[0].val; - FFI_CALL_TOS_1(fp,c); - pthread_exit(0); -} -int64_t __3DaysVGAMode() { - return 0; -} -void _3DaysSetVGAColor(int64_t i,uint32_t color) { -} -void _3DaysScaleScrn(){ - sigset_t set,old_set; - static int64_t mp_cnt; - sigemptyset(&set); - sigaddset(&set,SIGUSR2); - sigprocmask(SIG_BLOCK,&set,&old_set); - pthread_mutex_lock(&dw->pt); - //See T/GR/Scale - if(!mp_cnt) { - mp_cnt=sysconf(_SC_NPROCESSORS_ONLN); - } - pthread_t scalers[mp_cnt]; - int64_t i; - for(i=0;i!=mp_cnt;i++) - pthread_create(&scalers[i],NULL,&LaunchScaler,i); - for(i=0;i!=mp_cnt;i++) - pthread_join(scalers[i],NULL); - pthread_mutex_unlock(&dw->pt); - sigprocmask(SIG_SETMASK,&old_set,NULL); -} |