ucw.cz
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
List overview
Download
Gfxprim
March 2013
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
gfxprim@ucw.cz
1 participants
31 discussions
Start a n
N
ew thread
[repo.or.cz] gfxprim.git branch master updated: 21e1fa797b0f25794c323793ebcff1c1762c755a
by metan
01 Mar '13
01 Mar '13
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project gfxprim.git. The branch, master has been updated via 21e1fa797b0f25794c323793ebcff1c1762c755a (commit) via 1514e22782408ebbad3db2b9b4f37082f5e7e8f5 (commit) via 19ad346473c404690363482eb05aba63474eeed5 (commit) from 1436f47f05624f213e5065a9436ccc404e6b8bad (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/21e1fa797b0f25794c323793ebcff1c1762c…
commit 21e1fa797b0f25794c323793ebcff1c1762c755a Author: Cyril Hrubis <metan(a)ucw.cz> Date: Fri Mar 1 13:42:47 2013 +0100 libs: backends: X11 backend code refactoring. First part of the cleanup + initial support for multiple windows. diff --git a/libs/backends/GP_X11.c b/libs/backends/GP_X11.c index c5b17d8..3a6e2ba 100644 --- a/libs/backends/GP_X11.c +++ b/libs/backends/GP_X11.c @@ -42,103 +42,91 @@ #endif /* HAVE_X_SHM */ #include "input/GP_InputDriverX11.h" -#include "GP_X11.h" - -struct x11_priv { - /* Connection details */ - Display *dpy; - int scr; - Screen *scr_ptr; - int scr_depth; - Window win; - Visual *vis; - - /* Image details */ - XImage *img; - -#ifdef HAVE_X_SHM - XShmSegmentInfo shminfo; -#endif /* HAVE_X_SHM */ - - GP_Context context; - int resized_flag:1; - int shm_flag:1; +#include "backends/GP_X11.h" - /* used to store width and height from ConfigureNotify event */ - unsigned int new_w; - unsigned int new_h; -}; +#include "GP_X11_Conn.h" +#include "GP_X11_Win.h" static int resize_ximage(GP_Backend *self, int w, int h); static int resize_shm_ximage(GP_Backend *self, int w, int h); -static void putimage(struct GP_Backend *self, int x0, int y0, int x1, int y1) +static void putimage(struct x11_win *win, int x0, int y0, int x1, int y1) { - struct x11_priv *x11 = GP_BACKEND_PRIV(self); - #ifdef HAVE_X_SHM - if (x11->shm_flag) - XShmPutImage(x11->dpy, x11->win, DefaultGC(x11->dpy, x11->scr), - x11->img, x0, y0, x0, y0, x1-x0+1, y1-y0+1, False); + if (win->shm_flag) + XShmPutImage(win->dpy, win->win, DefaultGC(win->dpy, win->scr), + win->img, x0, y0, x0, y0, x1-x0+1, y1-y0+1, False); else #endif /* HAVE_X_SHM */ - XPutImage(x11->dpy, x11->win, DefaultGC(x11->dpy, x11->scr), - x11->img, x0, y0, x0, y0, x1-x0+1, y1-y0+1); + XPutImage(win->dpy, win->win, DefaultGC(win->dpy, win->scr), + win->img, x0, y0, x0, y0, x1-x0+1, y1-y0+1); } static void x11_update_rect(GP_Backend *self, GP_Coord x0, GP_Coord y0, GP_Coord x1, GP_Coord y1) { - struct x11_priv *x11 = GP_BACKEND_PRIV(self); - + struct x11_win *win = GP_BACKEND_PRIV(self); + GP_DEBUG(4, "Updating rect %ix%i-%ix%i", x0, y0, x1, y1); - - if (x11->resized_flag) { + + if (win->resized_flag) { GP_DEBUG(4, "Ignoring update rect, waiting for resize ack"); return; } - - XLockDisplay(x11->dpy); - putimage(self, x0, y0, x1, y1); + XLockDisplay(win->dpy); + + putimage(win, x0, y0, x1, y1); - XUnlockDisplay(x11->dpy); + XUnlockDisplay(win->dpy); } static void x11_flip(GP_Backend *self) { - struct x11_priv *x11 = GP_BACKEND_PRIV(self); + struct x11_win *win = GP_BACKEND_PRIV(self); unsigned int w = self->context->w; unsigned int h = self->context->h; GP_DEBUG(4, "Flipping context"); - - if (x11->resized_flag) { + + if (win->resized_flag) { GP_DEBUG(4, "Ignoring flip, waiting for resize ack"); return; } - - XLockDisplay(x11->dpy); + + XLockDisplay(win->dpy); #ifdef HAVE_X_SHM - if (x11->shm_flag) - XShmPutImage(x11->dpy, x11->win, DefaultGC(x11->dpy, x11->scr), - x11->img, 0, 0, 0, 0, w, h, False); + if (win->shm_flag) + XShmPutImage(win->dpy, win->win, DefaultGC(win->dpy, win->scr), + win->img, 0, 0, 0, 0, w, h, False); else #endif /* HAVE_X_SHM */ - XPutImage(x11->dpy, x11->win, DefaultGC(x11->dpy, x11->scr), - x11->img, 0, 0, 0, 0, w, h); - - XFlush(x11->dpy); - - XUnlockDisplay(x11->dpy); + XPutImage(win->dpy, win->win, DefaultGC(win->dpy, win->scr), + win->img, 0, 0, 0, 0, w, h); + + XFlush(win->dpy); + + XUnlockDisplay(win->dpy); } -static void x11_ev(GP_Backend *self, XEvent *ev) +static void x11_ev(XEvent *ev) { - struct x11_priv *x11 = GP_BACKEND_PRIV(self); - + /* Lookup for window */ + static struct x11_win *win = NULL; + + if (win == NULL || win->win != ev->xany.window) { + win = win_list_lookup(ev->xany.window); + + if (win == NULL) { + GP_WARN("Event for unknown window, ignoring."); + return; + } + } + + struct GP_Backend *self = GP_CONTAINER_OF(win, struct GP_Backend, priv); + switch (ev->type) { case Expose: GP_DEBUG(4, "Expose %ix%i-%ix%i %i", @@ -146,7 +134,7 @@ static void x11_ev(GP_Backend *self, XEvent *ev) ev->xexpose.width, ev->xexpose.height, ev->xexpose.count); - if (x11->resized_flag) + if (win->resized_flag) break; /* Safety measure */ @@ -154,7 +142,7 @@ static void x11_ev(GP_Backend *self, XEvent *ev) GP_WARN("Expose x + w > context->w"); break; } - + if (ev->xexpose.y + ev->xexpose.height > (int)self->context->h) { GP_WARN("Expose y + h > context->h"); break; @@ -170,58 +158,58 @@ static void x11_ev(GP_Backend *self, XEvent *ev) ev->xconfigure.height == (int)self->context->h) break; - if (ev->xconfigure.width == (int)x11->new_w && - ev->xconfigure.height == (int)x11->new_h) + if (ev->xconfigure.width == (int)win->new_w && + ev->xconfigure.height == (int)win->new_h) break; - x11->new_w = ev->xconfigure.width; - x11->new_h = ev->xconfigure.height; + win->new_w = ev->xconfigure.width; + win->new_h = ev->xconfigure.height; - GP_DEBUG(4, "Configure Notify %ux%u", x11->new_w, x11->new_h); + GP_DEBUG(4, "Configure Notify %ux%u", win->new_w, win->new_h); /* Window has been resized, set flag. */ - x11->resized_flag = 1; + win->resized_flag = 1; default: //TODO: More accurate window w and h? GP_InputDriverX11EventPut(&self->event_queue, ev, - x11->context.w, x11->context.h); + win->context.w, win->context.h); break; } } static void x11_poll(GP_Backend *self) { - struct x11_priv *x11 = GP_BACKEND_PRIV(self); + struct x11_win *win = GP_BACKEND_PRIV(self); XEvent ev; - XLockDisplay(x11->dpy); - - while (XPending(x11->dpy)) { - XNextEvent(x11->dpy, &ev); - x11_ev(self, &ev); + XLockDisplay(win->dpy); + + while (XPending(win->dpy)) { + XNextEvent(win->dpy, &ev); + x11_ev(&ev); } - - XUnlockDisplay(x11->dpy); + + XUnlockDisplay(win->dpy); } static void x11_wait(GP_Backend *self) { - struct x11_priv *x11 = GP_BACKEND_PRIV(self); + struct x11_win *win = GP_BACKEND_PRIV(self); XEvent ev; - XLockDisplay(x11->dpy); - - XNextEvent(x11->dpy, &ev); - x11_ev(self, &ev); - - XUnlockDisplay(x11->dpy); + XLockDisplay(win->dpy); + + XNextEvent(win->dpy, &ev); + x11_ev(&ev); + + XUnlockDisplay(win->dpy); } static int resize_buffer(struct GP_Backend *self, uint32_t w, uint32_t h) { - struct x11_priv *x11 = GP_BACKEND_PRIV(self); + struct x11_win *win = GP_BACKEND_PRIV(self); - if (x11->shm_flag) { + if (win->shm_flag) { if (resize_shm_ximage(self, w, h)) return 1; } else { @@ -236,54 +224,54 @@ static int x11_set_attributes(struct GP_Backend *self, uint32_t w, uint32_t h, const char *caption) { - struct x11_priv *x11 = GP_BACKEND_PRIV(self); + struct x11_win *win = GP_BACKEND_PRIV(self); - XLockDisplay(x11->dpy); + XLockDisplay(win->dpy); if (caption != NULL) { GP_DEBUG(3, "Setting window caption to '%s'", caption); - XmbSetWMProperties(x11->dpy, x11->win, caption, caption, + XmbSetWMProperties(win->dpy, win->win, caption, caption, NULL, 0, NULL, NULL, NULL); } if (w != 0 && h != 0) { GP_DEBUG(3, "Setting window size to %ux%u", w, h); - XResizeWindow(x11->dpy, x11->win, w, h); + XResizeWindow(win->dpy, win->win, w, h); } - XFlush(x11->dpy); + XFlush(win->dpy); - XUnlockDisplay(x11->dpy); + XUnlockDisplay(win->dpy); return 0; } static int x11_resize_ack(struct GP_Backend *self) { - struct x11_priv *x11 = GP_BACKEND_PRIV(self); + struct x11_win *win = GP_BACKEND_PRIV(self); int ret; - XLockDisplay(x11->dpy); + XLockDisplay(win->dpy); - GP_DEBUG(3, "Setting buffer size to %ux%u", x11->new_w, x11->new_h); + GP_DEBUG(3, "Setting buffer size to %ux%u", win->new_w, win->new_h); - ret = resize_buffer(self, x11->new_w, x11->new_h); + ret = resize_buffer(self, win->new_w, win->new_h); - x11->resized_flag = 0; + win->resized_flag = 0; if (!ret) { GP_EventQueueSetScreenSize(&self->event_queue, - x11->new_w, x11->new_h); + win->new_w, win->new_h); } GP_DEBUG(3, "Done"); - XUnlockDisplay(x11->dpy); + XUnlockDisplay(win->dpy); return ret; } -static void match_pixel_type(struct x11_priv *x11, +static void match_pixel_type(struct x11_win *win, enum GP_PixelType *pixel_type, int *depth) { /* @@ -292,9 +280,9 @@ static void match_pixel_type(struct x11_priv *x11, * Do best effor on selecting appropriate pixel type */ for (*depth = 8; *depth <= 32; *depth<<=1) { - *pixel_type = GP_PixelRGBMatch(x11->vis->red_mask, - x11->vis->green_mask, - x11->vis->blue_mask, + *pixel_type = GP_PixelRGBMatch(win->vis->red_mask, + win->vis->green_mask, + win->vis->blue_mask, 0x0, *depth); if (*pixel_type != GP_PIXEL_UNKNOWN) @@ -306,9 +294,9 @@ static void match_pixel_type(struct x11_priv *x11, static int create_shm_ximage(GP_Backend *self, GP_Size w, GP_Size h) { - struct x11_priv *x11 = GP_BACKEND_PRIV(self); + struct x11_win *win = GP_BACKEND_PRIV(self); - if (XShmQueryExtension(x11->dpy) == False) { + if (XShmQueryExtension(win->dpy) == False) { GP_DEBUG(1, "MIT SHM Extension not supported, " "falling back to XImage"); return 1; @@ -321,7 +309,7 @@ static int create_shm_ximage(GP_Backend *self, GP_Size w, GP_Size h) int depth; if (self->context == NULL) - match_pixel_type(x11, &pixel_type, &depth); + match_pixel_type(win, &pixel_type, &depth); else pixel_type = self->context->pixel_type; @@ -330,93 +318,93 @@ static int create_shm_ximage(GP_Backend *self, GP_Size w, GP_Size h) return 1; } - x11->img = XShmCreateImage(x11->dpy, x11->vis, x11->scr_depth, - ZPixmap, NULL, &x11->shminfo, w, h); + win->img = XShmCreateImage(win->dpy, win->vis, win->scr_depth, + ZPixmap, NULL, &win->shminfo, w, h); - if (x11->img == NULL) { + if (win->img == NULL) { GP_WARN("Failed to create SHM XImage"); return 1; } - size_t size = x11->img->bytes_per_line * x11->img->height; + size_t size = win->img->bytes_per_line * win->img->height; - x11->shminfo.shmid = shmget(IPC_PRIVATE, size, 0600); + win->shminfo.shmid = shmget(IPC_PRIVATE, size, 0600); - if (x11->shminfo.shmid == -1) { + if (win->shminfo.shmid == -1) { GP_WARN("Calling shmget() failed: %s", strerror(errno)); goto err0; } - x11->shminfo.shmaddr = x11->img->data = shmat(x11->shminfo.shmid, 0, 0); + win->shminfo.shmaddr = win->img->data = shmat(win->shminfo.shmid, 0, 0); - if (x11->shminfo.shmaddr == (void *)-1) { + if (win->shminfo.shmaddr == (void *)-1) { GP_WARN("Calling shmat() failed: %s", strerror(errno)); goto err1; } /* Mark SHM for deletion after detach */ - if (shmctl(x11->shminfo.shmid, IPC_RMID, 0)) { + if (shmctl(win->shminfo.shmid, IPC_RMID, 0)) { GP_WARN("Calling shmctl(..., IPC_RMID), 0) failed: %s", strerror(errno)); goto err2; } - x11->shminfo.readOnly = False; + win->shminfo.readOnly = False; - if (XShmAttach(x11->dpy, &x11->shminfo) == False) { + if (XShmAttach(win->dpy, &win->shminfo) == False) { GP_WARN("XShmAttach failed"); goto err2; } - GP_ContextInit(&x11->context, w, h, pixel_type, x11->shminfo.shmaddr); - x11->context.bytes_per_row = x11->img->bytes_per_line; + GP_ContextInit(&win->context, w, h, pixel_type, win->shminfo.shmaddr); + win->context.bytes_per_row = win->img->bytes_per_line; - self->context = &x11->context; + self->context = &win->context; - x11->shm_flag = 1; + win->shm_flag = 1; //FIXME: Proper synchronization - XSync(x11->dpy, True); + XSync(win->dpy, True); return 0; err2: - shmdt(x11->shminfo.shmaddr); + shmdt(win->shminfo.shmaddr); err1: - shmctl(x11->shminfo.shmid, IPC_RMID, 0); + shmctl(win->shminfo.shmid, IPC_RMID, 0); err0: - XDestroyImage(x11->img); + XDestroyImage(win->img); return 1; } static void destroy_shm_ximage(GP_Backend *self) { - struct x11_priv *x11 = GP_BACKEND_PRIV(self); + struct x11_win *win = GP_BACKEND_PRIV(self); - XLockDisplay(x11->dpy); + XLockDisplay(win->dpy); - XShmDetach(x11->dpy, &x11->shminfo); - XFlush(x11->dpy); - shmdt(x11->shminfo.shmaddr); - XDestroyImage(x11->img); - XFlush(x11->dpy); + XShmDetach(win->dpy, &win->shminfo); + XFlush(win->dpy); + shmdt(win->shminfo.shmaddr); + XDestroyImage(win->img); + XFlush(win->dpy); - XUnlockDisplay(x11->dpy); + XUnlockDisplay(win->dpy); } static int resize_shm_ximage(GP_Backend *self, int w, int h) { - struct x11_priv *x11 = GP_BACKEND_PRIV(self); + struct x11_win *win = GP_BACKEND_PRIV(self); int ret; GP_DEBUG(4, "Resizing XShmImage %ux%u -> %ux%u", self->context->w, self->context->h, w, h); - XLockDisplay(x11->dpy); + XLockDisplay(win->dpy); destroy_shm_ximage(self); ret = create_shm_ximage(self, w, h); - XUnlockDisplay(x11->dpy); + XUnlockDisplay(win->dpy); return ret; } @@ -445,11 +433,11 @@ static int resize_shm_ximage(GP_Backend GP_UNUSED(*self), static int create_ximage(GP_Backend *self, GP_Size w, GP_Size h) { - struct x11_priv *x11 = GP_BACKEND_PRIV(self); + struct x11_win *win = GP_BACKEND_PRIV(self); enum GP_PixelType pixel_type; int depth; - match_pixel_type(x11, &pixel_type, &depth); + match_pixel_type(win, &pixel_type, &depth); if (pixel_type == GP_PIXEL_UNKNOWN) { GP_DEBUG(1, "Unknown pixel type"); @@ -461,39 +449,39 @@ static int create_ximage(GP_Backend *self, GP_Size w, GP_Size h) if (self->context == NULL) return 1; - x11->img = XCreateImage(x11->dpy, x11->vis, x11->scr_depth, ZPixmap, 0, + win->img = XCreateImage(win->dpy, win->vis, win->scr_depth, ZPixmap, 0, NULL, w, h, depth, 0); - if (x11->img == NULL) { + if (win->img == NULL) { GP_DEBUG(1, "Failed to create XImage"); GP_ContextFree(self->context); return 1; } - x11->shm_flag = 0; + win->shm_flag = 0; - x11->img->data = (char*)self->context->pixels; + win->img->data = (char*)self->context->pixels; return 0; } static void destroy_ximage(GP_Backend *self) { - struct x11_priv *x11 = GP_BACKEND_PRIV(self); + struct x11_win *win = GP_BACKEND_PRIV(self); GP_ContextFree(self->context); - x11->img->data = NULL; - XDestroyImage(x11->img); + win->img->data = NULL; + XDestroyImage(win->img); } static int resize_ximage(GP_Backend *self, int w, int h) { - struct x11_priv *x11 = GP_BACKEND_PRIV(self); + struct x11_win *win = GP_BACKEND_PRIV(self); XImage *img; /* Create new X image */ - img = XCreateImage(x11->dpy, x11->vis, x11->scr_depth, ZPixmap, 0, NULL, - w, h, x11->img->bitmap_pad, 0); + img = XCreateImage(win->dpy, win->vis, win->scr_depth, ZPixmap, 0, NULL, + w, h, win->img->bitmap_pad, 0); if (img == NULL) { GP_DEBUG(2, "XCreateImage failed"); @@ -507,288 +495,39 @@ static int resize_ximage(GP_Backend *self, int w, int h) } /* Free old image */ - x11->img->data = NULL; - XDestroyImage(x11->img); + win->img->data = NULL; + XDestroyImage(win->img); /* Swap the pointers */ img->data = (char*)self->context->pixels; - x11->img = img; + win->img = img; return 0; } static void window_close(GP_Backend *self) { - struct x11_priv *x11 = GP_BACKEND_PRIV(self); + struct x11_win *win = GP_BACKEND_PRIV(self); - XLockDisplay(x11->dpy); + XLockDisplay(win->dpy); - if (x11->shm_flag) + if (win->shm_flag) destroy_shm_ximage(self); else destroy_ximage(self); - XDestroyWindow(x11->dpy, x11->win); - - XUnlockDisplay(x11->dpy); + x11_win_close(win); + + XUnlockDisplay(win->dpy); } static void x11_exit(GP_Backend *self) { - struct x11_priv *x11 = GP_BACKEND_PRIV(self); - - XLockDisplay(x11->dpy); - window_close(self); - /* I wonder if this is right sequence... */ - //XUnlockDisplay(x11->dpy); - XCloseDisplay(x11->dpy); - - free(self); -} - -static void create_window(struct x11_priv *x11, int x, int y, - unsigned int *w, unsigned int *h, - const char *caption, enum GP_BackendX11Flags flags) -{ - XSetWindowAttributes attrs; - unsigned long attr_mask = 0; - - /* Set event mask */ - attrs.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask | - KeyReleaseMask | PointerMotionMask; - attr_mask |= CWEventMask; - - /* - * If root window was selected, resize w and h and set x11->win to root - * window. - */ - if (flags & GP_X11_USE_ROOT_WIN) { - x11->win = DefaultRootWindow(x11->dpy); - *w = DisplayWidth(x11->dpy, x11->scr); - *h = DisplayHeight(x11->dpy, x11->scr); - - GP_DEBUG(2, "Using root window, owerriding size to %ux%u", - *w, *h); - - XChangeWindowAttributes(x11->dpy, x11->win, attr_mask, &attrs); - - return; - } - - /* - * For some reason reading mouse button clicks on root win are not - * allowed... - */ - attrs.event_mask |= ButtonPressMask | ButtonReleaseMask; - - /* - * Create undecoreated root window on background - */ - if (flags & GP_X11_CREATE_ROOT_WIN) { - Atom xa; - - *w = DisplayWidth(x11->dpy, x11->scr); - *h = DisplayHeight(x11->dpy, x11->scr); - - GP_DEBUG(2, "Creating a window above root, owerriding size to %ux%u", - *w, *h); - - x11->win = XCreateWindow(x11->dpy, DefaultRootWindow(x11->dpy), - 0, 0, *w, *h, 0, CopyFromParent, - InputOutput, CopyFromParent, attr_mask, &attrs); - - /* Set empty WM_PROTOCOLS */ - GP_DEBUG(2, "Setting empty MW_PROTOCOLS"); - XSetWMProtocols(x11->dpy, x11->win, NULL, 0); - - /* Set window type to desktop */ - xa = XInternAtom(x11->dpy, "_NET_WM_WINDOW_TYPE", False); - - if (xa != None) { - GP_DEBUG(2, "Setting Atom _NET_WM_WINDOW_TYPE to _NET_WM_WINDOW_TYPE_DESKTOP"); - - Atom xa_prop = XInternAtom(x11->dpy, "_NET_WM_WINDOW_TYPE_DESKTOP", False); - - XChangeProperty(x11->dpy, x11->win, xa, XA_ATOM, 32, - PropModeReplace, (unsigned char *) &xa_prop, 1); - } - - /* Turn off window decoration */ - xa = XInternAtom(x11->dpy, "_MOTIF_WM_HINTS", False); - - if (xa != None) { - GP_DEBUG(2, "Setting Atom _MOTIF_WM_HINTS to 2, 0, 0, 0, 0"); - - long prop[5] = {2, 0, 0, 0, 0}; - - XChangeProperty(x11->dpy, x11->win, xa, xa, 32, - PropModeReplace, (unsigned char *) prop, 5); - } - - /* Set below other windows */ - xa = XInternAtom(x11->dpy, "_WIN_LAYER", False); - - if (xa != None) { - GP_DEBUG(2, "Setting Atom _WIN_LAYER to 6"); - - long prop = 6; - - XChangeProperty(x11->dpy, x11->win, xa, XA_CARDINAL, 32, - PropModeAppend, (unsigned char *) &prop, 1); - } - - xa = XInternAtom(x11->dpy, "_NET_WM_STATE", False); - - if (xa != None) { - GP_DEBUG(2, "Setting Atom _NET_WM_STATE to _NET_WM_STATE_BELOW"); - - Atom xa_prop = XInternAtom(x11->dpy, "_NET_WM_STATE_BELOW", False); - - XChangeProperty(x11->dpy, x11->win, xa, XA_ATOM, 32, - PropModeAppend, (unsigned char *) &xa_prop, 1); - } - - /* Set sticky */ - xa = XInternAtom(x11->dpy, "_NET_WM_DESKTOP", False); - - if (xa != None) { - GP_DEBUG(2, "Setting Atom _NET_WM_DESKTOP to 0xffffffff"); - - CARD32 xa_prop = 0xffffffff; - - XChangeProperty(x11->dpy, x11->win, xa, XA_CARDINAL, 32, - PropModeAppend, (unsigned char *) &xa_prop, 1); - } - - xa = XInternAtom(x11->dpy, "_NET_WM_STATE", False); - - if (xa != None) { - GP_DEBUG(2, "Appending to Atom _NET_WM_STATE atom _NET_WM_STATE_STICKY"); - - Atom xa_prop = XInternAtom(x11->dpy, "_NET_WM_STATE_STICKY", False); - - XChangeProperty(x11->dpy, x11->win, xa, XA_ATOM, 32, - PropModeAppend, (unsigned char *) &xa_prop, 1); - } - - /* Skip taskbar */ - xa = XInternAtom(x11->dpy, "_NET_WM_STATE", False); - - if (xa != None) { - GP_DEBUG(2, "Appending to Atom _NET_WM_STATE atom _NET_STATE_SKIP_TASKBAR"); - - Atom xa_prop = XInternAtom(x11->dpy, "_NET_WM_STATE_SKIP_TASKBAR", False); - - XChangeProperty(x11->dpy, x11->win, xa, XA_ATOM, 32, - PropModeAppend, (unsigned char *) &xa_prop, 1); - } - - /* Skip pager */ - xa = XInternAtom(x11->dpy, "_NET_WM_STATE", False); - - if (xa != None) { - GP_DEBUG(2, "Appending to Atom _NET_WM_STATE atom _NET_STATE_SKIP_PAGER"); - - Atom xa_prop = XInternAtom(x11->dpy, "_NET_WM_STATE_SKIP_PAGER", False); - - XChangeProperty(x11->dpy, x11->win, xa, XA_ATOM, 32, - PropModeAppend, (unsigned char *) &xa_prop, 1); - } + x11_close(); - /* Set 100% opacity */ - xa = XInternAtom(x11->dpy, "_NET_WM_WINDOW_OPACITY", False); - - if (xa != None) { - GP_DEBUG(2, "Setting Atom _NET_WM_WINDOW_OPACITY to 0xffffffff"); - - long prop = 0xffffffff; - - XChangeProperty(x11->dpy, x11->win, xa, XA_CARDINAL, 32, - PropModeAppend, (unsigned char *) &prop, 1); - } - - /* Show window */ - XMapWindow(x11->dpy, x11->win); - return; - } - - GP_DEBUG(2, "Opening window '%s' %ix%i-%ux%u", - caption, x, y, *w, *h); - - x11->win = XCreateWindow(x11->dpy, DefaultRootWindow(x11->dpy), - x, y, *w, *h, 0, CopyFromParent, - InputOutput, CopyFromParent, attr_mask, &attrs); - - /* Set window caption */ - XmbSetWMProperties(x11->dpy, x11->win, caption, caption, - NULL, 0, NULL, NULL, NULL); - - /* Make the window close button send event */ - Atom xa = XInternAtom(x11->dpy, "WM_DELETE_WINDOW", True); - - if (xa != None) { - GP_DEBUG(2, "Setting WM_DELETE_WINDOW Atom to True"); - - XSetWMProtocols(x11->dpy, x11->win, &xa, 1); - } else { - GP_DEBUG(2, "Failed to set WM_DELETE_WINDOW Atom to True"); - } - - /* Show window */ - XMapWindow(x11->dpy, x11->win); -} - -#ifndef _NET_WM_STATE_ADD -# define _NET_WM_STATE_ADD 1 -#endif /* _NET_WM_STATE_ADD */ - -#ifndef _NET_WM_STATE_REMOVE -# define _NET_WM_STATE_REMOVE 0 -#endif /* _NET_WM_STATE_REMOVE */ - -/* Send NETWM message, most modern Window Managers should understand */ -static void request_fullscreen(struct GP_Backend *self, int mode) -{ - struct x11_priv *x11 = GP_BACKEND_PRIV(self); - - if (mode < 0 || mode > 2) { - GP_WARN("Invalid fullscreen mode = %u", mode); - return; - } - - GP_DEBUG(2, "Requesting fullscreen mode = %u", mode); - - Atom wm_state, fullscreen; - - wm_state = XInternAtom(x11->dpy, "_NET_WM_STATE", True); - fullscreen = XInternAtom(x11->dpy, "_NET_WM_STATE_FULLSCREEN", True); - - if (wm_state == None || fullscreen == None) { - GP_WARN("Failed to create _NET_WM_* atoms"); - return; - } - - XEvent ev; - - memset(&ev, 0, sizeof(ev)); - - ev.type = ClientMessage; - ev.xclient.window = x11->win; - ev.xclient.message_type = wm_state; - ev.xclient.format = 32; - ev.xclient.data.l[0] = mode; - ev.xclient.data.l[1] = fullscreen; - ev.xclient.data.l[2] = 0; - ev.xclient.data.l[3] = 1; - - if (!XSendEvent(x11->dpy, XDefaultRootWindow(x11->dpy), False, SubstructureNotifyMask, &ev)) { - GP_WARN("Failed to send _NET_WM_STATE_FULLSCREEN event"); - return; - } - - XFlush(x11->dpy); + free(self); } GP_Backend *GP_BackendX11Init(const char *display, int x, int y, @@ -797,53 +536,43 @@ GP_Backend *GP_BackendX11Init(const char *display, int x, int y, enum GP_BackendX11Flags flags) { GP_Backend *backend; - struct x11_priv *x11; - - GP_DEBUG(1, "Initalizing X11 display '%s'", display); - - if (!XInitThreads()) { - GP_DEBUG(2, "XInitThreads failed"); - return NULL; - } + struct x11_win *win; backend = malloc(sizeof(GP_Backend) + - sizeof(struct x11_priv)); + sizeof(struct x11_win)); if (backend == NULL) return NULL; - x11 = GP_BACKEND_PRIV(backend); - - x11->dpy = XOpenDisplay(display); - - if (x11->dpy == NULL) - goto err0; + win = GP_BACKEND_PRIV(backend); - /* Initialized key translation table */ - GP_InputDriverX11Init(x11->dpy); + //XSynchronize(win->dpy, True); - //XSynchronize(x11->dpy, True); + /* Pack parameters and open window */ + struct x11_wreq wreq = { + .win = win, + .display = display, + .x = x, + .y = y, + .w = w, + .h = h, + .caption = caption, + .flags = flags, + }; - x11->scr = DefaultScreen(x11->dpy); - x11->vis = DefaultVisual(x11->dpy, x11->scr); - x11->scr_ptr = DefaultScreenOfDisplay(x11->dpy); - x11->scr_depth = DefaultDepthOfScreen(x11->scr_ptr); + x11_win_open(&wreq); - GP_DEBUG(2, "Have Visual id %i, depth %u", (int)x11->vis->visualid, x11->scr_depth); - - create_window(x11, x, y, &w, &h, caption, flags); - - if (x11->win == None) { + if (win->win == None) { //TODO: Error message? GP_DEBUG(1, "Failed to create window"); goto err1; } /* Init the event queue, once we know the window size */ - GP_EventQueueInit(&backend->event_queue, w, h, 0); + GP_EventQueueInit(&backend->event_queue, wreq.w, wreq.h, 0); if (flags & GP_X11_FULLSCREEN) - request_fullscreen(backend, 1); + x11_win_fullscreen(win, 1); backend->context = NULL; @@ -851,9 +580,9 @@ GP_Backend *GP_BackendX11Init(const char *display, int x, int y, if (create_ximage(backend, w, h)) goto err1; - XFlush(x11->dpy); + XFlush(win->dpy); - x11->resized_flag = 0; + win->resized_flag = 0; backend->name = "X11"; backend->Flip = x11_flip; @@ -863,19 +592,20 @@ GP_Backend *GP_BackendX11Init(const char *display, int x, int y, backend->Wait = x11_wait; backend->SetAttributes = x11_set_attributes; backend->ResizeAck = x11_resize_ack; - backend->fd = XConnectionNumber(x11->dpy); + backend->fd = XConnectionNumber(win->dpy); return backend; err1: - XCloseDisplay(x11->dpy); -err0: + x11_close(); free(backend); return NULL; } void GP_BackendX11RequestFullscreen(GP_Backend *self, int mode) { - request_fullscreen(self, mode); + struct x11_win *win = GP_BACKEND_PRIV(self); + + x11_win_fullscreen(win, mode); } #else diff --git a/libs/backends/GP_X11_Conn.h b/libs/backends/GP_X11_Conn.h new file mode 100644 index 0000000..f8bf3bf --- /dev/null +++ b/libs/backends/GP_X11_Conn.h @@ -0,0 +1,79 @@ +/***************************************************************************** + * This file is part of gfxprim library. * + * * + * Gfxprim is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * Gfxprim is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with gfxprim; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> * + * * + *****************************************************************************/ + +/* + * X11 connection, singleton. + */ +struct x11_conn { + Display *dpy; + + /* window reference counter */ + unsigned int ref_cnt; +}; + +static struct x11_conn x11_conn = { + .dpy = NULL, + .ref_cnt = 0, +}; + +static unsigned int x11_open(const char *display) +{ + if (x11_conn.ref_cnt != 0) + return ++x11_conn.ref_cnt; + + GP_DEBUG(1, "Opening X11 display '%s'", display); + + if (!XInitThreads()) { + GP_DEBUG(2, "XInitThreads failed"); + return 0; + } + + x11_conn.dpy = XOpenDisplay(display); + + if (x11_conn.dpy == NULL) { + GP_WARN("Failed to initialize X11 display"); + return 0; + } + + /* Initialized key translation table */ + GP_InputDriverX11Init(x11_conn.dpy); + + return ++x11_conn.ref_cnt; +} + +static void x11_close(void) +{ + /* Ignore close requests if connection is closed */ + if (x11_conn.ref_cnt == 0) + return; + + if (--x11_conn.ref_cnt != 0) + return; + + GP_DEBUG(1, "Closing X11 display"); + + XLockDisplay(x11_conn.dpy); + + /* I wonder if this is right sequence... */ + //XUnlockDisplay(x11_conn.dpy); + XCloseDisplay(x11_conn.dpy); +} diff --git a/libs/backends/GP_X11_Win.h b/libs/backends/GP_X11_Win.h new file mode 100644 index 0000000..759ec73 --- /dev/null +++ b/libs/backends/GP_X11_Win.h @@ -0,0 +1,404 @@ +/***************************************************************************** + * This file is part of gfxprim library. * + * * + * Gfxprim is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * Gfxprim is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with gfxprim; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301 USA * + * * + * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> * + * * + *****************************************************************************/ + +/* + * X11 window. + */ +struct x11_win { + /* X11 Display */ + Display *dpy; + /* X11 Screen */ + int scr; + /* X11 Screen depth */ + int scr_depth; + /* X11 Visual */ + Visual *vis; + /* X11 Window */ + Window win; + + /* Image info SHM or XImage */ + XImage *img; + +#ifdef HAVE_X_SHM + XShmSegmentInfo shminfo; +#endif /* HAVE_X_SHM */ + + GP_Context context; + + /* Window list pointers */ + struct x11_win *prev; + struct x11_win *next; + + /* Flags */ + int resized_flag:1; + int shm_flag:1; + + /* used to store width and height from ConfigureNotify event */ + unsigned int new_w; + unsigned int new_h; +}; + +static struct x11_win *win_list = NULL; + +static void win_list_add(struct x11_win *win) +{ + win->next = win_list; + win->prev = NULL; + win_list = win; +} + +static void win_list_rem(struct x11_win *win) +{ + if (win->prev) + win->prev->next = win->next; + + if (win->next) + win->next->prev = win->prev; + + if (win == win_list) + win_list = win->next; +} + +struct x11_win *win_list_lookup(Window win) +{ + struct x11_win *i; + + for (i = win_list; i != NULL; i = i->next) { + if (i->win == win) + return i; + } + + return NULL; +} + +#ifndef _NET_WM_STATE_ADD +# define _NET_WM_STATE_ADD 1 +#endif /* _NET_WM_STATE_ADD */ + +#ifndef _NET_WM_STATE_REMOVE +# define _NET_WM_STATE_REMOVE 0 +#endif /* _NET_WM_STATE_REMOVE */ + +/* Send NETWM message, most modern Window Managers should understand */ +static void x11_win_fullscreen(struct x11_win *win, int mode) +{ + if (mode < 0 || mode > 2) { + GP_WARN("Invalid fullscreen mode = %u", mode); + return; + } + + GP_DEBUG(2, "Requesting fullscreen mode = %u", mode); + + Atom wm_state, fullscreen; + + wm_state = XInternAtom(win->dpy, "_NET_WM_STATE", True); + fullscreen = XInternAtom(win->dpy, "_NET_WM_STATE_FULLSCREEN", True); + + if (wm_state == None || fullscreen == None) { + GP_WARN("Failed to create _NET_WM_* atoms"); + return; + } + + XEvent ev; + + memset(&ev, 0, sizeof(ev)); + + ev.type = ClientMessage; + ev.xclient.window = win->win; + ev.xclient.message_type = wm_state; + ev.xclient.format = 32; + ev.xclient.data.l[0] = mode; + ev.xclient.data.l[1] = fullscreen; + ev.xclient.data.l[2] = 0; + ev.xclient.data.l[3] = 1; + + if (!XSendEvent(win->dpy, XDefaultRootWindow(win->dpy), + False, SubstructureNotifyMask, &ev)) { + GP_WARN("Failed to send _NET_WM_STATE_FULLSCREEN event"); + return; + } + + XFlush(win->dpy); +} + +/* Window request structure */ +struct x11_wreq { + struct x11_win *win; + + /* X11 display */ + const char *display; + + /* geometry */ + int x; + int y; + unsigned int w; + unsigned int h; + + const char *caption; + + unsigned int flags; +}; + +static void x11_get_screen_size(struct x11_wreq *wreq) +{ + wreq->w = DisplayWidth(wreq->win->dpy, wreq->win->scr); + wreq->h = DisplayHeight(wreq->win->dpy, wreq->win->scr); +} + +static int x11_win_open(struct x11_wreq *wreq) +{ + XSetWindowAttributes attrs; + unsigned long attr_mask = 0; + struct x11_win *win; + Screen *scr_ptr; + + /* Initialize connection/increase ref count */ + if (!x11_open(wreq->display)) + return 1; + + win = wreq->win; + + /* Copy display */ + win->dpy = x11_conn.dpy; + + /* Get visual and screen depth */ + win->scr = DefaultScreen(win->dpy); + win->vis = DefaultVisual(win->dpy, win->scr); + scr_ptr = DefaultScreenOfDisplay(win->dpy); + win->scr_depth = DefaultDepthOfScreen(scr_ptr); + + GP_DEBUG(2, "Have Visual id %i, depth %u", (int)win->vis->visualid, win->scr_depth); + + /* Set event mask */ + attrs.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask | + KeyReleaseMask | PointerMotionMask; + attr_mask |= CWEventMask; + + /* + * If root window was selected, resize w and h and set win->win to root + * window. + */ + if (wreq->flags & GP_X11_USE_ROOT_WIN) { + + win->win = DefaultRootWindow(win->dpy); + + x11_get_screen_size(wreq); + + GP_DEBUG(2, "Using root window, owerriding size to %ux%u", + wreq->w, wreq->h); + + win_list_add(win); + + XChangeWindowAttributes(win->dpy, win->win, attr_mask, &attrs); + + return 0; + } + + /* + * For some reason reading mouse button clicks on root win are not + * allowed... + */ + attrs.event_mask |= ButtonPressMask | ButtonReleaseMask; + + /* + * Create undecoreated root window on background + */ + if (wreq->flags & GP_X11_CREATE_ROOT_WIN) { + Atom xa; + + x11_get_screen_size(wreq); + + GP_DEBUG(2, "Creating a window above root, owerriding size to %ux%u", + wreq->w, wreq->h); + + win->win = XCreateWindow(win->dpy, DefaultRootWindow(win->dpy), + 0, 0, wreq->w, wreq->h, 0, CopyFromParent, + InputOutput, CopyFromParent, attr_mask, &attrs); + + /* Set empty WM_PROTOCOLS */ + GP_DEBUG(2, "Setting empty MW_PROTOCOLS"); + XSetWMProtocols(win->dpy, win->win, NULL, 0); + + /* Set window type to desktop */ + xa = XInternAtom(win->dpy, "_NET_WM_WINDOW_TYPE", False); + + if (xa != None) { + GP_DEBUG(2, "Setting Atom _NET_WM_WINDOW_TYPE to _NET_WM_WINDOW_TYPE_DESKTOP"); + + Atom xa_prop = XInternAtom(win->dpy, "_NET_WM_WINDOW_TYPE_DESKTOP", False); + + XChangeProperty(win->dpy, win->win, xa, XA_ATOM, 32, + PropModeReplace, (unsigned char *) &xa_prop, 1); + } + + /* Turn off window decoration */ + xa = XInternAtom(win->dpy, "_MOTIF_WM_HINTS", False); + + if (xa != None) { + GP_DEBUG(2, "Setting Atom _MOTIF_WM_HINTS to 2, 0, 0, 0, 0"); + + long prop[5] = {2, 0, 0, 0, 0}; + + XChangeProperty(win->dpy, win->win, xa, xa, 32, + PropModeReplace, (unsigned char *) prop, 5); + } + + /* Set below other windows */ + xa = XInternAtom(win->dpy, "_WIN_LAYER", False); + + if (xa != None) { + GP_DEBUG(2, "Setting Atom _WIN_LAYER to 6"); + + long prop = 6; + + XChangeProperty(win->dpy, win->win, xa, XA_CARDINAL, 32, + PropModeAppend, (unsigned char *) &prop, 1); + } + + xa = XInternAtom(win->dpy, "_NET_WM_STATE", False); + + if (xa != None) { + GP_DEBUG(2, "Setting Atom _NET_WM_STATE to _NET_WM_STATE_BELOW"); + + Atom xa_prop = XInternAtom(win->dpy, "_NET_WM_STATE_BELOW", False); + + XChangeProperty(win->dpy, win->win, xa, XA_ATOM, 32, + PropModeAppend, (unsigned char *) &xa_prop, 1); + } + + /* Set sticky */ + xa = XInternAtom(win->dpy, "_NET_WM_DESKTOP", False); + + if (xa != None) { + GP_DEBUG(2, "Setting Atom _NET_WM_DESKTOP to 0xffffffff"); + + CARD32 xa_prop = 0xffffffff; + + XChangeProperty(win->dpy, win->win, xa, XA_CARDINAL, 32, + PropModeAppend, (unsigned char *) &xa_prop, 1); + } + + xa = XInternAtom(win->dpy, "_NET_WM_STATE", False); + + if (xa != None) { + GP_DEBUG(2, "Appending to Atom _NET_WM_STATE atom _NET_WM_STATE_STICKY"); + + Atom xa_prop = XInternAtom(win->dpy, "_NET_WM_STATE_STICKY", False); + + XChangeProperty(win->dpy, win->win, xa, XA_ATOM, 32, + PropModeAppend, (unsigned char *) &xa_prop, 1); + } + + /* Skip taskbar */ + xa = XInternAtom(win->dpy, "_NET_WM_STATE", False); + + if (xa != None) { + GP_DEBUG(2, "Appending to Atom _NET_WM_STATE atom _NET_STATE_SKIP_TASKBAR"); + + Atom xa_prop = XInternAtom(win->dpy, "_NET_WM_STATE_SKIP_TASKBAR", False); + + XChangeProperty(win->dpy, win->win, xa, XA_ATOM, 32, + PropModeAppend, (unsigned char *) &xa_prop, 1); + } + + /* Skip pager */ + xa = XInternAtom(win->dpy, "_NET_WM_STATE", False); + + if (xa != None) { + GP_DEBUG(2, "Appending to Atom _NET_WM_STATE atom _NET_STATE_SKIP_PAGER"); + + Atom xa_prop = XInternAtom(win->dpy, "_NET_WM_STATE_SKIP_PAGER", False); + + XChangeProperty(win->dpy, win->win, xa, XA_ATOM, 32, + PropModeAppend, (unsigned char *) &xa_prop, 1); + } + + /* Set 100% opacity */ + xa = XInternAtom(win->dpy, "_NET_WM_WINDOW_OPACITY", False); + + if (xa != None) { + GP_DEBUG(2, "Setting Atom _NET_WM_WINDOW_OPACITY to 0xffffffff"); + + long prop = 0xffffffff; + + XChangeProperty(win->dpy, win->win, xa, XA_CARDINAL, 32, + PropModeAppend, (unsigned char *) &prop, 1); + } + + win_list_add(win); + + /* Show window */ + XMapWindow(win->dpy, win->win); + return 0; + } + + GP_DEBUG(2, "Opening window '%s' %ix%i-%ux%u", + wreq->caption, wreq->x, wreq->y, wreq->w, wreq->h); + + win->win = XCreateWindow(win->dpy, DefaultRootWindow(win->dpy), + wreq->x, wreq->y, wreq->w, wreq->h, 0, + CopyFromParent, InputOutput, CopyFromParent, + attr_mask, &attrs); + + /* Set window caption */ + XmbSetWMProperties(win->dpy, win->win, wreq->caption, wreq->caption, + NULL, 0, NULL, NULL, NULL); + + /* Make the window close button send event */ + Atom xa = XInternAtom(win->dpy, "WM_DELETE_WINDOW", True); + + if (xa != None) { + GP_DEBUG(2, "Setting WM_DELETE_WINDOW Atom to True"); + + XSetWMProtocols(win->dpy, win->win, &xa, 1); + } else { + GP_DEBUG(2, "Failed to set WM_DELETE_WINDOW Atom to True"); + } + + win_list_add(win); + + /* Show window */ + XMapWindow(win->dpy, win->win); + + return 0; +} + +void x11_win_close(struct x11_win *win) +{ + XLockDisplay(win->dpy); + + win_list_rem(win); + +/* + if (x11->shm_flag) + destroy_shm_ximage(self); + else + destroy_ximage(self); +*/ + + XDestroyWindow(win->dpy, win->win); + + XUnlockDisplay(win->dpy); + + /* Close connection/Decrease ref count */ + x11_close(); +}
http://repo.or.cz/w/gfxprim.git/commit/1514e22782408ebbad3db2b9b4f37082f5e7…
commit 1514e22782408ebbad3db2b9b4f37082f5e7e8f5 Author: Cyril Hrubis <metan(a)ucw.cz> Date: Fri Mar 1 13:42:21 2013 +0100 core: GP_Common.h: Add GP_CONTAINER_OF() diff --git a/include/core/GP_Common.h b/include/core/GP_Common.h index 8718054..5a779c0 100644 --- a/include/core/GP_Common.h +++ b/include/core/GP_Common.h @@ -78,6 +78,9 @@ #define GP_ARRAY_SIZE(array) (sizeof(array) / sizeof(*array)) +#define GP_CONTAINER_OF(ptr, structure, member) + ((structure *)((char *)(ptr) - offsetof(structure, member))) + #endif /* __cplusplus */ /*
http://repo.or.cz/w/gfxprim.git/commit/19ad346473c404690363482eb05aba63474e…
commit 19ad346473c404690363482eb05aba63474eeed5 Author: Cyril Hrubis <metan(a)ucw.cz> Date: Fri Mar 1 11:25:32 2013 +0100 libs: backends: Fixes. * Fix off-by-one in GP_BackendUpdateRectXYWH() * Allow for NULL UpdateRect and Flip - fix backends accordingly diff --git a/include/backends/GP_Backend.h b/include/backends/GP_Backend.h index f4db9e4..c1b89d6 100644 --- a/include/backends/GP_Backend.h +++ b/include/backends/GP_Backend.h @@ -145,10 +145,7 @@ typedef struct GP_Backend { /* * Calls backend->Flip(). */ -static inline void GP_BackendFlip(GP_Backend *backend) -{ - backend->Flip(backend); -} +void GP_BackendFlip(GP_Backend *backend); /* * Calls backend->UpdateRect(). @@ -168,7 +165,7 @@ static inline void GP_BackendUpdateRectXYWH(GP_Backend *backend, GP_Coord x, GP_Coord y, GP_Size w, GP_Size h) { - GP_BackendUpdateRectXYXY(backend, x, y, x + w, y + h); + GP_BackendUpdateRectXYXY(backend, x, y, x + w - 1, y + h - 1); } /* diff --git a/libs/backends/GP_Backend.c b/libs/backends/GP_Backend.c index 6839187..87959e3 100644 --- a/libs/backends/GP_Backend.c +++ b/libs/backends/GP_Backend.c @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * - * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> * + * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> * * * *****************************************************************************/ @@ -26,10 +26,19 @@ #include "backends/GP_Backend.h" +void GP_BackendFlip(GP_Backend *backend) +{ + if (backend->Flip != NULL) + backend->Flip(backend); +} + void GP_BackendUpdateRectXYXY(GP_Backend *backend, GP_Coord x0, GP_Coord y0, GP_Coord x1, GP_Coord y1) { + if (backend->UpdateRect == NULL) + return; + GP_TRANSFORM_POINT(backend->context, x0, y0); GP_TRANSFORM_POINT(backend->context, x1, y1); diff --git a/libs/backends/GP_LinuxFB.c b/libs/backends/GP_LinuxFB.c index 43197d6..38d9ae4 100644 --- a/libs/backends/GP_LinuxFB.c +++ b/libs/backends/GP_LinuxFB.c @@ -163,20 +163,6 @@ static int allocate_console(struct fb_priv *fb, int flag) /* Backend API callbacks */ -static void fb_flip_noop(GP_Backend *self __attribute__((unused))) -{ - -} - -static void fb_update_rect_noop(GP_Backend *self __attribute__((unused)), - GP_Coord x1 __attribute__((unused)), - GP_Coord y1 __attribute__((unused)), - GP_Coord x2 __attribute__((unused)), - GP_Coord y2 __attribute__((unused))) -{ - -} - static void fb_poll(GP_Backend *self) { struct fb_priv *fb = GP_BACKEND_PRIV(self); @@ -320,8 +306,8 @@ GP_Backend *GP_BackendLinuxFBInit(const char *path, int flag) /* update API */ backend->name = "Linux FB"; backend->context = &fb->context; - backend->Flip = fb_flip_noop; - backend->UpdateRect = fb_update_rect_noop; + backend->Flip = NULL; + backend->UpdateRect = NULL; backend->Exit = fb_exit; backend->SetAttributes = NULL; backend->ResizeAck = NULL; ----------------------------------------------------------------------- Summary of changes: include/backends/GP_Backend.h | 7 +- include/core/GP_Common.h | 3 + libs/backends/GP_Backend.c | 11 +- libs/backends/GP_LinuxFB.c | 18 +- libs/backends/GP_X11.c | 612 ++++++-------------- .../bogoman_debug.c => libs/backends/GP_X11_Conn.h | 66 ++- libs/backends/GP_X11_Win.h | 404 +++++++++++++ 7 files changed, 639 insertions(+), 482 deletions(-) copy demos/bogoman/bogoman_debug.c => libs/backends/GP_X11_Conn.h (62%) create mode 100644 libs/backends/GP_X11_Win.h repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive no reply. -- gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
0
0
← Newer
1
2
3
4
Older →
Jump to page:
1
2
3
4
Results per page:
10
25
50
100
200