Changeset a35b458 in mainline for uspace/lib/gui
- Timestamp:
- 2018-03-02T20:10:49Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1380b7
- Parents:
- 3061bc1
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
- Location:
- uspace/lib/gui
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/gui/button.c
r3061bc1 ra35b458 50 50 { 51 51 button_t *btn = (button_t *) widget; 52 52 53 53 surface_t *surface = window_claim(btn->widget.window); 54 54 if (!surface) 55 55 window_yield(btn->widget.window); 56 56 57 57 source_t source; 58 58 source_init(&source); 59 59 60 60 drawctx_t drawctx; 61 61 drawctx_init(&drawctx, surface); 62 62 63 63 drawctx_set_source(&drawctx, &btn->background); 64 64 drawctx_transfer(&drawctx, widget->hpos, widget->vpos, 65 65 widget->width, widget->height); 66 66 67 67 if ((widget->width >= 8) && (widget->height >= 8)) { 68 68 drawctx_set_source(&drawctx, &source); … … 70 70 widget->width - 6, widget->height - 6, color_highlight, 71 71 color_shadow); 72 72 73 73 drawctx_set_source(&drawctx, &btn->foreground); 74 74 drawctx_transfer(&drawctx, widget->hpos + 4, widget->vpos + 4, 75 75 widget->width - 8, widget->height - 8); 76 76 } 77 77 78 78 sysarg_t cpt_width; 79 79 sysarg_t cpt_height; 80 80 font_get_box(btn->font, btn->caption, &cpt_width, &cpt_height); 81 81 82 82 if ((widget->width >= cpt_width) && (widget->height >= cpt_height)) { 83 83 sysarg_t x = ((widget->width - cpt_width) / 2) + widget->hpos; 84 84 sysarg_t y = ((widget->height - cpt_height) / 2) + widget->vpos; 85 85 86 86 drawctx_set_source(&drawctx, &btn->text); 87 87 drawctx_set_font(&drawctx, btn->font); 88 88 89 89 if (btn->caption) 90 90 drawctx_print(&drawctx, btn->caption, x, y); 91 91 } 92 92 93 93 window_yield(btn->widget.window); 94 94 } … … 104 104 { 105 105 button_t *btn = (button_t *) widget; 106 106 107 107 deinit_button(btn); 108 108 free(btn); … … 130 130 { 131 131 button_t *btn = (button_t *) widget; 132 132 133 133 if (event.key == KC_ENTER && event.type == KEY_PRESS) 134 134 sig_send(&btn->clicked, NULL); … … 139 139 button_t *btn = (button_t *) widget; 140 140 widget->window->focus = widget; 141 141 142 142 // TODO make the click logic more robust (mouse grabbing, mouse moves) 143 143 if (event.btn_num == 1) { … … 152 152 { 153 153 widget_init(&btn->widget, parent, data); 154 154 155 155 btn->widget.destroy = button_destroy; 156 156 btn->widget.reconfigure = button_reconfigure; … … 159 159 btn->widget.handle_keyboard_event = button_handle_keyboard_event; 160 160 btn->widget.handle_position_event = button_handle_position_event; 161 161 162 162 source_init(&btn->background); 163 163 source_set_color(&btn->background, background); 164 164 165 165 source_init(&btn->foreground); 166 166 source_set_color(&btn->foreground, foreground); 167 167 168 168 source_init(&btn->text); 169 169 source_set_color(&btn->text, text); 170 170 171 171 if (caption == NULL) 172 172 btn->caption = NULL; 173 173 else 174 174 btn->caption = str_dup(caption); 175 175 176 176 errno_t rc = embedded_font_create(&btn->font, points); 177 177 if (rc != EOK) { … … 180 180 return false; 181 181 } 182 182 183 183 sysarg_t cpt_width; 184 184 sysarg_t cpt_height; … … 188 188 btn->widget.width_ideal = cpt_width + 30; 189 189 btn->widget.height_ideal = cpt_height + 10; 190 190 191 191 return true; 192 192 } … … 198 198 if (!btn) 199 199 return NULL; 200 200 201 201 if (init_button(btn, parent, data, caption, points, background, foreground, 202 202 text)) 203 203 return btn; 204 204 205 205 free(btn); 206 206 return NULL; -
uspace/lib/gui/canvas.c
r3061bc1 ra35b458 45 45 { 46 46 canvas_t *canvas = (canvas_t *) widget; 47 47 48 48 surface_t *surface = window_claim(canvas->widget.window); 49 49 if (!surface) { 50 50 window_yield(canvas->widget.window); 51 51 } 52 52 53 53 transform_t transform; 54 54 transform_identity(&transform); 55 55 transform_translate(&transform, widget->hpos, widget->vpos); 56 56 57 57 source_t source; 58 58 source_init(&source); … … 60 60 source_set_texture(&source, canvas->surface, 61 61 PIXELMAP_EXTEND_TRANSPARENT_BLACK); 62 62 63 63 drawctx_t drawctx; 64 64 drawctx_init(&drawctx, surface); 65 65 66 66 drawctx_set_source(&drawctx, &source); 67 67 drawctx_transfer(&drawctx, widget->hpos, widget->vpos, widget->width, 68 68 widget->height); 69 69 70 70 window_yield(canvas->widget.window); 71 71 } … … 79 79 { 80 80 canvas_t *canvas = (canvas_t *) widget; 81 81 82 82 deinit_canvas(canvas); 83 83 free(canvas); … … 93 93 { 94 94 canvas_t *canvas = (canvas_t *) widget; 95 95 96 96 widget_modify(widget, hpos, vpos, canvas->width, canvas->height); 97 97 paint_internal(widget); … … 107 107 { 108 108 canvas_t *canvas = (canvas_t *) widget; 109 109 110 110 sig_send(&canvas->keyboard_event, &event); 111 111 } … … 115 115 canvas_t *canvas = (canvas_t *) widget; 116 116 pos_event_t tevent; 117 117 118 118 tevent = event; 119 119 tevent.hpos -= widget->hpos; 120 120 tevent.vpos -= widget->vpos; 121 121 122 122 sig_send(&canvas->position_event, &tevent); 123 123 } … … 127 127 { 128 128 widget_init(&canvas->widget, parent, data); 129 129 130 130 canvas->widget.width = width; 131 131 canvas->widget.height = height; 132 132 133 133 canvas->widget.width_min = width; 134 134 canvas->widget.height_min = height; … … 137 137 canvas->widget.width_max = width; 138 138 canvas->widget.height_max = height; 139 139 140 140 canvas->widget.destroy = canvas_destroy; 141 141 canvas->widget.reconfigure = canvas_reconfigure; … … 144 144 canvas->widget.handle_keyboard_event = canvas_handle_keyboard_event; 145 145 canvas->widget.handle_position_event = canvas_handle_position_event; 146 146 147 147 canvas->width = width; 148 148 canvas->height = height; 149 149 canvas->surface = surface; 150 150 151 151 return true; 152 152 } … … 156 156 if (surface != NULL) 157 157 canvas->surface = surface; 158 158 159 159 canvas_repaint(&canvas->widget); 160 160 return true; … … 167 167 if (!canvas) 168 168 return NULL; 169 169 170 170 if (init_canvas(canvas, parent, data, width, height, surface)) 171 171 return canvas; 172 172 173 173 free(canvas); 174 174 return NULL; -
uspace/lib/gui/common.c
r3061bc1 ra35b458 63 63 pixel_t pixel = (cross_texture[offset] & (1 << (x % 8))) ? 64 64 highlight : shadow; 65 65 66 66 if (visible) 67 67 surface_put_pixel(surface, hpos + x, vpos + y, pixel); … … 77 77 drawctx_transfer(drawctx, hpos, vpos, width - 1, 1); 78 78 drawctx_transfer(drawctx, hpos, vpos + 1, 1, height - 2); 79 79 80 80 source_set_color(source, shadow); 81 81 drawctx_transfer(drawctx, hpos, vpos + height - 1, width, 1); -
uspace/lib/gui/connection.c
r3061bc1 ra35b458 200 200 if (data != NULL) 201 201 data_copy = malloc(data_size); 202 202 203 203 if (data_copy != NULL) 204 204 memcpy(data_copy, data, data_size); 205 205 206 206 window_event_t *event = 207 207 (window_event_t *) malloc(sizeof(window_event_t)); 208 208 209 209 if (event) { 210 210 link_initialize(&event->link); -
uspace/lib/gui/grid.c
r3061bc1 ra35b458 51 51 { 52 52 grid_t *grid = (grid_t *) widget; 53 53 54 54 surface_t *surface = window_claim(grid->widget.window); 55 55 if (!surface) { … … 57 57 return; 58 58 } 59 59 60 60 // FIXME: Replace with (accelerated) rectangle fill 61 61 for (sysarg_t y = widget->vpos; y < widget->vpos + widget->height; y++) { … … 63 63 surface_put_pixel(surface, x, y, grid->background); 64 64 } 65 65 66 66 window_yield(grid->widget.window); 67 67 } … … 71 71 if ((col < grid->cols) && (row < grid->rows)) 72 72 return grid->layout + (row * grid->cols + col); 73 73 74 74 return NULL; 75 75 } … … 82 82 if (cell) { 83 83 widget_t *widget = cell->widget; 84 84 85 85 if ((widget) && (hpos >= widget->hpos) && 86 86 (vpos >= widget->vpos) && … … 91 91 } 92 92 } 93 93 94 94 return NULL; 95 95 } … … 104 104 { 105 105 grid_t *grid = (grid_t *) widget; 106 106 107 107 deinit_grid(grid); 108 108 free(grid); … … 118 118 { 119 119 assert(run > 0); 120 120 121 121 sysarg_t dim_min_part = dim_min / run; 122 122 sysarg_t dim_min_rem = dim_min % run; 123 123 124 124 sysarg_t dim_max_part = dim_max / run; 125 125 sysarg_t dim_max_rem = dim_max % run; 126 126 127 127 for (size_t i = 0; i < run; i++) { 128 128 sysarg_t dim_min_cur = dim_min_part; 129 129 sysarg_t dim_max_cur = dim_max_part; 130 130 131 131 if (i == run - 1) { 132 132 dim_min_cur += dim_min_rem; 133 133 dim_max_cur += dim_max_rem; 134 134 } 135 135 136 136 /* 137 137 * We want the strongest constraint … … 140 140 if (cons[i].min < dim_min_cur) 141 141 cons[i].min = dim_min_cur; 142 142 143 143 /* 144 144 * The comparison is correct, we want … … 155 155 /* Initial solution */ 156 156 sysarg_t cur_sum = 0; 157 157 158 158 for (size_t i = 0; i < run; i++) { 159 159 cons[i].val = cons[i].min; 160 160 cur_sum += cons[i].val; 161 161 } 162 162 163 163 /* Iterative improvement */ 164 164 while (cur_sum < sum) { … … 166 166 if (delta == 0) 167 167 break; 168 168 169 169 cur_sum = 0; 170 170 171 171 for (size_t i = 0; i < run; i++) { 172 172 if (cons[i].val + delta < cons[i].max) 173 173 cons[i].val += delta; 174 174 175 175 cur_sum += cons[i].val; 176 176 } … … 182 182 { 183 183 grid_t *grid = (grid_t *) widget; 184 184 185 185 widget_modify(widget, hpos, vpos, width, height); 186 186 paint_internal(widget); 187 187 188 188 /* Compute column widths */ 189 189 constraints_t *widths = … … 193 193 for (size_t c = 0; c < grid->cols; c++) { 194 194 widths[c].min = 0; 195 195 196 196 for (size_t r = 0; r < grid->rows; r++) { 197 197 grid_cell_t *cell = grid_cell_at(grid, c, r); 198 198 if (!cell) 199 199 continue; 200 200 201 201 widget_t *widget = cell->widget; 202 202 if (widget) … … 205 205 } 206 206 } 207 207 208 208 solve_constraints(widths, grid->cols, width); 209 209 } 210 210 211 211 /* Compute row heights */ 212 212 constraints_t *heights = … … 216 216 for (size_t r = 0; r < grid->rows; r++) { 217 217 heights[r].min = 0; 218 218 219 219 for (size_t c = 0; c < grid->cols; c++) { 220 220 grid_cell_t *cell = grid_cell_at(grid, c, r); 221 221 if (!cell) 222 222 continue; 223 223 224 224 widget_t *widget = cell->widget; 225 225 if (widget) { … … 229 229 } 230 230 } 231 231 232 232 solve_constraints(heights, grid->rows, height); 233 233 } 234 234 235 235 /* Rearrange widgets */ 236 236 if ((widths) && (heights)) { 237 237 sysarg_t cur_vpos = vpos; 238 238 239 239 for (size_t r = 0; r < grid->rows; r++) { 240 240 sysarg_t cur_hpos = hpos; 241 241 242 242 for (size_t c = 0; c < grid->cols; c++) { 243 243 grid_cell_t *cell = grid_cell_at(grid, c, r); 244 244 if (!cell) 245 245 continue; 246 246 247 247 widget_t *widget = cell->widget; 248 248 if (widget) { 249 249 sysarg_t cur_width = 0; 250 250 sysarg_t cur_height = 0; 251 251 252 252 for (size_t cd = 0; cd < cell->cols; cd++) 253 253 cur_width += widths[c + cd].val; 254 254 255 255 for (size_t rd = 0; rd < cell->rows; rd++) 256 256 cur_height += heights[r + rd].val; 257 257 258 258 if ((cur_width > 0) && (cur_height > 0)) { 259 259 sysarg_t wwidth = cur_width; 260 260 sysarg_t wheight = cur_height; 261 261 262 262 /* 263 263 * Make sure the widget is respects its 264 264 * maximal constrains. 265 265 */ 266 266 267 267 if ((widget->width_max > 0) && 268 268 (wwidth > widget->width_max)) 269 269 wwidth = widget->width_max; 270 270 271 271 if ((widget->height_max > 0) && 272 272 (wheight > widget->height_max)) 273 273 wheight = widget->height_max; 274 274 275 275 widget->rearrange(widget, cur_hpos, cur_vpos, 276 276 wwidth, wheight); 277 277 } 278 279 278 279 280 280 } 281 281 282 282 cur_hpos += widths[c].val; 283 283 } 284 284 285 285 cur_vpos += heights[r].val; 286 286 } 287 287 } 288 288 289 289 if (widths) 290 290 free(widths); 291 291 292 292 if (heights) 293 293 free(heights); … … 297 297 { 298 298 paint_internal(widget); 299 299 300 300 list_foreach(widget->children, link, widget_t, child) { 301 301 child->repaint(child); 302 302 } 303 303 304 304 window_damage(widget->window); 305 305 } … … 313 313 { 314 314 grid_t *grid = (grid_t *) widget; 315 315 316 316 grid_cell_t *cell = grid_coords_at(grid, event.hpos, event.vpos); 317 317 if ((cell) && (cell->widget)) … … 325 325 (row + rows > grid->rows)) 326 326 return false; 327 327 328 328 grid_cell_t *cell = grid_cell_at(grid, col, row); 329 329 if (!cell) 330 330 return false; 331 331 332 332 /* 333 333 * Check whether the cell is not occupied by an … … 336 336 if ((!cell->widget) && (cell->cols > 0) && (cell->rows > 0)) 337 337 return false; 338 338 339 339 widget->parent = (widget_t *) grid; 340 340 341 341 list_append(&widget->link, &grid->widget.children); 342 342 widget->window = grid->widget.window; 343 343 344 344 /* Mark cells in layout */ 345 345 for (size_t r = row; r < row + rows; r++) { … … 359 359 } 360 360 } 361 361 362 362 return true; 363 363 } … … 368 368 if ((cols == 0) || (rows == 0)) 369 369 return false; 370 370 371 371 grid->layout = 372 372 (grid_cell_t *) calloc(cols * rows, sizeof(grid_cell_t)); 373 373 if (!grid->layout) 374 374 return false; 375 375 376 376 memset(grid->layout, 0, cols * rows * sizeof(grid_cell_t)); 377 377 378 378 widget_init(&grid->widget, parent, data); 379 379 380 380 grid->widget.destroy = grid_destroy; 381 381 grid->widget.reconfigure = grid_reconfigure; … … 384 384 grid->widget.handle_keyboard_event = grid_handle_keyboard_event; 385 385 grid->widget.handle_position_event = grid_handle_position_event; 386 386 387 387 grid->add = grid_add; 388 388 grid->background = background; 389 389 grid->cols = cols; 390 390 grid->rows = rows; 391 391 392 392 return true; 393 393 } … … 399 399 if (!grid) 400 400 return NULL; 401 401 402 402 if (init_grid(grid, parent, data, cols, rows, background)) 403 403 return grid; 404 404 405 405 free(grid); 406 406 return NULL; -
uspace/lib/gui/label.c
r3061bc1 ra35b458 50 50 if (!surface) 51 51 window_yield(lbl->widget.window); 52 52 53 53 drawctx_t drawctx; 54 54 drawctx_init(&drawctx, surface); 55 55 56 56 drawctx_set_source(&drawctx, &lbl->background); 57 57 drawctx_transfer(&drawctx, widget->hpos, widget->vpos, widget->width, 58 58 widget->height); 59 59 60 60 sysarg_t cpt_width; 61 61 sysarg_t cpt_height; 62 62 font_get_box(lbl->font, lbl->caption, &cpt_width, &cpt_height); 63 63 64 64 if ((widget->width >= cpt_width) && (widget->height >= cpt_height)) { 65 65 sysarg_t x = ((widget->width - cpt_width) / 2) + widget->hpos; 66 66 sysarg_t y = ((widget->height - cpt_height) / 2) + widget->vpos; 67 67 68 68 drawctx_set_source(&drawctx, &lbl->text); 69 69 drawctx_set_font(&drawctx, lbl->font); 70 70 71 71 if (lbl->caption) 72 72 drawctx_print(&drawctx, lbl->caption, x, y); 73 73 } 74 74 75 75 window_yield(lbl->widget.window); 76 76 } … … 80 80 if (data != NULL) { 81 81 label_t *lbl = (label_t *) widget; 82 82 83 83 const char *new_caption = (const char *) data; 84 84 lbl->caption = str_dup(new_caption); 85 85 86 86 sysarg_t cpt_width; 87 87 sysarg_t cpt_height; 88 88 font_get_box(lbl->font, lbl->caption, &cpt_width, &cpt_height); 89 89 90 90 lbl->widget.width_min = cpt_width + 4; 91 91 lbl->widget.height_min = cpt_height + 4; 92 92 lbl->widget.width_ideal = lbl->widget.width_min; 93 93 lbl->widget.height_ideal = lbl->widget.height_min; 94 94 95 95 window_refresh(lbl->widget.window); 96 96 } … … 107 107 { 108 108 label_t *lbl = (label_t *) widget; 109 109 110 110 deinit_label(lbl); 111 111 free(lbl); … … 144 144 { 145 145 widget_init(&lbl->widget, parent, data); 146 146 147 147 lbl->widget.destroy = label_destroy; 148 148 lbl->widget.reconfigure = label_reconfigure; … … 151 151 lbl->widget.handle_keyboard_event = label_handle_keyboard_event; 152 152 lbl->widget.handle_position_event = label_handle_position_event; 153 153 154 154 source_init(&lbl->background); 155 155 source_set_color(&lbl->background, background); 156 156 157 157 source_init(&lbl->text); 158 158 source_set_color(&lbl->text, text); 159 159 160 160 if (caption == NULL) 161 161 lbl->caption = NULL; 162 162 else 163 163 lbl->caption = str_dup(caption); 164 164 165 165 errno_t rc = embedded_font_create(&lbl->font, points); 166 166 if (rc != EOK) { … … 169 169 return false; 170 170 } 171 171 172 172 sysarg_t cpt_width; 173 173 sysarg_t cpt_height; 174 174 font_get_box(lbl->font, lbl->caption, &cpt_width, &cpt_height); 175 175 176 176 lbl->widget.width_min = cpt_width + 4; 177 177 lbl->widget.height_min = cpt_height + 4; 178 178 lbl->widget.width_ideal = lbl->widget.width_min; 179 179 lbl->widget.height_ideal = lbl->widget.height_min; 180 180 181 181 lbl->rewrite = on_rewrite; 182 182 183 183 return true; 184 184 } … … 190 190 if (!lbl) 191 191 return NULL; 192 192 193 193 if (init_label(lbl, parent, data, caption, points, background, text)) 194 194 return lbl; 195 195 196 196 free(lbl); 197 197 return NULL; -
uspace/lib/gui/minimal.c
r3061bc1 ra35b458 66 66 } 67 67 } 68 68 69 69 window_yield(min->widget.window); 70 70 } -
uspace/lib/gui/terminal.c
r3061bc1 ra35b458 118 118 [COLOR_YELLOW] = PIXEL(255, 240, 240, 0), 119 119 [COLOR_WHITE] = PIXEL(255, 240, 240, 240), 120 120 121 121 [COLOR_BLACK + 8] = PIXEL(255, 0, 0, 0), 122 122 [COLOR_BLUE + 8] = PIXEL(255, 0, 0, 255), … … 170 170 charfield_t *field = 171 171 chargrid_charfield_at(term->backbuf, col, row); 172 172 173 173 bool inverted = chargrid_cursor_at(term->backbuf, col, row); 174 174 175 175 sysarg_t bx = sx + (col * FONT_WIDTH); 176 176 sysarg_t by = sy + (row * FONT_SCANLINES); 177 177 178 178 pixel_t bgcolor = 0; 179 179 pixel_t fgcolor = 0; 180 180 181 181 if (inverted) 182 182 attrs_rgb(field->attrs, &fgcolor, &bgcolor); 183 183 else 184 184 attrs_rgb(field->attrs, &bgcolor, &fgcolor); 185 185 186 186 // FIXME: Glyph type should be actually uint32_t 187 187 // for full UTF-32 coverage. 188 188 189 189 uint16_t glyph = fb_font_glyph(field->ch, NULL); 190 190 191 191 for (unsigned int y = 0; y < FONT_SCANLINES; y++) { 192 192 pixel_t *dst = pixelmap_pixel_at( … … 207 207 { 208 208 sysarg_t top_row = chargrid_get_top_row(term->frontbuf); 209 209 210 210 if (term->top_row == top_row) 211 211 return false; 212 212 213 213 term->top_row = top_row; 214 214 215 215 for (sysarg_t row = 0; row < term->rows; row++) { 216 216 for (sysarg_t col = 0; col < term->cols; col++) { … … 220 220 chargrid_charfield_at(term->backbuf, col, row); 221 221 bool update = false; 222 222 223 223 if (front_field->ch != back_field->ch) { 224 224 back_field->ch = front_field->ch; 225 225 update = true; 226 226 } 227 227 228 228 if (!attrs_same(front_field->attrs, back_field->attrs)) { 229 229 back_field->attrs = front_field->attrs; 230 230 update = true; 231 231 } 232 232 233 233 front_field->flags &= ~CHAR_FLAG_DIRTY; 234 234 235 235 if (update) 236 236 term_update_char(term, surface, sx, sy, col, row); 237 237 } 238 238 } 239 239 240 240 return true; 241 241 } … … 245 245 { 246 246 bool damage = false; 247 247 248 248 sysarg_t front_col; 249 249 sysarg_t front_row; 250 250 chargrid_get_cursor(term->frontbuf, &front_col, &front_row); 251 251 252 252 sysarg_t back_col; 253 253 sysarg_t back_row; 254 254 chargrid_get_cursor(term->backbuf, &back_col, &back_row); 255 255 256 256 bool front_visibility = 257 257 chargrid_get_cursor_visibility(term->frontbuf) && … … 259 259 bool back_visibility = 260 260 chargrid_get_cursor_visibility(term->backbuf); 261 261 262 262 if (front_visibility != back_visibility) { 263 263 chargrid_set_cursor_visibility(term->backbuf, … … 266 266 damage = true; 267 267 } 268 268 269 269 if ((front_col != back_col) || (front_row != back_row)) { 270 270 chargrid_set_cursor(term->backbuf, front_col, front_row); … … 273 273 damage = true; 274 274 } 275 275 276 276 return damage; 277 277 } … … 280 280 { 281 281 fibril_mutex_lock(&term->mtx); 282 282 283 283 surface_t *surface = window_claim(term->widget.window); 284 284 if (!surface) { … … 287 287 return; 288 288 } 289 289 290 290 bool damage = false; 291 291 sysarg_t sx = term->widget.hpos; 292 292 sysarg_t sy = term->widget.vpos; 293 293 294 294 if (term_update_scroll(term, surface, sx, sy)) { 295 295 damage = true; … … 302 302 chargrid_charfield_at(term->backbuf, x, y); 303 303 bool update = false; 304 304 305 305 if ((front_field->flags & CHAR_FLAG_DIRTY) == 306 306 CHAR_FLAG_DIRTY) { … … 309 309 update = true; 310 310 } 311 311 312 312 if (!attrs_same(front_field->attrs, 313 313 back_field->attrs)) { … … 315 315 update = true; 316 316 } 317 317 318 318 front_field->flags &= ~CHAR_FLAG_DIRTY; 319 319 } 320 320 321 321 if (update) { 322 322 term_update_char(term, surface, sx, sy, x, y); … … 326 326 } 327 327 } 328 328 329 329 if (term_update_cursor(term, surface, sx, sy)) 330 330 damage = true; 331 331 332 332 window_yield(term->widget.window); 333 333 334 334 if (damage) 335 335 window_damage(term->widget.window); 336 336 337 337 fibril_mutex_unlock(&term->mtx); 338 338 } … … 341 341 { 342 342 fibril_mutex_lock(&term->mtx); 343 343 344 344 surface_t *surface = window_claim(term->widget.window); 345 345 if (!surface) { … … 348 348 return; 349 349 } 350 350 351 351 sysarg_t sx = term->widget.hpos; 352 352 sysarg_t sy = term->widget.vpos; 353 353 354 354 if (!term_update_scroll(term, surface, sx, sy)) { 355 355 for (sysarg_t y = 0; y < term->rows; y++) { … … 359 359 charfield_t *back_field = 360 360 chargrid_charfield_at(term->backbuf, x, y); 361 361 362 362 back_field->ch = front_field->ch; 363 363 back_field->attrs = front_field->attrs; 364 364 front_field->flags &= ~CHAR_FLAG_DIRTY; 365 365 366 366 term_update_char(term, surface, sx, sy, x, y); 367 367 } 368 368 } 369 369 } 370 370 371 371 term_update_cursor(term, surface, sx, sy); 372 372 373 373 window_yield(term->widget.window); 374 374 window_damage(term->widget.window); 375 375 376 376 fibril_mutex_unlock(&term->mtx); 377 377 } … … 392 392 uint8_t *bbuf = buf; 393 393 size_t pos = 0; 394 394 395 395 /* 396 396 * Read input from keyboard and copy it to the buffer. … … 403 403 bbuf[pos] = term->char_remains[0]; 404 404 pos++; 405 405 406 406 /* Unshift the array. */ 407 407 for (size_t i = 1; i < term->char_remains_len; i++) 408 408 term->char_remains[i - 1] = term->char_remains[i]; 409 409 410 410 term->char_remains_len--; 411 411 } 412 412 413 413 /* Still not enough? Then get another key from the queue. */ 414 414 if (pos < size) { 415 415 link_t *link = prodcons_consume(&term->input_pc); 416 416 cons_event_t *event = list_get_instance(link, cons_event_t, link); 417 417 418 418 /* Accept key presses of printable chars only. */ 419 419 if (event->type == CEV_KEY && event->ev.key.type == KEY_PRESS && … … 423 423 0 424 424 }; 425 425 426 426 wstr_to_str(term->char_remains, UTF8_CHAR_BUFFER_SIZE, tmp); 427 427 term->char_remains_len = str_size(term->char_remains); 428 428 } 429 429 430 430 free(event); 431 431 } 432 432 } 433 433 434 434 *nread = size; 435 435 return EOK; … … 439 439 { 440 440 sysarg_t updated = 0; 441 442 fibril_mutex_lock(&term->mtx); 443 441 442 fibril_mutex_lock(&term->mtx); 443 444 444 switch (ch) { 445 445 case '\n': … … 457 457 updated = chargrid_putchar(term->frontbuf, ch, true); 458 458 } 459 460 fibril_mutex_unlock(&term->mtx); 461 459 460 fibril_mutex_unlock(&term->mtx); 461 462 462 if (updated > 1) 463 463 term_update(term); … … 467 467 { 468 468 terminal_t *term = srv_to_terminal(srv); 469 469 470 470 size_t off = 0; 471 471 while (off < size) 472 472 term_write_char(term, str_decode(data, &off, size)); 473 473 474 474 *nwritten = size; 475 475 return EOK; … … 479 479 { 480 480 terminal_t *term = srv_to_terminal(srv); 481 481 482 482 term_update(term); 483 483 } … … 486 486 { 487 487 terminal_t *term = srv_to_terminal(srv); 488 488 489 489 fibril_mutex_lock(&term->mtx); 490 490 chargrid_clear(term->frontbuf); 491 491 fibril_mutex_unlock(&term->mtx); 492 492 493 493 term_update(term); 494 494 } … … 497 497 { 498 498 terminal_t *term = srv_to_terminal(srv); 499 499 500 500 fibril_mutex_lock(&term->mtx); 501 501 chargrid_set_cursor(term->frontbuf, col, row); 502 502 fibril_mutex_unlock(&term->mtx); 503 503 504 504 term_update(term); 505 505 } … … 508 508 { 509 509 terminal_t *term = srv_to_terminal(srv); 510 510 511 511 fibril_mutex_lock(&term->mtx); 512 512 chargrid_get_cursor(term->frontbuf, col, row); 513 513 fibril_mutex_unlock(&term->mtx); 514 514 515 515 return EOK; 516 516 } … … 519 519 { 520 520 terminal_t *term = srv_to_terminal(srv); 521 521 522 522 fibril_mutex_lock(&term->mtx); 523 523 *cols = term->cols; 524 524 *rows = term->rows; 525 525 fibril_mutex_unlock(&term->mtx); 526 526 527 527 return EOK; 528 528 } … … 532 532 (void) srv; 533 533 *caps = TERM_CAPS; 534 534 535 535 return EOK; 536 536 } … … 539 539 { 540 540 terminal_t *term = srv_to_terminal(srv); 541 541 542 542 fibril_mutex_lock(&term->mtx); 543 543 chargrid_set_style(term->frontbuf, style); … … 549 549 { 550 550 terminal_t *term = srv_to_terminal(srv); 551 551 552 552 fibril_mutex_lock(&term->mtx); 553 553 chargrid_set_color(term->frontbuf, bgcolor, fgcolor, attr); … … 559 559 { 560 560 terminal_t *term = srv_to_terminal(srv); 561 561 562 562 fibril_mutex_lock(&term->mtx); 563 563 chargrid_set_rgb_color(term->frontbuf, bgcolor, fgcolor); … … 568 568 { 569 569 terminal_t *term = srv_to_terminal(srv); 570 570 571 571 fibril_mutex_lock(&term->mtx); 572 572 chargrid_set_cursor_visibility(term->frontbuf, visible); 573 573 fibril_mutex_unlock(&term->mtx); 574 574 575 575 term_update(term); 576 576 } … … 581 581 link_t *link = prodcons_consume(&term->input_pc); 582 582 cons_event_t *ev = list_get_instance(link, cons_event_t, link); 583 583 584 584 *event = *ev; 585 585 free(ev); … … 591 591 list_remove(&term->link); 592 592 widget_deinit(&term->widget); 593 593 594 594 if (term->frontbuf) 595 595 chargrid_destroy(term->frontbuf); 596 596 597 597 if (term->backbuf) 598 598 chargrid_destroy(term->backbuf); … … 602 602 { 603 603 terminal_t *term = (terminal_t *) widget; 604 604 605 605 deinit_terminal(term); 606 606 free(term); … … 616 616 { 617 617 terminal_t *term = (terminal_t *) widget; 618 618 619 619 widget_modify(widget, hpos, vpos, width, height); 620 620 widget->width_ideal = width; 621 621 widget->height_ideal = height; 622 622 623 623 term_damage(term); 624 624 } … … 627 627 { 628 628 terminal_t *term = (terminal_t *) widget; 629 629 630 630 term_damage(term); 631 631 } … … 638 638 if (event == NULL) 639 639 return; 640 640 641 641 *event = *ev; 642 642 link_initialize(&event->link); 643 643 644 644 prodcons_produce(&term->input_pc, &event->link); 645 645 } … … 651 651 terminal_t *term = (terminal_t *) widget; 652 652 cons_event_t event; 653 653 654 654 event.type = CEV_KEY; 655 655 event.ev.key = kbd_event; 656 656 657 657 terminal_queue_cons_event(term, &event); 658 658 } … … 680 680 { 681 681 terminal_t *term = NULL; 682 682 683 683 list_foreach(terms, link, terminal_t, cur) { 684 684 if (cur->dsid == (service_id_t) IPC_GET_ARG2(*icall)) { … … 687 687 } 688 688 } 689 689 690 690 if (term == NULL) { 691 691 async_answer_0(iid, ENOENT); 692 692 return; 693 693 } 694 694 695 695 if (atomic_postinc(&term->refcnt) == 0) 696 696 chargrid_set_cursor_visibility(term->frontbuf, true); 697 697 698 698 con_conn(iid, icall, &term->srvs); 699 699 } … … 703 703 { 704 704 widget_init(&term->widget, parent, data); 705 705 706 706 link_initialize(&term->link); 707 707 fibril_mutex_initialize(&term->mtx); 708 708 atomic_set(&term->refcnt, 0); 709 709 710 710 prodcons_initialize(&term->input_pc); 711 711 term->char_remains_len = 0; 712 712 713 713 term->widget.width = width; 714 714 term->widget.height = height; 715 715 term->widget.width_ideal = width; 716 716 term->widget.height_ideal = height; 717 717 718 718 term->widget.destroy = terminal_destroy; 719 719 term->widget.reconfigure = terminal_reconfigure; … … 722 722 term->widget.handle_keyboard_event = terminal_handle_keyboard_event; 723 723 term->widget.handle_position_event = terminal_handle_position_event; 724 724 725 725 term->cols = width / FONT_WIDTH; 726 726 term->rows = height / FONT_SCANLINES; 727 727 728 728 term->frontbuf = NULL; 729 729 term->backbuf = NULL; 730 730 731 731 term->frontbuf = chargrid_create(term->cols, term->rows, 732 732 CHARGRID_FLAG_NONE); … … 735 735 return false; 736 736 } 737 737 738 738 term->backbuf = chargrid_create(term->cols, term->rows, 739 739 CHARGRID_FLAG_NONE); … … 742 742 return false; 743 743 } 744 744 745 745 chargrid_clear(term->frontbuf); 746 746 chargrid_clear(term->backbuf); 747 747 term->top_row = 0; 748 748 749 749 async_set_fallback_port_handler(term_connection, NULL); 750 750 con_srvs_init(&term->srvs); 751 751 term->srvs.ops = &con_ops; 752 752 term->srvs.sarg = term; 753 753 754 754 errno_t rc = loc_server_register(NAME); 755 755 if (rc != EOK) { … … 757 757 return false; 758 758 } 759 759 760 760 char vc[LOC_NAME_MAXLEN + 1]; 761 761 snprintf(vc, LOC_NAME_MAXLEN, "%s/%" PRIu64, NAMESPACE, 762 762 task_get_id()); 763 763 764 764 rc = loc_service_register(vc, &term->dsid); 765 765 if (rc != EOK) { … … 767 767 return false; 768 768 } 769 769 770 770 list_append(&term->link, &terms); 771 771 getterm(vc, "/app/bdsh"); 772 772 773 773 return true; 774 774 } … … 780 780 if (!term) 781 781 return NULL; 782 782 783 783 bool ret = init_terminal(term, parent, data, width, height); 784 784 if (!ret) { … … 786 786 return NULL; 787 787 } 788 788 789 789 return term; 790 790 } -
uspace/lib/gui/terminal.h
r3061bc1 ra35b458 52 52 typedef struct terminal { 53 53 widget_t widget; 54 54 55 55 fibril_mutex_t mtx; 56 56 link_t link; 57 57 atomic_t refcnt; 58 58 59 59 prodcons_t input_pc; 60 60 char char_remains[UTF8_CHAR_BUFFER_SIZE]; 61 61 size_t char_remains_len; 62 62 63 63 sysarg_t cols; 64 64 sysarg_t rows; … … 66 66 chargrid_t *backbuf; 67 67 sysarg_t top_row; 68 68 69 69 service_id_t dsid; 70 70 con_srvs_t srvs; -
uspace/lib/gui/widget.c
r3061bc1 ra35b458 41 41 link_initialize(&widget->link); 42 42 list_initialize(&widget->children); 43 43 44 44 if (parent) { 45 45 widget->parent = parent; … … 50 50 widget->window = NULL; 51 51 } 52 52 53 53 widget->data = data; 54 54 55 55 widget->hpos = 0; 56 56 widget->vpos = 0; 57 57 widget->width = 0; 58 58 widget->height = 0; 59 59 60 60 widget->width_min = 0; 61 61 widget->height_min = 0; -
uspace/lib/gui/widget.h
r3061bc1 ra35b458 56 56 window_t *window; /**< Window into which this widget belongs. */ 57 57 const void *data; /**< Custom client data. */ 58 58 59 59 sysarg_t hpos; /**< Horizontal position in window coordinates. */ 60 60 sysarg_t vpos; /**< Vertical position in window coordinates. */ 61 61 sysarg_t width; 62 62 sysarg_t height; 63 63 64 64 sysarg_t width_min; 65 65 sysarg_t height_min; -
uspace/lib/gui/window.c
r3061bc1 ra35b458 89 89 if (!surface) 90 90 window_yield(widget->window); 91 91 92 92 source_t source; 93 93 source_init(&source); 94 94 95 95 drawctx_t drawctx; 96 96 drawctx_init(&drawctx, surface); 97 97 drawctx_set_source(&drawctx, &source); 98 98 99 99 /* Window border outer bevel */ 100 100 101 101 draw_bevel(&drawctx, &source, widget->vpos, widget->hpos, 102 102 widget->width, widget->height, color_highlight, color_shadow); 103 103 104 104 /* Window border surface */ 105 105 106 106 source_set_color(&source, color_surface); 107 107 drawctx_transfer(&drawctx, widget->hpos + 1, widget->vpos + 1, … … 113 113 drawctx_transfer(&drawctx, widget->hpos + widget->width - 3, 114 114 widget->vpos + 1, 2, widget->height - 4); 115 115 116 116 /* Window border inner bevel */ 117 117 118 118 draw_bevel(&drawctx, &source, widget->hpos + 3, widget->vpos + 3, 119 119 widget->width - 6, widget->height - 6, color_shadow, 120 120 color_highlight); 121 121 122 122 /* Header bevel */ 123 123 124 124 sysarg_t header_hpos = widget->hpos + border_thickness; 125 125 sysarg_t header_vpos = widget->vpos + border_thickness; 126 126 sysarg_t header_width = widget->width - 2 * border_thickness - 127 127 close_thickness; 128 128 129 129 draw_bevel(&drawctx, &source, header_hpos, header_vpos, 130 130 header_width, header_height, widget->window->is_focused ? … … 132 132 widget->window->is_focused ? 133 133 color_header_focus_shadow : color_header_unfocus_shadow); 134 134 135 135 /* Header surface */ 136 136 137 137 source_set_color(&source, widget->window->is_focused ? 138 138 color_header_focus_surface : color_header_unfocus_surface); 139 139 drawctx_transfer(&drawctx, header_hpos + 1, header_vpos + 1, 140 140 header_width - 2, header_height - 2); 141 141 142 142 /* Close button bevel */ 143 143 144 144 sysarg_t close_hpos = widget->hpos + widget->width - 145 145 border_thickness - close_thickness; 146 146 sysarg_t close_vpos = widget->vpos + border_thickness; 147 147 148 148 draw_bevel(&drawctx, &source, close_hpos, close_vpos, 149 149 close_thickness, close_thickness, color_highlight, color_shadow); 150 150 151 151 /* Close button surface */ 152 152 153 153 source_set_color(&source, color_surface); 154 154 drawctx_transfer(&drawctx, close_hpos + 1, close_vpos + 1, 155 155 close_thickness - 2, close_thickness - 2); 156 156 157 157 /* Close button icon */ 158 158 159 159 draw_icon_cross(surface, close_hpos + 3, close_vpos + 3, 160 160 color_highlight, color_shadow); 161 161 162 162 /* Window caption */ 163 163 164 164 font_t *font; 165 165 errno_t rc = embedded_font_create(&font, 16); … … 168 168 return; 169 169 } 170 170 171 171 drawctx_set_font(&drawctx, font); 172 172 source_set_color(&source, widget->window->is_focused ? 173 173 color_caption_focus : color_caption_unfocus); 174 174 175 175 sysarg_t cpt_width; 176 176 sysarg_t cpt_height; 177 177 font_get_box(font, widget->window->caption, &cpt_width, &cpt_height); 178 178 179 179 bool draw_title = 180 180 (widget->width >= 2 * border_thickness + 2 * bevel_thickness + … … 184 184 sysarg_t cpt_y = ((header_height - cpt_height) / 2) + 185 185 widget->vpos + border_thickness; 186 186 187 187 if (widget->window->caption) 188 188 drawctx_print(&drawctx, widget->window->caption, cpt_x, cpt_y); 189 189 } 190 190 191 191 font_release(font); 192 192 window_yield(widget->window); … … 375 375 return; 376 376 } 377 377 378 378 if (height < 2 * border_thickness + header_height) { 379 379 win_damage(win->osess, 0, 0, 0, 0); 380 380 return; 381 381 } 382 382 383 383 /* Allocate resources for new surface. */ 384 384 surface_t *new_surface = surface_create(width, height, NULL, … … 386 386 if (!new_surface) 387 387 return; 388 388 389 389 /* Switch new and old surface. */ 390 390 fibril_mutex_lock(&win->guard); … … 392 392 win->surface = new_surface; 393 393 fibril_mutex_unlock(&win->guard); 394 394 395 395 /* 396 396 * Let all widgets in the tree alter their position and size. … … 398 398 */ 399 399 win->root.rearrange(&win->root, 0, 0, width, height); 400 400 401 401 fibril_mutex_lock(&win->guard); 402 402 surface_reset_damaged_region(win->surface); 403 403 fibril_mutex_unlock(&win->guard); 404 404 405 405 /* Inform compositor about new surface. */ 406 406 errno_t rc = win_resize(win->osess, offset_x, offset_y, width, height, 407 407 placement_flags, surface_direct_access(new_surface)); 408 408 409 409 if (rc != EOK) { 410 410 /* Rollback to old surface. Reverse all changes. */ 411 411 412 412 sysarg_t old_width = 0; 413 413 sysarg_t old_height = 0; 414 414 if (old_surface) 415 415 surface_get_resolution(old_surface, &old_width, &old_height); 416 416 417 417 fibril_mutex_lock(&win->guard); 418 418 new_surface = win->surface; 419 419 win->surface = old_surface; 420 420 fibril_mutex_unlock(&win->guard); 421 421 422 422 win->root.rearrange(&win->root, 0, 0, old_width, old_height); 423 423 424 424 if (win->surface) { 425 425 fibril_mutex_lock(&win->guard); … … 427 427 fibril_mutex_unlock(&win->guard); 428 428 } 429 429 430 430 surface_destroy(new_surface); 431 431 } else { … … 569 569 while (true) { 570 570 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t)); 571 571 572 572 if (event) { 573 573 rc = win_get_event(win->isess, event); … … 598 598 if (!win) 599 599 return NULL; 600 600 601 601 win->is_main = flags & WINDOW_MAIN; 602 602 win->is_decorated = flags & WINDOW_DECORATED; … … 604 604 prodcons_initialize(&win->events); 605 605 fibril_mutex_initialize(&win->guard); 606 606 607 607 widget_init(&win->root, NULL, data); 608 608 win->root.window = win; … … 616 616 win->focus = NULL; 617 617 win->surface = NULL; 618 618 619 619 service_id_t reg_dsid; 620 620 errno_t rc = loc_service_get_id(winreg, ®_dsid, 0); … … 623 623 return NULL; 624 624 } 625 625 626 626 async_sess_t *reg_sess = 627 627 loc_service_connect(reg_dsid, INTERFACE_COMPOSITOR, 0); … … 630 630 return NULL; 631 631 } 632 632 633 633 service_id_t in_dsid; 634 634 service_id_t out_dsid; … … 639 639 return NULL; 640 640 } 641 641 642 642 win->osess = loc_service_connect(out_dsid, INTERFACE_COMPOSITOR, 0); 643 643 if (win->osess == NULL) { … … 645 645 return NULL; 646 646 } 647 647 648 648 win->isess = loc_service_connect(in_dsid, INTERFACE_COMPOSITOR, 0); 649 649 if (win->isess == NULL) { … … 652 652 return NULL; 653 653 } 654 654 655 655 if (caption == NULL) 656 656 win->caption = NULL; 657 657 else 658 658 win->caption = str_dup(caption); 659 659 660 660 return win; 661 661 } … … 680 680 { 681 681 char *cap; 682 682 683 683 if (caption == NULL) { 684 684 win->caption = NULL; … … 690 690 win->caption = cap; 691 691 } 692 692 693 693 win->is_focused = false; 694 694 handle_refresh(win); 695 695 696 696 return EOK; 697 697 }
Note:
See TracChangeset
for help on using the changeset viewer.