Changeset dd0c8a0 in mainline for uspace/srv/hid/compositor/compositor.c
- Timestamp:
- 2013-09-29T06:56:33Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a9bd960d
- Parents:
- 3deb0155 (diff), 13be2583 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/compositor/compositor.c
r3deb0155 rdd0c8a0 90 90 typedef struct { 91 91 link_t link; 92 atomic_t ref_cnt; 92 93 service_id_t in_dsid; 93 94 service_id_t out_dsid; … … 138 139 } viewport_t; 139 140 141 static desktop_rect_t viewport_bound_rect; 140 142 static FIBRIL_MUTEX_INITIALIZE(viewport_list_mtx); 141 143 static LIST_INITIALIZE(viewport_list); 144 145 static FIBRIL_MUTEX_INITIALIZE(discovery_mtx); 142 146 143 147 /** Input server proxy */ … … 215 219 216 220 link_initialize(&win->link); 221 atomic_set(&win->ref_cnt, 0); 217 222 prodcons_initialize(&win->queue); 218 223 transform_identity(&win->transform); … … 232 237 static void window_destroy(window_t *win) 233 238 { 234 if (win) { 239 if (win && atomic_get(&win->ref_cnt) == 0) { 240 while (!list_empty(&win->queue.list)) { 241 window_event_t *event = (window_event_t *) list_first(&win->queue.list); 242 list_remove(&event->link); 243 free(event); 244 } 245 235 246 if (win->surface) { 236 247 surface_destroy(win->surface); … … 310 321 } 311 322 323 static void comp_restrict_pointers(void) 324 { 325 fibril_mutex_lock(&viewport_list_mtx); 326 327 sysarg_t x_res = coord_origin; 328 sysarg_t y_res = coord_origin; 329 sysarg_t w_res = 0; 330 sysarg_t h_res = 0; 331 332 if (!list_empty(&viewport_list)) { 333 viewport_t *vp = (viewport_t *) list_first(&viewport_list); 334 x_res = vp->pos.x; 335 y_res = vp->pos.y; 336 surface_get_resolution(vp->surface, &w_res, &h_res); 337 } 338 339 list_foreach(viewport_list, link, viewport_t, vp) { 340 sysarg_t w_vp, h_vp; 341 surface_get_resolution(vp->surface, &w_vp, &h_vp); 342 rectangle_union( 343 x_res, y_res, w_res, h_res, 344 vp->pos.x, vp->pos.y, w_vp, h_vp, 345 &x_res, &y_res, &w_res, &h_res); 346 } 347 348 viewport_bound_rect.x = x_res; 349 viewport_bound_rect.y = y_res; 350 viewport_bound_rect.w = w_res; 351 viewport_bound_rect.h = h_res; 352 353 fibril_mutex_unlock(&viewport_list_mtx); 354 355 fibril_mutex_lock(&pointer_list_mtx); 356 357 list_foreach(pointer_list, link, pointer_t, ptr) { 358 ptr->pos.x = ptr->pos.x > viewport_bound_rect.x ? ptr->pos.x : viewport_bound_rect.x; 359 ptr->pos.y = ptr->pos.y > viewport_bound_rect.y ? ptr->pos.y : viewport_bound_rect.y; 360 ptr->pos.x = ptr->pos.x < viewport_bound_rect.x + viewport_bound_rect.w ? 361 ptr->pos.x : viewport_bound_rect.x + viewport_bound_rect.w; 362 ptr->pos.y = ptr->pos.y < viewport_bound_rect.y + viewport_bound_rect.h ? 363 ptr->pos.y : viewport_bound_rect.y + viewport_bound_rect.h; 364 } 365 366 fibril_mutex_unlock(&pointer_list_mtx); 367 } 368 312 369 static void comp_damage(sysarg_t x_dmg_glob, sysarg_t y_dmg_glob, 313 370 sysarg_t w_dmg_glob, sysarg_t h_dmg_glob) … … 317 374 fibril_mutex_lock(&pointer_list_mtx); 318 375 319 list_foreach(viewport_list, link) { 320 376 list_foreach(viewport_list, link, viewport_t, vp) { 321 377 /* Determine what part of the viewport must be updated. */ 322 viewport_t *vp = list_get_instance(link, viewport_t, link);323 378 sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp; 324 379 surface_get_resolution(vp->surface, &w_dmg_vp, &h_dmg_vp); … … 389 444 } 390 445 391 list_foreach(pointer_list, link) { 392 393 pointer_t *ptr = list_get_instance(link, pointer_t, link); 446 list_foreach(pointer_list, link, pointer_t, ptr) { 394 447 if (ptr->ghost.surface) { 395 448 … … 465 518 } 466 519 467 list_foreach(pointer_list, link ) {520 list_foreach(pointer_list, link, pointer_t, ptr) { 468 521 469 522 /* Determine what part of the pointer intersects with the 470 523 * updated area of the current viewport. */ 471 pointer_t *ptr = list_get_instance(link, pointer_t, link);472 524 sysarg_t x_dmg_ptr, y_dmg_ptr, w_dmg_ptr, h_dmg_ptr; 473 525 surface_t *sf_ptr = ptr->cursor.states[ptr->state]; … … 512 564 513 565 /* Notify visualizers about updated regions. */ 514 list_foreach(viewport_list, link) { 515 viewport_t *vp = list_get_instance(link, viewport_t, link); 566 list_foreach(viewport_list, link, viewport_t, vp) { 516 567 sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp; 517 568 surface_get_damaged_region(vp->surface, &x_dmg_vp, &y_dmg_vp, &w_dmg_vp, &h_dmg_vp); … … 574 625 575 626 fibril_mutex_lock(&pointer_list_mtx); 576 list_foreach(pointer_list, link) { 577 pointer_t *pointer = list_get_instance(link, pointer_t, link); 627 list_foreach(pointer_list, link, pointer_t, pointer) { 578 628 if (pointer->id == pos_id) { 579 629 pointer->grab_flags = pointer->pressed ? grab_flags : GF_EMPTY; … … 653 703 { 654 704 fibril_mutex_lock(&window_list_mtx); 655 window_t *window = NULL; 656 list_foreach(window_list, link) { 657 window = list_get_instance(link, window_t, link); 705 706 list_foreach(window_list, link, window_t, window) { 658 707 if (window == target) { 659 708 prodcons_produce(&window->queue, &event->link); 660 }661 }662 if (!window) {663 free(event);664 } 709 fibril_mutex_unlock(&window_list_mtx); 710 return; 711 } 712 } 713 665 714 fibril_mutex_unlock(&window_list_mtx); 715 free(event); 666 716 } 667 717 … … 693 743 if (event_focus && win_focus) { 694 744 comp_post_event_win(event_focus, win_focus); 745 } 746 747 loc_service_unregister(win->in_dsid); 748 loc_service_unregister(win->out_dsid); 749 750 /* In case the client was killed, input fibril of the window might be 751 * still blocked on the condition within comp_window_get_event. */ 752 window_event_t *event_dummy = (window_event_t *) malloc(sizeof(window_event_t)); 753 if (event_dummy) { 754 link_initialize(&event_dummy->link); 755 prodcons_produce(&win->queue, &event_dummy->link); 695 756 } 696 757 … … 706 767 } 707 768 708 /* Release window resources. */709 loc_service_unregister(win->in_dsid);710 loc_service_unregister(win->out_dsid);711 while (!list_empty(&win->queue.list)) {712 list_remove(list_first(&win->queue.list));713 }714 window_destroy(win);715 716 769 comp_damage(x, y, width, height); 717 770 … … 803 856 window_t *win = NULL; 804 857 fibril_mutex_lock(&window_list_mtx); 805 list_foreach(window_list, link) { 806 window_t *cur = list_get_instance(link, window_t, link); 858 list_foreach(window_list, link, window_t, cur) { 807 859 if (cur->in_dsid == service_id || cur->out_dsid == service_id) { 808 860 win = cur; … … 813 865 814 866 if (win) { 867 atomic_inc(&win->ref_cnt); 815 868 async_answer_0(iid, EOK); 816 869 } else { … … 825 878 826 879 if (!IPC_GET_IMETHOD(call)) { 827 async_answer_0(callid, EINVAL); 880 async_answer_0(callid, EOK); 881 atomic_dec(&win->ref_cnt); 882 window_destroy(win); 828 883 return; 829 884 } … … 842 897 843 898 if (!IPC_GET_IMETHOD(call)) { 844 async_answer_0(callid, EINVAL); 899 comp_window_close(win, callid, &call); 900 atomic_dec(&win->ref_cnt); 901 window_destroy(win); 845 902 return; 846 903 } … … 857 914 break; 858 915 case WINDOW_CLOSE: 859 comp_window_close(win, callid, &call); 916 /* Postpone the closing until the phone is hung up to cover 917 * the case when the client is killed abruptly. */ 918 async_answer_0(callid, EOK); 860 919 break; 861 920 case WINDOW_CLOSE_REQUEST: … … 911 970 async_answer_0(iid, EOK); 912 971 972 comp_restrict_pointers(); 913 973 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 914 974 } … … 939 999 /* Close all clients and their windows. */ 940 1000 fibril_mutex_lock(&window_list_mtx); 941 list_foreach(window_list, link) { 942 window_t *win = list_get_instance(link, window_t, link); 1001 list_foreach(window_list, link, window_t, win) { 943 1002 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t)); 944 1003 if (event) { … … 956 1015 fibril_mutex_unlock(&viewport_list_mtx); 957 1016 async_answer_0(iid, EOK); 1017 1018 comp_restrict_pointers(); 1019 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 958 1020 } 959 1021 } … … 963 1025 viewport_t *vp = NULL; 964 1026 fibril_mutex_lock(&viewport_list_mtx); 965 list_foreach(viewport_list, link) { 966 viewport_t *cur = list_get_instance(link, viewport_t, link); 1027 list_foreach(viewport_list, link, viewport_t, cur) { 967 1028 if (cur->dsid == (service_id_t) IPC_GET_ARG1(*icall)) { 968 1029 vp = cur; … … 1391 1452 surface_get_resolution(pointer->cursor.states[pointer->state], 1392 1453 &cursor_width, &cursor_height); 1454 if (pointer->pos.x + dx < viewport_bound_rect.x) { 1455 dx = -1 * (pointer->pos.x - viewport_bound_rect.x); 1456 } 1457 if (pointer->pos.y + dy < viewport_bound_rect.y) { 1458 dy = -1 * (pointer->pos.y - viewport_bound_rect.y); 1459 } 1460 if (pointer->pos.x + dx > viewport_bound_rect.x + viewport_bound_rect.w) { 1461 dx = (viewport_bound_rect.x + viewport_bound_rect.w - pointer->pos.x); 1462 } 1463 if (pointer->pos.y + dy > viewport_bound_rect.y + viewport_bound_rect.h) { 1464 dy = (viewport_bound_rect.y + viewport_bound_rect.h - pointer->pos.y); 1465 } 1393 1466 pointer->pos.x += dx; 1394 1467 pointer->pos.y += dy; … … 1488 1561 1489 1562 /* Determine the window which the mouse click belongs to. */ 1490 list_foreach(window_list, link ) {1491 win = list_get_instance(link, window_t, link);1563 list_foreach(window_list, link, window_t, cw) { 1564 win = cw; 1492 1565 if (win->surface) { 1493 1566 surface_get_resolution(win->surface, &width, &height); … … 1910 1983 fibril_mutex_unlock(&viewport_list_mtx); 1911 1984 1985 comp_restrict_pointers(); 1912 1986 comp_damage(x, y, width, height); 1913 1987 } else { … … 2042 2116 } 2043 2117 2118 static int discover_viewports(void) 2119 { 2120 /* Create viewports and connect them to visualizers. */ 2121 category_id_t cat_id; 2122 int rc = loc_category_get_id("visualizer", &cat_id, IPC_FLAG_BLOCKING); 2123 if (rc != EOK) { 2124 printf("%s: Failed to get visualizer category.\n", NAME); 2125 return -1; 2126 } 2127 2128 service_id_t *svcs; 2129 size_t svcs_cnt = 0; 2130 rc = loc_category_get_svcs(cat_id, &svcs, &svcs_cnt); 2131 if (rc != EOK || svcs_cnt == 0) { 2132 printf("%s: Failed to get visualizer category services.\n", NAME); 2133 return -1; 2134 } 2135 2136 fibril_mutex_lock(&viewport_list_mtx); 2137 for (size_t i = 0; i < svcs_cnt; ++i) { 2138 bool exists = false; 2139 list_foreach(viewport_list, link, viewport_t, vp) { 2140 if (vp->dsid == svcs[i]) { 2141 exists = true; 2142 break; 2143 } 2144 } 2145 2146 if (exists) 2147 continue; 2148 2149 char *svc_name; 2150 rc = loc_service_get_name(svcs[i], &svc_name); 2151 if (rc == EOK) { 2152 viewport_t *vp = viewport_create(svc_name); 2153 if (vp != NULL) { 2154 list_append(&vp->link, &viewport_list); 2155 } 2156 } 2157 } 2158 fibril_mutex_unlock(&viewport_list_mtx); 2159 2160 /* TODO damage only newly added viewports */ 2161 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 2162 return EOK; 2163 } 2164 2165 static void category_change_cb(void) 2166 { 2167 fibril_mutex_lock(&discovery_mtx); 2168 discover_viewports(); 2169 fibril_mutex_unlock(&discovery_mtx); 2170 } 2171 2044 2172 static int compositor_srv_init(char *input_svc, char *name) 2045 2173 { … … 2048 2176 2049 2177 /* Color of the viewport background. Must be opaque. */ 2050 bg_color = PIXEL(255, 75, 70, 75);2178 bg_color = PIXEL(255, 69, 51, 103); 2051 2179 2052 2180 /* Register compositor server. */ … … 2088 2216 /* Establish input bidirectional connection. */ 2089 2217 rc = input_connect(input_svc); 2090 if (rc != EOK) 2218 if (rc != EOK) { 2219 printf("%s: Failed to connect to input service.\n", NAME); 2091 2220 return rc; 2092 2093 /* Create viewports and connect them to visualizers. */ 2094 category_id_t cat_id; 2095 rc = loc_category_get_id("visualizer", &cat_id, IPC_FLAG_BLOCKING); 2221 } 2222 2223 rc = loc_register_cat_change_cb(category_change_cb); 2224 if (rc != EOK) { 2225 printf("%s: Failed to register category change callback\n", NAME); 2226 input_disconnect(); 2227 return rc; 2228 } 2229 2230 rc = discover_viewports(); 2096 2231 if (rc != EOK) { 2097 2232 input_disconnect(); 2098 return -1; 2099 } 2100 2101 service_id_t *svcs; 2102 size_t svcs_cnt = 0; 2103 rc = loc_category_get_svcs(cat_id, &svcs, &svcs_cnt); 2104 if (rc != EOK || svcs_cnt == 0) { 2233 return rc; 2234 } 2235 2236 if (list_empty(&viewport_list)) { 2237 printf("%s: Failed to get viewports.\n", NAME); 2105 2238 input_disconnect(); 2106 2239 return -1; 2107 2240 } 2108 2109 for (size_t i = 0; i < svcs_cnt; ++i) { 2110 char *svc_name; 2111 rc = loc_service_get_name(svcs[i], &svc_name); 2112 if (rc == EOK) { 2113 viewport_t *vp = viewport_create(svc_name); 2114 if (vp != NULL) { 2115 list_append(&vp->link, &viewport_list); 2116 } 2117 } 2118 } 2119 2120 if (list_empty(&viewport_list)) { 2121 input_disconnect(); 2122 return -1; 2123 } 2124 2241 2242 comp_restrict_pointers(); 2125 2243 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 2244 2126 2245 2127 2246 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.