Changes in uspace/srv/hid/display/display.c [2ab8ab3:5d380b6] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/display/display.c
r2ab8ab3 r5d380b6 1 1 /* 2 * Copyright (c) 20 19Jiri Svoboda2 * Copyright (c) 2023 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 45 45 #include "cursimg.h" 46 46 #include "cursor.h" 47 #include "display.h" 47 48 #include "seat.h" 48 49 #include "window.h" 49 #include " display.h"50 #include "wmclient.h" 50 51 51 52 static gfx_context_t *ds_display_get_unbuf_gc(ds_display_t *); 52 53 static void ds_display_invalidate_cb(void *, gfx_rect_t *); 53 54 static void ds_display_update_cb(void *); 55 56 static mem_gc_cb_t ds_display_mem_gc_cb = { 57 .invalidate = ds_display_invalidate_cb, 58 .update = ds_display_update_cb 59 }; 54 60 55 61 /** Create display. … … 91 97 fibril_mutex_initialize(&disp->lock); 92 98 list_initialize(&disp->clients); 99 list_initialize(&disp->wmclients); 100 list_initialize(&disp->cfgclients); 93 101 disp->next_wnd_id = 1; 94 102 list_initialize(&disp->ddevs); 103 list_initialize(&disp->idevcfgs); 95 104 list_initialize(&disp->seats); 96 105 list_initialize(&disp->windows); … … 109 118 void ds_display_destroy(ds_display_t *disp) 110 119 { 120 int i; 121 111 122 assert(list_empty(&disp->clients)); 123 assert(list_empty(&disp->wmclients)); 124 assert(list_empty(&disp->cfgclients)); 112 125 assert(list_empty(&disp->seats)); 113 /* XXX destroy cursors */ 126 assert(list_empty(&disp->ddevs)); 127 assert(list_empty(&disp->idevcfgs)); 128 assert(list_empty(&disp->seats)); 129 assert(list_empty(&disp->windows)); 130 131 /* Destroy cursors */ 132 for (i = 0; i < dcurs_limit; i++) { 133 ds_cursor_destroy(disp->cursor[i]); 134 disp->cursor[i] = NULL; 135 } 136 114 137 gfx_color_delete(disp->bg_color); 115 138 free(disp); … … 198 221 199 222 return list_get_instance(link, ds_client_t, lclients); 223 } 224 225 /** Add WM client to display. 226 * 227 * @param disp Display 228 * @param wmclient WM client 229 */ 230 void ds_display_add_wmclient(ds_display_t *disp, ds_wmclient_t *wmclient) 231 { 232 assert(wmclient->display == NULL); 233 assert(!link_used(&wmclient->lwmclients)); 234 235 wmclient->display = disp; 236 list_append(&wmclient->lwmclients, &disp->wmclients); 237 } 238 239 /** Remove WM client from display. 240 * 241 * @param wmclient WM client 242 */ 243 void ds_display_remove_wmclient(ds_wmclient_t *wmclient) 244 { 245 list_remove(&wmclient->lwmclients); 246 wmclient->display = NULL; 247 } 248 249 /** Add CFG client to display. 250 * 251 * @param disp Display 252 * @param cfgclient CFG client 253 */ 254 void ds_display_add_cfgclient(ds_display_t *disp, ds_cfgclient_t *cfgclient) 255 { 256 assert(cfgclient->display == NULL); 257 assert(!link_used(&cfgclient->lcfgclients)); 258 259 cfgclient->display = disp; 260 list_append(&cfgclient->lcfgclients, &disp->cfgclients); 261 } 262 263 /** Remove CFG client from display. 264 * 265 * @param cfgclient CFG client 266 */ 267 void ds_display_remove_cfgclient(ds_cfgclient_t *cfgclient) 268 { 269 list_remove(&cfgclient->lcfgclients); 270 cfgclient->display = NULL; 271 } 272 273 /** Get first WM client in display. 274 * 275 * @param disp Display 276 * @return First WM client or @c NULL if there is none 277 */ 278 ds_wmclient_t *ds_display_first_wmclient(ds_display_t *disp) 279 { 280 link_t *link = list_first(&disp->wmclients); 281 282 if (link == NULL) 283 return NULL; 284 285 return list_get_instance(link, ds_wmclient_t, lwmclients); 286 } 287 288 /** Get next WM client in display. 289 * 290 * @param wmclient Current WM client 291 * @return Next WM client or @c NULL if there is none 292 */ 293 ds_wmclient_t *ds_display_next_wmclient(ds_wmclient_t *wmclient) 294 { 295 link_t *link = list_next(&wmclient->lwmclients, 296 &wmclient->display->wmclients); 297 298 if (link == NULL) 299 return NULL; 300 301 return list_get_instance(link, ds_wmclient_t, lwmclients); 200 302 } 201 303 … … 241 343 gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect); 242 344 243 if (gfx_pix_inside_rect(pos, &drect)) 345 if (gfx_pix_inside_rect(pos, &drect) && 346 ds_window_is_visible(wnd)) 244 347 return wnd; 245 348 … … 250 353 } 251 354 355 /** Add window to window list. 356 * 357 * Topmost windows are enlisted before any other window. Non-topmost 358 * windows are enlisted before any other non-topmost window. 359 * 360 * @param display Display 361 * @param wnd Window 362 */ 363 void ds_display_enlist_window(ds_display_t *display, ds_window_t *wnd) 364 { 365 ds_window_t *w; 366 367 assert(wnd->display == display); 368 assert(!link_used(&wnd->ldwindows)); 369 370 if ((wnd->flags & wndf_topmost) == 0) { 371 /* Find the first non-topmost window */ 372 w = ds_display_first_window(display); 373 while (w != NULL && (w->flags & wndf_topmost) != 0) 374 w = ds_display_next_window(w); 375 376 if (w != NULL) 377 list_insert_before(&wnd->ldwindows, &w->ldwindows); 378 else 379 list_append(&wnd->ldwindows, &display->windows); 380 } else { 381 /* Insert at the beginning */ 382 list_prepend(&wnd->ldwindows, &display->windows); 383 } 384 385 } 386 252 387 /** Add window to display. 253 388 * … … 257 392 void ds_display_add_window(ds_display_t *display, ds_window_t *wnd) 258 393 { 394 ds_wmclient_t *wmclient; 395 259 396 assert(wnd->display == NULL); 260 397 assert(!link_used(&wnd->ldwindows)); 261 398 262 399 wnd->display = display; 263 list_prepend(&wnd->ldwindows, &display->windows); 400 ds_display_enlist_window(display, wnd); 401 402 /* Notify window managers about the new window */ 403 wmclient = ds_display_first_wmclient(display); 404 while (wmclient != NULL) { 405 ds_wmclient_post_wnd_added_event(wmclient, wnd->id); 406 wmclient = ds_display_next_wmclient(wmclient); 407 } 264 408 } 265 409 … … 270 414 void ds_display_remove_window(ds_window_t *wnd) 271 415 { 416 ds_wmclient_t *wmclient; 417 ds_display_t *display; 418 419 display = wnd->display; 420 272 421 list_remove(&wnd->ldwindows); 273 422 wnd->display = NULL; 423 424 /* Notify window managers about the removed window */ 425 wmclient = ds_display_first_wmclient(display); 426 while (wmclient != NULL) { 427 ds_wmclient_post_wnd_removed_event(wmclient, wnd->id); 428 wmclient = ds_display_next_wmclient(wmclient); 429 } 430 } 431 432 /** Move window to top. 433 * 434 * @param display Display 435 * @param wnd Window 436 */ 437 void ds_display_window_to_top(ds_window_t *wnd) 438 { 439 assert(wnd->display != NULL); 440 assert(link_used(&wnd->ldwindows)); 441 442 list_remove(&wnd->ldwindows); 443 ds_display_enlist_window(wnd->display, wnd); 274 444 } 275 445 … … 347 517 ds_seat_t *seat; 348 518 349 / / TODO Determine which seat the event belongs to350 seat = ds_display_ first_seat(display);519 /* Determine which seat the event belongs to */ 520 seat = ds_display_seat_by_idev(display, event->kbd_id); 351 521 if (seat == NULL) 352 522 return EOK; … … 364 534 ds_seat_t *seat; 365 535 366 / / TODO Determine which seat the event belongs to367 seat = ds_display_ first_seat(display);536 /* Determine which seat the event belongs to */ 537 seat = ds_display_seat_by_idev(display, event->pos_id); 368 538 if (seat == NULL) 369 539 return EOK; … … 383 553 384 554 seat->display = disp; 555 seat->id = disp->next_seat_id++; 385 556 list_append(&seat->lseats, &disp->seats); 386 557 } … … 424 595 425 596 return list_get_instance(link, ds_seat_t, lseats); 597 } 598 599 /** Get default seat in display. 600 * 601 * @param disp Display 602 * @return First seat or @c NULL if there is none 603 */ 604 ds_seat_t *ds_display_default_seat(ds_display_t *disp) 605 { 606 /* XXX Probably not the best solution */ 607 return ds_display_first_seat(disp); 608 } 609 610 /** Find seat by ID. 611 * 612 * @param display Display 613 * @param id Seat ID 614 */ 615 ds_seat_t *ds_display_find_seat(ds_display_t *display, ds_seat_id_t id) 616 { 617 ds_seat_t *seat; 618 619 seat = ds_display_first_seat(display); 620 while (seat != NULL) { 621 if (seat->id == id) 622 return seat; 623 624 seat = ds_display_next_seat(seat); 625 } 626 627 return NULL; 628 } 629 630 /** Get seat which owns the specified input device. 631 * 632 * @param disp Display 633 * @param idev_id Input device ID 634 * @return Seat which owns device with ID @a idev_id or @c NULL if not found 635 */ 636 ds_seat_t *ds_display_seat_by_idev(ds_display_t *disp, ds_idev_id_t idev_id) 637 { 638 ds_idevcfg_t *idevcfg; 639 640 /* 641 * Find input device configuration entry that maps this input device 642 * to a seat. 643 */ 644 idevcfg = ds_display_first_idevcfg(disp); 645 while (idevcfg != NULL) { 646 if (idevcfg->svc_id == idev_id) 647 return idevcfg->seat; 648 649 idevcfg = ds_display_next_idevcfg(idevcfg); 650 } 651 652 /* If none was found, return the default seat */ 653 return ds_display_default_seat(disp); 426 654 } 427 655 … … 459 687 goto error; 460 688 461 rc = mem_gc_create(&disp->rect, &alloc, 462 ds_display_invalidate_cb, ds_display_update_cb, (void *) disp, 463 &disp->bbgc); 689 rc = mem_gc_create(&disp->rect, &alloc, &ds_display_mem_gc_cb, 690 (void *) disp, &disp->bbgc); 464 691 if (rc != EOK) 465 692 goto error; … … 489 716 { 490 717 errno_t rc; 718 gfx_rect_t old_disp_rect; 491 719 492 720 assert(ddev->display == NULL); 493 721 assert(!link_used(&ddev->lddevs)); 722 723 old_disp_rect = disp->rect; 494 724 495 725 ddev->display = disp; … … 503 733 /* Create cloning GC */ 504 734 rc = ds_clonegc_create(ddev->gc, &disp->fbgc); 505 if (rc != EOK) { 506 // XXX Remove output 507 return ENOMEM; 508 } 735 if (rc != EOK) 736 goto error; 509 737 510 738 /* Allocate backbuffer */ 511 739 rc = ds_display_alloc_backbuf(disp); 512 740 if (rc != EOK) { 513 // XXX Remove output514 // XXX Delete clone GC741 ds_clonegc_delete(disp->fbgc); 742 disp->fbgc = NULL; 515 743 goto error; 516 744 } … … 522 750 } 523 751 752 ds_display_update_max_rect(disp); 753 524 754 return EOK; 525 755 error: 526 disp->rect.p0.x = 0; 527 disp->rect.p0.y = 0; 528 disp->rect.p1.x = 0; 529 disp->rect.p1.y = 0; 756 disp->rect = old_disp_rect; 530 757 list_remove(&ddev->lddevs); 531 758 return rc; … … 572 799 } 573 800 801 /** Add input device configuration entry to display. 802 * 803 * @param disp Display 804 * @param idevcfg Input device configuration 805 */ 806 void ds_display_add_idevcfg(ds_display_t *disp, ds_idevcfg_t *idevcfg) 807 { 808 assert(idevcfg->display == NULL); 809 assert(!link_used(&idevcfg->ldispidcfgs)); 810 811 idevcfg->display = disp; 812 list_append(&idevcfg->ldispidcfgs, &disp->idevcfgs); 813 } 814 815 /** Remove input device configuration entry from display. 816 * 817 * @param idevcfg Input device configuration entry 818 */ 819 void ds_display_remove_idevcfg(ds_idevcfg_t *idevcfg) 820 { 821 list_remove(&idevcfg->ldispidcfgs); 822 idevcfg->display = NULL; 823 } 824 825 /** Get first input device configuration entry in display. 826 * 827 * @param disp Display 828 * @return First input device configuration entry or @c NULL if there is none 829 */ 830 ds_idevcfg_t *ds_display_first_idevcfg(ds_display_t *disp) 831 { 832 link_t *link = list_first(&disp->idevcfgs); 833 834 if (link == NULL) 835 return NULL; 836 837 return list_get_instance(link, ds_idevcfg_t, ldispidcfgs); 838 } 839 840 /** Get next input device configuration entry in display. 841 * 842 * @param idevcfg Current input device configuration entry 843 * @return Next input device configuration entry or @c NULL if there is none 844 */ 845 ds_idevcfg_t *ds_display_next_idevcfg(ds_idevcfg_t *idevcfg) 846 { 847 link_t *link = list_next(&idevcfg->ldispidcfgs, &idevcfg->display->idevcfgs); 848 849 if (link == NULL) 850 return NULL; 851 852 return list_get_instance(link, ds_idevcfg_t, ldispidcfgs); 853 } 854 574 855 /** Add cursor to display. 575 856 * … … 594 875 list_remove(&cursor->ldisplay); 595 876 cursor->display = NULL; 877 } 878 879 /** Update display maximize rectangle. 880 * 881 * Recalculate the maximize rectangle (the rectangle used for maximized 882 * windows). 883 * 884 * @param display Display 885 */ 886 void ds_display_update_max_rect(ds_display_t *display) 887 { 888 ds_window_t *wnd; 889 gfx_rect_t max_rect; 890 gfx_rect_t drect; 891 892 /* Start with the entire display */ 893 max_rect = display->rect; 894 895 wnd = ds_display_first_window(display); 896 while (wnd != NULL) { 897 /* Should maximized windows avoid this window? */ 898 if ((wnd->flags & wndf_avoid) != 0) { 899 /* Window bounding rectangle on display */ 900 gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect); 901 902 /* Crop maximized rectangle */ 903 ds_display_crop_max_rect(&drect, &max_rect); 904 } 905 906 wnd = ds_display_next_window(wnd); 907 } 908 909 /* Update the maximize rectangle */ 910 display->max_rect = max_rect; 911 } 912 913 /** Crop maximize rectangle. 914 * 915 * Use the avoid rectangle @a arect to crop off maximization rectangle 916 * @a mrect. If @a arect covers the top, bottom, left or right part 917 * of @a mrect, it will be cropped off. Otherwise there will be 918 * no effect. 919 * 920 * @param arect Avoid rectangle 921 * @param mrect Maximize rectangle to be modified 922 */ 923 void ds_display_crop_max_rect(gfx_rect_t *arect, gfx_rect_t *mrect) 924 { 925 if (arect->p0.x == mrect->p0.x && arect->p0.y == mrect->p0.y && 926 arect->p1.x == mrect->p1.x) { 927 /* Cropp off top part */ 928 mrect->p0.y = arect->p1.y; 929 } else if (arect->p0.x == mrect->p0.x && arect->p1.x == mrect->p1.x && 930 arect->p1.y == mrect->p1.y) { 931 /* Cropp off bottom part */ 932 mrect->p1.y = arect->p0.y; 933 } else if (arect->p0.x == mrect->p0.x && arect->p0.y == mrect->p0.y && 934 arect->p1.y == mrect->p1.y) { 935 /* Cropp off left part */ 936 mrect->p0.x = arect->p1.x; 937 } else if (arect->p0.y == mrect->p0.y && arect->p1.x == mrect->p1.x && 938 arect->p1.y == mrect->p1.y) { 939 /* Cropp off right part */ 940 mrect->p1.x = arect->p0.x; 941 } 596 942 } 597 943
Note:
See TracChangeset
for help on using the changeset viewer.