<br><br><div class="gmail_quote">On Tue, Feb 14, 2012 at 12:53 AM, Pekka Paalanen <span dir="ltr">&lt;<a href="mailto:ppaalanen@gmail.com">ppaalanen@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On Mon, 13 Feb 2012 15:26:16 -0700<br>
Scott Moreau &lt;<a href="mailto:oreaus@gmail.com">oreaus@gmail.com</a>&gt; wrote:<br>
<br>
&gt; Implements a modelview matrix for transforms to simulate camera movement.<br>
&gt; Ideally, we would want to use &lt;modifier&gt;+Scroll but that will have to<br>
&gt; wait for axis events to come. For now we double check for the binding<br>
&gt; in notify_key as a quick-n-dirty hack to avoid sending unwanted events.<br>
&gt; Zoom in/out with Super+Up/Down. Zoom area follows mouse pointer.<br>
&gt;<br>
&gt; ---<br>
&gt;  src/compositor.c |   43 +++++++++++++++++++++++++++++++++++++++++--<br>
&gt;  src/compositor.h |   15 +++++++++++++++<br>
&gt;  src/shell.c      |   43 +++++++++++++++++++++++++++++++++++++++++++<br>
&gt;  3 files changed, 99 insertions(+), 2 deletions(-)<br>
&gt;<br>
&gt; diff --git a/src/compositor.c b/src/compositor.c<br>
&gt; index ab90ded..de4f9f4 100644<br>
&gt; --- a/src/compositor.c<br>
&gt; +++ b/src/compositor.c<br>
&gt; @@ -307,6 +307,21 @@ surface_compute_bbox(struct weston_surface *surface, int32_t sx, int32_t sy,<br>
&gt;                                 ceilf(max_x) - int_x, ceilf(max_y) - int_y);<br>
&gt;  }<br>
&gt;<br>
&gt; +WL_EXPORT void<br>
&gt; +weston_update_zoom(struct weston_output *output, int x, int y)<br>
<br>
</div>We already have the name &quot;zoom&quot; in util.c for per-surface scaling<br>
effect. Is there a danger to confuse these?<br></blockquote><div> </div><div>Probably. Which is why I think it may be time to start thinking about how to separate functionalities better.<br></div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<br>
Following the naming conventions I were taught here, this function<br>
should at least be called weston_output_update_zoom(), since it is a<br>
weston_output method.<br></blockquote><div> </div><div>Noted.<br></div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div class="im"><br>
&gt; +{<br>
&gt; +     if (output-&gt;zoom.level &lt;= 0.0)<br>
&gt; +             return;<br>
&gt; +<br>
&gt; +     GLfloat ratio = (1 / output-&gt;zoom.level) - 1;<br>
&gt; +<br>
&gt; +     output-&gt;zoom.trans_x = (output-&gt;mm_width * ratio) *<br>
&gt; +                                                             ((float)x / output-&gt;mm_width);<br>
&gt; +     output-&gt;zoom.trans_y = (output-&gt;mm_height * ratio) *<br>
&gt; +                                                             ((float)y  / output-&gt;mm_height);<br>
<br>
</div>That indentation looks funny.<br></blockquote><div> </div><div>Maybe it can be output-&gt;zoom.trans_x =\n ...  </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<div class="im"><br>
&gt; +     weston_output_damage(output);<br>
&gt; +}<br>
&gt; +<br>
&gt;  static void<br>
&gt;  weston_surface_update_transform_disable(struct weston_surface *surface)<br>
&gt;  {<br>
&gt; @@ -774,7 +789,16 @@ weston_surface_draw(struct weston_surface *es, struct weston_output *output)<br>
&gt;               glUseProgram(es-&gt;shader-&gt;program);<br>
&gt;               ec-&gt;current_shader = es-&gt;shader;<br>
&gt;       }<br>
&gt; +     glUniform1f(es-&gt;shader-&gt;zoom_uniform, output-&gt;zoom.level);<br>
&gt;<br>
&gt; +     struct weston_matrix modelview_inverse;<br>
&gt; +     weston_matrix_init(&amp;output-&gt;modelview_matrix);<br>
&gt; +     weston_matrix_translate(&amp;output-&gt;modelview_matrix,<br>
&gt; +                                                                                     output-&gt;zoom.trans_x,<br>
&gt; +                                                                                     output-&gt;zoom.trans_y, 0);<br>
&gt; +     weston_matrix_invert(&amp;modelview_inverse, &amp;output-&gt;modelview_matrix);<br>
<br>
</div>Couldn&#39;t these computations be moved to some per-output function?<br>
Repeating the same computation per surface is unnecessary.<br></blockquote><div> </div><div>Didn&#39;t notice that, thanks.<br></div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<br>
Also, do you really need to call weston_matrix_invert() for inverting a<br>
pure translation matrix? ;-)<br></blockquote><div><br>For simple translation, it could be made much more compact but I wanted to simulate a camera matrix.<br></div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<div class="im"><br>
&gt; +     glUniformMatrix4fv(es-&gt;shader-&gt;modelview_uniform,<br>
&gt; +                        1, GL_FALSE, modelview_inverse.d);<br>
<br>
</div>The inverse matrix is going into modelview uniform, one of them needs a<br>
corretion in the name.<br>
<div class="im"><br>
&gt;       glUniformMatrix4fv(es-&gt;shader-&gt;proj_uniform,<br>
&gt;                          1, GL_FALSE, output-&gt;matrix.d);<br>
&gt;       glUniform1i(es-&gt;shader-&gt;tex_uniform, 0);<br>
&gt; @@ -1349,6 +1373,8 @@ notify_motion(struct wl_input_device *device, uint32_t time, int x, int y)<br>
&gt;                       max_x = output-&gt;x + output-&gt;current-&gt;width;<br>
&gt;               if (output-&gt;y + output-&gt;current-&gt;height &gt; max_y)<br>
&gt;                       max_y = output-&gt;y + output-&gt;current-&gt;height;<br>
&gt; +             if (output-&gt;zoom.active)<br>
&gt; +                     weston_update_zoom(output, x, y);<br>
&gt;       }<br>
&gt;<br>
&gt;       if (!x_valid) {<br>
&gt; @@ -1466,6 +1492,9 @@ notify_key(struct wl_input_device *device,<br>
&gt;<br>
&gt;       weston_compositor_run_binding(compositor, wd, time, key, 0, state);<br>
&gt;<br>
&gt; +     if (wd-&gt;modifier_state &amp; MODIFIER_SUPER &amp;&amp; (key == KEY_UP || key == KEY_DOWN))<br>
&gt; +             return;<br>
<br>
</div>This does look a bit suspicious. So the reason for this is, that if we<br>
have keyboard-only bindings, using them will send the key events also to<br>
the client?<br></blockquote><div> </div><div>Yes. <br></div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Hm, maybe we would need a keyboard grab for the time the binding is<br>
held down, to easily avoid sending both the key press and release, and<br>
getting clients out of sync. Waiting for proper keyboard grabs to be<br>
implemented...<br></blockquote><div><br>Yes, I&#39;ve been looking into how to do proper keyboard grabs.<br></div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<div><div class="h5"><br>
&gt; +<br>
&gt;       update_modifier_state(wd, key, state);<br>
&gt;       end = device-&gt;keys.data + device-&gt;keys.size;<br>
&gt;       for (k = device-&gt;keys.data; k &lt; end; k++) {<br>
&gt; @@ -1815,12 +1844,14 @@ bind_output(struct wl_client *client,<br>
&gt;<br>
&gt;  static const char vertex_shader[] =<br>
&gt;       &quot;uniform mat4 proj;\n&quot;<br>
&gt; +     &quot;uniform mat4 modelview;\n&quot;<br>
&gt; +     &quot;uniform float zoom;\n&quot;<br>
&gt;       &quot;attribute vec2 position;\n&quot;<br>
&gt;       &quot;attribute vec2 texcoord;\n&quot;<br>
&gt;       &quot;varying vec2 v_texcoord;\n&quot;<br>
&gt;       &quot;void main()\n&quot;<br>
&gt;       &quot;{\n&quot;<br>
&gt; -     &quot;   gl_Position = proj * vec4(position, 0.0, 1.0);\n&quot;<br>
&gt; +     &quot;   gl_Position = proj * (modelview * vec4(position, 0.0, zoom));\n&quot;<br>
&gt;       &quot;   v_texcoord = texcoord;\n&quot;<br>
&gt;       &quot;}\n&quot;;<br>
&gt;<br>
&gt; @@ -1894,6 +1925,8 @@ weston_shader_init(struct weston_shader *shader,<br>
&gt;       }<br>
&gt;<br>
&gt;       shader-&gt;proj_uniform = glGetUniformLocation(shader-&gt;program, &quot;proj&quot;);<br>
&gt; +     shader-&gt;modelview_uniform = glGetUniformLocation(shader-&gt;program, &quot;modelview&quot;);<br>
&gt; +     shader-&gt;zoom_uniform = glGetUniformLocation(shader-&gt;program, &quot;zoom&quot;);<br>
&gt;       shader-&gt;tex_uniform = glGetUniformLocation(shader-&gt;program, &quot;tex&quot;);<br>
&gt;       shader-&gt;alpha_uniform = glGetUniformLocation(shader-&gt;program, &quot;alpha&quot;);<br>
&gt;       shader-&gt;color_uniform = glGetUniformLocation(shader-&gt;program, &quot;color&quot;);<br>
&gt; @@ -1950,6 +1983,12 @@ weston_output_init(struct weston_output *output, struct weston_compositor *c,<br>
&gt;       output-&gt;mm_width = width;<br>
&gt;       output-&gt;mm_height = height;<br>
&gt;<br>
&gt; +     output-&gt;zoom.active = 0;<br>
&gt; +     output-&gt;zoom.increment = 0.05;<br>
&gt; +     output-&gt;zoom.level = 1.0;<br>
&gt; +     output-&gt;zoom.trans_x = 0.0;<br>
&gt; +     output-&gt;zoom.trans_y = 0.0;<br>
<br>
</div></div>AFAICT, you are only using trans_x,trans_y for creating an equivalent<br>
translation matrix. You could store the translation matrix here instead<br>
and change the x,y elements.<br></blockquote><div><br>Yes, it certainly could be much simpler strictly for zoom. As you said on irc though, this could potentially be used for screen rotation and possibly other things. I wanted to take steps to show the function without obfuscating much, while trying to make it versatile.<br>
</div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div><div class="h5"><br>
&gt; +<br>
&gt;       output-&gt;flags = flags;<br>
&gt;       weston_output_move(output, x, y);<br>
&gt;<br>
&gt; diff --git a/src/compositor.h b/src/compositor.h<br>
&gt; index 966d3f4..0f5827e 100644<br>
&gt; --- a/src/compositor.h<br>
&gt; +++ b/src/compositor.h<br>
&gt; @@ -54,10 +54,19 @@ struct weston_border {<br>
&gt;       int32_t left, right, top, bottom;<br>
&gt;  };<br>
&gt;<br>
&gt; +struct weston_composite_zoom {<br>
&gt; +     int active;<br>
&gt; +     /* 1.0 is no zoom, 0.0 is 100% zoomed in */<br>
&gt; +     GLfloat level;<br>
&gt; +     float increment;<br>
&gt; +     int trans_x, trans_y;<br>
&gt; +};<br>
&gt; +<br>
&gt;  struct weston_output {<br>
&gt;       struct wl_list link;<br>
&gt;       struct weston_compositor *compositor;<br>
&gt;       struct weston_matrix matrix;<br>
&gt; +     struct weston_matrix modelview_matrix;<br>
&gt;       struct wl_list frame_callback_list;<br>
&gt;       int32_t x, y, mm_width, mm_height;<br>
&gt;       struct weston_border border;<br>
&gt; @@ -66,6 +75,7 @@ struct weston_output {<br>
&gt;       uint32_t flags;<br>
&gt;       int repaint_needed;<br>
&gt;       int repaint_scheduled;<br>
&gt; +     struct weston_composite_zoom zoom;<br>
&gt;<br>
&gt;       char *make, *model;<br>
&gt;       uint32_t subpixel;<br>
&gt; @@ -105,6 +115,8 @@ struct weston_shader {<br>
&gt;       GLuint program;<br>
&gt;       GLuint vertex_shader, fragment_shader;<br>
&gt;       GLint proj_uniform;<br>
&gt; +     GLint modelview_uniform;<br>
&gt; +     GLint zoom_uniform;<br>
&gt;       GLint tex_uniform;<br>
&gt;       GLint alpha_uniform;<br>
&gt;       GLint color_uniform;<br>
&gt; @@ -325,6 +337,9 @@ void<br>
&gt;  weston_surface_draw(struct weston_surface *es, struct weston_output *output);<br>
&gt;<br>
&gt;  void<br>
&gt; +weston_update_zoom(struct weston_output *output, int x, int y);<br>
&gt; +<br>
&gt; +void<br>
&gt;  notify_motion(struct wl_input_device *device,<br>
&gt;             uint32_t time, int x, int y);<br>
&gt;  void<br>
&gt; diff --git a/src/shell.c b/src/shell.c<br>
&gt; index 66c4f01..6b2ffc0 100644<br>
&gt; --- a/src/shell.c<br>
&gt; +++ b/src/shell.c<br>
&gt; @@ -964,6 +964,45 @@ resize_binding(struct wl_input_device *device, uint32_t time,<br>
&gt;  }<br>
&gt;<br>
&gt;  static void<br>
&gt; +zoom_in_binding(struct wl_input_device *device, uint32_t time,<br>
&gt; +            uint32_t key, uint32_t button, uint32_t state, void *data)<br>
&gt; +{<br>
&gt; +     struct weston_input_device *wd = (struct weston_input_device *) device;<br>
&gt; +     struct weston_compositor *compositor = wd-&gt;compositor;<br>
&gt; +     struct weston_output *output;<br>
&gt; +     output = container_of(compositor-&gt;output_list.next,<br>
&gt; +                     struct weston_output, link);<br>
<br>
</div></div>You always zoom only the first output? How about an output where the<br>
pointer is in, or lacking a pointer, the output of the surface which<br>
has the keyboard focus?<br></blockquote><div> </div><div>Ah, should fix that. Thanks.<br></div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>