Changeset 563573b in mainline for uspace/srv/hid/compositor/compositor.c
- Timestamp:
- 2012-11-24T17:49:48Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c8e2ac5
- Parents:
- ba733e83
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/compositor/compositor.c
rba733e83 r563573b 90 90 typedef struct { 91 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 107 typedef struct {108 link_t link;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; … … 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 } … … 271 286 sysarg_t y[4]; 272 287 comp_coord_from_client(x_in, y_in, win_trans, &x[0], &y[0]); 273 comp_coord_from_client(x_in + w_in - 1, y_in, win_trans, &x[1], &y[1]);274 comp_coord_from_client(x_in + w_in - 1, y_in + h_in - 1, win_trans, &x[2], &y[2]);275 comp_coord_from_client(x_in, y_in + h_in - 1, win_trans, &x[3], &y[3]);288 comp_coord_from_client(x_in + w_in, y_in, win_trans, &x[1], &y[1]); 289 comp_coord_from_client(x_in + w_in, y_in + h_in, win_trans, &x[2], &y[2]); 290 comp_coord_from_client(x_in, y_in + h_in, win_trans, &x[3], &y[3]); 276 291 (*x_out) = x[0]; 277 292 (*y_out) = y[0]; … … 373 388 list_foreach(pointer_list, link) { 374 389 390 pointer_t *ptr = list_get_instance(link, pointer_t, link); 391 if (ptr->ghost.surface) { 392 393 sysarg_t x_bnd_ghost, y_bnd_ghost, w_bnd_ghost, h_bnd_ghost; 394 sysarg_t x_dmg_ghost, y_dmg_ghost, w_dmg_ghost, h_dmg_ghost; 395 surface_get_resolution(ptr->ghost.surface, &w_bnd_ghost, &h_bnd_ghost); 396 comp_coord_bounding_rect(0, 0, w_bnd_ghost, h_bnd_ghost, ptr->ghost.transform, 397 &x_bnd_ghost, &y_bnd_ghost, &w_bnd_ghost, &h_bnd_ghost); 398 bool isec_ghost = rectangle_intersect( 399 x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp, 400 x_bnd_ghost, y_bnd_ghost, w_bnd_ghost, h_bnd_ghost, 401 &x_dmg_ghost, &y_dmg_ghost, &w_dmg_ghost, &h_dmg_ghost); 402 403 if (isec_ghost) { 404 /* FIXME: Ghost is currently drawn based on the bounding 405 * rectangle of the window, which is sufficient as long 406 * as the windows can be rotated only by 90 degrees. 407 * For ghost to be compatible with arbitrary-angle 408 * rotation, it should be drawn as four lines adjusted 409 * by the transformation matrix. That would however 410 * require to equip libdraw with line drawing functionality. */ 411 412 transform_t transform = ptr->ghost.transform; 413 double_point_t pos; 414 pos.x = vp->pos.x; 415 pos.y = vp->pos.y; 416 transform_translate(&transform, -pos.x, -pos.y); 417 418 pixel_t ghost_color; 419 420 if (y_bnd_ghost == y_dmg_ghost) { 421 for (sysarg_t x = x_dmg_ghost - vp->pos.x; 422 x < x_dmg_ghost - vp->pos.x + w_dmg_ghost; ++x) { 423 ghost_color = surface_get_pixel(vp->surface, 424 x, y_dmg_ghost - vp->pos.y); 425 surface_put_pixel(vp->surface, 426 x, y_dmg_ghost - vp->pos.y, INVERT(ghost_color)); 427 } 428 } 429 430 if (y_bnd_ghost + h_bnd_ghost == y_dmg_ghost + h_dmg_ghost) { 431 for (sysarg_t x = x_dmg_ghost - vp->pos.x; 432 x < x_dmg_ghost - vp->pos.x + w_dmg_ghost; ++x) { 433 ghost_color = surface_get_pixel(vp->surface, 434 x, y_dmg_ghost - vp->pos.y + h_dmg_ghost - 1); 435 surface_put_pixel(vp->surface, 436 x, y_dmg_ghost - vp->pos.y + h_dmg_ghost - 1, INVERT(ghost_color)); 437 } 438 } 439 440 if (x_bnd_ghost == x_dmg_ghost) { 441 for (sysarg_t y = y_dmg_ghost - vp->pos.y; 442 y < y_dmg_ghost - vp->pos.y + h_dmg_ghost; ++y) { 443 ghost_color = surface_get_pixel(vp->surface, 444 x_dmg_ghost - vp->pos.x, y); 445 surface_put_pixel(vp->surface, 446 x_dmg_ghost - vp->pos.x, y, INVERT(ghost_color)); 447 } 448 } 449 450 if (x_bnd_ghost + w_bnd_ghost == x_dmg_ghost + w_dmg_ghost) { 451 for (sysarg_t y = y_dmg_ghost - vp->pos.y; 452 y < y_dmg_ghost - vp->pos.y + h_dmg_ghost; ++y) { 453 ghost_color = surface_get_pixel(vp->surface, 454 x_dmg_ghost - vp->pos.x + w_dmg_ghost - 1, y); 455 surface_put_pixel(vp->surface, 456 x_dmg_ghost - vp->pos.x + w_dmg_ghost - 1, y, INVERT(ghost_color)); 457 } 458 } 459 } 460 461 } 462 } 463 464 list_foreach(pointer_list, link) { 465 375 466 /* Determine what part of the pointer intersects with the 376 467 * updated area of the current viewport. */ … … 409 500 surface_add_damaged_region(vp->surface, x_vp, y_vp, w_dmg_ptr, h_dmg_ptr); 410 501 } 502 411 503 } 412 504 } … … 1007 1099 1008 1100 static void comp_window_animate(pointer_t *pointer, window_t *win, 1009 1101 sysarg_t *dmg_x, sysarg_t *dmg_y, sysarg_t *dmg_width, sysarg_t *dmg_height) 1010 1102 { 1011 1103 /* window_list_mtx locked by caller */ … … 1084 1176 dmg_x, dmg_y, dmg_width, dmg_height); 1085 1177 } 1178 1179 #if ANIMATE_WINDOW_TRANSFORMS == 0 1180 static void comp_ghost_animate(pointer_t *pointer, 1181 desktop_rect_t *rect1, desktop_rect_t *rect2, desktop_rect_t *rect3, desktop_rect_t *rect4) 1182 { 1183 int dx = pointer->accum_ghost.x; 1184 int dy = pointer->accum_ghost.y; 1185 pointer->accum_ghost.x = 0; 1186 pointer->accum_ghost.y = 0; 1187 1188 bool move = (pointer->grab_flags & GF_MOVE_X) || (pointer->grab_flags & GF_MOVE_Y); 1189 bool scale = (pointer->grab_flags & GF_SCALE_X) || (pointer->grab_flags & GF_SCALE_Y); 1190 bool resize = (pointer->grab_flags & GF_RESIZE_X) || (pointer->grab_flags & GF_RESIZE_Y); 1191 1192 sysarg_t width, height; 1193 surface_get_resolution(pointer->ghost.surface, &width, &height); 1194 1195 if (move) { 1196 double cx = 0; 1197 double cy = 0; 1198 if (pointer->grab_flags & GF_MOVE_X) { 1199 cx = 1; 1200 } 1201 if (pointer->grab_flags & GF_MOVE_Y) { 1202 cy = 1; 1203 } 1204 1205 if (scale || resize) { 1206 transform_t rotate; 1207 transform_identity(&rotate); 1208 transform_rotate(&rotate, pointer->ghost.angle); 1209 transform_apply_linear(&rotate, &cx, &cy); 1210 } 1211 1212 cx = (cx < 0) ? (-1 * cx) : cx; 1213 cy = (cy < 0) ? (-1 * cy) : cy; 1214 1215 pointer->ghost.dx += (cx * dx); 1216 pointer->ghost.dy += (cy * dy); 1217 } 1218 1219 if (scale || resize) { 1220 double _dx = dx; 1221 double _dy = dy; 1222 transform_t unrotate; 1223 transform_identity(&unrotate); 1224 transform_rotate(&unrotate, -pointer->ghost.angle); 1225 transform_apply_linear(&unrotate, &_dx, &_dy); 1226 _dx = (pointer->grab_flags & GF_MOVE_X) ? -_dx : _dx; 1227 _dy = (pointer->grab_flags & GF_MOVE_Y) ? -_dy : _dy; 1228 1229 if ((pointer->grab_flags & GF_SCALE_X) || (pointer->grab_flags & GF_RESIZE_X)) { 1230 double fx = 1.0 + (_dx / (width * pointer->ghost.fx)); 1231 pointer->ghost.fx *= fx; 1232 } 1233 1234 if ((pointer->grab_flags & GF_SCALE_Y) || (pointer->grab_flags & GF_RESIZE_Y)) { 1235 double fy = 1.0 + (_dy / (height * pointer->ghost.fy)); 1236 pointer->ghost.fy *= fy; 1237 } 1238 } 1239 1240 sysarg_t x1, y1, width1, height1; 1241 sysarg_t x2, y2, width2, height2; 1242 comp_coord_bounding_rect(0, 0, width, height, pointer->ghost.transform, 1243 &x1, &y1, &width1, &height1); 1244 comp_recalc_transform(&pointer->ghost); 1245 comp_coord_bounding_rect(0, 0, width, height, pointer->ghost.transform, 1246 &x2, &y2, &width2, &height2); 1247 1248 sysarg_t x_u, y_u, w_u, h_u; 1249 rectangle_union(x1, y1, width1, height1, x2, y2, width2, height2, 1250 &x_u, &y_u, &w_u, &h_u); 1251 1252 sysarg_t x_i, y_i, w_i, h_i; 1253 rectangle_intersect(x1, y1, width1, height1, x2, y2, width2, height2, 1254 &x_i, &y_i, &w_i, &h_i); 1255 1256 if (w_i == 0 || h_i == 0) { 1257 rect1->x = x_u; rect2->x = 0; rect3->x = 0; rect4->x = 0; 1258 rect1->y = y_u; rect2->y = 0; rect3->y = 0; rect4->y = 0; 1259 rect1->w = w_u; rect2->w = 0; rect3->w = 0; rect4->w = 0; 1260 rect1->h = h_u; rect2->h = 0; rect3->h = 0; rect4->h = 0; 1261 } else { 1262 rect1->x = x_u; 1263 rect1->y = y_u; 1264 rect1->w = x_i - x_u + 1; 1265 rect1->h = h_u; 1266 1267 rect2->x = x_u; 1268 rect2->y = y_u; 1269 rect2->w = w_u; 1270 rect2->h = y_i - y_u + 1; 1271 1272 rect3->x = x_i + w_i - 1; 1273 rect3->y = y_u; 1274 rect3->w = w_u - w_i - x_i + x_u + 1; 1275 rect3->h = h_u; 1276 1277 rect4->x = x_u; 1278 rect4->y = y_i + h_i - 1; 1279 rect4->w = w_u; 1280 rect4->h = h_u - h_i - y_i + y_u + 1; 1281 } 1282 } 1283 #endif 1086 1284 1087 1285 static int comp_abs_move(input_t *input, unsigned x , unsigned y, … … 1168 1366 pointer->accum.x += dx; 1169 1367 pointer->accum.y += dy; 1368 pointer->accum_ghost.x += dx; 1369 pointer->accum_ghost.y += dy; 1370 #if ANIMATE_WINDOW_TRANSFORMS == 0 1371 if (pointer->ghost.surface == NULL) { 1372 pointer->ghost.surface = top->surface; 1373 pointer->ghost.dx = top->dx; 1374 pointer->ghost.dy = top->dy; 1375 pointer->ghost.fx = top->fx; 1376 pointer->ghost.fy = top->fy; 1377 pointer->ghost.angle = top->angle; 1378 pointer->ghost.transform = top->transform; 1379 } 1380 desktop_rect_t dmg_rect1, dmg_rect2, dmg_rect3, dmg_rect4; 1381 comp_ghost_animate(pointer, &dmg_rect1, &dmg_rect2, &dmg_rect3, &dmg_rect4); 1382 #endif 1170 1383 #if ANIMATE_WINDOW_TRANSFORMS == 1 1171 1384 sysarg_t x, y, width, height; … … 1173 1386 #endif 1174 1387 fibril_mutex_unlock(&window_list_mtx); 1388 #if ANIMATE_WINDOW_TRANSFORMS == 0 1389 comp_damage(dmg_rect1.x, dmg_rect1.y, dmg_rect1.w, dmg_rect1.h); 1390 comp_damage(dmg_rect2.x, dmg_rect2.y, dmg_rect2.w, dmg_rect2.h); 1391 comp_damage(dmg_rect3.x, dmg_rect3.y, dmg_rect3.w, dmg_rect3.h); 1392 comp_damage(dmg_rect4.x, dmg_rect4.y, dmg_rect4.w, dmg_rect4.h); 1393 #endif 1175 1394 #if ANIMATE_WINDOW_TRANSFORMS == 1 1176 1395 comp_damage(x, y, width, height); … … 1219 1438 sysarg_t dmg_width = 0; 1220 1439 sysarg_t dmg_height = 0; 1440 1441 #if ANIMATE_WINDOW_TRANSFORMS == 0 1442 desktop_rect_t dmg_rect1, dmg_rect2, dmg_rect3, dmg_rect4; 1443 #endif 1221 1444 1222 1445 if (bpress) { … … 1251 1474 pointer->pressed = false; 1252 1475 1476 #if ANIMATE_WINDOW_TRANSFORMS == 0 1253 1477 sysarg_t pre_x = 0; 1254 1478 sysarg_t pre_y = 0; … … 1256 1480 sysarg_t pre_height = 0; 1257 1481 1258 #if ANIMATE_WINDOW_TRANSFORMS == 01259 1482 if (pointer->grab_flags != GF_EMPTY) { 1483 if (pointer->ghost.surface) { 1484 comp_ghost_animate(pointer, &dmg_rect1, &dmg_rect2, &dmg_rect3, &dmg_rect4); 1485 pointer->ghost.surface = NULL; 1486 } 1260 1487 comp_window_animate(pointer, top, &pre_x, &pre_y, &pre_width, &pre_height); 1261 1488 dmg_x = pre_x; … … 1321 1548 1322 1549 fibril_mutex_unlock(&window_list_mtx); 1550 1551 #if ANIMATE_WINDOW_TRANSFORMS == 0 1552 comp_damage(dmg_rect1.x, dmg_rect1.y, dmg_rect1.w, dmg_rect1.h); 1553 comp_damage(dmg_rect2.x, dmg_rect2.y, dmg_rect2.w, dmg_rect2.h); 1554 comp_damage(dmg_rect3.x, dmg_rect3.y, dmg_rect3.w, dmg_rect3.h); 1555 comp_damage(dmg_rect4.x, dmg_rect4.y, dmg_rect4.w, dmg_rect4.h); 1556 #endif 1323 1557 1324 1558 if (dmg_width > 0 && dmg_height > 0) { … … 1705 1939 { 1706 1940 /* Coordinates of the central pixel. */ 1707 coord_origin = UINT32_MAX / 2;1941 coord_origin = UINT32_MAX / 4; 1708 1942 1709 1943 /* Color of the viewport background. Must be opaque. */
Note:
See TracChangeset
for help on using the changeset viewer.