source: mainline/uspace/srv/hid/display/cursor.c@ 8edec53

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

Properly clip cursor when repainting a part of the display

Not doing so was causing excessively large update rectangles, increasing
CPU usage and display artifacts.

  • Property mode set to 100644
File size: 4.6 KB
Line 
1/*
2 * Copyright (c) 2020 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 Display server cursor
34 */
35
36#include <gfx/bitmap.h>
37#include <gfx/coord.h>
38#include <stdlib.h>
39#include "cursor.h"
40#include "display.h"
41
42/** Create cursor.
43 *
44 * @param disp Display
45 * @param rect Rectangle bounding cursor graphic
46 * @param image Cursor image (one entire byte per pixel)
47 * @param rcursor Place to store pointer to new cursor.
48 *
49 * @return EOK on success or an error code
50 */
51errno_t ds_cursor_create(ds_display_t *disp, gfx_rect_t *rect,
52 const uint8_t *image, ds_cursor_t **rcursor)
53{
54 ds_cursor_t *cursor = NULL;
55 errno_t rc;
56
57 cursor = calloc(1, sizeof(ds_cursor_t));
58 if (cursor == NULL) {
59 rc = ENOMEM;
60 goto error;
61 }
62
63 ds_display_add_cursor(disp, cursor);
64
65 cursor->rect = *rect;
66 cursor->image = image;
67 *rcursor = cursor;
68 return EOK;
69error:
70 return rc;
71}
72
73/** Destroy cusror.
74 *
75 * @param cursor Cursor
76 */
77void ds_cursor_destroy(ds_cursor_t *cursor)
78{
79 list_remove(&cursor->ldisplay);
80
81 if (cursor->bitmap != NULL)
82 gfx_bitmap_destroy(cursor->bitmap);
83
84 free(cursor);
85}
86
87/** Paint cusor.
88 *
89 * @param cursor Cusor to paint
90 * @param pos Position to paint at
91 * @param clip Clipping rectangle or @c NULL
92 * @return EOK on success or an error code
93 */
94errno_t ds_cursor_paint(ds_cursor_t *cursor, gfx_coord2_t *pos,
95 gfx_rect_t *clip)
96{
97 gfx_context_t *dgc;
98 gfx_coord_t x, y;
99 gfx_bitmap_params_t bparams;
100 gfx_bitmap_alloc_t alloc;
101 gfx_coord2_t dims;
102 gfx_rect_t sclip;
103 gfx_rect_t srect;
104 pixelmap_t pixelmap;
105 pixel_t pixel;
106 const uint8_t *pp;
107 errno_t rc;
108
109 dgc = ds_display_get_gc(cursor->display);
110 if (dgc == NULL)
111 return EOK;
112
113 gfx_bitmap_params_init(&bparams);
114 bparams.rect = cursor->rect;
115 bparams.flags = bmpf_color_key;
116 bparams.key_color = PIXEL(0, 0, 255, 255);
117
118 if (cursor->bitmap == NULL) {
119 rc = gfx_bitmap_create(dgc, &bparams, NULL, &cursor->bitmap);
120 if (rc != EOK)
121 goto error;
122
123 rc = gfx_bitmap_get_alloc(cursor->bitmap, &alloc);
124 if (rc != EOK) {
125 gfx_bitmap_destroy(cursor->bitmap);
126 cursor->bitmap = NULL;
127 goto error;
128 }
129
130 gfx_rect_dims(&cursor->rect, &dims);
131 pixelmap.width = dims.x;
132 pixelmap.height = dims.y;
133 pixelmap.data = alloc.pixels;
134
135 pp = cursor->image;
136 for (y = 0; y < dims.y; y++) {
137 for (x = 0; x < dims.x; x++) {
138 switch (*pp) {
139 case 1:
140 pixel = PIXEL(0, 0, 0, 0);
141 break;
142 case 2:
143 pixel = PIXEL(0, 255, 255, 255);
144 break;
145 default:
146 pixel = PIXEL(0, 0, 255, 255);
147 break;
148 }
149
150 pixelmap_put_pixel(&pixelmap, x, y, pixel);
151 ++pp;
152 }
153 }
154 }
155
156 /* Determine source rectangle */
157 if (clip == NULL) {
158 srect = cursor->rect;
159 } else {
160 gfx_rect_rtranslate(pos, clip, &sclip);
161 gfx_rect_clip(&cursor->rect, &sclip, &srect);
162 }
163
164 if (!gfx_rect_is_empty(&srect)) {
165 rc = gfx_bitmap_render(cursor->bitmap, &srect, pos);
166 if (rc != EOK)
167 return rc;
168 }
169
170 return EOK;
171error:
172 return rc;
173}
174
175/** Get rectangle covered by cursor when drawn at a specified position.
176 *
177 * @param cursor Cursor
178 * @param pos Position where cursor is situated
179 * @param rect Place to store rectangle covered by cursor
180 */
181void ds_cursor_get_rect(ds_cursor_t *cursor, gfx_coord2_t *pos,
182 gfx_rect_t *drect)
183{
184 gfx_rect_translate(pos, &cursor->rect, drect);
185}
186
187/** @}
188 */
Note: See TracBrowser for help on using the repository browser.