FreeRDP
shadow_surface.c
1 
19 #include <freerdp/config.h>
20 
21 #include "shadow.h"
22 
23 #include "shadow_surface.h"
24 #define ALIGN_SCREEN_SIZE(size, align) \
25  ((((size) % (align)) != 0) ? ((size) + (align) - ((size) % (align))) : (size))
26 
27 rdpShadowSurface* shadow_surface_new(rdpShadowServer* server, UINT16 x, UINT16 y, UINT32 width,
28  UINT32 height)
29 {
30  rdpShadowSurface* surface = NULL;
31  surface = (rdpShadowSurface*)calloc(1, sizeof(rdpShadowSurface));
32 
33  if (!surface)
34  return NULL;
35 
36  surface->server = server;
37  surface->x = x;
38  surface->y = y;
39  surface->width = width;
40  surface->height = height;
41  surface->scanline = ALIGN_SCREEN_SIZE(surface->width, 32) * 4;
42  surface->format = PIXEL_FORMAT_BGRX32;
43  surface->data = (BYTE*)calloc(ALIGN_SCREEN_SIZE(surface->height, 32), surface->scanline);
44 
45  if (!surface->data)
46  {
47  free(surface);
48  return NULL;
49  }
50 
51  if (!InitializeCriticalSectionAndSpinCount(&(surface->lock), 4000))
52  {
53  free(surface->data);
54  free(surface);
55  return NULL;
56  }
57 
58  region16_init(&(surface->invalidRegion));
59  return surface;
60 }
61 
62 void shadow_surface_free(rdpShadowSurface* surface)
63 {
64  if (!surface)
65  return;
66 
67  free(surface->data);
68  DeleteCriticalSection(&(surface->lock));
69  region16_uninit(&(surface->invalidRegion));
70  free(surface);
71 }
72 
73 BOOL shadow_surface_resize(rdpShadowSurface* surface, UINT16 x, UINT16 y, UINT32 width,
74  UINT32 height)
75 {
76  BYTE* buffer = NULL;
77  UINT32 scanline = ALIGN_SCREEN_SIZE(width, 4) * 4;
78 
79  if (!surface)
80  return FALSE;
81 
82  if ((width == surface->width) && (height == surface->height))
83  {
84  /* We don't need to reset frame buffer, just update left top */
85  surface->x = x;
86  surface->y = y;
87  return TRUE;
88  }
89 
90  buffer = (BYTE*)realloc(surface->data, 1ull * scanline * ALIGN_SCREEN_SIZE(height, 4ull));
91 
92  if (buffer)
93  {
94  surface->x = x;
95  surface->y = y;
96  surface->width = width;
97  surface->height = height;
98  surface->scanline = scanline;
99  surface->data = buffer;
100  return TRUE;
101  }
102 
103  return FALSE;
104 }