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