Changes in uspace/lib/gui/window.c [6d5e378:2cc1ec0] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/gui/window.c
r6d5e378 r2cc1ec0 34 34 */ 35 35 36 #include < bool.h>36 #include <stdbool.h> 37 37 #include <errno.h> 38 38 #include <stdio.h> … … 55 55 #include <drawctx.h> 56 56 #include <surface.h> 57 57 #include <font/embedded.h> 58 59 #include "common.h" 58 60 #include "connection.h" 59 61 #include "widget.h" 60 62 #include "window.h" 61 63 62 static sysarg_t border_thickness = 5; 64 static sysarg_t border_thickness = 4; 65 static sysarg_t bevel_thickness = 1; 63 66 static sysarg_t header_height = 20; 64 67 static sysarg_t header_min_width = 40; 65 static sysarg_t close_width = 20; 66 67 static pixel_t border_color = PIXEL(255, 0, 0, 0); 68 static pixel_t header_bgcolor = PIXEL(255, 25, 25, 112); 69 static pixel_t header_fgcolor = PIXEL(255, 255, 255, 255); 70 71 static void paint_internal(widget_t *w) 72 { 73 surface_t *surface = window_claim(w->window); 74 if (!surface) { 75 window_yield(w->window); 76 } 77 68 static sysarg_t close_thickness = 20; 69 70 static pixel_t color_highlight = PIXEL(255, 255, 255, 255); 71 static pixel_t color_shadow = PIXEL(255, 85, 85, 85); 72 static pixel_t color_surface = PIXEL(255, 186, 186, 186); 73 74 static pixel_t color_header_focus_highlight = PIXEL(255, 120, 145, 255); 75 static pixel_t color_header_focus_shadow = PIXEL(255, 40, 48, 89); 76 static pixel_t color_header_focus_surface = PIXEL(255, 88, 106, 196); 77 78 static pixel_t color_header_unfocus_highlight = PIXEL(255, 16, 78, 126); 79 static pixel_t color_header_unfocus_shadow = PIXEL(255, 5, 26, 42); 80 static pixel_t color_header_unfocus_surface = PIXEL(255, 12, 57, 92); 81 82 static pixel_t color_caption_focus = PIXEL(255, 255, 255, 255); 83 static pixel_t color_caption_unfocus = PIXEL(255, 207, 207, 207); 84 85 static void paint_internal(widget_t *widget) 86 { 87 surface_t *surface = window_claim(widget->window); 88 if (!surface) 89 window_yield(widget->window); 90 78 91 source_t source; 79 font_t font; 92 source_init(&source); 93 80 94 drawctx_t drawctx; 81 82 source_init(&source);83 font_init(&font, FONT_DECODER_EMBEDDED, NULL, 16);84 95 drawctx_init(&drawctx, surface); 85 96 drawctx_set_source(&drawctx, &source); 86 drawctx_set_font(&drawctx, &font); 87 88 source_set_color(&source, border_color); 89 drawctx_transfer(&drawctx, w->hpos, w->vpos, border_thickness, w->height); 90 drawctx_transfer(&drawctx, w->hpos + w->width - border_thickness, 91 w->vpos, border_thickness, w->height); 92 drawctx_transfer(&drawctx, w->hpos, w->vpos, w->width, border_thickness); 93 drawctx_transfer(&drawctx, w->hpos, 94 w->vpos + w->height - border_thickness, w->width, border_thickness); 95 96 source_set_color(&source, header_bgcolor); 97 drawctx_transfer(&drawctx, 98 w->hpos + border_thickness, w->vpos + border_thickness, 99 w->width - 2 * border_thickness, header_height); 100 97 98 /* Window border outer bevel */ 99 100 draw_bevel(&drawctx, &source, widget->vpos, widget->hpos, 101 widget->width, widget->height, color_highlight, color_shadow); 102 103 /* Window border surface */ 104 105 source_set_color(&source, color_surface); 106 drawctx_transfer(&drawctx, widget->hpos + 1, widget->vpos + 1, 107 widget->width - 2, 2); 108 drawctx_transfer(&drawctx, widget->hpos + 1, widget->vpos + 1, 109 2, widget->height - 2); 110 drawctx_transfer(&drawctx, widget->hpos + 1, 111 widget->vpos + widget->height - 3, widget->width - 2, 2); 112 drawctx_transfer(&drawctx, widget->hpos + widget->width - 3, 113 widget->vpos + 1, 2, widget->height - 4); 114 115 /* Window border inner bevel */ 116 117 draw_bevel(&drawctx, &source, widget->hpos + 3, widget->vpos + 3, 118 widget->width - 6, widget->height - 6, color_shadow, 119 color_highlight); 120 121 /* Header bevel */ 122 123 sysarg_t header_hpos = widget->hpos + border_thickness; 124 sysarg_t header_vpos = widget->vpos + border_thickness; 125 sysarg_t header_width = widget->width - 2 * border_thickness - 126 close_thickness; 127 128 draw_bevel(&drawctx, &source, header_hpos, header_vpos, 129 header_width, header_height, widget->window->is_focused ? 130 color_header_focus_highlight : color_header_unfocus_highlight, 131 widget->window->is_focused ? 132 color_header_focus_shadow : color_header_unfocus_shadow); 133 134 /* Header surface */ 135 136 source_set_color(&source, widget->window->is_focused ? 137 color_header_focus_surface : color_header_unfocus_surface); 138 drawctx_transfer(&drawctx, header_hpos + 1, header_vpos + 1, 139 header_width - 2, header_height - 2); 140 141 /* Close button bevel */ 142 143 sysarg_t close_hpos = widget->hpos + widget->width - 144 border_thickness - close_thickness; 145 sysarg_t close_vpos = widget->vpos + border_thickness; 146 147 draw_bevel(&drawctx, &source, close_hpos, close_vpos, 148 close_thickness, close_thickness, color_highlight, color_shadow); 149 150 /* Close button surface */ 151 152 source_set_color(&source, color_surface); 153 drawctx_transfer(&drawctx, close_hpos + 1, close_vpos + 1, 154 close_thickness - 2, close_thickness - 2); 155 156 /* Close button icon */ 157 158 draw_icon_cross(surface, close_hpos + 3, close_vpos + 3, 159 color_highlight, color_shadow); 160 161 /* Window caption */ 162 163 font_t *font; 164 int rc = embedded_font_create(&font, 16); 165 if (rc != EOK) { 166 window_yield(widget->window); 167 return; 168 } 169 170 drawctx_set_font(&drawctx, font); 171 source_set_color(&source, widget->window->is_focused ? 172 color_caption_focus : color_caption_unfocus); 173 101 174 sysarg_t cpt_width; 102 175 sysarg_t cpt_height; 103 font_get_box(&font, w->window->caption, &cpt_width, &cpt_height); 104 sysarg_t cls_width; 105 sysarg_t cls_height; 106 char cls_pict[] = "x"; 107 font_get_box(&font, cls_pict, &cls_width, &cls_height); 108 source_set_color(&source, header_fgcolor); 109 sysarg_t cls_x = ((close_width - cls_width) / 2) + w->hpos + w->width - 110 border_thickness - close_width; 111 sysarg_t cls_y = ((header_height - cls_height) / 2) + w->vpos + border_thickness; 112 drawctx_print(&drawctx, cls_pict, cls_x, cls_y); 113 114 bool draw_title = (w->width >= 2 * border_thickness + close_width + cpt_width); 176 font_get_box(font, widget->window->caption, &cpt_width, &cpt_height); 177 178 bool draw_title = 179 (widget->width >= 2 * border_thickness + 2 * bevel_thickness + 180 close_thickness + cpt_width); 115 181 if (draw_title) { 116 sysarg_t cpt_x = ((w->width - cpt_width) / 2) + w->hpos; 117 sysarg_t cpt_y = ((header_height - cpt_height) / 2) + w->vpos + border_thickness; 118 if (w->window->caption) { 119 drawctx_print(&drawctx, w->window->caption, cpt_x, cpt_y); 120 } 121 } 122 123 font_release(&font); 124 window_yield(w->window); 182 sysarg_t cpt_x = ((widget->width - cpt_width) / 2) + widget->hpos; 183 sysarg_t cpt_y = ((header_height - cpt_height) / 2) + 184 widget->vpos + border_thickness; 185 186 if (widget->window->caption) 187 drawctx_print(&drawctx, widget->window->caption, cpt_x, cpt_y); 188 } 189 190 font_release(font); 191 window_yield(widget->window); 125 192 } 126 193 … … 133 200 { 134 201 if (widget->window->is_decorated) { 135 list_foreach(widget->children, link) { 136 widget_t *child = list_get_instance(link, widget_t, link); 137 child->rearrange(child, 202 list_foreach(widget->children, link, widget_t, child) { 203 child->rearrange(child, 138 204 widget->hpos + border_thickness, 139 205 widget->vpos + border_thickness + header_height, … … 142 208 } 143 209 } else { 144 list_foreach(widget->children, link) { 145 widget_t *child = list_get_instance(link, widget_t, link); 210 list_foreach(widget->children, link, widget_t, child) { 146 211 child->rearrange(child, widget->hpos, widget->vpos, 147 212 widget->width, widget->height); … … 156 221 if (widget->window->is_decorated) { 157 222 paint_internal(widget); 158 list_foreach(widget->children, link) { 159 widget_t *child = list_get_instance(link, widget_t, link); 223 list_foreach(widget->children, link, widget_t, child) { 160 224 child->rearrange(child, 161 225 hpos + border_thickness, … … 165 229 } 166 230 } else { 167 list_foreach(widget->children, link) { 168 widget_t *child = list_get_instance(link, widget_t, link); 231 list_foreach(widget->children, link, widget_t, child) { 169 232 child->rearrange(child, hpos, vpos, width, height); 170 233 } … … 177 240 paint_internal(widget); 178 241 } 179 list_foreach(widget->children, link) { 180 widget_t *child = list_get_instance(link, widget_t, link); 242 list_foreach(widget->children, link, widget_t, child) { 181 243 child->repaint(child); 182 244 } … … 212 274 (event.vpos >= border_thickness) && 213 275 (event.vpos < border_thickness + header_height); 214 bool close = header && (event.hpos >= width - border_thickness - close_width); 276 bool close = (header) && 277 (event.hpos >= width - border_thickness - close_thickness); 215 278 216 279 if (top && left && allowed_button) { … … 264 327 win_grab(widget->window->osess, event.pos_id, flags); 265 328 } else { 266 list_foreach(widget->children, link) { 267 widget_t *child = list_get_instance(link, widget_t, link); 329 list_foreach(widget->children, link, widget_t, child) { 268 330 child->handle_position_event(child, event); 269 331 } 270 332 } 271 333 } else { 272 list_foreach(widget->children, link) { 273 widget_t *child = list_get_instance(link, widget_t, link); 334 list_foreach(widget->children, link, widget_t, child) { 274 335 child->handle_position_event(child, event); 275 336 } … … 295 356 } 296 357 297 static void handle_signal_event(window_t *win, sig _event_t event)358 static void handle_signal_event(window_t *win, signal_event_t event) 298 359 { 299 360 widget_t *widget = (widget_t *) event.object; … … 306 367 } 307 368 308 static void handle_resize(window_t *win, sysarg_t width, sysarg_t height) 309 { 310 int rc; 311 surface_t *old_surface; 312 surface_t *new_surface; 313 369 static void handle_resize(window_t *win, sysarg_t offset_x, sysarg_t offset_y, 370 sysarg_t width, sysarg_t height, window_placement_flags_t placement_flags) 371 { 314 372 if (width < 2 * border_thickness + header_min_width) { 315 373 win_damage(win->osess, 0, 0, 0, 0); 316 374 return; 317 375 } 318 376 319 377 if (height < 2 * border_thickness + header_height) { 320 378 win_damage(win->osess, 0, 0, 0, 0); 321 379 return; 322 380 } 323 381 324 382 /* Allocate resources for new surface. */ 325 new_surface = surface_create(width, height, NULL, SURFACE_FLAG_SHARED); 326 if (!new_surface) { 383 surface_t *new_surface = surface_create(width, height, NULL, 384 SURFACE_FLAG_SHARED); 385 if (!new_surface) 327 386 return; 328 } 329 387 330 388 /* Switch new and old surface. */ 331 389 fibril_mutex_lock(&win->guard); 332 old_surface = win->surface;390 surface_t *old_surface = win->surface; 333 391 win->surface = new_surface; 334 392 fibril_mutex_unlock(&win->guard); 335 336 /* Let all widgets in the tree alter their position and size. Widgets might 337 * also paint themselves onto the new surface. */ 393 394 /* 395 * Let all widgets in the tree alter their position and size. 396 * Widgets might also paint themselves onto the new surface. 397 */ 338 398 win->root.rearrange(&win->root, 0, 0, width, height); 339 399 340 400 fibril_mutex_lock(&win->guard); 341 401 surface_reset_damaged_region(win->surface); 342 402 fibril_mutex_unlock(&win->guard); 343 403 344 404 /* Inform compositor about new surface. */ 345 rc = win_resize(win->osess,346 width, height, surface_direct_access(new_surface));347 405 int rc = win_resize(win->osess, offset_x, offset_y, width, height, 406 placement_flags, surface_direct_access(new_surface)); 407 348 408 if (rc != EOK) { 349 409 /* Rollback to old surface. Reverse all changes. */ 350 410 351 411 sysarg_t old_width = 0; 352 412 sysarg_t old_height = 0; 353 if (old_surface) {413 if (old_surface) 354 414 surface_get_resolution(old_surface, &old_width, &old_height); 355 } 356 415 357 416 fibril_mutex_lock(&win->guard); 358 417 new_surface = win->surface; 359 418 win->surface = old_surface; 360 419 fibril_mutex_unlock(&win->guard); 361 420 362 421 win->root.rearrange(&win->root, 0, 0, old_width, old_height); 363 422 … … 367 426 fibril_mutex_unlock(&win->guard); 368 427 } 369 428 370 429 surface_destroy(new_surface); 371 return; 372 } 373 374 /* Finally deallocate old surface. */ 375 if (old_surface) { 376 surface_destroy(old_surface); 430 } else { 431 /* Deallocate old surface. */ 432 if (old_surface) 433 surface_destroy(old_surface); 377 434 } 378 435 } … … 420 477 421 478 while (!list_empty(&win->events.list)) { 422 list_remove(list_first(&win->events.list)); 479 window_event_t *event = (window_event_t *) list_first(&win->events.list); 480 list_remove(&event->link); 481 free(event); 423 482 } 424 483 … … 447 506 break; 448 507 case ET_POSITION_EVENT: 508 if (!win->is_focused) { 509 win->is_focused = true; 510 handle_refresh(win); 511 } 449 512 deliver_position_event(win, event->data.pos); 450 513 break; 451 514 case ET_SIGNAL_EVENT: 452 handle_signal_event(win, event->data.sig );515 handle_signal_event(win, event->data.signal); 453 516 break; 454 517 case ET_WINDOW_RESIZE: 455 handle_resize(win, event->data.rsz.width, event->data.rsz.height); 518 handle_resize(win, event->data.resize.offset_x, 519 event->data.resize.offset_y, event->data.resize.width, 520 event->data.resize.height, event->data.resize.placement_flags); 521 break; 522 case ET_WINDOW_FOCUS: 523 if (!win->is_focused) { 524 win->is_focused = true; 525 handle_refresh(win); 526 } 527 break; 528 case ET_WINDOW_UNFOCUS: 529 if (win->is_focused) { 530 win->is_focused = false; 531 handle_refresh(win); 532 } 456 533 break; 457 534 case ET_WINDOW_REFRESH: … … 514 591 } 515 592 516 window_t *window_open(char *winreg, bool is_main, bool is_decorated, const char *caption) 517 { 518 int rc; 519 593 window_t *window_open(const char *winreg, bool is_main, bool is_decorated, 594 const char *caption) 595 { 520 596 window_t *win = (window_t *) malloc(sizeof(window_t)); 521 if (!win) {597 if (!win) 522 598 return NULL; 523 } 524 599 525 600 win->is_main = is_main; 526 601 win->is_decorated = is_decorated; 602 win->is_focused = true; 527 603 prodcons_initialize(&win->events); 528 604 fibril_mutex_initialize(&win->guard); 605 529 606 widget_init(&win->root, NULL); 530 607 win->root.window = win; … … 538 615 win->focus = NULL; 539 616 win->surface = NULL; 540 617 541 618 service_id_t reg_dsid; 542 async_sess_t *reg_sess; 543 544 rc = loc_service_get_id(winreg, ®_dsid, 0); 619 int rc = loc_service_get_id(winreg, ®_dsid, 0); 545 620 if (rc != EOK) { 546 621 free(win); 547 622 return NULL; 548 623 } 549 550 reg_sess = loc_service_connect(EXCHANGE_SERIALIZE, reg_dsid, 0); 624 625 async_sess_t *reg_sess = loc_service_connect(EXCHANGE_SERIALIZE, 626 reg_dsid, 0); 551 627 if (reg_sess == NULL) { 552 628 free(win); 553 629 return NULL; 554 630 } 555 631 556 632 service_id_t in_dsid; 557 633 service_id_t out_dsid; 558 559 634 rc = win_register(reg_sess, &in_dsid, &out_dsid); 560 635 async_hangup(reg_sess); … … 563 638 return NULL; 564 639 } 565 640 566 641 win->osess = loc_service_connect(EXCHANGE_SERIALIZE, out_dsid, 0); 567 642 if (win->osess == NULL) { … … 569 644 return NULL; 570 645 } 571 646 572 647 win->isess = loc_service_connect(EXCHANGE_SERIALIZE, in_dsid, 0); 573 648 if (win->isess == NULL) { … … 576 651 return NULL; 577 652 } 578 579 if (caption == NULL) {653 654 if (caption == NULL) 580 655 win->caption = NULL; 581 } else {656 else 582 657 win->caption = str_dup(caption); 583 } 584 658 585 659 return win; 586 660 } 587 661 588 void window_resize(window_t *win, sysarg_t width, sysarg_t height) 662 void window_resize(window_t *win, sysarg_t offset_x, sysarg_t offset_y, 663 sysarg_t width, sysarg_t height, window_placement_flags_t placement_flags) 589 664 { 590 665 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t)); … … 592 667 link_initialize(&event->link); 593 668 event->type = ET_WINDOW_RESIZE; 594 event->data.rsz.width = width; 595 event->data.rsz.height = height; 669 event->data.resize.offset_x = offset_x; 670 event->data.resize.offset_y = offset_y; 671 event->data.resize.width = width; 672 event->data.resize.height = height; 673 event->data.resize.placement_flags = placement_flags; 596 674 prodcons_produce(&win->events, &event->link); 597 675 }
Note:
See TracChangeset
for help on using the changeset viewer.