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