Changes in uspace/srv/hid/compositor/compositor.c [2f6ad06:3b98311] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/compositor/compositor.c
r2f6ad06 r3b98311 55 55 #include <async.h> 56 56 #include <loc.h> 57 #include <task.h> 58 57 #include <devman.h> 58 59 #include <event.h> 60 #include <device/graph_dev.h> 59 61 #include <io/keycode.h> 60 62 #include <io/mode.h> 61 63 #include <io/visualizer.h> 62 64 #include <io/window.h> 63 #include <io/console.h>64 65 65 66 #include <transform.h> … … 71 72 #include <codec/tga.h> 72 73 74 #include "images.h" 73 75 #include "compositor.h" 74 76 … … 85 87 static sysarg_t coord_origin; 86 88 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;94 93 service_id_t in_dsid; 95 94 service_id_t out_dsid; … … 144 143 static LIST_INITIALIZE(viewport_list); 145 144 146 static FIBRIL_MUTEX_INITIALIZE(discovery_mtx);147 148 145 /** Input server proxy */ 149 146 static input_t *input; 150 static bool active = false; 151 152 static int comp_active(input_t *); 153 static int comp_deactive(input_t *); 147 154 148 static int comp_key_press(input_t *, kbd_event_type_t, keycode_t, keymod_t, wchar_t); 155 149 static int comp_mouse_move(input_t *, int, int); … … 158 152 159 153 static input_ev_ops_t input_ev_ops = { 160 .active = comp_active,161 .deactive = comp_deactive,162 154 .key = comp_key_press, 163 155 .move = comp_mouse_move, … … 166 158 }; 167 159 160 static void input_disconnect(void); 161 162 168 163 static pointer_t *input_pointer(input_t *input) 169 164 { … … 171 166 } 172 167 173 static pointer_t *pointer_create( void)168 static pointer_t *pointer_create() 174 169 { 175 170 pointer_t *p = (pointer_t *) malloc(sizeof(pointer_t)); 176 if (!p) 171 if (!p) { 177 172 return NULL; 178 173 } 174 179 175 link_initialize(&p->link); 180 176 p->pos.x = coord_origin; … … 188 184 p->state = 0; 189 185 cursor_init(&p->cursor, CURSOR_DECODER_EMBEDDED, NULL); 190 186 191 187 /* Ghost window for transformation animation. */ 192 188 transform_identity(&p->ghost.transform); … … 201 197 p->accum_ghost.x = 0; 202 198 p->accum_ghost.y = 0; 203 199 204 200 return p; 205 201 } … … 213 209 } 214 210 215 static window_t *window_create( void)211 static window_t *window_create(sysarg_t x_offset, sysarg_t y_offset) 216 212 { 217 213 window_t *win = (window_t *) malloc(sizeof(window_t)); 218 if (!win) 214 if (!win) { 219 215 return NULL; 220 216 } 217 221 218 link_initialize(&win->link); 222 219 atomic_set(&win->ref_cnt, 0); 223 220 prodcons_initialize(&win->queue); 224 221 transform_identity(&win->transform); 225 transform_translate(&win->transform, coord_origin, coord_origin); 226 win->dx = coord_origin; 227 win->dy = coord_origin; 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; 228 226 win->fx = 1; 229 227 win->fy = 1; … … 231 229 win->opacity = 255; 232 230 win->surface = NULL; 233 231 234 232 return win; 235 233 } … … 237 235 static void window_destroy(window_t *win) 238 236 { 239 if ( (win) && (atomic_get(&win->ref_cnt) == 0)) {237 if (win && atomic_get(&win->ref_cnt) == 0) { 240 238 while (!list_empty(&win->queue.list)) { 241 239 window_event_t *event = (window_event_t *) list_first(&win->queue.list); … … 243 241 free(event); 244 242 } 245 246 if (win->surface) 243 244 if (win->surface) { 247 245 surface_destroy(win->surface); 248 246 } 249 247 free(win); 250 248 } … … 258 256 transform_invert(&win_trans); 259 257 transform_apply_affine(&win_trans, &x, &y); 260 261 /* 262 * Since client coordinate origin is (0, 0), it is necessary to check 258 259 /* Since client coordinate origin is (0, 0), it is necessary to check 263 260 * coordinates to avoid underflow. Moreover, it is convenient to also 264 261 * check against provided upper limits to determine whether the converted 265 * coordinates are within the client window. 266 */ 267 if ((x < 0) || (y < 0)) 262 * coordinates are within the client window. */ 263 if (x < 0 || y < 0) { 268 264 return false; 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; 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 } 277 275 } 278 276 … … 284 282 transform_apply_affine(&win_trans, &x, &y); 285 283 286 /* 287 * It is assumed that compositor coordinate origin is chosen in such way, 288 * that underflow/overflow here would be unlikely. 289 */ 284 /* It is assumed that compositor coordinate origin is chosen in such way, 285 * that underflow/overflow here would be unlikely. */ 290 286 (*x_out) = (sysarg_t) (x + 0.5); 291 287 (*y_out) = (sysarg_t) (y + 0.5); … … 296 292 sysarg_t *x_out, sysarg_t *y_out, sysarg_t *w_out, sysarg_t *h_out) 297 293 { 298 if ( (w_in > 0) && (h_in > 0)) {294 if (w_in > 0 && h_in > 0) { 299 295 sysarg_t x[4]; 300 296 sysarg_t y[4]; 301 302 297 comp_coord_from_client(x_in, y_in, win_trans, &x[0], &y[0]); 303 298 comp_coord_from_client(x_in + w_in - 1, y_in, win_trans, &x[1], &y[1]); 304 299 comp_coord_from_client(x_in + w_in - 1, y_in + h_in - 1, win_trans, &x[2], &y[2]); 305 300 comp_coord_from_client(x_in, y_in + h_in - 1, win_trans, &x[3], &y[3]); 306 307 301 (*x_out) = x[0]; 308 302 (*y_out) = y[0]; 309 303 (*w_out) = x[0]; 310 304 (*h_out) = y[0]; 311 312 for (unsigned int i = 1; i < 4; ++i) { 305 for (int i = 1; i < 4; ++i) { 313 306 (*x_out) = (x[i] < (*x_out)) ? x[i] : (*x_out); 314 307 (*y_out) = (y[i] < (*y_out)) ? y[i] : (*y_out); … … 316 309 (*h_out) = (y[i] > (*h_out)) ? y[i] : (*h_out); 317 310 } 318 319 311 (*w_out) = (*w_out) - (*x_out) + 1; 320 312 (*h_out) = (*h_out) - (*y_out) + 1; … … 327 319 } 328 320 329 static void comp_ update_viewport_bound_rect(void)321 static void comp_restrict_pointers(void) 330 322 { 331 323 fibril_mutex_lock(&viewport_list_mtx); 332 324 333 325 sysarg_t x_res = coord_origin; 334 326 sysarg_t y_res = coord_origin; 335 327 sysarg_t w_res = 0; 336 328 sysarg_t h_res = 0; 337 329 338 330 if (!list_empty(&viewport_list)) { 339 331 viewport_t *vp = (viewport_t *) list_first(&viewport_list); … … 342 334 surface_get_resolution(vp->surface, &w_res, &h_res); 343 335 } 344 345 list_foreach(viewport_list, link, viewport_t, vp) { 336 337 list_foreach(viewport_list, link) { 338 viewport_t *vp = list_get_instance(link, viewport_t, link); 346 339 sysarg_t w_vp, h_vp; 347 340 surface_get_resolution(vp->surface, &w_vp, &h_vp); 348 rectangle_union(x_res, y_res, w_res, h_res, 341 rectangle_union( 342 x_res, y_res, w_res, h_res, 349 343 vp->pos.x, vp->pos.y, w_vp, h_vp, 350 344 &x_res, &y_res, &w_res, &h_res); 351 345 } 352 346 353 347 viewport_bound_rect.x = x_res; 354 348 viewport_bound_rect.y = y_res; 355 349 viewport_bound_rect.w = w_res; 356 350 viewport_bound_rect.h = h_res; 357 351 358 352 fibril_mutex_unlock(&viewport_list_mtx); 359 } 360 361 static void comp_restrict_pointers(void) 362 { 363 comp_update_viewport_bound_rect(); 364 353 365 354 fibril_mutex_lock(&pointer_list_mtx); 366 367 list_foreach(pointer_list, link, pointer_t, ptr) { 355 356 list_foreach(pointer_list, link) { 357 pointer_t *ptr = list_get_instance(link, pointer_t, link); 368 358 ptr->pos.x = ptr->pos.x > viewport_bound_rect.x ? ptr->pos.x : viewport_bound_rect.x; 369 359 ptr->pos.y = ptr->pos.y > viewport_bound_rect.y ? ptr->pos.y : viewport_bound_rect.y; … … 373 363 ptr->pos.y : viewport_bound_rect.y + viewport_bound_rect.h; 374 364 } 375 365 376 366 fibril_mutex_unlock(&pointer_list_mtx); 377 367 } … … 384 374 fibril_mutex_lock(&pointer_list_mtx); 385 375 386 list_foreach(viewport_list, link, viewport_t, vp) { 376 list_foreach(viewport_list, link) { 377 387 378 /* Determine what part of the viewport must be updated. */ 379 viewport_t *vp = list_get_instance(link, viewport_t, link); 388 380 sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp; 389 381 surface_get_resolution(vp->surface, &w_dmg_vp, &h_dmg_vp); … … 412 404 413 405 source_init(&source); 414 source_set_filter(&source, filter );406 source_set_filter(&source, filter_nearest); 415 407 drawctx_init(&context, vp->surface); 416 408 drawctx_set_compose(&context, compose_over); … … 445 437 transform_translate(&transform, -pos.x, -pos.y); 446 438 447 source_set_transform(&source, transform); 448 source_set_texture(&source, win->surface, 449 PIXELMAP_EXTEND_TRANSPARENT_SIDES); 439 source_set_transform(&source, transform); 440 source_set_texture(&source, win->surface, false); 450 441 source_set_alpha(&source, PIXEL(win->opacity, 0, 0, 0)); 451 442 … … 455 446 } 456 447 457 list_foreach(pointer_list, link, pointer_t, ptr) { 448 list_foreach(pointer_list, link) { 449 450 pointer_t *ptr = list_get_instance(link, pointer_t, link); 458 451 if (ptr->ghost.surface) { 459 452 … … 529 522 } 530 523 531 list_foreach(pointer_list, link , pointer_t, ptr) {524 list_foreach(pointer_list, link) { 532 525 533 526 /* Determine what part of the pointer intersects with the 534 527 * updated area of the current viewport. */ 528 pointer_t *ptr = list_get_instance(link, pointer_t, link); 535 529 sysarg_t x_dmg_ptr, y_dmg_ptr, w_dmg_ptr, h_dmg_ptr; 536 530 surface_t *sf_ptr = ptr->cursor.states[ptr->state]; … … 575 569 576 570 /* Notify visualizers about updated regions. */ 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 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 587 580 fibril_mutex_unlock(&viewport_list_mtx); 588 581 } … … 600 593 return; 601 594 } 602 603 595 int rc = async_data_read_finalize(callid, event, len); 604 596 if (rc != EOK) { … … 607 599 return; 608 600 } 609 610 601 async_answer_0(iid, EOK); 602 611 603 free(event); 612 604 } … … 619 611 double height = IPC_GET_ARG4(*icall); 620 612 621 if ( (width == 0) || (height == 0)) {613 if (width == 0 || height == 0) { 622 614 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 623 615 } else { … … 637 629 sysarg_t pos_id = IPC_GET_ARG1(*icall); 638 630 sysarg_t grab_flags = IPC_GET_ARG2(*icall); 639 640 /*641 * Filter out resize grab flags if the window642 * is not resizeable.643 */644 if ((win->flags & WINDOW_RESIZEABLE) != WINDOW_RESIZEABLE)645 grab_flags &= ~(GF_RESIZE_X | GF_RESIZE_Y);646 631 647 632 fibril_mutex_lock(&pointer_list_mtx); 648 list_foreach(pointer_list, link, pointer_t, pointer) { 633 list_foreach(pointer_list, link) { 634 pointer_t *pointer = list_get_instance(link, pointer_t, link); 649 635 if (pointer->id == pos_id) { 650 636 pointer->grab_flags = pointer->pressed ? grab_flags : GF_EMPTY; … … 663 649 } 664 650 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 694 651 static void comp_window_resize(window_t *win, ipc_callid_t iid, ipc_call_t *icall) 695 652 { 653 int rc; 654 696 655 ipc_callid_t callid; 697 656 size_t size; 698 657 unsigned int flags; 699 658 700 659 /* Start sharing resized window with client. */ 701 660 if (!async_share_out_receive(&callid, &size, &flags)) { … … 703 662 return; 704 663 } 705 706 664 void *new_cell_storage; 707 intrc = async_share_out_finalize(callid, &new_cell_storage);665 rc = async_share_out_finalize(callid, &new_cell_storage); 708 666 if ((rc != EOK) || (new_cell_storage == AS_MAP_FAILED)) { 709 667 async_answer_0(iid, ENOMEM); 710 668 return; 711 669 } 712 670 713 671 /* Create new surface for the resized window. */ 714 surface_t *new_surface = surface_create(IPC_GET_ARG3(*icall), 715 IPC_GET_ARG4(*icall), new_cell_storage, SURFACE_FLAG_SHARED); 672 surface_t *new_surface = surface_create( 673 IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall), 674 new_cell_storage, SURFACE_FLAG_SHARED); 716 675 if (!new_surface) { 717 676 as_area_destroy(new_cell_storage); … … 719 678 return; 720 679 } 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 680 729 681 /* Switch new surface with old surface and calculate damage. */ 730 682 fibril_mutex_lock(&window_list_mtx); 731 683 732 684 sysarg_t old_width = 0; 733 685 sysarg_t old_height = 0; 734 735 686 if (win->surface) { 736 687 surface_get_resolution(win->surface, &old_width, &old_height); 737 688 surface_destroy(win->surface); 738 689 } 739 690 740 691 win->surface = new_surface; 741 692 742 693 sysarg_t new_width = 0; 743 694 sysarg_t new_height = 0; 744 695 surface_get_resolution(win->surface, &new_width, &new_height); 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 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 801 702 fibril_mutex_unlock(&window_list_mtx); 802 703 803 704 comp_damage(x, y, width, height); 804 705 805 706 async_answer_0(iid, EOK); 806 707 } … … 809 710 { 810 711 fibril_mutex_lock(&window_list_mtx); 811 812 list_foreach(window_list, link, window_t, window) { 712 window_t *window = NULL; 713 list_foreach(window_list, link) { 714 window = list_get_instance(link, window_t, link); 813 715 if (window == target) { 814 716 prodcons_produce(&window->queue, &event->link); 815 fibril_mutex_unlock(&window_list_mtx);816 return;817 }818 }819 717 } 718 } 719 if (!window) { 720 free(event); 721 } 820 722 fibril_mutex_unlock(&window_list_mtx); 821 free(event);822 723 } 823 724 … … 825 726 { 826 727 fibril_mutex_lock(&window_list_mtx); 827 828 728 window_t *win = (window_t *) list_first(&window_list); 829 if (win) 729 if (win) { 830 730 prodcons_produce(&win->queue, &event->link); 831 else731 } else { 832 732 free(event); 833 733 } 834 734 fibril_mutex_unlock(&window_list_mtx); 835 735 } … … 875 775 876 776 comp_damage(x, y, width, height); 777 877 778 async_answer_0(iid, EOK); 878 779 } … … 880 781 static void comp_window_close_request(window_t *win, ipc_callid_t iid, ipc_call_t *icall) 881 782 { 882 783 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t)); 883 784 if (event == NULL) { 884 785 async_answer_0(iid, ENOMEM); … … 897 798 ipc_call_t call; 898 799 ipc_callid_t callid; 899 service_id_t service_id = (service_id_t) IPC_GET_ARG 2(*icall);800 service_id_t service_id = (service_id_t) IPC_GET_ARG1(*icall); 900 801 901 802 /* Allocate resources for new window and register it to the location service. */ … … 907 808 fibril_mutex_lock(&window_list_mtx); 908 809 909 window_t *win = window_create( );810 window_t *win = window_create(IPC_GET_ARG1(call), IPC_GET_ARG2(call)); 910 811 if (!win) { 911 812 async_answer_2(callid, ENOMEM, 0, 0); 912 813 return; 913 814 } 914 915 win->flags = IPC_GET_ARG1(call);916 815 917 816 char name_in[LOC_NAME_MAXLEN + 1]; … … 964 863 window_t *win = NULL; 965 864 fibril_mutex_lock(&window_list_mtx); 966 list_foreach(window_list, link, window_t, cur) { 865 list_foreach(window_list, link) { 866 window_t *cur = list_get_instance(link, window_t, link); 967 867 if (cur->in_dsid == service_id || cur->out_dsid == service_id) { 968 868 win = cur; … … 1022 922 break; 1023 923 case WINDOW_CLOSE: 1024 /* 1025 * Postpone the closing until the phone is hung up to cover 1026 * the case when the client is killed abruptly. 1027 */ 924 /* Postpone the closing until the phone is hung up to cover 925 * the case when the client is killed abruptly. */ 1028 926 async_answer_0(callid, EOK); 1029 927 break; … … 1040 938 static void comp_mode_change(viewport_t *vp, ipc_callid_t iid, ipc_call_t *icall) 1041 939 { 940 int rc; 1042 941 sysarg_t mode_idx = IPC_GET_ARG2(*icall); 1043 942 fibril_mutex_lock(&viewport_list_mtx); … … 1045 944 /* Retrieve the mode that shall be set. */ 1046 945 vslmode_t new_mode; 1047 intrc = visualizer_get_mode(vp->sess, &new_mode, mode_idx);946 rc = visualizer_get_mode(vp->sess, &new_mode, mode_idx); 1048 947 if (rc != EOK) { 1049 948 fibril_mutex_unlock(&viewport_list_mtx); … … 1063 962 /* Try to set the mode and share out the surface. */ 1064 963 rc = visualizer_set_mode(vp->sess, 1065 964 new_mode.index, new_mode.version, surface_direct_access(new_surface)); 1066 965 if (rc != EOK) { 1067 966 surface_destroy(new_surface); … … 1093 992 } 1094 993 1095 #if 01096 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 #endif1118 1119 994 static void comp_visualizer_disconnect(viewport_t *vp, ipc_callid_t iid, ipc_call_t *icall) 1120 995 { 1121 996 /* Release viewport resources. */ 1122 997 fibril_mutex_lock(&viewport_list_mtx); 1123 1124 998 list_remove(&vp->link); 1125 999 viewport_destroy(vp); 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); 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 } 1133 1030 } 1134 1031 … … 1137 1034 viewport_t *vp = NULL; 1138 1035 fibril_mutex_lock(&viewport_list_mtx); 1139 list_foreach(viewport_list, link, viewport_t, cur) { 1036 list_foreach(viewport_list, link) { 1037 viewport_t *cur = list_get_instance(link, viewport_t, link); 1140 1038 if (cur->dsid == (service_id_t) IPC_GET_ARG1(*icall)) { 1141 1039 vp = cur; … … 1145 1043 fibril_mutex_unlock(&viewport_list_mtx); 1146 1044 1147 if (!vp) 1045 if (!vp) { 1148 1046 return; 1047 } 1149 1048 1150 1049 /* Ignore parameters, the connection is already opened. */ … … 1171 1070 } 1172 1071 1173 static async_sess_t *vsl_connect( service_id_t sid,const char *svc)1072 static async_sess_t *vsl_connect(const char *svc) 1174 1073 { 1175 1074 int rc; 1176 1075 async_sess_t *sess; 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); 1076 service_id_t dsid; 1077 devman_handle_t handle; 1078 1079 rc = loc_service_get_id(svc, &dsid, 0); 1080 if (rc != EOK) { 1181 1081 return NULL; 1182 1082 } 1183 1083 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 1184 1105 async_exch_t *exch = async_exchange_begin(sess); 1185 1186 port_id_t port; 1187 rc = async_create_callback_port(exch, INTERFACE_VISUALIZER_CB, 0, 0, 1188 vsl_notifications, NULL, &port); 1189 1106 rc = async_connect_to_me(exch, dsid, 0, 0, vsl_notifications, NULL); 1190 1107 async_exchange_end(exch); 1191 1108 … … 1200 1117 } 1201 1118 1202 static viewport_t *viewport_create( service_id_t sid)1119 static viewport_t *viewport_create(const char *vsl_name) 1203 1120 { 1204 1121 int rc; 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; 1122 1123 viewport_t *vp = (viewport_t *) malloc(sizeof(viewport_t)); 1124 if (!vp) { 1125 return NULL; 1126 } 1216 1127 1217 1128 link_initialize(&vp->link); … … 1220 1131 1221 1132 /* Establish output bidirectional connection. */ 1222 vp->dsid = sid; 1223 vp->sess = vsl_connect(sid, vsl_name); 1224 if (vp->sess == NULL) 1225 goto error; 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 } 1226 1139 1227 1140 /* Claim the given visualizer. */ 1228 1141 rc = visualizer_claim(vp->sess, 0); 1229 1142 if (rc != EOK) { 1143 async_hangup(vp->sess); 1144 free(vp); 1230 1145 printf("%s: Unable to claim visualizer (%s)\n", NAME, str_error(rc)); 1231 goto error; 1232 } 1233 1234 claimed = true; 1146 return NULL; 1147 } 1235 1148 1236 1149 /* Retrieve the default mode. */ 1237 1150 rc = visualizer_get_default_mode(vp->sess, &vp->mode); 1238 1151 if (rc != EOK) { 1152 visualizer_yield(vp->sess); 1153 async_hangup(vp->sess); 1154 free(vp); 1239 1155 printf("%s: Unable to retrieve mode (%s)\n", NAME, str_error(rc)); 1240 goto error;1156 return NULL; 1241 1157 } 1242 1158 … … 1245 1161 NULL, SURFACE_FLAG_SHARED); 1246 1162 if (vp->surface == NULL) { 1163 visualizer_yield(vp->sess); 1164 async_hangup(vp->sess); 1165 free(vp); 1247 1166 printf("%s: Unable to create surface (%s)\n", NAME, str_error(rc)); 1248 goto error;1167 return NULL; 1249 1168 } 1250 1169 1251 1170 /* Try to set the mode and share out the surface. */ 1252 1171 rc = visualizer_set_mode(vp->sess, 1253 1172 vp->mode.index, vp->mode.version, surface_direct_access(vp->surface)); 1254 1173 if (rc != EOK) { 1174 visualizer_yield(vp->sess); 1175 surface_destroy(vp->surface); 1176 async_hangup(vp->sess); 1177 free(vp); 1255 1178 printf("%s: Unable to set mode (%s)\n", NAME, str_error(rc)); 1256 goto error;1179 return NULL; 1257 1180 } 1258 1181 1259 1182 return vp; 1260 error: 1261 if (claimed) 1262 visualizer_yield(vp->sess); 1263 1264 if (vp->sess != NULL) 1265 async_hangup(vp->sess); 1266 1267 free(vp); 1268 free(vsl_name); 1269 return NULL; 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; 1270 1215 } 1271 1216 … … 1291 1236 double cx = 0; 1292 1237 double cy = 0; 1293 1294 if (pointer->grab_flags & GF_MOVE_X) 1238 if (pointer->grab_flags & GF_MOVE_X) { 1295 1239 cx = 1; 1296 1297 if (pointer->grab_flags & GF_MOVE_Y) 1240 } 1241 if (pointer->grab_flags & GF_MOVE_Y) { 1298 1242 cy = 1; 1299 1300 if (((scale) || (resize)) && (win->angle != 0)) { 1243 } 1244 1245 if ((scale || resize) && (win->angle != 0)) { 1301 1246 transform_t rotate; 1302 1247 transform_identity(&rotate); 1303 1304 1248 transform_rotate(&rotate, win->angle); 1305 1249 transform_apply_linear(&rotate, &cx, &cy); 1306 1250 } 1307 1251 1308 cx = (cx < 0) ? (-1 * cx) : cx; 1252 cx = (cx < 0) ? (-1 * cx) : cx; 1309 1253 cy = (cy < 0) ? (-1 * cy) : cy; 1310 1254 1311 1255 win->dx += (cx * dx); 1312 1256 win->dy += (cy * dy); 1313 1257 } 1314 1258 1315 if ( (scale) || (resize)) {1259 if (scale || resize) { 1316 1260 double _dx = dx; 1317 1261 double _dy = dy; … … 1329 1273 if (fx > 0) { 1330 1274 #if ANIMATE_WINDOW_TRANSFORMS == 0 1331 if (scale) 1332 win->fx *= fx; 1275 if (scale) win->fx *= fx; 1333 1276 #endif 1334 1277 #if ANIMATE_WINDOW_TRANSFORMS == 1 … … 1511 1454 { 1512 1455 pointer_t *pointer = input_pointer(input); 1513 1514 comp_update_viewport_bound_rect(); 1515 1456 1516 1457 /* Update pointer position. */ 1517 1458 fibril_mutex_lock(&pointer_list_mtx); 1518 1519 1459 desktop_point_t old_pos = pointer->pos; 1520 1521 1460 sysarg_t cursor_width; 1522 1461 sysarg_t cursor_height; 1523 surface_get_resolution(pointer->cursor.states[pointer->state], 1462 surface_get_resolution(pointer->cursor.states[pointer->state], 1524 1463 &cursor_width, &cursor_height); 1525 1526 if (pointer->pos.x + dx < viewport_bound_rect.x) 1464 if (pointer->pos.x + dx < viewport_bound_rect.x) { 1527 1465 dx = -1 * (pointer->pos.x - viewport_bound_rect.x); 1528 1529 if (pointer->pos.y + dy < viewport_bound_rect.y) 1466 } 1467 if (pointer->pos.y + dy < viewport_bound_rect.y) { 1530 1468 dy = -1 * (pointer->pos.y - viewport_bound_rect.y); 1531 1532 if (pointer->pos.x + dx > viewport_bound_rect.x + viewport_bound_rect.w) 1469 } 1470 if (pointer->pos.x + dx > viewport_bound_rect.x + viewport_bound_rect.w) { 1533 1471 dx = (viewport_bound_rect.x + viewport_bound_rect.w - pointer->pos.x); 1534 1535 if (pointer->pos.y + dy > viewport_bound_rect.y + viewport_bound_rect.h) 1472 } 1473 if (pointer->pos.y + dy > viewport_bound_rect.y + viewport_bound_rect.h) { 1536 1474 dy = (viewport_bound_rect.y + viewport_bound_rect.h - pointer->pos.y); 1537 1475 } 1538 1476 pointer->pos.x += dx; 1539 1477 pointer->pos.y += dy; … … 1541 1479 comp_damage(old_pos.x, old_pos.y, cursor_width, cursor_height); 1542 1480 comp_damage(old_pos.x + dx, old_pos.y + dy, cursor_width, cursor_height); 1543 1481 1544 1482 fibril_mutex_lock(&window_list_mtx); 1545 1483 fibril_mutex_lock(&pointer_list_mtx); … … 1633 1571 1634 1572 /* Determine the window which the mouse click belongs to. */ 1635 list_foreach(window_list, link , window_t, cw) {1636 win = cw;1573 list_foreach(window_list, link) { 1574 win = list_get_instance(link, window_t, link); 1637 1575 if (win->surface) { 1638 1576 surface_get_resolution(win->surface, &width, &height); … … 1702 1640 1703 1641 #if ANIMATE_WINDOW_TRANSFORMS == 0 1704 sysarg_t pre_x = 0; 1642 sysarg_t pre_x = 0; 1705 1643 sysarg_t pre_y = 0; 1706 1644 sysarg_t pre_width = 0; … … 1734 1672 link_initialize(&event_top->link); 1735 1673 event_top->type = ET_WINDOW_RESIZE; 1736 1737 event_top->data.resize.offset_x = 0; 1738 event_top->data.resize.offset_y = 0; 1739 1674 1740 1675 int dx = (int) (((double) width) * (scale_back_x - 1.0)); 1741 1676 int dy = (int) (((double) height) * (scale_back_y - 1.0)); 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; 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 } 1757 1691 } 1758 1692 … … 1802 1736 } 1803 1737 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;1818 1738 return EOK; 1819 1739 } … … 1835 1755 bool viewport_change = (mods & KM_ALT) && ( 1836 1756 key == KC_O || key == KC_P); 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 ||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 || 1841 1761 win_opacity || win_close || win_switch || viewport_move || 1842 viewport_change || kconsole_switch || filter_switch);1843 1844 if ( key_filter) {1762 viewport_change || kconsole_switch || compositor_test); 1763 1764 if (filter) { 1845 1765 /* no-op */ 1846 1766 } else if (win_transform) { … … 1862 1782 break; 1863 1783 case KC_Q: 1864 win->angle += 0.1;1784 win->angle += (PI / 2); 1865 1785 break; 1866 1786 case KC_E: 1867 win->angle -= 0.1;1787 win->angle += -(PI / 2); 1868 1788 break; 1869 1789 case KC_R: … … 1900 1820 fibril_mutex_lock(&window_list_mtx); 1901 1821 window_t *win = (window_t *) list_first(&window_list); 1902 if ( (win) && (win->surface) && (win->flags & WINDOW_RESIZEABLE)) {1822 if (win && win->surface) { 1903 1823 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t)); 1904 1824 if (event == NULL) { … … 1906 1826 return ENOMEM; 1907 1827 } 1908 1828 1909 1829 sysarg_t width, height; 1910 1830 surface_get_resolution(win->surface, &width, &height); 1911 1831 1912 1832 link_initialize(&event->link); 1913 1833 event->type = ET_WINDOW_RESIZE; 1914 1915 event->data.resize.offset_x = 0; 1916 event->data.resize.offset_y = 0; 1917 1834 1918 1835 switch (key) { 1919 1836 case KC_T: 1920 event->data.r esize.width = width;1921 event->data.r esize.height = (height >= 20) ? height - 20 : 0;1837 event->data.rsz.width = width; 1838 event->data.rsz.height = (height >= 20) ? height - 20 : 0; 1922 1839 break; 1923 1840 case KC_G: 1924 event->data.r esize.width = width;1925 event->data.r esize.height = height + 20;1841 event->data.rsz.width = width; 1842 event->data.rsz.height = height + 20; 1926 1843 break; 1927 1844 case KC_B: 1928 event->data.r esize.width = (width >= 20) ? width - 20 : 0;;1929 event->data.r esize.height = height;1845 event->data.rsz.width = (width >= 20) ? width - 20 : 0;; 1846 event->data.rsz.height = height; 1930 1847 break; 1931 1848 case KC_N: 1932 event->data.r esize.width = width + 20;1933 event->data.r esize.height = height;1849 event->data.rsz.width = width + 20; 1850 event->data.rsz.height = height; 1934 1851 break; 1935 1852 default: 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 1853 event->data.rsz.width = 0; 1854 event->data.rsz.height = 0; 1855 break; 1856 } 1857 1943 1858 fibril_mutex_unlock(&window_list_mtx); 1944 1859 comp_post_event_top(event); … … 2108 2023 fibril_mutex_unlock(&viewport_list_mtx); 2109 2024 } else if (kconsole_switch) { 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 } 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); 2122 2054 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 2123 2055 } else { … … 2150 2082 } 2151 2083 2152 sess = loc_service_connect( dsid, INTERFACE_INPUT, 0);2084 sess = loc_service_connect(EXCHANGE_ATOMIC, dsid, 0); 2153 2085 if (sess == NULL) { 2154 2086 printf("%s: Unable to connect to input service %s\n", NAME, … … 2189 2121 } 2190 2122 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(); 2123 static void interrupt_received(ipc_callid_t callid, ipc_call_t *call) 2124 { 2125 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 2236 2126 } 2237 2127 … … 2242 2132 2243 2133 /* Color of the viewport background. Must be opaque. */ 2244 bg_color = PIXEL(255, 69, 51, 103);2134 bg_color = PIXEL(255, 75, 70, 75); 2245 2135 2246 2136 /* Register compositor server. */ 2247 async_set_fallback_port_handler(client_connection, NULL); 2248 2137 async_set_client_connection(client_connection); 2249 2138 int rc = loc_server_register(NAME); 2250 2139 if (rc != EOK) { 2251 2140 printf("%s: Unable to register server (%s)\n", NAME, str_error(rc)); 2252 2141 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)); 2253 2150 } 2254 2151 … … 2272 2169 return -1; 2273 2170 } 2274 2171 2275 2172 /* Establish input bidirectional connection. */ 2276 2173 rc = input_connect(input_svc); 2174 if (rc != EOK) 2175 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); 2277 2180 if (rc != EOK) { 2278 printf("%s: Failed to connect to input service.\n", NAME);2279 return rc;2280 }2281 2282 rc = loc_register_cat_change_cb(category_change_cb);2283 if (rc != EOK) {2284 printf("%s: Failed to register category change callback\n", NAME);2285 2181 input_disconnect(); 2286 return rc; 2287 } 2288 2289 discover_viewports(); 2290 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 2291 2209 comp_restrict_pointers(); 2292 2210 comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
Note:
See TracChangeset
for help on using the changeset viewer.