Initial commit - from Precise source
[freerdp-ubuntu-pcb-backport.git] / libfreerdp-cache / brush.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol Client
3  * Brush 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/update.h>
21 #include <freerdp/freerdp.h>
22 #include <freerdp/utils/stream.h>
23 #include <freerdp/utils/memory.h>
24
25 #include <freerdp/cache/brush.h>
26
27 void update_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
28 {
29         uint8 style;
30         rdpBrush* brush = &patblt->brush;
31         rdpCache* cache = context->cache;
32
33         style = brush->style;
34
35         if (brush->style & CACHED_BRUSH)
36         {
37                 brush->data = brush_cache_get(cache->brush, brush->index, &brush->bpp);
38                 brush->style = 0x03;
39         }
40
41         IFCALL(cache->brush->PatBlt, context, patblt);
42         brush->style = style;
43 }
44
45 void update_gdi_cache_brush(rdpContext* context, CACHE_BRUSH_ORDER* cache_brush)
46 {
47         rdpCache* cache = context->cache;
48         brush_cache_put(cache->brush, cache_brush->index, cache_brush->data, cache_brush->bpp);
49 }
50
51 void* brush_cache_get(rdpBrushCache* brush, uint32 index, uint32* bpp)
52 {
53         void* entry;
54
55         if (*bpp == 1)
56         {
57                 if (index > brush->maxMonoEntries)
58                 {
59                         printf("invalid brush (%d bpp) index: 0x%04X\n", *bpp, index);
60                         return NULL;
61                 }
62
63                 *bpp = brush->monoEntries[index].bpp;
64                 entry = brush->monoEntries[index].entry;
65         }
66         else
67         {
68                 if (index > brush->maxEntries)
69                 {
70                         printf("invalid brush (%d bpp) index: 0x%04X\n", *bpp, index);
71                         return NULL;
72                 }
73
74                 *bpp = brush->entries[index].bpp;
75                 entry = brush->entries[index].entry;
76         }
77
78         if (entry == NULL)
79         {
80                 printf("invalid brush (%d bpp) at index: 0x%04X\n", *bpp, index);
81                 return NULL;
82         }
83
84         return entry;
85 }
86
87 void brush_cache_put(rdpBrushCache* brush, uint32 index, void* entry, uint32 bpp)
88 {
89         void* prevEntry;
90
91         if (bpp == 1)
92         {
93                 if (index > brush->maxMonoEntries)
94                 {
95                         printf("invalid brush (%d bpp) index: 0x%04X\n", bpp, index);
96                         return;
97                 }
98
99                 prevEntry = brush->monoEntries[index].entry;
100
101                 if (prevEntry != NULL)
102                         xfree(prevEntry);
103
104                 brush->monoEntries[index].bpp = bpp;
105                 brush->monoEntries[index].entry = entry;
106         }
107         else
108         {
109                 if (index > brush->maxEntries)
110                 {
111                         printf("invalid brush (%d bpp) index: 0x%04X\n", bpp, index);
112                         return;
113                 }
114
115                 prevEntry = brush->entries[index].entry;
116
117                 if (prevEntry != NULL)
118                         xfree(prevEntry);
119
120                 brush->entries[index].bpp = bpp;
121                 brush->entries[index].entry = entry;
122         }
123 }
124
125 void brush_cache_register_callbacks(rdpUpdate* update)
126 {
127         rdpCache* cache = update->context->cache;
128
129         cache->brush->PatBlt = update->primary->PatBlt;
130
131         update->primary->PatBlt = update_gdi_patblt;
132         update->secondary->CacheBrush = update_gdi_cache_brush;
133 }
134
135 rdpBrushCache* brush_cache_new(rdpSettings* settings)
136 {
137         rdpBrushCache* brush;
138
139         brush = (rdpBrushCache*) xzalloc(sizeof(rdpBrushCache));
140
141         if (brush != NULL)
142         {
143                 brush->settings = settings;
144
145                 brush->maxEntries = 64;
146                 brush->maxMonoEntries = 64;
147
148                 brush->entries = (BRUSH_ENTRY*) xzalloc(sizeof(BRUSH_ENTRY) * brush->maxEntries);
149                 brush->monoEntries = (BRUSH_ENTRY*) xzalloc(sizeof(BRUSH_ENTRY) * brush->maxMonoEntries);
150         }
151
152         return brush;
153 }
154
155 void brush_cache_free(rdpBrushCache* brush)
156 {
157         int i;
158
159         if (brush != NULL)
160         {
161                 if (brush->entries != NULL)
162                 {
163                         for (i = 0; i < (int) brush->maxEntries; i++)
164                         {
165                                 if (brush->entries[i].entry != NULL)
166                                         xfree(brush->entries[i].entry);
167                         }
168
169                         xfree(brush->entries);
170                 }
171
172                 if (brush->monoEntries != NULL)
173                 {
174                         for (i = 0; i < (int) brush->maxMonoEntries; i++)
175                         {
176                                 if (brush->monoEntries[i].entry != NULL)
177                                         xfree(brush->monoEntries[i].entry);
178                         }
179
180                         xfree(brush->monoEntries);
181                 }
182
183                 xfree(brush);
184         }
185 }