Changes in uspace/srv/hid/compositor/compositor.c [d17a4a9:b8f1a349] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/compositor/compositor.c
rd17a4a9 rb8f1a349 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> … … 87 87 static sysarg_t coord_origin; 88 88 static pixel_t bg_color; 89 90 typedef struct {91 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 89 107 90 typedef struct { … … 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; … … 181 183 cursor_init(&p->cursor, CURSOR_DECODER_EMBEDDED, NULL); 182 184 185 /* Ghost window for transformation animation. */ 186 transform_identity(&p->ghost.transform); 187 transform_translate(&p->ghost.transform, coord_origin, coord_origin); 188 p->ghost.dx = coord_origin; 189 p->ghost.dy = coord_origin; 190 p->ghost.fx = 1; 191 p->ghost.fy = 1; 192 p->ghost.angle = 0; 193 p->ghost.opacity = 255; 194 p->ghost.surface = NULL; 195 p->accum_ghost.x = 0; 196 p->accum_ghost.y = 0; 197 183 198 return p; 184 199 } … … 192 207 } 193 208 194 static window_t *window_create( )209 static window_t *window_create(sysarg_t x_offset, sysarg_t y_offset) 195 210 { 196 211 window_t *win = (window_t *) malloc(sizeof(window_t)); … … 202 217 prodcons_initialize(&win->queue); 203 218 transform_identity(&win->transform); 204 transform_translate(&win->transform, coord_origin, coord_origin); 205 win->dx = coord_origin; 206 win->dy = coord_origin; 219 transform_translate(&win->transform, 220 coord_origin + x_offset, coord_origin + y_offset); 221 win->dx = coord_origin + x_offset; 222 win->dy = coord_origin + y_offset; 207 223 win->fx = 1; 208 224 win->fy = 1; … … 250 266 } 251 267 252 static void comp_coord_from_client( sysarg_t x_in, sysarg_ty_in, transform_t win_trans,268 static void comp_coord_from_client(double x_in, double y_in, transform_t win_trans, 253 269 sysarg_t *x_out, sysarg_t *y_out) 254 270 { … … 263 279 } 264 280 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,281 static void comp_coord_bounding_rect(double x_in, double y_in, 282 double w_in, double h_in, transform_t win_trans, 267 283 sysarg_t *x_out, sysarg_t *y_out, sysarg_t *w_out, sysarg_t *h_out) 268 284 { 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); 285 if (w_in > 0 && h_in > 0) { 286 sysarg_t x[4]; 287 sysarg_t y[4]; 288 comp_coord_from_client(x_in, y_in, win_trans, &x[0], &y[0]); 289 comp_coord_from_client(x_in + w_in - 1, y_in, win_trans, &x[1], &y[1]); 290 comp_coord_from_client(x_in + w_in - 1, y_in + h_in - 1, win_trans, &x[2], &y[2]); 291 comp_coord_from_client(x_in, y_in + h_in - 1, win_trans, &x[3], &y[3]); 292 (*x_out) = x[0]; 293 (*y_out) = y[0]; 294 (*w_out) = x[0]; 295 (*h_out) = y[0]; 296 for (int i = 1; i < 4; ++i) { 297 (*x_out) = (x[i] < (*x_out)) ? x[i] : (*x_out); 298 (*y_out) = (y[i] < (*y_out)) ? y[i] : (*y_out); 299 (*w_out) = (x[i] > (*w_out)) ? x[i] : (*w_out); 300 (*h_out) = (y[i] > (*h_out)) ? y[i] : (*h_out); 301 } 302 (*w_out) = (*w_out) - (*x_out) + 1; 303 (*h_out) = (*h_out) - (*y_out) + 1; 304 } else { 305 (*x_out) = 0; 306 (*y_out) = 0; 307 (*w_out) = 0; 308 (*h_out) = 0; 309 } 287 310 } 288 311 … … 309 332 /* Paint background color. */ 310 333 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); 334 pixel_t *dst = pixelmap_pixel_at( 335 surface_pixmap_access(vp->surface), x_dmg_vp - vp->pos.x, y); 336 sysarg_t count = w_dmg_vp; 337 while (count-- != 0) { 338 *dst++ = bg_color; 313 339 } 314 340 } 341 surface_add_damaged_region(vp->surface, 342 x_dmg_vp - vp->pos.x, y_dmg_vp - vp->pos.y, w_dmg_vp, h_dmg_vp); 315 343 316 344 transform_t transform; … … 363 391 list_foreach(pointer_list, link) { 364 392 393 pointer_t *ptr = list_get_instance(link, pointer_t, link); 394 if (ptr->ghost.surface) { 395 396 sysarg_t x_bnd_ghost, y_bnd_ghost, w_bnd_ghost, h_bnd_ghost; 397 sysarg_t x_dmg_ghost, y_dmg_ghost, w_dmg_ghost, h_dmg_ghost; 398 surface_get_resolution(ptr->ghost.surface, &w_bnd_ghost, &h_bnd_ghost); 399 comp_coord_bounding_rect(0, 0, w_bnd_ghost, h_bnd_ghost, ptr->ghost.transform, 400 &x_bnd_ghost, &y_bnd_ghost, &w_bnd_ghost, &h_bnd_ghost); 401 bool isec_ghost = rectangle_intersect( 402 x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp, 403 x_bnd_ghost, y_bnd_ghost, w_bnd_ghost, h_bnd_ghost, 404 &x_dmg_ghost, &y_dmg_ghost, &w_dmg_ghost, &h_dmg_ghost); 405 406 if (isec_ghost) { 407 /* FIXME: Ghost is currently drawn based on the bounding 408 * rectangle of the window, which is sufficient as long 409 * as the windows can be rotated only by 90 degrees. 410 * For ghost to be compatible with arbitrary-angle 411 * rotation, it should be drawn as four lines adjusted 412 * by the transformation matrix. That would however 413 * require to equip libdraw with line drawing functionality. */ 414 415 transform_t transform = ptr->ghost.transform; 416 double_point_t pos; 417 pos.x = vp->pos.x; 418 pos.y = vp->pos.y; 419 transform_translate(&transform, -pos.x, -pos.y); 420 421 pixel_t ghost_color; 422 423 if (y_bnd_ghost == y_dmg_ghost) { 424 for (sysarg_t x = x_dmg_ghost - vp->pos.x; 425 x < x_dmg_ghost - vp->pos.x + w_dmg_ghost; ++x) { 426 ghost_color = surface_get_pixel(vp->surface, 427 x, y_dmg_ghost - vp->pos.y); 428 surface_put_pixel(vp->surface, 429 x, y_dmg_ghost - vp->pos.y, INVERT(ghost_color)); 430 } 431 } 432 433 if (y_bnd_ghost + h_bnd_ghost == y_dmg_ghost + h_dmg_ghost) { 434 for (sysarg_t x = x_dmg_ghost - vp->pos.x; 435 x < x_dmg_ghost - vp->pos.x + w_dmg_ghost; ++x) { 436 ghost_color = surface_get_pixel(vp->surface, 437 x, y_dmg_ghost - vp->pos.y + h_dmg_ghost - 1); 438 surface_put_pixel(vp->surface, 439 x, y_dmg_ghost - vp->pos.y + h_dmg_ghost - 1, INVERT(ghost_color)); 440 } 441 } 442 443 if (x_bnd_ghost == x_dmg_ghost) { 444 for (sysarg_t y = y_dmg_ghost - vp->pos.y; 445 y < y_dmg_ghost - vp->pos.y + h_dmg_ghost; ++y) { 446 ghost_color = surface_get_pixel(vp->surface, 447 x_dmg_ghost - vp->pos.x, y); 448 surface_put_pixel(vp->surface, 449 x_dmg_ghost - vp->pos.x, y, INVERT(ghost_color)); 450 } 451 } 452 453 if (x_bnd_ghost + w_bnd_ghost == x_dmg_ghost + w_dmg_ghost) { 454 for (sysarg_t y = y_dmg_ghost - vp->pos.y; 455 y < y_dmg_ghost - vp->pos.y + h_dmg_ghost; ++y) { 456 ghost_color = surface_get_pixel(vp->surface, 457 x_dmg_ghost - vp->pos.x + w_dmg_ghost - 1, y); 458 surface_put_pixel(vp->surface, 459 x_dmg_ghost - vp->pos.x + w_dmg_ghost - 1, y, INVERT(ghost_color)); 460 } 461 } 462 } 463 464 } 465 } 466 467 list_foreach(pointer_list, link) { 468 365 469 /* Determine what part of the pointer intersects with the 366 470 * updated area of the current viewport. */ … … 376 480 if (isec_ptr) { 377 481 /* Pointer is currently painted directly by copying pixels. 378 * However, it is possible to draw the p ainter similarly482 * However, it is possible to draw the pointer similarly 379 483 * as window by using drawctx_transfer. It would allow 380 484 * more sophisticated control over drawing, but would also 381 485 * cost more regarding the performance. */ 382 486 383 pixel_t pix = 0;384 487 sysarg_t x_vp = x_dmg_ptr - vp->pos.x; 385 488 sysarg_t y_vp = y_dmg_ptr - vp->pos.y; … … 388 491 389 492 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 } 493 pixel_t *src = pixelmap_pixel_at( 494 surface_pixmap_access(sf_ptr), x_ptr, y_ptr + y); 495 pixel_t *dst = pixelmap_pixel_at( 496 surface_pixmap_access(vp->surface), x_vp, y_vp + y); 497 sysarg_t count = w_dmg_ptr; 498 while (count-- != 0) { 499 *dst = (*src & 0xff000000) ? *src : *dst; 500 ++dst; ++src; 395 501 } 396 502 } 503 surface_add_damaged_region(vp->surface, x_vp, y_vp, w_dmg_ptr, h_dmg_ptr); 397 504 } 505 398 506 } 399 507 } … … 441 549 static void comp_window_damage(window_t *win, ipc_callid_t iid, ipc_call_t *icall) 442 550 { 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);551 double x = IPC_GET_ARG1(*icall); 552 double y = IPC_GET_ARG2(*icall); 553 double width = IPC_GET_ARG3(*icall); 554 double height = IPC_GET_ARG4(*icall); 447 555 448 556 if (width == 0 || height == 0) { … … 450 558 } else { 451 559 fibril_mutex_lock(&window_list_mtx); 452 comp_coord_bounding_rect(x, y, width, height, 453 win->transform, &x, &y, &width, &height); 560 sysarg_t x_dmg_glob, y_dmg_glob, w_dmg_glob, h_dmg_glob; 561 comp_coord_bounding_rect(x - 1, y - 1, width + 2, height + 2, 562 win->transform, &x_dmg_glob, &y_dmg_glob, &w_dmg_glob, &h_dmg_glob); 454 563 fibril_mutex_unlock(&window_list_mtx); 455 comp_damage(x , y, width, height);564 comp_damage(x_dmg_glob, y_dmg_glob, w_dmg_glob, h_dmg_glob); 456 565 } 457 566 … … 468 577 pointer_t *pointer = list_get_instance(link, pointer_t, link); 469 578 if (pointer->id == pos_id) { 470 pointer->grab_flags = grab_flags;579 pointer->grab_flags = pointer->pressed ? grab_flags : GF_EMPTY; 471 580 // TODO change pointer->state according to grab_flags 472 581 break; … … 541 650 } 542 651 652 static void comp_post_event_win(window_event_t *event, window_t *target) 653 { 654 fibril_mutex_lock(&window_list_mtx); 655 window_t *window = NULL; 656 list_foreach(window_list, link) { 657 window = list_get_instance(link, window_t, link); 658 if (window == target) { 659 prodcons_produce(&window->queue, &event->link); 660 } 661 } 662 if (!window) { 663 free(event); 664 } 665 fibril_mutex_unlock(&window_list_mtx); 666 } 667 668 static void comp_post_event_top(window_event_t *event) 669 { 670 fibril_mutex_lock(&window_list_mtx); 671 window_t *win = (window_t *) list_first(&window_list); 672 if (win) { 673 prodcons_produce(&win->queue, &event->link); 674 } else { 675 free(event); 676 } 677 fibril_mutex_unlock(&window_list_mtx); 678 } 679 543 680 static void comp_window_close(window_t *win, ipc_callid_t iid, ipc_call_t *icall) 544 681 { … … 546 683 fibril_mutex_lock(&window_list_mtx); 547 684 list_remove(&win->link); 685 window_t *win_focus = (window_t *) list_first(&window_list); 686 window_event_t *event_focus = (window_event_t *) malloc(sizeof(window_event_t)); 687 if (event_focus) { 688 link_initialize(&event_focus->link); 689 event_focus->type = ET_WINDOW_FOCUS; 690 } 548 691 fibril_mutex_unlock(&window_list_mtx); 692 693 if (event_focus && win_focus) { 694 comp_post_event_win(event_focus, win_focus); 695 } 549 696 550 697 /* Calculate damage. */ … … 601 748 fibril_mutex_lock(&window_list_mtx); 602 749 603 window_t *win = window_create( );750 window_t *win = window_create(IPC_GET_ARG1(call), IPC_GET_ARG2(call)); 604 751 if (!win) { 605 752 async_answer_2(callid, ENOMEM, 0, 0); … … 630 777 } 631 778 779 window_t *win_unfocus = (window_t *) list_first(&window_list); 632 780 list_prepend(&win->link, &window_list); 781 782 window_event_t *event_unfocus = (window_event_t *) malloc(sizeof(window_event_t)); 783 if (event_unfocus) { 784 link_initialize(&event_unfocus->link); 785 event_unfocus->type = ET_WINDOW_UNFOCUS; 786 } 633 787 634 788 async_answer_2(callid, EOK, win->in_dsid, win->out_dsid); 635 789 fibril_mutex_unlock(&window_list_mtx); 790 791 if (event_unfocus && win_unfocus) { 792 comp_post_event_win(event_unfocus, win_unfocus); 793 } 794 636 795 return; 637 796 } else { … … 953 1112 } 954 1113 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 1114 static void comp_recalc_transform(window_t *win) 968 1115 { … … 973 1120 transform_t scale; 974 1121 transform_identity(&scale); 975 transform_scale(&scale, win->fx, win->fy); 1122 if (win->fx != 1 || win->fy != 1) { 1123 transform_scale(&scale, win->fx, win->fy); 1124 } 976 1125 977 1126 transform_t rotate; 978 1127 transform_identity(&rotate); 979 transform_rotate(&rotate, win->angle); 1128 if (win->angle != 0) { 1129 transform_rotate(&rotate, win->angle); 1130 } 980 1131 981 1132 transform_t transform; … … 994 1145 995 1146 static void comp_window_animate(pointer_t *pointer, window_t *win, 996 1147 sysarg_t *dmg_x, sysarg_t *dmg_y, sysarg_t *dmg_width, sysarg_t *dmg_height) 997 1148 { 998 1149 /* window_list_mtx locked by caller */ 1150 /* pointer_list_mtx locked by caller */ 999 1151 1000 1152 int dx = pointer->accum.x; … … 1020 1172 } 1021 1173 1022 if ( scale || resize) {1174 if ((scale || resize) && (win->angle != 0)) { 1023 1175 transform_t rotate; 1024 1176 transform_identity(&rotate); … … 1037 1189 double _dx = dx; 1038 1190 double _dy = dy; 1039 transform_t unrotate; 1040 transform_identity(&unrotate); 1041 transform_rotate(&unrotate, -win->angle); 1042 transform_apply_linear(&unrotate, &_dx, &_dy); 1191 if (win->angle != 0) { 1192 transform_t unrotate; 1193 transform_identity(&unrotate); 1194 transform_rotate(&unrotate, -win->angle); 1195 transform_apply_linear(&unrotate, &_dx, &_dy); 1196 } 1043 1197 _dx = (pointer->grab_flags & GF_MOVE_X) ? -_dx : _dx; 1044 1198 _dy = (pointer->grab_flags & GF_MOVE_Y) ? -_dy : _dy; 1045 1199 1046 1200 if ((pointer->grab_flags & GF_SCALE_X) || (pointer->grab_flags & GF_RESIZE_X)) { 1047 double fx = 1.0 + (_dx / ( width* win->fx));1201 double fx = 1.0 + (_dx / ((width - 1) * win->fx)); 1048 1202 if (fx > 0) { 1203 #if ANIMATE_WINDOW_TRANSFORMS == 0 1204 if (scale) win->fx *= fx; 1205 #endif 1206 #if ANIMATE_WINDOW_TRANSFORMS == 1 1049 1207 win->fx *= fx; 1208 #endif 1050 1209 scale_back_x *= fx; 1051 1210 } … … 1053 1212 1054 1213 if ((pointer->grab_flags & GF_SCALE_Y) || (pointer->grab_flags & GF_RESIZE_Y)) { 1055 double fy = 1.0 + (_dy / ( height* win->fy));1214 double fy = 1.0 + (_dy / ((height - 1) * win->fy)); 1056 1215 if (fy > 0) { 1216 #if ANIMATE_WINDOW_TRANSFORMS == 0 1217 if (scale) win->fy *= fy; 1218 #endif 1219 #if ANIMATE_WINDOW_TRANSFORMS == 1 1057 1220 win->fy *= fy; 1221 #endif 1058 1222 scale_back_y *= fy; 1059 1223 } … … 1071 1235 dmg_x, dmg_y, dmg_width, dmg_height); 1072 1236 } 1237 1238 #if ANIMATE_WINDOW_TRANSFORMS == 0 1239 static void comp_ghost_animate(pointer_t *pointer, 1240 desktop_rect_t *rect1, desktop_rect_t *rect2, desktop_rect_t *rect3, desktop_rect_t *rect4) 1241 { 1242 /* window_list_mtx locked by caller */ 1243 /* pointer_list_mtx locked by caller */ 1244 1245 int dx = pointer->accum_ghost.x; 1246 int dy = pointer->accum_ghost.y; 1247 pointer->accum_ghost.x = 0; 1248 pointer->accum_ghost.y = 0; 1249 1250 bool move = (pointer->grab_flags & GF_MOVE_X) || (pointer->grab_flags & GF_MOVE_Y); 1251 bool scale = (pointer->grab_flags & GF_SCALE_X) || (pointer->grab_flags & GF_SCALE_Y); 1252 bool resize = (pointer->grab_flags & GF_RESIZE_X) || (pointer->grab_flags & GF_RESIZE_Y); 1253 1254 sysarg_t width, height; 1255 surface_get_resolution(pointer->ghost.surface, &width, &height); 1256 1257 if (move) { 1258 double cx = 0; 1259 double cy = 0; 1260 if (pointer->grab_flags & GF_MOVE_X) { 1261 cx = 1; 1262 } 1263 if (pointer->grab_flags & GF_MOVE_Y) { 1264 cy = 1; 1265 } 1266 1267 if (scale || resize) { 1268 transform_t rotate; 1269 transform_identity(&rotate); 1270 transform_rotate(&rotate, pointer->ghost.angle); 1271 transform_apply_linear(&rotate, &cx, &cy); 1272 } 1273 1274 cx = (cx < 0) ? (-1 * cx) : cx; 1275 cy = (cy < 0) ? (-1 * cy) : cy; 1276 1277 pointer->ghost.dx += (cx * dx); 1278 pointer->ghost.dy += (cy * dy); 1279 } 1280 1281 if (scale || resize) { 1282 double _dx = dx; 1283 double _dy = dy; 1284 transform_t unrotate; 1285 transform_identity(&unrotate); 1286 transform_rotate(&unrotate, -pointer->ghost.angle); 1287 transform_apply_linear(&unrotate, &_dx, &_dy); 1288 _dx = (pointer->grab_flags & GF_MOVE_X) ? -_dx : _dx; 1289 _dy = (pointer->grab_flags & GF_MOVE_Y) ? -_dy : _dy; 1290 1291 if ((pointer->grab_flags & GF_SCALE_X) || (pointer->grab_flags & GF_RESIZE_X)) { 1292 double fx = 1.0 + (_dx / ((width - 1) * pointer->ghost.fx)); 1293 pointer->ghost.fx *= fx; 1294 } 1295 1296 if ((pointer->grab_flags & GF_SCALE_Y) || (pointer->grab_flags & GF_RESIZE_Y)) { 1297 double fy = 1.0 + (_dy / ((height - 1) * pointer->ghost.fy)); 1298 pointer->ghost.fy *= fy; 1299 } 1300 } 1301 1302 sysarg_t x1, y1, width1, height1; 1303 sysarg_t x2, y2, width2, height2; 1304 comp_coord_bounding_rect(0, 0, width, height, pointer->ghost.transform, 1305 &x1, &y1, &width1, &height1); 1306 comp_recalc_transform(&pointer->ghost); 1307 comp_coord_bounding_rect(0, 0, width, height, pointer->ghost.transform, 1308 &x2, &y2, &width2, &height2); 1309 1310 sysarg_t x_u, y_u, w_u, h_u; 1311 rectangle_union(x1, y1, width1, height1, x2, y2, width2, height2, 1312 &x_u, &y_u, &w_u, &h_u); 1313 1314 sysarg_t x_i, y_i, w_i, h_i; 1315 rectangle_intersect(x1, y1, width1, height1, x2, y2, width2, height2, 1316 &x_i, &y_i, &w_i, &h_i); 1317 1318 if (w_i == 0 || h_i == 0) { 1319 rect1->x = x_u; rect2->x = 0; rect3->x = 0; rect4->x = 0; 1320 rect1->y = y_u; rect2->y = 0; rect3->y = 0; rect4->y = 0; 1321 rect1->w = w_u; rect2->w = 0; rect3->w = 0; rect4->w = 0; 1322 rect1->h = h_u; rect2->h = 0; rect3->h = 0; rect4->h = 0; 1323 } else { 1324 rect1->x = x_u; 1325 rect1->y = y_u; 1326 rect1->w = x_i - x_u + 1; 1327 rect1->h = h_u; 1328 1329 rect2->x = x_u; 1330 rect2->y = y_u; 1331 rect2->w = w_u; 1332 rect2->h = y_i - y_u + 1; 1333 1334 rect3->x = x_i + w_i - 1; 1335 rect3->y = y_u; 1336 rect3->w = w_u - w_i - x_i + x_u + 1; 1337 rect3->h = h_u; 1338 1339 rect4->x = x_u; 1340 rect4->y = y_i + h_i - 1; 1341 rect4->w = w_u; 1342 rect4->h = h_u - h_i - y_i + y_u + 1; 1343 } 1344 } 1345 #endif 1073 1346 1074 1347 static int comp_abs_move(input_t *input, unsigned x , unsigned y, … … 1125 1398 1126 1399 fibril_mutex_lock(&window_list_mtx); 1400 fibril_mutex_lock(&pointer_list_mtx); 1127 1401 window_t *top = (window_t *) list_first(&window_list); 1128 1402 if (top && top->surface) { … … 1136 1410 within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y, 1137 1411 top->transform, width, height, &point_x, &point_y); 1138 fibril_mutex_unlock(&window_list_mtx); 1139 1412 1413 window_event_t *event = NULL; 1140 1414 if (within_client) { 1141 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));1415 event = (window_event_t *) malloc(sizeof(window_event_t)); 1142 1416 if (event) { 1143 1417 link_initialize(&event->link); … … 1148 1422 event->data.pos.hpos = point_x; 1149 1423 event->data.pos.vpos = point_y; 1150 comp_post_event(event);1151 1424 } 1152 1425 } 1426 1427 fibril_mutex_unlock(&pointer_list_mtx); 1428 fibril_mutex_unlock(&window_list_mtx); 1429 1430 if (event) { 1431 comp_post_event_top(event); 1432 } 1433 1153 1434 } else { 1154 1435 /* Pointer is grabbed by top-level window action. */ 1155 1436 pointer->accum.x += dx; 1156 1437 pointer->accum.y += dy; 1438 pointer->accum_ghost.x += dx; 1439 pointer->accum_ghost.y += dy; 1440 #if ANIMATE_WINDOW_TRANSFORMS == 0 1441 if (pointer->ghost.surface == NULL) { 1442 pointer->ghost.surface = top->surface; 1443 pointer->ghost.dx = top->dx; 1444 pointer->ghost.dy = top->dy; 1445 pointer->ghost.fx = top->fx; 1446 pointer->ghost.fy = top->fy; 1447 pointer->ghost.angle = top->angle; 1448 pointer->ghost.transform = top->transform; 1449 } 1450 desktop_rect_t dmg_rect1, dmg_rect2, dmg_rect3, dmg_rect4; 1451 comp_ghost_animate(pointer, &dmg_rect1, &dmg_rect2, &dmg_rect3, &dmg_rect4); 1452 #endif 1157 1453 #if ANIMATE_WINDOW_TRANSFORMS == 1 1158 1454 sysarg_t x, y, width, height; 1159 1455 comp_window_animate(pointer, top, &x, &y, &width, &height); 1160 1456 #endif 1457 fibril_mutex_unlock(&pointer_list_mtx); 1161 1458 fibril_mutex_unlock(&window_list_mtx); 1459 #if ANIMATE_WINDOW_TRANSFORMS == 0 1460 comp_damage(dmg_rect1.x, dmg_rect1.y, dmg_rect1.w, dmg_rect1.h); 1461 comp_damage(dmg_rect2.x, dmg_rect2.y, dmg_rect2.w, dmg_rect2.h); 1462 comp_damage(dmg_rect3.x, dmg_rect3.y, dmg_rect3.w, dmg_rect3.h); 1463 comp_damage(dmg_rect4.x, dmg_rect4.y, dmg_rect4.w, dmg_rect4.h); 1464 #endif 1162 1465 #if ANIMATE_WINDOW_TRANSFORMS == 1 1163 1466 comp_damage(x, y, width, height); … … 1165 1468 } 1166 1469 } else { 1470 fibril_mutex_unlock(&pointer_list_mtx); 1167 1471 fibril_mutex_unlock(&window_list_mtx); 1168 1472 } … … 1174 1478 { 1175 1479 pointer_t *pointer = input_pointer(input); 1480 1481 fibril_mutex_lock(&window_list_mtx); 1482 fibril_mutex_lock(&pointer_list_mtx); 1483 window_t *win = NULL; 1484 sysarg_t point_x = 0; 1485 sysarg_t point_y = 0; 1486 sysarg_t width, height; 1487 bool within_client = false; 1488 1489 /* Determine the window which the mouse click belongs to. */ 1490 list_foreach(window_list, link) { 1491 win = list_get_instance(link, window_t, link); 1492 if (win->surface) { 1493 surface_get_resolution(win->surface, &width, &height); 1494 within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y, 1495 win->transform, width, height, &point_x, &point_y); 1496 } 1497 if (within_client) { 1498 break; 1499 } 1500 } 1501 1502 /* Check whether the window is top-level window. */ 1503 window_t *top = (window_t *) list_first(&window_list); 1504 if (!win || !top) { 1505 fibril_mutex_unlock(&pointer_list_mtx); 1506 fibril_mutex_unlock(&window_list_mtx); 1507 return EOK; 1508 } 1509 1510 window_event_t *event_top = NULL; 1511 window_event_t *event_unfocus = NULL; 1512 window_t *win_unfocus = NULL; 1513 sysarg_t dmg_x, dmg_y; 1514 sysarg_t dmg_width = 0; 1515 sysarg_t dmg_height = 0; 1516 1517 #if ANIMATE_WINDOW_TRANSFORMS == 0 1518 desktop_rect_t dmg_rect1, dmg_rect2, dmg_rect3, dmg_rect4; 1519 #endif 1176 1520 1177 1521 if (bpress) { … … 1180 1524 pointer->pressed = true; 1181 1525 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. */ 1526 /* Bring the window to the foreground. */ 1527 if ((win != top) && within_client) { 1528 win_unfocus = (window_t *) list_first(&window_list); 1529 list_remove(&win->link); 1530 list_prepend(&win->link, &window_list); 1531 event_unfocus = (window_event_t *) malloc(sizeof(window_event_t)); 1532 if (event_unfocus) { 1533 link_initialize(&event_unfocus->link); 1534 event_unfocus->type = ET_WINDOW_UNFOCUS; 1535 } 1536 comp_coord_bounding_rect(0, 0, width, height, win->transform, 1537 &dmg_x, &dmg_y, &dmg_width, &dmg_height); 1538 } 1539 1540 /* Notify top-level window about mouse press. */ 1196 1541 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 } 1542 event_top = (window_event_t *) malloc(sizeof(window_event_t)); 1543 if (event_top) { 1544 link_initialize(&event_top->link); 1545 event_top->type = ET_POSITION_EVENT; 1546 event_top->data.pos.pos_id = pointer->id; 1547 event_top->data.pos.type = POS_PRESS; 1548 event_top->data.pos.btn_num = bnum; 1549 event_top->data.pos.hpos = point_x; 1550 event_top->data.pos.vpos = point_y; 1551 } 1552 pointer->grab_flags = GF_EMPTY; 1553 } 1554 1211 1555 } else if (pointer->pressed && pointer->btn_num == (unsigned)bnum) { 1212 1556 pointer->pressed = false; 1213 1557 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 1558 #if ANIMATE_WINDOW_TRANSFORMS == 0 1247 1559 sysarg_t pre_x = 0; 1248 1560 sysarg_t pre_y = 0; … … 1250 1562 sysarg_t pre_height = 0; 1251 1563 1252 #if ANIMATE_WINDOW_TRANSFORMS == 01253 1564 if (pointer->grab_flags != GF_EMPTY) { 1565 if (pointer->ghost.surface) { 1566 comp_ghost_animate(pointer, &dmg_rect1, &dmg_rect2, &dmg_rect3, &dmg_rect4); 1567 pointer->ghost.surface = NULL; 1568 } 1254 1569 comp_window_animate(pointer, top, &pre_x, &pre_y, &pre_width, &pre_height); 1255 1570 dmg_x = pre_x; … … 1263 1578 1264 1579 surface_get_resolution(top->surface, &width, &height); 1580 #if ANIMATE_WINDOW_TRANSFORMS == 1 1265 1581 top->fx *= (1.0 / scale_back_x); 1266 1582 top->fy *= (1.0 / scale_back_y); 1267 1583 comp_recalc_transform(top); 1584 #endif 1268 1585 1269 1586 /* 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;1587 event_top = (window_event_t *) malloc(sizeof(window_event_t)); 1588 if (event_top) { 1589 link_initialize(&event_top->link); 1590 event_top->type = ET_WINDOW_RESIZE; 1274 1591 1275 1592 int dx = (int) (((double) width) * (scale_back_x - 1.0)); … … 1277 1594 1278 1595 if (pointer->grab_flags & GF_RESIZE_X) { 1279 event ->data.rsz.width =1596 event_top->data.rsz.width = 1280 1597 ((((int) width) + dx) >= 0) ? (width + dx) : 0; 1281 1598 } else { 1282 event ->data.rsz.width = width;1599 event_top->data.rsz.width = width; 1283 1600 } 1284 1601 1285 1602 if (pointer->grab_flags & GF_RESIZE_Y) { 1286 event ->data.rsz.height =1603 event_top->data.rsz.height = 1287 1604 ((((int) height) + dy) >= 0) ? (height + dy) : 0; 1288 1605 } else { 1289 event ->data.rsz.height = height;1606 event_top->data.rsz.height = height; 1290 1607 } 1291 1608 } … … 1296 1613 1297 1614 /* 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;1615 event_top = (window_event_t *) malloc(sizeof(window_event_t)); 1616 if (event_top) { 1617 link_initialize(&event_top->link); 1618 event_top->type = ET_POSITION_EVENT; 1619 event_top->data.pos.pos_id = pointer->id; 1620 event_top->data.pos.type = POS_RELEASE; 1621 event_top->data.pos.btn_num = bnum; 1622 event_top->data.pos.hpos = point_x; 1623 event_top->data.pos.vpos = point_y; 1307 1624 } 1308 1625 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 1626 1318 1627 } else { … … 1320 1629 } 1321 1630 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 } 1631 } 1632 1633 fibril_mutex_unlock(&pointer_list_mtx); 1634 fibril_mutex_unlock(&window_list_mtx); 1635 1636 #if ANIMATE_WINDOW_TRANSFORMS == 0 1637 comp_damage(dmg_rect1.x, dmg_rect1.y, dmg_rect1.w, dmg_rect1.h); 1638 comp_damage(dmg_rect2.x, dmg_rect2.y, dmg_rect2.w, dmg_rect2.h); 1639 comp_damage(dmg_rect3.x, dmg_rect3.y, dmg_rect3.w, dmg_rect3.h); 1640 comp_damage(dmg_rect4.x, dmg_rect4.y, dmg_rect4.w, dmg_rect4.h); 1641 #endif 1642 1643 if (dmg_width > 0 && dmg_height > 0) { 1644 comp_damage(dmg_x, dmg_y, dmg_width, dmg_height); 1645 } 1646 1647 if (event_unfocus && win_unfocus) { 1648 comp_post_event_win(event_unfocus, win_unfocus); 1649 } 1650 1651 if (event_top) { 1652 comp_post_event_top(event_top); 1331 1653 } 1332 1654 … … 1452 1774 1453 1775 fibril_mutex_unlock(&window_list_mtx); 1454 comp_post_event (event);1776 comp_post_event_top(event); 1455 1777 } else { 1456 1778 fibril_mutex_unlock(&window_list_mtx); … … 1494 1816 event->type = ET_WINDOW_CLOSE; 1495 1817 1496 comp_post_event (event);1818 comp_post_event_top(event); 1497 1819 } else if (win_switch) { 1498 1820 fibril_mutex_lock(&window_list_mtx); … … 1502 1824 list_append(&win1->link, &window_list); 1503 1825 window_t *win2 = (window_t *) list_first(&window_list); 1826 1827 window_event_t *event1 = (window_event_t *) malloc(sizeof(window_event_t)); 1828 if (event1) { 1829 link_initialize(&event1->link); 1830 event1->type = ET_WINDOW_UNFOCUS; 1831 } 1832 1833 window_event_t *event2 = (window_event_t *) malloc(sizeof(window_event_t)); 1834 if (event2) { 1835 link_initialize(&event2->link); 1836 event2->type = ET_WINDOW_FOCUS; 1837 } 1504 1838 1505 1839 sysarg_t x1 = 0; … … 1530 1864 1531 1865 fibril_mutex_unlock(&window_list_mtx); 1866 1867 if (event1 && win1) { 1868 comp_post_event_win(event1, win1); 1869 } 1870 1871 if (event2 && win2) { 1872 comp_post_event_win(event2, win2); 1873 } 1874 1532 1875 comp_damage(x, y, width, height); 1533 1876 } else { … … 1600 1943 fibril_mutex_lock(&window_list_mtx); 1601 1944 1602 window_t *red_win = window_create( );1945 window_t *red_win = window_create(0, 0); 1603 1946 red_win->surface = surface_create(250, 150, NULL, 0); 1604 1947 pixel_t red_pix = PIXEL(255, 240, 0, 0); … … 1610 1953 list_prepend(&red_win->link, &window_list); 1611 1954 1612 window_t *blue_win = window_create( );1955 window_t *blue_win = window_create(0, 0); 1613 1956 blue_win->surface = surface_create(200, 100, NULL, 0); 1614 1957 pixel_t blue_pix = PIXEL(255, 0, 0, 240); … … 1619 1962 } 1620 1963 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(); 1964 1965 window_t *nameic_win = window_create(0, 0); 1627 1966 nameic_win->surface = decode_tga((void *) nameic_tga, nameic_tga_size, 0); 1628 1967 list_prepend(&nameic_win->link, &window_list); … … 1642 1981 event->data.kbd.c = c; 1643 1982 1644 comp_post_event (event);1983 comp_post_event_top(event); 1645 1984 } 1646 1985 … … 1693 2032 static void input_disconnect(void) 1694 2033 { 1695 2034 pointer_t *pointer = input->user; 1696 2035 input_close(input); 1697 2036 pointer_destroy(pointer); … … 1706 2045 { 1707 2046 /* Coordinates of the central pixel. */ 1708 coord_origin = UINT32_MAX / 2;2047 coord_origin = UINT32_MAX / 4; 1709 2048 1710 2049 /* Color of the viewport background. Must be opaque. */
Note:
See TracChangeset
for help on using the changeset viewer.