source: trunk/src/testing/app/vnc/main.cpp @ 4

Revision 4, 10.5 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1/*****************************************************************************************
2 * VNCViewer for SAGE
3 * Copyright (C) 2004 Electronic Visualization Laboratory,
4 * University of Illinois at Chicago
5 *
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 *  * Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 *  * Redistributions in binary form must reproduce the above
14 *    copyright notice, this list of conditions and the following disclaimer
15 *    in the documentation and/or other materials provided with the distribution.
16 *  * Neither the name of the University of Illinois at Chicago nor
17 *    the names of its contributors may be used to endorse or promote
18 *    products derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * Direct questions, comments etc about VNCViewer for SAGE to www.evl.uic.edu/cavern/forum
33 *****************************************************************************************/
34
35#if defined(USE_LIBVNC)
36#include <rfb/rfbclient.h>
37#else
38#include "sgVNCViewer.h"
39#include <sys/fcntl.h>
40#endif
41
42// headers for SAGE
43#include "sail.h"
44#include "misc.h"
45#include <time.h>
46#include <unistd.h>
47
48// Global variables
49char *passwd, *server;
50
51
52// Configuration for SAGE, example:
53//      nodeNum 1
54//      Init 200 200 1480 1224
55//      exec 10.0.8.120 VNCViewer 1
56//      nwProtocol tvTcpModule.so
57
58#if defined(WIN32)
59LARGE_INTEGER perf_freq;
60LARGE_INTEGER perf_start;
61#elif defined(__APPLE__)
62#include <mach/mach_time.h>
63static double perf_conversion = 0.0;
64static uint64_t perf_start;
65#else
66struct timeval tv_start;
67#endif
68
69void aInitialize()
70{
71#if defined(WIN32)
72    QueryPerformanceCounter(&perf_start);
73    QueryPerformanceFrequency(&perf_freq);
74#elif defined(__APPLE__)
75    if( perf_conversion == 0.0 )
76    {
77        mach_timebase_info_data_t info;
78        kern_return_t err = mach_timebase_info( &info );
79
80            //Convert the timebase into seconds
81        if( err == 0  )
82            perf_conversion = 1e-9 * (double) info.numer / (double) info.denom;
83    }
84        // Start of time
85    perf_start = mach_absolute_time();
86
87        // Initialize the random generator
88    srand(getpid());
89#else
90        // Start of time
91    gettimeofday(&tv_start,0);
92        // Initialize the random generator
93    srand(getpid());
94#endif
95}
96
97double aTime()
98// return time since start of process in seconds
99{
100#if defined(WIN32)
101    LARGE_INTEGER perf_counter;
102#else
103    struct timeval tv;
104#endif
105
106#if defined(WIN32)
107        // Windows: get performance counter and subtract starting mark
108    QueryPerformanceCounter(&perf_counter);
109    return (double)(perf_counter.QuadPart - perf_start.QuadPart) / (double)perf_freq.QuadPart;
110#elif defined(__APPLE__)
111    uint64_t difference = mach_absolute_time(); - perf_start;
112    return perf_conversion * (double) difference;
113#else
114        // UNIX: gettimeofday
115    gettimeofday(&tv,0);
116    return (double)(tv.tv_sec - tv_start.tv_sec) + (double)(tv.tv_usec - tv_start.tv_usec) / 1000000.0;
117#endif
118}
119
120// Comment/uncomment to use 24bit or 32bit SAGE application stream
121#define VNC_SAGE_USE_24bit 1
122
123#if defined(USE_LIBVNC)
124rfbClient* vnc;
125#else
126sgVNCViewer* vnc;
127#endif
128
129#if defined(USE_LIBVNC)
130
131static rfbBool got_data = FALSE;
132static void signal_handler(int signal)
133{
134    rfbClientLog("Cleaning up.\n");
135}
136
137static rfbBool resize_func(rfbClient* client)
138{
139    static rfbBool first=TRUE;
140    if(!first) {
141        rfbClientLog("I don't know yet how to change resolutions!\n");
142        exit(1);
143    }
144    signal(SIGINT,signal_handler);
145
146    int width=client->width;
147    int height=client->height;
148    int depth=client->format.bitsPerPixel;
149    client->updateRect.x = client->updateRect.y = 0;
150    client->updateRect.w = width; client->updateRect.h = height;
151
152    client->frameBuffer = (uint8_t*)malloc(width*height*depth);
153    memset(client->frameBuffer, 0, width*height*depth);
154
155    rfbClientLog("Allocate %d bytes: %d x %d x %d\n", width*height*depth, width,height,depth);
156    return TRUE;
157}
158
159static void frame_func(rfbClient* client)
160{
161    rfbClientLog("Received a frame\n");
162}
163
164static rfbBool position_func(rfbClient* client, int x, int y)
165{
166    //rfbClientLog("Received a position for %d,%d\n",x,y);
167    return TRUE;
168}
169
170static char *password_func(rfbClient* client)
171{
172    char *str = (char*)malloc(64);
173    memset(str, 0, 64);
174    strncpy(str, passwd, 64);
175    return str;
176}
177
178static void update_func(rfbClient* client,int x,int y,int w,int h)
179{
180    rfbPixelFormat* pf=&client->format;
181    int bpp=pf->bitsPerPixel/8;
182    int row_stride=client->width*bpp;
183
184    got_data = TRUE;
185
186    //rfbClientLog("Received an update for %d,%d,%d,%d.\n",x,y,w,h);
187}
188
189
190#endif
191
192int
193main(int argc, char **argv)
194{
195    int winWidth, winHeight, display;
196    sail sageInf; // sail object
197    double rate = 10;  //by default stream at 1fps
198
199    aInitialize();
200
201    if (argc < 6)
202    {
203        fprintf(stderr, "\nUsage> VNCviewer <hostname> <display#> <width> <height> <password> [fps]\n\n");
204        exit(0);
205    }
206
207        // VNC Init
208    server    = strdup(argv[1]);
209    display   = atoi(argv[2]);
210    winWidth  = atoi(argv[3]);
211    winHeight = atoi(argv[4]);
212    passwd    = argv[5];
213    if (argc > 6)
214        rate = atoi(argv[6]);
215
216
217#if defined(USE_LIBVNC)
218    // get a vnc client structure (don't connect yet).
219    // bits, channels, bytes
220    vnc = rfbGetClient(8,3,4);
221    vnc->canHandleNewFBSize = FALSE;
222    // to get position update callbacks
223    vnc->appData.useRemoteCursor=TRUE;
224    //vnc->appData.compressLevel=3;
225    //vnc->appData.qualityLevel=5;
226
227    /* open VNC connection */
228    vnc->MallocFrameBuffer=resize_func;
229    vnc->GotFrameBufferUpdate=update_func;
230    vnc->HandleCursorPos=position_func;
231    vnc->GetPassword=password_func;
232    //client->FinishedFrameBufferUpdate=frame_func;
233
234
235    int margc = 2;
236    char *margv[2];
237    margv[0] = strdup("vnc");
238    margv[1] = (char*)malloc(256);
239    memset(margv[1], 0, 256);
240    sprintf(margv[1], "%s:%d", server, display);
241    if(!rfbInitClient(vnc,&margc,margv)) {
242        printf("usage: %s server:port password\n"
243               "VNC client.\n", argv[0]);
244        exit(1);
245    }
246    if (vnc->serverPort==-1)
247        vnc->vncRec->doNotSleep = TRUE; /* vncrec playback */
248
249    winWidth  = vnc->width;
250    winHeight = vnc->height;
251
252#else
253
254        // Connection to VNC server:
255        //      host, display number, x offset, y offset, width, height, passwd
256        //      passwd is by default 'evl123' but a different one can be specified so that one will be used
257    vnc = new sgVNCViewer(server, display, 0,0,winWidth,winHeight, passwd);
258#endif
259
260        // Sage Init
261    sailConfig scfg;
262    scfg.init("VNCViewer.conf");
263    scfg.setAppName("VNCViewer");
264    scfg.rank = 0;
265
266    scfg.resX = winWidth;
267    scfg.resY = winHeight;
268
269    sageRect renderImageMap;
270    renderImageMap.left = 0.0;
271    renderImageMap.right = 1.0;
272    renderImageMap.bottom = 0.0;
273    renderImageMap.top = 1.0;
274
275    scfg.imageMap = renderImageMap;
276#if defined(VNC_SAGE_USE_24bit)
277    scfg.pixFmt = PIXFMT_888;
278#else
279    scfg.pixFmt = PIXFMT_8888;
280#endif
281    scfg.rowOrd = TOP_TO_BOTTOM;
282    scfg.master = true;
283
284    sageInf.init(scfg);
285
286
287        // data pointer
288    unsigned char *buffer = 0;
289    unsigned char *vncpixels;
290
291    double t1, t2;
292    t1 = aTime();
293
294        // Main lopp
295    while (1)
296    {
297#if defined(USE_LIBVNC)
298        double now = sage::getTime();
299        while ( (sage::getTime() - now) < (1000000/rate)) {
300            int i=WaitForMessage(vnc,100000);
301            if(i<0) {
302                rfbClientLog("VNC error, quit\n");
303                sageInf.shutdown();
304                exit(0);
305            }
306            if(i) {
307                if(!HandleRFBServerMessage(vnc)) {
308                    rfbClientLog("HandleRFBServerMessage quit\n");
309                    sageInf.shutdown();
310                    exit(0);
311                }
312            }
313        }
314
315        // Copy VNC buffer into SAGE buffer
316        buffer    = (unsigned char *) sageInf.getBuffer();
317        vncpixels = (unsigned char *) vnc->frameBuffer;
318
319        for (int k =0 ; k<winWidth*winHeight; k++) {
320            buffer[3*k + 0] = vncpixels[ 4*k + 0];
321            buffer[3*k + 1] = vncpixels[ 4*k + 1];
322            buffer[3*k + 2] = vncpixels[ 4*k + 2];
323        }
324
325
326        // SAGE Swap
327        sageInf.swapBuffer( );
328
329        // Process SAGE messages
330        sageMessage msg;
331        if (sageInf.checkMsg(msg, false) > 0) {
332            switch (msg.getCode()) {
333            case APP_QUIT:
334                sageInf.shutdown();
335                exit(0);
336                break;
337            }
338        }
339#else
340
341        if (!vnc->Step())
342        {
343            sageInf.shutdown();
344            exit(0);
345        }
346
347            // if it's been (roughly) xxx second since the last
348            // sent frame, send another one
349        t2 = aTime();
350        if ( (t2-t1) > (1.0/rate) )
351        {
352
353                //fprintf(stderr, "Rate: %.2f\n", 1.0/(t2-t1) );
354            buffer = (unsigned char *) sageInf.getBuffer();
355            vncpixels = (unsigned char *) vnc->Data();
356#if defined(VNC_SAGE_USE_24bit)
357            for (int k =0 ; k<winWidth*winHeight; k++) {
358                buffer[3*k + 0] = vncpixels[ 4*k + 0];
359                buffer[3*k + 1] = vncpixels[ 4*k + 1];
360                buffer[3*k + 2] = vncpixels[ 4*k + 2];
361            }
362#else
363            memcpy(buffer, (unsigned char *) vnc->Data(), winWidth*winHeight*4);
364#endif
365            sageInf.swapBuffer( );
366            t1 = aTime();
367        }
368
369        sageMessage msg;
370        if (sageInf.checkMsg(msg, false) > 0) {
371            switch (msg.getCode()) {
372                case APP_QUIT:
373                    exit(0);
374                    break;
375            }
376        }
377#endif
378    }
379
380    return 1;
381}
382
383
Note: See TracBrowser for help on using the repository browser.