91bbb9ae6dcb2bc8ab701002f0f55d79ef19e282
[tpg/acess2.git] / Usermode / Applications / axwin4_src / Server / CSurface.cpp
1 /*
2  * Acess2 GUI v4
3  * - By John Hodge (thePowersGang)
4  *
5  * CWindow.cpp
6  * - Window
7  */
8 #include <CSurface.hpp>
9 #include <cassert>
10 #include <stdexcept>
11 #include <cstring>
12 #include <system_error>
13 #include <cerrno>
14
15 namespace AxWin {
16
17 CSurface::CSurface(int x, int y, unsigned int w, unsigned int h):
18         m_rect(x,y, w,h),
19         m_fd(-1),
20         m_data(0)
21 {
22         if( w > 0 && h > 0 )
23         {
24                 m_data = new uint32_t[w * h];
25         }
26 }
27
28 CSurface::~CSurface()
29 {
30         if( m_fd == -1 ) {
31                 delete[] m_data;
32         }
33         else {
34                 size_t  size = m_rect.m_w*m_rect.m_h*4;
35                 _SysMUnMap(m_data, size);
36         }
37 }
38
39 uint64_t CSurface::GetSHMHandle()
40 {
41         size_t  size = m_rect.m_w*m_rect.m_h*4;
42         if( m_fd == -1 )
43         {
44                 // 2. Allocate a copy in SHM
45                 m_fd = _SysOpen("/Devices/shm/anon", OPENFLAG_WRITE|OPENFLAG_READ);
46                 if(m_fd == -1) {
47                         _SysDebug("GetSHMHandle: Unable to open anon SHM");
48                         return -1;
49                 }
50                 // 1. Free local buffer
51                 delete m_data;
52                 _SysTruncate(m_fd, size);
53         }
54         else
55         {
56                 _SysMUnMap(m_data, size);
57         }
58         // 3. mmap shm copy
59         m_data = static_cast<uint32_t*>( _SysMMap(nullptr, size, MMAP_PROT_WRITE, 0, m_fd, 0) );
60         if(!m_data)     throw ::std::system_error(errno, ::std::system_category());
61         
62         return _SysMarshalFD(m_fd);
63 }
64
65 void CSurface::Resize(unsigned int W, unsigned int H)
66 {
67         if( m_fd == -1 )
68         {
69                 // Easy realloc
70                 // TODO: Should I maintain window contents sanely? NOPE!
71                 delete m_data;
72                 m_data = new uint32_t[W * H];
73         }
74         else
75         {
76                 //_SysIOCtl(m_fd, SHM_IOCTL_SETSIZE, W*H*4);
77         }
78         m_rect.Resize(W, H);
79 }
80
81 void CSurface::DrawScanline(unsigned int row, unsigned int x_ofs, unsigned int w, const void* data)
82 {
83         if( row >= m_rect.m_h )
84                 throw ::std::out_of_range("CSurface::DrawScanline row");
85         if( x_ofs >= m_rect.m_w )
86                 throw ::std::out_of_range("CSurface::DrawScanline x_ofs");
87
88         if( w > m_rect.m_w )
89                 throw ::std::out_of_range("CSurface::DrawScanline width");
90         
91         size_t  ofs = row*m_rect.m_w + x_ofs;
92         ::memcpy( &m_data[ofs], data, w*4 );
93 }
94
95 const uint32_t* CSurface::GetScanline(unsigned int row, unsigned int x_ofs) const
96 {
97         if( row >= m_rect.m_h )
98                 throw ::std::out_of_range("CSurface::GetScanline row");
99         if( x_ofs >= m_rect.m_w )
100                 throw ::std::out_of_range("CSurface::GetScanline x_ofs");
101
102         return &m_data[row * m_rect.m_w + x_ofs];
103 }
104
105
106 };      // namespace AxWin
107
108

UCC git Repository :: git.ucc.asn.au