[c8cf261] | 1 | /*
|
---|
| 2 | * Copyright (c) 2019 Jiri Svoboda
|
---|
| 3 | * All rights reserved.
|
---|
| 4 | *
|
---|
| 5 | * Redistribution and use in source and binary forms, with or without
|
---|
| 6 | * modification, are permitted provided that the following conditions
|
---|
| 7 | * are met:
|
---|
| 8 | *
|
---|
| 9 | * - Redistributions of source code must retain the above copyright
|
---|
| 10 | * notice, this list of conditions and the following disclaimer.
|
---|
| 11 | * - Redistributions in binary form must reproduce the above copyright
|
---|
| 12 | * notice, this list of conditions and the following disclaimer in the
|
---|
| 13 | * documentation and/or other materials provided with the distribution.
|
---|
| 14 | * - The name of the author may not be used to endorse or promote products
|
---|
| 15 | * derived from this software without specific prior written permission.
|
---|
| 16 | *
|
---|
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
---|
| 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
---|
| 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
---|
| 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
---|
| 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
---|
| 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
---|
| 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
---|
| 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
---|
| 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
---|
| 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
---|
| 27 | */
|
---|
| 28 |
|
---|
| 29 | /** @addtogroup display
|
---|
| 30 | * @{
|
---|
| 31 | */
|
---|
| 32 | /**
|
---|
| 33 | * @file GFX window backend
|
---|
| 34 | *
|
---|
| 35 | * This implements a graphics context over display server window.
|
---|
| 36 | */
|
---|
| 37 |
|
---|
[0008c0f] | 38 | #include <gfx/bitmap.h>
|
---|
[c8cf261] | 39 | #include <gfx/color.h>
|
---|
[0008c0f] | 40 | #include <gfx/coord.h>
|
---|
[c8cf261] | 41 | #include <gfx/context.h>
|
---|
| 42 | #include <gfx/render.h>
|
---|
| 43 | #include <io/log.h>
|
---|
[946a666] | 44 | #include <io/pixelmap.h>
|
---|
[c8cf261] | 45 | #include <stdlib.h>
|
---|
[b3c185b6] | 46 | #include "client.h"
|
---|
[6af4b4f] | 47 | #include "display.h"
|
---|
| 48 | #include "window.h"
|
---|
[c8cf261] | 49 |
|
---|
[6af4b4f] | 50 | static errno_t ds_window_set_color(void *, gfx_color_t *);
|
---|
| 51 | static errno_t ds_window_fill_rect(void *, gfx_rect_t *);
|
---|
[0008c0f] | 52 | static errno_t ds_window_bitmap_create(void *, gfx_bitmap_params_t *,
|
---|
| 53 | gfx_bitmap_alloc_t *, void **);
|
---|
| 54 | static errno_t ds_window_bitmap_destroy(void *);
|
---|
| 55 | static errno_t ds_window_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
|
---|
| 56 | static errno_t ds_window_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
|
---|
[c8cf261] | 57 |
|
---|
[6af4b4f] | 58 | gfx_context_ops_t ds_window_ops = {
|
---|
| 59 | .set_color = ds_window_set_color,
|
---|
[0008c0f] | 60 | .fill_rect = ds_window_fill_rect,
|
---|
| 61 | .bitmap_create = ds_window_bitmap_create,
|
---|
| 62 | .bitmap_destroy = ds_window_bitmap_destroy,
|
---|
| 63 | .bitmap_render = ds_window_bitmap_render,
|
---|
| 64 | .bitmap_get_alloc = ds_window_bitmap_get_alloc
|
---|
[c8cf261] | 65 | };
|
---|
| 66 |
|
---|
| 67 | /** Set color on window GC.
|
---|
| 68 | *
|
---|
| 69 | * Set drawing color on window GC.
|
---|
| 70 | *
|
---|
| 71 | * @param arg Console GC
|
---|
| 72 | * @param color Color
|
---|
| 73 | *
|
---|
| 74 | * @return EOK on success or an error code
|
---|
| 75 | */
|
---|
[6af4b4f] | 76 | static errno_t ds_window_set_color(void *arg, gfx_color_t *color)
|
---|
[c8cf261] | 77 | {
|
---|
[6af4b4f] | 78 | ds_window_t *wnd = (ds_window_t *) arg;
|
---|
[946a666] | 79 | uint16_t r, g, b;
|
---|
[c8cf261] | 80 |
|
---|
[87a7cdb] | 81 | log_msg(LOG_DEFAULT, LVL_NOTE, "gc_set_color gc=%p",
|
---|
| 82 | ds_display_get_gc(wnd->display));
|
---|
[946a666] | 83 |
|
---|
| 84 | gfx_color_get_rgb_i16(color, &r, &g, &b);
|
---|
| 85 | wnd->color = PIXEL(0, r >> 8, g >> 8, b >> 8);
|
---|
| 86 |
|
---|
[87a7cdb] | 87 | return gfx_set_color(ds_display_get_gc(wnd->display), color);
|
---|
[c8cf261] | 88 | }
|
---|
| 89 |
|
---|
| 90 | /** Fill rectangle on window GC.
|
---|
| 91 | *
|
---|
[6af4b4f] | 92 | * @param arg Window GC
|
---|
[c8cf261] | 93 | * @param rect Rectangle
|
---|
| 94 | *
|
---|
| 95 | * @return EOK on success or an error code
|
---|
| 96 | */
|
---|
[6af4b4f] | 97 | static errno_t ds_window_fill_rect(void *arg, gfx_rect_t *rect)
|
---|
[c8cf261] | 98 | {
|
---|
[6af4b4f] | 99 | ds_window_t *wnd = (ds_window_t *) arg;
|
---|
[65160d7] | 100 | gfx_rect_t crect;
|
---|
[22faaf2] | 101 | gfx_rect_t drect;
|
---|
[946a666] | 102 | gfx_coord_t x, y;
|
---|
[c8cf261] | 103 |
|
---|
| 104 | log_msg(LOG_DEFAULT, LVL_NOTE, "gc_fill_rect");
|
---|
[946a666] | 105 |
|
---|
[65160d7] | 106 | gfx_rect_clip(rect, &wnd->rect, &crect);
|
---|
| 107 | gfx_rect_translate(&wnd->dpos, &crect, &drect);
|
---|
[946a666] | 108 |
|
---|
| 109 | /* Render a copy to the backbuffer */
|
---|
| 110 | for (y = crect.p0.y; y < crect.p1.y; y++) {
|
---|
| 111 | for (x = crect.p0.x; x < crect.p1.x; x++) {
|
---|
| 112 | pixelmap_put_pixel(&wnd->pixelmap, x - wnd->rect.p0.x,
|
---|
| 113 | y - wnd->rect.p0.y, wnd->color);
|
---|
| 114 | }
|
---|
| 115 | }
|
---|
| 116 |
|
---|
[87a7cdb] | 117 | return gfx_fill_rect(ds_display_get_gc(wnd->display), &drect);
|
---|
[c8cf261] | 118 | }
|
---|
| 119 |
|
---|
[946a666] | 120 | /** Create bitmap in window GC.
|
---|
[0008c0f] | 121 | *
|
---|
[946a666] | 122 | * @param arg Window GC
|
---|
[0008c0f] | 123 | * @param params Bitmap params
|
---|
| 124 | * @param alloc Bitmap allocation info or @c NULL
|
---|
| 125 | * @param rbm Place to store pointer to new bitmap
|
---|
| 126 | * @return EOK on success or an error code
|
---|
| 127 | */
|
---|
| 128 | errno_t ds_window_bitmap_create(void *arg, gfx_bitmap_params_t *params,
|
---|
| 129 | gfx_bitmap_alloc_t *alloc, void **rbm)
|
---|
| 130 | {
|
---|
| 131 | ds_window_t *wnd = (ds_window_t *) arg;
|
---|
| 132 | ds_window_bitmap_t *cbm = NULL;
|
---|
| 133 | errno_t rc;
|
---|
| 134 |
|
---|
| 135 | cbm = calloc(1, sizeof(ds_window_bitmap_t));
|
---|
| 136 | if (cbm == NULL)
|
---|
| 137 | return ENOMEM;
|
---|
| 138 |
|
---|
[87a7cdb] | 139 | rc = gfx_bitmap_create(ds_display_get_gc(wnd->display), params, alloc,
|
---|
[b3c185b6] | 140 | &cbm->bitmap);
|
---|
[0008c0f] | 141 | if (rc != EOK)
|
---|
| 142 | goto error;
|
---|
| 143 |
|
---|
| 144 | cbm->wnd = wnd;
|
---|
[65160d7] | 145 | cbm->rect = params->rect;
|
---|
[0008c0f] | 146 | *rbm = (void *)cbm;
|
---|
| 147 | return EOK;
|
---|
| 148 | error:
|
---|
| 149 | if (cbm != NULL)
|
---|
| 150 | free(cbm);
|
---|
| 151 | return rc;
|
---|
| 152 | }
|
---|
| 153 |
|
---|
[946a666] | 154 | /** Destroy bitmap in window GC.
|
---|
[0008c0f] | 155 | *
|
---|
| 156 | * @param bm Bitmap
|
---|
| 157 | * @return EOK on success or an error code
|
---|
| 158 | */
|
---|
| 159 | static errno_t ds_window_bitmap_destroy(void *bm)
|
---|
| 160 | {
|
---|
| 161 | ds_window_bitmap_t *cbm = (ds_window_bitmap_t *)bm;
|
---|
| 162 |
|
---|
| 163 | gfx_bitmap_destroy(cbm->bitmap);
|
---|
| 164 | free(cbm);
|
---|
| 165 | return EOK;
|
---|
| 166 | }
|
---|
| 167 |
|
---|
[946a666] | 168 | /** Render bitmap in window GC.
|
---|
[0008c0f] | 169 | *
|
---|
| 170 | * @param bm Bitmap
|
---|
| 171 | * @param srect0 Source rectangle or @c NULL
|
---|
| 172 | * @param offs0 Offset or @c NULL
|
---|
| 173 | * @return EOK on success or an error code
|
---|
| 174 | */
|
---|
| 175 | static errno_t ds_window_bitmap_render(void *bm, gfx_rect_t *srect0,
|
---|
| 176 | gfx_coord2_t *offs0)
|
---|
| 177 | {
|
---|
| 178 | ds_window_bitmap_t *cbm = (ds_window_bitmap_t *)bm;
|
---|
[22faaf2] | 179 | gfx_coord2_t doffs;
|
---|
[65160d7] | 180 | gfx_coord2_t offs;
|
---|
| 181 | gfx_rect_t srect;
|
---|
| 182 | gfx_rect_t swrect;
|
---|
| 183 | gfx_rect_t crect;
|
---|
[946a666] | 184 | gfx_coord_t x, y;
|
---|
| 185 | pixelmap_t pixelmap;
|
---|
| 186 | gfx_bitmap_alloc_t alloc;
|
---|
| 187 | pixel_t pixel;
|
---|
| 188 | errno_t rc;
|
---|
[65160d7] | 189 |
|
---|
| 190 | if (srect0 != NULL) {
|
---|
| 191 | /* Clip source rectangle to bitmap rectangle */
|
---|
| 192 | gfx_rect_clip(srect0, &cbm->rect, &srect);
|
---|
| 193 | } else {
|
---|
| 194 | /* Source is entire bitmap rectangle */
|
---|
| 195 | srect = cbm->rect;
|
---|
| 196 | }
|
---|
| 197 |
|
---|
| 198 | if (offs0 != NULL) {
|
---|
| 199 | offs = *offs0;
|
---|
| 200 | } else {
|
---|
| 201 | offs.x = 0;
|
---|
| 202 | offs.y = 0;
|
---|
| 203 | }
|
---|
| 204 |
|
---|
| 205 | /* Transform window rectangle back to bitmap coordinate system */
|
---|
| 206 | gfx_rect_rtranslate(&offs, &cbm->wnd->rect, &swrect);
|
---|
| 207 |
|
---|
| 208 | /* Clip so that transformed rectangle will be inside the window */
|
---|
| 209 | gfx_rect_clip(&srect, &swrect, &crect);
|
---|
| 210 |
|
---|
| 211 | /* Offset for rendering on screen = window pos + offs */
|
---|
| 212 | gfx_coord2_add(&cbm->wnd->dpos, &offs, &doffs);
|
---|
[22faaf2] | 213 |
|
---|
[946a666] | 214 | rc = gfx_bitmap_get_alloc(cbm->bitmap, &alloc);
|
---|
| 215 | if (rc != EOK)
|
---|
| 216 | return rc;
|
---|
| 217 |
|
---|
| 218 | pixelmap.width = cbm->rect.p1.x - cbm->rect.p0.x;
|
---|
| 219 | pixelmap.height = cbm->rect.p1.y - cbm->rect.p0.y;
|
---|
| 220 | pixelmap.data = alloc.pixels;
|
---|
| 221 |
|
---|
| 222 | /* Render a copy to the backbuffer */
|
---|
| 223 | for (y = crect.p0.y; y < crect.p1.y; y++) {
|
---|
| 224 | for (x = crect.p0.x; x < crect.p1.x; x++) {
|
---|
| 225 | pixel = pixelmap_get_pixel(&pixelmap,
|
---|
| 226 | x - cbm->rect.p0.x, y - cbm->rect.p0.y);
|
---|
| 227 | pixelmap_put_pixel(&cbm->wnd->pixelmap,
|
---|
| 228 | x + offs.x - cbm->rect.p0.x + cbm->wnd->rect.p0.x,
|
---|
| 229 | y + offs.y - cbm->rect.p0.y + cbm->wnd->rect.p0.y,
|
---|
| 230 | pixel);
|
---|
| 231 | }
|
---|
| 232 | }
|
---|
| 233 |
|
---|
| 234 | return gfx_bitmap_render(cbm->bitmap, &crect, &doffs);
|
---|
[0008c0f] | 235 | }
|
---|
| 236 |
|
---|
[946a666] | 237 | /** Get allocation info for bitmap in window GC.
|
---|
[0008c0f] | 238 | *
|
---|
| 239 | * @param bm Bitmap
|
---|
| 240 | * @param alloc Place to store allocation info
|
---|
| 241 | * @return EOK on success or an error code
|
---|
| 242 | */
|
---|
| 243 | static errno_t ds_window_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
|
---|
| 244 | {
|
---|
| 245 | ds_window_bitmap_t *cbm = (ds_window_bitmap_t *)bm;
|
---|
| 246 |
|
---|
| 247 | return gfx_bitmap_get_alloc(cbm->bitmap, alloc);
|
---|
| 248 | }
|
---|
| 249 |
|
---|
[6af4b4f] | 250 | /** Create window.
|
---|
[c8cf261] | 251 | *
|
---|
| 252 | * Create graphics context for rendering into a window.
|
---|
| 253 | *
|
---|
[8e9781f] | 254 | * @param client Client owning the window
|
---|
[3434233] | 255 | * @param params Window parameters
|
---|
[c8cf261] | 256 | * @param rgc Place to store pointer to new GC.
|
---|
| 257 | *
|
---|
| 258 | * @return EOK on success or an error code
|
---|
| 259 | */
|
---|
[3434233] | 260 | errno_t ds_window_create(ds_client_t *client, display_wnd_params_t *params,
|
---|
| 261 | ds_window_t **rgc)
|
---|
[c8cf261] | 262 | {
|
---|
[6af4b4f] | 263 | ds_window_t *wnd = NULL;
|
---|
[c8cf261] | 264 | gfx_context_t *gc = NULL;
|
---|
[946a666] | 265 | gfx_context_t *dgc;
|
---|
| 266 | gfx_rect_t rect;
|
---|
| 267 | gfx_coord2_t dims;
|
---|
| 268 | gfx_bitmap_params_t bparams;
|
---|
| 269 | gfx_bitmap_alloc_t alloc;
|
---|
[c8cf261] | 270 | errno_t rc;
|
---|
| 271 |
|
---|
[6af4b4f] | 272 | wnd = calloc(1, sizeof(ds_window_t));
|
---|
| 273 | if (wnd == NULL) {
|
---|
[c8cf261] | 274 | rc = ENOMEM;
|
---|
| 275 | goto error;
|
---|
| 276 | }
|
---|
| 277 |
|
---|
[6af4b4f] | 278 | rc = gfx_context_new(&ds_window_ops, wnd, &gc);
|
---|
[c8cf261] | 279 | if (rc != EOK)
|
---|
| 280 | goto error;
|
---|
| 281 |
|
---|
[b3c185b6] | 282 | ds_client_add_window(client, wnd);
|
---|
[fd777a2] | 283 | ds_display_add_window(client->display, wnd);
|
---|
[6af4b4f] | 284 |
|
---|
[946a666] | 285 | gfx_rect_points_sort(¶ms->rect, &rect);
|
---|
| 286 | gfx_coord2_subtract(&rect.p1, &rect.p0, &dims);
|
---|
| 287 |
|
---|
| 288 | bparams.rect = params->rect;
|
---|
| 289 |
|
---|
| 290 | dgc = ds_display_get_gc(wnd->display); // XXX
|
---|
| 291 | if (dgc != NULL) {
|
---|
| 292 | rc = gfx_bitmap_create(dgc, &bparams, NULL, &wnd->bitmap);
|
---|
| 293 | if (rc != EOK)
|
---|
| 294 | goto error;
|
---|
| 295 |
|
---|
| 296 | rc = gfx_bitmap_get_alloc(wnd->bitmap, &alloc);
|
---|
| 297 | if (rc != EOK)
|
---|
| 298 | goto error;
|
---|
| 299 |
|
---|
| 300 | wnd->pixelmap.width = dims.x;
|
---|
| 301 | wnd->pixelmap.height = dims.y;
|
---|
| 302 | wnd->pixelmap.data = alloc.pixels;
|
---|
| 303 | }
|
---|
| 304 |
|
---|
| 305 | if (wnd->pixelmap.data == NULL) {
|
---|
| 306 | rc = ENOMEM;
|
---|
| 307 | goto error;
|
---|
| 308 | }
|
---|
| 309 |
|
---|
[3434233] | 310 | wnd->rect = params->rect;
|
---|
[6af4b4f] | 311 | wnd->gc = gc;
|
---|
| 312 | *rgc = wnd;
|
---|
[c8cf261] | 313 | return EOK;
|
---|
| 314 | error:
|
---|
[946a666] | 315 | if (wnd != NULL) {
|
---|
| 316 | if (wnd->bitmap != NULL)
|
---|
| 317 | gfx_bitmap_destroy(wnd->bitmap);
|
---|
[6af4b4f] | 318 | free(wnd);
|
---|
[946a666] | 319 | }
|
---|
| 320 |
|
---|
[c8cf261] | 321 | gfx_context_delete(gc);
|
---|
| 322 | return rc;
|
---|
| 323 | }
|
---|
| 324 |
|
---|
| 325 | /** Delete window GC.
|
---|
| 326 | *
|
---|
[6af4b4f] | 327 | * @param wnd Window GC
|
---|
[c8cf261] | 328 | */
|
---|
[da412547] | 329 | void ds_window_destroy(ds_window_t *wnd)
|
---|
[c8cf261] | 330 | {
|
---|
[cc90846] | 331 | ds_display_t *disp;
|
---|
| 332 |
|
---|
| 333 | disp = wnd->display;
|
---|
| 334 |
|
---|
[b3c185b6] | 335 | ds_client_remove_window(wnd);
|
---|
[fd777a2] | 336 | ds_display_remove_window(wnd);
|
---|
[cc90846] | 337 |
|
---|
[da412547] | 338 | (void) gfx_context_delete(wnd->gc);
|
---|
[946a666] | 339 | if (wnd->bitmap != NULL)
|
---|
| 340 | gfx_bitmap_destroy(wnd->bitmap);
|
---|
[c8cf261] | 341 |
|
---|
[6af4b4f] | 342 | free(wnd);
|
---|
[cc90846] | 343 |
|
---|
| 344 | (void) ds_display_paint(disp, NULL);
|
---|
[c8cf261] | 345 | }
|
---|
| 346 |
|
---|
[6af4b4f] | 347 | /** Get generic graphic context from window.
|
---|
[c8cf261] | 348 | *
|
---|
[6af4b4f] | 349 | * @param wnd Window
|
---|
[c8cf261] | 350 | * @return Graphic context
|
---|
| 351 | */
|
---|
[6af4b4f] | 352 | gfx_context_t *ds_window_get_ctx(ds_window_t *wnd)
|
---|
[c8cf261] | 353 | {
|
---|
[6af4b4f] | 354 | return wnd->gc;
|
---|
[c8cf261] | 355 | }
|
---|
| 356 |
|
---|
[2012fe0] | 357 | /** Paint a window using its backing bitmap.
|
---|
[946a666] | 358 | *
|
---|
[2012fe0] | 359 | * @param wnd Window to paint
|
---|
| 360 | * @param rect Display rectangle to paint to
|
---|
[946a666] | 361 | * @return EOK on success or an error code
|
---|
| 362 | */
|
---|
[2012fe0] | 363 | errno_t ds_window_paint(ds_window_t *wnd, gfx_rect_t *rect)
|
---|
[946a666] | 364 | {
|
---|
[2012fe0] | 365 | gfx_rect_t srect;
|
---|
| 366 | gfx_rect_t *brect;
|
---|
| 367 | gfx_rect_t crect;
|
---|
| 368 |
|
---|
| 369 | log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_paint");
|
---|
| 370 |
|
---|
| 371 | if (rect != NULL) {
|
---|
| 372 | gfx_rect_rtranslate(&wnd->dpos, rect, &srect);
|
---|
| 373 |
|
---|
| 374 | /* Determine if we have anything to do */
|
---|
[01c2759] | 375 | gfx_rect_clip(&srect, &wnd->rect, &crect);
|
---|
[2012fe0] | 376 | if (gfx_rect_is_empty(&crect))
|
---|
| 377 | return EOK;
|
---|
| 378 |
|
---|
| 379 | brect = &srect;
|
---|
| 380 | } else {
|
---|
| 381 | brect = NULL;
|
---|
| 382 | }
|
---|
| 383 |
|
---|
| 384 | return gfx_bitmap_render(wnd->bitmap, brect, &wnd->dpos);
|
---|
[946a666] | 385 | }
|
---|
| 386 |
|
---|
[a40ae0d] | 387 | /** Start moving a window by mouse drag.
|
---|
| 388 | *
|
---|
| 389 | * @param wnd Window
|
---|
| 390 | * @param event Button press event
|
---|
| 391 | */
|
---|
| 392 | static void ds_window_start_move(ds_window_t *wnd, pos_event_t *event)
|
---|
| 393 | {
|
---|
| 394 | log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_start_move (%d, %d)",
|
---|
| 395 | (int) event->hpos, (int) event->vpos);
|
---|
| 396 |
|
---|
| 397 | assert(wnd->state == dsw_idle);
|
---|
| 398 |
|
---|
| 399 | wnd->orig_pos.x = event->hpos;
|
---|
| 400 | wnd->orig_pos.y = event->vpos;
|
---|
| 401 | wnd->state = dsw_moving;
|
---|
| 402 | }
|
---|
| 403 |
|
---|
| 404 | /** Finish moving a window by mouse drag.
|
---|
| 405 | *
|
---|
| 406 | * @param wnd Window
|
---|
| 407 | * @param event Button release event
|
---|
| 408 | */
|
---|
| 409 | static void ds_window_finish_move(ds_window_t *wnd, pos_event_t *event)
|
---|
| 410 | {
|
---|
| 411 | gfx_coord2_t pos;
|
---|
| 412 | gfx_coord2_t dmove;
|
---|
| 413 | gfx_coord2_t nwpos;
|
---|
| 414 |
|
---|
| 415 | log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_finish_move (%d, %d)",
|
---|
| 416 | (int) event->hpos, (int) event->vpos);
|
---|
| 417 |
|
---|
| 418 | assert(wnd->state == dsw_moving);
|
---|
| 419 | pos.x = event->hpos;
|
---|
| 420 | pos.y = event->vpos;
|
---|
| 421 | gfx_coord2_subtract(&pos, &wnd->orig_pos, &dmove);
|
---|
| 422 |
|
---|
| 423 | gfx_coord2_add(&wnd->dpos, &dmove, &nwpos);
|
---|
| 424 | wnd->dpos = nwpos;
|
---|
| 425 | wnd->state = dsw_idle;
|
---|
[946a666] | 426 |
|
---|
[2012fe0] | 427 | (void) ds_display_paint(wnd->display, NULL);
|
---|
[a40ae0d] | 428 | }
|
---|
| 429 |
|
---|
| 430 | /** Update window position when moving by mouse drag.
|
---|
| 431 | *
|
---|
| 432 | * @param wnd Window
|
---|
| 433 | * @param event Position update event
|
---|
| 434 | */
|
---|
| 435 | static void ds_window_update_move(ds_window_t *wnd, pos_event_t *event)
|
---|
| 436 | {
|
---|
| 437 | gfx_coord2_t pos;
|
---|
| 438 | gfx_coord2_t dmove;
|
---|
| 439 | gfx_coord2_t nwpos;
|
---|
| 440 | gfx_rect_t drect;
|
---|
| 441 | gfx_color_t *color;
|
---|
| 442 | gfx_context_t *gc;
|
---|
| 443 | errno_t rc;
|
---|
| 444 |
|
---|
| 445 | log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_move (%d, %d)",
|
---|
| 446 | (int) event->hpos, (int) event->vpos);
|
---|
| 447 |
|
---|
[c79545e] | 448 | gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);
|
---|
| 449 |
|
---|
| 450 | gc = ds_display_get_gc(wnd->display); // XXX
|
---|
| 451 | if (gc != NULL) {
|
---|
| 452 | gfx_set_color(gc, wnd->display->bg_color);
|
---|
| 453 | gfx_fill_rect(gc, &drect);
|
---|
| 454 | }
|
---|
| 455 |
|
---|
[a40ae0d] | 456 | assert(wnd->state == dsw_moving);
|
---|
| 457 | pos.x = event->hpos;
|
---|
| 458 | pos.y = event->vpos;
|
---|
| 459 | gfx_coord2_subtract(&pos, &wnd->orig_pos, &dmove);
|
---|
| 460 |
|
---|
| 461 | gfx_coord2_add(&wnd->dpos, &dmove, &nwpos);
|
---|
| 462 | gfx_rect_translate(&nwpos, &wnd->rect, &drect);
|
---|
| 463 |
|
---|
[c79545e] | 464 | wnd->orig_pos = pos;
|
---|
| 465 | wnd->dpos = nwpos;
|
---|
| 466 |
|
---|
[a40ae0d] | 467 | rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
|
---|
| 468 | if (rc != EOK)
|
---|
| 469 | return;
|
---|
| 470 |
|
---|
| 471 | gc = ds_display_get_gc(wnd->display); // XXX
|
---|
| 472 | if (gc != NULL) {
|
---|
[946a666] | 473 | gfx_set_color(gc, color);
|
---|
| 474 | gfx_fill_rect(gc, &drect);
|
---|
[a40ae0d] | 475 | }
|
---|
| 476 |
|
---|
| 477 | gfx_color_delete(color);
|
---|
| 478 | }
|
---|
| 479 |
|
---|
| 480 | /** Post position event to window.
|
---|
| 481 | *
|
---|
| 482 | * @param wnd Window
|
---|
| 483 | * @param event Position event
|
---|
| 484 | */
|
---|
| 485 | errno_t ds_window_post_pos_event(ds_window_t *wnd, pos_event_t *event)
|
---|
| 486 | {
|
---|
| 487 | log_msg(LOG_DEFAULT, LVL_DEBUG,
|
---|
| 488 | "ds_window_post_pos_event type=%d pos=%d,%d\n", event->type,
|
---|
| 489 | (int) event->hpos, (int) event->vpos);
|
---|
| 490 |
|
---|
| 491 | if (event->type == POS_PRESS) {
|
---|
| 492 | if (wnd->state == dsw_idle)
|
---|
| 493 | ds_window_start_move(wnd, event);
|
---|
| 494 | }
|
---|
| 495 |
|
---|
| 496 | if (event->type == POS_RELEASE) {
|
---|
| 497 | if (wnd->state == dsw_moving)
|
---|
| 498 | ds_window_finish_move(wnd, event);
|
---|
| 499 | }
|
---|
| 500 |
|
---|
| 501 | if (event->type == POS_UPDATE) {
|
---|
| 502 | if (wnd->state == dsw_moving)
|
---|
| 503 | ds_window_update_move(wnd, event);
|
---|
| 504 | }
|
---|
| 505 |
|
---|
| 506 | return EOK;
|
---|
| 507 | }
|
---|
| 508 |
|
---|
[c8cf261] | 509 | /** @}
|
---|
| 510 | */
|
---|