mirror of https://github.com/fltk/fltk
Wayland: improve layout of struct fl_wld_draw_buffer
This commit is contained in:
parent
45d119eb3c
commit
27c3d0b780
|
@ -39,7 +39,7 @@ typedef opaque fl_uintptr_t;
|
||||||
Platform-specific value representing an offscreen drawing buffer.
|
Platform-specific value representing an offscreen drawing buffer.
|
||||||
\note This value can be safely cast to these types on each platform:
|
\note This value can be safely cast to these types on each platform:
|
||||||
\li X11: Pixmap
|
\li X11: Pixmap
|
||||||
\li Wayland: struct fl_wld_buffer *
|
\li Wayland: struct fl_wld_draw_buffer *
|
||||||
\li Windows: HBITMAP
|
\li Windows: HBITMAP
|
||||||
\li macOS: CGContextRef
|
\li macOS: CGContextRef
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1133,24 +1133,32 @@ struct wld_window {
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
\anchor fl_wld_buffer
|
\anchor fl_wld_buffer
|
||||||
<h3>struct fl_wld_buffer</h3>
|
<h3>struct fl_wld_buffer and struct fl_wld_draw_buffer</h3>
|
||||||
Defined in \c Fl_Wayland_Graphics_Driver.H. One such record is created when and by:
|
Defined in \c Fl_Wayland_Graphics_Driver.H.
|
||||||
- an Fl_Window is show()'n or resized, by \c Fl_Wayland_Graphics_Driver::create_shm_buffer();
|
One <tt>struct fl_wld_buffer</tt> record is created
|
||||||
- an Fl_Image_Surface object is created, by the \c Fl_Wayland_Image_Surface_Driver c'tor;
|
by \c Fl_Wayland_Graphics_Driver::create_shm_buffer() when
|
||||||
- a custom cursor shape is created or text is dragged, by
|
an Fl_Window is show()'n or resized,
|
||||||
\c Fl_Wayland_Graphics_Driver::create_shm_buffer().
|
when a custom cursor shape is created, or when text is dragged.
|
||||||
|
|
||||||
|
A <tt>struct fl_wld_draw_buffer</tt> record is created when an Fl_Image_Surface object
|
||||||
|
is created by the \c Fl_Wayland_Image_Surface_Driver c'tor.
|
||||||
|
One such record is also embedded inside each <tt>struct fl_wld_buffer</tt> record.
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
struct fl_wld_buffer {
|
struct fl_wld_draw_buffer { // Under Wayland, Fl_Offscreen points to this structure
|
||||||
struct wl_buffer *wl_buffer; // the Wayland buffer
|
|
||||||
void *data; // address of the beginning of the Wayland buffer's byte array
|
|
||||||
size_t data_size; // of wl_buffer and draw_buffer
|
size_t data_size; // of wl_buffer and draw_buffer
|
||||||
int stride; // bytes per line
|
int stride; // bytes per line
|
||||||
int width;
|
int width;
|
||||||
unsigned char *draw_buffer; // address of the beginning of the Cairo image surface's byte array
|
unsigned char *buffer; // address of the beginning of the Cairo image surface's byte array
|
||||||
|
cairo_t *cairo_; // used when drawing to the Cairo image surface
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fl_wld_buffer {
|
||||||
|
struct fl_wld_draw_buffer draw_buffer;
|
||||||
|
struct wl_buffer *wl_buffer; // the Wayland buffer
|
||||||
|
void *data; // address of the beginning of the Wayland buffer's byte array
|
||||||
struct wl_callback *cb; // non-NULL while Wayland buffer is being committed
|
struct wl_callback *cb; // non-NULL while Wayland buffer is being committed
|
||||||
bool draw_buffer_needs_commit; // true when draw_buffer has been modified but not yet committed
|
bool draw_buffer_needs_commit; // true when draw_buffer has been modified but not yet committed
|
||||||
cairo_t *cairo_; // used when drawing to the Cairo image surface
|
|
||||||
struct wl_shm_pool *shm_pool; // pter to wl_shm_pool from which this wl_buffer comes
|
struct wl_shm_pool *shm_pool; // pter to wl_shm_pool from which this wl_buffer comes
|
||||||
struct wl_list link; // links all buffers from the same wl_shm_pool
|
struct wl_list link; // links all buffers from the same wl_shm_pool
|
||||||
};
|
};
|
||||||
|
|
|
@ -46,7 +46,7 @@ Fl_Wayland_Copy_Surface_Driver::~Fl_Wayland_Copy_Surface_Driver() {
|
||||||
|
|
||||||
void Fl_Wayland_Copy_Surface_Driver::set_current() {
|
void Fl_Wayland_Copy_Surface_Driver::set_current() {
|
||||||
Fl_Surface_Device::set_current();
|
Fl_Surface_Device::set_current();
|
||||||
((Fl_Wayland_Graphics_Driver*)driver())->set_buffer((struct fl_wld_buffer *)img_surf->offscreen());
|
((Fl_Wayland_Graphics_Driver*)driver())->set_cairo(((struct fl_wld_draw_buffer *)img_surf->offscreen())->cairo_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -114,9 +114,9 @@ char *Fl_Wayland_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n,
|
||||||
fl_draw(str, n, 0, fl_height() - fl_descent());
|
fl_draw(str, n, 0, fl_height() - fl_descent());
|
||||||
// get the R channel only of the bitmap
|
// get the R channel only of the bitmap
|
||||||
char *alpha_buf = new char[w*h], *r = alpha_buf;
|
char *alpha_buf = new char[w*h], *r = alpha_buf;
|
||||||
struct fl_wld_buffer *off = (struct fl_wld_buffer *)surf->offscreen();
|
struct fl_wld_draw_buffer *off = (struct fl_wld_draw_buffer *)surf->offscreen();
|
||||||
for (int i = 0; i < h; i++) {
|
for (int i = 0; i < h; i++) {
|
||||||
uchar *q = off->draw_buffer + i * off->stride;
|
uchar *q = off->buffer + i * off->stride;
|
||||||
for (int j = 0; j < w; j++) {
|
for (int j = 0; j < w; j++) {
|
||||||
*r++ = *q;
|
*r++ = *q;
|
||||||
q += 4;
|
q += 4;
|
||||||
|
|
|
@ -27,38 +27,39 @@
|
||||||
#include <wayland-client.h> // for wl_list
|
#include <wayland-client.h> // for wl_list
|
||||||
|
|
||||||
|
|
||||||
struct fl_wld_buffer {
|
struct fl_wld_draw_buffer { // Under Wayland, Fl_Offscreen points to this structure
|
||||||
struct wl_buffer *wl_buffer;
|
|
||||||
void *data;
|
|
||||||
size_t data_size; // of wl_buffer and draw_buffer
|
size_t data_size; // of wl_buffer and draw_buffer
|
||||||
int stride;
|
int stride;
|
||||||
int width;
|
int width;
|
||||||
unsigned char *draw_buffer;
|
unsigned char *buffer;
|
||||||
|
cairo_t *cairo_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct fl_wld_buffer {
|
||||||
|
struct fl_wld_draw_buffer draw_buffer;
|
||||||
|
struct wl_buffer *wl_buffer;
|
||||||
|
void *data;
|
||||||
struct wl_callback *cb;
|
struct wl_callback *cb;
|
||||||
bool draw_buffer_needs_commit;
|
bool draw_buffer_needs_commit;
|
||||||
cairo_t *cairo_;
|
|
||||||
struct wl_shm_pool *shm_pool;
|
struct wl_shm_pool *shm_pool;
|
||||||
struct wl_list link; // links all buffers from the same wl_shm_pool
|
struct wl_list link; // links all buffers from the same wl_shm_pool
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Fl_Wayland_Graphics_Driver : public Fl_Cairo_Graphics_Driver {
|
class Fl_Wayland_Graphics_Driver : public Fl_Cairo_Graphics_Driver {
|
||||||
private:
|
|
||||||
struct fl_wld_buffer *buffer_;
|
|
||||||
public:
|
public:
|
||||||
struct wld_shm_pool_data { // one record attached to each wl_shm_pool object
|
struct wld_shm_pool_data { // one record attached to each wl_shm_pool object
|
||||||
char *pool_memory; // start of mmap'ed memory encapsulated by the wl_shm_pool
|
char *pool_memory; // start of mmap'ed memory encapsulated by the wl_shm_pool
|
||||||
int pool_size; // size of encapsulated memory
|
int pool_size; // size of encapsulated memory
|
||||||
struct wl_list buffers; // to list of fl_wld_buffer's from this pool
|
struct wl_list buffers; // to list of fl_wld_buffer's from this pool
|
||||||
};
|
};
|
||||||
Fl_Wayland_Graphics_Driver();
|
|
||||||
static const uint32_t wld_format;
|
static const uint32_t wld_format;
|
||||||
void set_buffer(struct fl_wld_buffer *buffer, float scale = 0);
|
|
||||||
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 fl_wld_buffer *create_shm_buffer(int width, int height);
|
static struct fl_wld_buffer *create_shm_buffer(int width, int height);
|
||||||
static void buffer_release(struct wld_window *window);
|
static void buffer_release(struct wld_window *window);
|
||||||
static void buffer_commit(struct wld_window *window, struct flCairoRegion *r = NULL);
|
static void buffer_commit(struct wld_window *window, struct flCairoRegion *r = NULL);
|
||||||
static void cairo_init(struct fl_wld_buffer *buffer, int width, int height, int stride, cairo_format_t format);
|
static void cairo_init(struct fl_wld_draw_buffer *buffer, int width, int height, int stride, cairo_format_t format);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FL_WAYLAND_GRAPHICS_DRIVER_H
|
#endif // FL_WAYLAND_GRAPHICS_DRIVER_H
|
||||||
|
|
|
@ -44,7 +44,7 @@ struct fl_wld_buffer *Fl_Wayland_Graphics_Driver::create_shm_buffer(int width, i
|
||||||
if (pool) {
|
if (pool) {
|
||||||
// last fl_wld_buffer created from current pool
|
// last fl_wld_buffer created from current pool
|
||||||
struct fl_wld_buffer *record = wl_container_of(pool_data->buffers.next, record, link);
|
struct fl_wld_buffer *record = wl_container_of(pool_data->buffers.next, record, link);
|
||||||
chunk_offset = ((char*)record->data - pool_data->pool_memory) + record->data_size;
|
chunk_offset = ((char*)record->data - pool_data->pool_memory) + record->draw_buffer.data_size;
|
||||||
}
|
}
|
||||||
if (!pool || chunk_offset + size > pool_size) { // if true, a new pool is needed
|
if (!pool || chunk_offset + size > pool_size) { // if true, a new pool is needed
|
||||||
chunk_offset = 0;
|
chunk_offset = 0;
|
||||||
|
@ -70,7 +70,7 @@ struct fl_wld_buffer *Fl_Wayland_Graphics_Driver::create_shm_buffer(int width, i
|
||||||
wl_shm_pool_set_user_data(pool, pool_data);
|
wl_shm_pool_set_user_data(pool, pool_data);
|
||||||
}
|
}
|
||||||
buffer = (struct fl_wld_buffer*)calloc(1, sizeof(struct fl_wld_buffer));
|
buffer = (struct fl_wld_buffer*)calloc(1, sizeof(struct fl_wld_buffer));
|
||||||
buffer->stride = stride;
|
buffer->draw_buffer.stride = stride;
|
||||||
buffer->wl_buffer = wl_shm_pool_create_buffer(pool, chunk_offset, width, height, stride, Fl_Wayland_Graphics_Driver::wld_format);
|
buffer->wl_buffer = wl_shm_pool_create_buffer(pool, chunk_offset, width, height, stride, Fl_Wayland_Graphics_Driver::wld_format);
|
||||||
// add this buffer to head of list of current pool's buffers
|
// add this buffer to head of list of current pool's buffers
|
||||||
wl_list_insert(&pool_data->buffers, &buffer->link);
|
wl_list_insert(&pool_data->buffers, &buffer->link);
|
||||||
|
@ -79,7 +79,7 @@ struct fl_wld_buffer *Fl_Wayland_Graphics_Driver::create_shm_buffer(int width, i
|
||||||
//fprintf(stderr, "last=%p chunk_offset=%d ", pool_data->buffers.next, chunk_offset);
|
//fprintf(stderr, "last=%p chunk_offset=%d ", pool_data->buffers.next, chunk_offset);
|
||||||
buffer->draw_buffer_needs_commit = true;
|
buffer->draw_buffer_needs_commit = true;
|
||||||
//fprintf(stderr, "create_shm_buffer: %dx%d = %d\n", width, height, size);
|
//fprintf(stderr, "create_shm_buffer: %dx%d = %d\n", width, height, size);
|
||||||
cairo_init(buffer, width, height, stride, Fl_Cairo_Graphics_Driver::cairo_format);
|
cairo_init(&buffer->draw_buffer, width, height, stride, Fl_Cairo_Graphics_Driver::cairo_format);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,15 +115,15 @@ static void copy_region(struct wld_window *window, struct flCairoRegion *r) {
|
||||||
int top = r->rects[i].y * f;
|
int top = r->rects[i].y * f;
|
||||||
int width = r->rects[i].width * f;
|
int width = r->rects[i].width * f;
|
||||||
int height = r->rects[i].height * f;
|
int height = r->rects[i].height * f;
|
||||||
int offset = top * buffer->stride + 4 * left;
|
int offset = top * buffer->draw_buffer.stride + 4 * left;
|
||||||
int W4 = 4 * width;
|
int W4 = 4 * width;
|
||||||
for (int l = 0; l < height; l++) {
|
for (int l = 0; l < height; l++) {
|
||||||
if (offset + W4 >= (int)buffer->data_size) {
|
if (offset + W4 >= (int)buffer->draw_buffer.data_size) {
|
||||||
W4 = buffer->data_size - offset;
|
W4 = buffer->draw_buffer.data_size - offset;
|
||||||
if (W4 <= 0) break;
|
if (W4 <= 0) break;
|
||||||
}
|
}
|
||||||
memcpy((uchar*)buffer->data + offset, buffer->draw_buffer + offset, W4);
|
memcpy((uchar*)buffer->data + offset, buffer->draw_buffer.buffer + offset, W4);
|
||||||
offset += buffer->stride;
|
offset += buffer->draw_buffer.stride;
|
||||||
}
|
}
|
||||||
wl_surface_damage_buffer(window->wl_surface, left, top, width, height);
|
wl_surface_damage_buffer(window->wl_surface, left, top, width, height);
|
||||||
}
|
}
|
||||||
|
@ -132,11 +132,11 @@ static void copy_region(struct wld_window *window, struct flCairoRegion *r) {
|
||||||
|
|
||||||
void Fl_Wayland_Graphics_Driver::buffer_commit(struct wld_window *window,
|
void Fl_Wayland_Graphics_Driver::buffer_commit(struct wld_window *window,
|
||||||
struct flCairoRegion *r) {
|
struct flCairoRegion *r) {
|
||||||
cairo_surface_t *surf = cairo_get_target(window->buffer->cairo_);
|
cairo_surface_t *surf = cairo_get_target(window->buffer->draw_buffer.cairo_);
|
||||||
cairo_surface_flush(surf);
|
cairo_surface_flush(surf);
|
||||||
if (r) copy_region(window, r);
|
if (r) copy_region(window, r);
|
||||||
else {
|
else {
|
||||||
memcpy(window->buffer->data, window->buffer->draw_buffer, window->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);
|
wl_surface_damage_buffer(window->wl_surface, 0, 0, 1000000, 1000000);
|
||||||
}
|
}
|
||||||
wl_surface_attach(window->wl_surface, window->buffer->wl_buffer, 0, 0);
|
wl_surface_attach(window->wl_surface, window->buffer->wl_buffer, 0, 0);
|
||||||
|
@ -150,11 +150,11 @@ void Fl_Wayland_Graphics_Driver::buffer_commit(struct wld_window *window,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Fl_Wayland_Graphics_Driver::cairo_init(struct fl_wld_buffer *buffer, int width, int height, int stride, cairo_format_t format) {
|
void Fl_Wayland_Graphics_Driver::cairo_init(struct fl_wld_draw_buffer *buffer, int width, int height, int stride, cairo_format_t format) {
|
||||||
buffer->data_size = stride * height;
|
buffer->data_size = stride * height;
|
||||||
buffer->draw_buffer = new uchar[buffer->data_size];
|
buffer->buffer = new uchar[buffer->data_size];
|
||||||
buffer->width = width;
|
buffer->width = width;
|
||||||
cairo_surface_t *surf = cairo_image_surface_create_for_data(buffer->draw_buffer, format,
|
cairo_surface_t *surf = cairo_image_surface_create_for_data(buffer->buffer, format,
|
||||||
width, height, stride);
|
width, height, stride);
|
||||||
if (cairo_surface_status(surf) != CAIRO_STATUS_SUCCESS) {
|
if (cairo_surface_status(surf) != CAIRO_STATUS_SUCCESS) {
|
||||||
Fl::fatal("Can't create Cairo surface with cairo_image_surface_create_for_data()\n");
|
Fl::fatal("Can't create Cairo surface with cairo_image_surface_create_for_data()\n");
|
||||||
|
@ -167,7 +167,7 @@ void Fl_Wayland_Graphics_Driver::cairo_init(struct fl_wld_buffer *buffer, int wi
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cairo_surface_destroy(surf);
|
cairo_surface_destroy(surf);
|
||||||
memset(buffer->draw_buffer, 0, buffer->data_size); // useful for transparent windows
|
memset(buffer->buffer, 0, buffer->data_size); // useful for transparent windows
|
||||||
cairo_set_source_rgba(buffer->cairo_, .0, .0, .0, 1.0); // Black default color
|
cairo_set_source_rgba(buffer->cairo_, .0, .0, .0, 1.0); // Black default color
|
||||||
cairo_save(buffer->cairo_);
|
cairo_save(buffer->cairo_);
|
||||||
}
|
}
|
||||||
|
@ -192,9 +192,9 @@ void Fl_Wayland_Graphics_Driver::buffer_release(struct wld_window *window)
|
||||||
free(pool_data);
|
free(pool_data);
|
||||||
if (my_pool == pool) pool = NULL;
|
if (my_pool == pool) pool = NULL;
|
||||||
}
|
}
|
||||||
delete[] window->buffer->draw_buffer;
|
delete[] window->buffer->draw_buffer.buffer;
|
||||||
window->buffer->draw_buffer = NULL;
|
window->buffer->draw_buffer.buffer = NULL;
|
||||||
cairo_destroy(window->buffer->cairo_);
|
cairo_destroy(window->buffer->draw_buffer.cairo_);
|
||||||
free(window->buffer);
|
free(window->buffer);
|
||||||
window->buffer = NULL;
|
window->buffer = NULL;
|
||||||
}
|
}
|
||||||
|
@ -204,20 +204,9 @@ void Fl_Wayland_Graphics_Driver::buffer_release(struct wld_window *window)
|
||||||
const uint32_t Fl_Wayland_Graphics_Driver::wld_format = WL_SHM_FORMAT_ARGB8888;
|
const uint32_t Fl_Wayland_Graphics_Driver::wld_format = WL_SHM_FORMAT_ARGB8888;
|
||||||
|
|
||||||
|
|
||||||
Fl_Wayland_Graphics_Driver::Fl_Wayland_Graphics_Driver () : Fl_Cairo_Graphics_Driver() {
|
|
||||||
buffer_ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Fl_Wayland_Graphics_Driver::set_buffer(struct fl_wld_buffer *buffer, float scale) {
|
|
||||||
this->buffer_ = buffer;
|
|
||||||
set_cairo(buffer->cairo_, scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Fl_Wayland_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen src, int srcx, int srcy) {
|
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
|
||||||
struct fl_wld_buffer *osrc = (struct fl_wld_buffer *)src;
|
struct fl_wld_draw_buffer *osrc = (struct fl_wld_draw_buffer *)src;
|
||||||
cairo_matrix_t matrix;
|
cairo_matrix_t matrix;
|
||||||
cairo_get_matrix(cairo_, &matrix);
|
cairo_get_matrix(cairo_, &matrix);
|
||||||
double s = matrix.xx;
|
double s = matrix.xx;
|
||||||
|
|
|
@ -32,7 +32,7 @@ Fl_Wayland_Image_Surface_Driver::Fl_Wayland_Image_Surface_Driver(int w, int h, i
|
||||||
w = int(w * d);
|
w = int(w * d);
|
||||||
h = int(h * d);
|
h = int(h * d);
|
||||||
}
|
}
|
||||||
struct fl_wld_buffer *off_ = (struct fl_wld_buffer*)calloc(1, sizeof(struct fl_wld_buffer));
|
struct fl_wld_draw_buffer *off_ = (struct fl_wld_draw_buffer*)calloc(1, sizeof(struct fl_wld_draw_buffer));
|
||||||
off_->stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, w);
|
off_->stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, w);
|
||||||
offscreen = (Fl_Offscreen)off_;
|
offscreen = (Fl_Offscreen)off_;
|
||||||
Fl_Wayland_Graphics_Driver::cairo_init(off_, w, h, off_->stride, CAIRO_FORMAT_RGB24);
|
Fl_Wayland_Graphics_Driver::cairo_init(off_, w, h, off_->stride, CAIRO_FORMAT_RGB24);
|
||||||
|
@ -44,23 +44,23 @@ Fl_Wayland_Image_Surface_Driver::Fl_Wayland_Image_Surface_Driver(int w, int h, i
|
||||||
|
|
||||||
Fl_Wayland_Image_Surface_Driver::~Fl_Wayland_Image_Surface_Driver() {
|
Fl_Wayland_Image_Surface_Driver::~Fl_Wayland_Image_Surface_Driver() {
|
||||||
if (offscreen && !external_offscreen) {
|
if (offscreen && !external_offscreen) {
|
||||||
cairo_destroy(((struct fl_wld_buffer *)offscreen)->cairo_);
|
cairo_destroy(((struct fl_wld_draw_buffer *)offscreen)->cairo_);
|
||||||
delete[] ((struct fl_wld_buffer *)offscreen)->draw_buffer;
|
delete[] ((struct fl_wld_draw_buffer *)offscreen)->buffer;
|
||||||
free((struct fl_wld_buffer *)offscreen);
|
free((struct fl_wld_draw_buffer *)offscreen);
|
||||||
}
|
}
|
||||||
delete driver();
|
delete driver();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fl_Wayland_Image_Surface_Driver::set_current() {
|
void Fl_Wayland_Image_Surface_Driver::set_current() {
|
||||||
Fl_Surface_Device::set_current();
|
Fl_Surface_Device::set_current();
|
||||||
((Fl_Wayland_Graphics_Driver*)fl_graphics_driver)->set_buffer((struct fl_wld_buffer*)offscreen);
|
((Fl_Wayland_Graphics_Driver*)fl_graphics_driver)->set_cairo(((struct fl_wld_draw_buffer*)offscreen)->cairo_);
|
||||||
pre_window = Fl_Wayland_Window_Driver::wld_window;
|
pre_window = Fl_Wayland_Window_Driver::wld_window;
|
||||||
Fl_Wayland_Window_Driver::wld_window = NULL;
|
Fl_Wayland_Window_Driver::wld_window = NULL;
|
||||||
fl_window = 0;
|
fl_window = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fl_Wayland_Image_Surface_Driver::end_current() {
|
void Fl_Wayland_Image_Surface_Driver::end_current() {
|
||||||
cairo_surface_t *surf = cairo_get_target(((struct fl_wld_buffer *)offscreen)->cairo_);
|
cairo_surface_t *surf = cairo_get_target(((struct fl_wld_draw_buffer *)offscreen)->cairo_);
|
||||||
cairo_surface_flush(surf);
|
cairo_surface_flush(surf);
|
||||||
Fl_Wayland_Window_Driver::wld_window = pre_window;
|
Fl_Wayland_Window_Driver::wld_window = pre_window;
|
||||||
fl_window = (Window)pre_window;
|
fl_window = (Window)pre_window;
|
||||||
|
@ -77,20 +77,20 @@ void Fl_Wayland_Image_Surface_Driver::untranslate() {
|
||||||
|
|
||||||
Fl_RGB_Image* Fl_Wayland_Image_Surface_Driver::image() {
|
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
|
// Convert depth-4 image in draw_buffer to a depth-3 image while exchanging R and B colors
|
||||||
int height = ((struct fl_wld_buffer *)offscreen)->data_size / ((struct fl_wld_buffer *)offscreen)->stride;
|
int height = ((struct fl_wld_draw_buffer *)offscreen)->data_size / ((struct fl_wld_draw_buffer *)offscreen)->stride;
|
||||||
uchar *rgb = new uchar[((struct fl_wld_buffer *)offscreen)->width * height * 3];
|
uchar *rgb = new uchar[((struct fl_wld_draw_buffer *)offscreen)->width * height * 3];
|
||||||
uchar *p = rgb;
|
uchar *p = rgb;
|
||||||
uchar *q;
|
uchar *q;
|
||||||
for (int j = 0; j < height; j++) {
|
for (int j = 0; j < height; j++) {
|
||||||
q = ((struct fl_wld_buffer *)offscreen)->draw_buffer + j*((struct fl_wld_buffer *)offscreen)->stride;
|
q = ((struct fl_wld_draw_buffer *)offscreen)->buffer + j*((struct fl_wld_draw_buffer *)offscreen)->stride;
|
||||||
for (int i = 0; i < ((struct fl_wld_buffer *)offscreen)->width; i++) { // exchange R and B colors, transmit G
|
for (int i = 0; i < ((struct fl_wld_draw_buffer *)offscreen)->width; i++) { // exchange R and B colors, transmit G
|
||||||
*p = *(q+2);
|
*p = *(q+2);
|
||||||
*(p+1) = *(q+1);
|
*(p+1) = *(q+1);
|
||||||
*(p+2) = *q;
|
*(p+2) = *q;
|
||||||
p += 3; q += 4;
|
p += 3; q += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Fl_RGB_Image *image = new Fl_RGB_Image(rgb, ((struct fl_wld_buffer *)offscreen)->width, height, 3);
|
Fl_RGB_Image *image = new Fl_RGB_Image(rgb, ((struct fl_wld_draw_buffer *)offscreen)->width, height, 3);
|
||||||
image->alloc_array = 1;
|
image->alloc_array = 1;
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "xdg-shell-client-protocol.h"
|
#include "xdg-shell-client-protocol.h"
|
||||||
#include "../Posix/Fl_Posix_System_Driver.H"
|
#include "../Posix/Fl_Posix_System_Driver.H"
|
||||||
#include <FL/Fl.H>
|
#include <FL/Fl.H>
|
||||||
|
#include <FL/Fl_Image_Surface.H>
|
||||||
#include <FL/platform.H>
|
#include <FL/platform.H>
|
||||||
#include <FL/fl_ask.H>
|
#include <FL/fl_ask.H>
|
||||||
#include <FL/filename.H>
|
#include <FL/filename.H>
|
||||||
|
@ -1494,7 +1495,9 @@ void Fl_Wayland_Screen_Driver::get_system_colors()
|
||||||
Fl_RGB_Image *Fl_Wayland_Screen_Driver::read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win,
|
Fl_RGB_Image *Fl_Wayland_Screen_Driver::read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win,
|
||||||
bool ignore, bool *p_ignore) {
|
bool ignore, bool *p_ignore) {
|
||||||
struct wld_window* xid = win ? fl_wl_xid(win) : NULL;
|
struct wld_window* xid = win ? fl_wl_xid(win) : NULL;
|
||||||
struct fl_wld_buffer *buffer = win ? xid->buffer : (struct fl_wld_buffer *)Fl_Surface_Device::surface()->driver()->gc();
|
struct fl_wld_draw_buffer *buffer = win ? &xid->buffer->draw_buffer :
|
||||||
|
(struct fl_wld_draw_buffer *)
|
||||||
|
(((Fl_Image_Surface*)Fl_Surface_Device::surface())->offscreen());//to check
|
||||||
float s = win ?
|
float s = win ?
|
||||||
Fl_Wayland_Window_Driver::driver(win)->wld_scale() * scale(win->screen_num()) :
|
Fl_Wayland_Window_Driver::driver(win)->wld_scale() * scale(win->screen_num()) :
|
||||||
Fl_Surface_Device::surface()->driver()->scale();
|
Fl_Surface_Device::surface()->driver()->scale();
|
||||||
|
@ -1511,7 +1514,7 @@ Fl_RGB_Image *Fl_Wayland_Screen_Driver::read_win_rectangle(int X, int Y, int w,
|
||||||
uchar *data = new uchar[ws * hs * 3];
|
uchar *data = new uchar[ws * hs * 3];
|
||||||
uchar *p = data, *q;
|
uchar *p = data, *q;
|
||||||
for (int j = 0; j < hs; j++) {
|
for (int j = 0; j < hs; j++) {
|
||||||
q = buffer->draw_buffer + (j+Ys) * buffer->stride + 4 * Xs;
|
q = buffer->buffer + (j+Ys) * buffer->stride + 4 * Xs;
|
||||||
for (int i = 0; i < ws; i++) {
|
for (int i = 0; i < ws; i++) {
|
||||||
*p++ = *(q+2); // R
|
*p++ = *(q+2); // R
|
||||||
*p++ = *(q+1); // G
|
*p++ = *(q+1); // G
|
||||||
|
@ -1527,7 +1530,7 @@ Fl_RGB_Image *Fl_Wayland_Screen_Driver::read_win_rectangle(int X, int Y, int w,
|
||||||
|
|
||||||
void Fl_Wayland_Screen_Driver::offscreen_size(Fl_Offscreen off_, int &width, int &height)
|
void Fl_Wayland_Screen_Driver::offscreen_size(Fl_Offscreen off_, int &width, int &height)
|
||||||
{
|
{
|
||||||
struct fl_wld_buffer *off = (struct fl_wld_buffer *)off_;
|
struct fl_wld_draw_buffer *off = (struct fl_wld_draw_buffer *)off_;
|
||||||
width = off->width;
|
width = off->width;
|
||||||
height = off->data_size / off->stride;
|
height = off->data_size / off->stride;
|
||||||
}
|
}
|
||||||
|
|
|
@ -352,10 +352,10 @@ void Fl_Wayland_Window_Driver::make_current() {
|
||||||
((Fl_Cairo_Graphics_Driver*)fl_graphics_driver)->needs_commit_tag(
|
((Fl_Cairo_Graphics_Driver*)fl_graphics_driver)->needs_commit_tag(
|
||||||
&window->buffer->draw_buffer_needs_commit);
|
&window->buffer->draw_buffer_needs_commit);
|
||||||
}
|
}
|
||||||
((Fl_Wayland_Graphics_Driver*)fl_graphics_driver)->set_buffer(window->buffer, f * wld_s);
|
((Fl_Wayland_Graphics_Driver*)fl_graphics_driver)->set_cairo(window->buffer->draw_buffer.cairo_, f * wld_s);
|
||||||
int *poffset = Fl_Window_Driver::menu_offset_y(pWindow);
|
int *poffset = Fl_Window_Driver::menu_offset_y(pWindow);
|
||||||
if (poffset) { // for tall menu windows under KWIN to offset drawing inside window
|
if (poffset) { // for tall menu windows under KWIN to offset drawing inside window
|
||||||
cairo_translate(window->buffer->cairo_, 0, *poffset);
|
cairo_translate(window->buffer->draw_buffer.cairo_, 0, *poffset);
|
||||||
}
|
}
|
||||||
cairo_rectangle_int_t *extents = subRect();
|
cairo_rectangle_int_t *extents = subRect();
|
||||||
if (extents) { // make damage-to-buffer not to leak outside parent
|
if (extents) { // make damage-to-buffer not to leak outside parent
|
||||||
|
@ -593,8 +593,8 @@ int Fl_Wayland_Window_Driver::scroll(int src_x, int src_y, int src_w, int src_h,
|
||||||
i = src_h - 1; to = -1; step = -1;
|
i = src_h - 1; to = -1; step = -1;
|
||||||
}
|
}
|
||||||
while (i != to) {
|
while (i != to) {
|
||||||
memcpy(buffer->draw_buffer + (dest_y + i) * buffer->stride + 4 * dest_x,
|
memcpy(buffer->draw_buffer.buffer + (dest_y + i) * buffer->draw_buffer.stride + 4 * dest_x,
|
||||||
buffer->draw_buffer + (src_y + i) * buffer->stride + 4 * src_x, 4 * src_w);
|
buffer->draw_buffer.buffer + (src_y + i) * buffer->draw_buffer.stride + 4 * src_x, 4 * src_w);
|
||||||
i += step;
|
i += step;
|
||||||
}
|
}
|
||||||
} else { // horizontal scroll
|
} else { // horizontal scroll
|
||||||
|
@ -605,8 +605,8 @@ int Fl_Wayland_Window_Driver::scroll(int src_x, int src_y, int src_w, int src_h,
|
||||||
i = src_h - 1; to = -1; step = -1;
|
i = src_h - 1; to = -1; step = -1;
|
||||||
}
|
}
|
||||||
while (i != to) {
|
while (i != to) {
|
||||||
memmove(buffer->draw_buffer + (src_y + i) * buffer->stride + 4 * dest_x,
|
memmove(buffer->draw_buffer.buffer + (src_y + i) * buffer->draw_buffer.stride + 4 * dest_x,
|
||||||
buffer->draw_buffer + (src_y + i) * buffer->stride + 4 * src_x, 4 * src_w);
|
buffer->draw_buffer.buffer + (src_y + i) * buffer->draw_buffer.stride + 4 * src_x, 4 * src_w);
|
||||||
i += step;
|
i += step;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1628,15 +1628,15 @@ int Fl_Wayland_Window_Driver::set_cursor_4args(const Fl_RGB_Image *rgb, int hotx
|
||||||
new_cursor->images[0] = (struct wl_cursor_image*)new_image;
|
new_cursor->images[0] = (struct wl_cursor_image*)new_image;
|
||||||
new_cursor->name = strdup("custom cursor");
|
new_cursor->name = strdup("custom cursor");
|
||||||
// draw the rgb image to the cursor's drawing buffer
|
// draw the rgb image to the cursor's drawing buffer
|
||||||
Fl_Image_Surface *img_surf = new Fl_Image_Surface(new_image->image.width, new_image->image.height, 0, (Fl_Offscreen)offscreen);
|
Fl_Image_Surface *img_surf = new Fl_Image_Surface(new_image->image.width, new_image->image.height, 0, (Fl_Offscreen)&offscreen->draw_buffer);
|
||||||
Fl_Surface_Device::push_current(img_surf);
|
Fl_Surface_Device::push_current(img_surf);
|
||||||
Fl_Wayland_Graphics_Driver *driver = (Fl_Wayland_Graphics_Driver*)img_surf->driver();
|
Fl_Wayland_Graphics_Driver *driver = (Fl_Wayland_Graphics_Driver*)img_surf->driver();
|
||||||
cairo_scale(driver->cr(), scale, scale);
|
cairo_scale(driver->cr(), scale, scale);
|
||||||
memset(offscreen->draw_buffer, 0, offscreen->data_size);
|
memset(offscreen->draw_buffer.buffer, 0, offscreen->draw_buffer.data_size);
|
||||||
((Fl_RGB_Image*)rgb)->draw(0, 0);
|
((Fl_RGB_Image*)rgb)->draw(0, 0);
|
||||||
Fl_Surface_Device::pop_current();
|
Fl_Surface_Device::pop_current();
|
||||||
delete img_surf;
|
delete img_surf;
|
||||||
memcpy(offscreen->data, offscreen->draw_buffer, offscreen->data_size);
|
memcpy(offscreen->data, offscreen->draw_buffer.buffer, offscreen->draw_buffer.data_size);
|
||||||
// delete the previous custom cursor, if there was one, and keep its Fl_RGB_Image if appropriate
|
// delete the previous custom cursor, if there was one, and keep its Fl_RGB_Image if appropriate
|
||||||
delete_cursor_(xid, keep_copy);
|
delete_cursor_(xid, keep_copy);
|
||||||
//have this new cursor used
|
//have this new cursor used
|
||||||
|
@ -1681,7 +1681,7 @@ void Fl_Wayland_Window_Driver::resize(int X, int Y, int W, int H) {
|
||||||
int stride = cairo_format_stride_for_width(
|
int stride = cairo_format_stride_for_width(
|
||||||
Fl_Cairo_Graphics_Driver::cairo_format, int(W * scale) );
|
Fl_Cairo_Graphics_Driver::cairo_format, int(W * scale) );
|
||||||
size_t bsize = stride * int(H * scale);
|
size_t bsize = stride * int(H * scale);
|
||||||
true_rescale = (bsize != fl_win->buffer->data_size);
|
true_rescale = (bsize != fl_win->buffer->draw_buffer.data_size);
|
||||||
}
|
}
|
||||||
int is_a_resize = (W != w() || H != h() || true_rescale);
|
int is_a_resize = (W != w() || H != h() || true_rescale);
|
||||||
if (is_a_move) force_position(1);
|
if (is_a_move) force_position(1);
|
||||||
|
@ -1827,7 +1827,7 @@ void Fl_Wayland_Window_Driver::reposition_menu_window(int x, int y) {
|
||||||
*Fl_Window_Driver::menu_offset_y(pWindow) += (y - pWindow->y());
|
*Fl_Window_Driver::menu_offset_y(pWindow) += (y - pWindow->y());
|
||||||
struct wld_window *xid = fl_wl_xid(pWindow);
|
struct wld_window *xid = fl_wl_xid(pWindow);
|
||||||
wl_surface_set_opaque_region(xid->wl_surface, NULL);
|
wl_surface_set_opaque_region(xid->wl_surface, NULL);
|
||||||
if (xid->buffer) memset(xid->buffer->draw_buffer, 0, xid->buffer->data_size);
|
if (xid->buffer) memset(xid->buffer->draw_buffer.buffer, 0, xid->buffer->draw_buffer.data_size);
|
||||||
//printf("offset_y=%d\n", *Fl_Window_Driver::menu_offset_y(pWindow));
|
//printf("offset_y=%d\n", *Fl_Window_Driver::menu_offset_y(pWindow));
|
||||||
this->y(y);
|
this->y(y);
|
||||||
pWindow->redraw();
|
pWindow->redraw();
|
||||||
|
|
|
@ -176,7 +176,7 @@ static const struct wl_data_source_listener data_source_listener = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static Fl_Offscreen offscreen_from_text(const char *text, int scale) {
|
static struct fl_wld_buffer *offscreen_from_text(const char *text, int scale) {
|
||||||
const char *p, *q;
|
const char *p, *q;
|
||||||
int width = 0, height, w2, ltext = strlen(text);
|
int width = 0, height, w2, ltext = strlen(text);
|
||||||
fl_font(FL_HELVETICA, 10 * scale);
|
fl_font(FL_HELVETICA, 10 * scale);
|
||||||
|
@ -196,9 +196,9 @@ static Fl_Offscreen offscreen_from_text(const char *text, int scale) {
|
||||||
if (width > 300*scale) width = 300*scale;
|
if (width > 300*scale) width = 300*scale;
|
||||||
height = nl * fl_height() + 3;
|
height = nl * fl_height() + 3;
|
||||||
width += 6;
|
width += 6;
|
||||||
struct fl_wld_buffer * off = Fl_Wayland_Graphics_Driver::create_shm_buffer(width, height);
|
struct fl_wld_buffer *off = Fl_Wayland_Graphics_Driver::create_shm_buffer(width, height);
|
||||||
memset(off->draw_buffer, 0, off->data_size);
|
memset(off->draw_buffer.buffer, 0, off->draw_buffer.data_size);
|
||||||
Fl_Image_Surface *surf = new Fl_Image_Surface(width, height, 0, (Fl_Offscreen)off);
|
Fl_Image_Surface *surf = new Fl_Image_Surface(width, height, 0, (Fl_Offscreen)&off->draw_buffer);
|
||||||
Fl_Surface_Device::push_current(surf);
|
Fl_Surface_Device::push_current(surf);
|
||||||
p = text;
|
p = text;
|
||||||
fl_font(FL_HELVETICA, 10 * scale);
|
fl_font(FL_HELVETICA, 10 * scale);
|
||||||
|
@ -217,9 +217,9 @@ static Fl_Offscreen offscreen_from_text(const char *text, int scale) {
|
||||||
}
|
}
|
||||||
Fl_Surface_Device::pop_current();
|
Fl_Surface_Device::pop_current();
|
||||||
delete surf;
|
delete surf;
|
||||||
cairo_surface_flush( cairo_get_target(off->cairo_) );
|
cairo_surface_flush( cairo_get_target(off->draw_buffer.cairo_) );
|
||||||
memcpy(off->data, off->draw_buffer, off->data_size);
|
memcpy(off->data, off->draw_buffer.buffer, off->draw_buffer.data_size);
|
||||||
return (Fl_Offscreen)off;
|
return off;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue