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 )