[PATCH weston] shell: Implement wl_notification_daemon

2013-02-10 Thread Quentin Glidic
Implement the "bubbles list" style notifications.
Corner anchor, margin and order can be changed in the configuration.

Signed-off-by: Quentin Glidic 
---
 src/shell.c | 196 +---
 weston.ini  |   5 ++
 2 files changed, 193 insertions(+), 8 deletions(-)

diff --git a/src/shell.c b/src/shell.c
index 368fa5b..75857bd 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -41,6 +41,8 @@
 #define DEFAULT_NUM_WORKSPACES 1
 #define DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH 200
 
+#define DEFAULT_NOTIFICATIONS_MARGIN 20
+
 enum animation_type {
ANIMATION_NONE,
 
@@ -48,6 +50,25 @@ enum animation_type {
ANIMATION_FADE
 };
 
+enum edge_anchor {
+   EDGE_TOP= 1<<0,
+   EDGE_BOTTOM = 1<<1,
+   EDGE_LEFT   = 1<<2,
+   EDGE_RIGHT  = 1<<3
+};
+
+enum corner_anchor {
+   CORNER_TOP_RIGHT= EDGE_TOP | EDGE_RIGHT,
+   CORNER_TOP_LEFT = EDGE_TOP | EDGE_LEFT,
+   CORNER_BOTTOM_RIGHT = EDGE_BOTTOM | EDGE_RIGHT,
+   CORNER_BOTTOM_LEFT  = EDGE_BOTTOM | EDGE_LEFT,
+};
+
+enum notifications_order {
+   ORDER_NEWEST_FIRST,
+   ORDER_OLDEST_FIRST
+};
+
 struct focus_state {
struct weston_seat *seat;
struct workspace *ws;
@@ -79,6 +100,7 @@ struct desktop_shell {
struct wl_listener show_input_panel_listener;
struct wl_listener hide_input_panel_listener;
 
+   struct weston_layer notification_layer;
struct weston_layer fullscreen_layer;
struct weston_layer panel_layer;
struct weston_layer background_layer;
@@ -132,6 +154,14 @@ struct desktop_shell {
struct wl_list surfaces;
} input_panel;
 
+   struct {
+   enum corner_anchor corner;
+   enum notifications_order order;
+   int32_t margin;
+   struct weston_output *output;
+   struct wl_resource *binding;
+   } notification_daemon;
+
uint32_t binding_modifier;
enum animation_type win_animation_type;
 };
@@ -336,6 +366,43 @@ get_animation_type(char *animation)
return ANIMATION_NONE;
 }
 
+static enum corner_anchor
+get_corner_anchor(char *placement, enum corner_anchor default_anchor)
+{
+   if (placement == NULL)
+   return default_anchor;
+
+   if (strcmp("top-left", placement) == 0)
+   return CORNER_TOP_LEFT;
+   if (strcmp("top-right", placement) == 0)
+   return CORNER_TOP_RIGHT;
+   if (strcmp("bottom-right", placement) == 0)
+   return CORNER_BOTTOM_RIGHT;
+   if (strcmp("bottom-left", placement) == 0)
+   return CORNER_BOTTOM_LEFT;
+
+   return default_anchor;
+}
+
+static enum notifications_order
+get_notification_order(char *order)
+{
+   if (order == NULL)
+   return ORDER_NEWEST_FIRST;
+
+   if (strcmp("oldest-first", order) == 0)
+   return ORDER_OLDEST_FIRST;
+
+   return ORDER_NEWEST_FIRST;
+}
+
+static struct weston_output *
+get_default_output(struct weston_compositor *compositor)
+{
+   return container_of(compositor->output_list.next,
+   struct weston_output, link);
+}
+
 static void
 shell_configuration(struct desktop_shell *shell)
 {
@@ -345,6 +412,9 @@ shell_configuration(struct desktop_shell *shell)
unsigned int num_workspaces = DEFAULT_NUM_WORKSPACES;
char *modifier = NULL;
char *win_animation = NULL;
+   char *notifications_corner = NULL;
+   char *notifications_order = NULL;
+   int notifications_margin = DEFAULT_NOTIFICATIONS_MARGIN;
 
struct config_key shell_keys[] = {
{ "binding-modifier",   CONFIG_KEY_STRING, &modifier },
@@ -358,9 +428,16 @@ shell_configuration(struct desktop_shell *shell)
{ "duration",   CONFIG_KEY_INTEGER, &duration },
};
 
+   struct config_key notifications_keys[] = {
+   { "corner", CONFIG_KEY_STRING,  ¬ifications_corner },
+   { "order", CONFIG_KEY_STRING,  ¬ifications_order },
+   { "margin",CONFIG_KEY_INTEGER, ¬ifications_margin },
+   };
+
struct config_section cs[] = {
{ "shell", shell_keys, ARRAY_LENGTH(shell_keys), NULL },
{ "screensaver", saver_keys, ARRAY_LENGTH(saver_keys), NULL },
+   { "notifications", notifications_keys, 
ARRAY_LENGTH(notifications_keys), NULL },
};
 
config_file = config_file_path("weston.ini");
@@ -372,6 +449,13 @@ shell_configuration(struct desktop_shell *shell)
shell->binding_modifier = get_modifier(modifier);
shell->win_animation_type = get_animation_type(win_animation);
shell->workspaces.num = num_workspaces > 0 ? num_workspaces : 1;
+   shell->notification_daemon.corner = 
get_corner_anchor(notifications_corner, CORNER_TOP_RIGHT);
+   shell->notification_daemon.order = 
get_notification_order(notifications_order);
+   shell-

RE: How to create pixmap or pixmap surface in wayland?

2013-02-10 Thread Wang, Quanxian
Pq, thanks so much. It is very nice to get great suggestion.

> -Original Message-
> From: Pekka Paalanen [mailto:ppaala...@gmail.com]
> Sent: Friday, February 08, 2013 6:34 PM
> To: Wang, Quanxian
> Cc: wayland-devel@lists.freedesktop.org
> Subject: Re: How to create pixmap or pixmap surface in wayland?
> 
> On Fri, 8 Feb 2013 02:16:39 +
> "Wang, Quanxian"  wrote:
> 
> > Sorry Pq. I confused you so much.
> >
> > Just one requirement not related with architecture. You can imagine write a
> simple program for example glxgears. No compositor manager, no architecture,
> no window manager. Just has x server, or compositor server(weston).
> >
> > I want to call eglCreatePixmapSurface to create a pixmap surface. If the
> xserver is backend, I need to connect with X server and create a pixmap and
> then create the pixmap surface using egl interface provided by mesa.
> > If the backend is weston compositor, I need to connect with weston
> compositor and using egl to create the pixmap and its surface. Before that the
> context is created. Just like the code in simple-egl.c of weston.
> > ===
> > -- function init_egl()
> > ...
> > display->egl.dpy = eglGetDisplay(display->display);
> > assert(display->egl.dpy);
> >
> > ret = eglInitialize(display->egl.dpy, &major, &minor);
> > assert(ret == EGL_TRUE);
> > ret = eglBindAPI(EGL_OPENGL_ES_API);
> > assert(ret == EGL_TRUE);
> >
> > ret = eglChooseConfig(display->egl.dpy, config_attribs,
> >   &display->egl.conf, 1, &n);
> > assert(ret && n == 1);
> >
> > display->egl.ctx = eglCreateContext(display->egl.dpy,
> > display->egl.conf,
> > EGL_NO_CONTEXT,
> context_attribs);
> > assert(display->egl.ctx);
> > ...
> > ===
> >
> > The current issue is pixmap of wayland is not supported in wayland protocol
> and mesa. I could not do this like X.
> >
> > Sorry my title and description make you confused, I change it to 'how to
> create pixmap or pixmap surface in wayland'.
> 
> Alright, thanks. Let's see.
> 
> First you need an EGL display. I would recommend to ask EFL or whatever is
> creating the "main" Wayland connection for its struct wl_display pointer, and
> pass that to eglGetDisplay(). This way you are not creating a new Wayland
> connection, and your program will behave as a single Wayland client in the
> compositor's perspective. This will let you take advantage of sub-surfaces[1] 
> in
> the future, once we get them in a usable form.
> 
> I also assume there is no way to create an EGLDisplay without any window
> system connection. At least on a standard Linux system, I think you need to be
> authenticated in DRM, so ignoring the window system would not work.
> 
> Next you have to choose how get a render target. There are couple of
> options:
> A. use the surfaceless EGL extension, and use a FBO for the rendering B. 
> create
> a dummy wl_surface, use it as the EGLSurface, and use FBO for
>real rendering
> C. create a wl_subsurface, and just use it for rendering
> 
> In case A, depending on your EGL stack, you might not have the extension
> available. I think Mesa always has it, but others might not.
> 
> Both A and B require you to use FBOs. That may or may not be a problem,
> depending on how and what kind of an API you offer to e.g. webGL. If the
> webGL code does glBindFramebuffer(GL_FRAMEBUFFER, 0), can you intercept
> it and change it to activate your FBO?
> 
> The immediate downside of case C is that its not available just yet.
> However, it would have considerable benefits:
> - You get a real EGLSurface for rendering, no need for tricks with FBOs.
> - No need to read back the rendering in the client, i.e. no
>   glReadPixels or copying into the browser window image at client
>   side. The rendering will go directly to the compositor into the
>   sub-surface, and the compositor will combine it with the rest of your
>   browser graphics.
> - The sub-surface can use a different renderer than the main surface,
>   i.e. the sub-surface can be draw with GL and main surface in
>   software, or vice versa.
> - Even the compositor may avoid copying the sub-surface contents, as
>   the sub-surface might be assigned to a hardware overlay, that will
>   scan it out as is, without compositing.
> 
> With cases A and B, that is with FBO, you will render into a temporary buffer,
> and then you probably want to use that rendered image for something, most
> likely as a part of a web page your browser is rendering. So you either use
> glReadPixels (very slow) and draw the web page in software, or you can use the
> FBO render target as a texture, and draw the browser window in GL. After that,
> you send the image to the compositor for display.
> 
> As you see, the context and architecture information is quite essential to 
> get a
> useful reply. You don't only want to create