aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/Makefile10
-rw-r--r--modules/pdp_del.c56
-rw-r--r--modules/pdp_gradient.c7
-rw-r--r--modules/pdp_noise.c10
-rw-r--r--modules/pdp_qt.c18
-rw-r--r--modules/pdp_sdl.c245
-rw-r--r--modules/pdp_v4l.c61
-rw-r--r--modules/pdp_xv.c132
8 files changed, 369 insertions, 170 deletions
diff --git a/modules/Makefile b/modules/Makefile
index 8f743aa..09a9ce3 100644
--- a/modules/Makefile
+++ b/modules/Makefile
@@ -2,13 +2,15 @@ current: all_modules
include ../Makefile.config
-OBJECTS = pdp_xv.o pdp_qt.o pdp_add.o pdp_reg.o pdp_conv.o \
- pdp_mix.o pdp_v4l.o pdp_affine.o pdp_del.o pdp_mul.o pdp_randmix.o \
+PDP_MOD = pdp_add.o pdp_reg.o pdp_conv.o \
+ pdp_mix.o pdp_affine.o pdp_del.o pdp_mul.o pdp_randmix.o \
pdp_snap.o pdp_trigger.o pdp_bq.o pdp_noise.o pdp_gradient.o \
pdp_route.o pdp_gain.o pdp_grey.o pdp_chrot.o pdp_scope.o \
- pdp_scale.o pdp_zoom.o pdp_scan.o pdp_sdl.o pdp_cheby.o
+ pdp_scale.o pdp_zoom.o pdp_scan.o pdp_cheby.o pdp_scanxy.o \
+ pdp_grey2mask.o pdp_constant.o pdp_slice_cut.o pdp_slice_glue.o
-all_modules: $(OBJECTS)
+# build portable and optional modules
+all_modules: $(PDP_MOD) $(PDP_OPTMOD)
clean:
rm -f *~
diff --git a/modules/pdp_del.c b/modules/pdp_del.c
index 97e47fd..50813e3 100644
--- a/modules/pdp_del.c
+++ b/modules/pdp_del.c
@@ -23,29 +23,19 @@
#include "pdp.h"
-
-
-
-
-
-
-
-
-
-
-
-
typedef struct pdp_del_struct
{
- t_object x_obj;
- t_float x_f;
+ t_object x_obj;
+ t_float x_f;
- t_outlet *x_outlet0;
+ t_outlet *x_outlet0;
+
+ t_outlet **x_outlet;
- int *x_packet;
- int x_order;
- int x_head;
- int x_delay;
+ int *x_packet;
+ int x_order;
+ int x_head;
+ int x_delay;
} t_pdp_del;
@@ -63,7 +53,7 @@ static void pdp_del_input_0(t_pdp_del *x, t_symbol *s, t_floatarg f)
/* if this is a process message, start the processing + propagate stuff to outputs */
if (s == gensym("register_ro")){
- in = (x->x_head & (x->x_order-1));
+ in = (x->x_head % x->x_order);
//post("pdp_del: marking unused packed id=%d on loc %d", x->x_packet[0], in);
pdp_packet_mark_unused(x->x_packet[in]);
packet = pdp_packet_copy_ro((int)f);
@@ -71,7 +61,7 @@ static void pdp_del_input_0(t_pdp_del *x, t_symbol *s, t_floatarg f)
//post("pdp_del: writing packed id=%d on loc %d", packet, in);
}
else if (s == gensym("process")){
- out = ((x->x_head + x->x_delay) & (x->x_order-1));
+ out = (((x->x_head + x->x_delay)) % x->x_order);
packet = x->x_packet[out];
if (-1 != packet){
@@ -83,7 +73,7 @@ static void pdp_del_input_0(t_pdp_del *x, t_symbol *s, t_floatarg f)
else {
//post("pdp_del: packet %d is empty", out);
}
- x->x_head--;
+ x->x_head = (x->x_head + x->x_order - 1) % x->x_order;
}
@@ -132,39 +122,19 @@ void *pdp_del_new(t_floatarg forder, t_floatarg fdel)
int i;
t_pdp_del *x = (t_pdp_del *)pd_new(pdp_del_class);
-
del = order;
order++;
if (del < 0) del = 0;
-
-
if (order <= 2) order = 2;
- else {
-
- order--;
- logorder = 1;
-
- while ((order | 1) != 1) {
- order >>= 1;
- logorder++;
- }
-
- order = 1 << logorder;
- }
-
- post("pdp_del: order = %d", order);
+ //post("pdp_del: order = %d", order);
x->x_order = order;
x->x_packet = (int *)malloc(sizeof(int)*order);
for(i=0; i<order; i++) x->x_packet[i] = -1;
-
x->x_delay = del;
-
-
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("delay"));
-
x->x_outlet0 = outlet_new(&x->x_obj, &s_anything);
diff --git a/modules/pdp_gradient.c b/modules/pdp_gradient.c
index 5c92e12..3af2a84 100644
--- a/modules/pdp_gradient.c
+++ b/modules/pdp_gradient.c
@@ -265,8 +265,11 @@ static void pdp_gradient_input_0(t_pdp_gradient *x, t_symbol *s, t_floatarg f)
/* add the process method and callback to the process queue */
-
- pdp_queue_add(x, pdp_gradient_process, pdp_gradient_sendpacket, &x->x_queue_id);
+ // since the process method creates a packet, this is not processed in the thread
+ // $$$TODO: fix this
+ //pdp_queue_add(x, pdp_gradient_process, pdp_gradient_sendpacket, &x->x_queue_id);
+ pdp_gradient_process(x);
+ pdp_gradient_sendpacket(x);
}
}
diff --git a/modules/pdp_noise.c b/modules/pdp_noise.c
index f1a4661..84f4a72 100644
--- a/modules/pdp_noise.c
+++ b/modules/pdp_noise.c
@@ -149,16 +149,14 @@ static void pdp_noise_bang(t_pdp_noise *x)
/* release the packet */
-}
+}
static void pdp_noise_dim(t_pdp_noise *x, t_floatarg w, t_floatarg h)
{
- if (w<32.0f) w = 32.0f;
- if (h<32.0f) h = 32.0f;
-
- x->x_width = (unsigned int)w;
- x->x_height = (unsigned int)h;
+ x->x_width = pdp_imageproc_legalwidth((int)w);
+ x->x_height = pdp_imageproc_legalheight((int)h);
+ //post("dims %d %d", x->x_width, x->x_height);
}
diff --git a/modules/pdp_qt.c b/modules/pdp_qt.c
index 1c778d5..8ed633d 100644
--- a/modules/pdp_qt.c
+++ b/modules/pdp_qt.c
@@ -19,7 +19,6 @@
*/
-
#include "pdp.h"
#include "pdp_llconv.h"
#include <quicktime/lqt.h>
@@ -169,8 +168,15 @@ static void pdp_qt_close(t_pdp_qt *x)
void pdp_qt_create_pdp_packet(t_pdp_qt *x)
{
t_pdp *header;
- int nbpixels = x->x_video_width * x->x_video_height;
- //int packet_size = (x->x_qt_cmodel == BC_RGB888) ? (nbpixels << 1) : (nbpixels + (nbpixels >> 1)) << 1;
+
+
+ /* round to next legal size */
+ /* if size is illegal, image distortion will occur */
+ u32 w = pdp_imageproc_legalwidth(x->x_video_width);
+ u32 h = pdp_imageproc_legalheight(x->x_video_height);
+
+
+ int nbpixels = w * h;
int packet_size = (nbpixels + (nbpixels >> 1)) << 1;
@@ -180,8 +186,8 @@ void pdp_qt_create_pdp_packet(t_pdp_qt *x)
//header->info.image.encoding = (x->x_qt_cmodel == BC_RGB888) ? PDP_IMAGE_GREY : PDP_IMAGE_YV12;
header->info.image.encoding = PDP_IMAGE_YV12;
- header->info.image.width = x->x_video_width;
- header->info.image.height = x->x_video_height;
+ header->info.image.width = w;
+ header->info.image.height = h;
}
@@ -939,3 +945,5 @@ void pdp_qt_setup(void)
#ifdef __cplusplus
}
#endif
+
+
diff --git a/modules/pdp_sdl.c b/modules/pdp_sdl.c
index 7bd8992..d30ef84 100644
--- a/modules/pdp_sdl.c
+++ b/modules/pdp_sdl.c
@@ -1,6 +1,6 @@
/*
* Pure Data Packet module.
- * Copyright (c) by martin pi <pi@attacksyour.net>
+ * Copyright (c) 2003 by martin pi <pi@attacksyour.net>
* Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -33,16 +33,15 @@ TODO:
*/
-
#include <stdio.h>
-#include <unistd.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
+//#include <unistd.h>
+//#include <sys/ipc.h>
+//#include <sys/shm.h>
#include <SDL/SDL.h>
-#include <quicktime/lqt.h>
-#include <quicktime/colormodels.h>
+//#include <quicktime/lqt.h>
+//#include <quicktime/colormodels.h>
#include "pdp.h"
#include "pdp_llconv.h"
@@ -52,8 +51,6 @@ TODO:
#define PDP_SDL_W 320
#define PDP_SDL_H 240
-#define PDP_AUTOCREATE_RETRY 3
-
typedef struct pdp_sdl_struct {
t_object x_obj;
@@ -65,6 +62,8 @@ typedef struct pdp_sdl_struct {
SDL_Surface *x_sdl_surface;
SDL_Overlay *x_sdl_overlay;
SDL_Rect x_sdl_rect;
+
+ int x_xid;
Uint32 x_sdl_format;
@@ -74,59 +73,69 @@ typedef struct pdp_sdl_struct {
unsigned int x_width;
unsigned int x_height;
int x_last_encoding;
+ int x_cursor;
int x_initialized;
int x_backfromthread;
- int x_autocreate;
-
int x_fullscreen;
} t_pdp_sdl;
-static SDL_Surface *pdp_sdl_getSurface(char* title, int width, int height, int bits, int fullscreenflag) {
+static SDL_Surface *pdp_sdl_getSurface(int xid, char* title, int width, int height, int bits, int fullscreenflag, int cursorflag) {
Uint32 flags;
int size,i;
SDL_Surface *screen;
+ char SDL_hack[32];
+
+ /* next lines from gstreamer plugin sdlvideosink */
+ if (xid < 0) unsetenv("SDL_WINDOWID");
+ else {
+ sprintf(SDL_hack, "%d", xid);
+ setenv("SDL_WINDOWID", SDL_hack, 1);
+ }
/* Initialize SDL */
if (!SDL_WasInit(SDL_INIT_VIDEO)) {
if (SDL_Init (SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE)) {
- printf("SDL: Initializing of SDL failed: %s.\n", SDL_GetError());
- return (SDL_Surface *)-1;
+ post("SDL: Initializing of SDL failed: %s.\n", SDL_GetError());
+ return NULL;
}
- }
-
+ /* ignore events :: only keys and wm_quit */
+ for ( i=SDL_NOEVENT; i<SDL_NUMEVENTS; ++i )
+ if( !(i & (SDL_KEYDOWN|SDL_VIDEORESIZE)) )
+ SDL_EventState(i, SDL_IGNORE);
+
+ }
/*
gem : SDL_OPENGL|SDL_DOUBLEBUF|SDL_HWSURFACE|SDL_ANYFORMAT|SDL_OPENGLBLIT;
working: SDL_ANYFORMAT|SDL_RESIZABLE|SDL_RLEACCEL;
*/
-
- flags = SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL;
+ flags = SDL_SWSURFACE | SDL_RESIZABLE;
+// flags = SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL|SDL_ANYFORMAT|SDL_RLEACCEL;
if ( fullscreenflag>0 ) {
flags |= SDL_FULLSCREEN|SDL_DOUBLEBUF;
}
- /* Have a preference for 8-bit, but accept any depth */
screen = SDL_SetVideoMode(width, height, bits, flags);
if ( screen == NULL ) {
- fprintf(stderr, "Couldn't set video mode: %s\n",
- SDL_GetError());
+ post("Couldn't set video mode: %s\n", SDL_GetError());
return NULL;
}
SDL_WM_SetCaption (title, title);
- /* ignore events :: only keys and wm_quit */
- for ( i=SDL_NOEVENT; i<SDL_NUMEVENTS; ++i )
- if( !(i & (SDL_KEYDOWN|SDL_QUIT)) )
- SDL_EventState(i, SDL_IGNORE);
+ SDL_ShowCursor(cursorflag);
- SDL_ShowCursor(1);
+ return screen;
+}
- return screen; // Success
+static SDL_Surface *pdp_sdl_recreateSurface(SDL_Surface *old, int xid, char* title, int width, int height, int bits, int fullscreenflag, int cursorflag) {
+ SDL_Surface *new = pdp_sdl_getSurface(xid, title, width, height, bits, fullscreenflag, cursorflag);
+ if (new != NULL) SDL_FreeSurface(old);
+ return new;
}
static inline void pdp_sdl_getOverlay(t_pdp_sdl* x) {
@@ -169,30 +178,26 @@ static int pdp_sdl_drawImage(t_pdp_sdl* x, t_image *image, short int *pixels) {
return 1;
}
-static void pdp_sdl_resize(t_pdp_sdl* x, t_floatarg width, t_floatarg height) {
+static void pdp_sdl_fullscreen(t_pdp_sdl *x, t_floatarg f);
- if (x->x_initialized && (!x->x_fullscreen) && (width>0) && (height>0)){
-// disabled for now
-// if media size is different to the one set, it will resize (yet never dither)
- }
+static inline void pdp_sdl_recreate(t_pdp_sdl *x) {
+ x->x_sdl_surface = pdp_sdl_recreateSurface(x->x_sdl_surface, x->x_xid,"pdp-sdl", x->x_winwidth, x->x_winheight, 16, x->x_fullscreen,x->x_cursor);
}
-static void pdp_sdl_fullscreen(t_pdp_sdl *x, t_floatarg f);
-
static int pdp_sdl_create(t_pdp_sdl *x) {
if (x->x_initialized){
return 0;
}
x->x_initialized = 0;
- x->x_sdl_surface = pdp_sdl_getSurface("pdp-sdl", x->x_winwidth, x->x_winheight, 16, x->x_fullscreen);
+ x->x_sdl_surface = pdp_sdl_getSurface(x->x_xid, "pdp-sdl", x->x_winwidth, x->x_winheight, 16, x->x_fullscreen,x->x_cursor);
if (x->x_sdl_surface != NULL) {
pdp_sdl_getOverlay(x);
if (x->x_sdl_overlay != NULL) {
x->x_sdl_rect.x = 0;
x->x_sdl_rect.y = 0;
- x->x_sdl_rect.w = x->x_width;
- x->x_sdl_rect.h = x->x_height;
+ x->x_sdl_rect.w = x->x_winwidth;
+ x->x_sdl_rect.h = x->x_winheight;
x->x_initialized = 1;
post("created successfully");
}
@@ -203,12 +208,13 @@ static int pdp_sdl_create(t_pdp_sdl *x) {
}
static void pdp_sdl_destroy(t_pdp_sdl *x);
+static void pdp_sdl_resize(t_pdp_sdl *x,t_floatarg,t_floatarg);
static void pdp_sdl_checkEvents(t_pdp_sdl *x) {
Uint8 *keys;
SDL_Event event;
- if (!SDL_PollEvent(&event)) return;
+ if (SDL_PollEvent(&event)!=1) return;
switch( event.type ){
case SDL_KEYDOWN:
@@ -224,6 +230,9 @@ static void pdp_sdl_checkEvents(t_pdp_sdl *x) {
case SDL_QUIT:
pdp_sdl_destroy(x);
break;
+ case SDL_VIDEORESIZE:
+ pdp_sdl_resize(x,(t_floatarg)event.resize.w,(t_floatarg)event.resize.h);
+ break;
default:
break;
}
@@ -231,26 +240,6 @@ static void pdp_sdl_checkEvents(t_pdp_sdl *x) {
}
-static int pdp_sdl_try_autocreate(t_pdp_sdl *x)
-{
-
- if (x->x_autocreate){
- post("pdp_sdl: autocreate window");
- pdp_sdl_create(x);
- if (!(x->x_initialized)){
- x->x_autocreate--;
- if (!x->x_autocreate){
- post ("pdp_sdl: autocreate failed %d times: disabled", PDP_AUTOCREATE_RETRY);
- post ("pdp_sdl: send [autocreate 1] message to re-enable");
- return 0;
- }
- }
- else return 1;
-
- }
- return 0;
-}
-
static void pdp_sdl_bang(t_pdp_sdl *x);
static void pdp_sdl_process(t_pdp_sdl *x)
@@ -263,8 +252,7 @@ static void pdp_sdl_process(t_pdp_sdl *x)
/* check if window is initialized */
if (!(x->x_initialized)){
- post("trying to autocreate");
- if (!pdp_sdl_try_autocreate(x)) return;
+ if (!pdp_sdl_create(x)) return;
}
/* check for pending sdl events */
@@ -296,6 +284,7 @@ static void pdp_sdl_destroy(t_pdp_sdl *x) {
pdp_sdl_freeOverlay(x);
SDL_FreeSurface(x->x_sdl_surface);
x->x_initialized = 0;
+ SDL_Quit();
}
}
@@ -309,10 +298,8 @@ static void pdp_sdl_random(t_pdp_sdl *x) {
/* redisplays image */
static void pdp_sdl_bang_thread(t_pdp_sdl *x) {
-// if (x->x_sdl_overlay->pixels) {
- if (SDL_DisplayYUVOverlay(x->x_sdl_overlay, &(* x).x_sdl_rect) <0)
- post("pdp_sdl: __LINE__ cannot display");
-// }
+ if (SDL_DisplayYUVOverlay(x->x_sdl_overlay, &(* x).x_sdl_rect) <0)
+ post("pdp_sdl: __LINE__ cannot display");
}
static void pdp_sdl_bang_callback(t_pdp_sdl *x)
@@ -340,34 +327,122 @@ static void pdp_sdl_input_0(t_pdp_sdl *x, t_symbol *s, t_floatarg f) {
}
-static void pdp_sdl_autocreate(t_pdp_sdl *x, t_floatarg f) {
- if (f != 0.0f) x->x_autocreate = PDP_AUTOCREATE_RETRY;
- else x->x_autocreate = 0;
+static void pdp_sdl_resize(t_pdp_sdl* x, t_floatarg width, t_floatarg height) {
+
+ if (x->x_initialized && (!x->x_fullscreen) && (width>0) && (height>0)) {
+ post("should get %d/%d",(int)width,(int) height);
+ x->x_winwidth=(int)width;
+ x->x_winheight=(int)height;
+ pdp_sdl_recreate(x);
+ }
}
+
static void pdp_sdl_fullscreen(t_pdp_sdl *x, t_floatarg f) {
if (f == x->x_fullscreen) return;
- x->x_fullscreen = (f != 0.0f);
+ x->x_fullscreen = (f != 0.0f);
+ x->x_cursor=0;
+
+ pdp_sdl_recreate(x);
+}
+
+static void pdp_sdl_cursor(t_pdp_sdl *x, t_floatarg f) {
+ if (f == x->x_cursor) return;
+
+ x->x_cursor = (f != 0.0f);
+ SDL_ShowCursor(x->x_cursor);
+}
+
+
+/* sets new target window */
+
+static void pdp_sdl_win(t_pdp_sdl *x, t_floatarg *f) {
+ pdp_queue_finish(x->x_queue_id);
+ x->x_queue_id = -1;
+ x->x_xid = (int)f;
+ pdp_sdl_recreate(x);
+}
+
+/* be very carefule not to set DGA fro here! */
+/* use export SDL_VIDEODRIVER=dga (or equivalent for your shell) instead */
+
+static void pdp_sdl_renderer(t_pdp_sdl *x, t_symbol *s) {
+ char SDL_hack[32];
pdp_sdl_destroy(x);
+
+ /* next lines from gstreamer plugin sdlvideosink */
+ unsetenv("SDL_VIDEODRIVER");
+
+ sprintf(SDL_hack, "%s", s->s_name);
+ setenv("SDL_VIDEODRIVER", SDL_hack, 1);
+
pdp_sdl_create(x);
- SDL_ShowCursor(0);
}
static void pdp_sdl_free(t_pdp_sdl *x)
{
- pdp_queue_finish(x->x_queue_id);
- pdp_sdl_destroy(x);
- pdp_packet_mark_unused(x->x_packet0);
- SDL_Quit();
+ pdp_queue_finish(x->x_queue_id);
+ pdp_sdl_destroy(x);
+ pdp_packet_mark_unused(x->x_packet0);
+// SDL_Quit();
+}
+
+static void pdp_sdl_listmodes(const char* title, Uint32 flags) {
+ SDL_Rect ** modes;
+ int i;
+
+ /* Get available modes */
+ modes = SDL_ListModes(NULL, flags);
+
+ /* Check is there are any modes available */
+ if(modes == (SDL_Rect **)0){
+ printf("%s : No modes available!", title);
+ return;
+ }
+
+ /* Check if our resolution is restricted */
+ if(modes == (SDL_Rect **)-1){
+ post("%s : All resolutions available.", title);
+ } else {
+ /* Print valid modes */
+ for(i=0;modes[i];++i)
+ post("%s : %d x %d", title, modes[i]->w, modes[i]->h);
+ }
+
+}
+
+static void pdp_sdl_modes(t_pdp_sdl *x) {
+ pdp_sdl_listmodes("FULL|HWSURF|||||||||||||||||||||||||", SDL_FULLSCREEN|SDL_HWSURFACE);
+ pdp_sdl_listmodes("HWSURF|RESIZ|ASYNC|HWACCEL||||||||||", SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
+ pdp_sdl_listmodes("HWSURF|RESIZ|ASYNC|HWACCEL|FULL|DBUF", SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL|SDL_FULLSCREEN|SDL_DOUBLEBUF);
+ pdp_sdl_listmodes("OPENGL|DBUF|HWSURF|ANYF|GLBLIT||||||", SDL_OPENGL|SDL_DOUBLEBUF|SDL_HWSURFACE|SDL_ANYFORMAT|SDL_OPENGLBLIT);
+ pdp_sdl_listmodes("ANYF|RESIZ|RLEA|||||||||||||||||||||", SDL_ANYFORMAT|SDL_RESIZABLE|SDL_RLEACCEL);
}
+static void pdp_sdl_info(t_pdp_sdl *x) {
+ const SDL_VideoInfo *narf;
+ post("\nSDL video info: note that this only works under dga mode\n");
+ narf = SDL_GetVideoInfo();
+ post("Is it possible to create hardware surfaces?\t\thw_available=%d",narf->hw_available);
+ post("Is there a window manager available?\t\t\twm_available=%d",narf->wm_available);
+ post("Are hardware to hardware blits accelerated?\t\tblit_hw=%d",narf->blit_hw);
+ post("Are hardware to hardware colorkey blits accelerated?\tblit_hw_CC=%d",narf->blit_hw_CC);
+ post("Are hardware to hardware alpha bits accelerated?\tblit_hw_A=%d",narf->blit_hw_A);
+ post("Are software to hardware blits accelerated?\t\tblit_sw=%d",narf->blit_sw);
+ post("Are software to hardware colorkey blits accelerated?\tblit_sw_CC=%d",narf->blit_sw_CC);
+ post("Are software to hardware alpha blits accelerated?\tblit_sw_A=%d",narf->blit_sw_A);
+ post("Are color fills accelerated?\t\t\t\tblit_fill=%d",narf->blit_fill);
+ post("Total amount of video_mem: %d",narf->video_mem);
+
+}
t_class *pdp_sdl_class;
-void *pdp_sdl_new(void)
-{
+void *pdp_sdl_new(void) {
+
+
t_pdp_sdl *x = (t_pdp_sdl *)pd_new(pdp_sdl_class);
x->x_packet0 = -1;
@@ -385,9 +460,13 @@ void *pdp_sdl_new(void)
x->x_backfromthread = 1;
x->x_initialized = 0;
- pdp_sdl_autocreate(x,1);
- x->x_fullscreen = 0;
+ x->x_fullscreen = 0;
+ x->x_cursor=1;
+
+ x->x_xid = -1;
+
+ pdp_sdl_create(x);
return (void *)x;
}
@@ -411,13 +490,16 @@ void pdp_sdl_setup(void)
class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_bang, gensym("bang"), A_NULL);
class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_random, gensym("random"), A_NULL);
class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_create, gensym("create"), A_NULL);
- class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_autocreate, gensym("autocreate"), A_FLOAT, A_NULL);
+ class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_info, gensym("info"), A_NULL);
+ class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_modes, gensym("modes"), A_NULL);
class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_destroy, gensym("destroy"), A_NULL);
class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_destroy, gensym("close"), A_NULL);
-// class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_resize, gensym("dim"), A_FLOAT, A_FLOAT, A_NULL);
-// class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_resize, gensym("size"), A_FLOAT, A_FLOAT, A_NULL);
+ class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_resize, gensym("dim"), A_FLOAT, A_FLOAT, A_NULL);
+ class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_resize, gensym("size"), A_FLOAT, A_FLOAT, A_NULL);
class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_fullscreen, gensym("fullscreen"), A_FLOAT, A_NULL);
-// class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_display, gensym("display"), A_SYMBOL, A_NULL);
+ class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_cursor, gensym("cursor"), A_FLOAT, A_NULL);
+ class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_win, gensym("window"), A_FLOAT, A_NULL);
+ class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_renderer, gensym("renderer"), A_SYMBOL, A_NULL);
class_addmethod(pdp_sdl_class, (t_method)pdp_sdl_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL);
}
@@ -425,3 +507,4 @@ void pdp_sdl_setup(void)
#ifdef __cplusplus
}
#endif
+
diff --git a/modules/pdp_v4l.c b/modules/pdp_v4l.c
index e4dbff9..f1195c3 100644
--- a/modules/pdp_v4l.c
+++ b/modules/pdp_v4l.c
@@ -19,9 +19,10 @@
*/
-
+#include "pdp_config.h"
#include "pdp.h"
#include "pdp_llconv.h"
+#include "pdp_imageproc.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
@@ -45,9 +46,7 @@
// is reset when manually opened or closed
#define PDP_XV_RETRIES 10
-//uncomment this for additional philips webcam control
-//#define HAVE_V4LPWC
-#ifdef HAVE_V4LPWC
+#ifdef HAVE_PWCV4L
#include "pwc-ioctl.h"
#endif
@@ -107,6 +106,11 @@ typedef struct pdp_v4l_struct
int x_open_retry;
+ u32 x_minwidth;
+ u32 x_maxwidth;
+ u32 x_minheight;
+ u32 x_maxheight;
+
} t_pdp_v4l;
@@ -158,7 +162,7 @@ static void pdp_v4l_pwc_init(t_pdp_v4l *x)
{
/* todo add detection code for pwc */
-#ifdef HAVE_V4LPWC
+#ifdef HAVE_PWCV4L
if(ioctl(x->x_tvfd, VIDIOCPWCRUSER)){
perror("pdp_v4l: pwc: VIDIOCPWCRUSER");
@@ -259,6 +263,7 @@ static void *pdp_v4l_thread(void *voidx)
return 0;
}
+static void pdp_v4l_setlegaldim(t_pdp_v4l *x, int xx, int yy);
static void pdp_v4l_open(t_pdp_v4l *x, t_symbol *name)
{
@@ -302,6 +307,12 @@ static void pdp_v4l_open(t_pdp_v4l *x, t_symbol *name)
post("pdp_v4l: cap: name %s type %d channels %d maxw %d maxh %d minw %d minh %d",
x->x_vcap.name, x->x_vcap.type, x->x_vcap.channels, x->x_vcap.maxwidth, x->x_vcap.maxheight,
x->x_vcap.minwidth, x->x_vcap.minheight);
+
+ x->x_minwidth = pdp_imageproc_legalwidth(x->x_vcap.minwidth);
+ x->x_maxwidth = pdp_imageproc_legalwidth_round_down(x->x_vcap.maxwidth);
+ x->x_minheight = pdp_imageproc_legalheight(x->x_vcap.minheight);
+ x->x_maxheight = pdp_imageproc_legalheight_round_down(x->x_vcap.maxheight);
+
if (ioctl(x->x_tvfd, VIDIOCGPICT, &x->x_vpicture) < 0)
{
@@ -376,10 +387,9 @@ static void pdp_v4l_open(t_pdp_v4l *x, t_symbol *name)
goto closit;
}
- width = (x->x_width > (unsigned int)x->x_vcap.minwidth) ? x->x_width : (unsigned int)x->x_vcap.minwidth;
- width = (width > (unsigned int)x->x_vcap.maxwidth) ?(unsigned int) x->x_vcap.maxwidth : width;
- height = (x->x_height > (unsigned int)x->x_vcap.minheight) ? x->x_height :(unsigned int) x->x_vcap.minheight;
- height = (height > (unsigned int)x->x_vcap.maxheight) ? (unsigned int)x->x_vcap.maxheight : height;
+ pdp_v4l_setlegaldim(x, x->x_width, x->x_height);
+ width = x->x_width;
+ height = x->x_height;
for (i = 0; i < NBUF; i++)
{
@@ -633,27 +643,34 @@ static void pdp_v4l_bang(t_pdp_v4l *x)
}
-static void pdp_v4l_dim(t_pdp_v4l *x, t_floatarg xx, t_floatarg yy)
+static void pdp_v4l_setlegaldim(t_pdp_v4l *x, int xx, int yy)
{
- unsigned int w,h;
- xx = (xx < 0.0f) ? 0.0f : xx;
- yy = (yy < 0.0f) ? 0.0f : yy;
+ unsigned int w,h;
- w = (unsigned int)xx;
- h = (unsigned int)yy;
+ w = pdp_imageproc_legalwidth((int)xx);
+ h = pdp_imageproc_legalheight((int)yy);
+
+ w = (w < x->x_maxwidth) ? w : x->x_maxwidth;
+ w = (w > x->x_minwidth) ? w : x->x_minwidth;
+ h = (h < x->x_maxheight) ? h : x->x_maxheight;
+ h = (h > x->x_minheight) ? h : x->x_minheight;
- if (x->x_initialized){
- pdp_v4l_close(x);
x->x_width = w;
x->x_height = h;
+}
+
+static void pdp_v4l_dim(t_pdp_v4l *x, t_floatarg xx, t_floatarg yy)
+{
+ if (x->x_initialized){
+ pdp_v4l_close(x);
+ pdp_v4l_setlegaldim(x, (int)xx, (int)yy);
pdp_v4l_open(x, x->x_device);
}
else{
- x->x_width = w;
- x->x_height = h;
+ pdp_v4l_setlegaldim(x, (int)xx, (int)yy);
}
}
@@ -699,6 +716,12 @@ void *pdp_v4l_new(void)
x->x_channel = 0;
x->x_freq = -1; //don't set freq by default
+ x->x_minwidth = pdp_imageproc_legalwidth(0);
+ x->x_maxwidth = pdp_imageproc_legalwidth_round_down(0x7fffffff);
+ x->x_minheight = pdp_imageproc_legalheight(0);
+ x->x_maxheight = pdp_imageproc_legalheight_round_down(0x7fffffff);
+
+
return (void *)x;
}
diff --git a/modules/pdp_xv.c b/modules/pdp_xv.c
index c859a40..fde5409 100644
--- a/modules/pdp_xv.c
+++ b/modules/pdp_xv.c
@@ -24,9 +24,9 @@ pdp xvideo output
*/
-
// x stuff
#include <X11/Xlib.h>
+#include <X11/Xatom.h>
#include <X11/extensions/Xv.h>
#include <X11/extensions/Xvlib.h>
@@ -51,6 +51,7 @@ typedef struct pdp_xv_struct
{
t_object x_obj;
t_float x_f;
+ t_outlet *x_outlet;
int x_packet0;
int x_queue_id;
@@ -60,6 +61,7 @@ typedef struct pdp_xv_struct
int x_screen;
Window x_win;
GC x_gc;
+ Atom x_WM_DELETE_WINDOW;
int x_xv_format;
int x_xv_port;
@@ -77,6 +79,7 @@ typedef struct pdp_xv_struct
int x_autocreate;
float x_cursor;
+ t_symbol *x_dragbutton;
} t_pdp_xv;
@@ -122,10 +125,12 @@ void pdp_xv_create_xvimage(t_pdp_xv *x)
{
long size = (x->x_width * x->x_height + (((x->x_width>>1)*(x->x_height>>1))<<1));
+ //post("create xvimage %d %d", x->x_width, x->x_height);
x->x_data = (unsigned char *)malloc(size);
x->x_xvi = XvCreateImage(x->x_dpy, x->x_xv_port, x->x_xv_format, (char *)x->x_data, x->x_width, x->x_height);
x->x_last_encoding = -1;
- if (!(x->x_xvi) || (!x->x_data)) post ("ERROR CREATING XVIMAGE");
+ if ((!x->x_xvi) || (!x->x_data)) post ("ERROR CREATING XVIMAGE");
+ //post("created xvimag data:%x xvi:%x",x->x_data,x->x_xvi);
}
@@ -193,6 +198,7 @@ static void pdp_xv_create(t_pdp_xv* x)
XEvent e;
unsigned int i;
+
if( x->x_initialized ){
//post("pdp_xv: window already created");
return;
@@ -230,6 +236,11 @@ static void pdp_xv_create(t_pdp_xv* x)
BlackPixel(x->x_dpy, x->x_screen),
BlackPixel(x->x_dpy, x->x_screen));
+
+ /* enable handling of close window event */
+ x->x_WM_DELETE_WINDOW = XInternAtom(x->x_dpy, "WM_DELETE_WINDOW", True);
+ (void)XSetWMProtocols(x->x_dpy, x->x_win, &x->x_WM_DELETE_WINDOW, 1);
+
if(!(x->x_win)){
/* clean up mess */
post("pdp_xv: could not create window\n");
@@ -243,7 +254,10 @@ static void pdp_xv_create(t_pdp_xv* x)
return;
}
- XSelectInput(x->x_dpy, x->x_win, StructureNotifyMask);
+ /* select input events */
+ XSelectInput(x->x_dpy, x->x_win, StructureNotifyMask
+ | ButtonPressMask | ButtonReleaseMask | MotionNotify | ButtonMotionMask);
+
XMapWindow(x->x_dpy, x->x_win);
@@ -255,7 +269,10 @@ static void pdp_xv_create(t_pdp_xv* x)
}
+ /* we're done initializing */
x->x_initialized = true;
+
+ /* disable/enable cursor */
pdp_xv_cursor(x, x->x_cursor);
}
@@ -380,31 +397,104 @@ static void pdp_xv_random(t_pdp_xv *x)
for(i=0; i<x->x_width*x->x_height/4; i++) intdata[i]=random();
}
+
/* redisplays image */
static void pdp_xv_bang_thread(t_pdp_xv *x)
{
- XEvent e;
unsigned int i;
+ XEvent e;
+ XConfigureEvent *ce = (XConfigureEvent *)&e;
+ XButtonEvent *be = (XButtonEvent *)&e;
+ XMotionEvent *me = (XMotionEvent *)&e;
+ float inv_x, inv_y;
+ t_symbol *s;
+ t_atom atom[2];
+ char nextdrag[]="drag0";
+ char b='0';
+
+ inv_x = 1.0f / (float)(x->x_winwidth);
+ inv_y = 1.0f / (float)(x->x_winheight);
- //while (XEventsQueued(x->x_dpy, QueuedAlready)){
while (XPending(x->x_dpy)){
- //post("pdp_xv: waiting for event");
+
XNextEvent(x->x_dpy, &e);
- //post("pdp_xv: XEvent %d", e.type);
- if(e.type == ConfigureNotify){
- XConfigureEvent *ce = (XConfigureEvent *)&e;
+
+ switch(e.type){
+ case ConfigureNotify:
x->x_winwidth = ce->width;
x->x_winheight = ce->height;
+ inv_x = 1.0f / (float)(x->x_winwidth);
+ inv_y = 1.0f / (float)(x->x_winheight);
+ break;
+
+ case ClientMessage:
+ if ((Atom)e.xclient.data.l[0] == x->x_WM_DELETE_WINDOW) {
+ post("pdp_xv: button disabled, please send a \"close\" message to close the window");
+ //destroy = 1;
+ }
+ break;
+
+ case ButtonPress:
+ //post("pdp_xv: press %f %f", inv_x * (float)be->x, inv_y * (float)be->y);
+ SETFLOAT(atom+0,inv_x * (float)be->x);
+ SETFLOAT(atom+1,inv_y * (float)be->y);
+ outlet_anything(x->x_outlet, gensym("press"), 2, atom);
+ switch(be->button){
+ case Button1: outlet_anything(x->x_outlet, gensym("press1"), 2, atom); b='1'; break;
+ case Button2: outlet_anything(x->x_outlet, gensym("press2"), 2, atom); b='2'; break;
+ case Button3: outlet_anything(x->x_outlet, gensym("press3"), 2, atom); b='3'; break;
+ case Button4: outlet_anything(x->x_outlet, gensym("press4"), 2, atom); b='4'; break;
+ case Button5: outlet_anything(x->x_outlet, gensym("press5"), 2, atom); b='5'; break;
+ default: break;
+ }
+ nextdrag[4]=b;
+ x->x_dragbutton = gensym(nextdrag);
+ break;
+
+ case ButtonRelease:
+ //post("pdp_xv: release %f %f", inv_x * (float)be->x, inv_y * (float)be->y);
+ SETFLOAT(atom+0,inv_x * (float)be->x);
+ SETFLOAT(atom+1,inv_y * (float)be->y);
+ outlet_anything(x->x_outlet, gensym("release"), 2, atom);
+ switch(be->button){
+ case Button1: outlet_anything(x->x_outlet, gensym("release1"), 2, atom); break;
+ case Button2: outlet_anything(x->x_outlet, gensym("release2"), 2, atom); break;
+ case Button3: outlet_anything(x->x_outlet, gensym("release3"), 2, atom); break;
+ case Button4: outlet_anything(x->x_outlet, gensym("release4"), 2, atom); break;
+ case Button5: outlet_anything(x->x_outlet, gensym("release5"), 2, atom); break;
+ default: break;
+ }
+ break;
+ case MotionNotify:
+ //post("pdp_xv: drag %f %f", inv_x * (float)be->x, inv_y * (float)be->y);
+ SETFLOAT(atom+0,inv_x * (float)be->x);
+ SETFLOAT(atom+1,inv_y * (float)be->y);
+ outlet_anything(x->x_outlet, gensym("drag"), 2, atom);
+ outlet_anything(x->x_outlet, x->x_dragbutton, 2, atom);
+ break;
+
+ default:
+ //post("pdp_xv: unknown event");
+ break;
}
- //post("pdp_xv: received event");
}
+ // THIS SEEMS TO CRASH ON VERY LARGE IMAGES..
+ //post("start");
+ //post("XvPutImage xvi:%x",x->x_xvi);
XvPutImage(x->x_dpy,x->x_xv_port,x->x_win,x->x_gc,x->x_xvi,
0,0,x->x_width,x->x_height, 0,0,x->x_winwidth,x->x_winheight);
+ //post("XFlush");
XFlush(x->x_dpy);
+
+ //post("end");
+
+
+
+
}
static void pdp_xv_bang_callback(t_pdp_xv *x)
@@ -416,6 +506,11 @@ static void pdp_xv_bang_callback(t_pdp_xv *x)
static void pdp_xv_bang(t_pdp_xv *x)
{
+ /* check if window is initialized */
+ if (!(x->x_initialized)){
+ if (!pdp_xv_try_autocreate(x)) return;
+ }
+
/* if previous queued method returned
schedule a new one, else ignore */
@@ -434,6 +529,11 @@ static void pdp_xv_input_0(t_pdp_xv *x, t_symbol *s, t_floatarg f)
}
+static void pdp_xv_vga(t_pdp_xv *x)
+{
+ pdp_xv_resize(x, 640, 480);
+}
+
static void pdp_xv_autocreate(t_pdp_xv *x, t_floatarg f)
{
if (f != 0.0f) x->x_autocreate = PDP_XV_AUTOCREATE_RETRY;
@@ -468,6 +568,7 @@ t_class *pdp_xv_class;
void *pdp_xv_new(void)
{
t_pdp_xv *x = (t_pdp_xv *)pd_new(pdp_xv_class);
+ x->x_outlet = outlet_new(&x->x_obj, &s_anything);
x->x_packet0 = -1;
@@ -495,12 +596,17 @@ void *pdp_xv_new(void)
x->x_last_encoding = -1;
x->x_cursor = 0;
+ x->x_dragbutton = gensym("drag1");
+
+ //pdp_xv_create(x);
return (void *)x;
}
+
+
#ifdef __cplusplus
extern "C"
{
@@ -517,6 +623,7 @@ void pdp_xv_setup(void)
class_addmethod(pdp_xv_class, (t_method)pdp_xv_bang, gensym("bang"), A_NULL);
class_addmethod(pdp_xv_class, (t_method)pdp_xv_random, gensym("random"), A_NULL);
+ class_addmethod(pdp_xv_class, (t_method)pdp_xv_create, gensym("open"), A_NULL);
class_addmethod(pdp_xv_class, (t_method)pdp_xv_create, gensym("create"), A_NULL);
class_addmethod(pdp_xv_class, (t_method)pdp_xv_autocreate, gensym("autocreate"), A_FLOAT, A_NULL);
class_addmethod(pdp_xv_class, (t_method)pdp_xv_destroy, gensym("destroy"), A_NULL);
@@ -527,8 +634,13 @@ void pdp_xv_setup(void)
class_addmethod(pdp_xv_class, (t_method)pdp_xv_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL);
class_addmethod(pdp_xv_class, (t_method)pdp_xv_cursor, gensym("cursor"), A_FLOAT, A_NULL);
+ /* some shortcuts for the lazy */
+ class_addmethod(pdp_xv_class, (t_method)pdp_xv_vga, gensym("vga"), A_NULL);
+
}
#ifdef __cplusplus
}
#endif
+
+