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@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@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; }