From 8227dc75b8e236f7f9629d1bc49fae0addee3def Mon Sep 17 00:00:00 2001 From: Tom Schouten Date: Fri, 28 Feb 2003 09:48:54 +0000 Subject: pdp config svn path=/trunk/externals/pdp/; revision=440 --- modules/pdp_xv.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 122 insertions(+), 10 deletions(-) (limited to 'modules/pdp_xv.c') 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 +#include #include #include @@ -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; ix_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 + + -- cgit v1.2.1