~ubuntu-branches/ubuntu/karmic/recordmydesktop/karmic

« back to all changes in this revision

Viewing changes to include/recordmydesktop.h

  • Committer: Bazaar Package Importer
  • Author(s): José L. Redrejo Rodríguez
  • Date: 2007-04-25 11:54:22 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20070425115422-5jvf144ln0c44afr
Tags: 0.3.4-1
* New upstream release
* debian/control: conflicts with previous gtk-recordmydesktop versions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*********************************************************************************
2
 
*                             recordMyDesktop                                    *
3
 
**********************************************************************************
4
 
*                                                                                *
5
 
*             Copyright (C) 2006  John Varouhakis                                *
6
 
*                                                                                *
7
 
*                                                                                *
8
 
*    This program is free software; you can redistribute it and/or modify        *
9
 
*    it under the terms of the GNU General Public License as published by        *
10
 
*    the Free Software Foundation; either version 2 of the License, or           *
11
 
*    (at your option) any later version.                                         *
12
 
*                                                                                *
13
 
*    This program is distributed in the hope that it will be useful,             *
14
 
*    but WITHOUT ANY WARRANTY; without even the implied warranty of              *
15
 
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               *
16
 
*    GNU General Public License for more details.                                *
17
 
*                                                                                *
18
 
*    You should have received a copy of the GNU General Public License           *
19
 
*    along with this program; if not, write to the Free Software                 *
20
 
*    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   *
21
 
*                                                                                *
22
 
*                                                                                *
23
 
*                                                                                *
24
 
*    For further information contact me at johnvarouhakis@gmail.com              *
25
 
**********************************************************************************/
 
1
/******************************************************************************
 
2
*                            recordMyDesktop                                  *
 
3
*******************************************************************************
 
4
*                                                                             *
 
5
*            Copyright (C) 2006,2007 John Varouhakis                          *
 
6
*                                                                             *
 
7
*                                                                             *
 
8
*   This program is free software; you can redistribute it and/or modify      *
 
9
*   it under the terms of the GNU General Public License as published by      *
 
10
*   the Free Software Foundation; either version 2 of the License, or         *
 
11
*   (at your option) any later version.                                       *
 
12
*                                                                             *
 
13
*   This program is distributed in the hope that it will be useful,           *
 
14
*   but WITHOUT ANY WARRANTY; without even the implied warranty of            *
 
15
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
 
16
*   GNU General Public License for more details.                              *
 
17
*                                                                             *
 
18
*   You should have received a copy of the GNU General Public License         *
 
19
*   along with this program; if not, write to the Free Software               *
 
20
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA  *
 
21
*                                                                             *
 
22
*                                                                             *
 
23
*                                                                             *
 
24
*   For further information contact me at johnvarouhakis@gmail.com            *
 
25
******************************************************************************/
26
26
 
27
27
 
28
28
#ifndef RECORDMYDESKTOP_H
32
32
    #include <config.h>
33
33
#endif
34
34
 
35
 
#include <stdio.h>
36
 
#include <stdlib.h>
37
 
#include <string.h>
38
 
#include <errno.h>
39
 
#include <math.h>
40
 
#include <unistd.h>
41
 
#include <fcntl.h>
42
 
#include <time.h>
43
 
#include <signal.h>
44
 
#include <sys/time.h>
45
 
#include <sys/types.h>
46
 
#include <endian.h>
47
 
#include <limits.h>
48
 
#include <sys/stat.h>
49
 
#include <sys/ipc.h>
50
 
#include <sys/shm.h>
51
 
#include <pthread.h>
52
 
#include <zlib.h>
53
 
#include <X11/Xlib.h>
54
 
#include <X11/Xlibint.h>
55
 
#include <X11/Xatom.h>
56
 
#include <X11/extensions/Xfixes.h>
57
 
#include <X11/extensions/Xdamage.h>
58
 
#include <X11/extensions/XShm.h>
59
 
#include <theora/theora.h>
60
 
#include <vorbis/codec.h>
61
 
#include <vorbis/vorbisenc.h>
62
 
#include <ogg/ogg.h>
63
 
#include <alsa/asoundlib.h>
64
 
 
65
 
 
66
 
//define whcih way we are reading a pixmap
67
 
#if __BYTE_ORDER == __LITTLE_ENDIAN
68
 
#define __ABYTE 3
69
 
#define __RBYTE 2
70
 
#define __GBYTE 1
71
 
#define __BBYTE 0
72
 
 
73
 
#elif __BYTE_ORDER == __BIG_ENDIAN
74
 
 
75
 
#define __ABYTE 0
76
 
#define __RBYTE 1
77
 
#define __GBYTE 2
78
 
#define __BBYTE 3
79
 
 
80
 
#else
81
 
#error Only little-endian and big-endian systems are supported
82
 
#endif
83
 
 
84
 
#define __RVALUE(tmp_val) (((tmp_val)&0x00ff0000)>>16)
85
 
#define __GVALUE(tmp_val) (((tmp_val)&0x0000ff00)>>8)
86
 
#define __BVALUE(tmp_val) (((tmp_val)&0x000000ff))
87
 
 
88
 
//500 mb file size
89
 
#define CACHE_FILE_SIZE_LIMIT (500*1<<20)
90
 
 
91
 
 
92
 
 
93
 
/**Structs*/
94
 
 
95
 
typedef struct _DisplaySpecs{   //this struct holds some basic information
96
 
    int screen;                 //about the display,needed mostly for
97
 
    uint width;                 //validity checks at startup
98
 
    uint height;
99
 
    Window root;
100
 
    Visual *visual;
101
 
    GC gc;
102
 
    int depth;
103
 
    unsigned long bpixel;
104
 
    unsigned long wpixel;
105
 
}DisplaySpecs;
106
 
 
107
 
typedef struct _WGeometry{  //basic geometry of a window or area
108
 
    int x;
109
 
    int y;
110
 
    int width;
111
 
    int height;
112
 
}WGeometry;
113
 
 
114
 
typedef struct _RectArea{   //an area that has been damaged gets stored
115
 
    WGeometry geom;         //in a list comprised of structs of this type
116
 
    struct _RectArea *prev,*next;
117
 
}RectArea;
118
 
 
119
 
typedef struct _BRWindow{   //'basic recorded window' specs
120
 
    WGeometry geom;         //window attributes
121
 
    WGeometry rgeom;        //part of window that is recorded
122
 
    int nbytes;             //size of zpixmap when screenshoting
123
 
    Window windowid;           //id
124
 
}BRWindow;
125
 
 
126
 
//defaults in the following comment lines may be out of sync with reality
127
 
//check DEFAULT_ARGS macro further bellow
128
 
typedef struct _ProgArgs{
129
 
    int delay;          //start up delay
130
 
    Window windowid;    //window to record(default root)
131
 
    char *display;      //display to connect(default :0)
132
 
    int x,y;            //x,y offset(default 0,0)
133
 
    int width,height;   //defaults to window width and height
134
 
    int quietmode;      //no messages to stderr,stdout
135
 
    char *filename;     //output file(default out.[ogg|*])
136
 
    int cursor_color;   //black or white=>1 or 0
137
 
    int have_dummy_cursor;//disable/enable drawing of the dummy cursor
138
 
    int xfixes_cursor;   //disable/enable drawing of a cursor obtained
139
 
                        //through the xfixes extension
140
 
    float fps;            //desired framerate(default 15)
141
 
    unsigned int frequency;      //desired frequency (default 22050)
142
 
    unsigned int channels;       //no of channels(default 2)
143
 
    char *device;       //default sound device(default according to alsa or oss)
144
 
    snd_pcm_uframes_t buffsize;//buffer size(in frames) for sound capturing
145
 
    int nosound;        //do not record sound(default 0)
146
 
    int noshared;       //do not use shared memory extension(default 1)
147
 
    int nocondshared;   //do not use shared memory on large image aquititions
148
 
    int nowmcheck;      //do not check if there's a 3d comp window manager
149
 
                        //(which changes full-shots and with-shared to 1)
150
 
    int shared_thres;   //threshold to use shared memory
151
 
    int full_shots;     //do not poll damage, take full screenshots
152
 
    int no_quick_subsample;//average pixels in chroma planes
153
 
    int v_bitrate,v_quality,s_quality;//video bitrate,video-sound quality
154
 
    int dropframes;     //option for theora encoder
155
 
    int encOnTheFly;    //encode while recording, no caching(default 0)
156
 
    char *workdir;      //directory to be used for cache files(default $HOME)
157
 
    int zerocompression;//image data are always flushed uncompressed
158
 
    int overwrite;//overwite a previously existing file(do not add a .number postfix)
159
 
}ProgArgs;
160
 
 
161
 
 
162
 
//this struct holds anything related to encoding AND
163
 
//writting out to file.
164
 
typedef struct _EncData{
165
 
    ogg_stream_state m_ogg_ts;//theora
166
 
    ogg_stream_state m_ogg_vs;//vorbis
167
 
    ogg_page         m_ogg_pg;//this could be avoided since
168
 
                              // it is used only while initializing
169
 
    ogg_packet       m_ogg_pckt1;//theora stream
170
 
    ogg_packet       m_ogg_pckt2;//vorbis stream
171
 
//theora data
172
 
    theora_state     m_th_st;
173
 
    theora_info      m_th_inf;
174
 
    theora_comment   m_th_cmmnt;
175
 
    yuv_buffer       yuv;
176
 
//vorbis data
177
 
    vorbis_info      m_vo_inf;
178
 
    vorbis_comment   m_vo_cmmnt;
179
 
    vorbis_dsp_state m_vo_dsp;
180
 
    vorbis_block     m_vo_block;
181
 
//these should be 0, since area is quantized
182
 
//before input
183
 
    int             x_offset,
184
 
                    y_offset;
185
 
//our file
186
 
    FILE            *fp;
187
 
}EncData;
188
 
 
189
 
//this struct will hold a few basic
190
 
//information, needed for caching the frames.
191
 
typedef struct _CacheData{
192
 
    char    *workdir,  //The directory were the project will be stored, while recording.
193
 
                        //Since this will take a lot of space, the user must be
194
 
                        //able to change the location.
195
 
            *projname,  //This is the name of the folder that will hold the project.
196
 
                        //It is rMD-session-%d where %d is the pid of the current proccess.
197
 
                        //This way, running two instances will not create problems
198
 
                        //and also, a frontend can identify leftovers from a possible crash
199
 
                        //and delete them
200
 
            *imgdata,   //workdir+projname+img.out.gz
201
 
            *audiodata; //workdir+projname+audio.pcm
202
 
 
203
 
    gzFile  *ifp;       //image data file pointer
204
 
    FILE    *uncifp;    //uncompressed image data file pointer
205
 
 
206
 
    FILE    *afp;       //audio data file pointer
207
 
 
208
 
}CacheData;
209
 
 
210
 
//sound buffer
211
 
//sound keeps coming so we que it in this list
212
 
//which we then traverse
213
 
typedef struct _SndBuffer{
214
 
    signed char *data;
215
 
    struct _SndBuffer *next;
216
 
}SndBuffer;
217
 
 
218
 
//this structure holds any data related to the program
219
 
//It's usage is mostly to be given as an argument to the
220
 
//threads,so they will have access to the program data, avoiding
221
 
//at the same time usage of any globals.
222
 
typedef struct _ProgData{
223
 
    ProgArgs args;//the program arguments
224
 
    DisplaySpecs specs;//Display specific information
225
 
    BRWindow brwin;//recording window
226
 
    Display *dpy;//curtrent display
227
 
    char *window_manager;//name of the window manager at program launch
228
 
    XImage *image;//the image that holds the current full screenshot
229
 
    XImage *shimage;//the image that holds the current full screenshot(shared memory)
230
 
    unsigned char *dummy_pointer;//a dummy pointer to be drawn in every frame
231
 
                                //data is casted to unsigned for later use in YUV buffer
232
 
    int dummy_p_size;//initially 16x16,always square
233
 
    unsigned char npxl;//this is the no pixel convention when drawing the dummy pointer
234
 
    char    *datamain,//the data of  image
235
 
            *datash,//the data of shimage
236
 
            *datatemp;//buffer for the temporary image,which will be
237
 
                      //preallocated in case shared memory is not used.
238
 
    RectArea *rect_root[2];//the interchanging list roots for storing the changed regions
239
 
    int list_selector,//selector for the above
240
 
        damage_event,//damage event base code
241
 
        damage_error,//damage error base code
242
 
        running;
243
 
    SndBuffer *sound_buffer;
244
 
    EncData *enc_data;
245
 
    CacheData *cache_data;
246
 
    int hard_pause;//if sound device doesn't support pause
247
 
                    //we have to close and reopen
248
 
    int avd;//syncronization among audio and video
249
 
    unsigned int periodtime,
250
 
                frametime;
251
 
    pthread_mutex_t list_mutex[2],//mutexes for concurrency protection of the lists
252
 
                    sound_buffer_mutex,
253
 
                    libogg_mutex,//libogg is not thread safe,
254
 
//                     libtheora_mutex,//same for libtheora
255
 
//                     libvorbis_mutex,//and libvorbis.
256
 
                    yuv_mutex;//this might not be needed since we only have
257
 
                              //one read-only and  one write-only thread
258
 
                              //also on previous versions, y component was looped separately
259
 
                              //and then u and v so this was needed to avoid wrong coloring to render
260
 
                              //Currently this mutex only prevents the cursor from flickering
261
 
    pthread_cond_t  time_cond,//this gets a broadcast by the handler whenever it's time to get a screenshot
262
 
                    pause_cond,//this is blocks execution, when program is paused
263
 
                    sound_buffer_ready,//sound encoding finished
264
 
                    sound_data_read,//a buffer is ready for proccessing
265
 
                    image_buffer_ready,//image encoding finished
266
 
                    theora_lib_clean,//the flush_ogg thread cannot procceed to creating last
267
 
                    vorbis_lib_clean;//packages until these two libs are no longer used, by other threads
268
 
    int th_encoding_clean,//these indicate a wait condition on the above cond vars
269
 
        v_encoding_clean;
270
 
    int v_enc_thread_waiting,
271
 
        th_enc_thread_waiting;
272
 
    snd_pcm_t *sound_handle;
273
 
    snd_pcm_uframes_t periodsize;
274
 
}ProgData;
275
 
 
276
 
 
277
 
//This is the header of every frame.
278
 
//Reconstruction will be correct only if made on
279
 
//the same platform.
280
 
 
281
 
//We need the total number of blocks
282
 
//for each plane.
283
 
 
284
 
//The number of the frame compared to the
285
 
//number of time expirations at the time of
286
 
//caching, will enable us to make up for lost frames.
287
 
 
288
 
//default 4+4+2+2+2=14!bad!
289
 
//me add pad, make god of 2 happy!
290
 
typedef struct _FrameHeader{
291
 
    char        frame_prefix[4];//always FRAM
292
 
    u_int32_t   frameno,//number of frame(cached frames)
293
 
                current_total;//number of frames that should have been
294
 
                                  //taken at time of caching this one
295
 
    u_int16_t   Ynum,//number of changed blocks in the Y plane
296
 
                Unum,//number of changed blocks in the U plane
297
 
                Vnum;//number of changed blocks in the V plane
298
 
    u_int16_t   pad;//always zero
299
 
 
300
 
}FrameHeader;
301
 
 
302
 
//The frame after retrieval.
303
 
//Based on the Header information
304
 
//we can read the correct amount of bytes.
305
 
 
306
 
 
307
 
typedef struct _CachedFrame{
308
 
    FrameHeader *header;
309
 
    unsigned char *YBlocks;//identifying number on the grid, starting at top left
310
 
    unsigned char *UBlocks;//       >>      >>
311
 
    unsigned char *VBlocks;//       >>      >>
312
 
    unsigned char *YData;//pointer to data for the blocks that have changed,
313
 
    unsigned char *UData;//which have to be remapped on the buffer when reading
314
 
    unsigned char *VData;
315
 
}CachedFrame;
 
35
#include "rmdtypes.h"
 
36
#include "rmdmacro.h"
 
37
#include "rmdfunc.h"
 
38
 
316
39
 
317
40
 
318
41
/**Globals*/
320
43
 
321
44
int Paused,*Running,Aborted;
322
45
pthread_cond_t  *time_cond,*pause_cond;
 
46
pthread_mutex_t pause_mutex,time_mutex;
323
47
unsigned char   Yr[256],Yg[256],Yb[256],
324
48
                Ur[256],Ug[256],Ub[256],
325
49
                Vr[256],Vg[256],Vb[256];
326
50
//the following values are of no effect
327
51
//but they might be usefull later for profiling
328
 
unsigned int    frames_total,//frames calculated by total time expirations
329
 
                frames_lost;//the value of shame
 
52
unsigned int    frames_total,   //frames calculated by total time expirations
 
53
                frames_lost;    //the value of shame
330
54
//used to determine frame drop which can
331
55
//happen on failure to receive a signal over a condition variable
332
56
int capture_busy,
333
57
    encoder_busy;
334
58
 
335
59
 
336
 
/**Macros*/
337
 
 
338
 
#define CLIP_EVENT_AREA(e,brwin,wgeom){\
339
 
    if(((e)->area.x<=(brwin)->rgeom.x)&&((e)->area.y<=(brwin)->rgeom.y)&&\
340
 
        ((e)->area.width>=(brwin)->rgeom.width)&&((e)->area.height<(brwin)->rgeom.height)){\
341
 
        (wgeom)->x=(brwin)->rgeom.x;\
342
 
        (wgeom)->y=(brwin)->rgeom.y;\
343
 
        (wgeom)->width=(brwin)->rgeom.width;\
344
 
        (wgeom)->height=(brwin)->rgeom.height;\
345
 
    }\
346
 
    else{\
347
 
        (wgeom)->x=((((e)->area.x+(e)->area.width>=(brwin)->rgeom.x)&&\
348
 
        ((e)->area.x<=(brwin)->rgeom.x+(brwin)->rgeom.width))?\
349
 
        (((e)->area.x<=(brwin)->rgeom.x)?(brwin)->rgeom.x:(e)->area.x):-1);\
350
 
    \
351
 
        (wgeom)->y=((((e)->area.y+(e)->area.height>=(brwin)->rgeom.y)&&\
352
 
        ((e)->area.y<=(brwin)->rgeom.y+(brwin)->rgeom.height))?\
353
 
        (((e)->area.y<=(brwin)->rgeom.y)?(brwin)->rgeom.y:(e)->area.y):-1);\
354
 
    \
355
 
        (wgeom)->width=((e)->area.x<=(brwin)->rgeom.x)?\
356
 
        (e)->area.width-((brwin)->rgeom.x-(e)->area.x):\
357
 
        ((e)->area.x<=(brwin)->rgeom.x+(brwin)->rgeom.width)?\
358
 
        (((brwin)->rgeom.width-(e)->area.x+(brwin)->rgeom.x<(e)->area.width)?\
359
 
        (brwin)->rgeom.width-(e)->area.x+(brwin)->rgeom.x:e->area.width):-1;\
360
 
    \
361
 
        (wgeom)->height=((e)->area.y<=(brwin)->rgeom.y)?\
362
 
        (e)->area.height-((brwin)->rgeom.y-(e)->area.y):\
363
 
        ((e)->area.y<=(brwin)->rgeom.y+(brwin)->rgeom.height)?\
364
 
        (((brwin)->rgeom.height-(e)->area.y+(brwin)->rgeom.y<(e)->area.height)?\
365
 
        (brwin)->rgeom.height-(e)->area.y+(brwin)->rgeom.y:(e)->area.height):-1;\
366
 
    \
367
 
        if((wgeom)->width>(brwin)->rgeom.width)(wgeom)->width=(brwin)->rgeom.width;\
368
 
        if((wgeom)->height>(brwin)->rgeom.height)(wgeom)->height=(brwin)->rgeom.height;\
369
 
    }\
370
 
}
371
 
 
372
 
#define CLIP_DUMMY_POINTER_AREA(dummy_p_area,brwin,wgeom){\
373
 
    (wgeom)->x=((((dummy_p_area).x+(dummy_p_area).width>=(brwin)->rgeom.x)&&\
374
 
    ((dummy_p_area).x<=(brwin)->rgeom.x+(brwin)->rgeom.width))?\
375
 
    (((dummy_p_area).x<=(brwin)->rgeom.x)?(brwin)->rgeom.x:(dummy_p_area).x):-1);\
376
 
    (wgeom)->y=((((dummy_p_area).y+(dummy_p_area).height>=(brwin)->rgeom.y)&&\
377
 
    ((dummy_p_area).y<=(brwin)->rgeom.y+(brwin)->rgeom.height))?\
378
 
    (((dummy_p_area).y<=(brwin)->rgeom.y)?(brwin)->rgeom.y:(dummy_p_area).y):-1);\
379
 
    (wgeom)->width=((dummy_p_area).x<=(brwin)->rgeom.x)?\
380
 
    (dummy_p_area).width-((brwin)->rgeom.x-(dummy_p_area).x):\
381
 
    ((dummy_p_area).x<=(brwin)->rgeom.x+(brwin)->rgeom.width)?\
382
 
    ((brwin)->rgeom.width-(dummy_p_area).x+(brwin)->rgeom.x<(dummy_p_area).width)?\
383
 
    (brwin)->rgeom.width-(dummy_p_area).x+(brwin)->rgeom.x:(dummy_p_area).width:-1;\
384
 
    (wgeom)->height=((dummy_p_area).y<=(brwin)->rgeom.y)?\
385
 
    (dummy_p_area).height-((brwin)->rgeom.y-(dummy_p_area).y):\
386
 
    ((dummy_p_area).y<=(brwin)->rgeom.y+(brwin)->rgeom.height)?\
387
 
    ((brwin)->rgeom.height-(dummy_p_area).y+(brwin)->rgeom.y<(dummy_p_area).height)?\
388
 
    (brwin)->rgeom.height-(dummy_p_area).y+(brwin)->rgeom.y:(dummy_p_area).height:-1;\
389
 
    if((wgeom)->width>(brwin)->rgeom.width)(wgeom)->width=(brwin)->rgeom.width;\
390
 
    if((wgeom)->height>(brwin)->rgeom.height)(wgeom)->height=(brwin)->rgeom.height;\
391
 
}
392
 
 
393
 
 
394
 
 
395
 
#define DEFAULT_ARGS(args){\
396
 
    (args)->delay=0;\
397
 
    if(getenv("DISPLAY")!=NULL){\
398
 
        (args)->display=(char *)malloc(strlen(getenv("DISPLAY"))+1);\
399
 
        strcpy((args)->display,getenv("DISPLAY"));\
400
 
    }\
401
 
    else\
402
 
        (args)->display=NULL;\
403
 
    (args)->windowid=\
404
 
    (args)->x=\
405
 
    (args)->y=\
406
 
    (args)->width=\
407
 
    (args)->height=\
408
 
    (args)->quietmode=\
409
 
    (args)->nosound=\
410
 
    (args)->full_shots=\
411
 
    (args)->encOnTheFly=\
412
 
    (args)->zerocompression=\
413
 
    (args)->nowmcheck=\
414
 
    (args)->dropframes=\
415
 
    (args)->overwrite=\
416
 
    (args)->nocondshared=0;\
417
 
    (args)->no_quick_subsample=\
418
 
    (args)->noshared=1;\
419
 
    (args)->filename=(char *)malloc(8);\
420
 
    strcpy((args)->filename,"out.ogg");\
421
 
    (args)->cursor_color=1;\
422
 
    (args)->shared_thres=75;\
423
 
    (args)->have_dummy_cursor=0;\
424
 
    (args)->xfixes_cursor=1;\
425
 
    (args)->device=(char *)malloc(8);\
426
 
    strcpy((args)->device,"hw:0,0");\
427
 
    (args)->fps=15;\
428
 
    (args)->channels=1;\
429
 
    (args)->frequency=22050;\
430
 
    (args)->buffsize=4096;\
431
 
    (args)->v_bitrate=45000;\
432
 
    (args)->v_quality=63;\
433
 
    (args)->s_quality=10;\
434
 
    (args)->workdir=(char *)malloc(5);\
435
 
    strcpy((args)->workdir,"/tmp");\
436
 
}
437
 
 
438
 
#define QUERY_DISPLAY_SPECS(display,specstruct){\
439
 
    (specstruct)->screen=DefaultScreen(display);\
440
 
    (specstruct)->width=DisplayWidth(display,(specstruct)->screen);\
441
 
    (specstruct)->height=DisplayHeight(display,(specstruct)->screen);\
442
 
    (specstruct)->root=RootWindow(display,(specstruct)->screen);\
443
 
    (specstruct)->visual=DefaultVisual(display,(specstruct)->screen);\
444
 
    (specstruct)->gc=DefaultGC(display,(specstruct)->screen);\
445
 
    (specstruct)->depth=DefaultDepth(display,(specstruct)->screen);\
446
 
    (specstruct)->bpixel=XBlackPixel(display,(specstruct)->screen);\
447
 
    (specstruct)->wpixel=XWhitePixel(display,(specstruct)->screen);\
448
 
}
449
 
 
450
 
#define AVG_4_PIXELS(data_array,width_img,k_tm,i_tm,offset)\
451
 
    ((data_array[(k_tm*width_img+i_tm)*4+offset]+data_array[((k_tm-1)*width_img+i_tm)*4+offset]\
452
 
    +data_array[(k_tm*width_img+i_tm-1)*4+offset]+data_array[((k_tm-1)*width_img+i_tm-1)*4+offset])/4)
453
 
 
454
 
#define UPDATE_YUV_BUFFER_SH(yuv,data,x_tm,y_tm,width_tm,height_tm){\
455
 
    int k,i;\
456
 
    register unsigned int t_val;\
457
 
    register unsigned int *datapi=(unsigned int*)data+x_tm+y_tm*yuv->y_width;\
458
 
    register unsigned char  *yuv_y=yuv->y+x_tm+y_tm*yuv->y_width,\
459
 
                            *yuv_u=yuv->u+x_tm/2+(y_tm*yuv->uv_width)/2,\
460
 
                            *yuv_v=yuv->v+x_tm/2+(y_tm*yuv->uv_width)/2,\
461
 
                            *_yr=Yr,*_yg=Yg,*_yb=Yb,\
462
 
                            *_ur=Ur,*_ug=Ug,*_ub=Ub,\
463
 
                            *_vr=Vr,*_vg=Vg,*_vb=Vb;\
464
 
\
465
 
    for(k=0;k<height_tm;k++){\
466
 
        for(i=0;i<width_tm;i++){\
467
 
            t_val=*datapi;\
468
 
            *yuv_y=_yr[__RVALUE(t_val)] + _yg[__GVALUE(t_val)] + _yb[__BVALUE(t_val)] ;\
469
 
            datapi++;\
470
 
            yuv_y++;\
471
 
        }\
472
 
        yuv_y+=yuv->y_width-width_tm;\
473
 
        datapi+=yuv->y_width-width_tm;\
474
 
    }\
475
 
    datapi=(unsigned int*)data+x_tm+y_tm*yuv->y_width;\
476
 
    for(k=0;k<height_tm;k+=2){\
477
 
        for(i=0;i<width_tm;i+=2){\
478
 
            t_val=*datapi;\
479
 
            *yuv_u=\
480
 
            _ur[__RVALUE(t_val)] + _ug[__GVALUE(t_val)] + _ub[__BVALUE(t_val)];\
481
 
            *yuv_v=\
482
 
            _vr[__RVALUE(t_val)] + _vg[__GVALUE(t_val)] + _vb[__BVALUE(t_val)];\
483
 
            datapi+=2;\
484
 
            yuv_u++;\
485
 
            yuv_v++;\
486
 
        }\
487
 
        yuv_u+=(yuv->y_width-width_tm)/2;\
488
 
        yuv_v+=(yuv->y_width-width_tm)/2;\
489
 
        datapi+=(2*yuv->y_width-width_tm);\
490
 
    }\
491
 
}
492
 
 
493
 
#define UPDATE_YUV_BUFFER_SH_AVG(yuv,data,x_tm,y_tm,width_tm,height_tm){\
494
 
    int k,i;\
495
 
    register unsigned int t_val,t1,t2,t3,t4;\
496
 
    register unsigned int *datapi=(unsigned int*)data+x_tm+y_tm*yuv->y_width,\
497
 
                          *datapi_next=(unsigned int*)data+x_tm+(y_tm+1)*yuv->y_width;\
498
 
    register unsigned char  *yuv_y=yuv->y+x_tm+y_tm*yuv->y_width,\
499
 
                            *yuv_u=yuv->u+x_tm/2+(y_tm*yuv->uv_width)/2,\
500
 
                            *yuv_v=yuv->v+x_tm/2+(y_tm*yuv->uv_width)/2,\
501
 
                            *_yr=Yr,*_yg=Yg,*_yb=Yb,\
502
 
                            *_ur=Ur,*_ug=Ug,*_ub=Ub,\
503
 
                            *_vr=Vr,*_vg=Vg,*_vb=Vb;\
504
 
\
505
 
    for(k=0;k<height_tm;k++){\
506
 
        for(i=0;i<width_tm;i++){\
507
 
            t_val=*datapi;\
508
 
            *yuv_y=_yr[__RVALUE(t_val)] + _yg[__GVALUE(t_val)] + _yb[__BVALUE(t_val)] ;\
509
 
            datapi++;\
510
 
            yuv_y++;\
511
 
        }\
512
 
        yuv_y+=yuv->y_width-width_tm;\
513
 
        datapi+=yuv->y_width-width_tm;\
514
 
    }\
515
 
    datapi=(unsigned int*)data+x_tm+y_tm*yuv->y_width;\
516
 
    for(k=0;k<height_tm;k+=2){\
517
 
        for(i=0;i<width_tm;i+=2){\
518
 
            t1=*datapi;\
519
 
            t2=*(datapi+1);\
520
 
            t3=*datapi_next;\
521
 
            t4=*(datapi_next+1);\
522
 
            t_val=((((t1&0xff000000) +(t2&0xff000000)+\
523
 
            (t3&0xff000000)+(t4&0xff000000))/4)&0xff000000) \
524
 
            +((((t1&0x00ff0000) +(t2&0x00ff0000)+\
525
 
            (t3&0x00ff0000)+(t4&0x00ff0000))/4)&0x00ff0000)\
526
 
            +((((t1&0x0000ff00) +(t2&0x0000ff00)+\
527
 
            (t3&0x0000ff00)+(t4&0x0000ff00))/4)&0x0000ff00)\
528
 
            +((((t1&0x000000ff) +(t2&0x000000ff)+\
529
 
            (t3&0x000000ff)+(t4&0x000000ff))/4)&0x000000ff);\
530
 
\
531
 
            *yuv_u=\
532
 
            _ur[__RVALUE(t_val)] + _ug[__GVALUE(t_val)] + _ub[__BVALUE(t_val)];\
533
 
            *yuv_v=\
534
 
            _vr[__RVALUE(t_val)] + _vg[__GVALUE(t_val)] + _vb[__BVALUE(t_val)];\
535
 
            datapi+=2;\
536
 
            datapi_next+=2;\
537
 
            yuv_u++;\
538
 
            yuv_v++;\
539
 
        }\
540
 
        yuv_u+=(yuv->y_width-width_tm)/2;\
541
 
        yuv_v+=(yuv->y_width-width_tm)/2;\
542
 
        datapi+=(2*yuv->y_width-width_tm);\
543
 
        datapi_next+=(2*yuv->y_width-width_tm);\
544
 
    }\
545
 
}
546
 
 
547
 
 
548
 
 
549
 
#define UPDATE_YUV_BUFFER_IM(yuv,data,x_tm,y_tm,width_tm,height_tm){\
550
 
    int k,i;\
551
 
    register unsigned int t_val;\
552
 
    register unsigned int *datapi=(unsigned int*)data;\
553
 
    register unsigned char  *yuv_y=yuv->y+x_tm+y_tm*yuv->y_width,\
554
 
                            *yuv_u=yuv->u+x_tm/2+(y_tm*yuv->uv_width)/2,\
555
 
                            *yuv_v=yuv->v+x_tm/2+(y_tm*yuv->uv_width)/2,\
556
 
                            *_yr=Yr,*_yg=Yg,*_yb=Yb,\
557
 
                            *_ur=Ur,*_ug=Ug,*_ub=Ub,\
558
 
                            *_vr=Vr,*_vg=Vg,*_vb=Vb;\
559
 
\
560
 
    for(k=0;k<height_tm;k++){\
561
 
        for(i=0;i<width_tm;i++){\
562
 
            t_val=*datapi;\
563
 
            *yuv_y=_yr[__RVALUE(t_val)] + _yg[__GVALUE(t_val)] + _yb[__BVALUE(t_val)] ;\
564
 
            datapi++;\
565
 
            yuv_y++;\
566
 
        }\
567
 
        yuv_y+=yuv->y_width-width_tm;\
568
 
    }\
569
 
    datapi=(unsigned int*)data;\
570
 
    for(k=0;k<height_tm;k+=2){\
571
 
        for(i=0;i<width_tm;i+=2){\
572
 
            t_val=*datapi;\
573
 
            *yuv_u=\
574
 
            _ur[__RVALUE(t_val)] + _ug[__GVALUE(t_val)] + _ub[__BVALUE(t_val)];\
575
 
            *yuv_v=\
576
 
            _vr[__RVALUE(t_val)] + _vg[__GVALUE(t_val)] + _vb[__BVALUE(t_val)];\
577
 
            datapi+=2;\
578
 
            yuv_u++;\
579
 
            yuv_v++;\
580
 
        }\
581
 
        yuv_u+=(yuv->y_width-width_tm)/2;\
582
 
        yuv_v+=(yuv->y_width-width_tm)/2;\
583
 
        datapi+=width_tm;\
584
 
    }\
585
 
}
586
 
 
587
 
#define UPDATE_YUV_BUFFER_IM_AVG(yuv,data,x_tm,y_tm,width_tm,height_tm){\
588
 
    int k,i;\
589
 
    register unsigned int t_val,t1,t2,t3,t4;\
590
 
    register unsigned int *datapi=(unsigned int*)data,\
591
 
                          *datapi_next=(unsigned int*)data+width_tm;\
592
 
    register unsigned char  *yuv_y=yuv->y+x_tm+y_tm*yuv->y_width,\
593
 
                            *yuv_u=yuv->u+x_tm/2+(y_tm*yuv->uv_width)/2,\
594
 
                            *yuv_v=yuv->v+x_tm/2+(y_tm*yuv->uv_width)/2,\
595
 
                            *_yr=Yr,*_yg=Yg,*_yb=Yb,\
596
 
                            *_ur=Ur,*_ug=Ug,*_ub=Ub,\
597
 
                            *_vr=Vr,*_vg=Vg,*_vb=Vb;\
598
 
\
599
 
    for(k=0;k<height_tm;k++){\
600
 
        for(i=0;i<width_tm;i++){\
601
 
            t_val=*datapi;\
602
 
            *yuv_y=_yr[__RVALUE(t_val)] + _yg[__GVALUE(t_val)] + _yb[__BVALUE(t_val)] ;\
603
 
            datapi++;\
604
 
            yuv_y++;\
605
 
        }\
606
 
        yuv_y+=yuv->y_width-width_tm;\
607
 
    }\
608
 
    datapi=(unsigned int*)data;\
609
 
    for(k=0;k<height_tm;k+=2){\
610
 
        for(i=0;i<width_tm;i+=2){\
611
 
            t1=*datapi;\
612
 
            t2=*(datapi+1);\
613
 
            t3=*datapi_next;\
614
 
            t4=*(datapi_next+1);\
615
 
            t_val=((((t1&0xff000000) +(t2&0xff000000)+\
616
 
            (t3&0xff000000)+(t4&0xff000000))/4)&0xff000000) \
617
 
            +((((t1&0x00ff0000) +(t2&0x00ff0000)+\
618
 
            (t3&0x00ff0000)+(t4&0x00ff0000))/4)&0x00ff0000)\
619
 
            +((((t1&0x0000ff00) +(t2&0x0000ff00)+\
620
 
            (t3&0x0000ff00)+(t4&0x0000ff00))/4)&0x0000ff00)\
621
 
            +((((t1&0x000000ff) +(t2&0x000000ff)+\
622
 
            (t3&0x000000ff)+(t4&0x000000ff))/4)&0x000000ff);\
623
 
\
624
 
            *yuv_u=\
625
 
            _ur[__RVALUE(t_val)] + _ug[__GVALUE(t_val)] + _ub[__BVALUE(t_val)];\
626
 
            *yuv_v=\
627
 
            _vr[__RVALUE(t_val)] + _vg[__GVALUE(t_val)] + _vb[__BVALUE(t_val)];\
628
 
            datapi+=2;\
629
 
            datapi_next+=2;\
630
 
            yuv_u++;\
631
 
            yuv_v++;\
632
 
        }\
633
 
        yuv_u+=(yuv->y_width-width_tm)/2;\
634
 
        yuv_v+=(yuv->y_width-width_tm)/2;\
635
 
        datapi+=width_tm;\
636
 
        datapi_next+=width_tm;\
637
 
    }\
638
 
}
639
 
 
640
 
 
641
 
 
642
 
#define XFIXES_POINTER_TO_YUV(yuv,data,x_tm,y_tm,width_tm,height_tm,column_discard_stride){\
643
 
    int i,k,j=0;\
644
 
    unsigned char avg0,avg1,avg2,avg3;\
645
 
    int x_2=x_tm/2,y_2=y_tm/2;\
646
 
    for(k=0;k<height_tm;k++){\
647
 
        for(i=0;i<width_tm;i++){\
648
 
                yuv->y[x_tm+i+(k+y_tm)*yuv->y_width]=\
649
 
                (yuv->y[x_tm+i+(k+y_tm)*yuv->y_width]*(UCHAR_MAX-data[(j*4)+__ABYTE])+\
650
 
                (Yr[data[(j*4)+__RBYTE]] + Yg[data[(j*4)+__GBYTE]] + Yb[data[(j*4)+__BBYTE]])*data[(j*4)+__ABYTE])/UCHAR_MAX ;\
651
 
                if((k%2)&&(i%2)){\
652
 
                    avg3=AVG_4_PIXELS(data,(width_tm+column_discard_stride),k,i,__ABYTE);\
653
 
                    avg2=AVG_4_PIXELS(data,(width_tm+column_discard_stride),k,i,__RBYTE);\
654
 
                    avg1=AVG_4_PIXELS(data,(width_tm+column_discard_stride),k,i,__GBYTE);\
655
 
                    avg0=AVG_4_PIXELS(data,(width_tm+column_discard_stride),k,i,__BBYTE);\
656
 
                    yuv->u[x_2+i/2+(k/2+y_2)*yuv->uv_width]=\
657
 
                    (yuv->u[x_2+i/2+(k/2+y_2)*yuv->uv_width]*(UCHAR_MAX-avg3)+\
658
 
                    (Ur[avg2] + Ug[avg1] +Ub[avg0])*avg3)/UCHAR_MAX;\
659
 
                    yuv->v[x_2+i/2+(k/2+y_2)*yuv->uv_width]=\
660
 
                    (yuv->v[x_2+i/2+(k/2+y_2)*yuv->uv_width]*(UCHAR_MAX-avg3)+\
661
 
                    (Vr[avg2] + Vg[avg1] +Vb[avg0])*avg3)/UCHAR_MAX;\
662
 
                }\
663
 
            j++;\
664
 
        }\
665
 
        j+=column_discard_stride;\
666
 
    }\
667
 
}
668
 
 
669
 
#define DUMMY_POINTER_TO_YUV(yuv,data_tm,x_tm,y_tm,width_tm,height_tm,no_pixel){\
670
 
    int i,k,j=0;\
671
 
    int x_2=x_tm/2,y_2=y_tm/2,y_width_2=(yuv)->y_width/2;\
672
 
    for(k=0;k<height_tm;k++){\
673
 
        for(i=0;i<width_tm;i++){\
674
 
            if(data_tm[(j*4)]!=(no_pixel)){\
675
 
                (yuv)->y[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]];\
676
 
                if((k%2)&&(i%2)){\
677
 
                    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]];\
678
 
                    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]] ;\
679
 
                }\
680
 
            }\
681
 
            j++;\
682
 
        }\
683
 
        j+=16-width_tm;\
684
 
    }\
685
 
}
686
 
 
687
 
 
688
 
#define I16TOA(number,buffer){\
689
 
    int t_num=(number),__k=0,__i=0;\
690
 
    char *t_buf=malloc(8);\
691
 
    t_num=t_num&((2<<15)-1);\
692
 
    while(t_num>0){\
693
 
        int digit=t_num%10;\
694
 
        t_buf[__k]=digit+48;\
695
 
        t_num-=digit;\
696
 
        t_num/=10;\
697
 
        __k++;\
698
 
    }\
699
 
    while(__k>0)\
700
 
        (buffer)[__i++]=t_buf[--__k];\
701
 
    (buffer)[__i]='\0';\
702
 
    free(t_buf);\
703
 
};\
704
 
 
705
 
#define INIT_FRAME(frame_t,fheader_t,yuv_t){\
706
 
    (frame_t)->header=(fheader_t);\
707
 
    (frame_t)->YBlocks=malloc(256);\
708
 
    (frame_t)->UBlocks=malloc(64);\
709
 
    (frame_t)->VBlocks=malloc(64);\
710
 
    (frame_t)->YData=malloc((yuv_t)->y_width*(yuv_t)->y_height);\
711
 
    (frame_t)->UData=malloc((yuv_t)->uv_width*(yuv_t)->uv_height);\
712
 
    (frame_t)->VData=malloc((yuv_t)->uv_width*(yuv_t)->uv_height);\
713
 
};
714
 
 
715
 
#define CLEAR_FRAME(frame_t){\
716
 
    free((frame_t)->YBlocks);\
717
 
    free((frame_t)->UBlocks);\
718
 
    free((frame_t)->VBlocks);\
719
 
    free((frame_t)->YData);\
720
 
    free((frame_t)->UData);\
721
 
    free((frame_t)->VData);\
722
 
};
723
 
 
724
 
/**Function prototypes*/
725
 
 
726
 
/**
727
 
* Loop calling XNextEvent.Retrieve and place on
728
 
* list damage events that arive, create damage for new windows.
729
 
* \param pdata ProgData struct containing all program data
730
 
*/
731
 
void *PollDamage(ProgData *pdata);
732
 
 
733
 
/**
734
 
* Retrieve frame form xserver, and transform to a yuv buffer,
735
 
* either directly(full shots) or by calling UpdateImage.
736
 
* \param pdata ProgData struct containing all program data
737
 
*/
738
 
void *GetFrame(ProgData *pdata);
739
 
 
740
 
/**
741
 
* feed a yuv buffer to the theora encoder and submit outcome to
742
 
* the ogg stream.
743
 
* \param pdata ProgData struct containing all program data
744
 
*/
745
 
void *EncodeImageBuffer(ProgData *pdata);
746
 
 
747
 
/**
748
 
* Query theora and vorbis streams for ready packages and
749
 
* flush them on the disk
750
 
* \param pdata ProgData struct containing all program data
751
 
*/
752
 
void *FlushToOgg(ProgData *pdata);
753
 
 
754
 
/**
755
 
* Clean up a list of areas marked for update.
756
 
* \param root Root entry of the list
757
 
*/
758
 
void ClearList(RectArea **root);
759
 
 
760
 
/**
761
 
* Insert a new rectangle on the list, making sure it doesn't overlap
762
 
* with the existing ones
763
 
* \param root Root entry of the list
764
 
*
765
 
* \param wgeom New area to be inserted
766
 
*
767
 
* \returns Number of insertions during operation
768
 
*
769
 
* \note This function is reentrant and recursive. The number
770
 
* of insertions takes this into account.
771
 
*/
772
 
int RectInsert(RectArea **root,WGeometry *wgeom);
773
 
 
774
 
/**
775
 
* Collide two rectangles and dictate most sane action for insertion,
776
 
* as well as provide the updated rectangle(s)
777
 
* \param wgeom1 resident rectangle
778
 
*
779
 
* \param wgeom2 New rectangle
780
 
*
781
 
* \param wgeom_return Pointer to rectangles to be inserted
782
 
*
783
 
* \param ngeoms number of entries in wgeom_return
784
 
*
785
 
* \retval 0 No collision
786
 
*
787
 
* \retval 1 wgeom1 is covered by wgeom2
788
 
*
789
 
* \retval 2 wgeom2 is covered by wgeom1
790
 
*
791
 
* \retval -1 wgeom1 was broken (new is picked up in wgeom_return)
792
 
*
793
 
* \retval -2 wgeom2 was broken (new is picked up in wgeom_return)
794
 
*
795
 
* \retval -10 Grouping the two geoms is possible
796
 
*
797
 
*/
798
 
int CollideRects(WGeometry *wgeom1,WGeometry *wgeom2,WGeometry **wgeom_return,int *ngeoms);
799
 
 
800
 
/**
801
 
* Broadcast time condition variable, increment frame count.
802
 
*
803
 
* \param signum Number of signal received(unused, always SIGALRM)
804
 
*
805
 
*/
806
 
void SetExpired(int signum);
807
 
 
808
 
/**
809
 
* Set up all callbacks and signal handlers
810
 
* \param pdata ProgData struct containing all program data
811
 
*/
812
 
void RegisterCallbacks(ProgArgs *args);
813
 
 
814
 
/**
815
 
* Retrieve and apply all changes, if xdamage is used.
816
 
*
817
 
* \param dpy Connection to the server
818
 
*
819
 
* \param yuv yuv_buffer that is to be modified
820
 
*
821
 
* \param yuv_mutex lock on the buffer
822
 
*
823
 
* \param specs DisplaySpecs struct with information about the display to be recorded
824
 
*
825
 
* \param root Root entry of the list with damaged areas
826
 
*
827
 
* \param brwin BRWindow struct contaning the recording window specs
828
 
*
829
 
* \param enc Encoding options
830
 
*
831
 
* \param datatemp Buffer for pixel data to be retrieved before placed on the yuv buffer
832
 
*
833
 
* \param noshmem don't use MIT_Shm extension
834
 
*
835
 
* \param no_quick_subsample Don't do quick subsampling
836
 
*
837
 
*/
838
 
void UpdateImage(Display * dpy,
839
 
                yuv_buffer *yuv,
840
 
                pthread_mutex_t *yuv_mutex,
841
 
                DisplaySpecs *specs,
842
 
                RectArea **root,
843
 
                BRWindow *brwin,
844
 
                EncData *enc,
845
 
                char *datatemp,
846
 
                int noshmem,
847
 
                int no_quick_subsample);
848
 
 
849
 
/**
850
 
* Rerieve pixmap data from xserver
851
 
*
852
 
* \param dpy Connection to the server
853
 
*
854
 
* \param root root window of the display
855
 
*
856
 
* \param data (preallocated)buffer to place the data
857
 
*
858
 
* \param x x position of the screenshot
859
 
*
860
 
* \param y y position of the screenshot
861
 
*
862
 
* \param x x position of the screenshot
863
 
*
864
 
* \param width width of the screenshot
865
 
*
866
 
* \param height height position of the screenshot
867
 
*
868
 
* \param x x position of the screenshot
869
 
*
870
 
* \returns 0 on Success 1 on Failure
871
 
*/
872
 
int GetZPixmap(Display *dpy,Window root,char *data,int x,int y,int width,int height);
873
 
 
874
 
/**
875
 
* Fill ProgArgs struct with arguments entered at execution
876
 
*
877
 
* \param argc argc as entered  from main
878
 
*
879
 
* \param argv argv as entered  from main
880
 
*
881
 
* \param arg_return ProgArgs struct to be filled with the options
882
 
*
883
 
* \returns 0 on Success 1 on Failure
884
 
*/
885
 
int ParseArgs(int argc,char **argv,ProgArgs *arg_return);
886
 
 
887
 
/**
888
 
* Check if needed extensions are present
889
 
*
890
 
* \param dpy Connection to the server
891
 
*
892
 
* \param args ProgArgs struct containing the user-set options
893
 
*
894
 
* \param damage_event gets filled with damage event number
895
 
*
896
 
* \param damage_error gets filled with damage error number
897
 
*
898
 
* \note Can be an exit point if extensions are not found
899
 
*/
900
 
void QueryExtensions(Display *dpy,ProgArgs *args,int *damage_event,int *damage_error);
901
 
 
902
 
/**
903
 
* Check and align window size
904
 
*
905
 
* \param dpy Connection to the server
906
 
*
907
 
* \param brwin BRWindow struct contaning the initial and final window
908
 
*
909
 
* \param specs DisplaySpecs struct with information about the display to be recorded
910
 
*
911
 
* \param args ProgArgs struct containing the user-set options
912
 
*
913
 
* \returns 0 on Success 1 on Failure
914
 
*/
915
 
int SetBRWindow(Display *dpy,BRWindow *brwin,DisplaySpecs *specs,ProgArgs *args);
916
 
 
917
 
/**
918
 
* Create an array containing the data for the dummy pointer
919
 
*
920
 
* \param specs DisplaySpecs struct with information about the display to be recorded
921
 
*
922
 
* \param size  Pointer size, always square, always 16.(exists only for the possibility to create
923
 
*               more dummy cursors)
924
 
* \param color 0 white, 1 black
925
 
*
926
 
* \param type Always 0.(exists only for the possibility to create
927
 
*               more dummy cursors)
928
 
*
929
 
* \param npxl Return of pixel value that denotes non-drawing, while applying the cursor
930
 
*             on the target image
931
 
*
932
 
* \returns Pointer to pixel data of the cursor
933
 
*/
934
 
unsigned char *MakeDummyPointer(DisplaySpecs *specs,int size,int color,int type,unsigned char *npxl);
935
 
 
936
 
/**
937
 
* Sound capturing thread. Data are placed on a list to be picked up by other threads.
938
 
*
939
 
* \param pdata ProgData struct containing all program data
940
 
*/
941
 
void *CaptureSound(ProgData *pdata);
942
 
 
943
 
/**
944
 
* Sound encoding thread. Picks up data from the buffer queue , encodes and places them
945
 
* on the vorbis stream.
946
 
*
947
 
* \param pdata ProgData struct containing all program data
948
 
*/
949
 
void *EncodeSoundBuffer(ProgData *pdata);
950
 
 
951
 
/**
952
 
* Try to open sound device, with the desired parameters,
953
 
* and place the obtained ones on their place
954
 
*
955
 
* \param pcm_dev name of the device
956
 
*
957
 
* \param channels desired number of channels(gets modified with the acieved value)
958
 
*
959
 
* \param frequency desired frequency(gets modified with the acieved value)
960
 
*
961
 
* \param buffsize Size of buffer
962
 
*
963
 
* \param periodsize Size of a period(can be NULL)
964
 
*
965
 
* \param periodtime Duration of a period(can be NULL)
966
 
*
967
 
* \param hardpause Set to 1 when the device has to be stopped during pause
968
 
*                  and to 0 when it supports pausing
969
 
*                  (can be NULL)
970
 
*
971
 
* \returns snd_pcm_t handle on success, NULL on failure
972
 
*/
973
 
snd_pcm_t *OpenDev( const char *pcm_dev,
974
 
                    unsigned int *channels,
975
 
                    unsigned int *frequency,
976
 
                    snd_pcm_uframes_t *buffsize,
977
 
                    snd_pcm_uframes_t *periodsize,
978
 
                    unsigned int *periodtime,
979
 
                    int *hardpause);
980
 
/**
981
 
* Initialize theora,vorbis encoders, and their respective ogg streams.
982
 
*
983
 
* \param pdata ProgData struct containing all program data
984
 
*
985
 
* \param enc_data_t Encoding options
986
 
*
987
 
* \param buffer_ready when 1, the yuv buffer must be preallocated
988
 
*                     when 0 InitEncoder will alocate a new one
989
 
*
990
 
*/
991
 
void InitEncoder(ProgData *pdata,EncData *enc_data_t,int buffer_ready);
992
 
 
993
 
/**
994
 
* Fill Yr,Yg,Yb,Ur,Ug.Ub,Vr,Vg,Vb arrays(globals) with values.
995
 
*/
996
 
void MakeMatrices();
997
 
/**
998
 
*Align the recording window to a divisible by 2 pixel start and
999
 
*and a size divisible by 16.
1000
 
*
1001
 
* \param start x or y of the recording window
1002
 
*
1003
 
* \param size  width or height of the recording window
1004
 
*
1005
 
* \param limit  width or height of the Display
1006
 
*
1007
 
* \note This is called separately for width and height.
1008
 
*/
1009
 
void SizePack2_8_16(int *start,int *size,int limit);
1010
 
 
1011
 
/**
1012
 
* Image caching thread. Copies the yuv buffer, compares with the last one and
1013
 
* caches the result.
1014
 
*
1015
 
* \param pdata ProgData struct containing all program data
1016
 
*
1017
 
*/
1018
 
void *CacheImageBuffer(ProgData *pdata);
1019
 
 
1020
 
/**
1021
 
* Initializes paths and everything else needed to start caching
1022
 
*
1023
 
* \param pdata ProgData struct containing all program data
1024
 
*
1025
 
* \param enc_data_t Encoding options
1026
 
*
1027
 
* \param cache_data_t Caching options
1028
 
*
1029
 
*/
1030
 
void InitCacheData(ProgData *pdata,EncData *enc_data_t,CacheData *cache_data_t);
1031
 
 
1032
 
/**
1033
 
* Sound caching thread. Simply writes the pcm buffers on disk
1034
 
*
1035
 
* \param pdata ProgData struct containing all program data
1036
 
*
1037
 
*/
1038
 
void *CacheSoundBuffer(ProgData *pdata);
1039
 
 
1040
 
/**
1041
 
* Cache loading and processing thread
1042
 
*
1043
 
* \param pdata ProgData struct containing all program data
1044
 
*
1045
 
*/
1046
 
void *LoadCache(ProgData *pdata);
1047
 
 
1048
 
/**
1049
 
* As EncodeImageBuffer, only with the assumption that this is not a thread on it's own
1050
 
*
1051
 
* \param pdata ProgData struct containing all program data
1052
 
*
1053
 
*/
1054
 
void SyncEncodeImageBuffer(ProgData *pdata);
1055
 
 
1056
 
/**
1057
 
* Stop the timer
1058
 
*/
1059
 
void CancelTimer(void);
1060
 
 
1061
 
/**
1062
 
* As EncodeSoundBuffer, only with the assumption that this is not a thread on it's own
1063
 
*
1064
 
* \param pdata ProgData struct containing all program data
1065
 
*
1066
 
*/
1067
 
void SyncEncodeSoundBuffer(ProgData *pdata,signed char *buff);
1068
 
 
1069
 
/**
1070
 
*Check current running window manager.
1071
 
*
1072
 
* \param dpy Connection to the server
1073
 
*
1074
 
* \param root root window of the display
1075
 
*
1076
 
* \returns Window manager name
1077
 
*/
1078
 
char *rmdWMCheck(Display *dpy,Window root);
1079
 
 
1080
 
/**
1081
 
*Construct an number postfixed name
1082
 
*
1083
 
* \param name base name
1084
 
*
1085
 
* \param newname modified name
1086
 
*
1087
 
* \n number to be used as a postfix
1088
 
*
1089
 
*/
1090
 
void CacheFileN(char *name,char **newname,int n);
1091
 
 
1092
 
/**
1093
 
* Change file pointer to a new file while writting
1094
 
* (file name is incremented with CacheFileN)
1095
 
*
1096
 
* \param name base file name
1097
 
*
1098
 
* \param n number to be used as a postfix
1099
 
*
1100
 
* \param fp File pointer if compression is used(must be NULL otherwise)
1101
 
*
1102
 
* \param ucfp File pointer if compression is NOT used(must be NULL otherwise)
1103
 
*
1104
 
* \returns 0 on Success 1 on Failure
1105
 
*/
1106
 
int SwapCacheFilesWrite(char *name,int n,gzFile **fp,FILE **ucfp);
1107
 
 
1108
 
/**
1109
 
* Change file pointer to a new file while reading
1110
 
* (file name is incremented with CacheFileN)
1111
 
*
1112
 
* \param name base file name
1113
 
*
1114
 
* \param n number to be used as a postfix
1115
 
*
1116
 
* \param fp File pointer if compression is used(must be NULL otherwise)
1117
 
*
1118
 
* \param ucfp File pointer if compression is NOT used(must be NULL otherwise)
1119
 
*
1120
 
* \returns 0 on Success 1 on Failure
1121
 
*/
1122
 
int SwapCacheFilesRead(char *name,int n,gzFile **fp,FILE **ucfp);
1123
 
 
1124
 
/**
1125
 
* Delete all cache files
1126
 
*
1127
 
* \param cache_data_t Caching options(file names etc.)
1128
 
*
1129
 
* \returns 0 if all files and folders where deleted, 1 otherwise
1130
 
*/
1131
 
int PurgeCache(CacheData *cache_data_t,int sound);
 
60
 
1132
61
#endif
1133
62