Acme-MITHALDU-BleedingOpenGL

 view release on metacpan or  search on metacpan

pogl_glut.xs  view on Meta::CPAN

/*  Last saved: Tue 02 Apr 2013 02:45:10 PM */

/*  Copyright (c) 1998 Kenneth Albanowski. All rights reserved.
 *  Copyright (c) 2007 Bob Free. All rights reserved.
 *  Copyright (c) 2009 Chris Marshall. All rights reserved.
 *  Copyright (c) 2015 Bob Free. All rights reserved.
 *  This program is free software; you can redistribute it and/or
 *  modify it under the same terms as Perl itself.
 */

#include <stdio.h>

#include "pgopogl.h"


/* glut_util.h is where you include the appropriate GLUT header
 * file based on what is available.  It also defines some constants
 * that may not be defined everywhere.  Replace this by user
 * specified include information for the include and compile-time
 * perl constants rather than some special cases
 */
#include "glut_util.h"


/* TODO: calculate this from the actual GLUT include file */
#ifndef GLUT_API_VERSION
#define GLUT_API_VERSION 4
#endif

static int _done_glutInit = 0;
static int _done_glutCloseFunc_warn = 0;


/* Macros for GLUT callback and handler declarations */
#  define DO_perl_call_sv(handler, flag) perl_call_sv(handler, flag)
#  define ENSURE_callback_thread
#  define GLUT_PUSH_NEW_SV(sv)		XPUSHs(sv_2mortal(newSVsv(sv)))
#  define GLUT_PUSH_NEW_IV(i)		XPUSHs(sv_2mortal(newSViv(i)))
#  define GLUT_PUSH_NEW_U8(c)		XPUSHs(sv_2mortal(newSViv((int)c)))
#  define GLUT_EXTEND_STACK(sp,n)
#  define GLUT_PUSHMARK(sp)		PUSHMARK(sp)


/* Set up for all the GLUT callback handlers */
static AV * glut_handlers = 0;

/* Attach a handler to a window */
static void set_glut_win_handler(int win, int type, SV * data)
{
	SV ** h;
	AV * a;
	
	if (!glut_handlers)
		glut_handlers = newAV();
	
	h = av_fetch(glut_handlers, win, FALSE);
	
	if (!h) {
		a = newAV();
		av_store(glut_handlers, win, newRV_inc((SV*)a));
		SvREFCNT_dec(a);
	} else if (!SvOK(*h) || !SvROK(*h))
		croak("Unable to establish glut handler");
	else 
		a = (AV*)SvRV(*h);
	
	av_store(a, type, newRV_inc(data));
	SvREFCNT_dec(data);
}

/* Get a window's handler */
static SV * get_glut_win_handler(int win, int type)
{
	SV ** h;
	
	if (!glut_handlers)
		croak("Unable to locate glut handler");
	
	h = av_fetch(glut_handlers, win, FALSE);

	if (!h || !SvOK(*h) || !SvROK(*h))
		croak("Unable to locate glut handler");
	
	h = av_fetch((AV*)SvRV(*h), type, FALSE);
	
	if (!h || !SvOK(*h) || !SvROK(*h))
		croak("Unable to locate glut handler");

	return SvRV(*h);
}

/* Release a window's handlers */
static void destroy_glut_win_handlers(int win)
{
	SV ** h;
	

pogl_glut.xs  view on Meta::CPAN

/* Release a handler */
static void destroy_glut_win_handler(int win, int type)
{
	SV ** h;
	AV * a;
	
	if (!glut_handlers)
		glut_handlers = newAV();
	
	h = av_fetch(glut_handlers, win, FALSE);
	
	if (!h || !SvOK(*h) || !SvROK(*h))
		return;

	a = (AV*)SvRV(*h);
	
	av_store(a, type, newSVsv(&PL_sv_undef));
}

/* Begin window callback definition */
#define begin_decl_gwh(type, params, nparam)				\
									\
static void generic_glut_ ## type ## _handler params			\
{									\
	int win = glutGetWindow();					\
	AV * handler_data = (AV*)get_glut_win_handler(win, HANDLE_GLUT_ ## type);\
	SV * handler;							\
	int i;								\
	dSP;								\
									\
	handler = *av_fetch(handler_data, 0, 0);			\
									\
	GLUT_PUSHMARK(sp);						\
	GLUT_EXTEND_STACK(sp,av_len(handler_data)+nparam);		\
	for (i=1;i<=av_len(handler_data);i++)				\
		GLUT_PUSH_NEW_SV(*av_fetch(handler_data, i, 0));

/* End window callback definition */
#define end_decl_gwh()							\
	PUTBACK;							\
	DO_perl_call_sv(handler, G_DISCARD);				\
}

/* Activate a window callback handler */
#define decl_gwh_xs(type)						\
	{								\
		int win = glutGetWindow();				\
									\
		if (!handler || !SvOK(handler)) {			\
			destroy_glut_win_handler(win, HANDLE_GLUT_ ## type);\
			glut ## type ## Func(NULL);			\
		} else {						\
			AV * handler_data = newAV();			\
									\
			PackCallbackST(handler_data, 0);		\
									\
			set_glut_win_handler(win, HANDLE_GLUT_ ## type, (SV*)handler_data);\
									\
			glut ## type ## Func(generic_glut_ ## type ## _handler);\
		}							\
	ENSURE_callback_thread;}

/* Activate a window callback handler; die on failure */
#define decl_gwh_xs_nullfail(type, fail)				\
	{								\
		int win = glutGetWindow();				\
									\
		if (!handler || !SvOK(handler)) {			\
			croak fail;					\
		} else {						\
			AV * handler_data = newAV();			\
									\
			PackCallbackST(handler_data, 0);		\
									\
			set_glut_win_handler(win, HANDLE_GLUT_ ## type, (SV*)handler_data);\
									\
			glut ## type ## Func(generic_glut_ ## type ## _handler);\
		}							\
	ENSURE_callback_thread;}


/* Activate a global state callback handler */
#define decl_ggh_xs(type)						\
	{								\
		if (glut_ ## type ## _handler_data)			\
			SvREFCNT_dec(glut_ ## type ## _handler_data);	\
									\
		if (!handler || !SvOK(handler)) {			\
			glut_ ## type ## _handler_data = 0;		\
			glut ## type ## Func(NULL);			\
		} else {						\
			AV * handler_data = newAV();			\
									\
			PackCallbackST(handler_data, 0);		\
									\
			glut_ ## type ## _handler_data = handler_data;	\
									\
			glut ## type ## Func(generic_glut_ ## type ## _handler);\
		}							\
	ENSURE_callback_thread;}


/* Begin a global state callback definition */
#define begin_decl_ggh(type, params, nparam)				\
									\
static AV * glut_ ## type ## _handler_data = 0;				\
									\
static void generic_glut_ ## type ## _handler params			\
{									\
	AV * handler_data = glut_ ## type ## _handler_data;		\
	SV * handler;							\
	int i;								\
	dSP;								\
									\
	handler = *av_fetch(handler_data, 0, 0);			\
									\
	GLUT_PUSHMARK(sp);						\
	GLUT_EXTEND_STACK(sp,av_len(handler_data)+nparam);		\
	for (i=1;i<=av_len(handler_data);i++)				\
		GLUT_PUSH_NEW_SV(*av_fetch(handler_data, i, 0));

/* End a global state callback definition */
#define end_decl_ggh()							\
	PUTBACK;							\
	DO_perl_call_sv(handler, G_DISCARD);				\
}

/* Define callbacks */
enum {
	HANDLE_GLUT_Display,
	HANDLE_GLUT_OverlayDisplay,
	HANDLE_GLUT_Reshape,
	HANDLE_GLUT_Keyboard,
	HANDLE_GLUT_KeyboardUp,
	HANDLE_GLUT_Mouse,
    HANDLE_GLUT_MouseWheel,             /* Open/FreeGLUT -chm */
	HANDLE_GLUT_Motion,
	HANDLE_GLUT_PassiveMotion,
	HANDLE_GLUT_Entry,
	HANDLE_GLUT_Visibility,
	HANDLE_GLUT_WindowStatus,
	HANDLE_GLUT_Special,
	HANDLE_GLUT_SpecialUp,
    HANDLE_GLUT_Joystick,               /* Open/FreeGLUT -chm */
	HANDLE_GLUT_SpaceballMotion,
	HANDLE_GLUT_SpaceballRotate,
	HANDLE_GLUT_SpaceballButton,
	HANDLE_GLUT_ButtonBox,
	HANDLE_GLUT_Dials,
	HANDLE_GLUT_TabletMotion,
	HANDLE_GLUT_TabletButton,
    HANDLE_GLUT_MenuDestroy,            /* Open/FreeGLUT -chm */
	HANDLE_GLUT_Close,                  /* Open/FreeGLUT -chm */
	HANDLE_GLUT_WMClose,                /* AGL GLUT      -chm */
};

/* Callback for glutDisplayFunc */
begin_decl_gwh(Display, (void), 0)
end_decl_gwh()

pogl_glut.xs  view on Meta::CPAN

void
glutTabletMotionFunc(handler=0, ...)
	SV *	handler
	CODE:
	decl_gwh_xs(TabletMotion)

#//# glutTabletButtonFunc(\&callback);
void
glutTabletButtonFunc(handler=0, ...)
	SV *	handler
	CODE:
	decl_gwh_xs(TabletButton)

#endif

#if GLUT_API_VERSION >= 3

#//# glutMenuStatusFunc(\&callback);
void
glutMenuStatusFunc(handler=0, ...)
	SV *	handler
	CODE:
	decl_ggh_xs(MenuStatus)

#endif

#//# glutMenuStateFunc(\&callback);
void
glutMenuStateFunc(handler=0, ...)
	SV *	handler
	CODE:
	{
#if defined HAVE_FREEGLUT
		decl_ggh_xs(MenuState)
#endif
	}

#//# glutIdleFunc(\&callback);
void
glutIdleFunc(handler=0, ...)
	SV *	handler
	CODE:
	decl_ggh_xs(Idle)

#//# glutTimerFunc($msecs, \&callback);
void
glutTimerFunc(msecs, handler=0, ...)
	unsigned int	msecs
	SV *	handler
	CODE:
	{
		if (!handler || !SvOK(handler)) {
			croak("A handler must be specified");
		} else {
			AV * handler_data = newAV();
		
			PackCallbackST(handler_data, 1);
			
			glutTimerFunc(msecs, generic_glut_timer_handler, (int)handler_data);
		}
	ENSURE_callback_thread;}


# Colors

#//# glutSetColor($cell, $red, $green, $blue)
void
glutSetColor(cell, red, green, blue)
	int	cell
	GLfloat	red
	GLfloat	green
	GLfloat	blue

#//# glutGetColor($cell, $component);
GLfloat
glutGetColor(cell, component)
	int	cell
	int	component

#//# glutCopyColormap($win);
void
glutCopyColormap(win)
	int	win

# State

#//# glutGet($state);
int
glutGet(state)
	GLenum	state

#if GLUT_API_VERSION >= 3

#//# glutLayerGet(info);
int
glutLayerGet(info)
	GLenum	info

#endif

int
glutDeviceGet(info)
	GLenum	info

#if GLUT_API_VERSION >= 3

#//# glutGetModifiers();
int
glutGetModifiers()

#endif

#if GLUT_API_VERSION >= 2

#//# glutExtensionSupported($extension);
int
glutExtensionSupported(extension)
	char *	extension

#endif



( run in 1.954 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )