Changes in uspace/srv/hid/compositor/compositor.c [00ddb40:8e4a408] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/compositor/compositor.c
r00ddb40 r8e4a408 56 56 #include <loc.h> 57 57 58 #include <event.h> 58 59 #include <io/keycode.h> 59 60 #include <io/mode.h> 60 61 #include <io/visualizer.h> 61 62 #include <io/window.h> 62 #include <io/console.h>63 63 64 64 #include <transform.h> … … 84 84 static sysarg_t coord_origin; 85 85 static pixel_t bg_color; 86 static filter_t filter = filter_bilinear;87 static unsigned int filter_index = 1;88 86 89 87 typedef struct { … … 146 144 /** Input server proxy */ 147 145 static input_t *input; 148 static bool active = false; 149 150 static int comp_active(input_t *); 151 static int comp_deactive(input_t *); 146 152 147 static int comp_key_press(input_t *, kbd_event_type_t, keycode_t, keymod_t, wchar_t); 153 148 static int comp_mouse_move(input_t *, int, int); … … 156 151 157 152 static input_ev_ops_t input_ev_ops = { 158 .active = comp_active,159 .deactive = comp_deactive,160 153 .key = comp_key_press, 161 154 .move = comp_mouse_move, … … 163 156 .button = comp_mouse_button 164 157 }; 158 159 static void input_disconnect(void); 165 160 166 161 static pointer_t *input_pointer(input_t *input) … … 235 230 static void window_destroy(window_t *win) 236 231 { 237 if ( (win) && (atomic_get(&win->ref_cnt) == 0)) {232 if (win && atomic_get(&win->ref_cnt) == 0) { 238 233 while (!list_empty(&win->queue.list)) { 239 234 window_event_t *event = (window_event_t *) list_first(&win->queue.list); … … 241 236 free(event); 242 237 } 243 244 if (win->surface) 238 239 if (win->surface) { 245 240 surface_destroy(win->surface); 246 241 } 247 242 free(win); 248 243 } … … 256 251 transform_invert(&win_trans); 257 252 transform_apply_affine(&win_trans, &x, &y); 258 259 /* 260 * Since client coordinate origin is (0, 0), it is necessary to check 253 254 /* Since client coordinate origin is (0, 0), it is necessary to check 261 255 * coordinates to avoid underflow. Moreover, it is convenient to also 262 256 * check against provided upper limits to determine whether the converted 263 * coordinates are within the client window. 264 */ 265 if ((x < 0) || (y < 0)) 257 * coordinates are within the client window. */ 258 if (x < 0 || y < 0) { 266 259 return false; 267 268 (*x_out) = (sysarg_t) (x + 0.5); 269 (*y_out) = (sysarg_t) (y + 0.5); 270 271 if (((*x_out) >= x_lim) || ((*y_out) >= y_lim)) 272 return false; 273 274 return true; 260 } else { 261 (*x_out) = (sysarg_t) (x + 0.5); 262 (*y_out) = (sysarg_t) (y + 0.5); 263 264 if ((*x_out) >= x_lim || (*y_out) >= y_lim) { 265 return false; 266 } else { 267 return true; 268 } 269 } 275 270 } 276 271 … … 282 277 transform_apply_affine(&win_trans, &x, &y); 283 278 284 /* 285 * It is assumed that compositor coordinate origin is chosen in such way, 286 * that underflow/overflow here would be unlikely. 287 */ 279 /* It is assumed that compositor coordinate origin is chosen in such way, 280 * that underflow/overflow here would be unlikely. */ 288 281 (*x_out) = (sysarg_t) (x + 0.5); 289 282 (*y_out) = (sysarg_t) (y + 0.5); … … 410 403 411 404 source_init(&source); 412 source_set_filter(&source, filter );405 source_set_filter(&source, filter_nearest); 413 406 drawctx_init(&context, vp->surface); 414 407 drawctx_set_compose(&context, compose_over); … … 443 436 transform_translate(&transform, -pos.x, -pos.y); 444 437 445 source_set_transform(&source, transform); 446 source_set_texture(&source, win->surface, 447 PIXELMAP_EXTEND_TRANSPARENT_SIDES); 438 source_set_transform(&source, transform); 439 source_set_texture(&source, win->surface, false); 448 440 source_set_alpha(&source, PIXEL(win->opacity, 0, 0, 0)); 449 441 … … 573 565 574 566 /* Notify visualizers about updated regions. */ 575 if (active) { 576 list_foreach(viewport_list, link, viewport_t, vp) { 577 sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp; 578 surface_get_damaged_region(vp->surface, &x_dmg_vp, &y_dmg_vp, &w_dmg_vp, &h_dmg_vp); 579 surface_reset_damaged_region(vp->surface); 580 visualizer_update_damaged_region(vp->sess, 581 x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp, 0, 0); 582 } 583 } 584 567 list_foreach(viewport_list, link, viewport_t, vp) { 568 sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp; 569 surface_get_damaged_region(vp->surface, &x_dmg_vp, &y_dmg_vp, &w_dmg_vp, &h_dmg_vp); 570 surface_reset_damaged_region(vp->surface); 571 visualizer_update_damaged_region( 572 vp->sess, x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp, 0, 0); 573 } 574 585 575 fibril_mutex_unlock(&viewport_list_mtx); 586 576 } … … 598 588 return; 599 589 } 600 601 590 int rc = async_data_read_finalize(callid, event, len); 602 591 if (rc != EOK) { … … 605 594 return; 606 595 } 607 608 596 async_answer_0(iid, EOK); 597 609 598 free(event); 610 599 } … … 617 606 double height = IPC_GET_ARG4(*icall); 618 607 619 if ( (width == 0) || (height == 0)) {608 if (width == 0 || height == 0) { 620 609 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 621 610 } else { … … 866 855 867 856 comp_damage(x, y, width, height); 857 868 858 async_answer_0(iid, EOK); 869 859 } … … 871 861 static void comp_window_close_request(window_t *win, ipc_callid_t iid, ipc_call_t *icall) 872 862 { 873 863 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t)); 874 864 if (event == NULL) { 875 865 async_answer_0(iid, ENOMEM); … … 1011 1001 break; 1012 1002 case WINDOW_CLOSE: 1013 /* 1014 * Postpone the closing until the phone is hung up to cover 1015 * the case when the client is killed abruptly. 1016 */ 1003 /* Postpone the closing until the phone is hung up to cover 1004 * the case when the client is killed abruptly. */ 1017 1005 async_answer_0(callid, EOK); 1018 1006 break; … … 1029 1017 static void comp_mode_change(viewport_t *vp, ipc_callid_t iid, ipc_call_t *icall) 1030 1018 { 1019 int rc; 1031 1020 sysarg_t mode_idx = IPC_GET_ARG2(*icall); 1032 1021 fibril_mutex_lock(&viewport_list_mtx); … … 1034 1023 /* Retrieve the mode that shall be set. */ 1035 1024 vslmode_t new_mode; 1036 intrc = visualizer_get_mode(vp->sess, &new_mode, mode_idx);1025 rc = visualizer_get_mode(vp->sess, &new_mode, mode_idx); 1037 1026 if (rc != EOK) { 1038 1027 fibril_mutex_unlock(&viewport_list_mtx); … … 1052 1041 /* Try to set the mode and share out the surface. */ 1053 1042 rc = visualizer_set_mode(vp->sess, 1054 1043 new_mode.index, new_mode.version, surface_direct_access(new_surface)); 1055 1044 if (rc != EOK) { 1056 1045 surface_destroy(new_surface); … … 1082 1071 } 1083 1072 1084 #if 01085 static void comp_shutdown(void)1086 {1087 loc_service_unregister(winreg_id);1088 input_disconnect();1089 1090 /* Close all clients and their windows. */1091 fibril_mutex_lock(&window_list_mtx);1092 list_foreach(window_list, link, window_t, win) {1093 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));1094 if (event) {1095 link_initialize(&event->link);1096 event->type = WINDOW_CLOSE;1097 prodcons_produce(&win->queue, &event->link);1098 }1099 }1100 fibril_mutex_unlock(&window_list_mtx);1101 1102 async_answer_0(iid, EOK);1103 1104 /* All fibrils of the compositor will terminate soon. */1105 }1106 #endif1107 1108 1073 static void comp_visualizer_disconnect(viewport_t *vp, ipc_callid_t iid, ipc_call_t *icall) 1109 1074 { 1110 1075 /* Release viewport resources. */ 1111 1076 fibril_mutex_lock(&viewport_list_mtx); 1112 1113 1077 list_remove(&vp->link); 1114 1078 viewport_destroy(vp); 1115 1116 fibril_mutex_unlock(&viewport_list_mtx); 1117 1118 async_answer_0(iid, EOK); 1119 1120 comp_restrict_pointers(); 1121 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 1079 1080 /* Terminate compositor if there are no more viewports. */ 1081 if (list_empty(&viewport_list)) { 1082 fibril_mutex_unlock(&viewport_list_mtx); 1083 loc_service_unregister(winreg_id); 1084 input_disconnect(); 1085 1086 /* Close all clients and their windows. */ 1087 fibril_mutex_lock(&window_list_mtx); 1088 list_foreach(window_list, link, window_t, win) { 1089 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t)); 1090 if (event) { 1091 link_initialize(&event->link); 1092 event->type = WINDOW_CLOSE; 1093 prodcons_produce(&win->queue, &event->link); 1094 } 1095 } 1096 fibril_mutex_unlock(&window_list_mtx); 1097 1098 async_answer_0(iid, EOK); 1099 1100 /* All fibrils of the compositor will terminate soon. */ 1101 } else { 1102 fibril_mutex_unlock(&viewport_list_mtx); 1103 async_answer_0(iid, EOK); 1104 1105 comp_restrict_pointers(); 1106 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 1107 } 1122 1108 } 1123 1109 … … 1134 1120 fibril_mutex_unlock(&viewport_list_mtx); 1135 1121 1136 if (!vp) 1122 if (!vp) { 1137 1123 return; 1124 } 1138 1125 1139 1126 /* Ignore parameters, the connection is already opened. */ … … 1236 1223 /* Try to set the mode and share out the surface. */ 1237 1224 rc = visualizer_set_mode(vp->sess, 1238 1225 vp->mode.index, vp->mode.version, surface_direct_access(vp->surface)); 1239 1226 if (rc != EOK) { 1240 1227 printf("%s: Unable to set mode (%s)\n", NAME, str_error(rc)); … … 1246 1233 if (claimed) 1247 1234 visualizer_yield(vp->sess); 1248 1249 1235 if (vp->sess != NULL) 1250 1236 async_hangup(vp->sess); 1251 1252 1237 free(vp); 1253 1238 free(vsl_name); … … 1790 1775 } 1791 1776 1792 static int comp_active(input_t *input)1793 {1794 active = true;1795 comp_damage(0, 0, UINT32_MAX, UINT32_MAX);1796 1797 return EOK;1798 }1799 1800 static int comp_deactive(input_t *input)1801 {1802 active = false;1803 return EOK;1804 }1805 1806 1777 static int comp_key_press(input_t *input, kbd_event_type_t type, keycode_t key, 1807 1778 keymod_t mods, wchar_t c) … … 1821 1792 key == KC_O || key == KC_P); 1822 1793 bool kconsole_switch = (mods & KM_ALT) && (key == KC_M); 1823 bool filter_switch = (mods & KM_ALT) && (key == KC_Y); 1824 1825 bool key_filter = (type == KEY_RELEASE) && (win_transform || win_resize || 1794 1795 bool filter = (type == KEY_RELEASE) && (win_transform || win_resize || 1826 1796 win_opacity || win_close || win_switch || viewport_move || 1827 viewport_change || kconsole_switch || filter_switch);1828 1829 if ( key_filter) {1797 viewport_change || kconsole_switch); 1798 1799 if (filter) { 1830 1800 /* no-op */ 1831 1801 } else if (win_transform) { … … 2093 2063 fibril_mutex_unlock(&viewport_list_mtx); 2094 2064 } else if (kconsole_switch) { 2095 if (console_kcon()) 2096 active = false; 2097 } else if (filter_switch) { 2098 filter_index++; 2099 if (filter_index > 1) 2100 filter_index = 0; 2101 if (filter_index == 0) { 2102 filter = filter_nearest; 2103 } 2104 else { 2105 filter = filter_bilinear; 2106 } 2107 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 2065 __SYSCALL0(SYS_DEBUG_ACTIVATE_CONSOLE); 2108 2066 } else { 2109 2067 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t)); … … 2174 2132 } 2175 2133 2176 static void discover_viewports(void) 2177 { 2178 fibril_mutex_lock(&discovery_mtx); 2179 2134 static void interrupt_received(ipc_callid_t callid, ipc_call_t *call) 2135 { 2136 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 2137 } 2138 2139 static int discover_viewports(void) 2140 { 2180 2141 /* Create viewports and connect them to visualizers. */ 2181 2142 category_id_t cat_id; 2182 2143 int rc = loc_category_get_id("visualizer", &cat_id, IPC_FLAG_BLOCKING); 2183 if (rc != EOK) 2184 goto ret; 2144 if (rc != EOK) { 2145 printf("%s: Failed to get visualizer category.\n", NAME); 2146 return -1; 2147 } 2185 2148 2186 2149 service_id_t *svcs; 2187 2150 size_t svcs_cnt = 0; 2188 2151 rc = loc_category_get_svcs(cat_id, &svcs, &svcs_cnt); 2189 if (rc != EOK) 2190 goto ret; 2191 2192 fibril_mutex_lock(&viewport_list_mtx); 2152 if (rc != EOK || svcs_cnt == 0) { 2153 printf("%s: Failed to get visualizer category services.\n", NAME); 2154 return -1; 2155 } 2156 2157 fibril_mutex_lock(&viewport_list_mtx); 2193 2158 for (size_t i = 0; i < svcs_cnt; ++i) { 2194 2159 bool exists = false; … … 2209 2174 fibril_mutex_unlock(&viewport_list_mtx); 2210 2175 2211 if (!list_empty(&viewport_list)) 2212 input_activate(input); 2213 2214 ret: 2176 /* TODO damage only newly added viewports */ 2177 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 2178 return EOK; 2179 } 2180 2181 static void category_change_cb(void) 2182 { 2183 fibril_mutex_lock(&discovery_mtx); 2184 discover_viewports(); 2215 2185 fibril_mutex_unlock(&discovery_mtx); 2216 }2217 2218 static void category_change_cb(void)2219 {2220 discover_viewports();2221 2186 } 2222 2187 … … 2231 2196 /* Register compositor server. */ 2232 2197 async_set_client_connection(client_connection); 2233 2234 2198 int rc = loc_server_register(NAME); 2235 2199 if (rc != EOK) { 2236 2200 printf("%s: Unable to register server (%s)\n", NAME, str_error(rc)); 2237 2201 return -1; 2202 } 2203 2204 /* Register interrupt handler to switch back from kconsole. */ 2205 async_set_interrupt_received(interrupt_received); 2206 rc = event_subscribe(EVENT_KCONSOLE, 0); 2207 if (rc != EOK) { 2208 printf("%s: Failed to register kconsole notifications (%s)\n", 2209 NAME, str_error(rc)); 2238 2210 } 2239 2211 … … 2257 2229 return -1; 2258 2230 } 2259 2231 2260 2232 /* Establish input bidirectional connection. */ 2261 2233 rc = input_connect(input_svc); … … 2264 2236 return rc; 2265 2237 } 2266 2238 2267 2239 rc = loc_register_cat_change_cb(category_change_cb); 2268 2240 if (rc != EOK) { … … 2270 2242 input_disconnect(); 2271 2243 return rc; 2272 } 2273 2274 discover_viewports(); 2275 2244 } 2245 2246 rc = discover_viewports(); 2247 if (rc != EOK) { 2248 input_disconnect(); 2249 return rc; 2250 } 2251 2252 if (list_empty(&viewport_list)) { 2253 printf("%s: Failed to get viewports.\n", NAME); 2254 input_disconnect(); 2255 return -1; 2256 } 2257 2276 2258 comp_restrict_pointers(); 2277 2259 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 2260 2278 2261 2279 2262 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.