~ubuntu-branches/ubuntu/precise/freerdp/precise

« back to all changes in this revision

Viewing changes to server/X11/xf_peer.c

  • Committer: Package Import Robot
  • Author(s): Otavio Salvador, Jeremy Bicha
  • Date: 2012-02-11 10:34:05 UTC
  • mfrom: (1.1.7) (9.1.3 sid)
  • Revision ID: package-import@ubuntu.com-20120211103405-mk0gjhjn70eeyxul
Tags: 1.0.1-1
[ Jeremy Bicha ]
* New upstream release. Closes: #659332.
* Updated symbols

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
#include <sys/select.h>
30
30
#include <freerdp/kbd/kbd.h>
31
31
#include <freerdp/codec/color.h>
 
32
#include <freerdp/utils/file.h>
32
33
#include <freerdp/utils/sleep.h>
33
34
#include <freerdp/utils/memory.h>
34
35
#include <freerdp/utils/thread.h>
36
37
extern char* xf_pcap_file;
37
38
extern boolean xf_pcap_dump_realtime;
38
39
 
 
40
#include "xf_event.h"
 
41
#include "xf_input.h"
39
42
#include "xf_encode.h"
40
43
 
41
44
#include "xf_peer.h"
108
111
 
109
112
        values.subwindow_mode = IncludeInferiors;
110
113
        xfi->xdamage_gc = XCreateGC(xfi->display, xfi->root_window, GCSubwindowMode, &values);
 
114
        XSetFunction(xfi->display, xfi->xdamage_gc, GXcopy);
111
115
}
112
116
 
113
117
#endif
114
118
 
115
119
void xf_xshm_init(xfInfo* xfi)
116
120
{
117
 
        xfi->use_xshm = false;
118
121
        xfi->fb_shm_info.shmid = -1;
119
122
        xfi->fb_shm_info.shmaddr = (char*) -1;
120
123
 
154
157
        xfi->fb_pixmap = XShmCreatePixmap(xfi->display,
155
158
                        xfi->root_window, xfi->fb_image->data, &(xfi->fb_shm_info),
156
159
                        xfi->fb_image->width, xfi->fb_image->height, xfi->fb_image->depth);
157
 
 
158
 
        //xfi->use_xshm = true;
159
160
}
160
161
 
161
162
xfInfo* xf_info_init()
172
173
 
173
174
        xfi = xnew(xfInfo);
174
175
 
 
176
        //xfi->use_xshm = true;
175
177
        xfi->display = XOpenDisplay(NULL);
176
178
 
177
179
        XInitThreads();
182
184
                exit(1);
183
185
        }
184
186
 
 
187
        xfi->xfds = ConnectionNumber(xfi->display);
185
188
        xfi->number = DefaultScreen(xfi->display);
186
189
        xfi->screen = ScreenOfDisplay(xfi->display, xfi->number);
187
190
        xfi->depth = DefaultDepthOfScreen(xfi->screen);
234
237
        }
235
238
        XFree(vis);
236
239
 
237
 
        xfi->clrconv = (HCLRCONV) xnew(HCLRCONV);
238
 
        xfi->clrconv->invert = 1;
239
 
        xfi->clrconv->alpha = 1;
 
240
        xfi->clrconv = freerdp_clrconv_new(CLRCONV_ALPHA | CLRCONV_INVERT);
240
241
 
241
242
        XSelectInput(xfi->display, xfi->root_window, SubstructureNotifyMask);
242
243
 
246
247
 
247
248
        xf_xshm_init(xfi);
248
249
 
249
 
        xfi->bytesPerPixel = (xfi->use_xshm) ? 4 : 3;
 
250
        xfi->bytesPerPixel = 4;
250
251
 
251
252
        freerdp_kbd_init(xfi->display, 0);
252
253
 
261
262
        context->rfx_context->width = context->info->width;
262
263
        context->rfx_context->height = context->info->height;
263
264
 
264
 
        if (context->info->use_xshm)
265
 
                rfx_context_set_pixel_format(context->rfx_context, RFX_PIXEL_FORMAT_BGRA);
266
 
        else
267
 
                rfx_context_set_pixel_format(context->rfx_context, RFX_PIXEL_FORMAT_RGB);
 
265
        rfx_context_set_pixel_format(context->rfx_context, RFX_PIXEL_FORMAT_BGRA);
268
266
 
269
267
        context->s = stream_new(65536);
270
268
}
281
279
 
282
280
void xf_peer_init(freerdp_peer* client)
283
281
{
 
282
        xfInfo* xfi;
284
283
        xfPeerContext* xfp;
285
284
 
286
285
        client->context_size = sizeof(xfPeerContext);
290
289
 
291
290
        xfp = (xfPeerContext*) client->context;
292
291
 
293
 
        xfp->pipe_fd[0] = -1;
294
 
        xfp->pipe_fd[1] = -1;
295
 
 
296
 
        if (pipe(xfp->pipe_fd) < 0)
297
 
                printf("xf_peer_init: pipe failed\n");
298
 
 
 
292
        xfp->fps = 24;
299
293
        xfp->thread = 0;
300
294
        xfp->activations = 0;
301
 
 
302
 
        xfp->stopwatch = stopwatch_create();
303
 
 
304
 
        xfp->hdc = gdi_GetDC();
305
 
 
306
 
        xfp->hdc->hwnd = (HGDI_WND) malloc(sizeof(GDI_WND));
307
 
        xfp->hdc->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0);
308
 
        xfp->hdc->hwnd->invalid->null = 1;
309
 
 
310
 
        xfp->hdc->hwnd->count = 32;
311
 
        xfp->hdc->hwnd->cinvalid = (HGDI_RGN) malloc(sizeof(GDI_RGN) * xfp->hdc->hwnd->count);
312
 
        xfp->hdc->hwnd->ninvalid = 0;
 
295
        xfp->event_queue = xf_event_queue_new();
 
296
 
 
297
        xfi = xfp->info;
 
298
        xfp->hdc = gdi_CreateDC(xfi->clrconv, xfi->bpp);
313
299
 
314
300
        pthread_mutex_init(&(xfp->mutex), NULL);
315
301
}
321
307
        return context->s;
322
308
}
323
309
 
324
 
int xf_is_event_set(xfPeerContext* xfp)
325
 
{
326
 
        fd_set rfds;
327
 
        int num_set;
328
 
        struct timeval time;
329
 
 
330
 
        FD_ZERO(&rfds);
331
 
        FD_SET(xfp->pipe_fd[0], &rfds);
332
 
        memset(&time, 0, sizeof(time));
333
 
        num_set = select(xfp->pipe_fd[0] + 1, &rfds, 0, 0, &time);
334
 
 
335
 
        return (num_set == 1);
336
 
}
337
 
 
338
 
void xf_signal_event(xfPeerContext* xfp)
339
 
{
340
 
        int length;
341
 
 
342
 
        length = write(xfp->pipe_fd[1], "sig", 4);
343
 
 
344
 
        if (length != 4)
345
 
                printf("xf_signal_event: error\n");
346
 
}
347
 
 
348
 
void xf_clear_event(xfPeerContext* xfp)
349
 
{
350
 
        int length;
351
 
 
352
 
        while (xf_is_event_set(xfp))
353
 
        {
354
 
                length = read(xfp->pipe_fd[0], &length, 4);
355
 
 
356
 
                if (length != 4)
357
 
                        printf("xf_clear_event: error\n");
358
 
        }
359
 
}
360
 
 
361
 
void* xf_monitor_graphics(void* param)
362
 
{
363
 
        xfInfo* xfi;
364
 
        XEvent xevent;
365
 
        uint32 sec, usec;
366
 
        XRectangle region;
367
 
        xfPeerContext* xfp;
368
 
        freerdp_peer* client;
369
 
        int x, y, width, height;
370
 
        XDamageNotifyEvent* notify;
371
 
 
372
 
        client = (freerdp_peer*) param;
373
 
        xfp = (xfPeerContext*) client->context;
374
 
        xfi = xfp->info;
375
 
 
376
 
        xfp->capture_buffer = (uint8*) xmalloc(xfi->width * xfi->height * xfi->bytesPerPixel);
377
 
 
378
 
        pthread_detach(pthread_self());
379
 
 
380
 
        stopwatch_start(xfp->stopwatch);
381
 
 
382
 
        while (1)
383
 
        {
384
 
                pthread_mutex_lock(&(xfp->mutex));
385
 
 
386
 
                while (XPending(xfi->display))
387
 
                {
388
 
                        memset(&xevent, 0, sizeof(xevent));
389
 
                        XNextEvent(xfi->display, &xevent);
390
 
 
391
 
                        if (xevent.type == xfi->xdamage_notify_event)
392
 
                        {
393
 
                                notify = (XDamageNotifyEvent*) &xevent;
394
 
 
395
 
                                x = notify->area.x;
396
 
                                y = notify->area.y;
397
 
                                width = notify->area.width;
398
 
                                height = notify->area.height;
399
 
 
400
 
                                region.x = x;
401
 
                                region.y = y;
402
 
                                region.width = width;
403
 
                                region.height = height;
404
 
 
405
 
#ifdef WITH_XFIXES
406
 
                                XFixesSetRegion(xfi->display, xfi->xdamage_region, &region, 1);
407
 
                                XDamageSubtract(xfi->display, xfi->xdamage, xfi->xdamage_region, None);
408
 
#endif
409
 
 
410
 
                                gdi_InvalidateRegion(xfp->hdc, x, y, width, height);
411
 
 
412
 
                                stopwatch_stop(xfp->stopwatch);
413
 
                                stopwatch_get_elapsed_time_in_useconds(xfp->stopwatch, &sec, &usec);
414
 
 
415
 
                                if ((sec > 0) || (usec > 30))
416
 
                                        break;
417
 
                        }
418
 
                }
419
 
 
420
 
                stopwatch_stop(xfp->stopwatch);
421
 
                stopwatch_get_elapsed_time_in_useconds(xfp->stopwatch, &sec, &usec);
422
 
 
423
 
                if ((sec > 0) || (usec > 30))
424
 
                {
425
 
                        HGDI_RGN region;
426
 
 
427
 
                        stopwatch_reset(xfp->stopwatch);
428
 
                        stopwatch_start(xfp->stopwatch);
429
 
 
430
 
                        region = xfp->hdc->hwnd->invalid;
431
 
                        pthread_mutex_unlock(&(xfp->mutex));
432
 
 
433
 
                        xf_signal_event(xfp);
434
 
                }
435
 
                else
436
 
                {
437
 
                        pthread_mutex_unlock(&(xfp->mutex));
438
 
                }
439
 
 
440
 
                freerdp_usleep(30);
441
 
        }
442
 
 
443
 
        return NULL;
444
 
}
445
 
 
446
310
void xf_peer_live_rfx(freerdp_peer* client)
447
311
{
448
312
        xfPeerContext* xfp = (xfPeerContext*) client->context;
449
313
 
450
314
        if (xfp->activations == 1)
451
 
                pthread_create(&(xfp->thread), 0, xf_monitor_graphics, (void*) client);
 
315
                pthread_create(&(xfp->thread), 0, xf_monitor_updates, (void*) client);
452
316
}
453
317
 
454
318
static boolean xf_peer_sleep_tsdiff(uint32 *old_sec, uint32 *old_usec, uint32 new_sec, uint32 new_usec)
529
393
void xf_peer_rfx_update(freerdp_peer* client, int x, int y, int width, int height)
530
394
{
531
395
        STREAM* s;
 
396
        uint8* data;
532
397
        xfInfo* xfi;
533
398
        RFX_RECT rect;
534
399
        XImage* image;
546
411
 
547
412
        s = xf_peer_stream_init(xfp);
548
413
 
549
 
        image = xf_snapshot(xfp, x, y, width, height);
550
 
 
551
414
        if (xfi->use_xshm)
552
415
        {
553
 
                rect.x = 0;
554
 
                rect.y = 0;
 
416
                width = x + width;
 
417
                height = y + height;
 
418
                x = 0;
 
419
                y = 0;
 
420
 
 
421
                rect.x = x;
 
422
                rect.y = y;
555
423
                rect.width = width;
556
424
                rect.height = height;
557
425
 
558
 
                rfx_compose_message(xfp->rfx_context, s, &rect, 1,
559
 
                                (uint8*) image->data, width, height, image->bytes_per_line);
 
426
                image = xf_snapshot(xfp, x, y, width, height);
 
427
 
 
428
                data = (uint8*) image->data;
 
429
                data = &data[(y * image->bytes_per_line) + (x * image->bits_per_pixel)];
 
430
 
 
431
                rfx_compose_message(xfp->rfx_context, s, &rect, 1, data,
 
432
                                width, height, image->bytes_per_line);
560
433
 
561
434
                cmd->destLeft = x;
562
435
                cmd->destTop = y;
570
443
                rect.width = width;
571
444
                rect.height = height;
572
445
 
573
 
                freerdp_image_convert((uint8*) image->data, xfp->capture_buffer,
574
 
                                width, height, 32, 24, xfi->clrconv);
 
446
                image = xf_snapshot(xfp, x, y, width, height);
575
447
 
576
448
                rfx_compose_message(xfp->rfx_context, s, &rect, 1,
577
 
                                xfp->capture_buffer, width, height, width * xfi->bytesPerPixel);
 
449
                                (uint8*) image->data, width, height, width * xfi->bytesPerPixel);
578
450
 
579
451
                cmd->destLeft = x;
580
452
                cmd->destTop = y;
581
453
                cmd->destRight = x + width;
582
454
                cmd->destBottom = y + height;
 
455
 
 
456
                XDestroyImage(image);
583
457
        }
584
458
 
585
459
        cmd->bpp = 32;
596
470
{
597
471
        xfPeerContext* xfp = (xfPeerContext*) client->context;
598
472
 
599
 
        if (xfp->pipe_fd[0] == -1)
 
473
        if (xfp->event_queue->pipe_fd[0] == -1)
600
474
                return true;
601
475
 
602
 
        rfds[*rcount] = (void *)(long) xfp->pipe_fd[0];
 
476
        rfds[*rcount] = (void *)(long) xfp->event_queue->pipe_fd[0];
603
477
        (*rcount)++;
604
478
 
605
479
        return true;
608
482
boolean xf_peer_check_fds(freerdp_peer* client)
609
483
{
610
484
        xfInfo* xfi;
 
485
        xfEvent* event;
611
486
        xfPeerContext* xfp;
 
487
        HGDI_RGN invalid_region;
612
488
 
613
489
        xfp = (xfPeerContext*) client->context;
614
490
        xfi = xfp->info;
615
491
 
616
 
        if (xfp->pipe_fd[0] == -1)
617
 
                return true;
618
 
 
619
492
        if (xfp->activated == false)
620
493
                return true;
621
494
 
622
 
        if (xf_is_event_set(xfp))
 
495
        event = xf_event_peek(xfp->event_queue);
 
496
 
 
497
        if (event != NULL)
623
498
        {
624
 
                HGDI_RGN region;
625
 
 
626
 
                xf_clear_event(xfp);
627
 
 
628
 
                region = xfp->hdc->hwnd->invalid;
629
 
 
630
 
                if (region->null)
631
 
                        return true;
632
 
 
633
 
                xf_peer_rfx_update(client, region->x, region->y, region->w, region->h);
634
 
                region->null = true;
 
499
                if (event->type == XF_EVENT_TYPE_REGION)
 
500
                {
 
501
                        xfEventRegion* region = (xfEventRegion*) xf_event_pop(xfp->event_queue);
 
502
                        gdi_InvalidateRegion(xfp->hdc, region->x, region->y, region->width, region->height);
 
503
                        xf_event_region_free(region);
 
504
                }
 
505
                else if (event->type == XF_EVENT_TYPE_FRAME_TICK)
 
506
                {
 
507
                        event = xf_event_pop(xfp->event_queue);
 
508
                        invalid_region = xfp->hdc->hwnd->invalid;
 
509
 
 
510
                        if (invalid_region->null == false)
 
511
                        {
 
512
                                xf_peer_rfx_update(client, invalid_region->x, invalid_region->y,
 
513
                                        invalid_region->w, invalid_region->h);
 
514
                        }
 
515
 
 
516
                        invalid_region->null = 1;
 
517
                        xfp->hdc->hwnd->ninvalid = 0;
 
518
 
 
519
                        xf_event_free(event);
 
520
                }
635
521
        }
636
522
 
637
523
        return true;
703
589
        return true;
704
590
}
705
591
 
706
 
void xf_peer_synchronize_event(rdpInput* input, uint32 flags)
707
 
{
708
 
        printf("Client sent a synchronize event (flags:0x%X)\n", flags);
709
 
}
710
 
 
711
 
void xf_peer_keyboard_event(rdpInput* input, uint16 flags, uint16 code)
712
 
{
713
 
        unsigned int keycode;
714
 
        boolean extended = false;
715
 
        xfPeerContext* xfp = (xfPeerContext*) input->context;
716
 
        xfInfo* xfi = xfp->info;
717
 
 
718
 
        if (flags & KBD_FLAGS_EXTENDED)
719
 
                extended = true;
720
 
 
721
 
        keycode = freerdp_kbd_get_keycode_by_scancode(code, extended);
722
 
 
723
 
        if (keycode != 0)
724
 
        {
725
 
#ifdef WITH_XTEST
726
 
                pthread_mutex_lock(&(xfp->mutex));
727
 
 
728
 
                if (flags & KBD_FLAGS_DOWN)
729
 
                        XTestFakeKeyEvent(xfi->display, keycode, True, 0);
730
 
                else if (flags & KBD_FLAGS_RELEASE)
731
 
                        XTestFakeKeyEvent(xfi->display, keycode, False, 0);
732
 
 
733
 
                pthread_mutex_unlock(&(xfp->mutex));
734
 
#endif
735
 
        }
736
 
}
737
 
 
738
 
void xf_peer_unicode_keyboard_event(rdpInput* input, uint16 code)
739
 
{
740
 
        printf("Client sent a unicode keyboard event (code:0x%X)\n", code);
741
 
}
742
 
 
743
 
void xf_peer_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
744
 
{
745
 
        int button = 0;
746
 
        boolean down = false;
747
 
        xfPeerContext* xfp = (xfPeerContext*) input->context;
748
 
        xfInfo* xfi = xfp->info;
749
 
 
750
 
        pthread_mutex_lock(&(xfp->mutex));
751
 
#ifdef WITH_XTEST
752
 
 
753
 
        if (flags & PTR_FLAGS_WHEEL)
754
 
        {
755
 
                boolean negative = false;
756
 
 
757
 
                if (flags & PTR_FLAGS_WHEEL_NEGATIVE)
758
 
                        negative = true;
759
 
 
760
 
                button = (negative) ? 5 : 4;
761
 
 
762
 
                XTestFakeButtonEvent(xfi->display, button, True, 0);
763
 
                XTestFakeButtonEvent(xfi->display, button, False, 0);
764
 
        }
765
 
        else
766
 
        {
767
 
                if (flags & PTR_FLAGS_MOVE)
768
 
                        XTestFakeMotionEvent(xfi->display, 0, x, y, 0);
769
 
 
770
 
                if (flags & PTR_FLAGS_BUTTON1)
771
 
                        button = 1;
772
 
                else if (flags & PTR_FLAGS_BUTTON2)
773
 
                        button = 3;
774
 
                else if (flags & PTR_FLAGS_BUTTON3)
775
 
                        button = 2;
776
 
 
777
 
                if (flags & PTR_FLAGS_DOWN)
778
 
                        down = true;
779
 
 
780
 
                if (button != 0)
781
 
                        XTestFakeButtonEvent(xfi->display, button, down, 0);
782
 
        }
783
 
#endif
784
 
        pthread_mutex_unlock(&(xfp->mutex));
785
 
}
786
 
 
787
 
void xf_peer_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
788
 
{
789
 
        xfPeerContext* xfp = (xfPeerContext*) input->context;
790
 
        xfInfo* xfi = xfp->info;
791
 
 
792
 
        pthread_mutex_lock(&(xfp->mutex));
793
 
#ifdef WITH_XTEST
794
 
        XTestFakeMotionEvent(xfi->display, 0, x, y, CurrentTime);
795
 
#endif
796
 
        pthread_mutex_unlock(&(xfp->mutex));
797
 
}
798
 
 
799
592
void* xf_peer_main_loop(void* arg)
800
593
{
801
594
        int i;
804
597
        int rcount;
805
598
        void* rfds[32];
806
599
        fd_set rfds_set;
 
600
        rdpSettings* settings;
 
601
        char* server_file_path;
807
602
        freerdp_peer* client = (freerdp_peer*) arg;
808
603
 
809
604
        memset(rfds, 0, sizeof(rfds));
811
606
        printf("We've got a client %s\n", client->hostname);
812
607
 
813
608
        xf_peer_init(client);
 
609
        settings = client->settings;
814
610
 
815
611
        /* Initialize the real server settings here */
816
 
        client->settings->cert_file = xstrdup("server.crt");
817
 
        client->settings->privatekey_file = xstrdup("server.key");
818
 
        client->settings->nla_security = false;
819
 
        client->settings->rfx_codec = true;
 
612
 
 
613
        if (settings->development_mode)
 
614
        {
 
615
                server_file_path = freerdp_construct_path(settings->development_path, "server/X11");
 
616
        }
 
617
        else
 
618
        {
 
619
                server_file_path = freerdp_construct_path(settings->config_path, "server");
 
620
 
 
621
                if (!freerdp_check_file_exists(server_file_path))
 
622
                        freerdp_mkdir(server_file_path);
 
623
        }
 
624
 
 
625
        settings->cert_file = freerdp_construct_path(server_file_path, "server.crt");
 
626
        settings->privatekey_file = freerdp_construct_path(server_file_path, "server.key");
 
627
 
 
628
        settings->nla_security = false;
 
629
        settings->rfx_codec = true;
820
630
 
821
631
        client->Capabilities = xf_peer_capabilities;
822
632
        client->PostConnect = xf_peer_post_connect;
823
633
        client->Activate = xf_peer_activate;
824
634
 
825
 
        client->input->SynchronizeEvent = xf_peer_synchronize_event;
826
 
        client->input->KeyboardEvent = xf_peer_keyboard_event;
827
 
        client->input->UnicodeKeyboardEvent = xf_peer_unicode_keyboard_event;
828
 
        client->input->MouseEvent = xf_peer_mouse_event;
829
 
        client->input->ExtendedMouseEvent = xf_peer_extended_mouse_event;
 
635
        xf_input_register_callbacks(client->input);
830
636
 
831
637
        client->Initialize(client);
832
638