mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-29 23:32:04 +02:00
Compare commits
49 Commits
reactable
...
8d002397df
Author | SHA1 | Date | |
---|---|---|---|
|
8d002397df | ||
|
b9e98e2fdb | ||
|
555b93451e | ||
|
cdfac76d66 | ||
|
ed13d53db9 | ||
|
acf2b75f27 | ||
|
d9c8534bb7 | ||
|
292b339e8a | ||
|
ddfedddce5 | ||
|
743097060e | ||
|
b0b15cec5c | ||
|
b9a8b28a1f | ||
|
4c8c76c8f7 | ||
|
a5db6f701d | ||
|
4301a9a9fa | ||
|
c21e1c1c6a | ||
|
92e0e22e8b | ||
|
4d5519b42d | ||
|
4a34fb3484 | ||
|
d8ea220aad | ||
|
dc56cb201a | ||
|
07f944fb31 | ||
|
b2e6533c30 | ||
|
7a56fbfff8 | ||
|
7457ffda13 | ||
|
bee2e08fb1 | ||
|
0c1d291006 | ||
|
4002a63e3a | ||
|
ff054743e6 | ||
|
9432156aec | ||
|
47d3ebe693 | ||
|
5f8270f0e8 | ||
|
54f059aaa3 | ||
|
f63e13ed39 | ||
|
daadabba8d | ||
|
225e665aff | ||
|
31564b568b | ||
|
1c376612b8 | ||
|
c4afd8bea1 | ||
|
266c588db9 | ||
|
1c0049ec2b | ||
|
7f326e6875 | ||
|
16430c4c66 | ||
|
9f1102bafd | ||
|
7b4a19659b | ||
|
8fe46d315c | ||
|
b5cc171803 | ||
|
0f929014d5 | ||
|
f3b120f451 |
31
COPYING-LGPL
31
COPYING-LGPL
@@ -2,7 +2,7 @@
|
|||||||
Version 2.1, February 1999
|
Version 2.1, February 1999
|
||||||
|
|
||||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
<https://fsf.org/>
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
of this license document, but changing it is not allowed.
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ modified by someone else and passed on, the recipients should know
|
|||||||
that what they have is not the original version, so that the original
|
that what they have is not the original version, so that the original
|
||||||
author's reputation will not be affected by problems that might be
|
author's reputation will not be affected by problems that might be
|
||||||
introduced by others.
|
introduced by others.
|
||||||
|
|
||||||
Finally, software patents pose a constant threat to the existence of
|
Finally, software patents pose a constant threat to the existence of
|
||||||
any free program. We wish to make sure that a company cannot
|
any free program. We wish to make sure that a company cannot
|
||||||
effectively restrict the users of a free program by obtaining a
|
effectively restrict the users of a free program by obtaining a
|
||||||
@@ -111,7 +111,7 @@ modification follow. Pay close attention to the difference between a
|
|||||||
"work based on the library" and a "work that uses the library". The
|
"work based on the library" and a "work that uses the library". The
|
||||||
former contains code derived from the library, whereas the latter must
|
former contains code derived from the library, whereas the latter must
|
||||||
be combined with the library in order to run.
|
be combined with the library in order to run.
|
||||||
|
|
||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ Library.
|
|||||||
You may charge a fee for the physical act of transferring a copy,
|
You may charge a fee for the physical act of transferring a copy,
|
||||||
and you may at your option offer warranty protection in exchange for a
|
and you may at your option offer warranty protection in exchange for a
|
||||||
fee.
|
fee.
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Library or any portion
|
2. You may modify your copy or copies of the Library or any portion
|
||||||
of it, thus forming a work based on the Library, and copy and
|
of it, thus forming a work based on the Library, and copy and
|
||||||
distribute such modifications or work under the terms of Section 1
|
distribute such modifications or work under the terms of Section 1
|
||||||
@@ -216,7 +216,7 @@ instead of to this License. (If a newer version than version 2 of the
|
|||||||
ordinary GNU General Public License has appeared, then you can specify
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
that version instead if you wish.) Do not make any other change in
|
that version instead if you wish.) Do not make any other change in
|
||||||
these notices.
|
these notices.
|
||||||
|
|
||||||
Once this change is made in a given copy, it is irreversible for
|
Once this change is made in a given copy, it is irreversible for
|
||||||
that copy, so the ordinary GNU General Public License applies to all
|
that copy, so the ordinary GNU General Public License applies to all
|
||||||
subsequent copies and derivative works made from that copy.
|
subsequent copies and derivative works made from that copy.
|
||||||
@@ -267,7 +267,7 @@ Library will still fall under Section 6.)
|
|||||||
distribute the object code for the work under the terms of Section 6.
|
distribute the object code for the work under the terms of Section 6.
|
||||||
Any executables containing that work also fall under Section 6,
|
Any executables containing that work also fall under Section 6,
|
||||||
whether or not they are linked directly with the Library itself.
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
6. As an exception to the Sections above, you may also combine or
|
6. As an exception to the Sections above, you may also combine or
|
||||||
link a "work that uses the Library" with the Library to produce a
|
link a "work that uses the Library" with the Library to produce a
|
||||||
work containing portions of the Library, and distribute that work
|
work containing portions of the Library, and distribute that work
|
||||||
@@ -329,7 +329,7 @@ restrictions of other proprietary libraries that do not normally
|
|||||||
accompany the operating system. Such a contradiction means you cannot
|
accompany the operating system. Such a contradiction means you cannot
|
||||||
use both them and the Library together in an executable that you
|
use both them and the Library together in an executable that you
|
||||||
distribute.
|
distribute.
|
||||||
|
|
||||||
7. You may place library facilities that are a work based on the
|
7. You may place library facilities that are a work based on the
|
||||||
Library side-by-side in a single library together with other library
|
Library side-by-side in a single library together with other library
|
||||||
facilities not covered by this License, and distribute such a combined
|
facilities not covered by this License, and distribute such a combined
|
||||||
@@ -370,7 +370,7 @@ subject to these terms and conditions. You may not impose any further
|
|||||||
restrictions on the recipients' exercise of the rights granted herein.
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
You are not responsible for enforcing compliance by third parties with
|
You are not responsible for enforcing compliance by third parties with
|
||||||
this License.
|
this License.
|
||||||
|
|
||||||
11. If, as a consequence of a court judgment or allegation of patent
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
infringement or for any other reason (not limited to patent issues),
|
infringement or for any other reason (not limited to patent issues),
|
||||||
conditions are imposed on you (whether by court order, agreement or
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
@@ -422,7 +422,7 @@ conditions either of that version or of any later version published by
|
|||||||
the Free Software Foundation. If the Library does not specify a
|
the Free Software Foundation. If the Library does not specify a
|
||||||
license version number, you may choose any version ever published by
|
license version number, you may choose any version ever published by
|
||||||
the Free Software Foundation.
|
the Free Software Foundation.
|
||||||
|
|
||||||
14. If you wish to incorporate parts of the Library into other free
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
programs whose distribution conditions are incompatible with these,
|
programs whose distribution conditions are incompatible with these,
|
||||||
write to the author to ask for permission. For software which is
|
write to the author to ask for permission. For software which is
|
||||||
@@ -456,7 +456,7 @@ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
|||||||
DAMAGES.
|
DAMAGES.
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
How to Apply These Terms to Your New Libraries
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
If you develop a new library, and you want it to be of the greatest
|
If you develop a new library, and you want it to be of the greatest
|
||||||
@@ -484,9 +484,7 @@ convey the exclusion of warranty; and each file should have at least the
|
|||||||
Lesser General Public License for more details.
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
You should have received a copy of the GNU Lesser General Public
|
||||||
License along with this library; if not, write to the Free Software
|
License along with this library; if not, see <https://www.gnu.org/licenses/>.
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
|
||||||
USA
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
@@ -495,10 +493,9 @@ school, if any, to sign a "copyright disclaimer" for the library, if
|
|||||||
necessary. Here is a sample; alter the names:
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||||
library `Frob' (a library for tweaking knobs) written by James Random
|
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||||
Hacker.
|
|
||||||
|
|
||||||
<signature of Ty Coon>, 1 April 1990
|
<signature of Moe Ghoul>, 1 April 1990
|
||||||
Ty Coon, President of Vice
|
Moe Ghoul, President of Vice
|
||||||
|
|
||||||
That's all there is to it!
|
That's all there is to it!
|
||||||
|
153
doc/reference/clapper/clapper-enhancers.md
Normal file
153
doc/reference/clapper/clapper-enhancers.md
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
Title: Clapper Enhancers
|
||||||
|
Slug: clapper-enhancers
|
||||||
|
|
||||||
|
### Overview
|
||||||
|
|
||||||
|
Clapper Enhancers are special plugins loaded through `libpeas` for Clapper library.
|
||||||
|
The idea is to enhance it (including applications that use Clapper) with new
|
||||||
|
capabilities that do stuff outside of `GStreamer` scope of things without increasing
|
||||||
|
number of dependencies of Clapper itself (especially for features that not everyone needs).
|
||||||
|
|
||||||
|
To avoid confusion with term "plugins" that `GStreamer` uses, the name "enhancers"
|
||||||
|
was choosen instead.
|
||||||
|
|
||||||
|
In addition to writing enhancers in pure `C`, they can be written in any programmable
|
||||||
|
language that is supported by `libpeas` and works with Clapper library bindings
|
||||||
|
(examples being `Python`, `GJS` and `Vala`). This makes it possible for individual users
|
||||||
|
to add their own custom functionalities that they want to use individually.
|
||||||
|
|
||||||
|
### Types
|
||||||
|
|
||||||
|
Clapper gives three interfaces for writing enhancers for different things, these are:
|
||||||
|
|
||||||
|
- [Extractable](extractable-enhancers.html)
|
||||||
|
- [Playlistable](playlistable-enhancers.html)
|
||||||
|
- [Reactable](reactable-enhancers.html)
|
||||||
|
|
||||||
|
### Basics
|
||||||
|
|
||||||
|
Each enhancer is a `libpeas` compatible module. As such it follows its requirements for
|
||||||
|
writing plugins and is a [class@GObject.Object] sublass implementing one or more of interfaces
|
||||||
|
that Clapper library provides.
|
||||||
|
|
||||||
|
Due to the plugins nature, written enhancer can be either submitted to the main [Clapper Enhancers
|
||||||
|
repository](https://github.com/Rafostar/clapper-enhancers) when it seems useful for more than a single
|
||||||
|
application. Alternatively, it can be shipped as part your application. Users can also write their
|
||||||
|
own/custom local enhancer plugins.
|
||||||
|
|
||||||
|
### Loading Enhancers
|
||||||
|
|
||||||
|
Clapper will try to lazy load enhancer modules, meaning they will not be loaded unless they are used.
|
||||||
|
As an additional safety precaution, enhancers can be disallowed from their instances being created with
|
||||||
|
[property@Clapper.EnhancerProxy:target-creation-allowed]. Enhancers that operate on-demand
|
||||||
|
(when supported URI is given) such as [iface@Clapper.Extractable] and [iface@Clapper.Playlistable]
|
||||||
|
are allowed (enabled) by default, while [iface@Clapper.Reactable] are not.
|
||||||
|
|
||||||
|
Environment variables:
|
||||||
|
|
||||||
|
* `CLAPPER_ENHANCERS_PATH` - override for default path where Clapper loads enhancers from
|
||||||
|
* `CLAPPER_ENHANCERS_EXTRA_PATH` - additional path to scan for enhancer plugins
|
||||||
|
|
||||||
|
While both allow to specify multiple directories (with `:` separation), applications and
|
||||||
|
users should mostly use extra path in order to add their own enhancers from non-standard
|
||||||
|
installation directory. They can override default path in case where they want to forbid
|
||||||
|
using stock enhancers for some reason.
|
||||||
|
|
||||||
|
### Enhancer Proxies
|
||||||
|
|
||||||
|
In order to create enhancers when needed and use them only within thread they were created in,
|
||||||
|
Clapper manages enhancer instances on its own. It gives applications proxy objects for
|
||||||
|
browsing and configuring them.
|
||||||
|
|
||||||
|
Only after Clapper library is initialized, you can get either the global (application scope) list
|
||||||
|
([class@Clapper.EnhancerProxyList]) of enhancers proxies with [func@Clapper.get_global_enhancer_proxies]
|
||||||
|
or player scope with [method@Clapper.Player.get_enhancer_proxies].
|
||||||
|
|
||||||
|
Properties set on the global list will carry over to all created player instances afterwards.
|
||||||
|
While these set on a list from a player are applied to enhancers created by this player only.
|
||||||
|
You can use that to your advantage to only allow creation of some type of enhancer in only some
|
||||||
|
player instances.
|
||||||
|
|
||||||
|
### Properties
|
||||||
|
|
||||||
|
Some enhancers might want to expose some configuration. For this cases they should install
|
||||||
|
[class@GObject.Object] properties in their class. They must only use fundamental types from the list below:
|
||||||
|
|
||||||
|
* boolean
|
||||||
|
* int
|
||||||
|
* uint
|
||||||
|
* double
|
||||||
|
* string
|
||||||
|
|
||||||
|
They should include one or more of [flags@Clapper.EnhancerParamFlags].
|
||||||
|
Properties in object can have `global`, `local`, neither or both flags at once.
|
||||||
|
|
||||||
|
The ones with [Clapper.EnhancerParamFlags.GLOBAL] are for user to configure. They should
|
||||||
|
be exposed (ideally in the UI) and used for things that make sense to be set for all
|
||||||
|
applications at once (e.g. supported media codec by user device, preferred language, etc.).
|
||||||
|
|
||||||
|
On the other hand, properties with [Clapper.EnhancerParamFlags.LOCAL] are for application scope
|
||||||
|
usage only. They never carry over to other apps, nor they can be set on global enhancers list.
|
||||||
|
Instead they are configured per player instance.
|
||||||
|
|
||||||
|
When property is neither `global` or `local` it is considered to be plugin internal property.
|
||||||
|
Clapper will never access them, as such they can be of any type (not limited to above list).
|
||||||
|
This also makes properties that are already installed in base classes of subclassed object
|
||||||
|
not appear in the UI.
|
||||||
|
|
||||||
|
When both flags are set, property will initially use globally set value by user while still
|
||||||
|
allowing application to override this value locally per player instance.
|
||||||
|
|
||||||
|
Extra flags like [Clapper.EnhancerParamFlags.FILEPATH] and [Clapper.EnhancerParamFlags.DIRPATH]
|
||||||
|
can be used (usually with `string` type of property) in order to let application know that this
|
||||||
|
field holds a file/directory path and allow it to present file selection dialog to the user instead
|
||||||
|
of text entry.
|
||||||
|
|
||||||
|
### Configuring Enhancers
|
||||||
|
|
||||||
|
Applications browse properties of enhancer via [method@Clapper.EnhancerProxy.get_target_properties]
|
||||||
|
which returns a list of [class@GObject.ParamSpec]. By inspecting their `flags` application can know
|
||||||
|
whether property is `global`, `local` or both.
|
||||||
|
|
||||||
|
Use [method@Clapper.EnhancerProxy.get_settings] to get a [class@Gio.Settings] with `global` properties
|
||||||
|
to read and write (note that only users should be able to change them, thus you might want to bind these
|
||||||
|
into some UI widgets for that). These can be (with user consent) set on either proxy from global proxies
|
||||||
|
list or the player one.
|
||||||
|
|
||||||
|
Use [method@Clapper.EnhancerProxy.set_locally] to set `local` properties. These are meant for applications
|
||||||
|
to freely customize as they please. Remember that you can only set them on a enhancer proxy object belonging
|
||||||
|
to some player instance and not the global one.
|
||||||
|
|
||||||
|
### Plugin Info File
|
||||||
|
|
||||||
|
An enhancer plugin should be placed within directory that includes its [Peas] plugin
|
||||||
|
description file. It should be a text file with a `.plugin` extension and contain at least
|
||||||
|
following content:
|
||||||
|
|
||||||
|
```
|
||||||
|
[Plugin]
|
||||||
|
Module=example_enhancer
|
||||||
|
Name=Example Enhancer
|
||||||
|
Description=This enhancer serves as an example
|
||||||
|
Version=0.0.1
|
||||||
|
```
|
||||||
|
|
||||||
|
* `Module` - module entry file name. It also acts as enhancer ID and should be unique for each.
|
||||||
|
It is recommended to use app/custom prefix in its name.
|
||||||
|
* `Name` - module friendly name for displaying in UI and such.
|
||||||
|
* `Description` - description to present to the user for what it does.
|
||||||
|
* `Version` - enhancer version. In order to lazy load enhancers, Clapper will cache each
|
||||||
|
enhancer data and olny reload it if version changes, so keep this always updated.
|
||||||
|
|
||||||
|
If module is written in interpretable programming language it must also contain `Loader` key
|
||||||
|
with interpreter name (e.g. `Loader=python`).
|
||||||
|
|
||||||
|
Some enhancer interfaces require additional fields to be put in this file. They are described
|
||||||
|
in the requirements of each one in their documentation pages that are listed in the
|
||||||
|
[Types section](clapper-enhancers.html#types).
|
||||||
|
|
||||||
|
### Adding Enhancers to Flatpak App
|
||||||
|
|
||||||
|
If you are using Clapper as part of a `Flatpak` application, you can get all the enhancers from their main repo as an extension
|
||||||
|
(info [here](https://github.com/flathub/com.github.rafostar.Clapper?tab=readme-ov-file#comgithubrafostarclapperenhancers)),
|
||||||
|
thus you do not need to build them yourself.
|
@@ -66,6 +66,11 @@ base_url = "https://github.com/Rafostar/clapper/tree/master/"
|
|||||||
[extra]
|
[extra]
|
||||||
# The same order will be used when generating the index
|
# The same order will be used when generating the index
|
||||||
content_files = [
|
content_files = [
|
||||||
|
"clapper-enhancers.md",
|
||||||
|
"extractable-enhancers.md",
|
||||||
|
"playlistable-enhancers.md",
|
||||||
|
"reactable-enhancers.md",
|
||||||
|
"migrating-to-010.md",
|
||||||
]
|
]
|
||||||
content_images = [
|
content_images = [
|
||||||
"images/clapper-logo.svg",
|
"images/clapper-logo.svg",
|
||||||
|
76
doc/reference/clapper/extractable-enhancers.md
Normal file
76
doc/reference/clapper/extractable-enhancers.md
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
Title: Extractable Enhancers
|
||||||
|
Slug: extractable-enhancers
|
||||||
|
|
||||||
|
### Overview
|
||||||
|
|
||||||
|
[iface@Clapper.Extractable] is an interface to implement enhancers that need to
|
||||||
|
resolve given URI into data that `GStreamer` will be able to play. While not
|
||||||
|
limited to, main use-case is for media information extraction.
|
||||||
|
|
||||||
|
While implementer is free to write whole extraction by hand, he can alternatively
|
||||||
|
integrate some 3rd party library that does most of this work. In such case, extractable
|
||||||
|
enhancer is more of a wrapper for integrating said library. This is especially useful
|
||||||
|
if library that you want to use is written in different programming language than Clapper is.
|
||||||
|
|
||||||
|
For the basics about writing enhancers see [Clapper Enhancers](clapper-enhancers.html).
|
||||||
|
|
||||||
|
### Requirements
|
||||||
|
|
||||||
|
Additional fields for `.plugin` info file: `X-Schemes` and `X-Hosts`. The former one should
|
||||||
|
hold the `;` separated list of supported URI schemes, while the latter is for hostnames.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```
|
||||||
|
X-Schemes=https;expl
|
||||||
|
X-Hosts=example.com;other.example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
With this in place, enhancer will be loaded and used for URIs that match combinations
|
||||||
|
of one of the schemes and hosts. The special rule is that when using some custom URI
|
||||||
|
scheme other than `http(s)`, `X-Hosts` can be skipped since such URI explicitly
|
||||||
|
says to use this module.
|
||||||
|
|
||||||
|
Considering all of the above, this enhancer would try to extract URIs like:
|
||||||
|
|
||||||
|
* `https://example.com/video_id=ABCD`
|
||||||
|
* `expl://video.it?id=ABCD`
|
||||||
|
|
||||||
|
It would not act however for:
|
||||||
|
|
||||||
|
* `https://video.it?id=ABCD`
|
||||||
|
* `qwerty://other.example.com/video_id=ABCD`
|
||||||
|
|
||||||
|
An enhancer of this type must implement [vfunc@Clapper.Extractable.extract] virtual method.
|
||||||
|
|
||||||
|
### Harvesting data
|
||||||
|
|
||||||
|
When [vfunc@Clapper.Extractable.extract] is called, newly made [class@Clapper.Harvest]
|
||||||
|
is passed as this function argument. Implementation is responsible for filling it with
|
||||||
|
data (see [method@Clapper.Harvest.fill]) that can be played. Such content can be either
|
||||||
|
a resolved URI to actual media file or some streaming manifest (like `HLS` or `DASH`).
|
||||||
|
|
||||||
|
During extract function, implementation might optionally add media tags such as title
|
||||||
|
(which will be merged with tags of [class@Clapper.MediaItem]) and extra HTTP request
|
||||||
|
headers if any are required to access this content.
|
||||||
|
|
||||||
|
### Multiple items extraction
|
||||||
|
|
||||||
|
It is possible to handle URIs which would normally return more than one media item to play.
|
||||||
|
Examples being playlists, search queries, related videos, etc.
|
||||||
|
|
||||||
|
This can be handled in two ways, depending on set media type:
|
||||||
|
|
||||||
|
1. `text/uri-list`
|
||||||
|
2. `application/clapper-playlist`
|
||||||
|
|
||||||
|
If you use the first option, harvest should be filled with idividual URIs one per line.
|
||||||
|
Clapper will use its built-in URI list parser to create a media item for each URI and
|
||||||
|
place them in its playback queue. This is equivalent of creating [class@Clapper.MediaItem]
|
||||||
|
for each of these URIs without setting any tags in it initially.
|
||||||
|
|
||||||
|
The second option requires for this enhancer to also implement [iface@Clapper.Playlistable]
|
||||||
|
interface. In this case, you can fill harvest with ANY kind of data considering that
|
||||||
|
[vfunc@Clapper.Playlistable.parse] of your own enhancer will be used with the data you
|
||||||
|
passed. With this, you can add more info to media items such as extra tags, timeline markers
|
||||||
|
or subtitle URI. Useful if your extractor extracts both URIs and tags in one go.
|
@@ -6,6 +6,14 @@ clapper_toml = configure_file(
|
|||||||
install_dir: join_paths(datadir, 'doc', 'clapper'),
|
install_dir: join_paths(datadir, 'doc', 'clapper'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
extra_md_files = [
|
||||||
|
'clapper-enhancers.md',
|
||||||
|
'extractable-enhancers.md',
|
||||||
|
'playlistable-enhancers.md',
|
||||||
|
'reactable-enhancers.md',
|
||||||
|
'migrating-to-010.md',
|
||||||
|
]
|
||||||
|
|
||||||
custom_target('clapper-doc',
|
custom_target('clapper-doc',
|
||||||
input: [
|
input: [
|
||||||
clapper_toml,
|
clapper_toml,
|
||||||
@@ -23,6 +31,7 @@ custom_target('clapper-doc',
|
|||||||
'--content-dir=@0@'.format(meson.current_source_dir()),
|
'--content-dir=@0@'.format(meson.current_source_dir()),
|
||||||
'@INPUT1@',
|
'@INPUT1@',
|
||||||
],
|
],
|
||||||
|
depend_files: extra_md_files,
|
||||||
build_by_default: true,
|
build_by_default: true,
|
||||||
install: true,
|
install: true,
|
||||||
install_dir: join_paths(datadir, 'doc'),
|
install_dir: join_paths(datadir, 'doc'),
|
||||||
|
44
doc/reference/clapper/migrating-to-010.md
Normal file
44
doc/reference/clapper/migrating-to-010.md
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
Title: Migrating to Clapper 0.10
|
||||||
|
Slug: migrating-to-010
|
||||||
|
|
||||||
|
### Replace Features with Enhancers
|
||||||
|
|
||||||
|
Clapper 0.10 deprecates [class@Clapper.Feature] objects in favour [Clapper Enhancers](clapper-enhancers.html)
|
||||||
|
used via [class@Clapper.EnhancerProxy].
|
||||||
|
|
||||||
|
Old [class@Clapper.Feature] objects (including `mpris`, `discoverer` and `server`) are left for compatibility
|
||||||
|
reasons, but all apps using them are advised to migrate to enhancer plugins which already surpassed former
|
||||||
|
ones in what can be achieved with them.
|
||||||
|
|
||||||
|
Since these are now in the form of plugins scanned during init, one of the differences is that you now check
|
||||||
|
their availablity at runtime instead of compile time like before.
|
||||||
|
|
||||||
|
Something like this:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#if CLAPPER_HAVE_MPRIS
|
||||||
|
ClapperFeature *feature = CLAPPER_FEATURE (clapper_mpris_new (
|
||||||
|
mpris_name, APP_NAME, APP_ID));
|
||||||
|
clapper_player_add_feature (player, feature);
|
||||||
|
gst_object_unref (feature);
|
||||||
|
#endif
|
||||||
|
```
|
||||||
|
|
||||||
|
Can be implemented like this:
|
||||||
|
|
||||||
|
```c
|
||||||
|
ClapperEnhancerProxyList *proxies = clapper_player_get_enhancer_proxies (player);
|
||||||
|
ClapperEnhancerProxy *proxy = clapper_enhancer_proxy_list_get_proxy_by_module (proxies, "clapper-mpris");
|
||||||
|
|
||||||
|
if (proxy) {
|
||||||
|
clapper_enhancer_proxy_set_locally (proxy,
|
||||||
|
"own-name", mpris_name,
|
||||||
|
"identity", APP_NAME,
|
||||||
|
"desktop-entry", APP_ID, NULL);
|
||||||
|
clapper_enhancer_proxy_set_target_creation_allowed (proxy, TRUE);
|
||||||
|
gst_object_unref (proxy);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
For more information how to use enhancers and how to write your own,
|
||||||
|
see [Clapper Enhancers](clapper-enhancers.html) documentation.
|
39
doc/reference/clapper/playlistable-enhancers.md
Normal file
39
doc/reference/clapper/playlistable-enhancers.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
Title: Playlistable Enhancers
|
||||||
|
Slug: playlistable-enhancers
|
||||||
|
|
||||||
|
### Overview
|
||||||
|
|
||||||
|
[iface@Clapper.Playlistable] is an interface to implement playlist parsers.
|
||||||
|
Allows to expand Clapper library with an ability to read data from which one
|
||||||
|
or more media items should be created.
|
||||||
|
|
||||||
|
To load playlist within Clapper, just create a new media item which has an URI
|
||||||
|
leading to data that playlistable enhancer will act upon. After parsing, that item
|
||||||
|
will be merged with first parsed item and the rest will be inserted into queue after
|
||||||
|
its position.
|
||||||
|
|
||||||
|
Essentially, such enhancer inserts items from a playlist into playback queue upon
|
||||||
|
which Clapper operates. It can also handle nested playlits (a playlist URI within
|
||||||
|
another playlist) with unlimited amount of nested levels.
|
||||||
|
|
||||||
|
For the basics about writing enhancers see [Clapper Enhancers](clapper-enhancers.html).
|
||||||
|
|
||||||
|
### Requirements
|
||||||
|
|
||||||
|
Additional fields for `.plugin` info file:
|
||||||
|
|
||||||
|
* `X-Data-Prefix` - describe text that data should start with
|
||||||
|
* `X-Data-Contains` - data must contain given phrase
|
||||||
|
* `X-Data-Regex` - regular expression to run on data
|
||||||
|
|
||||||
|
These are used by `typefinder` to determine whether given data is a playlist for
|
||||||
|
this enhancer to handle. At least one of the above must be added to plugin info file.
|
||||||
|
|
||||||
|
An enhancer of this type must implement [vfunc@Clapper.Playlistable.parse] virtual method.
|
||||||
|
|
||||||
|
### Parsing data
|
||||||
|
|
||||||
|
When [vfunc@Clapper.Playlistable.parse] is called, an empty [class@Gio.ListStore] is
|
||||||
|
passed as this function argument. Implementation is responsible for parsing data, creating
|
||||||
|
[class@Clapper.MediaItem] objects and adding them to that list store. While doing so, it
|
||||||
|
can also populate each media item tags, timeline markers and/or set subtitle URI.
|
23
doc/reference/clapper/reactable-enhancers.md
Normal file
23
doc/reference/clapper/reactable-enhancers.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
Title: Reactable Enhancers
|
||||||
|
Slug: reactable-enhancers
|
||||||
|
|
||||||
|
### Overview
|
||||||
|
|
||||||
|
[iface@Clapper.Reactable] is an interface to implement enhancers that react to the
|
||||||
|
playback and/or events that should influence it.
|
||||||
|
|
||||||
|
Such enhancer can work not only in a way that triggers external actions due to some
|
||||||
|
playback events, but also in reverse - alters playback or its queue due to some
|
||||||
|
external event. It can do so by getting a hold of the player that given enhancer
|
||||||
|
instance reacts to with [method@Clapper.Reactable.get_player].
|
||||||
|
|
||||||
|
For the basics about writing enhancers see [Clapper Enhancers](clapper-enhancers.html).
|
||||||
|
|
||||||
|
### Requirements
|
||||||
|
|
||||||
|
An enhancer of this type should implement any of the [iface@Clapper.Reactable] virtual
|
||||||
|
methods that it needs.
|
||||||
|
|
||||||
|
Note that when implementing [vfunc@Clapper.Reactable.queue_item_removed] you probably
|
||||||
|
also want to implement [vfunc@Clapper.Reactable.queue_cleared] as the former is not
|
||||||
|
called for each item when clearing the whole queue for performance reasons.
|
49
examples/clapper-gtk/audio/simple/python/example.py
Executable file
49
examples/clapper-gtk/audio/simple/python/example.py
Executable file
@@ -0,0 +1,49 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import gi
|
||||||
|
gi.require_version('Adw', '1')
|
||||||
|
gi.require_version('Clapper', '0.0')
|
||||||
|
gi.require_version('ClapperGtk', '0.0')
|
||||||
|
gi.require_version('Gtk', '4.0')
|
||||||
|
from gi.repository import Adw, Clapper, ClapperGtk, Gtk
|
||||||
|
|
||||||
|
Clapper.init(None)
|
||||||
|
|
||||||
|
def on_activate(app):
|
||||||
|
# Create our widgets.
|
||||||
|
win = Gtk.ApplicationWindow(application=app, title='Clapper Audio', default_width=640, default_height=96)
|
||||||
|
audio = ClapperGtk.Audio()
|
||||||
|
box = Gtk.Box(valign=Gtk.Align.CENTER, margin_start=8, margin_end=8, spacing=4)
|
||||||
|
prev_btn = ClapperGtk.PreviousItemButton()
|
||||||
|
play_btn = ClapperGtk.TogglePlayButton()
|
||||||
|
next_btn = ClapperGtk.NextItemButton()
|
||||||
|
seek_bar = ClapperGtk.SeekBar()
|
||||||
|
|
||||||
|
# Add media for playback. First media item in queue will be automatically selected.
|
||||||
|
item = Clapper.MediaItem(uri='https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3')
|
||||||
|
audio.props.player.props.queue.add_item(item)
|
||||||
|
|
||||||
|
item = Clapper.MediaItem(uri='https://www.learningcontainer.com/wp-content/uploads/2020/02/Kalimba.mp3')
|
||||||
|
audio.props.player.props.queue.add_item(item)
|
||||||
|
|
||||||
|
# Assemble window.
|
||||||
|
box.append(prev_btn)
|
||||||
|
box.append(play_btn)
|
||||||
|
box.append(next_btn)
|
||||||
|
box.append(seek_bar)
|
||||||
|
audio.set_child(box)
|
||||||
|
win.set_child(audio)
|
||||||
|
win.present()
|
||||||
|
|
||||||
|
# Not too loud. Mind the ears.
|
||||||
|
audio.props.player.props.volume = 0.7
|
||||||
|
|
||||||
|
# Start playback.
|
||||||
|
audio.props.player.play()
|
||||||
|
|
||||||
|
# Create a new application.
|
||||||
|
app = Adw.Application(application_id='com.example.ClapperAudio')
|
||||||
|
app.connect('activate', on_activate)
|
||||||
|
|
||||||
|
# Run the application.
|
||||||
|
app.run(None)
|
@@ -1,5 +1,5 @@
|
|||||||
project('clapper', 'c',
|
project('clapper', 'c',
|
||||||
version: '0.9.0',
|
version: '0.9.1',
|
||||||
meson_version: '>= 0.64.0',
|
meson_version: '>= 0.64.0',
|
||||||
license: 'LGPL-2.1-or-later AND GPL-3.0-or-later', # LGPL-2.1+ for libs and gst-plugin, GPL-3.0+ for app
|
license: 'LGPL-2.1-or-later AND GPL-3.0-or-later', # LGPL-2.1+ for libs and gst-plugin, GPL-3.0+ for app
|
||||||
default_options: [
|
default_options: [
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
"autodelete": false
|
"autodelete": false
|
||||||
},
|
},
|
||||||
"com.github.rafostar.Clapper.Enhancers": {
|
"com.github.rafostar.Clapper.Enhancers": {
|
||||||
"versions": "master;test;stable",
|
"versions": "stable;test;master",
|
||||||
"directory": "extensions/clapper/enhancers",
|
"directory": "extensions/clapper/enhancers",
|
||||||
"add-ld-path": "lib",
|
"add-ld-path": "lib",
|
||||||
"no-autodownload": false,
|
"no-autodownload": false,
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
"autodelete": false
|
"autodelete": false
|
||||||
},
|
},
|
||||||
"com.github.rafostar.Clapper.Enhancers": {
|
"com.github.rafostar.Clapper.Enhancers": {
|
||||||
"versions": "master;test;stable",
|
"versions": "stable;test;master",
|
||||||
"directory": "extensions/clapper/enhancers",
|
"directory": "extensions/clapper/enhancers",
|
||||||
"add-ld-path": "lib",
|
"add-ld-path": "lib",
|
||||||
"no-autodownload": false,
|
"no-autodownload": false,
|
||||||
|
Submodule pkgs/flatpak/flathub updated: b7c25acba8...3a672be190
@@ -642,18 +642,6 @@ clapper_app_application_command_line (GApplication *app, GApplicationCommandLine
|
|||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
_is_claps_file (GFile *file)
|
|
||||||
{
|
|
||||||
gchar *basename = g_file_get_basename (file);
|
|
||||||
gboolean is_claps;
|
|
||||||
|
|
||||||
is_claps = (basename && g_str_has_suffix (basename, ".claps"));
|
|
||||||
g_free (basename);
|
|
||||||
|
|
||||||
return is_claps;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_item_from_file (GFile *file, ClapperQueue *queue)
|
add_item_from_file (GFile *file, ClapperQueue *queue)
|
||||||
{
|
{
|
||||||
@@ -666,51 +654,6 @@ add_item_from_file (GFile *file, ClapperQueue *queue)
|
|||||||
gst_object_unref (item);
|
gst_object_unref (item);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
add_items_from_claps_file (GFile *file, ClapperQueue *queue)
|
|
||||||
{
|
|
||||||
GDataInputStream *dstream = NULL;
|
|
||||||
GFileInputStream *stream;
|
|
||||||
GError *error = NULL;
|
|
||||||
gchar *line;
|
|
||||||
|
|
||||||
if (!(stream = g_file_read (file, NULL, &error)))
|
|
||||||
goto finish;
|
|
||||||
|
|
||||||
dstream = g_data_input_stream_new (G_INPUT_STREAM (stream));
|
|
||||||
|
|
||||||
while ((line = g_data_input_stream_read_line (
|
|
||||||
dstream, NULL, NULL, &error))) {
|
|
||||||
g_strstrip (line);
|
|
||||||
|
|
||||||
if (strlen (line) > 0) {
|
|
||||||
GFile *tmp_file = gst_uri_is_valid (line)
|
|
||||||
? g_file_new_for_uri (line)
|
|
||||||
: g_file_new_for_path (line);
|
|
||||||
|
|
||||||
if (_is_claps_file (tmp_file))
|
|
||||||
add_items_from_claps_file (tmp_file, queue);
|
|
||||||
else
|
|
||||||
add_item_from_file (tmp_file, queue);
|
|
||||||
|
|
||||||
g_object_unref (tmp_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (line);
|
|
||||||
}
|
|
||||||
|
|
||||||
finish:
|
|
||||||
if (error) {
|
|
||||||
GST_ERROR ("Could not read \".claps\" file, reason: %s", error->message);
|
|
||||||
g_error_free (error);
|
|
||||||
}
|
|
||||||
if (stream) {
|
|
||||||
g_input_stream_close (G_INPUT_STREAM (stream), NULL, NULL);
|
|
||||||
g_object_unref (stream);
|
|
||||||
}
|
|
||||||
g_clear_object (&dstream);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_item_with_subtitles (GFile *media_file,
|
add_item_with_subtitles (GFile *media_file,
|
||||||
GFile *subs_file, ClapperQueue *queue)
|
GFile *subs_file, ClapperQueue *queue)
|
||||||
@@ -779,12 +722,8 @@ clapper_app_application_open (GApplication *app,
|
|||||||
if (!handled) {
|
if (!handled) {
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
for (i = 0; i < n_files; ++i) {
|
for (i = 0; i < n_files; ++i)
|
||||||
if (_is_claps_file (files[i]))
|
add_item_from_file (files[i], queue);
|
||||||
add_items_from_claps_file (files[i], queue);
|
|
||||||
else
|
|
||||||
add_item_from_file (files[i], queue);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
add_only = (g_strcmp0 (hint, "add-only") == 0);
|
add_only = (g_strcmp0 (hint, "add-only") == 0);
|
||||||
|
@@ -582,7 +582,7 @@ _create_pipeline_svg_file_in_thread (GTask *task, GObject *source G_GNUC_UNUSED,
|
|||||||
GVC_t *gvc;
|
GVC_t *gvc;
|
||||||
gchar *path, *template = NULL, *dot_data = NULL, *img_data = NULL;
|
gchar *path, *template = NULL, *dot_data = NULL, *img_data = NULL;
|
||||||
gint fd;
|
gint fd;
|
||||||
guint size = 0;
|
gsize size = 0;
|
||||||
|
|
||||||
if (!(tmp_subdir = _create_tmp_subdir ("pipelines", cancellable, &error)))
|
if (!(tmp_subdir = _create_tmp_subdir ("pipelines", cancellable, &error)))
|
||||||
goto finish;
|
goto finish;
|
||||||
@@ -610,7 +610,16 @@ _create_pipeline_svg_file_in_thread (GTask *task, GObject *source G_GNUC_UNUSED,
|
|||||||
|
|
||||||
gvc = gvContext ();
|
gvc = gvContext ();
|
||||||
gvLayout (gvc, graph, "dot");
|
gvLayout (gvc, graph, "dot");
|
||||||
|
|
||||||
|
#ifdef HAVE_GVC_13
|
||||||
gvRenderData (gvc, graph, "svg", &img_data, &size);
|
gvRenderData (gvc, graph, "svg", &img_data, &size);
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
guint tmp_size = 0; // Temporary uint to satisfy older API
|
||||||
|
gvRenderData (gvc, graph, "svg", &img_data, &tmp_size);
|
||||||
|
size = tmp_size;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
agclose (graph);
|
agclose (graph);
|
||||||
gvFreeContext (gvc);
|
gvFreeContext (gvc);
|
||||||
|
@@ -231,7 +231,7 @@ video_map_cb (GtkWidget *widget, ClapperAppWindow *self)
|
|||||||
|
|
||||||
GST_TRACE_OBJECT (self, "Video map");
|
GST_TRACE_OBJECT (self, "Video map");
|
||||||
|
|
||||||
player = clapper_gtk_video_get_player (CLAPPER_GTK_VIDEO_CAST (self->video));
|
player = clapper_gtk_av_get_player (CLAPPER_GTK_AV_CAST (self->video));
|
||||||
|
|
||||||
g_signal_connect (player, "notify::volume",
|
g_signal_connect (player, "notify::volume",
|
||||||
G_CALLBACK (_player_volume_changed_cb), self);
|
G_CALLBACK (_player_volume_changed_cb), self);
|
||||||
@@ -252,7 +252,7 @@ video_unmap_cb (GtkWidget *widget, ClapperAppWindow *self)
|
|||||||
|
|
||||||
GST_TRACE_OBJECT (self, "Video unmap");
|
GST_TRACE_OBJECT (self, "Video unmap");
|
||||||
|
|
||||||
player = clapper_gtk_video_get_player (CLAPPER_GTK_VIDEO_CAST (self->video));
|
player = clapper_gtk_av_get_player (CLAPPER_GTK_AV_CAST (self->video));
|
||||||
|
|
||||||
g_signal_handlers_disconnect_by_func (player, _player_volume_changed_cb, self);
|
g_signal_handlers_disconnect_by_func (player, _player_volume_changed_cb, self);
|
||||||
g_signal_handlers_disconnect_by_func (player, _player_speed_changed_cb, self);
|
g_signal_handlers_disconnect_by_func (player, _player_speed_changed_cb, self);
|
||||||
@@ -524,7 +524,7 @@ drag_update_cb (GtkGestureDrag *drag,
|
|||||||
static inline void
|
static inline void
|
||||||
_alter_volume (ClapperAppWindow *self, gdouble dy)
|
_alter_volume (ClapperAppWindow *self, gdouble dy)
|
||||||
{
|
{
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (CLAPPER_GTK_VIDEO_CAST (self->video));
|
ClapperPlayer *player = clapper_gtk_av_get_player (CLAPPER_GTK_AV_CAST (self->video));
|
||||||
gdouble volume = clapper_player_get_volume (player);
|
gdouble volume = clapper_player_get_volume (player);
|
||||||
|
|
||||||
/* We do not want for volume to change too suddenly */
|
/* We do not want for volume to change too suddenly */
|
||||||
@@ -547,7 +547,7 @@ _alter_volume (ClapperAppWindow *self, gdouble dy)
|
|||||||
static inline void
|
static inline void
|
||||||
_alter_speed (ClapperAppWindow *self, gdouble dx)
|
_alter_speed (ClapperAppWindow *self, gdouble dx)
|
||||||
{
|
{
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (CLAPPER_GTK_VIDEO_CAST (self->video));
|
ClapperPlayer *player = clapper_gtk_av_get_player (CLAPPER_GTK_AV_CAST (self->video));
|
||||||
gdouble speed = clapper_player_get_speed (player);
|
gdouble speed = clapper_player_get_speed (player);
|
||||||
|
|
||||||
speed -= dx * 0.02;
|
speed -= dx * 0.02;
|
||||||
@@ -571,8 +571,7 @@ _begin_seek_operation (ClapperAppWindow *self)
|
|||||||
if (self->seeking)
|
if (self->seeking)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
player = clapper_gtk_video_get_player (
|
player = clapper_gtk_av_get_player (CLAPPER_GTK_AV_CAST (self->video));
|
||||||
CLAPPER_GTK_VIDEO_CAST (self->video));
|
|
||||||
queue = clapper_player_get_queue (player);
|
queue = clapper_player_get_queue (player);
|
||||||
current_item = clapper_queue_get_current_item (queue);
|
current_item = clapper_queue_get_current_item (queue);
|
||||||
|
|
||||||
@@ -600,8 +599,8 @@ static void
|
|||||||
_end_seek_operation (ClapperAppWindow *self)
|
_end_seek_operation (ClapperAppWindow *self)
|
||||||
{
|
{
|
||||||
if (self->seeking && self->current_duration > 0) {
|
if (self->seeking && self->current_duration > 0) {
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (
|
ClapperPlayer *player = clapper_gtk_av_get_player (
|
||||||
CLAPPER_GTK_VIDEO_CAST (self->video));
|
CLAPPER_GTK_AV_CAST (self->video));
|
||||||
|
|
||||||
clapper_player_seek_custom (player, self->pending_position,
|
clapper_player_seek_custom (player, self->pending_position,
|
||||||
g_settings_get_int (self->settings, "seek-method"));
|
g_settings_get_int (self->settings, "seek-method"));
|
||||||
@@ -764,8 +763,8 @@ _handle_seek_key_press (ClapperAppWindow *self, gboolean forward)
|
|||||||
static void
|
static void
|
||||||
_handle_chapter_key_press (ClapperAppWindow *self, gboolean forward)
|
_handle_chapter_key_press (ClapperAppWindow *self, gboolean forward)
|
||||||
{
|
{
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (
|
ClapperPlayer *player = clapper_gtk_av_get_player (
|
||||||
CLAPPER_GTK_VIDEO_CAST (self->video));
|
CLAPPER_GTK_AV_CAST (self->video));
|
||||||
ClapperQueue *queue = clapper_player_get_queue (player);
|
ClapperQueue *queue = clapper_player_get_queue (player);
|
||||||
ClapperMediaItem *current_item = clapper_queue_get_current_item (queue);
|
ClapperMediaItem *current_item = clapper_queue_get_current_item (queue);
|
||||||
ClapperTimeline *timeline;
|
ClapperTimeline *timeline;
|
||||||
@@ -855,8 +854,8 @@ _handle_chapter_key_press (ClapperAppWindow *self, gboolean forward)
|
|||||||
static void
|
static void
|
||||||
_handle_item_key_press (ClapperAppWindow *self, gboolean forward)
|
_handle_item_key_press (ClapperAppWindow *self, gboolean forward)
|
||||||
{
|
{
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (
|
ClapperPlayer *player = clapper_gtk_av_get_player (
|
||||||
CLAPPER_GTK_VIDEO_CAST (self->video));
|
CLAPPER_GTK_AV_CAST (self->video));
|
||||||
ClapperQueue *queue = clapper_player_get_queue (player);
|
ClapperQueue *queue = clapper_player_get_queue (player);
|
||||||
guint prev_index, index;
|
guint prev_index, index;
|
||||||
|
|
||||||
@@ -864,7 +863,7 @@ _handle_item_key_press (ClapperAppWindow *self, gboolean forward)
|
|||||||
|
|
||||||
prev_index = clapper_queue_get_current_index (queue);
|
prev_index = clapper_queue_get_current_index (queue);
|
||||||
gtk_widget_activate_action (self->video,
|
gtk_widget_activate_action (self->video,
|
||||||
(forward) ? "video.next-item" : "video.previous-item", NULL);
|
(forward) ? "av.next-item" : "av.previous-item", NULL);
|
||||||
index = clapper_queue_get_current_index (queue);
|
index = clapper_queue_get_current_index (queue);
|
||||||
|
|
||||||
/* Notify only when changed */
|
/* Notify only when changed */
|
||||||
@@ -881,14 +880,14 @@ _handle_speed_key_press (ClapperAppWindow *self, gboolean forward)
|
|||||||
forward ^= (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL);
|
forward ^= (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL);
|
||||||
|
|
||||||
gtk_widget_activate_action (self->video,
|
gtk_widget_activate_action (self->video,
|
||||||
(forward) ? "video.speed-up" : "video.speed-down", NULL);
|
(forward) ? "av.speed-up" : "av.speed-down", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
_handle_progression_key_press (ClapperAppWindow *self)
|
_handle_progression_key_press (ClapperAppWindow *self)
|
||||||
{
|
{
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (
|
ClapperPlayer *player = clapper_gtk_av_get_player (
|
||||||
CLAPPER_GTK_VIDEO_CAST (self->video));
|
CLAPPER_GTK_AV_CAST (self->video));
|
||||||
ClapperQueue *queue = clapper_player_get_queue (player);
|
ClapperQueue *queue = clapper_player_get_queue (player);
|
||||||
ClapperQueueProgressionMode mode;
|
ClapperQueueProgressionMode mode;
|
||||||
const gchar *icon = NULL, *label = NULL;
|
const gchar *icon = NULL, *label = NULL;
|
||||||
@@ -908,11 +907,11 @@ key_pressed_cb (GtkEventControllerKey *controller, guint keyval,
|
|||||||
switch (keyval) {
|
switch (keyval) {
|
||||||
case GDK_KEY_Up:
|
case GDK_KEY_Up:
|
||||||
if ((state & GDK_MODIFIER_MASK) == 0)
|
if ((state & GDK_MODIFIER_MASK) == 0)
|
||||||
gtk_widget_activate_action (self->video, "video.volume-up", NULL);
|
gtk_widget_activate_action (self->video, "av.volume-up", NULL);
|
||||||
break;
|
break;
|
||||||
case GDK_KEY_Down:
|
case GDK_KEY_Down:
|
||||||
if ((state & GDK_MODIFIER_MASK) == 0)
|
if ((state & GDK_MODIFIER_MASK) == 0)
|
||||||
gtk_widget_activate_action (self->video, "video.volume-down", NULL);
|
gtk_widget_activate_action (self->video, "av.volume-down", NULL);
|
||||||
break;
|
break;
|
||||||
case GDK_KEY_Left:
|
case GDK_KEY_Left:
|
||||||
if ((state & GDK_MODIFIER_MASK) == 0) {
|
if ((state & GDK_MODIFIER_MASK) == 0) {
|
||||||
@@ -943,7 +942,7 @@ key_pressed_cb (GtkEventControllerKey *controller, guint keyval,
|
|||||||
case GDK_KEY_space:
|
case GDK_KEY_space:
|
||||||
case GDK_KEY_k:
|
case GDK_KEY_k:
|
||||||
if (!self->key_held && (state & GDK_MODIFIER_MASK) == 0)
|
if (!self->key_held && (state & GDK_MODIFIER_MASK) == 0)
|
||||||
gtk_widget_activate_action (self->video, "video.toggle-play", NULL);
|
gtk_widget_activate_action (self->video, "av.toggle-play", NULL);
|
||||||
break;
|
break;
|
||||||
case GDK_KEY_less:
|
case GDK_KEY_less:
|
||||||
if (!self->key_held) // Needs seek (action is slow)
|
if (!self->key_held) // Needs seek (action is slow)
|
||||||
@@ -955,7 +954,7 @@ key_pressed_cb (GtkEventControllerKey *controller, guint keyval,
|
|||||||
break;
|
break;
|
||||||
case GDK_KEY_m:
|
case GDK_KEY_m:
|
||||||
if (!self->key_held && (state & GDK_MODIFIER_MASK) == 0)
|
if (!self->key_held && (state & GDK_MODIFIER_MASK) == 0)
|
||||||
gtk_widget_activate_action (self->video, "video.toggle-mute", NULL);
|
gtk_widget_activate_action (self->video, "av.toggle-mute", NULL);
|
||||||
break;
|
break;
|
||||||
case GDK_KEY_p:
|
case GDK_KEY_p:
|
||||||
if (!self->key_held && (state & GDK_MODIFIER_MASK) == 0)
|
if (!self->key_held && (state & GDK_MODIFIER_MASK) == 0)
|
||||||
@@ -1123,7 +1122,7 @@ clapper_app_window_get_video (ClapperAppWindow *self)
|
|||||||
ClapperPlayer *
|
ClapperPlayer *
|
||||||
clapper_app_window_get_player (ClapperAppWindow *self)
|
clapper_app_window_get_player (ClapperAppWindow *self)
|
||||||
{
|
{
|
||||||
return clapper_gtk_video_get_player (CLAPPER_GTK_VIDEO_CAST (self->video));
|
return clapper_gtk_av_get_player (CLAPPER_GTK_AV_CAST (self->video));
|
||||||
}
|
}
|
||||||
|
|
||||||
ClapperAppWindowExtraOptions *
|
ClapperAppWindowExtraOptions *
|
||||||
@@ -1198,6 +1197,7 @@ clapper_app_window_init (ClapperAppWindow *self)
|
|||||||
GtkSettings *settings;
|
GtkSettings *settings;
|
||||||
GtkWidget *dummy_titlebar;
|
GtkWidget *dummy_titlebar;
|
||||||
gint distance = 0;
|
gint distance = 0;
|
||||||
|
GtkWindowGroup *group;
|
||||||
|
|
||||||
gtk_widget_set_size_request (GTK_WIDGET (self),
|
gtk_widget_set_size_request (GTK_WIDGET (self),
|
||||||
MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT);
|
MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT);
|
||||||
@@ -1229,6 +1229,11 @@ clapper_app_window_init (ClapperAppWindow *self)
|
|||||||
|
|
||||||
gtk_drop_target_set_gtypes (self->drop_target,
|
gtk_drop_target_set_gtypes (self->drop_target,
|
||||||
(GType[3]) { GDK_TYPE_FILE_LIST, G_TYPE_FILE, G_TYPE_STRING }, 3);
|
(GType[3]) { GDK_TYPE_FILE_LIST, G_TYPE_FILE, G_TYPE_STRING }, 3);
|
||||||
|
|
||||||
|
/* Add to window group */
|
||||||
|
group = gtk_window_group_new ();
|
||||||
|
gtk_window_group_add_window (group, GTK_WINDOW (self));
|
||||||
|
g_object_unref (group);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1237,6 +1242,8 @@ clapper_app_window_constructed (GObject *object)
|
|||||||
ClapperAppWindow *self = CLAPPER_APP_WINDOW_CAST (object);
|
ClapperAppWindow *self = CLAPPER_APP_WINDOW_CAST (object);
|
||||||
ClapperPlayer *player = clapper_app_window_get_player (self);
|
ClapperPlayer *player = clapper_app_window_get_player (self);
|
||||||
ClapperQueue *queue = clapper_player_get_queue (player);
|
ClapperQueue *queue = clapper_player_get_queue (player);
|
||||||
|
ClapperEnhancerProxyList *proxies = clapper_player_get_enhancer_proxies (player);
|
||||||
|
ClapperEnhancerProxy *proxy;
|
||||||
ClapperGtkExtraMenuButton *button;
|
ClapperGtkExtraMenuButton *button;
|
||||||
AdwStyleManager *manager;
|
AdwStyleManager *manager;
|
||||||
|
|
||||||
@@ -1250,10 +1257,6 @@ clapper_app_window_constructed (GObject *object)
|
|||||||
#if (CLAPPER_HAVE_MPRIS || CLAPPER_HAVE_SERVER || CLAPPER_HAVE_DISCOVERER)
|
#if (CLAPPER_HAVE_MPRIS || CLAPPER_HAVE_SERVER || CLAPPER_HAVE_DISCOVERER)
|
||||||
ClapperFeature *feature = NULL;
|
ClapperFeature *feature = NULL;
|
||||||
#endif
|
#endif
|
||||||
#if (!CLAPPER_HAVE_MPRIS || !CLAPPER_HAVE_SERVER || !CLAPPER_HAVE_DISCOVERER)
|
|
||||||
ClapperEnhancerProxyList *proxies = clapper_player_get_enhancer_proxies (player);
|
|
||||||
ClapperEnhancerProxy *proxy;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gchar mpris_name[45];
|
gchar mpris_name[45];
|
||||||
g_snprintf (mpris_name, sizeof (mpris_name),
|
g_snprintf (mpris_name, sizeof (mpris_name),
|
||||||
@@ -1262,7 +1265,6 @@ clapper_app_window_constructed (GObject *object)
|
|||||||
self->settings = g_settings_new (CLAPPER_APP_ID);
|
self->settings = g_settings_new (CLAPPER_APP_ID);
|
||||||
self->last_volume = PERCENTAGE_ROUND (g_settings_get_double (self->settings, "volume"));
|
self->last_volume = PERCENTAGE_ROUND (g_settings_get_double (self->settings, "volume"));
|
||||||
|
|
||||||
#if !CLAPPER_HAVE_MPRIS
|
|
||||||
if ((proxy = clapper_enhancer_proxy_list_get_proxy_by_module (proxies, "clapper-mpris"))) {
|
if ((proxy = clapper_enhancer_proxy_list_get_proxy_by_module (proxies, "clapper-mpris"))) {
|
||||||
clapper_enhancer_proxy_set_locally (proxy,
|
clapper_enhancer_proxy_set_locally (proxy,
|
||||||
"own-name", mpris_name,
|
"own-name", mpris_name,
|
||||||
@@ -1270,14 +1272,15 @@ clapper_app_window_constructed (GObject *object)
|
|||||||
"desktop-entry", CLAPPER_APP_ID,
|
"desktop-entry", CLAPPER_APP_ID,
|
||||||
"queue-controllable", TRUE, NULL);
|
"queue-controllable", TRUE, NULL);
|
||||||
gst_object_unref (proxy);
|
gst_object_unref (proxy);
|
||||||
}
|
} else {
|
||||||
#else
|
#if CLAPPER_HAVE_MPRIS
|
||||||
feature = CLAPPER_FEATURE (clapper_mpris_new (
|
feature = CLAPPER_FEATURE (clapper_mpris_new (
|
||||||
mpris_name, CLAPPER_APP_NAME, CLAPPER_APP_ID));
|
mpris_name, CLAPPER_APP_NAME, CLAPPER_APP_ID));
|
||||||
clapper_mpris_set_queue_controllable (CLAPPER_MPRIS (feature), TRUE);
|
clapper_mpris_set_queue_controllable (CLAPPER_MPRIS (feature), TRUE);
|
||||||
clapper_player_add_feature (player, feature);
|
clapper_player_add_feature (player, feature);
|
||||||
gst_object_unref (feature);
|
gst_object_unref (feature);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#if CLAPPER_HAVE_SERVER
|
#if CLAPPER_HAVE_SERVER
|
||||||
feature = CLAPPER_FEATURE (clapper_server_new ());
|
feature = CLAPPER_FEATURE (clapper_server_new ());
|
||||||
|
@@ -31,8 +31,10 @@
|
|||||||
gint
|
gint
|
||||||
main (gint argc, gchar **argv)
|
main (gint argc, gchar **argv)
|
||||||
{
|
{
|
||||||
const gchar *clapper_ldir;
|
|
||||||
GApplication *application;
|
GApplication *application;
|
||||||
|
ClapperEnhancerProxyList *proxies;
|
||||||
|
const gchar *clapper_ldir;
|
||||||
|
guint i, n_proxies;
|
||||||
gint status;
|
gint status;
|
||||||
|
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
@@ -64,6 +66,15 @@ main (gint argc, gchar **argv)
|
|||||||
resolution = clapper_app_utils_win_hi_res_clock_start ();
|
resolution = clapper_app_utils_win_hi_res_clock_start ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
proxies = clapper_get_global_enhancer_proxies ();
|
||||||
|
n_proxies = clapper_enhancer_proxy_list_get_n_proxies (proxies);
|
||||||
|
|
||||||
|
/* Allow usage of all enhancers */
|
||||||
|
for (i = 0; i < n_proxies; ++i) {
|
||||||
|
ClapperEnhancerProxy *proxy = clapper_enhancer_proxy_list_peek_proxy (proxies, i);
|
||||||
|
clapper_enhancer_proxy_set_target_creation_allowed (proxy, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
application = clapper_app_application_new ();
|
application = clapper_app_application_new ();
|
||||||
|
|
||||||
status = g_application_run (application, argc, argv);
|
status = g_application_run (application, argc, argv);
|
||||||
|
@@ -105,6 +105,9 @@ if not pp_option.disabled()
|
|||||||
if cgraph_dep.found() and gvc_dep.found()
|
if cgraph_dep.found() and gvc_dep.found()
|
||||||
clapperapp_c_args += ['-DHAVE_GRAPHVIZ']
|
clapperapp_c_args += ['-DHAVE_GRAPHVIZ']
|
||||||
clapperapp_deps += [cgraph_dep, gvc_dep]
|
clapperapp_deps += [cgraph_dep, gvc_dep]
|
||||||
|
if gvc_dep.version().version_compare('>= 13.0.0')
|
||||||
|
clapperapp_c_args += ['-DHAVE_GVC_13']
|
||||||
|
endif
|
||||||
clapperapp_available_functionalities += 'pipeline-preview'
|
clapperapp_available_functionalities += 'pipeline-preview'
|
||||||
elif pp_option.enabled()
|
elif pp_option.enabled()
|
||||||
error('pipeline-preview option was enabled, but required dependencies were not found')
|
error('pipeline-preview option was enabled, but required dependencies were not found')
|
||||||
|
268
src/lib/clapper-gtk/clapper-gtk-audio.c
Normal file
268
src/lib/clapper-gtk/clapper-gtk-audio.c
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
/* Clapper GTK Integration Library
|
||||||
|
* Copyright (C) 2025 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, see
|
||||||
|
* <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClapperGtkAudio:
|
||||||
|
*
|
||||||
|
* A GTK widget for audio playback with Clapper API.
|
||||||
|
*
|
||||||
|
* #ClapperGtkAudio is a widget meant for integrating audio playback
|
||||||
|
* within GTK application. It exposes [class@Clapper.Player] through its
|
||||||
|
* base class [property@ClapperGtk.Av:player] property.
|
||||||
|
*
|
||||||
|
* Other widgets (buttons, seek bar, etc.) provided by `ClapperGtk` library, once placed
|
||||||
|
* anywhere inside audio container (including nesting within another widget like [class@Gtk.Box])
|
||||||
|
* will automatically control #ClapperGtkAudio they are within. This allows to freely create
|
||||||
|
* custom UI best suited for specific application.
|
||||||
|
*
|
||||||
|
* # Basic usage
|
||||||
|
*
|
||||||
|
* A typical use case is to embed audio widget as part of your app where audio playback
|
||||||
|
* is needed (can be even the very first child of the window). Get the [class@Clapper.Player]
|
||||||
|
* belonging to the AV widget and start adding new [class@Clapper.MediaItem] items to the
|
||||||
|
* [class@Clapper.Queue] for playback. For more information please refer to the Clapper
|
||||||
|
* playback library documentation.
|
||||||
|
*
|
||||||
|
* # Actions
|
||||||
|
*
|
||||||
|
* You can use built-in actions of parent [class@ClapperGtk.Av].
|
||||||
|
* See its documentation for the list of available ones.
|
||||||
|
*
|
||||||
|
* # ClapperGtkAudio as GtkBuildable
|
||||||
|
*
|
||||||
|
* #ClapperGtkAudio implementation of the [iface@Gtk.Buildable] interface supports
|
||||||
|
* placing a single widget (which might then hold multiple widgets) as `<child>` element.
|
||||||
|
*
|
||||||
|
* ```xml
|
||||||
|
* <object class="ClapperGtkAudio" id="audio">
|
||||||
|
* <child>
|
||||||
|
* <object class="GtkBox">
|
||||||
|
* <property name="orientation">horizontal</property>
|
||||||
|
* <child>
|
||||||
|
* <object class="ClapperGtkPreviousItemButton">
|
||||||
|
* </child>
|
||||||
|
* <child>
|
||||||
|
* <object class="ClapperGtkTogglePlayButton">
|
||||||
|
* </child>
|
||||||
|
* <child>
|
||||||
|
* <object class="ClapperGtkNextItemButton">
|
||||||
|
* </child>
|
||||||
|
* </object>
|
||||||
|
* </child>
|
||||||
|
* </object>
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Since: 0.10
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "clapper-gtk-audio.h"
|
||||||
|
|
||||||
|
#define GST_CAT_DEFAULT clapper_gtk_audio_debug
|
||||||
|
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||||
|
|
||||||
|
struct _ClapperGtkAudio
|
||||||
|
{
|
||||||
|
ClapperGtkAv parent;
|
||||||
|
|
||||||
|
GtkWidget *child;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
clapper_gtk_audio_add_child (GtkBuildable *buildable,
|
||||||
|
GtkBuilder *builder, GObject *child, const char *type)
|
||||||
|
{
|
||||||
|
if (GTK_IS_WIDGET (child)) {
|
||||||
|
clapper_gtk_audio_set_child (CLAPPER_GTK_AUDIO (buildable), GTK_WIDGET (child));
|
||||||
|
} else {
|
||||||
|
GtkBuildableIface *parent_iface = g_type_interface_peek_parent (GTK_BUILDABLE_GET_IFACE (buildable));
|
||||||
|
parent_iface->add_child (buildable, builder, child, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_buildable_iface_init (GtkBuildableIface *iface)
|
||||||
|
{
|
||||||
|
iface->add_child = clapper_gtk_audio_add_child;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define parent_class clapper_gtk_audio_parent_class
|
||||||
|
G_DEFINE_TYPE_WITH_CODE (ClapperGtkAudio, clapper_gtk_audio, CLAPPER_GTK_TYPE_AV,
|
||||||
|
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, _buildable_iface_init))
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
PROP_CHILD,
|
||||||
|
PROP_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
static GParamSpec *param_specs[PROP_LAST] = { NULL, };
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
_unparent_child (ClapperGtkAudio *self)
|
||||||
|
{
|
||||||
|
GtkWidget *child;
|
||||||
|
|
||||||
|
if ((child = gtk_widget_get_first_child (GTK_WIDGET (self))))
|
||||||
|
gtk_widget_unparent (child);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clapper_gtk_audio_new:
|
||||||
|
*
|
||||||
|
* Creates a new #ClapperGtkAudio instance.
|
||||||
|
*
|
||||||
|
* Newly created audio widget will also have set "scaletempo" GStreamer element
|
||||||
|
* as default audio filter on its [class@Clapper.Player] and disable video and
|
||||||
|
* subtitle streams. This can be changed after construction by setting
|
||||||
|
* corresponding player properties.
|
||||||
|
*
|
||||||
|
* Returns: a new audio #GtkWidget.
|
||||||
|
*/
|
||||||
|
GtkWidget *
|
||||||
|
clapper_gtk_audio_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (CLAPPER_GTK_TYPE_AUDIO, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clapper_gtk_audio_set_child:
|
||||||
|
* @audio: a #ClapperGtkAudio
|
||||||
|
* @child: (nullable): a #GtkWidget
|
||||||
|
*
|
||||||
|
* Set a child #GtkWidget of @audio.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clapper_gtk_audio_set_child (ClapperGtkAudio *self, GtkWidget *child)
|
||||||
|
{
|
||||||
|
g_return_if_fail (CLAPPER_GTK_IS_AUDIO (self));
|
||||||
|
g_return_if_fail (GTK_IS_WIDGET (child));
|
||||||
|
|
||||||
|
_unparent_child (self);
|
||||||
|
if (child)
|
||||||
|
gtk_widget_set_parent (child, GTK_WIDGET (self));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clapper_gtk_audio_get_child:
|
||||||
|
* @audio: a #ClapperGtkAudio
|
||||||
|
*
|
||||||
|
* Get a child #GtkWidget of @audio.
|
||||||
|
*
|
||||||
|
* Returns: (transfer none) (nullable): #GtkWidget set as child.
|
||||||
|
*/
|
||||||
|
GtkWidget *
|
||||||
|
clapper_gtk_audio_get_child (ClapperGtkAudio *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLAPPER_GTK_IS_AUDIO (self), NULL);
|
||||||
|
|
||||||
|
return gtk_widget_get_first_child (GTK_WIDGET (self));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clapper_gtk_audio_init (ClapperGtkAudio *self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clapper_gtk_audio_constructed (GObject *object)
|
||||||
|
{
|
||||||
|
ClapperGtkAudio *self = CLAPPER_GTK_AUDIO_CAST (object);
|
||||||
|
ClapperPlayer *player;
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||||
|
|
||||||
|
player = clapper_gtk_av_get_player (CLAPPER_GTK_AV_CAST (self));
|
||||||
|
|
||||||
|
clapper_player_set_video_enabled (player, FALSE);
|
||||||
|
clapper_player_set_subtitles_enabled (player, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clapper_gtk_audio_dispose (GObject *object)
|
||||||
|
{
|
||||||
|
ClapperGtkAudio *self = CLAPPER_GTK_AUDIO_CAST (object);
|
||||||
|
|
||||||
|
_unparent_child (self);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clapper_gtk_audio_get_property (GObject *object, guint prop_id,
|
||||||
|
GValue *value, GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClapperGtkAudio *self = CLAPPER_GTK_AUDIO_CAST (object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_CHILD:
|
||||||
|
g_value_set_object (value, clapper_gtk_audio_get_child (self));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clapper_gtk_audio_set_property (GObject *object, guint prop_id,
|
||||||
|
const GValue *value, GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClapperGtkAudio *self = CLAPPER_GTK_AUDIO_CAST (object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_CHILD:
|
||||||
|
clapper_gtk_audio_set_child (self, g_value_get_object (value));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clapper_gtk_audio_class_init (ClapperGtkAudioClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||||
|
GtkWidgetClass *widget_class = (GtkWidgetClass *) klass;
|
||||||
|
|
||||||
|
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clappergtkaudio", GST_DEBUG_FG_MAGENTA,
|
||||||
|
"Clapper GTK Audio");
|
||||||
|
|
||||||
|
gobject_class->constructed = clapper_gtk_audio_constructed;
|
||||||
|
gobject_class->get_property = clapper_gtk_audio_get_property;
|
||||||
|
gobject_class->set_property = clapper_gtk_audio_set_property;
|
||||||
|
gobject_class->dispose = clapper_gtk_audio_dispose;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClapperGtkAudio:child:
|
||||||
|
*
|
||||||
|
* The child widget of `ClapperGtkAudio`.
|
||||||
|
*/
|
||||||
|
param_specs[PROP_CHILD] = g_param_spec_object ("child",
|
||||||
|
NULL, NULL, GTK_TYPE_WIDGET,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
|
g_object_class_install_properties (gobject_class, PROP_LAST, param_specs);
|
||||||
|
|
||||||
|
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||||
|
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_GENERIC);
|
||||||
|
gtk_widget_class_set_css_name (widget_class, "clapper-gtk-audio");
|
||||||
|
}
|
49
src/lib/clapper-gtk/clapper-gtk-audio.h
Normal file
49
src/lib/clapper-gtk/clapper-gtk-audio.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/* Clapper GTK Integration Library
|
||||||
|
* Copyright (C) 2025 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, see
|
||||||
|
* <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(__CLAPPER_GTK_INSIDE__) && !defined(CLAPPER_GTK_COMPILATION)
|
||||||
|
#error "Only <clapper-gtk/clapper-gtk.h> can be included directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#include <clapper-gtk/clapper-gtk-av.h>
|
||||||
|
#include <clapper-gtk/clapper-gtk-visibility.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define CLAPPER_GTK_TYPE_AUDIO (clapper_gtk_audio_get_type())
|
||||||
|
#define CLAPPER_GTK_AUDIO_CAST(obj) ((ClapperGtkAudio *)(obj))
|
||||||
|
|
||||||
|
CLAPPER_GTK_API
|
||||||
|
G_DECLARE_FINAL_TYPE (ClapperGtkAudio, clapper_gtk_audio, CLAPPER_GTK, AUDIO, ClapperGtkAv)
|
||||||
|
|
||||||
|
CLAPPER_GTK_API
|
||||||
|
GtkWidget * clapper_gtk_audio_new (void);
|
||||||
|
|
||||||
|
CLAPPER_GTK_API
|
||||||
|
void clapper_gtk_audio_set_child (ClapperGtkAudio *audio, GtkWidget *child);
|
||||||
|
|
||||||
|
CLAPPER_GTK_API
|
||||||
|
GtkWidget * clapper_gtk_audio_get_child (ClapperGtkAudio *audio);
|
||||||
|
|
||||||
|
G_END_DECLS
|
645
src/lib/clapper-gtk/clapper-gtk-av.c
Normal file
645
src/lib/clapper-gtk/clapper-gtk-av.c
Normal file
@@ -0,0 +1,645 @@
|
|||||||
|
/* Clapper GTK Integration Library
|
||||||
|
* Copyright (C) 2025 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, see
|
||||||
|
* <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClapperGtkAv:
|
||||||
|
*
|
||||||
|
* A base class for GTK audio and video widgets.
|
||||||
|
*
|
||||||
|
* See its descendants: [class@ClapperGtk.Audio] and [class@ClapperGtk.Video].
|
||||||
|
*
|
||||||
|
* # Actions
|
||||||
|
*
|
||||||
|
* #ClapperGtkAv defines a set of built-in actions:
|
||||||
|
*
|
||||||
|
* ```yaml
|
||||||
|
* - "av.toggle-play": toggle play/pause
|
||||||
|
* - "av.play": start/resume playback
|
||||||
|
* - "av.pause": pause playback
|
||||||
|
* - "av.stop": stop playback
|
||||||
|
* - "av.seek": seek to position (variant "d")
|
||||||
|
* - "av.seek-custom": seek to position using seek method (variant "(di)")
|
||||||
|
* - "av.toggle-mute": toggle mute state
|
||||||
|
* - "av.set-mute": set mute state (variant "b")
|
||||||
|
* - "av.volume-up": increase volume by 2%
|
||||||
|
* - "av.volume-down": decrease volume by 2%
|
||||||
|
* - "av.set-volume": set volume to specified value (variant "d")
|
||||||
|
* - "av.speed-up": increase speed (from 0.05x - 2x range to nearest quarter)
|
||||||
|
* - "av.speed-down": decrease speed (from 0.05x - 2x range to nearest quarter)
|
||||||
|
* - "av.set-speed": set speed to specified value (variant "d")
|
||||||
|
* - "av.previous-item": select previous item in queue
|
||||||
|
* - "av.next-item": select next item in queue
|
||||||
|
* - "av.select-item": select item at specified index in queue (variant "u")
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Since: 0.10
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "clapper-gtk-av.h"
|
||||||
|
|
||||||
|
#define PERCENTAGE_ROUND(a) (round ((gdouble) a / 0.01) * 0.01)
|
||||||
|
|
||||||
|
#define DEFAULT_AUTO_INHIBIT FALSE
|
||||||
|
|
||||||
|
#define GST_CAT_DEFAULT clapper_gtk_av_debug
|
||||||
|
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||||
|
|
||||||
|
typedef struct _ClapperGtkAvPrivate ClapperGtkAvPrivate;
|
||||||
|
|
||||||
|
struct _ClapperGtkAvPrivate
|
||||||
|
{
|
||||||
|
ClapperPlayer *player;
|
||||||
|
gboolean auto_inhibit;
|
||||||
|
|
||||||
|
guint inhibit_cookie;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define parent_class clapper_gtk_av_parent_class
|
||||||
|
G_DEFINE_TYPE_WITH_PRIVATE (ClapperGtkAv, clapper_gtk_av, GTK_TYPE_WIDGET)
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
PROP_PLAYER,
|
||||||
|
PROP_AUTO_INHIBIT,
|
||||||
|
PROP_INHIBITED,
|
||||||
|
PROP_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
static gboolean provider_added = FALSE;
|
||||||
|
static GParamSpec *param_specs[PROP_LAST] = { NULL, };
|
||||||
|
|
||||||
|
static void
|
||||||
|
toggle_play_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||||
|
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||||
|
|
||||||
|
switch (clapper_player_get_state (player)) {
|
||||||
|
case CLAPPER_PLAYER_STATE_PLAYING:
|
||||||
|
clapper_player_pause (player);
|
||||||
|
break;
|
||||||
|
case CLAPPER_PLAYER_STATE_STOPPED:
|
||||||
|
case CLAPPER_PLAYER_STATE_PAUSED:
|
||||||
|
clapper_player_play (player);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
play_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||||
|
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||||
|
|
||||||
|
clapper_player_play (player);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pause_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||||
|
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||||
|
|
||||||
|
clapper_player_pause (player);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
stop_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||||
|
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||||
|
|
||||||
|
clapper_player_stop (player);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
seek_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||||
|
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||||
|
gdouble position = g_variant_get_double (parameter);
|
||||||
|
|
||||||
|
clapper_player_seek (player, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
seek_custom_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||||
|
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||||
|
ClapperPlayerSeekMethod method = CLAPPER_PLAYER_SEEK_METHOD_NORMAL;
|
||||||
|
gdouble position = 0;
|
||||||
|
|
||||||
|
g_variant_get (parameter, "(di)", &position, &method);
|
||||||
|
clapper_player_seek_custom (player, position, method);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
toggle_mute_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||||
|
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||||
|
|
||||||
|
clapper_player_set_mute (player, !clapper_player_get_mute (player));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_mute_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||||
|
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||||
|
gboolean mute = g_variant_get_boolean (parameter);
|
||||||
|
|
||||||
|
clapper_player_set_mute (player, mute);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
volume_up_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||||
|
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||||
|
gdouble volume = (clapper_player_get_volume (player) + 0.02);
|
||||||
|
|
||||||
|
if (volume > 2.0)
|
||||||
|
volume = 2.0;
|
||||||
|
|
||||||
|
clapper_player_set_volume (player, PERCENTAGE_ROUND (volume));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
volume_down_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||||
|
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||||
|
gdouble volume = (clapper_player_get_volume (player) - 0.02);
|
||||||
|
|
||||||
|
if (volume < 0)
|
||||||
|
volume = 0;
|
||||||
|
|
||||||
|
clapper_player_set_volume (player, PERCENTAGE_ROUND (volume));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_volume_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||||
|
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||||
|
gdouble volume = g_variant_get_double (parameter);
|
||||||
|
|
||||||
|
clapper_player_set_volume (player, volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
speed_up_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||||
|
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||||
|
gdouble dest, speed = clapper_player_get_speed (player);
|
||||||
|
|
||||||
|
if (speed >= 2.0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dest = 0.25;
|
||||||
|
while (speed >= dest)
|
||||||
|
dest += 0.25;
|
||||||
|
|
||||||
|
if (dest > 2.0)
|
||||||
|
dest = 2.0;
|
||||||
|
|
||||||
|
clapper_player_set_speed (player, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
speed_down_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||||
|
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||||
|
gdouble dest, speed = clapper_player_get_speed (player);
|
||||||
|
|
||||||
|
if (speed <= 0.05)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dest = 2.0;
|
||||||
|
while (speed <= dest)
|
||||||
|
dest -= 0.25;
|
||||||
|
|
||||||
|
if (dest < 0.05)
|
||||||
|
dest = 0.05;
|
||||||
|
|
||||||
|
clapper_player_set_speed (player, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_speed_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||||
|
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||||
|
gdouble speed = g_variant_get_double (parameter);
|
||||||
|
|
||||||
|
clapper_player_set_speed (player, speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
previous_item_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||||
|
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||||
|
|
||||||
|
clapper_queue_select_previous_item (clapper_player_get_queue (player));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
next_item_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||||
|
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||||
|
|
||||||
|
clapper_queue_select_next_item (clapper_player_get_queue (player));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
select_item_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||||
|
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||||
|
guint index = g_variant_get_uint32 (parameter);
|
||||||
|
|
||||||
|
clapper_queue_select_index (clapper_player_get_queue (player), index);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ensure_css_provider (void)
|
||||||
|
{
|
||||||
|
GdkDisplay *display;
|
||||||
|
|
||||||
|
if (provider_added)
|
||||||
|
return;
|
||||||
|
|
||||||
|
display = gdk_display_get_default ();
|
||||||
|
|
||||||
|
if (G_LIKELY (display != NULL)) {
|
||||||
|
GtkCssProvider *provider = gtk_css_provider_new ();
|
||||||
|
gtk_css_provider_load_from_resource (provider,
|
||||||
|
CLAPPER_GTK_RESOURCE_PREFIX "/css/styles.css");
|
||||||
|
|
||||||
|
gtk_style_context_add_provider_for_display (display,
|
||||||
|
(GtkStyleProvider *) provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION - 1);
|
||||||
|
g_object_unref (provider);
|
||||||
|
|
||||||
|
provider_added = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
_set_inhibit_session (ClapperGtkAv *self, gboolean inhibit)
|
||||||
|
{
|
||||||
|
ClapperGtkAvPrivate *priv = clapper_gtk_av_get_instance_private (self);
|
||||||
|
GtkRoot *root;
|
||||||
|
GApplication *app;
|
||||||
|
gboolean inhibited = (priv->inhibit_cookie != 0);
|
||||||
|
|
||||||
|
if (inhibited == inhibit)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (self, "Trying to %sinhibit session...", (inhibit) ? "" : "un");
|
||||||
|
|
||||||
|
root = gtk_widget_get_root (GTK_WIDGET (self));
|
||||||
|
|
||||||
|
if (!root && !GTK_IS_WINDOW (root)) {
|
||||||
|
GST_WARNING_OBJECT (self, "Cannot %sinhibit session "
|
||||||
|
"without root window", (inhibit) ? "" : "un");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOTE: Not using application from window prop,
|
||||||
|
* as it goes away early when unrooting */
|
||||||
|
app = g_application_get_default ();
|
||||||
|
|
||||||
|
if (!app && !GTK_IS_APPLICATION (app)) {
|
||||||
|
GST_WARNING_OBJECT (self, "Cannot %sinhibit session "
|
||||||
|
"without window application set", (inhibit) ? "" : "un");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inhibited) {
|
||||||
|
gtk_application_uninhibit (GTK_APPLICATION (app), priv->inhibit_cookie);
|
||||||
|
priv->inhibit_cookie = 0;
|
||||||
|
}
|
||||||
|
if (inhibit) {
|
||||||
|
priv->inhibit_cookie = gtk_application_inhibit (GTK_APPLICATION (app),
|
||||||
|
GTK_WINDOW (root), GTK_APPLICATION_INHIBIT_IDLE,
|
||||||
|
"Media is playing");
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (self, "Session %sinhibited", (inhibit) ? "" : "un");
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (self), param_specs[PROP_INHIBITED]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_player_state_changed_cb (ClapperPlayer *player,
|
||||||
|
GParamSpec *pspec G_GNUC_UNUSED, ClapperGtkAv *self)
|
||||||
|
{
|
||||||
|
ClapperGtkAvPrivate *priv = clapper_gtk_av_get_instance_private (self);
|
||||||
|
|
||||||
|
if (priv->auto_inhibit) {
|
||||||
|
ClapperPlayerState state = clapper_player_get_state (player);
|
||||||
|
_set_inhibit_session (self, state == CLAPPER_PLAYER_STATE_PLAYING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clapper_gtk_av_get_player:
|
||||||
|
* @av: a #ClapperGtkAv
|
||||||
|
*
|
||||||
|
* Get #ClapperPlayer used by this #ClapperGtkAv instance.
|
||||||
|
*
|
||||||
|
* Returns: (transfer none): a #ClapperPlayer used by widget.
|
||||||
|
*
|
||||||
|
* Since: 0.10
|
||||||
|
*/
|
||||||
|
ClapperPlayer *
|
||||||
|
clapper_gtk_av_get_player (ClapperGtkAv *self)
|
||||||
|
{
|
||||||
|
ClapperGtkAvPrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (CLAPPER_GTK_IS_AV (self), NULL);
|
||||||
|
|
||||||
|
priv = clapper_gtk_av_get_instance_private (self);
|
||||||
|
|
||||||
|
return priv->player;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clapper_gtk_av_set_auto_inhibit:
|
||||||
|
* @av: a #ClapperGtkAv
|
||||||
|
* @inhibit: whether to enable automatic session inhibit
|
||||||
|
*
|
||||||
|
* Set whether widget should try to automatically inhibit session
|
||||||
|
* from idling (and possibly screen going black) when media is playing.
|
||||||
|
*
|
||||||
|
* Since: 0.10
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clapper_gtk_av_set_auto_inhibit (ClapperGtkAv *self, gboolean inhibit)
|
||||||
|
{
|
||||||
|
ClapperGtkAvPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (CLAPPER_GTK_IS_AV (self));
|
||||||
|
|
||||||
|
priv = clapper_gtk_av_get_instance_private (self);
|
||||||
|
|
||||||
|
if (priv->auto_inhibit != inhibit) {
|
||||||
|
priv->auto_inhibit = inhibit;
|
||||||
|
|
||||||
|
/* Uninhibit if we were auto inhibited earlier */
|
||||||
|
if (!priv->auto_inhibit)
|
||||||
|
_set_inhibit_session (self, FALSE);
|
||||||
|
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (self), param_specs[PROP_AUTO_INHIBIT]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clapper_gtk_av_get_auto_inhibit:
|
||||||
|
* @av: a #ClapperGtkAv
|
||||||
|
*
|
||||||
|
* Get whether automatic session inhibit is enabled.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if enabled, %FALSE otherwise.
|
||||||
|
*
|
||||||
|
* Since: 0.10
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
clapper_gtk_av_get_auto_inhibit (ClapperGtkAv *self)
|
||||||
|
{
|
||||||
|
ClapperGtkAvPrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (CLAPPER_GTK_IS_AV (self), FALSE);
|
||||||
|
|
||||||
|
priv = clapper_gtk_av_get_instance_private (self);
|
||||||
|
|
||||||
|
return priv->auto_inhibit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clapper_gtk_av_get_inhibited:
|
||||||
|
* @av: a #ClapperGtkAv
|
||||||
|
*
|
||||||
|
* Get whether session is currently inhibited by
|
||||||
|
* [property@ClapperGtk.Av:auto-inhibit].
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if inhibited, %FALSE otherwise.
|
||||||
|
*
|
||||||
|
* Since: 0.10
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
clapper_gtk_av_get_inhibited (ClapperGtkAv *self)
|
||||||
|
{
|
||||||
|
ClapperGtkAvPrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (CLAPPER_GTK_IS_AV (self), FALSE);
|
||||||
|
|
||||||
|
priv = clapper_gtk_av_get_instance_private (self);
|
||||||
|
|
||||||
|
return (priv->inhibit_cookie != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clapper_gtk_av_root (GtkWidget *widget)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||||
|
ClapperGtkAvPrivate *priv = clapper_gtk_av_get_instance_private (self);
|
||||||
|
|
||||||
|
_ensure_css_provider ();
|
||||||
|
|
||||||
|
GTK_WIDGET_CLASS (parent_class)->root (widget);
|
||||||
|
|
||||||
|
if (priv->auto_inhibit) {
|
||||||
|
ClapperPlayerState state = clapper_player_get_state (priv->player);
|
||||||
|
_set_inhibit_session (self, state == CLAPPER_PLAYER_STATE_PLAYING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clapper_gtk_av_unroot (GtkWidget *widget)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||||
|
|
||||||
|
_set_inhibit_session (self, FALSE);
|
||||||
|
|
||||||
|
GTK_WIDGET_CLASS (parent_class)->unroot (widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clapper_gtk_av_init (ClapperGtkAv *self)
|
||||||
|
{
|
||||||
|
ClapperGtkAvPrivate *priv = clapper_gtk_av_get_instance_private (self);
|
||||||
|
|
||||||
|
priv->auto_inhibit = DEFAULT_AUTO_INHIBIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clapper_gtk_av_constructed (GObject *object)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (object);
|
||||||
|
ClapperGtkAvPrivate *priv = clapper_gtk_av_get_instance_private (self);
|
||||||
|
GstElement *afilter;
|
||||||
|
|
||||||
|
priv->player = clapper_player_new ();
|
||||||
|
|
||||||
|
g_signal_connect (priv->player, "notify::state",
|
||||||
|
G_CALLBACK (_player_state_changed_cb), self);
|
||||||
|
|
||||||
|
afilter = gst_element_factory_make ("scaletempo", NULL);
|
||||||
|
if (G_LIKELY (afilter != NULL))
|
||||||
|
clapper_player_set_audio_filter (priv->player, afilter);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clapper_gtk_av_dispose (GObject *object)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (object);
|
||||||
|
ClapperGtkAvPrivate *priv = clapper_gtk_av_get_instance_private (self);
|
||||||
|
|
||||||
|
/* Something else might still be holding a reference on the player,
|
||||||
|
* thus we should disconnect everything before disposing template */
|
||||||
|
if (priv->player) {
|
||||||
|
g_signal_handlers_disconnect_by_func (priv->player,
|
||||||
|
_player_state_changed_cb, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_clear_object (&priv->player);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clapper_gtk_av_get_property (GObject *object, guint prop_id,
|
||||||
|
GValue *value, GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_PLAYER:
|
||||||
|
g_value_set_object (value, clapper_gtk_av_get_player (self));
|
||||||
|
break;
|
||||||
|
case PROP_AUTO_INHIBIT:
|
||||||
|
g_value_set_boolean (value, clapper_gtk_av_get_auto_inhibit (self));
|
||||||
|
break;
|
||||||
|
case PROP_INHIBITED:
|
||||||
|
g_value_set_boolean (value, clapper_gtk_av_get_inhibited (self));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clapper_gtk_av_set_property (GObject *object, guint prop_id,
|
||||||
|
const GValue *value, GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_AUTO_INHIBIT:
|
||||||
|
clapper_gtk_av_set_auto_inhibit (self, g_value_get_boolean (value));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clapper_gtk_av_class_init (ClapperGtkAvClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||||
|
GtkWidgetClass *widget_class = (GtkWidgetClass *) klass;
|
||||||
|
|
||||||
|
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clappergtkav", GST_DEBUG_FG_MAGENTA,
|
||||||
|
"Clapper GTK AV");
|
||||||
|
|
||||||
|
widget_class->root = clapper_gtk_av_root;
|
||||||
|
widget_class->unroot = clapper_gtk_av_unroot;
|
||||||
|
|
||||||
|
gobject_class->constructed = clapper_gtk_av_constructed;
|
||||||
|
gobject_class->get_property = clapper_gtk_av_get_property;
|
||||||
|
gobject_class->set_property = clapper_gtk_av_set_property;
|
||||||
|
gobject_class->dispose = clapper_gtk_av_dispose;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClapperGtkAv:player:
|
||||||
|
*
|
||||||
|
* A #ClapperPlayer used by widget.
|
||||||
|
*/
|
||||||
|
param_specs[PROP_PLAYER] = g_param_spec_object ("player",
|
||||||
|
NULL, NULL, CLAPPER_TYPE_PLAYER,
|
||||||
|
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClapperGtkAv:auto-inhibit:
|
||||||
|
*
|
||||||
|
* Try to automatically inhibit session when media is playing.
|
||||||
|
*/
|
||||||
|
param_specs[PROP_AUTO_INHIBIT] = g_param_spec_boolean ("auto-inhibit",
|
||||||
|
NULL, NULL, DEFAULT_AUTO_INHIBIT,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClapperGtkAv:inhibited:
|
||||||
|
*
|
||||||
|
* Get whether session is currently inhibited by playback.
|
||||||
|
*/
|
||||||
|
param_specs[PROP_INHIBITED] = g_param_spec_boolean ("inhibited",
|
||||||
|
NULL, NULL, FALSE,
|
||||||
|
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
|
g_object_class_install_properties (gobject_class, PROP_LAST, param_specs);
|
||||||
|
|
||||||
|
gtk_widget_class_install_action (widget_class, "av.toggle-play", NULL, toggle_play_action_cb);
|
||||||
|
gtk_widget_class_install_action (widget_class, "av.play", NULL, play_action_cb);
|
||||||
|
gtk_widget_class_install_action (widget_class, "av.pause", NULL, pause_action_cb);
|
||||||
|
gtk_widget_class_install_action (widget_class, "av.stop", NULL, stop_action_cb);
|
||||||
|
gtk_widget_class_install_action (widget_class, "av.seek", "d", seek_action_cb);
|
||||||
|
gtk_widget_class_install_action (widget_class, "av.seek-custom", "(di)", seek_custom_action_cb);
|
||||||
|
gtk_widget_class_install_action (widget_class, "av.toggle-mute", NULL, toggle_mute_action_cb);
|
||||||
|
gtk_widget_class_install_action (widget_class, "av.set-mute", "b", set_mute_action_cb);
|
||||||
|
gtk_widget_class_install_action (widget_class, "av.volume-up", NULL, volume_up_action_cb);
|
||||||
|
gtk_widget_class_install_action (widget_class, "av.volume-down", NULL, volume_down_action_cb);
|
||||||
|
gtk_widget_class_install_action (widget_class, "av.set-volume", "d", set_volume_action_cb);
|
||||||
|
gtk_widget_class_install_action (widget_class, "av.speed-up", NULL, speed_up_action_cb);
|
||||||
|
gtk_widget_class_install_action (widget_class, "av.speed-down", NULL, speed_down_action_cb);
|
||||||
|
gtk_widget_class_install_action (widget_class, "av.set-speed", "d", set_speed_action_cb);
|
||||||
|
gtk_widget_class_install_action (widget_class, "av.previous-item", NULL, previous_item_action_cb);
|
||||||
|
gtk_widget_class_install_action (widget_class, "av.next-item", NULL, next_item_action_cb);
|
||||||
|
gtk_widget_class_install_action (widget_class, "av.select-item", "u", select_item_action_cb);
|
||||||
|
|
||||||
|
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||||
|
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_GENERIC);
|
||||||
|
gtk_widget_class_set_css_name (widget_class, "clapper-gtk-av");
|
||||||
|
}
|
60
src/lib/clapper-gtk/clapper-gtk-av.h
Normal file
60
src/lib/clapper-gtk/clapper-gtk-av.h
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/* Clapper GTK Integration Library
|
||||||
|
* Copyright (C) 2025 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, see
|
||||||
|
* <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(__CLAPPER_GTK_INSIDE__) && !defined(CLAPPER_GTK_COMPILATION)
|
||||||
|
#error "Only <clapper-gtk/clapper-gtk.h> can be included directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <clapper/clapper.h>
|
||||||
|
|
||||||
|
#include <clapper-gtk/clapper-gtk-visibility.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define CLAPPER_GTK_TYPE_AV (clapper_gtk_av_get_type())
|
||||||
|
#define CLAPPER_GTK_AV_CAST(obj) ((ClapperGtkAv *)(obj))
|
||||||
|
|
||||||
|
CLAPPER_GTK_API
|
||||||
|
G_DECLARE_DERIVABLE_TYPE (ClapperGtkAv, clapper_gtk_av, CLAPPER_GTK, AV, GtkWidget)
|
||||||
|
|
||||||
|
struct _ClapperGtkAvClass
|
||||||
|
{
|
||||||
|
GtkWidgetClass parent_class;
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
|
gpointer padding[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
CLAPPER_GTK_API
|
||||||
|
ClapperPlayer * clapper_gtk_av_get_player (ClapperGtkAv *av);
|
||||||
|
|
||||||
|
CLAPPER_GTK_API
|
||||||
|
void clapper_gtk_av_set_auto_inhibit (ClapperGtkAv *av, gboolean inhibit);
|
||||||
|
|
||||||
|
CLAPPER_GTK_API
|
||||||
|
gboolean clapper_gtk_av_get_auto_inhibit (ClapperGtkAv *av);
|
||||||
|
|
||||||
|
CLAPPER_GTK_API
|
||||||
|
gboolean clapper_gtk_av_get_inhibited (ClapperGtkAv *av);
|
||||||
|
|
||||||
|
G_END_DECLS
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <clapper/clapper.h>
|
#include <clapper/clapper.h>
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "clapper-gtk-buffering-paintable-private.h"
|
#include "clapper-gtk-buffering-paintable-private.h"
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <clapper/clapper.h>
|
#include <clapper/clapper.h>
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,7 +82,7 @@ clapper_gtk_next_item_button_init (ClapperGtkNextItemButton *self)
|
|||||||
{
|
{
|
||||||
gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
|
gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
|
||||||
gtk_button_set_icon_name (GTK_BUTTON (self), "media-skip-forward-symbolic");
|
gtk_button_set_icon_name (GTK_BUTTON (self), "media-skip-forward-symbolic");
|
||||||
gtk_actionable_set_action_name (GTK_ACTIONABLE (self), "video.next-item");
|
gtk_actionable_set_action_name (GTK_ACTIONABLE (self), "av.next-item");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,7 +82,7 @@ clapper_gtk_previous_item_button_init (ClapperGtkPreviousItemButton *self)
|
|||||||
{
|
{
|
||||||
gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
|
gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
|
||||||
gtk_button_set_icon_name (GTK_BUTTON (self), "media-skip-backward-symbolic");
|
gtk_button_set_icon_name (GTK_BUTTON (self), "media-skip-backward-symbolic");
|
||||||
gtk_actionable_set_action_name (GTK_ACTIONABLE (self), "video.previous-item");
|
gtk_actionable_set_action_name (GTK_ACTIONABLE (self), "av.previous-item");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -396,6 +395,47 @@ _update_duration_label (ClapperGtkSeekBar *self, gdouble duration)
|
|||||||
gtk_adjustment_set_upper (adjustment, duration);
|
gtk_adjustment_set_upper (adjustment, duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_find_marks_in_widget (GtkWidget *widget, GtkWidget **top_marks, GtkWidget **bottom_marks)
|
||||||
|
{
|
||||||
|
GtkWidget *child;
|
||||||
|
|
||||||
|
if (g_strcmp0 (gtk_widget_get_css_name (widget), "marks") == 0) {
|
||||||
|
if (gtk_widget_has_css_class (widget, "top"))
|
||||||
|
*top_marks = widget;
|
||||||
|
else if (gtk_widget_has_css_class (widget, "bottom"))
|
||||||
|
*bottom_marks = widget;
|
||||||
|
|
||||||
|
/* Its unexpected to have marks within marks,
|
||||||
|
* so do not iterate children of marks widget */
|
||||||
|
return (*top_marks && *bottom_marks);
|
||||||
|
}
|
||||||
|
|
||||||
|
child = gtk_widget_get_first_child (widget);
|
||||||
|
|
||||||
|
while (child != NULL) {
|
||||||
|
if (_find_marks_in_widget (child, top_marks, bottom_marks))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
child = gtk_widget_get_next_sibling (child);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_find_last_mark_in_marks (GtkWidget *marks, GtkWidget **last_mark)
|
||||||
|
{
|
||||||
|
GtkWidget *widget = gtk_widget_get_last_child (marks);
|
||||||
|
|
||||||
|
if (widget && g_strcmp0 (gtk_widget_get_css_name (widget), "mark") == 0) {
|
||||||
|
*last_mark = widget;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_update_scale_marks (ClapperGtkSeekBar *self, ClapperTimeline *timeline)
|
_update_scale_marks (ClapperGtkSeekBar *self, ClapperTimeline *timeline)
|
||||||
{
|
{
|
||||||
@@ -424,11 +464,43 @@ _update_scale_marks (ClapperGtkSeekBar *self, ClapperTimeline *timeline)
|
|||||||
|
|
||||||
for (i = 0; i < n_markers; ++i) {
|
for (i = 0; i < n_markers; ++i) {
|
||||||
ClapperMarker *marker = clapper_timeline_get_marker (timeline, i);
|
ClapperMarker *marker = clapper_timeline_get_marker (timeline, i);
|
||||||
|
ClapperMarkerType marker_type = clapper_marker_get_marker_type (marker);
|
||||||
gdouble start = clapper_marker_get_start (marker);
|
gdouble start = clapper_marker_get_start (marker);
|
||||||
|
|
||||||
gtk_scale_add_mark (GTK_SCALE (self->scale), start, GTK_POS_TOP, NULL);
|
gtk_scale_add_mark (GTK_SCALE (self->scale), start, GTK_POS_TOP, NULL);
|
||||||
gtk_scale_add_mark (GTK_SCALE (self->scale), start, GTK_POS_BOTTOM, NULL);
|
gtk_scale_add_mark (GTK_SCALE (self->scale), start, GTK_POS_BOTTOM, NULL);
|
||||||
|
|
||||||
|
if (marker_type >= CLAPPER_MARKER_TYPE_CUSTOM_1) {
|
||||||
|
GtkWidget *top_marks = NULL, *bottom_marks = NULL;
|
||||||
|
GtkWidget *top_mark = NULL, *bottom_mark = NULL;
|
||||||
|
|
||||||
|
if (_find_marks_in_widget (self->scale, &top_marks, &bottom_marks)
|
||||||
|
&& _find_last_mark_in_marks (top_marks, &top_mark)
|
||||||
|
&& _find_last_mark_in_marks (bottom_marks, &bottom_mark)) {
|
||||||
|
const gchar *custom_name;
|
||||||
|
|
||||||
|
switch (marker_type) {
|
||||||
|
case CLAPPER_MARKER_TYPE_CUSTOM_1:
|
||||||
|
custom_name = "custom1";
|
||||||
|
break;
|
||||||
|
case CLAPPER_MARKER_TYPE_CUSTOM_2:
|
||||||
|
custom_name = "custom2";
|
||||||
|
break;
|
||||||
|
case CLAPPER_MARKER_TYPE_CUSTOM_3:
|
||||||
|
custom_name = "custom3";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
custom_name = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (G_LIKELY (custom_name != NULL)) {
|
||||||
|
gtk_widget_add_css_class (top_mark, custom_name);
|
||||||
|
gtk_widget_add_css_class (bottom_mark, custom_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gst_object_unref (marker);
|
gst_object_unref (marker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,7 +83,7 @@ static void
|
|||||||
clapper_gtk_toggle_play_button_init (ClapperGtkTogglePlayButton *self)
|
clapper_gtk_toggle_play_button_init (ClapperGtkTogglePlayButton *self)
|
||||||
{
|
{
|
||||||
gtk_button_set_icon_name (GTK_BUTTON (self), PLAY_ICON_NAME);
|
gtk_button_set_icon_name (GTK_BUTTON (self), PLAY_ICON_NAME);
|
||||||
gtk_actionable_set_action_name (GTK_ACTIONABLE (self), "video.toggle-play");
|
gtk_actionable_set_action_name (GTK_ACTIONABLE (self), "av.toggle-play");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@@ -22,7 +21,7 @@
|
|||||||
#include <glib/gi18n-lib.h>
|
#include <glib/gi18n-lib.h>
|
||||||
|
|
||||||
#include "clapper-gtk-utils-private.h"
|
#include "clapper-gtk-utils-private.h"
|
||||||
#include "clapper-gtk-video.h"
|
#include "clapper-gtk-av.h"
|
||||||
|
|
||||||
static gboolean initialized = FALSE;
|
static gboolean initialized = FALSE;
|
||||||
|
|
||||||
@@ -30,18 +29,18 @@ static gboolean initialized = FALSE;
|
|||||||
* clapper_gtk_get_player_from_ancestor:
|
* clapper_gtk_get_player_from_ancestor:
|
||||||
* @widget: a #GtkWidget
|
* @widget: a #GtkWidget
|
||||||
*
|
*
|
||||||
* Get [class@Clapper.Player] used by [class@ClapperGtk.Video] ancestor of @widget.
|
* Get [class@Clapper.Player] used by [class@ClapperGtk.Av] ancestor of @widget.
|
||||||
*
|
*
|
||||||
* This utility is a convenience wrapper for calling [method@Gtk.Widget.get_ancestor]
|
* This utility is a convenience wrapper for calling [method@Gtk.Widget.get_ancestor]
|
||||||
* of type `CLAPPER_GTK_TYPE_VIDEO` and [method@ClapperGtk.Video.get_player] with
|
* of type `CLAPPER_GTK_TYPE_AV` and [method@ClapperGtk.Av.get_player] with
|
||||||
* additional %NULL checking and type casting.
|
* additional %NULL checking and type casting.
|
||||||
*
|
*
|
||||||
* This is meant to be used mainly for custom widget development as an easy access to the
|
* This is meant to be used mainly for custom widget development as an easy access to the
|
||||||
* underlying parent [class@Clapper.Player] object. If you want to get the player from
|
* underlying parent [class@Clapper.Player] object. If you want to get the player from
|
||||||
* [class@ClapperGtk.Video] widget itself, use [method@ClapperGtk.Video.get_player] instead.
|
* [class@ClapperGtk.Av] widget itself, use [method@ClapperGtk.Av.get_player] instead.
|
||||||
*
|
*
|
||||||
* Rememeber that this function will return %NULL when widget does not have
|
* Rememeber that this function will return %NULL when widget does not have
|
||||||
* a [class@ClapperGtk.Video] ancestor in widget hierarchy (widget is not yet placed).
|
* a [class@ClapperGtk.Av] ancestor in widget hierarchy (widget is not yet placed).
|
||||||
*
|
*
|
||||||
* Returns: (transfer none) (nullable): a #ClapperPlayer from ancestor of a @widget.
|
* Returns: (transfer none) (nullable): a #ClapperPlayer from ancestor of a @widget.
|
||||||
*/
|
*/
|
||||||
@@ -53,8 +52,8 @@ clapper_gtk_get_player_from_ancestor (GtkWidget *widget)
|
|||||||
|
|
||||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
|
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
|
||||||
|
|
||||||
if ((parent = gtk_widget_get_ancestor (widget, CLAPPER_GTK_TYPE_VIDEO)))
|
if ((parent = gtk_widget_get_ancestor (widget, CLAPPER_GTK_TYPE_AV)))
|
||||||
player = clapper_gtk_video_get_player (CLAPPER_GTK_VIDEO_CAST (parent));
|
player = clapper_gtk_av_get_player (CLAPPER_GTK_AV_CAST (parent));
|
||||||
|
|
||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
95
src/lib/clapper-gtk/clapper-gtk-version.c
Normal file
95
src/lib/clapper-gtk/clapper-gtk-version.c
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
/* Clapper GTK Integration Library
|
||||||
|
* Copyright (C) 2025 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, see
|
||||||
|
* <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "clapper-gtk-version.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clapper_gtk_get_major_version:
|
||||||
|
*
|
||||||
|
* ClapperGtk runtime major version component
|
||||||
|
*
|
||||||
|
* This returns the ClapperGtk library version your code is
|
||||||
|
* running against unlike [const@ClapperGtk.MAJOR_VERSION]
|
||||||
|
* which represents compile time version.
|
||||||
|
*
|
||||||
|
* Returns: the major version number of the ClapperGtk library
|
||||||
|
*
|
||||||
|
* Since: 0.10
|
||||||
|
*/
|
||||||
|
guint
|
||||||
|
clapper_gtk_get_major_version (void)
|
||||||
|
{
|
||||||
|
return CLAPPER_GTK_MAJOR_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clapper_gtk_get_minor_version:
|
||||||
|
*
|
||||||
|
* ClapperGtk runtime minor version component
|
||||||
|
*
|
||||||
|
* This returns the ClapperGtk library version your code is
|
||||||
|
* running against unlike [const@ClapperGtk.MINOR_VERSION]
|
||||||
|
* which represents compile time version.
|
||||||
|
*
|
||||||
|
* Returns: the minor version number of the ClapperGtk library
|
||||||
|
*
|
||||||
|
* Since: 0.10
|
||||||
|
*/
|
||||||
|
guint
|
||||||
|
clapper_gtk_get_minor_version (void)
|
||||||
|
{
|
||||||
|
return CLAPPER_GTK_MINOR_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clapper_gtk_get_micro_version:
|
||||||
|
*
|
||||||
|
* ClapperGtk runtime micro version component
|
||||||
|
*
|
||||||
|
* This returns the ClapperGtk library version your code is
|
||||||
|
* running against unlike [const@ClapperGtk.MICRO_VERSION]
|
||||||
|
* which represents compile time version.
|
||||||
|
*
|
||||||
|
* Returns: the micro version number of the ClapperGtk library
|
||||||
|
*
|
||||||
|
* Since: 0.10
|
||||||
|
*/
|
||||||
|
guint
|
||||||
|
clapper_gtk_get_micro_version (void)
|
||||||
|
{
|
||||||
|
return CLAPPER_GTK_MICRO_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clapper_gtk_get_version_s:
|
||||||
|
*
|
||||||
|
* ClapperGtk runtime version as string
|
||||||
|
*
|
||||||
|
* This returns the ClapperGtk library version your code is
|
||||||
|
* running against unlike [const@ClapperGtk.VERSION_S]
|
||||||
|
* which represents compile time version.
|
||||||
|
*
|
||||||
|
* Returns: the version of the ClapperGtk library as string
|
||||||
|
*
|
||||||
|
* Since: 0.10
|
||||||
|
*/
|
||||||
|
const gchar *
|
||||||
|
clapper_gtk_get_version_s (void)
|
||||||
|
{
|
||||||
|
return CLAPPER_GTK_VERSION_S;
|
||||||
|
}
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -23,6 +22,8 @@
|
|||||||
#error "Only <clapper-gtk/clapper-gtk.h> can be included directly."
|
#error "Only <clapper-gtk/clapper-gtk.h> can be included directly."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CLAPPER_GTK_MAJOR_VERSION:
|
* CLAPPER_GTK_MAJOR_VERSION:
|
||||||
*
|
*
|
||||||
@@ -74,3 +75,15 @@
|
|||||||
(CLAPPER_GTK_MAJOR_VERSION == (major) && CLAPPER_GTK_MINOR_VERSION > (minor)) || \
|
(CLAPPER_GTK_MAJOR_VERSION == (major) && CLAPPER_GTK_MINOR_VERSION > (minor)) || \
|
||||||
(CLAPPER_GTK_MAJOR_VERSION == (major) && CLAPPER_GTK_MINOR_VERSION == (minor) && \
|
(CLAPPER_GTK_MAJOR_VERSION == (major) && CLAPPER_GTK_MINOR_VERSION == (minor) && \
|
||||||
CLAPPER_GTK_MICRO_VERSION >= (micro)))
|
CLAPPER_GTK_MICRO_VERSION >= (micro)))
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
guint clapper_gtk_get_major_version (void);
|
||||||
|
|
||||||
|
guint clapper_gtk_get_minor_version (void);
|
||||||
|
|
||||||
|
guint clapper_gtk_get_micro_version (void);
|
||||||
|
|
||||||
|
const gchar * clapper_gtk_get_version_s (void);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -23,8 +22,8 @@
|
|||||||
* A ready to be used GTK video widget implementing Clapper API.
|
* A ready to be used GTK video widget implementing Clapper API.
|
||||||
*
|
*
|
||||||
* #ClapperGtkVideo is the main widget exposed by `ClapperGtk` API. It both displays
|
* #ClapperGtkVideo is the main widget exposed by `ClapperGtk` API. It both displays
|
||||||
* videos played by [class@Clapper.Player] (exposed as its property) and manages
|
* videos played by [class@Clapper.Player] (exposed as [property@ClapperGtk.Av:player] property)
|
||||||
* revealing and fading of any additional widgets overlaid on top of it.
|
* and manages revealing and fading of any additional widgets overlaid on top of it.
|
||||||
*
|
*
|
||||||
* Other widgets provided by `ClapperGtk` library, once placed anywhere on video
|
* Other widgets provided by `ClapperGtk` library, once placed anywhere on video
|
||||||
* (including nesting within another widget like [class@Gtk.Box]) will automatically
|
* (including nesting within another widget like [class@Gtk.Box]) will automatically
|
||||||
@@ -35,7 +34,7 @@
|
|||||||
* # Basic usage
|
* # Basic usage
|
||||||
*
|
*
|
||||||
* A typical use case is to embed video widget as part of your app where video playback
|
* A typical use case is to embed video widget as part of your app where video playback
|
||||||
* is needed. Get the [class@Clapper.Player] belonging to the video widget and start adding
|
* is needed. Get the [class@Clapper.Player] belonging to the AV widget and start adding
|
||||||
* new [class@Clapper.MediaItem] items to the [class@Clapper.Queue] for playback.
|
* new [class@Clapper.MediaItem] items to the [class@Clapper.Queue] for playback.
|
||||||
* For more information please refer to the Clapper playback library documentation.
|
* For more information please refer to the Clapper playback library documentation.
|
||||||
*
|
*
|
||||||
@@ -47,27 +46,8 @@
|
|||||||
*
|
*
|
||||||
* # Actions
|
* # Actions
|
||||||
*
|
*
|
||||||
* #ClapperGtkVideo defines a set of built-in actions:
|
* You can use built-in actions of parent [class@ClapperGtk.Av].
|
||||||
*
|
* See its documentation, for the list of available ones.
|
||||||
* ```yaml
|
|
||||||
* - "video.toggle-play": toggle play/pause
|
|
||||||
* - "video.play": start/resume playback
|
|
||||||
* - "video.pause": pause playback
|
|
||||||
* - "video.stop": stop playback
|
|
||||||
* - "video.seek": seek to position (variant "d")
|
|
||||||
* - "video.seek-custom": seek to position using seek method (variant "(di)")
|
|
||||||
* - "video.toggle-mute": toggle mute state
|
|
||||||
* - "video.set-mute": set mute state (variant "b")
|
|
||||||
* - "video.volume-up": increase volume by 2%
|
|
||||||
* - "video.volume-down": decrease volume by 2%
|
|
||||||
* - "video.set-volume": set volume to specified value (variant "d")
|
|
||||||
* - "video.speed-up": increase speed (from 0.05x - 2x range to nearest quarter)
|
|
||||||
* - "video.speed-down": decrease speed (from 0.05x - 2x range to nearest quarter)
|
|
||||||
* - "video.set-speed": set speed to specified value (variant "d")
|
|
||||||
* - "video.previous-item": select previous item in queue
|
|
||||||
* - "video.next-item": select next item in queue
|
|
||||||
* - "video.select-item": select item at specified index in queue (variant "u")
|
|
||||||
* ```
|
|
||||||
*
|
*
|
||||||
* # ClapperGtkVideo as GtkBuildable
|
* # ClapperGtkVideo as GtkBuildable
|
||||||
*
|
*
|
||||||
@@ -94,8 +74,6 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#include "clapper-gtk-enums.h"
|
#include "clapper-gtk-enums.h"
|
||||||
#include "clapper-gtk-video.h"
|
#include "clapper-gtk-video.h"
|
||||||
#include "clapper-gtk-lead-container.h"
|
#include "clapper-gtk-lead-container.h"
|
||||||
@@ -103,11 +81,8 @@
|
|||||||
#include "clapper-gtk-buffering-animation-private.h"
|
#include "clapper-gtk-buffering-animation-private.h"
|
||||||
#include "clapper-gtk-video-placeholder-private.h"
|
#include "clapper-gtk-video-placeholder-private.h"
|
||||||
|
|
||||||
#define PERCENTAGE_ROUND(a) (round ((gdouble) a / 0.01) * 0.01)
|
|
||||||
|
|
||||||
#define DEFAULT_FADE_DELAY 3000
|
#define DEFAULT_FADE_DELAY 3000
|
||||||
#define DEFAULT_TOUCH_FADE_DELAY 5000
|
#define DEFAULT_TOUCH_FADE_DELAY 5000
|
||||||
#define DEFAULT_AUTO_INHIBIT FALSE
|
|
||||||
|
|
||||||
#define MIN_MOTION_DELAY 100000
|
#define MIN_MOTION_DELAY 100000
|
||||||
|
|
||||||
@@ -116,7 +91,7 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
|||||||
|
|
||||||
struct _ClapperGtkVideo
|
struct _ClapperGtkVideo
|
||||||
{
|
{
|
||||||
GtkWidget parent;
|
ClapperGtkAv parent;
|
||||||
|
|
||||||
GtkWidget *overlay;
|
GtkWidget *overlay;
|
||||||
GtkWidget *status;
|
GtkWidget *status;
|
||||||
@@ -126,10 +101,8 @@ struct _ClapperGtkVideo
|
|||||||
GtkGesture *click_gesture;
|
GtkGesture *click_gesture;
|
||||||
|
|
||||||
/* Props */
|
/* Props */
|
||||||
ClapperPlayer *player;
|
|
||||||
guint fade_delay;
|
guint fade_delay;
|
||||||
guint touch_fade_delay;
|
guint touch_fade_delay;
|
||||||
gboolean auto_inhibit;
|
|
||||||
|
|
||||||
GPtrArray *overlays;
|
GPtrArray *overlays;
|
||||||
GPtrArray *fading_overlays;
|
GPtrArray *fading_overlays;
|
||||||
@@ -141,8 +114,6 @@ struct _ClapperGtkVideo
|
|||||||
guint fade_timeout;
|
guint fade_timeout;
|
||||||
gboolean reveal, revealed;
|
gboolean reveal, revealed;
|
||||||
|
|
||||||
guint inhibit_cookie;
|
|
||||||
|
|
||||||
/* Current pointer coords and type */
|
/* Current pointer coords and type */
|
||||||
gdouble x, y;
|
gdouble x, y;
|
||||||
gboolean is_touch;
|
gboolean is_touch;
|
||||||
@@ -175,17 +146,14 @@ _buildable_iface_init (GtkBuildableIface *iface)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define parent_class clapper_gtk_video_parent_class
|
#define parent_class clapper_gtk_video_parent_class
|
||||||
G_DEFINE_TYPE_WITH_CODE (ClapperGtkVideo, clapper_gtk_video, GTK_TYPE_WIDGET,
|
G_DEFINE_TYPE_WITH_CODE (ClapperGtkVideo, clapper_gtk_video, CLAPPER_GTK_TYPE_AV,
|
||||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, _buildable_iface_init))
|
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, _buildable_iface_init))
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_PLAYER,
|
|
||||||
PROP_FADE_DELAY,
|
PROP_FADE_DELAY,
|
||||||
PROP_TOUCH_FADE_DELAY,
|
PROP_TOUCH_FADE_DELAY,
|
||||||
PROP_AUTO_INHIBIT,
|
|
||||||
PROP_INHIBITED,
|
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -196,209 +164,111 @@ enum
|
|||||||
SIGNAL_LAST
|
SIGNAL_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
static gboolean provider_added = FALSE;
|
|
||||||
static GParamSpec *param_specs[PROP_LAST] = { NULL, };
|
static GParamSpec *param_specs[PROP_LAST] = { NULL, };
|
||||||
static guint signals[SIGNAL_LAST] = { 0, };
|
static guint signals[SIGNAL_LAST] = { 0, };
|
||||||
|
|
||||||
|
/* FIXME: 1.0: Remove these compat actions, since they were moved to base class */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
toggle_play_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
toggle_play_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
{
|
{
|
||||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
gtk_widget_activate_action_variant (widget, "av.toggle-play", parameter);
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
|
||||||
|
|
||||||
switch (clapper_player_get_state (player)) {
|
|
||||||
case CLAPPER_PLAYER_STATE_PLAYING:
|
|
||||||
clapper_player_pause (player);
|
|
||||||
break;
|
|
||||||
case CLAPPER_PLAYER_STATE_STOPPED:
|
|
||||||
case CLAPPER_PLAYER_STATE_PAUSED:
|
|
||||||
clapper_player_play (player);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
play_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
play_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
{
|
{
|
||||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
gtk_widget_activate_action_variant (widget, "av.play", parameter);
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
|
||||||
|
|
||||||
clapper_player_play (player);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pause_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
pause_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
{
|
{
|
||||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
gtk_widget_activate_action_variant (widget, "av.pause", parameter);
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
|
||||||
|
|
||||||
clapper_player_pause (player);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
stop_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
stop_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
{
|
{
|
||||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
gtk_widget_activate_action_variant (widget, "av.stop", parameter);
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
|
||||||
|
|
||||||
clapper_player_stop (player);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
seek_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
seek_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
{
|
{
|
||||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
gtk_widget_activate_action_variant (widget, "av.seek", parameter);
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
|
||||||
gdouble position = g_variant_get_double (parameter);
|
|
||||||
|
|
||||||
clapper_player_seek (player, position);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
seek_custom_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
seek_custom_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
{
|
{
|
||||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
gtk_widget_activate_action_variant (widget, "av.seek-custom", parameter);
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
|
||||||
ClapperPlayerSeekMethod method = CLAPPER_PLAYER_SEEK_METHOD_NORMAL;
|
|
||||||
gdouble position = 0;
|
|
||||||
|
|
||||||
g_variant_get (parameter, "(di)", &position, &method);
|
|
||||||
clapper_player_seek_custom (player, position, method);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
toggle_mute_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
toggle_mute_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
{
|
{
|
||||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
gtk_widget_activate_action_variant (widget, "av.toggle-mute", parameter);
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
|
||||||
|
|
||||||
clapper_player_set_mute (player, !clapper_player_get_mute (player));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_mute_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
set_mute_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
{
|
{
|
||||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
gtk_widget_activate_action_variant (widget, "av.set-mute", parameter);
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
|
||||||
gboolean mute = g_variant_get_boolean (parameter);
|
|
||||||
|
|
||||||
clapper_player_set_mute (player, mute);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
volume_up_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
volume_up_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
{
|
{
|
||||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
gtk_widget_activate_action_variant (widget, "av.volume-up", parameter);
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
|
||||||
gdouble volume = (clapper_player_get_volume (player) + 0.02);
|
|
||||||
|
|
||||||
if (volume > 2.0)
|
|
||||||
volume = 2.0;
|
|
||||||
|
|
||||||
clapper_player_set_volume (player, PERCENTAGE_ROUND (volume));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
volume_down_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
volume_down_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
{
|
{
|
||||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
gtk_widget_activate_action_variant (widget, "av.volume-down", parameter);
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
|
||||||
gdouble volume = (clapper_player_get_volume (player) - 0.02);
|
|
||||||
|
|
||||||
if (volume < 0)
|
|
||||||
volume = 0;
|
|
||||||
|
|
||||||
clapper_player_set_volume (player, PERCENTAGE_ROUND (volume));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_volume_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
set_volume_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
{
|
{
|
||||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
gtk_widget_activate_action_variant (widget, "av.set-volume", parameter);
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
|
||||||
gdouble volume = g_variant_get_double (parameter);
|
|
||||||
|
|
||||||
clapper_player_set_volume (player, volume);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
speed_up_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
speed_up_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
{
|
{
|
||||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
gtk_widget_activate_action_variant (widget, "av.speed-up", parameter);
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
|
||||||
gdouble dest, speed = clapper_player_get_speed (player);
|
|
||||||
|
|
||||||
if (speed >= 2.0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dest = 0.25;
|
|
||||||
while (speed >= dest)
|
|
||||||
dest += 0.25;
|
|
||||||
|
|
||||||
if (dest > 2.0)
|
|
||||||
dest = 2.0;
|
|
||||||
|
|
||||||
clapper_player_set_speed (player, dest);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
speed_down_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
speed_down_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
{
|
{
|
||||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
gtk_widget_activate_action_variant (widget, "av.speed-down", parameter);
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
|
||||||
gdouble dest, speed = clapper_player_get_speed (player);
|
|
||||||
|
|
||||||
if (speed <= 0.05)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dest = 2.0;
|
|
||||||
while (speed <= dest)
|
|
||||||
dest -= 0.25;
|
|
||||||
|
|
||||||
if (dest < 0.05)
|
|
||||||
dest = 0.05;
|
|
||||||
|
|
||||||
clapper_player_set_speed (player, dest);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_speed_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
set_speed_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
{
|
{
|
||||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
gtk_widget_activate_action_variant (widget, "av.set-speed", parameter);
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
|
||||||
gdouble speed = g_variant_get_double (parameter);
|
|
||||||
|
|
||||||
clapper_player_set_speed (player, speed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
previous_item_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
previous_item_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
{
|
{
|
||||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
gtk_widget_activate_action_variant (widget, "av.previous-item", parameter);
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
|
||||||
|
|
||||||
clapper_queue_select_previous_item (clapper_player_get_queue (player));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
next_item_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
next_item_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
{
|
{
|
||||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
gtk_widget_activate_action_variant (widget, "av.next-item", parameter);
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
|
||||||
|
|
||||||
clapper_queue_select_next_item (clapper_player_get_queue (player));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
select_item_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
select_item_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||||
{
|
{
|
||||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
gtk_widget_activate_action_variant (widget, "av.select-item", parameter);
|
||||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
|
||||||
guint index = g_variant_get_uint32 (parameter);
|
|
||||||
|
|
||||||
clapper_queue_select_index (clapper_player_get_queue (player), index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -872,73 +742,6 @@ touch_released_cb (GtkGestureClick *click, gint n_press,
|
|||||||
_reset_fade_timeout (self);
|
_reset_fade_timeout (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
_ensure_css_provider (void)
|
|
||||||
{
|
|
||||||
GdkDisplay *display;
|
|
||||||
|
|
||||||
if (provider_added)
|
|
||||||
return;
|
|
||||||
|
|
||||||
display = gdk_display_get_default ();
|
|
||||||
|
|
||||||
if (G_LIKELY (display != NULL)) {
|
|
||||||
GtkCssProvider *provider = gtk_css_provider_new ();
|
|
||||||
gtk_css_provider_load_from_resource (provider,
|
|
||||||
CLAPPER_GTK_RESOURCE_PREFIX "/css/styles.css");
|
|
||||||
|
|
||||||
gtk_style_context_add_provider_for_display (display,
|
|
||||||
(GtkStyleProvider *) provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION - 1);
|
|
||||||
g_object_unref (provider);
|
|
||||||
|
|
||||||
provider_added = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
_set_inhibit_session (ClapperGtkVideo *self, gboolean inhibit)
|
|
||||||
{
|
|
||||||
GtkRoot *root;
|
|
||||||
GApplication *app;
|
|
||||||
gboolean inhibited = (self->inhibit_cookie != 0);
|
|
||||||
|
|
||||||
if (inhibited == inhibit)
|
|
||||||
return;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "Trying to %sinhibit session...", (inhibit) ? "" : "un");
|
|
||||||
|
|
||||||
root = gtk_widget_get_root (GTK_WIDGET (self));
|
|
||||||
|
|
||||||
if (!root && !GTK_IS_WINDOW (root)) {
|
|
||||||
GST_WARNING_OBJECT (self, "Cannot %sinhibit session "
|
|
||||||
"without root window", (inhibit) ? "" : "un");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NOTE: Not using application from window prop,
|
|
||||||
* as it goes away early when unrooting */
|
|
||||||
app = g_application_get_default ();
|
|
||||||
|
|
||||||
if (!app && !GTK_IS_APPLICATION (app)) {
|
|
||||||
GST_WARNING_OBJECT (self, "Cannot %sinhibit session "
|
|
||||||
"without window application set", (inhibit) ? "" : "un");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inhibited) {
|
|
||||||
gtk_application_uninhibit (GTK_APPLICATION (app), self->inhibit_cookie);
|
|
||||||
self->inhibit_cookie = 0;
|
|
||||||
}
|
|
||||||
if (inhibit) {
|
|
||||||
self->inhibit_cookie = gtk_application_inhibit (GTK_APPLICATION (app),
|
|
||||||
GTK_WINDOW (root), GTK_APPLICATION_INHIBIT_IDLE,
|
|
||||||
"Video is playing");
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "Session %sinhibited", (inhibit) ? "" : "un");
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (self), param_specs[PROP_INHIBITED]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
_set_buffering_animation_enabled (ClapperGtkVideo *self, gboolean enabled)
|
_set_buffering_animation_enabled (ClapperGtkVideo *self, gboolean enabled)
|
||||||
{
|
{
|
||||||
@@ -964,9 +767,6 @@ _player_state_changed_cb (ClapperPlayer *player,
|
|||||||
{
|
{
|
||||||
ClapperPlayerState state = clapper_player_get_state (player);
|
ClapperPlayerState state = clapper_player_get_state (player);
|
||||||
|
|
||||||
if (self->auto_inhibit)
|
|
||||||
_set_inhibit_session (self, state == CLAPPER_PLAYER_STATE_PLAYING);
|
|
||||||
|
|
||||||
_set_buffering_animation_enabled (self, state == CLAPPER_PLAYER_STATE_BUFFERING);
|
_set_buffering_animation_enabled (self, state == CLAPPER_PLAYER_STATE_BUFFERING);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1107,7 +907,7 @@ _fading_overlay_revealed_cb (GtkRevealer *revealer,
|
|||||||
*
|
*
|
||||||
* Creates a new #ClapperGtkVideo instance.
|
* Creates a new #ClapperGtkVideo instance.
|
||||||
*
|
*
|
||||||
* Newly created video widget will also set some default GStreamer elements
|
* Newly created video widget will also have set some default GStreamer elements
|
||||||
* on its [class@Clapper.Player]. This includes Clapper own video sink and
|
* on its [class@Clapper.Player]. This includes Clapper own video sink and
|
||||||
* a "scaletempo" element as audio filter. Both can still be changed after
|
* a "scaletempo" element as audio filter. Both can still be changed after
|
||||||
* construction by setting corresponding player properties.
|
* construction by setting corresponding player properties.
|
||||||
@@ -1188,19 +988,21 @@ clapper_gtk_video_add_fading_overlay (ClapperGtkVideo *self, GtkWidget *widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clapper_gtk_video_get_player:
|
* clapper_gtk_video_get_player: (skip)
|
||||||
* @video: a #ClapperGtkVideo
|
* @video: a #ClapperGtkVideo
|
||||||
*
|
*
|
||||||
* Get #ClapperPlayer used by this #ClapperGtkVideo instance.
|
* Get #ClapperPlayer used by this #ClapperGtkVideo instance.
|
||||||
*
|
*
|
||||||
* Returns: (transfer none): a #ClapperPlayer used by video.
|
* Returns: (transfer none): a #ClapperPlayer used by video.
|
||||||
|
*
|
||||||
|
* Deprecated: 0.10: Use [method@ClapperGtk.Av.get_player] instead.
|
||||||
*/
|
*/
|
||||||
ClapperPlayer *
|
ClapperPlayer *
|
||||||
clapper_gtk_video_get_player (ClapperGtkVideo *self)
|
clapper_gtk_video_get_player (ClapperGtkVideo *self)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (CLAPPER_GTK_IS_VIDEO (self), NULL);
|
g_return_val_if_fail (CLAPPER_GTK_IS_VIDEO (self), NULL);
|
||||||
|
|
||||||
return self->player;
|
return clapper_gtk_av_get_player (CLAPPER_GTK_AV_CAST (self));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1276,60 +1078,58 @@ clapper_gtk_video_get_touch_fade_delay (ClapperGtkVideo *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clapper_gtk_video_set_auto_inhibit:
|
* clapper_gtk_video_set_auto_inhibit: (skip)
|
||||||
* @video: a #ClapperGtkVideo
|
* @video: a #ClapperGtkVideo
|
||||||
* @inhibit: whether to enable automatic session inhibit
|
* @inhibit: whether to enable automatic session inhibit
|
||||||
*
|
*
|
||||||
* Set whether video should try to automatically inhibit session
|
* Set whether video should try to automatically inhibit session
|
||||||
* from idling (and possibly screen going black) when video is playing.
|
* from idling (and possibly screen going black) when video is playing.
|
||||||
|
*
|
||||||
|
* Deprecated: 0.10: Use [method@ClapperGtk.Av.set_auto_inhibit] instead.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
clapper_gtk_video_set_auto_inhibit (ClapperGtkVideo *self, gboolean inhibit)
|
clapper_gtk_video_set_auto_inhibit (ClapperGtkVideo *self, gboolean inhibit)
|
||||||
{
|
{
|
||||||
g_return_if_fail (CLAPPER_GTK_IS_VIDEO (self));
|
g_return_if_fail (CLAPPER_GTK_IS_VIDEO (self));
|
||||||
|
|
||||||
if (self->auto_inhibit != inhibit) {
|
clapper_gtk_av_set_auto_inhibit (CLAPPER_GTK_AV_CAST (self), inhibit);
|
||||||
self->auto_inhibit = inhibit;
|
|
||||||
|
|
||||||
/* Uninhibit if we were auto inhibited earlier */
|
|
||||||
if (!self->auto_inhibit)
|
|
||||||
_set_inhibit_session (self, FALSE);
|
|
||||||
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (self), param_specs[PROP_AUTO_INHIBIT]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clapper_gtk_video_get_auto_inhibit:
|
* clapper_gtk_video_get_auto_inhibit: (skip)
|
||||||
* @video: a #ClapperGtkVideo
|
* @video: a #ClapperGtkVideo
|
||||||
*
|
*
|
||||||
* Get whether automatic session inhibit is enabled.
|
* Get whether automatic session inhibit is enabled.
|
||||||
*
|
*
|
||||||
* Returns: %TRUE if enabled, %FALSE otherwise.
|
* Returns: %TRUE if enabled, %FALSE otherwise.
|
||||||
|
*
|
||||||
|
* Deprecated: 0.10: Use [method@ClapperGtk.Av.get_auto_inhibit] instead.
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
clapper_gtk_video_get_auto_inhibit (ClapperGtkVideo *self)
|
clapper_gtk_video_get_auto_inhibit (ClapperGtkVideo *self)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (CLAPPER_GTK_IS_VIDEO (self), FALSE);
|
g_return_val_if_fail (CLAPPER_GTK_IS_VIDEO (self), FALSE);
|
||||||
|
|
||||||
return self->auto_inhibit;
|
return clapper_gtk_av_get_auto_inhibit (CLAPPER_GTK_AV_CAST (self));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clapper_gtk_video_get_inhibited:
|
* clapper_gtk_video_get_inhibited: (skip)
|
||||||
* @video: a #ClapperGtkVideo
|
* @video: a #ClapperGtkVideo
|
||||||
*
|
*
|
||||||
* Get whether session is currently inhibited by
|
* Get whether session is currently inhibited by
|
||||||
* [property@ClapperGtk.Video:auto-inhibit].
|
* [property@ClapperGtk.Av:auto-inhibit].
|
||||||
*
|
*
|
||||||
* Returns: %TRUE if inhibited, %FALSE otherwise.
|
* Returns: %TRUE if inhibited, %FALSE otherwise.
|
||||||
|
*
|
||||||
|
* Deprecated: 0.10: Use [method@ClapperGtk.Av.get_inhibited] instead.
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
clapper_gtk_video_get_inhibited (ClapperGtkVideo *self)
|
clapper_gtk_video_get_inhibited (ClapperGtkVideo *self)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (CLAPPER_GTK_IS_VIDEO (self), FALSE);
|
g_return_val_if_fail (CLAPPER_GTK_IS_VIDEO (self), FALSE);
|
||||||
|
|
||||||
return (self->inhibit_cookie != 0);
|
return clapper_gtk_av_get_inhibited (CLAPPER_GTK_AV_CAST (self));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1338,8 +1138,6 @@ clapper_gtk_video_root (GtkWidget *widget)
|
|||||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
||||||
GtkRoot *root;
|
GtkRoot *root;
|
||||||
|
|
||||||
_ensure_css_provider ();
|
|
||||||
|
|
||||||
GTK_WIDGET_CLASS (parent_class)->root (widget);
|
GTK_WIDGET_CLASS (parent_class)->root (widget);
|
||||||
|
|
||||||
root = gtk_widget_get_root (widget);
|
root = gtk_widget_get_root (widget);
|
||||||
@@ -1351,11 +1149,6 @@ clapper_gtk_video_root (GtkWidget *widget)
|
|||||||
G_CALLBACK (_window_is_active_cb), self);
|
G_CALLBACK (_window_is_active_cb), self);
|
||||||
_window_is_active_cb (window, NULL, self);
|
_window_is_active_cb (window, NULL, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->auto_inhibit) {
|
|
||||||
ClapperPlayerState state = clapper_player_get_state (self->player);
|
|
||||||
_set_inhibit_session (self, state == CLAPPER_PLAYER_STATE_PLAYING);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1369,8 +1162,6 @@ clapper_gtk_video_unroot (GtkWidget *widget)
|
|||||||
_window_is_active_cb, self);
|
_window_is_active_cb, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
_set_inhibit_session (self, FALSE);
|
|
||||||
|
|
||||||
GTK_WIDGET_CLASS (parent_class)->unroot (widget);
|
GTK_WIDGET_CLASS (parent_class)->unroot (widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1386,7 +1177,6 @@ clapper_gtk_video_init (ClapperGtkVideo *self)
|
|||||||
|
|
||||||
self->fade_delay = DEFAULT_FADE_DELAY;
|
self->fade_delay = DEFAULT_FADE_DELAY;
|
||||||
self->touch_fade_delay = DEFAULT_TOUCH_FADE_DELAY;
|
self->touch_fade_delay = DEFAULT_TOUCH_FADE_DELAY;
|
||||||
self->auto_inhibit = DEFAULT_AUTO_INHIBIT;
|
|
||||||
|
|
||||||
/* Ensure private types */
|
/* Ensure private types */
|
||||||
g_type_ensure (CLAPPER_GTK_TYPE_STATUS);
|
g_type_ensure (CLAPPER_GTK_TYPE_STATUS);
|
||||||
@@ -1401,15 +1191,18 @@ static void
|
|||||||
clapper_gtk_video_constructed (GObject *object)
|
clapper_gtk_video_constructed (GObject *object)
|
||||||
{
|
{
|
||||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (object);
|
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (object);
|
||||||
GstElement *afilter, *vsink;
|
GstElement *vsink;
|
||||||
|
ClapperPlayer *player;
|
||||||
ClapperQueue *queue;
|
ClapperQueue *queue;
|
||||||
|
|
||||||
self->player = clapper_player_new ();
|
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||||
queue = clapper_player_get_queue (self->player);
|
|
||||||
|
|
||||||
g_signal_connect (self->player, "notify::state",
|
player = clapper_gtk_av_get_player (CLAPPER_GTK_AV_CAST (self));
|
||||||
|
queue = clapper_player_get_queue (player);
|
||||||
|
|
||||||
|
g_signal_connect (player, "notify::state",
|
||||||
G_CALLBACK (_player_state_changed_cb), self);
|
G_CALLBACK (_player_state_changed_cb), self);
|
||||||
g_signal_connect (self->player, "notify::video-sink",
|
g_signal_connect (player, "notify::video-sink",
|
||||||
G_CALLBACK (_video_sink_changed_cb), self);
|
G_CALLBACK (_video_sink_changed_cb), self);
|
||||||
|
|
||||||
vsink = gst_element_factory_make ("clappersink", NULL);
|
vsink = gst_element_factory_make ("clappersink", NULL);
|
||||||
@@ -1429,28 +1222,23 @@ clapper_gtk_video_constructed (GObject *object)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clapper_player_set_video_sink (self->player, vsink);
|
clapper_player_set_video_sink (player, vsink);
|
||||||
}
|
}
|
||||||
|
|
||||||
afilter = gst_element_factory_make ("scaletempo", NULL);
|
g_signal_connect (player, "error",
|
||||||
if (G_LIKELY (afilter != NULL))
|
|
||||||
clapper_player_set_audio_filter (self->player, afilter);
|
|
||||||
|
|
||||||
g_signal_connect (self->player, "error",
|
|
||||||
G_CALLBACK (_player_error_cb), self);
|
G_CALLBACK (_player_error_cb), self);
|
||||||
g_signal_connect (self->player, "missing-plugin",
|
g_signal_connect (player, "missing-plugin",
|
||||||
G_CALLBACK (_player_missing_plugin_cb), self);
|
G_CALLBACK (_player_missing_plugin_cb), self);
|
||||||
|
|
||||||
g_signal_connect (queue, "notify::current-item",
|
g_signal_connect (queue, "notify::current-item",
|
||||||
G_CALLBACK (_queue_current_item_changed_cb), self);
|
G_CALLBACK (_queue_current_item_changed_cb), self);
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->constructed (object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clapper_gtk_video_dispose (GObject *object)
|
clapper_gtk_video_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (object);
|
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (object);
|
||||||
|
ClapperPlayer *player;
|
||||||
|
|
||||||
if (self->notify_revealed_id != 0) {
|
if (self->notify_revealed_id != 0) {
|
||||||
GtkRevealer *revealer = GTK_REVEALER (g_ptr_array_index (self->fading_overlays, 0));
|
GtkRevealer *revealer = GTK_REVEALER (g_ptr_array_index (self->fading_overlays, 0));
|
||||||
@@ -1461,18 +1249,20 @@ clapper_gtk_video_dispose (GObject *object)
|
|||||||
|
|
||||||
g_clear_handle_id (&self->fade_timeout, g_source_remove);
|
g_clear_handle_id (&self->fade_timeout, g_source_remove);
|
||||||
|
|
||||||
|
player = clapper_gtk_av_get_player (CLAPPER_GTK_AV_CAST (self));
|
||||||
|
|
||||||
/* Something else might still be holding a reference on the player,
|
/* Something else might still be holding a reference on the player,
|
||||||
* thus we should disconnect everything before disposing template */
|
* thus we should disconnect everything before disposing template */
|
||||||
if (self->player) {
|
if (player) { // NULL if dispose run multiple times
|
||||||
ClapperQueue *queue = clapper_player_get_queue (self->player);
|
ClapperQueue *queue = clapper_player_get_queue (player);
|
||||||
|
|
||||||
g_signal_handlers_disconnect_by_func (self->player,
|
g_signal_handlers_disconnect_by_func (player,
|
||||||
_player_state_changed_cb, self);
|
_player_state_changed_cb, self);
|
||||||
g_signal_handlers_disconnect_by_func (self->player,
|
g_signal_handlers_disconnect_by_func (player,
|
||||||
_video_sink_changed_cb, self);
|
_video_sink_changed_cb, self);
|
||||||
g_signal_handlers_disconnect_by_func (self->player,
|
g_signal_handlers_disconnect_by_func (player,
|
||||||
_player_error_cb, self);
|
_player_error_cb, self);
|
||||||
g_signal_handlers_disconnect_by_func (self->player,
|
g_signal_handlers_disconnect_by_func (player,
|
||||||
_player_missing_plugin_cb, self);
|
_player_missing_plugin_cb, self);
|
||||||
|
|
||||||
g_signal_handlers_disconnect_by_func (queue,
|
g_signal_handlers_disconnect_by_func (queue,
|
||||||
@@ -1482,7 +1272,6 @@ clapper_gtk_video_dispose (GObject *object)
|
|||||||
gtk_widget_dispose_template (GTK_WIDGET (object), CLAPPER_GTK_TYPE_VIDEO);
|
gtk_widget_dispose_template (GTK_WIDGET (object), CLAPPER_GTK_TYPE_VIDEO);
|
||||||
|
|
||||||
g_clear_pointer (&self->overlay, gtk_widget_unparent);
|
g_clear_pointer (&self->overlay, gtk_widget_unparent);
|
||||||
gst_clear_object (&self->player);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
@@ -1505,21 +1294,12 @@ clapper_gtk_video_get_property (GObject *object, guint prop_id,
|
|||||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (object);
|
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (object);
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_PLAYER:
|
|
||||||
g_value_set_object (value, clapper_gtk_video_get_player (self));
|
|
||||||
break;
|
|
||||||
case PROP_FADE_DELAY:
|
case PROP_FADE_DELAY:
|
||||||
g_value_set_uint (value, clapper_gtk_video_get_fade_delay (self));
|
g_value_set_uint (value, clapper_gtk_video_get_fade_delay (self));
|
||||||
break;
|
break;
|
||||||
case PROP_TOUCH_FADE_DELAY:
|
case PROP_TOUCH_FADE_DELAY:
|
||||||
g_value_set_uint (value, clapper_gtk_video_get_touch_fade_delay (self));
|
g_value_set_uint (value, clapper_gtk_video_get_touch_fade_delay (self));
|
||||||
break;
|
break;
|
||||||
case PROP_AUTO_INHIBIT:
|
|
||||||
g_value_set_boolean (value, clapper_gtk_video_get_auto_inhibit (self));
|
|
||||||
break;
|
|
||||||
case PROP_INHIBITED:
|
|
||||||
g_value_set_boolean (value, clapper_gtk_video_get_inhibited (self));
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@@ -1539,9 +1319,6 @@ clapper_gtk_video_set_property (GObject *object, guint prop_id,
|
|||||||
case PROP_TOUCH_FADE_DELAY:
|
case PROP_TOUCH_FADE_DELAY:
|
||||||
clapper_gtk_video_set_touch_fade_delay (self, g_value_get_uint (value));
|
clapper_gtk_video_set_touch_fade_delay (self, g_value_get_uint (value));
|
||||||
break;
|
break;
|
||||||
case PROP_AUTO_INHIBIT:
|
|
||||||
clapper_gtk_video_set_auto_inhibit (self, g_value_get_boolean (value));
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@@ -1566,15 +1343,6 @@ clapper_gtk_video_class_init (ClapperGtkVideoClass *klass)
|
|||||||
gobject_class->dispose = clapper_gtk_video_dispose;
|
gobject_class->dispose = clapper_gtk_video_dispose;
|
||||||
gobject_class->finalize = clapper_gtk_video_finalize;
|
gobject_class->finalize = clapper_gtk_video_finalize;
|
||||||
|
|
||||||
/**
|
|
||||||
* ClapperGtkVideo:player:
|
|
||||||
*
|
|
||||||
* A #ClapperPlayer used by video.
|
|
||||||
*/
|
|
||||||
param_specs[PROP_PLAYER] = g_param_spec_object ("player",
|
|
||||||
NULL, NULL, CLAPPER_TYPE_PLAYER,
|
|
||||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClapperGtkVideo:fade-delay:
|
* ClapperGtkVideo:fade-delay:
|
||||||
*
|
*
|
||||||
@@ -1594,24 +1362,6 @@ clapper_gtk_video_class_init (ClapperGtkVideoClass *klass)
|
|||||||
NULL, NULL, 1, G_MAXUINT, DEFAULT_TOUCH_FADE_DELAY,
|
NULL, NULL, 1, G_MAXUINT, DEFAULT_TOUCH_FADE_DELAY,
|
||||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
/**
|
|
||||||
* ClapperGtkVideo:auto-inhibit:
|
|
||||||
*
|
|
||||||
* Try to automatically inhibit session when video is playing.
|
|
||||||
*/
|
|
||||||
param_specs[PROP_AUTO_INHIBIT] = g_param_spec_boolean ("auto-inhibit",
|
|
||||||
NULL, NULL, DEFAULT_AUTO_INHIBIT,
|
|
||||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ClapperGtkVideo:inhibited:
|
|
||||||
*
|
|
||||||
* Get whether session is currently inhibited by the video.
|
|
||||||
*/
|
|
||||||
param_specs[PROP_INHIBITED] = g_param_spec_boolean ("inhibited",
|
|
||||||
NULL, NULL, FALSE,
|
|
||||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClapperGtkVideo::toggle-fullscreen:
|
* ClapperGtkVideo::toggle-fullscreen:
|
||||||
* @video: a #ClapperGtkVideo
|
* @video: a #ClapperGtkVideo
|
||||||
@@ -1643,6 +1393,8 @@ clapper_gtk_video_class_init (ClapperGtkVideoClass *klass)
|
|||||||
|
|
||||||
g_object_class_install_properties (gobject_class, PROP_LAST, param_specs);
|
g_object_class_install_properties (gobject_class, PROP_LAST, param_specs);
|
||||||
|
|
||||||
|
/* FIXME: 1.0: Remove these actions, since they were moved to
|
||||||
|
* base class AV widget, but are here for compat reasons. */
|
||||||
gtk_widget_class_install_action (widget_class, "video.toggle-play", NULL, toggle_play_action_cb);
|
gtk_widget_class_install_action (widget_class, "video.toggle-play", NULL, toggle_play_action_cb);
|
||||||
gtk_widget_class_install_action (widget_class, "video.play", NULL, play_action_cb);
|
gtk_widget_class_install_action (widget_class, "video.play", NULL, play_action_cb);
|
||||||
gtk_widget_class_install_action (widget_class, "video.pause", NULL, pause_action_cb);
|
gtk_widget_class_install_action (widget_class, "video.pause", NULL, pause_action_cb);
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -28,6 +27,7 @@
|
|||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <clapper/clapper.h>
|
#include <clapper/clapper.h>
|
||||||
|
|
||||||
|
#include <clapper-gtk/clapper-gtk-av.h>
|
||||||
#include <clapper-gtk/clapper-gtk-visibility.h>
|
#include <clapper-gtk/clapper-gtk-visibility.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
@@ -36,7 +36,7 @@ G_BEGIN_DECLS
|
|||||||
#define CLAPPER_GTK_VIDEO_CAST(obj) ((ClapperGtkVideo *)(obj))
|
#define CLAPPER_GTK_VIDEO_CAST(obj) ((ClapperGtkVideo *)(obj))
|
||||||
|
|
||||||
CLAPPER_GTK_API
|
CLAPPER_GTK_API
|
||||||
G_DECLARE_FINAL_TYPE (ClapperGtkVideo, clapper_gtk_video, CLAPPER_GTK, VIDEO, GtkWidget)
|
G_DECLARE_FINAL_TYPE (ClapperGtkVideo, clapper_gtk_video, CLAPPER_GTK, VIDEO, ClapperGtkAv)
|
||||||
|
|
||||||
CLAPPER_GTK_API
|
CLAPPER_GTK_API
|
||||||
GtkWidget * clapper_gtk_video_new (void);
|
GtkWidget * clapper_gtk_video_new (void);
|
||||||
@@ -47,7 +47,7 @@ void clapper_gtk_video_add_overlay (ClapperGtkVideo *video, GtkWidget *widget);
|
|||||||
CLAPPER_GTK_API
|
CLAPPER_GTK_API
|
||||||
void clapper_gtk_video_add_fading_overlay (ClapperGtkVideo *video, GtkWidget *widget);
|
void clapper_gtk_video_add_fading_overlay (ClapperGtkVideo *video, GtkWidget *widget);
|
||||||
|
|
||||||
CLAPPER_GTK_API
|
CLAPPER_GTK_DEPRECATED_FOR(clapper_gtk_av_get_player)
|
||||||
ClapperPlayer * clapper_gtk_video_get_player (ClapperGtkVideo *video);
|
ClapperPlayer * clapper_gtk_video_get_player (ClapperGtkVideo *video);
|
||||||
|
|
||||||
CLAPPER_GTK_API
|
CLAPPER_GTK_API
|
||||||
@@ -62,13 +62,13 @@ void clapper_gtk_video_set_touch_fade_delay (ClapperGtkVideo *video, guint delay
|
|||||||
CLAPPER_GTK_API
|
CLAPPER_GTK_API
|
||||||
guint clapper_gtk_video_get_touch_fade_delay (ClapperGtkVideo *video);
|
guint clapper_gtk_video_get_touch_fade_delay (ClapperGtkVideo *video);
|
||||||
|
|
||||||
CLAPPER_GTK_API
|
CLAPPER_GTK_DEPRECATED_FOR(clapper_gtk_av_set_auto_inhibit)
|
||||||
void clapper_gtk_video_set_auto_inhibit (ClapperGtkVideo *video, gboolean inhibit);
|
void clapper_gtk_video_set_auto_inhibit (ClapperGtkVideo *video, gboolean inhibit);
|
||||||
|
|
||||||
CLAPPER_GTK_API
|
CLAPPER_GTK_DEPRECATED_FOR(clapper_gtk_av_get_auto_inhibit)
|
||||||
gboolean clapper_gtk_video_get_auto_inhibit (ClapperGtkVideo *video);
|
gboolean clapper_gtk_video_get_auto_inhibit (ClapperGtkVideo *video);
|
||||||
|
|
||||||
CLAPPER_GTK_API
|
CLAPPER_GTK_DEPRECATED_FOR(clapper_gtk_av_get_inhibited)
|
||||||
gboolean clapper_gtk_video_get_inhibited (ClapperGtkVideo *video);
|
gboolean clapper_gtk_video_get_inhibited (ClapperGtkVideo *video);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -24,6 +23,8 @@
|
|||||||
#include <clapper-gtk/clapper-gtk-enums.h>
|
#include <clapper-gtk/clapper-gtk-enums.h>
|
||||||
#include <clapper-gtk/clapper-gtk-version.h>
|
#include <clapper-gtk/clapper-gtk-version.h>
|
||||||
|
|
||||||
|
#include <clapper-gtk/clapper-gtk-audio.h>
|
||||||
|
#include <clapper-gtk/clapper-gtk-av.h>
|
||||||
#include <clapper-gtk/clapper-gtk-billboard.h>
|
#include <clapper-gtk/clapper-gtk-billboard.h>
|
||||||
#include <clapper-gtk/clapper-gtk-container.h>
|
#include <clapper-gtk/clapper-gtk-container.h>
|
||||||
#include <clapper-gtk/clapper-gtk-extra-menu-button.h>
|
#include <clapper-gtk/clapper-gtk-extra-menu-button.h>
|
||||||
|
@@ -129,6 +129,15 @@ clapper-gtk-seek-bar label {
|
|||||||
margin-left: 2px;
|
margin-left: 2px;
|
||||||
margin-right: 2px;
|
margin-right: 2px;
|
||||||
}
|
}
|
||||||
|
clapper-gtk-seek-bar scale marks .custom1 indicator {
|
||||||
|
color: tomato;
|
||||||
|
}
|
||||||
|
clapper-gtk-seek-bar scale marks .custom2 indicator {
|
||||||
|
color: goldenrod;
|
||||||
|
}
|
||||||
|
clapper-gtk-seek-bar scale marks .custom3 indicator {
|
||||||
|
color: limegreen;
|
||||||
|
}
|
||||||
|
|
||||||
clapper-gtk-extra-menu-button popover .spinsidebutton {
|
clapper-gtk-extra-menu-button popover .spinsidebutton {
|
||||||
min-width: 28px;
|
min-width: 28px;
|
||||||
|
@@ -90,6 +90,8 @@ clappergtk_conf_inc = [
|
|||||||
|
|
||||||
clappergtk_headers = [
|
clappergtk_headers = [
|
||||||
'clapper-gtk.h',
|
'clapper-gtk.h',
|
||||||
|
'clapper-gtk-audio.h',
|
||||||
|
'clapper-gtk-av.h',
|
||||||
'clapper-gtk-enums.h',
|
'clapper-gtk-enums.h',
|
||||||
'clapper-gtk-billboard.h',
|
'clapper-gtk-billboard.h',
|
||||||
'clapper-gtk-container.h',
|
'clapper-gtk-container.h',
|
||||||
@@ -109,6 +111,8 @@ clappergtk_headers = [
|
|||||||
clappergtk_visibility_header,
|
clappergtk_visibility_header,
|
||||||
]
|
]
|
||||||
clappergtk_sources = [
|
clappergtk_sources = [
|
||||||
|
'clapper-gtk-audio.c',
|
||||||
|
'clapper-gtk-av.c',
|
||||||
'clapper-gtk-billboard.c',
|
'clapper-gtk-billboard.c',
|
||||||
'clapper-gtk-buffering-animation.c',
|
'clapper-gtk-buffering-animation.c',
|
||||||
'clapper-gtk-buffering-paintable.c',
|
'clapper-gtk-buffering-paintable.c',
|
||||||
@@ -127,6 +131,7 @@ clappergtk_sources = [
|
|||||||
'clapper-gtk-toggle-fullscreen-button.c',
|
'clapper-gtk-toggle-fullscreen-button.c',
|
||||||
'clapper-gtk-toggle-play-button.c',
|
'clapper-gtk-toggle-play-button.c',
|
||||||
'clapper-gtk-utils.c',
|
'clapper-gtk-utils.c',
|
||||||
|
'clapper-gtk-version.c',
|
||||||
'clapper-gtk-video.c',
|
'clapper-gtk-video.c',
|
||||||
'clapper-gtk-video-placeholder.c',
|
'clapper-gtk-video-placeholder.c',
|
||||||
clappergtk_resources,
|
clappergtk_resources,
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<interface domain="clapper-gtk">
|
<interface domain="clapper-gtk">
|
||||||
<template class="ClapperGtkVideo" parent="GtkWidget">
|
<template class="ClapperGtkVideo" parent="ClapperGtkAv">
|
||||||
<child type="overlay">
|
<child type="overlay">
|
||||||
<object class="ClapperGtkStatus" id="status">
|
<object class="ClapperGtkStatus" id="status">
|
||||||
<property name="halign">center</property>
|
<property name="halign">center</property>
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -45,12 +44,16 @@ void clapper_app_bus_post_refresh_streams (ClapperAppBus *app_bus, GstObject *sr
|
|||||||
|
|
||||||
void clapper_app_bus_post_refresh_timeline (ClapperAppBus *app_bus, GstObject *src);
|
void clapper_app_bus_post_refresh_timeline (ClapperAppBus *app_bus, GstObject *src);
|
||||||
|
|
||||||
|
void clapper_app_bus_post_insert_playlist (ClapperAppBus *app_bus, GstObject *src, GstObject *playlist_item, GObject *playlist);
|
||||||
|
|
||||||
void clapper_app_bus_post_simple_signal (ClapperAppBus *app_bus, GstObject *src, guint signal_id);
|
void clapper_app_bus_post_simple_signal (ClapperAppBus *app_bus, GstObject *src, guint signal_id);
|
||||||
|
|
||||||
void clapper_app_bus_post_object_desc_signal (ClapperAppBus *app_bus, GstObject *src, guint signal_id, GstObject *object, const gchar *desc);
|
void clapper_app_bus_post_object_desc_signal (ClapperAppBus *app_bus, GstObject *src, guint signal_id, GstObject *object, const gchar *desc);
|
||||||
|
|
||||||
void clapper_app_bus_post_desc_with_details_signal (ClapperAppBus *app_bus, GstObject *src, guint signal_id, const gchar *desc, const gchar *details);
|
void clapper_app_bus_post_desc_with_details_signal (ClapperAppBus *app_bus, GstObject *src, guint signal_id, const gchar *desc, const gchar *details);
|
||||||
|
|
||||||
|
void clapper_app_bus_post_message_signal (ClapperAppBus *app_bus, GstObject *src, guint signal_id, GstMessage *msg);
|
||||||
|
|
||||||
void clapper_app_bus_post_error_signal (ClapperAppBus *app_bus, GstObject *src, guint signal_id, GError *error, const gchar *debug_info);
|
void clapper_app_bus_post_error_signal (ClapperAppBus *app_bus, GstObject *src, guint signal_id, GError *error, const gchar *debug_info);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
@@ -22,6 +21,7 @@
|
|||||||
#include "clapper-bus-private.h"
|
#include "clapper-bus-private.h"
|
||||||
#include "clapper-app-bus-private.h"
|
#include "clapper-app-bus-private.h"
|
||||||
#include "clapper-player-private.h"
|
#include "clapper-player-private.h"
|
||||||
|
#include "clapper-queue-private.h"
|
||||||
#include "clapper-media-item-private.h"
|
#include "clapper-media-item-private.h"
|
||||||
#include "clapper-timeline-private.h"
|
#include "clapper-timeline-private.h"
|
||||||
|
|
||||||
@@ -42,9 +42,11 @@ enum
|
|||||||
CLAPPER_APP_BUS_STRUCTURE_PROP_NOTIFY,
|
CLAPPER_APP_BUS_STRUCTURE_PROP_NOTIFY,
|
||||||
CLAPPER_APP_BUS_STRUCTURE_REFRESH_STREAMS,
|
CLAPPER_APP_BUS_STRUCTURE_REFRESH_STREAMS,
|
||||||
CLAPPER_APP_BUS_STRUCTURE_REFRESH_TIMELINE,
|
CLAPPER_APP_BUS_STRUCTURE_REFRESH_TIMELINE,
|
||||||
|
CLAPPER_APP_BUS_STRUCTURE_INSERT_PLAYLIST,
|
||||||
CLAPPER_APP_BUS_STRUCTURE_SIMPLE_SIGNAL,
|
CLAPPER_APP_BUS_STRUCTURE_SIMPLE_SIGNAL,
|
||||||
CLAPPER_APP_BUS_STRUCTURE_OBJECT_DESC_SIGNAL,
|
CLAPPER_APP_BUS_STRUCTURE_OBJECT_DESC_SIGNAL,
|
||||||
CLAPPER_APP_BUS_STRUCTURE_DESC_WITH_DETAILS_SIGNAL,
|
CLAPPER_APP_BUS_STRUCTURE_DESC_WITH_DETAILS_SIGNAL,
|
||||||
|
CLAPPER_APP_BUS_STRUCTURE_MESSAGE_SIGNAL,
|
||||||
CLAPPER_APP_BUS_STRUCTURE_ERROR_SIGNAL
|
CLAPPER_APP_BUS_STRUCTURE_ERROR_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -53,9 +55,11 @@ static ClapperBusQuark _structure_quarks[] = {
|
|||||||
{"prop-notify", 0},
|
{"prop-notify", 0},
|
||||||
{"refresh-streams", 0},
|
{"refresh-streams", 0},
|
||||||
{"refresh-timeline", 0},
|
{"refresh-timeline", 0},
|
||||||
|
{"insert-playlist", 0},
|
||||||
{"simple-signal", 0},
|
{"simple-signal", 0},
|
||||||
{"object-desc-signal", 0},
|
{"object-desc-signal", 0},
|
||||||
{"desc-with-details-signal", 0},
|
{"desc-with-details-signal", 0},
|
||||||
|
{"message", 0},
|
||||||
{"error-signal", 0},
|
{"error-signal", 0},
|
||||||
{NULL, 0}
|
{NULL, 0}
|
||||||
};
|
};
|
||||||
@@ -66,6 +70,7 @@ enum
|
|||||||
CLAPPER_APP_BUS_FIELD_PSPEC,
|
CLAPPER_APP_BUS_FIELD_PSPEC,
|
||||||
CLAPPER_APP_BUS_FIELD_SIGNAL_ID,
|
CLAPPER_APP_BUS_FIELD_SIGNAL_ID,
|
||||||
CLAPPER_APP_BUS_FIELD_OBJECT,
|
CLAPPER_APP_BUS_FIELD_OBJECT,
|
||||||
|
CLAPPER_APP_BUS_FIELD_OTHER_OBJECT,
|
||||||
CLAPPER_APP_BUS_FIELD_DESC,
|
CLAPPER_APP_BUS_FIELD_DESC,
|
||||||
CLAPPER_APP_BUS_FIELD_DETAILS,
|
CLAPPER_APP_BUS_FIELD_DETAILS,
|
||||||
CLAPPER_APP_BUS_FIELD_ERROR,
|
CLAPPER_APP_BUS_FIELD_ERROR,
|
||||||
@@ -77,6 +82,7 @@ static ClapperBusQuark _field_quarks[] = {
|
|||||||
{"pspec", 0},
|
{"pspec", 0},
|
||||||
{"signal-id", 0},
|
{"signal-id", 0},
|
||||||
{"object", 0},
|
{"object", 0},
|
||||||
|
{"other-object", 0},
|
||||||
{"desc", 0},
|
{"desc", 0},
|
||||||
{"details", 0},
|
{"details", 0},
|
||||||
{"error", 0},
|
{"error", 0},
|
||||||
@@ -161,6 +167,36 @@ _handle_refresh_timeline_msg (GstMessage *msg, const GstStructure *structure)
|
|||||||
clapper_timeline_refresh (timeline);
|
clapper_timeline_refresh (timeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clapper_app_bus_post_insert_playlist (ClapperAppBus *self, GstObject *src,
|
||||||
|
GstObject *playlist_item, GObject *playlist)
|
||||||
|
{
|
||||||
|
GstStructure *structure = gst_structure_new_id (_STRUCTURE_QUARK (INSERT_PLAYLIST),
|
||||||
|
_FIELD_QUARK (OBJECT), GST_TYPE_OBJECT, playlist_item,
|
||||||
|
_FIELD_QUARK (OTHER_OBJECT), G_TYPE_OBJECT, playlist,
|
||||||
|
NULL);
|
||||||
|
gst_bus_post (GST_BUS_CAST (self), gst_message_new_application (src, structure));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
_handle_insert_playlist_msg (GstMessage *msg, const GstStructure *structure)
|
||||||
|
{
|
||||||
|
ClapperPlayer *player = CLAPPER_PLAYER_CAST (GST_MESSAGE_SRC (msg));
|
||||||
|
ClapperQueue *queue = clapper_player_get_queue (player);
|
||||||
|
GstObject *playlist_item;
|
||||||
|
GObject *playlist;
|
||||||
|
|
||||||
|
gst_structure_id_get (structure,
|
||||||
|
_FIELD_QUARK (OBJECT), GST_TYPE_OBJECT, &playlist_item,
|
||||||
|
_FIELD_QUARK (OTHER_OBJECT), G_TYPE_OBJECT, &playlist,
|
||||||
|
NULL);
|
||||||
|
clapper_queue_handle_playlist (queue,
|
||||||
|
CLAPPER_MEDIA_ITEM (playlist_item), G_LIST_STORE (playlist));
|
||||||
|
|
||||||
|
gst_object_unref (playlist_item);
|
||||||
|
g_object_unref (playlist);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
clapper_app_bus_post_simple_signal (ClapperAppBus *self, GstObject *src, guint signal_id)
|
clapper_app_bus_post_simple_signal (ClapperAppBus *self, GstObject *src, guint signal_id)
|
||||||
{
|
{
|
||||||
@@ -242,6 +278,53 @@ _handle_desc_with_details_signal_msg (GstMessage *msg, const GstStructure *struc
|
|||||||
g_free (details);
|
g_free (details);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clapper_app_bus_post_message_signal (ClapperAppBus *self,
|
||||||
|
GstObject *src, guint signal_id, GstMessage *msg)
|
||||||
|
{
|
||||||
|
/* Check for any "message" signal connection */
|
||||||
|
if (g_signal_handler_find (src, G_SIGNAL_MATCH_ID,
|
||||||
|
signal_id, 0, NULL, NULL, NULL) != 0) {
|
||||||
|
const GstStructure *structure = gst_message_get_structure (msg);
|
||||||
|
GQuark detail;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (structure == NULL))
|
||||||
|
return;
|
||||||
|
|
||||||
|
detail = g_quark_from_string (gst_structure_get_name (structure));
|
||||||
|
|
||||||
|
/* If specific detail is connected or ALL "message" handler */
|
||||||
|
if (g_signal_handler_find (src, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL,
|
||||||
|
signal_id, detail, NULL, NULL, NULL) != 0
|
||||||
|
|| g_signal_handler_find (src, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL,
|
||||||
|
signal_id, 0, NULL, NULL, NULL) != 0) {
|
||||||
|
GstStructure *structure = gst_structure_new_id (_STRUCTURE_QUARK (MESSAGE_SIGNAL),
|
||||||
|
_FIELD_QUARK (SIGNAL_ID), G_TYPE_UINT, signal_id,
|
||||||
|
_FIELD_QUARK (DETAILS), G_TYPE_UINT, detail,
|
||||||
|
_FIELD_QUARK (OBJECT), GST_TYPE_MESSAGE, msg,
|
||||||
|
NULL);
|
||||||
|
gst_bus_post (GST_BUS_CAST (self), gst_message_new_application (src, structure));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
_handle_message_signal_msg (GstMessage *msg, const GstStructure *structure)
|
||||||
|
{
|
||||||
|
guint signal_id = 0;
|
||||||
|
GQuark detail = 0;
|
||||||
|
GstMessage *fwd_message = NULL;
|
||||||
|
|
||||||
|
gst_structure_id_get (structure,
|
||||||
|
_FIELD_QUARK (SIGNAL_ID), G_TYPE_UINT, &signal_id,
|
||||||
|
_FIELD_QUARK (DETAILS), G_TYPE_UINT, &detail,
|
||||||
|
_FIELD_QUARK (OBJECT), GST_TYPE_MESSAGE, &fwd_message,
|
||||||
|
NULL);
|
||||||
|
g_signal_emit (_MESSAGE_SRC_GOBJECT (msg), signal_id, detail, fwd_message);
|
||||||
|
|
||||||
|
gst_message_unref (fwd_message);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
clapper_app_bus_post_error_signal (ClapperAppBus *self,
|
clapper_app_bus_post_error_signal (ClapperAppBus *self,
|
||||||
GstObject *src, guint signal_id,
|
GstObject *src, guint signal_id,
|
||||||
@@ -286,10 +369,14 @@ clapper_app_bus_message_func (GstBus *bus, GstMessage *msg, gpointer user_data G
|
|||||||
_handle_refresh_streams_msg (msg, structure);
|
_handle_refresh_streams_msg (msg, structure);
|
||||||
else if (quark == _STRUCTURE_QUARK (REFRESH_TIMELINE))
|
else if (quark == _STRUCTURE_QUARK (REFRESH_TIMELINE))
|
||||||
_handle_refresh_timeline_msg (msg, structure);
|
_handle_refresh_timeline_msg (msg, structure);
|
||||||
|
else if (quark == _STRUCTURE_QUARK (INSERT_PLAYLIST))
|
||||||
|
_handle_insert_playlist_msg (msg, structure);
|
||||||
else if (quark == _STRUCTURE_QUARK (SIMPLE_SIGNAL))
|
else if (quark == _STRUCTURE_QUARK (SIMPLE_SIGNAL))
|
||||||
_handle_simple_signal_msg (msg, structure);
|
_handle_simple_signal_msg (msg, structure);
|
||||||
else if (quark == _STRUCTURE_QUARK (OBJECT_DESC_SIGNAL))
|
else if (quark == _STRUCTURE_QUARK (OBJECT_DESC_SIGNAL))
|
||||||
_handle_object_desc_signal_msg (msg, structure);
|
_handle_object_desc_signal_msg (msg, structure);
|
||||||
|
else if (quark == _STRUCTURE_QUARK (MESSAGE_SIGNAL))
|
||||||
|
_handle_message_signal_msg (msg, structure);
|
||||||
else if (quark == _STRUCTURE_QUARK (ERROR_SIGNAL))
|
else if (quark == _STRUCTURE_QUARK (ERROR_SIGNAL))
|
||||||
_handle_error_signal_msg (msg, structure);
|
_handle_error_signal_msg (msg, structure);
|
||||||
else if (quark == _STRUCTURE_QUARK (DESC_WITH_DETAILS_SIGNAL))
|
else if (quark == _STRUCTURE_QUARK (DESC_WITH_DETAILS_SIGNAL))
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,14 +12,15 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "clapper-cache-private.h"
|
#include "clapper-cache-private.h"
|
||||||
#include "clapper-version.h"
|
#include "clapper-version.h"
|
||||||
|
|
||||||
#include "clapper-extractable.h"
|
#include "clapper-extractable.h"
|
||||||
|
#include "clapper-playlistable.h"
|
||||||
#include "clapper-reactable.h"
|
#include "clapper-reactable.h"
|
||||||
|
|
||||||
#define CLAPPER_CACHE_HEADER "CLAPPER"
|
#define CLAPPER_CACHE_HEADER "CLAPPER"
|
||||||
@@ -27,6 +28,7 @@
|
|||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
CLAPPER_CACHE_IFACE_EXTRACTABLE = 1,
|
CLAPPER_CACHE_IFACE_EXTRACTABLE = 1,
|
||||||
|
CLAPPER_CACHE_IFACE_PLAYLISTABLE,
|
||||||
CLAPPER_CACHE_IFACE_REACTABLE,
|
CLAPPER_CACHE_IFACE_REACTABLE,
|
||||||
} ClapperCacheIfaces;
|
} ClapperCacheIfaces;
|
||||||
|
|
||||||
@@ -245,6 +247,8 @@ clapper_cache_read_iface (const gchar **data)
|
|||||||
switch (iface_id) {
|
switch (iface_id) {
|
||||||
case CLAPPER_CACHE_IFACE_EXTRACTABLE:
|
case CLAPPER_CACHE_IFACE_EXTRACTABLE:
|
||||||
return CLAPPER_TYPE_EXTRACTABLE;
|
return CLAPPER_TYPE_EXTRACTABLE;
|
||||||
|
case CLAPPER_CACHE_IFACE_PLAYLISTABLE:
|
||||||
|
return CLAPPER_TYPE_PLAYLISTABLE;
|
||||||
case CLAPPER_CACHE_IFACE_REACTABLE:
|
case CLAPPER_CACHE_IFACE_REACTABLE:
|
||||||
return CLAPPER_TYPE_REACTABLE;
|
return CLAPPER_TYPE_REACTABLE;
|
||||||
default:
|
default:
|
||||||
@@ -437,6 +441,8 @@ clapper_cache_store_iface (GByteArray *bytes, GType iface)
|
|||||||
|
|
||||||
if (iface == CLAPPER_TYPE_EXTRACTABLE)
|
if (iface == CLAPPER_TYPE_EXTRACTABLE)
|
||||||
iface_id = CLAPPER_CACHE_IFACE_EXTRACTABLE;
|
iface_id = CLAPPER_CACHE_IFACE_EXTRACTABLE;
|
||||||
|
else if (iface == CLAPPER_TYPE_PLAYLISTABLE)
|
||||||
|
iface_id = CLAPPER_CACHE_IFACE_PLAYLISTABLE;
|
||||||
else if (iface == CLAPPER_TYPE_REACTABLE)
|
else if (iface == CLAPPER_TYPE_REACTABLE)
|
||||||
iface_id = CLAPPER_CACHE_IFACE_REACTABLE;
|
iface_id = CLAPPER_CACHE_IFACE_REACTABLE;
|
||||||
else
|
else
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,12 +46,14 @@
|
|||||||
#include "clapper-enhancer-proxy-list.h"
|
#include "clapper-enhancer-proxy-list.h"
|
||||||
#include "clapper-basic-functions.h"
|
#include "clapper-basic-functions.h"
|
||||||
#include "clapper-cache-private.h"
|
#include "clapper-cache-private.h"
|
||||||
#include "clapper-extractable.h"
|
|
||||||
#include "clapper-reactable.h"
|
|
||||||
#include "clapper-player-private.h"
|
#include "clapper-player-private.h"
|
||||||
#include "clapper-utils-private.h"
|
#include "clapper-utils-private.h"
|
||||||
#include "clapper-enums.h"
|
#include "clapper-enums.h"
|
||||||
|
|
||||||
|
#include "clapper-extractable.h"
|
||||||
|
#include "clapper-playlistable.h"
|
||||||
|
#include "clapper-reactable.h"
|
||||||
|
|
||||||
#include "clapper-functionalities-availability.h"
|
#include "clapper-functionalities-availability.h"
|
||||||
|
|
||||||
#if CLAPPER_WITH_ENHANCERS_LOADER
|
#if CLAPPER_WITH_ENHANCERS_LOADER
|
||||||
@@ -87,6 +88,8 @@ struct _ClapperEnhancerProxy
|
|||||||
ClapperEnhancerParamFlags scope;
|
ClapperEnhancerParamFlags scope;
|
||||||
GstStructure *local_config;
|
GstStructure *local_config;
|
||||||
|
|
||||||
|
gboolean allowed;
|
||||||
|
|
||||||
/* GSettings are not thread-safe,
|
/* GSettings are not thread-safe,
|
||||||
* so store schema instead */
|
* so store schema instead */
|
||||||
GSettingsSchema *schema;
|
GSettingsSchema *schema;
|
||||||
@@ -101,6 +104,7 @@ enum
|
|||||||
PROP_MODULE_DIR,
|
PROP_MODULE_DIR,
|
||||||
PROP_DESCRIPTION,
|
PROP_DESCRIPTION,
|
||||||
PROP_VERSION,
|
PROP_VERSION,
|
||||||
|
PROP_TARGET_CREATION_ALLOWED,
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -230,6 +234,8 @@ clapper_enhancer_proxy_copy (ClapperEnhancerProxy *src_proxy, const gchar *copy_
|
|||||||
if (src_proxy->local_config)
|
if (src_proxy->local_config)
|
||||||
copy->local_config = gst_structure_copy (src_proxy->local_config);
|
copy->local_config = gst_structure_copy (src_proxy->local_config);
|
||||||
|
|
||||||
|
copy->allowed = src_proxy->allowed;
|
||||||
|
|
||||||
GST_OBJECT_UNLOCK (src_proxy);
|
GST_OBJECT_UNLOCK (src_proxy);
|
||||||
|
|
||||||
gst_object_ref_sink (copy);
|
gst_object_ref_sink (copy);
|
||||||
@@ -360,6 +366,8 @@ clapper_enhancer_proxy_fill_from_cache (ClapperEnhancerProxy *self)
|
|||||||
if (G_UNLIKELY ((self->ifaces[i] = clapper_cache_read_iface (&data)) == 0))
|
if (G_UNLIKELY ((self->ifaces[i] = clapper_cache_read_iface (&data)) == 0))
|
||||||
goto abort_reading;
|
goto abort_reading;
|
||||||
}
|
}
|
||||||
|
/* Reactable type is always last */
|
||||||
|
self->allowed = (self->ifaces[self->n_ifaces - 1] != CLAPPER_TYPE_REACTABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore ParamSpecs */
|
/* Restore ParamSpecs */
|
||||||
@@ -457,7 +465,8 @@ clapper_enhancer_proxy_export_to_cache (ClapperEnhancerProxy *self)
|
|||||||
gboolean
|
gboolean
|
||||||
clapper_enhancer_proxy_fill_from_instance (ClapperEnhancerProxy *self, GObject *enhancer)
|
clapper_enhancer_proxy_fill_from_instance (ClapperEnhancerProxy *self, GObject *enhancer)
|
||||||
{
|
{
|
||||||
const GType enhancer_types[] = { CLAPPER_TYPE_EXTRACTABLE, CLAPPER_TYPE_REACTABLE };
|
/* NOTE: REACTABLE must be last for "allowed" to work as expected */
|
||||||
|
const GType enhancer_types[] = { CLAPPER_TYPE_EXTRACTABLE, CLAPPER_TYPE_PLAYLISTABLE, CLAPPER_TYPE_REACTABLE };
|
||||||
GType *ifaces;
|
GType *ifaces;
|
||||||
GParamSpec **pspecs;
|
GParamSpec **pspecs;
|
||||||
GParamFlags enhancer_flags;
|
GParamFlags enhancer_flags;
|
||||||
@@ -466,9 +475,12 @@ clapper_enhancer_proxy_fill_from_instance (ClapperEnhancerProxy *self, GObject *
|
|||||||
/* Filter to only Clapper interfaces */
|
/* Filter to only Clapper interfaces */
|
||||||
ifaces = g_type_interfaces (G_OBJECT_TYPE (enhancer), &n);
|
ifaces = g_type_interfaces (G_OBJECT_TYPE (enhancer), &n);
|
||||||
for (i = 0; i < n; ++i) {
|
for (i = 0; i < n; ++i) {
|
||||||
for (j = 0; j < G_N_ELEMENTS (enhancer_types); ++j) {
|
const guint n_types = G_N_ELEMENTS (enhancer_types);
|
||||||
|
|
||||||
|
for (j = 0; j < n_types; ++j) {
|
||||||
if (ifaces[i] == enhancer_types[j]) {
|
if (ifaces[i] == enhancer_types[j]) {
|
||||||
ifaces[write_index++] = ifaces[i];
|
ifaces[write_index++] = ifaces[i];
|
||||||
|
self->allowed = (j < n_types - 1);
|
||||||
break; // match found, do next iface
|
break; // match found, do next iface
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1089,6 +1101,58 @@ clapper_enhancer_proxy_set_locally_with_table (ClapperEnhancerProxy *self, GHash
|
|||||||
gst_structure_free (structure);
|
gst_structure_free (structure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clapper_enhancer_proxy_set_target_creation_allowed:
|
||||||
|
* @proxy: a #ClapperEnhancerProxy
|
||||||
|
* @allowed: whether allowed
|
||||||
|
*
|
||||||
|
* Set whether to allow instances of proxy target to be created.
|
||||||
|
*
|
||||||
|
* See [property@Clapper.EnhancerProxy:target-creation-allowed] for
|
||||||
|
* detailed descripton what this does.
|
||||||
|
*
|
||||||
|
* Since: 0.10
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clapper_enhancer_proxy_set_target_creation_allowed (ClapperEnhancerProxy *self, gboolean allowed)
|
||||||
|
{
|
||||||
|
gboolean changed;
|
||||||
|
|
||||||
|
g_return_if_fail (CLAPPER_IS_ENHANCER_PROXY (self));
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (self);
|
||||||
|
if ((changed = self->allowed != allowed))
|
||||||
|
self->allowed = allowed;
|
||||||
|
GST_OBJECT_UNLOCK (self);
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (self), param_specs[PROP_TARGET_CREATION_ALLOWED]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clapper_enhancer_proxy_get_target_creation_allowed:
|
||||||
|
* @proxy: a #ClapperEnhancerProxy
|
||||||
|
*
|
||||||
|
* Get whether it is allowed to create instances of enhancer that this proxy targets.
|
||||||
|
*
|
||||||
|
* Returns: whether target creation is allowed.
|
||||||
|
*
|
||||||
|
* Since: 0.10
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
clapper_enhancer_proxy_get_target_creation_allowed (ClapperEnhancerProxy *self)
|
||||||
|
{
|
||||||
|
gboolean allowed;
|
||||||
|
|
||||||
|
g_return_val_if_fail (CLAPPER_IS_ENHANCER_PROXY (self), FALSE);
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (self);
|
||||||
|
allowed = self->allowed;
|
||||||
|
GST_OBJECT_UNLOCK (self);
|
||||||
|
|
||||||
|
return allowed;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clapper_enhancer_proxy_init (ClapperEnhancerProxy *self)
|
clapper_enhancer_proxy_init (ClapperEnhancerProxy *self)
|
||||||
{
|
{
|
||||||
@@ -1138,6 +1202,25 @@ clapper_enhancer_proxy_get_property (GObject *object, guint prop_id,
|
|||||||
case PROP_VERSION:
|
case PROP_VERSION:
|
||||||
g_value_set_string (value, clapper_enhancer_proxy_get_version (self));
|
g_value_set_string (value, clapper_enhancer_proxy_get_version (self));
|
||||||
break;
|
break;
|
||||||
|
case PROP_TARGET_CREATION_ALLOWED:
|
||||||
|
g_value_set_boolean (value, clapper_enhancer_proxy_get_target_creation_allowed (self));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clapper_enhancer_proxy_set_property (GObject *object, guint prop_id,
|
||||||
|
const GValue *value, GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ClapperEnhancerProxy *self = CLAPPER_ENHANCER_PROXY_CAST (object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_TARGET_CREATION_ALLOWED:
|
||||||
|
clapper_enhancer_proxy_set_target_creation_allowed (self, g_value_get_boolean (value));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@@ -1153,6 +1236,7 @@ clapper_enhancer_proxy_class_init (ClapperEnhancerProxyClass *klass)
|
|||||||
"Clapper Enhancer Proxy");
|
"Clapper Enhancer Proxy");
|
||||||
|
|
||||||
gobject_class->get_property = clapper_enhancer_proxy_get_property;
|
gobject_class->get_property = clapper_enhancer_proxy_get_property;
|
||||||
|
gobject_class->set_property = clapper_enhancer_proxy_set_property;
|
||||||
gobject_class->finalize = clapper_enhancer_proxy_finalize;
|
gobject_class->finalize = clapper_enhancer_proxy_finalize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1210,5 +1294,29 @@ clapper_enhancer_proxy_class_init (ClapperEnhancerProxyClass *klass)
|
|||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClapperEnhancerProxy:target-creation-allowed:
|
||||||
|
*
|
||||||
|
* Whether to allow instances of proxy target to be created.
|
||||||
|
*
|
||||||
|
* This effectively means whether the given enhancer can be used.
|
||||||
|
*
|
||||||
|
* By default all enhancers that work on-demand ([iface@Clapper.Extractable], [iface@Clapper.Playlistable])
|
||||||
|
* are allowed while enhancers implementing [iface@Clapper.Reactable] are not.
|
||||||
|
*
|
||||||
|
* Value of this property from a `GLOBAL` [class@Clapper.EnhancerProxyList] will carry
|
||||||
|
* over to all newly created [class@Clapper.Player] objects, while altering this on
|
||||||
|
* `LOCAL` proxy list will only influence given player instance that list belongs to.
|
||||||
|
*
|
||||||
|
* Changing this property will not remove already created enhancer instances, thus
|
||||||
|
* it is usually best practice to allow/disallow creation of given enhancer plugin
|
||||||
|
* right after [class@Clapper.Player] is created (before it or its queue are used).
|
||||||
|
*
|
||||||
|
* Since: 0.10
|
||||||
|
*/
|
||||||
|
param_specs[PROP_TARGET_CREATION_ALLOWED] = g_param_spec_boolean ("target-creation-allowed",
|
||||||
|
NULL, NULL, FALSE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
g_object_class_install_properties (gobject_class, PROP_LAST, param_specs);
|
g_object_class_install_properties (gobject_class, PROP_LAST, param_specs);
|
||||||
}
|
}
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -77,4 +76,10 @@ void clapper_enhancer_proxy_set_locally (ClapperEnhancerProxy *proxy, const gcha
|
|||||||
CLAPPER_API
|
CLAPPER_API
|
||||||
void clapper_enhancer_proxy_set_locally_with_table (ClapperEnhancerProxy *proxy, GHashTable *table);
|
void clapper_enhancer_proxy_set_locally_with_table (ClapperEnhancerProxy *proxy, GHashTable *table);
|
||||||
|
|
||||||
|
CLAPPER_API
|
||||||
|
void clapper_enhancer_proxy_set_target_creation_allowed (ClapperEnhancerProxy *proxy, gboolean allowed);
|
||||||
|
|
||||||
|
CLAPPER_API
|
||||||
|
gboolean clapper_enhancer_proxy_get_target_creation_allowed (ClapperEnhancerProxy *proxy);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@@ -33,10 +32,9 @@ static HMODULE _enhancers_dll_handle = NULL;
|
|||||||
|
|
||||||
// Supported interfaces
|
// Supported interfaces
|
||||||
#include "clapper-extractable.h"
|
#include "clapper-extractable.h"
|
||||||
|
#include "clapper-playlistable.h"
|
||||||
#include "clapper-reactable.h"
|
#include "clapper-reactable.h"
|
||||||
|
|
||||||
#include <clapper-functionalities-availability.h>
|
|
||||||
|
|
||||||
#define GST_CAT_DEFAULT clapper_enhancers_loader_debug
|
#define GST_CAT_DEFAULT clapper_enhancers_loader_debug
|
||||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||||
|
|
||||||
@@ -55,6 +53,28 @@ _import_enhancers (const gchar *enhancers_path)
|
|||||||
g_strfreev (dir_paths);
|
g_strfreev (dir_paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GObject *
|
||||||
|
_force_create_enhancer (ClapperEnhancerProxy *proxy, GType iface_type)
|
||||||
|
{
|
||||||
|
GObject *enhancer = NULL;
|
||||||
|
PeasPluginInfo *info = (PeasPluginInfo *) clapper_enhancer_proxy_get_peas_info (proxy);
|
||||||
|
|
||||||
|
g_mutex_lock (&load_lock);
|
||||||
|
|
||||||
|
if (!peas_plugin_info_is_loaded (info) && !peas_engine_load_plugin (_engine, info)) {
|
||||||
|
GST_ERROR ("Could not load enhancer: %s", peas_plugin_info_get_module_name (info));
|
||||||
|
} else if (!peas_engine_provides_extension (_engine, info, iface_type)) {
|
||||||
|
GST_LOG ("No \"%s\" enhancer in module: %s", g_type_name (iface_type),
|
||||||
|
peas_plugin_info_get_module_name (info));
|
||||||
|
} else {
|
||||||
|
enhancer = peas_engine_create_extension (_engine, info, iface_type, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_mutex_unlock (&load_lock);
|
||||||
|
|
||||||
|
return enhancer;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* clapper_enhancers_loader_initialize:
|
* clapper_enhancers_loader_initialize:
|
||||||
*
|
*
|
||||||
@@ -113,36 +133,6 @@ clapper_enhancers_loader_initialize (ClapperEnhancerProxyList *proxies)
|
|||||||
ClapperEnhancerProxy *proxy;
|
ClapperEnhancerProxy *proxy;
|
||||||
gboolean filled;
|
gboolean filled;
|
||||||
|
|
||||||
/* FIXME: 1.0: Remove together with features code and manager.
|
|
||||||
* These would clash with each other, so avoid loading these
|
|
||||||
* as enhancers when also compiled as part of the library. */
|
|
||||||
#if (CLAPPER_HAVE_MPRIS || CLAPPER_HAVE_DISCOVERER || CLAPPER_HAVE_SERVER)
|
|
||||||
guint f_index;
|
|
||||||
const gchar *module_name = peas_plugin_info_get_module_name (info);
|
|
||||||
const gchar *ported_features[] = {
|
|
||||||
#if CLAPPER_HAVE_MPRIS
|
|
||||||
"clapper-mpris",
|
|
||||||
#endif
|
|
||||||
#if CLAPPER_HAVE_DISCOVERER
|
|
||||||
"clapper-discoverer",
|
|
||||||
#endif
|
|
||||||
#if CLAPPER_HAVE_SERVER
|
|
||||||
"clapper-server",
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
for (f_index = 0; f_index < G_N_ELEMENTS (ported_features); ++f_index) {
|
|
||||||
if (strcmp (module_name, ported_features[f_index]) == 0) {
|
|
||||||
GST_INFO ("Skipped \"%s\" enhancer module, since its"
|
|
||||||
" loaded from deprecated feature object", module_name);
|
|
||||||
g_clear_object (&info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!info) // cleared when exists as feature
|
|
||||||
continue;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Clapper supports only 1 proxy per plugin. Each plugin can
|
/* Clapper supports only 1 proxy per plugin. Each plugin can
|
||||||
* ship 1 class, but it can implement more than 1 interface. */
|
* ship 1 class, but it can implement more than 1 interface. */
|
||||||
proxy = clapper_enhancer_proxy_new_global_take ((GObject *) info);
|
proxy = clapper_enhancer_proxy_new_global_take ((GObject *) info);
|
||||||
@@ -151,12 +141,12 @@ clapper_enhancers_loader_initialize (ClapperEnhancerProxyList *proxies)
|
|||||||
* Otherwise make an instance and fill missing data from it (slow). */
|
* Otherwise make an instance and fill missing data from it (slow). */
|
||||||
if (!(filled = clapper_enhancer_proxy_fill_from_cache (proxy))) {
|
if (!(filled = clapper_enhancer_proxy_fill_from_cache (proxy))) {
|
||||||
GObject *enhancer;
|
GObject *enhancer;
|
||||||
const GType main_types[] = { CLAPPER_TYPE_EXTRACTABLE, CLAPPER_TYPE_REACTABLE };
|
const GType main_types[] = { CLAPPER_TYPE_EXTRACTABLE, CLAPPER_TYPE_PLAYLISTABLE, CLAPPER_TYPE_REACTABLE };
|
||||||
guint j;
|
guint j;
|
||||||
|
|
||||||
/* We cannot ask libpeas for "any" of our main interfaces, so try each one until found */
|
/* We cannot ask libpeas for "any" of our main interfaces, so try each one until found */
|
||||||
for (j = 0; j < G_N_ELEMENTS (main_types); ++j) {
|
for (j = 0; j < G_N_ELEMENTS (main_types); ++j) {
|
||||||
if ((enhancer = clapper_enhancers_loader_create_enhancer (proxy, main_types[j]))) {
|
if ((enhancer = _force_create_enhancer (proxy, main_types[j]))) {
|
||||||
filled = clapper_enhancer_proxy_fill_from_instance (proxy, enhancer);
|
filled = clapper_enhancer_proxy_fill_from_instance (proxy, enhancer);
|
||||||
g_object_unref (enhancer);
|
g_object_unref (enhancer);
|
||||||
|
|
||||||
@@ -201,21 +191,8 @@ clapper_enhancers_loader_initialize (ClapperEnhancerProxyList *proxies)
|
|||||||
GObject *
|
GObject *
|
||||||
clapper_enhancers_loader_create_enhancer (ClapperEnhancerProxy *proxy, GType iface_type)
|
clapper_enhancers_loader_create_enhancer (ClapperEnhancerProxy *proxy, GType iface_type)
|
||||||
{
|
{
|
||||||
GObject *enhancer = NULL;
|
if (!clapper_enhancer_proxy_get_target_creation_allowed (proxy))
|
||||||
PeasPluginInfo *info = (PeasPluginInfo *) clapper_enhancer_proxy_get_peas_info (proxy);
|
return NULL;
|
||||||
|
|
||||||
g_mutex_lock (&load_lock);
|
return _force_create_enhancer (proxy, iface_type);
|
||||||
|
|
||||||
if (!peas_plugin_info_is_loaded (info) && !peas_engine_load_plugin (_engine, info)) {
|
|
||||||
GST_ERROR ("Could not load enhancer: %s", peas_plugin_info_get_module_name (info));
|
|
||||||
} else if (!peas_engine_provides_extension (_engine, info, iface_type)) {
|
|
||||||
GST_LOG ("No \"%s\" enhancer in module: %s", g_type_name (iface_type),
|
|
||||||
peas_plugin_info_get_module_name (info));
|
|
||||||
} else {
|
|
||||||
enhancer = peas_engine_create_extension (_engine, info, iface_type, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_mutex_unlock (&load_lock);
|
|
||||||
|
|
||||||
return enhancer;
|
|
||||||
}
|
}
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@@ -12,9 +12,8 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, see
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
* <https://www.gnu.org/licenses/>.
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user