This is fxevent.c in view mode; [Download] [Up]
/* event.c modified for 3Dfx driver */ #if defined(FX) #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #if defined(__WIN32__) #include <windows.h> #include <conio.h> #endif #include "gltk.h" #include "GL/fxmesa.h" /******************************************************************************/ void (*ExposeFunc)(int, int) = 0; void (*ReshapeFunc)(int, int) = 0; void (*DisplayFunc)(void) = 0; GLenum (*KeyDownFunc)(int, GLenum) = 0; GLenum (*MouseDownFunc)(int, int, GLenum) = 0; GLenum (*MouseUpFunc)(int, int, GLenum) = 0; GLenum (*MouseMoveFunc)(int, int, GLenum) = 0; void (*IdleFunc)(void) = 0; static int width,height; static int startx = 0,starty = 0; static fxMesaContext fc=NULL; static int WindowType = 0; /******************************************************************************/ #ifdef __linux__ #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <termios.h> #include <fcntl.h> GLenum tkSetWindowLevel(GLenum level) { return GL_TRUE; } void tkNewCursor(GLint id, GLubyte *shapeBuf, GLubyte *maskBuf, GLenum fgColor, GLenum bgColor, GLint hotX, GLint hotY) { } void tkSetCursor(GLint id) { } void tkGetMouseLoc (int *x, int *y) { *x = (int)0; *y = (int)0; } void tkGetSystem(TKenum type, void *ptr) { type = (TKenum)NULL; ptr = NULL; } void tkCloseWindow() {} void tkSetFogRamp(int density, int startIndex) {} #define NCOLORS 8 float tkRGBMap[NCOLORS][3] = { {0,0,0}, {1,0,0}, {0,1,0}, {1,1,0}, {0,0,1}, {1,0,1}, {0,1,1}, {1,1,1} }; static int sg_tty_fd = -1; int tty_open_nonblock (void) { struct termios term; sg_tty_fd = open ("/dev/tty", O_RDONLY, -1, -1); if (sg_tty_fd < 0) { printf ("error opening /dev/tty\n"); return (sg_tty_fd); } if (tcgetattr (sg_tty_fd, &term) == -1) perror ("tty_open_nonblock:tcgetattr"); /* * If the user wants signals to be valid so that things like suspend * and interrupt (^Z & ^C) work for terminal-connected lines, * we need to set the ISIG flag. We also want to post process * newlines in this case so they get mapped to CRNL */ term.c_lflag = ISIG; term.c_oflag = OPOST | ONLCR; term.c_iflag &= ~INPCK; term.c_cflag &= ~PARENB; term.c_iflag = 0; term.c_lflag &= ~ICANON; term.c_lflag &= ~ECHO; term.c_cc[VMIN] = 1; term.c_cc[VTIME] = 0; term.c_cflag |= CLOCAL | CS8 | CREAD; if (tcsetattr (sg_tty_fd, TCSADRAIN, &term) == -1) perror ("tty_open_nonblock:tcflush"); if (fcntl (sg_tty_fd, F_SETFL, O_NONBLOCK) == -1) perror ("tty_open_nonblock:fcntl"); if (tcflush (sg_tty_fd, TCIFLUSH) == -1) perror ("tty_open_nonblock:tcflush"); return 0; } int tty_read (int *charptr) { int rc; rc = read (sg_tty_fd, charptr, 1); return (rc); } #elif !defined(__WIN32__) /* DOS section */ int _tkkbhit(void ) { return(kbhit()); } int _tkgetch(void ) { return(getch()); } #else static HWND hWndMain = 0; static HANDLE hMainInstance = 0; static int fullscreen = GL_TRUE; static int qhead = 0; static int qtail = 0; static int queue[256] = {0}; static char *fakeName = "WinTkMesa3DfxApplication"; static char *argvbuf[32]; static char cmdLineBuffer[1024]; char **commandLineToArgv(LPSTR lpCmdLine,int *pArgc); /* * MainWndproc * * Callback for all Windows messages */ long FAR PASCAL MainWndproc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; switch(message) { case WM_SETCURSOR: if(!fullscreen) { SetCursor(NULL); return(0); } break; case WM_CREATE: break; case WM_PAINT: hdc = BeginPaint(hWnd,&ps); EndPaint(hWnd,&ps); return(1); case WM_CLOSE: tkQuit(); break; case WM_DESTROY: break; case WM_MOVE: if(!grSstControl(GR_CONTROL_MOVE)) { tkQuit(); return(0); } break; case WM_DISPLAYCHANGE: case WM_SIZE: { RECT rect; GetClientRect(hWndMain,&rect); if(ReshapeFunc) (*ReshapeFunc)(rect.right,rect.bottom); } if(!grSstControl(GR_CONTROL_RESIZE)) { tkQuit(); return(0); } break; case WM_ACTIVATE: { WORD fActive = LOWORD(wParam); BOOL fMinimized = (BOOL) HIWORD(wParam); if((fActive == WA_INACTIVE) || fMinimized) grSstControl(GR_CONTROL_DEACTIVATE); else grSstControl(GR_CONTROL_ACTIVATE); } break; case WM_KEYDOWN: switch (wParam) { case VK_LEFT: queue[qhead++] = 0; qhead &= 255; queue[qhead++] = 'K'; qhead &= 255; break; case VK_RIGHT: queue[qhead++] = 0; qhead &= 255; queue[qhead++] = 'M'; qhead &= 255; break; case VK_UP: queue[qhead++] = 0; qhead &= 255; queue[qhead++] = 'H'; qhead &= 255; break; case VK_DOWN: queue[qhead++] = 0; qhead &= 255; queue[qhead++] = 'P'; qhead &= 255; break; } break; case WM_CHAR: if(!isascii(wParam)) break; queue[qhead++] = wParam; qhead &= 255; break; default: break; } return(DefWindowProc(hWnd,message,wParam,lParam)); } /* MainWndproc */ /* * initApplication * * Do that Windows initialization stuff... */ static BOOL initApplication(HANDLE hInstance,int nCmdShow) { WNDCLASS wc; BOOL rc; wc.style = CS_DBLCLKS; wc.lpfnWndProc = MainWndproc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); /* generic icon */ wc.hCursor = LoadCursor(NULL,IDC_ARROW); wc.hbrBackground = GetStockObject(BLACK_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = "WinTkMesa3DfxClass"; rc = RegisterClass(&wc); if(!rc) return(FALSE); hMainInstance = hInstance; return(TRUE); } /* initApplication */ /* * WinMain */ int PASCAL WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow) { int argc; char **argv; extern int main(int argc,char **argv); if(!initApplication(hInstance,nCmdShow)) return(FALSE); argv = commandLineToArgv(lpCmdLine,&argc); main(argc,argv); if(hWndMain) { DestroyWindow(hWndMain); hWndMain = 0; } return(FALSE); } /* WinMain */ /* * Converts lpCmdLine to WinMain into argc, argv */ char **commandLineToArgv(LPSTR lpCmdLine,int *pArgc) { char *p,*pEnd; int argc = 0; argvbuf[argc++] = fakeName; if(lpCmdLine == NULL) { *pArgc = argc; return(argvbuf); } strcpy(cmdLineBuffer,lpCmdLine); p = cmdLineBuffer; pEnd = p + strlen(cmdLineBuffer); if(pEnd >= &cmdLineBuffer[1022]) pEnd = &cmdLineBuffer[1022]; while(1) { /* skip over white space */ while(*p == ' ') p++; if(p >= pEnd) break; argvbuf[argc++] = p; if(argc >= 32) break; /* skip till there's a 0 or a white space */ while(*p && (*p != ' ')) p++; if(*p == ' ') *p++ = 0; } *pArgc = argc; return(argvbuf); } int _tkkbhit(void) { MSG msg; if(qhead != qtail) return(1); while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); /* this might change qhead */ if(qhead != qtail) return(1); } return(0); } char _tkgetch(void) { MSG msg; char rv; if(qtail != qhead) { rv = queue[qtail++]; qtail &= 255; return(rv); } while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); if(qtail != qhead) { rv = queue[qtail++]; qtail &= 255; return(rv); } } /* Should never get here!! */ /* printf("Bad exit..\n"); */ /* fflush(stdout); */ } #endif void tkExec(void) { static int firsttime=1; int key; int ch; GLenum mask=0; #ifdef __linux__ if (firsttime) { if (ReshapeFunc) (*ReshapeFunc)(640,480); tty_open_nonblock (); firsttime = 0; ch = 0; } while (ch!=0x1b) { /* TODO: block on tty_read() if there's no idle loop! */ key = tty_read ( &ch ); if ( key >= 0 ) { ch &= 0xFF; #else if(ReshapeFunc && firsttime) { (*ReshapeFunc)(width,height); firsttime=0; ch=0; } while (ch!=27) { if(_tkkbhit()) { ch = _tkgetch(); if(KeyDownFunc) { #endif switch(ch) { case ' ': key = TK_SPACE; break; case '1': key = TK_1; break; case '2': key = TK_2; break; case '3': key = TK_3; break; case '4': key = TK_4; break; case '5': key = TK_5; break; case '6': key = TK_6; break; case '7': key = TK_7; break; case '8': key = TK_8; break; case '9': key = TK_9; break; case '0': key = TK_0; break; case 'a': key = TK_a; break; case 'b': key = TK_b; break; case 'c': key = TK_c; break; case 'd': key = TK_d; break; case 'e': key = TK_e; break; case 'f': key = TK_f; break; case 'g': key = TK_g; break; case 'h': key = TK_h; break; case 'i': key = TK_i; break; case 'j': key = TK_j; break; case 'k': key = TK_k; break; case 'l': key = TK_l; break; case 'm': key = TK_m; break; case 'n': key = TK_n; break; case 'o': key = TK_o; break; case 'p': key = TK_p; break; case 'q': key = TK_q; break; case 'r': key = TK_r; break; case 's': key = TK_s; break; case 't': key = TK_t; break; case 'u': key = TK_u; break; case 'v': key = TK_v; break; case 'w': key = TK_w; break; case 'x': key = TK_x; break; case 'y': key = TK_y; break; case 'z': key = TK_z; break; case 'A': key = TK_A; break; case 'B': key = TK_B; break; case 'C': key = TK_C; break; case 'D': key = TK_D; break; case 'E': key = TK_E; break; case 'F': key = TK_F; break; case 'G': key = TK_G; break; case 'H': key = TK_H; break; case 'I': key = TK_I; break; case 'J': key = TK_J; break; case 'K': key = TK_K; break; case 'L': key = TK_L; break; case 'M': key = TK_M; break; case 'N': key = TK_N; break; case 'O': key = TK_O; break; case 'P': key = TK_P; break; case 'Q': key = TK_Q; break; case 'R': key = TK_R; break; case 'S': key = TK_S; break; case 'T': key = TK_T; break; case 'U': key = TK_U; break; case 'V': key = TK_V; break; case 'W': key = TK_W; break; case 'X': key = TK_X; break; case 'Y': key = TK_Y; break; case 'Z': key = TK_Z; break; #ifdef __linux__ case 0x1b: key = tty_read ( &ch ); if (key < 0) { key = TK_ESCAPE; break; } key = tty_read ( &ch ); if (key < 0) break; ch &= 0xFF; switch ( ch ) { case 'A': key = TK_UP; break; case 'B': key = TK_DOWN; break; case 'C': key = TK_RIGHT; break; case 'D': key = TK_LEFT; break; } break; #else case 27: key = TK_ESCAPE; break; case 0: case 0xe0: ch = _tkgetch(); switch( ch ) { case 'P': key = TK_DOWN; break; case 'M': key = TK_RIGHT; break; case 'K': key = TK_LEFT; break; case 'H': key = TK_UP; break; } break; #endif /*default: printf("\n====%x %c %d\n",ch,ch,ch); break;*/ } (*KeyDownFunc)(key,mask); key = 0; } #ifndef __linux__ } #endif if (IdleFunc) (*IdleFunc)(); if(DisplayFunc) (*DisplayFunc)(); } } /******************************************************************************/ void tkExposeFunc(void (*Func)(int, int)) { ExposeFunc = Func; } /******************************************************************************/ void tkReshapeFunc(void (*Func)(int, int)) { ReshapeFunc = Func; } /******************************************************************************/ void tkDisplayFunc(void (*Func)(void)) { DisplayFunc = Func; } /******************************************************************************/ void tkKeyDownFunc(GLenum (*Func)(int, GLenum)) { KeyDownFunc = Func; } /******************************************************************************/ void tkMouseDownFunc(GLenum (*Func)(int, int, GLenum)) { MouseDownFunc = Func; } /******************************************************************************/ void tkMouseUpFunc(GLenum (*Func)(int, int, GLenum)) { MouseUpFunc = Func; } /******************************************************************************/ void tkMouseMoveFunc(GLenum (*Func)(int, int, GLenum)) { MouseMoveFunc = Func; } /******************************************************************************/ void tkIdleFunc(void (*Func)(void)) { IdleFunc = Func; } /******************************************************************************/ void tkInitDisplayMode(GLenum type) { #ifdef WIN32 if(!hMainInstance) initApplication(0,FALSE); #endif WindowType = type; } void tkInitPosition(int x, int y, int w, int h) { startx = x; starty = y; /* If grSstWinOpen is defined, then the possibility exists of * the 3Dfx-based card being a Voodoo Rush, and the resolution * need not be 640x480. Otherwise, if only grSstOpen exists, * we're probably using a prior version of Glide (like 2.2) * and we need to force width to 640 and height to 480. */ #if USE_GLIDE_FULLSCREEN width=640; height=480; #else width=w; height=h; #endif } void tkSwapBuffers(void) { fxMesaSwapBuffers(); } void tkQuit(void) { fxMesaDestroyContext(fc); #ifdef WIN32 if(hWndMain) DestroyWindow(hWndMain); hWndMain = 0; #endif exit(0); } GLenum tkInitWindow(char *title) { #define NUM_RES 3 static GrScreenResolution_t res[NUM_RES+1] = { GR_RESOLUTION_512x384, GR_RESOLUTION_640x480, GR_RESOLUTION_800x600, GR_RESOLUTION_NONE}; static int xres[NUM_RES]={512,640,800}; static int yres[NUM_RES]={384,480,600}; int i; GLuint window; GLint attribs[100]; /* Build fxMesa attribute list */ i = 0; if (TK_IS_DOUBLE(WindowType)) { attribs[i] = FXMESA_DOUBLEBUFFER; i++; } if (TK_HAS_DEPTH(WindowType)) { attribs[i] = FXMESA_DEPTH_SIZE; i++; attribs[i] = 1; i++; } if (TK_HAS_ALPHA(WindowType)) { attribs[i] = FXMESA_ALPHA_SIZE; i++; attribs[i] = 1; i++; } if (TK_HAS_ACCUM(WindowType)) { attribs[i] = FXMESA_ACCUM_SIZE; i++; attribs[i] = 1; i++; } if (TK_HAS_STENCIL(WindowType)) { attribs[i] = FXMESA_STENCIL_SIZE; i++; attribs[i] = 1; i++; } attribs[i] = FXMESA_NONE; /* end of list */ for(i=0;i<NUM_RES;i++) if((width==xres[i]) && (height==yres[i])) break; #ifdef __WIN32__ if(i == NUM_RES) fullscreen = GL_FALSE; hWndMain = CreateWindowEx(WS_EX_APPWINDOW,"WinTkMesa3DfxClass",title, WS_OVERLAPPED | WS_CAPTION | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_VISIBLE | /* so we don't have to call ShowWindow */ WS_POPUP | /* non-app window */ WS_SYSMENU, /* so we get an icon in the tray */ startx,starty, fullscreen ? 200 : width, fullscreen ? 200 : height, NULL,NULL,hMainInstance,NULL); if(!hWndMain) return(GL_FALSE); ShowWindow(hWndMain,SW_NORMAL); UpdateWindow(hWndMain); window = (GLuint)(fullscreen ? 0 : hWndMain); #else if(i == NUM_RES) return(GL_FALSE); window = 0; #endif fc = fxMesaCreateContext(window, res[i], GR_REFRESH_75Hz, attribs); if(!fc) return(GL_FALSE); fxMesaMakeCurrent(fc); return(GL_TRUE); } void tkSetOneColor(int index, float r, float g, float b) { } void tkSetGreyRamp(void) { } void tkSetRGBMap( int Size, float *Values ) { } GLint tkGetColorMapSize(void) { return 256; } #else void tk_dummy_func(void) { } #endif /*defined(FX)*/
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.