/****************************************************************************** * recordMyDesktop * ******************************************************************************* * * * Copyright (C) 2006,2007 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 RMDFUNC_H #define RMDFUNC_H 1 #ifdef HAVE_CONFIG_H #include #endif #include "rmdtypes.h" /**Function prototypes*/ /** * Loop calling XNextEvent.Retrieve and place on * list damage events that arive, create damage for new windows * and pickup key events for shortcuts. * \param pdata ProgData struct containing all program data */ void *PollEvents(ProgData *pdata); /** * Loop ,signal timer cond var,sleep-\ * ^ | * |________________________________/ * * * \param pdata ProgData struct containing all program data */ void *rmdTimer(ProgData *pdata); /** * Retrieve frame form xserver, and transform to a yuv buffer, * either directly(full shots) or by calling UpdateImage. * \param pdata ProgData struct containing all program data */ void *GetFrame(ProgData *pdata); /** * feed a yuv buffer to the theora encoder and submit outcome to * the ogg stream. * \param pdata ProgData struct containing all program data */ void *EncodeImageBuffer(ProgData *pdata); /** * Query theora and vorbis streams for ready packages and * flush them on the disk * \param pdata ProgData struct containing all program data */ void *FlushToOgg(ProgData *pdata); /** * Clean up a list of areas marked for update. * \param root Root entry of the list */ void ClearList(RectArea **root); /** * Insert a new rectangle on the list, making sure it doesn't overlap * with the existing ones * \param root Root entry of the list * * \param wgeom New area to be inserted * * \returns Number of insertions during operation * * \note This function is reentrant and recursive. The number * of insertions takes this into account. */ int RectInsert(RectArea **root,WGeometry *wgeom); /** * Collide two rectangles and dictate most sane action for insertion, * as well as provide the updated rectangle(s) * \param wgeom1 resident rectangle * * \param wgeom2 New rectangle * * \param wgeom_return Pointer to rectangles to be inserted * * \param ngeoms number of entries in wgeom_return * * \retval 0 No collision * * \retval 1 wgeom1 is covered by wgeom2 * * \retval 2 wgeom2 is covered by wgeom1 * * \retval -1 wgeom1 was broken (new is picked up in wgeom_return) * * \retval -2 wgeom2 was broken (new is picked up in wgeom_return) * * \retval -10 Grouping the two geoms is possible * */ int CollideRects(WGeometry *wgeom1, WGeometry *wgeom2, WGeometry **wgeom_return, int *ngeoms); /** * Set up all callbacks and signal handlers * \param pdata ProgData struct containing all program data */ void RegisterCallbacks(ProgArgs *args); /** * Retrieve and apply all changes, if xdamage is used. * * \param dpy Connection to the server * * \param yuv yuv_buffer that is to be modified * * \param specs DisplaySpecs struct with * information about the display to be recorded * * \param root Root entry of the list with damaged areas * * \param brwin BRWindow struct contaning the recording window specs * * \param enc Encoding options * * \param datatemp Buffer for pixel data to be * retrieved before placed on the yuv buffer * * \param noshmem don't use MIT_Shm extension * * \param no_quick_subsample Don't do quick subsampling * */ void UpdateImage(Display * dpy, yuv_buffer *yuv, DisplaySpecs *specs, RectArea **root, BRWindow *brwin, EncData *enc, char *datatemp, int noshmem, XShmSegmentInfo *shminfo, int shm_opcode, int no_quick_subsample); /** * Rerieve pixmap data from xserver * * \param dpy Connection to the server * * \param root root window of the display * * \param data (preallocated)buffer to place the data * * \param x x position of the screenshot * * \param y y position of the screenshot * * \param x x position of the screenshot * * \param width width of the screenshot * * \param height height position of the screenshot * * \returns 0 on Success 1 on Failure */ int GetZPixmap(Display *dpy, Window root, char *data, int x, int y, int width, int height); /** * Rerieve pixmap data from xserver through the MIT-Shm extension * * \param dpy Connection to the server * * \param root root window of the display * * \param shminfo Info for the shared memory segment * * \param shm_opcode Opcode of Shm extension * * \param data (preallocated)buffer to place the data * * \param x x position of the screenshot * * \param y y position of the screenshot * * \param x x position of the screenshot * * \param width width of the screenshot * * \param height height position of the screenshot * * \returns 0 on Success 1 on Failure */ int GetZPixmapSHM(Display *dpy, Window root, XShmSegmentInfo *shminfo, int shm_opcode, char *data, int x, int y, int width, int height); /** * Fill ProgArgs struct with arguments entered at execution * * \param argc argc as entered from main * * \param argv argv as entered from main * * \param arg_return ProgArgs struct to be filled with the options * * \returns 0 on Success 1 on Failure */ int ParseArgs(int argc,char **argv,ProgArgs *arg_return); /** * Check if needed extensions are present * * \param dpy Connection to the server * * \param args ProgArgs struct containing the user-set options * * \param damage_event gets filled with damage event number * * \param damage_error gets filled with damage error number * * \note Can be an exit point if extensions are not found */ void QueryExtensions(Display *dpy, ProgArgs *args, int *damage_event, int *damage_error, int *shm_opcode); /** * Check and align window size * * \param dpy Connection to the server * * \param brwin BRWindow struct contaning the initial and final window * * \param specs DisplaySpecs struct with * information about the display to be recorded * * \param args ProgArgs struct containing the user-set options * * \returns 0 on Success 1 on Failure */ int SetBRWindow(Display *dpy, BRWindow *brwin, DisplaySpecs *specs, ProgArgs *args); /** * Create an array containing the data for the dummy pointer * * \param specs DisplaySpecs struct with * information about the display to be recorded * * \param size Pointer size, always square, always 16.(exists only * for the possibility to create more dummy cursors) * \param color 0 white, 1 black * * \param type Always 0.(exists only for the possibility to create * more dummy cursors) * * \param npxl Return of pixel value that denotes non-drawing, while * applying the cursor on the target image * * \returns Pointer to pixel data of the cursor */ unsigned char *MakeDummyPointer(DisplaySpecs *specs, int size, int color, int type, unsigned char *npxl); /** * Sound capturing thread. Data are placed on a * list to be picked up by other threads. * * \param pdata ProgData struct containing all program data */ void *CaptureSound(ProgData *pdata); /** * Sound encoding thread. Picks up data from the buffer queue , * encodes and places them on the vorbis stream. * * \param pdata ProgData struct containing all program data */ void *EncodeSoundBuffer(ProgData *pdata); #ifdef HAVE_LIBASOUND /** * Try to open (alsa) sound device, with the desired parameters, * and place the obtained ones on their place * * \param pcm_dev name of the device * * \param channels desired number of channels * (gets modified with the acieved value) * * \param frequency desired frequency(gets modified with the acieved value) * * \param buffsize Size of buffer * * \param periodsize Size of a period(can be NULL) * * \param periodtime Duration of a period(can be NULL) * * \param hardpause Set to 1 when the device has to be stopped during pause * and to 0 when it supports pausing * (can be NULL) * * \returns snd_pcm_t handle on success, NULL on failure */ snd_pcm_t *OpenDev( const char *pcm_dev, unsigned int *channels, unsigned int *frequency, snd_pcm_uframes_t *buffsize, snd_pcm_uframes_t *periodsize, unsigned int *periodtime, int *hardpause); #else /** * Try to open (OSS) sound device, with the desired parameters. * * * \param pcm_dev name of the device * * \param channels desired number of channels * * \param frequency desired frequency * * * \returns file descriptor of open device,-1 on failure */ int OpenDev( const char *pcm_dev, unsigned int channels, unsigned int frequency); #endif /** * Initialize theora,vorbis encoders, and their respective ogg streams. * * \param pdata ProgData struct containing all program data * * \param enc_data_t Encoding options * * \param buffer_ready when 1, the yuv buffer must be preallocated * when 0 InitEncoder will alocate a new one * */ void InitEncoder(ProgData *pdata,EncData *enc_data_t,int buffer_ready); /** * Fill Yr,Yg,Yb,Ur,Ug.Ub,Vr,Vg,Vb arrays(globals) with values. */ void MakeMatrices(); /** *Align the recording window to a divisible by 2 pixel start and *and a size divisible by 16. * * \param start x or y of the recording window * * \param size width or height of the recording window * * \param limit width or height of the Display * * \note This is called separately for width and height. */ void SizePack2_8_16(int *start,int *size,int limit); /** * Image caching thread. Copies the yuv buffer, compares with the last one and * caches the result. * * \param pdata ProgData struct containing all program data * */ void *CacheImageBuffer(ProgData *pdata); /** * Initializes paths and everything else needed to start caching * * \param pdata ProgData struct containing all program data * * \param enc_data_t Encoding options * * \param cache_data_t Caching options * */ void InitCacheData(ProgData *pdata, EncData *enc_data_t, CacheData *cache_data_t); /** * Sound caching thread. Simply writes the pcm buffers on disk * * \param pdata ProgData struct containing all program data * */ void *CacheSoundBuffer(ProgData *pdata); /** * Cache loading and processing thread * * \param pdata ProgData struct containing all program data * */ void *LoadCache(ProgData *pdata); /** * As EncodeImageBuffer, only with the assumption that * this is not a thread on it's own * * \param pdata ProgData struct containing all program data * */ void SyncEncodeImageBuffer(ProgData *pdata); /** * As EncodeSoundBuffer, only with the assumption that * this is not a thread on it's own * * \param pdata ProgData struct containing all program data * */ void SyncEncodeSoundBuffer(ProgData *pdata,signed char *buff); /** *Check current running window manager. * * \param dpy Connection to the server * * \param root root window of the display * * \returns Window manager name */ char *rmdWMCheck(Display *dpy,Window root); /** *Construct an number postfixed name * * \param name base name * * \param newname modified name * * \n number to be used as a postfix * */ void CacheFileN(char *name,char **newname,int n); /** * Change file pointer to a new file while writting * (file name is incremented with CacheFileN) * * \param name base file name * * \param n number to be used as a postfix * * \param fp File pointer if compression is used(must be NULL otherwise) * * \param ucfp File pointer if compression is NOT used(must be NULL otherwise) * * \returns 0 on Success 1 on Failure */ int SwapCacheFilesWrite(char *name,int n,gzFile **fp,FILE **ucfp); /** * Change file pointer to a new file while reading * (file name is incremented with CacheFileN) * * \param name base file name * * \param n number to be used as a postfix * * \param fp File pointer if compression is used(must be NULL otherwise) * * \param ucfp File pointer if compression is NOT used(must be NULL otherwise) * * \returns 0 on Success 1 on Failure */ int SwapCacheFilesRead(char *name,int n,gzFile **fp,FILE **ucfp); /** * Delete all cache files * * \param cache_data_t Caching options(file names etc.) * * \returns 0 if all files and folders where deleted, 1 otherwise */ int PurgeCache(CacheData *cache_data_t,int sound); /** * Encode cache into an * ogg stream. * \param pdata ProgData struct containing all program data */ void EncodeCache(ProgData *pdata); /** * Launch and wait capture threads. * Also creates and waits the encoding threads when * encode-on-the-fly is enabled. * * \param pdata ProgData struct containing all program data */ void rmdThreads(ProgData *pdata); /** * initialize lists,mutexes,image buffers, take first screenshot, * and anything else needed before launching the capture threads. * * \param pdata ProgData struct containing all program data * * \param enc_data reference to enc_data structure * * \param cache_data reference to cache_data structure * * \returns 0 on success, other values must cause the program to exit */ int InitializeData(ProgData *pdata, EncData *enc_data, CacheData *cache_data); #ifdef HAVE_JACK_H /** * * Global Fuction Pointers To Jack API Calls * */ jack_client_t *(*jack_client_new_p)(const char *client_name); jack_nframes_t (*jack_get_sample_rate_p)(jack_client_t * client); int (*jack_set_buffer_size_p)(jack_client_t *client, jack_nframes_t nframes); jack_nframes_t (*jack_get_buffer_size_p)(jack_client_t *client); int (*jack_set_process_callback_p)(jack_client_t *client, JackProcessCallback process_callback, void *arg); void (*jack_on_shutdown_p)(jack_client_t *client, void(*function)(void *arg), void *arg); int (*jack_activate_p)(jack_client_t *client); int (*jack_client_close_p)(jack_client_t *client); void *(*jack_port_get_buffer_p)(jack_port_t *port,jack_nframes_t); jack_port_t *(*jack_port_register_p)(jack_client_t *client, const char *port_name, const char *port_type, unsigned long flags, unsigned long buffer_size); int (*jack_connect_p)(jack_client_t *client, const char *source_port, const char *destination_port); const char *(*jack_port_name_p)(const jack_port_t *port); int (*jack_port_name_size_p)(void); jack_ringbuffer_t *(*jack_ringbuffer_create_p)(size_t sz); void (*jack_ringbuffer_free_p)(jack_ringbuffer_t *rb); size_t (*jack_ringbuffer_read_p)(jack_ringbuffer_t *rb, char *dest, size_t cnt); size_t (*jack_ringbuffer_read_space_p)(const jack_ringbuffer_t *rb); size_t (*jack_ringbuffer_write_p)(jack_ringbuffer_t *rb, const char *src, size_t cnt); /** * End Of Function Pointers */ /** * Callback for capture through jack * * \param nframes Number of frames captured * * \param jdata_t Pointer to JackData struct containing port * and client information * * \returns Zero always */ int JackCapture(jack_nframes_t nframes,void *jdata_t); /** * Callback for jack server shutdown * * \param jdata_t Pointer to JackData struct containing port * and client information */ void JackShutdown(void *jdata_t); /** * Register and Activate specified ports * * \param jdata_t Pointer to JackData struct containing port * and client information * * \returns 0 on Success, 1 on failure */ int SetupPorts(JackData *jdata); /** * dlopen libjack and dlsym all needed functions * * \param jack_lib_handle Pointer to handle for jack library * * \returns 0 on Success, 1 on failure */ int LoadJackLib(void *jack_lib_handle); /** * Load libjack, create and activate client,register ports * * \param jdata_t Pointer to JackData struct containing port * and client information * * \returns 0 on Success, error code on failure * (depending on where the error occured) */ int StartJackClient(JackData *jdata); /** * Close Jack Client * * \param jdata_t Pointer to JackData struct containing port * and client information * * \returns 0 on Success, 1 on failure */ int StopJackClient(JackData *jdata); #endif /** * Extract cache blocks from damage list * * \param root Root entry of the list with damaged areas * * \param x_offset left x of the recording area * * \param x_offset upper y of the recording area * * \param blocknum_x Width of image in blocks * * \param blocknum_y Height of image in blocks */ void BlocksFromList(RectArea **root, unsigned int x_offset, unsigned int y_offset, unsigned int blocknum_x, unsigned int blocknum_y); /** * Currently only frees some memory * (y,u,v blocks) * * */ void CleanUp(void); /* * Check a shortcut combination and if valid, * register it, on the root window. * * \param dpy Connection to the X Server * * \param root Root window id * * \param shortcut String represantation of the shortcut * * \param HotKey Pre-allocated struct that is filled with the * modifiers and the keycode, for checks on incoming * keypress events. Left untouched if the call fails. * * * \returns 0 on Success, 1 on Failure. * */ int RegisterShortcut(Display *dpy, Window root, const char *shortcut, HotKey *hotkey); /* * Handling of X errors. * Ignores, bad access when registering shortcuts * and BadWindow on XQueryTree * * \param dpy Connection to the X Server * * \param e XErrorEvent struct containing error info * * \returns 0 on the two ignored cases, calls exit(1) * otherwise. * */ int rmdErrorHandler(Display *dpy,XErrorEvent *e); /* * Create a frame that marks the recording area. * * \param dpy Connection to the X Server * * \param screen Recorded screen * * \param root Root window of the display * * \param x X pos of the recorded area * * \param y Y pos of the recorded area * * \param width Width of the recorded area * * \param height Height of the recorded area * * \returns The WindowID of the frame * */ Window rmdFrameInit(Display *dpy, int screen, Window root, int x, int y, int width, int height); /* * Move the frame (subtracts the borderwidth) * * \param dpy Connection to the X Server * * \param win WindowId of the frame * * \param x New X pos of the recorded area * * \param y New Y pos of the recorded area * */ void rmdMoveFrame(Display *dpy, Window win, int x, int y); /* * Redraw the frame that marks the recording area. * * \param dpy Connection to the X Server * * \param screen Recorded screen * * \param win WindoID of the frame * * \param width Width of the recorded area * * \param height Height of the recorded area * */ void rmdDrawFrame(Display *dpy, int screen, Window win, int width, int height); /* * Create a text file that holds the required * capture attributes, in the cache directory. * * \param pdata ProgData struct containing all program data * * \returns 0 on Success, 1 on failure * */ int WriteSpecsFile(ProgData *pdata); /* * Read the text file that holds the required * capture attributes, in the cache directory. * * \param pdata ProgData struct that will be fille * with all program data * * \returns 0 on Success, 1 on failure * */ int ReadSpecsFile(ProgData *pdata); /* * Restore a previous recording, found in * the given path. * * \param path Path to the cache folder. * * \returns 0 on Success, 1 on failure * */ int rmdRestore(const char *path); #endif