add shm_buffer class
This commit is contained in:
		
							parent
							
								
									4e4b82e478
								
							
						
					
					
						commit
						d8098fccc0
					
				| @ -10,6 +10,7 @@ subdir('protocols') | ||||
| 
 | ||||
| executable('somebar', | ||||
|   'src/main.cpp', | ||||
|   'src/shm_buffer.cpp', | ||||
|   wayland_sources, | ||||
|   #moc, | ||||
|   dependencies: [qt5_dep, wayland_dep]) | ||||
|  | ||||
							
								
								
									
										16
									
								
								src/bar.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/bar.hpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | ||||
| // somebar - dwl bar
 | ||||
| // See LICENSE file for copyright and license details.
 | ||||
| 
 | ||||
| #pragma once | ||||
| #include <wayland-client.h> | ||||
| #include "wlr-layer-shell-unstable-v1-client-protocol.h" | ||||
| #include "common.hpp" | ||||
| #include "shm_buffer.hpp" | ||||
| 
 | ||||
| class Bar { | ||||
|     wl_surface *_surface {nullptr}; | ||||
|     zwlr_layer_surface_v1 *_layerSurface {nullptr}; | ||||
|     ShmBuffer _bufs; | ||||
| public: | ||||
|     explicit Bar(wl_output *output); | ||||
| }; | ||||
							
								
								
									
										13
									
								
								src/common.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/common.hpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| // somebar - dwl bar
 | ||||
| // See LICENSE file for copyright and license details.
 | ||||
| 
 | ||||
| #pragma once | ||||
| #include <wayland-client.h> | ||||
| #include "wlr-layer-shell-unstable-v1-client-protocol.h" | ||||
| 
 | ||||
| void waylandFlush(); | ||||
| 
 | ||||
| extern wl_display *display; | ||||
| extern wl_compositor *compositor; | ||||
| extern wl_shm *shm; | ||||
| extern zwlr_layer_shell_v1 *wlrLayerShell; | ||||
							
								
								
									
										37
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								src/main.cpp
									
									
									
									
									
								
							| @ -11,18 +11,18 @@ | ||||
| #include "qnamespace.h" | ||||
| #include "wlr-layer-shell-unstable-v1-client-protocol.h" | ||||
| #include "xdg-shell-client-protocol.h" | ||||
| #include "common.hpp" | ||||
| #include "shm_buffer.hpp" | ||||
| 
 | ||||
| constexpr uint32_t barSize = 20; | ||||
| 
 | ||||
| static void waylandFlush(); | ||||
| static void waylandWriteReady(); | ||||
| static void requireGlobal(const void *p, const char *name); | ||||
| 
 | ||||
| // wayland globals
 | ||||
| static wl_display *display; | ||||
| static wl_compositor *compositor; | ||||
| static wl_shm *shm; | ||||
| static zwlr_layer_shell_v1 *wlrLayerShell; | ||||
| wl_display *display; | ||||
| wl_compositor *compositor; | ||||
| wl_shm *shm; | ||||
| zwlr_layer_shell_v1 *wlrLayerShell; | ||||
| static QSocketNotifier *displayWriteNotifier; | ||||
| 
 | ||||
| static xdg_wm_base *xdgWmBase; | ||||
| @ -33,37 +33,25 @@ static const struct xdg_wm_base_listener xdgWmBaseListener = { | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| static const struct wl_buffer_listener wlBufferListener { | ||||
|     [](void*, wl_buffer *buffer) { | ||||
|         wl_buffer_destroy(buffer); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| // app globals
 | ||||
| static wl_surface *surface; | ||||
| static zwlr_layer_surface_v1 *layerSurface; | ||||
| static const struct wl_surface_listener surfaceListener = { | ||||
|     // todo
 | ||||
| }; | ||||
| static ShmBuffer *xbuf; | ||||
| static const struct zwlr_layer_surface_v1_listener layerSurfaceListener = { | ||||
|     [](void*, zwlr_layer_surface_v1 *layerSurface, uint32_t serial, uint32_t width, uint32_t height) { | ||||
|         zwlr_layer_surface_v1_ack_configure(layerSurface, serial); | ||||
|         printf("configured to %d x %d\n", width, height); | ||||
|         auto stride = width * 4; | ||||
|         auto size = stride * height; | ||||
|         auto fd = memfd_create("somebar-surface", MFD_CLOEXEC); | ||||
|         ftruncate(fd, size); | ||||
|         auto buffer = reinterpret_cast<char*>(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); | ||||
|         auto pool = wl_shm_create_pool(shm, fd, size); | ||||
|         auto wlBuffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride, WL_SHM_FORMAT_XRGB8888); | ||||
|         wl_shm_pool_destroy(pool); | ||||
|         close(fd); | ||||
|         xbuf = new ShmBuffer(width, height, WL_SHM_FORMAT_XRGB8888); | ||||
|         auto buffer = xbuf->data(); | ||||
| 
 | ||||
|         auto w = 2*M_PI/(width / 10); | ||||
|         for (auto x = 0; x < width; x++) { | ||||
|             auto val = 255*(sin(x*w)/2+0.5); | ||||
|             for (auto y = 0; y < height; y++) { | ||||
|                 auto p = &buffer[y*stride+x*4]; | ||||
|                 auto p = &buffer[y*xbuf->stride+x*4]; | ||||
|                 *p++ = 0; | ||||
|                 *p++ = 0; | ||||
|                 *p++ = val; | ||||
| @ -71,8 +59,7 @@ static const struct zwlr_layer_surface_v1_listener layerSurfaceListener = { | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         wl_buffer_add_listener(wlBuffer, &wlBufferListener, nullptr); | ||||
|         wl_surface_attach(surface, wlBuffer, 0, 0); | ||||
|         wl_surface_attach(surface, xbuf->buffer(), 0, 0); | ||||
|         wl_surface_commit(surface); | ||||
|         waylandFlush(); | ||||
|     } | ||||
| @ -156,7 +143,7 @@ int main(int argc, char **argv) | ||||
|     return app.exec(); | ||||
| } | ||||
| 
 | ||||
| static void waylandFlush() | ||||
| void waylandFlush() | ||||
| { | ||||
|     wl_display_dispatch_pending(display); | ||||
|     if (wl_display_flush(display) < 0 && errno == EAGAIN) { | ||||
|  | ||||
							
								
								
									
										42
									
								
								src/shm_buffer.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/shm_buffer.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | ||||
| // somebar - dwl bar
 | ||||
| // See LICENSE file for copyright and license details.
 | ||||
| 
 | ||||
| #include <sys/mman.h> | ||||
| #include <unistd.h> | ||||
| #include "shm_buffer.hpp" | ||||
| #include "common.hpp" | ||||
| 
 | ||||
| constexpr int n = 2; | ||||
| 
 | ||||
| ShmBuffer::ShmBuffer(int w, int h, wl_shm_format format) | ||||
|     : width(w) | ||||
|     , height(h) | ||||
|     , stride(w*4) | ||||
| { | ||||
|     auto oneSize = stride*h; | ||||
|     _totalSize = oneSize * n; | ||||
|     auto fd = memfd_create("wl_shm", MFD_CLOEXEC); | ||||
|     ftruncate(fd, _totalSize); | ||||
|     auto pool = wl_shm_create_pool(shm, fd, _totalSize); | ||||
|     auto ptr = reinterpret_cast<char*>(mmap(nullptr, _totalSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); | ||||
|     close(fd); | ||||
|     for (auto i=0; i<n; i++) { | ||||
|         auto offset = oneSize*i; | ||||
|         auto buffer = wl_shm_pool_create_buffer(pool, offset, width, height, stride, format); | ||||
|         _buffers[i] = { ptr+offset, buffer }; | ||||
|     } | ||||
|     wl_shm_pool_destroy(pool); | ||||
| } | ||||
| 
 | ||||
| ShmBuffer::~ShmBuffer() | ||||
| { | ||||
|     munmap(_buffers[0].data, _totalSize); | ||||
|     for (auto i=0; i<n; i++) { | ||||
|         wl_buffer_destroy(_buffers[i].buffer); | ||||
|     } | ||||
|     waylandFlush(); | ||||
| } | ||||
| 
 | ||||
| char* ShmBuffer::data() const { return _buffers[_current].data; } | ||||
| wl_buffer* ShmBuffer::buffer() const { return _buffers[_current].buffer; } | ||||
| void ShmBuffer::flip() { _current = 1-_current; } | ||||
							
								
								
									
										25
									
								
								src/shm_buffer.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/shm_buffer.hpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | ||||
| // somebar - dwl bar
 | ||||
| // See LICENSE file for copyright and license details.
 | ||||
| 
 | ||||
| #pragma once | ||||
| #include <array> | ||||
| #include <wayland-client.h> | ||||
| 
 | ||||
| // double buffered shm
 | ||||
| // format is must be 32-bit
 | ||||
| class ShmBuffer { | ||||
|     struct Buf { | ||||
|         char *data {nullptr}; | ||||
|         wl_buffer *buffer {nullptr}; | ||||
|     }; | ||||
|     std::array<Buf, 2> _buffers; | ||||
|     int _current {0}; | ||||
|     size_t _totalSize {0}; | ||||
| public: | ||||
|     int width, height, stride; | ||||
|     explicit ShmBuffer(int width, int height, wl_shm_format format); | ||||
|     char* data() const; | ||||
|     wl_buffer* buffer() const; | ||||
|     void flip(); | ||||
|     ~ShmBuffer(); | ||||
| }; | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user