Changes in uspace/srv/hid/compositor/compositor.c [62fbb7e:00ddb40] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/compositor/compositor.c
r62fbb7e r00ddb40 55 55 #include <async.h> 56 56 #include <loc.h> 57 #include <devman.h> 58 59 #include <event.h> 60 #include <device/graph_dev.h> 57 61 58 #include <io/keycode.h> 62 59 #include <io/mode.h> 63 60 #include <io/visualizer.h> 64 61 #include <io/window.h> 62 #include <io/console.h> 65 63 66 64 #include <transform.h> … … 86 84 static sysarg_t coord_origin; 87 85 static pixel_t bg_color; 86 static filter_t filter = filter_bilinear; 87 static unsigned int filter_index = 1; 88 88 89 89 typedef struct { … … 146 146 /** Input server proxy */ 147 147 static input_t *input; 148 148 static bool active = false; 149 150 static int comp_active(input_t *); 151 static int comp_deactive(input_t *); 149 152 static int comp_key_press(input_t *, kbd_event_type_t, keycode_t, keymod_t, wchar_t); 150 153 static int comp_mouse_move(input_t *, int, int); … … 153 156 154 157 static input_ev_ops_t input_ev_ops = { 158 .active = comp_active, 159 .deactive = comp_deactive, 155 160 .key = comp_key_press, 156 161 .move = comp_mouse_move, … … 158 163 .button = comp_mouse_button 159 164 }; 160 161 static void input_disconnect(void);162 165 163 166 static pointer_t *input_pointer(input_t *input) … … 232 235 static void window_destroy(window_t *win) 233 236 { 234 if ( win && atomic_get(&win->ref_cnt) == 0) {237 if ((win) && (atomic_get(&win->ref_cnt) == 0)) { 235 238 while (!list_empty(&win->queue.list)) { 236 239 window_event_t *event = (window_event_t *) list_first(&win->queue.list); … … 238 241 free(event); 239 242 } 240 241 if (win->surface) {243 244 if (win->surface) 242 245 surface_destroy(win->surface); 243 }246 244 247 free(win); 245 248 } … … 253 256 transform_invert(&win_trans); 254 257 transform_apply_affine(&win_trans, &x, &y); 255 256 /* 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 257 261 * coordinates to avoid underflow. Moreover, it is convenient to also 258 262 * check against provided upper limits to determine whether the converted 259 * coordinates are within the client window. */ 260 if (x < 0 || y < 0) { 263 * coordinates are within the client window. 264 */ 265 if ((x < 0) || (y < 0)) 261 266 return false; 262 } else { 263 (*x_out) = (sysarg_t) (x + 0.5); 264 (*y_out) = (sysarg_t) (y + 0.5); 265 266 if ((*x_out) >= x_lim || (*y_out) >= y_lim) { 267 return false; 268 } else { 269 return true; 270 } 271 } 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; 272 275 } 273 276 … … 279 282 transform_apply_affine(&win_trans, &x, &y); 280 283 281 /* It is assumed that compositor coordinate origin is chosen in such way, 282 * 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 */ 283 288 (*x_out) = (sysarg_t) (x + 0.5); 284 289 (*y_out) = (sysarg_t) (y + 0.5); … … 405 410 406 411 source_init(&source); 407 source_set_filter(&source, filter _nearest);412 source_set_filter(&source, filter); 408 413 drawctx_init(&context, vp->surface); 409 414 drawctx_set_compose(&context, compose_over); … … 438 443 transform_translate(&transform, -pos.x, -pos.y); 439 444 440 source_set_transform(&source, transform); 441 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); 442 448 source_set_alpha(&source, PIXEL(win->opacity, 0, 0, 0)); 443 449 … … 567 573 568 574 /* Notify visualizers about updated regions. */ 569 list_foreach(viewport_list, link, viewport_t, vp) { 570 sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp; 571 surface_get_damaged_region(vp->surface, &x_dmg_vp, &y_dmg_vp, &w_dmg_vp, &h_dmg_vp); 572 surface_reset_damaged_region(vp->surface); 573 visualizer_update_damaged_region( 574 vp->sess, x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp, 0, 0); 575 } 576 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 577 585 fibril_mutex_unlock(&viewport_list_mtx); 578 586 } … … 590 598 return; 591 599 } 600 592 601 int rc = async_data_read_finalize(callid, event, len); 593 602 if (rc != EOK) { … … 596 605 return; 597 606 } 607 598 608 async_answer_0(iid, EOK); 599 600 609 free(event); 601 610 } … … 608 617 double height = IPC_GET_ARG4(*icall); 609 618 610 if ( width == 0 || height == 0) {619 if ((width == 0) || (height == 0)) { 611 620 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 612 621 } else { … … 665 674 transform_identity(&transform); 666 675 temp = transform; 667 transform_ multiply(&transform, &temp, &translate);676 transform_product(&transform, &temp, &translate); 668 677 temp = transform; 669 transform_ multiply(&transform, &temp, &rotate);678 transform_product(&transform, &temp, &rotate); 670 679 temp = transform; 671 transform_ multiply(&transform, &temp, &scale);680 transform_product(&transform, &temp, &scale); 672 681 673 682 win->transform = transform; … … 857 866 858 867 comp_damage(x, y, width, height); 859 860 868 async_answer_0(iid, EOK); 861 869 } … … 863 871 static void comp_window_close_request(window_t *win, ipc_callid_t iid, ipc_call_t *icall) 864 872 { 865 873 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t)); 866 874 if (event == NULL) { 867 875 async_answer_0(iid, ENOMEM); … … 1003 1011 break; 1004 1012 case WINDOW_CLOSE: 1005 /* Postpone the closing until the phone is hung up to cover 1006 * 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 */ 1007 1017 async_answer_0(callid, EOK); 1008 1018 break; … … 1019 1029 static void comp_mode_change(viewport_t *vp, ipc_callid_t iid, ipc_call_t *icall) 1020 1030 { 1021 int rc;1022 1031 sysarg_t mode_idx = IPC_GET_ARG2(*icall); 1023 1032 fibril_mutex_lock(&viewport_list_mtx); … … 1025 1034 /* Retrieve the mode that shall be set. */ 1026 1035 vslmode_t new_mode; 1027 rc = visualizer_get_mode(vp->sess, &new_mode, mode_idx);1036 int rc = visualizer_get_mode(vp->sess, &new_mode, mode_idx); 1028 1037 if (rc != EOK) { 1029 1038 fibril_mutex_unlock(&viewport_list_mtx); … … 1043 1052 /* Try to set the mode and share out the surface. */ 1044 1053 rc = visualizer_set_mode(vp->sess, 1045 1054 new_mode.index, new_mode.version, surface_direct_access(new_surface)); 1046 1055 if (rc != EOK) { 1047 1056 surface_destroy(new_surface); … … 1073 1082 } 1074 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 1075 1108 static void comp_visualizer_disconnect(viewport_t *vp, ipc_callid_t iid, ipc_call_t *icall) 1076 1109 { 1077 1110 /* Release viewport resources. */ 1078 1111 fibril_mutex_lock(&viewport_list_mtx); 1112 1079 1113 list_remove(&vp->link); 1080 1114 viewport_destroy(vp); 1081 1082 /* Terminate compositor if there are no more viewports. */ 1083 if (list_empty(&viewport_list)) { 1084 fibril_mutex_unlock(&viewport_list_mtx); 1085 loc_service_unregister(winreg_id); 1086 input_disconnect(); 1087 1088 /* Close all clients and their windows. */ 1089 fibril_mutex_lock(&window_list_mtx); 1090 list_foreach(window_list, link, window_t, win) { 1091 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t)); 1092 if (event) { 1093 link_initialize(&event->link); 1094 event->type = WINDOW_CLOSE; 1095 prodcons_produce(&win->queue, &event->link); 1096 } 1097 } 1098 fibril_mutex_unlock(&window_list_mtx); 1099 1100 async_answer_0(iid, EOK); 1101 1102 /* All fibrils of the compositor will terminate soon. */ 1103 } else { 1104 fibril_mutex_unlock(&viewport_list_mtx); 1105 async_answer_0(iid, EOK); 1106 1107 comp_restrict_pointers(); 1108 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 1109 } 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); 1110 1122 } 1111 1123 … … 1122 1134 fibril_mutex_unlock(&viewport_list_mtx); 1123 1135 1124 if (!vp) {1136 if (!vp) 1125 1137 return; 1126 }1127 1138 1128 1139 /* Ignore parameters, the connection is already opened. */ … … 1149 1160 } 1150 1161 1151 static async_sess_t *vsl_connect( const char *svc)1162 static async_sess_t *vsl_connect(service_id_t sid, const char *svc) 1152 1163 { 1153 1164 int rc; 1154 1165 async_sess_t *sess; 1155 service_id_t dsid; 1156 devman_handle_t handle; 1157 1158 rc = loc_service_get_id(svc, &dsid, 0); 1159 if (rc != EOK) { 1166 1167 sess = loc_service_connect(EXCHANGE_SERIALIZE, sid, 0); 1168 if (sess == NULL) { 1169 printf("%s: Unable to connect to visualizer %s\n", NAME, svc); 1160 1170 return NULL; 1161 1171 } 1162 1172 1163 rc = devman_fun_sid_to_handle(dsid, &handle);1164 if (rc == EOK) {1165 sess = devman_device_connect(EXCHANGE_SERIALIZE, handle, 0);1166 if (sess == NULL) {1167 printf("%s: Unable to connect to visualizer %s\n", NAME, svc);1168 return NULL;1169 }1170 rc = graph_dev_connect(sess);1171 if (rc != EOK) {1172 return NULL;1173 }1174 } else if (rc == ENOENT) {1175 sess = loc_service_connect(EXCHANGE_SERIALIZE, dsid, 0);1176 if (sess == NULL) {1177 printf("%s: Unable to connect to visualizer %s\n", NAME, svc);1178 return NULL;1179 }1180 } else {1181 return NULL;1182 }1183 1184 1173 async_exch_t *exch = async_exchange_begin(sess); 1185 rc = async_connect_to_me(exch, dsid, 0, 0, vsl_notifications, NULL);1174 rc = async_connect_to_me(exch, sid, 0, 0, vsl_notifications, NULL); 1186 1175 async_exchange_end(exch); 1187 1176 … … 1196 1185 } 1197 1186 1198 static viewport_t *viewport_create( const char *vsl_name)1187 static viewport_t *viewport_create(service_id_t sid) 1199 1188 { 1200 1189 int rc; 1201 1202 viewport_t *vp = (viewport_t *) malloc(sizeof(viewport_t)); 1203 if (!vp) { 1204 return NULL; 1205 } 1190 char *vsl_name = NULL; 1191 viewport_t *vp = NULL; 1192 bool claimed = false; 1193 1194 rc = loc_service_get_name(sid, &vsl_name); 1195 if (rc != EOK) 1196 goto error; 1197 1198 vp = (viewport_t *) calloc(1, sizeof(viewport_t)); 1199 if (!vp) 1200 goto error; 1206 1201 1207 1202 link_initialize(&vp->link); … … 1210 1205 1211 1206 /* Establish output bidirectional connection. */ 1212 vp->sess = vsl_connect(vsl_name); 1213 rc = loc_service_get_id(vsl_name, &vp->dsid, 0); 1214 if (vp->sess == NULL || rc != EOK) { 1215 free(vp); 1216 return NULL; 1217 } 1207 vp->dsid = sid; 1208 vp->sess = vsl_connect(sid, vsl_name); 1209 if (vp->sess == NULL) 1210 goto error; 1218 1211 1219 1212 /* Claim the given visualizer. */ 1220 1213 rc = visualizer_claim(vp->sess, 0); 1221 1214 if (rc != EOK) { 1222 async_hangup(vp->sess);1223 free(vp);1224 1215 printf("%s: Unable to claim visualizer (%s)\n", NAME, str_error(rc)); 1225 return NULL; 1226 } 1216 goto error; 1217 } 1218 1219 claimed = true; 1227 1220 1228 1221 /* Retrieve the default mode. */ 1229 1222 rc = visualizer_get_default_mode(vp->sess, &vp->mode); 1230 1223 if (rc != EOK) { 1231 visualizer_yield(vp->sess);1232 async_hangup(vp->sess);1233 free(vp);1234 1224 printf("%s: Unable to retrieve mode (%s)\n", NAME, str_error(rc)); 1235 return NULL;1225 goto error; 1236 1226 } 1237 1227 … … 1240 1230 NULL, SURFACE_FLAG_SHARED); 1241 1231 if (vp->surface == NULL) { 1242 visualizer_yield(vp->sess);1243 async_hangup(vp->sess);1244 free(vp);1245 1232 printf("%s: Unable to create surface (%s)\n", NAME, str_error(rc)); 1246 return NULL;1233 goto error; 1247 1234 } 1248 1235 1249 1236 /* Try to set the mode and share out the surface. */ 1250 1237 rc = visualizer_set_mode(vp->sess, 1251 1238 vp->mode.index, vp->mode.version, surface_direct_access(vp->surface)); 1252 1239 if (rc != EOK) { 1240 printf("%s: Unable to set mode (%s)\n", NAME, str_error(rc)); 1241 goto error; 1242 } 1243 1244 return vp; 1245 error: 1246 if (claimed) 1253 1247 visualizer_yield(vp->sess); 1254 surface_destroy(vp->surface); 1248 1249 if (vp->sess != NULL) 1255 1250 async_hangup(vp->sess); 1256 free(vp); 1257 printf("%s: Unable to set mode (%s)\n", NAME, str_error(rc)); 1258 return NULL; 1259 } 1260 1261 return vp; 1251 1252 free(vp); 1253 free(vsl_name); 1254 return NULL; 1262 1255 } 1263 1256 … … 1797 1790 } 1798 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 1799 1806 static int comp_key_press(input_t *input, kbd_event_type_t type, keycode_t key, 1800 1807 keymod_t mods, wchar_t c) … … 1814 1821 key == KC_O || key == KC_P); 1815 1822 bool kconsole_switch = (mods & KM_ALT) && (key == KC_M); 1816 1817 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 || 1818 1826 win_opacity || win_close || win_switch || viewport_move || 1819 viewport_change || kconsole_switch );1820 1821 if ( filter) {1827 viewport_change || kconsole_switch || filter_switch); 1828 1829 if (key_filter) { 1822 1830 /* no-op */ 1823 1831 } else if (win_transform) { … … 1839 1847 break; 1840 1848 case KC_Q: 1841 win->angle += (PI / 2);1849 win->angle += 0.1; 1842 1850 break; 1843 1851 case KC_E: 1844 win->angle += -(PI / 2);1852 win->angle -= 0.1; 1845 1853 break; 1846 1854 case KC_R: … … 2085 2093 fibril_mutex_unlock(&viewport_list_mtx); 2086 2094 } else if (kconsole_switch) { 2087 __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); 2088 2108 } else { 2089 2109 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t)); … … 2154 2174 } 2155 2175 2156 static void interrupt_received(ipc_callid_t callid, ipc_call_t *call) 2157 { 2158 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 2159 } 2160 2161 static int discover_viewports(void) 2162 { 2176 static void discover_viewports(void) 2177 { 2178 fibril_mutex_lock(&discovery_mtx); 2179 2163 2180 /* Create viewports and connect them to visualizers. */ 2164 2181 category_id_t cat_id; 2165 2182 int rc = loc_category_get_id("visualizer", &cat_id, IPC_FLAG_BLOCKING); 2166 if (rc != EOK) { 2167 printf("%s: Failed to get visualizer category.\n", NAME); 2168 return -1; 2169 } 2183 if (rc != EOK) 2184 goto ret; 2170 2185 2171 2186 service_id_t *svcs; 2172 2187 size_t svcs_cnt = 0; 2173 2188 rc = loc_category_get_svcs(cat_id, &svcs, &svcs_cnt); 2174 if (rc != EOK || svcs_cnt == 0) { 2175 printf("%s: Failed to get visualizer category services.\n", NAME); 2176 return -1; 2177 } 2178 2179 fibril_mutex_lock(&viewport_list_mtx); 2189 if (rc != EOK) 2190 goto ret; 2191 2192 fibril_mutex_lock(&viewport_list_mtx); 2180 2193 for (size_t i = 0; i < svcs_cnt; ++i) { 2181 2194 bool exists = false; … … 2190 2203 continue; 2191 2204 2192 char *svc_name; 2193 rc = loc_service_get_name(svcs[i], &svc_name); 2194 if (rc == EOK) { 2195 viewport_t *vp = viewport_create(svc_name); 2196 if (vp != NULL) { 2197 list_append(&vp->link, &viewport_list); 2198 } 2199 } 2205 viewport_t *vp = viewport_create(svcs[i]); 2206 if (vp != NULL) 2207 list_append(&vp->link, &viewport_list); 2200 2208 } 2201 2209 fibril_mutex_unlock(&viewport_list_mtx); 2202 2210 2203 /* TODO damage only newly added viewports */ 2204 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 2205 return EOK; 2211 if (!list_empty(&viewport_list)) 2212 input_activate(input); 2213 2214 ret: 2215 fibril_mutex_unlock(&discovery_mtx); 2206 2216 } 2207 2217 2208 2218 static void category_change_cb(void) 2209 2219 { 2210 fibril_mutex_lock(&discovery_mtx);2211 2220 discover_viewports(); 2212 fibril_mutex_unlock(&discovery_mtx);2213 2221 } 2214 2222 … … 2223 2231 /* Register compositor server. */ 2224 2232 async_set_client_connection(client_connection); 2233 2225 2234 int rc = loc_server_register(NAME); 2226 2235 if (rc != EOK) { 2227 2236 printf("%s: Unable to register server (%s)\n", NAME, str_error(rc)); 2228 2237 return -1; 2229 }2230 2231 /* Register interrupt handler to switch back from kconsole. */2232 async_set_interrupt_received(interrupt_received);2233 rc = event_subscribe(EVENT_KCONSOLE, 0);2234 if (rc != EOK) {2235 printf("%s: Failed to register kconsole notifications (%s)\n",2236 NAME, str_error(rc));2237 2238 } 2238 2239 … … 2256 2257 return -1; 2257 2258 } 2258 2259 2259 2260 /* Establish input bidirectional connection. */ 2260 2261 rc = input_connect(input_svc); … … 2263 2264 return rc; 2264 2265 } 2265 2266 2266 2267 rc = loc_register_cat_change_cb(category_change_cb); 2267 2268 if (rc != EOK) { … … 2269 2270 input_disconnect(); 2270 2271 return rc; 2271 } 2272 2273 rc = discover_viewports(); 2274 if (rc != EOK) { 2275 input_disconnect(); 2276 return rc; 2277 } 2278 2279 if (list_empty(&viewport_list)) { 2280 printf("%s: Failed to get viewports.\n", NAME); 2281 input_disconnect(); 2282 return -1; 2283 } 2284 2272 } 2273 2274 discover_viewports(); 2275 2285 2276 comp_restrict_pointers(); 2286 2277 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 2287 2288 2278 2289 2279 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.