ftp.nice.ch/Attic/openStep/developer/resources/Mesa3DFramework.s.tgz#/GL/MesaTK.subproj/fxevent.c

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.