source: mainline/uspace/srv/hid/display/window.c@ d70e7b7b

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since d70e7b7b was d70e7b7b, checked in by Jiri Svoboda <jiri@…>, 5 years ago

Fix typos

  • Property mode set to 100644
File size: 16.3 KB
RevLine 
[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/**
[4d8002d]33 * @file Display server window
[c8cf261]34 */
35
[0008c0f]36#include <gfx/bitmap.h>
[c8cf261]37#include <gfx/color.h>
[0008c0f]38#include <gfx/coord.h>
[c8cf261]39#include <gfx/context.h>
40#include <gfx/render.h>
41#include <io/log.h>
[946a666]42#include <io/pixelmap.h>
[9b502dd]43#include <macros.h>
[dbef30f]44#include <memgfx/memgc.h>
[c8cf261]45#include <stdlib.h>
[b3c185b6]46#include "client.h"
[6af4b4f]47#include "display.h"
[9901f267]48#include "seat.h"
[6af4b4f]49#include "window.h"
[c8cf261]50
[dbef30f]51static void ds_window_update_cb(void *, gfx_rect_t *);
[0008c0f]52
[6af4b4f]53/** Create window.
[c8cf261]54 *
55 * Create graphics context for rendering into a window.
56 *
[8e9781f]57 * @param client Client owning the window
[3434233]58 * @param params Window parameters
[c8cf261]59 * @param rgc Place to store pointer to new GC.
60 *
61 * @return EOK on success or an error code
62 */
[3434233]63errno_t ds_window_create(ds_client_t *client, display_wnd_params_t *params,
64 ds_window_t **rgc)
[c8cf261]65{
[6af4b4f]66 ds_window_t *wnd = NULL;
[946a666]67 gfx_context_t *dgc;
68 gfx_coord2_t dims;
69 gfx_bitmap_params_t bparams;
70 gfx_bitmap_alloc_t alloc;
[c8cf261]71 errno_t rc;
72
[6af4b4f]73 wnd = calloc(1, sizeof(ds_window_t));
74 if (wnd == NULL) {
[c8cf261]75 rc = ENOMEM;
76 goto error;
77 }
78
[b3c185b6]79 ds_client_add_window(client, wnd);
[fd777a2]80 ds_display_add_window(client->display, wnd);
[6af4b4f]81
[a8eed5f]82 gfx_bitmap_params_init(&bparams);
[946a666]83 bparams.rect = params->rect;
84
85 dgc = ds_display_get_gc(wnd->display); // XXX
86 if (dgc != NULL) {
87 rc = gfx_bitmap_create(dgc, &bparams, NULL, &wnd->bitmap);
88 if (rc != EOK)
89 goto error;
90
91 rc = gfx_bitmap_get_alloc(wnd->bitmap, &alloc);
92 if (rc != EOK)
93 goto error;
94
[0e6e77f]95 gfx_rect_dims(&params->rect, &dims);
[946a666]96 wnd->pixelmap.width = dims.x;
97 wnd->pixelmap.height = dims.y;
98 wnd->pixelmap.data = alloc.pixels;
[dbef30f]99 } else {
100 /* This is just for unit tests */
101 gfx_rect_dims(&params->rect, &dims);
102 alloc.pitch = dims.x * sizeof(uint32_t);
103 alloc.off0 = 0;
104 alloc.pixels = calloc(1, alloc.pitch * dims.y);
[946a666]105 }
106
[dbef30f]107 rc = mem_gc_create(&params->rect, &alloc, ds_window_update_cb,
108 (void *)wnd, &wnd->mgc);
109 if (rc != EOK)
110 goto error;
111
[3434233]112 wnd->rect = params->rect;
[9b502dd]113 wnd->min_size = params->min_size;
[dbef30f]114 wnd->gc = mem_gc_get_ctx(wnd->mgc);
[9242ad9]115 wnd->cursor = wnd->display->cursor[dcurs_arrow];
[6af4b4f]116 *rgc = wnd;
[c8cf261]117 return EOK;
118error:
[946a666]119 if (wnd != NULL) {
120 if (wnd->bitmap != NULL)
121 gfx_bitmap_destroy(wnd->bitmap);
[6af4b4f]122 free(wnd);
[946a666]123 }
124
[c8cf261]125 return rc;
126}
127
[0e6e77f]128/** Destroy window.
[c8cf261]129 *
[0e6e77f]130 * @param wnd Window
[c8cf261]131 */
[da412547]132void ds_window_destroy(ds_window_t *wnd)
[c8cf261]133{
[cc90846]134 ds_display_t *disp;
135
136 disp = wnd->display;
137
[b3c185b6]138 ds_client_remove_window(wnd);
[fd777a2]139 ds_display_remove_window(wnd);
[cc90846]140
[dbef30f]141 mem_gc_delete(wnd->mgc);
142
[946a666]143 if (wnd->bitmap != NULL)
144 gfx_bitmap_destroy(wnd->bitmap);
[c8cf261]145
[6af4b4f]146 free(wnd);
[cc90846]147
148 (void) ds_display_paint(disp, NULL);
[c8cf261]149}
150
[1a1271d]151/** Bring window to top.
152 *
153 * @param wnd Window
154 */
[b5c7cee]155void ds_window_bring_to_top(ds_window_t *wnd)
156{
157 ds_display_t *disp = wnd->display;
158
159 ds_display_remove_window(wnd);
160 ds_display_add_window(disp, wnd);
161}
162
[6af4b4f]163/** Get generic graphic context from window.
[c8cf261]164 *
[6af4b4f]165 * @param wnd Window
[c8cf261]166 * @return Graphic context
167 */
[6af4b4f]168gfx_context_t *ds_window_get_ctx(ds_window_t *wnd)
[c8cf261]169{
[6af4b4f]170 return wnd->gc;
[c8cf261]171}
172
[2012fe0]173/** Paint a window using its backing bitmap.
[946a666]174 *
[2012fe0]175 * @param wnd Window to paint
176 * @param rect Display rectangle to paint to
[946a666]177 * @return EOK on success or an error code
178 */
[2012fe0]179errno_t ds_window_paint(ds_window_t *wnd, gfx_rect_t *rect)
[946a666]180{
[2012fe0]181 gfx_rect_t srect;
182 gfx_rect_t *brect;
183 gfx_rect_t crect;
184
185 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_paint");
186
187 if (rect != NULL) {
188 gfx_rect_rtranslate(&wnd->dpos, rect, &srect);
189
190 /* Determine if we have anything to do */
[01c2759]191 gfx_rect_clip(&srect, &wnd->rect, &crect);
[2012fe0]192 if (gfx_rect_is_empty(&crect))
193 return EOK;
194
195 brect = &srect;
196 } else {
197 brect = NULL;
198 }
199
[f5191b4]200 /* This can happen in unit tests */
201 if (wnd->bitmap == NULL)
202 return EOK;
203
[2012fe0]204 return gfx_bitmap_render(wnd->bitmap, brect, &wnd->dpos);
[946a666]205}
206
[a40ae0d]207/** Start moving a window by mouse drag.
208 *
209 * @param wnd Window
[76a02db]210 * @param pos Position where mouse button was pressed
[a40ae0d]211 */
[76a02db]212static void ds_window_start_move(ds_window_t *wnd, gfx_coord2_t *pos)
[a40ae0d]213{
[1b443cc0]214 gfx_color_t *color;
215 gfx_context_t *gc;
216 gfx_rect_t drect;
217 errno_t rc;
218
[a40ae0d]219 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_start_move (%d, %d)",
[76a02db]220 (int) pos->x, (int) pos->y);
[a40ae0d]221
[a2e104e]222 if (wnd->state != dsw_idle)
223 return;
[a40ae0d]224
[76a02db]225 wnd->orig_pos = *pos;
[a40ae0d]226 wnd->state = dsw_moving;
[1b443cc0]227 wnd->preview_pos = wnd->dpos;
228
229 rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
230 if (rc != EOK)
231 return;
232
233 gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);
234
235 gc = ds_display_get_gc(wnd->display); // XXX
236 if (gc != NULL) {
237 gfx_set_color(gc, color);
238 gfx_fill_rect(gc, &drect);
239 }
240
241 gfx_color_delete(color);
[a40ae0d]242}
243
244/** Finish moving a window by mouse drag.
245 *
246 * @param wnd Window
[76a02db]247 * @param pos Position where mouse button was released
[a40ae0d]248 */
[76a02db]249static void ds_window_finish_move(ds_window_t *wnd, gfx_coord2_t *pos)
[a40ae0d]250{
251 gfx_coord2_t dmove;
252 gfx_coord2_t nwpos;
253
254 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_finish_move (%d, %d)",
[76a02db]255 (int) pos->x, (int) pos->y);
[a40ae0d]256
[5f483be]257 assert(wnd->state == dsw_moving);
[a2e104e]258
[76a02db]259 gfx_coord2_subtract(pos, &wnd->orig_pos, &dmove);
[a40ae0d]260
261 gfx_coord2_add(&wnd->dpos, &dmove, &nwpos);
262 wnd->dpos = nwpos;
263 wnd->state = dsw_idle;
[946a666]264
[2012fe0]265 (void) ds_display_paint(wnd->display, NULL);
[a40ae0d]266}
267
268/** Update window position when moving by mouse drag.
269 *
270 * @param wnd Window
[76a02db]271 * @param pos Current mouse position
[a40ae0d]272 */
[76a02db]273static void ds_window_update_move(ds_window_t *wnd, gfx_coord2_t *pos)
[a40ae0d]274{
275 gfx_coord2_t dmove;
276 gfx_coord2_t nwpos;
277 gfx_rect_t drect;
278 gfx_color_t *color;
279 gfx_context_t *gc;
280 errno_t rc;
281
282 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_move (%d, %d)",
[76a02db]283 (int) pos->x, (int) pos->y);
[a40ae0d]284
[5f483be]285 assert(wnd->state == dsw_moving);
[a2e104e]286
[1b443cc0]287 gfx_rect_translate(&wnd->preview_pos, &wnd->rect, &drect);
288 ds_display_paint(wnd->display, &drect);
[c79545e]289
[76a02db]290 gfx_coord2_subtract(pos, &wnd->orig_pos, &dmove);
[a40ae0d]291
292 gfx_coord2_add(&wnd->dpos, &dmove, &nwpos);
[1b443cc0]293 wnd->preview_pos = nwpos;
[a40ae0d]294
[1b443cc0]295 gfx_rect_translate(&nwpos, &wnd->rect, &drect);
[c79545e]296
[a40ae0d]297 rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
298 if (rc != EOK)
299 return;
300
301 gc = ds_display_get_gc(wnd->display); // XXX
302 if (gc != NULL) {
[946a666]303 gfx_set_color(gc, color);
304 gfx_fill_rect(gc, &drect);
[a40ae0d]305 }
306
307 gfx_color_delete(color);
308}
309
[76a02db]310/** Start resizing a window by mouse drag.
311 *
312 * @param wnd Window
313 * @param rsztype Resize type (which part of window is being dragged)
314 * @param pos Position where mouse button was pressed
315 */
316static void ds_window_start_resize(ds_window_t *wnd,
317 display_wnd_rsztype_t rsztype, gfx_coord2_t *pos)
318{
[9901f267]319 ds_seat_t *seat;
320 display_stock_cursor_t ctype;
321
[76a02db]322 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_start_resize (%d, %d)",
323 (int) pos->x, (int) pos->y);
324
325 if (wnd->state != dsw_idle)
326 return;
327
328 wnd->orig_pos = *pos;
329 wnd->state = dsw_resizing;
330 wnd->rsztype = rsztype;
[71eff34]331 wnd->preview_rect = wnd->rect;
[9901f267]332
333 // XXX Need client to tell us which seat started the resize!
334 seat = ds_display_first_seat(wnd->display);
335 ctype = display_cursor_from_wrsz(rsztype);
336 ds_seat_set_wm_cursor(seat, wnd->display->cursor[ctype]);
[76a02db]337}
338
[e022819]339/** Finish resizing a window by mouse drag.
340 *
341 * @param wnd Window
[76a02db]342 * @param pos Position where mouse button was released
[e022819]343 */
[76a02db]344static void ds_window_finish_resize(ds_window_t *wnd, gfx_coord2_t *pos)
[e022819]345{
346 gfx_coord2_t dresize;
347 gfx_rect_t nrect;
[9901f267]348 ds_seat_t *seat;
[e022819]349
350 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_finish_resize (%d, %d)",
[76a02db]351 (int) pos->x, (int) pos->y);
[e022819]352
[5f483be]353 assert(wnd->state == dsw_resizing);
[e022819]354
[03c8081]355 (void) ds_display_paint(wnd->display, NULL);
356
[76a02db]357 gfx_coord2_subtract(pos, &wnd->orig_pos, &dresize);
[e022819]358
359 /* Compute new rectangle */
360 ds_window_calc_resize(wnd, &dresize, &nrect);
361
362 wnd->state = dsw_idle;
363 ds_client_post_resize_event(wnd->client, wnd, &nrect);
[9901f267]364
365 // XXX Need to know which seat started the resize!
366 seat = ds_display_first_seat(wnd->display);
367 ds_seat_set_wm_cursor(seat, NULL);
[e022819]368}
369
370/** Update window position when resizing by mouse drag.
371 *
372 * @param wnd Window
[76a02db]373 * @param pos Current mouse position
[e022819]374 */
[76a02db]375static void ds_window_update_resize(ds_window_t *wnd, gfx_coord2_t *pos)
[e022819]376{
377 gfx_coord2_t dresize;
378 gfx_rect_t nrect;
379 gfx_rect_t drect;
380 gfx_color_t *color;
381 gfx_context_t *gc;
382 errno_t rc;
383
384 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_resize (%d, %d)",
[76a02db]385 (int) pos->x, (int) pos->y);
[e022819]386
[5f483be]387 assert(wnd->state == dsw_resizing);
[e022819]388
[71eff34]389 gfx_rect_translate(&wnd->dpos, &wnd->preview_rect, &drect);
390 (void) ds_display_paint(wnd->display, &drect);
[e022819]391
[76a02db]392 gfx_coord2_subtract(pos, &wnd->orig_pos, &dresize);
[e022819]393
394 ds_window_calc_resize(wnd, &dresize, &nrect);
395 gfx_rect_translate(&wnd->dpos, &nrect, &drect);
[71eff34]396 wnd->preview_rect = nrect;
[e022819]397
398 rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
399 if (rc != EOK)
400 return;
401
402 gc = ds_display_get_gc(wnd->display); // XXX
403 if (gc != NULL) {
404 gfx_set_color(gc, color);
405 gfx_fill_rect(gc, &drect);
406 }
407
408 gfx_color_delete(color);
409}
410
[338d0935]411/** Post keyboard event to window.
412 *
413 * @param wnd Window
414 * @param event Event
415 *
416 * @return EOK on success or an error code
417 */
418errno_t ds_window_post_kbd_event(ds_window_t *wnd, kbd_event_t *event)
419{
420 bool alt_or_shift;
421
422 alt_or_shift = event->mods & (KM_SHIFT | KM_ALT);
423
424 if (event->type == KEY_PRESS && alt_or_shift && event->key == KC_F4) {
425 /* On Alt-F4 or Shift-F4 send close event to the window */
426 ds_client_post_close_event(wnd->client, wnd);
427 return EOK;
428 }
429
430 return ds_client_post_kbd_event(wnd->client, wnd, event);
431}
432
[a40ae0d]433/** Post position event to window.
434 *
435 * @param wnd Window
436 * @param event Position event
437 */
438errno_t ds_window_post_pos_event(ds_window_t *wnd, pos_event_t *event)
439{
[f7fb2b21]440 pos_event_t tevent;
[a2e104e]441 gfx_coord2_t pos;
442 gfx_rect_t drect;
443 bool inside;
[f7fb2b21]444
[a40ae0d]445 log_msg(LOG_DEFAULT, LVL_DEBUG,
446 "ds_window_post_pos_event type=%d pos=%d,%d\n", event->type,
447 (int) event->hpos, (int) event->vpos);
448
[a2e104e]449 pos.x = event->hpos;
450 pos.y = event->vpos;
451 gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);
452 inside = gfx_pix_inside_rect(&pos, &drect);
[a40ae0d]453
[5f483be]454 if (event->type == POS_PRESS && event->btn_num == 2 && inside) {
[76a02db]455 ds_window_start_move(wnd, &pos);
[5f483be]456 return EOK;
457 }
[a40ae0d]458
[e022819]459 if (event->type == POS_RELEASE) {
[5f483be]460 if (wnd->state == dsw_moving) {
461 ds_window_finish_move(wnd, &pos);
462 return EOK;
463 }
464
465 if (wnd->state == dsw_resizing) {
466 ds_window_finish_resize(wnd, &pos);
467 return EOK;
468 }
[e022819]469 }
[a2e104e]470
[e022819]471 if (event->type == POS_UPDATE) {
[5f483be]472 if (wnd->state == dsw_moving) {
473 ds_window_update_move(wnd, &pos);
474 return EOK;
475 }
476
477 if (wnd->state == dsw_resizing) {
478 ds_window_update_resize(wnd, &pos);
479 return EOK;
480 }
[e022819]481 }
[a40ae0d]482
[f7fb2b21]483 /* Transform event coordinates to window-local */
484 tevent = *event;
485 tevent.hpos -= wnd->dpos.x;
486 tevent.vpos -= wnd->dpos.y;
487
488 return ds_client_post_pos_event(wnd->client, wnd, &tevent);
[a40ae0d]489}
490
[b0a94854]491/** Post focus event to window.
492 *
493 * @param wnd Window
494 */
495errno_t ds_window_post_focus_event(ds_window_t *wnd)
496{
497 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_focus_event\n");
498
499 return ds_client_post_focus_event(wnd->client, wnd);
500}
501
502/** Post unfocus event to window.
503 *
504 * @param wnd Window
505 */
506errno_t ds_window_post_unfocus_event(ds_window_t *wnd)
507{
508 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_unfocus_event\n");
509
510 return ds_client_post_unfocus_event(wnd->client, wnd);
511}
512
[e022819]513/** Start moving a window, detected by client.
514 *
515 * @param wnd Window
516 * @param pos Position where the pointer was when the move started
517 * relative to the window
518 * @param event Button press event
519 */
520void ds_window_move_req(ds_window_t *wnd, gfx_coord2_t *pos)
521{
[76a02db]522 gfx_coord2_t orig_pos;
523
[e022819]524 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_move_req (%d, %d)",
525 (int) pos->x, (int) pos->y);
526
[76a02db]527 gfx_coord2_add(&wnd->dpos, pos, &orig_pos);
528 ds_window_start_move(wnd, &orig_pos);
[e022819]529}
530
[0680854]531/** Move window.
532 *
533 * @param wnd Window
534 */
535void ds_window_move(ds_window_t *wnd, gfx_coord2_t *dpos)
536{
537 wnd->dpos = *dpos;
538 (void) ds_display_paint(wnd->display, NULL);
539}
540
[e022819]541/** Start resizing a window, detected by client.
542 *
543 * @param wnd Window
544 * @param rsztype Resize type (which part of window is being dragged)
545 * @param pos Position where the pointer was when the resize started
546 * relative to the window
547 * @param event Button press event
548 */
549void ds_window_resize_req(ds_window_t *wnd, display_wnd_rsztype_t rsztype,
550 gfx_coord2_t *pos)
551{
[76a02db]552 gfx_coord2_t orig_pos;
553
[e022819]554 log_msg(LOG_DEFAULT, LVL_NOTE, "ds_window_resize_req (%d, %d, %d)",
555 (int) rsztype, (int) pos->x, (int) pos->y);
556
[76a02db]557 gfx_coord2_add(&wnd->dpos, pos, &orig_pos);
558 ds_window_start_resize(wnd, rsztype, &orig_pos);
[e022819]559}
560
[0680854]561/** Resize window.
562 *
563 * @param wnd Window
564 */
565errno_t ds_window_resize(ds_window_t *wnd, gfx_coord2_t *offs,
566 gfx_rect_t *nrect)
567{
568 gfx_context_t *dgc;
569 gfx_bitmap_params_t bparams;
570 gfx_bitmap_t *nbitmap;
571 pixelmap_t npixelmap;
572 gfx_coord2_t dims;
573 gfx_bitmap_alloc_t alloc;
574 gfx_coord2_t ndpos;
575 errno_t rc;
576
577 dgc = ds_display_get_gc(wnd->display); // XXX
578 if (dgc != NULL) {
579 gfx_bitmap_params_init(&bparams);
580 bparams.rect = *nrect;
581
582 rc = gfx_bitmap_create(dgc, &bparams, NULL, &nbitmap);
583 if (rc != EOK)
584 return ENOMEM;
585
586 rc = gfx_bitmap_get_alloc(nbitmap, &alloc);
587 if (rc != EOK) {
588 gfx_bitmap_destroy(nbitmap);
589 return ENOMEM;
590 }
591
592 gfx_rect_dims(nrect, &dims);
593 npixelmap.width = dims.x;
594 npixelmap.height = dims.y;
595 npixelmap.data = alloc.pixels;
596
597 /* TODO: Transfer contents within overlap */
598
599 if (wnd->bitmap != NULL)
600 gfx_bitmap_destroy(wnd->bitmap);
601
602 wnd->bitmap = nbitmap;
603 wnd->pixelmap = npixelmap;
[dbef30f]604
605 /* Point memory GC to the new bitmap */
606 mem_gc_retarget(wnd->mgc, nrect, &alloc);
[0680854]607 }
608
609 gfx_coord2_add(&wnd->dpos, offs, &ndpos);
610
611 wnd->dpos = ndpos;
612 wnd->rect = *nrect;
613
614 (void) ds_display_paint(wnd->display, NULL);
615 return EOK;
616}
617
[e022819]618/** Compute new window rectangle after resize operation.
619 *
620 * @param wnd Window which is being resized (in dsw_resizing state and thus
621 * has rsztype set)
622 * @param dresize Amount by which to resize
623 * @param nrect Place to store new rectangle
624 */
625void ds_window_calc_resize(ds_window_t *wnd, gfx_coord2_t *dresize,
626 gfx_rect_t *nrect)
627{
[9b502dd]628 if ((wnd->rsztype & display_wr_top) != 0) {
629 nrect->p0.y = min(wnd->rect.p0.y + dresize->y,
630 wnd->rect.p1.y - wnd->min_size.y);
631 } else {
632 nrect->p0.y = wnd->rect.p0.y;
633 }
634
635 if ((wnd->rsztype & display_wr_left) != 0) {
636 nrect->p0.x = min(wnd->rect.p0.x + dresize->x,
637 wnd->rect.p1.x - wnd->min_size.x);
638 } else {
639 nrect->p0.x = wnd->rect.p0.x;
640 }
641
642 if ((wnd->rsztype & display_wr_bottom) != 0) {
643 nrect->p1.y = max(wnd->rect.p1.y + dresize->y,
644 wnd->rect.p0.y + wnd->min_size.y);
645 } else {
646 nrect->p1.y = wnd->rect.p1.y;
647 }
648
649 if ((wnd->rsztype & display_wr_right) != 0) {
650 nrect->p1.x = max(wnd->rect.p1.x + dresize->x,
651 wnd->rect.p0.x + wnd->min_size.x);
652 } else {
653 nrect->p1.x = wnd->rect.p1.x;
654 }
[e022819]655}
656
[9242ad9]657/** Set window cursor.
658 *
659 * @param wnd Window
660 * @return EOK on success, EINVAL if @a cursor is invalid
661 */
662errno_t ds_window_set_cursor(ds_window_t *wnd, display_stock_cursor_t cursor)
663{
664 if (cursor >= dcurs_arrow &&
665 cursor < (display_stock_cursor_t) dcurs_limit) {
666 wnd->cursor = wnd->display->cursor[cursor];
667 return EOK;
668 } else {
669 return EINVAL;
670 }
671}
672
[d70e7b7b]673/** Window memory GC update callback.
[dbef30f]674 *
675 * This is called by the window's memory GC when a rectangle us updated.
676 */
677static void ds_window_update_cb(void *arg, gfx_rect_t *rect)
678{
679 ds_window_t *wnd = (ds_window_t *)arg;
680 gfx_rect_t drect;
681
682 /* Repaint the corresponding part of the display */
683 gfx_rect_translate(&wnd->dpos, rect, &drect);
684 (void) ds_display_paint(wnd->display, &drect);
685}
686
[c8cf261]687/** @}
688 */
Note: See TracBrowser for help on using the repository browser.