demo
This commit is contained in:
35
Makefile
Normal file
35
Makefile
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# Makefile
|
||||||
|
|
||||||
|
CXX = g++
|
||||||
|
CXXFLAGS = -Wall -g -std=c++17
|
||||||
|
LIBS = $(shell pkg-config --cflags --libs wayland-client wayland-egl egl glesv2 xkbcommon)
|
||||||
|
|
||||||
|
# Wayland protocols
|
||||||
|
WAYLAND_PROTOCOLS_DIR = $(shell pkg-config --variable=pkgdatadir wayland-protocols)
|
||||||
|
WAYLAND_SCANNER = $(shell pkg-config --variable=wayland_scanner wayland-scanner)
|
||||||
|
|
||||||
|
XDG_SHELL_XML = $(WAYLAND_PROTOCOLS_DIR)/stable/xdg-shell/xdg-shell.xml
|
||||||
|
|
||||||
|
all: shader-demo
|
||||||
|
|
||||||
|
# Generate code from xml
|
||||||
|
xdg-shell-protocol.c:
|
||||||
|
$(WAYLAND_SCANNER) private-code < $(XDG_SHELL_XML) > $@
|
||||||
|
|
||||||
|
xdg-shell-client-protocol.h:
|
||||||
|
$(WAYLAND_SCANNER) client-header < $(XDG_SHELL_XML) > $@
|
||||||
|
|
||||||
|
# Compile rule
|
||||||
|
OBJS = main.o xdg-shell-protocol.o
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(CC) -c -o $@ $< $(CFLAGS)
|
||||||
|
|
||||||
|
main.o: main.cpp xdg-shell-client-protocol.h
|
||||||
|
$(CXX) -c -o $@ $< $(CXXFLAGS)
|
||||||
|
|
||||||
|
shader-demo: $(OBJS)
|
||||||
|
$(CXX) -o $@ $(OBJS) $(LIBS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f shader-demo *.o xdg-shell-protocol.c xdg-shell-client-protocol.h
|
||||||
82
font8x8.h
Normal file
82
font8x8.h
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
#ifndef FONT8X8_H
|
||||||
|
#define FONT8X8_H
|
||||||
|
|
||||||
|
// Minimal 8x8 font (A-Z only for brevity, 0 for unknown)
|
||||||
|
// Each byte is a row, top to bottom.
|
||||||
|
unsigned char font8x8_basic[128][8] = {
|
||||||
|
{0,0,0,0,0,0,0,0}, // 0-31 control chars (empty)
|
||||||
|
{0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, // ...
|
||||||
|
{0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, // End control
|
||||||
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 32 SPACE
|
||||||
|
{0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00}, // 33 !
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 34 "
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 35 #
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 36 $
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 37 %
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 38 &
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 39 '
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 40 (
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 41 )
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 42 *
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 43 +
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 44 ,
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 45 -
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 46 .
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 47 /
|
||||||
|
{0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00}, // 48 0
|
||||||
|
{0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00}, // 49 1
|
||||||
|
{0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00}, // 50 2
|
||||||
|
{0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00}, // 51 3
|
||||||
|
{0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00}, // 52 4
|
||||||
|
{0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00}, // 53 5
|
||||||
|
{0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00}, // 54 6
|
||||||
|
{0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00}, // 55 7
|
||||||
|
{0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // 56 8
|
||||||
|
{0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00}, // 57 9
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 58 :
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 59 ;
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 60 <
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 61 =
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 62 >
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 63 ?
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 64 @
|
||||||
|
{0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // 65 A
|
||||||
|
{0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // 66 B
|
||||||
|
{0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00}, // 67 C
|
||||||
|
{0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00}, // 68 D
|
||||||
|
{0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // 69 E
|
||||||
|
{0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00}, // 70 F
|
||||||
|
{0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00}, // 71 G
|
||||||
|
{0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // 72 H
|
||||||
|
{0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // 73 I
|
||||||
|
{0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00}, // 74 J
|
||||||
|
{0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // 75 K
|
||||||
|
{0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00}, // 76 L
|
||||||
|
{0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // 77 M
|
||||||
|
{0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // 78 N
|
||||||
|
{0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // 79 O
|
||||||
|
{0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // 80 P
|
||||||
|
{0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00}, // 81 Q
|
||||||
|
{0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00}, // 82 R
|
||||||
|
{0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00}, // 83 S
|
||||||
|
{0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // 84 T
|
||||||
|
{0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00}, // 85 U
|
||||||
|
{0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // 86 V
|
||||||
|
{0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // 87 W
|
||||||
|
{0x63, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x63, 0x00}, // 88 X
|
||||||
|
{0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // 89 Y
|
||||||
|
{0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // 90 Z
|
||||||
|
{0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
477
main.cpp
Normal file
477
main.cpp
Normal file
@@ -0,0 +1,477 @@
|
|||||||
|
#include <wayland-client.h>
|
||||||
|
#include <wayland-egl.h>
|
||||||
|
#include <EGL/egl.h>
|
||||||
|
#include <GLES2/gl2.h>
|
||||||
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <chrono>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#include "xdg-shell-client-protocol.h"
|
||||||
|
#include "font8x8.h"
|
||||||
|
|
||||||
|
// --- Globals & State ---
|
||||||
|
|
||||||
|
struct wl_display *display = nullptr;
|
||||||
|
struct wl_registry *registry = nullptr;
|
||||||
|
struct wl_compositor *compositor = nullptr;
|
||||||
|
struct xdg_wm_base *wm_base = nullptr;
|
||||||
|
struct wl_seat *seat = nullptr;
|
||||||
|
struct wl_pointer *pointer = nullptr;
|
||||||
|
|
||||||
|
struct wl_surface *surface = nullptr;
|
||||||
|
struct xdg_surface *xdg_surface = nullptr;
|
||||||
|
struct xdg_toplevel *xdg_toplevel = nullptr;
|
||||||
|
struct wl_egl_window *egl_window = nullptr;
|
||||||
|
|
||||||
|
EGLDisplay egl_display;
|
||||||
|
EGLContext egl_context;
|
||||||
|
EGLSurface egl_surface;
|
||||||
|
|
||||||
|
// Text State
|
||||||
|
GLuint font_texture;
|
||||||
|
GLuint text_program;
|
||||||
|
|
||||||
|
bool running = true;
|
||||||
|
int width = 800;
|
||||||
|
int height = 600;
|
||||||
|
|
||||||
|
// Input state
|
||||||
|
double cursor_x = 0;
|
||||||
|
double cursor_y = 0;
|
||||||
|
bool button_pressed = false;
|
||||||
|
|
||||||
|
// Time state
|
||||||
|
auto start_time = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
|
// Shaders
|
||||||
|
struct ShaderProgram {
|
||||||
|
GLuint program;
|
||||||
|
GLint posAttrib;
|
||||||
|
GLint timeUniform;
|
||||||
|
GLint resolutionUniform;
|
||||||
|
std::string name;
|
||||||
|
float color[3]; // For sidebar button color
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<ShaderProgram> shaders;
|
||||||
|
int current_shader_index = 0;
|
||||||
|
GLuint sidebar_program; // Simple shader for drawing UI quads
|
||||||
|
|
||||||
|
// UI Layout
|
||||||
|
const int SIDEBAR_WIDTH = 200;
|
||||||
|
const int BUTTON_HEIGHT = 60;
|
||||||
|
const int BUTTON_MARGIN = 10;
|
||||||
|
|
||||||
|
// Forward declarations
|
||||||
|
void render_frame();
|
||||||
|
GLuint load_shader_src(const char *source, GLenum type);
|
||||||
|
|
||||||
|
// --- Font & Text Utils ---
|
||||||
|
|
||||||
|
void init_font() {
|
||||||
|
int tex_w = 128; // 16 chars * 8 px
|
||||||
|
int tex_h = 64; // 8 chars * 8 px
|
||||||
|
std::vector<GLubyte> pixels(tex_w * tex_h, 0);
|
||||||
|
|
||||||
|
for (int char_idx = 0; char_idx < 128; ++char_idx) {
|
||||||
|
int grid_x = char_idx % 16;
|
||||||
|
int grid_y = char_idx / 16;
|
||||||
|
|
||||||
|
for (int row = 0; row < 8; ++row) {
|
||||||
|
unsigned char bits = font8x8_basic[char_idx][row];
|
||||||
|
for (int col = 0; col < 8; ++col) {
|
||||||
|
if ((bits >> col) & 1) {
|
||||||
|
int px = grid_x * 8 + col;
|
||||||
|
int py = grid_y * 8 + row;
|
||||||
|
pixels[py * tex_w + px] = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glGenTextures(1, &font_texture);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, font_texture);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex_w, tex_h, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data());
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_text_shader() {
|
||||||
|
const char* vs =
|
||||||
|
"#version 100\n"
|
||||||
|
"attribute vec2 position;\n"
|
||||||
|
"attribute vec2 texcoord;\n"
|
||||||
|
"varying vec2 v_tex;\n"
|
||||||
|
"uniform vec2 u_screen_size;\n"
|
||||||
|
"void main() {\n"
|
||||||
|
" vec2 ndc = (position / u_screen_size) * 2.0 - 1.0;\n"
|
||||||
|
" gl_Position = vec4(ndc.x, -ndc.y, 0.0, 1.0);\n"
|
||||||
|
" v_tex = texcoord;\n"
|
||||||
|
"}";
|
||||||
|
const char* fs =
|
||||||
|
"#version 100\n"
|
||||||
|
"precision mediump float;\n"
|
||||||
|
"varying vec2 v_tex;\n"
|
||||||
|
"uniform sampler2D u_tex;\n"
|
||||||
|
"uniform vec3 u_color;\n"
|
||||||
|
"void main() {\n"
|
||||||
|
" float alpha = texture2D(u_tex, v_tex).a;\n"
|
||||||
|
" if (alpha < 0.5) discard;\n"
|
||||||
|
" gl_FragColor = vec4(u_color, 1.0);\n"
|
||||||
|
"}";
|
||||||
|
|
||||||
|
GLuint v = load_shader_src(vs, GL_VERTEX_SHADER);
|
||||||
|
GLuint f = load_shader_src(fs, GL_FRAGMENT_SHADER);
|
||||||
|
text_program = glCreateProgram();
|
||||||
|
glAttachShader(text_program, v);
|
||||||
|
glAttachShader(text_program, f);
|
||||||
|
glLinkProgram(text_program);
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_text(const std::string& text, float x, float y, float scale, float r, float g, float b) {
|
||||||
|
glUseProgram(text_program);
|
||||||
|
GLint posLoc = glGetAttribLocation(text_program, "position");
|
||||||
|
GLint texLoc = glGetAttribLocation(text_program, "texcoord");
|
||||||
|
GLint scrLoc = glGetUniformLocation(text_program, "u_screen_size");
|
||||||
|
GLint colLoc = glGetUniformLocation(text_program, "u_color");
|
||||||
|
|
||||||
|
glUniform2f(scrLoc, (float)width, (float)height);
|
||||||
|
glUniform3f(colLoc, r, g, b);
|
||||||
|
|
||||||
|
std::vector<float> verts;
|
||||||
|
float cx = x;
|
||||||
|
float cy = y;
|
||||||
|
|
||||||
|
for (char c : text) {
|
||||||
|
if (c < 0 || c > 127) continue;
|
||||||
|
int grid_x = c % 16;
|
||||||
|
int grid_y = c / 16;
|
||||||
|
|
||||||
|
float u1 = (float)grid_x / 16.0;
|
||||||
|
float v1 = (float)grid_y / 8.0;
|
||||||
|
float u2 = u1 + 1.0/16.0;
|
||||||
|
float v2 = v1 + 1.0/8.0;
|
||||||
|
|
||||||
|
float w = 8 * scale;
|
||||||
|
float h = 8 * scale;
|
||||||
|
|
||||||
|
verts.push_back(cx); verts.push_back(cy + h); verts.push_back(u1); verts.push_back(v2);
|
||||||
|
verts.push_back(cx + w); verts.push_back(cy + h); verts.push_back(u2); verts.push_back(v2);
|
||||||
|
verts.push_back(cx + w); verts.push_back(cy); verts.push_back(u2); verts.push_back(v1);
|
||||||
|
|
||||||
|
verts.push_back(cx); verts.push_back(cy + h); verts.push_back(u1); verts.push_back(v2);
|
||||||
|
verts.push_back(cx + w); verts.push_back(cy); verts.push_back(u2); verts.push_back(v1);
|
||||||
|
verts.push_back(cx); verts.push_back(cy); verts.push_back(u1); verts.push_back(v1);
|
||||||
|
|
||||||
|
cx += w + 2.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(posLoc);
|
||||||
|
glEnableVertexAttribArray(texLoc);
|
||||||
|
glVertexAttribPointer(posLoc, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), verts.data());
|
||||||
|
glVertexAttribPointer(texLoc, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), verts.data() + 2);
|
||||||
|
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, verts.size() / 4);
|
||||||
|
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Shader Utilities ---
|
||||||
|
|
||||||
|
GLuint load_shader_src(const char *source, GLenum type) {
|
||||||
|
GLuint shader = glCreateShader(type);
|
||||||
|
glShaderSource(shader, 1, &source, nullptr);
|
||||||
|
glCompileShader(shader);
|
||||||
|
|
||||||
|
GLint compiled;
|
||||||
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
|
||||||
|
if (!compiled) {
|
||||||
|
char log[512];
|
||||||
|
glGetShaderInfoLog(shader, 512, nullptr, log);
|
||||||
|
std::cerr << "Shader compile error: " << log << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint load_shader_file(const char *path, GLenum type) {
|
||||||
|
std::ifstream file(path);
|
||||||
|
if (!file.is_open()) {
|
||||||
|
std::cerr << "Failed to open shader: " << path << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
std::stringstream buffer;
|
||||||
|
buffer << file.rdbuf();
|
||||||
|
std::string source_str = buffer.str();
|
||||||
|
return load_shader_src(source_str.c_str(), type);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint create_program(const char* vertPath, const char* fragPath) {
|
||||||
|
GLuint vert = load_shader_file(vertPath, GL_VERTEX_SHADER);
|
||||||
|
GLuint frag = load_shader_file(fragPath, GL_FRAGMENT_SHADER);
|
||||||
|
GLuint prog = glCreateProgram();
|
||||||
|
glAttachShader(prog, vert);
|
||||||
|
glAttachShader(prog, frag);
|
||||||
|
glLinkProgram(prog);
|
||||||
|
return prog;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Input Handling (Pointer) ---
|
||||||
|
|
||||||
|
static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t sx, wl_fixed_t sy) {}
|
||||||
|
static void pointer_handle_leave(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface) {}
|
||||||
|
|
||||||
|
static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time, wl_fixed_t sx, wl_fixed_t sy) {
|
||||||
|
cursor_x = wl_fixed_to_double(sx);
|
||||||
|
cursor_y = wl_fixed_to_double(sy);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state) {
|
||||||
|
if (state == WL_POINTER_BUTTON_STATE_PRESSED && button == 0x110) { // Left click
|
||||||
|
if (cursor_x < SIDEBAR_WIDTH) {
|
||||||
|
int clicked_index = -1;
|
||||||
|
for (size_t i = 0; i < shaders.size(); ++i) {
|
||||||
|
int y_start = BUTTON_MARGIN + i * (BUTTON_HEIGHT + BUTTON_MARGIN);
|
||||||
|
int y_end = y_start + BUTTON_HEIGHT;
|
||||||
|
if (cursor_y >= y_start && cursor_y <= y_end && cursor_x >= BUTTON_MARGIN && cursor_x <= SIDEBAR_WIDTH - BUTTON_MARGIN) {
|
||||||
|
clicked_index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (clicked_index != -1) {
|
||||||
|
current_shader_index = clicked_index;
|
||||||
|
std::cout << "Switched to shader: " << shaders[current_shader_index].name << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) {}
|
||||||
|
|
||||||
|
static const struct wl_pointer_listener pointer_listener = {
|
||||||
|
.enter = pointer_handle_enter,
|
||||||
|
.leave = pointer_handle_leave,
|
||||||
|
.motion = pointer_handle_motion,
|
||||||
|
.button = pointer_handle_button,
|
||||||
|
.axis = pointer_handle_axis,
|
||||||
|
};
|
||||||
|
|
||||||
|
// --- Seat Listener ---
|
||||||
|
|
||||||
|
static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, uint32_t capabilities) {
|
||||||
|
if (capabilities & WL_SEAT_CAPABILITY_POINTER) {
|
||||||
|
pointer = wl_seat_get_pointer(wl_seat);
|
||||||
|
wl_pointer_add_listener(pointer, &pointer_listener, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void seat_handle_name(void *data, struct wl_seat *wl_seat, const char *name) {}
|
||||||
|
|
||||||
|
static const struct wl_seat_listener seat_listener = {
|
||||||
|
.capabilities = seat_handle_capabilities,
|
||||||
|
.name = seat_handle_name,
|
||||||
|
};
|
||||||
|
|
||||||
|
// --- Wayland/XDG Code ---
|
||||||
|
|
||||||
|
static void xdg_wm_base_ping(void *data, struct xdg_wm_base *xdg_wm_base, uint32_t serial) { xdg_wm_base_pong(xdg_wm_base, serial); }
|
||||||
|
static const struct xdg_wm_base_listener xdg_wm_base_listener = { .ping = xdg_wm_base_ping };
|
||||||
|
|
||||||
|
static void xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, uint32_t serial) {
|
||||||
|
xdg_surface_ack_configure(xdg_surface, serial);
|
||||||
|
}
|
||||||
|
static const struct xdg_surface_listener xdg_surface_listener = { .configure = xdg_surface_configure };
|
||||||
|
|
||||||
|
static void xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel, int32_t w, int32_t h, struct wl_array *states) {
|
||||||
|
if (w > 0 && h > 0) {
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
|
if (egl_window) wl_egl_window_resize(egl_window, width, height, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void xdg_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel) { running = false; }
|
||||||
|
static const struct xdg_toplevel_listener xdg_toplevel_listener = { .configure = xdg_toplevel_configure, .close = xdg_toplevel_close };
|
||||||
|
|
||||||
|
static void registry_handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) {
|
||||||
|
if (strcmp(interface, wl_compositor_interface.name) == 0) {
|
||||||
|
compositor = (struct wl_compositor *)wl_registry_bind(registry, name, &wl_compositor_interface, 1);
|
||||||
|
} else if (strcmp(interface, xdg_wm_base_interface.name) == 0) {
|
||||||
|
wm_base = (struct xdg_wm_base *)wl_registry_bind(registry, name, &xdg_wm_base_interface, 1);
|
||||||
|
xdg_wm_base_add_listener(wm_base, &xdg_wm_base_listener, nullptr);
|
||||||
|
} else if (strcmp(interface, wl_seat_interface.name) == 0) {
|
||||||
|
seat = (struct wl_seat *)wl_registry_bind(registry, name, &wl_seat_interface, 1);
|
||||||
|
wl_seat_add_listener(seat, &seat_listener, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static const struct wl_registry_listener registry_listener = { .global = registry_handle_global, .global_remove = [](void*, wl_registry*, uint32_t){} };
|
||||||
|
|
||||||
|
// --- Rendering ---
|
||||||
|
|
||||||
|
static void frame_handle_done(void *data, struct wl_callback *callback, uint32_t time);
|
||||||
|
static const struct wl_callback_listener frame_listener = { .done = frame_handle_done };
|
||||||
|
|
||||||
|
static void frame_handle_done(void *data, struct wl_callback *callback, uint32_t time) {
|
||||||
|
wl_callback_destroy(callback);
|
||||||
|
render_frame();
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_quad(float x, float y, float w, float h, float screen_w, float screen_h, float r, float g, float b) {
|
||||||
|
float x1 = (x / screen_w) * 2.0f - 1.0f;
|
||||||
|
float y1 = 1.0f - (y / screen_h) * 2.0f;
|
||||||
|
float x2 = ((x + w) / screen_w) * 2.0f - 1.0f;
|
||||||
|
float y2 = 1.0f - ((y + h) / screen_h) * 2.0f;
|
||||||
|
|
||||||
|
GLfloat vertices[] = { x1, y1, x1, y2, x2, y2, x2, y2, x2, y1, x1, y1 };
|
||||||
|
|
||||||
|
GLint posLoc = glGetAttribLocation(sidebar_program, "position");
|
||||||
|
GLint colLoc = glGetUniformLocation(sidebar_program, "u_color");
|
||||||
|
|
||||||
|
glUseProgram(sidebar_program);
|
||||||
|
glUniform3f(colLoc, r, g, b);
|
||||||
|
glVertexAttribPointer(posLoc, 2, GL_FLOAT, GL_FALSE, 0, vertices);
|
||||||
|
glEnableVertexAttribArray(posLoc);
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_frame() {
|
||||||
|
if (!running) return;
|
||||||
|
|
||||||
|
// 1. Sidebar BG
|
||||||
|
glViewport(0, 0, width, height);
|
||||||
|
glUseProgram(sidebar_program);
|
||||||
|
draw_quad(0, 0, SIDEBAR_WIDTH, height, width, height, 0.2f, 0.2f, 0.2f);
|
||||||
|
|
||||||
|
// 2. Buttons
|
||||||
|
for (size_t i = 0; i < shaders.size(); ++i) {
|
||||||
|
float r = shaders[i].color[0];
|
||||||
|
float g = shaders[i].color[1];
|
||||||
|
float b = shaders[i].color[2];
|
||||||
|
|
||||||
|
if ((int)i == current_shader_index) {
|
||||||
|
r = std::min(r + 0.3f, 1.0f);
|
||||||
|
g = std::min(g + 0.3f, 1.0f);
|
||||||
|
b = std::min(b + 0.3f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
float by = BUTTON_MARGIN + i * (BUTTON_HEIGHT + BUTTON_MARGIN);
|
||||||
|
|
||||||
|
// Quad
|
||||||
|
glUseProgram(sidebar_program);
|
||||||
|
draw_quad(BUTTON_MARGIN, by, SIDEBAR_WIDTH - 2 * BUTTON_MARGIN, BUTTON_HEIGHT, width, height, r, g, b);
|
||||||
|
|
||||||
|
// Text
|
||||||
|
float text_scale = 2.0f;
|
||||||
|
float text_h = 8 * text_scale;
|
||||||
|
float text_y = by + (BUTTON_HEIGHT - text_h) / 2;
|
||||||
|
float text_x = BUTTON_MARGIN + 10;
|
||||||
|
draw_text(shaders[i].name, text_x, text_y, text_scale, 0.0f, 0.0f, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Shader
|
||||||
|
glViewport(SIDEBAR_WIDTH, 0, width - SIDEBAR_WIDTH, height);
|
||||||
|
|
||||||
|
ShaderProgram &active = shaders[current_shader_index];
|
||||||
|
glUseProgram(active.program);
|
||||||
|
|
||||||
|
auto now = std::chrono::high_resolution_clock::now();
|
||||||
|
float time = std::chrono::duration<float>(now - start_time).count();
|
||||||
|
|
||||||
|
if (active.timeUniform != -1) glUniform1f(active.timeUniform, time);
|
||||||
|
if (active.resolutionUniform != -1) glUniform2f(active.resolutionUniform, (float)(width - SIDEBAR_WIDTH), (float)height);
|
||||||
|
|
||||||
|
GLfloat vertices[] = { -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1 };
|
||||||
|
glVertexAttribPointer(active.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, vertices);
|
||||||
|
glEnableVertexAttribArray(active.posAttrib);
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||||
|
|
||||||
|
struct wl_callback *callback = wl_surface_frame(surface);
|
||||||
|
wl_callback_add_listener(callback, &frame_listener, nullptr);
|
||||||
|
|
||||||
|
eglSwapBuffers(egl_display, egl_surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Init & Main ---
|
||||||
|
|
||||||
|
void init_shaders() {
|
||||||
|
const char* sidebar_vert =
|
||||||
|
"#version 100\n"
|
||||||
|
"attribute vec2 position;\n"
|
||||||
|
"void main() { gl_Position = vec4(position, 0.0, 1.0); }";
|
||||||
|
const char* sidebar_frag =
|
||||||
|
"#version 100\n"
|
||||||
|
"precision mediump float;\n"
|
||||||
|
"uniform vec3 u_color;\n"
|
||||||
|
"void main() { gl_FragColor = vec4(u_color, 1.0); }";
|
||||||
|
|
||||||
|
GLuint sv = load_shader_src(sidebar_vert, GL_VERTEX_SHADER);
|
||||||
|
GLuint sf = load_shader_src(sidebar_frag, GL_FRAGMENT_SHADER);
|
||||||
|
sidebar_program = glCreateProgram();
|
||||||
|
glAttachShader(sidebar_program, sv);
|
||||||
|
glAttachShader(sidebar_program, sf);
|
||||||
|
glLinkProgram(sidebar_program);
|
||||||
|
|
||||||
|
auto add_shader = [&](const char* name, const char* fpath, float r, float g, float b) {
|
||||||
|
GLuint prog = create_program("shaders/vert.glsl", fpath);
|
||||||
|
if (prog) {
|
||||||
|
ShaderProgram sp;
|
||||||
|
sp.program = prog;
|
||||||
|
sp.name = name; // Now used for text!
|
||||||
|
sp.posAttrib = glGetAttribLocation(prog, "position");
|
||||||
|
sp.timeUniform = glGetUniformLocation(prog, "u_time");
|
||||||
|
sp.resolutionUniform = glGetUniformLocation(prog, "u_resolution");
|
||||||
|
sp.color[0] = r; sp.color[1] = g; sp.color[2] = b;
|
||||||
|
shaders.push_back(sp);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
add_shader("PLASMA", "shaders/plasma.frag", 0.8f, 0.2f, 0.2f);
|
||||||
|
add_shader("TUNNEL", "shaders/tunnel.frag", 0.2f, 0.8f, 0.2f);
|
||||||
|
add_shader("FRACTAL", "shaders/fractal.frag", 0.2f, 0.2f, 0.8f);
|
||||||
|
add_shader("MANDEL", "shaders/mandelbrot.frag", 0.5f, 0.0f, 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
display = wl_display_connect(nullptr);
|
||||||
|
if (!display) return 1;
|
||||||
|
registry = wl_display_get_registry(display);
|
||||||
|
wl_registry_add_listener(registry, ®istry_listener, nullptr);
|
||||||
|
wl_display_roundtrip(display);
|
||||||
|
|
||||||
|
egl_display = eglGetDisplay((EGLNativeDisplayType)display);
|
||||||
|
eglInitialize(egl_display, nullptr, nullptr);
|
||||||
|
EGLint attribs[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE };
|
||||||
|
EGLConfig config; EGLint num; eglChooseConfig(egl_display, attribs, &config, 1, &num);
|
||||||
|
EGLint ctx_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
|
||||||
|
egl_context = eglCreateContext(egl_display, config, EGL_NO_CONTEXT, ctx_attribs);
|
||||||
|
|
||||||
|
surface = wl_compositor_create_surface(compositor);
|
||||||
|
xdg_surface = xdg_wm_base_get_xdg_surface(wm_base, surface);
|
||||||
|
xdg_surface_add_listener(xdg_surface, &xdg_surface_listener, nullptr);
|
||||||
|
xdg_toplevel = xdg_surface_get_toplevel(xdg_surface);
|
||||||
|
xdg_toplevel_add_listener(xdg_toplevel, &xdg_toplevel_listener, nullptr);
|
||||||
|
xdg_toplevel_set_title(xdg_toplevel, "Shader Studio");
|
||||||
|
wl_surface_commit(surface);
|
||||||
|
wl_display_roundtrip(display);
|
||||||
|
|
||||||
|
egl_window = wl_egl_window_create(surface, width, height);
|
||||||
|
egl_surface = eglCreateWindowSurface(egl_display, config, (EGLNativeWindowType)egl_window, nullptr);
|
||||||
|
eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context);
|
||||||
|
|
||||||
|
// Initialize Shaders & Font
|
||||||
|
init_font();
|
||||||
|
init_text_shader();
|
||||||
|
init_shaders();
|
||||||
|
|
||||||
|
render_frame();
|
||||||
|
|
||||||
|
while (running && wl_display_dispatch(display) != -1) {}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
shader-demo
Executable file
BIN
shader-demo
Executable file
Binary file not shown.
22
shaders/fractal.frag
Normal file
22
shaders/fractal.frag
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#version 100
|
||||||
|
precision mediump float;
|
||||||
|
uniform float u_time;
|
||||||
|
uniform vec2 u_resolution;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 uv = (gl_FragCoord.xy * 2.0 - u_resolution.xy) / u_resolution.y;
|
||||||
|
vec2 u0 = uv;
|
||||||
|
vec3 finalColor = vec3(0.0);
|
||||||
|
|
||||||
|
for (float i = 0.0; i < 4.0; i++) {
|
||||||
|
uv = fract(uv * 1.5) - 0.5;
|
||||||
|
float d = length(uv) * exp(-length(u0));
|
||||||
|
vec3 col = vec3(0.2, 0.5, 0.82);
|
||||||
|
d = sin(d * 8.0 + u_time) / 8.0;
|
||||||
|
d = abs(d);
|
||||||
|
d = pow(0.01 / d, 1.2);
|
||||||
|
finalColor += col * d;
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_FragColor = vec4(finalColor, 1.0);
|
||||||
|
}
|
||||||
7
shaders/frag.glsl
Normal file
7
shaders/frag.glsl
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#version 100
|
||||||
|
precision mediump float;
|
||||||
|
varying vec3 v_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_FragColor = vec4(v_color, 1.0);
|
||||||
|
}
|
||||||
31
shaders/mandelbrot.frag
Normal file
31
shaders/mandelbrot.frag
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#version 100
|
||||||
|
precision mediump float;
|
||||||
|
uniform float u_time;
|
||||||
|
uniform vec2 u_resolution;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 uv = (gl_FragCoord.xy * 2.0 - u_resolution.xy) / u_resolution.y;
|
||||||
|
|
||||||
|
// Auto zoom
|
||||||
|
float zoom = 1.0 + sin(u_time * 0.1) * 0.5;
|
||||||
|
zoom = pow(zoom, 4.0);
|
||||||
|
vec2 c = uv / zoom - vec2(0.74364388703, 0.13182590421); // Zoom into a specific interesting point
|
||||||
|
|
||||||
|
vec2 z = vec2(0.0);
|
||||||
|
float iter = 0.0;
|
||||||
|
float max_iter = 100.0;
|
||||||
|
|
||||||
|
for (float i = 0.0; i < 100.0; i++) {
|
||||||
|
z = vec2(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y) + c;
|
||||||
|
if (length(z) > 4.0) break;
|
||||||
|
iter += 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float f = iter / max_iter;
|
||||||
|
vec3 col = vec3(f);
|
||||||
|
col = 0.5 + 0.5 * cos(3.0 + f * 10.0 + vec3(0.0, 0.6, 1.0));
|
||||||
|
|
||||||
|
if (iter >= 99.0) col = vec3(0.0);
|
||||||
|
|
||||||
|
gl_FragColor = vec4(col, 1.0);
|
||||||
|
}
|
||||||
18
shaders/plasma.frag
Normal file
18
shaders/plasma.frag
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#version 100
|
||||||
|
precision mediump float;
|
||||||
|
uniform float u_time;
|
||||||
|
uniform vec2 u_resolution;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 uv = gl_FragCoord.xy / u_resolution.xy;
|
||||||
|
float v = 0.0;
|
||||||
|
vec2 c = uv * 5.0 - vec2(2.5);
|
||||||
|
v += sin((c.x + u_time));
|
||||||
|
v += sin((c.y + u_time) / 2.0);
|
||||||
|
v += sin((c.x + c.y + u_time) / 2.0);
|
||||||
|
c += vec2(sin(u_time / 3.0), cos(u_time / 2.0));
|
||||||
|
v += sin(sqrt(c.x * c.x + c.y * c.y + 1.0) + u_time);
|
||||||
|
v = v / 2.0;
|
||||||
|
vec3 col = vec3(sin(v * 3.14159), sin(v * 3.14159 + 2.09439), sin(v * 3.14159 + 4.18879));
|
||||||
|
gl_FragColor = vec4(col * 0.5 + 0.5, 1.0);
|
||||||
|
}
|
||||||
23
shaders/tunnel.frag
Normal file
23
shaders/tunnel.frag
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#version 100
|
||||||
|
precision mediump float;
|
||||||
|
uniform float u_time;
|
||||||
|
uniform vec2 u_resolution;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 p = (2.0 * gl_FragCoord.xy - u_resolution.xy) / u_resolution.y;
|
||||||
|
float a = atan(p.y, p.x);
|
||||||
|
float r = length(p);
|
||||||
|
vec2 uv = vec2(0.5 / r + 0.5 * u_time, a / 3.14159);
|
||||||
|
|
||||||
|
// Simple checkerboard pattern
|
||||||
|
float f = sin(uv.x * 20.0) * sin(uv.y * 20.0);
|
||||||
|
vec3 col = vec3(f);
|
||||||
|
|
||||||
|
// Fade to black in center
|
||||||
|
col *= r;
|
||||||
|
|
||||||
|
// Add some color
|
||||||
|
col *= vec3(0.5 + 0.5 * sin(u_time), 0.5, 0.5 + 0.5 * cos(u_time));
|
||||||
|
|
||||||
|
gl_FragColor = vec4(col, 1.0);
|
||||||
|
}
|
||||||
9
shaders/vert.glsl
Normal file
9
shaders/vert.glsl
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#version 100
|
||||||
|
attribute vec2 position;
|
||||||
|
attribute vec3 color;
|
||||||
|
varying vec3 v_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = vec4(position, 0.0, 1.0);
|
||||||
|
v_color = color;
|
||||||
|
}
|
||||||
2384
xdg-shell-client-protocol.h
Normal file
2384
xdg-shell-client-protocol.h
Normal file
File diff suppressed because it is too large
Load Diff
184
xdg-shell-protocol.c
Normal file
184
xdg-shell-protocol.c
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
/* Generated by wayland-scanner 1.24.0 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright © 2008-2013 Kristian Høgsberg
|
||||||
|
* Copyright © 2013 Rafael Antognolli
|
||||||
|
* Copyright © 2013 Jasper St. Pierre
|
||||||
|
* Copyright © 2010-2013 Intel Corporation
|
||||||
|
* Copyright © 2015-2017 Samsung Electronics Co., Ltd
|
||||||
|
* Copyright © 2015-2017 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "wayland-util.h"
|
||||||
|
|
||||||
|
#ifndef __has_attribute
|
||||||
|
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||||
|
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||||
|
#else
|
||||||
|
#define WL_PRIVATE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const struct wl_interface wl_output_interface;
|
||||||
|
extern const struct wl_interface wl_seat_interface;
|
||||||
|
extern const struct wl_interface wl_surface_interface;
|
||||||
|
extern const struct wl_interface xdg_popup_interface;
|
||||||
|
extern const struct wl_interface xdg_positioner_interface;
|
||||||
|
extern const struct wl_interface xdg_surface_interface;
|
||||||
|
extern const struct wl_interface xdg_toplevel_interface;
|
||||||
|
|
||||||
|
static const struct wl_interface *xdg_shell_types[] = {
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&xdg_positioner_interface,
|
||||||
|
&xdg_surface_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
&xdg_toplevel_interface,
|
||||||
|
&xdg_popup_interface,
|
||||||
|
&xdg_surface_interface,
|
||||||
|
&xdg_positioner_interface,
|
||||||
|
&xdg_toplevel_interface,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_output_interface,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
&xdg_positioner_interface,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_wm_base_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "create_positioner", "n", xdg_shell_types + 4 },
|
||||||
|
{ "get_xdg_surface", "no", xdg_shell_types + 5 },
|
||||||
|
{ "pong", "u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_wm_base_events[] = {
|
||||||
|
{ "ping", "u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface xdg_wm_base_interface = {
|
||||||
|
"xdg_wm_base", 7,
|
||||||
|
4, xdg_wm_base_requests,
|
||||||
|
1, xdg_wm_base_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_positioner_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "set_size", "ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_anchor_rect", "iiii", xdg_shell_types + 0 },
|
||||||
|
{ "set_anchor", "u", xdg_shell_types + 0 },
|
||||||
|
{ "set_gravity", "u", xdg_shell_types + 0 },
|
||||||
|
{ "set_constraint_adjustment", "u", xdg_shell_types + 0 },
|
||||||
|
{ "set_offset", "ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_reactive", "3", xdg_shell_types + 0 },
|
||||||
|
{ "set_parent_size", "3ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_parent_configure", "3u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface xdg_positioner_interface = {
|
||||||
|
"xdg_positioner", 7,
|
||||||
|
10, xdg_positioner_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_surface_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "get_toplevel", "n", xdg_shell_types + 7 },
|
||||||
|
{ "get_popup", "n?oo", xdg_shell_types + 8 },
|
||||||
|
{ "set_window_geometry", "iiii", xdg_shell_types + 0 },
|
||||||
|
{ "ack_configure", "u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_surface_events[] = {
|
||||||
|
{ "configure", "u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface xdg_surface_interface = {
|
||||||
|
"xdg_surface", 7,
|
||||||
|
5, xdg_surface_requests,
|
||||||
|
1, xdg_surface_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_toplevel_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "set_parent", "?o", xdg_shell_types + 11 },
|
||||||
|
{ "set_title", "s", xdg_shell_types + 0 },
|
||||||
|
{ "set_app_id", "s", xdg_shell_types + 0 },
|
||||||
|
{ "show_window_menu", "ouii", xdg_shell_types + 12 },
|
||||||
|
{ "move", "ou", xdg_shell_types + 16 },
|
||||||
|
{ "resize", "ouu", xdg_shell_types + 18 },
|
||||||
|
{ "set_max_size", "ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_min_size", "ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_maximized", "", xdg_shell_types + 0 },
|
||||||
|
{ "unset_maximized", "", xdg_shell_types + 0 },
|
||||||
|
{ "set_fullscreen", "?o", xdg_shell_types + 21 },
|
||||||
|
{ "unset_fullscreen", "", xdg_shell_types + 0 },
|
||||||
|
{ "set_minimized", "", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_toplevel_events[] = {
|
||||||
|
{ "configure", "iia", xdg_shell_types + 0 },
|
||||||
|
{ "close", "", xdg_shell_types + 0 },
|
||||||
|
{ "configure_bounds", "4ii", xdg_shell_types + 0 },
|
||||||
|
{ "wm_capabilities", "5a", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface xdg_toplevel_interface = {
|
||||||
|
"xdg_toplevel", 7,
|
||||||
|
14, xdg_toplevel_requests,
|
||||||
|
4, xdg_toplevel_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_popup_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "grab", "ou", xdg_shell_types + 22 },
|
||||||
|
{ "reposition", "3ou", xdg_shell_types + 24 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_popup_events[] = {
|
||||||
|
{ "configure", "iiii", xdg_shell_types + 0 },
|
||||||
|
{ "popup_done", "", xdg_shell_types + 0 },
|
||||||
|
{ "repositioned", "3u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface xdg_popup_interface = {
|
||||||
|
"xdg_popup", 7,
|
||||||
|
3, xdg_popup_requests,
|
||||||
|
3, xdg_popup_events,
|
||||||
|
};
|
||||||
|
|
||||||
BIN
xdg-shell-protocol.o
Normal file
BIN
xdg-shell-protocol.o
Normal file
Binary file not shown.
Reference in New Issue
Block a user