Changes in uspace/srv/hid/compositor/compositor.c [3b98311:2f6ad06] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/compositor/compositor.c
r3b98311 r2f6ad06 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 #include <task.h> 58 61 59 #include <io/keycode.h> 62 60 #include <io/mode.h> 63 61 #include <io/visualizer.h> 64 62 #include <io/window.h> 63 #include <io/console.h> 65 64 66 65 #include <transform.h> … … 72 71 #include <codec/tga.h> 73 72 74 #include "images.h"75 73 #include "compositor.h" 76 74 … … 87 85 static sysarg_t coord_origin; 88 86 static pixel_t bg_color; 87 static filter_t filter = filter_bilinear; 88 static unsigned int filter_index = 1; 89 89 90 90 typedef struct { 91 91 link_t link; 92 92 atomic_t ref_cnt; 93 window_flags_t flags; 93 94 service_id_t in_dsid; 94 95 service_id_t out_dsid; … … 143 144 static LIST_INITIALIZE(viewport_list); 144 145 146 static FIBRIL_MUTEX_INITIALIZE(discovery_mtx); 147 145 148 /** Input server proxy */ 146 149 static input_t *input; 147 150 static bool active = false; 151 152 static int comp_active(input_t *); 153 static int comp_deactive(input_t *); 148 154 static int comp_key_press(input_t *, kbd_event_type_t, keycode_t, keymod_t, wchar_t); 149 155 static int comp_mouse_move(input_t *, int, int); … … 152 158 153 159 static input_ev_ops_t input_ev_ops = { 160 .active = comp_active, 161 .deactive = comp_deactive, 154 162 .key = comp_key_press, 155 163 .move = comp_mouse_move, … … 158 166 }; 159 167 160 static void input_disconnect(void);161 162 163 168 static pointer_t *input_pointer(input_t *input) 164 169 { … … 166 171 } 167 172 168 static pointer_t *pointer_create( )173 static pointer_t *pointer_create(void) 169 174 { 170 175 pointer_t *p = (pointer_t *) malloc(sizeof(pointer_t)); 171 if (!p) {176 if (!p) 172 177 return NULL; 173 } 174 178 175 179 link_initialize(&p->link); 176 180 p->pos.x = coord_origin; … … 184 188 p->state = 0; 185 189 cursor_init(&p->cursor, CURSOR_DECODER_EMBEDDED, NULL); 186 190 187 191 /* Ghost window for transformation animation. */ 188 192 transform_identity(&p->ghost.transform); … … 197 201 p->accum_ghost.x = 0; 198 202 p->accum_ghost.y = 0; 199 203 200 204 return p; 201 205 } … … 209 213 } 210 214 211 static window_t *window_create( sysarg_t x_offset, sysarg_t y_offset)215 static window_t *window_create(void) 212 216 { 213 217 window_t *win = (window_t *) malloc(sizeof(window_t)); 214 if (!win) {218 if (!win) 215 219 return NULL; 216 } 217 220 218 221 link_initialize(&win->link); 219 222 atomic_set(&win->ref_cnt, 0); 220 223 prodcons_initialize(&win->queue); 221 224 transform_identity(&win->transform); 222 transform_translate(&win->transform, 223 coord_origin + x_offset, coord_origin + y_offset); 224 win->dx = coord_origin + x_offset; 225 win->dy = coord_origin + y_offset; 225 transform_translate(&win->transform, coord_origin, coord_origin); 226 win->dx = coord_origin; 227 win->dy = coord_origin; 226 228 win->fx = 1; 227 229 win->fy = 1; … … 229 231 win->opacity = 255; 230 232 win->surface = NULL; 231 233 232 234 return win; 233 235 } … … 235 237 static void window_destroy(window_t *win) 236 238 { 237 if ( win && atomic_get(&win->ref_cnt) == 0) {239 if ((win) && (atomic_get(&win->ref_cnt) == 0)) { 238 240 while (!list_empty(&win->queue.list)) { 239 241 window_event_t *event = (window_event_t *) list_first(&win->queue.list); … … 241 243 free(event); 242 244 } 243 244 if (win->surface) {245 246 if (win->surface) 245 247 surface_destroy(win->surface); 246 }248 247 249 free(win); 248 250 } … … 256 258 transform_invert(&win_trans); 257 259 transform_apply_affine(&win_trans, &x, &y); 258 259 /* Since client coordinate origin is (0, 0), it is necessary to check 260 261 /* 262 * Since client coordinate origin is (0, 0), it is necessary to check 260 263 * coordinates to avoid underflow. Moreover, it is convenient to also 261 264 * check against provided upper limits to determine whether the converted 262 * coordinates are within the client window. */ 263 if (x < 0 || y < 0) { 265 * coordinates are within the client window. 266 */ 267 if ((x < 0) || (y < 0)) 264 268 return false; 265 } else { 266 (*x_out) = (sysarg_t) (x + 0.5); 267 (*y_out) = (sysarg_t) (y + 0.5); 268 269 if ((*x_out) >= x_lim || (*y_out) >= y_lim) { 270 return false; 271 } else { 272 return true; 273 } 274 } 269 270 (*x_out) = (sysarg_t) (x + 0.5); 271 (*y_out) = (sysarg_t) (y + 0.5); 272 273 if (((*x_out) >= x_lim) || ((*y_out) >= y_lim)) 274 return false; 275 276 return true; 275 277 } 276 278 … … 282 284 transform_apply_affine(&win_trans, &x, &y); 283 285 284 /* It is assumed that compositor coordinate origin is chosen in such way, 285 * that underflow/overflow here would be unlikely. */ 286 /* 287 * It is assumed that compositor coordinate origin is chosen in such way, 288 * that underflow/overflow here would be unlikely. 289 */ 286 290 (*x_out) = (sysarg_t) (x + 0.5); 287 291 (*y_out) = (sysarg_t) (y + 0.5); … … 292 296 sysarg_t *x_out, sysarg_t *y_out, sysarg_t *w_out, sysarg_t *h_out) 293 297 { 294 if ( w_in > 0 && h_in > 0) {298 if ((w_in > 0) && (h_in > 0)) { 295 299 sysarg_t x[4]; 296 300 sysarg_t y[4]; 301 297 302 comp_coord_from_client(x_in, y_in, win_trans, &x[0], &y[0]); 298 303 comp_coord_from_client(x_in + w_in - 1, y_in, win_trans, &x[1], &y[1]); 299 304 comp_coord_from_client(x_in + w_in - 1, y_in + h_in - 1, win_trans, &x[2], &y[2]); 300 305 comp_coord_from_client(x_in, y_in + h_in - 1, win_trans, &x[3], &y[3]); 306 301 307 (*x_out) = x[0]; 302 308 (*y_out) = y[0]; 303 309 (*w_out) = x[0]; 304 310 (*h_out) = y[0]; 305 for (int i = 1; i < 4; ++i) { 311 312 for (unsigned int i = 1; i < 4; ++i) { 306 313 (*x_out) = (x[i] < (*x_out)) ? x[i] : (*x_out); 307 314 (*y_out) = (y[i] < (*y_out)) ? y[i] : (*y_out); … … 309 316 (*h_out) = (y[i] > (*h_out)) ? y[i] : (*h_out); 310 317 } 318 311 319 (*w_out) = (*w_out) - (*x_out) + 1; 312 320 (*h_out) = (*h_out) - (*y_out) + 1; … … 319 327 } 320 328 321 static void comp_ restrict_pointers(void)329 static void comp_update_viewport_bound_rect(void) 322 330 { 323 331 fibril_mutex_lock(&viewport_list_mtx); 324 332 325 333 sysarg_t x_res = coord_origin; 326 334 sysarg_t y_res = coord_origin; 327 335 sysarg_t w_res = 0; 328 336 sysarg_t h_res = 0; 329 337 330 338 if (!list_empty(&viewport_list)) { 331 339 viewport_t *vp = (viewport_t *) list_first(&viewport_list); … … 334 342 surface_get_resolution(vp->surface, &w_res, &h_res); 335 343 } 336 337 list_foreach(viewport_list, link) { 338 viewport_t *vp = list_get_instance(link, viewport_t, link); 344 345 list_foreach(viewport_list, link, viewport_t, vp) { 339 346 sysarg_t w_vp, h_vp; 340 347 surface_get_resolution(vp->surface, &w_vp, &h_vp); 341 rectangle_union( 342 x_res, y_res, w_res, h_res, 348 rectangle_union(x_res, y_res, w_res, h_res, 343 349 vp->pos.x, vp->pos.y, w_vp, h_vp, 344 350 &x_res, &y_res, &w_res, &h_res); 345 351 } 346 352 347 353 viewport_bound_rect.x = x_res; 348 354 viewport_bound_rect.y = y_res; 349 355 viewport_bound_rect.w = w_res; 350 356 viewport_bound_rect.h = h_res; 351 357 352 358 fibril_mutex_unlock(&viewport_list_mtx); 353 359 } 360 361 static void comp_restrict_pointers(void) 362 { 363 comp_update_viewport_bound_rect(); 364 354 365 fibril_mutex_lock(&pointer_list_mtx); 355 356 list_foreach(pointer_list, link) { 357 pointer_t *ptr = list_get_instance(link, pointer_t, link); 366 367 list_foreach(pointer_list, link, pointer_t, ptr) { 358 368 ptr->pos.x = ptr->pos.x > viewport_bound_rect.x ? ptr->pos.x : viewport_bound_rect.x; 359 369 ptr->pos.y = ptr->pos.y > viewport_bound_rect.y ? ptr->pos.y : viewport_bound_rect.y; … … 363 373 ptr->pos.y : viewport_bound_rect.y + viewport_bound_rect.h; 364 374 } 365 375 366 376 fibril_mutex_unlock(&pointer_list_mtx); 367 377 } … … 374 384 fibril_mutex_lock(&pointer_list_mtx); 375 385 376 list_foreach(viewport_list, link) { 377 386 list_foreach(viewport_list, link, viewport_t, vp) { 378 387 /* Determine what part of the viewport must be updated. */ 379 viewport_t *vp = list_get_instance(link, viewport_t, link);380 388 sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp; 381 389 surface_get_resolution(vp->surface, &w_dmg_vp, &h_dmg_vp); … … 404 412 405 413 source_init(&source); 406 source_set_filter(&source, filter _nearest);414 source_set_filter(&source, filter); 407 415 drawctx_init(&context, vp->surface); 408 416 drawctx_set_compose(&context, compose_over); … … 437 445 transform_translate(&transform, -pos.x, -pos.y); 438 446 439 source_set_transform(&source, transform); 440 source_set_texture(&source, win->surface, false); 447 source_set_transform(&source, transform); 448 source_set_texture(&source, win->surface, 449 PIXELMAP_EXTEND_TRANSPARENT_SIDES); 441 450 source_set_alpha(&source, PIXEL(win->opacity, 0, 0, 0)); 442 451 … … 446 455 } 447 456 448 list_foreach(pointer_list, link) { 449 450 pointer_t *ptr = list_get_instance(link, pointer_t, link); 457 list_foreach(pointer_list, link, pointer_t, ptr) { 451 458 if (ptr->ghost.surface) { 452 459 … … 522 529 } 523 530 524 list_foreach(pointer_list, link ) {531 list_foreach(pointer_list, link, pointer_t, ptr) { 525 532 526 533 /* Determine what part of the pointer intersects with the 527 534 * updated area of the current viewport. */ 528 pointer_t *ptr = list_get_instance(link, pointer_t, link);529 535 sysarg_t x_dmg_ptr, y_dmg_ptr, w_dmg_ptr, h_dmg_ptr; 530 536 surface_t *sf_ptr = ptr->cursor.states[ptr->state]; … … 569 575 570 576 /* Notify visualizers about updated regions. */ 571 list_foreach(viewport_list, link) { 572 viewport_t *vp = list_get_instance(link, viewport_t, link); 573 sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp; 574 surface_get_damaged_region(vp->surface, &x_dmg_vp, &y_dmg_vp, &w_dmg_vp, &h_dmg_vp); 575 surface_reset_damaged_region(vp->surface); 576 visualizer_update_damaged_region( 577 vp->sess, x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp, 0, 0); 578 } 579 577 if (active) { 578 list_foreach(viewport_list, link, viewport_t, vp) { 579 sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp; 580 surface_get_damaged_region(vp->surface, &x_dmg_vp, &y_dmg_vp, &w_dmg_vp, &h_dmg_vp); 581 surface_reset_damaged_region(vp->surface); 582 visualizer_update_damaged_region(vp->sess, 583 x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp, 0, 0); 584 } 585 } 586 580 587 fibril_mutex_unlock(&viewport_list_mtx); 581 588 } … … 593 600 return; 594 601 } 602 595 603 int rc = async_data_read_finalize(callid, event, len); 596 604 if (rc != EOK) { … … 599 607 return; 600 608 } 609 601 610 async_answer_0(iid, EOK); 602 603 611 free(event); 604 612 } … … 611 619 double height = IPC_GET_ARG4(*icall); 612 620 613 if ( width == 0 || height == 0) {621 if ((width == 0) || (height == 0)) { 614 622 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 615 623 } else { … … 629 637 sysarg_t pos_id = IPC_GET_ARG1(*icall); 630 638 sysarg_t grab_flags = IPC_GET_ARG2(*icall); 639 640 /* 641 * Filter out resize grab flags if the window 642 * is not resizeable. 643 */ 644 if ((win->flags & WINDOW_RESIZEABLE) != WINDOW_RESIZEABLE) 645 grab_flags &= ~(GF_RESIZE_X | GF_RESIZE_Y); 631 646 632 647 fibril_mutex_lock(&pointer_list_mtx); 633 list_foreach(pointer_list, link) { 634 pointer_t *pointer = list_get_instance(link, pointer_t, link); 648 list_foreach(pointer_list, link, pointer_t, pointer) { 635 649 if (pointer->id == pos_id) { 636 650 pointer->grab_flags = pointer->pressed ? grab_flags : GF_EMPTY; … … 649 663 } 650 664 665 static void comp_recalc_transform(window_t *win) 666 { 667 transform_t translate; 668 transform_identity(&translate); 669 transform_translate(&translate, win->dx, win->dy); 670 671 transform_t scale; 672 transform_identity(&scale); 673 if ((win->fx != 1) || (win->fy != 1)) 674 transform_scale(&scale, win->fx, win->fy); 675 676 transform_t rotate; 677 transform_identity(&rotate); 678 if (win->angle != 0) 679 transform_rotate(&rotate, win->angle); 680 681 transform_t transform; 682 transform_t temp; 683 transform_identity(&transform); 684 temp = transform; 685 transform_product(&transform, &temp, &translate); 686 temp = transform; 687 transform_product(&transform, &temp, &rotate); 688 temp = transform; 689 transform_product(&transform, &temp, &scale); 690 691 win->transform = transform; 692 } 693 651 694 static void comp_window_resize(window_t *win, ipc_callid_t iid, ipc_call_t *icall) 652 695 { 653 int rc;654 655 696 ipc_callid_t callid; 656 697 size_t size; 657 698 unsigned int flags; 658 699 659 700 /* Start sharing resized window with client. */ 660 701 if (!async_share_out_receive(&callid, &size, &flags)) { … … 662 703 return; 663 704 } 705 664 706 void *new_cell_storage; 665 rc = async_share_out_finalize(callid, &new_cell_storage);707 int rc = async_share_out_finalize(callid, &new_cell_storage); 666 708 if ((rc != EOK) || (new_cell_storage == AS_MAP_FAILED)) { 667 709 async_answer_0(iid, ENOMEM); 668 710 return; 669 711 } 670 712 671 713 /* Create new surface for the resized window. */ 672 surface_t *new_surface = surface_create( 673 IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall), 674 new_cell_storage, SURFACE_FLAG_SHARED); 714 surface_t *new_surface = surface_create(IPC_GET_ARG3(*icall), 715 IPC_GET_ARG4(*icall), new_cell_storage, SURFACE_FLAG_SHARED); 675 716 if (!new_surface) { 676 717 as_area_destroy(new_cell_storage); … … 678 719 return; 679 720 } 680 721 722 sysarg_t offset_x = IPC_GET_ARG1(*icall); 723 sysarg_t offset_y = IPC_GET_ARG2(*icall); 724 window_placement_flags_t placement_flags = 725 (window_placement_flags_t) IPC_GET_ARG5(*icall); 726 727 comp_update_viewport_bound_rect(); 728 681 729 /* Switch new surface with old surface and calculate damage. */ 682 730 fibril_mutex_lock(&window_list_mtx); 683 731 684 732 sysarg_t old_width = 0; 685 733 sysarg_t old_height = 0; 734 686 735 if (win->surface) { 687 736 surface_get_resolution(win->surface, &old_width, &old_height); 688 737 surface_destroy(win->surface); 689 738 } 690 739 691 740 win->surface = new_surface; 692 741 693 742 sysarg_t new_width = 0; 694 743 sysarg_t new_height = 0; 695 744 surface_get_resolution(win->surface, &new_width, &new_height); 696 697 sysarg_t x, y; 698 sysarg_t width = old_width > new_width ? old_width : new_width; 699 sysarg_t height = old_height > new_height ? old_height : new_height; 700 comp_coord_bounding_rect(0, 0, width, height, win->transform, &x, &y, &width, &height); 701 745 746 if (placement_flags & WINDOW_PLACEMENT_CENTER_X) 747 win->dx = viewport_bound_rect.x + viewport_bound_rect.w / 2 - 748 new_width / 2; 749 750 if (placement_flags & WINDOW_PLACEMENT_CENTER_Y) 751 win->dy = viewport_bound_rect.y + viewport_bound_rect.h / 2 - 752 new_height / 2; 753 754 if (placement_flags & WINDOW_PLACEMENT_LEFT) 755 win->dx = viewport_bound_rect.x; 756 757 if (placement_flags & WINDOW_PLACEMENT_TOP) 758 win->dy = viewport_bound_rect.y; 759 760 if (placement_flags & WINDOW_PLACEMENT_RIGHT) 761 win->dx = viewport_bound_rect.x + viewport_bound_rect.w - 762 new_width; 763 764 if (placement_flags & WINDOW_PLACEMENT_BOTTOM) 765 win->dy = viewport_bound_rect.y + viewport_bound_rect.h - 766 new_height; 767 768 if (placement_flags & WINDOW_PLACEMENT_ABSOLUTE_X) 769 win->dx = coord_origin + offset_x; 770 771 if (placement_flags & WINDOW_PLACEMENT_ABSOLUTE_Y) 772 win->dy = coord_origin + offset_y; 773 774 /* Transform the window and calculate damage. */ 775 sysarg_t x1; 776 sysarg_t y1; 777 sysarg_t width1; 778 sysarg_t height1; 779 780 comp_coord_bounding_rect(0, 0, old_width, old_height, win->transform, 781 &x1, &y1, &width1, &height1); 782 783 comp_recalc_transform(win); 784 785 sysarg_t x2; 786 sysarg_t y2; 787 sysarg_t width2; 788 sysarg_t height2; 789 790 comp_coord_bounding_rect(0, 0, new_width, new_height, win->transform, 791 &x2, &y2, &width2, &height2); 792 793 sysarg_t x; 794 sysarg_t y; 795 sysarg_t width; 796 sysarg_t height; 797 798 rectangle_union(x1, y1, width1, height1, x2, y2, width2, height2, 799 &x, &y, &width, &height); 800 702 801 fibril_mutex_unlock(&window_list_mtx); 703 802 704 803 comp_damage(x, y, width, height); 705 804 706 805 async_answer_0(iid, EOK); 707 806 } … … 710 809 { 711 810 fibril_mutex_lock(&window_list_mtx); 712 window_t *window = NULL; 713 list_foreach(window_list, link) { 714 window = list_get_instance(link, window_t, link); 811 812 list_foreach(window_list, link, window_t, window) { 715 813 if (window == target) { 716 814 prodcons_produce(&window->queue, &event->link); 717 } 718 } 719 if (!window) { 815 fibril_mutex_unlock(&window_list_mtx); 816 return; 817 } 818 } 819 820 fibril_mutex_unlock(&window_list_mtx); 821 free(event); 822 } 823 824 static void comp_post_event_top(window_event_t *event) 825 { 826 fibril_mutex_lock(&window_list_mtx); 827 828 window_t *win = (window_t *) list_first(&window_list); 829 if (win) 830 prodcons_produce(&win->queue, &event->link); 831 else 720 832 free(event); 721 } 722 fibril_mutex_unlock(&window_list_mtx); 723 } 724 725 static void comp_post_event_top(window_event_t *event) 726 { 727 fibril_mutex_lock(&window_list_mtx); 728 window_t *win = (window_t *) list_first(&window_list); 729 if (win) { 730 prodcons_produce(&win->queue, &event->link); 731 } else { 732 free(event); 733 } 833 734 834 fibril_mutex_unlock(&window_list_mtx); 735 835 } … … 775 875 776 876 comp_damage(x, y, width, height); 777 778 877 async_answer_0(iid, EOK); 779 878 } … … 781 880 static void comp_window_close_request(window_t *win, ipc_callid_t iid, ipc_call_t *icall) 782 881 { 783 882 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t)); 784 883 if (event == NULL) { 785 884 async_answer_0(iid, ENOMEM); … … 798 897 ipc_call_t call; 799 898 ipc_callid_t callid; 800 service_id_t service_id = (service_id_t) IPC_GET_ARG 1(*icall);899 service_id_t service_id = (service_id_t) IPC_GET_ARG2(*icall); 801 900 802 901 /* Allocate resources for new window and register it to the location service. */ … … 808 907 fibril_mutex_lock(&window_list_mtx); 809 908 810 window_t *win = window_create( IPC_GET_ARG1(call), IPC_GET_ARG2(call));909 window_t *win = window_create(); 811 910 if (!win) { 812 911 async_answer_2(callid, ENOMEM, 0, 0); 813 912 return; 814 913 } 914 915 win->flags = IPC_GET_ARG1(call); 815 916 816 917 char name_in[LOC_NAME_MAXLEN + 1]; … … 863 964 window_t *win = NULL; 864 965 fibril_mutex_lock(&window_list_mtx); 865 list_foreach(window_list, link) { 866 window_t *cur = list_get_instance(link, window_t, link); 966 list_foreach(window_list, link, window_t, cur) { 867 967 if (cur->in_dsid == service_id || cur->out_dsid == service_id) { 868 968 win = cur; … … 922 1022 break; 923 1023 case WINDOW_CLOSE: 924 /* Postpone the closing until the phone is hung up to cover 925 * the case when the client is killed abruptly. */ 1024 /* 1025 * Postpone the closing until the phone is hung up to cover 1026 * the case when the client is killed abruptly. 1027 */ 926 1028 async_answer_0(callid, EOK); 927 1029 break; … … 938 1040 static void comp_mode_change(viewport_t *vp, ipc_callid_t iid, ipc_call_t *icall) 939 1041 { 940 int rc;941 1042 sysarg_t mode_idx = IPC_GET_ARG2(*icall); 942 1043 fibril_mutex_lock(&viewport_list_mtx); … … 944 1045 /* Retrieve the mode that shall be set. */ 945 1046 vslmode_t new_mode; 946 rc = visualizer_get_mode(vp->sess, &new_mode, mode_idx);1047 int rc = visualizer_get_mode(vp->sess, &new_mode, mode_idx); 947 1048 if (rc != EOK) { 948 1049 fibril_mutex_unlock(&viewport_list_mtx); … … 962 1063 /* Try to set the mode and share out the surface. */ 963 1064 rc = visualizer_set_mode(vp->sess, 964 1065 new_mode.index, new_mode.version, surface_direct_access(new_surface)); 965 1066 if (rc != EOK) { 966 1067 surface_destroy(new_surface); … … 992 1093 } 993 1094 1095 #if 0 1096 static void comp_shutdown(void) 1097 { 1098 loc_service_unregister(winreg_id); 1099 input_disconnect(); 1100 1101 /* Close all clients and their windows. */ 1102 fibril_mutex_lock(&window_list_mtx); 1103 list_foreach(window_list, link, window_t, win) { 1104 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t)); 1105 if (event) { 1106 link_initialize(&event->link); 1107 event->type = WINDOW_CLOSE; 1108 prodcons_produce(&win->queue, &event->link); 1109 } 1110 } 1111 fibril_mutex_unlock(&window_list_mtx); 1112 1113 async_answer_0(iid, EOK); 1114 1115 /* All fibrils of the compositor will terminate soon. */ 1116 } 1117 #endif 1118 994 1119 static void comp_visualizer_disconnect(viewport_t *vp, ipc_callid_t iid, ipc_call_t *icall) 995 1120 { 996 1121 /* Release viewport resources. */ 997 1122 fibril_mutex_lock(&viewport_list_mtx); 1123 998 1124 list_remove(&vp->link); 999 1125 viewport_destroy(vp); 1000 1001 /* Terminate compositor if there are no more viewports. */ 1002 if (list_empty(&viewport_list)) { 1003 fibril_mutex_unlock(&viewport_list_mtx); 1004 loc_service_unregister(winreg_id); 1005 input_disconnect(); 1006 1007 /* Close all clients and their windows. */ 1008 fibril_mutex_lock(&window_list_mtx); 1009 list_foreach(window_list, link) { 1010 window_t *win = list_get_instance(link, window_t, link); 1011 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t)); 1012 if (event) { 1013 link_initialize(&event->link); 1014 event->type = WINDOW_CLOSE; 1015 prodcons_produce(&win->queue, &event->link); 1016 } 1017 } 1018 fibril_mutex_unlock(&window_list_mtx); 1019 1020 async_answer_0(iid, EOK); 1021 1022 /* All fibrils of the compositor will terminate soon. */ 1023 } else { 1024 fibril_mutex_unlock(&viewport_list_mtx); 1025 async_answer_0(iid, EOK); 1026 1027 comp_restrict_pointers(); 1028 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 1029 } 1126 1127 fibril_mutex_unlock(&viewport_list_mtx); 1128 1129 async_answer_0(iid, EOK); 1130 1131 comp_restrict_pointers(); 1132 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 1030 1133 } 1031 1134 … … 1034 1137 viewport_t *vp = NULL; 1035 1138 fibril_mutex_lock(&viewport_list_mtx); 1036 list_foreach(viewport_list, link) { 1037 viewport_t *cur = list_get_instance(link, viewport_t, link); 1139 list_foreach(viewport_list, link, viewport_t, cur) { 1038 1140 if (cur->dsid == (service_id_t) IPC_GET_ARG1(*icall)) { 1039 1141 vp = cur; … … 1043 1145 fibril_mutex_unlock(&viewport_list_mtx); 1044 1146 1045 if (!vp) {1147 if (!vp) 1046 1148 return; 1047 }1048 1149 1049 1150 /* Ignore parameters, the connection is already opened. */ … … 1070 1171 } 1071 1172 1072 static async_sess_t *vsl_connect( const char *svc)1173 static async_sess_t *vsl_connect(service_id_t sid, const char *svc) 1073 1174 { 1074 1175 int rc; 1075 1176 async_sess_t *sess; 1076 service_id_t dsid; 1077 devman_handle_t handle; 1078 1079 rc = loc_service_get_id(svc, &dsid, 0); 1080 if (rc != EOK) { 1177 1178 sess = loc_service_connect(sid, INTERFACE_DDF, 0); 1179 if (sess == NULL) { 1180 printf("%s: Unable to connect to visualizer %s\n", NAME, svc); 1081 1181 return NULL; 1082 1182 } 1083 1183 1084 rc = devman_fun_sid_to_handle(dsid, &handle);1085 if (rc == EOK) {1086 sess = devman_device_connect(EXCHANGE_SERIALIZE, handle, 0);1087 if (sess == NULL) {1088 printf("%s: Unable to connect to visualizer %s\n", NAME, svc);1089 return NULL;1090 }1091 rc = graph_dev_connect(sess);1092 if (rc != EOK) {1093 return NULL;1094 }1095 } else if (rc == ENOENT) {1096 sess = loc_service_connect(EXCHANGE_SERIALIZE, dsid, 0);1097 if (sess == NULL) {1098 printf("%s: Unable to connect to visualizer %s\n", NAME, svc);1099 return NULL;1100 }1101 } else {1102 return NULL;1103 }1104 1105 1184 async_exch_t *exch = async_exchange_begin(sess); 1106 rc = async_connect_to_me(exch, dsid, 0, 0, vsl_notifications, NULL); 1185 1186 port_id_t port; 1187 rc = async_create_callback_port(exch, INTERFACE_VISUALIZER_CB, 0, 0, 1188 vsl_notifications, NULL, &port); 1189 1107 1190 async_exchange_end(exch); 1108 1191 … … 1117 1200 } 1118 1201 1119 static viewport_t *viewport_create( const char *vsl_name)1202 static viewport_t *viewport_create(service_id_t sid) 1120 1203 { 1121 1204 int rc; 1122 1123 viewport_t *vp = (viewport_t *) malloc(sizeof(viewport_t)); 1124 if (!vp) { 1125 return NULL; 1126 } 1205 char *vsl_name = NULL; 1206 viewport_t *vp = NULL; 1207 bool claimed = false; 1208 1209 rc = loc_service_get_name(sid, &vsl_name); 1210 if (rc != EOK) 1211 goto error; 1212 1213 vp = (viewport_t *) calloc(1, sizeof(viewport_t)); 1214 if (!vp) 1215 goto error; 1127 1216 1128 1217 link_initialize(&vp->link); … … 1131 1220 1132 1221 /* Establish output bidirectional connection. */ 1133 vp->sess = vsl_connect(vsl_name); 1134 rc = loc_service_get_id(vsl_name, &vp->dsid, 0); 1135 if (vp->sess == NULL || rc != EOK) { 1136 free(vp); 1137 return NULL; 1138 } 1222 vp->dsid = sid; 1223 vp->sess = vsl_connect(sid, vsl_name); 1224 if (vp->sess == NULL) 1225 goto error; 1139 1226 1140 1227 /* Claim the given visualizer. */ 1141 1228 rc = visualizer_claim(vp->sess, 0); 1142 1229 if (rc != EOK) { 1143 async_hangup(vp->sess);1144 free(vp);1145 1230 printf("%s: Unable to claim visualizer (%s)\n", NAME, str_error(rc)); 1146 return NULL; 1147 } 1231 goto error; 1232 } 1233 1234 claimed = true; 1148 1235 1149 1236 /* Retrieve the default mode. */ 1150 1237 rc = visualizer_get_default_mode(vp->sess, &vp->mode); 1151 1238 if (rc != EOK) { 1152 visualizer_yield(vp->sess);1153 async_hangup(vp->sess);1154 free(vp);1155 1239 printf("%s: Unable to retrieve mode (%s)\n", NAME, str_error(rc)); 1156 return NULL;1240 goto error; 1157 1241 } 1158 1242 … … 1161 1245 NULL, SURFACE_FLAG_SHARED); 1162 1246 if (vp->surface == NULL) { 1163 visualizer_yield(vp->sess);1164 async_hangup(vp->sess);1165 free(vp);1166 1247 printf("%s: Unable to create surface (%s)\n", NAME, str_error(rc)); 1167 return NULL;1248 goto error; 1168 1249 } 1169 1250 1170 1251 /* Try to set the mode and share out the surface. */ 1171 1252 rc = visualizer_set_mode(vp->sess, 1172 1253 vp->mode.index, vp->mode.version, surface_direct_access(vp->surface)); 1173 1254 if (rc != EOK) { 1255 printf("%s: Unable to set mode (%s)\n", NAME, str_error(rc)); 1256 goto error; 1257 } 1258 1259 return vp; 1260 error: 1261 if (claimed) 1174 1262 visualizer_yield(vp->sess); 1175 surface_destroy(vp->surface); 1263 1264 if (vp->sess != NULL) 1176 1265 async_hangup(vp->sess); 1177 free(vp); 1178 printf("%s: Unable to set mode (%s)\n", NAME, str_error(rc)); 1179 return NULL; 1180 } 1181 1182 return vp; 1183 } 1184 1185 static void comp_recalc_transform(window_t *win) 1186 { 1187 transform_t translate; 1188 transform_identity(&translate); 1189 transform_translate(&translate, win->dx, win->dy); 1190 1191 transform_t scale; 1192 transform_identity(&scale); 1193 if (win->fx != 1 || win->fy != 1) { 1194 transform_scale(&scale, win->fx, win->fy); 1195 } 1196 1197 transform_t rotate; 1198 transform_identity(&rotate); 1199 if (win->angle != 0) { 1200 transform_rotate(&rotate, win->angle); 1201 } 1202 1203 transform_t transform; 1204 transform_t temp; 1205 transform_identity(&transform); 1206 temp = transform; 1207 transform_multiply(&transform, &temp, &translate); 1208 temp = transform; 1209 transform_multiply(&transform, &temp, &rotate); 1210 temp = transform; 1211 transform_multiply(&transform, &temp, &scale); 1212 1213 1214 win->transform = transform; 1266 1267 free(vp); 1268 free(vsl_name); 1269 return NULL; 1215 1270 } 1216 1271 … … 1236 1291 double cx = 0; 1237 1292 double cy = 0; 1238 if (pointer->grab_flags & GF_MOVE_X) { 1293 1294 if (pointer->grab_flags & GF_MOVE_X) 1239 1295 cx = 1; 1240 }1241 if (pointer->grab_flags & GF_MOVE_Y) {1296 1297 if (pointer->grab_flags & GF_MOVE_Y) 1242 1298 cy = 1; 1243 } 1244 1245 if ((scale || resize) && (win->angle != 0)) { 1299 1300 if (((scale) || (resize)) && (win->angle != 0)) { 1246 1301 transform_t rotate; 1247 1302 transform_identity(&rotate); 1303 1248 1304 transform_rotate(&rotate, win->angle); 1249 1305 transform_apply_linear(&rotate, &cx, &cy); 1250 1306 } 1251 1307 1252 cx = (cx < 0) ? (-1 * cx) : cx; 1308 cx = (cx < 0) ? (-1 * cx) : cx; 1253 1309 cy = (cy < 0) ? (-1 * cy) : cy; 1254 1310 1255 1311 win->dx += (cx * dx); 1256 1312 win->dy += (cy * dy); 1257 1313 } 1258 1314 1259 if ( scale || resize) {1315 if ((scale) || (resize)) { 1260 1316 double _dx = dx; 1261 1317 double _dy = dy; … … 1273 1329 if (fx > 0) { 1274 1330 #if ANIMATE_WINDOW_TRANSFORMS == 0 1275 if (scale) win->fx *= fx; 1331 if (scale) 1332 win->fx *= fx; 1276 1333 #endif 1277 1334 #if ANIMATE_WINDOW_TRANSFORMS == 1 … … 1454 1511 { 1455 1512 pointer_t *pointer = input_pointer(input); 1456 1513 1514 comp_update_viewport_bound_rect(); 1515 1457 1516 /* Update pointer position. */ 1458 1517 fibril_mutex_lock(&pointer_list_mtx); 1518 1459 1519 desktop_point_t old_pos = pointer->pos; 1520 1460 1521 sysarg_t cursor_width; 1461 1522 sysarg_t cursor_height; 1462 surface_get_resolution(pointer->cursor.states[pointer->state], 1523 surface_get_resolution(pointer->cursor.states[pointer->state], 1463 1524 &cursor_width, &cursor_height); 1464 if (pointer->pos.x + dx < viewport_bound_rect.x) { 1525 1526 if (pointer->pos.x + dx < viewport_bound_rect.x) 1465 1527 dx = -1 * (pointer->pos.x - viewport_bound_rect.x); 1466 }1467 if (pointer->pos.y + dy < viewport_bound_rect.y) {1528 1529 if (pointer->pos.y + dy < viewport_bound_rect.y) 1468 1530 dy = -1 * (pointer->pos.y - viewport_bound_rect.y); 1469 }1470 if (pointer->pos.x + dx > viewport_bound_rect.x + viewport_bound_rect.w) {1531 1532 if (pointer->pos.x + dx > viewport_bound_rect.x + viewport_bound_rect.w) 1471 1533 dx = (viewport_bound_rect.x + viewport_bound_rect.w - pointer->pos.x); 1472 }1473 if (pointer->pos.y + dy > viewport_bound_rect.y + viewport_bound_rect.h) {1534 1535 if (pointer->pos.y + dy > viewport_bound_rect.y + viewport_bound_rect.h) 1474 1536 dy = (viewport_bound_rect.y + viewport_bound_rect.h - pointer->pos.y); 1475 }1537 1476 1538 pointer->pos.x += dx; 1477 1539 pointer->pos.y += dy; … … 1479 1541 comp_damage(old_pos.x, old_pos.y, cursor_width, cursor_height); 1480 1542 comp_damage(old_pos.x + dx, old_pos.y + dy, cursor_width, cursor_height); 1481 1543 1482 1544 fibril_mutex_lock(&window_list_mtx); 1483 1545 fibril_mutex_lock(&pointer_list_mtx); … … 1571 1633 1572 1634 /* Determine the window which the mouse click belongs to. */ 1573 list_foreach(window_list, link ) {1574 win = list_get_instance(link, window_t, link);1635 list_foreach(window_list, link, window_t, cw) { 1636 win = cw; 1575 1637 if (win->surface) { 1576 1638 surface_get_resolution(win->surface, &width, &height); … … 1640 1702 1641 1703 #if ANIMATE_WINDOW_TRANSFORMS == 0 1642 sysarg_t pre_x = 0; 1704 sysarg_t pre_x = 0; 1643 1705 sysarg_t pre_y = 0; 1644 1706 sysarg_t pre_width = 0; … … 1672 1734 link_initialize(&event_top->link); 1673 1735 event_top->type = ET_WINDOW_RESIZE; 1674 1736 1737 event_top->data.resize.offset_x = 0; 1738 event_top->data.resize.offset_y = 0; 1739 1675 1740 int dx = (int) (((double) width) * (scale_back_x - 1.0)); 1676 1741 int dy = (int) (((double) height) * (scale_back_y - 1.0)); 1677 1678 if (pointer->grab_flags & GF_RESIZE_X) { 1679 event_top->data.rsz.width = 1680 ((((int) width) + dx) >= 0) ? (width + dx) : 0; 1681 } else { 1682 event_top->data.rsz.width = width; 1683 } 1684 1685 if (pointer->grab_flags & GF_RESIZE_Y) { 1686 event_top->data.rsz.height = 1687 ((((int) height) + dy) >= 0) ? (height + dy) : 0; 1688 } else { 1689 event_top->data.rsz.height = height; 1690 } 1742 1743 if (pointer->grab_flags & GF_RESIZE_X) 1744 event_top->data.resize.width = 1745 ((((int) width) + dx) >= 0) ? (width + dx) : 0; 1746 else 1747 event_top->data.resize.width = width; 1748 1749 if (pointer->grab_flags & GF_RESIZE_Y) 1750 event_top->data.resize.height = 1751 ((((int) height) + dy) >= 0) ? (height + dy) : 0; 1752 else 1753 event_top->data.resize.height = height; 1754 1755 event_top->data.resize.placement_flags = 1756 WINDOW_PLACEMENT_ANY; 1691 1757 } 1692 1758 … … 1736 1802 } 1737 1803 1804 return EOK; 1805 } 1806 1807 static int comp_active(input_t *input) 1808 { 1809 active = true; 1810 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 1811 1812 return EOK; 1813 } 1814 1815 static int comp_deactive(input_t *input) 1816 { 1817 active = false; 1738 1818 return EOK; 1739 1819 } … … 1755 1835 bool viewport_change = (mods & KM_ALT) && ( 1756 1836 key == KC_O || key == KC_P); 1757 bool kconsole_switch = ( mods & KM_ALT) && (key == KC_M);1758 bool compositor_test = (mods & KM_ALT) && (key == KC_H);1759 1760 bool filter = (type == KEY_RELEASE) && (win_transform || win_resize ||1837 bool kconsole_switch = (key == KC_PAUSE) || (key == KC_BREAK); 1838 bool filter_switch = (mods & KM_ALT) && (key == KC_Y); 1839 1840 bool key_filter = (type == KEY_RELEASE) && (win_transform || win_resize || 1761 1841 win_opacity || win_close || win_switch || viewport_move || 1762 viewport_change || kconsole_switch || compositor_test);1763 1764 if ( filter) {1842 viewport_change || kconsole_switch || filter_switch); 1843 1844 if (key_filter) { 1765 1845 /* no-op */ 1766 1846 } else if (win_transform) { … … 1782 1862 break; 1783 1863 case KC_Q: 1784 win->angle += (PI / 2);1864 win->angle += 0.1; 1785 1865 break; 1786 1866 case KC_E: 1787 win->angle += -(PI / 2);1867 win->angle -= 0.1; 1788 1868 break; 1789 1869 case KC_R: … … 1820 1900 fibril_mutex_lock(&window_list_mtx); 1821 1901 window_t *win = (window_t *) list_first(&window_list); 1822 if ( win && win->surface) {1902 if ((win) && (win->surface) && (win->flags & WINDOW_RESIZEABLE)) { 1823 1903 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t)); 1824 1904 if (event == NULL) { … … 1826 1906 return ENOMEM; 1827 1907 } 1828 1908 1829 1909 sysarg_t width, height; 1830 1910 surface_get_resolution(win->surface, &width, &height); 1831 1911 1832 1912 link_initialize(&event->link); 1833 1913 event->type = ET_WINDOW_RESIZE; 1834 1914 1915 event->data.resize.offset_x = 0; 1916 event->data.resize.offset_y = 0; 1917 1835 1918 switch (key) { 1836 1919 case KC_T: 1837 event->data.r sz.width = width;1838 event->data.r sz.height = (height >= 20) ? height - 20 : 0;1920 event->data.resize.width = width; 1921 event->data.resize.height = (height >= 20) ? height - 20 : 0; 1839 1922 break; 1840 1923 case KC_G: 1841 event->data.r sz.width = width;1842 event->data.r sz.height = height + 20;1924 event->data.resize.width = width; 1925 event->data.resize.height = height + 20; 1843 1926 break; 1844 1927 case KC_B: 1845 event->data.r sz.width = (width >= 20) ? width - 20 : 0;;1846 event->data.r sz.height = height;1928 event->data.resize.width = (width >= 20) ? width - 20 : 0;; 1929 event->data.resize.height = height; 1847 1930 break; 1848 1931 case KC_N: 1849 event->data.r sz.width = width + 20;1850 event->data.r sz.height = height;1932 event->data.resize.width = width + 20; 1933 event->data.resize.height = height; 1851 1934 break; 1852 1935 default: 1853 event->data.rsz.width = 0; 1854 event->data.rsz.height = 0; 1855 break; 1856 } 1857 1936 event->data.resize.width = 0; 1937 event->data.resize.height = 0; 1938 break; 1939 } 1940 1941 event->data.resize.placement_flags = WINDOW_PLACEMENT_ANY; 1942 1858 1943 fibril_mutex_unlock(&window_list_mtx); 1859 1944 comp_post_event_top(event); … … 2023 2108 fibril_mutex_unlock(&viewport_list_mtx); 2024 2109 } else if (kconsole_switch) { 2025 __SYSCALL0(SYS_DEBUG_ACTIVATE_CONSOLE); 2026 } else if (compositor_test) { 2027 fibril_mutex_lock(&window_list_mtx); 2028 2029 window_t *red_win = window_create(0, 0); 2030 red_win->surface = surface_create(250, 150, NULL, 0); 2031 pixel_t red_pix = PIXEL(255, 240, 0, 0); 2032 for (sysarg_t y = 0; y < 150; ++y) { 2033 for (sysarg_t x = 0; x < 250; ++x) { 2034 surface_put_pixel(red_win->surface, x, y, red_pix); 2035 } 2036 } 2037 list_prepend(&red_win->link, &window_list); 2038 2039 window_t *blue_win = window_create(0, 0); 2040 blue_win->surface = surface_create(200, 100, NULL, 0); 2041 pixel_t blue_pix = PIXEL(255, 0, 0, 240); 2042 for (sysarg_t y = 0; y < 100; ++y) { 2043 for (sysarg_t x = 0; x < 200; ++x) { 2044 surface_put_pixel(blue_win->surface, x, y, blue_pix); 2045 } 2046 } 2047 list_prepend(&blue_win->link, &window_list); 2048 2049 window_t *nameic_win = window_create(0, 0); 2050 nameic_win->surface = decode_tga((void *) nameic_tga, nameic_tga_size, 0); 2051 list_prepend(&nameic_win->link, &window_list); 2052 2053 fibril_mutex_unlock(&window_list_mtx); 2110 if (console_kcon()) 2111 active = false; 2112 } else if (filter_switch) { 2113 filter_index++; 2114 if (filter_index > 1) 2115 filter_index = 0; 2116 if (filter_index == 0) { 2117 filter = filter_nearest; 2118 } 2119 else { 2120 filter = filter_bilinear; 2121 } 2054 2122 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 2055 2123 } else { … … 2082 2150 } 2083 2151 2084 sess = loc_service_connect( EXCHANGE_ATOMIC, dsid, 0);2152 sess = loc_service_connect(dsid, INTERFACE_INPUT, 0); 2085 2153 if (sess == NULL) { 2086 2154 printf("%s: Unable to connect to input service %s\n", NAME, … … 2121 2189 } 2122 2190 2123 static void interrupt_received(ipc_callid_t callid, ipc_call_t *call) 2124 { 2125 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 2191 static void discover_viewports(void) 2192 { 2193 fibril_mutex_lock(&discovery_mtx); 2194 2195 /* Create viewports and connect them to visualizers. */ 2196 category_id_t cat_id; 2197 int rc = loc_category_get_id("visualizer", &cat_id, IPC_FLAG_BLOCKING); 2198 if (rc != EOK) 2199 goto ret; 2200 2201 service_id_t *svcs; 2202 size_t svcs_cnt = 0; 2203 rc = loc_category_get_svcs(cat_id, &svcs, &svcs_cnt); 2204 if (rc != EOK) 2205 goto ret; 2206 2207 fibril_mutex_lock(&viewport_list_mtx); 2208 for (size_t i = 0; i < svcs_cnt; ++i) { 2209 bool exists = false; 2210 list_foreach(viewport_list, link, viewport_t, vp) { 2211 if (vp->dsid == svcs[i]) { 2212 exists = true; 2213 break; 2214 } 2215 } 2216 2217 if (exists) 2218 continue; 2219 2220 viewport_t *vp = viewport_create(svcs[i]); 2221 if (vp != NULL) 2222 list_append(&vp->link, &viewport_list); 2223 } 2224 fibril_mutex_unlock(&viewport_list_mtx); 2225 2226 if (!list_empty(&viewport_list)) 2227 input_activate(input); 2228 2229 ret: 2230 fibril_mutex_unlock(&discovery_mtx); 2231 } 2232 2233 static void category_change_cb(void) 2234 { 2235 discover_viewports(); 2126 2236 } 2127 2237 … … 2132 2242 2133 2243 /* Color of the viewport background. Must be opaque. */ 2134 bg_color = PIXEL(255, 75, 70, 75);2244 bg_color = PIXEL(255, 69, 51, 103); 2135 2245 2136 2246 /* Register compositor server. */ 2137 async_set_client_connection(client_connection); 2247 async_set_fallback_port_handler(client_connection, NULL); 2248 2138 2249 int rc = loc_server_register(NAME); 2139 2250 if (rc != EOK) { 2140 2251 printf("%s: Unable to register server (%s)\n", NAME, str_error(rc)); 2141 2252 return -1; 2142 }2143 2144 /* Register interrupt handler to switch back from kconsole. */2145 async_set_interrupt_received(interrupt_received);2146 rc = event_subscribe(EVENT_KCONSOLE, 0);2147 if (rc != EOK) {2148 printf("%s: Failed to register kconsole notifications (%s)\n",2149 NAME, str_error(rc));2150 2253 } 2151 2254 … … 2169 2272 return -1; 2170 2273 } 2171 2274 2172 2275 /* Establish input bidirectional connection. */ 2173 2276 rc = input_connect(input_svc); 2174 if (rc != EOK) 2277 if (rc != EOK) { 2278 printf("%s: Failed to connect to input service.\n", NAME); 2175 2279 return rc; 2176 2177 /* Create viewports and connect them to visualizers. */ 2178 category_id_t cat_id; 2179 rc = loc_category_get_id("visualizer", &cat_id, IPC_FLAG_BLOCKING); 2280 } 2281 2282 rc = loc_register_cat_change_cb(category_change_cb); 2180 2283 if (rc != EOK) { 2284 printf("%s: Failed to register category change callback\n", NAME); 2181 2285 input_disconnect(); 2182 return -1; 2183 } 2184 2185 service_id_t *svcs; 2186 size_t svcs_cnt = 0; 2187 rc = loc_category_get_svcs(cat_id, &svcs, &svcs_cnt); 2188 if (rc != EOK || svcs_cnt == 0) { 2189 input_disconnect(); 2190 return -1; 2191 } 2192 2193 for (size_t i = 0; i < svcs_cnt; ++i) { 2194 char *svc_name; 2195 rc = loc_service_get_name(svcs[i], &svc_name); 2196 if (rc == EOK) { 2197 viewport_t *vp = viewport_create(svc_name); 2198 if (vp != NULL) { 2199 list_append(&vp->link, &viewport_list); 2200 } 2201 } 2202 } 2203 2204 if (list_empty(&viewport_list)) { 2205 input_disconnect(); 2206 return -1; 2207 } 2208 2286 return rc; 2287 } 2288 2289 discover_viewports(); 2290 2209 2291 comp_restrict_pointers(); 2210 2292 comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
Note:
See TracChangeset
for help on using the changeset viewer.