[PD-cvs] externals/pdp/system/X11 Makefile, 1.2, 1.3 pdp_xvideo.c, 1.2, 1.3 pdp_xwindow.c, 1.2, 1.3
Hans-Christoph Steiner
eighthave at users.sourceforge.net
Fri Dec 16 02:05:40 CET 2005
- Previous message: [PD-cvs] externals/pdp/scaf/test test_pdp_ca.pd, 1.2, 1.3 test_pdp_ca2.pd, 1.2, 1.3 test_pdp_ca3.pd, 1.2, 1.3
- Next message: [PD-cvs] externals/pdp/scaf/rules Makefile, 1.2, 1.3 carules.scaf, 1.2, 1.3
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/pure-data/externals/pdp/system/X11
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6756/system/X11
Added Files:
Makefile pdp_xvideo.c pdp_xwindow.c
Log Message:
checking in pdp 0.12.4 from http://zwizwa.fartit.com/pd/pdp/pdp-0.12.4.tar.gz
--- NEW FILE: pdp_xwindow.c ---
/*
* Pure Data Packet system module. - x window glue code (fairly tied to pd and pdp)
* Copyright (c) by Tom Schouten <pdp at zzz.kotnet.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
// this code is fairly tied to pd and pdp. serves mainly as reusable glue code
// for pdp_xv, pdp_glx, pdp_3d_windowcontext, ...
#include <string.h>
#include "pdp_xwindow.h"
#include "pdp_post.h"
#include "pdp_debug.h"
#include "pdp_symbol.h"
#include "pdp_list.h"
#define D if(0)
// xwin->xdisplay->screen = DefaultScreen(xwin->xdisplay->dpy);
/* x display class
typedef struct _pdp_xdisplay
{
Display *dpy; // the display connection
int screen; // the screen
t_pdp_list *windowlist; // all windows belonging to this connection
// this contains (xwindow object, eventlist)
} t_pdp_xdisplay; */
/************************************* PDP_XDISPLAY ************************************/
t_pdp_xdisplay *pdp_xdisplay_new(char *dpy_string)
{
t_pdp_xdisplay *d = pdp_alloc(sizeof(*d));
if (!(d->dpy = XOpenDisplay(dpy_string))){
pdp_post ("pdp_xdisplay_new: can't open display %s", dpy_string);
pdp_dealloc(d);
return (0);
}
d->windowlist = pdp_list_new(0);
d->screen = DefaultScreen(d->dpy);
d->dragbutton = -1;
return d;
}
void pdp_xdisplay_free(t_pdp_xdisplay *d)
{
XCloseDisplay(d->dpy);
PDP_ASSERT(0 == d->windowlist->elements); // make sure there are no dangling xwindow objects
pdp_list_free(d->windowlist);
pdp_dealloc(d);
}
/* some private members */
static int _windowset_contains(t_pdp_xdisplay *d, t_pdp_xwindow *w)
{
t_pdp_atom *a;
for (a=d->windowlist->first; a; a=a->next){
if (w == a->w.w_list->first->w.w_pointer) return 1;
}
return 0;
}
static void _windowset_add(t_pdp_xdisplay *d, t_pdp_xwindow *w)
{
t_pdp_list *l = pdp_list_new(0); // a new list for this window
t_pdp_list *l_ev = pdp_list_new(0); // the event list
pdp_list_add_back_pointer(l, w);
pdp_list_add_back(l, a_list, (t_pdp_word)l_ev);
pdp_list_add_back(d->windowlist, a_list, (t_pdp_word)l);
}
/* get the list describing this window */
static t_pdp_list *_windowset_get_info_for_Window(t_pdp_xdisplay *d, Window win)
{
t_pdp_atom *a;
for (a=d->windowlist->first; a; a=a->next){
if (win == ((t_pdp_xwindow *)a->w.w_list->first->w.w_pointer)->win) return a->w.w_list;
}
return 0;
}
static t_pdp_list *_windowset_get_info(t_pdp_xdisplay *d, t_pdp_xwindow *w)
{
t_pdp_atom *a;
for (a=d->windowlist->first; a; a=a->next){
if (w == a->w.w_list->first->w.w_pointer) return a->w.w_list;
}
return 0;
}
static void _windowset_remove(t_pdp_xdisplay *d, t_pdp_xwindow *w)
{
t_pdp_list *l = _windowset_get_info(d, w);
if (l){
pdp_list_remove(d->windowlist, a_list, (t_pdp_word)l);
pdp_tree_free(l);
}
}
void pdp_xdisplay_register_window(t_pdp_xdisplay *d, t_pdp_xwindow *w)
{
if (!_windowset_contains(d, w)) _windowset_add(d, w);
}
void pdp_xdisplay_unregister_window(t_pdp_xdisplay *d, t_pdp_xwindow *w)
{
if (_windowset_contains(d, w)) _windowset_remove(d, w);
}
/* LOCKING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1111*/
/* get events from display and store in queues */
void pdp_xdisplay_get_events(t_pdp_xdisplay *d)
{
unsigned int i;
XEvent e;
/* event tags */
char tag_drag[] = "drag0";
char tag_press[] = "press0";
char tag_release[] = "release0";
char tag_motion[] = "motion0";
char *BUT(char *c) {return c + strlen(c) - 1;}
/* button chars */
char *but_drag = BUT(tag_drag);
char *but_press = BUT(tag_press);
char *but_release = BUT(tag_release);
char *but_motion = BUT(tag_motion);
int nbEvents = XEventsQueued(d->dpy, QueuedAlready);
int bmask = Button1Mask
| Button2Mask
| Button3Mask
| Button4Mask
| Button5Mask;
while (XPending(d->dpy)){
XNextEvent(d->dpy, &e);
/* get the window info list for this X11 Window */
t_pdp_list *winfo = _windowset_get_info_for_Window(d, e.xany.window);
/* get the window object */
t_pdp_xwindow *xwin = (t_pdp_xwindow *)winfo->first->w.w_pointer;
/* get the event list corresponding to this window */
t_pdp_list *eventlist = winfo->first->next->w.w_list;
/* set dim scalers */
float inv_x = 1.0f / (float)(xwin->winwidth);
float inv_y = 1.0f / (float)(xwin->winheight);
/* list to store new event */
t_pdp_list *newevent = 0;
/* event tag */
char *tag;
char *but;
/* handle event */
switch(e.type){
case ConfigureNotify:
/* store new dimensions */
xwin->winwidth = e.xconfigure.width;
xwin->winheight = e.xconfigure.height;
break;
case ClientMessage:
if ((Atom)e.xclient.data.l[0] == xwin->WM_DELETE_WINDOW) {
newevent = pdp_list_new(1);
pdp_list_set_0(newevent, a_symbol, (t_pdp_word)pdp_gensym("close"));
pdp_list_add_back(eventlist, a_list, (t_pdp_word)newevent);
}
break;
case KeyPress:
case KeyRelease:
newevent = pdp_list_new(2);
pdp_list_set_0(newevent, a_symbol, (t_pdp_word)pdp_gensym(e.type == KeyPress ? "keypress" : "keyrelease"));
pdp_list_set_1(newevent, a_int, (t_pdp_word)(int)e.xkey.keycode);
pdp_list_add_back(eventlist, a_list, (t_pdp_word)newevent);
break;
case ButtonPress:
case ButtonRelease:
/* event specific stuff */
if (e.type == ButtonPress){
tag = tag_press;
but = but_press;
}
else {
tag = tag_release;
but = but_release;
}
/* send generic event */
*but = 0;
newevent = pdp_list_new(3);
pdp_list_set_0(newevent, a_symbol, (t_pdp_word)pdp_gensym(tag));
pdp_list_set_1(newevent, a_float, (t_pdp_word)(inv_x * (float)e.xbutton.x));
pdp_list_set_2(newevent, a_float, (t_pdp_word)(inv_y * (float)e.xbutton.y));
pdp_list_add_back(eventlist, a_list, (t_pdp_word)newevent);
/* send button specific event */
*but = '1' + e.xbutton.button - Button1;
newevent = pdp_list_new(3);
pdp_list_set_0(newevent, a_symbol, (t_pdp_word)pdp_gensym(tag));
pdp_list_set_1(newevent, a_float, (t_pdp_word)(inv_x * (float)e.xbutton.x));
pdp_list_set_2(newevent, a_float, (t_pdp_word)(inv_y * (float)e.xbutton.y));
pdp_list_add_back(eventlist, a_list, (t_pdp_word)newevent);
/* save drag button */
xwin->lastbut = *but;
break;
case MotionNotify:
if (e.xbutton.state & bmask){
/* button is down: it is a drag event */
tag = tag_drag;
but = but_drag;
/* send generic event */
*but = 0;
newevent = pdp_list_new(3);
pdp_list_set_0(newevent, a_symbol, (t_pdp_word)pdp_gensym(tag));
pdp_list_set_1(newevent, a_float, (t_pdp_word)(inv_x * (float)e.xbutton.x));
pdp_list_set_2(newevent, a_float, (t_pdp_word)(inv_y * (float)e.xbutton.y));
pdp_list_add_back(eventlist, a_list, (t_pdp_word)newevent);
/* send button specific event */
*but = xwin->lastbut;
newevent = pdp_list_new(3);
pdp_list_set_0(newevent, a_symbol, (t_pdp_word)pdp_gensym(tag));
pdp_list_set_1(newevent, a_float, (t_pdp_word)(inv_x * (float)e.xbutton.x));
pdp_list_set_2(newevent, a_float, (t_pdp_word)(inv_y * (float)e.xbutton.y));
pdp_list_add_back(eventlist, a_list, (t_pdp_word)newevent);
}
else {
tag = tag_motion;
but = but_motion;
*but = 0;
/* send generic event */
newevent = pdp_list_new(3);
pdp_list_set_0(newevent, a_symbol, (t_pdp_word)pdp_gensym(tag));
pdp_list_set_1(newevent, a_float, (t_pdp_word)(inv_x * (float)e.xbutton.x));
pdp_list_set_2(newevent, a_float, (t_pdp_word)(inv_y * (float)e.xbutton.y));
pdp_list_add_back(eventlist, a_list, (t_pdp_word)newevent);
}
default:
//pdp_post("pdp_xv: unknown event");
break;
}
}
}
/* return a list containing event lists */
t_pdp_list *pdp_xdisplay_get_events_for_window(t_pdp_xdisplay *d, t_pdp_xwindow *w)
{
t_pdp_list *info = _windowset_get_info(d, w);
t_pdp_list *eventlist;
PDP_ASSERT(info);
/* get all pending events from display */
pdp_xdisplay_get_events(d);
/* get the event list for this window and create a new one */
eventlist = info->first->next->w.w_list;
info->first->next->w.w_list = pdp_list_new(0);
return eventlist;
}
/************************************* PDP_XWINDOW ************************************/
void pdp_xwindow_warppointer(t_pdp_xwindow *xwin, int x, int y)
{
if (xwin->initialized){
XWarpPointer(xwin->xdisplay->dpy, None, xwin->win, 0, 0, 0, 0, x, y);
}
}
static void pdp_xwindow_overrideredirect(t_pdp_xwindow *xwin, int b)
{
XSetWindowAttributes new_attr;
new_attr.override_redirect = b ? True : False;
XChangeWindowAttributes(xwin->xdisplay->dpy, xwin->win, CWOverrideRedirect, &new_attr);
//XFlush(xwin->xdisplay->dpy);
}
void pdp_xwindow_moveresize(t_pdp_xwindow *xwin, int xoffset, int yoffset, int width, int height)
{
D pdp_post("_pdp_xwindow_moveresize");
if ((width > 0) && (height > 0)){
xwin->winwidth = width;
xwin->winheight = height;
xwin->winxoffset = xoffset;
xwin->winyoffset = yoffset;
if (xwin->initialized){
XMoveResizeWindow(xwin->xdisplay->dpy, xwin->win, xoffset, yoffset, width, height);
XFlush(xwin->xdisplay->dpy);
}
}
}
void pdp_xwindow_fullscreen(t_pdp_xwindow *xwin)
{
XWindowAttributes rootwin_attr;
D pdp_post("pdp_xwindow_fullscreen");
/* hmm.. fullscreen and xlib the big puzzle..
if it looks like a hack it is a hack. */
if (xwin->initialized){
XGetWindowAttributes(xwin->xdisplay->dpy, RootWindow(xwin->xdisplay->dpy, xwin->xdisplay->screen), &rootwin_attr );
//pdp_xwindow_overrideredirect(xwin, 0);
pdp_xwindow_moveresize(xwin, 0, 0, rootwin_attr.width, rootwin_attr.height);
//pdp_xwindow_overrideredirect(xwin, 1);
//XRaiseWindow(xwin->xdisplay->dpy, xwin->win);
//pdp_xwindow_moveresize(xwin, 0, 0, rootwin_attr.width, rootwin_attr.height);
//pdp_xwindow_overrideredirect(xwin, 0);
}
}
void pdp_xwindow_tile(t_pdp_xwindow *xwin, int x_tiles, int y_tiles, int i, int j)
{
XWindowAttributes rootwin_attr;
XSetWindowAttributes new_attr;
D pdp_post("pdp_xwindow_fullscreen");
if (xwin->initialized){
int tile_w;
int tile_h;
XGetWindowAttributes(xwin->xdisplay->dpy, RootWindow(xwin->xdisplay->dpy, xwin->xdisplay->screen), &rootwin_attr );
tile_w = rootwin_attr.width / x_tiles;
tile_h = rootwin_attr.height / y_tiles;
xwin->winwidth = (x_tiles-1) ? rootwin_attr.width - (x_tiles-1)*tile_w : tile_w;
xwin->winheight = (y_tiles-1) ? rootwin_attr.height - (y_tiles-1)*tile_h : tile_h;
xwin->winxoffset = i * tile_w;
xwin->winyoffset = j * tile_h;
//new_attr.override_redirect = True;
//XChangeWindowAttributes(xwin->xdisplay->dpy, xwin->win, CWOverrideRedirect, &new_attr );
XMoveResizeWindow(xwin->xdisplay->dpy, xwin->win, xwin->winxoffset, xwin->winyoffset, xwin->winwidth, xwin->winheight);
}
}
/* resize window */
void pdp_xwindow_resize(t_pdp_xwindow *xwin, int width, int height)
{
D pdp_post("pdp_xwindow_resize");
if ((width > 0) && (height > 0)){
xwin->winwidth = width;
xwin->winheight = height;
if (xwin->initialized){
XResizeWindow(xwin->xdisplay->dpy, xwin->win, width, height);
XFlush(xwin->xdisplay->dpy);
}
}
//_pdp_xwindow_moveresize(xwin, xwin->winxoffset, xwin->winyoffset, width, height);
}
/* move window */
void pdp_xwindow_move(t_pdp_xwindow *xwin, int xoffset, int yoffset)
{
D pdp_post("pdp_xwindow_move");
pdp_xwindow_moveresize(xwin, xoffset, yoffset, xwin->winwidth, xwin->winheight);
}
/* send events to a pd outlet (don't call this outside the pd thread) */
t_pdp_list *pdp_xwindow_get_eventlist(t_pdp_xwindow *xwin)
{
t_pdp_list *eventlist;
eventlist = pdp_xdisplay_get_events_for_window(xwin->xdisplay, xwin);
D pdp_list_print(eventlist);
return eventlist;
}
/* set an arbitrary cursor image */
void pdp_xwindow_cursor_image(t_pdp_xwindow *xwin, char *data, int width, int height)
{
if (!xwin->initialized) return;
Cursor cursor;
Pixmap pm;
XColor fg;
XColor bg;
fg.red = fg.green = fg.blue = 0xffff;
bg.red = bg.green = bg.blue = 0x0000;
pm = XCreateBitmapFromData(xwin->xdisplay->dpy, xwin->win, data, width, height);
cursor = XCreatePixmapCursor(xwin->xdisplay->dpy, pm, pm, &fg,
&bg, width/2, height/2);
XFreePixmap(xwin->xdisplay->dpy, pm);
XDefineCursor(xwin->xdisplay->dpy, xwin->win,cursor);
}
/* enable / disable cursor */
void pdp_xwindow_cursor(t_pdp_xwindow *xwin, int i){
if (!xwin->initialized) return;
if (i == 0) {
char data[] = {0};
pdp_xwindow_cursor_image(xwin, data, 1, 1);
}
else
XUndefineCursor(xwin->xdisplay->dpy, xwin->win);
xwin->cursor = i;
}
void pdp_xwindow_title(t_pdp_xwindow *xwin, char *title)
{
if (xwin->initialized)
XStoreName(xwin->xdisplay->dpy, xwin->win, title);
}
/* create xwindow */
int pdp_xwindow_create_on_display(t_pdp_xwindow *xwin, t_pdp_xdisplay *d)
{
XEvent e;
unsigned int i;
/* check if already opened */
if( xwin->initialized ){
pdp_post("pdp_xwindow_create_on_display: window already created");
goto exit;
}
xwin->xdisplay = d;
PDP_ASSERT(xwin->xdisplay);
/* create a window */
xwin->win = XCreateSimpleWindow(
xwin->xdisplay->dpy,
RootWindow(xwin->xdisplay->dpy, xwin->xdisplay->screen), xwin->winxoffset, xwin->winyoffset, xwin->winwidth, xwin->winheight, 0,
BlackPixel(xwin->xdisplay->dpy, xwin->xdisplay->screen),
BlackPixel(xwin->xdisplay->dpy, xwin->xdisplay->screen));
/* enable handling of close window event */
xwin->WM_DELETE_WINDOW = XInternAtom(xwin->xdisplay->dpy, "WM_DELETE_WINDOW", True);
(void)XSetWMProtocols(xwin->xdisplay->dpy, xwin->win, &xwin->WM_DELETE_WINDOW, 1);
if(!(xwin->win)){
/* clean up mess */
pdp_post("pdp_xwindow_create_on_display: could not create window. closing.\n");
//XCloseDisplay(xwin->xdisplay->dpy); NOT OWNER
xwin->xdisplay = 0;
xwin->initialized = 0;
goto exit;
}
/* select input events */
XSelectInput(xwin->xdisplay->dpy, xwin->win,
StructureNotifyMask
| KeyPressMask
| KeyReleaseMask
| ButtonPressMask
| ButtonReleaseMask
| MotionNotify
| PointerMotionMask);
// | ButtonMotionMask);
//XSelectInput(xwin->xdisplay->dpy, xwin->win, StructureNotifyMask);
/* map */
XMapWindow(xwin->xdisplay->dpy, xwin->win);
/* create graphics context */
xwin->gc = XCreateGC(xwin->xdisplay->dpy, xwin->win, 0, 0);
/* catch mapnotify */
for(;;){
XNextEvent(xwin->xdisplay->dpy, &e);
if (e.type == MapNotify) break;
}
/* we're done initializing */
xwin->initialized = 1;
/* disable/enable cursor */
pdp_xwindow_cursor(xwin, xwin->cursor);
/* set window title */
pdp_xwindow_title(xwin, "pdp");
/* register window for events */
/* TODO: move event selection ETC to xdisplay object */
pdp_xdisplay_register_window(xwin->xdisplay, xwin);
exit:
return xwin->initialized;
}
void pdp_xwindow_init(t_pdp_xwindow *xwin)
{
xwin->xdisplay = 0;
xwin->winwidth = 320;
xwin->winheight = 240;
xwin->winxoffset = 0;
xwin->winyoffset = 0;
xwin->initialized = 0;
xwin->cursor = 0;
//xwin->dragbutton = gensym("drag1");
}
t_pdp_xwindow *pdp_xwindow_new(void)
{
t_pdp_xwindow *xwin = pdp_alloc(sizeof(*xwin));
pdp_xwindow_init(xwin);
return xwin;
}
void pdp_xwindow_close(t_pdp_xwindow *xwin)
{
XEvent e;
if (xwin->initialized){
XFreeGC(xwin->xdisplay->dpy, xwin->gc);
XDestroyWindow(xwin->xdisplay->dpy, xwin->win);
while(XPending(xwin->xdisplay->dpy)) XNextEvent(xwin->xdisplay->dpy, &e);
pdp_xdisplay_unregister_window(xwin->xdisplay, xwin);
xwin->xdisplay = 0;
xwin->initialized = 0;
}
}
void pdp_xwindow_cleanup(t_pdp_xwindow *x)
{
// close win
pdp_xwindow_close(x);
// no more dynamic data to free
}
void pdp_xwindow_free(t_pdp_xwindow *xwin)
{
pdp_xwindow_cleanup(xwin);
pdp_dealloc(xwin);
}
--- NEW FILE: Makefile ---
OBJECTS = $(PDP_X11MOD)
include ../../Makefile.config
all: $(OBJECTS)
clean:
rm -f *~
rm -f *.o
--- NEW FILE: pdp_xvideo.c ---
/*
* Pure Data Packet system module. - x window glue code (fairly tied to pd and pdp)
* Copyright (c) by Tom Schouten <pdp at zzz.kotnet.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
// this code is fairly tied to pd and pdp. serves mainly as reusable glue code
// for pdp_xv, pdp_glx, pdp_3d_windowcontext, ...
#include <string.h>
#include "pdp_xwindow.h"
#include "pdp_xvideo.h"
#include "pdp_post.h"
#include "pdp_packet.h"
#define D if(0)
/************************************* PDP_XVIDEO ************************************/
static void pdp_xvideo_create_xvimage(t_pdp_xvideo *xvid, int width, int height)
{
int i;
long size;
//post("pdp_xvideo_create_xvimage");
xvid->width = width;
xvid->height = height;
size = (xvid->width * xvid->height + (((xvid->width>>1)*(xvid->height>>1))<<1));
//post("create xvimage %d %d", xvid->width, xvid->height);
xvid->data = (unsigned char *)pdp_alloc(size);
for (i=0; i<size; i++) xvid->data[i] = i;
xvid->xvi = XvCreateImage(xvid->xdpy->dpy, xvid->xv_port, xvid->xv_format, (char *)xvid->data, xvid->width, xvid->height);
xvid->last_encoding = -1;
if ((!xvid->xvi) || (!xvid->data)) pdp_post ("ERROR CREATING XVIMAGE");
//pdp_post("created xvimag data:%x xvi:%x",xvid->data,xvid->xvi);
}
static void pdp_xvideo_destroy_xvimage(t_pdp_xvideo *xvid)
{
if(xvid->data) pdp_dealloc(xvid->data);
if (xvid->xvi) XFree(xvid->xvi);
xvid->xvi = 0;
xvid->data = 0;
}
void pdp_xvideo_display_packet(t_pdp_xvideo *xvid, t_pdp_xwindow *xwin, int packet)
{
t_pdp *header = pdp_packet_header(packet);
void *data = pdp_packet_data(packet);
t_bitmap * bm = pdp_packet_bitmap_info(packet);
unsigned int width, height, encoding, size, nbpixels;
/* some checks: only display when initialized and when pacet is bitmap YV12 */
if (!xvid->initialized) return;
if (!header) return;
if (!bm) return;
width = bm->width;
height = bm->height;
encoding = bm->encoding;
size = (width * height + (((width>>1)*(height>>1))<<1));
nbpixels = width * height;
if (PDP_BITMAP != header->type) return;
if (PDP_BITMAP_YV12 != encoding) return;
/* check if xvimage needs to be recreated */
if ((width != xvid->width) || (height != xvid->height)){
//pdp_post("pdp_xv: replace image");
pdp_xvideo_destroy_xvimage(xvid);
pdp_xvideo_create_xvimage(xvid, width, height);
}
/* copy the data to the XvImage buffer */
memcpy(xvid->data, data, size);
/* display */
XvPutImage(xvid->xdpy->dpy,xvid->xv_port, xwin->win,xwin->gc,xvid->xvi,
0,0,xvid->width,xvid->height, 0,0,xwin->winwidth,xwin->winheight);
XFlush(xvid->xdpy->dpy);
}
void pdp_xvideo_close(t_pdp_xvideo* xvid)
{
if (xvid->initialized){
if (xvid->xvi) pdp_xvideo_destroy_xvimage(xvid);
XvUngrabPort(xvid->xdpy->dpy, xvid->xv_port, CurrentTime);
xvid->xv_port = 0;
xvid->xdpy = 0;
xvid->last_encoding = -1;
xvid->initialized = false;
}
}
void pdp_xvideo_cleanup(t_pdp_xvideo* xvid)
{
// close xvideo port (and delete XvImage)
pdp_xvideo_close(xvid);
// no more dynamic data to free
}
void pdp_xvideo_free(t_pdp_xvideo* xvid){
pdp_xvideo_cleanup(xvid);
pdp_dealloc(xvid);
}
void pdp_xvideo_init(t_pdp_xvideo *xvid)
{
xvid->xdpy = 0;
xvid->xv_format = FOURCC_YV12;
xvid->xv_port = 0;
xvid->width = 320;
xvid->height = 240;
xvid->data = 0;
xvid->xvi = 0;
xvid->initialized = 0;
xvid->last_encoding = -1;
}
t_pdp_xvideo *pdp_xvideo_new(void)
{
t_pdp_xvideo *xvid = pdp_alloc(sizeof(*xvid));
pdp_xvideo_init(xvid);
return xvid;
}
int pdp_xvideo_open_on_display(t_pdp_xvideo *xvid, t_pdp_xdisplay *d)
{
unsigned int ver, rel, req, ev, err, i, j;
unsigned int adaptors;
int formats;
XvAdaptorInfo *ai;
if (xvid->initialized) return 1;
if (!d) return 0;
xvid->xdpy = d;
if (Success != XvQueryExtension(xvid->xdpy->dpy,&ver,&rel,&req,&ev,&err)) return 0;
/* find + lock port */
if (Success != XvQueryAdaptors(xvid->xdpy->dpy,DefaultRootWindow(xvid->xdpy->dpy),&adaptors,&ai))
return 0;
for (i = 0; i < adaptors; i++) {
if ((ai[i].type & XvInputMask) && (ai[i].type & XvImageMask)) {
for (j=0; j < ai[i].num_ports; j++){
if (Success != XvGrabPort(xvid->xdpy->dpy,ai[i].base_id+j,CurrentTime)) {
//fprintf(stderr,"INFO: Xvideo port %ld on adapter %d: is busy, skipping\n",ai[i].base_id+j, i);
}
else {
xvid->xv_port = ai[i].base_id + j;
goto breakout;
}
}
}
}
breakout:
XFree(ai);
if (0 == xvid->xv_port) return 0;
pdp_post("pdp_xvideo: grabbed port %d on adaptor %d", xvid->xv_port, i);
xvid->initialized = 1;
pdp_xvideo_create_xvimage(xvid, xvid->width, xvid->height);
return 1;
}
- Previous message: [PD-cvs] externals/pdp/scaf/test test_pdp_ca.pd, 1.2, 1.3 test_pdp_ca2.pd, 1.2, 1.3 test_pdp_ca3.pd, 1.2, 1.3
- Next message: [PD-cvs] externals/pdp/scaf/rules Makefile, 1.2, 1.3 carules.scaf, 1.2, 1.3
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Pd-cvs
mailing list