FreeRDP
nine_grid.c
1 
20 #include <freerdp/config.h>
21 
22 #include <stdio.h>
23 
24 #include <winpr/crt.h>
25 
26 #include <freerdp/log.h>
27 #include <freerdp/update.h>
28 #include <freerdp/freerdp.h>
29 #include <winpr/stream.h>
30 
31 #include "nine_grid.h"
32 #include "cache.h"
33 
34 #define TAG FREERDP_TAG("cache.nine_grid")
35 
36 typedef struct
37 {
38  void* entry;
39 } NINE_GRID_ENTRY;
40 
41 struct rdp_nine_grid_cache
42 {
43  pDrawNineGrid DrawNineGrid; /* 0 */
44  pMultiDrawNineGrid MultiDrawNineGrid; /* 1 */
45  UINT32 paddingA[16 - 2]; /* 2 */
46 
47  UINT32 maxEntries; /* 16 */
48  UINT32 maxSize; /* 17 */
49  NINE_GRID_ENTRY* entries; /* 18 */
50  UINT32 paddingB[32 - 19]; /* 19 */
51 
52  rdpContext* context;
53 };
54 
55 static void* nine_grid_cache_get(rdpNineGridCache* nine_grid, UINT32 index);
56 static void nine_grid_cache_put(rdpNineGridCache* nine_grid, UINT32 index, void* entry);
57 
58 static BOOL update_gdi_draw_nine_grid(rdpContext* context,
59  const DRAW_NINE_GRID_ORDER* draw_nine_grid)
60 {
61  rdpCache* cache = context->cache;
62  return IFCALLRESULT(TRUE, cache->nine_grid->DrawNineGrid, context, draw_nine_grid);
63 }
64 
65 static BOOL update_gdi_multi_draw_nine_grid(rdpContext* context,
66  const MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid)
67 {
68  rdpCache* cache = context->cache;
69  return IFCALLRESULT(TRUE, cache->nine_grid->MultiDrawNineGrid, context, multi_draw_nine_grid);
70 }
71 
72 void nine_grid_cache_register_callbacks(rdpUpdate* update)
73 {
74  rdpCache* cache = update->context->cache;
75 
76  cache->nine_grid->DrawNineGrid = update->primary->DrawNineGrid;
77  cache->nine_grid->MultiDrawNineGrid = update->primary->MultiDrawNineGrid;
78 
79  update->primary->DrawNineGrid = update_gdi_draw_nine_grid;
80  update->primary->MultiDrawNineGrid = update_gdi_multi_draw_nine_grid;
81 }
82 
83 void* nine_grid_cache_get(rdpNineGridCache* nine_grid, UINT32 index)
84 {
85  void* entry = NULL;
86 
87  if (index >= nine_grid->maxEntries)
88  {
89  WLog_ERR(TAG, "invalid NineGrid index: 0x%08" PRIX32 "", index);
90  return NULL;
91  }
92 
93  entry = nine_grid->entries[index].entry;
94 
95  if (entry == NULL)
96  {
97  WLog_ERR(TAG, "invalid NineGrid at index: 0x%08" PRIX32 "", index);
98  return NULL;
99  }
100 
101  return entry;
102 }
103 
104 void nine_grid_cache_put(rdpNineGridCache* nine_grid, UINT32 index, void* entry)
105 {
106  if (index >= nine_grid->maxEntries)
107  {
108  WLog_ERR(TAG, "invalid NineGrid index: 0x%08" PRIX32 "", index);
109  return;
110  }
111 
112  free(nine_grid->entries[index].entry);
113  nine_grid->entries[index].entry = entry;
114 }
115 
116 rdpNineGridCache* nine_grid_cache_new(rdpContext* context)
117 {
118  rdpNineGridCache* nine_grid = NULL;
119  rdpSettings* settings = NULL;
120 
121  WINPR_ASSERT(context);
122 
123  settings = context->settings;
124  WINPR_ASSERT(settings);
125 
126  nine_grid = (rdpNineGridCache*)calloc(1, sizeof(rdpNineGridCache));
127  if (!nine_grid)
128  return NULL;
129 
130  nine_grid->context = context;
131 
132  nine_grid->maxSize = 2560;
133  nine_grid->maxEntries = 256;
134 
135  if (!freerdp_settings_set_uint32(settings, FreeRDP_DrawNineGridCacheSize, nine_grid->maxSize))
136  goto fail;
137  if (!freerdp_settings_set_uint32(settings, FreeRDP_DrawNineGridCacheEntries,
138  nine_grid->maxEntries))
139  goto fail;
140 
141  nine_grid->entries = (NINE_GRID_ENTRY*)calloc(nine_grid->maxEntries, sizeof(NINE_GRID_ENTRY));
142  if (!nine_grid->entries)
143  goto fail;
144 
145  return nine_grid;
146 
147 fail:
148  WINPR_PRAGMA_DIAG_PUSH
149  WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
150  nine_grid_cache_free(nine_grid);
151  WINPR_PRAGMA_DIAG_POP
152  return NULL;
153 }
154 
155 void nine_grid_cache_free(rdpNineGridCache* nine_grid)
156 {
157  if (nine_grid != NULL)
158  {
159  if (nine_grid->entries != NULL)
160  {
161  for (size_t i = 0; i < nine_grid->maxEntries; i++)
162  free(nine_grid->entries[i].entry);
163 
164  free(nine_grid->entries);
165  }
166 
167  free(nine_grid);
168  }
169 }
FREERDP_API BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 param)
Sets a UINT32 settings value.