xfreerdp: started handling RemoteApp icons

This commit is contained in:
Marc-André Moreau
2011-08-21 17:32:18 -04:00
parent 961b5f5e49
commit 00733ab128
15 changed files with 346 additions and 47 deletions

View File

@@ -112,6 +112,17 @@ void xf_rail_SetWindowText(rdpRail* rail, rdpWindow* window)
XStoreName(xfi->display, xfw->handle, window->title);
}
void xf_rail_SetWindowIcon(rdpRail* rail, rdpWindow* window, rdpIcon* icon)
{
xfInfo* xfi;
xfWindow* xfw;
xfi = (xfInfo*) rail->extra;
xfw = (xfWindow*) window->extra;
xf_SetWindowIcon(xfi, xfw, icon);
}
void xf_rail_DestroyWindow(rdpRail* rail, rdpWindow* window)
{
xfWindow* xfw;
@@ -125,6 +136,7 @@ void xf_rail_register_callbacks(xfInfo* xfi, rdpRail* rail)
rail->CreateWindow = xf_rail_CreateWindow;
rail->MoveWindow = xf_rail_MoveWindow;
rail->SetWindowText = xf_rail_SetWindowText;
rail->SetWindowIcon = xf_rail_SetWindowIcon;
rail->DestroyWindow = xf_rail_DestroyWindow;
}
@@ -186,12 +198,15 @@ void xf_process_rail_server_sysparam_event(xfInfo* xfi, rdpChanMan* chanman, RDP
switch (sysparam->param)
{
case SPI_SET_SCREEN_SAVE_ACTIVE:
printf("xf_process_rail_server_sysparam_event: Server System Param PDU: setScreenSaveActive=%d\n", sysparam->setScreenSaveActive);
break;
case SPI_SET_SCREEN_SAVE_SECURE:
printf("xf_process_rail_server_sysparam_event: Server System Param PDU: setScreenSaveSecure=%d\n", sysparam->setScreenSaveSecure);
break;
case SPI_SET_SCREEN_SAVE_ACTIVE:
printf("xf_process_rail_server_sysparam_event: Server System Param PDU: setScreenSaveActive=%d\n",
sysparam->setScreenSaveActive);
break;
case SPI_SET_SCREEN_SAVE_SECURE:
printf("xf_process_rail_server_sysparam_event: Server System Param PDU: setScreenSaveSecure=%d\n",
sysparam->setScreenSaveSecure);
break;
}
}
@@ -202,23 +217,14 @@ void xf_process_rail_server_minmaxinfo_event(xfInfo* xfi, rdpChanMan* chanman, R
printf("Server Min Max Info PDU: windowId=0x%X "
"maxWidth=%d maxHeight=%d maxPosX=%d maxPosY=%d "
"minTrackWidth=%d minTrackHeight=%d maxTrackWidth=%d maxTrackHeight=%d\n",
minmax->windowId,
minmax->maxWidth,
minmax->maxHeight,
minmax->maxPosX,
minmax->maxPosY,
minmax->minTrackWidth,
minmax->minTrackHeight,
minmax->maxTrackWidth,
minmax->maxTrackHeight
);
minmax->windowId, minmax->maxWidth, minmax->maxHeight,
minmax->maxPosX, minmax->maxPosY,
minmax->minTrackWidth, minmax->minTrackHeight,
minmax->maxTrackWidth, minmax->maxTrackHeight);
}
void xf_process_rail_server_localmovesize_event(xfInfo* xfi, rdpChanMan* chanman, RDP_EVENT* event)
const char* movetype_names[] =
{
RAIL_LOCALMOVESIZE_ORDER* movesize = (RAIL_LOCALMOVESIZE_ORDER*)event->user_data;
const char* movetype_names[] =
{
"(invalid)",
"RAIL_WMSZ_LEFT",
"RAIL_WMSZ_RIGHT",
@@ -230,17 +236,17 @@ void xf_process_rail_server_localmovesize_event(xfInfo* xfi, rdpChanMan* chanman
"RAIL_WMSZ_BOTTOMRIGHT",
"RAIL_WMSZ_MOVE",
"RAIL_WMSZ_KEYMOVE",
"RAIL_WMSZ_KEYSIZE",
};
"RAIL_WMSZ_KEYSIZE"
};
void xf_process_rail_server_localmovesize_event(xfInfo* xfi, rdpChanMan* chanman, RDP_EVENT* event)
{
RAIL_LOCALMOVESIZE_ORDER* movesize = (RAIL_LOCALMOVESIZE_ORDER*) event->user_data;
printf("Server Local MoveSize PDU: windowId=0x%X "
"isMoveSizeStart=%d moveSizeType=%s PosX=%d PosY=%d\n",
movesize->windowId,
movesize->isMoveSizeStart,
movetype_names[movesize->moveSizeType],
movesize->posX,
movesize->posY
);
movesize->windowId, movesize->isMoveSizeStart,
movetype_names[movesize->moveSizeType], movesize->posX, movesize->posY);
}
void xf_process_rail_appid_resp_event(xfInfo* xfi, rdpChanMan* chanman, RDP_EVENT* event)
@@ -250,20 +256,18 @@ void xf_process_rail_appid_resp_event(xfInfo* xfi, rdpChanMan* chanman, RDP_EVEN
printf("Server Application ID Response PDU: windowId=0x%X "
"applicationId=(length=%d dump)\n",
appid_resp->windowId,
appid_resp->applicationId.length
);
appid_resp->windowId, appid_resp->applicationId.length);
freerdp_hexdump(appid_resp->applicationId.string, appid_resp->applicationId.length);
}
void xf_process_rail_langbarinfo_event(xfInfo* xfi, rdpChanMan* chanman, RDP_EVENT* event)
{
RAIL_LANGBAR_INFO_ORDER* langbar =
(RAIL_LANGBAR_INFO_ORDER*)event->user_data;
(RAIL_LANGBAR_INFO_ORDER*) event->user_data;
printf("Language Bar Information PDU: languageBarStatus=0x%X\n",
langbar->languageBarStatus
);
langbar->languageBarStatus);
}
void xf_process_rail_event(xfInfo* xfi, rdpChanMan* chanman, RDP_EVENT* event)

View File

@@ -23,6 +23,10 @@
/* Extended Window Manager Hints: http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html */
#ifndef XA_CARDINAL
#define XA_CARDINAL 6
#endif
#define MWM_HINTS_DECORATIONS (1L << 1)
#define PROP_MOTIF_WM_HINTS_ELEMENTS 5
@@ -305,6 +309,52 @@ void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int h
window->height = height;
}
void xf_SetWindowIcon(xfInfo* xfi, xfWindow* window, rdpIcon* icon)
{
Atom atom;
int x, y;
int pixels;
int propsize;
long* propdata;
long* dstp;
uint32* srcp;
if ((icon->big != True) || (icon->entry->bpp != 32))
return;
pixels = icon->entry->width * icon->entry->height;
propsize = 2 + pixels;
propdata = xmalloc(propsize * sizeof(long));
propdata[0] = icon->entry->width;
propdata[1] = icon->entry->height;
dstp = &(propdata[2]);
srcp = (uint32*) icon->entry->bitsColor;
for (y = 0; y < icon->entry->height; y++)
{
for (x = 0; x < icon->entry->width; x++)
{
*dstp++ = *srcp++;
}
}
atom = XInternAtom(xfi->display, "_NET_WM_ICON", False);
if (!atom)
{
printf("xf_SetWindowIcon: failed to obtain atom _NET_WM_ICON\n");
return;
}
else
{
XChangeProperty(xfi->display, window->handle, atom, XA_CARDINAL, 32,
PropModeReplace, (uint8*) propdata, propsize);
XFlush(xfi->display);
}
}
void xf_DestroyWindow(xfInfo* xfi, xfWindow* window)
{
XFreeGC(xfi->display, window->gc);

View File

@@ -51,6 +51,7 @@ xfWindow* desktop_create(xfInfo* xfi, char* name);
xfWindow* xf_CreateWindow(xfInfo* xfi, int x, int y, int width, int height, char* name);
void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height);
void xf_SetWindowIcon(xfInfo* xfi, xfWindow* window, rdpIcon* icon);
void xf_DestroyWindow(xfInfo* xfi, xfWindow* window);
#endif /* __XF_WINDOW_H */

View File

@@ -376,7 +376,7 @@ boolean xf_post_connect(freerdp* instance)
instance->update->BeginPaint = xf_begin_paint;
instance->update->EndPaint = xf_end_paint;
xfi->rail = rail_new();
xfi->rail = rail_new(instance->settings);
instance->update->rail = (void*) xfi->rail;
rail_register_update_callbacks(xfi->rail, instance->update);
xf_rail_register_callbacks(xfi, xfi->rail);

View File

@@ -0,0 +1,61 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Window Icon Cache
*
* 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 __RAIL_ICON_CACHE_H
#define __RAIL_ICON_CACHE_H
#include <freerdp/api.h>
#include <freerdp/rail.h>
#include <freerdp/types.h>
#include <freerdp/update.h>
#include <freerdp/utils/stream.h>
typedef struct rdp_icon rdpIcon;
typedef struct rdp_icon_cache rdpIconCache;
#include <freerdp/rail/rail.h>
struct rdp_icon
{
ICON_INFO* entry;
boolean big;
void* extra;
};
struct _WINDOW_ICON_CACHE
{
rdpIcon* entries;
};
typedef struct _WINDOW_ICON_CACHE WINDOW_ICON_CACHE;
struct rdp_icon_cache
{
rdpRail* rail;
uint8 numCaches;
uint16 numCacheEntries;
WINDOW_ICON_CACHE* caches;
};
ICON_INFO* icon_cache_get(rdpIconCache* cache, uint8 id, uint16 index, void** extra);
void icon_cache_put(rdpIconCache* cache, uint8 id, uint16 index, ICON_INFO* entry, void* extra);
rdpIconCache* icon_cache_new(rdpRail* rail);
void icon_cache_free(rdpIconCache* cache);
#endif /* __RAIL_ICON_H */

View File

@@ -28,6 +28,7 @@
typedef struct rdp_rail rdpRail;
#include <freerdp/rail/icon.h>
#include <freerdp/rail/window.h>
#include <freerdp/rail/window_list.h>
@@ -35,21 +36,25 @@ typedef void (*railCreateWindow)(rdpRail* rail, rdpWindow* window);
typedef void (*railDestroyWindow)(rdpRail* rail, rdpWindow* window);
typedef void (*railMoveWindow)(rdpRail* rail, rdpWindow* window);
typedef void (*railSetWindowText)(rdpRail* rail, rdpWindow* window);
typedef void (*railSetWindowIcon)(rdpRail* rail, rdpWindow* window, rdpIcon* icon);
struct rdp_rail
{
void* extra;
UNICONV* uniconv;
rdpIconCache* cache;
rdpWindowList* list;
rdpSettings* settings;
railCreateWindow CreateWindow;
railDestroyWindow DestroyWindow;
railMoveWindow MoveWindow;
railSetWindowText SetWindowText;
railSetWindowIcon SetWindowIcon;
};
FREERDP_API void rail_register_update_callbacks(rdpRail* rail, rdpUpdate* update);
FREERDP_API rdpRail* rail_new();
FREERDP_API rdpRail* rail_new(rdpSettings* settings);
FREERDP_API void rail_free(rdpRail* rail);
#endif /* __RAIL_H */

View File

@@ -17,8 +17,8 @@
* limitations under the License.
*/
#ifndef __WINDOW_H
#define __WINDOW_H
#ifndef __RAIL_WINDOW_H
#define __RAIL_WINDOW_H
#include <freerdp/api.h>
#include <freerdp/rail.h>
@@ -29,12 +29,15 @@
typedef struct rdp_window rdpWindow;
#include <freerdp/rail/rail.h>
#include <freerdp/rail/icon.h>
struct rdp_window
{
void* extra;
void* extraId;
char* title;
rdpIcon* bigIcon;
rdpIcon* smallIcon;
uint32 fieldFlags;
rdpWindow* prev;
rdpWindow* next;
@@ -70,4 +73,4 @@ FREERDP_API void rail_CreateWindow(rdpRail* rail, rdpWindow* window);
FREERDP_API void rail_UpdateWindow(rdpRail* rail, rdpWindow* window);
FREERDP_API void rail_DestroyWindow(rdpRail* rail, rdpWindow* window);
#endif /* __WINDOW_H */
#endif /* __RAIL_WINDOW_H */

View File

@@ -17,8 +17,8 @@
* limitations under the License.
*/
#ifndef __WINDOW_LIST_H
#define __WINDOW_LIST_H
#ifndef __RAIL_WINDOW_LIST_H
#define __RAIL_WINDOW_LIST_H
#include <freerdp/api.h>
#include <freerdp/types.h>
@@ -42,7 +42,8 @@ FREERDP_API void window_list_rewind(rdpWindowList* list);
FREERDP_API boolean window_list_has_next(rdpWindowList* list);
FREERDP_API rdpWindow* window_list_get_next(rdpWindowList* list);
rdpWindow* window_list_get_by_extra_id(rdpWindowList* list, void* extraId);
FREERDP_API rdpWindow* window_list_get_by_id(rdpWindowList* list, uint32 windowId);
FREERDP_API rdpWindow* window_list_get_by_extra_id(rdpWindowList* list, void* extraId);
FREERDP_API void window_list_create(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state);
FREERDP_API void window_list_update(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state);
@@ -51,4 +52,4 @@ FREERDP_API void window_list_delete(rdpWindowList* list, WINDOW_ORDER_INFO* orde
FREERDP_API rdpWindowList* window_list_new(rdpRail* rail);
FREERDP_API void window_list_free(rdpWindowList* list);
#endif /* __WINDOW_LIST_H */
#endif /* __RAIL_WINDOW_LIST_H */

View File

@@ -748,7 +748,7 @@ typedef struct _WINDOW_STATE_ORDER WINDOW_STATE_ORDER;
struct _WINDOW_ICON_ORDER
{
ICON_INFO iconInfo;
ICON_INFO* iconInfo;
};
typedef struct _WINDOW_ICON_ORDER WINDOW_ICON_ORDER;

View File

@@ -243,6 +243,6 @@ void update_read_draw_gdiplus_cache_first_order(STREAM* s, DRAW_GDIPLUS_CACHE_FI
void update_read_draw_gdiplus_cache_next_order(STREAM* s, DRAW_GDIPLUS_CACHE_NEXT_ORDER* draw_gdiplus_cache_next);
void update_read_draw_gdiplus_cache_end_order(STREAM* s, DRAW_GDIPLUS_CACHE_END_ORDER* draw_gdiplus_cache_end);
#define WITH_DEBUG_ORDERS 1
//#define WITH_DEBUG_ORDERS 1
#endif /* __ORDERS_H */

View File

@@ -177,7 +177,8 @@ void update_read_window_state_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WIN
void update_read_window_icon_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* window_icon)
{
update_read_icon_info(s, &window_icon->iconInfo); /* iconInfo (ICON_INFO) */
window_icon->iconInfo = (ICON_INFO*) xzalloc(sizeof(ICON_INFO));
update_read_icon_info(s, window_icon->iconInfo); /* iconInfo (ICON_INFO) */
}
void update_read_window_cached_icon_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WINDOW_CACHED_ICON_ORDER* window_cached_icon)

View File

@@ -20,6 +20,7 @@
set(FREERDP_RAIL_SRCS
window_list.c
window.c
icon.c
rail.c)
add_library(freerdp-rail SHARED ${FREERDP_RAIL_SRCS})

112
libfreerdp-rail/icon.c Normal file
View File

@@ -0,0 +1,112 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Window Icon Cache
*
* 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.
*/
#include <freerdp/utils/stream.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/hexdump.h>
#include <freerdp/utils/unicode.h>
#include <freerdp/rail/icon.h>
ICON_INFO* icon_cache_get(rdpIconCache* cache, uint8 id, uint16 index, void** extra)
{
ICON_INFO* entry;
if (id >= cache->numCaches)
{
printf("invalid window icon cache id:%d\n", id);
return (ICON_INFO*) NULL;
}
if (index >= cache->numCacheEntries)
{
printf("invalid window icon cache index:%d in cache id:%d\n", index, id);
return (ICON_INFO*) NULL;
}
entry = cache->caches[id].entries[index].entry;
if (extra != NULL)
*extra = cache->caches[id].entries[index].extra;
return entry;
}
void icon_cache_put(rdpIconCache* cache, uint8 id, uint16 index, ICON_INFO* entry, void* extra)
{
if (id >= cache->numCaches)
{
printf("invalid window icon cache id:%d\n", id);
return;
}
if (index >= cache->numCacheEntries)
{
printf("invalid window icon cache index:%d in cache id:%d\n", index, id);
return;
}
cache->caches[id].entries[index].entry = entry;
if (extra != NULL)
cache->caches[id].entries[index].extra = extra;
}
rdpIconCache* icon_cache_new(rdpRail* rail)
{
rdpIconCache* cache;
cache = (rdpIconCache*) xzalloc(sizeof(rdpIconCache));
if (cache != NULL)
{
int i;
cache->rail = rail;
cache->numCaches = rail->settings->num_icon_cache_entries;
cache->numCacheEntries = rail->settings->num_icon_cache_entries;
cache->caches = xzalloc(cache->numCaches * sizeof(WINDOW_ICON_CACHE));
for (i = 0; i < cache->numCaches; i++)
{
cache->caches[i].entries = xzalloc(cache->numCacheEntries * sizeof(rdpIconCache));
}
}
return cache;
}
void icon_cache_free(rdpIconCache* cache)
{
if (cache != NULL)
{
int i;
for (i = 0; i < cache->numCaches; i++)
{
xfree(cache->caches[i].entries);
}
xfree(cache->caches);
xfree(cache);
}
}

View File

@@ -21,6 +21,7 @@
#include <freerdp/utils/memory.h>
#include <freerdp/rail/rail.h>
#include <freerdp/rail/window_list.h>
static void rail_WindowCreate(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state)
{
@@ -43,14 +44,54 @@ static void rail_WindowDelete(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo)
window_list_delete(rail->list, orderInfo);
}
static void rail_WindowIcon(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* window_icon)
{
rdpRail* rail;
rdpIcon* icon;
rdpWindow* window;
rail = (rdpRail*) update->rail;
if (window_icon->iconInfo->cacheEntry != 0xFFFF)
{
/* cache icon */
}
window = window_list_get_by_id(rail->list, orderInfo->windowId);
icon = (rdpIcon*) xzalloc(sizeof(rdpIcon));
icon->entry = window_icon->iconInfo;
icon->big = (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ICON_BIG) ? True : False;
printf("Window Icon: %dx%d@%dbpp cbBitsColor:%d cbBitsMask:%d cbColorTable:%d\n",
window_icon->iconInfo->width, window_icon->iconInfo->height, window_icon->iconInfo->bpp,
window_icon->iconInfo->cbBitsColor, window_icon->iconInfo->cbBitsMask, window_icon->iconInfo->cbColorTable);
if (icon->big)
window->bigIcon = icon;
else
window->smallIcon = icon;
IFCALL(rail->SetWindowIcon, rail, window, icon);
}
static void rail_WindowCachedIcon(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo, WINDOW_CACHED_ICON_ORDER* window_cached_icon)
{
rdpRail* rail;
rail = (rdpRail*) update->rail;
printf("rail_WindowCachedIcon\n");
}
void rail_register_update_callbacks(rdpRail* rail, rdpUpdate* update)
{
update->WindowCreate = rail_WindowCreate;
update->WindowUpdate = rail_WindowUpdate;
update->WindowDelete = rail_WindowDelete;
update->WindowIcon = rail_WindowIcon;
update->WindowCachedIcon = rail_WindowCachedIcon;
}
rdpRail* rail_new()
rdpRail* rail_new(rdpSettings* settings)
{
rdpRail* rail;
@@ -58,6 +99,8 @@ rdpRail* rail_new()
if (rail != NULL)
{
rail->settings = settings;
rail->cache = icon_cache_new(rail);
rail->list = window_list_new(rail);
rail->uniconv = freerdp_uniconv_new();
}
@@ -69,6 +112,7 @@ void rail_free(rdpRail* rail)
{
if (rail != NULL)
{
icon_cache_free(rail->cache);
window_list_free(rail->list);
freerdp_uniconv_free(rail->uniconv);
xfree(rail);

View File

@@ -31,12 +31,14 @@ void window_state_update(rdpWindow* window, WINDOW_ORDER_INFO* orderInfo, WINDOW
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OWNER)
{
window->ownerWindowId = window_state->ownerWindowId;
printf("ownerWindowId:0x%08X\n", window->ownerWindowId);
}
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_STYLE)
{
window->style = window_state->style;
window->extendedStyle = window_state->extendedStyle;
printf("Style:%d, ExtendedStyle:%d\n", window->style, window->extendedStyle);
}
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_SHOW)
@@ -110,7 +112,14 @@ void window_state_update(rdpWindow* window, WINDOW_ORDER_INFO* orderInfo, WINDOW
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
{
int i;
for (i = 0; i < window_state->numWindowRects; i++)
{
printf("Window Rect #%d: left:%d top:%d right:%d bottom:%d\n", i,
window_state->windowRects->left, window_state->windowRects->top,
window_state->windowRects->right, window_state->windowRects->bottom);
}
}
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
@@ -124,7 +133,14 @@ void window_state_update(rdpWindow* window, WINDOW_ORDER_INFO* orderInfo, WINDOW
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
{
int i;
for (i = 0; i < window_state->numVisibilityRects; i++)
{
printf("Visibility Rect #%d: left:%d top:%d right:%d bottom:%d\n", i,
window_state->visibilityRects->left, window_state->visibilityRects->top,
window_state->visibilityRects->right, window_state->visibilityRects->bottom);
}
}
}