From f9563ee14b530fa38701b00d551891a6bdcd0352 Mon Sep 17 00:00:00 2001 From: iovar Date: Fri, 6 Oct 2006 14:14:57 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r85, which included commits to RCS files with non-trunk default branches. git-svn-id: https://recordmydesktop.svn.sourceforge.net/svnroot/recordmydesktop/trunk@86 f606c939-3180-4ac9-a4b8-4b8779d57d0a --- rMD-exp/include/recordmydesktop.h | 508 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 508 insertions(+) create mode 100644 rMD-exp/include/recordmydesktop.h (limited to 'rMD-exp/include/recordmydesktop.h') diff --git a/rMD-exp/include/recordmydesktop.h b/rMD-exp/include/recordmydesktop.h new file mode 100644 index 0000000..4533b87 --- /dev/null +++ b/rMD-exp/include/recordmydesktop.h @@ -0,0 +1,508 @@ +/********************************************************************************* +* recordMyDesktop * +********************************************************************************** +* * +* Copyright (C) 2006 John Varouhakis * +* * +* * +* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * +* * +* * +* * +* For further information contact me at johnvarouhakis@gmail.com * +**********************************************************************************/ + + +#ifndef RECORDMYDESKTOP_H +#define RECORDMYDESKTOP_H 1 + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +//define whcih way we are reading a pixmap +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define __ABYTE 3 +#define __RBYTE 2 +#define __GBYTE 1 +#define __BBYTE 0 +#elif __BYTE_ORDER == __BIG_ENDIAN +#define __ABYTE 0 +#define __RBYTE 1 +#define __GBYTE 2 +#define __BBYTE 3 +#else +#error Only little-endian and big-endian systems are supported +#endif + + +//do not be confused +//this is useless and obsolete. +//There are no plans for other fotmats +enum {UNSPECIFIED,OGG_THEORA_VORBIS}; + + +/**Structs*/ + +typedef struct _DisplaySpecs{ //this struct holds some basic information + int screen; //about the display,needed mostly for + uint width; //validity checks at startup + uint height; + Window root; + Visual *visual; + GC gc; + int depth; + unsigned long bpixel; + unsigned long wpixel; +}DisplaySpecs; + +typedef struct _WGeometry{ //basic geometry of a window or area + int x; + int y; + int width; + int height; +}WGeometry; + +typedef struct _RectArea{ //an area that has been damaged gets stored + WGeometry geom; //in a list comprised of structs of this type + struct _RectArea *prev,*next; +}RectArea; + +typedef struct _BRWindow{ //'basic recorded window' specs + WGeometry geom; //window attributes + WGeometry rgeom; //part of window that is recorded + int nbytes; //size of zpixmap when screenshoting + Window windowid; //id +}BRWindow; + +//defaults in the following comment lines may be out of sync with reality +//check DEFAULT_ARGS macro further bellow +typedef struct _ProgArgs{ + int delay; //start up delay + Window windowid; //window to record(default root) + char *display; //display to connect(default :0) + int x,y; //x,y offset(default 0,0) + int width,height; //defaults to window width and height + int quietmode; //no messages to stderr,stdout + char *filename; //output file(default out.[ogg|*]) + int encoding; //encoding(default OGG_THEORA_VORBIS) + int cursor_color; //black or white=>1 or 0 + int have_dummy_cursor;//disable/enable drawing of the dummy cursor + int xfixes_cursor; //disable/enable drawing of a cursor obtained + //through the xfixes extension + float fps; //desired framerate(default 15) + unsigned int frequency; //desired frequency (default 22050) + unsigned int channels; //no of channels(default 2) + char *device; //default sound device(default according to alsa or oss) + int nosound; //do not record sound(default 0) + int noshared; //do not use shared memory extension(default 1) + int nocondshared; //de not use shared memory on large image aquititions + int shared_thres; //threshold to use shared memory + int full_shots; //do not poll damage, take full screenshots + int no_quick_subsample;//average pixels in chroma planes + int scshot; //take screenshot and exit(default 0) + int scale_shot; //screenshot subscale factor(default 1) + int v_bitrate,v_quality,s_quality;//video bitrate,video-sound quality + int dropframes; //option for theora encoder +}ProgArgs; + + +//this struct holds anything related to encoding AND +//writting out to file. +typedef struct _EncData{ + ogg_stream_state m_ogg_ts;//theora + ogg_stream_state m_ogg_vs;//vorbis + ogg_page m_ogg_pg;//this could be avoided since + // it is used only while initializing + ogg_packet m_ogg_pckt1;//theora stream + ogg_packet m_ogg_pckt2;//vorbis stream +//theora data + theora_state m_th_st; + theora_info m_th_inf; + theora_comment m_th_cmmnt; + yuv_buffer yuv; +//vorbis data + vorbis_info m_vo_inf; + vorbis_comment m_vo_cmmnt; + vorbis_dsp_state m_vo_dsp; + vorbis_block m_vo_block; +//these should be 0, since area is quantized +//before input + int x_offset, + y_offset; +//our file + FILE *fp; +}EncData; + +//sound buffer +//sound keeps coming so we que it in this list +//which we then traverse +typedef struct _SndBuffer{ + signed char *data; + struct _SndBuffer *next; +}SndBuffer; + +//this structure holds any data related to the program +//It's usage is mostly to be given as an argument to the +//threads,so they will have access to the program data, avoiding +//at the same time usage of any globals. +typedef struct _ProgData{ + ProgArgs args;//the program arguments + DisplaySpecs specs;//Display specific information + BRWindow brwin;//recording window + Display *dpy;//curtrent display + XImage *image;//the image that holds the current full screenshot + XImage *shimage;//the image that holds the current full screenshot(shared memory) + unsigned char *dummy_pointer;//a dummy pointer to be drawn in every frame + //data is casted to unsigned for later use in YUV buffer + int dummy_p_size;//initially 16x16,always square + unsigned char npxl;//this is the no pixel convention when drawing the dummy pointer + char *datamain,//the data of image + *datash,//the data of shimage + *datatemp;//buffer for the temporary image,which will be + //preallocated in case shared memory is not used. + RectArea *rect_root[2];//the interchanging list roots for storing the changed regions + int list_selector,//selector for the above + damage_event,//damage event base code + damage_error,//damage error base code + running; + SndBuffer *sound_buffer; + EncData *enc_data; + int hard_pause;//if sound device doesn't support pause + //we have to close and reopen + int avd;//syncronization among audio and video + unsigned int periodtime, + frametime; + pthread_mutex_t list_mutex[2],//mutexes for concurrency protection of the lists + sound_buffer_mutex, + libogg_mutex,//libogg is not thread safe + yuv_mutex;//this might not be needed since we only have + //one read-only and one write-only thread + //also on previous versions, y component was looped separately + //and then u and v so this was needed to avoid wrong coloring to render + //Currently this mutex only prevents the cursor from flickering + pthread_cond_t time_cond,//this gets a broadcast by the handler whenever it's time to get a screenshot + pause_cond,//this is blocks execution, when program is paused + sound_buffer_ready,//sound encoding finished + sound_data_read,//a buffer is ready for proccessing + image_buffer_ready;//image encoding finished + snd_pcm_t *sound_handle; + snd_pcm_uframes_t periodsize; +}ProgData; + +/**Globals*/ +//I've read somewhere that I'll go to hell for using globals... + +int Paused,*Running,Aborted; +pthread_cond_t *time_cond,*pause_cond; +unsigned char Yr[256],Yg[256],Yb[256], + Ur[256],Ug[256],Ub[256], + Vr[256],Vg[256],Vb[256]; +//the following values are of no effect +//but they might be usefull later for profiling +unsigned int frames_total,//frames calculated by total time expirations + frames_lost;//the value of shame +//used to determine frame drop which can +//happen on failure to receive a signal over a condition variable +int capture_busy, + encoder_busy; + + +/**Macros*/ + +#define CLIP_EVENT_AREA(e,brwin,wgeom){\ + if(((e)->area.x<=(brwin)->rgeom.x)&&((e)->area.y<=(brwin)->rgeom.y)&&\ + ((e)->area.width>=(brwin)->rgeom.width)&&((e)->area.height<(brwin)->rgeom.height)){\ + (wgeom)->x=(brwin)->rgeom.x;\ + (wgeom)->y=(brwin)->rgeom.y;\ + (wgeom)->width=(brwin)->rgeom.width;\ + (wgeom)->height=(brwin)->rgeom.height;\ + }\ + else{\ + (wgeom)->x=((((e)->area.x+(e)->area.width>=(brwin)->rgeom.x)&&\ + ((e)->area.x<=(brwin)->rgeom.x+(brwin)->rgeom.width))?\ + (((e)->area.x<=(brwin)->rgeom.x)?(brwin)->rgeom.x:(e)->area.x):-1);\ + \ + (wgeom)->y=((((e)->area.y+(e)->area.height>=(brwin)->rgeom.y)&&\ + ((e)->area.y<=(brwin)->rgeom.y+(brwin)->rgeom.height))?\ + (((e)->area.y<=(brwin)->rgeom.y)?(brwin)->rgeom.y:(e)->area.y):-1);\ + \ + (wgeom)->width=((e)->area.x<=(brwin)->rgeom.x)?\ + (e)->area.width-((brwin)->rgeom.x-(e)->area.x):\ + ((e)->area.x<=(brwin)->rgeom.x+(brwin)->rgeom.width)?\ + (((brwin)->rgeom.width-(e)->area.x+(brwin)->rgeom.x<(e)->area.width)?\ + (brwin)->rgeom.width-(e)->area.x+(brwin)->rgeom.x:e->area.width):-1;\ + \ + (wgeom)->height=((e)->area.y<=(brwin)->rgeom.y)?\ + (e)->area.height-((brwin)->rgeom.y-(e)->area.y):\ + ((e)->area.y<=(brwin)->rgeom.y+(brwin)->rgeom.height)?\ + (((brwin)->rgeom.height-(e)->area.y+(brwin)->rgeom.y<(e)->area.height)?\ + (brwin)->rgeom.height-(e)->area.y+(brwin)->rgeom.y:(e)->area.height):-1;\ + \ + if((wgeom)->width>(brwin)->rgeom.width)(wgeom)->width=(brwin)->rgeom.width;\ + if((wgeom)->height>(brwin)->rgeom.height)(wgeom)->height=(brwin)->rgeom.height;\ + }\ +} + +#define CLIP_DUMMY_POINTER_AREA(dummy_p_area,brwin,wgeom){\ + (wgeom)->x=((((dummy_p_area).x+(dummy_p_area).width>=(brwin)->rgeom.x)&&\ + ((dummy_p_area).x<=(brwin)->rgeom.x+(brwin)->rgeom.width))?\ + (((dummy_p_area).x<=(brwin)->rgeom.x)?(brwin)->rgeom.x:(dummy_p_area).x):-1);\ + (wgeom)->y=((((dummy_p_area).y+(dummy_p_area).height>=(brwin)->rgeom.y)&&\ + ((dummy_p_area).y<=(brwin)->rgeom.y+(brwin)->rgeom.height))?\ + (((dummy_p_area).y<=(brwin)->rgeom.y)?(brwin)->rgeom.y:(dummy_p_area).y):-1);\ + (wgeom)->width=((dummy_p_area).x<=(brwin)->rgeom.x)?\ + (dummy_p_area).width-((brwin)->rgeom.x-(dummy_p_area).x):\ + ((dummy_p_area).x<=(brwin)->rgeom.x+(brwin)->rgeom.width)?\ + ((brwin)->rgeom.width-(dummy_p_area).x+(brwin)->rgeom.x<(dummy_p_area).width)?\ + (brwin)->rgeom.width-(dummy_p_area).x+(brwin)->rgeom.x:(dummy_p_area).width:-1;\ + (wgeom)->height=((dummy_p_area).y<=(brwin)->rgeom.y)?\ + (dummy_p_area).height-((brwin)->rgeom.y-(dummy_p_area).y):\ + ((dummy_p_area).y<=(brwin)->rgeom.y+(brwin)->rgeom.height)?\ + ((brwin)->rgeom.height-(dummy_p_area).y+(brwin)->rgeom.y<(dummy_p_area).height)?\ + (brwin)->rgeom.height-(dummy_p_area).y+(brwin)->rgeom.y:(dummy_p_area).height:-1;\ + if((wgeom)->width>(brwin)->rgeom.width)(wgeom)->width=(brwin)->rgeom.width;\ + if((wgeom)->height>(brwin)->rgeom.height)(wgeom)->height=(brwin)->rgeom.height;\ +} + + + +#define DEFAULT_ARGS(args){\ + (args)->delay=0;\ + if(getenv("DISPLAY")!=NULL){\ + (args)->display=(char *)malloc(strlen(getenv("DISPLAY"))+1);\ + strcpy((args)->display,getenv("DISPLAY"));\ + }\ + else\ + (args)->display=NULL;\ + (args)->windowid=(args)->x=(args)->y\ + =(args)->width=(args)->height=(args)->quietmode\ + =(args)->nosound=(args)->scshot=(args)->full_shots=0;\ + (args)->noshared=(args)->scale_shot=1;\ + (args)->dropframes=(args)->nocondshared=0;\ + (args)->no_quick_subsample=1;\ + (args)->filename=(char *)malloc(8);\ + strcpy((args)->filename,"out.ogg");\ + (args)->encoding=OGG_THEORA_VORBIS;\ + (args)->cursor_color=1;\ + (args)->shared_thres=75;\ + (args)->have_dummy_cursor=0;\ + (args)->xfixes_cursor=1;\ + (args)->device=(char *)malloc(8);\ + strcpy((args)->device,"hw:0,0");\ + (args)->fps=15;\ + (args)->channels=1;\ + (args)->frequency=22050;\ + (args)->v_bitrate=45000;\ + (args)->v_quality=63;\ + (args)->s_quality=10;\ +} + +#define QUERY_DISPLAY_SPECS(display,specstruct){\ + (specstruct)->screen=DefaultScreen(display);\ + (specstruct)->width=DisplayWidth(display,(specstruct)->screen);\ + (specstruct)->height=DisplayHeight(display,(specstruct)->screen);\ + (specstruct)->root=RootWindow(display,(specstruct)->screen);\ + (specstruct)->visual=DefaultVisual(display,(specstruct)->screen);\ + (specstruct)->gc=DefaultGC(display,(specstruct)->screen);\ + (specstruct)->depth=DefaultDepth(display,(specstruct)->screen);\ + (specstruct)->bpixel=XBlackPixel(display,(specstruct)->screen);\ + (specstruct)->wpixel=XWhitePixel(display,(specstruct)->screen);\ +} + +#define AVG_4_PIXELS(data_array,width_img,k_tm,i_tm,offset)\ + ((data_array[(k_tm*width_img+i_tm)*4+offset]+data_array[((k_tm-1)*width_img+i_tm)*4+offset]\ + +data_array[(k_tm*width_img+i_tm-1)*4+offset]+data_array[((k_tm-1)*width_img+i_tm-1)*4+offset])/4) + +#define UPDATE_YUV_BUFFER_SH(yuv,data,x_tm,y_tm,width_tm,height_tm){\ + int i,k;\ + for(k=y_tm;ky[i+k*yuv->y_width]=Yr[data[(i+k*yuv->y_width)*4+__RBYTE]] + Yg[data[(i+k*yuv->y_width)*4+__GBYTE]] + Yb[data[(i+k*yuv->y_width)*4+__BBYTE]];\ + if((k%2)&&(i%2)){\ + yuv->u[i/2+k/2*yuv->uv_width]=Ur[data[(i+k*yuv->y_width)*4+__RBYTE]] + Ug[data[(i+k*yuv->y_width)*4+__GBYTE]] + Ub[data[(i+k*yuv->y_width)*4+__BBYTE]] ;\ + yuv->v[i/2+k/2*yuv->uv_width]=Vr[data[(i+k*yuv->y_width)*4+__RBYTE]] + Vg[data[(i+k*yuv->y_width)*4+__GBYTE]] + Vb[data[(i+k*yuv->y_width)*4+__BBYTE]] ;\ + }\ + }\ + }\ +} + +#define UPDATE_YUV_BUFFER_SH_AVG(yuv,data,x_tm,y_tm,width_tm,height_tm){\ + int i,k;\ + unsigned char avg0,avg1,avg2;\ + for(k=y_tm;ky[i+k*yuv->y_width]=Yr[data[(i+k*yuv->y_width)*4+__RBYTE]] + Yg[data[(i+k*yuv->y_width)*4+__GBYTE]] + Yb[data[(i+k*yuv->y_width)*4+__BBYTE]];\ + if((k%2)&&(i%2)){\ + avg2=AVG_4_PIXELS(data,(yuv->y_width),k,i,__RBYTE);\ + avg1=AVG_4_PIXELS(data,(yuv->y_width),k,i,__GBYTE);\ + avg0=AVG_4_PIXELS(data,(yuv->y_width),k,i,__BBYTE);\ + yuv->u[i/2+k/2*yuv->uv_width]=Ur[avg2] +\ + Ug[avg1] +\ + Ub[avg0] ;\ + yuv->v[i/2+k/2*yuv->uv_width]=Vr[avg2] +\ + Vg[avg1] +\ + Vb[avg0] ;\ + }\ + }\ + }\ +} + +#define UPDATE_YUV_BUFFER_IM(yuv,data,x_tm,y_tm,width_tm,height_tm){\ + int i,k,j=0;\ + int x_2=x_tm/2,y_2=y_tm/2;\ + for(k=0;ky[x_tm+i+(k+y_tm)*yuv->y_width]=Yr[data[(j*4)+__RBYTE]] + Yg[data[(j*4)+__GBYTE]] + Yb[data[(j*4)+__BBYTE]] ;\ + if((k%2)&&(i%2)){\ + yuv->u[x_2+i/2+(k/2+y_2)*yuv->uv_width]=\ + Ur[data[(k*width_tm+i)*4+__RBYTE]] + Ug[data[(k*width_tm+i)*4+__GBYTE]] + Ub[data[(k*width_tm+i)*4+__BBYTE]];\ + yuv->v[x_2+i/2+(k/2+y_2)*yuv->uv_width]=\ + Vr[data[(k*width_tm+i)*4+__RBYTE]] + Vg[data[(k*width_tm+i)*4+__GBYTE]] + Vb[data[(k*width_tm+i)*4+__BBYTE]];\ + }\ + \ + j++;\ + }\ + }\ +} + + + +#define UPDATE_YUV_BUFFER_IM_AVG(yuv,data,x_tm,y_tm,width_tm,height_tm){\ + int i,k,j=0;\ + unsigned char avg0,avg1,avg2;\ + int x_2=x_tm/2,y_2=y_tm/2;\ + for(k=0;ky[x_tm+i+(k+y_tm)*yuv->y_width]=Yr[data[(j*4)+__RBYTE]] + Yg[data[(j*4)+__GBYTE]] + Yb[data[(j*4)+__BBYTE]] ;\ + if((k%2)&&(i%2)){\ + avg2=AVG_4_PIXELS(data,width_tm,k,i,__RBYTE);\ + avg1=AVG_4_PIXELS(data,width_tm,k,i,__GBYTE);\ + avg0=AVG_4_PIXELS(data,width_tm,k,i,__BBYTE);\ + yuv->u[x_2+i/2+(k/2+y_2)*yuv->uv_width]=\ + Ur[avg2] + Ug[avg1] +\ + Ub[avg0];\ + yuv->v[x_2+i/2+(k/2+y_2)*yuv->uv_width]=\ + Vr[avg2] + Vg[avg1] +\ + Vb[avg0];\ + }\ + \ + j++;\ + }\ + }\ +} + +#define XFIXES_POINTER_TO_YUV(yuv,data,x_tm,y_tm,width_tm,height_tm,column_discard_stride){\ + int i,k,j=0;\ + unsigned char avg0,avg1,avg2,avg3;\ + int x_2=x_tm/2,y_2=y_tm/2;\ + for(k=0;ky[x_tm+i+(k+y_tm)*yuv->y_width]=\ + (yuv->y[x_tm+i+(k+y_tm)*yuv->y_width]*(UCHAR_MAX-data[(j*4)+__ABYTE])+\ + (Yr[data[(j*4)+__RBYTE]] + Yg[data[(j*4)+__GBYTE]] + Yb[data[(j*4)+__BBYTE]])*data[(j*4)+__ABYTE])/UCHAR_MAX ;\ + if((k%2)&&(i%2)){\ + avg3=AVG_4_PIXELS(data,(width_tm+column_discard_stride),k,i,__ABYTE);\ + avg2=AVG_4_PIXELS(data,(width_tm+column_discard_stride),k,i,__RBYTE);\ + avg1=AVG_4_PIXELS(data,(width_tm+column_discard_stride),k,i,__GBYTE);\ + avg0=AVG_4_PIXELS(data,(width_tm+column_discard_stride),k,i,__BBYTE);\ + yuv->u[x_2+i/2+(k/2+y_2)*yuv->uv_width]=\ + (yuv->u[x_2+i/2+(k/2+y_2)*yuv->uv_width]*(UCHAR_MAX-avg3)+\ + (Ur[avg2] + Ug[avg1] +Ub[avg0])*avg3)/UCHAR_MAX;\ + yuv->v[x_2+i/2+(k/2+y_2)*yuv->uv_width]=\ + (yuv->v[x_2+i/2+(k/2+y_2)*yuv->uv_width]*(UCHAR_MAX-avg3)+\ + (Vr[avg2] + Vg[avg1] +Vb[avg0])*avg3)/UCHAR_MAX;\ + }\ + j++;\ + }\ + j+=column_discard_stride;\ + }\ +} + +#define DUMMY_POINTER_TO_YUV(yuv,data_tm,x_tm,y_tm,width_tm,height_tm,no_pixel){\ + int i,k,j=0;\ + int x_2=x_tm/2,y_2=y_tm/2,y_width_2=(yuv)->y_width/2;\ + for(k=0;ky[x_tm+i+(k+y_tm)*(yuv)->y_width]=Yr[data_tm[(j*4)+__RBYTE]] + Yg[data_tm[(j*4)+__GBYTE]] + Yb[data_tm[(j*4)+__BBYTE]];\ + if((k%2)&&(i%2)){\ + yuv->u[x_2+i/2+(k/2+y_2)*y_width_2]=Ur[data_tm[(k*width_tm+i)*4+__RBYTE]] + Ug[data_tm[(k*width_tm+i)*4+__GBYTE]] + Ub[data_tm[(k*width_tm+i)*4+__BBYTE]];\ + yuv->v[x_2+i/2+(k/2+y_2)*y_width_2]=Vr[data_tm[(k*width_tm+i)*4+__RBYTE]] + Vg[data_tm[(k*width_tm+i)*4+__GBYTE]] + Vb[data_tm[(k*width_tm+i)*4+__BBYTE]] ;\ + }\ + }\ + j++;\ + }\ + j+=16-width_tm;\ + }\ +} + + +/**Function prototypes*/ + +void *PollDamage(void *pdata); +void *GetFrame(void *pdata); +void *EncodeImageBuffer(void *pdata); +void *FlushToOgg(void *pdata); +void UpdateYUVBuffer(yuv_buffer *yuv,unsigned char *data,int x,int y,int width,int height); +void ClearList(RectArea **root); +int RectInsert(RectArea **root,WGeometry *wgeom); +int CollideRects(WGeometry *wgeom1,WGeometry *wgeom2,WGeometry **wgeom_return,int *ngeoms); +void SetExpired(int signum); +void RegisterCallbacks(ProgArgs *args); +void UpdateImage(Display * dpy,yuv_buffer *yuv,pthread_mutex_t *yuv_mutex,DisplaySpecs *specs,RectArea **root,BRWindow *brwin,EncData *enc,char *datatemp,int noshmem,int no_quick_subsample); +int GetZPixmap(Display *dpy,Window root,char *data,int x,int y,int width,int height); +int ParseArgs(int argc,char **argv,ProgArgs *arg_return); +void QueryExtensions(Display *dpy,ProgArgs *args,int *damage_event,int *damage_error); +int SetBRWindow(Display *dpy,BRWindow *brwin,DisplaySpecs *specs,ProgArgs *args); +int ZPixmapToBMP(XImage *imgz,BRWindow *brwin,char *fname,int nbytes,int scale); +unsigned char *MakeDummyPointer(DisplaySpecs *specs,int size,int color,int type,unsigned char *npxl); +void *CaptureSound(void *pdata); +void *EncodeSoundBuffer(void *pdata); +snd_pcm_t *OpenDev(const char *pcm_dev,unsigned int *channels,unsigned int *frequency,snd_pcm_uframes_t *periodsize,unsigned int *periodtime,int *hardpause); +void InitEncoder(ProgData *pdata,EncData *enc_data_t); +void MakeMatrices(); +void SizePack2_8_16(int *start,int *size,int limit); +#endif + -- cgit v1.2.1