libfreerdp-cache: added bitmap_v2 cache

This commit is contained in:
Marc-André Moreau 2011-08-05 16:56:40 -04:00
parent 2d5ade5c92
commit 809338d213
13 changed files with 537 additions and 30 deletions

View File

@ -56,10 +56,17 @@ void df_end_paint(rdpUpdate* update)
if (gdi->primary->hdc->hwnd->invalid->null)
return;
#if 1
dfi->update_rect.x = gdi->primary->hdc->hwnd->invalid->x;
dfi->update_rect.y = gdi->primary->hdc->hwnd->invalid->y;
dfi->update_rect.w = gdi->primary->hdc->hwnd->invalid->w;
dfi->update_rect.h = gdi->primary->hdc->hwnd->invalid->h;
#else
dfi->update_rect.x = 0;
dfi->update_rect.y = 0;
dfi->update_rect.w = gdi->width;
dfi->update_rect.h = gdi->height;
#endif
dfi->primary->Blit(dfi->primary, dfi->surface, &(dfi->update_rect), dfi->update_rect.x, dfi->update_rect.y);
}
@ -115,7 +122,7 @@ boolean df_pre_connect(freerdp* instance)
settings->order_support[NEG_POLYLINE_INDEX] = True;
settings->order_support[NEG_MEMBLT_INDEX] = True;
settings->order_support[NEG_MEM3BLT_INDEX] = False;
settings->order_support[NEG_SAVEBITMAP_INDEX] = False;
settings->order_support[NEG_SAVEBITMAP_INDEX] = True;
settings->order_support[NEG_GLYPH_INDEX_INDEX] = True;
settings->order_support[NEG_FAST_INDEX_INDEX] = True;
settings->order_support[NEG_FAST_GLYPH_INDEX] = True;

View File

@ -27,3 +27,4 @@ add_executable(freerdp-test
target_link_libraries(freerdp-test freerdp-core)
target_link_libraries(freerdp-test freerdp-gdi)
target_link_libraries(freerdp-test freerdp-utils)
target_link_libraries(freerdp-test freerdp-chanman)

View File

@ -2,7 +2,7 @@
* FreeRDP: A Remote Desktop Protocol Client
* FreeRDP Test UI
*
* Copyright 2010 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* 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.
@ -18,26 +18,302 @@
*/
#include "gdi.h"
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/select.h>
#include <freerdp/utils/args.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/semaphore.h>
#include <freerdp/utils/event.h>
#include <freerdp/constants.h>
#include <freerdp/chanman.h>
#define SET_TFI(_instance, _tfi) (_instance)->param1 = _tfi
#define GET_TFI(_instance) ((tfInfo*) ((_instance)->param1))
#define SET_CHANMAN(_instance, _chanman) (_instance)->param2 = _chanman
#define GET_CHANMAN(_instance) ((rdpChanMan*) ((_instance)->param2))
struct tf_info
{
};
typedef struct tf_info tfInfo;
freerdp_sem g_sem;
static int g_thread_count = 0;
struct thread_data
{
freerdp* instance;
};
#include <freerdp/freerdp.h>
#include <freerdp/utils/args.h>
freerdp* instance;
rdpSettings* settings;
int main(int argc, char* argv[])
void tf_begin_paint(rdpUpdate* update)
{
instance = freerdp_new();
GDI* gdi = GET_GDI(update);
gdi->primary->hdc->hwnd->invalid->null = 1;
}
void tf_end_paint(rdpUpdate* update)
{
GDI* gdi;
tfInfo* tfi;
gdi = GET_GDI(update);
tfi = GET_TFI(update);
if (gdi->primary->hdc->hwnd->invalid->null)
return;
}
int tf_receive_channel_data(freerdp* instance, int channelId, uint8* data, int size, int flags, int total_size)
{
return freerdp_chanman_data(instance, channelId, data, size, flags, total_size);
}
int tf_process_plugin_args(rdpSettings* settings, const char* name, FRDP_PLUGIN_DATA* plugin_data, void* user_data)
{
rdpChanMan* chanman = (rdpChanMan*) user_data;
printf("Load plugin %s\n", name);
freerdp_chanman_load_plugin(chanman, settings, name, plugin_data);
return 1;
}
void tf_process_cb_sync_event(rdpChanMan* chanman, freerdp* instance)
{
FRDP_EVENT* event;
FRDP_CB_FORMAT_LIST_EVENT* format_list_event;
event = freerdp_event_new(FRDP_EVENT_TYPE_CB_FORMAT_LIST, NULL, NULL);
format_list_event = (FRDP_CB_FORMAT_LIST_EVENT*)event;
format_list_event->num_formats = 0;
freerdp_chanman_send_event(chanman, "cliprdr", event);
}
void tf_process_channel_event(rdpChanMan* chanman, freerdp* instance)
{
FRDP_EVENT* event;
event = freerdp_chanman_pop_event(chanman);
if (event)
{
switch (event->event_type)
{
case FRDP_EVENT_TYPE_CB_SYNC:
tf_process_cb_sync_event(chanman, instance);
break;
default:
printf("tf_process_channel_event: unknown event type %d\n", event->event_type);
break;
}
freerdp_event_free(event);
}
}
boolean tf_pre_connect(freerdp* instance)
{
tfInfo* tfi;
rdpSettings* settings;
tfi = (tfInfo*) xzalloc(sizeof(tfInfo));
SET_TFI(instance, tfi);
settings = instance->settings;
freerdp_parse_args(settings, argc, argv, NULL, NULL, NULL, NULL);
settings->order_support[NEG_DSTBLT_INDEX] = True;
settings->order_support[NEG_PATBLT_INDEX] = True;
settings->order_support[NEG_SCRBLT_INDEX] = True;
settings->order_support[NEG_OPAQUE_RECT_INDEX] = True;
settings->order_support[NEG_DRAWNINEGRID_INDEX] = True;
settings->order_support[NEG_MULTIDSTBLT_INDEX] = True;
settings->order_support[NEG_MULTIPATBLT_INDEX] = True;
settings->order_support[NEG_MULTISCRBLT_INDEX] = True;
settings->order_support[NEG_MULTIOPAQUERECT_INDEX] = True;
settings->order_support[NEG_MULTI_DRAWNINEGRID_INDEX] = True;
settings->order_support[NEG_LINETO_INDEX] = True;
settings->order_support[NEG_POLYLINE_INDEX] = True;
settings->order_support[NEG_MEMBLT_INDEX] = True;
settings->order_support[NEG_MEM3BLT_INDEX] = True;
settings->order_support[NEG_SAVEBITMAP_INDEX] = True;
settings->order_support[NEG_GLYPH_INDEX_INDEX] = True;
settings->order_support[NEG_FAST_INDEX_INDEX] = True;
settings->order_support[NEG_FAST_GLYPH_INDEX] = True;
settings->order_support[NEG_POLYGON_SC_INDEX] = True;
settings->order_support[NEG_POLYGON_CB_INDEX] = True;
settings->order_support[NEG_ELLIPSE_SC_INDEX] = True;
settings->order_support[NEG_ELLIPSE_CB_INDEX] = True;
gdi_init(instance, 0);
freerdp_chanman_pre_connect(GET_CHANMAN(instance), instance);
return True;
}
boolean tf_post_connect(freerdp* instance)
{
GDI* gdi;
tfInfo* tfi;
tfi = GET_TFI(instance);
SET_TFI(instance->update, tfi);
gdi_init(instance, CLRCONV_ALPHA | CLRBUF_16BPP | CLRBUF_32BPP);
gdi = GET_GDI(instance->update);
instance->update->BeginPaint = tf_begin_paint;
instance->update->EndPaint = tf_end_paint;
freerdp_chanman_post_connect(GET_CHANMAN(instance), instance);
return True;
}
int tfreerdp_run(freerdp* instance)
{
int i;
int fds;
int max_fds;
int rcount;
int wcount;
void* rfds[32];
void* wfds[32];
fd_set rfds_set;
fd_set wfds_set;
rdpChanMan* chanman;
memset(rfds, 0, sizeof(rfds));
memset(wfds, 0, sizeof(wfds));
chanman = GET_CHANMAN(instance);
instance->Connect(instance);
while (1)
{
rcount = 0;
wcount = 0;
if (instance->GetFileDescriptor(instance, rfds, &rcount, wfds, &wcount) != True)
{
printf("Failed to get FreeRDP file descriptor\n");
break;
}
if (freerdp_chanman_get_fds(chanman, instance, rfds, &rcount, wfds, &wcount) != True)
{
printf("Failed to get channel manager file descriptor\n");
break;
}
max_fds = 0;
FD_ZERO(&rfds_set);
for (i = 0; i < rcount; i++)
{
fds = (int)(long)(rfds[i]);
if (fds > max_fds)
max_fds = fds;
FD_SET(fds, &rfds_set);
}
if (max_fds == 0)
break;
if (select(max_fds + 1, &rfds_set, &wfds_set, NULL, NULL) == -1)
{
/* these are not really errors */
if (!((errno == EAGAIN) ||
(errno == EWOULDBLOCK) ||
(errno == EINPROGRESS) ||
(errno == EINTR))) /* signal occurred */
{
printf("tfreerdp_run: select failed\n");
break;
}
}
if (instance->CheckFileDescriptor(instance) != True)
{
printf("Failed to check FreeRDP file descriptor\n");
break;
}
if (freerdp_chanman_check_fds(chanman, instance) != True)
{
printf("Failed to check channel manager file descriptor\n");
break;
}
tf_process_channel_event(chanman, instance);
}
freerdp_chanman_close(chanman, instance);
freerdp_chanman_free(chanman);
freerdp_free(instance);
return 0;
}
void* thread_func(void* param)
{
struct thread_data* data;
data = (struct thread_data*) param;
tfreerdp_run(data->instance);
xfree(data);
pthread_detach(pthread_self());
g_thread_count--;
if (g_thread_count < 1)
freerdp_sem_signal(&g_sem);
return NULL;
}
int main(int argc, char* argv[])
{
pthread_t thread;
freerdp* instance;
struct thread_data* data;
rdpChanMan* chanman;
freerdp_chanman_global_init();
g_sem = freerdp_sem_new(1);
instance = freerdp_new();
instance->PreConnect = tf_pre_connect;
instance->PostConnect = tf_post_connect;
instance->ReceiveChannelData = tf_receive_channel_data;
chanman = freerdp_chanman_new();
SET_CHANMAN(instance, chanman);
freerdp_parse_args(instance->settings, argc, argv, tf_process_plugin_args, chanman, NULL, NULL);
data = (struct thread_data*) xzalloc(sizeof(struct thread_data));
data->instance = instance;
g_thread_count++;
pthread_create(&thread, 0, thread_func, data);
while (g_thread_count > 0)
{
freerdp_sem_wait(g_sem);
}
freerdp_chanman_global_uninit();
return 0;
}

View File

@ -133,6 +133,20 @@ struct rdp_ext_set
void * data; /* plugin data */
};
struct _BITMAP_CACHE_CELL_INFO
{
uint16 numEntries;
uint16 maxSize;
};
typedef struct _BITMAP_CACHE_CELL_INFO BITMAP_CACHE_CELL_INFO;
struct _BITMAP_CACHE_V2_CELL_INFO
{
uint32 numEntries;
boolean persistent;
};
typedef struct _BITMAP_CACHE_V2_CELL_INFO BITMAP_CACHE_V2_CELL_INFO;
struct rdp_monitor
{
int x;
@ -227,6 +241,9 @@ struct rdp_settings
boolean bitmap_cache;
boolean persistent_bitmap_cache;
uint8 bitmapCacheV2NumCells;
BITMAP_CACHE_V2_CELL_INFO bitmapCacheV2CellInfo[6];
uint32 vc_chunk_size;
boolean draw_nine_grid;

View File

@ -20,6 +20,8 @@
set(FREERDP_CACHE_SRCS
brush.c
brush.h
bitmap_v2.c
bitmap_v2.h
offscreen.c
offscreen.h
color_table.c

View File

@ -0,0 +1,127 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Bitmap Cache V2
*
* 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 "bitmap_v2.h"
void* bitmap_v2_get(rdpBitmapV2* bitmap_v2, uint8 id, uint16 index)
{
void* entry;
if (index > bitmap_v2->maxCells)
{
printf("invalid bitmap_v2 cell id: %d\n", id);
return NULL;
}
if (index > bitmap_v2->cells[id].number)
{
printf("invalid bitmap_v2 index %d in cell id: %d\n", index, id);
return NULL;
}
entry = bitmap_v2->cells[id].entries[index].entry;
if (entry == NULL)
{
printf("invalid bitmap_v2 at index %d in cell id: %d\n", index, id);
return NULL;
}
return entry;
}
void bitmap_v2_put(rdpBitmapV2* bitmap_v2, uint8 id, uint16 index, void* entry)
{
if (id > bitmap_v2->maxCells)
{
printf("invalid bitmap_v2 cell id: %d\n", id);
return;
}
if (index > bitmap_v2->cells[id].number)
{
printf("invalid bitmap_v2 index %d in cell id: %d\n", index, id);
return;
}
bitmap_v2->cells[id].entries[index].entry = entry;
}
rdpBitmapV2* bitmap_v2_new(rdpSettings* settings)
{
int i;
rdpBitmapV2* bitmap_v2;
bitmap_v2 = (rdpBitmapV2*) xzalloc(sizeof(rdpBitmapV2));
if (bitmap_v2 != NULL)
{
bitmap_v2->settings = settings;
bitmap_v2->maxCells = 5;
settings->bitmap_cache = True;
settings->bitmapCacheV2NumCells = 5;
settings->bitmapCacheV2CellInfo[0].numEntries = 600;
settings->bitmapCacheV2CellInfo[0].persistent = False;
settings->bitmapCacheV2CellInfo[1].numEntries = 600;
settings->bitmapCacheV2CellInfo[1].persistent = False;
settings->bitmapCacheV2CellInfo[2].numEntries = 2048;
settings->bitmapCacheV2CellInfo[2].persistent = False;
settings->bitmapCacheV2CellInfo[3].numEntries = 4096;
settings->bitmapCacheV2CellInfo[3].persistent = False;
settings->bitmapCacheV2CellInfo[4].numEntries = 2048;
settings->bitmapCacheV2CellInfo[4].persistent = False;
bitmap_v2->cells = (BITMAP_V2_CELL*) xzalloc(sizeof(BITMAP_V2_CELL) * bitmap_v2->maxCells);
for (i = 0; i < bitmap_v2->maxCells; i++)
{
bitmap_v2->cells[i].number = settings->bitmapCacheV2CellInfo[i].numEntries;
bitmap_v2->cells[i].entries = (BITMAP_V2_ENTRY*) xzalloc(sizeof(BITMAP_V2_ENTRY) * bitmap_v2->cells[i].number);
}
}
return bitmap_v2;
}
void bitmap_v2_free(rdpBitmapV2* bitmap_v2)
{
int i, j;
if (bitmap_v2 != NULL)
{
for (i = 0; i < bitmap_v2->maxCells; i++)
{
for (j = 0; j < bitmap_v2->cells[i].number; j++)
{
if (bitmap_v2->cells[i].entries[j].entry != NULL)
xfree(bitmap_v2->cells[i].entries[j].entry);
}
xfree(bitmap_v2->cells[i].entries);
}
xfree(bitmap_v2->cells);
xfree(bitmap_v2);
}
}

View File

@ -0,0 +1,53 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Bitmap Cache V2
*
* 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 __BITMAP_V2_CACHE_H
#define __BITMAP_V2_CACHE_H
#include <freerdp/types.h>
#include <freerdp/utils/stream.h>
struct _BITMAP_V2_ENTRY
{
void* entry;
};
typedef struct _BITMAP_V2_ENTRY BITMAP_V2_ENTRY;
struct _BITMAP_V2_CELL
{
uint32 number;
BITMAP_V2_ENTRY* entries;
};
typedef struct _BITMAP_V2_CELL BITMAP_V2_CELL;
struct rdp_bitmap_v2
{
uint8 maxCells;
rdpSettings* settings;
BITMAP_V2_CELL* cells;
};
typedef struct rdp_bitmap_v2 rdpBitmapV2;
void* bitmap_v2_get(rdpBitmapV2* bitmap_v2, uint8 id, uint16 index);
void bitmap_v2_put(rdpBitmapV2* bitmap_v2, uint8 id, uint16 index, void* entry);
rdpBitmapV2* bitmap_v2_new(rdpSettings* settings);
void bitmap_v2_free(rdpBitmapV2* bitmap_v2);
#endif /* __BITMAP_V2_CACHE_H */

View File

@ -32,6 +32,7 @@ rdpCache* cache_new(rdpSettings* settings)
{
cache->settings = settings;
cache->brush = brush_new(settings);
cache->bitmap_v2 = bitmap_v2_new(settings);
cache->offscreen = offscreen_new(settings);
cache->color_table = color_table_new(settings);
}
@ -44,6 +45,7 @@ void cache_free(rdpCache* cache)
if (cache != NULL)
{
brush_free(cache->brush);
bitmap_v2_free(cache->bitmap_v2);
offscreen_free(cache->offscreen);
color_table_free(cache->color_table);
xfree(cache);

View File

@ -21,6 +21,7 @@
#define __CACHE_H
#include "brush.h"
#include "bitmap_v2.h"
#include "offscreen.h"
#include "color_table.h"
@ -34,6 +35,7 @@ struct rdp_cache
rdpSettings* settings;
rdpBrush* brush;
rdpBitmapV2* bitmap_v2;
rdpOffscreen* offscreen;
rdpColorTable* color_table;
};

View File

@ -202,7 +202,7 @@ void rdp_write_bitmap_capability_set(STREAM* s, rdpSettings* settings)
header = rdp_capability_set_start(s);
drawingFlags = 0;
drawingFlags = 1;
if (settings->rdp_version > 5)
preferredBitsPerPixel = settings->color_depth;
@ -280,10 +280,9 @@ void rdp_write_order_capability_set(STREAM* s, rdpSettings* settings)
header = rdp_capability_set_start(s);
orderFlags = NEGOTIATE_ORDER_SUPPORT |
orderFlags = NEGOTIATE_ORDER_SUPPORT |
ZERO_BOUNDS_DELTA_SUPPORT |
COLOR_INDEX_SUPPORT |
ORDER_FLAGS_EXTRA_SUPPORT;
COLOR_INDEX_SUPPORT;
orderSupportExFlags = 0;
@ -1384,7 +1383,7 @@ void rdp_read_demand_active(STREAM* s, rdpSettings* settings)
uint16 lengthSourceDescriptor;
uint16 lengthCombinedCapabilities;
printf("Demand Active PDU\n");
//printf("Demand Active PDU\n");
stream_read_uint32(s, settings->share_id); /* shareId (4 bytes) */
stream_read_uint16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */
@ -1399,7 +1398,7 @@ void rdp_read_demand_active(STREAM* s, rdpSettings* settings)
stream_get_mark(s, bm);
rdp_read_capability_set_header(s, &length, &type);
printf("%s Capability Set (0x%02X), length:%d\n", CAPSET_TYPE_STRINGS[type], type, length);
//printf("%s Capability Set (0x%02X), length:%d\n", CAPSET_TYPE_STRINGS[type], type, length);
settings->received_caps[type] = True;
em = bm + length;
@ -1562,7 +1561,12 @@ void rdp_write_confirm_active(STREAM* s, rdpSettings* settings)
rdp_write_general_capability_set(s, settings);
rdp_write_bitmap_capability_set(s, settings);
rdp_write_order_capability_set(s, settings);
rdp_write_bitmap_cache_capability_set(s, settings);
if (settings->rdp_version >= 5)
rdp_write_bitmap_cache_v2_capability_set(s, settings);
else
rdp_write_bitmap_cache_capability_set(s, settings);
rdp_write_pointer_capability_set(s, settings);
rdp_write_input_capability_set(s, settings);
rdp_write_brush_capability_set(s, settings);

View File

@ -97,9 +97,9 @@ rdpSettings* settings_new()
settings->bitmap_cache = True;
settings->persistent_bitmap_cache = False;
settings->offscreen_bitmap_cache = False;
settings->offscreen_bitmap_cache_size = 0;
settings->offscreen_bitmap_cache_entries = 0;
settings->offscreen_bitmap_cache = True;
settings->offscreen_bitmap_cache_size = 7680;
settings->offscreen_bitmap_cache_entries = 100;
settings->draw_nine_grid_cache_size = 2560;
settings->draw_nine_grid_cache_entries = 256;

View File

@ -90,11 +90,19 @@ void update_read_bitmap_data(STREAM* s, BITMAP_DATA* bitmap_data)
}
else
{
int y;
int offset;
int scanline;
stream_get_mark(s, srcData);
dstSize = bitmap_data->length;
stream_seek(s, bitmap_data->length);
bitmap_data->data = (uint8*) xzalloc(dstSize);
memcpy(bitmap_data->data, srcData, dstSize);
scanline = bitmap_data->width * (bitmap_data->bpp / 8);
for (y = 0; y < bitmap_data->height; y++)
{
offset = (bitmap_data->height - y - 1) * scanline;
stream_read(s, &bitmap_data->data[offset], scanline);
}
}
}
@ -154,8 +162,7 @@ void update_recv(rdpUpdate* update, STREAM* s)
stream_read_uint16(s, updateType); /* updateType (2 bytes) */
if (updateType != UPDATE_TYPE_BITMAP)
printf("%s Update Data PDU\n", UPDATE_TYPE_STRINGS[updateType]);
printf("%s Update Data PDU\n", UPDATE_TYPE_STRINGS[updateType]);
IFCALL(update->BeginPaint, update);

View File

@ -454,8 +454,13 @@ void gdi_bitmap_update(rdpUpdate* update, BITMAP_UPDATE* bitmap)
for (i = 0; i < bitmap->number; i++)
{
bmp = &bitmap->bitmaps[i];
gdi_bmp = gdi_bitmap_new(gdi, bmp->width, bmp->height, gdi->dstBpp, bmp->data);
gdi_BitBlt(gdi->primary->hdc, bmp->left, bmp->top, bmp->width, bmp->height, gdi_bmp->hdc, 0, 0, GDI_SRCCOPY);
gdi_BitBlt(gdi->primary->hdc,
bmp->left, bmp->top, bmp->right - bmp->left + 1,
bmp->bottom - bmp->top + 1, gdi_bmp->hdc, 0, 0, GDI_SRCCOPY);
gdi_bitmap_free((GDI_IMAGE*) gdi_bmp);
}
}
@ -584,7 +589,7 @@ void gdi_multi_opaque_rect(rdpUpdate* update, MULTI_OPAQUE_RECT_ORDER* multi_opa
DELTA_RECT* rectangle;
GDI *gdi = GET_GDI(update);
for (i = 0; i < multi_opaque_rect->numRectangles; i++)
for (i = 1; i < multi_opaque_rect->numRectangles + 1; i++)
{
rectangle = &multi_opaque_rect->rectangles[i];
@ -649,9 +654,6 @@ void gdi_create_offscreen_bitmap(rdpUpdate* update, CREATE_OFFSCREEN_BITMAP_ORDE
GDI_IMAGE* gdi_bmp;
GDI* gdi = GET_GDI(update);
printf("create_offscreen_bitmap: id:%d cx:%d cy:%d\n",
create_offscreen_bitmap->id, create_offscreen_bitmap->cx, create_offscreen_bitmap->cy);
gdi_bmp = gdi_bitmap_new(gdi, create_offscreen_bitmap->cx, create_offscreen_bitmap->cy, gdi->dstBpp, NULL);
offscreen_put(gdi->cache->offscreen, create_offscreen_bitmap->id, (void*) gdi_bmp);
@ -662,8 +664,6 @@ void gdi_switch_surface(rdpUpdate* update, SWITCH_SURFACE_ORDER* switch_surface)
GDI_IMAGE* gdi_bmp;
GDI* gdi = GET_GDI(update);
printf("switch surface: 0x%04X\n", switch_surface->bitmapId);
if (switch_surface->bitmapId == SCREEN_BITMAP_SURFACE)
{
gdi->drawing = (GDI_IMAGE*) gdi->primary;
@ -675,6 +675,14 @@ void gdi_switch_surface(rdpUpdate* update, SWITCH_SURFACE_ORDER* switch_surface)
}
}
void gdi_cache_bitmap_v2(rdpUpdate* update, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2)
{
GDI* gdi = GET_GDI(update);
bitmap_v2_put(gdi->cache->bitmap_v2, cache_bitmap_v2->cacheId,
cache_bitmap_v2->cacheIndex, cache_bitmap_v2->bitmapDataStream);
}
void gdi_cache_color_table(rdpUpdate* update, CACHE_COLOR_TABLE_ORDER* cache_color_table)
{
GDI* gdi = GET_GDI(update);
@ -723,6 +731,7 @@ void gdi_register_update_callbacks(rdpUpdate* update)
update->CreateOffscreenBitmap = gdi_create_offscreen_bitmap;
update->SwitchSurface = gdi_switch_surface;
update->CacheBitmapV2 = gdi_cache_bitmap_v2;
update->CacheColorTable = gdi_cache_color_table;
update->CacheBrush = gdi_cache_brush;
}