Wayland: whitespace only changes

This commit is contained in:
ManoloFLTK
2023-10-05 17:00:07 +02:00
parent e8f633cf2f
commit 6571bd2f28
12 changed files with 493 additions and 275 deletions
@@ -54,7 +54,8 @@ private:
void redraw_overlay() FL_OVERRIDE;
void gl_start() FL_OVERRIDE;
void gl_visual(Fl_Gl_Choice *c) FL_OVERRIDE;
char *alpha_mask_for_string(const char *str, int n, int w, int h, Fl_Fontsize fs) FL_OVERRIDE;
char *alpha_mask_for_string(
const char *str, int n, int w, int h, Fl_Fontsize fs) FL_OVERRIDE;
void init();
public:
//virtual bool need_scissor() { return true; } // CONTROL_LEAKING_SUB_GL_WINDOWS
@@ -53,6 +53,7 @@ public:
}
};
struct gl_start_support { // to support use of gl_start / gl_finish
struct wl_surface *surface;
struct wl_subsurface *subsurface;
@@ -60,12 +61,15 @@ struct gl_start_support { // to support use of gl_start / gl_finish
EGLSurface egl_surface;
};
static EGLConfig wld_egl_conf = NULL;
EGLDisplay Fl_Wayland_Gl_Window_Driver::egl_display = EGL_NO_DISPLAY;
Fl_Wayland_Gl_Window_Driver::Fl_Wayland_Gl_Window_Driver(Fl_Gl_Window *win) : Fl_Gl_Window_Driver(win) {
Fl_Wayland_Gl_Window_Driver::Fl_Wayland_Gl_Window_Driver(Fl_Gl_Window *win) :
Fl_Gl_Window_Driver(win) {
if (egl_display == EGL_NO_DISPLAY) init();
egl_window = NULL;
egl_surface = NULL;
@@ -94,14 +98,14 @@ void Fl_Wayland_Gl_Window_Driver::init() {
Fl::fatal("Can't initialise egl display\n");
}
//printf("EGL major: %d, minor %d\n", major, minor);
//eglGetConfigs(egl_display, NULL, 0, &configs_count);
//printf("EGL has %d configs\n", configs_count);
eglBindAPI(EGL_OPENGL_API);
}
char *Fl_Wayland_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n, int w, int h, Fl_Fontsize fs)
char *Fl_Wayland_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n,
int w, int h, Fl_Fontsize fs)
{
// write str to a bitmap just big enough
Fl_Image_Surface *surf = new Fl_Image_Surface(w, h);
@@ -133,7 +137,8 @@ Fl_Gl_Choice *Fl_Wayland_Gl_Window_Driver::find(int m, const int *alistp)
{
m |= FL_DOUBLE;
//if (pWindow->parent()) m |= FL_ALPHA; // CONTROL_LEAKING_SUB_GL_WINDOWS
Fl_Wayland_Gl_Choice *g = (Fl_Wayland_Gl_Choice*)Fl_Gl_Window_Driver::find_begin(m, alistp);
Fl_Wayland_Gl_Choice *g = (Fl_Wayland_Gl_Choice*)Fl_Gl_Window_Driver::find_begin(
m, alistp);
if (g) return g;
EGLint n;
@@ -176,7 +181,10 @@ GLContext Fl_Wayland_Gl_Window_Driver::create_gl_context(Fl_Window* window,
if (context_list && nContext) shared_ctx = context_list[0];
static const EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
GLContext ctx = (GLContext)eglCreateContext(egl_display, ((Fl_Wayland_Gl_Choice*)g)->egl_conf, shared_ctx?(EGLContext)shared_ctx:EGL_NO_CONTEXT, context_attribs);
GLContext ctx = (GLContext)eglCreateContext(egl_display,
((Fl_Wayland_Gl_Choice*)g)->egl_conf,
(shared_ctx ? (EGLContext)shared_ctx : EGL_NO_CONTEXT),
context_attribs);
//fprintf(stderr, "eglCreateContext=%p shared_ctx=%p\n", ctx, shared_ctx);
if (ctx) {
add_context(ctx);
@@ -203,7 +211,8 @@ void Fl_Wayland_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context
float s = Fl::screen_scale(w->screen_num());
Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver();
// the GL scene will be a transparent subsurface above the cairo-drawn surface
dr->gl_start_support_->surface = wl_compositor_create_surface(scr_driver->wl_compositor);
dr->gl_start_support_->surface =
wl_compositor_create_surface(scr_driver->wl_compositor);
dr->gl_start_support_->subsurface = wl_subcompositor_get_subsurface(
scr_driver->wl_subcompositor, dr->gl_start_support_->surface, win->wl_surface);
wl_subsurface_set_position(dr->gl_start_support_->subsurface, w->x() * s, w->y() * s);
@@ -216,7 +225,8 @@ void Fl_Wayland_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context
if (context != cached_context || w != cached_window) {
cached_context = context;
cached_window = w;
if (eglMakeCurrent(egl_display, target_egl_surface, target_egl_surface, (EGLContext)context)) {
if (eglMakeCurrent(egl_display, target_egl_surface, target_egl_surface,
(EGLContext)context)) {
//fprintf(stderr, "EGLContext %p made current\n", context);
} else {
Fl::error("eglMakeCurrent() failed\n");
@@ -247,12 +257,8 @@ void Fl_Wayland_Gl_Window_Driver::delete_gl_context(GLContext context) {
cached_context = 0;
cached_window = 0;
}
//EGLBoolean b =
eglDestroyContext(egl_display, (EGLContext)context);
//fprintf(stderr,"EGL context %p destroyed %s\n", context, b==EGL_TRUE?"successfully":"w/ error");
//b =
eglDestroySurface(egl_display, egl_surface);
//fprintf(stderr,"EGLSurface %p destroyed %s\n", egl_surface, b==EGL_TRUE?"successfully":"w/ error");
egl_surface = NULL;
wl_egl_window_destroy(egl_window);
egl_window = NULL;
@@ -261,12 +267,11 @@ void Fl_Wayland_Gl_Window_Driver::delete_gl_context(GLContext context) {
void Fl_Wayland_Gl_Window_Driver::make_overlay_current() {
//fprintf(stderr, "make_overlay_current\n");
glDrawBuffer(GL_FRONT);
}
void Fl_Wayland_Gl_Window_Driver::redraw_overlay() {
//fprintf(stderr, "redraw_overlay\n");
pWindow->redraw();
}
@@ -281,12 +286,9 @@ void Fl_Wayland_Gl_Window_Driver::make_current_before() {
egl_window = wl_egl_window_create(surface, (W/scale)*scale, (H/scale)*scale);
if (egl_window == EGL_NO_SURFACE) {
Fl::fatal("Can't create egl window with wl_egl_window_create()\n");
} else {
//fprintf(stderr, "Created egl window=%p\n", egl_window);
}
Fl_Wayland_Gl_Choice *g = (Fl_Wayland_Gl_Choice*)this->g();
egl_surface = eglCreateWindowSurface(egl_display, g->egl_conf, egl_window, NULL);
//fprintf(stderr, "Created egl surface=%p at scale=%d\n", egl_surface, win->scale);
wl_surface_set_buffer_scale(surface, scale);
// Tested apps: shape, glpuzzle, cube, fractals, gl_overlay, fullscreen, unittests,
// OpenGL3-glut-test, OpenGL3test.
@@ -327,7 +329,7 @@ void Fl_Wayland_Gl_Window_Driver::swap_buffers() {
glPushMatrix();
glLoadIdentity();
glScalef(2.0f/wo, 2.0f/ho, 1.0f);
glTranslatef(-wo/2.0f, -ho/2.0f, 0.0f); // set transform so 0,0 is bottom/left of Gl_Window
glTranslatef(-wo/2.0f, -ho/2.0f, 0.0f); // set transform so 0,0 is bottom/left of window
glRasterPos2i(0,0); // set glRasterPos to bottom left corner
{
// Emulate overlay by doing copypixels
@@ -367,7 +369,8 @@ public:
}
}
void destroy(struct gl_start_support *gl_start_support_) FL_OVERRIDE {
eglDestroySurface(Fl_Wayland_Gl_Window_Driver::egl_display, gl_start_support_->egl_surface);
eglDestroySurface(Fl_Wayland_Gl_Window_Driver::egl_display,
gl_start_support_->egl_surface);
wl_egl_window_destroy(gl_start_support_->egl_window);
wl_subsurface_destroy(gl_start_support_->subsurface);
wl_surface_destroy(gl_start_support_->surface);
@@ -375,13 +378,16 @@ public:
}
};
static Fl_Wayland_Gl_Plugin Gl_Overlay_Plugin;
/* CONTROL_LEAKING_SUB_GL_WINDOWS
static void delayed_scissor(Fl_Wayland_Gl_Window_Driver *dr) {
dr->apply_scissor();
}*/
void Fl_Wayland_Gl_Window_Driver::resize(int is_a_resize, int W, int H) {
if (!egl_window) return;
float f = Fl::screen_scale(pWindow->screen_num());
@@ -392,8 +398,6 @@ void Fl_Wayland_Gl_Window_Driver::resize(int is_a_resize, int W, int H) {
wl_egl_window_get_attached_size(egl_window, &W2, &H2);
if (W2 != W || H2 != H) {
wl_egl_window_resize(egl_window, W, H, 0, 0);
//fprintf(stderr, "Fl_Wayland_Gl_Window_Driver::resize from %dx%d to %dx%d\n",
// W2, H2, W, H);
}
/* CONTROL_LEAKING_SUB_GL_WINDOWS
if (Fl_Wayland_Window_Driver::driver(pWindow)->subRect()) {
@@ -53,12 +53,14 @@ public:
struct wl_list buffers; // to list of fl_wld_buffer's from this pool
};
static const uint32_t wld_format;
void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen osrc, int srcx, int srcy) FL_OVERRIDE;
void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen osrc,
int srcx, int srcy) FL_OVERRIDE;
static struct wld_buffer *create_wld_buffer(int width, int height, bool with_shm = true);
static void create_shm_buffer(wld_buffer *buffer);
static void buffer_release(struct wld_window *window);
static void buffer_commit(struct wld_window *window, struct flCairoRegion *r = NULL);
static void cairo_init(struct draw_buffer *buffer, int width, int height, int stride, cairo_format_t format);
static void cairo_init(struct draw_buffer *buffer, int width, int height, int stride,
cairo_format_t format);
static struct draw_buffer *offscreen_buffer(Fl_Offscreen);
static const cairo_user_data_key_t key;
static Fl_Image_Surface *custom_offscreen(int w, int h, struct wld_buffer **buffer);
@@ -62,7 +62,8 @@ void Fl_Wayland_Graphics_Driver::create_shm_buffer(
if (pool && !wl_list_empty(&pool_data->buffers)) {
// last wld_buffer created from current pool
struct wld_buffer *record = wl_container_of(pool_data->buffers.next, record, link);
chunk_offset = ((char*)record->data - pool_data->pool_memory) + record->draw_buffer.data_size;
chunk_offset = ((char*)record->data - pool_data->pool_memory) +
record->draw_buffer.data_size;
}
if (!pool || chunk_offset + buffer->draw_buffer.data_size > pool_size) {
// if true, a new pool is needed
@@ -120,12 +121,10 @@ struct Fl_Wayland_Graphics_Driver::wld_buffer *
// used to support both normal and progressive drawing
static void surface_frame_done(void *data, struct wl_callback *cb, uint32_t time) {
struct wld_window *window = (struct wld_window *)data;
//fprintf(stderr,"surface_frame_done: draw_buffer_needs_commit=%d\n", window->buffer->draw_buffer_needs_commit);
wl_callback_destroy(cb);
if (window->buffer) { // fix for issue #712
window->buffer->cb = NULL;
if (window->buffer->draw_buffer_needs_commit) {
//fprintf(stderr,"surface_frame_done calls buffer_commit\n");
Fl_Wayland_Graphics_Driver::buffer_commit(window);
}
}
@@ -169,18 +168,18 @@ void Fl_Wayland_Graphics_Driver::buffer_commit(struct wld_window *window,
cairo_surface_flush(surf);
if (r) copy_region(window, r);
else {
memcpy(window->buffer->data, window->buffer->draw_buffer.buffer, window->buffer->draw_buffer.data_size);
memcpy(window->buffer->data, window->buffer->draw_buffer.buffer,
window->buffer->draw_buffer.data_size);
wl_surface_damage_buffer(window->wl_surface, 0, 0, 1000000, 1000000);
}
window->buffer->in_use = true;
wl_surface_attach(window->wl_surface, window->buffer->wl_buffer, 0, 0);
wl_surface_set_buffer_scale(window->wl_surface,
Fl_Wayland_Window_Driver::driver(window->fl_win)->wld_scale());
wl_surface_set_buffer_scale( window->wl_surface,
Fl_Wayland_Window_Driver::driver(window->fl_win)->wld_scale() );
window->buffer->cb = wl_surface_frame(window->wl_surface);
wl_callback_add_listener(window->buffer->cb, &surface_frame_listener, window);
wl_surface_commit(window->wl_surface);
window->buffer->draw_buffer_needs_commit = false;
//fprintf(stderr,"buffer_commit %s\n", window->fl_win->parent()?"child":"top");
}
@@ -244,12 +243,14 @@ void Fl_Wayland_Graphics_Driver::buffer_release(struct wld_window *window)
}
}
// this refers to the same memory layout for pixel data as does CAIRO_FORMAT_ARGB32
const uint32_t Fl_Wayland_Graphics_Driver::wld_format = WL_SHM_FORMAT_ARGB8888;
void Fl_Wayland_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen src, int srcx, int srcy) {
// draw portion srcx,srcy,w,h of osrc to position x,y (top-left) of the graphics driver's surface
// draw portion srcx,srcy,w,h of osrc to position x,y (top-left) of
// the graphics driver's surface
cairo_matrix_t matrix;
cairo_get_matrix(cairo_, &matrix);
double s = matrix.xx;
@@ -267,8 +268,10 @@ void Fl_Wayland_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_O
cairo_restore(cairo_);
}
const cairo_user_data_key_t Fl_Wayland_Graphics_Driver::key = {};
struct
Fl_Wayland_Graphics_Driver::draw_buffer *Fl_Wayland_Graphics_Driver::offscreen_buffer(
Fl_Offscreen offscreen) {
@@ -1,7 +1,7 @@
//
// Draw-to-image code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2021 by Bill Spitzak and others.
// Copyright 1998-2022 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -20,12 +20,15 @@
#include "Fl_Wayland_Image_Surface_Driver.H"
Fl_Wayland_Image_Surface_Driver::Fl_Wayland_Image_Surface_Driver(int w, int h, int high_res, Fl_Offscreen off) : Fl_Image_Surface_Driver(w, h, high_res, off) {
Fl_Wayland_Image_Surface_Driver::Fl_Wayland_Image_Surface_Driver(int w, int h,
int high_res, Fl_Offscreen off) : Fl_Image_Surface_Driver(w, h, high_res, off) {
float d = 1;
if (!off) {
fl_open_display();
if (Fl_Wayland_Window_Driver::wld_window) {
d = Fl_Wayland_Window_Driver::driver(Fl_Wayland_Window_Driver::wld_window->fl_win)->wld_scale();
d = Fl_Wayland_Window_Driver::driver(
Fl_Wayland_Window_Driver::wld_window->fl_win
)->wld_scale();
}
d *= fl_graphics_driver->scale();
if (d != 1 && high_res) {
@@ -56,6 +59,7 @@ Fl_Wayland_Image_Surface_Driver::~Fl_Wayland_Image_Surface_Driver() {
delete driver();
}
void Fl_Wayland_Image_Surface_Driver::set_current() {
Fl_Surface_Device::set_current();
((Fl_Wayland_Graphics_Driver*)fl_graphics_driver)->set_cairo((cairo_t*)offscreen);
@@ -64,6 +68,7 @@ void Fl_Wayland_Image_Surface_Driver::set_current() {
fl_window = 0;
}
void Fl_Wayland_Image_Surface_Driver::end_current() {
cairo_surface_t *surf = cairo_get_target((cairo_t*)offscreen);
cairo_surface_flush(surf);
@@ -72,17 +77,21 @@ void Fl_Wayland_Image_Surface_Driver::end_current() {
Fl_Surface_Device::end_current();
}
void Fl_Wayland_Image_Surface_Driver::translate(int x, int y) {
((Fl_Wayland_Graphics_Driver*)driver())->ps_translate(x, y);
}
void Fl_Wayland_Image_Surface_Driver::untranslate() {
((Fl_Wayland_Graphics_Driver*)driver())->ps_untranslate();
}
Fl_RGB_Image* Fl_Wayland_Image_Surface_Driver::image() {
// Convert depth-4 image in draw_buffer to a depth-3 image while exchanging R and B colors
struct Fl_Wayland_Graphics_Driver::draw_buffer *off_buf = Fl_Wayland_Graphics_Driver::offscreen_buffer(offscreen);
struct Fl_Wayland_Graphics_Driver::draw_buffer *off_buf =
Fl_Wayland_Graphics_Driver::offscreen_buffer(offscreen);
int height = off_buf->data_size / off_buf->stride;
uchar *rgb = new uchar[off_buf->width * height * 3];
uchar *p = rgb;
@@ -146,7 +146,8 @@ public:
int dnd(int unused) FL_OVERRIDE;
int compose(int &del) FL_OVERRIDE;
void compose_reset() FL_OVERRIDE;
Fl_RGB_Image *read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win, bool may_capture_subwins, bool *did_capture_subwins) FL_OVERRIDE;
Fl_RGB_Image *read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win,
bool may_capture_subwins, bool *did_capture_subwins) FL_OVERRIDE;
int get_mouse(int &x, int &y) FL_OVERRIDE;
void open_display_platform() FL_OVERRIDE;
void close_display() FL_OVERRIDE;
File diff suppressed because it is too large Load Diff
@@ -56,7 +56,7 @@ private:
Fl_Image* shape_; ///< shape image
cairo_pattern_t *mask_pattern_;
} *shape_data_;
cairo_rectangle_int_t *subRect_; // makes sure subwindow remains inside its parent window
cairo_rectangle_int_t *subRect_; // makes sure subwindow remains inside its parent window
static bool in_flush_; // useful for progressive window drawing
Fl_Cursor standard_cursor_; // window's standard custom kind
void delete_cursor_(struct wld_window *, bool delete_rgb = true);
@@ -88,7 +88,9 @@ public:
static struct wld_window *wld_window;
static Fl_Window *surface_to_window(struct wl_surface *);
static inline Fl_Wayland_Window_Driver* driver(const Fl_Window *w) {return (Fl_Wayland_Window_Driver*)Fl_Window_Driver::driver(w);}
static inline Fl_Wayland_Window_Driver* driver(const Fl_Window *w) {
return (Fl_Wayland_Window_Driver*)Fl_Window_Driver::driver(w);
}
static void resize_after_screen_change(void *data);
static Fl_Wayland_Plugin *gl_plugin();
@@ -122,8 +124,10 @@ public:
int set_cursor_4args(const Fl_RGB_Image*, int, int, bool);
void shape(const Fl_Image* img) FL_OVERRIDE;
void capture_titlebar_and_borders(Fl_RGB_Image*& top, Fl_RGB_Image*& left, Fl_RGB_Image*& bottom, Fl_RGB_Image*& right) FL_OVERRIDE;
int scroll(int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y, void (*draw_area)(void*, int,int,int,int), void* data) FL_OVERRIDE;
void capture_titlebar_and_borders(Fl_RGB_Image*& top, Fl_RGB_Image*& left,
Fl_RGB_Image*& bottom, Fl_RGB_Image*& right) FL_OVERRIDE;
int scroll(int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y,
void (*draw_area)(void*, int,int,int,int), void* data) FL_OVERRIDE;
void wait_for_expose() FL_OVERRIDE;
// menu-related stuff
void reposition_menu_window(int x, int y) FL_OVERRIDE;
File diff suppressed because it is too large Load Diff
@@ -74,10 +74,13 @@ void write_data_source_cb(FL_SOCKET fd, data_source_write_struct *data) {
close(fd);
}
static void data_source_handle_send(void *data, struct wl_data_source *source, const char *mime_type, int fd) {
static void data_source_handle_send(void *data, struct wl_data_source *source,
const char *mime_type, int fd) {
fl_intptr_t rank = (fl_intptr_t)data;
//fprintf(stderr, "data_source_handle_send: %s fd=%d l=%d\n", mime_type, fd, fl_selection_length[1]);
if (((!strcmp(mime_type, wld_plain_text_clipboard) || !strcmp(mime_type, "text/plain")) && fl_selection_type[rank] == Fl::clipboard_plain_text)
if (((!strcmp(mime_type, wld_plain_text_clipboard) || !strcmp(mime_type, "text/plain")) &&
fl_selection_type[rank] == Fl::clipboard_plain_text)
||
(!strcmp(mime_type, "image/bmp") && fl_selection_type[rank] == Fl::clipboard_image) ) {
data_source_write_struct *write_data = new data_source_write_struct;
@@ -90,12 +93,14 @@ static void data_source_handle_send(void *data, struct wl_data_source *source, c
}
}
static Fl_Window *fl_dnd_target_window = 0;
static wl_surface *fl_dnd_target_surface = 0;
static bool doing_dnd = false; // true when DnD is in action
static wl_surface *dnd_icon = NULL; // non null when DnD uses text as cursor
static wl_cursor* save_cursor = NULL; // non null when DnD uses "dnd-copy" cursor
static void data_source_handle_cancelled(void *data, struct wl_data_source *source) {
// An application has replaced the clipboard contents or DnD finished
//fprintf(stderr, "data_source_handle_cancelled: %p\n", source);
@@ -140,9 +145,12 @@ static void data_source_handle_target(void *data, struct wl_data_source *source,
}
}
static uint32_t last_dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
static void data_source_handle_action(void *data, struct wl_data_source *source, uint32_t dnd_action) {
static void data_source_handle_action(void *data, struct wl_data_source *source,
uint32_t dnd_action) {
last_dnd_action = dnd_action;
switch (dnd_action) {
case WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY:
@@ -154,10 +162,12 @@ static void data_source_handle_action(void *data, struct wl_data_source *source,
}
}
static void data_source_handle_dnd_drop_performed(void *data, struct wl_data_source *source) {
//printf("Drop performed\n");
}
static void data_source_handle_dnd_finished(void *data, struct wl_data_source *source) {
switch (last_dnd_action) {
case WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE:
@@ -169,6 +179,7 @@ static void data_source_handle_dnd_finished(void *data, struct wl_data_source *s
}
}
static const struct wl_data_source_listener data_source_listener = {
.target = data_source_handle_target,
.send = data_source_handle_send,
@@ -179,7 +190,8 @@ static const struct wl_data_source_listener data_source_listener = {
};
static struct Fl_Wayland_Graphics_Driver::wld_buffer *offscreen_from_text(const char *text, int scale) {
static struct Fl_Wayland_Graphics_Driver::wld_buffer *offscreen_from_text(const char *text,
int scale) {
const char *p, *q;
int width = 0, height, w2, ltext = strlen(text);
fl_font(FL_HELVETICA, 10 * scale);
@@ -248,7 +260,8 @@ int Fl_Wayland_Screen_Driver::dnd(int use_selection) {
} else dnd_icon = NULL;
doing_dnd = true;
wl_data_device_start_drag(scr_driver->seat->data_device, source,
scr_driver->seat->pointer_focus, dnd_icon, scr_driver->seat->serial);
scr_driver->seat->pointer_focus, dnd_icon,
scr_driver->seat->serial);
if (use_selection) {
wl_surface_attach(dnd_icon, off->wl_buffer, 0, 0);
wl_surface_set_buffer_scale(dnd_icon, s);
@@ -267,13 +280,15 @@ int Fl_Wayland_Screen_Driver::dnd(int use_selection) {
}
static void data_offer_handle_offer(void *data, struct wl_data_offer *offer, const char *mime_type) {
static void data_offer_handle_offer(void *data, struct wl_data_offer *offer,
const char *mime_type) {
// runs when app becomes active and lists possible clipboard types
//fprintf(stderr, "Clipboard offer=%p supports MIME type: %s\n", offer, mime_type);
if (strcmp(mime_type, "image/png") == 0) {
fl_selection_type[1] = Fl::clipboard_image;
fl_selection_offer_type = "image/png";
} else if (strcmp(mime_type, "image/bmp") == 0 && (!fl_selection_offer_type || strcmp(fl_selection_offer_type, "image/png"))) {
} else if (strcmp(mime_type, "image/bmp") == 0 && (!fl_selection_offer_type ||
strcmp(fl_selection_offer_type, "image/png"))) {
fl_selection_type[1] = Fl::clipboard_image;
fl_selection_offer_type = "image/bmp";
} else if (strcmp(mime_type, "text/uri-list") == 0 && !fl_selection_type[1]) {
@@ -286,13 +301,16 @@ static void data_offer_handle_offer(void *data, struct wl_data_offer *offer, con
}
static void data_offer_handle_source_actions(void *data, struct wl_data_offer *offer, uint32_t actions) {
static void data_offer_handle_source_actions(void *data, struct wl_data_offer *offer,
uint32_t actions) {
if (actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY) {
//printf("Drag supports the copy action\n");
}
}
static void data_offer_handle_action(void *data, struct wl_data_offer *offer, uint32_t dnd_action) {
static void data_offer_handle_action(void *data, struct wl_data_offer *offer,
uint32_t dnd_action) {
switch (dnd_action) {
case WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE:
//printf("A move action would be performed if dropped\n");
@@ -306,13 +324,16 @@ static void data_offer_handle_action(void *data, struct wl_data_offer *offer, ui
}
}
static const struct wl_data_offer_listener data_offer_listener = {
.offer = data_offer_handle_offer,
.source_actions = data_offer_handle_source_actions,
.action = data_offer_handle_action,
};
static void data_device_handle_data_offer(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer) {
static void data_device_handle_data_offer(void *data, struct wl_data_device *data_device,
struct wl_data_offer *offer) {
// An application has created a new data source
//fprintf(stderr, "data_device_handle_data_offer offer=%p\n", offer);
fl_selection_type[1] = NULL;
@@ -321,7 +342,8 @@ static void data_device_handle_data_offer(void *data, struct wl_data_device *dat
}
static void data_device_handle_selection(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer) {
static void data_device_handle_selection(void *data, struct wl_data_device *data_device,
struct wl_data_offer *offer) {
// An application has set the clipboard contents. W
//fprintf(stderr, "data_device_handle_selection\n");
if (fl_selection_offer) wl_data_offer_destroy(fl_selection_offer);
@@ -405,12 +427,15 @@ way_out:
Fl::e_clipboard_type = Fl::clipboard_plain_text;
}
static struct wl_data_offer *current_drag_offer = NULL;
static uint32_t fl_dnd_serial;
static void data_device_handle_enter(void *data, struct wl_data_device *data_device, uint32_t serial,
struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *offer) {
static void data_device_handle_enter(void *data, struct wl_data_device *data_device,
uint32_t serial, struct wl_surface *surface,
wl_fixed_t x, wl_fixed_t y,
struct wl_data_offer *offer) {
Fl_Window *win = Fl_Wayland_Window_Driver::surface_to_window(surface);
//printf("Drag entered our surface %p(win=%p) at %dx%d\n", surface, win, wl_fixed_to_int(x), wl_fixed_to_int(y));
if (win) {
@@ -435,8 +460,9 @@ static void data_device_handle_enter(void *data, struct wl_data_device *data_dev
wl_data_offer_set_actions(offer, supported_actions, preferred_action);
}
static void data_device_handle_motion(void *data, struct wl_data_device *data_device, uint32_t time,
wl_fixed_t x, wl_fixed_t y) {
static void data_device_handle_motion(void *data, struct wl_data_device *data_device,
uint32_t time, wl_fixed_t x, wl_fixed_t y) {
if (!current_drag_offer) return;
//printf("data_device_handle_motion fl_dnd_target_window=%p\n", fl_dnd_target_window);
int ret = 0;
@@ -455,16 +481,18 @@ static void data_device_handle_motion(void *data, struct wl_data_device *data_de
ret = Fl::handle(FL_DND_DRAG, fl_dnd_target_window);
if (Fl::belowmouse()) Fl::belowmouse()->take_focus();
}
uint32_t supported_actions = ret && (Fl::pushed() || !doing_dnd) ? WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY : WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
uint32_t supported_actions = ret && (Fl::pushed() || !doing_dnd) ?
WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY : WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
uint32_t preferred_action = supported_actions;
wl_data_offer_set_actions(current_drag_offer, supported_actions, preferred_action);
wl_display_roundtrip(Fl_Wayland_Screen_Driver::wl_display);
if (ret && current_drag_offer) wl_data_offer_accept(current_drag_offer, fl_dnd_serial, "text/plain");
}
static void data_device_handle_leave(void *data, struct wl_data_device *data_device) {
//printf("Drag left our surface\n");
if (current_drag_offer) Fl::handle(FL_DND_LEAVE, fl_dnd_target_window);
//printf("Drag left our surface\n");
if (current_drag_offer) Fl::handle(FL_DND_LEAVE, fl_dnd_target_window);
}
@@ -497,6 +525,7 @@ static void data_device_handle_drop(void *data, struct wl_data_device *data_devi
current_drag_offer = NULL;
}
static const struct wl_data_device_listener data_device_listener = {
.data_offer = data_device_handle_data_offer,
.enter = data_device_handle_enter,
@@ -507,7 +536,8 @@ static const struct wl_data_device_listener data_device_listener = {
};
const struct wl_data_device_listener *Fl_Wayland_Screen_Driver::p_data_device_listener = &data_device_listener;
const struct wl_data_device_listener *Fl_Wayland_Screen_Driver::p_data_device_listener =
&data_device_listener;
// Reads from the clipboard an image which can be in image/bmp or image/png MIME type.
@@ -540,7 +570,8 @@ static int get_clipboard_image() {
int ld = shared->ld() ? shared->ld() : shared->w() * shared->d();
uchar *rgb = new uchar[shared->w() * shared->h() * shared->d()];
memcpy(rgb, shared->data()[0], ld * shared->h() );
Fl_RGB_Image *image = new Fl_RGB_Image(rgb, shared->w(), shared->h(), shared->d(), shared->ld());
Fl_RGB_Image *image = new Fl_RGB_Image(rgb, shared->w(), shared->h(), shared->d(),
shared->ld());
shared->release();
image->alloc_array = 1;
Fl::e_clipboard_data = (void*)image;
@@ -553,7 +584,8 @@ static int get_clipboard_image() {
int w, h; // size of the BMP image
Fl_Unix_System_Driver::read_int(buf + 18, w);
Fl_Unix_System_Driver::read_int(buf + 22, h);
int R = ((3*w+3)/4) * 4; // the number of bytes per row of BMP image, rounded up to multiple of 4
// the number of bytes per row of BMP image, rounded up to multiple of 4
int R = ((3*w+3)/4) * 4;
bmp = new char[R * h + 54];
memcpy(bmp, buf, 54);
char *from = bmp + 54;
@@ -618,7 +650,8 @@ void Fl_Wayland_Screen_Driver::paste(Fl_Widget &receiver, int clipboard, const c
}
void Fl_Wayland_Screen_Driver::copy(const char *stuff, int len, int clipboard, const char *type) {
void Fl_Wayland_Screen_Driver::copy(const char *stuff, int len, int clipboard,
const char *type) {
if (!stuff || len < 0) return;
if (clipboard >= 2)
@@ -636,11 +669,14 @@ void Fl_Wayland_Screen_Driver::copy(const char *stuff, int len, int clipboard, c
fl_selection_type[clipboard] = Fl::clipboard_plain_text;
if (clipboard == 1) {
Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver();
scr_driver->seat->data_source = wl_data_device_manager_create_data_source(scr_driver->seat->data_device_manager);
scr_driver->seat->data_source =
wl_data_device_manager_create_data_source(scr_driver->seat->data_device_manager);
// we transmit the adequate value of index in fl_selection_buffer[index]
wl_data_source_add_listener(scr_driver->seat->data_source, &data_source_listener, (void*)1);
wl_data_source_add_listener(scr_driver->seat->data_source, &data_source_listener,
(void*)1);
wl_data_source_offer(scr_driver->seat->data_source, wld_plain_text_clipboard);
wl_data_device_set_selection(scr_driver->seat->data_device, scr_driver->seat->data_source, scr_driver->seat->keyboard_enter_serial);
wl_data_device_set_selection(scr_driver->seat->data_device, scr_driver->seat->data_source,
scr_driver->seat->keyboard_enter_serial);
//fprintf(stderr, "wl_data_device_set_selection len=%d to %d\n", len, clipboard);
}
}
@@ -650,7 +686,8 @@ void Fl_Wayland_Screen_Driver::copy(const char *stuff, int len, int clipboard, c
void Fl_Wayland_Screen_Driver::copy_image(const unsigned char *data, int W, int H){
if (!data || W <= 0 || H <= 0) return;
delete[] fl_selection_buffer[1];
fl_selection_buffer[1] = (char *)Fl_Unix_System_Driver::create_bmp(data,W,H,&fl_selection_length[1]);
fl_selection_buffer[1] =
(char *)Fl_Unix_System_Driver::create_bmp(data,W,H,&fl_selection_length[1]);
fl_selection_buffer_length[1] = fl_selection_length[1];
fl_i_own_selection[1] = 1;
fl_selection_type[1] = Fl::clipboard_image;
@@ -658,7 +695,8 @@ void Fl_Wayland_Screen_Driver::copy_image(const unsigned char *data, int W, int
// we transmit the adequate value of index in fl_selection_buffer[index]
wl_data_source_add_listener(seat->data_source, &data_source_listener, (void*)1);
wl_data_source_offer(seat->data_source, "image/bmp");
wl_data_device_set_selection(seat->data_device, seat->data_source, seat->keyboard_enter_serial);
wl_data_device_set_selection(seat->data_device, seat->data_source,
seat->keyboard_enter_serial);
//fprintf(stderr, "copy_image: len=%d\n", fl_selection_length[1]);
}
@@ -58,7 +58,7 @@ static bool attempt_wayland() {
if (backend && strcmp(backend, "wayland") == 0) {
Fl_Wayland_Screen_Driver::wl_display = wl_display_connect(NULL);
if (!Fl_Wayland_Screen_Driver::wl_display) {
fprintf(stderr, "Error: no Wayland connection available, FLTK_BACKEND = '%s'\n", backend);
fprintf(stderr, "Error: no Wayland connection available, FLTK_BACKEND='wayland'\n");
exit(1);
}
return true;