xfreerdp-server: replaced old eventing system with MessageQueue

This commit is contained in:
Marc-André Moreau 2013-02-17 11:59:29 -05:00
parent edc2b1de9e
commit aa8851fb45
8 changed files with 51 additions and 331 deletions

View File

@ -22,7 +22,6 @@ include_directories(${X11_INCLUDE_DIRS})
set(${MODULE_PREFIX}_SRCS
xf_peer.c
xf_event.c
xf_input.c
xf_encode.c
xfreerdp.c)

View File

@ -85,7 +85,6 @@ void xf_xdamage_subtract_region(xfPeerContext* xfp, int x, int y, int width, int
void* xf_frame_rate_thread(void* param)
{
xfInfo* xfi;
xfEvent* event;
xfPeerContext* xfp;
freerdp_peer* client;
UINT32 wait_interval;
@ -100,9 +99,10 @@ void* xf_frame_rate_thread(void* param)
{
/* check if we should terminate */
pthread_testcancel();
event = xf_event_new(XF_EVENT_TYPE_FRAME_TICK);
xf_event_push(xfp->event_queue, (xfEvent*) event);
MessageQueue_Post(xfp->queue, (void*) xfp,
MakeMessageId(PeerEvent, FrameRateTick), NULL, NULL);
USleep(wait_interval);
}
}
@ -121,7 +121,6 @@ void* xf_monitor_updates(void* param)
struct timeval timeout;
int x, y, width, height;
XDamageNotifyEvent* notify;
xfEventRegion* event_region;
client = (freerdp_peer*) param;
xfp = (xfPeerContext*) client->context;
@ -167,6 +166,7 @@ void* xf_monitor_updates(void* param)
if (xevent.type == xfi->xdamage_notify_event)
{
UINT32 xy, wh;
notify = (XDamageNotifyEvent*) &xevent;
x = notify->area.x;
@ -176,8 +176,12 @@ void* xf_monitor_updates(void* param)
xf_xdamage_subtract_region(xfp, x, y, width, height);
event_region = xf_event_region_new(x, y, width, height);
xf_event_push(xfp->event_queue, (xfEvent*) event_region);
xy = (x << 16) | y;
wh = (width << 16) | height;
MessageQueue_Post(xfp->queue, (void*) xfp,
MakeMessageId(PeerEvent, InvalidRegion),
(void*) (size_t) xy, (void*) (size_t) wh);
}
}
}

View File

@ -1,225 +0,0 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* X11 Server Event Handling
*
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <winpr/crt.h>
#include "xf_event.h"
int xf_is_event_set(xfEventQueue* event_queue)
{
fd_set rfds;
int num_set;
struct timeval time;
FD_ZERO(&rfds);
FD_SET(event_queue->pipe_fd[0], &rfds);
memset(&time, 0, sizeof(time));
num_set = select(event_queue->pipe_fd[0] + 1, &rfds, 0, 0, &time);
return (num_set == 1);
}
void xf_signal_event(xfEventQueue* event_queue)
{
int length;
length = write(event_queue->pipe_fd[1], "sig", 4);
if (length != 4)
printf("xf_signal_event: error\n");
}
void xf_set_event(xfEventQueue* event_queue)
{
int length;
length = write(event_queue->pipe_fd[1], "sig", 4);
if (length != 4)
printf("xf_set_event: error\n");
}
void xf_clear_events(xfEventQueue* event_queue)
{
int length;
while (xf_is_event_set(event_queue))
{
length = read(event_queue->pipe_fd[0], &length, 4);
if (length != 4)
printf("xf_clear_event: error\n");
}
}
void xf_clear_event(xfEventQueue* event_queue)
{
int length;
length = read(event_queue->pipe_fd[0], &length, 4);
if (length != 4)
printf("xf_clear_event: error\n");
}
void xf_event_push(xfEventQueue* event_queue, xfEvent* event)
{
pthread_mutex_lock(&(event_queue->mutex));
if (event_queue->count >= event_queue->size)
{
event_queue->size *= 2;
event_queue->events = (xfEvent**) realloc((void*) event_queue->events, sizeof(xfEvent*) * event_queue->size);
}
event_queue->events[(event_queue->count)++] = event;
pthread_mutex_unlock(&(event_queue->mutex));
xf_set_event(event_queue);
}
xfEvent* xf_event_peek(xfEventQueue* event_queue)
{
xfEvent* event;
pthread_mutex_lock(&(event_queue->mutex));
if (event_queue->count < 1)
event = NULL;
else
event = event_queue->events[0];
pthread_mutex_unlock(&(event_queue->mutex));
return event;
}
xfEvent* xf_event_pop(xfEventQueue* event_queue)
{
xfEvent* event;
pthread_mutex_lock(&(event_queue->mutex));
if (event_queue->count < 1)
return NULL;
/* remove event signal */
xf_clear_event(event_queue);
event = event_queue->events[0];
(event_queue->count)--;
memmove(&event_queue->events[0], &event_queue->events[1], event_queue->count * sizeof(void*));
pthread_mutex_unlock(&(event_queue->mutex));
return event;
}
xfEventRegion* xf_event_region_new(int x, int y, int width, int height)
{
xfEventRegion* event_region;
event_region = (xfEventRegion*) malloc(sizeof(xfEventRegion));
ZeroMemory(event_region, sizeof(xfEventRegion));
if (event_region != NULL)
{
event_region->x = x;
event_region->y = y;
event_region->width = width;
event_region->height = height;
}
return event_region;
}
void xf_event_region_free(xfEventRegion* event_region)
{
free(event_region);
}
xfEvent* xf_event_new(int type)
{
xfEvent* event;
event = (xfEvent*) malloc(sizeof(xfEvent));
ZeroMemory(event, sizeof(xfEvent));
event->type = type;
return event;
}
void xf_event_free(xfEvent* event)
{
free(event);
}
xfEventQueue* xf_event_queue_new()
{
xfEventQueue* event_queue;
event_queue = (xfEventQueue*) malloc(sizeof(xfEventQueue));
ZeroMemory(event_queue, sizeof(xfEventQueue));
if (event_queue != NULL)
{
event_queue->pipe_fd[0] = -1;
event_queue->pipe_fd[1] = -1;
event_queue->size = 16;
event_queue->count = 0;
event_queue->events = (xfEvent**) malloc(sizeof(xfEvent*) * event_queue->size);
ZeroMemory(event_queue->events, sizeof(xfEvent*) * event_queue->size);
if (pipe(event_queue->pipe_fd) < 0)
printf("xf_event_queue_new: pipe failed\n");
pthread_mutex_init(&(event_queue->mutex), NULL);
}
return event_queue;
}
void xf_event_queue_free(xfEventQueue* event_queue)
{
if (event_queue->pipe_fd[0] != -1)
{
close(event_queue->pipe_fd[0]);
event_queue->pipe_fd[0] = -1;
}
if (event_queue->pipe_fd[1] != -1)
{
close(event_queue->pipe_fd[1]);
event_queue->pipe_fd[1] = -1;
}
pthread_mutex_destroy(&(event_queue->mutex));
}

View File

@ -1,75 +0,0 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* X11 Server Event Handling
*
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __XF_EVENT_H
#define __XF_EVENT_H
typedef struct xf_event xfEvent;
typedef struct xf_event_queue xfEventQueue;
typedef struct xf_event_region xfEventRegion;
#include <pthread.h>
#include "xfreerdp.h"
#include "xf_peer.h"
enum xf_event_type
{
XF_EVENT_TYPE_REGION,
XF_EVENT_TYPE_FRAME_TICK
};
struct xf_event
{
int type;
};
struct xf_event_queue
{
int size;
int count;
int pipe_fd[2];
xfEvent** events;
pthread_mutex_t mutex;
};
struct xf_event_region
{
int type;
int x;
int y;
int width;
int height;
};
void xf_event_push(xfEventQueue* event_queue, xfEvent* event);
xfEvent* xf_event_peek(xfEventQueue* event_queue);
xfEvent* xf_event_pop(xfEventQueue* event_queue);
xfEventRegion* xf_event_region_new(int x, int y, int width, int height);
void xf_event_region_free(xfEventRegion* event_region);
xfEvent* xf_event_new(int type);
void xf_event_free(xfEvent* event);
xfEventQueue* xf_event_queue_new(void);
void xf_event_queue_free(xfEventQueue* event_queue);
#endif /* __XF_EVENT_H */

View File

@ -25,6 +25,8 @@
#include <freerdp/locale/keyboard.h>
#include "xf_peer.h"
#include "xf_input.h"
void xf_input_synchronize_event(rdpInput* input, UINT32 flags)

View File

@ -44,7 +44,6 @@
extern char* xf_pcap_file;
extern BOOL xf_pcap_dump_realtime;
#include "xf_event.h"
#include "xf_input.h"
#include "xf_encode.h"
@ -313,7 +312,8 @@ void xf_peer_init(freerdp_peer* client)
xfp->fps = 24;
xfp->thread = 0;
xfp->activations = 0;
xfp->event_queue = xf_event_queue_new();
xfp->queue = MessageQueue_New();
xfi = xfp->info;
xfp->hdc = gdi_CreateDC(xfi->clrconv, xfi->bpp);
@ -490,12 +490,13 @@ void xf_peer_rfx_update(freerdp_peer* client, int x, int y, int width, int heigh
BOOL xf_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount)
{
int fds;
HANDLE event;
xfPeerContext* xfp = (xfPeerContext*) client->context;
if (xfp->event_queue->pipe_fd[0] == -1)
return TRUE;
rfds[*rcount] = (void *)(long) xfp->event_queue->pipe_fd[0];
event = MessageQueue_Event(xfp->queue);
fds = GetEventFileDescriptor(event);
rfds[*rcount] = (void*) (long) fds;
(*rcount)++;
return TRUE;
@ -504,7 +505,7 @@ BOOL xf_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount)
BOOL xf_peer_check_fds(freerdp_peer* client)
{
xfInfo* xfi;
xfEvent* event;
wMessage message;
xfPeerContext* xfp;
HGDI_RGN invalid_region;
@ -514,22 +515,29 @@ BOOL xf_peer_check_fds(freerdp_peer* client)
if (xfp->activated == FALSE)
return TRUE;
event = xf_event_peek(xfp->event_queue);
if (event != NULL)
if (MessageQueue_Peek(xfp->queue, &message, TRUE))
{
if (event->type == XF_EVENT_TYPE_REGION)
if (message.id == MakeMessageId(PeerEvent, InvalidRegion))
{
xfEventRegion* region = (xfEventRegion*) xf_event_pop(xfp->event_queue);
gdi_InvalidateRegion(xfp->hdc, region->x, region->y, region->width, region->height);
xf_event_region_free(region);
UINT32 xy, wh;
UINT16 x, y, w, h;
xy = (UINT32) (size_t) message.wParam;
wh = (UINT32) (size_t) message.lParam;
x = ((xy & 0xFFFF0000) >> 16);
y = (xy & 0x0000FFFF);
w = ((wh & 0xFFFF0000) >> 16);
h = (wh & 0x0000FFFF);
gdi_InvalidateRegion(xfp->hdc, x, y, w, h);
}
else if (event->type == XF_EVENT_TYPE_FRAME_TICK)
else if (message.id == MakeMessageId(PeerEvent, FrameRateTick))
{
event = xf_event_pop(xfp->event_queue);
invalid_region = xfp->hdc->hwnd->invalid;
if (invalid_region->null == FALSE)
if (!invalid_region->null)
{
xf_peer_rfx_update(client, invalid_region->x, invalid_region->y,
invalid_region->w, invalid_region->h);
@ -537,8 +545,6 @@ BOOL xf_peer_check_fds(freerdp_peer* client)
invalid_region->null = 1;
xfp->hdc->hwnd->ninvalid = 0;
xf_event_free(event);
}
}
@ -628,7 +634,7 @@ void* xf_peer_main_loop(void* arg)
freerdp_peer* client = (freerdp_peer*) arg;
xfPeerContext* xfp;
memset(rfds, 0, sizeof(rfds));
ZeroMemory(rfds, sizeof(rfds));
printf("We've got a client %s\n", client->hostname);

View File

@ -20,6 +20,9 @@
#ifndef __XF_PEER_H
#define __XF_PEER_H
#include <winpr/crt.h>
#include <winpr/collections.h>
#include <freerdp/gdi/gdi.h>
#include <freerdp/gdi/dc.h>
#include <freerdp/gdi/region.h>
@ -32,6 +35,13 @@ typedef struct xf_peer_context xfPeerContext;
#include "xfreerdp.h"
#define PeerEvent_Base 0
#define PeerEvent_Class (PeerEvent_Base + 1)
#define PeerEvent_InvalidRegion 1
#define PeerEvent_FrameRateTick 2
struct xf_peer_context
{
rdpContext _p;
@ -45,8 +55,9 @@ struct xf_peer_context
BOOL activated;
pthread_mutex_t mutex;
RFX_CONTEXT* rfx_context;
xfEventQueue* event_queue;
pthread_t frame_rate_thread;
wMessageQueue* queue;
};
void xf_peer_accepted(freerdp_listener* instance, freerdp_peer* client);

View File

@ -40,8 +40,6 @@
typedef struct xf_info xfInfo;
#include "xf_event.h"
struct xf_info
{
int bpp;