Changes in uspace/srv/hid/compositor/compositor.c [d17a4a9:c072a29] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/compositor/compositor.c
rd17a4a9 rc072a29 34 34 35 35 #include <sys/types.h> 36 #include < bool.h>36 #include <stdbool.h> 37 37 #include <errno.h> 38 38 #include <str_error.h> … … 55 55 #include <async.h> 56 56 #include <loc.h> 57 #include <devman.h> 58 59 #include <event.h> 60 #include <device/graph_dev.h> 57 61 58 #include <io/keycode.h> 62 59 #include <io/mode.h> 63 60 #include <io/visualizer.h> 64 61 #include <io/window.h> 62 #include <io/console.h> 65 63 66 64 #include <transform.h> … … 72 70 #include <codec/tga.h> 73 71 74 #include "images.h"75 72 #include "compositor.h" 76 73 … … 87 84 static sysarg_t coord_origin; 88 85 static pixel_t bg_color; 86 static filter_t filter = filter_bilinear; 87 static unsigned int filter_index = 1; 89 88 90 89 typedef struct { 91 90 link_t link; 92 sysarg_t id; 93 uint8_t state; 94 desktop_point_t pos; 95 sysarg_t btn_num; 96 desktop_point_t btn_pos; 97 desktop_vector_t accum; 98 sysarg_t grab_flags; 99 bool pressed; 100 cursor_t cursor; 101 } pointer_t; 102 103 static sysarg_t pointer_id = 0; 104 static FIBRIL_MUTEX_INITIALIZE(pointer_list_mtx); 105 static LIST_INITIALIZE(pointer_list); 106 107 typedef struct { 108 link_t link; 91 atomic_t ref_cnt; 109 92 service_id_t in_dsid; 110 93 service_id_t out_dsid; … … 129 112 typedef struct { 130 113 link_t link; 114 sysarg_t id; 115 uint8_t state; 116 desktop_point_t pos; 117 sysarg_t btn_num; 118 desktop_point_t btn_pos; 119 desktop_vector_t accum; 120 sysarg_t grab_flags; 121 bool pressed; 122 cursor_t cursor; 123 window_t ghost; 124 desktop_vector_t accum_ghost; 125 } pointer_t; 126 127 static sysarg_t pointer_id = 0; 128 static FIBRIL_MUTEX_INITIALIZE(pointer_list_mtx); 129 static LIST_INITIALIZE(pointer_list); 130 131 typedef struct { 132 link_t link; 131 133 service_id_t dsid; 132 134 vslmode_t mode; … … 136 138 } viewport_t; 137 139 140 static desktop_rect_t viewport_bound_rect; 138 141 static FIBRIL_MUTEX_INITIALIZE(viewport_list_mtx); 139 142 static LIST_INITIALIZE(viewport_list); 140 143 144 static FIBRIL_MUTEX_INITIALIZE(discovery_mtx); 145 141 146 /** Input server proxy */ 142 147 static input_t *input; 143 148 static bool active = false; 149 150 static int comp_active(input_t *); 151 static int comp_deactive(input_t *); 144 152 static int comp_key_press(input_t *, kbd_event_type_t, keycode_t, keymod_t, wchar_t); 145 153 static int comp_mouse_move(input_t *, int, int); … … 148 156 149 157 static input_ev_ops_t input_ev_ops = { 158 .active = comp_active, 159 .deactive = comp_deactive, 150 160 .key = comp_key_press, 151 161 .move = comp_mouse_move, … … 154 164 }; 155 165 156 static void input_disconnect(void);157 158 159 166 static pointer_t *input_pointer(input_t *input) 160 167 { … … 162 169 } 163 170 164 static pointer_t *pointer_create( )171 static pointer_t *pointer_create(void) 165 172 { 166 173 pointer_t *p = (pointer_t *) malloc(sizeof(pointer_t)); 167 if (!p) {174 if (!p) 168 175 return NULL; 169 } 170 176 171 177 link_initialize(&p->link); 172 178 p->pos.x = coord_origin; … … 180 186 p->state = 0; 181 187 cursor_init(&p->cursor, CURSOR_DECODER_EMBEDDED, NULL); 182 188 189 /* Ghost window for transformation animation. */ 190 transform_identity(&p->ghost.transform); 191 transform_translate(&p->ghost.transform, coord_origin, coord_origin); 192 p->ghost.dx = coord_origin; 193 p->ghost.dy = coord_origin; 194 p->ghost.fx = 1; 195 p->ghost.fy = 1; 196 p->ghost.angle = 0; 197 p->ghost.opacity = 255; 198 p->ghost.surface = NULL; 199 p->accum_ghost.x = 0; 200 p->accum_ghost.y = 0; 201 183 202 return p; 184 203 } … … 192 211 } 193 212 194 static window_t *window_create( )213 static window_t *window_create(void) 195 214 { 196 215 window_t *win = (window_t *) malloc(sizeof(window_t)); 197 if (!win) {216 if (!win) 198 217 return NULL; 199 } 200 218 201 219 link_initialize(&win->link); 220 atomic_set(&win->ref_cnt, 0); 202 221 prodcons_initialize(&win->queue); 203 222 transform_identity(&win->transform); … … 210 229 win->opacity = 255; 211 230 win->surface = NULL; 212 231 213 232 return win; 214 233 } … … 216 235 static void window_destroy(window_t *win) 217 236 { 218 if (win) { 219 if (win->surface) { 237 if ((win) && (atomic_get(&win->ref_cnt) == 0)) { 238 while (!list_empty(&win->queue.list)) { 239 window_event_t *event = (window_event_t *) list_first(&win->queue.list); 240 list_remove(&event->link); 241 free(event); 242 } 243 244 if (win->surface) 220 245 surface_destroy(win->surface); 221 }246 222 247 free(win); 223 248 } … … 231 256 transform_invert(&win_trans); 232 257 transform_apply_affine(&win_trans, &x, &y); 233 234 /* Since client coordinate origin is (0, 0), it is necessary to check 258 259 /* 260 * Since client coordinate origin is (0, 0), it is necessary to check 235 261 * coordinates to avoid underflow. Moreover, it is convenient to also 236 262 * check against provided upper limits to determine whether the converted 237 * coordinates are within the client window. */ 238 if (x < 0 || y < 0) { 263 * coordinates are within the client window. 264 */ 265 if ((x < 0) || (y < 0)) 239 266 return false; 240 } else { 241 (*x_out) = (sysarg_t) (x + 0.5); 242 (*y_out) = (sysarg_t) (y + 0.5); 243 244 if ((*x_out) >= x_lim || (*y_out) >= y_lim) { 245 return false; 246 } else { 247 return true; 248 } 249 } 250 } 251 252 static void comp_coord_from_client(sysarg_t x_in, sysarg_t y_in, transform_t win_trans, 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; 275 } 276 277 static void comp_coord_from_client(double x_in, double y_in, transform_t win_trans, 253 278 sysarg_t *x_out, sysarg_t *y_out) 254 279 { … … 257 282 transform_apply_affine(&win_trans, &x, &y); 258 283 259 /* It is assumed that compositor coordinate origin is chosen in such way, 260 * that underflow/overflow here would be unlikely. */ 284 /* 285 * It is assumed that compositor coordinate origin is chosen in such way, 286 * that underflow/overflow here would be unlikely. 287 */ 261 288 (*x_out) = (sysarg_t) (x + 0.5); 262 289 (*y_out) = (sysarg_t) (y + 0.5); 263 290 } 264 291 265 static void comp_coord_bounding_rect( sysarg_t x_in, sysarg_ty_in,266 sysarg_t w_in, sysarg_th_in, transform_t win_trans,292 static void comp_coord_bounding_rect(double x_in, double y_in, 293 double w_in, double h_in, transform_t win_trans, 267 294 sysarg_t *x_out, sysarg_t *y_out, sysarg_t *w_out, sysarg_t *h_out) 268 295 { 269 sysarg_t x[4]; 270 sysarg_t y[4]; 271 comp_coord_from_client(x_in, y_in, win_trans, &x[0], &y[0]); 272 comp_coord_from_client(x_in + w_in, y_in, win_trans, &x[1], &y[1]); 273 comp_coord_from_client(x_in + w_in, y_in + h_in, win_trans, &x[2], &y[2]); 274 comp_coord_from_client(x_in, y_in + h_in, win_trans, &x[3], &y[3]); 275 (*x_out) = x[0]; 276 (*y_out) = y[0]; 277 (*w_out) = x[0]; 278 (*h_out) = y[0]; 279 for (int i = 1; i < 4; ++i) { 280 (*x_out) = (x[i] < (*x_out)) ? x[i] : (*x_out); 281 (*y_out) = (y[i] < (*y_out)) ? y[i] : (*y_out); 282 (*w_out) = (x[i] > (*w_out)) ? x[i] : (*w_out); 283 (*h_out) = (y[i] > (*h_out)) ? y[i] : (*h_out); 284 } 285 (*w_out) -= (*x_out); 286 (*h_out) -= (*y_out); 296 if ((w_in > 0) && (h_in > 0)) { 297 sysarg_t x[4]; 298 sysarg_t y[4]; 299 300 comp_coord_from_client(x_in, y_in, win_trans, &x[0], &y[0]); 301 comp_coord_from_client(x_in + w_in - 1, y_in, win_trans, &x[1], &y[1]); 302 comp_coord_from_client(x_in + w_in - 1, y_in + h_in - 1, win_trans, &x[2], &y[2]); 303 comp_coord_from_client(x_in, y_in + h_in - 1, win_trans, &x[3], &y[3]); 304 305 (*x_out) = x[0]; 306 (*y_out) = y[0]; 307 (*w_out) = x[0]; 308 (*h_out) = y[0]; 309 310 for (unsigned int i = 1; i < 4; ++i) { 311 (*x_out) = (x[i] < (*x_out)) ? x[i] : (*x_out); 312 (*y_out) = (y[i] < (*y_out)) ? y[i] : (*y_out); 313 (*w_out) = (x[i] > (*w_out)) ? x[i] : (*w_out); 314 (*h_out) = (y[i] > (*h_out)) ? y[i] : (*h_out); 315 } 316 317 (*w_out) = (*w_out) - (*x_out) + 1; 318 (*h_out) = (*h_out) - (*y_out) + 1; 319 } else { 320 (*x_out) = 0; 321 (*y_out) = 0; 322 (*w_out) = 0; 323 (*h_out) = 0; 324 } 325 } 326 327 static void comp_update_viewport_bound_rect(void) 328 { 329 fibril_mutex_lock(&viewport_list_mtx); 330 331 sysarg_t x_res = coord_origin; 332 sysarg_t y_res = coord_origin; 333 sysarg_t w_res = 0; 334 sysarg_t h_res = 0; 335 336 if (!list_empty(&viewport_list)) { 337 viewport_t *vp = (viewport_t *) list_first(&viewport_list); 338 x_res = vp->pos.x; 339 y_res = vp->pos.y; 340 surface_get_resolution(vp->surface, &w_res, &h_res); 341 } 342 343 list_foreach(viewport_list, link, viewport_t, vp) { 344 sysarg_t w_vp, h_vp; 345 surface_get_resolution(vp->surface, &w_vp, &h_vp); 346 rectangle_union(x_res, y_res, w_res, h_res, 347 vp->pos.x, vp->pos.y, w_vp, h_vp, 348 &x_res, &y_res, &w_res, &h_res); 349 } 350 351 viewport_bound_rect.x = x_res; 352 viewport_bound_rect.y = y_res; 353 viewport_bound_rect.w = w_res; 354 viewport_bound_rect.h = h_res; 355 356 fibril_mutex_unlock(&viewport_list_mtx); 357 } 358 359 static void comp_restrict_pointers(void) 360 { 361 comp_update_viewport_bound_rect(); 362 363 fibril_mutex_lock(&pointer_list_mtx); 364 365 list_foreach(pointer_list, link, pointer_t, ptr) { 366 ptr->pos.x = ptr->pos.x > viewport_bound_rect.x ? ptr->pos.x : viewport_bound_rect.x; 367 ptr->pos.y = ptr->pos.y > viewport_bound_rect.y ? ptr->pos.y : viewport_bound_rect.y; 368 ptr->pos.x = ptr->pos.x < viewport_bound_rect.x + viewport_bound_rect.w ? 369 ptr->pos.x : viewport_bound_rect.x + viewport_bound_rect.w; 370 ptr->pos.y = ptr->pos.y < viewport_bound_rect.y + viewport_bound_rect.h ? 371 ptr->pos.y : viewport_bound_rect.y + viewport_bound_rect.h; 372 } 373 374 fibril_mutex_unlock(&pointer_list_mtx); 287 375 } 288 376 … … 294 382 fibril_mutex_lock(&pointer_list_mtx); 295 383 296 list_foreach(viewport_list, link) { 297 384 list_foreach(viewport_list, link, viewport_t, vp) { 298 385 /* Determine what part of the viewport must be updated. */ 299 viewport_t *vp = list_get_instance(link, viewport_t, link);300 386 sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp; 301 387 surface_get_resolution(vp->surface, &w_dmg_vp, &h_dmg_vp); … … 309 395 /* Paint background color. */ 310 396 for (sysarg_t y = y_dmg_vp - vp->pos.y; y < y_dmg_vp - vp->pos.y + h_dmg_vp; ++y) { 311 for (sysarg_t x = x_dmg_vp - vp->pos.x; x < x_dmg_vp - vp->pos.x + w_dmg_vp; ++x) { 312 surface_put_pixel(vp->surface, x, y, bg_color); 397 pixel_t *dst = pixelmap_pixel_at( 398 surface_pixmap_access(vp->surface), x_dmg_vp - vp->pos.x, y); 399 sysarg_t count = w_dmg_vp; 400 while (count-- != 0) { 401 *dst++ = bg_color; 313 402 } 314 403 } 404 surface_add_damaged_region(vp->surface, 405 x_dmg_vp - vp->pos.x, y_dmg_vp - vp->pos.y, w_dmg_vp, h_dmg_vp); 315 406 316 407 transform_t transform; … … 319 410 320 411 source_init(&source); 321 source_set_filter(&source, filter _nearest);412 source_set_filter(&source, filter); 322 413 drawctx_init(&context, vp->surface); 323 414 drawctx_set_compose(&context, compose_over); … … 352 443 transform_translate(&transform, -pos.x, -pos.y); 353 444 354 source_set_transform(&source, transform); 355 source_set_texture(&source, win->surface, false); 445 source_set_transform(&source, transform); 446 source_set_texture(&source, win->surface, 447 PIXELMAP_EXTEND_TRANSPARENT_SIDES); 356 448 source_set_alpha(&source, PIXEL(win->opacity, 0, 0, 0)); 357 449 … … 361 453 } 362 454 363 list_foreach(pointer_list, link) { 455 list_foreach(pointer_list, link, pointer_t, ptr) { 456 if (ptr->ghost.surface) { 457 458 sysarg_t x_bnd_ghost, y_bnd_ghost, w_bnd_ghost, h_bnd_ghost; 459 sysarg_t x_dmg_ghost, y_dmg_ghost, w_dmg_ghost, h_dmg_ghost; 460 surface_get_resolution(ptr->ghost.surface, &w_bnd_ghost, &h_bnd_ghost); 461 comp_coord_bounding_rect(0, 0, w_bnd_ghost, h_bnd_ghost, ptr->ghost.transform, 462 &x_bnd_ghost, &y_bnd_ghost, &w_bnd_ghost, &h_bnd_ghost); 463 bool isec_ghost = rectangle_intersect( 464 x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp, 465 x_bnd_ghost, y_bnd_ghost, w_bnd_ghost, h_bnd_ghost, 466 &x_dmg_ghost, &y_dmg_ghost, &w_dmg_ghost, &h_dmg_ghost); 467 468 if (isec_ghost) { 469 /* FIXME: Ghost is currently drawn based on the bounding 470 * rectangle of the window, which is sufficient as long 471 * as the windows can be rotated only by 90 degrees. 472 * For ghost to be compatible with arbitrary-angle 473 * rotation, it should be drawn as four lines adjusted 474 * by the transformation matrix. That would however 475 * require to equip libdraw with line drawing functionality. */ 476 477 transform_t transform = ptr->ghost.transform; 478 double_point_t pos; 479 pos.x = vp->pos.x; 480 pos.y = vp->pos.y; 481 transform_translate(&transform, -pos.x, -pos.y); 482 483 pixel_t ghost_color; 484 485 if (y_bnd_ghost == y_dmg_ghost) { 486 for (sysarg_t x = x_dmg_ghost - vp->pos.x; 487 x < x_dmg_ghost - vp->pos.x + w_dmg_ghost; ++x) { 488 ghost_color = surface_get_pixel(vp->surface, 489 x, y_dmg_ghost - vp->pos.y); 490 surface_put_pixel(vp->surface, 491 x, y_dmg_ghost - vp->pos.y, INVERT(ghost_color)); 492 } 493 } 494 495 if (y_bnd_ghost + h_bnd_ghost == y_dmg_ghost + h_dmg_ghost) { 496 for (sysarg_t x = x_dmg_ghost - vp->pos.x; 497 x < x_dmg_ghost - vp->pos.x + w_dmg_ghost; ++x) { 498 ghost_color = surface_get_pixel(vp->surface, 499 x, y_dmg_ghost - vp->pos.y + h_dmg_ghost - 1); 500 surface_put_pixel(vp->surface, 501 x, y_dmg_ghost - vp->pos.y + h_dmg_ghost - 1, INVERT(ghost_color)); 502 } 503 } 504 505 if (x_bnd_ghost == x_dmg_ghost) { 506 for (sysarg_t y = y_dmg_ghost - vp->pos.y; 507 y < y_dmg_ghost - vp->pos.y + h_dmg_ghost; ++y) { 508 ghost_color = surface_get_pixel(vp->surface, 509 x_dmg_ghost - vp->pos.x, y); 510 surface_put_pixel(vp->surface, 511 x_dmg_ghost - vp->pos.x, y, INVERT(ghost_color)); 512 } 513 } 514 515 if (x_bnd_ghost + w_bnd_ghost == x_dmg_ghost + w_dmg_ghost) { 516 for (sysarg_t y = y_dmg_ghost - vp->pos.y; 517 y < y_dmg_ghost - vp->pos.y + h_dmg_ghost; ++y) { 518 ghost_color = surface_get_pixel(vp->surface, 519 x_dmg_ghost - vp->pos.x + w_dmg_ghost - 1, y); 520 surface_put_pixel(vp->surface, 521 x_dmg_ghost - vp->pos.x + w_dmg_ghost - 1, y, INVERT(ghost_color)); 522 } 523 } 524 } 525 526 } 527 } 528 529 list_foreach(pointer_list, link, pointer_t, ptr) { 364 530 365 531 /* Determine what part of the pointer intersects with the 366 532 * updated area of the current viewport. */ 367 pointer_t *ptr = list_get_instance(link, pointer_t, link);368 533 sysarg_t x_dmg_ptr, y_dmg_ptr, w_dmg_ptr, h_dmg_ptr; 369 534 surface_t *sf_ptr = ptr->cursor.states[ptr->state]; … … 376 541 if (isec_ptr) { 377 542 /* Pointer is currently painted directly by copying pixels. 378 * However, it is possible to draw the p ainter similarly543 * However, it is possible to draw the pointer similarly 379 544 * as window by using drawctx_transfer. It would allow 380 545 * more sophisticated control over drawing, but would also 381 546 * cost more regarding the performance. */ 382 547 383 pixel_t pix = 0;384 548 sysarg_t x_vp = x_dmg_ptr - vp->pos.x; 385 549 sysarg_t y_vp = y_dmg_ptr - vp->pos.y; … … 388 552 389 553 for (sysarg_t y = 0; y < h_dmg_ptr; ++y) { 390 for (sysarg_t x = 0; x < w_dmg_ptr; ++x) { 391 pix = surface_get_pixel(sf_ptr, x_ptr + x, y_ptr + y); 392 if (ALPHA(pix) == 255) { 393 surface_put_pixel(vp->surface, x_vp + x, y_vp + y, pix); 394 } 554 pixel_t *src = pixelmap_pixel_at( 555 surface_pixmap_access(sf_ptr), x_ptr, y_ptr + y); 556 pixel_t *dst = pixelmap_pixel_at( 557 surface_pixmap_access(vp->surface), x_vp, y_vp + y); 558 sysarg_t count = w_dmg_ptr; 559 while (count-- != 0) { 560 *dst = (*src & 0xff000000) ? *src : *dst; 561 ++dst; ++src; 395 562 } 396 563 } 564 surface_add_damaged_region(vp->surface, x_vp, y_vp, w_dmg_ptr, h_dmg_ptr); 397 565 } 566 398 567 } 399 568 } … … 404 573 405 574 /* Notify visualizers about updated regions. */ 406 list_foreach(viewport_list, link) { 407 viewport_t *vp = list_get_instance(link, viewport_t, link); 408 sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp; 409 surface_get_damaged_region(vp->surface, &x_dmg_vp, &y_dmg_vp, &w_dmg_vp, &h_dmg_vp); 410 surface_reset_damaged_region(vp->surface); 411 visualizer_update_damaged_region( 412 vp->sess, x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp, 0, 0); 413 } 414 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 415 585 fibril_mutex_unlock(&viewport_list_mtx); 416 586 } … … 428 598 return; 429 599 } 600 430 601 int rc = async_data_read_finalize(callid, event, len); 431 602 if (rc != EOK) { … … 434 605 return; 435 606 } 607 436 608 async_answer_0(iid, EOK); 437 438 609 free(event); 439 610 } … … 441 612 static void comp_window_damage(window_t *win, ipc_callid_t iid, ipc_call_t *icall) 442 613 { 443 sysarg_tx = IPC_GET_ARG1(*icall);444 sysarg_ty = IPC_GET_ARG2(*icall);445 sysarg_twidth = IPC_GET_ARG3(*icall);446 sysarg_theight = IPC_GET_ARG4(*icall);447 448 if ( width == 0 || height == 0) {614 double x = IPC_GET_ARG1(*icall); 615 double y = IPC_GET_ARG2(*icall); 616 double width = IPC_GET_ARG3(*icall); 617 double height = IPC_GET_ARG4(*icall); 618 619 if ((width == 0) || (height == 0)) { 449 620 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 450 621 } else { 451 622 fibril_mutex_lock(&window_list_mtx); 452 comp_coord_bounding_rect(x, y, width, height, 453 win->transform, &x, &y, &width, &height); 623 sysarg_t x_dmg_glob, y_dmg_glob, w_dmg_glob, h_dmg_glob; 624 comp_coord_bounding_rect(x - 1, y - 1, width + 2, height + 2, 625 win->transform, &x_dmg_glob, &y_dmg_glob, &w_dmg_glob, &h_dmg_glob); 454 626 fibril_mutex_unlock(&window_list_mtx); 455 comp_damage(x , y, width, height);627 comp_damage(x_dmg_glob, y_dmg_glob, w_dmg_glob, h_dmg_glob); 456 628 } 457 629 … … 465 637 466 638 fibril_mutex_lock(&pointer_list_mtx); 467 list_foreach(pointer_list, link) { 468 pointer_t *pointer = list_get_instance(link, pointer_t, link); 639 list_foreach(pointer_list, link, pointer_t, pointer) { 469 640 if (pointer->id == pos_id) { 470 pointer->grab_flags = grab_flags;641 pointer->grab_flags = pointer->pressed ? grab_flags : GF_EMPTY; 471 642 // TODO change pointer->state according to grab_flags 472 643 break; … … 483 654 } 484 655 656 static void comp_recalc_transform(window_t *win) 657 { 658 transform_t translate; 659 transform_identity(&translate); 660 transform_translate(&translate, win->dx, win->dy); 661 662 transform_t scale; 663 transform_identity(&scale); 664 if ((win->fx != 1) || (win->fy != 1)) 665 transform_scale(&scale, win->fx, win->fy); 666 667 transform_t rotate; 668 transform_identity(&rotate); 669 if (win->angle != 0) 670 transform_rotate(&rotate, win->angle); 671 672 transform_t transform; 673 transform_t temp; 674 transform_identity(&transform); 675 temp = transform; 676 transform_product(&transform, &temp, &translate); 677 temp = transform; 678 transform_product(&transform, &temp, &rotate); 679 temp = transform; 680 transform_product(&transform, &temp, &scale); 681 682 win->transform = transform; 683 } 684 485 685 static void comp_window_resize(window_t *win, ipc_callid_t iid, ipc_call_t *icall) 486 686 { 487 int rc;488 489 687 ipc_callid_t callid; 490 688 size_t size; 491 689 unsigned int flags; 492 690 493 691 /* Start sharing resized window with client. */ 494 692 if (!async_share_out_receive(&callid, &size, &flags)) { … … 496 694 return; 497 695 } 696 498 697 void *new_cell_storage; 499 rc = async_share_out_finalize(callid, &new_cell_storage);698 int rc = async_share_out_finalize(callid, &new_cell_storage); 500 699 if ((rc != EOK) || (new_cell_storage == AS_MAP_FAILED)) { 501 700 async_answer_0(iid, ENOMEM); 502 701 return; 503 702 } 504 703 505 704 /* Create new surface for the resized window. */ 506 surface_t *new_surface = surface_create( 507 IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall), 508 new_cell_storage, SURFACE_FLAG_SHARED); 705 surface_t *new_surface = surface_create(IPC_GET_ARG3(*icall), 706 IPC_GET_ARG4(*icall), new_cell_storage, SURFACE_FLAG_SHARED); 509 707 if (!new_surface) { 510 708 as_area_destroy(new_cell_storage); … … 512 710 return; 513 711 } 514 712 713 sysarg_t offset_x = IPC_GET_ARG1(*icall); 714 sysarg_t offset_y = IPC_GET_ARG2(*icall); 715 window_placement_flags_t placement_flags = 716 (window_placement_flags_t) IPC_GET_ARG5(*icall); 717 718 comp_update_viewport_bound_rect(); 719 515 720 /* Switch new surface with old surface and calculate damage. */ 516 721 fibril_mutex_lock(&window_list_mtx); 517 722 518 723 sysarg_t old_width = 0; 519 724 sysarg_t old_height = 0; 725 520 726 if (win->surface) { 521 727 surface_get_resolution(win->surface, &old_width, &old_height); 522 728 surface_destroy(win->surface); 523 729 } 524 730 525 731 win->surface = new_surface; 526 732 527 733 sysarg_t new_width = 0; 528 734 sysarg_t new_height = 0; 529 735 surface_get_resolution(win->surface, &new_width, &new_height); 530 531 sysarg_t x, y; 532 sysarg_t width = old_width > new_width ? old_width : new_width; 533 sysarg_t height = old_height > new_height ? old_height : new_height; 534 comp_coord_bounding_rect(0, 0, width, height, win->transform, &x, &y, &width, &height); 535 736 737 if (placement_flags & WINDOW_PLACEMENT_CENTER_X) 738 win->dx = viewport_bound_rect.x + viewport_bound_rect.w / 2 - 739 new_width / 2; 740 741 if (placement_flags & WINDOW_PLACEMENT_CENTER_Y) 742 win->dy = viewport_bound_rect.y + viewport_bound_rect.h / 2 - 743 new_height / 2; 744 745 if (placement_flags & WINDOW_PLACEMENT_LEFT) 746 win->dx = viewport_bound_rect.x; 747 748 if (placement_flags & WINDOW_PLACEMENT_TOP) 749 win->dy = viewport_bound_rect.y; 750 751 if (placement_flags & WINDOW_PLACEMENT_RIGHT) 752 win->dx = viewport_bound_rect.x + viewport_bound_rect.w - 753 new_width; 754 755 if (placement_flags & WINDOW_PLACEMENT_BOTTOM) 756 win->dy = viewport_bound_rect.y + viewport_bound_rect.h - 757 new_height; 758 759 if (placement_flags & WINDOW_PLACEMENT_ABSOLUTE_X) 760 win->dx = coord_origin + offset_x; 761 762 if (placement_flags & WINDOW_PLACEMENT_ABSOLUTE_Y) 763 win->dy = coord_origin + offset_y; 764 765 /* Transform the window and calculate damage. */ 766 sysarg_t x1; 767 sysarg_t y1; 768 sysarg_t width1; 769 sysarg_t height1; 770 771 comp_coord_bounding_rect(0, 0, old_width, old_height, win->transform, 772 &x1, &y1, &width1, &height1); 773 774 comp_recalc_transform(win); 775 776 sysarg_t x2; 777 sysarg_t y2; 778 sysarg_t width2; 779 sysarg_t height2; 780 781 comp_coord_bounding_rect(0, 0, new_width, new_height, win->transform, 782 &x2, &y2, &width2, &height2); 783 784 sysarg_t x; 785 sysarg_t y; 786 sysarg_t width; 787 sysarg_t height; 788 789 rectangle_union(x1, y1, width1, height1, x2, y2, width2, height2, 790 &x, &y, &width, &height); 791 536 792 fibril_mutex_unlock(&window_list_mtx); 537 793 538 794 comp_damage(x, y, width, height); 539 795 540 796 async_answer_0(iid, EOK); 797 } 798 799 static void comp_post_event_win(window_event_t *event, window_t *target) 800 { 801 fibril_mutex_lock(&window_list_mtx); 802 803 list_foreach(window_list, link, window_t, window) { 804 if (window == target) { 805 prodcons_produce(&window->queue, &event->link); 806 fibril_mutex_unlock(&window_list_mtx); 807 return; 808 } 809 } 810 811 fibril_mutex_unlock(&window_list_mtx); 812 free(event); 813 } 814 815 static void comp_post_event_top(window_event_t *event) 816 { 817 fibril_mutex_lock(&window_list_mtx); 818 819 window_t *win = (window_t *) list_first(&window_list); 820 if (win) 821 prodcons_produce(&win->queue, &event->link); 822 else 823 free(event); 824 825 fibril_mutex_unlock(&window_list_mtx); 541 826 } 542 827 … … 546 831 fibril_mutex_lock(&window_list_mtx); 547 832 list_remove(&win->link); 833 window_t *win_focus = (window_t *) list_first(&window_list); 834 window_event_t *event_focus = (window_event_t *) malloc(sizeof(window_event_t)); 835 if (event_focus) { 836 link_initialize(&event_focus->link); 837 event_focus->type = ET_WINDOW_FOCUS; 838 } 548 839 fibril_mutex_unlock(&window_list_mtx); 840 841 if (event_focus && win_focus) { 842 comp_post_event_win(event_focus, win_focus); 843 } 844 845 loc_service_unregister(win->in_dsid); 846 loc_service_unregister(win->out_dsid); 847 848 /* In case the client was killed, input fibril of the window might be 849 * still blocked on the condition within comp_window_get_event. */ 850 window_event_t *event_dummy = (window_event_t *) malloc(sizeof(window_event_t)); 851 if (event_dummy) { 852 link_initialize(&event_dummy->link); 853 prodcons_produce(&win->queue, &event_dummy->link); 854 } 549 855 550 856 /* Calculate damage. */ … … 559 865 } 560 866 561 /* Release window resources. */562 loc_service_unregister(win->in_dsid);563 loc_service_unregister(win->out_dsid);564 while (!list_empty(&win->queue.list)) {565 list_remove(list_first(&win->queue.list));566 }567 window_destroy(win);568 569 867 comp_damage(x, y, width, height); 570 571 868 async_answer_0(iid, EOK); 572 869 } … … 574 871 static void comp_window_close_request(window_t *win, ipc_callid_t iid, ipc_call_t *icall) 575 872 { 576 873 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t)); 577 874 if (event == NULL) { 578 875 async_answer_0(iid, ENOMEM); … … 630 927 } 631 928 929 window_t *win_unfocus = (window_t *) list_first(&window_list); 632 930 list_prepend(&win->link, &window_list); 931 932 window_event_t *event_unfocus = (window_event_t *) malloc(sizeof(window_event_t)); 933 if (event_unfocus) { 934 link_initialize(&event_unfocus->link); 935 event_unfocus->type = ET_WINDOW_UNFOCUS; 936 } 633 937 634 938 async_answer_2(callid, EOK, win->in_dsid, win->out_dsid); 635 939 fibril_mutex_unlock(&window_list_mtx); 940 941 if (event_unfocus && win_unfocus) { 942 comp_post_event_win(event_unfocus, win_unfocus); 943 } 944 636 945 return; 637 946 } else { … … 644 953 window_t *win = NULL; 645 954 fibril_mutex_lock(&window_list_mtx); 646 list_foreach(window_list, link) { 647 window_t *cur = list_get_instance(link, window_t, link); 955 list_foreach(window_list, link, window_t, cur) { 648 956 if (cur->in_dsid == service_id || cur->out_dsid == service_id) { 649 957 win = cur; … … 654 962 655 963 if (win) { 964 atomic_inc(&win->ref_cnt); 656 965 async_answer_0(iid, EOK); 657 966 } else { … … 666 975 667 976 if (!IPC_GET_IMETHOD(call)) { 668 async_answer_0(callid, EINVAL); 977 async_answer_0(callid, EOK); 978 atomic_dec(&win->ref_cnt); 979 window_destroy(win); 669 980 return; 670 981 } … … 683 994 684 995 if (!IPC_GET_IMETHOD(call)) { 685 async_answer_0(callid, EINVAL); 996 comp_window_close(win, callid, &call); 997 atomic_dec(&win->ref_cnt); 998 window_destroy(win); 686 999 return; 687 1000 } … … 698 1011 break; 699 1012 case WINDOW_CLOSE: 700 comp_window_close(win, callid, &call); 1013 /* 1014 * Postpone the closing until the phone is hung up to cover 1015 * the case when the client is killed abruptly. 1016 */ 1017 async_answer_0(callid, EOK); 701 1018 break; 702 1019 case WINDOW_CLOSE_REQUEST: … … 712 1029 static void comp_mode_change(viewport_t *vp, ipc_callid_t iid, ipc_call_t *icall) 713 1030 { 714 int rc;715 1031 sysarg_t mode_idx = IPC_GET_ARG2(*icall); 716 1032 fibril_mutex_lock(&viewport_list_mtx); … … 718 1034 /* Retrieve the mode that shall be set. */ 719 1035 vslmode_t new_mode; 720 rc = visualizer_get_mode(vp->sess, &new_mode, mode_idx);1036 int rc = visualizer_get_mode(vp->sess, &new_mode, mode_idx); 721 1037 if (rc != EOK) { 722 1038 fibril_mutex_unlock(&viewport_list_mtx); … … 736 1052 /* Try to set the mode and share out the surface. */ 737 1053 rc = visualizer_set_mode(vp->sess, 738 1054 new_mode.index, new_mode.version, surface_direct_access(new_surface)); 739 1055 if (rc != EOK) { 740 1056 surface_destroy(new_surface); … … 752 1068 async_answer_0(iid, EOK); 753 1069 1070 comp_restrict_pointers(); 754 1071 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 755 1072 } … … 765 1082 } 766 1083 1084 #if 0 1085 static void comp_shutdown(void) 1086 { 1087 loc_service_unregister(winreg_id); 1088 input_disconnect(); 1089 1090 /* Close all clients and their windows. */ 1091 fibril_mutex_lock(&window_list_mtx); 1092 list_foreach(window_list, link, window_t, win) { 1093 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t)); 1094 if (event) { 1095 link_initialize(&event->link); 1096 event->type = WINDOW_CLOSE; 1097 prodcons_produce(&win->queue, &event->link); 1098 } 1099 } 1100 fibril_mutex_unlock(&window_list_mtx); 1101 1102 async_answer_0(iid, EOK); 1103 1104 /* All fibrils of the compositor will terminate soon. */ 1105 } 1106 #endif 1107 767 1108 static void comp_visualizer_disconnect(viewport_t *vp, ipc_callid_t iid, ipc_call_t *icall) 768 1109 { 769 1110 /* Release viewport resources. */ 770 1111 fibril_mutex_lock(&viewport_list_mtx); 1112 771 1113 list_remove(&vp->link); 772 1114 viewport_destroy(vp); 773 774 /* Terminate compositor if there are no more viewports. */ 775 if (list_empty(&viewport_list)) { 776 fibril_mutex_unlock(&viewport_list_mtx); 777 loc_service_unregister(winreg_id); 778 input_disconnect(); 779 780 /* Close all clients and their windows. */ 781 fibril_mutex_lock(&window_list_mtx); 782 list_foreach(window_list, link) { 783 window_t *win = list_get_instance(link, window_t, link); 784 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t)); 785 if (event) { 786 link_initialize(&event->link); 787 event->type = WINDOW_CLOSE; 788 prodcons_produce(&win->queue, &event->link); 789 } 790 } 791 fibril_mutex_unlock(&window_list_mtx); 792 793 async_answer_0(iid, EOK); 794 795 /* All fibrils of the compositor will terminate soon. */ 796 } else { 797 fibril_mutex_unlock(&viewport_list_mtx); 798 async_answer_0(iid, EOK); 799 } 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); 800 1122 } 801 1123 … … 804 1126 viewport_t *vp = NULL; 805 1127 fibril_mutex_lock(&viewport_list_mtx); 806 list_foreach(viewport_list, link) { 807 viewport_t *cur = list_get_instance(link, viewport_t, link); 1128 list_foreach(viewport_list, link, viewport_t, cur) { 808 1129 if (cur->dsid == (service_id_t) IPC_GET_ARG1(*icall)) { 809 1130 vp = cur; … … 813 1134 fibril_mutex_unlock(&viewport_list_mtx); 814 1135 815 if (!vp) {1136 if (!vp) 816 1137 return; 817 }818 1138 819 1139 /* Ignore parameters, the connection is already opened. */ … … 840 1160 } 841 1161 842 static async_sess_t *vsl_connect( const char *svc)1162 static async_sess_t *vsl_connect(service_id_t sid, const char *svc) 843 1163 { 844 1164 int rc; 845 1165 async_sess_t *sess; 846 service_id_t dsid; 847 devman_handle_t handle; 848 849 rc = loc_service_get_id(svc, &dsid, 0); 850 if (rc != EOK) { 1166 1167 sess = loc_service_connect(EXCHANGE_SERIALIZE, sid, 0); 1168 if (sess == NULL) { 1169 printf("%s: Unable to connect to visualizer %s\n", NAME, svc); 851 1170 return NULL; 852 1171 } 853 1172 854 rc = devman_fun_sid_to_handle(dsid, &handle);855 if (rc == EOK) {856 sess = devman_device_connect(EXCHANGE_SERIALIZE, handle, 0);857 if (sess == NULL) {858 printf("%s: Unable to connect to visualizer %s\n", NAME, svc);859 return NULL;860 }861 rc = graph_dev_connect(sess);862 if (rc != EOK) {863 return NULL;864 }865 } else if (rc == ENOENT) {866 sess = loc_service_connect(EXCHANGE_SERIALIZE, dsid, 0);867 if (sess == NULL) {868 printf("%s: Unable to connect to visualizer %s\n", NAME, svc);869 return NULL;870 }871 } else {872 return NULL;873 }874 875 1173 async_exch_t *exch = async_exchange_begin(sess); 876 rc = async_connect_to_me(exch, dsid, 0, 0, vsl_notifications, NULL);1174 rc = async_connect_to_me(exch, sid, 0, 0, vsl_notifications, NULL); 877 1175 async_exchange_end(exch); 878 1176 … … 887 1185 } 888 1186 889 static viewport_t *viewport_create( const char *vsl_name)1187 static viewport_t *viewport_create(service_id_t sid) 890 1188 { 891 1189 int rc; 892 893 viewport_t *vp = (viewport_t *) malloc(sizeof(viewport_t)); 894 if (!vp) { 895 return NULL; 896 } 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; 897 1201 898 1202 link_initialize(&vp->link); … … 901 1205 902 1206 /* Establish output bidirectional connection. */ 903 vp->sess = vsl_connect(vsl_name); 904 rc = loc_service_get_id(vsl_name, &vp->dsid, 0); 905 if (vp->sess == NULL || rc != EOK) { 906 free(vp); 907 return NULL; 908 } 1207 vp->dsid = sid; 1208 vp->sess = vsl_connect(sid, vsl_name); 1209 if (vp->sess == NULL) 1210 goto error; 909 1211 910 1212 /* Claim the given visualizer. */ 911 1213 rc = visualizer_claim(vp->sess, 0); 912 1214 if (rc != EOK) { 913 async_hangup(vp->sess);914 free(vp);915 1215 printf("%s: Unable to claim visualizer (%s)\n", NAME, str_error(rc)); 916 return NULL; 917 } 1216 goto error; 1217 } 1218 1219 claimed = true; 918 1220 919 1221 /* Retrieve the default mode. */ 920 1222 rc = visualizer_get_default_mode(vp->sess, &vp->mode); 921 1223 if (rc != EOK) { 922 visualizer_yield(vp->sess);923 async_hangup(vp->sess);924 free(vp);925 1224 printf("%s: Unable to retrieve mode (%s)\n", NAME, str_error(rc)); 926 return NULL;1225 goto error; 927 1226 } 928 1227 … … 931 1230 NULL, SURFACE_FLAG_SHARED); 932 1231 if (vp->surface == NULL) { 933 visualizer_yield(vp->sess);934 async_hangup(vp->sess);935 free(vp);936 1232 printf("%s: Unable to create surface (%s)\n", NAME, str_error(rc)); 937 return NULL;1233 goto error; 938 1234 } 939 1235 940 1236 /* Try to set the mode and share out the surface. */ 941 1237 rc = visualizer_set_mode(vp->sess, 942 1238 vp->mode.index, vp->mode.version, surface_direct_access(vp->surface)); 943 1239 if (rc != EOK) { 1240 printf("%s: Unable to set mode (%s)\n", NAME, str_error(rc)); 1241 goto error; 1242 } 1243 1244 return vp; 1245 error: 1246 if (claimed) 944 1247 visualizer_yield(vp->sess); 945 surface_destroy(vp->surface); 1248 1249 if (vp->sess != NULL) 946 1250 async_hangup(vp->sess); 947 free(vp); 948 printf("%s: Unable to set mode (%s)\n", NAME, str_error(rc)); 949 return NULL; 950 } 951 952 return vp; 953 } 954 955 static void comp_post_event(window_event_t *event) 956 { 957 fibril_mutex_lock(&window_list_mtx); 958 window_t *win = (window_t *) list_first(&window_list); 959 if (win) { 960 prodcons_produce(&win->queue, &event->link); 961 } else { 962 free(event); 963 } 964 fibril_mutex_unlock(&window_list_mtx); 965 } 966 967 static void comp_recalc_transform(window_t *win) 968 { 969 transform_t translate; 970 transform_identity(&translate); 971 transform_translate(&translate, win->dx, win->dy); 972 973 transform_t scale; 974 transform_identity(&scale); 975 transform_scale(&scale, win->fx, win->fy); 976 977 transform_t rotate; 978 transform_identity(&rotate); 979 transform_rotate(&rotate, win->angle); 980 981 transform_t transform; 982 transform_t temp; 983 transform_identity(&transform); 984 temp = transform; 985 transform_multiply(&transform, &temp, &translate); 986 temp = transform; 987 transform_multiply(&transform, &temp, &rotate); 988 temp = transform; 989 transform_multiply(&transform, &temp, &scale); 990 991 992 win->transform = transform; 1251 1252 free(vp); 1253 free(vsl_name); 1254 return NULL; 993 1255 } 994 1256 995 1257 static void comp_window_animate(pointer_t *pointer, window_t *win, 996 1258 sysarg_t *dmg_x, sysarg_t *dmg_y, sysarg_t *dmg_width, sysarg_t *dmg_height) 997 1259 { 998 1260 /* window_list_mtx locked by caller */ 1261 /* pointer_list_mtx locked by caller */ 999 1262 1000 1263 int dx = pointer->accum.x; … … 1013 1276 double cx = 0; 1014 1277 double cy = 0; 1015 if (pointer->grab_flags & GF_MOVE_X) { 1278 1279 if (pointer->grab_flags & GF_MOVE_X) 1016 1280 cx = 1; 1017 }1018 if (pointer->grab_flags & GF_MOVE_Y) {1281 1282 if (pointer->grab_flags & GF_MOVE_Y) 1019 1283 cy = 1; 1020 } 1021 1022 if (scale || resize) { 1284 1285 if (((scale) || (resize)) && (win->angle != 0)) { 1023 1286 transform_t rotate; 1024 1287 transform_identity(&rotate); 1288 1025 1289 transform_rotate(&rotate, win->angle); 1026 1290 transform_apply_linear(&rotate, &cx, &cy); 1027 1291 } 1028 1292 1029 cx = (cx < 0) ? (-1 * cx) : cx; 1293 cx = (cx < 0) ? (-1 * cx) : cx; 1030 1294 cy = (cy < 0) ? (-1 * cy) : cy; 1031 1295 1032 1296 win->dx += (cx * dx); 1033 1297 win->dy += (cy * dy); 1034 1298 } 1035 1299 1036 if ( scale || resize) {1300 if ((scale) || (resize)) { 1037 1301 double _dx = dx; 1038 1302 double _dy = dy; 1039 transform_t unrotate; 1040 transform_identity(&unrotate); 1041 transform_rotate(&unrotate, -win->angle); 1042 transform_apply_linear(&unrotate, &_dx, &_dy); 1303 if (win->angle != 0) { 1304 transform_t unrotate; 1305 transform_identity(&unrotate); 1306 transform_rotate(&unrotate, -win->angle); 1307 transform_apply_linear(&unrotate, &_dx, &_dy); 1308 } 1043 1309 _dx = (pointer->grab_flags & GF_MOVE_X) ? -_dx : _dx; 1044 1310 _dy = (pointer->grab_flags & GF_MOVE_Y) ? -_dy : _dy; 1045 1311 1046 1312 if ((pointer->grab_flags & GF_SCALE_X) || (pointer->grab_flags & GF_RESIZE_X)) { 1047 double fx = 1.0 + (_dx / ( width* win->fx));1313 double fx = 1.0 + (_dx / ((width - 1) * win->fx)); 1048 1314 if (fx > 0) { 1315 #if ANIMATE_WINDOW_TRANSFORMS == 0 1316 if (scale) 1317 win->fx *= fx; 1318 #endif 1319 #if ANIMATE_WINDOW_TRANSFORMS == 1 1049 1320 win->fx *= fx; 1321 #endif 1050 1322 scale_back_x *= fx; 1051 1323 } … … 1053 1325 1054 1326 if ((pointer->grab_flags & GF_SCALE_Y) || (pointer->grab_flags & GF_RESIZE_Y)) { 1055 double fy = 1.0 + (_dy / ( height* win->fy));1327 double fy = 1.0 + (_dy / ((height - 1) * win->fy)); 1056 1328 if (fy > 0) { 1329 #if ANIMATE_WINDOW_TRANSFORMS == 0 1330 if (scale) win->fy *= fy; 1331 #endif 1332 #if ANIMATE_WINDOW_TRANSFORMS == 1 1057 1333 win->fy *= fy; 1334 #endif 1058 1335 scale_back_y *= fy; 1059 1336 } … … 1072 1349 } 1073 1350 1351 #if ANIMATE_WINDOW_TRANSFORMS == 0 1352 static void comp_ghost_animate(pointer_t *pointer, 1353 desktop_rect_t *rect1, desktop_rect_t *rect2, desktop_rect_t *rect3, desktop_rect_t *rect4) 1354 { 1355 /* window_list_mtx locked by caller */ 1356 /* pointer_list_mtx locked by caller */ 1357 1358 int dx = pointer->accum_ghost.x; 1359 int dy = pointer->accum_ghost.y; 1360 pointer->accum_ghost.x = 0; 1361 pointer->accum_ghost.y = 0; 1362 1363 bool move = (pointer->grab_flags & GF_MOVE_X) || (pointer->grab_flags & GF_MOVE_Y); 1364 bool scale = (pointer->grab_flags & GF_SCALE_X) || (pointer->grab_flags & GF_SCALE_Y); 1365 bool resize = (pointer->grab_flags & GF_RESIZE_X) || (pointer->grab_flags & GF_RESIZE_Y); 1366 1367 sysarg_t width, height; 1368 surface_get_resolution(pointer->ghost.surface, &width, &height); 1369 1370 if (move) { 1371 double cx = 0; 1372 double cy = 0; 1373 if (pointer->grab_flags & GF_MOVE_X) { 1374 cx = 1; 1375 } 1376 if (pointer->grab_flags & GF_MOVE_Y) { 1377 cy = 1; 1378 } 1379 1380 if (scale || resize) { 1381 transform_t rotate; 1382 transform_identity(&rotate); 1383 transform_rotate(&rotate, pointer->ghost.angle); 1384 transform_apply_linear(&rotate, &cx, &cy); 1385 } 1386 1387 cx = (cx < 0) ? (-1 * cx) : cx; 1388 cy = (cy < 0) ? (-1 * cy) : cy; 1389 1390 pointer->ghost.dx += (cx * dx); 1391 pointer->ghost.dy += (cy * dy); 1392 } 1393 1394 if (scale || resize) { 1395 double _dx = dx; 1396 double _dy = dy; 1397 transform_t unrotate; 1398 transform_identity(&unrotate); 1399 transform_rotate(&unrotate, -pointer->ghost.angle); 1400 transform_apply_linear(&unrotate, &_dx, &_dy); 1401 _dx = (pointer->grab_flags & GF_MOVE_X) ? -_dx : _dx; 1402 _dy = (pointer->grab_flags & GF_MOVE_Y) ? -_dy : _dy; 1403 1404 if ((pointer->grab_flags & GF_SCALE_X) || (pointer->grab_flags & GF_RESIZE_X)) { 1405 double fx = 1.0 + (_dx / ((width - 1) * pointer->ghost.fx)); 1406 pointer->ghost.fx *= fx; 1407 } 1408 1409 if ((pointer->grab_flags & GF_SCALE_Y) || (pointer->grab_flags & GF_RESIZE_Y)) { 1410 double fy = 1.0 + (_dy / ((height - 1) * pointer->ghost.fy)); 1411 pointer->ghost.fy *= fy; 1412 } 1413 } 1414 1415 sysarg_t x1, y1, width1, height1; 1416 sysarg_t x2, y2, width2, height2; 1417 comp_coord_bounding_rect(0, 0, width, height, pointer->ghost.transform, 1418 &x1, &y1, &width1, &height1); 1419 comp_recalc_transform(&pointer->ghost); 1420 comp_coord_bounding_rect(0, 0, width, height, pointer->ghost.transform, 1421 &x2, &y2, &width2, &height2); 1422 1423 sysarg_t x_u, y_u, w_u, h_u; 1424 rectangle_union(x1, y1, width1, height1, x2, y2, width2, height2, 1425 &x_u, &y_u, &w_u, &h_u); 1426 1427 sysarg_t x_i, y_i, w_i, h_i; 1428 rectangle_intersect(x1, y1, width1, height1, x2, y2, width2, height2, 1429 &x_i, &y_i, &w_i, &h_i); 1430 1431 if (w_i == 0 || h_i == 0) { 1432 rect1->x = x_u; rect2->x = 0; rect3->x = 0; rect4->x = 0; 1433 rect1->y = y_u; rect2->y = 0; rect3->y = 0; rect4->y = 0; 1434 rect1->w = w_u; rect2->w = 0; rect3->w = 0; rect4->w = 0; 1435 rect1->h = h_u; rect2->h = 0; rect3->h = 0; rect4->h = 0; 1436 } else { 1437 rect1->x = x_u; 1438 rect1->y = y_u; 1439 rect1->w = x_i - x_u + 1; 1440 rect1->h = h_u; 1441 1442 rect2->x = x_u; 1443 rect2->y = y_u; 1444 rect2->w = w_u; 1445 rect2->h = y_i - y_u + 1; 1446 1447 rect3->x = x_i + w_i - 1; 1448 rect3->y = y_u; 1449 rect3->w = w_u - w_i - x_i + x_u + 1; 1450 rect3->h = h_u; 1451 1452 rect4->x = x_u; 1453 rect4->y = y_i + h_i - 1; 1454 rect4->w = w_u; 1455 rect4->h = h_u - h_i - y_i + y_u + 1; 1456 } 1457 } 1458 #endif 1459 1074 1460 static int comp_abs_move(input_t *input, unsigned x , unsigned y, 1075 1461 unsigned max_x, unsigned max_y) … … 1110 1496 { 1111 1497 pointer_t *pointer = input_pointer(input); 1112 1498 1499 comp_update_viewport_bound_rect(); 1500 1113 1501 /* Update pointer position. */ 1114 1502 fibril_mutex_lock(&pointer_list_mtx); 1503 1115 1504 desktop_point_t old_pos = pointer->pos; 1505 1116 1506 sysarg_t cursor_width; 1117 1507 sysarg_t cursor_height; 1118 surface_get_resolution(pointer->cursor.states[pointer->state], 1508 surface_get_resolution(pointer->cursor.states[pointer->state], 1119 1509 &cursor_width, &cursor_height); 1510 1511 if (pointer->pos.x + dx < viewport_bound_rect.x) 1512 dx = -1 * (pointer->pos.x - viewport_bound_rect.x); 1513 1514 if (pointer->pos.y + dy < viewport_bound_rect.y) 1515 dy = -1 * (pointer->pos.y - viewport_bound_rect.y); 1516 1517 if (pointer->pos.x + dx > viewport_bound_rect.x + viewport_bound_rect.w) 1518 dx = (viewport_bound_rect.x + viewport_bound_rect.w - pointer->pos.x); 1519 1520 if (pointer->pos.y + dy > viewport_bound_rect.y + viewport_bound_rect.h) 1521 dy = (viewport_bound_rect.y + viewport_bound_rect.h - pointer->pos.y); 1522 1120 1523 pointer->pos.x += dx; 1121 1524 pointer->pos.y += dy; … … 1123 1526 comp_damage(old_pos.x, old_pos.y, cursor_width, cursor_height); 1124 1527 comp_damage(old_pos.x + dx, old_pos.y + dy, cursor_width, cursor_height); 1125 1528 1126 1529 fibril_mutex_lock(&window_list_mtx); 1530 fibril_mutex_lock(&pointer_list_mtx); 1127 1531 window_t *top = (window_t *) list_first(&window_list); 1128 1532 if (top && top->surface) { … … 1136 1540 within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y, 1137 1541 top->transform, width, height, &point_x, &point_y); 1138 fibril_mutex_unlock(&window_list_mtx); 1139 1542 1543 window_event_t *event = NULL; 1140 1544 if (within_client) { 1141 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));1545 event = (window_event_t *) malloc(sizeof(window_event_t)); 1142 1546 if (event) { 1143 1547 link_initialize(&event->link); … … 1148 1552 event->data.pos.hpos = point_x; 1149 1553 event->data.pos.vpos = point_y; 1150 comp_post_event(event);1151 1554 } 1152 1555 } 1556 1557 fibril_mutex_unlock(&pointer_list_mtx); 1558 fibril_mutex_unlock(&window_list_mtx); 1559 1560 if (event) { 1561 comp_post_event_top(event); 1562 } 1563 1153 1564 } else { 1154 1565 /* Pointer is grabbed by top-level window action. */ 1155 1566 pointer->accum.x += dx; 1156 1567 pointer->accum.y += dy; 1568 pointer->accum_ghost.x += dx; 1569 pointer->accum_ghost.y += dy; 1570 #if ANIMATE_WINDOW_TRANSFORMS == 0 1571 if (pointer->ghost.surface == NULL) { 1572 pointer->ghost.surface = top->surface; 1573 pointer->ghost.dx = top->dx; 1574 pointer->ghost.dy = top->dy; 1575 pointer->ghost.fx = top->fx; 1576 pointer->ghost.fy = top->fy; 1577 pointer->ghost.angle = top->angle; 1578 pointer->ghost.transform = top->transform; 1579 } 1580 desktop_rect_t dmg_rect1, dmg_rect2, dmg_rect3, dmg_rect4; 1581 comp_ghost_animate(pointer, &dmg_rect1, &dmg_rect2, &dmg_rect3, &dmg_rect4); 1582 #endif 1157 1583 #if ANIMATE_WINDOW_TRANSFORMS == 1 1158 1584 sysarg_t x, y, width, height; 1159 1585 comp_window_animate(pointer, top, &x, &y, &width, &height); 1160 1586 #endif 1587 fibril_mutex_unlock(&pointer_list_mtx); 1161 1588 fibril_mutex_unlock(&window_list_mtx); 1589 #if ANIMATE_WINDOW_TRANSFORMS == 0 1590 comp_damage(dmg_rect1.x, dmg_rect1.y, dmg_rect1.w, dmg_rect1.h); 1591 comp_damage(dmg_rect2.x, dmg_rect2.y, dmg_rect2.w, dmg_rect2.h); 1592 comp_damage(dmg_rect3.x, dmg_rect3.y, dmg_rect3.w, dmg_rect3.h); 1593 comp_damage(dmg_rect4.x, dmg_rect4.y, dmg_rect4.w, dmg_rect4.h); 1594 #endif 1162 1595 #if ANIMATE_WINDOW_TRANSFORMS == 1 1163 1596 comp_damage(x, y, width, height); … … 1165 1598 } 1166 1599 } else { 1600 fibril_mutex_unlock(&pointer_list_mtx); 1167 1601 fibril_mutex_unlock(&window_list_mtx); 1168 1602 } … … 1174 1608 { 1175 1609 pointer_t *pointer = input_pointer(input); 1610 1611 fibril_mutex_lock(&window_list_mtx); 1612 fibril_mutex_lock(&pointer_list_mtx); 1613 window_t *win = NULL; 1614 sysarg_t point_x = 0; 1615 sysarg_t point_y = 0; 1616 sysarg_t width, height; 1617 bool within_client = false; 1618 1619 /* Determine the window which the mouse click belongs to. */ 1620 list_foreach(window_list, link, window_t, cw) { 1621 win = cw; 1622 if (win->surface) { 1623 surface_get_resolution(win->surface, &width, &height); 1624 within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y, 1625 win->transform, width, height, &point_x, &point_y); 1626 } 1627 if (within_client) { 1628 break; 1629 } 1630 } 1631 1632 /* Check whether the window is top-level window. */ 1633 window_t *top = (window_t *) list_first(&window_list); 1634 if (!win || !top) { 1635 fibril_mutex_unlock(&pointer_list_mtx); 1636 fibril_mutex_unlock(&window_list_mtx); 1637 return EOK; 1638 } 1639 1640 window_event_t *event_top = NULL; 1641 window_event_t *event_unfocus = NULL; 1642 window_t *win_unfocus = NULL; 1643 sysarg_t dmg_x, dmg_y; 1644 sysarg_t dmg_width = 0; 1645 sysarg_t dmg_height = 0; 1646 1647 #if ANIMATE_WINDOW_TRANSFORMS == 0 1648 desktop_rect_t dmg_rect1, dmg_rect2, dmg_rect3, dmg_rect4; 1649 #endif 1176 1650 1177 1651 if (bpress) { … … 1180 1654 pointer->pressed = true; 1181 1655 1182 /* Check whether mouse press belongs to the top-level window. */ 1183 fibril_mutex_lock(&window_list_mtx); 1184 window_t *win = (window_t *) list_first(&window_list); 1185 if (!win || !win->surface) { 1186 fibril_mutex_unlock(&window_list_mtx); 1187 return EOK; 1188 } 1189 sysarg_t x, y, width, height; 1190 surface_get_resolution(win->surface, &width, &height); 1191 bool within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y, 1192 win->transform, width, height, &x, &y); 1193 fibril_mutex_unlock(&window_list_mtx); 1194 1195 /* Send mouse press to the top-level window. */ 1656 /* Bring the window to the foreground. */ 1657 if ((win != top) && within_client) { 1658 win_unfocus = (window_t *) list_first(&window_list); 1659 list_remove(&win->link); 1660 list_prepend(&win->link, &window_list); 1661 event_unfocus = (window_event_t *) malloc(sizeof(window_event_t)); 1662 if (event_unfocus) { 1663 link_initialize(&event_unfocus->link); 1664 event_unfocus->type = ET_WINDOW_UNFOCUS; 1665 } 1666 comp_coord_bounding_rect(0, 0, width, height, win->transform, 1667 &dmg_x, &dmg_y, &dmg_width, &dmg_height); 1668 } 1669 1670 /* Notify top-level window about mouse press. */ 1196 1671 if (within_client) { 1197 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t)); 1198 if (event) { 1199 link_initialize(&event->link); 1200 event->type = ET_POSITION_EVENT; 1201 event->data.pos.pos_id = pointer->id; 1202 event->data.pos.type = POS_PRESS; 1203 event->data.pos.btn_num = bnum; 1204 event->data.pos.hpos = x; 1205 event->data.pos.vpos = y; 1206 comp_post_event(event); 1207 } else { 1208 return ENOMEM; 1209 } 1210 } 1672 event_top = (window_event_t *) malloc(sizeof(window_event_t)); 1673 if (event_top) { 1674 link_initialize(&event_top->link); 1675 event_top->type = ET_POSITION_EVENT; 1676 event_top->data.pos.pos_id = pointer->id; 1677 event_top->data.pos.type = POS_PRESS; 1678 event_top->data.pos.btn_num = bnum; 1679 event_top->data.pos.hpos = point_x; 1680 event_top->data.pos.vpos = point_y; 1681 } 1682 pointer->grab_flags = GF_EMPTY; 1683 } 1684 1211 1685 } else if (pointer->pressed && pointer->btn_num == (unsigned)bnum) { 1212 1686 pointer->pressed = false; 1213 1687 1214 fibril_mutex_lock(&window_list_mtx); 1215 window_t *win = NULL; 1216 sysarg_t point_x = 0; 1217 sysarg_t point_y = 0; 1218 sysarg_t width, height; 1219 bool within_client = false; 1220 1221 /* Determine the window which the mouse release belongs to. */ 1222 list_foreach(window_list, link) { 1223 win = list_get_instance(link, window_t, link); 1224 if (win->surface) { 1225 surface_get_resolution(win->surface, &width, &height); 1226 within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y, 1227 win->transform, width, height, &point_x, &point_y); 1228 } 1229 if (within_client) { 1230 break; 1231 } 1232 } 1233 1234 /* Check whether the window is top-level window. */ 1235 window_t *top = (window_t *) list_first(&window_list); 1236 if (!win || !top) { 1237 pointer->grab_flags = GF_EMPTY; 1238 fibril_mutex_unlock(&window_list_mtx); 1239 return EOK; 1240 } 1241 1242 window_event_t *event = NULL; 1243 sysarg_t dmg_x, dmg_y; 1244 sysarg_t dmg_width = 0; 1245 sysarg_t dmg_height = 0; 1246 1247 sysarg_t pre_x = 0; 1688 #if ANIMATE_WINDOW_TRANSFORMS == 0 1689 sysarg_t pre_x = 0; 1248 1690 sysarg_t pre_y = 0; 1249 1691 sysarg_t pre_width = 0; 1250 1692 sysarg_t pre_height = 0; 1251 1693 1252 #if ANIMATE_WINDOW_TRANSFORMS == 01253 1694 if (pointer->grab_flags != GF_EMPTY) { 1695 if (pointer->ghost.surface) { 1696 comp_ghost_animate(pointer, &dmg_rect1, &dmg_rect2, &dmg_rect3, &dmg_rect4); 1697 pointer->ghost.surface = NULL; 1698 } 1254 1699 comp_window_animate(pointer, top, &pre_x, &pre_y, &pre_width, &pre_height); 1255 1700 dmg_x = pre_x; … … 1263 1708 1264 1709 surface_get_resolution(top->surface, &width, &height); 1710 #if ANIMATE_WINDOW_TRANSFORMS == 1 1265 1711 top->fx *= (1.0 / scale_back_x); 1266 1712 top->fy *= (1.0 / scale_back_y); 1267 1713 comp_recalc_transform(top); 1714 #endif 1268 1715 1269 1716 /* Commit proper resize action. */ 1270 event = (window_event_t *) malloc(sizeof(window_event_t)); 1271 if (event) { 1272 link_initialize(&event->link); 1273 event->type = ET_WINDOW_RESIZE; 1274 1717 event_top = (window_event_t *) malloc(sizeof(window_event_t)); 1718 if (event_top) { 1719 link_initialize(&event_top->link); 1720 event_top->type = ET_WINDOW_RESIZE; 1721 1722 event_top->data.resize.offset_x = 0; 1723 event_top->data.resize.offset_y = 0; 1724 1275 1725 int dx = (int) (((double) width) * (scale_back_x - 1.0)); 1276 1726 int dy = (int) (((double) height) * (scale_back_y - 1.0)); 1277 1278 if (pointer->grab_flags & GF_RESIZE_X) { 1279 event->data.rsz.width = 1280 ((((int) width) + dx) >= 0) ? (width + dx) : 0; 1281 } else { 1282 event->data.rsz.width = width; 1283 } 1284 1285 if (pointer->grab_flags & GF_RESIZE_Y) { 1286 event->data.rsz.height = 1287 ((((int) height) + dy) >= 0) ? (height + dy) : 0; 1288 } else { 1289 event->data.rsz.height = height; 1290 } 1727 1728 if (pointer->grab_flags & GF_RESIZE_X) 1729 event_top->data.resize.width = 1730 ((((int) width) + dx) >= 0) ? (width + dx) : 0; 1731 else 1732 event_top->data.resize.width = width; 1733 1734 if (pointer->grab_flags & GF_RESIZE_Y) 1735 event_top->data.resize.height = 1736 ((((int) height) + dy) >= 0) ? (height + dy) : 0; 1737 else 1738 event_top->data.resize.height = height; 1739 1740 event_top->data.resize.placement_flags = 1741 WINDOW_PLACEMENT_ANY; 1291 1742 } 1292 1743 … … 1296 1747 1297 1748 /* Notify top-level window about mouse release. */ 1298 event = (window_event_t *) malloc(sizeof(window_event_t));1299 if (event ) {1300 link_initialize(&event ->link);1301 event ->type = ET_POSITION_EVENT;1302 event ->data.pos.pos_id = pointer->id;1303 event ->data.pos.type = POS_RELEASE;1304 event ->data.pos.btn_num = bnum;1305 event ->data.pos.hpos = point_x;1306 event ->data.pos.vpos = point_y;1749 event_top = (window_event_t *) malloc(sizeof(window_event_t)); 1750 if (event_top) { 1751 link_initialize(&event_top->link); 1752 event_top->type = ET_POSITION_EVENT; 1753 event_top->data.pos.pos_id = pointer->id; 1754 event_top->data.pos.type = POS_RELEASE; 1755 event_top->data.pos.btn_num = bnum; 1756 event_top->data.pos.hpos = point_x; 1757 event_top->data.pos.vpos = point_y; 1307 1758 } 1308 1759 pointer->grab_flags = GF_EMPTY; 1309 1310 } else if (within_client && (pointer->grab_flags == GF_EMPTY) && (bnum == 1)) {1311 1312 /* Bring the window to the foreground. */1313 list_remove(&win->link);1314 list_prepend(&win->link, &window_list);1315 comp_coord_bounding_rect(0, 0, width, height, win->transform,1316 &dmg_x, &dmg_y, &dmg_width, &dmg_height);1317 1760 1318 1761 } else { … … 1320 1763 } 1321 1764 1322 fibril_mutex_unlock(&window_list_mtx); 1323 1324 if (dmg_width > 0 && dmg_height > 0) { 1325 comp_damage(dmg_x, dmg_y, dmg_width, dmg_height); 1326 } 1327 1328 if (event) { 1329 comp_post_event(event); 1330 } 1331 } 1332 1765 } 1766 1767 fibril_mutex_unlock(&pointer_list_mtx); 1768 fibril_mutex_unlock(&window_list_mtx); 1769 1770 #if ANIMATE_WINDOW_TRANSFORMS == 0 1771 comp_damage(dmg_rect1.x, dmg_rect1.y, dmg_rect1.w, dmg_rect1.h); 1772 comp_damage(dmg_rect2.x, dmg_rect2.y, dmg_rect2.w, dmg_rect2.h); 1773 comp_damage(dmg_rect3.x, dmg_rect3.y, dmg_rect3.w, dmg_rect3.h); 1774 comp_damage(dmg_rect4.x, dmg_rect4.y, dmg_rect4.w, dmg_rect4.h); 1775 #endif 1776 1777 if (dmg_width > 0 && dmg_height > 0) { 1778 comp_damage(dmg_x, dmg_y, dmg_width, dmg_height); 1779 } 1780 1781 if (event_unfocus && win_unfocus) { 1782 comp_post_event_win(event_unfocus, win_unfocus); 1783 } 1784 1785 if (event_top) { 1786 comp_post_event_top(event_top); 1787 } 1788 1789 return EOK; 1790 } 1791 1792 static int comp_active(input_t *input) 1793 { 1794 active = true; 1795 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 1796 1797 return EOK; 1798 } 1799 1800 static int comp_deactive(input_t *input) 1801 { 1802 active = false; 1333 1803 return EOK; 1334 1804 } … … 1350 1820 bool viewport_change = (mods & KM_ALT) && ( 1351 1821 key == KC_O || key == KC_P); 1352 bool kconsole_switch = ( mods & KM_ALT) && (key == KC_M);1353 bool compositor_test = (mods & KM_ALT) && (key == KC_H);1354 1355 bool filter = (type == KEY_RELEASE) && (win_transform || win_resize ||1822 bool kconsole_switch = (key == KC_PAUSE) || (key == KC_BREAK); 1823 bool filter_switch = (mods & KM_ALT) && (key == KC_Y); 1824 1825 bool key_filter = (type == KEY_RELEASE) && (win_transform || win_resize || 1356 1826 win_opacity || win_close || win_switch || viewport_move || 1357 viewport_change || kconsole_switch || compositor_test);1358 1359 if ( filter) {1827 viewport_change || kconsole_switch || filter_switch); 1828 1829 if (key_filter) { 1360 1830 /* no-op */ 1361 1831 } else if (win_transform) { … … 1377 1847 break; 1378 1848 case KC_Q: 1379 win->angle += (PI / 2);1849 win->angle += 0.1; 1380 1850 break; 1381 1851 case KC_E: 1382 win->angle += -(PI / 2);1852 win->angle -= 0.1; 1383 1853 break; 1384 1854 case KC_R: … … 1421 1891 return ENOMEM; 1422 1892 } 1423 1893 1424 1894 sysarg_t width, height; 1425 1895 surface_get_resolution(win->surface, &width, &height); 1426 1896 1427 1897 link_initialize(&event->link); 1428 1898 event->type = ET_WINDOW_RESIZE; 1429 1899 1900 event->data.resize.offset_x = 0; 1901 event->data.resize.offset_y = 0; 1902 1430 1903 switch (key) { 1431 1904 case KC_T: 1432 event->data.r sz.width = width;1433 event->data.r sz.height = (height >= 20) ? height - 20 : 0;1905 event->data.resize.width = width; 1906 event->data.resize.height = (height >= 20) ? height - 20 : 0; 1434 1907 break; 1435 1908 case KC_G: 1436 event->data.r sz.width = width;1437 event->data.r sz.height = height + 20;1909 event->data.resize.width = width; 1910 event->data.resize.height = height + 20; 1438 1911 break; 1439 1912 case KC_B: 1440 event->data.r sz.width = (width >= 20) ? width - 20 : 0;;1441 event->data.r sz.height = height;1913 event->data.resize.width = (width >= 20) ? width - 20 : 0;; 1914 event->data.resize.height = height; 1442 1915 break; 1443 1916 case KC_N: 1444 event->data.r sz.width = width + 20;1445 event->data.r sz.height = height;1917 event->data.resize.width = width + 20; 1918 event->data.resize.height = height; 1446 1919 break; 1447 1920 default: 1448 event->data.rsz.width = 0; 1449 event->data.rsz.height = 0; 1450 break; 1451 } 1452 1921 event->data.resize.width = 0; 1922 event->data.resize.height = 0; 1923 break; 1924 } 1925 1926 event->data.resize.placement_flags = WINDOW_PLACEMENT_ANY; 1927 1453 1928 fibril_mutex_unlock(&window_list_mtx); 1454 comp_post_event (event);1929 comp_post_event_top(event); 1455 1930 } else { 1456 1931 fibril_mutex_unlock(&window_list_mtx); … … 1494 1969 event->type = ET_WINDOW_CLOSE; 1495 1970 1496 comp_post_event (event);1971 comp_post_event_top(event); 1497 1972 } else if (win_switch) { 1498 1973 fibril_mutex_lock(&window_list_mtx); … … 1502 1977 list_append(&win1->link, &window_list); 1503 1978 window_t *win2 = (window_t *) list_first(&window_list); 1979 1980 window_event_t *event1 = (window_event_t *) malloc(sizeof(window_event_t)); 1981 if (event1) { 1982 link_initialize(&event1->link); 1983 event1->type = ET_WINDOW_UNFOCUS; 1984 } 1985 1986 window_event_t *event2 = (window_event_t *) malloc(sizeof(window_event_t)); 1987 if (event2) { 1988 link_initialize(&event2->link); 1989 event2->type = ET_WINDOW_FOCUS; 1990 } 1504 1991 1505 1992 sysarg_t x1 = 0; … … 1530 2017 1531 2018 fibril_mutex_unlock(&window_list_mtx); 2019 2020 if (event1 && win1) { 2021 comp_post_event_win(event1, win1); 2022 } 2023 2024 if (event2 && win2) { 2025 comp_post_event_win(event2, win2); 2026 } 2027 1532 2028 comp_damage(x, y, width, height); 1533 2029 } else { … … 1567 2063 fibril_mutex_unlock(&viewport_list_mtx); 1568 2064 2065 comp_restrict_pointers(); 1569 2066 comp_damage(x, y, width, height); 1570 2067 } else { … … 1596 2093 fibril_mutex_unlock(&viewport_list_mtx); 1597 2094 } else if (kconsole_switch) { 1598 __SYSCALL0(SYS_DEBUG_ACTIVATE_CONSOLE); 1599 } else if (compositor_test) { 1600 fibril_mutex_lock(&window_list_mtx); 1601 1602 window_t *red_win = window_create(); 1603 red_win->surface = surface_create(250, 150, NULL, 0); 1604 pixel_t red_pix = PIXEL(255, 240, 0, 0); 1605 for (sysarg_t y = 0; y < 150; ++y) { 1606 for (sysarg_t x = 0; x < 250; ++x) { 1607 surface_put_pixel(red_win->surface, x, y, red_pix); 1608 } 1609 } 1610 list_prepend(&red_win->link, &window_list); 1611 1612 window_t *blue_win = window_create(); 1613 blue_win->surface = surface_create(200, 100, NULL, 0); 1614 pixel_t blue_pix = PIXEL(255, 0, 0, 240); 1615 for (sysarg_t y = 0; y < 100; ++y) { 1616 for (sysarg_t x = 0; x < 200; ++x) { 1617 surface_put_pixel(blue_win->surface, x, y, blue_pix); 1618 } 1619 } 1620 list_prepend(&blue_win->link, &window_list); 1621 1622 window_t *helenos_win = window_create(); 1623 helenos_win->surface = decode_tga((void *) helenos_tga, helenos_tga_size, 0); 1624 list_prepend(&helenos_win->link, &window_list); 1625 1626 window_t *nameic_win = window_create(); 1627 nameic_win->surface = decode_tga((void *) nameic_tga, nameic_tga_size, 0); 1628 list_prepend(&nameic_win->link, &window_list); 1629 1630 fibril_mutex_unlock(&window_list_mtx); 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 } 1631 2107 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 1632 2108 } else { … … 1642 2118 event->data.kbd.c = c; 1643 2119 1644 comp_post_event (event);2120 comp_post_event_top(event); 1645 2121 } 1646 2122 … … 1693 2169 static void input_disconnect(void) 1694 2170 { 1695 2171 pointer_t *pointer = input->user; 1696 2172 input_close(input); 1697 2173 pointer_destroy(pointer); 1698 2174 } 1699 2175 1700 static void interrupt_received(ipc_callid_t callid, ipc_call_t *call) 1701 { 1702 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 2176 static void discover_viewports(void) 2177 { 2178 fibril_mutex_lock(&discovery_mtx); 2179 2180 /* Create viewports and connect them to visualizers. */ 2181 category_id_t cat_id; 2182 int rc = loc_category_get_id("visualizer", &cat_id, IPC_FLAG_BLOCKING); 2183 if (rc != EOK) 2184 goto ret; 2185 2186 service_id_t *svcs; 2187 size_t svcs_cnt = 0; 2188 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); 2193 for (size_t i = 0; i < svcs_cnt; ++i) { 2194 bool exists = false; 2195 list_foreach(viewport_list, link, viewport_t, vp) { 2196 if (vp->dsid == svcs[i]) { 2197 exists = true; 2198 break; 2199 } 2200 } 2201 2202 if (exists) 2203 continue; 2204 2205 viewport_t *vp = viewport_create(svcs[i]); 2206 if (vp != NULL) 2207 list_append(&vp->link, &viewport_list); 2208 } 2209 fibril_mutex_unlock(&viewport_list_mtx); 2210 2211 if (!list_empty(&viewport_list)) 2212 input_activate(input); 2213 2214 ret: 2215 fibril_mutex_unlock(&discovery_mtx); 2216 } 2217 2218 static void category_change_cb(void) 2219 { 2220 discover_viewports(); 1703 2221 } 1704 2222 … … 1706 2224 { 1707 2225 /* Coordinates of the central pixel. */ 1708 coord_origin = UINT32_MAX / 2;2226 coord_origin = UINT32_MAX / 4; 1709 2227 1710 2228 /* Color of the viewport background. Must be opaque. */ 1711 bg_color = PIXEL(255, 75, 70, 75);2229 bg_color = PIXEL(255, 69, 51, 103); 1712 2230 1713 2231 /* Register compositor server. */ 1714 2232 async_set_client_connection(client_connection); 2233 1715 2234 int rc = loc_server_register(NAME); 1716 2235 if (rc != EOK) { 1717 2236 printf("%s: Unable to register server (%s)\n", NAME, str_error(rc)); 1718 2237 return -1; 1719 }1720 1721 /* Register interrupt handler to switch back from kconsole. */1722 async_set_interrupt_received(interrupt_received);1723 rc = event_subscribe(EVENT_KCONSOLE, 0);1724 if (rc != EOK) {1725 printf("%s: Failed to register kconsole notifications (%s)\n",1726 NAME, str_error(rc));1727 2238 } 1728 2239 … … 1746 2257 return -1; 1747 2258 } 1748 2259 1749 2260 /* Establish input bidirectional connection. */ 1750 2261 rc = input_connect(input_svc); 1751 if (rc != EOK) 2262 if (rc != EOK) { 2263 printf("%s: Failed to connect to input service.\n", NAME); 1752 2264 return rc; 1753 1754 /* Create viewports and connect them to visualizers. */ 1755 category_id_t cat_id; 1756 rc = loc_category_get_id("visualizer", &cat_id, IPC_FLAG_BLOCKING); 2265 } 2266 2267 rc = loc_register_cat_change_cb(category_change_cb); 1757 2268 if (rc != EOK) { 2269 printf("%s: Failed to register category change callback\n", NAME); 1758 2270 input_disconnect(); 1759 return -1; 1760 } 1761 1762 service_id_t *svcs; 1763 size_t svcs_cnt = 0; 1764 rc = loc_category_get_svcs(cat_id, &svcs, &svcs_cnt); 1765 if (rc != EOK || svcs_cnt == 0) { 1766 input_disconnect(); 1767 return -1; 1768 } 1769 1770 for (size_t i = 0; i < svcs_cnt; ++i) { 1771 char *svc_name; 1772 rc = loc_service_get_name(svcs[i], &svc_name); 1773 if (rc == EOK) { 1774 viewport_t *vp = viewport_create(svc_name); 1775 if (vp != NULL) { 1776 list_append(&vp->link, &viewport_list); 1777 } 1778 } 1779 } 1780 1781 if (list_empty(&viewport_list)) { 1782 input_disconnect(); 1783 return -1; 1784 } 1785 2271 return rc; 2272 } 2273 2274 discover_viewports(); 2275 2276 comp_restrict_pointers(); 1786 2277 comp_damage(0, 0, UINT32_MAX, UINT32_MAX); 1787 2278
Note:
See TracChangeset
for help on using the changeset viewer.