Changes in uspace/srv/hid/compositor/compositor.c [fbb2d0d:b8f1a349] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/compositor/compositor.c
rfbb2d0d rb8f1a349 90 90 typedef struct { 91 91 link_t link; 92 atomic_t ref_cnt;93 92 service_id_t in_dsid; 94 93 service_id_t out_dsid; … … 139 138 } viewport_t; 140 139 141 static desktop_rect_t viewport_bound_rect;142 140 static FIBRIL_MUTEX_INITIALIZE(viewport_list_mtx); 143 141 static LIST_INITIALIZE(viewport_list); 144 145 static FIBRIL_MUTEX_INITIALIZE(discovery_mtx);146 142 147 143 /** Input server proxy */ … … 219 215 220 216 link_initialize(&win->link); 221 atomic_set(&win->ref_cnt, 0);222 217 prodcons_initialize(&win->queue); 223 218 transform_identity(&win->transform); … … 237 232 static void window_destroy(window_t *win) 238 233 { 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 234 if (win) { 246 235 if (win->surface) { 247 236 surface_destroy(win->surface); … … 321 310 } 322 311 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 369 312 static void comp_damage(sysarg_t x_dmg_glob, sysarg_t y_dmg_glob, 370 313 sysarg_t w_dmg_glob, sysarg_t h_dmg_glob) … … 374 317 fibril_mutex_lock(&pointer_list_mtx); 375 318 376 list_foreach(viewport_list, link, viewport_t, vp) { 319 list_foreach(viewport_list, link) { 320 377 321 /* Determine what part of the viewport must be updated. */ 322 viewport_t *vp = list_get_instance(link, viewport_t, link); 378 323 sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp; 379 324 surface_get_resolution(vp->surface, &w_dmg_vp, &h_dmg_vp); … … 444 389 } 445 390 446 list_foreach(pointer_list, link, pointer_t, ptr) { 391 list_foreach(pointer_list, link) { 392 393 pointer_t *ptr = list_get_instance(link, pointer_t, link); 447 394 if (ptr->ghost.surface) { 448 395 … … 518 465 } 519 466 520 list_foreach(pointer_list, link , pointer_t, ptr) {467 list_foreach(pointer_list, link) { 521 468 522 469 /* Determine what part of the pointer intersects with the 523 470 * updated area of the current viewport. */ 471 pointer_t *ptr = list_get_instance(link, pointer_t, link); 524 472 sysarg_t x_dmg_ptr, y_dmg_ptr, w_dmg_ptr, h_dmg_ptr; 525 473 surface_t *sf_ptr = ptr->cursor.states[ptr->state]; … … 564 512 565 513 /* Notify visualizers about updated regions. */ 566 list_foreach(viewport_list, link, viewport_t, vp) { 514 list_foreach(viewport_list, link) { 515 viewport_t *vp = list_get_instance(link, viewport_t, link); 567 516 sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp; 568 517 surface_get_damaged_region(vp->surface, &x_dmg_vp, &y_dmg_vp, &w_dmg_vp, &h_dmg_vp); … … 625 574 626 575 fibril_mutex_lock(&pointer_list_mtx); 627 list_foreach(pointer_list, link, pointer_t, pointer) { 576 list_foreach(pointer_list, link) { 577 pointer_t *pointer = list_get_instance(link, pointer_t, link); 628 578 if (pointer->id == pos_id) { 629 579 pointer->grab_flags = pointer->pressed ? grab_flags : GF_EMPTY; … … 703 653 { 704 654 fibril_mutex_lock(&window_list_mtx); 705 706 list_foreach(window_list, link, window_t, window) { 655 window_t *window = NULL; 656 list_foreach(window_list, link) { 657 window = list_get_instance(link, window_t, link); 707 658 if (window == target) { 708 659 prodcons_produce(&window->queue, &event->link); 709 fibril_mutex_unlock(&window_list_mtx);710 return;711 }712 }713 660 } 661 } 662 if (!window) { 663 free(event); 664 } 714 665 fibril_mutex_unlock(&window_list_mtx); 715 free(event);716 666 } 717 667 … … 743 693 if (event_focus && win_focus) { 744 694 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 be751 * 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);756 695 } 757 696 … … 767 706 } 768 707 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 769 716 comp_damage(x, y, width, height); 770 717 … … 856 803 window_t *win = NULL; 857 804 fibril_mutex_lock(&window_list_mtx); 858 list_foreach(window_list, link, window_t, cur) { 805 list_foreach(window_list, link) { 806 window_t *cur = list_get_instance(link, window_t, link); 859 807 if (cur->in_dsid == service_id || cur->out_dsid == service_id) { 860 808 win = cur; … … 865 813 866 814 if (win) { 867 atomic_inc(&win->ref_cnt);868 815 async_answer_0(iid, EOK); 869 816 } else { … … 878 825 879 826 if (!IPC_GET_IMETHOD(call)) { 880 async_answer_0(callid, EOK); 881 atomic_dec(&win->ref_cnt); 882 window_destroy(win); 827 async_answer_0(callid, EINVAL); 883 828 return; 884 829 } … … 897 842 898 843 if (!IPC_GET_IMETHOD(call)) { 899 comp_window_close(win, callid, &call); 900 atomic_dec(&win->ref_cnt); 901 window_destroy(win); 844 async_answer_0(callid, EINVAL); 902 845 return; 903 846 } … … 914 857 break; 915 858 case WINDOW_CLOSE: 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); 859 comp_window_close(win, callid, &call); 919 860 break; 920 861 case WINDOW_CLOSE_REQUEST: … … 970 911 async_answer_0(iid, EOK); 971 912 972 comp_restrict_pointers();973 913 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 974 914 } … … 999 939 /* Close all clients and their windows. */ 1000 940 fibril_mutex_lock(&window_list_mtx); 1001 list_foreach(window_list, link, window_t, win) { 941 list_foreach(window_list, link) { 942 window_t *win = list_get_instance(link, window_t, link); 1002 943 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t)); 1003 944 if (event) { … … 1015 956 fibril_mutex_unlock(&viewport_list_mtx); 1016 957 async_answer_0(iid, EOK); 1017 1018 comp_restrict_pointers();1019 comp_damage(0, 0, UINT32_MAX, UINT32_MAX);1020 958 } 1021 959 } … … 1025 963 viewport_t *vp = NULL; 1026 964 fibril_mutex_lock(&viewport_list_mtx); 1027 list_foreach(viewport_list, link, viewport_t, cur) { 965 list_foreach(viewport_list, link) { 966 viewport_t *cur = list_get_instance(link, viewport_t, link); 1028 967 if (cur->dsid == (service_id_t) IPC_GET_ARG1(*icall)) { 1029 968 vp = cur; … … 1452 1391 surface_get_resolution(pointer->cursor.states[pointer->state], 1453 1392 &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 }1466 1393 pointer->pos.x += dx; 1467 1394 pointer->pos.y += dy; … … 1561 1488 1562 1489 /* Determine the window which the mouse click belongs to. */ 1563 list_foreach(window_list, link , window_t, cw) {1564 win = cw;1490 list_foreach(window_list, link) { 1491 win = list_get_instance(link, window_t, link); 1565 1492 if (win->surface) { 1566 1493 surface_get_resolution(win->surface, &width, &height); … … 1983 1910 fibril_mutex_unlock(&viewport_list_mtx); 1984 1911 1985 comp_restrict_pointers();1986 1912 comp_damage(x, y, width, height); 1987 1913 } else { … … 2116 2042 } 2117 2043 2118 static int discover_viewports(void) 2119 { 2044 static int compositor_srv_init(char *input_svc, char *name) 2045 { 2046 /* Coordinates of the central pixel. */ 2047 coord_origin = UINT32_MAX / 4; 2048 2049 /* Color of the viewport background. Must be opaque. */ 2050 bg_color = PIXEL(255, 75, 70, 75); 2051 2052 /* Register compositor server. */ 2053 async_set_client_connection(client_connection); 2054 int rc = loc_server_register(NAME); 2055 if (rc != EOK) { 2056 printf("%s: Unable to register server (%s)\n", NAME, str_error(rc)); 2057 return -1; 2058 } 2059 2060 /* Register interrupt handler to switch back from kconsole. */ 2061 async_set_interrupt_received(interrupt_received); 2062 rc = event_subscribe(EVENT_KCONSOLE, 0); 2063 if (rc != EOK) { 2064 printf("%s: Failed to register kconsole notifications (%s)\n", 2065 NAME, str_error(rc)); 2066 } 2067 2068 server_name = name; 2069 2070 char svc[LOC_NAME_MAXLEN + 1]; 2071 snprintf(svc, LOC_NAME_MAXLEN, "%s/%s", NAMESPACE, server_name); 2072 2073 service_id_t service_id; 2074 rc = loc_service_register(svc, &service_id); 2075 if (rc != EOK) { 2076 printf("%s: Unable to register service %s\n", NAME, svc); 2077 return rc; 2078 } 2079 2080 /* Prepare window registrator (entrypoint for clients). */ 2081 char winreg[LOC_NAME_MAXLEN + 1]; 2082 snprintf(winreg, LOC_NAME_MAXLEN, "%s%s/winreg", NAMESPACE, server_name); 2083 if (loc_service_register(winreg, &winreg_id) != EOK) { 2084 printf("%s: Unable to register service %s\n", NAME, winreg); 2085 return -1; 2086 } 2087 2088 /* Establish input bidirectional connection. */ 2089 rc = input_connect(input_svc); 2090 if (rc != EOK) 2091 return rc; 2092 2120 2093 /* Create viewports and connect them to visualizers. */ 2121 2094 category_id_t cat_id; 2122 intrc = loc_category_get_id("visualizer", &cat_id, IPC_FLAG_BLOCKING);2095 rc = loc_category_get_id("visualizer", &cat_id, IPC_FLAG_BLOCKING); 2123 2096 if (rc != EOK) { 2124 printf("%s: Failed to get visualizer category.\n", NAME);2097 input_disconnect(); 2125 2098 return -1; 2126 2099 } … … 2130 2103 rc = loc_category_get_svcs(cat_id, &svcs, &svcs_cnt); 2131 2104 if (rc != EOK || svcs_cnt == 0) { 2132 printf("%s: Failed to get visualizer category services.\n", NAME);2105 input_disconnect(); 2133 2106 return -1; 2134 2107 } 2135 2136 fibril_mutex_lock(&viewport_list_mtx); 2108 2137 2109 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 2110 char *svc_name; 2150 2111 rc = loc_service_get_name(svcs[i], &svc_name); … … 2156 2117 } 2157 2118 } 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 2172 static int compositor_srv_init(char *input_svc, char *name)2173 {2174 /* Coordinates of the central pixel. */2175 coord_origin = UINT32_MAX / 4;2176 2177 /* Color of the viewport background. Must be opaque. */2178 bg_color = PIXEL(255, 69, 51, 103);2179 2180 /* Register compositor server. */2181 async_set_client_connection(client_connection);2182 int rc = loc_server_register(NAME);2183 if (rc != EOK) {2184 printf("%s: Unable to register server (%s)\n", NAME, str_error(rc));2185 return -1;2186 }2187 2188 /* Register interrupt handler to switch back from kconsole. */2189 async_set_interrupt_received(interrupt_received);2190 rc = event_subscribe(EVENT_KCONSOLE, 0);2191 if (rc != EOK) {2192 printf("%s: Failed to register kconsole notifications (%s)\n",2193 NAME, str_error(rc));2194 }2195 2196 server_name = name;2197 2198 char svc[LOC_NAME_MAXLEN + 1];2199 snprintf(svc, LOC_NAME_MAXLEN, "%s/%s", NAMESPACE, server_name);2200 2201 service_id_t service_id;2202 rc = loc_service_register(svc, &service_id);2203 if (rc != EOK) {2204 printf("%s: Unable to register service %s\n", NAME, svc);2205 return rc;2206 }2207 2208 /* Prepare window registrator (entrypoint for clients). */2209 char winreg[LOC_NAME_MAXLEN + 1];2210 snprintf(winreg, LOC_NAME_MAXLEN, "%s%s/winreg", NAMESPACE, server_name);2211 if (loc_service_register(winreg, &winreg_id) != EOK) {2212 printf("%s: Unable to register service %s\n", NAME, winreg);2213 return -1;2214 }2215 2216 /* Establish input bidirectional connection. */2217 rc = input_connect(input_svc);2218 if (rc != EOK) {2219 printf("%s: Failed to connect to input service.\n", NAME);2220 return rc;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();2231 if (rc != EOK) {2232 input_disconnect();2233 return rc;2234 }2235 2119 2236 2120 if (list_empty(&viewport_list)) { 2237 printf("%s: Failed to get viewports.\n", NAME);2238 2121 input_disconnect(); 2239 2122 return -1; 2240 2123 } 2241 2242 comp_restrict_pointers(); 2124 2243 2125 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 2244 2245 2126 2246 2127 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.