57
57
StubKMSOutputContainer()
59
{10, std::make_shared<testing::NiceMock<MockKMSOutput>>()},
60
{11, std::make_shared<testing::NiceMock<MockKMSOutput>>()},
61
{12, std::make_shared<testing::NiceMock<MockKMSOutput>>()}}
59
std::make_shared<testing::NiceMock<MockKMSOutput>>(),
60
std::make_shared<testing::NiceMock<MockKMSOutput>>(),
61
std::make_shared<testing::NiceMock<MockKMSOutput>>()}
63
63
// These need to be established before Cursor construction:
64
for (auto& entry : outputs)
64
for (auto& output : outputs)
66
auto& out = *entry.second;
67
67
ON_CALL(out, has_cursor())
68
68
.WillByDefault(Return(true));
69
ON_CALL(out, set_cursor(_))
70
.WillByDefault(Return(true));
71
ON_CALL(out, clear_cursor())
72
.WillByDefault(Return(true));
72
std::shared_ptr<mgm::KMSOutput> get_kms_output_for(uint32_t connector_id)
74
return outputs[connector_id];
77
void for_each_output(std::function<void(mgm::KMSOutput&)> functor) const
79
for (auto const& pair : outputs)
80
functor(*pair.second);
76
void for_each_output(std::function<void(std::shared_ptr<mgm::KMSOutput> const&)> functor) const
78
for (auto const& output : outputs)
83
82
void verify_and_clear_expectations()
85
for (auto const& pair : outputs)
86
::testing::Mock::VerifyAndClearExpectations(pair.second.get());
89
std::unordered_map<uint32_t,std::shared_ptr<testing::NiceMock<MockKMSOutput>>> outputs;
84
for (auto const& output : outputs)
85
::testing::Mock::VerifyAndClearExpectations(output.get());
88
void update_from_hardware_state()
92
std::vector<std::shared_ptr<testing::NiceMock<MockKMSOutput>>> outputs;
92
95
struct StubKMSDisplayConfiguration : public mgm::KMSDisplayConfiguration
94
StubKMSDisplayConfiguration()
97
StubKMSDisplayConfiguration(mgm::KMSOutputContainer& container)
95
98
: mgm::KMSDisplayConfiguration(),
98
mg::DisplayConfigurationOutputId{10},
102
mg::DisplayConfigurationOutputId{0},
99
103
mg::DisplayConfigurationCardId{},
100
104
mg::DisplayConfigurationOutputType::vga,
234
mgm::KMSOutputContainer& container;
224
235
mtd::StubDisplayConfig stub_config;
236
std::vector<std::shared_ptr<mgm::KMSOutput>> outputs;
227
239
struct StubCurrentConfiguration : public mgm::CurrentConfiguration
241
StubCurrentConfiguration(mgm::KMSOutputContainer& container)
229
246
void with_current_configuration_do(
230
247
std::function<void(mgm::KMSDisplayConfiguration const&)> const& exec)
281
298
size_t const cursor_side{64};
283
300
: cursor{mock_gbm.fake_gbm.device, output_container,
284
mt::fake_shared(current_configuration),
285
mt::fake_shared(stub_image)}
301
mt::fake_shared(current_configuration)}
287
303
using namespace ::testing;
288
304
ON_CALL(mock_drm, drmGetCap(_, DRM_CAP_CURSOR_WIDTH, _))
333
349
GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE));
335
351
mgm::Cursor cursor_tmp{mock_gbm.fake_gbm.device, output_container,
336
std::make_shared<StubCurrentConfiguration>(),
337
std::make_shared<StubCursorImage>()};
352
std::make_shared<StubCurrentConfiguration>(output_container)};
340
355
TEST_F(MesaCursorTest, queries_received_cursor_size)
345
360
EXPECT_CALL(mock_gbm, gbm_bo_get_height(_));
347
362
mgm::Cursor cursor_tmp{mock_gbm.fake_gbm.device, output_container,
348
std::make_shared<StubCurrentConfiguration>(),
349
std::make_shared<StubCursorImage>()};
363
std::make_shared<StubCurrentConfiguration>(output_container)};
352
366
TEST_F(MesaCursorTest, respects_drm_cap_cursor)
361
375
EXPECT_CALL(mock_gbm, gbm_bo_create(_, drm_buffer_size, drm_buffer_size, _, _));
363
377
mgm::Cursor cursor_tmp{mock_gbm.fake_gbm.device, output_container,
364
std::make_shared<StubCurrentConfiguration>(),
365
std::make_shared<StubCursorImage>()};
378
std::make_shared<StubCurrentConfiguration>(output_container)};
368
381
TEST_F(MesaCursorTest, can_force_64x64_cursor)
379
392
EXPECT_CALL(mock_gbm, gbm_bo_create(_, 64, 64, _, _));
381
394
mgm::Cursor cursor_tmp{mock_gbm.fake_gbm.device, output_container,
382
std::make_shared<StubCurrentConfiguration>(),
383
std::make_shared<StubCursorImage>()};
395
std::make_shared<StubCurrentConfiguration>(output_container)};
386
398
TEST_F(MesaCursorTest, show_cursor_writes_to_bo)
444
456
EXPECT_CALL(mock_gbm, gbm_bo_write(mock_gbm.fake_gbm.bo, ContainsASingleWhitePixel(width*height), buffer_size_bytes));
446
458
mgm::Cursor cursor_tmp{mock_gbm.fake_gbm.device, output_container,
447
std::make_shared<StubCurrentConfiguration>(),
448
std::make_shared<SinglePixelCursorImage>()};
459
std::make_shared<StubCurrentConfiguration>(output_container)};
460
cursor_tmp.show(SinglePixelCursorImage());
451
463
TEST_F(MesaCursorTest, throws_when_images_are_too_large)
467
479
}, std::logic_error);
470
TEST_F(MesaCursorTest, forces_cursor_state_on_construction)
482
TEST_F(MesaCursorTest, clears_cursor_state_on_construction)
472
484
using namespace testing;
474
EXPECT_CALL(*output_container.outputs[10], move_cursor(geom::Point{0,0}));
475
EXPECT_CALL(*output_container.outputs[10], set_cursor(_));
476
EXPECT_CALL(*output_container.outputs[11], clear_cursor());
477
EXPECT_CALL(*output_container.outputs[12], clear_cursor());
486
EXPECT_CALL(*output_container.outputs[0], clear_cursor());
487
EXPECT_CALL(*output_container.outputs[1], clear_cursor());
488
EXPECT_CALL(*output_container.outputs[2], clear_cursor());
479
490
/* No checking of existing cursor state */
480
EXPECT_CALL(*output_container.outputs[10], has_cursor()).Times(1);
481
EXPECT_CALL(*output_container.outputs[11], has_cursor()).Times(0);
482
EXPECT_CALL(*output_container.outputs[12], has_cursor()).Times(0);
491
EXPECT_CALL(*output_container.outputs[0], has_cursor()).Times(0);
492
EXPECT_CALL(*output_container.outputs[1], has_cursor()).Times(0);
493
EXPECT_CALL(*output_container.outputs[2], has_cursor()).Times(0);
484
495
mgm::Cursor cursor_tmp{mock_gbm.fake_gbm.device, output_container,
485
std::make_shared<StubCurrentConfiguration>(),
486
std::make_shared<StubCursorImage>()};
496
std::make_shared<StubCurrentConfiguration>(output_container)};
488
498
output_container.verify_and_clear_expectations();
493
503
using namespace testing;
495
EXPECT_CALL(*output_container.outputs[10], has_cursor())
496
.WillOnce(Return(false));
505
ON_CALL(*output_container.outputs[0], clear_cursor())
506
.WillByDefault(Return(false));
507
ON_CALL(*output_container.outputs[0], set_cursor(_))
508
.WillByDefault(Return(false));
509
ON_CALL(*output_container.outputs[0], has_cursor())
510
.WillByDefault(Return(false));
499
513
mgm::Cursor cursor_tmp(mock_gbm.fake_gbm.device, output_container,
500
std::make_shared<StubCurrentConfiguration>(),
501
std::make_shared<StubCursorImage>())
514
std::make_shared<StubCurrentConfiguration>(output_container));
502
515
, std::runtime_error);
507
520
using namespace testing;
509
EXPECT_CALL(*output_container.outputs[10], has_cursor())
522
cursor.show(stub_image);
524
EXPECT_CALL(*output_container.outputs[0], has_cursor())
510
525
.WillOnce(Return(false))
511
526
.WillOnce(Return(true));
512
EXPECT_CALL(*output_container.outputs[10], set_cursor(_));
527
EXPECT_CALL(*output_container.outputs[0], set_cursor(_));
514
EXPECT_CALL(*output_container.outputs[11], has_cursor())
529
EXPECT_CALL(*output_container.outputs[1], has_cursor())
515
530
.WillOnce(Return(true));
516
EXPECT_CALL(*output_container.outputs[11], clear_cursor());
531
EXPECT_CALL(*output_container.outputs[1], clear_cursor());
518
533
cursor.move_to({10, 10});
525
540
using namespace testing;
527
EXPECT_CALL(*output_container.outputs[10], has_cursor())
542
cursor.show(stub_image);
544
EXPECT_CALL(*output_container.outputs[0], has_cursor())
528
545
.WillOnce(Return(true));
529
EXPECT_CALL(*output_container.outputs[10], set_cursor(_))
546
EXPECT_CALL(*output_container.outputs[0], set_cursor(_))
532
EXPECT_CALL(*output_container.outputs[11], has_cursor())
549
EXPECT_CALL(*output_container.outputs[1], has_cursor())
533
550
.WillOnce(Return(false));
534
EXPECT_CALL(*output_container.outputs[11], clear_cursor())
551
EXPECT_CALL(*output_container.outputs[1], clear_cursor())
537
554
cursor.move_to({10, 10});
544
561
using namespace testing;
546
EXPECT_CALL(*output_container.outputs[10], move_cursor(geom::Point{10,10}));
547
EXPECT_CALL(*output_container.outputs[11], move_cursor(_))
563
cursor.show(stub_image);
565
EXPECT_CALL(*output_container.outputs[0], move_cursor(geom::Point{10,10}));
566
EXPECT_CALL(*output_container.outputs[1], move_cursor(_))
550
569
cursor.move_to({10, 10});
552
571
output_container.verify_and_clear_expectations();
554
EXPECT_CALL(*output_container.outputs[10], move_cursor(_))
573
EXPECT_CALL(*output_container.outputs[0], move_cursor(_))
556
EXPECT_CALL(*output_container.outputs[11], move_cursor(geom::Point{50,100}));
575
EXPECT_CALL(*output_container.outputs[1], move_cursor(geom::Point{50,100}));
558
577
cursor.move_to({150, 150});
560
579
output_container.verify_and_clear_expectations();
562
EXPECT_CALL(*output_container.outputs[10], move_cursor(geom::Point{150,75}));
563
EXPECT_CALL(*output_container.outputs[11], move_cursor(geom::Point{50,25}));
581
EXPECT_CALL(*output_container.outputs[0], move_cursor(geom::Point{150,75}));
582
EXPECT_CALL(*output_container.outputs[1], move_cursor(geom::Point{50,25}));
565
584
cursor.move_to({150, 75});
567
586
output_container.verify_and_clear_expectations();
569
EXPECT_CALL(*output_container.outputs[10], move_cursor(_))
588
EXPECT_CALL(*output_container.outputs[0], move_cursor(_))
571
EXPECT_CALL(*output_container.outputs[11], move_cursor(_))
590
EXPECT_CALL(*output_container.outputs[1], move_cursor(_))
574
593
cursor.move_to({-1, -1});
581
600
using namespace testing;
583
current_configuration.conf.set_orentation_of_output(mg::DisplayConfigurationOutputId{12}, mir_orientation_left);
585
EXPECT_CALL(*output_container.outputs[12], move_cursor(geom::Point{112,100}));
586
EXPECT_CALL(*output_container.outputs[12], move_cursor(geom::Point{150,96}));
602
cursor.show(stub_image);
604
current_configuration.conf.set_orentation_of_output(mg::DisplayConfigurationOutputId{2}, mir_orientation_left);
606
EXPECT_CALL(*output_container.outputs[2], move_cursor(geom::Point{112,100}));
607
EXPECT_CALL(*output_container.outputs[2], move_cursor(geom::Point{150,96}));
588
609
cursor.move_to({766, 112});
589
610
cursor.move_to({770, 150});
597
618
using namespace testing;
599
current_configuration.conf.set_orentation_of_output(mg::DisplayConfigurationOutputId{12}, mir_orientation_right);
602
EXPECT_CALL(*output_container.outputs[12], move_cursor(geom::Point{688,100}));
603
EXPECT_CALL(*output_container.outputs[12], move_cursor(geom::Point{650,104}));
620
cursor.show(stub_image);
622
current_configuration.conf.set_orentation_of_output(mg::DisplayConfigurationOutputId{2}, mir_orientation_right);
625
EXPECT_CALL(*output_container.outputs[2], move_cursor(geom::Point{688,100}));
626
EXPECT_CALL(*output_container.outputs[2], move_cursor(geom::Point{650,104}));
605
628
cursor.move_to({766, 112});
606
629
cursor.move_to({770, 150});
613
636
using namespace testing;
615
current_configuration.conf.set_orentation_of_output(mg::DisplayConfigurationOutputId{12}, mir_orientation_inverted);
617
EXPECT_CALL(*output_container.outputs[12], move_cursor(geom::Point{700,88}));
618
EXPECT_CALL(*output_container.outputs[12], move_cursor(geom::Point{696,50}));
638
cursor.show(stub_image);
640
current_configuration.conf.set_orentation_of_output(mg::DisplayConfigurationOutputId{2}, mir_orientation_inverted);
642
EXPECT_CALL(*output_container.outputs[2], move_cursor(geom::Point{700,88}));
643
EXPECT_CALL(*output_container.outputs[2], move_cursor(geom::Point{696,50}));
620
645
cursor.move_to({766, 112});
621
646
cursor.move_to({770, 150});
628
653
using namespace testing;
630
EXPECT_CALL(*output_container.outputs[10], clear_cursor());
631
EXPECT_CALL(*output_container.outputs[11], clear_cursor());
632
EXPECT_CALL(*output_container.outputs[12], clear_cursor());
655
EXPECT_CALL(*output_container.outputs[0], clear_cursor());
656
EXPECT_CALL(*output_container.outputs[1], clear_cursor());
657
EXPECT_CALL(*output_container.outputs[2], clear_cursor());
641
666
using namespace testing;
643
EXPECT_CALL(*output_container.outputs[10], clear_cursor());
644
EXPECT_CALL(*output_container.outputs[11], clear_cursor());
645
EXPECT_CALL(*output_container.outputs[12], clear_cursor());
646
EXPECT_CALL(*output_container.outputs[10], move_cursor(_)).Times(0);
647
EXPECT_CALL(*output_container.outputs[11], move_cursor(_)).Times(0);
648
EXPECT_CALL(*output_container.outputs[12], move_cursor(_)).Times(0);
668
EXPECT_CALL(*output_container.outputs[0], clear_cursor());
669
EXPECT_CALL(*output_container.outputs[1], clear_cursor());
670
EXPECT_CALL(*output_container.outputs[2], clear_cursor());
671
EXPECT_CALL(*output_container.outputs[0], move_cursor(_)).Times(0);
672
EXPECT_CALL(*output_container.outputs[1], move_cursor(_)).Times(0);
673
EXPECT_CALL(*output_container.outputs[2], move_cursor(_)).Times(0);
651
676
cursor.move_to({17, 29});
658
683
using namespace testing;
660
EXPECT_CALL(*output_container.outputs[10], clear_cursor());
661
EXPECT_CALL(*output_container.outputs[11], clear_cursor());
662
EXPECT_CALL(*output_container.outputs[12], clear_cursor());
685
EXPECT_CALL(*output_container.outputs[0], clear_cursor());
686
EXPECT_CALL(*output_container.outputs[1], clear_cursor());
687
EXPECT_CALL(*output_container.outputs[2], clear_cursor());
665
690
TEST_F(MesaCursorTest, cursor_is_shown_at_correct_location_after_suspend_resume)
667
692
using namespace testing;
669
EXPECT_CALL(*output_container.outputs[10], move_cursor(geom::Point{150,75}));
670
EXPECT_CALL(*output_container.outputs[11], move_cursor(geom::Point{50,25}));
671
EXPECT_CALL(*output_container.outputs[10], clear_cursor());
672
EXPECT_CALL(*output_container.outputs[11], clear_cursor());
673
EXPECT_CALL(*output_container.outputs[12], has_cursor())
694
cursor.show(stub_image);
696
EXPECT_CALL(*output_container.outputs[0], move_cursor(geom::Point{150,75}));
697
EXPECT_CALL(*output_container.outputs[1], move_cursor(geom::Point{50,25}));
698
EXPECT_CALL(*output_container.outputs[0], clear_cursor());
699
EXPECT_CALL(*output_container.outputs[1], clear_cursor());
700
EXPECT_CALL(*output_container.outputs[2], has_cursor())
674
701
.WillRepeatedly(Return(false));
675
EXPECT_CALL(*output_container.outputs[12], clear_cursor());
702
EXPECT_CALL(*output_container.outputs[2], clear_cursor());
677
704
cursor.move_to({150, 75});
678
705
cursor.suspend();
680
707
output_container.verify_and_clear_expectations();
682
EXPECT_CALL(*output_container.outputs[10], set_cursor(_));
683
EXPECT_CALL(*output_container.outputs[11], set_cursor(_));
684
EXPECT_CALL(*output_container.outputs[10], move_cursor(geom::Point{150,75}));
685
EXPECT_CALL(*output_container.outputs[11], move_cursor(geom::Point{50,25}));
709
EXPECT_CALL(*output_container.outputs[0], set_cursor(_));
710
EXPECT_CALL(*output_container.outputs[1], set_cursor(_));
711
EXPECT_CALL(*output_container.outputs[0], move_cursor(geom::Point{150,75}));
712
EXPECT_CALL(*output_container.outputs[1], move_cursor(geom::Point{50,25}));
688
715
output_container.verify_and_clear_expectations();
693
720
using namespace testing;
695
EXPECT_CALL(*output_container.outputs[10], clear_cursor()).Times(AnyNumber());
696
EXPECT_CALL(*output_container.outputs[11], clear_cursor()).Times(AnyNumber());
697
EXPECT_CALL(*output_container.outputs[12], clear_cursor()).Times(AnyNumber());
722
EXPECT_CALL(*output_container.outputs[0], clear_cursor()).Times(AnyNumber());
723
EXPECT_CALL(*output_container.outputs[1], clear_cursor()).Times(AnyNumber());
724
EXPECT_CALL(*output_container.outputs[2], clear_cursor()).Times(AnyNumber());
700
727
cursor.suspend();
702
729
output_container.verify_and_clear_expectations();
704
EXPECT_CALL(*output_container.outputs[10], set_cursor(_)).Times(0);
705
EXPECT_CALL(*output_container.outputs[11], set_cursor(_)).Times(0);
706
EXPECT_CALL(*output_container.outputs[12], set_cursor(_)).Times(0);
731
EXPECT_CALL(*output_container.outputs[0], set_cursor(_)).Times(0);
732
EXPECT_CALL(*output_container.outputs[1], set_cursor(_)).Times(0);
733
EXPECT_CALL(*output_container.outputs[2], set_cursor(_)).Times(0);
709
736
output_container.verify_and_clear_expectations();
739
TEST_F(MesaCursorTest, show_with_param_places_cursor_on_output)
741
EXPECT_CALL(*output_container.outputs[0], clear_cursor());
744
output_container.verify_and_clear_expectations();
746
EXPECT_CALL(*output_container.outputs[0], set_cursor(_));
747
cursor.show(stub_image);
713
750
TEST_F(MesaCursorTest, show_without_param_places_cursor_on_output_output)
715
752
using namespace testing;
716
EXPECT_CALL(*output_container.outputs[10], clear_cursor());
753
EXPECT_CALL(*output_container.outputs[0], clear_cursor());
719
756
output_container.verify_and_clear_expectations();
721
EXPECT_CALL(*output_container.outputs[10], set_cursor(_));
758
EXPECT_CALL(*output_container.outputs[0], set_cursor(_));
748
787
EXPECT_CALL(mock_gbm, gbm_bo_write(_, _, _)).Times(AnyNumber());
749
EXPECT_CALL(*output_container.outputs[10], set_cursor(_)).Times(AnyNumber());
788
EXPECT_CALL(*output_container.outputs[0], set_cursor(_)).Times(AnyNumber());
751
790
// When we set the image with the hotspot, first we should see the cursor move from its initial
752
791
// location, to account for the displacement. Further movement should be offset by the hotspot.
755
EXPECT_CALL(*output_container.outputs[10], move_cursor(initial_buffer_location));
756
EXPECT_CALL(*output_container.outputs[10], move_cursor(expected_buffer_location_1));
757
EXPECT_CALL(*output_container.outputs[10], move_cursor(expected_buffer_location_2));
794
EXPECT_CALL(*output_container.outputs[0], move_cursor(initial_buffer_location));
795
EXPECT_CALL(*output_container.outputs[0], move_cursor(expected_buffer_location_1));
796
EXPECT_CALL(*output_container.outputs[0], move_cursor(expected_buffer_location_2));
760
799
cursor.show(HotspotCursor());