Compare commits
	
		
			1055 Commits
		
	
	
		
			3.11.91-wa
			...
			wip/xtogls
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 3ac563307e | ||
|   | 24956fadcc | ||
|   | fc5de438b5 | ||
|   | 94cee3ef09 | ||
|   | 1e6b042778 | ||
|   | 048f035d30 | ||
|   | b32c837df9 | ||
|   | dd03a76d51 | ||
|   | 806a666950 | ||
|   | b240a5e819 | ||
|   | fe823b3553 | ||
|   | d380d30ef4 | ||
|   | 1fe5b3e7d5 | ||
|   | a8df208a5c | ||
|   | f3f3c94831 | ||
|   | 6e06648f7a | ||
|   | afb41f715b | ||
|   | 19d26dde92 | ||
|   | 4acb902423 | ||
|   | 626516d12e | ||
|   | 1c94df2553 | ||
|   | 43762da9d3 | ||
|   | 266166a2d6 | ||
|   | 3a0af0faae | ||
|   | 0890eaa3fe | ||
|   | d4058d947b | ||
|   | b704659899 | ||
|   | 0a9187a6e9 | ||
|   | 31db32e826 | ||
|   | c2ea650b3c | ||
|   | 969131f00e | ||
|   | c98090c061 | ||
|   | 3168d3b5e6 | ||
|   | efcd7d86e7 | ||
|   | 04449923bd | ||
|   | 47b3336ffa | ||
|   | 0f37c1b58e | ||
|   | a3747725ed | ||
|   | c448650a60 | ||
|   | c45f616fdc | ||
|   | 9402691aaa | ||
|   | cbffbb0be0 | ||
|   | 9df5b17940 | ||
|   | feae23506b | ||
|   | 6408e59c7c | ||
|   | 47d72680ff | ||
|   | 6513cbb470 | ||
|   | 50b81fe4b9 | ||
|   | f38c1f6ab4 | ||
|   | f159611fab | ||
|   | f1a7231ac2 | ||
|   | 21991a7edb | ||
|   | 3f1b6ddc8f | ||
|   | aa84813400 | ||
|   | dd243813e1 | ||
|   | d8c2933c58 | ||
|   | 2b798511de | ||
|   | 6c37f6e601 | ||
|   | 92e9f3d467 | ||
|   | 05419b8450 | ||
|   | e215c07439 | ||
|   | 5b7dff7a57 | ||
|   | 1a3aa75385 | ||
|   | 41880778b5 | ||
|   | ecb4e09ec5 | ||
|   | d02505852d | ||
|   | 3941dc7537 | ||
|   | e790c45303 | ||
|   | ae4e553ddb | ||
|   | 809568280b | ||
|   | 4053c92abf | ||
|   | 56906a29e0 | ||
|   | 2c0ad5bef7 | ||
|   | 4a7939268c | ||
|   | 80266d3071 | ||
|   | 8e5cfccf49 | ||
|   | dcf64ca167 | ||
|   | f93fc1506b | ||
|   | 4ee8fb8154 | ||
|   | 446b75907e | ||
|   | 550f1989ff | ||
|   | 91a6f42345 | ||
|   | e97cae0eb3 | ||
|   | 8640982e68 | ||
|   | 480a853263 | ||
|   | b05953d960 | ||
|   | 3a0de6a4f1 | ||
|   | fb9f22c02f | ||
|   | 10ac1000f7 | ||
|   | c81a0dede2 | ||
|   | fc8a2b8a42 | ||
|   | 2ae0a72dad | ||
|   | 5b17c72047 | ||
|   | 8d9653dece | ||
|   | e2b7b26f28 | ||
|   | ff2eb77fcd | ||
|   | 0588399ac7 | ||
|   | 71544fbf4e | ||
|   | c8f3820956 | ||
|   | f57b0726a0 | ||
|   | da175bca52 | ||
|   | 33cb7f4a2c | ||
|   | 7732447abc | ||
|   | c49c37999c | ||
|   | 91f35d6a01 | ||
|   | 549df04ed8 | ||
|   | 4334135c52 | ||
|   | 03c4de5590 | ||
|   | 7a109a18af | ||
|   | d9b72b0f43 | ||
|   | a7ea54bd7d | ||
|   | df642b96e2 | ||
|   | f56cc1f733 | ||
|   | f5bff4b7f3 | ||
|   | bbfdf5dd2a | ||
|   | 9b95eda42a | ||
|   | 2d225a3386 | ||
|   | 7b3cdc8f96 | ||
|   | b6f9500ccc | ||
|   | ea354e96cb | ||
|   | 098c8908ed | ||
|   | ab632e36a5 | ||
|   | 1427d20922 | ||
|   | aed671810c | ||
|   | 324d7d720d | ||
|   | 413e39ecbb | ||
|   | 2ca2c18c2a | ||
|   | 01cd4b2ba0 | ||
|   | bca210db45 | ||
|   | 66d6f73af2 | ||
|   | bc8799d7d7 | ||
|   | fd5c14550a | ||
|   | a5cca5296c | ||
|   | f4ef4b79f9 | ||
|   | 6c7a51378f | ||
|   | 9c4908b44a | ||
|   | afaab8aef2 | ||
|   | 845fdda22c | ||
|   | fa29a1a99e | ||
|   | f9bffae9fd | ||
|   | 31c925c602 | ||
|   | 5d310e06ba | ||
|   | 25a16c3379 | ||
|   | 730ed6f75f | ||
|   | a6601e92aa | ||
|   | f3a2bb7779 | ||
|   | 73e2d7049a | ||
|   | a6353944f6 | ||
|   | 43d6088ebb | ||
|   | e3001794f2 | ||
|   | e97ca325e6 | ||
|   | c9c6645284 | ||
|   | 57bb297450 | ||
|   | 06ca99c3a3 | ||
|   | 4b5593c67f | ||
|   | acb3dc6754 | ||
|   | 4c21a46452 | ||
|   | 900ae2c1fa | ||
|   | 01b6445708 | ||
|   | 292d502205 | ||
|   | adf2e44a82 | ||
|   | b075d576a0 | ||
|   | a7665a3e05 | ||
|   | d2e40273ae | ||
|   | d456e68375 | ||
|   | 03efa3ccbc | ||
|   | 2101c8357b | ||
|   | 575963bee7 | ||
|   | 7726001d43 | ||
|   | e382a4b560 | ||
|   | 70713cc7db | ||
|   | 417090f3fa | ||
|   | 9fcc57cdec | ||
|   | 7bf0c77193 | ||
|   | f2328f1105 | ||
|   | d9a2443e53 | ||
|   | b773898a60 | ||
|   | 8461b2c910 | ||
|   | 9b760dbbab | ||
|   | 8b0747786a | ||
|   | 41235fcb86 | ||
|   | 1d5b4e5b2f | ||
|   | 6e8d1d79d1 | ||
|   | 7cefe91c3c | ||
|   | 1ef6a5542a | ||
|   | bc0f7def47 | ||
|   | f0175d1234 | ||
|   | eb0c4db46d | ||
|   | 19e97ec567 | ||
|   | ce5c029509 | ||
|   | 647743aa5f | ||
|   | e94f169d4e | ||
|   | e6b0525c70 | ||
|   | 23ae11043f | ||
|   | 78657dafca | ||
|   | 0f47eae33a | ||
|   | 2209eac2bf | ||
|   | aed6d4fbb7 | ||
|   | 270c7abd3c | ||
|   | e2bd15541b | ||
|   | 9607513e62 | ||
|   | 18730f2a5e | ||
|   | 4e584c2cf0 | ||
|   | d1619e4f53 | ||
|   | c8d0a66921 | ||
|   | dd4d6af185 | ||
|   | 1016e2555a | ||
|   | 657318d4d3 | ||
|   | f051e05b0a | ||
|   | ca75513880 | ||
|   | 63f1a10e33 | ||
|   | 14f839c53c | ||
|   | ebb6847bd1 | ||
|   | c5d4f4a245 | ||
|   | a027937ccc | ||
|   | 925075ddaf | ||
|   | 41de208f31 | ||
|   | c8e3b52160 | ||
|   | 2c53919462 | ||
|   | a6f3534ff0 | ||
|   | 490f1a6249 | ||
|   | 5b83bfb1db | ||
|   | 1ef06207a4 | ||
|   | 0a6fa202a8 | ||
|   | 18d609ad6d | ||
|   | c95c501a5b | ||
|   | 8c5da24401 | ||
|   | 01a773ed5a | ||
|   | 2435d132ac | ||
|   | 72c65cbff0 | ||
|   | 97074ccdad | ||
|   | 6111bb9dec | ||
|   | eed03d38b0 | ||
|   | e9eb3c32a9 | ||
|   | 61b714c666 | ||
|   | e9263d25b9 | ||
|   | d590626017 | ||
|   | fdd43fc2d9 | ||
|   | 4cbf420b4b | ||
|   | fd373948d2 | ||
|   | 1dc8a7eca3 | ||
|   | 861cfc23df | ||
|   | 86368e7e07 | ||
|   | f42184ded8 | ||
|   | af515732b0 | ||
|   | 98a1573bee | ||
|   | 1762436775 | ||
|   | 4fd017d23d | ||
|   | 2f6ce4783b | ||
|   | c6296aa17f | ||
|   | b501ca5a24 | ||
|   | 10ac86b950 | ||
|   | def097359c | ||
|   | 6c743dad88 | ||
|   | 274047c3f8 | ||
|   | e04e9aac39 | ||
|   | 59fc9d832b | ||
|   | 0bf5c831d5 | ||
|   | 777a6d4570 | ||
|   | 003ff3d255 | ||
|   | 88040d6b8a | ||
|   | eaf85ddec9 | ||
|   | fa2e1e4eda | ||
|   | 5752079cbb | ||
|   | 7014dc5368 | ||
|   | fdaeb0cf9c | ||
|   | 59415bf49f | ||
|   | 3c3b94921f | ||
|   | 0d9fa24be4 | ||
|   | 9a98ec81d7 | ||
|   | d0142d6ab6 | ||
|   | dd440e64da | ||
|   | a1ba480c8a | ||
|   | 93600d6166 | ||
|   | 33f3ca7fba | ||
|   | d27e267382 | ||
|   | 91784d87b6 | ||
|   | 2769683521 | ||
|   | 6072e981a8 | ||
|   | e21677c782 | ||
|   | 168ede9374 | ||
|   | a0d608e083 | ||
|   | 326740e00f | ||
|   | eac6e9ed41 | ||
|   | 4ea9a28eee | ||
|   | ca11b88fcd | ||
|   | 20a0eb9809 | ||
|   | d8dfe4e4ad | ||
|   | 28666da6a1 | ||
|   | bb4896f1af | ||
|   | a17b86dfbe | ||
|   | d9450c46b9 | ||
|   | e80c37f857 | ||
|   | ef44cc5a53 | ||
|   | 7c0d75e34f | ||
|   | ee812e3fe0 | ||
|   | 52cf9104d9 | ||
|   | 3d091e514d | ||
|   | 3c0ca1f2af | ||
|   | 9a6f5e115d | ||
|   | 731e1ed74f | ||
|   | eba5648c27 | ||
|   | d1a31952de | ||
|   | 13a444482a | ||
|   | 9d780bca7a | ||
|   | b6a80934d6 | ||
|   | 75b5d15598 | ||
|   | c44b1d730d | ||
|   | 48dc544bef | ||
|   | 31d744195d | ||
|   | 00ea9bf14b | ||
|   | f3ee9be4cb | ||
|   | 2d6bcf3885 | ||
|   | d189ddcc86 | ||
|   | 18770aaa63 | ||
|   | adf0d08585 | ||
|   | 813206393a | ||
|   | 7c0a3dfeb8 | ||
|   | cd4e6fcdee | ||
|   | 2f9c601ae4 | ||
|   | bec3db3068 | ||
|   | cef2745bc0 | ||
|   | 064ef09c99 | ||
|   | 9ca0349c2b | ||
|   | f9305be450 | ||
|   | 6c9aa15814 | ||
|   | d09116ebce | ||
|   | beca90a689 | ||
|   | e55dd4e3f4 | ||
|   | 02c31ac069 | ||
|   | 3f375c9426 | ||
|   | 258112d6a7 | ||
|   | ceb0f1005d | ||
|   | a378faf495 | ||
|   | c9e99ebbbf | ||
|   | 020f209c45 | ||
|   | 45df3e41c5 | ||
|   | 1a723954fc | ||
|   | 3e554efc70 | ||
|   | d68da0b8cf | ||
|   | de7a644656 | ||
|   | 16bcbd1a34 | ||
|   | 29439f8de2 | ||
|   | 97a69cee5a | ||
|   | 2e2dd247ce | ||
|   | de6054d557 | ||
|   | db56a7cecb | ||
|   | f92c1af24a | ||
|   | 4ab71ec942 | ||
|   | 2748661f63 | ||
|   | aee074b11d | ||
|   | 5f29b8c206 | ||
|   | 92340fd8da | ||
|   | 7c6c4d63c5 | ||
|   | 5d43e33032 | ||
|   | 45a8a3f490 | ||
|   | bdf55bc674 | ||
|   | e15c260e56 | ||
|   | 65ed8a817d | ||
|   | a8d2dfd14f | ||
|   | e02bf13206 | ||
|   | 4b7d77864a | ||
|   | 72e4d42267 | ||
|   | 1abdd7be10 | ||
|   | f3d88ca1d1 | ||
|   | 15d89d451f | ||
|   | 4510b82361 | ||
|   | ae0853ed86 | ||
|   | 76544ff6e1 | ||
|   | dde96951a7 | ||
|   | 24eb737858 | ||
|   | ddc7938961 | ||
|   | 4f2dc77ec3 | ||
|   | 678fa52ae1 | ||
|   | 1be97f3d59 | ||
|   | 30ecd7c770 | ||
|   | 0dd27edb91 | ||
|   | 6a44f04b51 | ||
|   | 745134e066 | ||
|   | 72b1a2837d | ||
|   | e5ab4f13f1 | ||
|   | 14deeef8a7 | ||
|   | 57cc68096b | ||
|   | 7af429150e | ||
|   | d7ee5cf33d | ||
|   | a2fb2c05ae | ||
|   | abd0ac2cc3 | ||
|   | 8c0ef829c9 | ||
|   | eb1c9175f9 | ||
|   | f25243e121 | ||
|   | c1f4352683 | ||
|   | 0797206cc2 | ||
|   | 260b6d02f2 | ||
|   | 0440765cb7 | ||
|   | 40214b72bf | ||
|   | 339a78718d | ||
|   | f1034d0459 | ||
|   | edfaf3de49 | ||
|   | bbec66c2d8 | ||
|   | 339b856d84 | ||
|   | 7560aaee73 | ||
|   | 2bcd4ab159 | ||
|   | 86100936d9 | ||
|   | 37de96ce86 | ||
|   | e81433f58d | ||
|   | 6219ae782a | ||
|   | 1169e104cb | ||
|   | 87bec99a0a | ||
|   | 5defe574d7 | ||
|   | 59541dfa14 | ||
|   | becce7afa0 | ||
|   | 862d57d459 | ||
|   | c9d2a5bee2 | ||
|   | bb62f49c98 | ||
|   | b4293d46a6 | ||
|   | 30d534f17e | ||
|   | d004f3f990 | ||
|   | 62e5faeb0c | ||
|   | 03cfe602d9 | ||
|   | e1b0c9c756 | ||
|   | dbe4fc0e45 | ||
|   | f0bf9c7fc3 | ||
|   | d0f0be8b03 | ||
|   | f5e77d7f63 | ||
|   | 277879c11b | ||
|   | 1a4c16659f | ||
|   | 239195c1d1 | ||
|   | 7c4f4c6f36 | ||
|   | e8447ad9bb | ||
|   | c55f64fdf2 | ||
|   | d53e04f4c8 | ||
|   | b37223b9bb | ||
|   | d1173ce860 | ||
|   | df733c9cee | ||
|   | 6054a3ce76 | ||
|   | 3ba8532bdc | ||
|   | 912cf8ee5f | ||
|   | 85eab49b53 | ||
|   | 954677dcbd | ||
|   | d7c4f57aae | ||
|   | 333d78f338 | ||
|   | 814b2dbda9 | ||
|   | ebbdfabed6 | ||
|   | 4396ac809b | ||
|   | c2b9155979 | ||
|   | f68d65a5ae | ||
|   | 42f267bb50 | ||
|   | e215f3f5eb | ||
|   | 7ac66faa72 | ||
|   | d0b870d3a9 | ||
|   | 99ad5c00a7 | ||
|   | 797c46ba7d | ||
|   | ab0bd59f5e | ||
|   | 0c0973bbd8 | ||
|   | feca0fb512 | ||
|   | 2f229c3928 | ||
|   | a730361d6c | ||
|   | db058d4a81 | ||
|   | 15cf804dbc | ||
|   | b38b037092 | ||
|   | 42bcad6549 | ||
|   | b0ea0afd2f | ||
|   | 1d08d75108 | ||
|   | 4daf20483d | ||
|   | 96b6dcec01 | ||
|   | 9fe5a3b407 | ||
|   | a967d479c5 | ||
|   | a7d4713393 | ||
|   | 4d4ecae2a1 | ||
|   | 545c3b6678 | ||
|   | e70f336a09 | ||
|   | 806f1742ac | ||
|   | 0dc63f395d | ||
|   | 616f1a09b1 | ||
|   | 50e69109b6 | ||
|   | 242784d3e4 | ||
|   | 0466fe9301 | ||
|   | dbf5d8f9bc | ||
|   | b9e9595e8b | ||
|   | 75de29f5f7 | ||
|   | e2b24092d6 | ||
|   | 0e6570b09b | ||
|   | 840378ae68 | ||
|   | 4752776ebf | ||
|   | c40868b239 | ||
|   | a21e7a2188 | ||
|   | 371fba6843 | ||
|   | be02fa1120 | ||
|   | 43730f1660 | ||
|   | 4f609dbf5e | ||
|   | 2a7d12ba14 | ||
|   | c4c0b5f0ab | ||
|   | 8373c90cd8 | ||
|   | eb5b54dd8b | ||
|   | 9653b79a35 | ||
|   | e07bd15fc2 | ||
|   | 5cf0740b4e | ||
|   | c540ddf59b | ||
|   | a44295599c | ||
|   | af272f2685 | ||
|   | 81d033ec73 | ||
|   | e9ee984921 | ||
|   | 3c404c5db3 | ||
|   | e4cd000cef | ||
|   | 6296fefea6 | ||
|   | c1e3a6b742 | ||
|   | dcd83b7365 | ||
|   | 617b00dfbd | ||
|   | 94692414cb | ||
|   | ab6bc76bfd | ||
|   | 57803f1d59 | ||
|   | 67b6737b27 | ||
|   | 29396014fd | ||
|   | 899d4d8477 | ||
|   | f1c7063ee7 | ||
|   | 216ff7ebe5 | ||
|   | 34cc5efb90 | ||
|   | bce1d5117b | ||
|   | d5552cc372 | ||
|   | fd392cc1e7 | ||
|   | b641d9d5a8 | ||
|   | 5bcc78498f | ||
|   | 521125b672 | ||
|   | 89b931435d | ||
|   | e22e9f5df5 | ||
|   | 20547e3b63 | ||
|   | 2cf185b4e4 | ||
|   | 229360b248 | ||
|   | ccced506ed | ||
|   | 28b9160c01 | ||
|   | ba6584a0d7 | ||
|   | 2a0289a216 | ||
|   | f6a73bcf22 | ||
|   | 59e064f610 | ||
|   | ba131626c2 | ||
|   | 30ebf46aa4 | ||
|   | da27735265 | ||
|   | 78dbf8cb56 | ||
|   | f4e299ca46 | ||
|   | f95f2b0c6d | ||
|   | fe42a4eb4e | ||
|   | 565883dadb | ||
|   | be60e4f6e7 | ||
|   | fa60824096 | ||
|   | 0efb0b47eb | ||
|   | 0f810a4e21 | ||
|   | 383d4c7e4e | ||
|   | 21425b5833 | ||
|   | 863569b702 | ||
|   | 5f52f55916 | ||
|   | 0aec98cf02 | ||
|   | b64d14ff4a | ||
|   | 08a8254deb | ||
|   | 11de01741c | ||
|   | a7ea2cd365 | ||
|   | a15a4faff0 | ||
|   | b93176d89a | ||
|   | f842ea6d15 | ||
|   | 422f2e5fe6 | ||
|   | 3961f291e4 | ||
|   | 61d8b35254 | ||
|   | 78457cf7b4 | ||
|   | 1e2bdcc3c5 | ||
|   | 490e1c8c3b | ||
|   | 9a751a95e3 | ||
|   | afce448281 | ||
|   | b2405b701a | ||
|   | 390c028da7 | ||
|   | 82e02e39d3 | ||
|   | 9707c1061d | ||
|   | 29cb77ce70 | ||
|   | 0f9b29b140 | ||
|   | b367965f6c | ||
|   | ed9dbf6aa2 | ||
|   | e10fd19d24 | ||
|   | f4f529385a | ||
|   | 3f70bdd331 | ||
|   | 6eeaf09ab7 | ||
|   | f93fa1d705 | ||
|   | cd905a34fb | ||
|   | 47aa583625 | ||
|   | d7519f4ebc | ||
|   | 97ea4e8717 | ||
|   | 208296a619 | ||
|   | cc0488f1e2 | ||
|   | e30ed6892c | ||
|   | d699b2409a | ||
|   | ef65848d11 | ||
|   | 272676b896 | ||
|   | 44580ddb80 | ||
|   | 456e3e2429 | ||
|   | eba848e8aa | ||
|   | 71be7e8493 | ||
|   | a742b17805 | ||
|   | 7484d540cd | ||
|   | a55622d924 | ||
|   | c4b65e0e6e | ||
|   | 9ec8232417 | ||
|   | 768e830f11 | ||
|   | 4a4a624b77 | ||
|   | 1cfaf45389 | ||
|   | 42491f7724 | ||
|   | 9696e785da | ||
|   | 0de83ebfb5 | ||
|   | 337db2a660 | ||
|   | 054c307353 | ||
|   | 852589897e | ||
|   | 46b4d6c0f0 | ||
|   | ab2224686a | ||
|   | 24b08d1a36 | ||
|   | 0808adefaf | ||
|   | 14f424cd02 | ||
|   | 9debd2fb0d | ||
|   | 57359da9b4 | ||
|   | e67abdd3ff | ||
|   | ca4777f778 | ||
|   | 76dc0ca681 | ||
|   | 8968501031 | ||
|   | 1b29113150 | ||
|   | 15c59f9919 | ||
|   | a53e094fcd | ||
|   | a377a1a110 | ||
|   | 74a1e00e30 | ||
|   | 1c41f71eef | ||
|   | 63350c52cc | ||
|   | b13b7ea72e | ||
|   | 9a89cc1198 | ||
|   | 56e8c3b625 | ||
|   | ce3d9fb89f | ||
|   | 27c018ab98 | ||
|   | a1427c7130 | ||
|   | 91ad92c968 | ||
|   | f0c7b518e6 | ||
|   | 5fa5ace5e6 | ||
|   | 044c06bff3 | ||
|   | a3ccc4fd1c | ||
|   | 0a20f7458c | ||
|   | 9c94f8ae47 | ||
|   | f940292cfe | ||
|   | 48a36356dd | ||
|   | f05983be42 | ||
|   | dfcefd3315 | ||
|   | 3fe755e684 | ||
|   | 0eb86de807 | ||
|   | ff635bad3b | ||
|   | 43a409dec4 | ||
|   | b087fce062 | ||
|   | 420f322910 | ||
|   | 4bf6e0ae8c | ||
|   | 97872e70a5 | ||
|   | be57308663 | ||
|   | 33f1bd96f5 | ||
|   | 9ba49358e5 | ||
|   | 8b2b65246a | ||
|   | 4fdbb466e1 | ||
|   | da48b18188 | ||
|   | a5f1790828 | ||
|   | 6efcf2526d | ||
|   | d6a27195d3 | ||
|   | 8f151842fb | ||
|   | 6f7023bc6b | ||
|   | 63b158e4da | ||
|   | b3364cad3e | ||
|   | 3502cfba34 | ||
|   | 5cc6becb63 | ||
|   | ae8f21a3dc | ||
|   | 0cdf3bd383 | ||
|   | 3de58189c0 | ||
|   | 5270c469a3 | ||
|   | 7504f16e59 | ||
|   | cdb7947dd1 | ||
|   | cdfc6f5b53 | ||
|   | fcb2ab41b2 | ||
|   | f5bd7c5f50 | ||
|   | cb549154aa | ||
|   | ada9610e30 | ||
|   | f11bf44525 | ||
|   | 1f15c85c00 | ||
|   | 8b4c5459c0 | ||
|   | b8eb7b883f | ||
|   | d07d5d1328 | ||
|   | 535685742a | ||
|   | 62e45b6d5e | ||
|   | 3c6dd5bf6d | ||
|   | 0f85986340 | ||
|   | 93ac0329db | ||
|   | c539dfe0d7 | ||
|   | 4f9872c037 | ||
|   | 24e12053ea | ||
|   | 1502d2a79f | ||
|   | a9d8107c3d | ||
|   | a5d2c51392 | ||
|   | 991c85f6a0 | ||
|   | d1ea17e6a4 | ||
|   | b37ad66e9d | ||
|   | c1f15348a5 | ||
|   | 4880ee9bb6 | ||
|   | 857561baed | ||
|   | a44cc9ef47 | ||
|   | 2f77b71933 | ||
|   | d47b7ba038 | ||
|   | f21312e2fd | ||
|   | 394af33607 | ||
|   | 7314cdac94 | ||
|   | 81025e37ea | ||
|   | 1bb9f1e333 | ||
|   | b11c75c1c9 | ||
|   | 757b626aee | ||
|   | fb3df5243f | ||
|   | e34792d9f0 | ||
|   | f397c32192 | ||
|   | f79314d7b5 | ||
|   | 55c61259d8 | ||
|   | 5298cf0a3a | ||
|   | f1dc1a0cbc | ||
|   | 2cf80bc647 | ||
|   | 40c15f6e2a | ||
|   | 47273eaab6 | ||
|   | 202e6bd654 | ||
|   | a8849621c9 | ||
|   | fd41ab93da | ||
|   | 49c0be11d6 | ||
|   | 9df8e831be | ||
|   | 84c6b2a3fa | ||
|   | a07fe23d7a | ||
|   | 06cd669ccb | ||
|   | 81eb7d9537 | ||
|   | dd8d8e436d | ||
|   | d6b6b363ad | ||
|   | 254e2e993c | ||
|   | c595a9c29f | ||
|   | ef0763fd04 | ||
|   | b5ef6703fc | ||
|   | dde25e831f | ||
|   | dfc7f7222b | ||
|   | ef278eb547 | ||
|   | 38e26e5cc3 | ||
|   | 9773a879c3 | ||
|   | 8358b5dd24 | ||
|   | 34a9c95b7f | ||
|   | dd76c92f30 | ||
|   | abd2abcde6 | ||
|   | a8f4651c72 | ||
|   | 70e3ef02a6 | ||
|   | b159d6a5e1 | ||
|   | 4c2e39bf2c | ||
|   | 4a8f7aa884 | ||
|   | c8f466cb85 | ||
|   | 2edec1bfa8 | ||
|   | 73acbdd30c | ||
|   | c07004aefe | ||
|   | 7e8833a215 | ||
|   | 266ac00e56 | ||
|   | 2b3fc741fb | ||
|   | 91389c89a1 | ||
|   | abb060b272 | ||
|   | 41e6cd8aa9 | ||
|   | bb5631793c | ||
|   | f77fc447e0 | ||
|   | c63d7cb692 | ||
|   | ac28b91bf6 | ||
|   | 334e7373cd | ||
|   | b9b6eb99c3 | ||
|   | 463318ac4c | ||
|   | 3ee63d5a99 | ||
|   | eb01163656 | ||
|   | 2bf844d585 | ||
|   | 585fdd781c | ||
|   | 54f8b5d69a | ||
|   | fc24552e0e | ||
|   | be352c2bf1 | ||
|   | 36009cbae1 | ||
|   | 21f9bf530d | ||
|   | 64a82c8d77 | ||
|   | 29edefdfc5 | ||
|   | 7253a5d274 | ||
|   | ad43cbd70b | ||
|   | 682d6f9ee2 | ||
|   | 1e01a55cdc | ||
|   | 1acb1bb7e6 | ||
|   | 487602c409 | ||
|   | a7fa90b750 | ||
|   | 0054e637cc | ||
|   | 8c69f1b33c | ||
|   | 870c6382ed | ||
|   | 91770d0477 | ||
|   | 6b81a05341 | ||
|   | 5298a834ef | ||
|   | 6ceddd626a | ||
|   | a538f36524 | ||
|   | e3a93db712 | ||
|   | 7cdf55871e | ||
|   | c78089437d | ||
|   | ad1e23ce7d | ||
|   | 52d411bd85 | ||
|   | 3aac2bf934 | ||
|   | e053f7f2f4 | ||
|   | fb6a7cda70 | ||
|   | 9c20de1adb | ||
|   | 9935b4fd66 | ||
|   | 45ff615b46 | ||
|   | 79e96a6a1a | ||
|   | 497541730f | ||
|   | 101a13c86d | ||
|   | 18cfcc0221 | ||
|   | 8daefd92df | ||
|   | b580ccfe56 | ||
|   | d3c2607e53 | ||
|   | f64cea3fc3 | ||
|   | 7a33fa6817 | ||
|   | 67560db7b8 | ||
|   | 6b7f7c66ec | ||
|   | 79a3b23cec | ||
|   | ce99362094 | ||
|   | 099fd2b3fb | ||
|   | abebb4775b | ||
|   | 4752d427e4 | ||
|   | 16a8e6ffe0 | ||
|   | b8aa9bddf9 | ||
|   | 8e0bc053d4 | ||
|   | 757674a9d6 | ||
|   | 254afc5022 | ||
|   | 56f8d32ca9 | ||
|   | 1f6158ace7 | ||
|   | 4cc842296e | ||
|   | f6e58be4b0 | ||
|   | a285bbbd14 | ||
|   | 52c24c5c71 | ||
|   | 64e09b37ac | ||
|   | f3908bb0b8 | ||
|   | aab354b72b | ||
|   | 1f1aa85d68 | ||
|   | 2bc0e35f7d | ||
|   | be501479da | ||
|   | 707d728722 | ||
|   | ae05059cef | ||
|   | c1f5741ac0 | ||
|   | f5bb6e407f | ||
|   | 3548e6da73 | ||
|   | d2a1db8834 | ||
|   | 0b003bb895 | ||
|   | ebcd60d0b3 | ||
|   | a9a31b206b | ||
|   | a56df823f1 | ||
|   | fbec4718f8 | ||
|   | 911cca9c99 | ||
|   | abb021e51e | ||
|   | 03ee7e05d5 | ||
|   | 02426c50cb | ||
|   | 477acddf64 | ||
|   | 1d04ea62ba | ||
|   | 10c1903c72 | ||
|   | 69dfd07a7f | ||
|   | bc9b923d5c | ||
|   | fef32fb0d4 | ||
|   | 0e9491a415 | ||
|   | c7725ddf2a | ||
|   | 5c7ea17abd | ||
|   | c6a6d057a8 | ||
|   | ed4fb0695e | ||
|   | addac8825d | ||
|   | 8e74880b55 | ||
|   | 6891ce95dc | ||
|   | b7e62d3ca5 | ||
|   | 27a0b8f87a | ||
|   | 21e94ed109 | ||
|   | 0fe5c4f957 | ||
|   | 75f5d59d53 | ||
|   | 1db95bc32b | ||
|   | 93a8933282 | ||
|   | 5a63aaa5ac | ||
|   | a3eb5e562a | ||
|   | 8a76383eca | ||
|   | 734deeb17c | ||
|   | f8b4c28278 | ||
|   | 3e179c07bc | ||
|   | 56aae17b46 | ||
|   | 78741846a4 | ||
|   | 55180f5bb3 | ||
|   | 62b884dd42 | ||
|   | 3283018bfb | ||
|   | 55226ada8a | ||
|   | ff790f7b39 | ||
|   | 899570d213 | ||
|   | 3b2506851c | ||
|   | 9b88059e55 | ||
|   | 59168b2c64 | ||
|   | 47144253e4 | ||
|   | d8c66077f0 | ||
|   | 59a01137e1 | ||
|   | ce3804ee04 | ||
|   | f0bc53ce5a | ||
|   | b8938e9d4d | ||
|   | 7116d9cedb | ||
|   | 66fb86fd0c | ||
|   | 59cfbb07c8 | ||
|   | dc5bc3fea8 | ||
|   | fbbc32422e | ||
|   | fe8829f324 | ||
|   | b4036e061a | ||
|   | 4ee9f3563b | ||
|   | c652a54f59 | ||
|   | 61881477ac | ||
|   | 4373916d9d | ||
|   | 660d7df5ab | ||
|   | b7e3f627f1 | ||
|   | ca5d115715 | ||
|   | 21c46852cd | ||
|   | 10036832dd | ||
|   | 25b5ea8b4f | ||
|   | 20beaf7fe1 | ||
|   | e72af50420 | ||
|   | ef4417b717 | ||
|   | cf943627e2 | ||
|   | 96543cb009 | ||
|   | fbb2207f8c | ||
|   | cce8a4341b | ||
|   | b82784ee46 | ||
|   | 6b8959916c | ||
|   | ecc1830296 | ||
|   | 497916aad7 | ||
|   | e171a31ac5 | ||
|   | a9a10aaa20 | ||
|   | 656d079ffc | ||
|   | d801f699af | ||
|   | 89d01d2c17 | ||
|   | ec284bc56a | ||
|   | db2e00d41c | ||
|   | 0a616c9fcb | ||
|   | fed3cd9e82 | ||
|   | d0d8a3d4ea | ||
|   | bdf5f88349 | ||
|   | 809dbe16d6 | ||
|   | badebfae6b | ||
|   | 6693420005 | ||
|   | 0e3aab8691 | ||
|   | 55840c626c | ||
|   | f0e5656717 | ||
|   | 8af0e10aa4 | ||
|   | 71f574bc52 | ||
|   | 2518d6138f | ||
|   | 36be084655 | ||
|   | d863182810 | ||
|   | 85c2bc29e6 | ||
|   | 4eeeb1557a | ||
|   | dd64f62b2f | ||
|   | 7b84590c71 | ||
|   | 2601b30c7e | ||
|   | d38f89636a | ||
|   | caf6c650a6 | ||
|   | e285628cd7 | ||
|   | d253580d14 | ||
|   | 4edfafb61f | ||
|   | c07957d6ec | ||
|   | 423bd70238 | ||
|   | 2fc9e1af58 | ||
|   | baa6d808c2 | ||
|   | 1e1c26c91a | ||
|   | eba27a7e05 | ||
|   | 4009267c2b | ||
|   | 8a370c0094 | ||
|   | abe0701ce7 | ||
|   | eef6570962 | ||
|   | a2c7c8f26a | ||
|   | 91ce46f6f3 | ||
|   | c5ebe75424 | ||
|   | 08161078f4 | ||
|   | 9def55914c | ||
|   | f044eda079 | ||
|   | 4883b96e0d | ||
|   | ca6a1aac2b | ||
|   | cc3f6c5ca9 | ||
|   | cacdaa0067 | ||
|   | 016e2aec8e | ||
|   | 9c5416d598 | ||
|   | 5f50bc6380 | ||
|   | e44aef6d5a | ||
|   | 2ff904915e | ||
|   | 565c04b989 | ||
|   | 7dfc8fd446 | ||
|   | f96dc97c4f | ||
|   | 40163c737c | ||
|   | 6327b8d15a | ||
|   | 3053cc0de4 | ||
|   | 0b89e34439 | ||
|   | c5bf60eab4 | ||
|   | bdbb852163 | ||
|   | 4a11f126cd | ||
|   | 03f736607b | ||
|   | 5aa3a288dc | ||
|   | ddf566a3c4 | ||
|   | d50ea010ef | ||
|   | 9678a412e2 | ||
|   | 46f4ea7ed7 | ||
|   | e3b1c2dea0 | ||
|   | 5cbac5bf23 | ||
|   | 7050b97d94 | ||
|   | 23e9947f7a | ||
|   | fc605d2561 | ||
|   | ab4c929a07 | ||
|   | c251ab5092 | ||
|   | 57258dc1d4 | ||
|   | f1df49ad17 | ||
|   | 9d8e7371fb | ||
|   | 84a1b394a1 | ||
|   | 4ea8b91e0b | ||
|   | 8e1e0fc344 | ||
|   | 7186d0ce55 | ||
|   | 6393789345 | ||
|   | 2a5c2aa404 | ||
|   | d0210c1a97 | ||
|   | 691c107ce9 | ||
|   | 5b4924c76e | ||
|   | a292d21b6c | ||
|   | 576cd87a5b | ||
|   | e74ed92993 | ||
|   | eeed3d605b | ||
|   | a3037a6dd1 | ||
|   | 207fdd4a34 | ||
|   | cb242318d4 | ||
|   | 29cd09a6ca | ||
|   | 54fc2daa46 | ||
|   | a4cc394c22 | ||
|   | 0a0bcf65ad | ||
|   | d36f544069 | ||
|   | d99c0ad384 | ||
|   | 387b53977d | ||
|   | c63e5f755f | ||
|   | 7476419940 | ||
|   | 25ad3486a4 | ||
|   | 9198de7d45 | ||
|   | 88b2b6cb83 | ||
|   | 8a0b1ceb4c | ||
|   | 54d18c0196 | ||
|   | e24f0a77c4 | ||
|   | 7fc9a807a0 | ||
|   | fdfde62a33 | ||
|   | 4366687b95 | ||
|   | f28fed51da | ||
|   | 2b940f6aba | ||
|   | f42682711b | ||
|   | ad159d3ebd | ||
|   | faa3e2d04d | ||
|   | 604a79ad98 | ||
|   | ce0c6b8d9f | ||
|   | 9552ec89fb | ||
|   | 3a7c1e7b6c | ||
|   | 6980256a42 | ||
|   | 3f2dcf1698 | ||
|   | 44097c1b37 | ||
|   | 551b188c01 | ||
|   | 3a786542c4 | ||
|   | bb2df9b2c6 | ||
|   | 7d1e149905 | ||
|   | 1dcd52838b | 
							
								
								
									
										32
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -22,7 +22,7 @@ missing | ||||
| src/50-mutter-navigation.xml | ||||
| src/50-mutter-system.xml | ||||
| src/50-mutter-windows.xml | ||||
| src/mutter-wm.desktop | ||||
| src/mutter.desktop | ||||
| src/mutter-wayland.desktop | ||||
| *.o | ||||
| *.a | ||||
| @@ -46,9 +46,8 @@ POTFILES | ||||
| po/*.pot | ||||
| 50-metacity-desktop-key.xml | ||||
| 50-metacity-key.xml | ||||
| libmutter-wayland.pc | ||||
| mutter-wayland | ||||
| mutter-launch | ||||
| libmutter.pc | ||||
| mutter | ||||
| org.gnome.mutter.gschema.valid | ||||
| org.gnome.mutter.gschema.xml | ||||
| org.gnome.mutter.wayland.gschema.valid | ||||
| @@ -56,6 +55,7 @@ org.gnome.mutter.wayland.gschema.xml | ||||
| testasyncgetprop | ||||
| testboxes | ||||
| testgradient | ||||
| m4/* | ||||
| mutter-grayscale | ||||
| mutter-mag | ||||
| mutter-message | ||||
| @@ -75,15 +75,15 @@ src/mutter-enum-types.[ch] | ||||
| src/stamp-mutter-enum-types.h | ||||
| src/mutter-marshal.[ch] | ||||
| src/stamp-mutter-marshal.h | ||||
| src/meta-dbus-xrandr.[ch] | ||||
| src/meta-dbus-display-config.[ch] | ||||
| src/meta-dbus-idle-monitor.[ch] | ||||
| src/mutter-plugins.pc | ||||
| src/wayland/gtk-shell-protocol.c | ||||
| src/wayland/gtk-shell-server-protocol.h | ||||
| src/wayland/xdg-shell-protocol.c | ||||
| src/wayland/xdg-shell-server-protocol.h | ||||
| src/wayland/xserver-protocol.c | ||||
| src/wayland/xserver-server-protocol.h | ||||
| src/meta-dbus-login1.[ch] | ||||
| src/gtk-shell-protocol.c | ||||
| src/gtk-shell-server-protocol.h | ||||
| src/xdg-shell-protocol.c | ||||
| src/xdg-shell-server-protocol.h | ||||
| src/xserver-protocol.c | ||||
| src/xserver-server-protocol.h | ||||
| doc/reference/*.args | ||||
| doc/reference/*.bak | ||||
| doc/reference/*.hierarchy | ||||
| @@ -101,3 +101,11 @@ doc/reference/meta-undocumented.txt | ||||
| doc/reference/meta-unused.txt | ||||
| doc/reference/meta-docs.sgml | ||||
| doc/reference/meta.types | ||||
| gtk-doc.m4 | ||||
| intltool.m4 | ||||
| libtool.m4 | ||||
| ltoptions.m4 | ||||
| ltsugar.m4 | ||||
| ltversion.m4 | ||||
| lt~obsolete.m4 | ||||
| .dirstamp | ||||
|   | ||||
							
								
								
									
										159
									
								
								COMPLIANCE
									
									
									
									
									
								
							
							
						
						
									
										159
									
								
								COMPLIANCE
									
									
									
									
									
								
							| @@ -1,159 +0,0 @@ | ||||
| Metacity Standards Compliance | ||||
| ============================= | ||||
| $Id$ | ||||
|  | ||||
| 1) Introduction | ||||
| 2) EWMH Compliance | ||||
|   a. Root Window Properties | ||||
|   b. Root Window Messages | ||||
|   c. Application Window Properties | ||||
|   d. Window Manager Protocols | ||||
| 3) ICCCM Compliance | ||||
|  | ||||
| 1) Introduction | ||||
| --------------- | ||||
|  | ||||
| This document details metacity compliance with the relevent standards. | ||||
| The format of this document is as follows: | ||||
|  | ||||
| [-/+?] Hint Name/Feature Name (Version number) | ||||
|        Errata/Comments | ||||
|  | ||||
| The first character indicates the level of compliance as follows: | ||||
|     -   none | ||||
|     /   partial | ||||
|     +   complete | ||||
|     ?   unknown | ||||
|  | ||||
| The title indicates a feature or a hint in the specification, and the | ||||
| version number indicates the minimum version of the specification | ||||
| supported by metacity.  Later versions may be supported if no | ||||
| incompatible changes have been made in the specification. | ||||
|  | ||||
| 2) EWMH Compliance | ||||
| ------------------ | ||||
|  | ||||
| The EWMH, or Extended Window Manager Hints is a freedesktop.org- | ||||
| developed standard to support a number of conventions for | ||||
| communication between the window manager and clients.  It builds on | ||||
| and extends the ICCCM (See Section 3).  A copy of the current EWMH | ||||
| standard is available at http://freedesktop.org/Standards/wm-spec/ | ||||
|  | ||||
|   a. Root Window Properties | ||||
|   ------------------------- | ||||
|  | ||||
| + _NET_SUPPORTED (1.3) | ||||
|  | ||||
| + _NET_CLIENT_LIST (1.3) | ||||
|  | ||||
| + _NET_NUMBER_OF_DESKTOPS (1.3) | ||||
|  | ||||
| + _NET_DESKTOP_GEOMETRY (1.3) | ||||
|   Metacity does not implement large desktops, so this is kept set to | ||||
|   the screen size. | ||||
|  | ||||
| + _NET_DESKTOP_VIEWPORT (1.3) | ||||
|   Metacity does not implement viewports, so this is a constant (0,0). | ||||
|  | ||||
| + _NET_CURRENT_DESKTOP (1.3) | ||||
|  | ||||
| + _NET_DESKTOP_NAMES (1.3) | ||||
|  | ||||
| + _NET_ACTIVE_WINDOW (1.3) | ||||
|  | ||||
| + _NET_WORKAREA (1.3) | ||||
|  | ||||
| + _NET_SUPPORTING_WM_CHECK (1.3) | ||||
|  | ||||
| + _NET_VIRTUAL_ROOTS (1.3) | ||||
|   Metacity does not read or set this property, but it does not use | ||||
|   virtual roots to implement virtual desktops, so it complies with the | ||||
|   specification. | ||||
|  | ||||
| + _NET_DESKTOP_LAYOUT (1.3) | ||||
|  | ||||
| + _NET_SHOWING_DESKTOP (1.3) | ||||
|  | ||||
|   b. Root Window Messages | ||||
|   ----------------------- | ||||
|  | ||||
| + _NET_CLOSE_WINDOW (1.3) | ||||
|  | ||||
| - _NET_MOVERESIZE_WINDOW (1.3) | ||||
|   Metacity supports this message, but the specification is unclear on | ||||
|   the layout of the detail value, and as such it is #if 0'd in the code | ||||
|  | ||||
| + _NET_WM_MOVERESIZE (1.3) | ||||
|  | ||||
| - _NET_RESTACK_WINDOW (1.3) | ||||
|   Metacity will raise or lower windows in response to this message, | ||||
|   but the sibling restack modes are not supported, and it is currently | ||||
|   #if 0'd in the code. | ||||
|  | ||||
| + _NET_REQUEST_FRAME_EXTENTS (1.3)   | ||||
|  | ||||
|   c. Application Window Properties | ||||
|   -------------------------------- | ||||
|  | ||||
| + _NET_WM_NAME (1.3) | ||||
|  | ||||
| + _NET_WM_VISIBLE_NAME (1.3) | ||||
|   Metacity does not set this property, but metacity will never display | ||||
|   a name different from _NET_WM_NAME | ||||
|  | ||||
| + _NET_WM_ICON_NAME (1.3) | ||||
|  | ||||
| + _NET_WM_VISIBLE_ICON_NAME (1.3) | ||||
|   Metacity does not set this property, but metacity will never display | ||||
|   a name different from _NET_WM_NAME | ||||
|  | ||||
| + _NET_WM_DESKTOP (1.3) | ||||
|  | ||||
| + _NET_WM_WINDOW_TYPE (1.3) | ||||
|  | ||||
| / _NET_WM_STATE (1.3) | ||||
|   This property is read and updated according to the specification, | ||||
|   but see caveat below. | ||||
|   Metacity does not recognize separate vertical and horizontal | ||||
|   maximization states.  Currently metacity will do a two-dimensional | ||||
|   maximization if either property is set. | ||||
|   See: http://bugzilla.gnome.org/show_bug.cgi?id=113601 | ||||
|   Metacity doesn't implement viewports so _NET_WM_STATE_STICKY is | ||||
|   unimplemented. | ||||
|  | ||||
| + _NET_WM_ALLOWED_ACTIONS (1.3) | ||||
|   Metacity keeps this hint up to date.  The code is somewhat crufty | ||||
|   and should be rewritten, though it is functional. | ||||
|   See: http://bugzilla.gnome.org/show_bug.cgi?id=90420 | ||||
|  | ||||
| + _NET_WM_STRUT (1.3) | ||||
|  | ||||
| + _NET_WM_STRUT_PARTIAL (1.3) | ||||
|  | ||||
| + _NET_WM_ICON_GEOMETRY (1.3) | ||||
|   Metacity uses this property to draw minimize/restore animations | ||||
|  | ||||
| + _NET_WM_ICON (1.3) | ||||
|  | ||||
| + _NET_WM_PID (1.3) | ||||
|  | ||||
| + _NET_WM_HANDLED_ICONS (1.3) | ||||
|   Metacity does not read or set this property.  However, metacity | ||||
|   never manages iconified windows, and so has no need to do so. | ||||
|  | ||||
| + _NET_WM_USER_TIME (1.3) | ||||
|   Metacity uses this property to prevent applications from stealing | ||||
|   focus if supported by the toolkit. | ||||
|  | ||||
| + _NET_FRAME_EXTENTS (1.3) | ||||
|   If set in response to a _NET_REQUEST_FRAME_EXTENTS message received | ||||
|   prior to the window being mapped, this may be an estimate.  This is, | ||||
|   however, expressly allowed by the specification. | ||||
|  | ||||
|   d. Window Manager Protocols | ||||
|   --------------------------- | ||||
| + _NET_WM_PING (1.3) | ||||
|  | ||||
| 3) ICCCM Compliance | ||||
| ------------------- | ||||
| TODO | ||||
							
								
								
									
										298
									
								
								HACKING
									
									
									
									
									
								
							
							
						
						
									
										298
									
								
								HACKING
									
									
									
									
									
								
							| @@ -1,298 +0,0 @@ | ||||
| Intro... | ||||
|  | ||||
| Window managers have a few ways in which they are significantly different | ||||
| from other applications.  This file, combined with the code overview in | ||||
| doc/code-overview.txt, should hopefully provide a series of relatively | ||||
| quick pointers (hopefully only a few minutes each) to some of the places | ||||
| one can look to orient themselves and get started.  Some of this will be | ||||
| general to window managers on X, much will be specific to Metacity, and | ||||
| there's probably some information that's common to programs in general but | ||||
| is nonetheless useful. | ||||
|  | ||||
| Overview | ||||
|   Administrative issues | ||||
|   Minimal Building/Testing Environment | ||||
|   Relevant standards and X properties | ||||
|   Debugging and testing | ||||
|     Debugging logs | ||||
|     Adding information to the log | ||||
|     Valgrind | ||||
|     Testing Utilities | ||||
|   Technical gotchas to keep in mind | ||||
|   Other important reading | ||||
|     Extra reading | ||||
|     Ideas for tasks to work on | ||||
|  | ||||
|  | ||||
| Administrative issues | ||||
|   Don't commit substantive code in here without asking hp@redhat.com. | ||||
|   Adding translations, no-brainer typo fixes, etc. is fine. | ||||
|  | ||||
|   The code could use cleanup in a lot of places, feel free to do so. | ||||
|  | ||||
|   See http://developer.gnome.org/dotplan/for_maintainers.html for | ||||
|   information on how to make a release.  The only difference from those | ||||
|   instructions is that the minor version number of a Metacity release | ||||
|   should always be a number from the Fibonacci sequence. | ||||
|  | ||||
| Minimal Building/Testing Environment | ||||
|   You do not need to _install_ a development version of Metacity to | ||||
|   build, run and test it; you can run it from some temporary | ||||
|   directory.  Also, you do not need to build all of Gnome in order to | ||||
|   build a development version of Metacity -- odds are, you may be able | ||||
|   to build metacity from CVS without building any other modules. | ||||
|  | ||||
|   As long as you have gtk+ >= 3.0 and GIO >= 2.25.10 with your distro | ||||
|   (gtk+ >= 2.6 if you manually revert the change from bug 348633), you | ||||
|   should be able to install your distro's development packages | ||||
|   (e.g. gtk2-devel, glib-devel, startup-notification-devel on | ||||
|   Fedora; also, remember to install the gnome-common package which is | ||||
|   needed for building cvs versions of Gnome modules like Metacity) as | ||||
|   well as the standard development tools (gcc, autoconf, automake, | ||||
|   pkg-config, intltool, and libtool) and be ready to build and test | ||||
|   Metacity.  Steps to do so: | ||||
|  | ||||
|   $ svn checkout http://svn.gnome.org/svn/metacity/trunk metacity | ||||
|   $ cd metacity | ||||
|   $ ./autogen.sh --prefix /usr | ||||
|   $ make | ||||
|   $ ./src/metacity --replace | ||||
|  | ||||
|   Again, note that you do not need to run 'make install'. | ||||
|  | ||||
| Relevant standards and X properties | ||||
|   There are two documents that describe some basics about how window | ||||
|   managers should behave: the ICCCM (Inter-Client Communication Conventions | ||||
|   Manual) and EWMH (Extended Window Manager Hints).  You can find these at | ||||
|   the following locations: | ||||
|     ICCCM - http://tronche.com/gui/x/icccm/ | ||||
|     EWMH  - :pserver:anoncvs@pdx.freedesktop.org:/cvs | ||||
|   The ICCCM is usually available in RPM or DEB format as well.  There is | ||||
|   actually an online version of the EWMH, but it is almost always woefully | ||||
|   out of date.  Just get it from cvs with these commands (the backslash | ||||
|   means include the stuff from the next line): | ||||
|     cvs -d :pserver:anoncvs@cvs.freedesktop.org:/cvs/icccm-extensions login | ||||
|     cvs -d :pserver:anoncvs@cvs.freedesktop.org:/cvs/icccm-extensions \ | ||||
|       checkout wm-spec | ||||
|  | ||||
|   DO NOT GO AND READ THOSE THINGS.  THEY ARE REALLY, REALLY BORING. | ||||
|  | ||||
|   If you do, you'll probably end up catching up on your sleep instead of | ||||
|   hacking on Metacity. ;-)  Instead, just look at the table of contents and | ||||
|   glance at a page or two to get an idea of what's in there.  Then only | ||||
|   refer to it if you see something weird in the code and you don't know | ||||
|   what it is but has some funny looking name like you see in one of those | ||||
|   two documents. | ||||
|  | ||||
|   You can refer to the COMPLIANCE file for additional information on these | ||||
|   specifications and Metacity's compliance therewith. | ||||
|  | ||||
|   One of the major things those documents cover that are useful to learn | ||||
|   about immediately are X properties.  The right way to learn about those, | ||||
|   though, is through hand on experimentation with the xprop command (and | ||||
|   then look up things you find from xprop in those two manuals if you're | ||||
|   curious enough).  First, try running | ||||
|     xprop | ||||
|   in a terminal and click on one of the windows on your screen.  That gives | ||||
|   you the x properties for that window.  Look through them and get a basic | ||||
|   idea of what's there for kicks.  Note that you can get rid of some of the | ||||
|   verboseness by grepping out the _NET_WM_ICON stuff, i.e. | ||||
|     xprop | grep -v _NET_WM_ICON | ||||
|   Next, try running | ||||
|     xprop -root | ||||
|   in a terminal.  There's all the properties of the root window (which you | ||||
|   can think of as the "main" Xserver window).  You can also manually | ||||
|   specify individual windows that you want the properties of with | ||||
|     xprop -id <id> | ||||
|   if you know the id of the window in question.  You can get the id of a | ||||
|   given window by either running xwininfo, e.g. | ||||
|     xwininfo | grep "Window id" | cut -f 4 -d ' ' | ||||
|   or by looking at the _NET_CLIENT_STACKING property of the root | ||||
|   window.  Finally, it can also be useful to add "-spy" (without the | ||||
|   quotes) to the xprop command to get it to continually monitor that | ||||
|   window and report any changes to you. | ||||
|  | ||||
| Debugging information | ||||
|   Trying to run a window manager under a typical debugger, such as gdb, | ||||
|   unfortunately just doesn't work very well.  So, we have to resort to | ||||
|   other methods. | ||||
|  | ||||
|   Debugging logs | ||||
|  | ||||
|   First, note that you can start a new version of metacity to replace the | ||||
|   existing one by running | ||||
|     metacity --replace | ||||
|   (which also comes in handy in the form "./src/metacity --replace" when | ||||
|   trying to quickly test a small change while hacking on metacity without | ||||
|   doing a full "make install", though I'm going off topic...)  This will | ||||
|   allow you to see any warnings printed at the terminal.  Sometimes it's | ||||
|   useful to have these directed to a logfile instead, which you can do by | ||||
|   running | ||||
|     METACITY_USE_LOGFILE=1 metacity --replace | ||||
|   The logfile it uses will be printed in the terminal.  Sometimes, it's | ||||
|   useful to get more information than just warnings.  You can set | ||||
|   METACITY_VERBOSE to do that, like so: | ||||
|     METACITY_VERBOSE=1 METACITY_USE_LOGFILE=1 metacity --replace | ||||
|   (note that METACITY_VERBOSE=1 can be problematic without | ||||
|   METACITY_USE_LOGFILE=1; avoid it unless running in from something that | ||||
|   won't be managed by the new Metacity--see bug 305091 for more details). | ||||
|   There are also other flags, such as METACITY_DEBUG, most of which I | ||||
|   haven't tried and don't know what they do.  Go to the source code | ||||
|   directory and run | ||||
|     grep "METACITY_" * | grep getenv | ||||
|   to find out what the other ones are. | ||||
|  | ||||
|   Adding information to the log | ||||
|  | ||||
|   Since we can't single step with a debugger, we often have to fall back to | ||||
|   the primitive method of getting information we want to know: adding | ||||
|   "print" statements.  Metacity has a fairly structured way to do this, | ||||
|   using the functions meta_warning, meta_topic, and meta_verbose.  All | ||||
|   three have the same basic format as printf, except that meta_topic also | ||||
|   takes a leading enumeration parameter to specify the type of message | ||||
|   being shown (makes it easier for grepping in a verbose log).  You'll find | ||||
|   tons of examples in the source code if you need them; just do a quick | ||||
|   grep or look in most any file.  Note that meta_topic and meta_verbose | ||||
|   messages only appear if verbosity is turned on.  I tend to frequently add | ||||
|   temporary meta_warning statements (or switch meta_topic or meta_verbose | ||||
|   ones to meta_warning ones) and then undo the changes once I've learned | ||||
|   the info that I needed. | ||||
|  | ||||
|   There is also a meta_print_backtrace (which again is only active if | ||||
|   verbosity is turned on) that can also be useful if you want to learn how | ||||
|   a particular line of code gets called.  And, of course, there's always | ||||
|   g_assert if you want to make sure some section isn't executed (or isn't | ||||
|   executed under certain conditions). | ||||
|  | ||||
|   Valgrind | ||||
|  | ||||
|   Valgrind is awesome for finding memory leaks or corruption and | ||||
|   uninitialized variables.  But I also tend to use it in a non-traditional | ||||
|   way as a partial substitute for a normal debugger: it can provide me with | ||||
|   a stack trace of where metacity is crashing if I made a change that | ||||
|   caused it to do so, which is one of the major uses of debuggers.  (And, | ||||
|   what makes it cooler than a debugger is that there will also often be | ||||
|   warnings pinpointing the cause of the crash from either some kind of | ||||
|   simple memory corruption or an uninitialized variable).  Sometimes, when | ||||
|   I merely want to know what is calling a particular function I'll just | ||||
|   throw in an "int i; printf("%d\n", i);" just because valgrind will give | ||||
|   me a full stacktrace whenever it sees that uninitialized variable being | ||||
|   used (yes, I could use meta_print_backtrace, but that means I have to | ||||
|   turn verbosity on). | ||||
|  | ||||
|   To run metacity under valgrind, use options typical for any Gnome | ||||
|   program, such as | ||||
|     valgrind --log-file=metacity.log --tool=memcheck --num-callers=48 \ | ||||
|     --leak-check=yes --leak-resolution=high --show-reachable=yes     \ | ||||
|     ./src/metacity --replace | ||||
|   where, again, the backslashes mean to join all the stuff on the following | ||||
|   line with the previous one. | ||||
|  | ||||
|   However, there is a downside.  Things run a little bit slowly, and it | ||||
|   appears that you'll need about 1.5GB of ram, which unfortunately prevents | ||||
|   most people from trying this. | ||||
|  | ||||
|   Testing Utilities | ||||
|  | ||||
|   src/run-metacity.sh | ||||
|     The script src/run-metacity.sh is useful to hack on the window manager.  | ||||
|     It runs metacity in an Xnest. e.g.: | ||||
|       CLIENTS=3 ./run-metacity.sh | ||||
|     or  | ||||
|       DEBUG=memprof ./run-metacity.sh | ||||
|     or | ||||
|       DEBUG_TEST=1 ./run-metacity-sh | ||||
|     or whatever. | ||||
|  | ||||
|   metacity-message | ||||
|     The tool metacity-message can be used as follows: | ||||
|       metacity-message reload-theme | ||||
|       metacity-message restart | ||||
|       metacity-message enable-keybindings | ||||
|       metacity-message disable-keybindings | ||||
|     The first of these is useful for testing themes, the second is just | ||||
|     another way (besides the --restart flag to metacity itself) of | ||||
|     restarting metacity, and the third is useful for testing Metacity when | ||||
|     running it under an Xnest (typically, the Metacity under the Xnest | ||||
|     wouldn't get keybinding notifications--making keyboard navigation not | ||||
|     work--but if you disable the keybindings for the global Metacity then | ||||
|     the Metacity under the Xnest can then get those keybinding notifications). | ||||
|  | ||||
|   metacity-window-demo | ||||
|     metacity-window-demo is good for trying behavior of various kinds | ||||
|     of window without launching a full desktop. | ||||
|  | ||||
| Technical gotchas to keep in mind | ||||
|   Files that include gdk.h or gtk.h are not supposed to include | ||||
|   display.h or window.h or other core files.  Files in the core | ||||
|   (display.[hc], window.[hc]) are not supposed to include gdk.h or | ||||
|   gtk.h.  Reasons: | ||||
|  | ||||
|     "Basically you don't want GDK most of the time. It adds | ||||
|     abstractions that cause problems, because they aren't designed to | ||||
|     be used in a WM where we do weird stuff (display grabs, and just | ||||
|     being the WM). At best GDK adds inefficiency, at worst it breaks | ||||
|     things in weird ways where you have to be a GDK guru to figure | ||||
|     them out. Owen also told me that they didn't want to start adding | ||||
|     a lot of hacks to GDK to let a WM use it; we both agreed back in | ||||
|     the mists of time that metacity would only use it for the "UI" | ||||
|     bits as it does. | ||||
|  | ||||
|     Having the split in the source code contains and makes very clear | ||||
|     the interface between the WM and GDK/GTK. This keeps people from | ||||
|     introducing extra GDK/GTK usage when it isn't needed or | ||||
|     appropriate. Also, it speeds up the compilation a bit, though this | ||||
|     was perhaps more relevant 5 years ago than it is now. | ||||
|  | ||||
|     There was also a very old worry that the GDK stuff might have to | ||||
|     be in a separate process to work right; that turned out to be | ||||
|     untrue. Though who knows what issues the CM will introduce." | ||||
|  | ||||
|   Remember that strings stored in X properties are not in UTF-8, and they | ||||
|   have to end up in UTF-8 before we try putting them through Pango. | ||||
|  | ||||
|   If you make any X request involving a client window, you have to | ||||
|   meta_error_trap_push() around the call; this is not necessary for X | ||||
|   requests on the frame windows. | ||||
|  | ||||
|   Remember that not all windows have frames, and window->frame can be NULL. | ||||
|  | ||||
| Other important reading & where to get started | ||||
|   Extra reading | ||||
|  | ||||
|   There are some other important things to read to get oriented as well. | ||||
|   These are: | ||||
|     http://pobox.com/~hp/features.html | ||||
|     rationales.txt | ||||
|     doc/code-overview.txt | ||||
|  | ||||
|   It pays to read http://pobox.com/~hp/features.html in order | ||||
|   to understand the philosophy of Metacity. | ||||
|  | ||||
|   The rationales.txt file has two things: (1) a list of design choices with | ||||
|   links in the form of bugzilla bugs that discuss the issue, and (2) a list | ||||
|   outstanding bug categories, each of which is tracked by a particular | ||||
|   tracker bug in bugzilla from which you can find several closely related | ||||
|   bug reports. | ||||
|  | ||||
|   doc/code-overview.txt provides a fairly good overview of the code, | ||||
|   including coverage of the function of the various files, the main | ||||
|   structures and their relationships, and places to start looking in the | ||||
|   code tailored to general categories of tasks. | ||||
|  | ||||
|   Ideas for tasks to work on | ||||
|  | ||||
|   There are a variety of things you could work on in the code.  You may | ||||
|   have ideas of your own, but in case you don't, let me provide a list of | ||||
|   ideas you could choose from: | ||||
|  | ||||
|   If you're ambitious, there's a list of things Havoc made that he'd really | ||||
|   like to see tackled, which you can find at | ||||
|   http://log.ometer.com/2004-05.html.  Be sure to double check with someone | ||||
|   to make sure the item is still relevant if you're interested in one of | ||||
|   these.  Another place to look for ideas, of course, is bugzilla.  One can | ||||
|   just do queries and look for things that look fixable. | ||||
|  | ||||
|   However, perhaps the best way of getting ideas of related tasks to work | ||||
|   on, is to look at the second half of the rationales.txt file, which tries | ||||
|   to group bugs by type. | ||||
| @@ -1,8 +0,0 @@ | ||||
| Tomas Frydrych | ||||
| Email: tf linux intel com | ||||
| Userid: tomasf | ||||
|  | ||||
| Owen Taylor | ||||
| Email: otaylor redhat com | ||||
| Userid: otaylor | ||||
|  | ||||
| @@ -1,43 +0,0 @@ | ||||
| Currently active maintainers | ||||
| -------------------------------- | ||||
|  | ||||
| Elijah Newren | ||||
| Email: newren gmail com | ||||
| Userid: newren | ||||
|  | ||||
|   - Usually won't touch the theme bugs (isn't interested) or the | ||||
|     compositor (until open source nvidia drivers are up to snuff). | ||||
|     Tends to be most interested in libwnck/gtk interactions, focus | ||||
|     issues, constraints problems, and raising/stacking, but works on | ||||
|     just about anything other than themes and the compositor. | ||||
|  | ||||
| Thomas Thurman | ||||
| Email: thomas thurman org uk | ||||
| Userid: tthurman | ||||
|  | ||||
|   - Responsible for all theme bugs and the compositor (thank goodness | ||||
|     Thomas got involved, eh?).  I'm sure he'll replace this sentence | ||||
|     with his interests when he reads it.  ;-) | ||||
|  | ||||
|  | ||||
| Semi-active maintainers | ||||
| -------------------------------- | ||||
|  | ||||
| Havoc Pennington | ||||
| Email: hp  redhat com | ||||
| Userid: hp | ||||
|   - Original author.  Doesn't patch metacity anymore, but is active in | ||||
|     answering questions, responding to bugs, providing very helpful | ||||
|     suggestions and insight, and even assisting with debugging. | ||||
|  | ||||
|  | ||||
| Important historical figureheads | ||||
| -------------------------------- | ||||
|  | ||||
| Rob Adams (readams  readams net) | ||||
|   - Was the main maintainer of metacity for a while; particular areas | ||||
|     of focus included xinerama, placement, and an older version of the | ||||
|     constraints code.  Still responds to bugs every once in a while. | ||||
|  | ||||
| Søren Sandmann (sandmann  redhat com) | ||||
|   - Wrote most of the current compositing manager code + libcm | ||||
| @@ -1,7 +1,7 @@ | ||||
|  | ||||
| SUBDIRS=src protocol po doc | ||||
| SUBDIRS=src po doc | ||||
|  | ||||
| EXTRA_DIST = HACKING MAINTAINERS rationales.txt | ||||
| ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} | ||||
|  | ||||
| DISTCLEANFILES = intltool-extract intltool-merge intltool-update po/stamp-it po/.intltool-merge-cache | ||||
|  | ||||
|   | ||||
							
								
								
									
										67
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										67
									
								
								NEWS
									
									
									
									
									
								
							| @@ -1,3 +1,70 @@ | ||||
| 3.13.2 | ||||
| ====== | ||||
| * Add basic HiDPI support on wayland [Adel; #728902] | ||||
| * Fix crash when monitors change during suspend [Giovanni; #725637] | ||||
| * Replace mutter-launch with logind integration [Jasper; #724604] | ||||
| * Move window menu into the compositor [Jasper; #726352] | ||||
| * Fix delayed focus-follows-mouse support [Florian; #730541] | ||||
| * Support fallback app menu in window decorations [Florian; #730752] | ||||
| * Misc. bug fixes and cleanups [Giovanni, Jonas, Jasper; #729732, #729602, | ||||
|   #726714] | ||||
|  | ||||
| Contributors: | ||||
|   Jonas Ådahl, Giovanni Campagna, Adel Gadllah, Florian Müllner, | ||||
|   Jasper St. Pierre, Rico Tzschichholz | ||||
|  | ||||
| Translations: | ||||
|   Pau Iranzo [ca], Daniel Mustieles [es] | ||||
|  | ||||
| 3.13.1 | ||||
| ====== | ||||
| * Fix opacity values from _NET_WM_WINDOW_OPACITY [Nirbheek; #727874] | ||||
| * Merge wayland branch [Jasper, Giovanni, Robert B., Neil, Adel, Rui, Jonas, | ||||
|   Lionel, Tim, Owen, Florian, Colin W., Cosimo, Ray, Kalev, Pavel, Robert A., | ||||
|   Magdalen, Marek, Matthias, Alban, Seán, Daniel, Stefano, Carlos, Colin G., | ||||
|   Andreas, Alexander, Ryan, Marc-André, Asad, Alberto, Bastien, Hans, | ||||
|   Debarshi, Sindhu, Andika, Rico, Olav] | ||||
| * Don't prevent workspace switches for present_with_time() [Florian; #728018] | ||||
| * Add shortcuts for switching to the last workspace [Elad; #659288] | ||||
| * Make move/resize menu items behave like the keybindings [Jasper; #728617] | ||||
| * Misc. bug fixes and cleanups  [Jasper, Bastien, Florian, Adel; #720631, | ||||
|   #727979, #728423, #728395, #729044] | ||||
|  | ||||
| Contributors: | ||||
|   Jonas Ådahl, Elad Alfassa, Robert Ancell, Magdalen Berns, Robert Bragg, | ||||
|   Giovanni Campagna, Cosimo Cecchi, Marek Chalupa, Nirbheek Chauhan, | ||||
|   Matthias Clasen, Alban Crequy, Seán de Búrca, Daniel Drake, Jason Ekstrand, | ||||
|   Stefano Facchini, Adel Gadllah, Carlos Garnacho, Colin Guthrie, | ||||
|   Andreas Heider, Lionel Landwerlin, Alexander Larsson, Kalev Lember, | ||||
|   Ryan Lortie, Tim Lunn, Marc-André Lureau, Rui Matos, Asad Mehmood, | ||||
|   Alberto Milone, Florian Müllner, Bastien Nocera, Hans Petter Jansson, | ||||
|   Debarshi Ray, Neil Roberts, Sindhu S, Jasper St. Pierre, Ray Strode, | ||||
|   Andika Triwidada, Rico Tzschichholz, Pavel Vasin, Olav Vitters, | ||||
|   Colin Walters, A. Walton, Owen W. Taylor | ||||
|  | ||||
| Translations: | ||||
|   Inaki Larranaga Murgoitio [eu], marablack3 [el], Daniel Mustieles [es], | ||||
|   Fran Diéguez [gl], Yosef Or Boczko [he], Dirgita [id] | ||||
|  | ||||
| 3.12.0 | ||||
| ====== | ||||
| * Fix grab issue with SSD xwayland windows [Rui; #726123] | ||||
| * Misc. bug fixes [Jasper, Ray, Rui, Florian; #727011] | ||||
|  | ||||
| Contributors: | ||||
|   Rui Matos, Florian Müllner, Jasper St. Pierre, Ray Strode | ||||
|  | ||||
| 3.11.92 | ||||
| ======= | ||||
| * Fix identification of CSD windows [Owen; #723029] | ||||
| * Update keyboard state unconditionally [Rui; #722847] | ||||
| * Misc bug fixes and cleanups [Owen, Rui, Giovanni, Matthias, Adel, Ryan, | ||||
|   Jasper, Marek, Florian; #723580, #726123, #726683] | ||||
|  | ||||
| Contributors: | ||||
|   Giovanni Campagna, Marek Chalupa, Matthias Clasen, Adel Gadllah, Ryan Lortie, | ||||
|   Rui Matos, Florian Müllner, Jasper St. Pierre, Owen W. Taylor | ||||
|  | ||||
| 3.11.91 | ||||
| ======= | ||||
| * Don't use keysym to match keybindings [Rui; #678001] | ||||
|   | ||||
							
								
								
									
										416
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										416
									
								
								README
									
									
									
									
									
								
							| @@ -1,416 +0,0 @@ | ||||
| The original codebase named "Metacity" is not a meta-City as in an | ||||
| urban center, but rather Meta-ness as in the state of being | ||||
| meta. i.e. metacity : meta as opacity : opaque. Also it may have | ||||
| something to do with the Meta key on UNIX keyboards. | ||||
|  | ||||
| Since then, it has been renamed mutter after a rebase on top of | ||||
| clutter as a compositing manager. | ||||
|  | ||||
| COMPILING MUTTER | ||||
| === | ||||
|  | ||||
| You need GTK+ 2.2.  For startup notification to work you need | ||||
| libstartup-notification at | ||||
| http://www.freedesktop.org/software/startup-notification/ or on the | ||||
| GNOME ftp site. | ||||
| You need Clutter 1.0. You need gobject-introspection 0.6.3. | ||||
|  | ||||
| REPORTING BUGS AND SUBMITTING PATCHES | ||||
| === | ||||
|  | ||||
| Report new bugs on http://bugzilla.gnome.org. Please check for | ||||
| duplicates, *especially* if you are reporting a feature request.  | ||||
|  | ||||
| Please do *not* add "me too!" or "yes I really want this!" comments to | ||||
| feature requests in bugzilla. Please read | ||||
| http://pobox.com/~hp/features.html prior to adding any kind of flame | ||||
| about missing features or misfeatures. | ||||
|  | ||||
| Feel free to send patches too; Metacity is relatively small and | ||||
| simple, so if you find a bug or want to add a feature it should be | ||||
| pretty easy.  Send me mail, or put the patch in bugzilla. | ||||
|  | ||||
| See the HACKING file for some notes on hacking Mutter. | ||||
|  | ||||
| MUTTER FEATURES | ||||
| === | ||||
|  | ||||
|  - Uses GTK+ 2.0 for drawing window frames. This means colors, fonts,  | ||||
|    etc. come from GTK+ theme. | ||||
|  | ||||
|  - Does not expose the concept of "window manager" to the user.  Some | ||||
|    of the features in the GNOME control panel and other parts of the | ||||
|    desktop happen to be implemented in metacity, such as changing your | ||||
|    window border theme, or changing your window navigation shortcuts, | ||||
|    but the user doesn't need to know this. | ||||
|  | ||||
|  - Includes only the window manager; does not try to be a desktop | ||||
|    environment. The pager, configuration, etc. are all separate and | ||||
|    modular. The "libwnck" library (which I also wrote) is available | ||||
|    for writing metacity extensions, pagers, and so on. (But libwnck | ||||
|    isn't metacity specific, or GNOME-dependent; it requires only GTK, | ||||
|    and should work with KWin, fvwm2, and other EWMH-compliant WMs.) | ||||
|  | ||||
|  - Has a simple theme system and a couple of extra themes come with it. | ||||
|    Change themes via gsettings: | ||||
|      gsettings set org.gnome.desktop.wm.preferences theme Crux | ||||
|      gsettings set org.gnome.desktop.wm.preferences theme Gorilla | ||||
|      gsettings set org.gnome.desktop.wm.preferences theme Atlanta | ||||
|      gsettings set org.gnome.desktop.wm.preferences theme Bright | ||||
|  | ||||
|    See theme-format.txt for docs on the theme format. Use  | ||||
|    metacity-theme-viewer to preview themes. | ||||
|  | ||||
|  - Change number of workspaces via gsettings: | ||||
|      gsettings set org.gnome.desktop.wm.preferences num-workspaces 5 | ||||
|  | ||||
|    Can also change workspaces from GNOME 2 pager. | ||||
|  | ||||
|  - Change focus mode: | ||||
|      gsettings set org.gnome.desktop.wm.preferences focus-mode mouse | ||||
|      gsettings set org.gnome.desktop.wm.preferences focus-mode sloppy | ||||
|      gsettings set org.gnome.desktop.wm.preferences focus-mode click | ||||
|  | ||||
|  - Global keybinding defaults include:    | ||||
|  | ||||
|     Alt-Tab                forward cycle window focus | ||||
|     Alt-Shift-Tab          backward cycle focus | ||||
|     Alt-Ctrl-Tab           forward cycle focus among panels | ||||
|     Alt-Ctrl-Shift-Tab     backward cycle focus among panels | ||||
|     Alt-Escape             cycle window focus without a popup thingy | ||||
|     Ctrl-Alt-Left Arrow    previous workspace | ||||
|     Ctrl-Alt-Right Arrow   next workspace | ||||
|     Ctrl-Alt-D             minimize/unminimize all, to show desktop | ||||
|  | ||||
|    Change keybindings for example: | ||||
|  | ||||
|      gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-1 '[<Alt>F1]' | ||||
|     | ||||
|    Also try the GNOME keyboard shortcuts control panel. | ||||
|  | ||||
|  - Window keybindings: | ||||
|  | ||||
|     Alt-space         window menu | ||||
|  | ||||
|     Mnemonics work in the menu. That is, Alt-space then underlined | ||||
|     letter in the menu item works. | ||||
|  | ||||
|     Choose Move from menu, and arrow keys to move the window. | ||||
|  | ||||
|     While moving, hold down Control to move slower, and  | ||||
|       Shift to snap to edges. | ||||
|  | ||||
|     Choose Resize from menu, and nothing happens yet, but  | ||||
|       eventually I might implement something. | ||||
|  | ||||
|     Keybindings for things like maximize window, vertical maximize, | ||||
|     etc. can be bound, but may not all exist by default. See | ||||
|     metacity.schemas. | ||||
|  | ||||
|  - Window mouse bindings: | ||||
|  | ||||
|     Clicking anywhere on frame with button 1 will raise/focus window | ||||
|      | ||||
|     If you click a window control, such as the close button, then the  | ||||
|      control will activate on button release if you are still over it | ||||
|      on release (as with most GUI toolkits) | ||||
|  | ||||
|     If you click and drag borders with button 1 it resizes the window | ||||
|      | ||||
|     If you click and drag the titlebar with button 1 it moves the  | ||||
|      window. | ||||
|  | ||||
|     If you click anywhere on the frame with button 2 it lowers the  | ||||
|      window. | ||||
|  | ||||
|     If you click anywhere on the frame with button 3 it shows the  | ||||
|      window menu. | ||||
|  | ||||
|     If you hold down Super (windows key) and click inside a window, it | ||||
|      will move the window (buttons 1 and 2) or show menu (button 3). | ||||
|      Or you can configure a different modifier for this. | ||||
|  | ||||
|     If you pick up a window with button 1 and then switch workspaces | ||||
|      the window will come with you to the new workspace, this is  | ||||
|      a feature copied from Enlightenment. | ||||
|  | ||||
|     If you hold down Shift while moving a window, the window snaps | ||||
|      to edges of other windows and the screen. | ||||
|  | ||||
|  - Session management: | ||||
|  | ||||
|     Mutter connects to the session manager and will set itself up to | ||||
|      be respawned. It theoretically restores sizes/positions/workspace | ||||
|      for session-aware applications. | ||||
|  | ||||
|  - Mutter implements much of the EWMH window manager specification | ||||
|    from freedesktop.org, as well as the older ICCCM.  Please refer to | ||||
|    the COMPLIANCE file for information on mutter compliance with | ||||
|    these standards. | ||||
|  | ||||
|  - Uses Pango to render text, so has cool i18n capabilities.  | ||||
|    Supports UTF-8 window titles and such. | ||||
|  | ||||
|  - There are simple animations for actions such as minimization,  | ||||
|    to help users see what is happening. Should probably  | ||||
|    have a few more of these and make them nicer. | ||||
|  | ||||
|  - if you have the proper X setup, set the GDK_USE_XFT=1  | ||||
|    environment variable to get antialiased window titles. | ||||
|  | ||||
|  - considers the panel when placing windows and maximizing | ||||
|    them. | ||||
|  | ||||
|  - handles the window manager selection from the ICCCM. Will exit if | ||||
|    another WM claims it, and can claim it from another WM if you pass | ||||
|    the --replace argument. So if you're running another | ||||
|    ICCCM-compliant WM, you can run "mutter --replace" to replace it | ||||
|    with Metacity. | ||||
|  | ||||
|  - does basic colormap handling | ||||
|  | ||||
|  - and much more! well, maybe not a lot more. | ||||
|  | ||||
| HOW TO ADD EXTERNAL FEATURES | ||||
| === | ||||
|  | ||||
| You can write a mutter "plugin" such as a pager, window list, icon | ||||
| box, task menu, or even things like "window matching" using the | ||||
| Extended Window Manager Hints. See http://www.freedesktop.org for the | ||||
| EWMH specification. An easy-to-use library called "libwnck" is | ||||
| available that uses the EWMH and is specifically designed for writing | ||||
| WM accessories. | ||||
|  | ||||
| You might be interested in existing accessories such as "Devil's Pie" | ||||
| by Ross Burton, which add features to Mutter (or other | ||||
| EWMH-compliant WMs). | ||||
|  | ||||
| MUTTER BUGS, NON-FEATURES, AND CAVEATS | ||||
| === | ||||
|  | ||||
| See bugzilla: http://bugzilla.gnome.org/query.cgi | ||||
|  | ||||
| FAQ | ||||
| === | ||||
|  | ||||
| Q: Will you add my feature? | ||||
|  | ||||
| A: If it makes sense to turn on unconditionally, or is genuinely a | ||||
|    harmless preference that I would not be embarrassed to put in a | ||||
|    simple, uncluttered, user-friendly configuration dialog. | ||||
|  | ||||
|    If the only rationale for your feature is that other window | ||||
|    managers have it, or that you are personally used to it, or | ||||
|    something like that, then I will not be impressed. Metacity is | ||||
|    firmly in the "choose good defaults" camp rather than the "offer 6 | ||||
|    equally broken ways to do it, and let the user pick one" camp. | ||||
|  | ||||
|    This is part of a "no crackrock" policy, despite some exceptions | ||||
|    I'm mildly embarrassed about. For example, multiple workspaces | ||||
|    probably constitute crackrock, they confuse most users and really | ||||
|    are not that useful if you have a decent tasklist and so on. But I | ||||
|    am too used to them to turn them off.  Or alternatively | ||||
|    iconification/tasklist is crack, and workspaces/pager are good. But | ||||
|    having both is certainly a bit wrong.  Sloppy focus is probably | ||||
|    crackrock too. | ||||
|  | ||||
|    But don't think unlimited crack is OK just because I slipped up a | ||||
|    little. No slippery slope here. | ||||
|  | ||||
|    Don't let this discourage patches and fixes - I love those. ;-) | ||||
|    Just be prepared to hear the above objections if your patch adds | ||||
|    some crack-ridden configuration option. | ||||
|  | ||||
|    http://pobox.com/~hp/free-software-ui.html | ||||
|    http://pobox.com/~hp/features.html    | ||||
|  | ||||
| Q: Will Mutter be part of GNOME? | ||||
|  | ||||
| A: It is not officially part of GNOME as of GNOME 2.27. We are | ||||
|    hoping to have mutter officially included as of GNOME 2.28.  | ||||
|  | ||||
| Q: Why does Mutter remember the workspace/position of some apps  | ||||
|    but not others across logout/login? | ||||
|  | ||||
| A: Mutter only stores sizes/positions for apps that are session | ||||
|    managed. As far as I can determine, there is no way to attempt to | ||||
|    remember workspace/position for non-session-aware apps without | ||||
|    causing a lot of weird effects. | ||||
|  | ||||
|    The reason is that you don't know which non-SM-aware apps were | ||||
|    launched by the session. When you initially log in, Metacity sees a | ||||
|    bunch of new windows appear. But it can't distinguish between | ||||
|    windows that were stored in your session, or windows you just | ||||
|    launched after logging in. If Metacity tried to guess that a window | ||||
|    was from the session, it could e.g. end up maximizing a dialog, or | ||||
|    put a window you just launched on another desktop or in a weird | ||||
|    place. And in fact I see a lot of bugs like this in window managers | ||||
|    that try to handle non-session-aware apps. | ||||
|  | ||||
|    However, for session-aware apps, Mutter can tell that the | ||||
|    application instance is from the session and thus restore it | ||||
|    reliably, assuming the app properly restores the windows it had  | ||||
|    open on session save. | ||||
|     | ||||
|    So the correct way to fix the situation is to make apps | ||||
|    session-aware. libSM has come with X for years, it's very | ||||
|    standardized, it's shared by GNOME and KDE - even twm is | ||||
|    session-aware. So anyone who won't take a patch to add SM is more | ||||
|    archaic than twm - and you should flame them. ;-) | ||||
|  | ||||
|    Docs on session management: | ||||
|     http://www.fifi.org/doc/xspecs/xsmp.txt.gz | ||||
|     http://www.fifi.org/doc/xspecs/SMlib.txt.gz | ||||
|  | ||||
|    See also the ICCCM section on SM. For GNOME apps, use the | ||||
|    GnomeClient object. For a simple example of using libSM directly, | ||||
|    twm/session.c in the twm source code is pretty easy to understand. | ||||
|  | ||||
| Q: How about adding viewports in addition to workspaces? | ||||
|  | ||||
| A: I could conceivably be convinced to use viewports _instead_ of | ||||
|    workspaces, though currently I'm not thinking that. But I don't | ||||
|    think it makes any sense to have both; it's just confusing. They | ||||
|    are functionally equivalent. | ||||
|  | ||||
|    You may think this means that you won't have certain keybindings,  | ||||
|    or something like that. This is a misconception. The only  | ||||
|    _fundamental_ difference between viewports and workspaces is that  | ||||
|    with viewports, windows can "overlap" and appear partially on  | ||||
|    one and partially on another. All other differences that | ||||
|    traditionally exist in other window managers are accidental -  | ||||
|    the features commonly associated with viewports can be implemented | ||||
|    for workspaces, and vice versa. | ||||
|  | ||||
|    So I don't want to have two kinds of | ||||
|    workspace/desktop/viewport/whatever, but I'm willing to add | ||||
|    features traditionally associated with either kind if those | ||||
|    features make sense. | ||||
|  | ||||
| Q: Why is the panel always on top? | ||||
|  | ||||
| A: Because it's a better user interface, and until we made this not | ||||
|    configurable a bunch of apps were not getting fixed (the app | ||||
|    authors were just saying "put your panel on the bottom" instead of | ||||
|    properly supporting fullscreen mode, and such). | ||||
|  | ||||
|    rationales.txt has the bugzilla URL for some flamefesting on this, | ||||
|    if you want to go back and relive the glory. | ||||
|    Read these and the bugzilla stuff before asking/commenting: | ||||
|      http://pobox.com/~hp/free-software-ui.html | ||||
|      http://pobox.com/~hp/features.html    | ||||
|  | ||||
| Q: Why is there no edge flipping? | ||||
|  | ||||
| A: This one is also in rationales.txt. Because "ouija board" UI, where | ||||
|    you just move the mouse around and the computer guesses what you | ||||
|    mean, has a lot of issues. This includes mouse focus, shade-hover | ||||
|    mode, edge flipping, autoraise, etc. Metacity has mouse focus and | ||||
|    autoraise as a compromise, but these features are all confusing for | ||||
|    many users, and cause problems with accessibility, fitt's law, and | ||||
|    so on. | ||||
|  | ||||
|    Read these and the bugzilla stuff before asking/commenting: | ||||
|      http://pobox.com/~hp/free-software-ui.html | ||||
|      http://pobox.com/~hp/features.html    | ||||
|  | ||||
| Q: Why does wireframe move/resize suck? | ||||
|  | ||||
| A: You can turn it on with the reduced_resources setting. | ||||
|  | ||||
|    But: it has low usability, and is a pain | ||||
|    to implement, and there's no reason opaque move/resize should be a | ||||
|    problem on any setup that can run a modern desktop worth a darn to | ||||
|    begin with. | ||||
|  | ||||
|    Read these and the bugzilla stuff before asking/commenting: | ||||
|      http://pobox.com/~hp/free-software-ui.html | ||||
|      http://pobox.com/~hp/features.html    | ||||
|  | ||||
|    The reason we had to add wireframe anyway was broken  | ||||
|    proprietary apps that can't handle lots of resize events. | ||||
|  | ||||
| Q: Why no XYZ? | ||||
|  | ||||
| A: You are probably getting the idea by now - check rationales.txt, | ||||
|    query/search bugzilla, and read http://pobox.com/~hp/features.html | ||||
|    and http://pobox.com/~hp/free-software-ui.html | ||||
|  | ||||
|    Then sit down and answer the question for yourself.  Is the feature | ||||
|    good? What's the rationale for it? Answer "why" not just "why not." | ||||
|    Justify in terms of users as a whole, not just users like | ||||
|    yourself. How else can you solve the same problem? etc. If that | ||||
|    leads you to a strong opinion, then please, post the rationale for | ||||
|    discussion to an appropriate bugzilla bug, or to | ||||
|    usability@gnome.org. | ||||
|  | ||||
|    Please don't just "me too!" on bugzilla bugs, please don't think | ||||
|    flames will get you anywhere, and please don't repeat rationale | ||||
|    that's already been offered. | ||||
|  | ||||
| Q: Your dumb web pages you made me read talk about solving problems in | ||||
|    fundamental ways instead of adding preferences or workarounds. | ||||
|    What are some examples where metacity has done this? | ||||
|  | ||||
| A: There are quite a few, though many opportunities remain.  Sometimes | ||||
|    the real fix involves application changes. The metacity approach is | ||||
|    that it's OK to require apps to change, though there are also | ||||
|    plenty of workarounds in metacity for battles considered too hard | ||||
|    to fight. | ||||
|  | ||||
|    Here are some examples: | ||||
|  | ||||
|    - fullscreen mode was introduced to allow position constraints, | ||||
|      panel-on-top, and other such things to apply to normal windows | ||||
|      while still allowing video players etc. to "just work" | ||||
|  | ||||
|    - "whether to include minimized windows in Alt+Tab" was solved  | ||||
|      by putting minimized windows at the *end* of the tab order.  | ||||
|  | ||||
|    - Whether to pop up a feedback display during Alt+Tab was solved by | ||||
|      having both Alt+Tab and Alt+Esc | ||||
|  | ||||
|    - Whether to have a "kill" feature was solved by automatically | ||||
|      detecting and offering to kill stuck apps. Better, metacity | ||||
|      actually does "kill -9" on the process, it doesn't just | ||||
|      disconnect the process from the X server. You'll appreciate this | ||||
|      if you ever did a "kill" on Netscape 4, and watched it keep | ||||
|      eating 100% CPU even though the X server had booted it. | ||||
|  | ||||
|    - The workspaces vs. viewports mess was avoided by adding | ||||
|      directional navigation and such to workspaces, see discussion | ||||
|      earlier in this file. | ||||
|  | ||||
|    - Instead of configurable placement algorithms, there's just one  | ||||
|      that works fairly well most of the time. | ||||
|  | ||||
|    - To avoid excess CPU use during opaque move/resize, we rate limit | ||||
|      the updates to the application window's size. | ||||
|  | ||||
|    - Instead of configurable "show size of window while resizing," | ||||
|      it's only shown for windows where it matters, such as terminals. | ||||
|      (Only use-case given for all windows is for web designers | ||||
|      choosing their web browser size, but there are web sites and | ||||
|      desktop backgrounds that do this for you.) | ||||
|  | ||||
|    - Using startup notification, applications open on the workspace | ||||
|      where you launched them, not the active workspace when their | ||||
|      window is opened. | ||||
|  | ||||
|    - and much more. | ||||
|  | ||||
| Q: I think mutter sucks. | ||||
|  | ||||
| A: Feel free to use any WM you like. The reason metacity follows the | ||||
|    ICCCM and EWMH specifications is that it makes metacity a modular, | ||||
|    interchangeable part in the desktop. libwnck-based apps such as the | ||||
|    GNOME window list will work just fine with any EWMH-compliant WM. | ||||
|  | ||||
| Q: Did you spend a lot of time on this? | ||||
|  | ||||
| A: Originally the answer was no. Sadly the answer is now yes. | ||||
|  | ||||
| Q: How can you claim that you are anti-crack, while still  | ||||
|    writing a window manager? | ||||
|  | ||||
| A: I have no comment on that. | ||||
| @@ -5,7 +5,7 @@ srcdir=`dirname $0` | ||||
| test -z "$srcdir" && srcdir=. | ||||
|  | ||||
| PKG_NAME="mutter" | ||||
| REQUIRED_AUTOMAKE_VERSION=1.13 | ||||
| REQUIRED_AUTOMAKE_VERSION=1.10 | ||||
|  | ||||
| (test -f $srcdir/configure.ac \ | ||||
|   && test -d $srcdir/src) || { | ||||
|   | ||||
							
								
								
									
										106
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										106
									
								
								configure.ac
									
									
									
									
									
								
							| @@ -2,8 +2,8 @@ AC_PREREQ(2.50) | ||||
| AC_CONFIG_MACRO_DIR([m4]) | ||||
|  | ||||
| m4_define([mutter_major_version], [3]) | ||||
| m4_define([mutter_minor_version], [11]) | ||||
| m4_define([mutter_micro_version], [91]) | ||||
| m4_define([mutter_minor_version], [13]) | ||||
| m4_define([mutter_micro_version], [2]) | ||||
|  | ||||
| m4_define([mutter_version], | ||||
|           [mutter_major_version.mutter_minor_version.mutter_micro_version]) | ||||
| @@ -13,17 +13,14 @@ m4_define([mutter_plugin_api_version], [3]) | ||||
| AC_INIT([mutter], [mutter_version], | ||||
|         [http://bugzilla.gnome.org/enter_bug.cgi?product=mutter]) | ||||
|  | ||||
| AC_CONFIG_MACRO_DIR([m4]) | ||||
| AC_CONFIG_SRCDIR(src/core/display.c) | ||||
| AC_CONFIG_HEADERS(config.h) | ||||
|  | ||||
| AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz tar-ustar]) | ||||
| AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz tar-ustar subdir-objects]) | ||||
| m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],) | ||||
| AM_MAINTAINER_MODE([enable]) | ||||
|  | ||||
| # Change pkglibdir and pkgdatadir to mutter-wayland instead of mutter | ||||
| PACKAGE="mutter-wayland" | ||||
| AC_SUBST([PACKAGE], [$PACKAGE]) | ||||
|  | ||||
| MUTTER_MAJOR_VERSION=mutter_major_version | ||||
| MUTTER_MINOR_VERSION=mutter_minor_version | ||||
| MUTTER_MICRO_VERSION=mutter_micro_version | ||||
| @@ -39,7 +36,7 @@ AC_SUBST(MUTTER_PLUGIN_DIR) | ||||
| # Honor aclocal flags | ||||
| AC_SUBST(ACLOCAL_AMFLAGS, "\${ACLOCAL_FLAGS}") | ||||
|  | ||||
| GETTEXT_PACKAGE=mutter-wayland | ||||
| GETTEXT_PACKAGE=mutter | ||||
| AC_SUBST(GETTEXT_PACKAGE) | ||||
| AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE",[Name of default gettext domain]) | ||||
|  | ||||
| @@ -72,12 +69,12 @@ CANBERRA_GTK_VERSION=0.26 | ||||
| CLUTTER_PACKAGE=clutter-1.0 | ||||
|  | ||||
| MUTTER_PC_MODULES=" | ||||
|    gtk+-3.0 >= 3.3.7 | ||||
|    gtk+-3.0 >= 3.9.11 | ||||
|    gio-2.0 >= 2.25.10 | ||||
|    pango >= 1.2.0 | ||||
|    cairo >= 1.10.0 | ||||
|    gsettings-desktop-schemas >= 3.7.3 | ||||
|    xcomposite >= 0.2 xfixes xrender xdamage xi >= 1.6.0 | ||||
|    xcomposite >= 0.2 xfixes xext xdamage xi >= 1.6.0 | ||||
|    $CLUTTER_PACKAGE >= 1.17.5 | ||||
|    cogl-1.0 >= 1.17.1 | ||||
|    upower-glib >= 0.99.0 | ||||
| @@ -120,32 +117,16 @@ AC_ARG_ENABLE(shape, | ||||
|                  [disable mutter's use of the shaped window extension]),, | ||||
|   enable_shape=auto) | ||||
|  | ||||
| ## Wayland support requires the xserver.xml protocol extension found in the weston | ||||
| ## repository but since there aren't currently established conventions for | ||||
| ## installing and discovering these we simply require a location to be given | ||||
| ## explicitly... | ||||
| AC_ARG_WITH([wayland-protocols], | ||||
|             [AS_HELP_STRING([--with-wayland-protocols], [Location for wayland extension protocol specs])], | ||||
|             [ | ||||
|             ], | ||||
|             []) | ||||
|  | ||||
| AC_ARG_WITH([xwayland-path], | ||||
|             [AS_HELP_STRING([--with-xwayland-path], [Absolute path for an X Wayland server])], | ||||
|             [XWAYLAND_PATH="$withval"], | ||||
|             [XWAYLAND_PATH="$bindir/Xorg"]) | ||||
|             [XWAYLAND_PATH="$bindir/Xwayland"]) | ||||
|  | ||||
| AM_GLIB_GNU_GETTEXT | ||||
|  | ||||
| ## here we get the flags we'll actually use | ||||
| # GRegex requires Glib-2.14.0 | ||||
| PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.14.0) | ||||
| PKG_CHECK_MODULES(MUTTER_LAUNCH, libdrm libsystemd-login) | ||||
|  | ||||
| saved_LIBS="$LIBS" | ||||
| LIBS="$LIBS $MUTTER_LAUNCH" | ||||
| AC_CHECK_FUNCS([sd_session_get_vt]) | ||||
| LIBS="$saved_LIBS" | ||||
|  | ||||
| # Unconditionally use this dir to avoid a circular dep with gnomecc | ||||
| GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings" | ||||
| @@ -218,9 +199,15 @@ AS_IF([test "x$WAYLAND_SCANNER" = "xno"], | ||||
| AC_SUBST([WAYLAND_SCANNER]) | ||||
| AC_SUBST(XWAYLAND_PATH) | ||||
|  | ||||
| MUTTER_PC_MODULES="$MUTTER_PC_MODULES clutter-wayland-1.0 clutter-wayland-compositor-1.0 clutter-egl-1.0 wayland-server libdrm" | ||||
| MUTTER_PC_MODULES="$MUTTER_PC_MODULES clutter-wayland-1.0 clutter-wayland-compositor-1.0 clutter-egl-1.0 wayland-server >= 1.4.93" | ||||
| PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES) | ||||
|  | ||||
| PKG_CHECK_MODULES(MUTTER_NATIVE_BACKEND, [libdrm libsystemd], [have_native_backend=yes], [have_native_backend=no]) | ||||
| if test $have_native_backend = yes; then | ||||
|    AC_DEFINE([HAVE_NATIVE_BACKEND],[1],[Define if you want to enable the native (KMS) backend based on systemd]) | ||||
| fi | ||||
| AM_CONDITIONAL([HAVE_NATIVE_BACKEND],[test $have_native_backend = yes]) | ||||
|  | ||||
| PKG_CHECK_EXISTS([xi >= 1.6.99.1], | ||||
|                  AC_DEFINE([HAVE_XI23],[1],[Define if you have support for XInput 2.3 or greater])) | ||||
|  | ||||
| @@ -257,28 +244,6 @@ if test x$have_xinerama = xno; then | ||||
|    AC_MSG_ERROR([Xinerama extension was not found]) | ||||
| fi | ||||
|  | ||||
| SHAPE_LIBS= | ||||
| found_shape=no | ||||
| AC_CHECK_LIB(Xext, XShapeQueryExtension, | ||||
|                [AC_CHECK_HEADER(X11/extensions/shape.h, | ||||
|                                 SHAPE_LIBS=-lXext found_shape=yes)], | ||||
|                , $ALL_X_LIBS) | ||||
|  | ||||
| if test x$enable_shape = xno; then | ||||
|    found_shape=no | ||||
| fi | ||||
|  | ||||
| if test x$enable_shape = xyes; then | ||||
|    if test "$found_shape" = "no"; then | ||||
|       AC_MSG_ERROR([--enable-shape forced and Shape not found]) | ||||
|       exit 1 | ||||
|    fi | ||||
| fi | ||||
|  | ||||
| if test "x$found_shape" = "xyes"; then | ||||
|    AC_DEFINE(HAVE_SHAPE, , [Have the shape extension library]) | ||||
| fi | ||||
|  | ||||
| found_xkb=no | ||||
| AC_CHECK_LIB(X11, XkbQueryExtension, | ||||
|                [AC_CHECK_HEADER(X11/XKBlib.h, | ||||
| @@ -296,37 +261,13 @@ AC_CHECK_LIB(Xrandr, XRRUpdateConfiguration, | ||||
|                [AC_CHECK_HEADER(X11/extensions/Xrandr.h, | ||||
|                                 RANDR_LIBS=-lXrandr found_randr=yes,, | ||||
| 				[#include <X11/Xlib.h>])], | ||||
|                , -lXrender -lXext $ALL_X_LIBS) | ||||
|                , -lXext $ALL_X_LIBS) | ||||
|  | ||||
| if test "x$found_randr" = "xyes"; then | ||||
|    AC_DEFINE(HAVE_RANDR, , [Have the Xrandr extension library]) | ||||
| fi | ||||
|  | ||||
| XSYNC_LIBS= | ||||
| found_xsync=no | ||||
| AC_CHECK_LIB(Xext, XSyncQueryExtension, | ||||
|                [AC_CHECK_HEADER(X11/extensions/sync.h, | ||||
|                                 found_xsync=yes,, | ||||
| 				[#include <X11/Xlib.h>])], | ||||
|                , $ALL_X_LIBS) | ||||
|  | ||||
| if test x$enable_xsync = xno; then | ||||
|    found_xsync=no | ||||
| fi | ||||
|  | ||||
| if test x$enable_xsync = xyes; then | ||||
|    if test "$found_xsync" = "no"; then | ||||
|       AC_MSG_ERROR([--enable-xsync forced and XSync not found]) | ||||
|       exit 1 | ||||
|    fi | ||||
| fi | ||||
|  | ||||
| if test "x$found_xsync" = "xyes"; then | ||||
|    XSYNC_LIBS=-lXext | ||||
|    AC_DEFINE(HAVE_XSYNC, , [Have the Xsync extension library]) | ||||
| fi | ||||
|  | ||||
| MUTTER_LIBS="$MUTTER_LIBS $XSYNC_LIBS $RANDR_LIBS $SHAPE_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS -lm" | ||||
| MUTTER_LIBS="$MUTTER_LIBS $RANDR_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS -lm" | ||||
|  | ||||
| found_sm=no | ||||
| case "$MUTTER_LIBS" in | ||||
| @@ -383,6 +324,11 @@ fi | ||||
|  | ||||
| GTK_DOC_CHECK([1.15], [--flavour no-tmpl]) | ||||
|  | ||||
| AC_CHECK_DECL([GL_EXT_x11_sync_object], | ||||
|               [], | ||||
|               [AC_MSG_ERROR([GL_EXT_x11_sync_object definition not found, please update your GL headers])], | ||||
|               [#include <GL/glx.h>]) | ||||
|  | ||||
| #### Warnings (last since -Werror can disturb other tests) | ||||
|  | ||||
| # Stay command-line compatible with the gnome-common configure option. Here | ||||
| @@ -456,9 +402,8 @@ doc/man/Makefile | ||||
| doc/reference/Makefile | ||||
| doc/reference/meta-docs.sgml | ||||
| src/Makefile | ||||
| src/libmutter-wayland.pc | ||||
| src/libmutter.pc | ||||
| src/compositor/plugins/Makefile | ||||
| protocol/Makefile | ||||
| po/Makefile.in | ||||
| ]) | ||||
|  | ||||
| @@ -474,7 +419,7 @@ fi | ||||
|  | ||||
| dnl ========================================================================== | ||||
| echo " | ||||
| mutter-wayland-$VERSION | ||||
| mutter-$VERSION | ||||
|  | ||||
| 	prefix:                   ${prefix} | ||||
| 	source code location:	  ${srcdir} | ||||
| @@ -484,9 +429,6 @@ mutter-wayland-$VERSION | ||||
| 	libcanberra:              ${have_libcanberra} | ||||
| 	Introspection:            ${found_introspection} | ||||
| 	Session management:       ${found_sm} | ||||
| 	Shape extension:          ${found_shape} | ||||
| 	Xsync:                    ${found_xsync} | ||||
| 	Xcursor:                  ${have_xcursor} | ||||
| " | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										3
									
								
								data/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								data/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| defaultcursordir = $(datadir)/mutter/cursors | ||||
|  | ||||
| dist_defaultcursor_DATA = left_ptr.png | ||||
| @@ -1,4 +1,4 @@ | ||||
| SUBDIRS = man reference | ||||
|  | ||||
| EXTRA_DIST=theme-format.txt dialogs.txt code-overview.txt \ | ||||
| 	how-to-get-focus-right.txt | ||||
| 	how-to-get-focus-right.txt rationales.txt | ||||
|   | ||||
| @@ -79,8 +79,6 @@ IGNORE_HFILES= \ | ||||
| 	iconcache.h \ | ||||
| 	inlinepixbufs.h \ | ||||
| 	keybindings-private.h \ | ||||
| 	menu.h \ | ||||
| 	metaaccellabel.h \ | ||||
| 	meta-background-actor-private.h \ | ||||
| 	meta-background-group-private.h \ | ||||
| 	meta-module.h \ | ||||
| @@ -140,7 +138,7 @@ expand_content_files= \ | ||||
| # e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) | ||||
| # e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) | ||||
| GTKDOC_CFLAGS=$(MUTTER_CFLAGS) | ||||
| GTKDOC_LIBS=$(MUTTER_LIBS) $(top_builddir)/src/libmutter-wayland.la | ||||
| GTKDOC_LIBS=$(MUTTER_LIBS) $(top_builddir)/src/libmutter.la | ||||
|  | ||||
| # This includes the standard gtk-doc make rules, copied by gtkdocize. | ||||
| include $(top_srcdir)/gtk-doc.make | ||||
|   | ||||
| @@ -21,7 +21,6 @@ environment.</description> | ||||
|   --> | ||||
|   <mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/gnome-shell-list" /> | ||||
|   <download-page rdf:resource="http://download.gnome.org/sources/mutter/" /> | ||||
|   <download-page rdf:resource="http://download.gnome.org/sources/mutter-wayland/" /> | ||||
|   <bug-database rdf:resource="http://bugzilla.gnome.org/browse.cgi?product=mutter" /> | ||||
|  | ||||
|   <category rdf:resource="http://api.gnome.org/doap-extensions#desktop" /> | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| src/50-mutter-navigation.xml.in | ||||
| src/50-mutter-system.xml.in | ||||
| src/50-mutter-windows.xml.in | ||||
| src/backends/meta-monitor-manager.c | ||||
| src/compositor/compositor.c | ||||
| src/compositor/meta-background.c | ||||
| src/core/bell.c | ||||
| @@ -12,21 +13,18 @@ src/core/display.c | ||||
| src/core/errors.c | ||||
| src/core/keybindings.c | ||||
| src/core/main.c | ||||
| src/core/monitor.c | ||||
| src/core/mutter.c | ||||
| src/core/prefs.c | ||||
| src/core/screen.c | ||||
| src/core/session.c | ||||
| src/core/util.c | ||||
| src/core/window.c | ||||
| src/core/window-props.c | ||||
| src/core/xprops.c | ||||
| src/mutter-wayland.desktop.in | ||||
| src/mutter.desktop.in | ||||
| src/org.gnome.mutter.gschema.xml.in | ||||
| src/org.gnome.mutter.wayland.gschema.xml.in | ||||
| src/ui/frames.c | ||||
| src/ui/menu.c | ||||
| src/ui/metaaccellabel.c | ||||
| src/ui/resizepopup.c | ||||
| src/ui/theme.c | ||||
| src/ui/theme-parser.c | ||||
| src/x11/session.c | ||||
| src/x11/window-props.c | ||||
| src/x11/xprops.c | ||||
|   | ||||
| @@ -1,2 +1,2 @@ | ||||
| src/metacity.schemas.in | ||||
|  | ||||
| src/mutter-wayland.desktop.in | ||||
|   | ||||
							
								
								
									
										2834
									
								
								po/ca@valencia.po
									
									
									
									
									
								
							
							
						
						
									
										2834
									
								
								po/ca@valencia.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										805
									
								
								po/pt_BR.po
									
									
									
									
									
								
							
							
						
						
									
										805
									
								
								po/pt_BR.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										417
									
								
								po/sk.po
									
									
									
									
									
								
							
							
						
						
									
										417
									
								
								po/sk.po
									
									
									
									
									
								
							| @@ -13,9 +13,9 @@ msgstr "" | ||||
| "Project-Id-Version: mutter\n" | ||||
| "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" | ||||
| "product=mutter&keywords=I18N+L10N&component=general\n" | ||||
| "POT-Creation-Date: 2013-05-24 21:44+0000\n" | ||||
| "PO-Revision-Date: 2013-05-18 16:53+0100\n" | ||||
| "Last-Translator: Jan Kyselica <kyselica.jan@gmail.com>\n" | ||||
| "POT-Creation-Date: 2013-08-21 17:41+0000\n" | ||||
| "PO-Revision-Date: 2013-08-02 14:46+0200\n" | ||||
| "Last-Translator: Ján Kyselica <kyselica.jan@gmail.com>\n" | ||||
| "Language-Team: Slovak <gnome-sk-list@gnome.org>\n" | ||||
| "Language: sk\n" | ||||
| "MIME-Version: 1.0\n" | ||||
| @@ -87,9 +87,8 @@ msgstr "Prepnúť okná aplikácie" | ||||
| # PK: zisti co to robi | ||||
| # description | ||||
| #: ../src/50-mutter-navigation.xml.in.h:13 | ||||
| #, fuzzy | ||||
| msgid "Switch system controls" | ||||
| msgstr "Prepnúť medzi systémovými ovládacími prvkami" | ||||
| msgstr "Prepnúť medzi ovládacími prvkami systému" | ||||
|  | ||||
| # description | ||||
| #: ../src/50-mutter-navigation.xml.in.h:14 | ||||
| @@ -104,9 +103,8 @@ msgstr "Prepnúť okná aplikácie priamo" | ||||
| # MČ: podobne ako vyššie: „cycle-panels“ | ||||
| # description | ||||
| #: ../src/50-mutter-navigation.xml.in.h:16 | ||||
| #, fuzzy | ||||
| msgid "Switch system controls directly" | ||||
| msgstr "Prepnúť medzi systémovými ovládacími prvkami priamo" | ||||
| msgstr "Prepnúť medzi ovládacími prvkami systému priamo" | ||||
|  | ||||
| # description | ||||
| #: ../src/50-mutter-navigation.xml.in.h:17 | ||||
| @@ -267,13 +265,13 @@ msgstr "Zobraziť rozdelenie napravo" | ||||
| # PK: je %i cislo obrazovky? ak ano tak "č. %i" | ||||
| #. This probably means that a non-WM compositor like xcompmgr is running; | ||||
| #. * we have no way to get it to exit | ||||
| #: ../src/compositor/compositor.c:571 | ||||
| #, fuzzy, c-format | ||||
| #: ../src/compositor/compositor.c:596 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Another compositing manager is already running on screen %i on display \"%s" | ||||
| "\"." | ||||
| msgstr "" | ||||
| "Pre obrazovku %i na displeji „%s“ je spustený už iný správca rozloženia." | ||||
| "Pre obrazovku č. %i na displeji „%s“ je spustený už iný správca rozloženia." | ||||
|  | ||||
| #: ../src/compositor/meta-background.c:1076 | ||||
| msgid "background texture could not be created from file" | ||||
| @@ -313,18 +311,18 @@ msgstr "_Počkať" | ||||
| msgid "_Force Quit" | ||||
| msgstr "_Vynútiť ukončenie" | ||||
|  | ||||
| #: ../src/core/display.c:401 | ||||
| #: ../src/core/display.c:421 | ||||
| #, c-format | ||||
| msgid "Missing %s extension required for compositing" | ||||
| msgstr "Rozšírenie %s, potrebné pre kompozitné prostredie, chýba" | ||||
|  | ||||
| # X window system preloz, napr. system na spravu okien X | ||||
| #: ../src/core/display.c:493 | ||||
| #: ../src/core/display.c:513 | ||||
| #, c-format | ||||
| msgid "Failed to open X Window System display '%s'\n" | ||||
| msgstr "Zlyhalo otvorenie displeja systému na správu okien X „%s“\n" | ||||
|  | ||||
| #: ../src/core/keybindings.c:970 | ||||
| #: ../src/core/keybindings.c:1136 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Some other program is already using the key %s with modifiers %x as a " | ||||
| @@ -332,7 +330,7 @@ msgid "" | ||||
| msgstr "" | ||||
| "Iný program už používa kláves %s s modifikátormi %x ako klávesovú skratku\n" | ||||
|  | ||||
| #: ../src/core/keybindings.c:1151 | ||||
| #: ../src/core/keybindings.c:1333 | ||||
| #, c-format | ||||
| msgid "\"%s\" is not a valid accelerator\n" | ||||
| msgstr "„%s“ nie je platný akcelerátor\n" | ||||
| @@ -378,6 +376,20 @@ msgid "" | ||||
| msgstr "" | ||||
| "Nepodarilo sa nájsť tému! Overte, že %s existuje a obsahuje obvyklé témy.\n" | ||||
|  | ||||
| #: ../src/core/monitor.c:702 | ||||
| msgid "Built-in display" | ||||
| msgstr "Vstavaný displej" | ||||
|  | ||||
| #. TRANSLATORS: this is a monitor name (in case we don't know | ||||
| #. the vendor), it's Unknown followed by a size in inches, | ||||
| #. like 'Unknown 15"' | ||||
| #. | ||||
| #: ../src/core/monitor.c:730 | ||||
| #, c-format | ||||
| #| msgid "Unknown element %s" | ||||
| msgid "Unknown %s" | ||||
| msgstr "Neznámy %s" | ||||
|  | ||||
| #: ../src/core/mutter.c:40 | ||||
| #, c-format | ||||
| msgid "" | ||||
| @@ -403,7 +415,7 @@ msgstr "Zobrazí verziu" | ||||
| msgid "Mutter plugin to use" | ||||
| msgstr "Použije zásuvný modul Mutter" | ||||
|  | ||||
| #: ../src/core/prefs.c:1193 | ||||
| #: ../src/core/prefs.c:1202 | ||||
| msgid "" | ||||
| "Workarounds for broken applications disabled. Some applications may not " | ||||
| "behave properly.\n" | ||||
| @@ -411,12 +423,12 @@ msgstr "" | ||||
| "Náhradné riešenia pre chybné aplikácie nie sú povolené. Niektoré aplikácie " | ||||
| "sa nemusia správať správne.\n" | ||||
|  | ||||
| #: ../src/core/prefs.c:1268 | ||||
| #: ../src/core/prefs.c:1277 | ||||
| #, c-format | ||||
| msgid "Could not parse font description \"%s\" from GSettings key %s\n" | ||||
| msgstr "Nepodarilo sa spracovať popis písma „%s“ z kľúča GSettings %s\n" | ||||
|  | ||||
| #: ../src/core/prefs.c:1334 | ||||
| #: ../src/core/prefs.c:1343 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "\"%s\" found in configuration database is not a valid value for mouse button " | ||||
| @@ -425,7 +437,7 @@ msgstr "" | ||||
| "V konfiguračnej databáze sa našlo „%s“, čo nie je platná hodnota pre " | ||||
| "modifikátor tlačidla myši\n" | ||||
|  | ||||
| #: ../src/core/prefs.c:1881 | ||||
| #: ../src/core/prefs.c:1909 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "\"%s\" found in configuration database is not a valid value for keybinding " | ||||
| @@ -434,17 +446,17 @@ msgstr "" | ||||
| "V konfiguračnej databáze sa našlo „%s“, čo nie je platná hodnota pre " | ||||
| "klávesovú skratku „%s“\n" | ||||
|  | ||||
| #: ../src/core/prefs.c:1945 | ||||
| #: ../src/core/prefs.c:1999 | ||||
| #, c-format | ||||
| msgid "Workspace %d" | ||||
| msgstr "Pracovný priestor č. %d" | ||||
|  | ||||
| #: ../src/core/screen.c:691 | ||||
| #: ../src/core/screen.c:537 | ||||
| #, c-format | ||||
| msgid "Screen %d on display '%s' is invalid\n" | ||||
| msgstr "Obrazovka č. %d na displeji „%s“ nie je platná\n" | ||||
|  | ||||
| #: ../src/core/screen.c:707 | ||||
| #: ../src/core/screen.c:553 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Screen %d on display \"%s\" already has a window manager; try using the --" | ||||
| @@ -453,7 +465,7 @@ msgstr "" | ||||
| "Obrazovka č. %d na displeji „%s“ už má správcu okien. Skúste použiť prepínač " | ||||
| "--replace, aby sa aktuálny správca nahradil.\n" | ||||
|  | ||||
| #: ../src/core/screen.c:734 | ||||
| #: ../src/core/screen.c:580 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Could not acquire window manager selection on screen %d display \"%s\"\n" | ||||
| @@ -461,12 +473,12 @@ msgstr "" | ||||
| "Nepodarilo sa získať výber správcu okien pre obrazovku č. %d na displeji " | ||||
| "„%s“\n" | ||||
|  | ||||
| #: ../src/core/screen.c:812 | ||||
| #: ../src/core/screen.c:658 | ||||
| #, c-format | ||||
| msgid "Screen %d on display \"%s\" already has a window manager\n" | ||||
| msgstr "Obrazovka č. %d na displeji „%s“ už má správcu okien\n" | ||||
|  | ||||
| #: ../src/core/screen.c:998 | ||||
| #: ../src/core/screen.c:850 | ||||
| #, c-format | ||||
| msgid "Could not release screen %d on display \"%s\"\n" | ||||
| msgstr "Nepodarilo sa uvoľniť obrazovku č. %d na displeji „%s“\n" | ||||
| @@ -542,8 +554,7 @@ msgstr "Zlyhalo otvorenie súboru so záznamom pomocou fdopen() %s: %s\n" | ||||
| msgid "Opened log file %s\n" | ||||
| msgstr "Otvorený súbor so záznamom %s\n" | ||||
|  | ||||
| #: ../src/core/util.c:119 ../src/tools/mutter-message.c:149 | ||||
| #, c-format | ||||
| #: ../src/core/util.c:119 | ||||
| msgid "Mutter was compiled without support for verbose mode\n" | ||||
| msgstr "Mutter bol skompilovaný bez výpisu podrobností pri behu\n" | ||||
|  | ||||
| @@ -551,20 +562,20 @@ msgstr "Mutter bol skompilovaný bez výpisu podrobností pri behu\n" | ||||
| msgid "Window manager: " | ||||
| msgstr "Správca okien: " | ||||
|  | ||||
| #: ../src/core/util.c:412 | ||||
| #: ../src/core/util.c:414 | ||||
| msgid "Bug in window manager: " | ||||
| msgstr "Chyba v správcovi okien: " | ||||
|  | ||||
| #: ../src/core/util.c:443 | ||||
| #: ../src/core/util.c:445 | ||||
| msgid "Window manager warning: " | ||||
| msgstr "Varovanie správcu okien: " | ||||
|  | ||||
| #: ../src/core/util.c:471 | ||||
| #: ../src/core/util.c:473 | ||||
| msgid "Window manager error: " | ||||
| msgstr "Chyba správcu okien: " | ||||
|  | ||||
| #. first time through | ||||
| #: ../src/core/window.c:7505 | ||||
| #: ../src/core/window.c:7533 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER " | ||||
| @@ -580,7 +591,7 @@ msgstr "" | ||||
| #. * MWM but not WM_NORMAL_HINTS are basically broken. We complain | ||||
| #. * about these apps but make them work. | ||||
| #. | ||||
| #: ../src/core/window.c:8229 | ||||
| #: ../src/core/window.c:8257 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Window %s sets an MWM hint indicating it isn't resizable, but sets min size " | ||||
| @@ -590,7 +601,7 @@ msgstr "" | ||||
| "nastavuje minimálnu veľkosť %d x %d a maximálnu veľkosť %d x %d. To nedáva " | ||||
| "zmysel.\n" | ||||
|  | ||||
| #: ../src/core/window-props.c:318 | ||||
| #: ../src/core/window-props.c:347 | ||||
| #, c-format | ||||
| msgid "Application set a bogus _NET_WM_PID %lu\n" | ||||
| msgstr "Aplikácia nastavila neplatné _NET_WM_PID %lu\n" | ||||
| @@ -598,18 +609,18 @@ msgstr "Aplikácia nastavila neplatné _NET_WM_PID %lu\n" | ||||
| # PK: co je toto? | ||||
| # JK: nedokazem zistit | ||||
| # PM: vyžiadaj komentár od vývojárov, pomožeme aj ostatným prekladateľom | ||||
| #: ../src/core/window-props.c:434 | ||||
| #: ../src/core/window-props.c:463 | ||||
| #, fuzzy, c-format | ||||
| msgid "%s (on %s)" | ||||
| msgstr "%s (na %s)" | ||||
|  | ||||
| #: ../src/core/window-props.c:1517 | ||||
| #: ../src/core/window-props.c:1546 | ||||
| #, c-format | ||||
| msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n" | ||||
| msgstr "Neplatné WM_TRANSIENT_FOR okno 0x%lx nastavené pre %s.\n" | ||||
|  | ||||
| # MČ: zacykliť sa, alebo vytvoriť slučku. | ||||
| #: ../src/core/window-props.c:1528 | ||||
| #: ../src/core/window-props.c:1557 | ||||
| #, c-format | ||||
| msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n" | ||||
| msgstr "WM_TRANSIENT_FOR okno 0x%lx  pre %s môže vytvoriť slučku.\n" | ||||
| @@ -697,9 +708,9 @@ msgid "" | ||||
| "vertically and resizes them horizontally to cover half of the available " | ||||
| "area. Dropping windows on the top screen edge maximizes them completely." | ||||
| msgstr "" | ||||
| "Ak je povolené, upustenie okien pri zvislých okrajoch obrazovky ich " | ||||
| "zvislo maximalizuje a vodorovná veľkosť sa zmení na polovicu dostupnej " | ||||
| "plochy. Upustenie okien pri vrchnom okraji obrazovky ich maximalizuje úplne." | ||||
| "Ak je povolené, upustenie okien pri zvislých okrajoch obrazovky ich zvislo " | ||||
| "maximalizuje a vodorovná veľkosť sa zmení na polovicu dostupnej plochy. " | ||||
| "Upustenie okien pri vrchnom okraji obrazovky ich maximalizuje úplne." | ||||
|  | ||||
| # summary | ||||
| #: ../src/org.gnome.mutter.gschema.xml.in.h:7 | ||||
| @@ -735,9 +746,8 @@ msgstr "" | ||||
| # PM: ja by som dal Bez vyvovlávania tabulátorom | ||||
| # summary | ||||
| #: ../src/org.gnome.mutter.gschema.xml.in.h:11 | ||||
| #, fuzzy | ||||
| msgid "No tab popup" | ||||
| msgstr "Nepoužívať prekryvnú ponuku tabulátora" | ||||
| msgstr "Bez vyvolávania tabulátorom" | ||||
|  | ||||
| # MČ: Neviem, čo to presne má robiť, ale popis som pochopil inak. „…či sa má používať rozbaľovacia ponuka a zvýraznenie rámikom sa má vypnúť…“ | ||||
| # description | ||||
| @@ -806,109 +816,104 @@ msgstr "Vybrať okno z rozbaľovacej ponuky tabulátoru" | ||||
| msgid "Cancel tab popup" | ||||
| msgstr "Zrušit rozbaľovaciu ponuku tabulátoru" | ||||
|  | ||||
| #: ../src/tools/mutter-message.c:123 | ||||
| #, c-format | ||||
| msgid "Usage: %s\n" | ||||
| msgstr "Použitie: %s\n" | ||||
|  | ||||
| #. Translators: Translate this string the same way as you do in libwnck! | ||||
| #: ../src/ui/menu.c:69 | ||||
| #: ../src/ui/menu.c:67 | ||||
| msgid "Mi_nimize" | ||||
| msgstr "Mi_nimalizovať" | ||||
|  | ||||
| #. Translators: Translate this string the same way as you do in libwnck! | ||||
| #: ../src/ui/menu.c:71 | ||||
| #: ../src/ui/menu.c:69 | ||||
| msgid "Ma_ximize" | ||||
| msgstr "Ma_ximalizovať" | ||||
|  | ||||
| #. Translators: Translate this string the same way as you do in libwnck! | ||||
| #: ../src/ui/menu.c:73 | ||||
| #: ../src/ui/menu.c:71 | ||||
| msgid "Unma_ximize" | ||||
| msgstr "Zrušiť ma_ximalizáciu" | ||||
|  | ||||
| #. Translators: Translate this string the same way as you do in libwnck! | ||||
| #: ../src/ui/menu.c:75 | ||||
| #: ../src/ui/menu.c:73 | ||||
| msgid "Roll _Up" | ||||
| msgstr "_Zabaliť" | ||||
|  | ||||
| #. Translators: Translate this string the same way as you do in libwnck! | ||||
| #: ../src/ui/menu.c:77 | ||||
| #: ../src/ui/menu.c:75 | ||||
| msgid "_Unroll" | ||||
| msgstr "_Rozbaliť" | ||||
|  | ||||
| #. Translators: Translate this string the same way as you do in libwnck! | ||||
| #: ../src/ui/menu.c:79 | ||||
| #: ../src/ui/menu.c:77 | ||||
| msgid "_Move" | ||||
| msgstr "Pre_miestniť" | ||||
|  | ||||
| #. Translators: Translate this string the same way as you do in libwnck! | ||||
| #: ../src/ui/menu.c:81 | ||||
| #: ../src/ui/menu.c:79 | ||||
| msgid "_Resize" | ||||
| msgstr "Zmeniť veľko_sť" | ||||
|  | ||||
| #. Translators: Translate this string the same way as you do in libwnck! | ||||
| #: ../src/ui/menu.c:83 | ||||
| #: ../src/ui/menu.c:81 | ||||
| msgid "Move Titlebar On_screen" | ||||
| msgstr "Presunúť titulok na _obrazovku" | ||||
|  | ||||
| #. separator | ||||
| #. Translators: Translate this string the same way as you do in libwnck! | ||||
| #: ../src/ui/menu.c:86 ../src/ui/menu.c:88 | ||||
| #: ../src/ui/menu.c:84 ../src/ui/menu.c:86 | ||||
| msgid "Always on _Top" | ||||
| msgstr "Vždy na_vrchu" | ||||
|  | ||||
| #. Translators: Translate this string the same way as you do in libwnck! | ||||
| #: ../src/ui/menu.c:90 | ||||
| #: ../src/ui/menu.c:88 | ||||
| msgid "_Always on Visible Workspace" | ||||
| msgstr "Vž_dy na viditeľnom pracovnom priestore" | ||||
|  | ||||
| #. Translators: Translate this string the same way as you do in libwnck! | ||||
| #: ../src/ui/menu.c:92 | ||||
| #: ../src/ui/menu.c:90 | ||||
| msgid "_Only on This Workspace" | ||||
| msgstr "_Len na tomto pracovnom priestore" | ||||
|  | ||||
| #. Translators: Translate this string the same way as you do in libwnck! | ||||
| #: ../src/ui/menu.c:94 | ||||
| #: ../src/ui/menu.c:92 | ||||
| msgid "Move to Workspace _Left" | ||||
| msgstr "Presunúť na pracovný priestor vľav_o" | ||||
|  | ||||
| #. Translators: Translate this string the same way as you do in libwnck! | ||||
| #: ../src/ui/menu.c:96 | ||||
| #: ../src/ui/menu.c:94 | ||||
| msgid "Move to Workspace R_ight" | ||||
| msgstr "Presunúť na pracovný priestor v_pravo" | ||||
|  | ||||
| #. Translators: Translate this string the same way as you do in libwnck! | ||||
| #: ../src/ui/menu.c:98 | ||||
| #: ../src/ui/menu.c:96 | ||||
| msgid "Move to Workspace _Up" | ||||
| msgstr "Presunúť na pracovný priestor _hore" | ||||
|  | ||||
| #. Translators: Translate this string the same way as you do in libwnck! | ||||
| #: ../src/ui/menu.c:100 | ||||
| #: ../src/ui/menu.c:98 | ||||
| msgid "Move to Workspace _Down" | ||||
| msgstr "Presunúť na pracovný priestor _dole" | ||||
|  | ||||
| #. separator | ||||
| #. Translators: Translate this string the same way as you do in libwnck! | ||||
| #: ../src/ui/menu.c:104 | ||||
| #: ../src/ui/menu.c:102 | ||||
| msgid "_Close" | ||||
| msgstr "_Zavrieť" | ||||
|  | ||||
| #: ../src/ui/menu.c:204 | ||||
| #: ../src/ui/menu.c:202 | ||||
| #, c-format | ||||
| msgid "Workspace %d%n" | ||||
| msgstr "Pracovná priestor %d%n" | ||||
|  | ||||
| #: ../src/ui/menu.c:214 | ||||
| #: ../src/ui/menu.c:212 | ||||
| #, c-format | ||||
| msgid "Workspace 1_0" | ||||
| msgstr "Pracovný priestor 1_0" | ||||
|  | ||||
| #: ../src/ui/menu.c:216 | ||||
| #: ../src/ui/menu.c:214 | ||||
| #, c-format | ||||
| msgid "Workspace %s%d" | ||||
| msgstr "Pracovný priestor %s%d" | ||||
|  | ||||
| #: ../src/ui/menu.c:397 | ||||
| #: ../src/ui/menu.c:384 | ||||
| msgid "Move to Another _Workspace" | ||||
| msgstr "P_resunúť na iný pracovný priestor" | ||||
|  | ||||
| @@ -1066,21 +1071,21 @@ msgstr "" | ||||
| # MČ: Preformuloval by som koniec: „platné sú len znaky A-Za-z0-9-_“ | ||||
| # PK: color_name je asi nejaky atribut, to sa nepreklada, ked tak do zatvorky | ||||
| #: ../src/ui/theme.c:1219 | ||||
| #, fuzzy, c-format | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-" | ||||
| "_ are valid" | ||||
| msgstr "" | ||||
| "V parametri názov_farby pre gtk:custom je neplatný znak „%c“, platné sú len " | ||||
| "V parametri color_name (názov farby) pre gtk:custom je neplatný znak „%c“, platné sú len " | ||||
| "znaky A-Za-z0-9-_" | ||||
|  | ||||
| #: ../src/ui/theme.c:1233 | ||||
| #, fuzzy, c-format | ||||
| #, c-format | ||||
| msgid "" | ||||
| "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not " | ||||
| "fit the format" | ||||
| msgstr "" | ||||
| "Formát Gtk:custom je  „gtk:custom(názov_farby,fallback)“, „%s“ tomu " | ||||
| "Formát Gtk:custom je  „gtk:custom(color_name,fallback)“, „%s“ tomu " | ||||
| "nezodpovedá" | ||||
|  | ||||
| #: ../src/ui/theme.c:1278 | ||||
| @@ -1266,20 +1271,20 @@ msgid "" | ||||
| "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>" | ||||
| msgstr "Chýbajúce <frame state=„%s“ resize=„%s“ focus=„%s“ style=„whatever“/>" | ||||
|  | ||||
| #: ../src/ui/theme.c:5084 | ||||
| #: ../src/ui/theme.c:5082 | ||||
| #, c-format | ||||
| msgid "Failed to load theme \"%s\": %s\n" | ||||
| msgstr "Zlyhalo načítanie témy „%s“: %s\n" | ||||
|  | ||||
| # PK: prvok? | ||||
| # JK: XML značka (XML tag) | ||||
| #: ../src/ui/theme.c:5220 ../src/ui/theme.c:5227 ../src/ui/theme.c:5234 | ||||
| #: ../src/ui/theme.c:5241 ../src/ui/theme.c:5248 | ||||
| #: ../src/ui/theme.c:5218 ../src/ui/theme.c:5225 ../src/ui/theme.c:5232 | ||||
| #: ../src/ui/theme.c:5239 ../src/ui/theme.c:5246 | ||||
| #, c-format | ||||
| msgid "No <%s> set for theme \"%s\"" | ||||
| msgstr "Pre tému „%s“ nie je nastavená <%s>" | ||||
|  | ||||
| #: ../src/ui/theme.c:5256 | ||||
| #: ../src/ui/theme.c:5254 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "No frame style set for window type \"%s\" in theme \"%s\", add a <window " | ||||
| @@ -1288,13 +1293,13 @@ msgstr "" | ||||
| "Pre typ okna „%s“ nie je sada štýlov v téme „%s“, pridajte prvok <window " | ||||
| "type=„%s“ style_set=„whatever“/>" | ||||
|  | ||||
| #: ../src/ui/theme.c:5663 ../src/ui/theme.c:5725 ../src/ui/theme.c:5788 | ||||
| #: ../src/ui/theme.c:5661 ../src/ui/theme.c:5723 ../src/ui/theme.c:5786 | ||||
| #, c-format | ||||
| msgid "" | ||||
| "User-defined constants must begin with a capital letter; \"%s\" does not" | ||||
| msgstr "Používateľské konštanty musia začínať veľkým písmenom, „%s“ nezačína" | ||||
|  | ||||
| #: ../src/ui/theme.c:5671 ../src/ui/theme.c:5733 ../src/ui/theme.c:5796 | ||||
| #: ../src/ui/theme.c:5669 ../src/ui/theme.c:5731 ../src/ui/theme.c:5794 | ||||
| #, c-format | ||||
| msgid "Constant \"%s\" has already been defined" | ||||
| msgstr "Konštanta „%s“ už je definovaná" | ||||
| @@ -1397,7 +1402,7 @@ msgstr "<%s> musí uvádzať buď geometriu alebo rodiča, ktorý má geometriu" | ||||
| msgid "You must specify a background for an alpha value to be meaningful" | ||||
| msgstr "Ak má byť hodnota alpha zmysluplná, tak musíte vybrať nejaké pozadie" | ||||
|  | ||||
| # PM: asi atribút type | ||||
| #  PM: asi atribút type | ||||
| # JK: https://bugzilla.gnome.org/show_bug.cgi?id=698123 | ||||
| #: ../src/ui/theme-parser.c:1264 | ||||
| #, fuzzy, c-format | ||||
| @@ -1559,6 +1564,7 @@ msgid "\"%s\" is not a valid value for resize attribute" | ||||
| msgstr "„%s“ nie je platná hodnota pre atribút zmeny veľkosti" | ||||
|  | ||||
| # PK: shaded states? to zatvorky daj popis co je resize | ||||
| # PM: skôr "pre stavy maximized (maximalizovaný)/shaded (zatienený)" | ||||
| #: ../src/ui/theme-parser.c:3147 | ||||
| #, fuzzy, c-format | ||||
| msgid "" | ||||
| @@ -1700,221 +1706,172 @@ msgstr "<%s> uvedený dvakrát pre túto tému" | ||||
| msgid "Failed to find a valid file for theme %s\n" | ||||
| msgstr "Zlyhalo nájdenie platného súboru pre tému%s\n" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:99 | ||||
| msgid "_Windows" | ||||
| msgstr "_Okná" | ||||
| #~ msgid "Usage: %s\n" | ||||
| #~ msgstr "Použitie: %s\n" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:100 | ||||
| msgid "_Dialog" | ||||
| msgstr "_Dialógové okno" | ||||
| #~ msgid "_Windows" | ||||
| #~ msgstr "_Okná" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:101 | ||||
| msgid "_Modal dialog" | ||||
| msgstr "_Modálne dialógové okno" | ||||
| #~ msgid "_Dialog" | ||||
| #~ msgstr "_Dialógové okno" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:102 | ||||
| msgid "_Utility" | ||||
| msgstr "_Nástroje" | ||||
| #~ msgid "_Modal dialog" | ||||
| #~ msgstr "_Modálne dialógové okno" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:103 | ||||
| msgid "_Splashscreen" | ||||
| msgstr "Ú_vodná obrazovka" | ||||
| #~ msgid "_Utility" | ||||
| #~ msgstr "_Nástroje" | ||||
|  | ||||
| #~ msgid "_Splashscreen" | ||||
| #~ msgstr "Ú_vodná obrazovka" | ||||
|  | ||||
| # MČ: nie som si istý prekladom „dok“, nemal by to byť „panel“? | ||||
| #: ../src/ui/theme-viewer.c:104 | ||||
| msgid "_Top dock" | ||||
| msgstr "_Horný panel" | ||||
| #~ msgid "_Top dock" | ||||
| #~ msgstr "_Horný panel" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:105 | ||||
| msgid "_Bottom dock" | ||||
| msgstr "_Spodný panel" | ||||
| #~ msgid "_Bottom dock" | ||||
| #~ msgstr "_Spodný panel" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:106 | ||||
| msgid "_Left dock" | ||||
| msgstr "Ľ_avý panel" | ||||
| #~ msgid "_Left dock" | ||||
| #~ msgstr "Ľ_avý panel" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:107 | ||||
| msgid "_Right dock" | ||||
| msgstr "_Pravý panel" | ||||
| #~ msgid "_Right dock" | ||||
| #~ msgstr "_Pravý panel" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:108 | ||||
| msgid "_All docks" | ||||
| msgstr "_Všetky panely" | ||||
| #~ msgid "_All docks" | ||||
| #~ msgstr "_Všetky panely" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:109 | ||||
| msgid "Des_ktop" | ||||
| msgstr "P_racovná plocha" | ||||
| #~ msgid "Des_ktop" | ||||
| #~ msgstr "P_racovná plocha" | ||||
|  | ||||
| # tooltip | ||||
| #: ../src/ui/theme-viewer.c:115 | ||||
| msgid "Open another one of these windows" | ||||
| msgstr "Otvorí ďalšie z týchto okien" | ||||
| #~ msgid "Open another one of these windows" | ||||
| #~ msgstr "Otvorí ďalšie z týchto okien" | ||||
|  | ||||
| # PK: prekladat to v uvodzovkach? nahlas bug | ||||
| # tooltip | ||||
| # JK: https://bugzilla.gnome.org/show_bug.cgi?id=698123 | ||||
| #: ../src/ui/theme-viewer.c:117 | ||||
| #, fuzzy | ||||
| msgid "This is a demo button with an 'open' icon" | ||||
| msgstr "Toto je ukážkové tlačidlo s ikonou „open“" | ||||
| #~ msgid "This is a demo button with an 'open' icon" | ||||
| #~ msgstr "Toto je ukážkové tlačidlo s ikonou „open“" | ||||
|  | ||||
| # tooltip | ||||
| # JK: https://bugzilla.gnome.org/show_bug.cgi?id=698123 | ||||
| #: ../src/ui/theme-viewer.c:119 | ||||
| #, fuzzy | ||||
| msgid "This is a demo button with a 'quit' icon" | ||||
| msgstr "Toto je ukážkové tlačidlo s ikonou „quit“" | ||||
| #~ msgid "This is a demo button with a 'quit' icon" | ||||
| #~ msgstr "Toto je ukážkové tlačidlo s ikonou „quit“" | ||||
|  | ||||
| # label | ||||
| #: ../src/ui/theme-viewer.c:248 | ||||
| msgid "This is a sample message in a sample dialog" | ||||
| msgstr "Toto je ukážková správa v ukážkovom dialógovom okne" | ||||
| #~ msgid "This is a sample message in a sample dialog" | ||||
| #~ msgstr "Toto je ukážková správa v ukážkovom dialógovom okne" | ||||
|  | ||||
| # PK: falosna | ||||
| #: ../src/ui/theme-viewer.c:328 | ||||
| #, c-format | ||||
| msgid "Fake menu item %d\n" | ||||
| msgstr "Falošná položka ponuky č. %d\n" | ||||
| #~ msgid "Fake menu item %d\n" | ||||
| #~ msgstr "Falošná položka ponuky č. %d\n" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:363 | ||||
| msgid "Border-only window" | ||||
| msgstr "Okno len s okrajom" | ||||
| #~ msgid "Border-only window" | ||||
| #~ msgstr "Okno len s okrajom" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:365 | ||||
| msgid "Bar" | ||||
| msgstr "Lišta" | ||||
| #~ msgid "Bar" | ||||
| #~ msgstr "Lišta" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:382 | ||||
| msgid "Normal Application Window" | ||||
| msgstr "Normálne aplikačné okno" | ||||
| #~ msgid "Normal Application Window" | ||||
| #~ msgstr "Normálne aplikačné okno" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:386 | ||||
| msgid "Dialog Box" | ||||
| msgstr "Dialógové okno" | ||||
| #~ msgid "Dialog Box" | ||||
| #~ msgstr "Dialógové okno" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:390 | ||||
| msgid "Modal Dialog Box" | ||||
| msgstr "Modálne dialógové okno" | ||||
| #~ msgid "Modal Dialog Box" | ||||
| #~ msgstr "Modálne dialógové okno" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:394 | ||||
| msgid "Utility Palette" | ||||
| msgstr "Paleta nástrojov" | ||||
| #~ msgid "Utility Palette" | ||||
| #~ msgstr "Paleta nástrojov" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:398 | ||||
| msgid "Torn-off Menu" | ||||
| msgstr "Vypnúť ponuku" | ||||
| #~ msgid "Torn-off Menu" | ||||
| #~ msgstr "Vypnúť ponuku" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:402 | ||||
| msgid "Border" | ||||
| msgstr "Okraj" | ||||
| #~ msgid "Border" | ||||
| #~ msgstr "Okraj" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:406 | ||||
| msgid "Attached Modal Dialog" | ||||
| msgstr "Pričlenené modálne okno" | ||||
| #~ msgid "Attached Modal Dialog" | ||||
| #~ msgstr "Pričlenené modálne okno" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:737 | ||||
| #, c-format | ||||
| msgid "Button layout test %d" | ||||
| msgstr "Test rozloženia tlačidiel č. %d" | ||||
| #~ msgid "Button layout test %d" | ||||
| #~ msgstr "Test rozloženia tlačidiel č. %d" | ||||
|  | ||||
| # PK: plural forms | ||||
| # JK: https://bugzilla.gnome.org/show_bug.cgi?id=697987 | ||||
| #: ../src/ui/theme-viewer.c:766 | ||||
| #, fuzzy, c-format | ||||
| msgid "%g milliseconds to draw one window frame" | ||||
| msgstr "%g milisekúnd pre vykreslenie jedného rámca okna" | ||||
| #, fuzzy | ||||
| #~ msgid "%g milliseconds to draw one window frame" | ||||
| #~ msgstr "%g milisekúnd pre vykreslenie jedného rámca okna" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:811 | ||||
| #, c-format | ||||
| msgid "Usage: metacity-theme-viewer [THEMENAME]\n" | ||||
| msgstr "Použitie: metacity-theme-viewer [NÁZOVTÉMY]\n" | ||||
| #~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n" | ||||
| #~ msgstr "Použitie: metacity-theme-viewer [NÁZOVTÉMY]\n" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:818 | ||||
| #, c-format | ||||
| msgid "Error loading theme: %s\n" | ||||
| msgstr "Chyba pri načítavaní témy: %s\n" | ||||
| #~ msgid "Error loading theme: %s\n" | ||||
| #~ msgstr "Chyba pri načítavaní témy: %s\n" | ||||
|  | ||||
| # PK: plural forms | ||||
| # JK: https://bugzilla.gnome.org/show_bug.cgi?id=697987 | ||||
| #: ../src/ui/theme-viewer.c:824 | ||||
| #, fuzzy, c-format | ||||
| msgid "Loaded theme \"%s\" in %g seconds\n" | ||||
| msgstr "Téma „%s“ načítaná za %g sekúnd\n" | ||||
| #, fuzzy | ||||
| #~ msgid "Loaded theme \"%s\" in %g seconds\n" | ||||
| #~ msgstr "Téma „%s“ načítaná za %g sekúnd\n" | ||||
|  | ||||
| # PK: inde titulku, aky je rozdiel | ||||
| #: ../src/ui/theme-viewer.c:869 | ||||
| msgid "Normal Title Font" | ||||
| msgstr "Obyčajné písmo titulku" | ||||
| #~ msgid "Normal Title Font" | ||||
| #~ msgstr "Obyčajné písmo titulku" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:875 | ||||
| msgid "Small Title Font" | ||||
| msgstr "Malé písmo titulku" | ||||
| #~ msgid "Small Title Font" | ||||
| #~ msgstr "Malé písmo titulku" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:881 | ||||
| msgid "Large Title Font" | ||||
| msgstr "Veľké písmo titulku" | ||||
| #~ msgid "Large Title Font" | ||||
| #~ msgstr "Veľké písmo titulku" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:886 | ||||
| msgid "Button Layouts" | ||||
| msgstr "Rozloženia tlačidiel" | ||||
| #~ msgid "Button Layouts" | ||||
| #~ msgstr "Rozloženia tlačidiel" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:891 | ||||
| msgid "Benchmark" | ||||
| msgstr "Test rýchlosti" | ||||
| #~ msgid "Benchmark" | ||||
| #~ msgstr "Test rýchlosti" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:947 | ||||
| msgid "Window Title Goes Here" | ||||
| msgstr "Sem príde názov okna" | ||||
| #~ msgid "Window Title Goes Here" | ||||
| #~ msgstr "Sem príde názov okna" | ||||
|  | ||||
| # PK: plural forms | ||||
| # JK: https://bugzilla.gnome.org/show_bug.cgi?id=697987 | ||||
| #: ../src/ui/theme-viewer.c:1053 | ||||
| #, fuzzy, c-format | ||||
| msgid "" | ||||
| "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g " | ||||
| "seconds wall clock time including X server resources (%g milliseconds per " | ||||
| "frame)\n" | ||||
| msgstr "" | ||||
| "Vykreslených %d rámcov za %g sekúnd na strane klienta (%g milisekúnd na " | ||||
| "rámec) a %g sekúnd celkového času vrátane zdrojov servera X (%g milisekúnd " | ||||
| "na rámec)\n" | ||||
| #, fuzzy | ||||
| #~ msgid "" | ||||
| #~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and " | ||||
| #~ "%g seconds wall clock time including X server resources (%g milliseconds " | ||||
| #~ "per frame)\n" | ||||
| #~ msgstr "" | ||||
| #~ "Vykreslených %d rámcov za %g sekúnd na strane klienta (%g milisekúnd na " | ||||
| #~ "rámec) a %g sekúnd celkového času vrátane zdrojov servera X (%g " | ||||
| #~ "milisekúnd na rámec)\n" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:1273 | ||||
| msgid "position expression test returned TRUE but set error" | ||||
| msgstr "test výrazu polohy vrátil TRUE, ale nastavil chybu" | ||||
| #~ msgid "position expression test returned TRUE but set error" | ||||
| #~ msgstr "test výrazu polohy vrátil TRUE, ale nastavil chybu" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:1275 | ||||
| msgid "position expression test returned FALSE but didn't set error" | ||||
| msgstr "test výrazu polohy vrátil FALSE, ale nenastavil chybu" | ||||
| #~ msgid "position expression test returned FALSE but didn't set error" | ||||
| #~ msgstr "test výrazu polohy vrátil FALSE, ale nenastavil chybu" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:1279 | ||||
| msgid "Error was expected but none given" | ||||
| msgstr "Bola očakávaná chyba, ale žiadna nenastala" | ||||
| #~ msgid "Error was expected but none given" | ||||
| #~ msgstr "Bola očakávaná chyba, ale žiadna nenastala" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:1281 | ||||
| #, c-format | ||||
| msgid "Error %d was expected but %d given" | ||||
| msgstr "Bola očakávaná chyba %d, ale nastala %d" | ||||
| #~ msgid "Error %d was expected but %d given" | ||||
| #~ msgstr "Bola očakávaná chyba %d, ale nastala %d" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:1287 | ||||
| #, c-format | ||||
| msgid "Error not expected but one was returned: %s" | ||||
| msgstr "Chyba nebola očakávaná, ale bola vrátená: %s" | ||||
| #~ msgid "Error not expected but one was returned: %s" | ||||
| #~ msgstr "Chyba nebola očakávaná, ale bola vrátená: %s" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:1291 | ||||
| #, c-format | ||||
| msgid "x value was %d, %d was expected" | ||||
| msgstr "hodnota x bola %d, očakávaná bola %d" | ||||
| #~ msgid "x value was %d, %d was expected" | ||||
| #~ msgstr "hodnota x bola %d, očakávaná bola %d" | ||||
|  | ||||
| #: ../src/ui/theme-viewer.c:1294 | ||||
| #, c-format | ||||
| msgid "y value was %d, %d was expected" | ||||
| msgstr "hodnota y bola %d, očakávaná bola %d" | ||||
| #~ msgid "y value was %d, %d was expected" | ||||
| #~ msgstr "hodnota y bola %d, očakávaná bola %d" | ||||
|  | ||||
| # PK: plural forms | ||||
| # JK: https://bugzilla.gnome.org/show_bug.cgi?id=697987 | ||||
| #: ../src/ui/theme-viewer.c:1359 | ||||
| #, fuzzy, c-format | ||||
| msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" | ||||
| msgstr "" | ||||
| "%d výrazov pre súradnice analyzovaných za %g sekúnd (priemer %g sekúnd)\n" | ||||
| #, fuzzy | ||||
| #~ msgid "" | ||||
| #~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n" | ||||
| #~ msgstr "" | ||||
| #~ "%d výrazov pre súradnice analyzovaných za %g sekúnd (priemer %g sekúnd)\n" | ||||
|   | ||||
							
								
								
									
										762
									
								
								po/sr@latin.po
									
									
									
									
									
								
							
							
						
						
									
										762
									
								
								po/sr@latin.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1288
									
								
								po/zh_CN.po
									
									
									
									
									
								
							
							
						
						
									
										1288
									
								
								po/zh_CN.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										528
									
								
								po/zh_HK.po
									
									
									
									
									
								
							
							
						
						
									
										528
									
								
								po/zh_HK.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										528
									
								
								po/zh_TW.po
									
									
									
									
									
								
							
							
						
						
									
										528
									
								
								po/zh_TW.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,7 +0,0 @@ | ||||
| NULL = | ||||
|  | ||||
| EXTRA_DIST = \ | ||||
| 	gtk-shell.xml \ | ||||
| 	xdg-shell.xml \ | ||||
| 	xserver.xml \ | ||||
| 	$(NULL) | ||||
| @@ -1,18 +0,0 @@ | ||||
| <protocol name="xserver"> | ||||
|  | ||||
|   <interface name="xserver" version="1"> | ||||
|     <request name="set_window_id"> | ||||
|       <arg name="surface" type="object" interface="wl_surface"/> | ||||
|       <arg name="id" type="uint"/> | ||||
|     </request> | ||||
|  | ||||
|     <event name="client"> | ||||
|       <arg name="fd" type="fd"/> | ||||
|     </event> | ||||
|  | ||||
|     <event name="listen_socket"> | ||||
|       <arg name="fd" type="fd"/> | ||||
|     </event> | ||||
|   </interface> | ||||
|  | ||||
| </protocol> | ||||
| @@ -17,6 +17,9 @@ | ||||
| 	<KeyListEntry name="move-to-workspace-4" | ||||
| 	              _description="Move window to workspace 4" /> | ||||
|  | ||||
|         <KeyListEntry name="move-to-workspace-last" | ||||
|                       _description="Move window to last workspace" /> | ||||
|  | ||||
| 	<KeyListEntry name="move-to-workspace-left" | ||||
| 	              _description="Move window one workspace to the left" /> | ||||
|  | ||||
| @@ -77,6 +80,9 @@ | ||||
| 	<KeyListEntry name="switch-to-workspace-4" | ||||
| 	              _description="Switch to workspace 4" /> | ||||
|  | ||||
| 	<KeyListEntry name="switch-to-workspace-last" | ||||
| 	              _description="Switch to last workspace" /> | ||||
|  | ||||
| 	<KeyListEntry name="switch-to-workspace-left" | ||||
| 	              _description="Move to workspace left" /> | ||||
|  | ||||
|   | ||||
							
								
								
									
										232
									
								
								src/Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										232
									
								
								src/Makefile.am
									
									
									
									
									
								
							| @@ -1,7 +1,7 @@ | ||||
| # Flag build for parallelism; see https://savannah.gnu.org/patch/?6905 | ||||
| .AUTOPARALLEL: | ||||
|  | ||||
| lib_LTLIBRARIES = libmutter-wayland.la | ||||
| lib_LTLIBRARIES = libmutter.la | ||||
|  | ||||
| SUBDIRS=compositor/plugins | ||||
|  | ||||
| @@ -11,8 +11,9 @@ INCLUDES=								\ | ||||
| 	-DCOGL_ENABLE_EXPERIMENTAL_API					\ | ||||
| 	-DCOGL_ENABLE_EXPERIMENTAL_2_0_API                              \ | ||||
| 	$(MUTTER_CFLAGS)						\ | ||||
| 	-I$(top_builddir)						\ | ||||
| 	$(MUTTER_NATIVE_BACKEND_CFLAGS)					\ | ||||
| 	-I$(srcdir)							\ | ||||
| 	-I$(srcdir)/backends						\ | ||||
| 	-I$(srcdir)/core						\ | ||||
| 	-I$(srcdir)/ui							\ | ||||
| 	-I$(srcdir)/compositor						\ | ||||
| @@ -29,28 +30,58 @@ INCLUDES=								\ | ||||
| 	-DMUTTER_PLUGIN_API_VERSION=$(MUTTER_PLUGIN_API_VERSION)	\ | ||||
| 	-DMUTTER_PKGLIBDIR=\"$(pkglibdir)\"				\ | ||||
| 	-DMUTTER_PLUGIN_DIR=\"@MUTTER_PLUGIN_DIR@\"			\ | ||||
| 	-DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" | ||||
|  | ||||
| INCLUDES += \ | ||||
| 	-I$(srcdir)/wayland						\ | ||||
| 	-I$(builddir)/wayland						\ | ||||
| 	-DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\"			\ | ||||
| 	-DXWAYLAND_PATH='"@XWAYLAND_PATH@"' | ||||
|  | ||||
| mutter_built_sources = \ | ||||
| 	$(dbus_idle_built_sources)		\ | ||||
| 	$(dbus_xrandr_built_sources)		\ | ||||
| 	$(dbus_display_config_built_sources)	\ | ||||
| 	$(dbus_login1_built_sources)		\ | ||||
| 	mutter-enum-types.h 			\ | ||||
| 	mutter-enum-types.c			\ | ||||
| 	wayland/gtk-shell-protocol.c		\ | ||||
| 	wayland/gtk-shell-server-protocol.h	\ | ||||
| 	wayland/xdg-shell-protocol.c		\ | ||||
| 	wayland/xdg-shell-server-protocol.h	\ | ||||
| 	wayland/xserver-protocol.c		\ | ||||
| 	wayland/xserver-server-protocol.h | ||||
| 	gtk-shell-protocol.c			\ | ||||
| 	gtk-shell-server-protocol.h		\ | ||||
| 	xdg-shell-protocol.c			\ | ||||
| 	xdg-shell-server-protocol.h | ||||
|  | ||||
| libmutter_wayland_la_SOURCES =			\ | ||||
| 	core/async-getprop.c			\ | ||||
| 	core/async-getprop.h			\ | ||||
| wayland_protocols = \ | ||||
| 	wayland/protocol/gtk-shell.xml		\ | ||||
| 	wayland/protocol/xdg-shell.xml | ||||
|  | ||||
| libmutter_la_SOURCES =				\ | ||||
| 	backends/meta-backend.c			\ | ||||
| 	backends/meta-backend.h			\ | ||||
| 	backends/meta-backend-private.h		\ | ||||
| 	backends/meta-cursor.c			\ | ||||
| 	backends/meta-cursor.h			\ | ||||
| 	backends/meta-cursor-private.h		\ | ||||
| 	backends/meta-cursor-tracker.c		\ | ||||
| 	backends/meta-cursor-tracker-private.h	\ | ||||
| 	backends/meta-cursor-renderer.c		\ | ||||
| 	backends/meta-cursor-renderer.h		\ | ||||
| 	backends/meta-display-config-shared.h	\ | ||||
| 	backends/meta-idle-monitor.c		\ | ||||
| 	backends/meta-idle-monitor-private.h	\ | ||||
| 	backends/meta-idle-monitor-dbus.c	\ | ||||
| 	backends/meta-idle-monitor-dbus.h	\ | ||||
| 	backends/meta-monitor-config.c		\ | ||||
| 	backends/meta-monitor-config.h		\ | ||||
| 	backends/meta-monitor-manager.c		\ | ||||
| 	backends/meta-monitor-manager.h		\ | ||||
| 	backends/meta-monitor-manager-dummy.c	\ | ||||
| 	backends/meta-monitor-manager-dummy.h	\ | ||||
| 	backends/edid-parse.c			\ | ||||
| 	backends/edid.h				\ | ||||
| 	backends/x11/meta-backend-x11.c			\ | ||||
| 	backends/x11/meta-backend-x11.h			\ | ||||
| 	backends/x11/meta-cursor-renderer-x11.c		\ | ||||
| 	backends/x11/meta-cursor-renderer-x11.h		\ | ||||
| 	backends/x11/meta-idle-monitor-xsync.c		\ | ||||
| 	backends/x11/meta-idle-monitor-xsync.h		\ | ||||
| 	backends/x11/meta-monitor-manager-xrandr.c	\ | ||||
| 	backends/x11/meta-monitor-manager-xrandr.h	\ | ||||
| 	core/meta-accel-parse.c			\ | ||||
| 	core/meta-accel-parse.h			\ | ||||
| 	core/barrier.c				\ | ||||
| 	meta/barrier.h				\ | ||||
| 	core/bell.c				\ | ||||
| @@ -85,6 +116,10 @@ libmutter_wayland_la_SOURCES =			\ | ||||
| 	compositor/meta-surface-actor-x11.h	\ | ||||
| 	compositor/meta-surface-actor-wayland.c	\ | ||||
| 	compositor/meta-surface-actor-wayland.h	\ | ||||
| 	compositor/meta-stage.h			\ | ||||
| 	compositor/meta-stage.c			\ | ||||
| 	compositor/meta-sync-ring.c		\ | ||||
| 	compositor/meta-sync-ring.h		\ | ||||
| 	compositor/meta-texture-rectangle.c	\ | ||||
| 	compositor/meta-texture-rectangle.h	\ | ||||
| 	compositor/meta-texture-tower.c		\ | ||||
| @@ -105,7 +140,6 @@ libmutter_wayland_la_SOURCES =			\ | ||||
| 	meta/meta-shadow-factory.h		\ | ||||
| 	meta/meta-window-actor.h		\ | ||||
| 	meta/compositor-mutter.h 		\ | ||||
| 	core/above-tab-keycode.c		\ | ||||
| 	core/constraints.c			\ | ||||
| 	core/constraints.h			\ | ||||
| 	core/core.c				\ | ||||
| @@ -115,35 +149,17 @@ libmutter_wayland_la_SOURCES =			\ | ||||
| 	meta/display.h				\ | ||||
| 	core/edge-resistance.c			\ | ||||
| 	core/edge-resistance.h			\ | ||||
| 	core/edid-parse.c			\ | ||||
| 	core/edid.h				\ | ||||
| 	core/events.c				\ | ||||
| 	core/events.h				\ | ||||
| 	core/errors.c				\ | ||||
| 	meta/errors.h				\ | ||||
| 	core/frame.c				\ | ||||
| 	core/frame.h				\ | ||||
| 	ui/gradient.c				\ | ||||
| 	meta/gradient.h				\ | ||||
| 	core/group-private.h			\ | ||||
| 	core/group-props.c			\ | ||||
| 	core/group-props.h			\ | ||||
| 	core/group.c				\ | ||||
| 	meta/group.h				\ | ||||
| 	core/iconcache.c			\ | ||||
| 	core/iconcache.h			\ | ||||
| 	core/keybindings.c			\ | ||||
| 	core/keybindings-private.h		\ | ||||
| 	core/main.c				\ | ||||
| 	core/meta-cursor-tracker.c		\ | ||||
| 	core/meta-cursor-tracker-private.h	\ | ||||
| 	core/meta-idle-monitor.c		\ | ||||
| 	core/meta-idle-monitor-private.h	\ | ||||
| 	core/meta-xrandr-shared.h		\ | ||||
| 	core/monitor.c				\ | ||||
| 	core/monitor-config.c			\ | ||||
| 	core/monitor-kms.c			\ | ||||
| 	core/monitor-private.h			\ | ||||
| 	core/monitor-xrandr.c			\ | ||||
| 	core/mutter-Xatomtype.h			\ | ||||
| 	core/place.c				\ | ||||
| 	core/place.h				\ | ||||
| 	core/prefs.c				\ | ||||
| @@ -152,8 +168,6 @@ libmutter_wayland_la_SOURCES =			\ | ||||
| 	core/screen-private.h			\ | ||||
| 	meta/screen.h				\ | ||||
| 	meta/types.h				\ | ||||
| 	core/session.c				\ | ||||
| 	core/session.h				\ | ||||
| 	core/stack.c				\ | ||||
| 	core/stack.h				\ | ||||
| 	core/stack-tracker.c			\ | ||||
| @@ -161,26 +175,16 @@ libmutter_wayland_la_SOURCES =			\ | ||||
| 	core/util.c				\ | ||||
| 	meta/util.h				\ | ||||
| 	core/util-private.h			\ | ||||
| 	core/window-props.c			\ | ||||
| 	core/window-props.h			\ | ||||
| 	core/window-x11.c			\ | ||||
| 	core/window-x11.h			\ | ||||
| 	core/window.c				\ | ||||
| 	core/window-private.h			\ | ||||
| 	meta/window.h				\ | ||||
| 	core/workspace.c			\ | ||||
| 	core/workspace-private.h		\ | ||||
| 	core/xprops.c				\ | ||||
| 	core/xprops.h				\ | ||||
| 	meta/common.h				\ | ||||
| 	core/core.h				\ | ||||
| 	ui/ui.h					\ | ||||
| 	ui/frames.c				\ | ||||
| 	ui/frames.h				\ | ||||
| 	ui/menu.c				\ | ||||
| 	ui/menu.h				\ | ||||
| 	ui/metaaccellabel.c			\ | ||||
| 	ui/metaaccellabel.h			\ | ||||
| 	ui/resizepopup.c			\ | ||||
| 	ui/resizepopup.h			\ | ||||
| 	ui/theme-parser.c			\ | ||||
| @@ -188,11 +192,31 @@ libmutter_wayland_la_SOURCES =			\ | ||||
| 	meta/theme.h				\ | ||||
| 	ui/theme-private.h			\ | ||||
| 	ui/ui.c					\ | ||||
| 	x11/iconcache.c				\ | ||||
| 	x11/iconcache.h				\ | ||||
| 	x11/async-getprop.c			\ | ||||
| 	x11/async-getprop.h			\ | ||||
| 	x11/group-private.h			\ | ||||
| 	x11/group-props.c			\ | ||||
| 	x11/group-props.h			\ | ||||
| 	x11/group.c				\ | ||||
| 	meta/group.h				\ | ||||
| 	x11/session.c				\ | ||||
| 	x11/session.h				\ | ||||
| 	x11/window-props.c			\ | ||||
| 	x11/window-props.h			\ | ||||
| 	x11/window-x11.c			\ | ||||
| 	x11/window-x11.h			\ | ||||
| 	x11/window-x11-private.h		\ | ||||
| 	x11/xprops.c				\ | ||||
| 	x11/xprops.h				\ | ||||
| 	x11/mutter-Xatomtype.h			\ | ||||
| 	wayland/meta-wayland.c			\ | ||||
| 	wayland/meta-wayland.h			\ | ||||
| 	wayland/meta-wayland-private.h		\ | ||||
| 	wayland/meta-xwayland-private.h		\ | ||||
| 	wayland/meta-xwayland.c			\ | ||||
| 	wayland/meta-xwayland.h			\ | ||||
| 	wayland/meta-xwayland-private.h		\ | ||||
| 	wayland/meta-wayland-data-device.c      \ | ||||
| 	wayland/meta-wayland-data-device.h      \ | ||||
| 	wayland/meta-wayland-keyboard.c		\ | ||||
| @@ -201,20 +225,36 @@ libmutter_wayland_la_SOURCES =			\ | ||||
| 	wayland/meta-wayland-pointer.h		\ | ||||
| 	wayland/meta-wayland-seat.c		\ | ||||
| 	wayland/meta-wayland-seat.h		\ | ||||
| 	wayland/meta-wayland-stage.h		\ | ||||
| 	wayland/meta-wayland-stage.c		\ | ||||
| 	wayland/meta-wayland-surface.c		\ | ||||
| 	wayland/meta-wayland-surface.h		\ | ||||
| 	wayland/meta-wayland-types.h		\ | ||||
| 	wayland/meta-wayland-versions.h		\ | ||||
| 	wayland/meta-weston-launch.c		\ | ||||
| 	wayland/meta-weston-launch.h | ||||
| 	wayland/meta-wayland-outputs.c		\ | ||||
| 	wayland/meta-wayland-outputs.h		\ | ||||
| 	wayland/window-wayland.c		\ | ||||
| 	wayland/window-wayland.h | ||||
|  | ||||
| nodist_libmutter_wayland_la_SOURCES =		\ | ||||
| if HAVE_NATIVE_BACKEND | ||||
| libmutter_la_SOURCES +=					\ | ||||
| 	backends/native/meta-backend-native.c		\ | ||||
| 	backends/native/meta-backend-native.h		\ | ||||
| 	backends/native/meta-cursor-renderer-native.c	\ | ||||
| 	backends/native/meta-cursor-renderer-native.h	\ | ||||
| 	backends/native/meta-idle-monitor-native.c	\ | ||||
| 	backends/native/meta-idle-monitor-native.h	\ | ||||
| 	backends/native/meta-monitor-manager-kms.c	\ | ||||
| 	backends/native/meta-monitor-manager-kms.h	\ | ||||
| 	backends/native/meta-launcher.c			\ | ||||
| 	backends/native/meta-launcher.h			\ | ||||
| 	backends/native/dbus-utils.c			\ | ||||
| 	backends/native/dbus-utils.h | ||||
| endif | ||||
|  | ||||
| nodist_libmutter_la_SOURCES =			\ | ||||
| 	$(mutter_built_sources) | ||||
|  | ||||
| libmutter_wayland_la_LDFLAGS = -no-undefined | ||||
| libmutter_wayland_la_LIBADD  = $(MUTTER_LIBS) | ||||
| libmutter_la_LDFLAGS = -no-undefined | ||||
| libmutter_la_LIBADD  = $(MUTTER_LIBS) $(MUTTER_NATIVE_BACKEND_LIBS) | ||||
|  | ||||
| # Headers installed for plugins; introspected information will | ||||
| # be extracted into Mutter-<version>.gir | ||||
| @@ -252,27 +292,16 @@ libmutterinclude_base_headers =		\ | ||||
| libmutterinclude_extra_headers =		\ | ||||
| 	meta/atomnames.h | ||||
|  | ||||
| libmutterincludedir = $(includedir)/mutter-wayland/meta | ||||
| libmutterincludedir = $(includedir)/mutter/meta | ||||
|  | ||||
| libmutterinclude_HEADERS =			\ | ||||
| 	$(libmutterinclude_base_headers)	\ | ||||
| 	$(libmutterinclude_extra_headers) | ||||
|  | ||||
| bin_PROGRAMS=mutter-wayland | ||||
| bin_PROGRAMS=mutter | ||||
|  | ||||
| mutter_wayland_SOURCES = core/mutter.c | ||||
| mutter_wayland_LDADD = $(MUTTER_LIBS) libmutter-wayland.la | ||||
|  | ||||
| bin_PROGRAMS+=mutter-launch | ||||
|  | ||||
| mutter_launch_SOURCES = wayland/weston-launch.c wayland/weston-launch.h | ||||
|  | ||||
| mutter_launch_CFLAGS = $(MUTTER_LAUNCH_CFLAGS) -DLIBDIR=\"$(libdir)\" | ||||
| mutter_launch_LDFLAGS = $(MUTTER_LAUNCH_LIBS) -lpam | ||||
|  | ||||
| install-exec-hook: | ||||
| 	-chown root $(DESTDIR)$(bindir)/mutter-launch | ||||
| 	-chmod u+s $(DESTDIR)$(bindir)/mutter-launch | ||||
| mutter_SOURCES = core/mutter.c | ||||
| mutter_LDADD = $(MUTTER_LIBS) libmutter.la | ||||
|  | ||||
| if HAVE_INTROSPECTION | ||||
| include $(INTROSPECTION_MAKEFILE) | ||||
| @@ -294,33 +323,33 @@ typelib_DATA = Meta-$(api_version).typelib | ||||
|  | ||||
| INTROSPECTION_GIRS = Meta-$(api_version).gir | ||||
|  | ||||
| Meta-$(api_version).gir: libmutter-wayland.la | ||||
| Meta-$(api_version).gir: libmutter.la | ||||
| @META_GIR@_INCLUDES = GObject-2.0 GDesktopEnums-3.0 Gdk-3.0 Gtk-3.0 Clutter-1.0 xlib-2.0 xfixes-4.0 Cogl-1.0 | ||||
| @META_GIR@_EXPORT_PACKAGES = libmutter-wayland | ||||
| @META_GIR@_EXPORT_PACKAGES = libmutter | ||||
| @META_GIR@_CFLAGS = $(INCLUDES) | ||||
| @META_GIR@_LIBS = libmutter-wayland.la | ||||
| @META_GIR@_LIBS = libmutter.la | ||||
| @META_GIR@_FILES =				\ | ||||
| 	mutter-enum-types.h			\ | ||||
| 	$(libmutterinclude_base_headers)	\ | ||||
| 	$(filter %.c,$(libmutter_wayland_la_SOURCES) $(nodist_libmutter_wayland_la_SOURCES)) | ||||
| 	$(filter %.c,$(libmutter_la_SOURCES) $(nodist_libmutter_la_SOURCES)) | ||||
| @META_GIR@_SCANNERFLAGS = --warn-all --warn-error | ||||
|  | ||||
| endif | ||||
|  | ||||
| testboxes_SOURCES = core/testboxes.c | ||||
| testgradient_SOURCES = ui/testgradient.c | ||||
| testasyncgetprop_SOURCES = core/testasyncgetprop.c | ||||
| testasyncgetprop_SOURCES = x11/testasyncgetprop.c | ||||
|  | ||||
| noinst_PROGRAMS=testboxes testgradient testasyncgetprop | ||||
|  | ||||
| testboxes_LDADD = $(MUTTER_LIBS) libmutter-wayland.la | ||||
| testgradient_LDADD = $(MUTTER_LIBS) libmutter-wayland.la | ||||
| testasyncgetprop_LDADD = $(MUTTER_LIBS) libmutter-wayland.la | ||||
| testboxes_LDADD = $(MUTTER_LIBS) libmutter.la | ||||
| testgradient_LDADD = $(MUTTER_LIBS) libmutter.la | ||||
| testasyncgetprop_LDADD = $(MUTTER_LIBS) libmutter.la | ||||
|  | ||||
| @INTLTOOL_DESKTOP_RULE@ | ||||
|  | ||||
| desktopfilesdir=$(datadir)/applications | ||||
| desktopfiles_in_files=mutter-wayland.desktop.in | ||||
| desktopfiles_in_files=mutter.desktop.in | ||||
| desktopfiles_files=$(desktopfiles_in_files:.desktop.in=.desktop) | ||||
| desktopfiles_DATA = $(desktopfiles_files) | ||||
|  | ||||
| @@ -341,7 +370,7 @@ convertdir = $(datadir)/GConf/gsettings | ||||
| convert_DATA = mutter-schemas.convert | ||||
|  | ||||
| CLEANFILES =					\ | ||||
| 	mutter-wayland.desktop			\ | ||||
| 	mutter.desktop				\ | ||||
| 	mutter-wm.desktop			\ | ||||
| 	org.gnome.mutter.gschema.xml		\ | ||||
| 	org.gnome.mutter.wayland.gschema.xml	\ | ||||
| @@ -352,7 +381,7 @@ CLEANFILES =					\ | ||||
|  | ||||
| pkgconfigdir = $(libdir)/pkgconfig | ||||
|  | ||||
| pkgconfig_DATA = libmutter-wayland.pc | ||||
| pkgconfig_DATA = libmutter.pc | ||||
|  | ||||
| EXTRA_DIST=$(desktopfiles_files) 	\ | ||||
| 	$(wmproperties_files)		\ | ||||
| @@ -360,13 +389,16 @@ EXTRA_DIST=$(desktopfiles_files) 	\ | ||||
| 	$(desktopfiles_in_files)	\ | ||||
| 	$(wmproperties_in_files)	\ | ||||
| 	$(xml_in_files)			\ | ||||
| 	$(wayland_protocols)		\ | ||||
| 	org.gnome.mutter.gschema.xml.in \ | ||||
| 	org.gnome.mutter.wayland.gschema.xml.in \ | ||||
| 	mutter-schemas.convert \ | ||||
| 	libmutter-wayland.pc.in \ | ||||
| 	libmutter.pc.in \ | ||||
| 	mutter-enum-types.h.in \ | ||||
| 	mutter-enum-types.c.in \ | ||||
| 	xrandr.xml idle-monitor.xml | ||||
| 	org.freedesktop.login1.xml	\ | ||||
| 	org.gnome.Mutter.DisplayConfig.xml	\ | ||||
| 	org.gnome.Mutter.IdleMonitor.xml | ||||
|  | ||||
| BUILT_SOURCES = $(mutter_built_sources) | ||||
| MUTTER_STAMP_FILES = stamp-mutter-enum-types.h | ||||
| @@ -391,27 +423,33 @@ mutter-enum-types.c: stamp-mutter-enum-types.h mutter-enum-types.c.in | ||||
| 	cp xgen-tetc mutter-enum-types.c && \ | ||||
| 	rm -f xgen-tetc | ||||
|  | ||||
| dbus_xrandr_built_sources = meta-dbus-xrandr.c meta-dbus-xrandr.h | ||||
| dbus_display_config_built_sources = meta-dbus-display-config.c meta-dbus-display-config.h | ||||
|  | ||||
| $(dbus_xrandr_built_sources) : Makefile.am xrandr.xml | ||||
| $(dbus_display_config_built_sources) : Makefile.am org.gnome.Mutter.DisplayConfig.xml | ||||
| 	$(AM_V_GEN)gdbus-codegen							\ | ||||
| 		--interface-prefix org.gnome.Mutter					\ | ||||
| 		--c-namespace MetaDBus							\ | ||||
| 		--generate-c-code meta-dbus-xrandr					\ | ||||
| 		$(srcdir)/xrandr.xml | ||||
| 		--generate-c-code meta-dbus-display-config				\ | ||||
| 		$(srcdir)/org.gnome.Mutter.DisplayConfig.xml | ||||
|  | ||||
|  | ||||
| $(dbus_idle_built_sources) : Makefile.am idle-monitor.xml | ||||
| $(dbus_idle_built_sources) : Makefile.am org.gnome.Mutter.IdleMonitor.xml | ||||
| 	$(AM_V_GEN)gdbus-codegen							\ | ||||
| 		--interface-prefix org.gnome.Mutter					\ | ||||
| 		--c-namespace MetaDBus							\ | ||||
| 		--generate-c-code meta-dbus-idle-monitor				\ | ||||
| 		--c-generate-object-manager						\ | ||||
| 		$(srcdir)/idle-monitor.xml | ||||
| 		$(srcdir)/org.gnome.Mutter.IdleMonitor.xml | ||||
|  | ||||
| wayland/%-protocol.c : $(top_builddir)/protocol/%.xml | ||||
| 	mkdir -p wayland | ||||
| dbus_login1_built_sources = meta-dbus-login1.c meta-dbus-login1.h | ||||
|  | ||||
| $(dbus_login1_built_sources) : Makefile.am org.freedesktop.login1.xml | ||||
| 	$(AM_V_GEN)gdbus-codegen							\ | ||||
| 		--interface-prefix org.freedesktop.login1				\ | ||||
| 		--c-namespace Login1							\ | ||||
| 		--generate-c-code meta-dbus-login1					\ | ||||
| 		$(srcdir)/org.freedesktop.login1.xml | ||||
|  | ||||
| %-protocol.c : $(srcdir)/wayland/protocol/%.xml | ||||
| 	$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@ | ||||
| wayland/%-server-protocol.h : $(top_builddir)/protocol/%.xml | ||||
| 	mkdir -p wayland | ||||
| %-server-protocol.h : $(srcdir)/wayland/protocol/%.xml | ||||
| 	$(AM_V_GEN)$(WAYLAND_SCANNER) server-header < $< > $@ | ||||
|   | ||||
| @@ -179,7 +179,7 @@ decode_display_parameters (const uchar *edid, MonitorInfo *info) | ||||
|   else if (edid[0x16] == 0) | ||||
|     { | ||||
|       info->width_mm = -1; | ||||
|       info->height_mm = -1;  | ||||
|       info->height_mm = -1; | ||||
|       info->aspect_ratio = 100.0 / (edid[0x15] + 99); | ||||
|     } | ||||
|   else if (edid[0x15] == 0) | ||||
| @@ -267,7 +267,7 @@ decode_color_characteristics (const uchar *edid, MonitorInfo *info) | ||||
| static int | ||||
| decode_established_timings (const uchar *edid, MonitorInfo *info) | ||||
| { | ||||
|   static const Timing established[][8] =  | ||||
|   static const Timing established[][8] = | ||||
|     { | ||||
|       { | ||||
|         { 800, 600, 60 }, | ||||
| @@ -1,9 +1,9 @@ | ||||
| /* edid.h
 | ||||
|  * | ||||
|  * Copyright 2007, 2008, Red Hat, Inc. | ||||
|  *  | ||||
|  * | ||||
|  * This file is part of the Gnome Library. | ||||
|  *  | ||||
|  * | ||||
|  * The Gnome Library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Library General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
| @@ -13,12 +13,12 @@ | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Library General Public License for more details. | ||||
|  *  | ||||
|  * | ||||
|  * You should have received a copy of the GNU Library General Public | ||||
|  * License along with the Gnome Library; see the file COPYING.LIB.  If not, | ||||
|  * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||||
|  * Boston, MA 02110-1301, USA. | ||||
|  *  | ||||
|  * | ||||
|  * Author: Soren Sandmann <sandmann@redhat.com> | ||||
|  */ | ||||
| 
 | ||||
| @@ -177,7 +177,7 @@ struct MonitorInfo | ||||
|   DetailedTiming detailed_timings[4];	/* If monitor has a preferred
 | ||||
|                                          * mode, it is the first one | ||||
|                                          * (whether it has, is | ||||
|                                          * determined by the  | ||||
|                                          * determined by the | ||||
|                                          * preferred_timing_includes | ||||
|                                          * bit. | ||||
|                                          */ | ||||
							
								
								
									
										71
									
								
								src/backends/meta-backend-private.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/backends/meta-backend-private.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2014 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jasper St. Pierre <jstpierre@mecheye.net> | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #ifndef META_BACKEND_PRIVATE_H | ||||
| #define META_BACKEND_PRIVATE_H | ||||
|  | ||||
| #include <glib-object.h> | ||||
|  | ||||
| #include "meta-backend.h" | ||||
|  | ||||
| #define META_TYPE_BACKEND             (meta_backend_get_type ()) | ||||
| #define META_BACKEND(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BACKEND, MetaBackend)) | ||||
| #define META_BACKEND_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_BACKEND, MetaBackendClass)) | ||||
| #define META_IS_BACKEND(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_BACKEND)) | ||||
| #define META_IS_BACKEND_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_BACKEND)) | ||||
| #define META_BACKEND_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_BACKEND, MetaBackendClass)) | ||||
|  | ||||
| struct _MetaBackend | ||||
| { | ||||
|   GObject parent; | ||||
|  | ||||
|   MetaIdleMonitor *device_monitors[256]; | ||||
|   int device_id_max; | ||||
| }; | ||||
|  | ||||
| struct _MetaBackendClass | ||||
| { | ||||
|   GObjectClass parent_class; | ||||
|  | ||||
|   void (* post_init) (MetaBackend *backend); | ||||
|  | ||||
|   MetaIdleMonitor * (* create_idle_monitor) (MetaBackend *backend, | ||||
|                                              int          device_id); | ||||
|   MetaMonitorManager * (* create_monitor_manager) (MetaBackend *backend); | ||||
|   MetaCursorRenderer * (* create_cursor_renderer) (MetaBackend *backend); | ||||
|  | ||||
|   gboolean (* grab_device) (MetaBackend *backend, | ||||
|                             int          device_id, | ||||
|                             uint32_t     timestamp); | ||||
|   gboolean (* ungrab_device) (MetaBackend *backend, | ||||
|                               int          device_id, | ||||
|                               uint32_t     timestamp); | ||||
|  | ||||
|   void (* warp_pointer) (MetaBackend *backend, | ||||
|                          int          x, | ||||
|                          int          y); | ||||
| }; | ||||
|  | ||||
| #endif /* META_BACKEND_PRIVATE_H */ | ||||
							
								
								
									
										299
									
								
								src/backends/meta-backend.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										299
									
								
								src/backends/meta-backend.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,299 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2014 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jasper St. Pierre <jstpierre@mecheye.net> | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "meta-backend.h" | ||||
| #include "meta-backend-private.h" | ||||
|  | ||||
| #include <clutter/clutter.h> | ||||
|  | ||||
| #include "backends/x11/meta-backend-x11.h" | ||||
|  | ||||
| #ifdef HAVE_NATIVE_BACKEND | ||||
| #include "backends/native/meta-backend-native.h" | ||||
| #endif | ||||
|  | ||||
| static MetaBackend *_backend; | ||||
|  | ||||
| MetaBackend * | ||||
| meta_get_backend (void) | ||||
| { | ||||
|   return _backend; | ||||
| } | ||||
|  | ||||
| struct _MetaBackendPrivate | ||||
| { | ||||
|   MetaMonitorManager *monitor_manager; | ||||
|   MetaCursorRenderer *cursor_renderer; | ||||
| }; | ||||
| typedef struct _MetaBackendPrivate MetaBackendPrivate; | ||||
|  | ||||
| G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaBackend, meta_backend, G_TYPE_OBJECT); | ||||
|  | ||||
| static void | ||||
| meta_backend_finalize (GObject *object) | ||||
| { | ||||
|   MetaBackend *backend = META_BACKEND (object); | ||||
|   MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); | ||||
|   int i; | ||||
|  | ||||
|   g_clear_object (&priv->monitor_manager); | ||||
|  | ||||
|   for (i = 0; i <= backend->device_id_max; i++) | ||||
|     { | ||||
|       if (backend->device_monitors[i]) | ||||
|         g_object_unref (backend->device_monitors[i]); | ||||
|     } | ||||
|  | ||||
|   G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_backend_real_post_init (MetaBackend *backend) | ||||
| { | ||||
|   MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); | ||||
|  | ||||
|   priv->monitor_manager = META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend); | ||||
|   priv->cursor_renderer = META_BACKEND_GET_CLASS (backend)->create_cursor_renderer (backend); | ||||
| } | ||||
|  | ||||
| static MetaCursorRenderer * | ||||
| meta_backend_real_create_cursor_renderer (MetaBackend *backend) | ||||
| { | ||||
|   return meta_cursor_renderer_new (); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_backend_real_grab_device (MetaBackend *backend, | ||||
|                                int          device_id, | ||||
|                                uint32_t     timestamp) | ||||
| { | ||||
|   /* Do nothing */ | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_backend_real_ungrab_device (MetaBackend *backend, | ||||
|                                  int          device_id, | ||||
|                                  uint32_t     timestamp) | ||||
| { | ||||
|   /* Do nothing */ | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_backend_real_warp_pointer (MetaBackend *backend, | ||||
|                                 int          x, | ||||
|                                 int          y) | ||||
| { | ||||
|   /* Do nothing */ | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_backend_class_init (MetaBackendClass *klass) | ||||
| { | ||||
|   GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   object_class->finalize = meta_backend_finalize; | ||||
|  | ||||
|   klass->post_init = meta_backend_real_post_init; | ||||
|   klass->create_cursor_renderer = meta_backend_real_create_cursor_renderer; | ||||
|   klass->grab_device = meta_backend_real_grab_device; | ||||
|   klass->ungrab_device = meta_backend_real_ungrab_device; | ||||
|   klass->warp_pointer = meta_backend_real_warp_pointer; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_backend_init (MetaBackend *backend) | ||||
| { | ||||
|   _backend = backend; | ||||
| } | ||||
|  | ||||
| /* FIXME -- destroy device monitors at some point */ | ||||
| G_GNUC_UNUSED static void | ||||
| destroy_device_monitor (MetaBackend *backend, | ||||
|                         int          device_id) | ||||
| { | ||||
|   g_clear_object (&backend->device_monitors[device_id]); | ||||
|   if (device_id == backend->device_id_max) | ||||
|     backend->device_id_max--; | ||||
| } | ||||
|  | ||||
| static MetaIdleMonitor * | ||||
| meta_backend_create_idle_monitor (MetaBackend *backend, | ||||
|                                   int          device_id) | ||||
| { | ||||
|   return META_BACKEND_GET_CLASS (backend)->create_idle_monitor (backend, device_id); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_backend_post_init (MetaBackend *backend) | ||||
| { | ||||
|   META_BACKEND_GET_CLASS (backend)->post_init (backend); | ||||
| } | ||||
|  | ||||
| MetaIdleMonitor * | ||||
| meta_backend_get_idle_monitor (MetaBackend *backend, | ||||
|                                int          device_id) | ||||
| { | ||||
|   g_return_val_if_fail (device_id >= 0 && device_id < 256, NULL); | ||||
|  | ||||
|   if (!backend->device_monitors[device_id]) | ||||
|     { | ||||
|       backend->device_monitors[device_id] = meta_backend_create_idle_monitor (backend, device_id); | ||||
|       backend->device_id_max = MAX (backend->device_id_max, device_id); | ||||
|     } | ||||
|  | ||||
|   return backend->device_monitors[device_id]; | ||||
| } | ||||
|  | ||||
| MetaMonitorManager * | ||||
| meta_backend_get_monitor_manager (MetaBackend *backend) | ||||
| { | ||||
|   MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); | ||||
|  | ||||
|   return priv->monitor_manager; | ||||
| } | ||||
|  | ||||
| MetaCursorRenderer * | ||||
| meta_backend_get_cursor_renderer (MetaBackend *backend) | ||||
| { | ||||
|   MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); | ||||
|  | ||||
|   return priv->cursor_renderer; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_backend_grab_device (MetaBackend *backend, | ||||
|                           int          device_id, | ||||
|                           uint32_t     timestamp) | ||||
| { | ||||
|   return META_BACKEND_GET_CLASS (backend)->grab_device (backend, device_id, timestamp); | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_backend_ungrab_device (MetaBackend *backend, | ||||
|                             int          device_id, | ||||
|                             uint32_t     timestamp) | ||||
| { | ||||
|   return META_BACKEND_GET_CLASS (backend)->ungrab_device (backend, device_id, timestamp); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_backend_warp_pointer (MetaBackend *backend, | ||||
|                            int          x, | ||||
|                            int          y) | ||||
| { | ||||
|   META_BACKEND_GET_CLASS (backend)->warp_pointer (backend, x, y); | ||||
| } | ||||
|  | ||||
| static GType | ||||
| get_backend_type (void) | ||||
| { | ||||
| #if defined(CLUTTER_WINDOWING_X11) | ||||
|   if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11)) | ||||
|     return META_TYPE_BACKEND_X11; | ||||
| #endif | ||||
|  | ||||
| #if defined(CLUTTER_WINDOWING_EGL) && defined(HAVE_NATIVE_BACKEND) | ||||
|   if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL)) | ||||
|     return META_TYPE_BACKEND_NATIVE; | ||||
| #endif | ||||
|  | ||||
|   g_assert_not_reached (); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_create_backend (void) | ||||
| { | ||||
|   /* meta_backend_init() above install the backend globally so | ||||
|    * so meta_get_backend() works even during initialization. */ | ||||
|   g_object_new (get_backend_type (), NULL); | ||||
| } | ||||
|  | ||||
| /* Mutter is responsible for pulling events off the X queue, so Clutter | ||||
|  * doesn't need (and shouldn't) run its normal event source which polls | ||||
|  * the X fd, but we do have to deal with dispatching events that accumulate | ||||
|  * in the clutter queue. This happens, for example, when clutter generate | ||||
|  * enter/leave events on mouse motion - several events are queued in the | ||||
|  * clutter queue but only one dispatched. It could also happen because of | ||||
|  * explicit calls to clutter_event_put(). We add a very simple custom | ||||
|  * event loop source which is simply responsible for pulling events off | ||||
|  * of the queue and dispatching them before we block for new events. | ||||
|  */ | ||||
|  | ||||
| static gboolean | ||||
| event_prepare (GSource    *source, | ||||
|                gint       *timeout_) | ||||
| { | ||||
|   *timeout_ = -1; | ||||
|  | ||||
|   return clutter_events_pending (); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| event_check (GSource *source) | ||||
| { | ||||
|   return clutter_events_pending (); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| event_dispatch (GSource    *source, | ||||
|                 GSourceFunc callback, | ||||
|                 gpointer    user_data) | ||||
| { | ||||
|   ClutterEvent *event = clutter_event_get (); | ||||
|  | ||||
|   if (event) | ||||
|     { | ||||
|       clutter_do_event (event); | ||||
|       clutter_event_free (event); | ||||
|     } | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static GSourceFuncs event_funcs = { | ||||
|   event_prepare, | ||||
|   event_check, | ||||
|   event_dispatch | ||||
| }; | ||||
|  | ||||
| void | ||||
| meta_clutter_init (void) | ||||
| { | ||||
|   GSource *source; | ||||
|  | ||||
|   meta_create_backend (); | ||||
|  | ||||
|   if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS) | ||||
|     g_error ("Unable to initialize Clutter.\n"); | ||||
|  | ||||
|   source = g_source_new (&event_funcs, sizeof (GSource)); | ||||
|   g_source_attach (source, NULL); | ||||
|   g_source_unref (source); | ||||
|  | ||||
|   meta_backend_post_init (_backend); | ||||
| } | ||||
							
								
								
									
										59
									
								
								src/backends/meta-backend.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/backends/meta-backend.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2014 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jasper St. Pierre <jstpierre@mecheye.net> | ||||
|  */ | ||||
|  | ||||
| #ifndef META_BACKEND_H | ||||
| #define META_BACKEND_H | ||||
|  | ||||
| #include <glib-object.h> | ||||
|  | ||||
| #include <meta/meta-idle-monitor.h> | ||||
| #include "meta-monitor-manager.h" | ||||
| #include "meta-cursor-renderer.h" | ||||
|  | ||||
| typedef struct _MetaBackend        MetaBackend; | ||||
| typedef struct _MetaBackendClass   MetaBackendClass; | ||||
|  | ||||
| GType meta_backend_get_type (void); | ||||
|  | ||||
| MetaBackend * meta_get_backend (void); | ||||
|  | ||||
| MetaIdleMonitor * meta_backend_get_idle_monitor (MetaBackend *backend, | ||||
|                                                  int          device_id); | ||||
| MetaMonitorManager * meta_backend_get_monitor_manager (MetaBackend *backend); | ||||
| MetaCursorRenderer * meta_backend_get_cursor_renderer (MetaBackend *backend); | ||||
|  | ||||
| gboolean meta_backend_grab_device (MetaBackend *backend, | ||||
|                                    int          device_id, | ||||
|                                    uint32_t     timestamp); | ||||
| gboolean meta_backend_ungrab_device (MetaBackend *backend, | ||||
|                                      int          device_id, | ||||
|                                      uint32_t     timestamp); | ||||
|  | ||||
| void meta_backend_warp_pointer (MetaBackend *backend, | ||||
|                                 int          x, | ||||
|                                 int          y); | ||||
|  | ||||
| void meta_clutter_init (void); | ||||
|  | ||||
| #endif /* META_BACKEND_H */ | ||||
							
								
								
									
										51
									
								
								src/backends/meta-cursor-private.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/backends/meta-cursor-private.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright 2013 Red Hat, Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * Author: Giovanni Campagna <gcampagn@redhat.com> | ||||
|  */ | ||||
|  | ||||
| #ifndef META_CURSOR_PRIVATE_H | ||||
| #define META_CURSOR_PRIVATE_H | ||||
|  | ||||
| #include "meta-cursor.h" | ||||
|  | ||||
| #include <cogl/cogl.h> | ||||
| #include <gbm.h> | ||||
|  | ||||
| typedef struct { | ||||
|   CoglTexture2D *texture; | ||||
|   struct gbm_bo *bo; | ||||
|   int hot_x, hot_y; | ||||
| } MetaCursorImage; | ||||
|  | ||||
| struct _MetaCursorReference { | ||||
|   int ref_count; | ||||
|  | ||||
|   MetaCursor cursor; | ||||
|   MetaCursorImage image; | ||||
| }; | ||||
|  | ||||
| CoglTexture *meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor, | ||||
|                                                      int                 *hot_x, | ||||
|                                                      int                 *hot_y); | ||||
|  | ||||
| struct gbm_bo *meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor, | ||||
|                                                  int                 *hot_x, | ||||
|                                                  int                 *hot_y); | ||||
|  | ||||
| #endif /* META_CURSOR_PRIVATE_H */ | ||||
							
								
								
									
										172
									
								
								src/backends/meta-cursor-renderer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								src/backends/meta-cursor-renderer.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,172 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2014 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jasper St. Pierre <jstpierre@mecheye.net> | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "meta-cursor-renderer.h" | ||||
| #include "meta-cursor-private.h" | ||||
|  | ||||
| #include <cogl/cogl.h> | ||||
| #include <cogl/cogl-wayland-server.h> | ||||
| #include <clutter/clutter.h> | ||||
|  | ||||
| #include "meta-stage.h" | ||||
|  | ||||
| #include "wayland/meta-wayland-private.h" | ||||
|  | ||||
| struct _MetaCursorRendererPrivate | ||||
| { | ||||
|   int current_x, current_y; | ||||
|   MetaRectangle current_rect; | ||||
|  | ||||
|   MetaCursorReference *displayed_cursor; | ||||
|   gboolean handled_by_backend; | ||||
| }; | ||||
| typedef struct _MetaCursorRendererPrivate MetaCursorRendererPrivate; | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRenderer, meta_cursor_renderer, G_TYPE_OBJECT); | ||||
|  | ||||
| static void | ||||
| queue_redraw (MetaCursorRenderer *renderer) | ||||
| { | ||||
|   MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); | ||||
|   MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); | ||||
|   ClutterActor *stage = compositor->stage; | ||||
|  | ||||
|   /* During early initialization, we can have no stage */ | ||||
|   if (!stage) | ||||
|     return; | ||||
|  | ||||
|   if (priv->handled_by_backend) | ||||
|     meta_stage_set_cursor (META_STAGE (stage), NULL, &priv->current_rect); | ||||
|   else | ||||
|     meta_stage_set_cursor (META_STAGE (stage), priv->displayed_cursor, &priv->current_rect); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_cursor_renderer_real_update_cursor (MetaCursorRenderer *renderer) | ||||
| { | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_cursor_renderer_class_init (MetaCursorRendererClass *klass) | ||||
| { | ||||
|   klass->update_cursor = meta_cursor_renderer_real_update_cursor; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_cursor_renderer_init (MetaCursorRenderer *renderer) | ||||
| { | ||||
| } | ||||
|  | ||||
| static void | ||||
| update_cursor (MetaCursorRenderer *renderer) | ||||
| { | ||||
|   MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); | ||||
|   gboolean handled_by_backend; | ||||
|   gboolean should_redraw = FALSE; | ||||
|  | ||||
|   if (priv->displayed_cursor) | ||||
|     { | ||||
|       CoglTexture *texture; | ||||
|       int hot_x, hot_y; | ||||
|  | ||||
|       texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, &hot_x, &hot_y); | ||||
|  | ||||
|       priv->current_rect.x = priv->current_x - hot_x; | ||||
|       priv->current_rect.y = priv->current_y - hot_y; | ||||
|       priv->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (texture)); | ||||
|       priv->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (texture)); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       priv->current_rect.x = 0; | ||||
|       priv->current_rect.y = 0; | ||||
|       priv->current_rect.width = 0; | ||||
|       priv->current_rect.height = 0; | ||||
|     } | ||||
|  | ||||
|   handled_by_backend = META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer); | ||||
|   if (handled_by_backend != priv->handled_by_backend) | ||||
|     { | ||||
|       priv->handled_by_backend = handled_by_backend; | ||||
|       should_redraw = TRUE; | ||||
|     } | ||||
|  | ||||
|   if (!handled_by_backend) | ||||
|     should_redraw = TRUE; | ||||
|  | ||||
|   if (should_redraw) | ||||
|     queue_redraw (renderer); | ||||
| } | ||||
|  | ||||
| MetaCursorRenderer * | ||||
| meta_cursor_renderer_new (void) | ||||
| { | ||||
|   return g_object_new (META_TYPE_CURSOR_RENDERER, NULL); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_cursor_renderer_set_cursor (MetaCursorRenderer  *renderer, | ||||
|                                  MetaCursorReference *cursor) | ||||
| { | ||||
|   MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); | ||||
|  | ||||
|   if (priv->displayed_cursor == cursor) | ||||
|     return; | ||||
|  | ||||
|   priv->displayed_cursor = cursor; | ||||
|   update_cursor (renderer); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_cursor_renderer_set_position (MetaCursorRenderer *renderer, | ||||
|                                    int x, int y) | ||||
| { | ||||
|   MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); | ||||
|  | ||||
|   g_assert (meta_is_wayland_compositor ()); | ||||
|  | ||||
|   priv->current_x = x; | ||||
|   priv->current_y = y; | ||||
|  | ||||
|   update_cursor (renderer); | ||||
| } | ||||
|  | ||||
| MetaCursorReference * | ||||
| meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer) | ||||
| { | ||||
|   MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); | ||||
|  | ||||
|   return priv->displayed_cursor; | ||||
| } | ||||
|  | ||||
| const MetaRectangle * | ||||
| meta_cursor_renderer_get_rect (MetaCursorRenderer *renderer) | ||||
| { | ||||
|   MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); | ||||
|  | ||||
|   return &priv->current_rect; | ||||
| } | ||||
							
								
								
									
										70
									
								
								src/backends/meta-cursor-renderer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/backends/meta-cursor-renderer.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2014 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jasper St. Pierre <jstpierre@mecheye.net> | ||||
|  */ | ||||
|  | ||||
| #ifndef META_CURSOR_RENDERER_H | ||||
| #define META_CURSOR_RENDERER_H | ||||
|  | ||||
| #include <glib-object.h> | ||||
|  | ||||
| #include <meta/screen.h> | ||||
| #include "meta-cursor.h" | ||||
|  | ||||
| #include <gbm.h> | ||||
|  | ||||
| #define META_TYPE_CURSOR_RENDERER            (meta_cursor_renderer_get_type ()) | ||||
| #define META_CURSOR_RENDERER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CURSOR_RENDERER, MetaCursorRenderer)) | ||||
| #define META_CURSOR_RENDERER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_CURSOR_RENDERER, MetaCursorRendererClass)) | ||||
| #define META_IS_CURSOR_RENDERER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_CURSOR_RENDERER)) | ||||
| #define META_IS_CURSOR_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_CURSOR_RENDERER)) | ||||
| #define META_CURSOR_RENDERER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_CURSOR_RENDERER, MetaCursorRendererClass)) | ||||
|  | ||||
| typedef struct _MetaCursorRenderer        MetaCursorRenderer; | ||||
| typedef struct _MetaCursorRendererClass   MetaCursorRendererClass; | ||||
|  | ||||
| struct _MetaCursorRenderer | ||||
| { | ||||
|   GObject parent; | ||||
| }; | ||||
|  | ||||
| struct _MetaCursorRendererClass | ||||
| { | ||||
|   GObjectClass parent_class; | ||||
|  | ||||
|   gboolean (* update_cursor) (MetaCursorRenderer *renderer); | ||||
| }; | ||||
|  | ||||
| GType meta_cursor_renderer_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| MetaCursorRenderer * meta_cursor_renderer_new (void); | ||||
|  | ||||
| void meta_cursor_renderer_set_cursor (MetaCursorRenderer  *renderer, | ||||
|                                       MetaCursorReference *cursor); | ||||
|  | ||||
| void meta_cursor_renderer_set_position (MetaCursorRenderer *renderer, | ||||
|                                         int x, int y); | ||||
|  | ||||
| MetaCursorReference * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer); | ||||
| const MetaRectangle * meta_cursor_renderer_get_rect (MetaCursorRenderer *renderer); | ||||
|  | ||||
| #endif /* META_CURSOR_RENDERER_H */ | ||||
| @@ -24,23 +24,52 @@ | ||||
| 
 | ||||
| #include <meta/meta-cursor-tracker.h> | ||||
| #include <wayland-server.h> | ||||
| #include <clutter/clutter.h> | ||||
| #include <gbm.h> | ||||
| 
 | ||||
| #include "meta-cursor.h" | ||||
| #include "meta-cursor-renderer.h" | ||||
| 
 | ||||
| struct _MetaCursorTracker { | ||||
|   GObject parent_instance; | ||||
| 
 | ||||
|   MetaScreen *screen; | ||||
|   MetaCursorRenderer *renderer; | ||||
| 
 | ||||
|   gboolean is_showing; | ||||
| 
 | ||||
|   MetaCursorReference *displayed_cursor; | ||||
| 
 | ||||
|   /* Wayland clients can set a NULL buffer as their cursor
 | ||||
|    * explicitly, which means that we shouldn't display anything. | ||||
|    * So, we can't simply store a NULL in window_cursor to | ||||
|    * determine an unset window cursor; we need an extra boolean. | ||||
|    */ | ||||
|   gboolean has_window_cursor; | ||||
|   MetaCursorReference *window_cursor; | ||||
| 
 | ||||
|   MetaCursorReference *root_cursor; | ||||
| 
 | ||||
|   /* The cursor from the X11 server. */ | ||||
|   MetaCursorReference *xfixes_cursor; | ||||
| }; | ||||
| 
 | ||||
| struct _MetaCursorTrackerClass { | ||||
|   GObjectClass parent_class; | ||||
| }; | ||||
| 
 | ||||
| gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker, | ||||
| 					    XEvent            *xevent); | ||||
| 
 | ||||
| void     meta_cursor_tracker_set_grab_cursor     (MetaCursorTracker  *tracker, | ||||
|                                                   MetaCursor          cursor); | ||||
| void     meta_cursor_tracker_set_window_cursor   (MetaCursorTracker  *tracker, | ||||
|                                                   struct wl_resource *buffer, | ||||
|                                                   int                 hot_x, | ||||
|                                                   int                 hot_y); | ||||
| void     meta_cursor_tracker_unset_window_cursor (MetaCursorTracker  *tracker); | ||||
| void     meta_cursor_tracker_set_root_cursor     (MetaCursorTracker  *tracker, | ||||
|                                                   MetaCursor          cursor); | ||||
| void     meta_cursor_tracker_set_window_cursor   (MetaCursorTracker   *tracker, | ||||
|                                                   MetaCursorReference *cursor); | ||||
| void     meta_cursor_tracker_unset_window_cursor (MetaCursorTracker   *tracker); | ||||
| void     meta_cursor_tracker_set_root_cursor     (MetaCursorTracker   *tracker, | ||||
|                                                   MetaCursorReference *cursor); | ||||
| 
 | ||||
| void     meta_cursor_tracker_update_position (MetaCursorTracker *tracker, | ||||
| 					      int                new_x, | ||||
| 					      int                new_y); | ||||
| void     meta_cursor_tracker_paint           (MetaCursorTracker *tracker); | ||||
| 
 | ||||
| MetaCursorReference * meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker); | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										478
									
								
								src/backends/meta-cursor-tracker.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										478
									
								
								src/backends/meta-cursor-tracker.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,478 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright 2013 Red Hat, Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * Author: Giovanni Campagna <gcampagn@redhat.com> | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * SECTION:cursor-tracker | ||||
|  * @title: MetaCursorTracker | ||||
|  * @short_description: Mutter cursor tracking helper. Originally only | ||||
|  *                     tracking the cursor image, now more of a "core | ||||
|  *                     pointer abstraction" | ||||
|  */ | ||||
|  | ||||
| #include <config.h> | ||||
| #include <string.h> | ||||
| #include <meta/main.h> | ||||
| #include <meta/util.h> | ||||
| #include <meta/errors.h> | ||||
|  | ||||
| #include <cogl/cogl.h> | ||||
| #include <cogl/cogl-wayland-server.h> | ||||
| #include <clutter/clutter.h> | ||||
|  | ||||
| #include <gdk/gdk.h> | ||||
| #include <gdk/gdkx.h> | ||||
|  | ||||
| #include "meta-backend.h" | ||||
|  | ||||
| #include "meta-cursor-private.h" | ||||
| #include "meta-cursor-tracker-private.h" | ||||
| #include "screen-private.h" | ||||
|  | ||||
| #include "wayland/meta-wayland-private.h" | ||||
|  | ||||
| G_DEFINE_TYPE (MetaCursorTracker, meta_cursor_tracker, G_TYPE_OBJECT); | ||||
|  | ||||
| enum { | ||||
|     CURSOR_CHANGED, | ||||
|     LAST_SIGNAL | ||||
| }; | ||||
|  | ||||
| static guint signals[LAST_SIGNAL]; | ||||
|  | ||||
| static MetaCursorReference * | ||||
| get_displayed_cursor (MetaCursorTracker *tracker) | ||||
| { | ||||
|   if (!tracker->is_showing) | ||||
|     return NULL; | ||||
|  | ||||
|   if (tracker->screen->display->grab_op == META_GRAB_OP_NONE) | ||||
|     { | ||||
|       if (tracker->has_window_cursor) | ||||
|         return tracker->window_cursor; | ||||
|     } | ||||
|  | ||||
|   return tracker->root_cursor; | ||||
| } | ||||
|  | ||||
| static void | ||||
| update_displayed_cursor (MetaCursorTracker *tracker) | ||||
| { | ||||
|   meta_cursor_renderer_set_cursor (tracker->renderer, tracker->displayed_cursor); | ||||
| } | ||||
|  | ||||
| static void | ||||
| sync_cursor (MetaCursorTracker *tracker) | ||||
| { | ||||
|   MetaCursorReference *displayed_cursor = get_displayed_cursor (tracker); | ||||
|  | ||||
|   if (tracker->displayed_cursor == displayed_cursor) | ||||
|     return; | ||||
|  | ||||
|   g_clear_pointer (&tracker->displayed_cursor, meta_cursor_reference_unref); | ||||
|   if (displayed_cursor) | ||||
|     tracker->displayed_cursor = meta_cursor_reference_ref (displayed_cursor); | ||||
|  | ||||
|   update_displayed_cursor (tracker); | ||||
|   g_signal_emit (tracker, signals[CURSOR_CHANGED], 0); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_cursor_tracker_init (MetaCursorTracker *self) | ||||
| { | ||||
|   self->is_showing = TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_cursor_tracker_finalize (GObject *object) | ||||
| { | ||||
|   MetaCursorTracker *self = META_CURSOR_TRACKER (object); | ||||
|  | ||||
|   if (self->displayed_cursor) | ||||
|     meta_cursor_reference_unref (self->displayed_cursor); | ||||
|   if (self->root_cursor) | ||||
|     meta_cursor_reference_unref (self->root_cursor); | ||||
|  | ||||
|   G_OBJECT_CLASS (meta_cursor_tracker_parent_class)->finalize (object); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_cursor_tracker_class_init (MetaCursorTrackerClass *klass) | ||||
| { | ||||
|   GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   object_class->finalize = meta_cursor_tracker_finalize; | ||||
|  | ||||
|   signals[CURSOR_CHANGED] = g_signal_new ("cursor-changed", | ||||
|                                           G_TYPE_FROM_CLASS (klass), | ||||
|                                           G_SIGNAL_RUN_LAST, | ||||
|                                           0, | ||||
|                                           NULL, NULL, NULL, | ||||
|                                           G_TYPE_NONE, 0); | ||||
| } | ||||
|  | ||||
| static MetaCursorTracker * | ||||
| make_wayland_cursor_tracker (MetaScreen *screen) | ||||
| { | ||||
|   MetaBackend *backend = meta_get_backend (); | ||||
|   MetaWaylandCompositor *compositor; | ||||
|   MetaCursorTracker *self; | ||||
|  | ||||
|   self = g_object_new (META_TYPE_CURSOR_TRACKER, NULL); | ||||
|   self->screen = screen; | ||||
|   self->renderer = meta_backend_get_cursor_renderer (backend); | ||||
|  | ||||
|   compositor = meta_wayland_compositor_get_default (); | ||||
|   compositor->seat->pointer.cursor_tracker = self; | ||||
|   meta_cursor_tracker_update_position (self, 0, 0); | ||||
|  | ||||
|   return self; | ||||
| } | ||||
|  | ||||
| static MetaCursorTracker * | ||||
| make_x11_cursor_tracker (MetaScreen *screen) | ||||
| { | ||||
|   MetaBackend *backend = meta_get_backend (); | ||||
|   MetaCursorTracker *self; | ||||
|  | ||||
|   self = g_object_new (META_TYPE_CURSOR_TRACKER, NULL); | ||||
|   self->screen = screen; | ||||
|   self->renderer = meta_backend_get_cursor_renderer (backend); | ||||
|  | ||||
|   XFixesSelectCursorInput (screen->display->xdisplay, | ||||
|                            screen->xroot, | ||||
|                            XFixesDisplayCursorNotifyMask); | ||||
|  | ||||
|   return self; | ||||
| } | ||||
|  | ||||
| static MetaCursorTracker * | ||||
| meta_cursor_tracker_new (MetaScreen *screen) | ||||
| { | ||||
|   if (meta_is_wayland_compositor ()) | ||||
|     return make_wayland_cursor_tracker (screen); | ||||
|   else | ||||
|     return make_x11_cursor_tracker (screen); | ||||
| } | ||||
|  | ||||
| static MetaCursorTracker *_cursor_tracker; | ||||
|  | ||||
| /** | ||||
|  * meta_cursor_tracker_get_for_screen: | ||||
|  * @screen: the #MetaScreen | ||||
|  * | ||||
|  * Retrieves the cursor tracker object for @screen. | ||||
|  * | ||||
|  * Returns: (transfer none): | ||||
|  */ | ||||
| MetaCursorTracker * | ||||
| meta_cursor_tracker_get_for_screen (MetaScreen *screen) | ||||
| { | ||||
|   if (!_cursor_tracker) | ||||
|     _cursor_tracker = meta_cursor_tracker_new (screen); | ||||
|  | ||||
|   return _cursor_tracker; | ||||
| } | ||||
|  | ||||
| static void | ||||
| set_window_cursor (MetaCursorTracker   *tracker, | ||||
|                    gboolean             has_cursor, | ||||
|                    MetaCursorReference *cursor) | ||||
| { | ||||
|   g_clear_pointer (&tracker->window_cursor, meta_cursor_reference_unref); | ||||
|   if (cursor) | ||||
|     tracker->window_cursor = meta_cursor_reference_ref (cursor); | ||||
|   tracker->has_window_cursor = has_cursor; | ||||
|   sync_cursor (tracker); | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker, | ||||
|                                    XEvent            *xevent) | ||||
| { | ||||
|   XFixesCursorNotifyEvent *notify_event; | ||||
|  | ||||
|   if (meta_is_wayland_compositor ()) | ||||
|     return FALSE; | ||||
|  | ||||
|   if (xevent->xany.type != tracker->screen->display->xfixes_event_base + XFixesCursorNotify) | ||||
|     return FALSE; | ||||
|  | ||||
|   notify_event = (XFixesCursorNotifyEvent *)xevent; | ||||
|   if (notify_event->subtype != XFixesDisplayCursorNotify) | ||||
|     return FALSE; | ||||
|  | ||||
|   g_clear_pointer (&tracker->xfixes_cursor, meta_cursor_reference_unref); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static MetaCursorReference * | ||||
| meta_cursor_reference_take_texture (CoglTexture2D *texture, | ||||
|                                     int            hot_x, | ||||
|                                     int            hot_y) | ||||
| { | ||||
|   MetaCursorReference *self; | ||||
|  | ||||
|   self = g_slice_new0 (MetaCursorReference); | ||||
|   self->ref_count = 1; | ||||
|   self->image.texture = texture; | ||||
|   self->image.hot_x = hot_x; | ||||
|   self->image.hot_y = hot_y; | ||||
|  | ||||
|   return self; | ||||
| } | ||||
|  | ||||
| static void | ||||
| ensure_xfixes_cursor (MetaCursorTracker *tracker) | ||||
| { | ||||
|   XFixesCursorImage *cursor_image; | ||||
|   CoglTexture2D *sprite; | ||||
|   guint8 *cursor_data; | ||||
|   gboolean free_cursor_data; | ||||
|   CoglContext *ctx; | ||||
|  | ||||
|   if (tracker->xfixes_cursor) | ||||
|     return; | ||||
|  | ||||
|   cursor_image = XFixesGetCursorImage (tracker->screen->display->xdisplay); | ||||
|   if (!cursor_image) | ||||
|     return; | ||||
|  | ||||
|   /* Like all X APIs, XFixesGetCursorImage() returns arrays of 32-bit | ||||
|    * quantities as arrays of long; we need to convert on 64 bit */ | ||||
|   if (sizeof(long) == 4) | ||||
|     { | ||||
|       cursor_data = (guint8 *)cursor_image->pixels; | ||||
|       free_cursor_data = FALSE; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       int i, j; | ||||
|       guint32 *cursor_words; | ||||
|       gulong *p; | ||||
|       guint32 *q; | ||||
|  | ||||
|       cursor_words = g_new (guint32, cursor_image->width * cursor_image->height); | ||||
|       cursor_data = (guint8 *)cursor_words; | ||||
|  | ||||
|       p = cursor_image->pixels; | ||||
|       q = cursor_words; | ||||
|       for (j = 0; j < cursor_image->height; j++) | ||||
|         for (i = 0; i < cursor_image->width; i++) | ||||
|           *(q++) = *(p++); | ||||
|  | ||||
|       free_cursor_data = TRUE; | ||||
|     } | ||||
|  | ||||
|   ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); | ||||
|   sprite = cogl_texture_2d_new_from_data (ctx, | ||||
|                                           cursor_image->width, | ||||
|                                           cursor_image->height, | ||||
|                                           CLUTTER_CAIRO_FORMAT_ARGB32, | ||||
|                                           cursor_image->width * 4, /* stride */ | ||||
|                                           cursor_data, | ||||
|                                           NULL); | ||||
|  | ||||
|   if (free_cursor_data) | ||||
|     g_free (cursor_data); | ||||
|  | ||||
|   if (sprite != NULL) | ||||
|     { | ||||
|       MetaCursorReference *cursor = meta_cursor_reference_take_texture (sprite, | ||||
|                                                                         cursor_image->xhot, | ||||
|                                                                         cursor_image->yhot); | ||||
|       tracker->xfixes_cursor = cursor; | ||||
|     } | ||||
|   XFree (cursor_image); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_cursor_tracker_get_sprite: | ||||
|  * | ||||
|  * Returns: (transfer none): | ||||
|  */ | ||||
| CoglTexture * | ||||
| meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker) | ||||
| { | ||||
|   MetaCursorReference *cursor; | ||||
|  | ||||
|   g_return_val_if_fail (META_IS_CURSOR_TRACKER (tracker), NULL); | ||||
|  | ||||
|   if (meta_is_wayland_compositor ()) | ||||
|     { | ||||
|       cursor = tracker->displayed_cursor; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       ensure_xfixes_cursor (tracker); | ||||
|       cursor = tracker->xfixes_cursor; | ||||
|     } | ||||
|  | ||||
|   if (cursor) | ||||
|     return meta_cursor_reference_get_cogl_texture (cursor, NULL, NULL); | ||||
|   else | ||||
|     return NULL; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_cursor_tracker_get_hot: | ||||
|  * @tracker: | ||||
|  * @x: (out): | ||||
|  * @y: (out): | ||||
|  * | ||||
|  */ | ||||
| void | ||||
| meta_cursor_tracker_get_hot (MetaCursorTracker *tracker, | ||||
|                              int               *x, | ||||
|                              int               *y) | ||||
| { | ||||
|   MetaCursorReference *cursor; | ||||
|  | ||||
|   g_return_if_fail (META_IS_CURSOR_TRACKER (tracker)); | ||||
|  | ||||
|   if (meta_is_wayland_compositor ()) | ||||
|     { | ||||
|       cursor = tracker->displayed_cursor; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       ensure_xfixes_cursor (tracker); | ||||
|       cursor = tracker->xfixes_cursor; | ||||
|     } | ||||
|  | ||||
|   if (cursor) | ||||
|     meta_cursor_reference_get_cogl_texture (cursor, x, y); | ||||
|   else | ||||
|     { | ||||
|       if (x) | ||||
|         *x = 0; | ||||
|       if (y) | ||||
|         *y = 0; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_cursor_tracker_set_window_cursor (MetaCursorTracker   *tracker, | ||||
|                                        MetaCursorReference *cursor) | ||||
| { | ||||
|   set_window_cursor (tracker, TRUE, cursor); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker) | ||||
| { | ||||
|   set_window_cursor (tracker, FALSE, NULL); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_cursor_tracker_set_root_cursor (MetaCursorTracker   *tracker, | ||||
|                                      MetaCursorReference *cursor) | ||||
| { | ||||
|   g_clear_pointer (&tracker->root_cursor, meta_cursor_reference_unref); | ||||
|   if (cursor) | ||||
|     tracker->root_cursor = meta_cursor_reference_ref (cursor); | ||||
|  | ||||
|   sync_cursor (tracker); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_cursor_tracker_update_position (MetaCursorTracker *tracker, | ||||
|                                      int                new_x, | ||||
|                                      int                new_y) | ||||
| { | ||||
|   g_assert (meta_is_wayland_compositor ()); | ||||
|  | ||||
|   meta_cursor_renderer_set_position (tracker->renderer, new_x, new_y); | ||||
| } | ||||
|  | ||||
| static void | ||||
| get_pointer_position_gdk (int         *x, | ||||
|                           int         *y, | ||||
|                           int         *mods) | ||||
| { | ||||
|   GdkDeviceManager *gmanager; | ||||
|   GdkDevice *gdevice; | ||||
|   GdkScreen *gscreen; | ||||
|  | ||||
|   gmanager = gdk_display_get_device_manager (gdk_display_get_default ()); | ||||
|   gdevice = gdk_x11_device_manager_lookup (gmanager, META_VIRTUAL_CORE_POINTER_ID); | ||||
|  | ||||
|   gdk_device_get_position (gdevice, &gscreen, x, y); | ||||
|   if (mods) | ||||
|     gdk_device_get_state (gdevice, | ||||
|                           gdk_screen_get_root_window (gscreen), | ||||
|                           NULL, (GdkModifierType*)mods); | ||||
| } | ||||
|  | ||||
| static void | ||||
| get_pointer_position_clutter (int         *x, | ||||
|                               int         *y, | ||||
|                               int         *mods) | ||||
| { | ||||
|   ClutterDeviceManager *cmanager; | ||||
|   ClutterInputDevice *cdevice; | ||||
|   ClutterPoint point; | ||||
|  | ||||
|   cmanager = clutter_device_manager_get_default (); | ||||
|   cdevice = clutter_device_manager_get_core_device (cmanager, CLUTTER_POINTER_DEVICE); | ||||
|  | ||||
|   clutter_input_device_get_coords (cdevice, NULL, &point); | ||||
|   if (x) | ||||
|     *x = point.x; | ||||
|   if (y) | ||||
|     *y = point.y; | ||||
|   if (mods) | ||||
|     *mods = clutter_input_device_get_modifier_state (cdevice); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_cursor_tracker_get_pointer (MetaCursorTracker   *tracker, | ||||
|                                  int                 *x, | ||||
|                                  int                 *y, | ||||
|                                  ClutterModifierType *mods) | ||||
| { | ||||
|   /* We can't use the clutter interface when not running as a wayland compositor, | ||||
|      because we need to query the server, rather than using the last cached value. | ||||
|      OTOH, on wayland we can't use GDK, because that only sees the events | ||||
|      we forward to xwayland. | ||||
|   */ | ||||
|   if (meta_is_wayland_compositor ()) | ||||
|     get_pointer_position_clutter (x, y, (int*)mods); | ||||
|   else | ||||
|     get_pointer_position_gdk (x, y, (int*)mods); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker, | ||||
|                                          gboolean           visible) | ||||
| { | ||||
|   if (visible == tracker->is_showing) | ||||
|     return; | ||||
|   tracker->is_showing = visible; | ||||
|  | ||||
|   sync_cursor (tracker); | ||||
| } | ||||
|  | ||||
| MetaCursorReference * | ||||
| meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker) | ||||
| { | ||||
|   return tracker->displayed_cursor; | ||||
| } | ||||
							
								
								
									
										377
									
								
								src/backends/meta-cursor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										377
									
								
								src/backends/meta-cursor.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,377 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright 2013 Red Hat, Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * Author: Giovanni Campagna <gcampagn@redhat.com> | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "meta-cursor-private.h" | ||||
|  | ||||
| #include <meta/errors.h> | ||||
|  | ||||
| #include "display-private.h" | ||||
| #include "screen-private.h" | ||||
| #include "meta-backend.h" | ||||
|  | ||||
| #ifdef HAVE_NATIVE_BACKEND | ||||
| #include "backends/native/meta-cursor-renderer-native.h" | ||||
| #endif | ||||
|  | ||||
| #include <string.h> | ||||
|  | ||||
| #include <X11/cursorfont.h> | ||||
| #include <X11/extensions/Xfixes.h> | ||||
| #include <X11/Xcursor/Xcursor.h> | ||||
|  | ||||
| #include <cogl/cogl-wayland-server.h> | ||||
|  | ||||
| MetaCursorReference * | ||||
| meta_cursor_reference_ref (MetaCursorReference *self) | ||||
| { | ||||
|   g_assert (self->ref_count > 0); | ||||
|   self->ref_count++; | ||||
|  | ||||
|   return self; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_cursor_image_free (MetaCursorImage *image) | ||||
| { | ||||
|   cogl_object_unref (image->texture); | ||||
|   if (image->bo) | ||||
|     gbm_bo_destroy (image->bo); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_cursor_reference_free (MetaCursorReference *self) | ||||
| { | ||||
|   meta_cursor_image_free (&self->image); | ||||
|   g_slice_free (MetaCursorReference, self); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_cursor_reference_unref (MetaCursorReference *self) | ||||
| { | ||||
|   self->ref_count--; | ||||
|  | ||||
|   if (self->ref_count == 0) | ||||
|     meta_cursor_reference_free (self); | ||||
| } | ||||
|  | ||||
| static const char * | ||||
| translate_meta_cursor (MetaCursor cursor) | ||||
| { | ||||
|   switch (cursor) | ||||
|     { | ||||
|     case META_CURSOR_DEFAULT: | ||||
|       return "left_ptr"; | ||||
|     case META_CURSOR_NORTH_RESIZE: | ||||
|       return "top_side"; | ||||
|     case META_CURSOR_SOUTH_RESIZE: | ||||
|       return "bottom_side"; | ||||
|     case META_CURSOR_WEST_RESIZE: | ||||
|       return "left_side"; | ||||
|     case META_CURSOR_EAST_RESIZE: | ||||
|       return "right_side"; | ||||
|     case META_CURSOR_SE_RESIZE: | ||||
|       return "bottom_right_corner"; | ||||
|     case META_CURSOR_SW_RESIZE: | ||||
|       return "bottom_left_corner"; | ||||
|     case META_CURSOR_NE_RESIZE: | ||||
|       return "top_right_corner"; | ||||
|     case META_CURSOR_NW_RESIZE: | ||||
|       return "top_left_corner"; | ||||
|     case META_CURSOR_MOVE_OR_RESIZE_WINDOW: | ||||
|       return "fleur"; | ||||
|     case META_CURSOR_BUSY: | ||||
|       return "watch"; | ||||
|     case META_CURSOR_DND_IN_DRAG: | ||||
|       return "dnd-none"; | ||||
|     case META_CURSOR_DND_MOVE: | ||||
|       return "dnd-move"; | ||||
|     case META_CURSOR_DND_COPY: | ||||
|       return "dnd-copy"; | ||||
|     case META_CURSOR_DND_UNSUPPORTED_TARGET: | ||||
|       return "dnd-none"; | ||||
|     case META_CURSOR_POINTING_HAND: | ||||
|       return "hand2"; | ||||
|     case META_CURSOR_CROSSHAIR: | ||||
|       return "crosshair"; | ||||
|     case META_CURSOR_IBEAM: | ||||
|       return "xterm"; | ||||
|     default: | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|   g_assert_not_reached (); | ||||
| } | ||||
|  | ||||
| Cursor | ||||
| meta_cursor_create_x_cursor (Display    *xdisplay, | ||||
|                              MetaCursor  cursor) | ||||
| { | ||||
|   return XcursorLibraryLoadCursor (xdisplay, translate_meta_cursor (cursor)); | ||||
| } | ||||
|  | ||||
| static XcursorImage * | ||||
| load_cursor_on_client (MetaCursor cursor) | ||||
| { | ||||
|   return XcursorLibraryLoadImage (translate_meta_cursor (cursor), | ||||
|                                   meta_prefs_get_cursor_theme (), | ||||
|                                   meta_prefs_get_cursor_size ()); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_cursor_image_load_gbm_buffer (struct gbm_device *gbm, | ||||
|                                    MetaCursorImage   *image, | ||||
|                                    uint8_t           *pixels, | ||||
|                                    int                width, | ||||
|                                    int                height, | ||||
|                                    int                rowstride, | ||||
|                                    uint32_t           gbm_format) | ||||
| { | ||||
|   if (width > 64 || height > 64) | ||||
|     { | ||||
|       meta_warning ("Invalid theme cursor size (must be at most 64x64)\n"); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   if (gbm_device_is_format_supported (gbm, gbm_format, | ||||
|                                       GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE)) | ||||
|     { | ||||
|       uint8_t buf[4 * 64 * 64]; | ||||
|       int i; | ||||
|  | ||||
|       image->bo = gbm_bo_create (gbm, 64, 64, | ||||
|                                  gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE); | ||||
|  | ||||
|       memset (buf, 0, sizeof(buf)); | ||||
|       for (i = 0; i < height; i++) | ||||
|         memcpy (buf + i * 4 * 64, pixels + i * rowstride, width * 4); | ||||
|  | ||||
|       gbm_bo_write (image->bo, buf, 64 * 64 * 4); | ||||
|     } | ||||
|   else | ||||
|     meta_warning ("HW cursor for format %d not supported\n", gbm_format); | ||||
| } | ||||
|  | ||||
| static struct gbm_device * | ||||
| get_gbm_device (void) | ||||
| { | ||||
| #ifdef HAVE_NATIVE_BACKEND | ||||
|   MetaBackend *meta_backend = meta_get_backend (); | ||||
|   MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (meta_backend); | ||||
|  | ||||
|   if (META_IS_CURSOR_RENDERER_NATIVE (renderer)) | ||||
|     return meta_cursor_renderer_native_get_gbm_device (META_CURSOR_RENDERER_NATIVE (renderer)); | ||||
| #endif | ||||
|  | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_cursor_image_load_from_xcursor_image (MetaCursorImage   *image, | ||||
|                                            XcursorImage      *xc_image) | ||||
| { | ||||
|   int width, height, rowstride; | ||||
|   CoglPixelFormat cogl_format; | ||||
|   uint32_t gbm_format; | ||||
|   ClutterBackend *clutter_backend; | ||||
|   CoglContext *cogl_context; | ||||
|   struct gbm_device *gbm; | ||||
|  | ||||
|   width           = xc_image->width; | ||||
|   height          = xc_image->height; | ||||
|   rowstride       = width * 4; | ||||
|  | ||||
|   gbm_format = GBM_FORMAT_ARGB8888; | ||||
| #if G_BYTE_ORDER == G_LITTLE_ENDIAN | ||||
|   cogl_format = COGL_PIXEL_FORMAT_BGRA_8888; | ||||
| #else | ||||
|   cogl_format = COGL_PIXEL_FORMAT_ARGB_8888; | ||||
| #endif | ||||
|  | ||||
|   image->hot_x = xc_image->xhot; | ||||
|   image->hot_y = xc_image->yhot; | ||||
|  | ||||
|   clutter_backend = clutter_get_default_backend (); | ||||
|   cogl_context = clutter_backend_get_cogl_context (clutter_backend); | ||||
|   image->texture = cogl_texture_2d_new_from_data (cogl_context, | ||||
|                                                   width, height, | ||||
|                                                   cogl_format, | ||||
|                                                   rowstride, | ||||
|                                                   (uint8_t *) xc_image->pixels, | ||||
|                                                   NULL); | ||||
|  | ||||
|   gbm = get_gbm_device (); | ||||
|   if (gbm) | ||||
|     meta_cursor_image_load_gbm_buffer (gbm, | ||||
|                                        image, | ||||
|                                        (uint8_t *) xc_image->pixels, | ||||
|                                        width, height, rowstride, | ||||
|                                        gbm_format); | ||||
| } | ||||
|  | ||||
| MetaCursorReference * | ||||
| meta_cursor_reference_from_theme (MetaCursor cursor) | ||||
| { | ||||
|   MetaCursorReference *self; | ||||
|   XcursorImage *image; | ||||
|  | ||||
|   image = load_cursor_on_client (cursor); | ||||
|   if (!image) | ||||
|     return NULL; | ||||
|  | ||||
|   self = g_slice_new0 (MetaCursorReference); | ||||
|   self->ref_count = 1; | ||||
|   self->cursor = cursor; | ||||
|   meta_cursor_image_load_from_xcursor_image (&self->image, image); | ||||
|  | ||||
|   XcursorImageDestroy (image); | ||||
|   return self; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_cursor_image_load_from_buffer (MetaCursorImage    *image, | ||||
|                                     struct wl_resource *buffer, | ||||
|                                     int                 hot_x, | ||||
|                                     int                 hot_y) | ||||
| { | ||||
|   struct gbm_device *gbm = get_gbm_device (); | ||||
|  | ||||
|   ClutterBackend *backend; | ||||
|   CoglContext *cogl_context; | ||||
|   struct wl_shm_buffer *shm_buffer; | ||||
|   uint32_t gbm_format; | ||||
|   int width, height; | ||||
|  | ||||
|   image->hot_x = hot_x; | ||||
|   image->hot_y = hot_y; | ||||
|  | ||||
|   backend = clutter_get_default_backend (); | ||||
|   cogl_context = clutter_backend_get_cogl_context (backend); | ||||
|  | ||||
|   image->texture = cogl_wayland_texture_2d_new_from_buffer (cogl_context, buffer, NULL); | ||||
|  | ||||
|   width = cogl_texture_get_width (COGL_TEXTURE (image->texture)); | ||||
|   height = cogl_texture_get_height (COGL_TEXTURE (image->texture)); | ||||
|  | ||||
|   shm_buffer = wl_shm_buffer_get (buffer); | ||||
|   if (shm_buffer) | ||||
|     { | ||||
|       if (gbm) | ||||
|         { | ||||
|           int rowstride = wl_shm_buffer_get_stride (shm_buffer); | ||||
|  | ||||
|           switch (wl_shm_buffer_get_format (shm_buffer)) | ||||
|             { | ||||
| #if G_BYTE_ORDER == G_BIG_ENDIAN | ||||
|             case WL_SHM_FORMAT_ARGB8888: | ||||
|               gbm_format = GBM_FORMAT_ARGB8888; | ||||
|               break; | ||||
|             case WL_SHM_FORMAT_XRGB8888: | ||||
|               gbm_format = GBM_FORMAT_XRGB8888; | ||||
|               break; | ||||
| #else | ||||
|             case WL_SHM_FORMAT_ARGB8888: | ||||
|               gbm_format = GBM_FORMAT_ARGB8888; | ||||
|               break; | ||||
|             case WL_SHM_FORMAT_XRGB8888: | ||||
|               gbm_format = GBM_FORMAT_XRGB8888; | ||||
|               break; | ||||
| #endif | ||||
|             default: | ||||
|               g_warn_if_reached (); | ||||
|               gbm_format = GBM_FORMAT_ARGB8888; | ||||
|             } | ||||
|  | ||||
|           meta_cursor_image_load_gbm_buffer (gbm, | ||||
|                                              image, | ||||
|                                              (uint8_t *) wl_shm_buffer_get_data (shm_buffer), | ||||
|                                              width, height, rowstride, | ||||
|                                              gbm_format); | ||||
|         } | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* HW cursors must be 64x64, but 64x64 is huge, and no cursor theme actually uses | ||||
|          that, so themed cursors must be padded with transparent pixels to fill the | ||||
|          overlay. This is trivial if we have CPU access to the data, but it's not | ||||
|          possible if the buffer is in GPU memory (and possibly tiled too), so if we | ||||
|          don't get the right size, we fallback to GL. | ||||
|       */ | ||||
|       if (width != 64 || height != 64) | ||||
|         { | ||||
|           meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n"); | ||||
|           return; | ||||
|         } | ||||
|  | ||||
|       if (gbm) | ||||
|         { | ||||
|           image->bo = gbm_bo_import (gbm, GBM_BO_IMPORT_WL_BUFFER, | ||||
|                                      buffer, GBM_BO_USE_CURSOR_64X64); | ||||
|           if (!image->bo) | ||||
|             meta_warning ("Importing HW cursor from wl_buffer failed\n"); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| MetaCursorReference * | ||||
| meta_cursor_reference_from_buffer (struct wl_resource *buffer, | ||||
|                                    int                 hot_x, | ||||
|                                    int                 hot_y) | ||||
| { | ||||
|   MetaCursorReference *self; | ||||
|  | ||||
|   self = g_slice_new0 (MetaCursorReference); | ||||
|   self->ref_count = 1; | ||||
|   meta_cursor_image_load_from_buffer (&self->image, buffer, hot_x, hot_y); | ||||
|  | ||||
|   return self; | ||||
| } | ||||
|  | ||||
| CoglTexture * | ||||
| meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor, | ||||
|                                         int                 *hot_x, | ||||
|                                         int                 *hot_y) | ||||
| { | ||||
|   if (hot_x) | ||||
|     *hot_x = cursor->image.hot_x; | ||||
|   if (hot_y) | ||||
|     *hot_y = cursor->image.hot_y; | ||||
|   return COGL_TEXTURE (cursor->image.texture); | ||||
| } | ||||
|  | ||||
| struct gbm_bo * | ||||
| meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor, | ||||
|                                   int                 *hot_x, | ||||
|                                   int                 *hot_y) | ||||
| { | ||||
|   if (hot_x) | ||||
|     *hot_x = cursor->image.hot_x; | ||||
|   if (hot_y) | ||||
|     *hot_y = cursor->image.hot_y; | ||||
|   return cursor->image.bo; | ||||
| } | ||||
|  | ||||
| MetaCursor | ||||
| meta_cursor_reference_get_meta_cursor (MetaCursorReference *cursor) | ||||
| { | ||||
|   return cursor->cursor; | ||||
| } | ||||
							
								
								
									
										44
									
								
								src/backends/meta-cursor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/backends/meta-cursor.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright 2013 Red Hat, Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * Author: Giovanni Campagna <gcampagn@redhat.com> | ||||
|  */ | ||||
|  | ||||
| #ifndef META_CURSOR_H | ||||
| #define META_CURSOR_H | ||||
|  | ||||
| typedef struct _MetaCursorReference MetaCursorReference; | ||||
|  | ||||
| MetaCursorReference * meta_cursor_reference_ref (MetaCursorReference *cursor); | ||||
| void meta_cursor_reference_unref (MetaCursorReference *cursor); | ||||
|  | ||||
| #include <meta/common.h> | ||||
| #include <wayland-server.h> | ||||
|  | ||||
| MetaCursorReference * meta_cursor_reference_from_theme  (MetaCursor          cursor); | ||||
|  | ||||
| MetaCursorReference * meta_cursor_reference_from_buffer (struct wl_resource *buffer, | ||||
|                                                          int                 hot_x, | ||||
|                                                          int                 hot_y); | ||||
|  | ||||
| MetaCursor meta_cursor_reference_get_meta_cursor (MetaCursorReference *cursor); | ||||
|  | ||||
| Cursor meta_cursor_create_x_cursor (Display    *xdisplay, | ||||
|                                     MetaCursor  cursor); | ||||
|  | ||||
| #endif /* META_CURSOR_H */ | ||||
| @@ -1,7 +1,7 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
| /* 
 | ||||
| /*
 | ||||
|  * Copyright (C) 2013 Red Hat Inc. | ||||
|  *  | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
| @@ -11,12 +11,12 @@ | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  *  | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| /* This file is shared between mutter (src/core/meta-xrandr-shared.h)
 | ||||
| /* This file is shared between mutter (src/core/meta-display-config-shared.h)
 | ||||
|    and gnome-desktop (libgnome-desktop/meta-xrandr-shared.h). | ||||
| 
 | ||||
|    The canonical place for all changes is mutter. | ||||
| @@ -24,8 +24,8 @@ | ||||
|    There should be no includes in this file. | ||||
| */ | ||||
| 
 | ||||
| #ifndef META_XRANDR_SHARED_H | ||||
| #define META_XRANDR_SHARED_H | ||||
| #ifndef META_DISPLAY_CONFIG_SHARED_H | ||||
| #define META_DISPLAY_CONFIG_SHARED_H | ||||
| 
 | ||||
| typedef enum { | ||||
|   META_POWER_SAVE_UNSUPPORTED = -1, | ||||
| @@ -35,4 +35,4 @@ typedef enum { | ||||
|   META_POWER_SAVE_OFF, | ||||
| } MetaPowerSave; | ||||
| 
 | ||||
| #endif | ||||
| #endif /* META_DISPLAY_CONFIG_SHARED_H */ | ||||
							
								
								
									
										289
									
								
								src/backends/meta-idle-monitor-dbus.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										289
									
								
								src/backends/meta-idle-monitor-dbus.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,289 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright 2013 Red Hat, Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and | ||||
|  *         from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "meta-idle-monitor-dbus.h" | ||||
| #include <meta/meta-idle-monitor.h> | ||||
| #include "meta-dbus-idle-monitor.h" | ||||
|  | ||||
| #include <clutter/clutter.h> | ||||
| #include <meta/util.h> | ||||
| #include <meta/main.h> /* for meta_get_replace_current_wm () */ | ||||
|  | ||||
| static gboolean | ||||
| handle_get_idletime (MetaDBusIdleMonitor   *skeleton, | ||||
|                      GDBusMethodInvocation *invocation, | ||||
|                      MetaIdleMonitor       *monitor) | ||||
| { | ||||
|   guint64 idletime; | ||||
|  | ||||
|   idletime = meta_idle_monitor_get_idletime (monitor); | ||||
|   meta_dbus_idle_monitor_complete_get_idletime (skeleton, invocation, idletime); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| typedef struct { | ||||
|   MetaDBusIdleMonitor *dbus_monitor; | ||||
|   MetaIdleMonitor *monitor; | ||||
|   char *dbus_name; | ||||
|   guint watch_id; | ||||
|   guint name_watcher_id; | ||||
| } DBusWatch; | ||||
|  | ||||
| static void | ||||
| destroy_dbus_watch (gpointer data) | ||||
| { | ||||
|   DBusWatch *watch = data; | ||||
|  | ||||
|   g_object_unref (watch->dbus_monitor); | ||||
|   g_object_unref (watch->monitor); | ||||
|   g_free (watch->dbus_name); | ||||
|   g_bus_unwatch_name (watch->name_watcher_id); | ||||
|  | ||||
|   g_slice_free (DBusWatch, watch); | ||||
| } | ||||
|  | ||||
| static void | ||||
| dbus_idle_callback (MetaIdleMonitor *monitor, | ||||
|                     guint            watch_id, | ||||
|                     gpointer         user_data) | ||||
| { | ||||
|   DBusWatch *watch = user_data; | ||||
|   GDBusInterfaceSkeleton *skeleton = G_DBUS_INTERFACE_SKELETON (watch->dbus_monitor); | ||||
|  | ||||
|   g_dbus_connection_emit_signal (g_dbus_interface_skeleton_get_connection (skeleton), | ||||
|                                  watch->dbus_name, | ||||
|                                  g_dbus_interface_skeleton_get_object_path (skeleton), | ||||
|                                  "org.gnome.Mutter.IdleMonitor", | ||||
|                                  "WatchFired", | ||||
|                                  g_variant_new ("(u)", watch_id), | ||||
|                                  NULL); | ||||
| } | ||||
|  | ||||
| static void | ||||
| name_vanished_callback (GDBusConnection *connection, | ||||
|                         const char      *name, | ||||
|                         gpointer         user_data) | ||||
| { | ||||
|   DBusWatch *watch = user_data; | ||||
|  | ||||
|   meta_idle_monitor_remove_watch (watch->monitor, watch->watch_id); | ||||
| } | ||||
|  | ||||
| static DBusWatch * | ||||
| make_dbus_watch (MetaDBusIdleMonitor   *skeleton, | ||||
|                  GDBusMethodInvocation *invocation, | ||||
|                  MetaIdleMonitor       *monitor) | ||||
| { | ||||
|   DBusWatch *watch; | ||||
|  | ||||
|   watch = g_slice_new (DBusWatch); | ||||
|   watch->dbus_monitor = g_object_ref (skeleton); | ||||
|   watch->monitor = g_object_ref (monitor); | ||||
|   watch->dbus_name = g_strdup (g_dbus_method_invocation_get_sender (invocation)); | ||||
|   watch->name_watcher_id = g_bus_watch_name_on_connection (g_dbus_method_invocation_get_connection (invocation), | ||||
|                                                            watch->dbus_name, | ||||
|                                                            G_BUS_NAME_WATCHER_FLAGS_NONE, | ||||
|                                                            NULL, /* appeared */ | ||||
|                                                            name_vanished_callback, | ||||
|                                                            watch, NULL); | ||||
|  | ||||
|   return watch; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| handle_add_idle_watch (MetaDBusIdleMonitor   *skeleton, | ||||
|                        GDBusMethodInvocation *invocation, | ||||
|                        guint64                interval, | ||||
|                        MetaIdleMonitor       *monitor) | ||||
| { | ||||
|   DBusWatch *watch; | ||||
|  | ||||
|   watch = make_dbus_watch (skeleton, invocation, monitor); | ||||
|   watch->watch_id = meta_idle_monitor_add_idle_watch (monitor, interval, | ||||
|                                                       dbus_idle_callback, watch, destroy_dbus_watch); | ||||
|  | ||||
|   meta_dbus_idle_monitor_complete_add_idle_watch (skeleton, invocation, watch->watch_id); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| handle_add_user_active_watch (MetaDBusIdleMonitor   *skeleton, | ||||
|                               GDBusMethodInvocation *invocation, | ||||
|                               MetaIdleMonitor       *monitor) | ||||
| { | ||||
|   DBusWatch *watch; | ||||
|  | ||||
|   watch = make_dbus_watch (skeleton, invocation, monitor); | ||||
|   watch->watch_id = meta_idle_monitor_add_user_active_watch (monitor, | ||||
|                                                              dbus_idle_callback, watch, | ||||
|                                                              destroy_dbus_watch); | ||||
|  | ||||
|   meta_dbus_idle_monitor_complete_add_user_active_watch (skeleton, invocation, watch->watch_id); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| handle_remove_watch (MetaDBusIdleMonitor   *skeleton, | ||||
|                      GDBusMethodInvocation *invocation, | ||||
|                      guint                  id, | ||||
|                      MetaIdleMonitor       *monitor) | ||||
| { | ||||
|   meta_idle_monitor_remove_watch (monitor, id); | ||||
|   meta_dbus_idle_monitor_complete_remove_watch (skeleton, invocation); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| create_monitor_skeleton (GDBusObjectManagerServer *manager, | ||||
|                          MetaIdleMonitor          *monitor, | ||||
|                          const char               *path) | ||||
| { | ||||
|   MetaDBusIdleMonitor *skeleton; | ||||
|   MetaDBusObjectSkeleton *object; | ||||
|  | ||||
|   skeleton = meta_dbus_idle_monitor_skeleton_new (); | ||||
|   g_signal_connect_object (skeleton, "handle-add-idle-watch", | ||||
|                            G_CALLBACK (handle_add_idle_watch), monitor, 0); | ||||
|   g_signal_connect_object (skeleton, "handle-add-user-active-watch", | ||||
|                            G_CALLBACK (handle_add_user_active_watch), monitor, 0); | ||||
|   g_signal_connect_object (skeleton, "handle-remove-watch", | ||||
|                            G_CALLBACK (handle_remove_watch), monitor, 0); | ||||
|   g_signal_connect_object (skeleton, "handle-get-idletime", | ||||
|                            G_CALLBACK (handle_get_idletime), monitor, 0); | ||||
|  | ||||
|   object = meta_dbus_object_skeleton_new (path); | ||||
|   meta_dbus_object_skeleton_set_idle_monitor (object, skeleton); | ||||
|  | ||||
|   g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object)); | ||||
|  | ||||
|   g_object_unref (skeleton); | ||||
|   g_object_unref (object); | ||||
| } | ||||
|  | ||||
| static void | ||||
| on_device_added (ClutterDeviceManager     *device_manager, | ||||
|                  ClutterInputDevice       *device, | ||||
|                  GDBusObjectManagerServer *manager) | ||||
| { | ||||
|  | ||||
|   MetaIdleMonitor *monitor; | ||||
|   int device_id; | ||||
|   char *path; | ||||
|  | ||||
|   device_id = clutter_input_device_get_device_id (device); | ||||
|   monitor = meta_idle_monitor_get_for_device (device_id); | ||||
|   path = g_strdup_printf ("/org/gnome/Mutter/IdleMonitor/Device%d", device_id); | ||||
|  | ||||
|   create_monitor_skeleton (manager, monitor, path); | ||||
|   g_free (path); | ||||
| } | ||||
|  | ||||
| static void | ||||
| on_device_removed (ClutterDeviceManager     *device_manager, | ||||
|                    ClutterInputDevice       *device, | ||||
|                    GDBusObjectManagerServer *manager) | ||||
| { | ||||
|   int device_id; | ||||
|   char *path; | ||||
|  | ||||
|   device_id = clutter_input_device_get_device_id (device); | ||||
|   path = g_strdup_printf ("/org/gnome/Mutter/IdleMonitor/Device%d", device_id); | ||||
|   g_dbus_object_manager_server_unexport (manager, path); | ||||
|   g_free (path); | ||||
| } | ||||
|  | ||||
| static void | ||||
| on_bus_acquired (GDBusConnection *connection, | ||||
|                  const char      *name, | ||||
|                  gpointer         user_data) | ||||
| { | ||||
|   GDBusObjectManagerServer *manager; | ||||
|   ClutterDeviceManager *device_manager; | ||||
|   MetaIdleMonitor *monitor; | ||||
|   GSList *devices, *iter; | ||||
|   char *path; | ||||
|  | ||||
|   manager = g_dbus_object_manager_server_new ("/org/gnome/Mutter/IdleMonitor"); | ||||
|  | ||||
|   /* We never clear the core monitor, as that's supposed to cumulate idle times from | ||||
|      all devices */ | ||||
|   monitor = meta_idle_monitor_get_core (); | ||||
|   path = g_strdup ("/org/gnome/Mutter/IdleMonitor/Core"); | ||||
|   create_monitor_skeleton (manager, monitor, path); | ||||
|   g_free (path); | ||||
|  | ||||
|   device_manager = clutter_device_manager_get_default (); | ||||
|   devices = clutter_device_manager_list_devices (device_manager); | ||||
|  | ||||
|   for (iter = devices; iter; iter = iter->next) | ||||
|     on_device_added (device_manager, iter->data, manager); | ||||
|  | ||||
|   g_slist_free (devices); | ||||
|  | ||||
|   g_signal_connect_object (device_manager, "device-added", | ||||
|                            G_CALLBACK (on_device_added), manager, 0); | ||||
|   g_signal_connect_object (device_manager, "device-removed", | ||||
|                            G_CALLBACK (on_device_removed), manager, 0); | ||||
|  | ||||
|   g_dbus_object_manager_server_set_connection (manager, connection); | ||||
| } | ||||
|  | ||||
| static void | ||||
| on_name_acquired (GDBusConnection *connection, | ||||
|                   const char      *name, | ||||
|                   gpointer         user_data) | ||||
| { | ||||
|   meta_verbose ("Acquired name %s\n", name); | ||||
| } | ||||
|  | ||||
| static void | ||||
| on_name_lost (GDBusConnection *connection, | ||||
|               const char      *name, | ||||
|               gpointer         user_data) | ||||
| { | ||||
|   meta_verbose ("Lost or failed to acquire name %s\n", name); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_idle_monitor_init_dbus (void) | ||||
| { | ||||
|   static int dbus_name_id; | ||||
|  | ||||
|   if (dbus_name_id > 0) | ||||
|     return; | ||||
|  | ||||
|   dbus_name_id = g_bus_own_name (G_BUS_TYPE_SESSION, | ||||
|                                  "org.gnome.Mutter.IdleMonitor", | ||||
|                                  G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | | ||||
|                                  (meta_get_replace_current_wm () ? | ||||
|                                   G_BUS_NAME_OWNER_FLAGS_REPLACE : 0), | ||||
|                                  on_bus_acquired, | ||||
|                                  on_name_acquired, | ||||
|                                  on_name_lost, | ||||
|                                  NULL, NULL); | ||||
| } | ||||
| @@ -1,8 +1,8 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
| 
 | ||||
| /* 
 | ||||
| /*
 | ||||
|  * Copyright 2013 Red Hat, Inc. | ||||
|  *  | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
| @@ -12,7 +12,7 @@ | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  *  | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
| @@ -20,10 +20,9 @@ | ||||
|  *         from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c | ||||
|  */ | ||||
| 
 | ||||
| #include <meta/meta-idle-monitor.h> | ||||
| 
 | ||||
| void meta_idle_monitor_handle_xevent_all (XEvent *xevent); | ||||
| 
 | ||||
| void meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor); | ||||
| #ifndef META_IDLE_MONITOR_DBUS_H | ||||
| #define META_IDLE_MONITOR_DBUS_H | ||||
| 
 | ||||
| void meta_idle_monitor_init_dbus (void); | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										65
									
								
								src/backends/meta-idle-monitor-private.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								src/backends/meta-idle-monitor-private.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright 2013 Red Hat, Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and | ||||
|  *         from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c | ||||
|  */ | ||||
|  | ||||
| #ifndef META_IDLE_MONITOR_PRIVATE_H | ||||
| #define META_IDLE_MONITOR_PRIVATE_H | ||||
|  | ||||
| #include <meta/meta-idle-monitor.h> | ||||
| #include "display-private.h" | ||||
|  | ||||
| #include <X11/Xlib.h> | ||||
| #include <X11/extensions/sync.h> | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   MetaIdleMonitor          *monitor; | ||||
|   guint	                    id; | ||||
|   MetaIdleMonitorWatchFunc  callback; | ||||
|   gpointer		    user_data; | ||||
|   GDestroyNotify            notify; | ||||
|   guint64                   timeout_msec; | ||||
|   int                       idle_source_id; | ||||
| } MetaIdleMonitorWatch; | ||||
|  | ||||
| struct _MetaIdleMonitor | ||||
| { | ||||
|   GObject parent_instance; | ||||
|  | ||||
|   GHashTable *watches; | ||||
|   int device_id; | ||||
| }; | ||||
|  | ||||
| struct _MetaIdleMonitorClass | ||||
| { | ||||
|   GObjectClass parent_class; | ||||
|  | ||||
|   gint64 (*get_idletime) (MetaIdleMonitor *monitor); | ||||
|   MetaIdleMonitorWatch * (*make_watch) (MetaIdleMonitor           *monitor, | ||||
|                                         guint64                    timeout_msec, | ||||
|                                         MetaIdleMonitorWatchFunc   callback, | ||||
|                                         gpointer                   user_data, | ||||
|                                         GDestroyNotify             notify); | ||||
| }; | ||||
|  | ||||
| void _meta_idle_monitor_watch_fire (MetaIdleMonitorWatch *watch); | ||||
|  | ||||
| #endif /* META_IDLE_MONITOR_PRIVATE_H */ | ||||
							
								
								
									
										318
									
								
								src/backends/meta-idle-monitor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										318
									
								
								src/backends/meta-idle-monitor.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,318 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright 2013 Red Hat, Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and | ||||
|  *         from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * SECTION:idle-monitor | ||||
|  * @title: MetaIdleMonitor | ||||
|  * @short_description: Mutter idle counter (similar to X's IDLETIME) | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include <string.h> | ||||
| #include <clutter/clutter.h> | ||||
| #include <X11/Xlib.h> | ||||
| #include <X11/extensions/sync.h> | ||||
|  | ||||
| #include <meta/util.h> | ||||
| #include <meta/main.h> | ||||
| #include <meta/meta-idle-monitor.h> | ||||
| #include "meta-idle-monitor-private.h" | ||||
| #include "meta-idle-monitor-dbus.h" | ||||
| #include "meta-backend.h" | ||||
|  | ||||
| G_STATIC_ASSERT(sizeof(unsigned long) == sizeof(gpointer)); | ||||
|  | ||||
| enum | ||||
| { | ||||
|   PROP_0, | ||||
|   PROP_DEVICE_ID, | ||||
|   PROP_LAST, | ||||
| }; | ||||
|  | ||||
| static GParamSpec *obj_props[PROP_LAST]; | ||||
|  | ||||
| G_DEFINE_TYPE (MetaIdleMonitor, meta_idle_monitor, G_TYPE_OBJECT) | ||||
|  | ||||
| void | ||||
| _meta_idle_monitor_watch_fire (MetaIdleMonitorWatch *watch) | ||||
| { | ||||
|   MetaIdleMonitor *monitor; | ||||
|   guint id; | ||||
|   gboolean is_user_active_watch; | ||||
|  | ||||
|   monitor = watch->monitor; | ||||
|   g_object_ref (monitor); | ||||
|  | ||||
|   if (watch->idle_source_id) | ||||
|     { | ||||
|       g_source_remove (watch->idle_source_id); | ||||
|       watch->idle_source_id = 0; | ||||
|     } | ||||
|  | ||||
|   id = watch->id; | ||||
|   is_user_active_watch = (watch->timeout_msec == 0); | ||||
|  | ||||
|   if (watch->callback) | ||||
|     watch->callback (monitor, id, watch->user_data); | ||||
|  | ||||
|   if (is_user_active_watch) | ||||
|     meta_idle_monitor_remove_watch (monitor, id); | ||||
|  | ||||
|   g_object_unref (monitor); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_idle_monitor_dispose (GObject *object) | ||||
| { | ||||
|   MetaIdleMonitor *monitor = META_IDLE_MONITOR (object); | ||||
|  | ||||
|   g_clear_pointer (&monitor->watches, g_hash_table_destroy); | ||||
|  | ||||
|   G_OBJECT_CLASS (meta_idle_monitor_parent_class)->dispose (object); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_idle_monitor_get_property (GObject    *object, | ||||
|                                 guint       prop_id, | ||||
|                                 GValue     *value, | ||||
|                                 GParamSpec *pspec) | ||||
| { | ||||
|   MetaIdleMonitor *monitor = META_IDLE_MONITOR (object); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_DEVICE_ID: | ||||
|       g_value_set_int (value, monitor->device_id); | ||||
|       break; | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_idle_monitor_set_property (GObject      *object, | ||||
|                                 guint         prop_id, | ||||
|                                 const GValue *value, | ||||
|                                 GParamSpec   *pspec) | ||||
| { | ||||
|   MetaIdleMonitor *monitor = META_IDLE_MONITOR (object); | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_DEVICE_ID: | ||||
|       monitor->device_id = g_value_get_int (value); | ||||
|       break; | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_idle_monitor_class_init (MetaIdleMonitorClass *klass) | ||||
| { | ||||
|   GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   object_class->dispose = meta_idle_monitor_dispose; | ||||
|   object_class->get_property = meta_idle_monitor_get_property; | ||||
|   object_class->set_property = meta_idle_monitor_set_property; | ||||
|  | ||||
|   /** | ||||
|    * MetaIdleMonitor:device_id: | ||||
|    * | ||||
|    * The device to listen to idletime on. | ||||
|    */ | ||||
|   obj_props[PROP_DEVICE_ID] = | ||||
|     g_param_spec_int ("device-id", | ||||
|                       "Device ID", | ||||
|                       "The device to listen to idletime on", | ||||
|                       0, 255, 0, | ||||
|                       G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); | ||||
|   g_object_class_install_property (object_class, PROP_DEVICE_ID, obj_props[PROP_DEVICE_ID]); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_idle_monitor_init (MetaIdleMonitor *monitor) | ||||
| { | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_idle_monitor_get_core: | ||||
|  * | ||||
|  * Returns: (transfer none): the #MetaIdleMonitor that tracks the server-global | ||||
|  * idletime for all devices. To track device-specific idletime, | ||||
|  * use meta_idle_monitor_get_for_device(). | ||||
|  */ | ||||
| MetaIdleMonitor * | ||||
| meta_idle_monitor_get_core (void) | ||||
| { | ||||
|   MetaBackend *backend = meta_get_backend (); | ||||
|   return meta_backend_get_idle_monitor (backend, 0); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_idle_monitor_get_for_device: | ||||
|  * @device_id: the device to get the idle time for. | ||||
|  * | ||||
|  * Returns: (transfer none): a new #MetaIdleMonitor that tracks the | ||||
|  * device-specific idletime for @device. To track server-global idletime | ||||
|  * for all devices, use meta_idle_monitor_get_core(). | ||||
|  */ | ||||
| MetaIdleMonitor * | ||||
| meta_idle_monitor_get_for_device (int device_id) | ||||
| { | ||||
|   MetaBackend *backend = meta_get_backend (); | ||||
|   return meta_backend_get_idle_monitor (backend, device_id); | ||||
| } | ||||
|  | ||||
| static MetaIdleMonitorWatch * | ||||
| make_watch (MetaIdleMonitor           *monitor, | ||||
|             guint64                    timeout_msec, | ||||
|             MetaIdleMonitorWatchFunc   callback, | ||||
|             gpointer                   user_data, | ||||
|             GDestroyNotify             notify) | ||||
| { | ||||
|   MetaIdleMonitorWatch *watch; | ||||
|  | ||||
|   watch = META_IDLE_MONITOR_GET_CLASS (monitor)->make_watch (monitor, | ||||
|                                                              timeout_msec, | ||||
|                                                              callback, | ||||
|                                                              user_data, | ||||
|                                                              notify); | ||||
|  | ||||
|   g_hash_table_insert (monitor->watches, | ||||
|                        GUINT_TO_POINTER (watch->id), | ||||
|                        watch); | ||||
|   return watch; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_idle_monitor_add_idle_watch: | ||||
|  * @monitor: A #MetaIdleMonitor | ||||
|  * @interval_msec: The idletime interval, in milliseconds | ||||
|  * @callback: (nullable): The callback to call when the user has | ||||
|  *     accumulated @interval_msec milliseconds of idle time. | ||||
|  * @user_data: (nullable): The user data to pass to the callback | ||||
|  * @notify: A #GDestroyNotify | ||||
|  * | ||||
|  * Returns: a watch id | ||||
|  * | ||||
|  * Adds a watch for a specific idle time. The callback will be called | ||||
|  * when the user has accumulated @interval_msec milliseconds of idle time. | ||||
|  * This function will return an ID that can either be passed to | ||||
|  * meta_idle_monitor_remove_watch(), or can be used to tell idle time | ||||
|  * watches apart if you have more than one. | ||||
|  * | ||||
|  * Also note that this function will only care about positive transitions | ||||
|  * (user's idle time exceeding a certain time). If you want to know about | ||||
|  * when the user has become active, use | ||||
|  * meta_idle_monitor_add_user_active_watch(). | ||||
|  */ | ||||
| guint | ||||
| meta_idle_monitor_add_idle_watch (MetaIdleMonitor	       *monitor, | ||||
|                                   guint64	                interval_msec, | ||||
|                                   MetaIdleMonitorWatchFunc      callback, | ||||
|                                   gpointer			user_data, | ||||
|                                   GDestroyNotify		notify) | ||||
| { | ||||
|   MetaIdleMonitorWatch *watch; | ||||
|  | ||||
|   g_return_val_if_fail (META_IS_IDLE_MONITOR (monitor), 0); | ||||
|   g_return_val_if_fail (interval_msec > 0, 0); | ||||
|  | ||||
|   watch = make_watch (monitor, | ||||
|                       interval_msec, | ||||
|                       callback, | ||||
|                       user_data, | ||||
|                       notify); | ||||
|  | ||||
|   return watch->id; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_idle_monitor_add_user_active_watch: | ||||
|  * @monitor: A #MetaIdleMonitor | ||||
|  * @callback: (nullable): The callback to call when the user is | ||||
|  *     active again. | ||||
|  * @user_data: (nullable): The user data to pass to the callback | ||||
|  * @notify: A #GDestroyNotify | ||||
|  * | ||||
|  * Returns: a watch id | ||||
|  * | ||||
|  * Add a one-time watch to know when the user is active again. | ||||
|  * Note that this watch is one-time and will de-activate after the | ||||
|  * function is called, for efficiency purposes. It's most convenient | ||||
|  * to call this when an idle watch, as added by | ||||
|  * meta_idle_monitor_add_idle_watch(), has triggered. | ||||
|  */ | ||||
| guint | ||||
| meta_idle_monitor_add_user_active_watch (MetaIdleMonitor          *monitor, | ||||
|                                          MetaIdleMonitorWatchFunc  callback, | ||||
|                                          gpointer		   user_data, | ||||
|                                          GDestroyNotify	           notify) | ||||
| { | ||||
|   MetaIdleMonitorWatch *watch; | ||||
|  | ||||
|   g_return_val_if_fail (META_IS_IDLE_MONITOR (monitor), 0); | ||||
|  | ||||
|   watch = make_watch (monitor, | ||||
|                       0, | ||||
|                       callback, | ||||
|                       user_data, | ||||
|                       notify); | ||||
|  | ||||
|   return watch->id; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_idle_monitor_remove_watch: | ||||
|  * @monitor: A #MetaIdleMonitor | ||||
|  * @id: A watch ID | ||||
|  * | ||||
|  * Removes an idle time watcher, previously added by | ||||
|  * meta_idle_monitor_add_idle_watch() or | ||||
|  * meta_idle_monitor_add_user_active_watch(). | ||||
|  */ | ||||
| void | ||||
| meta_idle_monitor_remove_watch (MetaIdleMonitor *monitor, | ||||
|                                 guint	         id) | ||||
| { | ||||
|   g_return_if_fail (META_IS_IDLE_MONITOR (monitor)); | ||||
|  | ||||
|   g_object_ref (monitor); | ||||
|   g_hash_table_remove (monitor->watches, | ||||
|                        GUINT_TO_POINTER (id)); | ||||
|   g_object_unref (monitor); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_idle_monitor_get_idletime: | ||||
|  * @monitor: A #MetaIdleMonitor | ||||
|  * | ||||
|  * Returns: The current idle time, in milliseconds, or -1 for not supported | ||||
|  */ | ||||
| gint64 | ||||
| meta_idle_monitor_get_idletime (MetaIdleMonitor *monitor) | ||||
| { | ||||
|   return META_IDLE_MONITOR_GET_CLASS (monitor)->get_idletime (monitor); | ||||
| } | ||||
| @@ -1,6 +1,6 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
| 
 | ||||
| /* 
 | ||||
| /*
 | ||||
|  * Copyright (C) 2001, 2002 Havoc Pennington | ||||
|  * Copyright (C) 2002, 2003 Red Hat Inc. | ||||
|  * Some ICCCM manager selection code derived from fvwm2, | ||||
| @@ -8,7 +8,7 @@ | ||||
|  * Copyright (C) 2003 Rob Adams | ||||
|  * Copyright (C) 2004-2006 Elijah Newren | ||||
|  * Copyright (C) 2013 Red Hat Inc. | ||||
|  *  | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
| @@ -18,7 +18,7 @@ | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  *  | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| @@ -34,13 +34,14 @@ | ||||
| 
 | ||||
| #include "config.h" | ||||
| 
 | ||||
| #include "meta-monitor-config.h" | ||||
| 
 | ||||
| #include <string.h> | ||||
| #include <clutter/clutter.h> | ||||
| #include <libupower-glib/upower.h> | ||||
| 
 | ||||
| #include <meta/main.h> | ||||
| #include <meta/errors.h> | ||||
| #include "monitor-private.h" | ||||
| 
 | ||||
| /* These structures represent the intended/persistent configuration,
 | ||||
|    as stored in the monitors.xml file. | ||||
| @@ -77,6 +78,7 @@ struct _MetaMonitorConfig { | ||||
|   GHashTable *configs; | ||||
|   MetaConfiguration *current; | ||||
|   gboolean current_is_stored; | ||||
|   gboolean current_is_for_laptop_lid; | ||||
|   MetaConfiguration *previous; | ||||
| 
 | ||||
|   GFile *file; | ||||
| @@ -569,7 +571,7 @@ is_all_whitespace (const char *text, | ||||
|                    gsize       text_len) | ||||
| { | ||||
|   gsize i; | ||||
|    | ||||
| 
 | ||||
|   for (i = 0; i < text_len; i++) | ||||
|     if (!g_ascii_isspace (text[i])) | ||||
|       return FALSE; | ||||
| @@ -839,6 +841,9 @@ meta_monitor_config_get_stored (MetaMonitorConfig *self, | ||||
|   MetaConfiguration key; | ||||
|   MetaConfiguration *stored; | ||||
| 
 | ||||
|   if (n_outputs == 0) | ||||
|     return NULL; | ||||
| 
 | ||||
|   make_config_key (&key, outputs, n_outputs, -1); | ||||
|   stored = g_hash_table_lookup (self->configs, &key); | ||||
| 
 | ||||
| @@ -873,7 +878,8 @@ apply_configuration (MetaMonitorConfig  *self, | ||||
| 
 | ||||
|   /* Stored (persistent) configurations override the previous one always.
 | ||||
|      Also, we clear the previous configuration if the current one (which is | ||||
|      about to become previous) is stored. | ||||
|      about to become previous) is stored, or if the current one has | ||||
|      different outputs. | ||||
|   */ | ||||
|   if (stored || | ||||
|       (self->current && self->current_is_stored)) | ||||
| @@ -884,11 +890,27 @@ apply_configuration (MetaMonitorConfig  *self, | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       self->previous = self->current; | ||||
|       /* Despite the name, config_equal() only checks the set of outputs,
 | ||||
|          not their modes | ||||
|       */ | ||||
|       if (self->current && config_equal (self->current, config)) | ||||
|         { | ||||
|           self->previous = self->current; | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           if (self->current) | ||||
|             config_free (self->current); | ||||
|           self->previous = NULL; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   self->current = config; | ||||
|   self->current_is_stored = stored; | ||||
|   /* If true, we'll be overridden at the end of this call
 | ||||
|      inside turn_off_laptop_display() | ||||
|   */ | ||||
|   self->current_is_for_laptop_lid = FALSE; | ||||
| 
 | ||||
|   if (self->current == self->previous) | ||||
|     self->previous = NULL; | ||||
| @@ -1005,8 +1027,16 @@ meta_monitor_config_apply_stored (MetaMonitorConfig  *self, | ||||
|       if (self->lid_is_closed && | ||||
|           stored->n_outputs > 1 && | ||||
|           laptop_display_is_on (stored)) | ||||
|         return apply_configuration (self, make_laptop_lid_config (stored), | ||||
|                                     manager, FALSE); | ||||
|         { | ||||
|           if (apply_configuration (self, make_laptop_lid_config (stored), | ||||
|                                    manager, FALSE)) | ||||
|             { | ||||
|               self->current_is_for_laptop_lid = TRUE; | ||||
|               return TRUE; | ||||
|             } | ||||
|           else | ||||
|             return FALSE; | ||||
|         } | ||||
|       else | ||||
|         return apply_configuration (self, stored, manager, TRUE); | ||||
|     } | ||||
| @@ -1246,6 +1276,12 @@ meta_monitor_config_make_default (MetaMonitorConfig  *self, | ||||
|   outputs = meta_monitor_manager_get_outputs (manager, &n_outputs); | ||||
|   meta_monitor_manager_get_screen_limits (manager, &max_width, &max_height); | ||||
| 
 | ||||
|   if (n_outputs == 0) | ||||
|     { | ||||
|       meta_verbose ("No output connected, not applying configuration\n"); | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|   default_config = make_default_config (self, outputs, n_outputs, max_width, max_height); | ||||
| 
 | ||||
|   if (default_config != NULL) | ||||
| @@ -1347,6 +1383,7 @@ turn_off_laptop_display (MetaMonitorConfig  *self, | ||||
| 
 | ||||
|   new = make_laptop_lid_config (self->current); | ||||
|   apply_configuration (self, new, manager, FALSE); | ||||
|   self->current_is_for_laptop_lid = TRUE; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| @@ -1366,7 +1403,7 @@ power_client_changed_cb (UpClient   *client, | ||||
| 
 | ||||
|       if (is_closed) | ||||
|         turn_off_laptop_display (self, manager); | ||||
|       else | ||||
|       else if (self->current_is_for_laptop_lid) | ||||
|         meta_monitor_config_restore_previous (self, manager); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										55
									
								
								src/backends/meta-monitor-config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/backends/meta-monitor-config.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2001 Havoc Pennington | ||||
|  * Copyright (C) 2003 Rob Adams | ||||
|  * Copyright (C) 2004-2006 Elijah Newren | ||||
|  * Copyright (C) 2013 Red Hat Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| #ifndef META_MONITOR_CONFIG_H | ||||
| #define META_MONITOR_CONFIG_H | ||||
|  | ||||
| #include "meta-monitor-manager.h" | ||||
|  | ||||
| #define META_TYPE_MONITOR_CONFIG            (meta_monitor_config_get_type ()) | ||||
| #define META_MONITOR_CONFIG(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_CONFIG, MetaMonitorConfig)) | ||||
| #define META_MONITOR_CONFIG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_MONITOR_CONFIG, MetaMonitorConfigClass)) | ||||
| #define META_IS_MONITOR_CONFIG(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_MONITOR_CONFIG)) | ||||
| #define META_IS_MONITOR_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_MONITOR_CONFIG)) | ||||
| #define META_MONITOR_CONFIG_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_MONITOR_CONFIG, MetaMonitorConfigClass)) | ||||
|  | ||||
| GType meta_monitor_config_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| MetaMonitorConfig *meta_monitor_config_new (void); | ||||
|  | ||||
| gboolean           meta_monitor_config_match_current (MetaMonitorConfig  *config, | ||||
|                                                       MetaMonitorManager *manager); | ||||
|  | ||||
| gboolean           meta_monitor_config_apply_stored (MetaMonitorConfig  *config, | ||||
|                                                      MetaMonitorManager *manager); | ||||
|  | ||||
| void               meta_monitor_config_make_default (MetaMonitorConfig  *config, | ||||
|                                                      MetaMonitorManager *manager); | ||||
|  | ||||
| void               meta_monitor_config_update_current (MetaMonitorConfig  *config, | ||||
|                                                        MetaMonitorManager *manager); | ||||
| void               meta_monitor_config_make_persistent (MetaMonitorConfig *config); | ||||
|  | ||||
| void               meta_monitor_config_restore_previous (MetaMonitorConfig  *config, | ||||
|                                                          MetaMonitorManager *manager); | ||||
|  | ||||
| #endif /* META_MONITOR_CONFIG_H */ | ||||
							
								
								
									
										227
									
								
								src/backends/meta-monitor-manager-dummy.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										227
									
								
								src/backends/meta-monitor-manager-dummy.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,227 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2001, 2002 Havoc Pennington | ||||
|  * Copyright (C) 2002, 2003 Red Hat Inc. | ||||
|  * Some ICCCM manager selection code derived from fvwm2, | ||||
|  * Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team | ||||
|  * Copyright (C) 2003 Rob Adams | ||||
|  * Copyright (C) 2004-2006 Elijah Newren | ||||
|  * Copyright (C) 2013 Red Hat Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "meta-monitor-manager-dummy.h" | ||||
|  | ||||
| #define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1) | ||||
|  | ||||
| struct _MetaMonitorManagerDummy | ||||
| { | ||||
|   MetaMonitorManager parent_instance; | ||||
| }; | ||||
|  | ||||
| struct _MetaMonitorManagerDummyClass | ||||
| { | ||||
|   MetaMonitorManagerClass parent_class; | ||||
| }; | ||||
|  | ||||
| G_DEFINE_TYPE (MetaMonitorManagerDummy, meta_monitor_manager_dummy, META_TYPE_MONITOR_MANAGER); | ||||
|  | ||||
| static void | ||||
| meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager) | ||||
| { | ||||
|   manager->max_screen_width = 65535; | ||||
|   manager->max_screen_height = 65535; | ||||
|   manager->screen_width = 1024; | ||||
|   manager->screen_height = 768; | ||||
|  | ||||
|   manager->modes = g_new0 (MetaMonitorMode, 1); | ||||
|   manager->n_modes = 1; | ||||
|  | ||||
|   manager->modes[0].mode_id = 0; | ||||
|   manager->modes[0].width = 1024; | ||||
|   manager->modes[0].height = 768; | ||||
|   manager->modes[0].refresh_rate = 60.0; | ||||
|  | ||||
|   manager->crtcs = g_new0 (MetaCRTC, 1); | ||||
|   manager->n_crtcs = 1; | ||||
|  | ||||
|   manager->crtcs[0].crtc_id = 1; | ||||
|   manager->crtcs[0].rect.x = 0; | ||||
|   manager->crtcs[0].rect.y = 0; | ||||
|   manager->crtcs[0].rect.width = manager->modes[0].width; | ||||
|   manager->crtcs[0].rect.height = manager->modes[0].height; | ||||
|   manager->crtcs[0].current_mode = &manager->modes[0]; | ||||
|   manager->crtcs[0].transform = WL_OUTPUT_TRANSFORM_NORMAL; | ||||
|   manager->crtcs[0].all_transforms = ALL_WL_TRANSFORMS; | ||||
|   manager->crtcs[0].is_dirty = FALSE; | ||||
|   manager->crtcs[0].logical_monitor = NULL; | ||||
|  | ||||
|   manager->outputs = g_new0 (MetaOutput, 1); | ||||
|   manager->n_outputs = 1; | ||||
|  | ||||
|   manager->outputs[0].crtc = &manager->crtcs[0]; | ||||
|   manager->outputs[0].output_id = 1; | ||||
|   manager->outputs[0].name = g_strdup ("LVDS"); | ||||
|   manager->outputs[0].vendor = g_strdup ("MetaProducts Inc."); | ||||
|   manager->outputs[0].product = g_strdup ("unknown"); | ||||
|   manager->outputs[0].serial = g_strdup ("0xC0FFEE"); | ||||
|   manager->outputs[0].width_mm = 222; | ||||
|   manager->outputs[0].height_mm = 125; | ||||
|   manager->outputs[0].subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; | ||||
|   manager->outputs[0].preferred_mode = &manager->modes[0]; | ||||
|   manager->outputs[0].n_modes = 1; | ||||
|   manager->outputs[0].modes = g_new0 (MetaMonitorMode *, 1); | ||||
|   manager->outputs[0].modes[0] = &manager->modes[0]; | ||||
|   manager->outputs[0].n_possible_crtcs = 1; | ||||
|   manager->outputs[0].possible_crtcs = g_new0 (MetaCRTC *, 1); | ||||
|   manager->outputs[0].possible_crtcs[0] = &manager->crtcs[0]; | ||||
|   manager->outputs[0].n_possible_clones = 0; | ||||
|   manager->outputs[0].possible_clones = g_new0 (MetaOutput *, 0); | ||||
|   manager->outputs[0].backlight = -1; | ||||
|   manager->outputs[0].backlight_min = 0; | ||||
|   manager->outputs[0].backlight_max = 0; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_monitor_manager_dummy_apply_config (MetaMonitorManager *manager, | ||||
|                                          MetaCRTCInfo       **crtcs, | ||||
|                                          unsigned int         n_crtcs, | ||||
|                                          MetaOutputInfo     **outputs, | ||||
|                                          unsigned int         n_outputs) | ||||
| { | ||||
|     unsigned i; | ||||
|     int screen_width = 0, screen_height = 0; | ||||
|  | ||||
|   for (i = 0; i < n_crtcs; i++) | ||||
|     { | ||||
|       MetaCRTCInfo *crtc_info = crtcs[i]; | ||||
|       MetaCRTC *crtc = crtc_info->crtc; | ||||
|       crtc->is_dirty = TRUE; | ||||
|  | ||||
|       if (crtc_info->mode == NULL) | ||||
|         { | ||||
|           crtc->rect.x = 0; | ||||
|           crtc->rect.y = 0; | ||||
|           crtc->rect.width = 0; | ||||
|           crtc->rect.height = 0; | ||||
|           crtc->current_mode = NULL; | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           MetaMonitorMode *mode; | ||||
|           MetaOutput *output; | ||||
|           int i, n_outputs; | ||||
|           int width, height; | ||||
|  | ||||
|           mode = crtc_info->mode; | ||||
|  | ||||
|           if (meta_monitor_transform_is_rotated (crtc_info->transform)) | ||||
|             { | ||||
|               width = mode->height; | ||||
|               height = mode->width; | ||||
|             } | ||||
|           else | ||||
|             { | ||||
|               width = mode->width; | ||||
|               height = mode->height; | ||||
|             } | ||||
|  | ||||
|           crtc->rect.x = crtc_info->x; | ||||
|           crtc->rect.y = crtc_info->y; | ||||
|           crtc->rect.width = width; | ||||
|           crtc->rect.height = height; | ||||
|           crtc->current_mode = mode; | ||||
|           crtc->transform = crtc_info->transform; | ||||
|  | ||||
|           screen_width = MAX (screen_width, crtc_info->x + width); | ||||
|           screen_height = MAX (screen_height, crtc_info->y + height); | ||||
|  | ||||
|           n_outputs = crtc_info->outputs->len; | ||||
|           for (i = 0; i < n_outputs; i++) | ||||
|             { | ||||
|               output = ((MetaOutput**)crtc_info->outputs->pdata)[i]; | ||||
|  | ||||
|               output->is_dirty = TRUE; | ||||
|               output->crtc = crtc; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   for (i = 0; i < n_outputs; i++) | ||||
|     { | ||||
|       MetaOutputInfo *output_info = outputs[i]; | ||||
|       MetaOutput *output = output_info->output; | ||||
|  | ||||
|       output->is_primary = output_info->is_primary; | ||||
|       output->is_presentation = output_info->is_presentation; | ||||
|     } | ||||
|  | ||||
|   /* Disable CRTCs not mentioned in the list */ | ||||
|   for (i = 0; i < manager->n_crtcs; i++) | ||||
|     { | ||||
|       MetaCRTC *crtc = &manager->crtcs[i]; | ||||
|  | ||||
|       crtc->logical_monitor = NULL; | ||||
|  | ||||
|       if (crtc->is_dirty) | ||||
|         { | ||||
|           crtc->is_dirty = FALSE; | ||||
|           continue; | ||||
|         } | ||||
|  | ||||
|       crtc->rect.x = 0; | ||||
|       crtc->rect.y = 0; | ||||
|       crtc->rect.width = 0; | ||||
|       crtc->rect.height = 0; | ||||
|       crtc->current_mode = NULL; | ||||
|     } | ||||
|  | ||||
|   /* Disable outputs not mentioned in the list */ | ||||
|   for (i = 0; i < manager->n_outputs; i++) | ||||
|     { | ||||
|       MetaOutput *output = &manager->outputs[i]; | ||||
|  | ||||
|       if (output->is_dirty) | ||||
|         { | ||||
|           output->is_dirty = FALSE; | ||||
|           continue; | ||||
|         } | ||||
|  | ||||
|       output->crtc = NULL; | ||||
|       output->is_primary = FALSE; | ||||
|     } | ||||
|  | ||||
|   manager->screen_width = screen_width; | ||||
|   manager->screen_height = screen_height; | ||||
|  | ||||
|   meta_monitor_manager_rebuild_derived (manager); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_monitor_manager_dummy_class_init (MetaMonitorManagerDummyClass *klass) | ||||
| { | ||||
|   MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_CLASS (klass); | ||||
|  | ||||
|   manager_class->read_current = meta_monitor_manager_dummy_read_current; | ||||
|   manager_class->apply_configuration = meta_monitor_manager_dummy_apply_config; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_monitor_manager_dummy_init (MetaMonitorManagerDummy *manager) | ||||
| { | ||||
| } | ||||
							
								
								
									
										40
									
								
								src/backends/meta-monitor-manager-dummy.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/backends/meta-monitor-manager-dummy.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2001 Havoc Pennington | ||||
|  * Copyright (C) 2003 Rob Adams | ||||
|  * Copyright (C) 2004-2006 Elijah Newren | ||||
|  * Copyright (C) 2013 Red Hat Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| #ifndef META_MONITOR_MANAGER_DUMMY_H | ||||
| #define META_MONITOR_MANAGER_DUMMY_H | ||||
|  | ||||
| #include "meta-monitor-manager.h" | ||||
|  | ||||
| #define META_TYPE_MONITOR_MANAGER_DUMMY            (meta_monitor_manager_dummy_get_type ()) | ||||
| #define META_MONITOR_MANAGER_DUMMY(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER_DUMMY, MetaMonitorManagerDummy)) | ||||
| #define META_MONITOR_MANAGER_DUMMY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_MONITOR_MANAGER_DUMMY, MetaMonitorManagerDummyClass)) | ||||
| #define META_IS_MONITOR_MANAGER_DUMMY(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_MONITOR_MANAGER_DUMMY)) | ||||
| #define META_IS_MONITOR_MANAGER_DUMMY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_MONITOR_MANAGER_DUMMY)) | ||||
| #define META_MONITOR_MANAGER_DUMMY_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_MONITOR_MANAGER_DUMMY, MetaMonitorManagerDummyClass)) | ||||
|  | ||||
| typedef struct _MetaMonitorManagerDummyClass    MetaMonitorManagerDummyClass; | ||||
| typedef struct _MetaMonitorManagerDummy         MetaMonitorManagerDummy; | ||||
|  | ||||
| GType meta_monitor_manager_dummy_get_type (void); | ||||
|  | ||||
| #endif /* META_MONITOR_MANAGER_DUMMY_H */ | ||||
| @@ -1,6 +1,6 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
| 
 | ||||
| /* 
 | ||||
| /*
 | ||||
|  * Copyright (C) 2001, 2002 Havoc Pennington | ||||
|  * Copyright (C) 2002, 2003 Red Hat Inc. | ||||
|  * Some ICCCM manager selection code derived from fvwm2, | ||||
| @@ -8,7 +8,7 @@ | ||||
|  * Copyright (C) 2003 Rob Adams | ||||
|  * Copyright (C) 2004-2006 Elijah Newren | ||||
|  * Copyright (C) 2013 Red Hat Inc. | ||||
|  *  | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
| @@ -18,13 +18,15 @@ | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  *  | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| #include "config.h" | ||||
| 
 | ||||
| #include "meta-monitor-manager.h" | ||||
| 
 | ||||
| #include <string.h> | ||||
| #include <math.h> | ||||
| #include <stdlib.h> | ||||
| @@ -33,11 +35,9 @@ | ||||
| #include <meta/main.h> | ||||
| #include "util-private.h" | ||||
| #include <meta/errors.h> | ||||
| #include "monitor-private.h" | ||||
| 
 | ||||
| #include "meta-dbus-xrandr.h" | ||||
| 
 | ||||
| #define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1) | ||||
| #include "meta-monitor-config.h" | ||||
| #include "backends/x11/meta-monitor-manager-xrandr.h" | ||||
| #include "meta-backend.h" | ||||
| 
 | ||||
| enum { | ||||
|   CONFIRM_DISPLAY_CHANGE, | ||||
| @@ -54,196 +54,11 @@ static int signals[SIGNALS_LAST]; | ||||
| 
 | ||||
| static void meta_monitor_manager_display_config_init (MetaDBusDisplayConfigIface *iface); | ||||
| 
 | ||||
| G_DEFINE_TYPE_WITH_CODE (MetaMonitorManager, meta_monitor_manager, META_DBUS_TYPE_DISPLAY_CONFIG_SKELETON, | ||||
|                          G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_DISPLAY_CONFIG, meta_monitor_manager_display_config_init)); | ||||
| G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaMonitorManager, meta_monitor_manager, META_DBUS_TYPE_DISPLAY_CONFIG_SKELETON, | ||||
|                                   G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_DISPLAY_CONFIG, meta_monitor_manager_display_config_init)); | ||||
| 
 | ||||
| static void initialize_dbus_interface (MetaMonitorManager *manager); | ||||
| 
 | ||||
| static void | ||||
| read_current_dummy (MetaMonitorManager *manager) | ||||
| { | ||||
|   manager->max_screen_width = 65535; | ||||
|   manager->max_screen_height = 65535; | ||||
|   manager->screen_width = 1024; | ||||
|   manager->screen_height = 768; | ||||
| 
 | ||||
|   manager->modes = g_new0 (MetaMonitorMode, 1); | ||||
|   manager->n_modes = 1; | ||||
| 
 | ||||
|   manager->modes[0].mode_id = 0; | ||||
|   manager->modes[0].width = 1024; | ||||
|   manager->modes[0].height = 768; | ||||
|   manager->modes[0].refresh_rate = 60.0; | ||||
| 
 | ||||
|   manager->crtcs = g_new0 (MetaCRTC, 1); | ||||
|   manager->n_crtcs = 1; | ||||
| 
 | ||||
|   manager->crtcs[0].crtc_id = 1; | ||||
|   manager->crtcs[0].rect.x = 0; | ||||
|   manager->crtcs[0].rect.y = 0; | ||||
|   manager->crtcs[0].rect.width = manager->modes[0].width; | ||||
|   manager->crtcs[0].rect.height = manager->modes[0].height; | ||||
|   manager->crtcs[0].current_mode = &manager->modes[0]; | ||||
|   manager->crtcs[0].transform = WL_OUTPUT_TRANSFORM_NORMAL; | ||||
|   manager->crtcs[0].all_transforms = ALL_WL_TRANSFORMS; | ||||
|   manager->crtcs[0].is_dirty = FALSE; | ||||
|   manager->crtcs[0].logical_monitor = NULL; | ||||
| 
 | ||||
|   manager->outputs = g_new0 (MetaOutput, 1); | ||||
|   manager->n_outputs = 1; | ||||
| 
 | ||||
|   manager->outputs[0].crtc = &manager->crtcs[0]; | ||||
|   manager->outputs[0].output_id = 1; | ||||
|   manager->outputs[0].name = g_strdup ("LVDS"); | ||||
|   manager->outputs[0].vendor = g_strdup ("MetaProducts Inc."); | ||||
|   manager->outputs[0].product = g_strdup ("unknown"); | ||||
|   manager->outputs[0].serial = g_strdup ("0xC0FFEE"); | ||||
|   manager->outputs[0].width_mm = 222; | ||||
|   manager->outputs[0].height_mm = 125; | ||||
|   manager->outputs[0].subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; | ||||
|   manager->outputs[0].preferred_mode = &manager->modes[0]; | ||||
|   manager->outputs[0].n_modes = 1; | ||||
|   manager->outputs[0].modes = g_new0 (MetaMonitorMode *, 1); | ||||
|   manager->outputs[0].modes[0] = &manager->modes[0]; | ||||
|   manager->outputs[0].n_possible_crtcs = 1; | ||||
|   manager->outputs[0].possible_crtcs = g_new0 (MetaCRTC *, 1); | ||||
|   manager->outputs[0].possible_crtcs[0] = &manager->crtcs[0]; | ||||
|   manager->outputs[0].n_possible_clones = 0; | ||||
|   manager->outputs[0].possible_clones = g_new0 (MetaOutput *, 0); | ||||
|   manager->outputs[0].backlight = -1; | ||||
|   manager->outputs[0].backlight_min = 0; | ||||
|   manager->outputs[0].backlight_max = 0; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| apply_config_dummy (MetaMonitorManager *manager, | ||||
|                     MetaCRTCInfo       **crtcs, | ||||
|                     unsigned int         n_crtcs, | ||||
|                     MetaOutputInfo     **outputs, | ||||
|                     unsigned int         n_outputs) | ||||
| { | ||||
|   unsigned i; | ||||
|   int screen_width = 0, screen_height = 0; | ||||
| 
 | ||||
|   for (i = 0; i < n_crtcs; i++) | ||||
|     { | ||||
|       MetaCRTCInfo *crtc_info = crtcs[i]; | ||||
|       MetaCRTC *crtc = crtc_info->crtc; | ||||
|       crtc->is_dirty = TRUE; | ||||
| 
 | ||||
|       if (crtc_info->mode == NULL) | ||||
|         { | ||||
|           crtc->rect.x = 0; | ||||
|           crtc->rect.y = 0; | ||||
|           crtc->rect.width = 0; | ||||
|           crtc->rect.height = 0; | ||||
|           crtc->current_mode = NULL; | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           MetaMonitorMode *mode; | ||||
|           MetaOutput *output; | ||||
|           int i, n_outputs; | ||||
|           int width, height; | ||||
| 
 | ||||
|           mode = crtc_info->mode; | ||||
| 
 | ||||
|           if (meta_monitor_transform_is_rotated (crtc_info->transform)) | ||||
|             { | ||||
|               width = mode->height; | ||||
|               height = mode->width; | ||||
|             } | ||||
|           else | ||||
|             { | ||||
|               width = mode->width; | ||||
|               height = mode->height; | ||||
|             } | ||||
| 
 | ||||
|           crtc->rect.x = crtc_info->x; | ||||
|           crtc->rect.y = crtc_info->y; | ||||
|           crtc->rect.width = width; | ||||
|           crtc->rect.height = height; | ||||
|           crtc->current_mode = mode; | ||||
|           crtc->transform = crtc_info->transform; | ||||
| 
 | ||||
|           screen_width = MAX (screen_width, crtc_info->x + width); | ||||
|           screen_height = MAX (screen_height, crtc_info->y + height); | ||||
| 
 | ||||
|           n_outputs = crtc_info->outputs->len; | ||||
|           for (i = 0; i < n_outputs; i++) | ||||
|             { | ||||
|               output = ((MetaOutput**)crtc_info->outputs->pdata)[i]; | ||||
| 
 | ||||
|               output->is_dirty = TRUE; | ||||
|               output->crtc = crtc; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   for (i = 0; i < n_outputs; i++) | ||||
|     { | ||||
|       MetaOutputInfo *output_info = outputs[i]; | ||||
|       MetaOutput *output = output_info->output; | ||||
| 
 | ||||
|       output->is_primary = output_info->is_primary; | ||||
|       output->is_presentation = output_info->is_presentation; | ||||
|     } | ||||
| 
 | ||||
|   /* Disable CRTCs not mentioned in the list */ | ||||
|   for (i = 0; i < manager->n_crtcs; i++) | ||||
|     { | ||||
|       MetaCRTC *crtc = &manager->crtcs[i]; | ||||
| 
 | ||||
|       crtc->logical_monitor = NULL; | ||||
| 
 | ||||
|       if (crtc->is_dirty) | ||||
|         { | ||||
|           crtc->is_dirty = FALSE; | ||||
|           continue; | ||||
|         } | ||||
| 
 | ||||
|       crtc->rect.x = 0; | ||||
|       crtc->rect.y = 0; | ||||
|       crtc->rect.width = 0; | ||||
|       crtc->rect.height = 0; | ||||
|       crtc->current_mode = NULL; | ||||
|     } | ||||
| 
 | ||||
|   /* Disable outputs not mentioned in the list */ | ||||
|   for (i = 0; i < manager->n_outputs; i++) | ||||
|     { | ||||
|       MetaOutput *output = &manager->outputs[i]; | ||||
| 
 | ||||
|       if (output->is_dirty) | ||||
|         { | ||||
|           output->is_dirty = FALSE; | ||||
|           continue; | ||||
|         } | ||||
| 
 | ||||
|       output->crtc = NULL; | ||||
|       output->is_primary = FALSE; | ||||
|     } | ||||
| 
 | ||||
|   manager->screen_width = screen_width; | ||||
|   manager->screen_height = screen_height; | ||||
| 
 | ||||
|   meta_monitor_manager_rebuild_derived (manager); | ||||
| } | ||||
| 
 | ||||
| static GBytes * | ||||
| read_edid_dummy (MetaMonitorManager *manager, | ||||
|                  MetaOutput         *output) | ||||
| { | ||||
|   return NULL; | ||||
| } | ||||
| 
 | ||||
| static char * | ||||
| get_edid_file_dummy (MetaMonitorManager *manager, | ||||
|                      MetaOutput         *output) | ||||
| { | ||||
|   return NULL; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| meta_monitor_manager_init (MetaMonitorManager *manager) | ||||
| { | ||||
| @@ -352,58 +167,6 @@ make_logical_config (MetaMonitorManager *manager) | ||||
|   manager->monitor_infos = (void*)g_array_free (monitor_infos, FALSE); | ||||
| } | ||||
| 
 | ||||
| static GType | ||||
| get_default_backend (void) | ||||
| { | ||||
| #if defined(CLUTTER_WINDOWING_EGL) | ||||
|   if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL)) | ||||
|     return META_TYPE_MONITOR_MANAGER_KMS; | ||||
| #endif | ||||
| 
 | ||||
| #if defined(CLUTTER_WINDOWING_X11) | ||||
|   if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11)) | ||||
|     { | ||||
|       /* If we're a Wayland compositor using the X11 backend,
 | ||||
|        * we're a nested configuration, so return the dummy | ||||
|        * monitor setup. */ | ||||
|       if (meta_is_wayland_compositor ()) | ||||
|         return META_TYPE_MONITOR_MANAGER; | ||||
|       else | ||||
|         return META_TYPE_MONITOR_MANAGER_XRANDR; | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
| #if defined(CLUTTER_WINDOWING_WAYLAND) | ||||
|   if (clutter_check_windowing_backend (CLUTTER_WINDOWING_WAYLAND)) | ||||
|     { | ||||
|       /* Use the dummy implementation on Wayland for now.
 | ||||
|        * In the future, we should support wl_fullscreen_output | ||||
|        * which will have CRTC management in the protocol. */ | ||||
|       return META_TYPE_MONITOR_MANAGER; | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|   g_assert_not_reached (); | ||||
| } | ||||
| 
 | ||||
| static MetaMonitorManager * | ||||
| meta_monitor_manager_new (void) | ||||
| { | ||||
|   const char *env; | ||||
|   GType type; | ||||
| 
 | ||||
|   env = g_getenv ("META_DEBUG_MULTIMONITOR"); | ||||
| 
 | ||||
|   if (env == NULL) | ||||
|     type = get_default_backend (); | ||||
|   else if (strcmp (env, "xrandr") == 0) | ||||
|     type = META_TYPE_MONITOR_MANAGER_XRANDR; | ||||
|   else | ||||
|     type = META_TYPE_MONITOR_MANAGER; | ||||
| 
 | ||||
|   return g_object_new (type, NULL); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| meta_monitor_manager_constructed (GObject *object) | ||||
| { | ||||
| @@ -573,6 +336,20 @@ meta_monitor_manager_get_property (GObject      *object, | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static GBytes * | ||||
| meta_monitor_manager_real_read_edid (MetaMonitorManager *manager, | ||||
|                                      MetaOutput         *output) | ||||
| { | ||||
|   return NULL; | ||||
| } | ||||
| 
 | ||||
| static char * | ||||
| meta_monitor_manager_real_get_edid_file (MetaMonitorManager *manager, | ||||
|                                          MetaOutput         *output) | ||||
| { | ||||
|   return NULL; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| meta_monitor_manager_class_init (MetaMonitorManagerClass *klass) | ||||
| { | ||||
| @@ -584,10 +361,8 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass) | ||||
|   object_class->dispose = meta_monitor_manager_dispose; | ||||
|   object_class->finalize = meta_monitor_manager_finalize; | ||||
| 
 | ||||
|   klass->read_current = read_current_dummy; | ||||
|   klass->apply_configuration = apply_config_dummy; | ||||
|   klass->get_edid_file = get_edid_file_dummy; | ||||
|   klass->read_edid = read_edid_dummy; | ||||
|   klass->get_edid_file = meta_monitor_manager_real_get_edid_file; | ||||
|   klass->read_edid = meta_monitor_manager_real_read_edid; | ||||
| 
 | ||||
|   signals[CONFIRM_DISPLAY_CHANGE] = | ||||
|     g_signal_new ("confirm-display-change", | ||||
| @@ -708,13 +483,13 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton, | ||||
| 
 | ||||
|       g_variant_builder_add (&crtc_builder, "(uxiiiiiuaua{sv})", | ||||
|                              i, /* ID */ | ||||
|                              crtc->crtc_id, | ||||
|                              (gint64)crtc->crtc_id, | ||||
|                              (int)crtc->rect.x, | ||||
|                              (int)crtc->rect.y, | ||||
|                              (int)crtc->rect.width, | ||||
|                              (int)crtc->rect.height, | ||||
|                              (int)(crtc->current_mode ? crtc->current_mode - manager->modes : -1), | ||||
|                              crtc->transform, | ||||
|                              (guint32)crtc->transform, | ||||
|                              &transforms, | ||||
|                              NULL /* properties */); | ||||
|     } | ||||
| @@ -785,7 +560,7 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton, | ||||
| 
 | ||||
|       g_variant_builder_add (&output_builder, "(uxiausauaua{sv})", | ||||
|                              i, /* ID */ | ||||
|                              output->output_id, | ||||
|                              (gint64)output->output_id, | ||||
|                              (int)(output->crtc ? output->crtc - manager->crtcs : -1), | ||||
|                              &crtcs, | ||||
|                              output->name, | ||||
| @@ -800,9 +575,9 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton, | ||||
| 
 | ||||
|       g_variant_builder_add (&mode_builder, "(uxuud)", | ||||
|                              i, /* ID */ | ||||
|                              mode->mode_id, | ||||
|                              mode->width, | ||||
|                              mode->height, | ||||
|                              (gint64)mode->mode_id, | ||||
|                              (guint32)mode->width, | ||||
|                              (guint32)mode->height, | ||||
|                              (double)mode->refresh_rate); | ||||
|     } | ||||
| 
 | ||||
| @@ -1077,7 +852,7 @@ meta_monitor_manager_handle_apply_configuration  (MetaDBusDisplayConfig *skeleto | ||||
|   /* If we were in progress of making a persistent change and we see a
 | ||||
|      new request, it's likely that the old one failed in some way, so | ||||
|      don't save it, but also don't queue for restoring it. | ||||
|   */  | ||||
|   */ | ||||
|   if (manager->persistent_timeout_id && persistent) | ||||
|     { | ||||
|       g_source_remove (manager->persistent_timeout_id); | ||||
| @@ -1103,6 +878,7 @@ meta_monitor_manager_handle_apply_configuration  (MetaDBusDisplayConfig *skeleto | ||||
|   if (persistent) | ||||
|     { | ||||
|       manager->persistent_timeout_id = g_timeout_add_seconds (20, save_config_timeout, manager); | ||||
|       g_source_set_name_by_id (manager->persistent_timeout_id, "[mutter] save_config_timeout"); | ||||
|       g_signal_emit (manager, signals[CONFIRM_DISPLAY_CHANGE], 0); | ||||
|     } | ||||
| 
 | ||||
| @@ -1350,20 +1126,12 @@ initialize_dbus_interface (MetaMonitorManager *manager) | ||||
|                                           g_object_unref); | ||||
| } | ||||
| 
 | ||||
| static MetaMonitorManager *global_monitor_manager; | ||||
| 
 | ||||
| void | ||||
| meta_monitor_manager_initialize (void) | ||||
| { | ||||
|   global_monitor_manager = meta_monitor_manager_new (); | ||||
| } | ||||
| 
 | ||||
| MetaMonitorManager * | ||||
| meta_monitor_manager_get (void) | ||||
| { | ||||
|   g_assert (global_monitor_manager != NULL); | ||||
|   MetaBackend *backend = meta_get_backend (); | ||||
| 
 | ||||
|   return global_monitor_manager; | ||||
|   return meta_backend_get_monitor_manager (backend); | ||||
| } | ||||
| 
 | ||||
| MetaMonitorInfo * | ||||
| @@ -1449,16 +1217,3 @@ meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager) | ||||
|   g_free (old_monitor_infos); | ||||
| } | ||||
| 
 | ||||
| gboolean | ||||
| meta_monitor_manager_handle_xevent (MetaMonitorManager *manager, | ||||
|                                     XEvent             *event) | ||||
| { | ||||
|   MetaMonitorManagerClass *klass; | ||||
| 
 | ||||
|   klass = META_MONITOR_MANAGER_GET_CLASS (manager); | ||||
|   if (klass->handle_xevent) | ||||
|     return klass->handle_xevent (manager, event); | ||||
|   else | ||||
|     return FALSE; | ||||
| } | ||||
| 
 | ||||
| @@ -12,12 +12,12 @@ | ||||
|  * at MetaScreen instead. | ||||
|  */ | ||||
| 
 | ||||
| /* 
 | ||||
| /*
 | ||||
|  * Copyright (C) 2001 Havoc Pennington | ||||
|  * Copyright (C) 2003 Rob Adams | ||||
|  * Copyright (C) 2004-2006 Elijah Newren | ||||
|  * Copyright (C) 2013 Red Hat Inc. | ||||
|  *  | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
| @@ -27,7 +27,7 @@ | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  *  | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| @@ -43,9 +43,10 @@ | ||||
| #include "stack-tracker.h" | ||||
| #include "ui.h" | ||||
| #include <wayland-server.h> | ||||
| #include "meta-xrandr-shared.h" | ||||
| 
 | ||||
| #include "meta-dbus-xrandr.h" | ||||
| #include "meta-display-config-shared.h" | ||||
| #include "meta-dbus-display-config.h" | ||||
| #include "meta-cursor.h" | ||||
| 
 | ||||
| typedef struct _MetaMonitorManagerClass    MetaMonitorManagerClass; | ||||
| typedef struct _MetaMonitorManager         MetaMonitorManager; | ||||
| @@ -72,6 +73,7 @@ struct _MetaOutput | ||||
|   int width_mm; | ||||
|   int height_mm; | ||||
|   CoglSubpixelOrder subpixel_order; | ||||
|   int scale; | ||||
| 
 | ||||
|   MetaMonitorMode *preferred_mode; | ||||
|   MetaMonitorMode **modes; | ||||
| @@ -123,8 +125,7 @@ struct _MetaCRTC | ||||
|   /* Used when changing configuration */ | ||||
|   gboolean is_dirty; | ||||
| 
 | ||||
|   /* Updated by MetaCursorTracker */ | ||||
|   gboolean has_hw_cursor; | ||||
|   MetaCursorReference *cursor; | ||||
| }; | ||||
| 
 | ||||
| struct _MetaMonitorMode | ||||
| @@ -227,8 +228,6 @@ struct _MetaMonitorManager | ||||
|      CRTCs refer to stuff that can drive outputs | ||||
|      (like encoders, but less tied to the HW), | ||||
|      while monitor_infos refer to logical ones. | ||||
| 
 | ||||
|      See also the comment in monitor-private.h | ||||
|   */ | ||||
|   MetaOutput *outputs; | ||||
|   unsigned int n_outputs; | ||||
| @@ -287,14 +286,10 @@ struct _MetaMonitorManagerClass | ||||
|                           unsigned short     *, | ||||
|                           unsigned short     *, | ||||
|                           unsigned short     *); | ||||
| 
 | ||||
|   gboolean (*handle_xevent) (MetaMonitorManager *, | ||||
|                              XEvent             *); | ||||
| }; | ||||
| 
 | ||||
| GType meta_monitor_manager_get_type (void); | ||||
| 
 | ||||
| void                meta_monitor_manager_initialize (void); | ||||
| MetaMonitorManager *meta_monitor_manager_get  (void); | ||||
| 
 | ||||
| void                meta_monitor_manager_rebuild_derived   (MetaMonitorManager *manager); | ||||
| @@ -315,9 +310,6 @@ void                meta_monitor_manager_get_resources     (MetaMonitorManager | ||||
| 
 | ||||
| int                 meta_monitor_manager_get_primary_index (MetaMonitorManager *manager); | ||||
| 
 | ||||
| gboolean            meta_monitor_manager_handle_xevent     (MetaMonitorManager *manager, | ||||
|                                                             XEvent             *event); | ||||
| 
 | ||||
| void                meta_monitor_manager_get_screen_size   (MetaMonitorManager *manager, | ||||
|                                                             int                *width, | ||||
|                                                             int                *height); | ||||
| @@ -335,57 +327,6 @@ void                meta_monitor_manager_apply_configuration (MetaMonitorManager | ||||
| void                meta_monitor_manager_confirm_configuration (MetaMonitorManager *manager, | ||||
|                                                                 gboolean            ok); | ||||
| 
 | ||||
| #define META_TYPE_MONITOR_MANAGER_XRANDR            (meta_monitor_manager_xrandr_get_type ()) | ||||
| #define META_MONITOR_MANAGER_XRANDR(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER_XRANDR, MetaMonitorManagerXrandr)) | ||||
| #define META_MONITOR_MANAGER_XRANDR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_MONITOR_MANAGER_XRANDR, MetaMonitorManagerXrandrClass)) | ||||
| #define META_IS_MONITOR_MANAGER_XRANDR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_MONITOR_MANAGER_XRANDR)) | ||||
| #define META_IS_MONITOR_MANAGER_XRANDR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_MONITOR_MANAGER_XRANDR)) | ||||
| #define META_MONITOR_MANAGER_XRANDR_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_MONITOR_MANAGER_XRANDR, MetaMonitorManagerXrandrClass)) | ||||
| 
 | ||||
| typedef struct _MetaMonitorManagerXrandrClass    MetaMonitorManagerXrandrClass; | ||||
| typedef struct _MetaMonitorManagerXrandr         MetaMonitorManagerXrandr; | ||||
| 
 | ||||
| GType meta_monitor_manager_xrandr_get_type (void); | ||||
| 
 | ||||
| #define META_TYPE_MONITOR_MANAGER_KMS            (meta_monitor_manager_kms_get_type ()) | ||||
| #define META_MONITOR_MANAGER_KMS(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER_KMS, MetaMonitorManagerKms)) | ||||
| #define META_MONITOR_MANAGER_KMS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_MONITOR_MANAGER_KMS, MetaMonitorManagerKmsClass)) | ||||
| #define META_IS_MONITOR_MANAGER_KMS(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_MONITOR_MANAGER_KMS)) | ||||
| #define META_IS_MONITOR_MANAGER_KMS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_MONITOR_MANAGER_KMS)) | ||||
| #define META_MONITOR_MANAGER_KMS_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_MONITOR_MANAGER_KMS, MetaMonitorManagerKmsClass)) | ||||
| 
 | ||||
| typedef struct _MetaMonitorManagerKmsClass    MetaMonitorManagerKmsClass; | ||||
| typedef struct _MetaMonitorManagerKms         MetaMonitorManagerKms; | ||||
| 
 | ||||
| GType meta_monitor_manager_kms_get_type (void); | ||||
| 
 | ||||
| #define META_TYPE_MONITOR_CONFIG            (meta_monitor_config_get_type ()) | ||||
| #define META_MONITOR_CONFIG(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_CONFIG, MetaMonitorConfig)) | ||||
| #define META_MONITOR_CONFIG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_MONITOR_CONFIG, MetaMonitorConfigClass)) | ||||
| #define META_IS_MONITOR_CONFIG(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_MONITOR_CONFIG)) | ||||
| #define META_IS_MONITOR_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_MONITOR_CONFIG)) | ||||
| #define META_MONITOR_CONFIG_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_MONITOR_CONFIG, MetaMonitorConfigClass)) | ||||
| 
 | ||||
| GType meta_monitor_config_get_type (void) G_GNUC_CONST; | ||||
| 
 | ||||
| MetaMonitorConfig *meta_monitor_config_new (void); | ||||
| 
 | ||||
| gboolean           meta_monitor_config_match_current (MetaMonitorConfig  *config, | ||||
|                                                       MetaMonitorManager *manager); | ||||
| 
 | ||||
| gboolean           meta_monitor_config_apply_stored (MetaMonitorConfig  *config, | ||||
|                                                      MetaMonitorManager *manager); | ||||
| 
 | ||||
| void               meta_monitor_config_make_default (MetaMonitorConfig  *config, | ||||
|                                                      MetaMonitorManager *manager); | ||||
| 
 | ||||
| void               meta_monitor_config_update_current (MetaMonitorConfig  *config, | ||||
|                                                        MetaMonitorManager *manager); | ||||
| void               meta_monitor_config_make_persistent (MetaMonitorConfig *config); | ||||
| 
 | ||||
| void               meta_monitor_config_restore_previous (MetaMonitorConfig  *config, | ||||
|                                                          MetaMonitorManager *manager); | ||||
| 
 | ||||
| void               meta_crtc_info_free   (MetaCRTCInfo   *info); | ||||
| void               meta_output_info_free (MetaOutputInfo *info); | ||||
| 
 | ||||
							
								
								
									
										107
									
								
								src/backends/native/dbus-utils.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								src/backends/native/dbus-utils.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,107 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2014 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jasper St. Pierre <jstpierre@mecheye.net> | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "dbus-utils.h" | ||||
|  | ||||
| #include <glib.h> | ||||
|  | ||||
| /* Stolen from tp_escape_as_identifier, from tp-glib, | ||||
|  * which follows the same escaping convention as systemd. | ||||
|  */ | ||||
| static inline gboolean | ||||
| _esc_ident_bad (gchar c, gboolean is_first) | ||||
| { | ||||
|   return ((c < 'a' || c > 'z') && | ||||
|           (c < 'A' || c > 'Z') && | ||||
|           (c < '0' || c > '9' || is_first)); | ||||
| } | ||||
|  | ||||
| static gchar * | ||||
| escape_dbus_component (const gchar *name) | ||||
| { | ||||
|   gboolean bad = FALSE; | ||||
|   size_t len = 0; | ||||
|   GString *op; | ||||
|   const gchar *ptr, *first_ok; | ||||
|  | ||||
|   g_return_val_if_fail (name != NULL, NULL); | ||||
|  | ||||
|   /* fast path for empty name */ | ||||
|   if (name[0] == '\0') | ||||
|     return g_strdup ("_"); | ||||
|  | ||||
|   for (ptr = name; *ptr; ptr++) | ||||
|     { | ||||
|       if (_esc_ident_bad (*ptr, ptr == name)) | ||||
|         { | ||||
|           bad = TRUE; | ||||
|           len += 3; | ||||
|         } | ||||
|       else | ||||
|         len++; | ||||
|     } | ||||
|  | ||||
|   /* fast path if it's clean */ | ||||
|   if (!bad) | ||||
|     return g_strdup (name); | ||||
|  | ||||
|   /* If strictly less than ptr, first_ok is the first uncopied safe character. | ||||
|    */ | ||||
|   first_ok = name; | ||||
|   op = g_string_sized_new (len); | ||||
|   for (ptr = name; *ptr; ptr++) | ||||
|     { | ||||
|       if (_esc_ident_bad (*ptr, ptr == name)) | ||||
|         { | ||||
|           /* copy preceding safe characters if any */ | ||||
|           if (first_ok < ptr) | ||||
|             { | ||||
|               g_string_append_len (op, first_ok, ptr - first_ok); | ||||
|             } | ||||
|           /* escape the unsafe character */ | ||||
|           g_string_append_printf (op, "_%02x", (unsigned char)(*ptr)); | ||||
|           /* restart after it */ | ||||
|           first_ok = ptr + 1; | ||||
|         } | ||||
|     } | ||||
|   /* copy trailing safe characters if any */ | ||||
|   if (first_ok < ptr) | ||||
|     { | ||||
|       g_string_append_len (op, first_ok, ptr - first_ok); | ||||
|     } | ||||
|   return g_string_free (op, FALSE); | ||||
| } | ||||
|  | ||||
| char * | ||||
| get_escaped_dbus_path (const char *prefix, | ||||
|                        const char *component) | ||||
| { | ||||
|   char *escaped_component = escape_dbus_component (component); | ||||
|   char *path = g_strconcat (prefix, "/", escaped_component, NULL); | ||||
|  | ||||
|   g_free (escaped_component); | ||||
|   return path; | ||||
| } | ||||
							
								
								
									
										32
									
								
								src/backends/native/dbus-utils.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/backends/native/dbus-utils.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2014 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jasper St. Pierre <jstpierre@mecheye.net> | ||||
|  */ | ||||
|  | ||||
| #ifndef DBUS_UTILS_H | ||||
| #define DBUS_UTILS_H | ||||
|  | ||||
| char * | ||||
| get_escaped_dbus_path (const char *prefix, | ||||
|                        const char *component); | ||||
|  | ||||
| #endif /* DBUS_UTILS_H */ | ||||
							
								
								
									
										235
									
								
								src/backends/native/meta-backend-native.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										235
									
								
								src/backends/native/meta-backend-native.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,235 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2014 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jasper St. Pierre <jstpierre@mecheye.net> | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include <meta/main.h> | ||||
| #include <clutter/evdev/clutter-evdev.h> | ||||
| #include "meta-backend-native.h" | ||||
|  | ||||
| #include "meta-idle-monitor-native.h" | ||||
| #include "meta-monitor-manager-kms.h" | ||||
| #include "meta-cursor-renderer-native.h" | ||||
| #include "meta-launcher.h" | ||||
|  | ||||
| struct _MetaBackendNativePrivate | ||||
| { | ||||
|   MetaLauncher *launcher; | ||||
| }; | ||||
| typedef struct _MetaBackendNativePrivate MetaBackendNativePrivate; | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_PRIVATE (MetaBackendNative, meta_backend_native, META_TYPE_BACKEND); | ||||
|  | ||||
| /* | ||||
|  * The pointer constrain code is mostly a rip-off of the XRandR code from Xorg. | ||||
|  * (from xserver/randr/rrcrtc.c, RRConstrainCursorHarder) | ||||
|  * | ||||
|  * Copyright © 2006 Keith Packard | ||||
|  * Copyright 2010 Red Hat, Inc | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| static gboolean | ||||
| check_all_screen_monitors(MetaMonitorInfo *monitors, | ||||
| 			  unsigned         n_monitors, | ||||
| 			  float            x, | ||||
| 			  float            y) | ||||
| { | ||||
|   unsigned int i; | ||||
|  | ||||
|   for (i = 0; i < n_monitors; i++) | ||||
|     { | ||||
|       MetaMonitorInfo *monitor = &monitors[i]; | ||||
|       int left, right, top, bottom; | ||||
|  | ||||
|       left = monitor->rect.x; | ||||
|       right = left + monitor->rect.width; | ||||
|       top = monitor->rect.y; | ||||
|       bottom = left + monitor->rect.height; | ||||
|  | ||||
|       if ((x >= left) && (x < right) && (y >= top) && (y < bottom)) | ||||
| 	return TRUE; | ||||
|     } | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| constrain_all_screen_monitors (ClutterInputDevice *device, | ||||
| 			       MetaMonitorInfo    *monitors, | ||||
| 			       unsigned            n_monitors, | ||||
| 			       float              *x, | ||||
| 			       float              *y) | ||||
| { | ||||
|   ClutterPoint current; | ||||
|   unsigned int i; | ||||
|  | ||||
|   clutter_input_device_get_coords (device, NULL, ¤t); | ||||
|  | ||||
|   /* if we're trying to escape, clamp to the CRTC we're coming from */ | ||||
|   for (i = 0; i < n_monitors; i++) | ||||
|     { | ||||
|       MetaMonitorInfo *monitor = &monitors[i]; | ||||
|       int left, right, top, bottom; | ||||
|       float nx, ny; | ||||
|  | ||||
|       left = monitor->rect.x; | ||||
|       right = left + monitor->rect.width; | ||||
|       top = monitor->rect.y; | ||||
|       bottom = left + monitor->rect.height; | ||||
|  | ||||
|       nx = current.x; | ||||
|       ny = current.y; | ||||
|  | ||||
|       if ((nx >= left) && (nx < right) && (ny >= top) && (ny < bottom)) | ||||
| 	{ | ||||
| 	  if (*x < left) | ||||
| 	    *x = left; | ||||
| 	  if (*x >= right) | ||||
| 	    *x = right - 1; | ||||
| 	  if (*y < top) | ||||
| 	    *y = top; | ||||
| 	  if (*y >= bottom) | ||||
| 	    *y = bottom - 1; | ||||
|  | ||||
| 	  return; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| pointer_constrain_callback (ClutterInputDevice *device, | ||||
| 			    guint32             time, | ||||
| 			    float              *new_x, | ||||
| 			    float              *new_y, | ||||
| 			    gpointer            user_data) | ||||
| { | ||||
|   MetaMonitorManager *monitor_manager; | ||||
|   MetaMonitorInfo *monitors; | ||||
|   unsigned int n_monitors; | ||||
|   gboolean ret; | ||||
|  | ||||
|   monitor_manager = meta_monitor_manager_get (); | ||||
|   monitors = meta_monitor_manager_get_monitor_infos (monitor_manager, &n_monitors); | ||||
|  | ||||
|   /* if we're moving inside a monitor, we're fine */ | ||||
|   ret = check_all_screen_monitors(monitors, n_monitors, *new_x, *new_y); | ||||
|   if (ret == TRUE) | ||||
|     return; | ||||
|  | ||||
|   /* if we're trying to escape, clamp to the CRTC we're coming from */ | ||||
|   constrain_all_screen_monitors(device, monitors, n_monitors, new_x, new_y); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_backend_native_post_init (MetaBackend *backend) | ||||
| { | ||||
|   ClutterDeviceManager *manager = clutter_device_manager_get_default (); | ||||
|  | ||||
|   META_BACKEND_CLASS (meta_backend_native_parent_class)->post_init (backend); | ||||
|  | ||||
|   clutter_evdev_set_pointer_constrain_callback (manager, pointer_constrain_callback, | ||||
|                                                 NULL, NULL); | ||||
| } | ||||
|  | ||||
| static MetaIdleMonitor * | ||||
| meta_backend_native_create_idle_monitor (MetaBackend *backend, | ||||
|                                          int          device_id) | ||||
| { | ||||
|   return g_object_new (META_TYPE_IDLE_MONITOR_NATIVE, | ||||
|                        "device-id", device_id, | ||||
|                        NULL); | ||||
| } | ||||
|  | ||||
| static MetaMonitorManager * | ||||
| meta_backend_native_create_monitor_manager (MetaBackend *backend) | ||||
| { | ||||
|   return g_object_new (META_TYPE_MONITOR_MANAGER_KMS, NULL); | ||||
| } | ||||
|  | ||||
| static MetaCursorRenderer * | ||||
| meta_backend_native_create_cursor_renderer (MetaBackend *backend) | ||||
| { | ||||
|   return g_object_new (META_TYPE_CURSOR_RENDERER_NATIVE, NULL); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_backend_native_class_init (MetaBackendNativeClass *klass) | ||||
| { | ||||
|   MetaBackendClass *backend_class = META_BACKEND_CLASS (klass); | ||||
|  | ||||
|   backend_class->post_init = meta_backend_native_post_init; | ||||
|   backend_class->create_idle_monitor = meta_backend_native_create_idle_monitor; | ||||
|   backend_class->create_monitor_manager = meta_backend_native_create_monitor_manager; | ||||
|   backend_class->create_cursor_renderer = meta_backend_native_create_cursor_renderer; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_backend_native_init (MetaBackendNative *native) | ||||
| { | ||||
|   MetaBackendNativePrivate *priv = meta_backend_native_get_instance_private (native); | ||||
|  | ||||
|   /* We're a display server, so start talking to weston-launch. */ | ||||
|   priv->launcher = meta_launcher_new (); | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_activate_vt (int vt, GError **error) | ||||
| { | ||||
|   MetaBackend *backend = meta_get_backend (); | ||||
|   MetaBackendNative *native = META_BACKEND_NATIVE (backend); | ||||
|   MetaBackendNativePrivate *priv = meta_backend_native_get_instance_private (native); | ||||
|  | ||||
|   return meta_launcher_activate_vt (priv->launcher, vt, error); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_activate_session: | ||||
|  * | ||||
|  * Tells mutter to activate the session. When mutter is a | ||||
|  * Wayland compositor, this tells logind to switch over to | ||||
|  * the new session. | ||||
|  */ | ||||
| gboolean | ||||
| meta_activate_session (void) | ||||
| { | ||||
|   GError *error = NULL; | ||||
|   MetaBackend *backend = meta_get_backend (); | ||||
|  | ||||
|   /* Do nothing. */ | ||||
|   if (!META_IS_BACKEND_NATIVE (backend)) | ||||
|     return TRUE; | ||||
|  | ||||
|   MetaBackendNative *native = META_BACKEND_NATIVE (backend); | ||||
|   MetaBackendNativePrivate *priv = meta_backend_native_get_instance_private (native); | ||||
|  | ||||
|   if (!meta_launcher_activate_session (priv->launcher, &error)) | ||||
|     { | ||||
|       g_warning ("Could not activate session: %s\n", error->message); | ||||
|       g_error_free (error); | ||||
|       return FALSE; | ||||
|     } | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
							
								
								
									
										54
									
								
								src/backends/native/meta-backend-native.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								src/backends/native/meta-backend-native.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2014 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jasper St. Pierre <jstpierre@mecheye.net> | ||||
|  */ | ||||
|  | ||||
| #ifndef META_BACKEND_NATIVE_H | ||||
| #define META_BACKEND_NATIVE_H | ||||
|  | ||||
| #include "backends/meta-backend-private.h" | ||||
|  | ||||
| #define META_TYPE_BACKEND_NATIVE             (meta_backend_native_get_type ()) | ||||
| #define META_BACKEND_NATIVE(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BACKEND_NATIVE, MetaBackendNative)) | ||||
| #define META_BACKEND_NATIVE_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_BACKEND_NATIVE, MetaBackendNativeClass)) | ||||
| #define META_IS_BACKEND_NATIVE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_BACKEND_NATIVE)) | ||||
| #define META_IS_BACKEND_NATIVE_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_BACKEND_NATIVE)) | ||||
| #define META_BACKEND_NATIVE_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_BACKEND_NATIVE, MetaBackendNativeClass)) | ||||
|  | ||||
| typedef struct _MetaBackendNative        MetaBackendNative; | ||||
| typedef struct _MetaBackendNativeClass   MetaBackendNativeClass; | ||||
|  | ||||
| struct _MetaBackendNative | ||||
| { | ||||
|   MetaBackend parent; | ||||
| }; | ||||
|  | ||||
| struct _MetaBackendNativeClass | ||||
| { | ||||
|   MetaBackendClass parent_class; | ||||
| }; | ||||
|  | ||||
| GType meta_backend_native_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| gboolean meta_activate_vt (int vt, GError **error); | ||||
|  | ||||
| #endif /* META_BACKEND_NATIVE_H */ | ||||
							
								
								
									
										205
									
								
								src/backends/native/meta-cursor-renderer-native.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										205
									
								
								src/backends/native/meta-cursor-renderer-native.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,205 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2014 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jasper St. Pierre <jstpierre@mecheye.net> | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "meta-cursor-renderer-native.h" | ||||
|  | ||||
| #include <gbm.h> | ||||
|  | ||||
| #include "meta-cursor-private.h" | ||||
| #include "meta-monitor-manager.h" | ||||
|  | ||||
| struct _MetaCursorRendererNativePrivate | ||||
| { | ||||
|   gboolean has_hw_cursor; | ||||
|  | ||||
|   int drm_fd; | ||||
|   struct gbm_device *gbm; | ||||
| }; | ||||
| typedef struct _MetaCursorRendererNativePrivate MetaCursorRendererNativePrivate; | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRendererNative, meta_cursor_renderer_native, META_TYPE_CURSOR_RENDERER); | ||||
|  | ||||
| static void | ||||
| meta_cursor_renderer_native_finalize (GObject *object) | ||||
| { | ||||
|   MetaCursorRendererNative *renderer = META_CURSOR_RENDERER_NATIVE (object); | ||||
|   MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (renderer); | ||||
|  | ||||
|   if (priv->gbm) | ||||
|     gbm_device_destroy (priv->gbm); | ||||
|  | ||||
|   G_OBJECT_CLASS (meta_cursor_renderer_native_parent_class)->finalize (object); | ||||
| } | ||||
|  | ||||
| static void | ||||
| set_crtc_cursor (MetaCursorRendererNative *native, | ||||
|                  MetaCRTC                 *crtc, | ||||
|                  MetaCursorReference      *cursor, | ||||
|                  gboolean                  force) | ||||
| { | ||||
|   MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native); | ||||
|  | ||||
|   if (crtc->cursor == cursor && !force) | ||||
|     return; | ||||
|  | ||||
|   crtc->cursor = cursor; | ||||
|  | ||||
|   if (cursor) | ||||
|     { | ||||
|       struct gbm_bo *bo; | ||||
|       union gbm_bo_handle handle; | ||||
|       int width, height; | ||||
|       int hot_x, hot_y; | ||||
|  | ||||
|       bo = meta_cursor_reference_get_gbm_bo (cursor, &hot_x, &hot_y); | ||||
|  | ||||
|       handle = gbm_bo_get_handle (bo); | ||||
|       width = gbm_bo_get_width (bo); | ||||
|       height = gbm_bo_get_height (bo); | ||||
|  | ||||
|       drmModeSetCursor2 (priv->drm_fd, crtc->crtc_id, handle.u32, | ||||
|                          width, height, hot_x, hot_y); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       drmModeSetCursor2 (priv->drm_fd, crtc->crtc_id, 0, 0, 0, 0, 0); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| update_hw_cursor (MetaCursorRendererNative *native, | ||||
|                   gboolean                  force) | ||||
| { | ||||
|   MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native); | ||||
|   MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native); | ||||
|   const MetaRectangle *cursor_rect = meta_cursor_renderer_get_rect (renderer); | ||||
|   MetaCursorReference *cursor = meta_cursor_renderer_get_cursor (renderer); | ||||
|   MetaMonitorManager *monitors; | ||||
|   MetaCRTC *crtcs; | ||||
|   unsigned int i, n_crtcs; | ||||
|  | ||||
|   monitors = meta_monitor_manager_get (); | ||||
|   meta_monitor_manager_get_resources (monitors, NULL, NULL, &crtcs, &n_crtcs, NULL, NULL); | ||||
|  | ||||
|   for (i = 0; i < n_crtcs; i++) | ||||
|     { | ||||
|       gboolean crtc_should_have_cursor; | ||||
|       MetaCursorReference *crtc_cursor; | ||||
|       MetaRectangle *crtc_rect; | ||||
|  | ||||
|       crtc_rect = &crtcs[i].rect; | ||||
|  | ||||
|       crtc_should_have_cursor = (priv->has_hw_cursor && meta_rectangle_overlap (cursor_rect, crtc_rect)); | ||||
|       if (crtc_should_have_cursor) | ||||
|         crtc_cursor = cursor; | ||||
|       else | ||||
|         crtc_cursor = NULL; | ||||
|  | ||||
|       set_crtc_cursor (native, &crtcs[i], crtc_cursor, force); | ||||
|  | ||||
|       if (crtc_cursor) | ||||
|         { | ||||
|           drmModeMoveCursor (priv->drm_fd, crtcs[i].crtc_id, | ||||
|                              cursor_rect->x - crtc_rect->x, | ||||
|                              cursor_rect->y - crtc_rect->y); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| should_have_hw_cursor (MetaCursorRenderer *renderer) | ||||
| { | ||||
|   MetaCursorReference *cursor = meta_cursor_renderer_get_cursor (renderer); | ||||
|  | ||||
|   if (cursor) | ||||
|     return (meta_cursor_reference_get_gbm_bo (cursor, NULL, NULL) != NULL); | ||||
|   else | ||||
|     return FALSE; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer) | ||||
| { | ||||
|   MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer); | ||||
|   MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native); | ||||
|  | ||||
|   priv->has_hw_cursor = should_have_hw_cursor (renderer); | ||||
|   update_hw_cursor (native, FALSE); | ||||
|   return priv->has_hw_cursor; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_cursor_renderer_native_class_init (MetaCursorRendererNativeClass *klass) | ||||
| { | ||||
|   MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_CLASS (klass); | ||||
|   GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   object_class->finalize = meta_cursor_renderer_native_finalize; | ||||
|   renderer_class->update_cursor = meta_cursor_renderer_native_update_cursor; | ||||
| } | ||||
|  | ||||
| static void | ||||
| on_monitors_changed (MetaMonitorManager       *monitors, | ||||
|                      MetaCursorRendererNative *native) | ||||
| { | ||||
|   /* Our tracking is all messed up, so force an update. */ | ||||
|   update_hw_cursor (native, TRUE); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_cursor_renderer_native_init (MetaCursorRendererNative *native) | ||||
| { | ||||
|   MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native); | ||||
|   CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); | ||||
|   MetaMonitorManager *monitors; | ||||
|  | ||||
|   monitors = meta_monitor_manager_get (); | ||||
|   g_signal_connect_object (monitors, "monitors-changed", | ||||
|                            G_CALLBACK (on_monitors_changed), native, 0); | ||||
|  | ||||
| #if defined(CLUTTER_WINDOWING_EGL) | ||||
|   if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL)) | ||||
|     { | ||||
|       CoglRenderer *cogl_renderer = cogl_display_get_renderer (cogl_context_get_display (ctx)); | ||||
|       priv->drm_fd = cogl_kms_renderer_get_kms_fd (cogl_renderer); | ||||
|       priv->gbm = gbm_create_device (priv->drm_fd); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
|  | ||||
| struct gbm_device * | ||||
| meta_cursor_renderer_native_get_gbm_device (MetaCursorRendererNative *native) | ||||
| { | ||||
|   MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native); | ||||
|  | ||||
|   return priv->gbm; | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_cursor_renderer_native_force_update (MetaCursorRendererNative *native) | ||||
| { | ||||
|   update_hw_cursor (native, TRUE); | ||||
| } | ||||
							
								
								
									
										55
									
								
								src/backends/native/meta-cursor-renderer-native.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/backends/native/meta-cursor-renderer-native.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2014 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jasper St. Pierre <jstpierre@mecheye.net> | ||||
|  */ | ||||
|  | ||||
| #ifndef META_CURSOR_RENDERER_NATIVE_H | ||||
| #define META_CURSOR_RENDERER_NATIVE_H | ||||
|  | ||||
| #include "meta-cursor-renderer.h" | ||||
|  | ||||
| #define META_TYPE_CURSOR_RENDERER_NATIVE             (meta_cursor_renderer_native_get_type ()) | ||||
| #define META_CURSOR_RENDERER_NATIVE(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CURSOR_RENDERER_NATIVE, MetaCursorRendererNative)) | ||||
| #define META_CURSOR_RENDERER_NATIVE_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_CURSOR_RENDERER_NATIVE, MetaCursorRendererNativeClass)) | ||||
| #define META_IS_CURSOR_RENDERER_NATIVE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_CURSOR_RENDERER_NATIVE)) | ||||
| #define META_IS_CURSOR_RENDERER_NATIVE_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_CURSOR_RENDERER_NATIVE)) | ||||
| #define META_CURSOR_RENDERER_NATIVE_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_CURSOR_RENDERER_NATIVE, MetaCursorRendererNativeClass)) | ||||
|  | ||||
| typedef struct _MetaCursorRendererNative        MetaCursorRendererNative; | ||||
| typedef struct _MetaCursorRendererNativeClass   MetaCursorRendererNativeClass; | ||||
|  | ||||
| struct _MetaCursorRendererNative | ||||
| { | ||||
|   MetaCursorRenderer parent; | ||||
| }; | ||||
|  | ||||
| struct _MetaCursorRendererNativeClass | ||||
| { | ||||
|   MetaCursorRendererClass parent_class; | ||||
| }; | ||||
|  | ||||
| GType meta_cursor_renderer_native_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| struct gbm_device * meta_cursor_renderer_native_get_gbm_device (MetaCursorRendererNative *renderer); | ||||
| void meta_cursor_renderer_native_force_update (MetaCursorRendererNative *renderer); | ||||
|  | ||||
| #endif /* META_CURSOR_RENDERER_NATIVE_H */ | ||||
							
								
								
									
										219
									
								
								src/backends/native/meta-idle-monitor-native.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										219
									
								
								src/backends/native/meta-idle-monitor-native.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,219 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright 2013 Red Hat, Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and | ||||
|  *         from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "meta-idle-monitor-native.h" | ||||
| #include "meta-idle-monitor-private.h" | ||||
|  | ||||
| #include <meta/util.h> | ||||
| #include "display-private.h" | ||||
|  | ||||
| #include <string.h> | ||||
|  | ||||
| struct _MetaIdleMonitorNative | ||||
| { | ||||
|   MetaIdleMonitor parent; | ||||
|  | ||||
|   guint64 last_event_time; | ||||
| }; | ||||
|  | ||||
| struct _MetaIdleMonitorNativeClass | ||||
| { | ||||
|   MetaIdleMonitorClass parent_class; | ||||
| }; | ||||
|  | ||||
| typedef struct { | ||||
|   MetaIdleMonitorWatch base; | ||||
|  | ||||
|   GSource *timeout_source; | ||||
| } MetaIdleMonitorWatchNative; | ||||
|  | ||||
| G_DEFINE_TYPE (MetaIdleMonitorNative, meta_idle_monitor_native, META_TYPE_IDLE_MONITOR) | ||||
|  | ||||
| static gint64 | ||||
| meta_idle_monitor_native_get_idletime (MetaIdleMonitor *monitor) | ||||
| { | ||||
|   MetaIdleMonitorNative *monitor_native = META_IDLE_MONITOR_NATIVE (monitor); | ||||
|  | ||||
|   return (g_get_monotonic_time () - monitor_native->last_event_time) / 1000; | ||||
| } | ||||
|  | ||||
| static guint32 | ||||
| get_next_watch_serial (void) | ||||
| { | ||||
|   static guint32 serial = 0; | ||||
|   g_atomic_int_inc (&serial); | ||||
|   return serial; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| native_dispatch_timeout (GSource     *source, | ||||
|                          GSourceFunc  callback, | ||||
|                          gpointer     user_data) | ||||
| { | ||||
|   MetaIdleMonitorWatchNative *watch_native = user_data; | ||||
|   MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch_native; | ||||
|  | ||||
|   _meta_idle_monitor_watch_fire (watch); | ||||
|   g_source_set_ready_time (watch_native->timeout_source, -1); | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static GSourceFuncs native_source_funcs = { | ||||
|   NULL, /* prepare */ | ||||
|   NULL, /* check */ | ||||
|   native_dispatch_timeout, | ||||
|   NULL, /* finalize */ | ||||
| }; | ||||
|  | ||||
| static void | ||||
| free_watch (gpointer data) | ||||
| { | ||||
|   MetaIdleMonitorWatchNative *watch_native = data; | ||||
|   MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch_native; | ||||
|   MetaIdleMonitor *monitor = watch->monitor; | ||||
|  | ||||
|   g_object_ref (monitor); | ||||
|  | ||||
|   if (watch->idle_source_id) | ||||
|     { | ||||
|       g_source_remove (watch->idle_source_id); | ||||
|       watch->idle_source_id = 0; | ||||
|     } | ||||
|  | ||||
|   if (watch->notify != NULL) | ||||
|     watch->notify (watch->user_data); | ||||
|  | ||||
|   if (watch_native->timeout_source != NULL) | ||||
|     g_source_destroy (watch_native->timeout_source); | ||||
|  | ||||
|   g_object_unref (monitor); | ||||
|   g_slice_free (MetaIdleMonitorWatchNative, watch_native); | ||||
| } | ||||
|  | ||||
| static MetaIdleMonitorWatch * | ||||
| meta_idle_monitor_native_make_watch (MetaIdleMonitor           *monitor, | ||||
|                                      guint64                    timeout_msec, | ||||
|                                      MetaIdleMonitorWatchFunc   callback, | ||||
|                                      gpointer                   user_data, | ||||
|                                      GDestroyNotify             notify) | ||||
| { | ||||
|   MetaIdleMonitorWatchNative *watch_native; | ||||
|   MetaIdleMonitorWatch *watch; | ||||
|   MetaIdleMonitorNative *monitor_native = META_IDLE_MONITOR_NATIVE (monitor); | ||||
|  | ||||
|   watch_native = g_slice_new0 (MetaIdleMonitorWatchNative); | ||||
|   watch = (MetaIdleMonitorWatch *) watch_native; | ||||
|  | ||||
|   watch->monitor = monitor; | ||||
|   watch->id = get_next_watch_serial (); | ||||
|   watch->callback = callback; | ||||
|   watch->user_data = user_data; | ||||
|   watch->notify = notify; | ||||
|   watch->timeout_msec = timeout_msec; | ||||
|  | ||||
|   if (timeout_msec != 0) | ||||
|     { | ||||
|       GSource *source = g_source_new (&native_source_funcs, sizeof (GSource)); | ||||
|  | ||||
|       g_source_set_callback (source, NULL, watch, NULL); | ||||
|       g_source_set_ready_time (source, monitor_native->last_event_time + timeout_msec * 1000); | ||||
|       g_source_attach (source, NULL); | ||||
|       g_source_unref (source); | ||||
|  | ||||
|       watch_native->timeout_source = source; | ||||
|     } | ||||
|  | ||||
|   return watch; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_idle_monitor_native_class_init (MetaIdleMonitorNativeClass *klass) | ||||
| { | ||||
|   MetaIdleMonitorClass *idle_monitor_class = META_IDLE_MONITOR_CLASS (klass); | ||||
|  | ||||
|   idle_monitor_class->get_idletime = meta_idle_monitor_native_get_idletime; | ||||
|   idle_monitor_class->make_watch = meta_idle_monitor_native_make_watch; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_idle_monitor_native_init (MetaIdleMonitorNative *monitor_native) | ||||
| { | ||||
|   MetaIdleMonitor *monitor = META_IDLE_MONITOR (monitor_native); | ||||
|  | ||||
|   monitor->watches = g_hash_table_new_full (NULL, NULL, NULL, free_watch); | ||||
| } | ||||
|  | ||||
| typedef struct { | ||||
|   MetaIdleMonitorNative *monitor_native; | ||||
|   GList *fired_watches; | ||||
| } CheckNativeClosure; | ||||
|  | ||||
| static gboolean | ||||
| check_native_watch (gpointer key, | ||||
|                     gpointer value, | ||||
|                     gpointer user_data) | ||||
| { | ||||
|   MetaIdleMonitorWatchNative *watch_native = value; | ||||
|   MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch_native; | ||||
|   CheckNativeClosure *closure = user_data; | ||||
|   gboolean steal; | ||||
|  | ||||
|   if (watch->timeout_msec == 0) | ||||
|     { | ||||
|       closure->fired_watches = g_list_prepend (closure->fired_watches, watch); | ||||
|       steal = TRUE; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       g_source_set_ready_time (watch_native->timeout_source, | ||||
|                                closure->monitor_native->last_event_time + | ||||
|                                watch->timeout_msec * 1000); | ||||
|       steal = FALSE; | ||||
|     } | ||||
|  | ||||
|   return steal; | ||||
| } | ||||
|  | ||||
| static void | ||||
| fire_native_watch (gpointer watch, | ||||
|                    gpointer data) | ||||
| { | ||||
|   _meta_idle_monitor_watch_fire (watch); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_idle_monitor_native_reset_idletime (MetaIdleMonitor *monitor) | ||||
| { | ||||
|   MetaIdleMonitorNative *monitor_native = META_IDLE_MONITOR_NATIVE (monitor); | ||||
|   CheckNativeClosure closure; | ||||
|  | ||||
|   monitor_native->last_event_time = g_get_monotonic_time (); | ||||
|  | ||||
|   closure.monitor_native = monitor_native; | ||||
|   closure.fired_watches = NULL; | ||||
|   g_hash_table_foreach_steal (monitor->watches, check_native_watch, &closure); | ||||
|  | ||||
|   g_list_foreach (closure.fired_watches, fire_native_watch, NULL); | ||||
|   g_list_free (closure.fired_watches); | ||||
| } | ||||
							
								
								
									
										43
									
								
								src/backends/native/meta-idle-monitor-native.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/backends/native/meta-idle-monitor-native.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright 2013 Red Hat, Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and | ||||
|  *         from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c | ||||
|  */ | ||||
|  | ||||
| #ifndef META_IDLE_MONITOR_NATIVE_H | ||||
| #define META_IDLE_MONITOR_NATIVE_H | ||||
|  | ||||
| #include <glib-object.h> | ||||
| #include <meta/meta-idle-monitor.h> | ||||
|  | ||||
| #define META_TYPE_IDLE_MONITOR_NATIVE            (meta_idle_monitor_native_get_type ()) | ||||
| #define META_IDLE_MONITOR_NATIVE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_IDLE_MONITOR_NATIVE, MetaIdleMonitorNative)) | ||||
| #define META_IDLE_MONITOR_NATIVE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_IDLE_MONITOR_NATIVE, MetaIdleMonitorNativeClass)) | ||||
| #define META_IS_IDLE_MONITOR_NATIVE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_IDLE_MONITOR_NATIVE)) | ||||
| #define META_IS_IDLE_MONITOR_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_IDLE_MONITOR_NATIVE)) | ||||
| #define META_IDLE_MONITOR_NATIVE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_IDLE_MONITOR_NATIVE, MetaIdleMonitorNativeClass)) | ||||
|  | ||||
| typedef struct _MetaIdleMonitorNative        MetaIdleMonitorNative; | ||||
| typedef struct _MetaIdleMonitorNativeClass   MetaIdleMonitorNativeClass; | ||||
|  | ||||
| GType meta_idle_monitor_native_get_type (void); | ||||
|  | ||||
| void meta_idle_monitor_native_reset_idletime (MetaIdleMonitor *monitor); | ||||
|  | ||||
| #endif /* META_IDLE_MONITOR_NATIVE_H */ | ||||
							
								
								
									
										368
									
								
								src/backends/native/meta-launcher.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										368
									
								
								src/backends/native/meta-launcher.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,368 @@ | ||||
| /* | ||||
|  * Copyright (C) 2013 Red Hat, Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "meta-launcher.h" | ||||
|  | ||||
| #include <gio/gunixfdlist.h> | ||||
|  | ||||
| #include <clutter/clutter.h> | ||||
| #include <clutter/egl/clutter-egl.h> | ||||
| #include <clutter/evdev/clutter-evdev.h> | ||||
|  | ||||
| #include <sys/types.h> | ||||
| #include <sys/stat.h> | ||||
| #include <malloc.h> | ||||
| #include <fcntl.h> | ||||
| #include <errno.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
|  | ||||
| #include <systemd/sd-login.h> | ||||
|  | ||||
| #include "dbus-utils.h" | ||||
| #include "meta-dbus-login1.h" | ||||
|  | ||||
| #include "wayland/meta-wayland-private.h" | ||||
| #include "backends/meta-backend.h" | ||||
| #include "meta-cursor-renderer-native.h" | ||||
|  | ||||
| struct _MetaLauncher | ||||
| { | ||||
|   Login1Session *session_proxy; | ||||
|   Login1Seat *seat_proxy; | ||||
|  | ||||
|   gboolean session_active; | ||||
| }; | ||||
|  | ||||
| static Login1Session * | ||||
| get_session_proxy (GCancellable *cancellable) | ||||
| { | ||||
|   char *proxy_path; | ||||
|   char *session_id; | ||||
|   Login1Session *session_proxy; | ||||
|  | ||||
|   if (sd_pid_get_session (getpid (), &session_id) < 0) | ||||
|     return NULL; | ||||
|  | ||||
|   proxy_path = get_escaped_dbus_path ("/org/freedesktop/login1/session", session_id); | ||||
|  | ||||
|   session_proxy = login1_session_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, | ||||
|                                                          G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, | ||||
|                                                          "org.freedesktop.login1", | ||||
|                                                          proxy_path, | ||||
|                                                          cancellable, NULL); | ||||
|   free (proxy_path); | ||||
|  | ||||
|   return session_proxy; | ||||
| } | ||||
|  | ||||
| static Login1Seat * | ||||
| get_seat_proxy (GCancellable *cancellable) | ||||
| { | ||||
|   return login1_seat_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, | ||||
|                                              G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, | ||||
|                                              "org.freedesktop.login1", | ||||
|                                              "/org/freedesktop/login1/seat/self", | ||||
|                                              cancellable, NULL); | ||||
| } | ||||
|  | ||||
| static void | ||||
| session_unpause (void) | ||||
| { | ||||
|   ClutterBackend *backend; | ||||
|   CoglContext *cogl_context; | ||||
|   CoglDisplay *cogl_display; | ||||
|  | ||||
|   backend = clutter_get_default_backend (); | ||||
|   cogl_context = clutter_backend_get_cogl_context (backend); | ||||
|   cogl_display = cogl_context_get_display (cogl_context); | ||||
|   cogl_kms_display_queue_modes_reset (cogl_display); | ||||
|  | ||||
|   clutter_evdev_reclaim_devices (); | ||||
|   clutter_egl_thaw_master_clock (); | ||||
|  | ||||
|   { | ||||
|     MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); | ||||
|     MetaBackend *backend = meta_get_backend (); | ||||
|     MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (backend); | ||||
|  | ||||
|     /* When we mode-switch back, we need to immediately queue a redraw | ||||
|      * in case nothing else queued one for us, and force the cursor to | ||||
|      * update. */ | ||||
|  | ||||
|     clutter_actor_queue_redraw (compositor->stage); | ||||
|     meta_cursor_renderer_native_force_update (META_CURSOR_RENDERER_NATIVE (renderer)); | ||||
|   } | ||||
| } | ||||
|  | ||||
| static void | ||||
| session_pause (void) | ||||
| { | ||||
|   clutter_evdev_release_devices (); | ||||
|   clutter_egl_freeze_master_clock (); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| take_device (Login1Session *session_proxy, | ||||
|              int            dev_major, | ||||
|              int            dev_minor, | ||||
|              int           *out_fd, | ||||
|              GCancellable  *cancellable, | ||||
|              GError       **error) | ||||
| { | ||||
|   gboolean ret = FALSE; | ||||
|   GVariant *fd_variant = NULL; | ||||
|   int fd = -1; | ||||
|   GUnixFDList *fd_list; | ||||
|  | ||||
|   if (!login1_session_call_take_device_sync (session_proxy, | ||||
|                                              dev_major, | ||||
|                                              dev_minor, | ||||
|                                              NULL, | ||||
|                                              &fd_variant, | ||||
|                                              NULL, /* paused */ | ||||
|                                              &fd_list, | ||||
|                                              cancellable, | ||||
|                                              error)) | ||||
|     goto out; | ||||
|  | ||||
|   fd = g_unix_fd_list_get (fd_list, g_variant_get_handle (fd_variant), error); | ||||
|   if (fd == -1) | ||||
|     goto out; | ||||
|  | ||||
|   *out_fd = fd; | ||||
|   ret = TRUE; | ||||
|  | ||||
|  out: | ||||
|   if (fd_variant) | ||||
|     g_variant_unref (fd_variant); | ||||
|   if (fd_list) | ||||
|     g_object_unref (fd_list); | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| get_device_info_from_path (const char *path, | ||||
|                            int        *out_major, | ||||
|                            int        *out_minor) | ||||
| { | ||||
|   gboolean ret = FALSE; | ||||
|   int r; | ||||
|   struct stat st; | ||||
|  | ||||
|   r = stat (path, &st); | ||||
|   if (r < 0) | ||||
|     goto out; | ||||
|   if (!S_ISCHR (st.st_mode)) | ||||
|     goto out; | ||||
|  | ||||
|   *out_major = major (st.st_rdev); | ||||
|   *out_minor = minor (st.st_rdev); | ||||
|   ret = TRUE; | ||||
|  | ||||
|  out: | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| get_device_info_from_fd (int  fd, | ||||
|                          int *out_major, | ||||
|                          int *out_minor) | ||||
| { | ||||
|   gboolean ret = FALSE; | ||||
|   int r; | ||||
|   struct stat st; | ||||
|  | ||||
|   r = fstat (fd, &st); | ||||
|   if (r < 0) | ||||
|     goto out; | ||||
|   if (!S_ISCHR (st.st_mode)) | ||||
|     goto out; | ||||
|  | ||||
|   *out_major = major (st.st_rdev); | ||||
|   *out_minor = minor (st.st_rdev); | ||||
|   ret = TRUE; | ||||
|  | ||||
|  out: | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| static int | ||||
| on_evdev_device_open (const char  *path, | ||||
|                       int          flags, | ||||
|                       gpointer     user_data, | ||||
|                       GError     **error) | ||||
| { | ||||
|   MetaLauncher *self = user_data; | ||||
|   int fd; | ||||
|   int major, minor; | ||||
|  | ||||
|   if (!get_device_info_from_path (path, &major, &minor)) | ||||
|     { | ||||
|       g_set_error (error, | ||||
|                    G_IO_ERROR, | ||||
|                    G_IO_ERROR_NOT_FOUND, | ||||
|                    "Could not get device info for path %s: %m", path); | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
|   if (!take_device (self->session_proxy, major, minor, &fd, NULL, error)) | ||||
|     return -1; | ||||
|  | ||||
|   return fd; | ||||
| } | ||||
|  | ||||
| static void | ||||
| on_evdev_device_close (int      fd, | ||||
|                        gpointer user_data) | ||||
| { | ||||
|   MetaLauncher *self = user_data; | ||||
|   int major, minor; | ||||
|   GError *error = NULL; | ||||
|  | ||||
|   if (!get_device_info_from_fd (fd, &major, &minor)) | ||||
|     { | ||||
|       g_warning ("Could not get device info for fd %d: %m", fd); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   if (!login1_session_call_release_device_sync (self->session_proxy, | ||||
|                                                 major, minor, | ||||
|                                                 NULL, &error)) | ||||
|     { | ||||
|       g_warning ("Could not release device %d,%d: %s", major, minor, error->message); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| sync_active (MetaLauncher *self) | ||||
| { | ||||
|   gboolean active = login1_session_get_active (LOGIN1_SESSION (self->session_proxy)); | ||||
|  | ||||
|   if (active == self->session_active) | ||||
|     return; | ||||
|  | ||||
|   self->session_active = active; | ||||
|  | ||||
|   if (active) | ||||
|     session_unpause (); | ||||
|   else | ||||
|     session_pause (); | ||||
| } | ||||
|  | ||||
| static void | ||||
| on_active_changed (Login1Session *session, | ||||
|                    GParamSpec    *pspec, | ||||
|                    gpointer       user_data) | ||||
| { | ||||
|   MetaLauncher *self = user_data; | ||||
|   sync_active (self); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| get_kms_fd (Login1Session *session_proxy, | ||||
|             int *fd_out) | ||||
| { | ||||
|   int major, minor; | ||||
|   int fd; | ||||
|   GError *error = NULL; | ||||
|  | ||||
|   /* XXX -- use udev to find the DRM master device */ | ||||
|   if (!get_device_info_from_path ("/dev/dri/card0", &major, &minor)) | ||||
|     { | ||||
|       g_warning ("Could not stat /dev/dri/card0: %m"); | ||||
|       return FALSE; | ||||
|     } | ||||
|  | ||||
|   if (!take_device (session_proxy, major, minor, &fd, NULL, &error)) | ||||
|     { | ||||
|       g_warning ("Could not open DRM device: %s\n", error->message); | ||||
|       g_error_free (error); | ||||
|       return FALSE; | ||||
|     } | ||||
|  | ||||
|   *fd_out = fd; | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| MetaLauncher * | ||||
| meta_launcher_new (void) | ||||
| { | ||||
|   MetaLauncher *self; | ||||
|   Login1Session *session_proxy; | ||||
|   GError *error = NULL; | ||||
|   int kms_fd; | ||||
|  | ||||
|   session_proxy = get_session_proxy (NULL); | ||||
|   if (!login1_session_call_take_control_sync (session_proxy, FALSE, NULL, &error)) | ||||
|     { | ||||
|       g_warning ("Could not take control: %s", error->message); | ||||
|       g_error_free (error); | ||||
|       return NULL; | ||||
|     } | ||||
|  | ||||
|   if (!get_kms_fd (session_proxy, &kms_fd)) | ||||
|     return NULL; | ||||
|  | ||||
|   self = g_slice_new0 (MetaLauncher); | ||||
|   self->session_proxy = session_proxy; | ||||
|   self->seat_proxy = get_seat_proxy (NULL); | ||||
|  | ||||
|   self->session_active = TRUE; | ||||
|  | ||||
|   clutter_egl_set_kms_fd (kms_fd); | ||||
|   clutter_evdev_set_device_callbacks (on_evdev_device_open, | ||||
|                                       on_evdev_device_close, | ||||
|                                       self); | ||||
|  | ||||
|   g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self); | ||||
|  | ||||
|   return self; | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_launcher_free (MetaLauncher *self) | ||||
| { | ||||
|   g_object_unref (self->seat_proxy); | ||||
|   g_object_unref (self->session_proxy); | ||||
|   g_slice_free (MetaLauncher, self); | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_launcher_activate_session (MetaLauncher  *launcher, | ||||
|                                 GError       **error) | ||||
| { | ||||
|   if (!login1_session_call_activate_sync (launcher->session_proxy, NULL, error)) | ||||
|     return FALSE; | ||||
|  | ||||
|   sync_active (launcher); | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| meta_launcher_activate_vt (MetaLauncher  *launcher, | ||||
|                            signed char    vt, | ||||
|                            GError       **error) | ||||
| { | ||||
|   return login1_seat_call_switch_to_sync (launcher->seat_proxy, vt, NULL, error); | ||||
| } | ||||
| @@ -17,30 +17,21 @@ | ||||
|  * 02111-1307, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef META_WESTON_LAUNCH_H | ||||
| #define META_WESTON_LAUNCH_H | ||||
| #ifndef META_LAUNCHER_H | ||||
| #define META_LAUNCHER_H | ||||
| 
 | ||||
| #include <glib-object.h> | ||||
| #include "weston-launch.h" | ||||
| 
 | ||||
| typedef struct _MetaLauncher MetaLauncher; | ||||
| 
 | ||||
| MetaLauncher     *meta_launcher_new                     (void); | ||||
| void              meta_launcher_free                    (MetaLauncher  *self); | ||||
| 
 | ||||
| gboolean          meta_launcher_activate_session        (MetaLauncher  *self, | ||||
| 							 GError       **error); | ||||
| 
 | ||||
| gboolean          meta_launcher_activate_vt             (MetaLauncher  *self, | ||||
| 							 int            number, | ||||
| 							 signed char    vt, | ||||
| 							 GError       **error); | ||||
| 
 | ||||
| gboolean          meta_launcher_set_drm_fd              (MetaLauncher  *self, | ||||
| 							 int            drm_fd, | ||||
| 							 GError       **error); | ||||
| gboolean          meta_launcher_set_master              (MetaLauncher  *self, | ||||
| 							 gboolean       master, | ||||
| 							 GError       **error); | ||||
| int               meta_launcher_open_input_device       (MetaLauncher  *self, | ||||
| 							 const char    *name, | ||||
| 							 int            flags, | ||||
| 							 GError       **error); | ||||
| 
 | ||||
| #endif | ||||
| #endif /* META_LAUNCHER_H */ | ||||
| @@ -1,8 +1,8 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
| 
 | ||||
| /* 
 | ||||
| /*
 | ||||
|  * Copyright (C) 2013 Red Hat Inc. | ||||
|  *  | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
| @@ -12,7 +12,7 @@ | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  *  | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
| @@ -23,6 +23,8 @@ | ||||
| 
 | ||||
| #include "config.h" | ||||
| 
 | ||||
| #include "meta-monitor-manager-kms.h" | ||||
| 
 | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| #include <clutter/clutter.h> | ||||
| @@ -36,7 +38,6 @@ | ||||
| 
 | ||||
| #include <meta/main.h> | ||||
| #include <meta/errors.h> | ||||
| #include "monitor-private.h" | ||||
| #include "edid.h" | ||||
| 
 | ||||
| #define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1) | ||||
							
								
								
									
										40
									
								
								src/backends/native/meta-monitor-manager-kms.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/backends/native/meta-monitor-manager-kms.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2001 Havoc Pennington | ||||
|  * Copyright (C) 2003 Rob Adams | ||||
|  * Copyright (C) 2004-2006 Elijah Newren | ||||
|  * Copyright (C) 2013 Red Hat Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| #ifndef META_MONITOR_MANAGER_KMS_H | ||||
| #define META_MONITOR_MANAGER_KMS_H | ||||
|  | ||||
| #include "meta-monitor-manager.h" | ||||
|  | ||||
| #define META_TYPE_MONITOR_MANAGER_KMS            (meta_monitor_manager_kms_get_type ()) | ||||
| #define META_MONITOR_MANAGER_KMS(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER_KMS, MetaMonitorManagerKms)) | ||||
| #define META_MONITOR_MANAGER_KMS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_MONITOR_MANAGER_KMS, MetaMonitorManagerKmsClass)) | ||||
| #define META_IS_MONITOR_MANAGER_KMS(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_MONITOR_MANAGER_KMS)) | ||||
| #define META_IS_MONITOR_MANAGER_KMS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_MONITOR_MANAGER_KMS)) | ||||
| #define META_MONITOR_MANAGER_KMS_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_MONITOR_MANAGER_KMS, MetaMonitorManagerKmsClass)) | ||||
|  | ||||
| typedef struct _MetaMonitorManagerKmsClass    MetaMonitorManagerKmsClass; | ||||
| typedef struct _MetaMonitorManagerKms         MetaMonitorManagerKms; | ||||
|  | ||||
| GType meta_monitor_manager_kms_get_type (void); | ||||
|  | ||||
| #endif /* META_MONITOR_MANAGER_KMS_H */ | ||||
							
								
								
									
										406
									
								
								src/backends/x11/meta-backend-x11.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										406
									
								
								src/backends/x11/meta-backend-x11.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,406 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2014 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jasper St. Pierre <jstpierre@mecheye.net> | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "meta-backend-x11.h" | ||||
|  | ||||
| #include <clutter/x11/clutter-x11.h> | ||||
|  | ||||
| #include <X11/extensions/sync.h> | ||||
|  | ||||
| #include "meta-idle-monitor-xsync.h" | ||||
| #include "meta-monitor-manager-xrandr.h" | ||||
| #include "backends/meta-monitor-manager-dummy.h" | ||||
| #include "meta-cursor-renderer-x11.h" | ||||
|  | ||||
| #include <meta/util.h> | ||||
| #include "display-private.h" | ||||
| #include "compositor/compositor-private.h" | ||||
|  | ||||
| struct _MetaBackendX11Private | ||||
| { | ||||
|   /* The host X11 display */ | ||||
|   Display *xdisplay; | ||||
|   GSource *source; | ||||
|  | ||||
|   int xsync_event_base; | ||||
|   int xsync_error_base; | ||||
|  | ||||
|   int xinput_opcode; | ||||
|   int xinput_event_base; | ||||
|   int xinput_error_base; | ||||
| }; | ||||
| typedef struct _MetaBackendX11Private MetaBackendX11Private; | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_PRIVATE (MetaBackendX11, meta_backend_x11, META_TYPE_BACKEND); | ||||
|  | ||||
| static void | ||||
| handle_alarm_notify (MetaBackend *backend, | ||||
|                      XEvent      *event) | ||||
| { | ||||
|   int i; | ||||
|  | ||||
|   for (i = 0; i <= backend->device_id_max; i++) | ||||
|     if (backend->device_monitors[i]) | ||||
|       meta_idle_monitor_xsync_handle_xevent (backend->device_monitors[i], (XSyncAlarmNotifyEvent*) event); | ||||
| } | ||||
|  | ||||
| static void | ||||
| translate_device_event (MetaBackendX11 *x11, | ||||
|                         XIDeviceEvent  *device_event) | ||||
| { | ||||
|   Window stage_window = meta_backend_x11_get_xwindow (x11); | ||||
|  | ||||
|   if (device_event->event != stage_window) | ||||
|     { | ||||
|       /* This codepath should only ever trigger as an X11 compositor, | ||||
|        * and never under nested, as under nested all backend events | ||||
|        * should be reported with respect to the stage window. */ | ||||
|       g_assert (!meta_is_wayland_compositor ()); | ||||
|  | ||||
|       device_event->event = stage_window; | ||||
|  | ||||
|       /* As an X11 compositor, the stage window is always at 0,0, so | ||||
|        * using root coordinates will give us correct stage coordinates | ||||
|        * as well... */ | ||||
|       device_event->event_x = device_event->root_x; | ||||
|       device_event->event_y = device_event->root_y; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /* Clutter makes the assumption that there is only one X window | ||||
|  * per stage, which is a valid assumption to make for a generic | ||||
|  * application toolkit. As such, it will ignore any events sent | ||||
|  * to the a stage that isn't its X window. | ||||
|  * | ||||
|  * When running as an X window manager, we need to respond to | ||||
|  * events from lots of windows. Trick Clutter into translating | ||||
|  * these events by pretending we got an event on the stage window. | ||||
|  */ | ||||
| static void | ||||
| maybe_spoof_event_as_stage_event (MetaBackendX11 *x11, | ||||
|                                   XEvent         *event) | ||||
| { | ||||
|   MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); | ||||
|  | ||||
|   if (event->type == GenericEvent && | ||||
|       event->xcookie.extension == priv->xinput_opcode) | ||||
|     { | ||||
|       XIEvent *input_event = (XIEvent *) event->xcookie.data; | ||||
|  | ||||
|       switch (input_event->evtype) | ||||
|         { | ||||
|         case XI_Motion: | ||||
|         case XI_ButtonPress: | ||||
|         case XI_ButtonRelease: | ||||
|         case XI_KeyPress: | ||||
|         case XI_KeyRelease: | ||||
|           translate_device_event (x11, (XIDeviceEvent *) input_event); | ||||
|           break; | ||||
|         default: | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| handle_host_xevent (MetaBackend *backend, | ||||
|                     XEvent      *event) | ||||
| { | ||||
|   MetaBackendX11 *x11 = META_BACKEND_X11 (backend); | ||||
|   MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); | ||||
|   gboolean bypass_clutter = FALSE; | ||||
|  | ||||
|   XGetEventData (priv->xdisplay, &event->xcookie); | ||||
|  | ||||
|   if (event->type == (priv->xsync_event_base + XSyncAlarmNotify)) | ||||
|     handle_alarm_notify (backend, event); | ||||
|  | ||||
|   { | ||||
|     MetaMonitorManager *manager = meta_backend_get_monitor_manager (backend); | ||||
|     if (META_IS_MONITOR_MANAGER_XRANDR (manager) && | ||||
|         meta_monitor_manager_xrandr_handle_xevent (META_MONITOR_MANAGER_XRANDR (manager), event)) | ||||
|       { | ||||
|         bypass_clutter = TRUE; | ||||
|         goto out; | ||||
|       } | ||||
|   } | ||||
|  | ||||
|   maybe_spoof_event_as_stage_event (x11, event); | ||||
|  | ||||
|  out: | ||||
|   if (!bypass_clutter) | ||||
|     clutter_x11_handle_event (event); | ||||
|  | ||||
|   XFreeEventData (priv->xdisplay, &event->xcookie); | ||||
| } | ||||
|  | ||||
| typedef struct { | ||||
|   GSource base; | ||||
|   GPollFD event_poll_fd; | ||||
|   MetaBackend *backend; | ||||
| } XEventSource; | ||||
|  | ||||
| static gboolean | ||||
| x_event_source_prepare (GSource *source, | ||||
|                         int     *timeout) | ||||
| { | ||||
|   XEventSource *x_source = (XEventSource *) source; | ||||
|   MetaBackend *backend = x_source->backend; | ||||
|   MetaBackendX11 *x11 = META_BACKEND_X11 (backend); | ||||
|   MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); | ||||
|  | ||||
|   *timeout = -1; | ||||
|  | ||||
|   return XPending (priv->xdisplay); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| x_event_source_check (GSource *source) | ||||
| { | ||||
|   XEventSource *x_source = (XEventSource *) source; | ||||
|   MetaBackend *backend = x_source->backend; | ||||
|   MetaBackendX11 *x11 = META_BACKEND_X11 (backend); | ||||
|   MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); | ||||
|  | ||||
|   return XPending (priv->xdisplay); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| x_event_source_dispatch (GSource     *source, | ||||
|                          GSourceFunc  callback, | ||||
|                          gpointer     user_data) | ||||
| { | ||||
|   XEventSource *x_source = (XEventSource *) source; | ||||
|   MetaBackend *backend = x_source->backend; | ||||
|   MetaBackendX11 *x11 = META_BACKEND_X11 (backend); | ||||
|   MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); | ||||
|  | ||||
|   while (XPending (priv->xdisplay)) | ||||
|     { | ||||
|       XEvent event; | ||||
|  | ||||
|       XNextEvent (priv->xdisplay, &event); | ||||
|  | ||||
|       handle_host_xevent (backend, &event); | ||||
|     } | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static GSourceFuncs x_event_funcs = { | ||||
|   x_event_source_prepare, | ||||
|   x_event_source_check, | ||||
|   x_event_source_dispatch, | ||||
| }; | ||||
|  | ||||
| static GSource * | ||||
| x_event_source_new (MetaBackend *backend) | ||||
| { | ||||
|   MetaBackendX11 *x11 = META_BACKEND_X11 (backend); | ||||
|   MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); | ||||
|   GSource *source; | ||||
|   XEventSource *x_source; | ||||
|  | ||||
|   source = g_source_new (&x_event_funcs, sizeof (XEventSource)); | ||||
|   x_source = (XEventSource *) source; | ||||
|   x_source->backend = backend; | ||||
|   x_source->event_poll_fd.fd = ConnectionNumber (priv->xdisplay); | ||||
|   x_source->event_poll_fd.events = G_IO_IN; | ||||
|   g_source_add_poll (source, &x_source->event_poll_fd); | ||||
|  | ||||
|   g_source_attach (source, NULL); | ||||
|   return source; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_backend_x11_post_init (MetaBackend *backend) | ||||
| { | ||||
|   MetaBackendX11 *x11 = META_BACKEND_X11 (backend); | ||||
|   MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); | ||||
|   int major, minor; | ||||
|  | ||||
|   priv->xdisplay = clutter_x11_get_default_display (); | ||||
|  | ||||
|   priv->source = x_event_source_new (backend); | ||||
|  | ||||
|   if (!XSyncQueryExtension (priv->xdisplay, &priv->xsync_event_base, &priv->xsync_error_base) || | ||||
|       !XSyncInitialize (priv->xdisplay, &major, &minor)) | ||||
|     meta_fatal ("Could not initialize XSync"); | ||||
|  | ||||
|   { | ||||
|     int major = 2, minor = 3; | ||||
|     gboolean has_xi = FALSE; | ||||
|  | ||||
|     if (XQueryExtension (priv->xdisplay, | ||||
|                          "XInputExtension", | ||||
|                          &priv->xinput_opcode, | ||||
|                          &priv->xinput_error_base, | ||||
|                          &priv->xinput_event_base)) | ||||
|       { | ||||
|         if (XIQueryVersion (priv->xdisplay, &major, &minor) == Success) | ||||
|           { | ||||
|             int version = (major * 10) + minor; | ||||
|             if (version >= 22) | ||||
|               has_xi = TRUE; | ||||
|           } | ||||
|       } | ||||
|  | ||||
|     if (!has_xi) | ||||
|       meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n"); | ||||
|   } | ||||
|  | ||||
|   META_BACKEND_CLASS (meta_backend_x11_parent_class)->post_init (backend); | ||||
| } | ||||
|  | ||||
| static MetaIdleMonitor * | ||||
| meta_backend_x11_create_idle_monitor (MetaBackend *backend, | ||||
|                                       int          device_id) | ||||
| { | ||||
|   return g_object_new (META_TYPE_IDLE_MONITOR_XSYNC, | ||||
|                        "device-id", device_id, | ||||
|                        NULL); | ||||
| } | ||||
|  | ||||
| static MetaMonitorManager * | ||||
| meta_backend_x11_create_monitor_manager (MetaBackend *backend) | ||||
| { | ||||
|   /* If we're a Wayland compositor using the X11 backend, | ||||
|    * we're a nested configuration, so return the dummy | ||||
|    * monitor setup. */ | ||||
|   if (meta_is_wayland_compositor ()) | ||||
|     return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL); | ||||
|  | ||||
|   return g_object_new (META_TYPE_MONITOR_MANAGER_XRANDR, NULL); | ||||
| } | ||||
|  | ||||
| static MetaCursorRenderer * | ||||
| meta_backend_x11_create_cursor_renderer (MetaBackend *backend) | ||||
| { | ||||
|   return g_object_new (META_TYPE_CURSOR_RENDERER_X11, NULL); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_backend_x11_grab_device (MetaBackend *backend, | ||||
|                               int          device_id, | ||||
|                               uint32_t     timestamp) | ||||
| { | ||||
|   MetaBackendX11 *x11 = META_BACKEND_X11 (backend); | ||||
|   MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); | ||||
|   unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; | ||||
|   XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; | ||||
|   int ret; | ||||
|  | ||||
|   XISetMask (mask.mask, XI_ButtonPress); | ||||
|   XISetMask (mask.mask, XI_ButtonRelease); | ||||
|   XISetMask (mask.mask, XI_Enter); | ||||
|   XISetMask (mask.mask, XI_Leave); | ||||
|   XISetMask (mask.mask, XI_Motion); | ||||
|   XISetMask (mask.mask, XI_KeyPress); | ||||
|   XISetMask (mask.mask, XI_KeyRelease); | ||||
|  | ||||
|   ret = XIGrabDevice (priv->xdisplay, device_id, | ||||
|                       meta_backend_x11_get_xwindow (x11), | ||||
|                       timestamp, | ||||
|                       None, | ||||
|                       XIGrabModeAsync, XIGrabModeAsync, | ||||
|                       False, /* owner_events */ | ||||
|                       &mask); | ||||
|  | ||||
|   return (ret == Success); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| meta_backend_x11_ungrab_device (MetaBackend *backend, | ||||
|                                 int          device_id, | ||||
|                                 uint32_t     timestamp) | ||||
| { | ||||
|   MetaBackendX11 *x11 = META_BACKEND_X11 (backend); | ||||
|   MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); | ||||
|   int ret; | ||||
|  | ||||
|   ret = XIUngrabDevice (priv->xdisplay, device_id, timestamp); | ||||
|  | ||||
|   return (ret == Success); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_backend_x11_warp_pointer (MetaBackend *backend, | ||||
|                                int          x, | ||||
|                                int          y) | ||||
| { | ||||
|   MetaBackendX11 *x11 = META_BACKEND_X11 (backend); | ||||
|   MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); | ||||
|  | ||||
|   XIWarpPointer (priv->xdisplay, | ||||
|                  META_VIRTUAL_CORE_POINTER_ID, | ||||
|                  None, | ||||
|                  meta_backend_x11_get_xwindow (x11), | ||||
|                  0, 0, 0, 0, | ||||
|                  x, y); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_backend_x11_class_init (MetaBackendX11Class *klass) | ||||
| { | ||||
|   MetaBackendClass *backend_class = META_BACKEND_CLASS (klass); | ||||
|  | ||||
|   backend_class->post_init = meta_backend_x11_post_init; | ||||
|   backend_class->create_idle_monitor = meta_backend_x11_create_idle_monitor; | ||||
|   backend_class->create_monitor_manager = meta_backend_x11_create_monitor_manager; | ||||
|   backend_class->create_cursor_renderer = meta_backend_x11_create_cursor_renderer; | ||||
|  | ||||
|   backend_class->grab_device = meta_backend_x11_grab_device; | ||||
|   backend_class->ungrab_device = meta_backend_x11_ungrab_device; | ||||
|   backend_class->warp_pointer = meta_backend_x11_warp_pointer; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_backend_x11_init (MetaBackendX11 *x11) | ||||
| { | ||||
|   /* We do X11 event retrieval ourselves */ | ||||
|   clutter_x11_disable_event_retrieval (); | ||||
| } | ||||
|  | ||||
| Display * | ||||
| meta_backend_x11_get_xdisplay (MetaBackendX11 *x11) | ||||
| { | ||||
|   MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); | ||||
|  | ||||
|   return priv->xdisplay; | ||||
| } | ||||
|  | ||||
| Window | ||||
| meta_backend_x11_get_xwindow (MetaBackendX11 *x11) | ||||
| { | ||||
|   MetaDisplay *display = meta_get_display (); | ||||
|   MetaCompositor *compositor = display->compositor; | ||||
|  | ||||
|   if (compositor == NULL) | ||||
|     return None; | ||||
|  | ||||
|   ClutterStage *stage = CLUTTER_STAGE (compositor->stage); | ||||
|   return clutter_x11_get_stage_window (stage); | ||||
| } | ||||
							
								
								
									
										58
									
								
								src/backends/x11/meta-backend-x11.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/backends/x11/meta-backend-x11.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2014 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jasper St. Pierre <jstpierre@mecheye.net> | ||||
|  */ | ||||
|  | ||||
| #ifndef META_BACKEND_X11_H | ||||
| #define META_BACKEND_X11_H | ||||
|  | ||||
| #include "backends/meta-backend-private.h" | ||||
|  | ||||
| #include <X11/Xlib.h> | ||||
|  | ||||
| #define META_TYPE_BACKEND_X11             (meta_backend_x11_get_type ()) | ||||
| #define META_BACKEND_X11(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BACKEND_X11, MetaBackendX11)) | ||||
| #define META_BACKEND_X11_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_BACKEND_X11, MetaBackendX11Class)) | ||||
| #define META_IS_BACKEND_X11(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_BACKEND_X11)) | ||||
| #define META_IS_BACKEND_X11_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_BACKEND_X11)) | ||||
| #define META_BACKEND_X11_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_BACKEND_X11, MetaBackendX11Class)) | ||||
|  | ||||
| typedef struct _MetaBackendX11        MetaBackendX11; | ||||
| typedef struct _MetaBackendX11Class   MetaBackendX11Class; | ||||
|  | ||||
| struct _MetaBackendX11 | ||||
| { | ||||
|   MetaBackend parent; | ||||
| }; | ||||
|  | ||||
| struct _MetaBackendX11Class | ||||
| { | ||||
|   MetaBackendClass parent_class; | ||||
| }; | ||||
|  | ||||
| GType meta_backend_x11_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| Display * meta_backend_x11_get_xdisplay (MetaBackendX11 *backend); | ||||
|  | ||||
| Window meta_backend_x11_get_xwindow (MetaBackendX11 *backend); | ||||
|  | ||||
| #endif /* META_BACKEND_X11_H */ | ||||
							
								
								
									
										99
									
								
								src/backends/x11/meta-cursor-renderer-x11.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								src/backends/x11/meta-cursor-renderer-x11.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,99 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2014 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jasper St. Pierre <jstpierre@mecheye.net> | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "meta-cursor-renderer-x11.h" | ||||
|  | ||||
| #include "meta-backend-x11.h" | ||||
| #include "meta-stage.h" | ||||
|  | ||||
| struct _MetaCursorRendererX11Private | ||||
| { | ||||
|   gboolean server_cursor_visible; | ||||
| }; | ||||
| typedef struct _MetaCursorRendererX11Private MetaCursorRendererX11Private; | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRendererX11, meta_cursor_renderer_x11, META_TYPE_CURSOR_RENDERER); | ||||
|  | ||||
| static gboolean | ||||
| meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer) | ||||
| { | ||||
|   MetaCursorRendererX11 *x11 = META_CURSOR_RENDERER_X11 (renderer); | ||||
|   MetaCursorRendererX11Private *priv = meta_cursor_renderer_x11_get_instance_private (x11); | ||||
|  | ||||
|   MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ()); | ||||
|   Window xwindow = meta_backend_x11_get_xwindow (backend); | ||||
|  | ||||
|   if (xwindow == None) | ||||
|     return FALSE; | ||||
|  | ||||
|   Display *xdisplay = meta_backend_x11_get_xdisplay (backend); | ||||
|  | ||||
|   MetaCursorReference *cursor_ref = meta_cursor_renderer_get_cursor (renderer); | ||||
|   gboolean has_server_cursor = FALSE; | ||||
|  | ||||
|   if (cursor_ref) | ||||
|     { | ||||
|       MetaCursor cursor = meta_cursor_reference_get_meta_cursor (cursor_ref); | ||||
|       if (cursor != META_CURSOR_NONE) | ||||
|         { | ||||
|           Cursor xcursor = meta_cursor_create_x_cursor (xdisplay, cursor); | ||||
|           XDefineCursor (xdisplay, xwindow, xcursor); | ||||
|           XFlush (xdisplay); | ||||
|           XFreeCursor (xdisplay, xcursor); | ||||
|  | ||||
|           has_server_cursor = TRUE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   if (has_server_cursor != priv->server_cursor_visible) | ||||
|     { | ||||
|       if (has_server_cursor) | ||||
|         XFixesShowCursor (xdisplay, xwindow); | ||||
|       else | ||||
|         XFixesHideCursor (xdisplay, xwindow); | ||||
|  | ||||
|       priv->server_cursor_visible = has_server_cursor; | ||||
|     } | ||||
|  | ||||
|   return priv->server_cursor_visible; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_cursor_renderer_x11_class_init (MetaCursorRendererX11Class *klass) | ||||
| { | ||||
|   MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_CLASS (klass); | ||||
|  | ||||
|   renderer_class->update_cursor = meta_cursor_renderer_x11_update_cursor; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_cursor_renderer_x11_init (MetaCursorRendererX11 *x11) | ||||
| { | ||||
|   MetaCursorRendererX11Private *priv = meta_cursor_renderer_x11_get_instance_private (x11); | ||||
|  | ||||
|   /* XFixes has no way to retrieve the current cursor visibility. */ | ||||
|   priv->server_cursor_visible = TRUE; | ||||
| } | ||||
							
								
								
									
										52
									
								
								src/backends/x11/meta-cursor-renderer-x11.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/backends/x11/meta-cursor-renderer-x11.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (C) 2014 Red Hat | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||||
|  * 02111-1307, USA. | ||||
|  * | ||||
|  * Written by: | ||||
|  *     Jasper St. Pierre <jstpierre@mecheye.net> | ||||
|  */ | ||||
|  | ||||
| #ifndef META_CURSOR_RENDERER_X11_H | ||||
| #define META_CURSOR_RENDERER_X11_H | ||||
|  | ||||
| #include "meta-cursor-renderer.h" | ||||
|  | ||||
| #define META_TYPE_CURSOR_RENDERER_X11             (meta_cursor_renderer_x11_get_type ()) | ||||
| #define META_CURSOR_RENDERER_X11(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CURSOR_RENDERER_X11, MetaCursorRendererX11)) | ||||
| #define META_CURSOR_RENDERER_X11_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_CURSOR_RENDERER_X11, MetaCursorRendererX11Class)) | ||||
| #define META_IS_CURSOR_RENDERER_X11(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_CURSOR_RENDERER_X11)) | ||||
| #define META_IS_CURSOR_RENDERER_X11_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_CURSOR_RENDERER_X11)) | ||||
| #define META_CURSOR_RENDERER_X11_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_CURSOR_RENDERER_X11, MetaCursorRendererX11Class)) | ||||
|  | ||||
| typedef struct _MetaCursorRendererX11        MetaCursorRendererX11; | ||||
| typedef struct _MetaCursorRendererX11Class   MetaCursorRendererX11Class; | ||||
|  | ||||
| struct _MetaCursorRendererX11 | ||||
| { | ||||
|   MetaCursorRenderer parent; | ||||
| }; | ||||
|  | ||||
| struct _MetaCursorRendererX11Class | ||||
| { | ||||
|   MetaCursorRendererClass parent_class; | ||||
| }; | ||||
|  | ||||
| GType meta_cursor_renderer_x11_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| #endif /* META_CURSOR_RENDERER_X11_H */ | ||||
							
								
								
									
										367
									
								
								src/backends/x11/meta-idle-monitor-xsync.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										367
									
								
								src/backends/x11/meta-idle-monitor-xsync.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,367 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright 2013 Red Hat, Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and | ||||
|  *         from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "meta-idle-monitor-xsync.h" | ||||
| #include "meta-idle-monitor-private.h" | ||||
|  | ||||
| #include "meta-backend-x11.h" | ||||
|  | ||||
| #include <string.h> | ||||
|  | ||||
| struct _MetaIdleMonitorXSync | ||||
| { | ||||
|   MetaIdleMonitor parent; | ||||
|  | ||||
|   GHashTable  *alarms; | ||||
|   Display     *display; | ||||
|   XSyncCounter counter; | ||||
|   XSyncAlarm   user_active_alarm; | ||||
| }; | ||||
|  | ||||
| struct _MetaIdleMonitorXSyncClass | ||||
| { | ||||
|   MetaIdleMonitorClass parent_class; | ||||
| }; | ||||
|  | ||||
| typedef struct { | ||||
|   MetaIdleMonitorWatch base; | ||||
|  | ||||
|   XSyncAlarm xalarm; | ||||
| } MetaIdleMonitorWatchXSync; | ||||
|  | ||||
| G_DEFINE_TYPE (MetaIdleMonitorXSync, meta_idle_monitor_xsync, META_TYPE_IDLE_MONITOR) | ||||
|  | ||||
| static gint64 | ||||
| _xsyncvalue_to_int64 (XSyncValue value) | ||||
| { | ||||
|   return ((guint64) XSyncValueHigh32 (value)) << 32 | ||||
|     | (guint64) XSyncValueLow32 (value); | ||||
| } | ||||
|  | ||||
| #define GUINT64_TO_XSYNCVALUE(value, ret) XSyncIntsToValue (ret, (value) & 0xFFFFFFFF, ((guint64)(value)) >> 32) | ||||
|  | ||||
| static XSyncAlarm | ||||
| _xsync_alarm_set (MetaIdleMonitorXSync	*monitor_xsync, | ||||
| 		  XSyncTestType          test_type, | ||||
| 		  guint64                interval, | ||||
| 		  gboolean               want_events) | ||||
| { | ||||
|   XSyncAlarmAttributes attr; | ||||
|   XSyncValue	     delta; | ||||
|   guint		     flags; | ||||
|  | ||||
|   flags = XSyncCACounter | XSyncCAValueType | XSyncCATestType | | ||||
|     XSyncCAValue | XSyncCADelta | XSyncCAEvents; | ||||
|  | ||||
|   XSyncIntToValue (&delta, 0); | ||||
|   attr.trigger.counter = monitor_xsync->counter; | ||||
|   attr.trigger.value_type = XSyncAbsolute; | ||||
|   attr.delta = delta; | ||||
|   attr.events = want_events; | ||||
|  | ||||
|   GUINT64_TO_XSYNCVALUE (interval, &attr.trigger.wait_value); | ||||
|   attr.trigger.test_type = test_type; | ||||
|   return XSyncCreateAlarm (monitor_xsync->display, flags, &attr); | ||||
| } | ||||
|  | ||||
| static void | ||||
| ensure_alarm_rescheduled (Display    *dpy, | ||||
| 			  XSyncAlarm  alarm) | ||||
| { | ||||
|   XSyncAlarmAttributes attr; | ||||
|  | ||||
|   /* Some versions of Xorg have an issue where alarms aren't | ||||
|    * always rescheduled. Calling XSyncChangeAlarm, even | ||||
|    * without any attributes, will reschedule the alarm. */ | ||||
|   XSyncChangeAlarm (dpy, alarm, 0, &attr); | ||||
| } | ||||
|  | ||||
| static void | ||||
| set_alarm_enabled (Display    *dpy, | ||||
| 		   XSyncAlarm  alarm, | ||||
| 		   gboolean    enabled) | ||||
| { | ||||
|   XSyncAlarmAttributes attr; | ||||
|   attr.events = enabled; | ||||
|   XSyncChangeAlarm (dpy, alarm, XSyncCAEvents, &attr); | ||||
| } | ||||
|  | ||||
| static void | ||||
| check_x11_watch (gpointer data, | ||||
|                  gpointer user_data) | ||||
| { | ||||
|   MetaIdleMonitorWatchXSync *watch_xsync = data; | ||||
|   MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch_xsync; | ||||
|   XSyncAlarm alarm = (XSyncAlarm) user_data; | ||||
|  | ||||
|   if (watch_xsync->xalarm != alarm) | ||||
|     return; | ||||
|  | ||||
|   _meta_idle_monitor_watch_fire (watch); | ||||
| } | ||||
|  | ||||
| static char * | ||||
| counter_name_for_device (int device_id) | ||||
| { | ||||
|   if (device_id > 0) | ||||
|     return g_strdup_printf ("DEVICEIDLETIME %d", device_id); | ||||
|  | ||||
|   return g_strdup ("IDLETIME"); | ||||
| } | ||||
|  | ||||
| static XSyncCounter | ||||
| find_idletime_counter (MetaIdleMonitorXSync *monitor_xsync) | ||||
| { | ||||
|   MetaIdleMonitor *monitor = META_IDLE_MONITOR (monitor_xsync); | ||||
|   int		      i; | ||||
|   int		      ncounters; | ||||
|   XSyncSystemCounter *counters; | ||||
|   XSyncCounter        counter = None; | ||||
|   char               *counter_name; | ||||
|  | ||||
|   counter_name = counter_name_for_device (monitor->device_id); | ||||
|   counters = XSyncListSystemCounters (monitor_xsync->display, &ncounters); | ||||
|   for (i = 0; i < ncounters; i++) | ||||
|     { | ||||
|       if (counters[i].name != NULL && strcmp (counters[i].name, counter_name) == 0) | ||||
|         { | ||||
|           counter = counters[i].counter; | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
|   XSyncFreeSystemCounterList (counters); | ||||
|   g_free (counter_name); | ||||
|  | ||||
|   return counter; | ||||
| } | ||||
|  | ||||
| static void | ||||
| init_xsync (MetaIdleMonitorXSync *monitor_xsync) | ||||
| { | ||||
|   monitor_xsync->counter = find_idletime_counter (monitor_xsync); | ||||
|   /* IDLETIME counter not found? */ | ||||
|   if (monitor_xsync->counter == None) | ||||
|     { | ||||
|       g_warning ("IDLETIME counter not found\n"); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   monitor_xsync->user_active_alarm = _xsync_alarm_set (monitor_xsync, XSyncNegativeTransition, 1, FALSE); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_idle_monitor_xsync_dispose (GObject *object) | ||||
| { | ||||
|   MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (object); | ||||
|  | ||||
|   if (monitor_xsync->user_active_alarm != None) | ||||
|     { | ||||
|       XSyncDestroyAlarm (monitor_xsync->display, monitor_xsync->user_active_alarm); | ||||
|       monitor_xsync->user_active_alarm = None; | ||||
|     } | ||||
|  | ||||
|   g_clear_pointer (&monitor_xsync->alarms, g_hash_table_destroy); | ||||
|  | ||||
|   G_OBJECT_CLASS (meta_idle_monitor_xsync_parent_class)->dispose (object); | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_idle_monitor_xsync_constructed (GObject *object) | ||||
| { | ||||
|   MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (object); | ||||
|   MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ()); | ||||
|  | ||||
|   monitor_xsync->display = meta_backend_x11_get_xdisplay (backend); | ||||
|   init_xsync (monitor_xsync); | ||||
|  | ||||
|   G_OBJECT_CLASS (meta_idle_monitor_xsync_parent_class)->constructed (object); | ||||
| } | ||||
|  | ||||
| static gint64 | ||||
| meta_idle_monitor_xsync_get_idletime (MetaIdleMonitor *monitor) | ||||
| { | ||||
|   MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (monitor); | ||||
|   XSyncValue value; | ||||
|  | ||||
|   if (!XSyncQueryCounter (monitor_xsync->display, monitor_xsync->counter, &value)) | ||||
|     return -1; | ||||
|  | ||||
|   return _xsyncvalue_to_int64 (value); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| fire_watch_idle (gpointer data) | ||||
| { | ||||
|   MetaIdleMonitorWatch *watch = data; | ||||
|  | ||||
|   watch->idle_source_id = 0; | ||||
|   _meta_idle_monitor_watch_fire (watch); | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| static guint32 | ||||
| get_next_watch_serial (void) | ||||
| { | ||||
|   static guint32 serial = 0; | ||||
|   g_atomic_int_inc (&serial); | ||||
|   return serial; | ||||
| } | ||||
|  | ||||
| static void | ||||
| free_watch (gpointer data) | ||||
| { | ||||
|   MetaIdleMonitorWatchXSync *watch_xsync = data; | ||||
|   MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch_xsync; | ||||
|   MetaIdleMonitor *monitor = watch->monitor; | ||||
|   MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (monitor); | ||||
|  | ||||
|   g_object_ref (monitor); | ||||
|  | ||||
|   if (watch->idle_source_id) | ||||
|     { | ||||
|       g_source_remove (watch->idle_source_id); | ||||
|       watch->idle_source_id = 0; | ||||
|     } | ||||
|  | ||||
|   if (watch->notify != NULL) | ||||
|     watch->notify (watch->user_data); | ||||
|  | ||||
|   if (watch_xsync->xalarm != monitor_xsync->user_active_alarm && | ||||
|       watch_xsync->xalarm != None) | ||||
|     { | ||||
|       XSyncDestroyAlarm (monitor_xsync->display, watch_xsync->xalarm); | ||||
|       g_hash_table_remove (monitor_xsync->alarms, (gpointer) watch_xsync->xalarm); | ||||
|     } | ||||
|  | ||||
|   g_object_unref (monitor); | ||||
|   g_slice_free (MetaIdleMonitorWatchXSync, watch_xsync); | ||||
| } | ||||
|  | ||||
| static MetaIdleMonitorWatch * | ||||
| meta_idle_monitor_xsync_make_watch (MetaIdleMonitor           *monitor, | ||||
|                                     guint64                    timeout_msec, | ||||
|                                     MetaIdleMonitorWatchFunc   callback, | ||||
|                                     gpointer                   user_data, | ||||
|                                     GDestroyNotify             notify) | ||||
| { | ||||
|   MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (monitor); | ||||
|   MetaIdleMonitorWatchXSync *watch_xsync; | ||||
|   MetaIdleMonitorWatch *watch; | ||||
|  | ||||
|   watch_xsync = g_slice_new0 (MetaIdleMonitorWatchXSync); | ||||
|   watch = (MetaIdleMonitorWatch *) watch_xsync; | ||||
|  | ||||
|   watch->monitor = monitor; | ||||
|   watch->id = get_next_watch_serial (); | ||||
|   watch->callback = callback; | ||||
|   watch->user_data = user_data; | ||||
|   watch->notify = notify; | ||||
|   watch->timeout_msec = timeout_msec; | ||||
|  | ||||
|   if (monitor_xsync->user_active_alarm != None) | ||||
|     { | ||||
|       if (timeout_msec != 0) | ||||
|         { | ||||
|           watch_xsync->xalarm = _xsync_alarm_set (monitor_xsync, XSyncPositiveTransition, timeout_msec, TRUE); | ||||
|  | ||||
|           g_hash_table_add (monitor_xsync->alarms, (gpointer) watch_xsync->xalarm); | ||||
|  | ||||
|           if (meta_idle_monitor_get_idletime (monitor) > (gint64)timeout_msec) | ||||
|             { | ||||
|               watch->idle_source_id = g_idle_add (fire_watch_idle, watch); | ||||
|               g_source_set_name_by_id (watch->idle_source_id, "[mutter] fire_watch_idle"); | ||||
|             } | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           watch_xsync->xalarm = monitor_xsync->user_active_alarm; | ||||
|  | ||||
|           set_alarm_enabled (monitor_xsync->display, monitor_xsync->user_active_alarm, TRUE); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   return watch; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_idle_monitor_xsync_class_init (MetaIdleMonitorXSyncClass *klass) | ||||
| { | ||||
|   GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||||
|   MetaIdleMonitorClass *idle_monitor_class = META_IDLE_MONITOR_CLASS (klass); | ||||
|  | ||||
|   object_class->dispose = meta_idle_monitor_xsync_dispose; | ||||
|   object_class->constructed = meta_idle_monitor_xsync_constructed; | ||||
|  | ||||
|   idle_monitor_class->get_idletime = meta_idle_monitor_xsync_get_idletime; | ||||
|   idle_monitor_class->make_watch = meta_idle_monitor_xsync_make_watch; | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_idle_monitor_xsync_init (MetaIdleMonitorXSync *monitor_xsync) | ||||
| { | ||||
|   MetaIdleMonitor *monitor = META_IDLE_MONITOR (monitor_xsync); | ||||
|  | ||||
|   monitor->watches = g_hash_table_new_full (NULL, NULL, NULL, free_watch); | ||||
|   monitor_xsync->alarms = g_hash_table_new (NULL, NULL); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_idle_monitor_xsync_handle_xevent (MetaIdleMonitor       *monitor, | ||||
|                                        XSyncAlarmNotifyEvent *alarm_event) | ||||
| { | ||||
|   MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (monitor); | ||||
|   XSyncAlarm alarm; | ||||
|   GList *watches; | ||||
|   gboolean has_alarm; | ||||
|  | ||||
|   if (alarm_event->state != XSyncAlarmActive) | ||||
|     return; | ||||
|  | ||||
|   alarm = alarm_event->alarm; | ||||
|  | ||||
|   has_alarm = FALSE; | ||||
|  | ||||
|   if (alarm == monitor_xsync->user_active_alarm) | ||||
|     { | ||||
|       set_alarm_enabled (monitor_xsync->display, | ||||
|                          alarm, | ||||
|                          FALSE); | ||||
|       has_alarm = TRUE; | ||||
|     } | ||||
|   else if (g_hash_table_contains (monitor_xsync->alarms, (gpointer) alarm)) | ||||
|     { | ||||
|       ensure_alarm_rescheduled (monitor_xsync->display, | ||||
|                                 alarm); | ||||
|       has_alarm = TRUE; | ||||
|     } | ||||
|  | ||||
|   if (has_alarm) | ||||
|     { | ||||
|       watches = g_hash_table_get_values (monitor->watches); | ||||
|  | ||||
|       g_list_foreach (watches, check_x11_watch, (gpointer) alarm); | ||||
|       g_list_free (watches); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										47
									
								
								src/backends/x11/meta-idle-monitor-xsync.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/backends/x11/meta-idle-monitor-xsync.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
|  | ||||
| /* | ||||
|  * Copyright 2013 Red Hat, Inc. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and | ||||
|  *         from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c | ||||
|  */ | ||||
|  | ||||
| #ifndef META_IDLE_MONITOR_XSYNC_H | ||||
| #define META_IDLE_MONITOR_XSYNC_H | ||||
|  | ||||
| #include <glib-object.h> | ||||
| #include <meta/meta-idle-monitor.h> | ||||
|  | ||||
| #include <X11/Xlib.h> | ||||
| #include <X11/extensions/sync.h> | ||||
|  | ||||
| #define META_TYPE_IDLE_MONITOR_XSYNC            (meta_idle_monitor_xsync_get_type ()) | ||||
| #define META_IDLE_MONITOR_XSYNC(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_IDLE_MONITOR_XSYNC, MetaIdleMonitorXSync)) | ||||
| #define META_IDLE_MONITOR_XSYNC_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_IDLE_MONITOR_XSYNC, MetaIdleMonitorXSyncClass)) | ||||
| #define META_IS_IDLE_MONITOR_XSYNC(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_IDLE_MONITOR_XSYNC)) | ||||
| #define META_IS_IDLE_MONITOR_XSYNC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_IDLE_MONITOR_XSYNC)) | ||||
| #define META_IDLE_MONITOR_XSYNC_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_IDLE_MONITOR_XSYNC, MetaIdleMonitorXSyncClass)) | ||||
|  | ||||
| typedef struct _MetaIdleMonitorXSync        MetaIdleMonitorXSync; | ||||
| typedef struct _MetaIdleMonitorXSyncClass   MetaIdleMonitorXSyncClass; | ||||
|  | ||||
| GType meta_idle_monitor_xsync_get_type (void); | ||||
|  | ||||
| void meta_idle_monitor_xsync_handle_xevent (MetaIdleMonitor       *monitor, | ||||
|                                             XSyncAlarmNotifyEvent *xevent); | ||||
|  | ||||
| #endif /* META_IDLE_MONITOR_XSYNC_H */ | ||||
| @@ -1,6 +1,6 @@ | ||||
| /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | ||||
| 
 | ||||
| /* 
 | ||||
| /*
 | ||||
|  * Copyright (C) 2001, 2002 Havoc Pennington | ||||
|  * Copyright (C) 2002, 2003 Red Hat Inc. | ||||
|  * Some ICCCM manager selection code derived from fvwm2, | ||||
| @@ -8,7 +8,7 @@ | ||||
|  * Copyright (C) 2003 Rob Adams | ||||
|  * Copyright (C) 2004-2006 Elijah Newren | ||||
|  * Copyright (C) 2013 Red Hat Inc. | ||||
|  *  | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
| @@ -18,13 +18,15 @@ | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  *  | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| #include "config.h" | ||||
| 
 | ||||
| #include "meta-monitor-manager-xrandr.h" | ||||
| 
 | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| #include <math.h> | ||||
| @@ -34,11 +36,11 @@ | ||||
| #include <X11/extensions/Xrandr.h> | ||||
| #include <X11/extensions/dpms.h> | ||||
| 
 | ||||
| #include "meta-backend-x11.h" | ||||
| #include <meta/main.h> | ||||
| #include <meta/errors.h> | ||||
| #include "monitor-private.h" | ||||
| 
 | ||||
| #include "edid.h" | ||||
| #include "meta-monitor-config.h" | ||||
| 
 | ||||
| #define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1) | ||||
| 
 | ||||
| @@ -140,16 +142,16 @@ static gboolean | ||||
| output_get_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr, | ||||
|                                 MetaOutput               *output) | ||||
| { | ||||
|   MetaDisplay *display = meta_get_display (); | ||||
|   gboolean value; | ||||
|   Atom actual_type; | ||||
|   Atom atom, actual_type; | ||||
|   int actual_format; | ||||
|   unsigned long nitems, bytes_after; | ||||
|   unsigned char *buffer; | ||||
| 
 | ||||
|   atom = XInternAtom (manager_xrandr->xdisplay, "_MUTTER_PRESENTATION_OUTPUT", False); | ||||
|   XRRGetOutputProperty (manager_xrandr->xdisplay, | ||||
|                         (XID)output->output_id, | ||||
|                         display->atom__MUTTER_PRESENTATION_OUTPUT, | ||||
|                         atom, | ||||
|                         0, G_MAXLONG, False, False, XA_CARDINAL, | ||||
|                         &actual_type, &actual_format, | ||||
|                         &nitems, &bytes_after, &buffer); | ||||
| @@ -176,16 +178,16 @@ static int | ||||
| output_get_backlight_xrandr (MetaMonitorManagerXrandr *manager_xrandr, | ||||
|                              MetaOutput               *output) | ||||
| { | ||||
|   MetaDisplay *display = meta_get_display (); | ||||
|   gboolean value; | ||||
|   Atom actual_type; | ||||
|   Atom atom, actual_type; | ||||
|   int actual_format; | ||||
|   unsigned long nitems, bytes_after; | ||||
|   unsigned char *buffer; | ||||
| 
 | ||||
|   atom = XInternAtom (manager_xrandr->xdisplay, "Backlight", False); | ||||
|   XRRGetOutputProperty (manager_xrandr->xdisplay, | ||||
|                         (XID)output->output_id, | ||||
|                         display->atom_BACKLIGHT, | ||||
|                         atom, | ||||
|                         0, G_MAXLONG, False, False, XA_INTEGER, | ||||
|                         &actual_type, &actual_format, | ||||
|                         &nitems, &bytes_after, &buffer); | ||||
| @@ -204,14 +206,13 @@ static void | ||||
| output_get_backlight_limits_xrandr (MetaMonitorManagerXrandr *manager_xrandr, | ||||
|                                     MetaOutput               *output) | ||||
| { | ||||
|   MetaDisplay *display = meta_get_display (); | ||||
|   Atom atom; | ||||
|   XRRPropertyInfo *info; | ||||
| 
 | ||||
|   meta_error_trap_push (display); | ||||
|   atom = XInternAtom (manager_xrandr->xdisplay, "Backlight", False); | ||||
|   info = XRRQueryOutputProperty (manager_xrandr->xdisplay, | ||||
|                                  (XID)output->output_id, | ||||
|                                  display->atom_BACKLIGHT); | ||||
|   meta_error_trap_pop (display); | ||||
|                                  atom); | ||||
| 
 | ||||
|   if (info == NULL) | ||||
|     { | ||||
| @@ -271,7 +272,7 @@ get_edid_property (Display  *dpy, | ||||
|     } | ||||
| 
 | ||||
|   XFree (prop); | ||||
|      | ||||
| 
 | ||||
|   return result; | ||||
| } | ||||
| 
 | ||||
| @@ -313,14 +314,13 @@ static gboolean | ||||
| output_get_hotplug_mode_update (MetaMonitorManagerXrandr *manager_xrandr, | ||||
|                                 XID                       output_id) | ||||
| { | ||||
|   MetaDisplay *display = meta_get_display (); | ||||
|   Atom atom; | ||||
|   XRRPropertyInfo *info; | ||||
|   gboolean result = FALSE; | ||||
| 
 | ||||
|   meta_error_trap_push (display); | ||||
|   atom = XInternAtom (manager_xrandr->xdisplay, "hotplug_mode_update", False); | ||||
|   info = XRRQueryOutputProperty (manager_xrandr->xdisplay, output_id, | ||||
|                                  display->atom_hotplug_mode_update); | ||||
|   meta_error_trap_pop (display); | ||||
|                                  atom); | ||||
| 
 | ||||
|   if (info) | ||||
|     { | ||||
| @@ -349,9 +349,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager) | ||||
|     XRRFreeScreenResources (manager_xrandr->resources); | ||||
|   manager_xrandr->resources = NULL; | ||||
| 
 | ||||
|   meta_error_trap_push (meta_get_display ()); | ||||
|   dpms_capable = DPMSCapable (manager_xrandr->xdisplay); | ||||
|   meta_error_trap_pop (meta_get_display ()); | ||||
| 
 | ||||
|   if (dpms_capable && | ||||
|       DPMSInfo (manager_xrandr->xdisplay, &dpms_state, &dpms_enabled) && | ||||
| @@ -451,10 +449,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager) | ||||
|       XRRFreeCrtcInfo (crtc); | ||||
|     } | ||||
| 
 | ||||
|   meta_error_trap_push (meta_get_display ()); | ||||
|   primary_output = XRRGetOutputPrimary (manager_xrandr->xdisplay, | ||||
| 					DefaultRootWindow (manager_xrandr->xdisplay)); | ||||
|   meta_error_trap_pop (meta_get_display ()); | ||||
| 
 | ||||
|   n_actual_outputs = 0; | ||||
|   for (i = 0; i < (unsigned)resources->noutput; i++) | ||||
| @@ -636,10 +632,8 @@ meta_monitor_manager_xrandr_set_power_save_mode (MetaMonitorManager *manager, | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   meta_error_trap_push (meta_get_display ()); | ||||
|   DPMSForceLevel (manager_xrandr->xdisplay, state); | ||||
|   DPMSSetTimeouts (manager_xrandr->xdisplay, 0, 0, 0); | ||||
|   meta_error_trap_pop (meta_get_display ()); | ||||
| } | ||||
| 
 | ||||
| static Rotation | ||||
| @@ -673,12 +667,13 @@ output_set_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr, | ||||
|                                 MetaOutput               *output, | ||||
|                                 gboolean                  presentation) | ||||
| { | ||||
|   MetaDisplay *display = meta_get_display (); | ||||
|   Atom atom; | ||||
|   int value = presentation; | ||||
| 
 | ||||
|   atom = XInternAtom (manager_xrandr->xdisplay, "_MUTTER_PRESENTATION_OUTPUT", False); | ||||
|   XRRChangeOutputProperty (manager_xrandr->xdisplay, | ||||
|                            (XID)output->output_id, | ||||
|                            display->atom__MUTTER_PRESENTATION_OUTPUT, | ||||
|                            atom, | ||||
|                            XA_CARDINAL, 32, PropModeReplace, | ||||
|                            (unsigned char*) &value, 1); | ||||
| } | ||||
| @@ -691,11 +686,10 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, | ||||
| 						 unsigned int         n_outputs) | ||||
| { | ||||
|   MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager); | ||||
|   MetaDisplay *display = meta_get_display (); | ||||
|   unsigned i; | ||||
|   int width, height, width_mm, height_mm; | ||||
| 
 | ||||
|   meta_display_grab (display); | ||||
|   XGrabServer (manager_xrandr->xdisplay); | ||||
| 
 | ||||
|   /* First compute the new size of the screen (framebuffer) */ | ||||
|   width = 0; height = 0; | ||||
| @@ -789,10 +783,8 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, | ||||
|    */ | ||||
|   width_mm = (width / DPI_FALLBACK) * 25.4 + 0.5; | ||||
|   height_mm = (height / DPI_FALLBACK) * 25.4 + 0.5; | ||||
|   meta_error_trap_push (display); | ||||
|   XRRSetScreenSize (manager_xrandr->xdisplay, DefaultRootWindow (manager_xrandr->xdisplay), | ||||
|                     width, height, width_mm, height_mm); | ||||
|   meta_error_trap_pop (display); | ||||
| 
 | ||||
|   for (i = 0; i < n_crtcs; i++) | ||||
|     { | ||||
| @@ -849,7 +841,6 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, | ||||
|               goto next; | ||||
|             } | ||||
| 
 | ||||
|           meta_error_trap_push (display); | ||||
|           ok = XRRSetCrtcConfig (manager_xrandr->xdisplay, | ||||
|                                  manager_xrandr->resources, | ||||
|                                  (XID)crtc->crtc_id, | ||||
| @@ -858,7 +849,6 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, | ||||
|                                  (XID)mode->mode_id, | ||||
|                                  wl_transform_to_xrandr (crtc_info->transform), | ||||
|                                  outputs, n_outputs); | ||||
|           meta_error_trap_pop (display); | ||||
| 
 | ||||
|           if (ok != Success) | ||||
|             { | ||||
| @@ -899,11 +889,9 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, | ||||
| 
 | ||||
|       if (output_info->is_primary) | ||||
|         { | ||||
|           meta_error_trap_push (display); | ||||
|           XRRSetOutputPrimary (manager_xrandr->xdisplay, | ||||
|                                DefaultRootWindow (manager_xrandr->xdisplay), | ||||
|                                (XID)output_info->output->output_id); | ||||
|           meta_error_trap_pop (display); | ||||
|         } | ||||
| 
 | ||||
|       output_set_presentation_xrandr (manager_xrandr, | ||||
| @@ -929,7 +917,8 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager, | ||||
|       output->is_primary = FALSE; | ||||
|     } | ||||
| 
 | ||||
|   meta_display_ungrab (display); | ||||
|   XUngrabServer (manager_xrandr->xdisplay); | ||||
|   XFlush (manager_xrandr->xdisplay); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| @@ -938,18 +927,17 @@ meta_monitor_manager_xrandr_change_backlight (MetaMonitorManager *manager, | ||||
| 					      gint                value) | ||||
| { | ||||
|   MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager); | ||||
|   MetaDisplay *display = meta_get_display (); | ||||
|   Atom atom; | ||||
|   int hw_value; | ||||
| 
 | ||||
|   hw_value = round ((double)value / 100.0 * output->backlight_max + output->backlight_min); | ||||
| 
 | ||||
|   meta_error_trap_push (display); | ||||
|   atom = XInternAtom (manager_xrandr->xdisplay, "Backlight", False); | ||||
|   XRRChangeOutputProperty (manager_xrandr->xdisplay, | ||||
|                            (XID)output->output_id, | ||||
|                            display->atom_BACKLIGHT, | ||||
|                            atom, | ||||
|                            XA_INTEGER, 32, PropModeReplace, | ||||
|                            (unsigned char *) &hw_value, 1); | ||||
|   meta_error_trap_pop (display); | ||||
| 
 | ||||
|   /* We're not selecting for property notifies, so update the value immediately */ | ||||
|   output->backlight = normalize_backlight (output, hw_value); | ||||
| @@ -1007,11 +995,65 @@ meta_monitor_manager_xrandr_rebuild_derived (MetaMonitorManager *manager) | ||||
|   meta_monitor_manager_rebuild_derived (manager); | ||||
| } | ||||
| 
 | ||||
| static gboolean | ||||
| meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager, | ||||
| 					   XEvent             *event) | ||||
| static void | ||||
| meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr) | ||||
| { | ||||
|   MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager); | ||||
|   MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ()); | ||||
| 
 | ||||
|   manager_xrandr->xdisplay = meta_backend_x11_get_xdisplay (backend); | ||||
| 
 | ||||
|   if (!XRRQueryExtension (manager_xrandr->xdisplay, | ||||
| 			  &manager_xrandr->rr_event_base, | ||||
| 			  &manager_xrandr->rr_error_base)) | ||||
|     { | ||||
|       return; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* We only use ScreenChangeNotify, but GDK uses the others,
 | ||||
| 	 and we don't want to step on its toes */ | ||||
|       XRRSelectInput (manager_xrandr->xdisplay, | ||||
| 		      DefaultRootWindow (manager_xrandr->xdisplay), | ||||
| 		      RRScreenChangeNotifyMask | ||||
| 		      | RRCrtcChangeNotifyMask | ||||
| 		      | RROutputPropertyNotifyMask); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| meta_monitor_manager_xrandr_finalize (GObject *object) | ||||
| { | ||||
|   MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (object); | ||||
| 
 | ||||
|   if (manager_xrandr->resources) | ||||
|     XRRFreeScreenResources (manager_xrandr->resources); | ||||
|   manager_xrandr->resources = NULL; | ||||
| 
 | ||||
|   G_OBJECT_CLASS (meta_monitor_manager_xrandr_parent_class)->finalize (object); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass) | ||||
| { | ||||
|   MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_CLASS (klass); | ||||
|   GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||||
| 
 | ||||
|   object_class->finalize = meta_monitor_manager_xrandr_finalize; | ||||
| 
 | ||||
|   manager_class->read_current = meta_monitor_manager_xrandr_read_current; | ||||
|   manager_class->read_edid = meta_monitor_manager_xrandr_read_edid; | ||||
|   manager_class->apply_configuration = meta_monitor_manager_xrandr_apply_configuration; | ||||
|   manager_class->set_power_save_mode = meta_monitor_manager_xrandr_set_power_save_mode; | ||||
|   manager_class->change_backlight = meta_monitor_manager_xrandr_change_backlight; | ||||
|   manager_class->get_crtc_gamma = meta_monitor_manager_xrandr_get_crtc_gamma; | ||||
|   manager_class->set_crtc_gamma = meta_monitor_manager_xrandr_set_crtc_gamma; | ||||
| } | ||||
| 
 | ||||
| gboolean | ||||
| meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr, | ||||
| 					   XEvent                   *event) | ||||
| { | ||||
|   MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr); | ||||
|   MetaOutput *old_outputs; | ||||
|   MetaCRTC *old_crtcs; | ||||
|   MetaMonitorMode *old_modes; | ||||
| @@ -1072,59 +1114,3 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager, | ||||
| 
 | ||||
|   return TRUE; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr) | ||||
| { | ||||
|   MetaDisplay *display = meta_get_display (); | ||||
| 
 | ||||
|   manager_xrandr->xdisplay = display->xdisplay; | ||||
| 
 | ||||
|   if (!XRRQueryExtension (manager_xrandr->xdisplay, | ||||
| 			  &manager_xrandr->rr_event_base, | ||||
| 			  &manager_xrandr->rr_error_base)) | ||||
|     { | ||||
|       return; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* We only use ScreenChangeNotify, but GDK uses the others,
 | ||||
| 	 and we don't want to step on its toes */ | ||||
|       XRRSelectInput (manager_xrandr->xdisplay, | ||||
| 		      DefaultRootWindow (manager_xrandr->xdisplay), | ||||
| 		      RRScreenChangeNotifyMask | ||||
| 		      | RRCrtcChangeNotifyMask | ||||
| 		      | RROutputPropertyNotifyMask); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| meta_monitor_manager_xrandr_finalize (GObject *object) | ||||
| { | ||||
|   MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (object); | ||||
| 
 | ||||
|   if (manager_xrandr->resources) | ||||
|     XRRFreeScreenResources (manager_xrandr->resources); | ||||
|   manager_xrandr->resources = NULL; | ||||
| 
 | ||||
|   G_OBJECT_CLASS (meta_monitor_manager_xrandr_parent_class)->finalize (object); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass) | ||||
| { | ||||
|   MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_CLASS (klass); | ||||
|   GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||||
| 
 | ||||
|   object_class->finalize = meta_monitor_manager_xrandr_finalize; | ||||
| 
 | ||||
|   manager_class->read_current = meta_monitor_manager_xrandr_read_current; | ||||
|   manager_class->read_edid = meta_monitor_manager_xrandr_read_edid; | ||||
|   manager_class->apply_configuration = meta_monitor_manager_xrandr_apply_configuration; | ||||
|   manager_class->set_power_save_mode = meta_monitor_manager_xrandr_set_power_save_mode; | ||||
|   manager_class->change_backlight = meta_monitor_manager_xrandr_change_backlight; | ||||
|   manager_class->get_crtc_gamma = meta_monitor_manager_xrandr_get_crtc_gamma; | ||||
|   manager_class->set_crtc_gamma = meta_monitor_manager_xrandr_set_crtc_gamma; | ||||
|   manager_class->handle_xevent = meta_monitor_manager_xrandr_handle_xevent; | ||||
| } | ||||
| 
 | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user