Initial commit - from Precise source
[freerdp-ubuntu-pcb-backport.git] / libfreerdp-cache / offscreen.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol Client
3  * Offscreen Bitmap Cache
4  *
5  * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 #include <freerdp/utils/stream.h>
21 #include <freerdp/utils/memory.h>
22
23 #include <freerdp/cache/offscreen.h>
24
25 void update_gdi_create_offscreen_bitmap(rdpContext* context, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap)
26 {
27         int i;
28         uint16 index;
29         rdpBitmap* bitmap;
30         rdpCache* cache = context->cache;
31
32         bitmap = Bitmap_Alloc(context);
33
34         bitmap->width = create_offscreen_bitmap->cx;
35         bitmap->height = create_offscreen_bitmap->cy;
36
37         bitmap->New(context, bitmap);
38
39         offscreen_cache_delete(cache->offscreen, create_offscreen_bitmap->id);
40         offscreen_cache_put(cache->offscreen, create_offscreen_bitmap->id, bitmap);
41
42         if(cache->offscreen->currentSurface == create_offscreen_bitmap->id)
43                 Bitmap_SetSurface(context, bitmap, false);
44
45         for (i = 0; i < (int) create_offscreen_bitmap->deleteList.cIndices; i++)
46         {
47                 index = create_offscreen_bitmap->deleteList.indices[i];
48                 offscreen_cache_delete(cache->offscreen, index);
49         }
50 }
51
52 void update_gdi_switch_surface(rdpContext* context, SWITCH_SURFACE_ORDER* switch_surface)
53 {
54         rdpCache* cache = context->cache;
55
56         if (switch_surface->bitmapId == SCREEN_BITMAP_SURFACE)
57         {
58                 Bitmap_SetSurface(context, NULL, true);
59         }
60         else
61         {
62                 rdpBitmap* bitmap;
63                 bitmap = offscreen_cache_get(cache->offscreen, switch_surface->bitmapId);
64                 Bitmap_SetSurface(context, bitmap, false);
65         }
66
67         cache->offscreen->currentSurface = switch_surface->bitmapId;
68 }
69
70 rdpBitmap* offscreen_cache_get(rdpOffscreenCache* offscreen_cache, uint32 index)
71 {
72         rdpBitmap* bitmap;
73
74         if (index > offscreen_cache->maxEntries)
75         {
76                 printf("invalid offscreen bitmap index: 0x%04X\n", index);
77                 return NULL;
78         }
79
80         bitmap = offscreen_cache->entries[index];
81
82         if (bitmap == NULL)
83         {
84                 printf("invalid offscreen bitmap at index: 0x%04X\n", index);
85                 return NULL;
86         }
87
88         return bitmap;
89 }
90
91 void offscreen_cache_put(rdpOffscreenCache* offscreen, uint32 index, rdpBitmap* bitmap)
92 {
93         if (index > offscreen->maxEntries)
94         {
95                 printf("invalid offscreen bitmap index: 0x%04X\n", index);
96                 return;
97         }
98
99         offscreen_cache_delete(offscreen, index);
100         offscreen->entries[index] = bitmap;
101 }
102
103 void offscreen_cache_delete(rdpOffscreenCache* offscreen, uint32 index)
104 {
105         rdpBitmap* prevBitmap;
106
107         if (index > offscreen->maxEntries)
108         {
109                 printf("invalid offscreen bitmap index (delete): 0x%04X\n", index);
110                 return;
111         }
112
113         prevBitmap = offscreen->entries[index];
114
115         if (prevBitmap != NULL)
116                 Bitmap_Free(offscreen->update->context, prevBitmap);
117
118         offscreen->entries[index] = NULL;
119 }
120
121 void offscreen_cache_register_callbacks(rdpUpdate* update)
122 {
123         update->altsec->CreateOffscreenBitmap = update_gdi_create_offscreen_bitmap;
124         update->altsec->SwitchSurface = update_gdi_switch_surface;
125 }
126
127 rdpOffscreenCache* offscreen_cache_new(rdpSettings* settings)
128 {
129         rdpOffscreenCache* offscreen_cache;
130
131         offscreen_cache = (rdpOffscreenCache*) xzalloc(sizeof(rdpOffscreenCache));
132
133         if (offscreen_cache != NULL)
134         {
135                 offscreen_cache->settings = settings;
136                 offscreen_cache->update = ((freerdp*) settings->instance)->update;
137
138                 offscreen_cache->currentSurface = SCREEN_BITMAP_SURFACE;
139                 offscreen_cache->maxSize = 7680;
140                 offscreen_cache->maxEntries = 100;
141
142                 settings->offscreen_bitmap_cache_size = offscreen_cache->maxSize;
143                 settings->offscreen_bitmap_cache_entries = offscreen_cache->maxEntries;
144
145                 offscreen_cache->entries = (rdpBitmap**) xzalloc(sizeof(rdpBitmap*) * offscreen_cache->maxEntries);
146         }
147
148         return offscreen_cache;
149 }
150
151 void offscreen_cache_free(rdpOffscreenCache* offscreen_cache)
152 {
153         int i;
154         rdpBitmap* bitmap;
155
156         if (offscreen_cache != NULL)
157         {
158                 for (i = 0; i < (int) offscreen_cache->maxEntries; i++)
159                 {
160                         bitmap = offscreen_cache->entries[i];
161
162                         if (bitmap != NULL)
163                                 Bitmap_Free(offscreen_cache->update->context, bitmap);
164                 }
165
166                 xfree(offscreen_cache->entries);
167                 xfree(offscreen_cache);
168         }
169 }