Changeset 0680854 in mainline for uspace/srv/hid/display/window.c
- Timestamp:
- 2020-03-20T15:42:27Z (5 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0b7e394
- Parents:
- aeb3037
- git-author:
- Jiri Svoboda <jiri@…> (2020-03-19 19:42:21)
- git-committer:
- Jiri Svoboda <jiri@…> (2020-03-20 15:42:27)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/display/window.c
raeb3037 r0680854 346 346 } 347 347 348 /** Bring window to top. 349 * 350 * @param wnd Window 351 */ 352 void ds_window_bring_to_top(ds_window_t *wnd) 353 { 354 ds_display_t *disp = wnd->display; 355 356 ds_display_remove_window(wnd); 357 ds_display_add_window(disp, wnd); 358 } 359 360 /** Get generic graphic context from window. 361 * 362 * @param wnd Window 363 * @return Graphic context 364 */ 365 gfx_context_t *ds_window_get_ctx(ds_window_t *wnd) 366 { 367 return wnd->gc; 368 } 369 370 /** Paint a window using its backing bitmap. 371 * 372 * @param wnd Window to paint 373 * @param rect Display rectangle to paint to 374 * @return EOK on success or an error code 375 */ 376 errno_t ds_window_paint(ds_window_t *wnd, gfx_rect_t *rect) 377 { 378 gfx_rect_t srect; 379 gfx_rect_t *brect; 380 gfx_rect_t crect; 381 382 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_paint"); 383 384 if (rect != NULL) { 385 gfx_rect_rtranslate(&wnd->dpos, rect, &srect); 386 387 /* Determine if we have anything to do */ 388 gfx_rect_clip(&srect, &wnd->rect, &crect); 389 if (gfx_rect_is_empty(&crect)) 390 return EOK; 391 392 brect = &srect; 393 } else { 394 brect = NULL; 395 } 396 397 /* This can happen in unit tests */ 398 if (wnd->bitmap == NULL) 399 return EOK; 400 401 return gfx_bitmap_render(wnd->bitmap, brect, &wnd->dpos); 402 } 403 404 /** Start moving a window by mouse drag. 405 * 406 * @param wnd Window 407 * @param event Button press event 408 */ 409 static void ds_window_start_move(ds_window_t *wnd, pos_event_t *event) 410 { 411 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_start_move (%d, %d)", 412 (int) event->hpos, (int) event->vpos); 413 414 if (wnd->state != dsw_idle) 415 return; 416 417 wnd->orig_pos.x = event->hpos; 418 wnd->orig_pos.y = event->vpos; 419 wnd->state = dsw_moving; 420 } 421 422 /** Finish moving a window by mouse drag. 423 * 424 * @param wnd Window 425 * @param event Button release event 426 */ 427 static void ds_window_finish_move(ds_window_t *wnd, pos_event_t *event) 428 { 429 gfx_coord2_t pos; 430 gfx_coord2_t dmove; 431 gfx_coord2_t nwpos; 432 433 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_finish_move (%d, %d)", 434 (int) event->hpos, (int) event->vpos); 435 436 if (wnd->state != dsw_moving) 437 return; 438 439 pos.x = event->hpos; 440 pos.y = event->vpos; 441 gfx_coord2_subtract(&pos, &wnd->orig_pos, &dmove); 442 443 gfx_coord2_add(&wnd->dpos, &dmove, &nwpos); 444 wnd->dpos = nwpos; 445 wnd->state = dsw_idle; 446 447 (void) ds_display_paint(wnd->display, NULL); 448 } 449 450 /** Update window position when moving by mouse drag. 451 * 452 * @param wnd Window 453 * @param event Position update event 454 */ 455 static void ds_window_update_move(ds_window_t *wnd, pos_event_t *event) 456 { 457 gfx_coord2_t pos; 458 gfx_coord2_t dmove; 459 gfx_coord2_t nwpos; 460 gfx_rect_t drect; 461 gfx_color_t *color; 462 gfx_context_t *gc; 463 errno_t rc; 464 465 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_move (%d, %d)", 466 (int) event->hpos, (int) event->vpos); 467 468 if (wnd->state != dsw_moving) 469 return; 470 471 gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect); 472 473 gc = ds_display_get_gc(wnd->display); // XXX 474 if (gc != NULL) { 475 gfx_set_color(gc, wnd->display->bg_color); 476 gfx_fill_rect(gc, &drect); 477 } 478 479 pos.x = event->hpos; 480 pos.y = event->vpos; 481 gfx_coord2_subtract(&pos, &wnd->orig_pos, &dmove); 482 483 gfx_coord2_add(&wnd->dpos, &dmove, &nwpos); 484 gfx_rect_translate(&nwpos, &wnd->rect, &drect); 485 486 wnd->orig_pos = pos; 487 wnd->dpos = nwpos; 488 489 rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color); 490 if (rc != EOK) 491 return; 492 493 gc = ds_display_get_gc(wnd->display); // XXX 494 if (gc != NULL) { 495 gfx_set_color(gc, color); 496 gfx_fill_rect(gc, &drect); 497 } 498 499 gfx_color_delete(color); 500 } 501 502 /** Finish resizing a window by mouse drag. 503 * 504 * @param wnd Window 505 * @param event Button release event 506 */ 507 static void ds_window_finish_resize(ds_window_t *wnd, pos_event_t *event) 508 { 509 gfx_coord2_t pos; 510 gfx_coord2_t dresize; 511 gfx_rect_t nrect; 512 513 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_finish_resize (%d, %d)", 514 (int) event->hpos, (int) event->vpos); 515 516 if (wnd->state != dsw_resizing) 517 return; 518 519 (void) ds_display_paint(wnd->display, NULL); 520 521 pos.x = event->hpos; 522 pos.y = event->vpos; 523 gfx_coord2_subtract(&pos, &wnd->orig_pos, &dresize); 524 525 /* Compute new rectangle */ 526 ds_window_calc_resize(wnd, &dresize, &nrect); 527 528 wnd->state = dsw_idle; 529 ds_client_post_resize_event(wnd->client, wnd, &nrect); 530 } 531 532 /** Update window position when resizing by mouse drag. 533 * 534 * @param wnd Window 535 * @param event Position update event 536 */ 537 static void ds_window_update_resize(ds_window_t *wnd, pos_event_t *event) 538 { 539 gfx_coord2_t pos; 540 gfx_coord2_t dresize; 541 gfx_rect_t nrect; 542 gfx_rect_t drect; 543 gfx_color_t *color; 544 gfx_context_t *gc; 545 errno_t rc; 546 547 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_resize (%d, %d)", 548 (int) event->hpos, (int) event->vpos); 549 550 if (wnd->state != dsw_resizing) 551 return; 552 553 gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect); 554 555 gc = ds_display_get_gc(wnd->display); // XXX 556 if (gc != NULL) { 557 gfx_set_color(gc, wnd->display->bg_color); 558 gfx_fill_rect(gc, &drect); 559 } 560 561 pos.x = event->hpos; 562 pos.y = event->vpos; 563 gfx_coord2_subtract(&pos, &wnd->orig_pos, &dresize); 564 565 ds_window_calc_resize(wnd, &dresize, &nrect); 566 gfx_rect_translate(&wnd->dpos, &nrect, &drect); 567 568 rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color); 569 if (rc != EOK) 570 return; 571 572 gc = ds_display_get_gc(wnd->display); // XXX 573 if (gc != NULL) { 574 gfx_set_color(gc, color); 575 gfx_fill_rect(gc, &drect); 576 } 577 578 gfx_color_delete(color); 579 } 580 581 /** Post keyboard event to window. 582 * 583 * @param wnd Window 584 * @param event Event 585 * 586 * @return EOK on success or an error code 587 */ 588 errno_t ds_window_post_kbd_event(ds_window_t *wnd, kbd_event_t *event) 589 { 590 bool alt_or_shift; 591 592 alt_or_shift = event->mods & (KM_SHIFT | KM_ALT); 593 594 if (event->type == KEY_PRESS && alt_or_shift && event->key == KC_F4) { 595 /* On Alt-F4 or Shift-F4 send close event to the window */ 596 ds_client_post_close_event(wnd->client, wnd); 597 return EOK; 598 } 599 600 return ds_client_post_kbd_event(wnd->client, wnd, event); 601 } 602 603 /** Post position event to window. 604 * 605 * @param wnd Window 606 * @param event Position event 607 */ 608 errno_t ds_window_post_pos_event(ds_window_t *wnd, pos_event_t *event) 609 { 610 pos_event_t tevent; 611 gfx_coord2_t pos; 612 gfx_rect_t drect; 613 bool inside; 614 615 log_msg(LOG_DEFAULT, LVL_DEBUG, 616 "ds_window_post_pos_event type=%d pos=%d,%d\n", event->type, 617 (int) event->hpos, (int) event->vpos); 618 619 pos.x = event->hpos; 620 pos.y = event->vpos; 621 gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect); 622 inside = gfx_pix_inside_rect(&pos, &drect); 623 624 if (event->type == POS_PRESS && event->btn_num == 2 && inside) 625 ds_window_start_move(wnd, event); 626 627 if (event->type == POS_RELEASE) { 628 ds_window_finish_move(wnd, event); 629 ds_window_finish_resize(wnd, event); 630 } 631 632 if (event->type == POS_UPDATE) { 633 ds_window_update_move(wnd, event); 634 ds_window_update_resize(wnd, event); 635 } 636 637 /* Transform event coordinates to window-local */ 638 tevent = *event; 639 tevent.hpos -= wnd->dpos.x; 640 tevent.vpos -= wnd->dpos.y; 641 642 return ds_client_post_pos_event(wnd->client, wnd, &tevent); 643 } 644 645 /** Post focus event to window. 646 * 647 * @param wnd Window 648 */ 649 errno_t ds_window_post_focus_event(ds_window_t *wnd) 650 { 651 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_focus_event\n"); 652 653 return ds_client_post_focus_event(wnd->client, wnd); 654 } 655 656 /** Post unfocus event to window. 657 * 658 * @param wnd Window 659 */ 660 errno_t ds_window_post_unfocus_event(ds_window_t *wnd) 661 { 662 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_unfocus_event\n"); 663 664 return ds_client_post_unfocus_event(wnd->client, wnd); 665 } 666 667 /** Start moving a window, detected by client. 668 * 669 * @param wnd Window 670 * @param pos Position where the pointer was when the move started 671 * relative to the window 672 * @param event Button press event 673 */ 674 void ds_window_move_req(ds_window_t *wnd, gfx_coord2_t *pos) 675 { 676 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_move_req (%d, %d)", 677 (int) pos->x, (int) pos->y); 678 679 if (wnd->state != dsw_idle) 680 return; 681 682 gfx_coord2_add(&wnd->dpos, pos, &wnd->orig_pos); 683 wnd->state = dsw_moving; 684 } 685 686 /** Move window. 687 * 688 * @param wnd Window 689 */ 690 void ds_window_move(ds_window_t *wnd, gfx_coord2_t *dpos) 691 { 692 wnd->dpos = *dpos; 693 (void) ds_display_paint(wnd->display, NULL); 694 } 695 696 /** Start resizing a window, detected by client. 697 * 698 * @param wnd Window 699 * @param rsztype Resize type (which part of window is being dragged) 700 * @param pos Position where the pointer was when the resize started 701 * relative to the window 702 * @param event Button press event 703 */ 704 void ds_window_resize_req(ds_window_t *wnd, display_wnd_rsztype_t rsztype, 705 gfx_coord2_t *pos) 706 { 707 log_msg(LOG_DEFAULT, LVL_NOTE, "ds_window_resize_req (%d, %d, %d)", 708 (int) rsztype, (int) pos->x, (int) pos->y); 709 710 if (wnd->state != dsw_idle) 711 return; 712 713 gfx_coord2_add(&wnd->dpos, pos, &wnd->orig_pos); 714 wnd->state = dsw_resizing; 715 wnd->rsztype = rsztype; 716 } 717 348 718 /** Resize window. 349 719 * … … 400 770 } 401 771 402 /** Bring window to top.403 *404 * @param wnd Window405 */406 void ds_window_bring_to_top(ds_window_t *wnd)407 {408 ds_display_t *disp = wnd->display;409 410 ds_display_remove_window(wnd);411 ds_display_add_window(disp, wnd);412 }413 414 /** Get generic graphic context from window.415 *416 * @param wnd Window417 * @return Graphic context418 */419 gfx_context_t *ds_window_get_ctx(ds_window_t *wnd)420 {421 return wnd->gc;422 }423 424 /** Paint a window using its backing bitmap.425 *426 * @param wnd Window to paint427 * @param rect Display rectangle to paint to428 * @return EOK on success or an error code429 */430 errno_t ds_window_paint(ds_window_t *wnd, gfx_rect_t *rect)431 {432 gfx_rect_t srect;433 gfx_rect_t *brect;434 gfx_rect_t crect;435 436 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_paint");437 438 if (rect != NULL) {439 gfx_rect_rtranslate(&wnd->dpos, rect, &srect);440 441 /* Determine if we have anything to do */442 gfx_rect_clip(&srect, &wnd->rect, &crect);443 if (gfx_rect_is_empty(&crect))444 return EOK;445 446 brect = &srect;447 } else {448 brect = NULL;449 }450 451 /* This can happen in unit tests */452 if (wnd->bitmap == NULL)453 return EOK;454 455 return gfx_bitmap_render(wnd->bitmap, brect, &wnd->dpos);456 }457 458 /** Start moving a window by mouse drag.459 *460 * @param wnd Window461 * @param event Button press event462 */463 static void ds_window_start_move(ds_window_t *wnd, pos_event_t *event)464 {465 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_start_move (%d, %d)",466 (int) event->hpos, (int) event->vpos);467 468 if (wnd->state != dsw_idle)469 return;470 471 wnd->orig_pos.x = event->hpos;472 wnd->orig_pos.y = event->vpos;473 wnd->state = dsw_moving;474 }475 476 /** Finish moving a window by mouse drag.477 *478 * @param wnd Window479 * @param event Button release event480 */481 static void ds_window_finish_move(ds_window_t *wnd, pos_event_t *event)482 {483 gfx_coord2_t pos;484 gfx_coord2_t dmove;485 gfx_coord2_t nwpos;486 487 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_finish_move (%d, %d)",488 (int) event->hpos, (int) event->vpos);489 490 if (wnd->state != dsw_moving)491 return;492 493 pos.x = event->hpos;494 pos.y = event->vpos;495 gfx_coord2_subtract(&pos, &wnd->orig_pos, &dmove);496 497 gfx_coord2_add(&wnd->dpos, &dmove, &nwpos);498 wnd->dpos = nwpos;499 wnd->state = dsw_idle;500 501 (void) ds_display_paint(wnd->display, NULL);502 }503 504 /** Update window position when moving by mouse drag.505 *506 * @param wnd Window507 * @param event Position update event508 */509 static void ds_window_update_move(ds_window_t *wnd, pos_event_t *event)510 {511 gfx_coord2_t pos;512 gfx_coord2_t dmove;513 gfx_coord2_t nwpos;514 gfx_rect_t drect;515 gfx_color_t *color;516 gfx_context_t *gc;517 errno_t rc;518 519 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_move (%d, %d)",520 (int) event->hpos, (int) event->vpos);521 522 if (wnd->state != dsw_moving)523 return;524 525 gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);526 527 gc = ds_display_get_gc(wnd->display); // XXX528 if (gc != NULL) {529 gfx_set_color(gc, wnd->display->bg_color);530 gfx_fill_rect(gc, &drect);531 }532 533 pos.x = event->hpos;534 pos.y = event->vpos;535 gfx_coord2_subtract(&pos, &wnd->orig_pos, &dmove);536 537 gfx_coord2_add(&wnd->dpos, &dmove, &nwpos);538 gfx_rect_translate(&nwpos, &wnd->rect, &drect);539 540 wnd->orig_pos = pos;541 wnd->dpos = nwpos;542 543 rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);544 if (rc != EOK)545 return;546 547 gc = ds_display_get_gc(wnd->display); // XXX548 if (gc != NULL) {549 gfx_set_color(gc, color);550 gfx_fill_rect(gc, &drect);551 }552 553 gfx_color_delete(color);554 }555 556 /** Finish resizing a window by mouse drag.557 *558 * @param wnd Window559 * @param event Button release event560 */561 static void ds_window_finish_resize(ds_window_t *wnd, pos_event_t *event)562 {563 gfx_coord2_t pos;564 gfx_coord2_t dresize;565 gfx_rect_t nrect;566 567 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_finish_resize (%d, %d)",568 (int) event->hpos, (int) event->vpos);569 570 if (wnd->state != dsw_resizing)571 return;572 573 (void) ds_display_paint(wnd->display, NULL);574 575 pos.x = event->hpos;576 pos.y = event->vpos;577 gfx_coord2_subtract(&pos, &wnd->orig_pos, &dresize);578 579 /* Compute new rectangle */580 ds_window_calc_resize(wnd, &dresize, &nrect);581 582 wnd->state = dsw_idle;583 ds_client_post_resize_event(wnd->client, wnd, &nrect);584 }585 586 /** Update window position when resizing by mouse drag.587 *588 * @param wnd Window589 * @param event Position update event590 */591 static void ds_window_update_resize(ds_window_t *wnd, pos_event_t *event)592 {593 gfx_coord2_t pos;594 gfx_coord2_t dresize;595 gfx_rect_t nrect;596 gfx_rect_t drect;597 gfx_color_t *color;598 gfx_context_t *gc;599 errno_t rc;600 601 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_resize (%d, %d)",602 (int) event->hpos, (int) event->vpos);603 604 if (wnd->state != dsw_resizing)605 return;606 607 gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);608 609 gc = ds_display_get_gc(wnd->display); // XXX610 if (gc != NULL) {611 gfx_set_color(gc, wnd->display->bg_color);612 gfx_fill_rect(gc, &drect);613 }614 615 pos.x = event->hpos;616 pos.y = event->vpos;617 gfx_coord2_subtract(&pos, &wnd->orig_pos, &dresize);618 619 ds_window_calc_resize(wnd, &dresize, &nrect);620 gfx_rect_translate(&wnd->dpos, &nrect, &drect);621 622 rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);623 if (rc != EOK)624 return;625 626 gc = ds_display_get_gc(wnd->display); // XXX627 if (gc != NULL) {628 gfx_set_color(gc, color);629 gfx_fill_rect(gc, &drect);630 }631 632 gfx_color_delete(color);633 }634 635 /** Post keyboard event to window.636 *637 * @param wnd Window638 * @param event Event639 *640 * @return EOK on success or an error code641 */642 errno_t ds_window_post_kbd_event(ds_window_t *wnd, kbd_event_t *event)643 {644 bool alt_or_shift;645 646 alt_or_shift = event->mods & (KM_SHIFT | KM_ALT);647 648 if (event->type == KEY_PRESS && alt_or_shift && event->key == KC_F4) {649 /* On Alt-F4 or Shift-F4 send close event to the window */650 ds_client_post_close_event(wnd->client, wnd);651 return EOK;652 }653 654 return ds_client_post_kbd_event(wnd->client, wnd, event);655 }656 657 /** Post position event to window.658 *659 * @param wnd Window660 * @param event Position event661 */662 errno_t ds_window_post_pos_event(ds_window_t *wnd, pos_event_t *event)663 {664 pos_event_t tevent;665 gfx_coord2_t pos;666 gfx_rect_t drect;667 bool inside;668 669 log_msg(LOG_DEFAULT, LVL_DEBUG,670 "ds_window_post_pos_event type=%d pos=%d,%d\n", event->type,671 (int) event->hpos, (int) event->vpos);672 673 pos.x = event->hpos;674 pos.y = event->vpos;675 gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);676 inside = gfx_pix_inside_rect(&pos, &drect);677 678 if (event->type == POS_PRESS && event->btn_num == 2 && inside)679 ds_window_start_move(wnd, event);680 681 if (event->type == POS_RELEASE) {682 ds_window_finish_move(wnd, event);683 ds_window_finish_resize(wnd, event);684 }685 686 if (event->type == POS_UPDATE) {687 ds_window_update_move(wnd, event);688 ds_window_update_resize(wnd, event);689 }690 691 /* Transform event coordinates to window-local */692 tevent = *event;693 tevent.hpos -= wnd->dpos.x;694 tevent.vpos -= wnd->dpos.y;695 696 return ds_client_post_pos_event(wnd->client, wnd, &tevent);697 }698 699 /** Post focus event to window.700 *701 * @param wnd Window702 */703 errno_t ds_window_post_focus_event(ds_window_t *wnd)704 {705 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_focus_event\n");706 707 return ds_client_post_focus_event(wnd->client, wnd);708 }709 710 /** Post unfocus event to window.711 *712 * @param wnd Window713 */714 errno_t ds_window_post_unfocus_event(ds_window_t *wnd)715 {716 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_unfocus_event\n");717 718 return ds_client_post_unfocus_event(wnd->client, wnd);719 }720 721 /** Start moving a window, detected by client.722 *723 * @param wnd Window724 * @param pos Position where the pointer was when the move started725 * relative to the window726 * @param event Button press event727 */728 void ds_window_move_req(ds_window_t *wnd, gfx_coord2_t *pos)729 {730 log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_move_req (%d, %d)",731 (int) pos->x, (int) pos->y);732 733 if (wnd->state != dsw_idle)734 return;735 736 gfx_coord2_add(&wnd->dpos, pos, &wnd->orig_pos);737 wnd->state = dsw_moving;738 }739 740 /** Start resizing a window, detected by client.741 *742 * @param wnd Window743 * @param rsztype Resize type (which part of window is being dragged)744 * @param pos Position where the pointer was when the resize started745 * relative to the window746 * @param event Button press event747 */748 void ds_window_resize_req(ds_window_t *wnd, display_wnd_rsztype_t rsztype,749 gfx_coord2_t *pos)750 {751 log_msg(LOG_DEFAULT, LVL_NOTE, "ds_window_resize_req (%d, %d, %d)",752 (int) rsztype, (int) pos->x, (int) pos->y);753 754 if (wnd->state != dsw_idle)755 return;756 757 gfx_coord2_add(&wnd->dpos, pos, &wnd->orig_pos);758 wnd->state = dsw_resizing;759 wnd->rsztype = rsztype;760 }761 762 772 /** Compute new window rectangle after resize operation. 763 773 *
Note:
See TracChangeset
for help on using the changeset viewer.