Import Upstream version 1.12.7
This commit is contained in:
commit
7189d70440
|
@ -0,0 +1,44 @@
|
|||
*.la
|
||||
*.lo
|
||||
*.log
|
||||
*.memlog
|
||||
*.o
|
||||
*.swp
|
||||
*.tar.xz
|
||||
*.trs
|
||||
.deps/
|
||||
.dirstamp
|
||||
.libs/
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
build-aux/
|
||||
config.h
|
||||
config.h.in
|
||||
config.h.in~
|
||||
config.log
|
||||
config.status
|
||||
configure
|
||||
libtool
|
||||
m4/
|
||||
miracle-dhcp
|
||||
miracle-sinkctl
|
||||
miracle-wifictl
|
||||
miracle-wifid
|
||||
miracle-uibcctl
|
||||
miraclectl
|
||||
miracled
|
||||
stamp-h1
|
||||
test-suite.log
|
||||
test_rtsp
|
||||
test_valgrind
|
||||
test_wpas
|
||||
wpa_cli
|
||||
wpa_supplicant
|
||||
CMakeFiles/
|
||||
cmake_install.cmake
|
||||
CMakeCache.txt
|
||||
libmiracle-shared.a
|
||||
install_manifest.txt
|
||||
/build/
|
|
@ -0,0 +1,35 @@
|
|||
version: v1.0
|
||||
name: Docker
|
||||
|
||||
agent:
|
||||
machine:
|
||||
type: e1-standard-2
|
||||
os_image: ubuntu1804
|
||||
|
||||
global_job_config:
|
||||
secrets:
|
||||
- name: dockerhub
|
||||
|
||||
blocks:
|
||||
- name: Checkout
|
||||
task:
|
||||
jobs:
|
||||
- name: Checkout
|
||||
commands:
|
||||
- checkout
|
||||
- name: Build
|
||||
task:
|
||||
jobs:
|
||||
- name: Autotools
|
||||
commands:
|
||||
- checkout
|
||||
- docker build -t autotools -f autotools.Dockerfile .
|
||||
- name: Cmake
|
||||
commands:
|
||||
- checkout
|
||||
- docker build -t cmake -f cmake.Dockerfile .
|
||||
- name: meson
|
||||
commands:
|
||||
- checkout
|
||||
- docker build -t meson -f meson.Dockerfile .
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
language: c
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- stage: autotools
|
||||
script:
|
||||
docker build -t autotools -f autotools.Dockerfile .
|
||||
- stage: cmake
|
||||
script:
|
||||
docker build -t cmake -f cmake.Dockerfile .
|
||||
- stage: meson
|
||||
script:
|
||||
docker build -t meson -f meson.Dockerfile .
|
|
@ -0,0 +1,52 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
project(Miraclecast)
|
||||
|
||||
SET(PACKAGE_NAME kylin-miraclecast)
|
||||
SET(PACKAGE_VERSION 1)
|
||||
SET(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
|
||||
SET(CMAKE_BUILD_TYPE "Debug")
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake
|
||||
${CMAKE_MODULE_PATH})
|
||||
|
||||
set(CMAKE_C_FLAGS "-std=gnu11 ${CMAKE_C_FLAGS}")
|
||||
add_definitions(-D_GNU_SOURCE)
|
||||
|
||||
SET(BUILD_BINDIR "${CMAKE_INSTALL_PREFIX}/bin")
|
||||
OPTION(BUILD_ENABLE_DEBUG "Enable Debug" ON )
|
||||
OPTION(RELY_UDEV "Rely in udev tag to select device" OFF )
|
||||
OPTION(BUILD_TESTS "Enable TEST" ON )
|
||||
OPTION(BUILD_ENABLE_CPPCHECK "Enable CPPCheck static analysis" OFF )
|
||||
|
||||
if(BUILD_ENABLE_DEBUG)
|
||||
add_definitions(-DBUILD_ENABLE_DEBUG)
|
||||
endif()
|
||||
|
||||
set(SYSCONFDIR "/etc" CACHE STRING "system config dir")
|
||||
set(DATADIR "${CMAKE_INSTALL_PREFIX}/share" CACHE STRING "shared data dir")
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules (GLIB2 REQUIRED glib-2.0)
|
||||
pkg_check_modules (UDEV REQUIRED libudev)
|
||||
pkg_check_modules (SYSTEMD REQUIRED libsystemd)
|
||||
|
||||
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/config.h.cmake ${CMAKE_BINARY_DIR}/config.h)
|
||||
|
||||
if(BUILD_ENABLE_CPPCHECK)
|
||||
find_program(CMAKE_C_CPPCHECK NAMES cppcheck)
|
||||
if (CMAKE_C_CPPCHECK)
|
||||
list(
|
||||
APPEND CMAKE_C_CPPCHECK
|
||||
"--enable=warning"
|
||||
"--inline-suppr"
|
||||
"--std=c11"
|
||||
"-D__SIZEOF_POINTER__=8"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(res)
|
||||
add_subdirectory(test)
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
= Authors =
|
||||
|
||||
This software was written by:
|
||||
David Herrmann <dh.herrmann@gmail.com>
|
||||
|
||||
= Copyright Notice =
|
||||
|
||||
This software is licensed under the terms of the LGPL. Please see each source
|
||||
file for the related copyright notice and license.
|
||||
|
||||
If a file does not contain a copright notice, the following notice shall apply:
|
||||
|
||||
MiracleCast - Wifi-Display/Miracast Implementation
|
||||
|
||||
Copyright (c) 2013-2014 David Herrmann <dh.herrmann@gmail.com>
|
||||
|
||||
MiracleCast 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.
|
||||
|
||||
MiracleCast 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 MiracleCast; If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
== Third-Party Source ==
|
||||
|
||||
src/shl_htable.[ch]: Released under the conditions of the LGPLv2+.
|
||||
Please see LICENSE_htable for more.
|
||||
|
||||
src/dhcp/*: Released under the conditions of the GPLv2.
|
||||
Please see LICENSE_gdhcp for more.
|
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
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 fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
|
@ -0,0 +1,510 @@
|
|||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations
|
||||
below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
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
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it
|
||||
becomes a de-facto standard. To achieve this, non-free programs must
|
||||
be allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control
|
||||
compilation and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
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
|
||||
fee.
|
||||
|
||||
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
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
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
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
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
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
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
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at least
|
||||
three years, to give the same user the materials specified in
|
||||
Subsection 6a, above, for a charge no more than the cost of
|
||||
performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
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
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply, and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License
|
||||
may add an explicit geographical distribution limitation excluding those
|
||||
countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms
|
||||
of the ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library.
|
||||
It is safest to attach them to the start of each source file to most
|
||||
effectively convey the exclusion of warranty; and each file should
|
||||
have at least the "copyright" line and a pointer to where the full
|
||||
notice is found.
|
||||
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or
|
||||
your school, if any, to sign a "copyright disclaimer" for the library,
|
||||
if necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James
|
||||
Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
|
@ -0,0 +1,502 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
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
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
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
|
||||
fee.
|
||||
|
||||
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
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
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
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
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
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
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
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
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
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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, write to the Free Software
|
||||
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.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
|
@ -0,0 +1,24 @@
|
|||
SUBDIRS = src res test
|
||||
EXTRA_DIST = README.md \
|
||||
COPYING \
|
||||
NEWS
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
.PHONY: lcov genlcov lcov-clean
|
||||
|
||||
lcov:
|
||||
-$(MAKE) $(AM_MAKEFLAGS) -k check
|
||||
$(MAKE) $(AM_MAKEFLAGS) genlcov
|
||||
|
||||
# we have to massage the lcov.info file slightly to hide the effect of libtool
|
||||
# placing the objects files in the .libs/ directory separate from the *.c
|
||||
genlcov:
|
||||
$(LTP) --directory $(top_builddir) --capture --output-file miraclecast-lcov.info --test-name GLIB_PERF --no-checksum
|
||||
LANG=C $(LTP_GENHTML) --prefix $(top_builddir) --output-directory miraclecast-lcov --title "Miraclecast Code Coverage" --legend --show-details miraclecast-lcov.info
|
||||
|
||||
lcov-clean:
|
||||
-$(LTP) --directory $(top_builddir) -z
|
||||
-rm -rf miraclecast-lcov.info miraclecast-lcov
|
||||
-find -name '*.gcda' -print | xargs -Ix rm x
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
# MiracleCast - Wifi-Display/Miracast Implementation
|
||||
|
||||
[![Join the chat at https://gitter.im/albfan/miraclecast](https://badges.gitter.im/albfan/miraclecast.svg)](https://gitter.im/albfan/miraclecast?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[![Semaphore CI Build Status](https://albfan.semaphoreci.com/badges/miraclecast/branches/master.svg?style=shields)](https://albfan.semaphoreci.com/projects/miraclecast)
|
||||
[![Travis CI Build Status](https://travis-ci.org/albfan/miraclecast.svg?branch=master)](https://travis-ci.org/albfan/miraclecast)
|
||||
[![Coverage Status](https://coveralls.io/repos/github/albfan/miraclecast/badge.svg?branch=master)](https://coveralls.io/github/albfan/miraclecast?branch=master)
|
||||
|
||||
The MiracleCast project provides software to connect external monitors to your system via Wi-Fi. It is compatible to the Wifi-Display specification also known as Miracast. MiracleCast implements the Display-Source as well as Display-Sink side.
|
||||
|
||||
The Display-Source side allows you to connect external displays to your system and stream local content to the device. A lot of effort is put into making this as easy as connecting external displays via HDMI.
|
||||
|
||||
On the other hand, the Display-Sink side allows you to create wifi-capable external displays yourself. You can use it on your embedded devices or even on full desktops to allow other systems to use your device as external display.
|
||||
|
||||
|
||||
## Requirements
|
||||
|
||||
The MiracleCast projects requires the following software to be installed:
|
||||
- **systemd**: A system management daemon. It is used for device-management (udev), dbus management (sd-bus) and service management.
|
||||
Systemd >= 221 will work out of the box. For earlier versions systemd must be compiled with --enable-kdbus, even though kdbus isn't used, but only the independent, experimental sd-libraries.
|
||||
*required*: >=systemd-213
|
||||
|
||||
- **glib**: A utility library. Used by the current DHCP implementation. Will be removed once sd-dns gains DHCP-server capabilities.
|
||||
*required*: ~=glib2-2.38 (might work with older releases, untested..)
|
||||
|
||||
- **check**: Test-suite for C programs. Used for optional tests of the MiracleCast code base.
|
||||
*optional*: ~=check-0.9.11 (might work with older releases, untested..)
|
||||
|
||||
- **gstreamer**: MiracleCast rely on gstreamer to show cast its output. You can test if all needed is installed launching [res/test-viewer.sh](https://github.com/albfan/miraclecast/blob/master/res/test-viewer.sh)
|
||||
|
||||
- **P2P Wi-Fi device** Although widespread these days, there are some devices not compatible with [Wi-Fi Direct](http://en.wikipedia.org/wiki/Wi-Fi_Direct) (prior know as Wi-Fi P2P). Test yours with [res/test-hardware-capabilities.sh](https://github.com/albfan/miraclecast/blob/master/res/test-hardware-capabilities.sh)
|
||||
|
||||
- copy the dbus policy **res/org.freedesktop.miracle.conf** to `/etc/dbus-1/system.d/`
|
||||
|
||||
## Build and install
|
||||
|
||||
To compile MiracleCast, you can choose from:
|
||||
|
||||
- [autotools](http://en.wikipedia.org/wiki/GNU_build_system)
|
||||
- [cmake](http://en.wikipedia.org/wiki/CMake)
|
||||
- [meson](http://mesonbuild.com/)
|
||||
|
||||
See more info on wiki [Building](https://github.com/albfan/miraclecast/wiki/Building)
|
||||
|
||||
## Automatic interface selection with udev
|
||||
|
||||
If you want to select the interface to start miraclecast with, add a udev rule with the script [res/write-udev-rule.sh](https://github.com/albfan/miraclecast/blob/master/res/write-udev-rule.sh) and configure miraclecast with
|
||||
|
||||
$ ../configure --enable-rely-udev
|
||||
|
||||
You can also choose the interface with `--interface` option for miracle-wifid.
|
||||
|
||||
## Linux Flavours and general compilation instructions
|
||||
|
||||
### Ubuntu
|
||||
|
||||
Check your systemd version with:
|
||||
|
||||
$ systemctl --version
|
||||
|
||||
If you are on 221 or above your systemd has kdbus enabled.
|
||||
|
||||
If you are below 221, an alternative repo was created to install systemd with dbus
|
||||
|
||||
https://github.com/albfan/systemd-ubuntu-with-dbus
|
||||
|
||||
See there was interface changes on systemd 219, if you are below that version, use branch [systemd-219](https://github.com/albfan/miraclecast/tree/systemd-219) to compile miraclecast
|
||||
|
||||
> See specific instructions on that repo
|
||||
|
||||
### Arch linux
|
||||
|
||||
Use existing [AUR package](https://aur.archlinux.org/packages/miraclecast-git/). Remember to enable kdus to systemd-git dependency if you are below 221 systemd.
|
||||
|
||||
$ export _systemd_git_kdbus=--enable-kdbus
|
||||
|
||||
You can achieve installation using [yaourt](https://wiki.archlinux.org/index.php/Yaourt)
|
||||
|
||||
### Other flavours
|
||||
|
||||
If you feel confidence enough (since systemd is the entrypoint for an OS) extract instructions from arch linux AUR PKGBUILD:
|
||||
|
||||
- [systemd-kdbus](https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=systemd-kdbus)
|
||||
- [miraclecast](https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=miraclecast)
|
||||
|
||||
## Documentation
|
||||
|
||||
### Steps to use it as sink
|
||||
|
||||
1. shutdown wpa_supplicant and NetworkManager
|
||||
|
||||
$ systemctl stop NetworkManager.service
|
||||
$ systemctl stop wpa_supplicant.service
|
||||
|
||||
2. launch wifi daemon
|
||||
|
||||
$ sudo miracle-wifid &
|
||||
|
||||
3. launch sink control (your network card will be detected. here 3)
|
||||
|
||||
$ sudo miracle-sinkctl
|
||||
[ADD] Link: 3
|
||||
|
||||
4. run WiFi Display on link:
|
||||
|
||||
> run 3
|
||||
|
||||
5. Pair your machine with other miracast device (mirroring)
|
||||
|
||||
6. See your screen device on this machine
|
||||
|
||||
### Steps to use it as peer
|
||||
|
||||
1. Repeat steps 1 and 2 from "use as sink"
|
||||
|
||||
2. launch wifi control
|
||||
|
||||
$ sudo miracle-wifictl
|
||||
|
||||
3. Enable visibility for other devices
|
||||
|
||||
4. Locate them using scanning
|
||||
|
||||
> p2p-scan
|
||||
|
||||
5. Apart from list, or show info with peer <mac> there's nothing useful here by now. For a Q&D see [Using as peer](https://github.com/albfan/miraclecast/issues/4)
|
||||
|
||||
## UIBC
|
||||
|
||||
> The User Input Back Channel (UIBC) is an optional WFD feature that when implemented facilitates communication of user inputs to a User Interface, present at the WFD Sink, to the WFD Source.
|
||||
|
||||
To use it just add `--uibc` on `miracle-sinkctl` startup. Single mouse events and key events are implemented.
|
||||
|
||||
## Autocompletion
|
||||
|
||||
Source [res/miraclecast-completion](https://github.com/albfan/miraclecast/blob/master/res/miraclecast-completion) for autocompletion
|
||||
|
||||
## License
|
||||
|
||||
This software is licensed under the terms of the GNU-LGPL license. Please see ./COPYING for further information.
|
||||
|
||||
## Credits
|
||||
|
||||
This software is originally maintained by: David Herrmann dh.herrmann@gmail.com
|
||||
|
||||
This fork is maintained by: Alberto Fanjul albertofanjul@gmail.com
|
||||
|
||||
If you have any questions, do not hesitate to contact one of the maintainers.
|
||||
|
||||
## Additional urls
|
||||
|
||||
- Website: http://www.freedesktop.org/wiki/Software/miracle
|
||||
- Original repo: git://people.freedesktop.org/~dvdhrm/miracle
|
||||
- Fork repo: https://github.com/albfan/miraclecast
|
||||
- Technical spec: https://www.wi-fi.org/file/wi-fi-display-technical-specification-v11 (free registration required)
|
|
@ -0,0 +1,72 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
oldpwd=$(pwd)
|
||||
topdir=$(dirname $0)
|
||||
cd $topdir
|
||||
|
||||
#intltoolize --force --automake
|
||||
autoreconf --force --install --symlink
|
||||
|
||||
libdir() {
|
||||
echo $(cd "$1/$(gcc -print-multi-os-directory)"; pwd)
|
||||
}
|
||||
|
||||
args="\
|
||||
--sysconfdir=/etc \
|
||||
--localstatedir=/var \
|
||||
--libdir=$(libdir /usr/lib) \
|
||||
"
|
||||
|
||||
if [ -f "$topdir/.config.args" ]; then
|
||||
args="$args $(cat $topdir/.config.args)"
|
||||
fi
|
||||
|
||||
cd $oldpwd
|
||||
|
||||
if [ "x$1" = "xc" ]; then
|
||||
shift
|
||||
args="$args $@"
|
||||
$topdir/configure CFLAGS='-g -O0 -ftrapv' $args
|
||||
make clean
|
||||
elif [ "x$1" = "xg" ]; then
|
||||
shift
|
||||
args="$args $@"
|
||||
$topdir/configure CFLAGS='-g -O0 -ftrapv' $args
|
||||
make clean
|
||||
elif [ "x$1" = "xa" ]; then
|
||||
shift
|
||||
args="$args $@"
|
||||
$topdir/configure CFLAGS='-g -O0 -Wsuggest-attribute=pure -Wsuggest-attribute=const -ftrapv' $args
|
||||
make clean
|
||||
elif [ "x$1" = "xl" ]; then
|
||||
shift
|
||||
args="$args $@"
|
||||
$topdir/configure CC=clang CFLAGS='-g -O0 -ftrapv' $args
|
||||
make clean
|
||||
elif [ "x$1" = "xs" ]; then
|
||||
shift
|
||||
args="$args $@"
|
||||
scan-build $topdir/configure CFLAGS='-std=gnu99 -g -O0 -ftrapv' $args
|
||||
scan-build make
|
||||
else
|
||||
cat <<EOF
|
||||
|
||||
----------------------------------------------------------------
|
||||
Initialized build system. For a common configuration please run:
|
||||
----------------------------------------------------------------
|
||||
|
||||
$topdir/configure CFLAGS='-g -O0 -ftrapv' $args
|
||||
|
||||
or run $0 with param:
|
||||
|
||||
- c: compilation
|
||||
- g: debugging
|
||||
- a: pure/const warning
|
||||
- l: clang build
|
||||
- s: scan-build reporting
|
||||
|
||||
EOF
|
||||
|
||||
fi
|
|
@ -0,0 +1,11 @@
|
|||
FROM docker.io/albfan/miraclecast-ci
|
||||
|
||||
COPY . ./
|
||||
|
||||
RUN rm -rf build-autotools ; \
|
||||
mkdir build-autotools; \
|
||||
cd build-autotools; \
|
||||
../autogen.sh; \
|
||||
../configure; \
|
||||
make; \
|
||||
make check
|
|
@ -0,0 +1,9 @@
|
|||
FROM docker.io/albfan/miraclecast-ci
|
||||
|
||||
COPY . ./
|
||||
|
||||
RUN rm -rf build-cmake; \
|
||||
mkdir build-cmake; \
|
||||
cd build-cmake; \
|
||||
cmake ..; \
|
||||
make
|
|
@ -0,0 +1,29 @@
|
|||
# from http://websvn.kde.org/trunk/KDE/kdeedu/cmake/modules/FindReadline.cmake
|
||||
# http://websvn.kde.org/trunk/KDE/kdeedu/cmake/modules/COPYING-CMAKE-SCRIPTS
|
||||
# --> BSD licensed
|
||||
#
|
||||
# GNU Readline library finder
|
||||
if(READLINE_INCLUDE_DIR AND READLINE_LIBRARY AND NCURSES_LIBRARY)
|
||||
set(READLINE_FOUND TRUE)
|
||||
else(READLINE_INCLUDE_DIR AND READLINE_LIBRARY AND NCURSES_LIBRARY)
|
||||
FIND_PATH(READLINE_INCLUDE_DIR readline/readline.h
|
||||
/usr/include/readline
|
||||
)
|
||||
|
||||
# 2008-04-22 The next clause used to read like this:
|
||||
#
|
||||
# FIND_LIBRARY(READLINE_LIBRARY NAMES readline)
|
||||
# FIND_LIBRARY(NCURSES_LIBRARY NAMES ncurses )
|
||||
# include(FindPackageHandleStandardArgs)
|
||||
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(Readline DEFAULT_MSG NCURSES_LIBRARY READLINE_INCLUDE_DIR READLINE_LIBRARY )
|
||||
#
|
||||
# I was advised to modify it such that it will find an ncurses library if
|
||||
# required, but not if one was explicitly given, that is, it allows the
|
||||
# default to be overridden. PH
|
||||
|
||||
FIND_LIBRARY(READLINE_LIBRARY NAMES readline)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Readline DEFAULT_MSG READLINE_INCLUDE_DIR READLINE_LIBRARY )
|
||||
|
||||
MARK_AS_ADVANCED(READLINE_INCLUDE_DIR READLINE_LIBRARY)
|
||||
endif(READLINE_INCLUDE_DIR AND READLINE_LIBRARY AND NCURSES_LIBRARY)
|
|
@ -0,0 +1,18 @@
|
|||
AM_CFLAGS = -Wall \
|
||||
-pipe \
|
||||
-fno-common \
|
||||
-ffast-math \
|
||||
-fdiagnostics-show-option \
|
||||
-fno-strict-aliasing \
|
||||
-fvisibility=hidden \
|
||||
-ffunction-sections \
|
||||
-fdata-sections
|
||||
|
||||
AM_CPPFLAGS = -include $(top_builddir)/config.h \
|
||||
-I $(top_srcdir)/src \
|
||||
-I $(top_srcdir)/src/shared
|
||||
|
||||
AM_LDFLAGS = -Wl,--as-needed \
|
||||
-Wl,--gc-sections \
|
||||
-Wl,-z,relro \
|
||||
-Wl,-z,now
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#cmakedefine BUILD_BINDIR "@BUILD_BINDIR@"
|
||||
|
||||
#cmakedefine PACKAGE_STRING "@PACKAGE_STRING@"
|
||||
|
||||
#endif // CONFIG_H
|
|
@ -0,0 +1,191 @@
|
|||
#
|
||||
# MiracleCast - build configuration script
|
||||
# Copyright (c) 2013-2014 David Herrmann <dh.herrmann@gmail.com>
|
||||
#
|
||||
|
||||
AC_PREREQ(2.68)
|
||||
|
||||
AC_INIT([miracle],
|
||||
[1],
|
||||
[http://www.freedesktop.org/wiki/Software/miracle],
|
||||
[miracle],
|
||||
[http://www.freedesktop.org/wiki/Software/miracle])
|
||||
AC_CONFIG_SRCDIR([src/miracled.h])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
AC_SYS_LARGEFILE
|
||||
AC_CANONICAL_HOST
|
||||
|
||||
AM_INIT_AUTOMAKE([foreign 1.11 subdir-objects dist-xz no-dist-gzip tar-pax -Wall -Werror -Wno-portability])
|
||||
AM_SILENT_RULES([yes])
|
||||
|
||||
AC_SUBST(PACKAGE_DESCRIPTION, ["Wifi-Display/Miracast Implementation"])
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_CC_C99
|
||||
AM_PROG_CC_C_O
|
||||
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
|
||||
AC_PROG_SED
|
||||
AC_PROG_MKDIR_P
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_GREP
|
||||
AC_PROG_AWK
|
||||
|
||||
LT_PREREQ(2.2)
|
||||
LT_INIT
|
||||
LT_LIB_M
|
||||
|
||||
AC_ARG_ENABLE([rely-udev],
|
||||
AS_HELP_STRING([--enable-rely-udev], [Use tagged device with miraclecast]), AC_DEFINE([RELY_UDEV], [], [Rely on udev to find miraclecast device]))
|
||||
AC_ARG_ENABLE([log-debug],
|
||||
AS_HELP_STRING([--disable-log-debug], [Disable log debug]), , AC_DEFINE([BUILD_ENABLE_DEBUG], [], [Enable debug log level]))
|
||||
#
|
||||
# Mandatory dependencies
|
||||
#
|
||||
|
||||
m4_ifdef([PKG_CHECK_MODULES], [
|
||||
PKG_CHECK_MODULES([DEPS], [libudev libsystemd > 219])
|
||||
PKG_CHECK_MODULES([GLIB], [glib-2.0])
|
||||
])
|
||||
|
||||
AC_CHECK_HEADERS(readline/readline.h,, AC_MSG_ERROR(GNU readline not found))
|
||||
|
||||
#
|
||||
# Test for "check" which we use for our test-suite. If not found, we disable
|
||||
# all tests.
|
||||
#
|
||||
|
||||
m4_ifdef([PKG_CHECK_MODULES], [
|
||||
PKG_CHECK_MODULES([CHECK], [check],
|
||||
[have_check=yes], [have_check=no])
|
||||
])
|
||||
AM_CONDITIONAL([BUILD_HAVE_CHECK], [test "x$have_check" = "xyes"])
|
||||
|
||||
if test "x$have_check" = "xyes"
|
||||
then
|
||||
|
||||
dnl ************************************
|
||||
dnl *** Enable lcov coverage reports ***
|
||||
dnl ************************************
|
||||
|
||||
AC_ARG_ENABLE(gcov,
|
||||
AS_HELP_STRING([--enable-gcov],
|
||||
[Enable gcov]),
|
||||
[use_gcov=$enableval], [use_gcov=no])
|
||||
|
||||
if test "x$use_gcov" = "xyes"; then
|
||||
dnl we need gcc:
|
||||
if test "$GCC" != "yes"; then
|
||||
AC_MSG_ERROR([GCC is required for --enable-gcov])
|
||||
fi
|
||||
|
||||
dnl Check if ccache is being used
|
||||
AC_CHECK_PROG(SHTOOL, shtool, shtool)
|
||||
case `$SHTOOL path $CC` in
|
||||
*ccache*[)] gcc_ccache=yes;;
|
||||
*[)] gcc_ccache=no;;
|
||||
esac
|
||||
|
||||
if test "$gcc_ccache" = "yes" && (test -z "$CCACHE_DISABLE" || test "$CCACHE_DISABLE" != "1"); then
|
||||
AC_MSG_ERROR([ccache must be disabled when --enable-gcov option is used. You can disable ccache by setting environment variable CCACHE_DISABLE=1.])
|
||||
fi
|
||||
|
||||
ltp_version_list="1.6 1.7 1.8 1.10 1.11 1.12"
|
||||
AC_CHECK_PROG(LTP, lcov, lcov)
|
||||
AC_CHECK_PROG(LTP_GENHTML, genhtml, genhtml)
|
||||
|
||||
if test "$LTP"; then
|
||||
AC_CACHE_CHECK([for ltp version], glib_cv_ltp_version, [
|
||||
glib_cv_ltp_version=invalid
|
||||
ltp_version=`$LTP -v 2>/dev/null | $SED -e 's/^.* //'`
|
||||
for ltp_check_version in $ltp_version_list; do
|
||||
if test "$ltp_version" = "$ltp_check_version"; then
|
||||
glib_cv_ltp_version="$ltp_check_version (ok)"
|
||||
fi
|
||||
done
|
||||
])
|
||||
else
|
||||
ltp_msg="To enable code coverage reporting you must have one of the following LTP versions installed: $ltp_version_list"
|
||||
AC_MSG_ERROR([$ltp_msg])
|
||||
fi
|
||||
|
||||
case $glib_cv_ltp_version in
|
||||
""|invalid[)]
|
||||
ltp_msg="You must have one of the following versions of LTP: $ltp_version_list (found: $ltp_version)."
|
||||
AC_MSG_ERROR([$ltp_msg])
|
||||
LTP="exit 0;"
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -z "$LTP_GENHTML"; then
|
||||
AC_MSG_ERROR([Could not find genhtml from the LTP package])
|
||||
fi
|
||||
|
||||
AC_DEFINE(HAVE_GCOV, 1, [Whether you have gcov])
|
||||
|
||||
dnl Remove all optimization flags from CFLAGS
|
||||
changequote({,})
|
||||
CFLAGS=`echo "$CFLAGS" | $SED -e 's/-O[0-9]*//g'`
|
||||
changequote([,])
|
||||
|
||||
dnl Add the special gcc flags
|
||||
CFLAGS="$CFLAGS -O0 -fprofile-arcs -ftest-coverage"
|
||||
LDFLAGS="$LDFLAGS -lgcov"
|
||||
fi
|
||||
fi
|
||||
#
|
||||
# Makefile vars
|
||||
# After everything is configured, we create all makefiles.
|
||||
#
|
||||
|
||||
AC_CONFIG_FILES([Makefile
|
||||
res/Makefile
|
||||
src/Makefile
|
||||
src/ctl/Makefile
|
||||
src/dhcp/Makefile
|
||||
src/shared/Makefile
|
||||
src/wifi/Makefile
|
||||
src/uibc/Makefile
|
||||
test/Makefile])
|
||||
AC_OUTPUT
|
||||
|
||||
#
|
||||
# Configuration output
|
||||
# Show configuration to the user so they can check whether everything was
|
||||
# configured as expected.
|
||||
#
|
||||
|
||||
if test "x$have_check" = "xyes"
|
||||
then
|
||||
AC_MSG_NOTICE([Build configuration:
|
||||
prefix: $prefix
|
||||
exec-prefix: $exec_prefix
|
||||
bindir: $bindir
|
||||
libdir: $libdir
|
||||
includedir: $includedir
|
||||
|
||||
Miscellaneous Options:
|
||||
building tests: $have_check
|
||||
code coverage: $use_gcov
|
||||
|
||||
Compilation
|
||||
mkdir build && cd build
|
||||
"${MAKE-make}" to start compilation process
|
||||
"${MAKE-make}" check to pass test])
|
||||
else
|
||||
AC_MSG_NOTICE([Build configuration:
|
||||
prefix: $prefix
|
||||
exec-prefix: $exec_prefix
|
||||
bindir: $bindir
|
||||
libdir: $libdir
|
||||
includedir: $includedir
|
||||
|
||||
Miscellaneous Options:
|
||||
building tests: $have_check
|
||||
|
||||
Compilation
|
||||
mkdir build && cd build
|
||||
"${MAKE-make}" to start compilation process])
|
||||
fi
|
|
@ -0,0 +1,8 @@
|
|||
miraclecast for Debian
|
||||
|
||||
Please edit this to provide information specific to
|
||||
this miraclecast Debian package.
|
||||
|
||||
(Automatically generated by debmake Version 4.3.1)
|
||||
|
||||
-- di wang <wangdi1@kylinos.cn> Tue, 30 Mar 2021 10:12:44 +0800
|
|
@ -0,0 +1,6 @@
|
|||
kylin-miraclecast (1.12.7-ok1) v101; urgency=medium
|
||||
* Bug号 :
|
||||
* 需求号:
|
||||
* 其他 : openkylin 第一版提交,并修改包名
|
||||
-- wangdi <wangdi1@kylinos.cn> Wed, 20 Jul 2022 17:29:06 +0800
|
||||
|
|
@ -0,0 +1 @@
|
|||
11
|
|
@ -0,0 +1,16 @@
|
|||
Source: kylin-miraclecast
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Maintainer: di wang <wangdi1@kylinos.cn>
|
||||
Build-Depends: debhelper (>=11~), cmake (>=3.15), libglib2.0-dev, libudev-dev, libsystemd-dev, libreadline-dev, check, libdbus-1-dev, libdbus-glib-1-dev, libgtk-3-dev, libpango1.0-dev, libharfbuzz-dev, libcairo2-dev, libgdk-pixbuf2.0-dev, libatk1.0-dev,qtbase5-dev,libgstreamer1.0-dev,librust-gstreamer-video-sys-dev,qtmultimedia5-dev,libukcc-dev,qttools5-dev-tools,libqt5svg5-dev, libgsettings-qt-dev,libmatekbd-dev,libqt5x11extras5-dev,libxklavier-dev,libkf5screen-dev,libkf5screen-bin,libkf5i18n-dev,libkf5windowsystem-dev,libkf5xmlgui-dev,libkf5globalaccel-dev,qtdeclarative5-dev,libdconf-dev,libasound2-dev,libxml2-dev,libcanberra-dev,libmate-desktop-dev, libx11-dev,libxkbfile-dev,libboost-dev, libxcb-xkb-dev,libpolkit-qt5-1-dev,libpulse-dev, libkf5bluezqt-dev,libpwquality-dev,xserver-xorg-dev,libupower-glib-dev, libpam0g-dev, libopencv-dev,libmatemixer-dev,libkysdk-qtwidgets-dev,pkg-config
|
||||
Standards-Version: 4.1.4
|
||||
Homepage: <insert the upstream URL, if relevant>
|
||||
|
||||
Package: kylin-miraclecast
|
||||
Architecture: any
|
||||
Essential:no
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends}, wpasupplicant (>=2:2.9-1kylin4.8), udev, network-manager, systemd, libsystemd0, dbus, libdbus-1-3, gstreamer1.0-plugins-bad, gstreamer1.0-plugins-base, gstreamer1.0-plugins-good, gstreamer1.0-libav, gstreamer1.0-tools, gstreamer1.0-x, gstreamer1.0-alsa, gir1.2-gstreamer-1.0, gir1.2-gst-plugins-base-1.0, libgstreamer-gl1.0-0, libgstreamer-plugins-base1.0-0, libgstreamer-plugins-good1.0-0, libgstreamer-plugins-bad1.0-0, libgstreamer1.0-0, gstreamer1.0-vaapi, va-driver-all, ukui-control-center (>=3.1.1+1103),ubuntukylin-theme (>=2.0.81), kylin-miraclecast-frontend
|
||||
Description: auto-generated package by debmake
|
||||
This Debian binary package was auto-generated by the
|
||||
debmake(1) command provided by the debmake package.
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,6 @@
|
|||
gstplayer-1.0/castplayer /usr/bin/
|
||||
plugin/projection/translations/zh_CN.qm /usr/share/projection/translations/
|
||||
plugin/projection/translations/zh_CN.ts /usr/share/projection/translations/
|
||||
plugin/projection/translations/en_US.qm /usr/share/projection/translations/
|
||||
plugin/projection/translations/en_US.ts /usr/share/projection/translations/
|
||||
libprojection.so /usr/share/projection/translations/
|
|
@ -0,0 +1,17 @@
|
|||
#!/bin/bash
|
||||
|
||||
#This is a script executed after package installed
|
||||
set -e
|
||||
|
||||
SO_PATH="/usr/lib/`/usr/bin/dpkg-architecture -qDEB_TARGET_MULTIARCH`/ukui-control-center/libprojection.so"
|
||||
mv /usr/share/projection/translations/libprojection.so $SO_PATH
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
PROG_PNUM=`ps -ef | grep miracle-agent | grep -v grep | awk '{print $2}'`
|
||||
if [ $PROG_PNUM ];then
|
||||
if [ $PROG_PNUM -gt 0 ];then
|
||||
echo "restart miralcecast agent"
|
||||
kill -9 $PROG_PNUM
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
rm -rf /root/.config/miracast
|
||||
#DEBHELPER#
|
|
@ -0,0 +1,10 @@
|
|||
#!/bin/bash
|
||||
|
||||
#This is a script executed after package installed
|
||||
set -e
|
||||
|
||||
#path="/usr/lib/`/usr/bin/dpkg-architecture -qDEB_TARGET_MULTIARCH`/ukui-control-center/libprojection.so"
|
||||
#dpkg-divert --package kylin-miraclecast --rename --divert "$path"".old" --add $path
|
||||
|
||||
rm -rf /root/.config/miracast
|
||||
echo "REMOVE old config path"
|
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/make -f
|
||||
# You must remove unused comment lines for the released package.
|
||||
#export DH_VERBOSE = 1
|
||||
#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
||||
#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
|
||||
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
|
||||
|
||||
%:
|
||||
# dh $@ --buildsystem=cmake
|
||||
dh $@ --with autoreconf
|
||||
|
||||
override_dh_auto_configure:
|
||||
dh_auto_configure --sourcedirectory=gstplayer-1.0 \
|
||||
--buildsystem=qmake
|
||||
dh_auto_configure --sourcedirectory=plugin/projection \
|
||||
--buildsystem=qmake
|
||||
dh_auto_configure -O--buildsystem=cmake
|
||||
override_dh_auto_build:
|
||||
dh_auto_build --sourcedirectory=gstplayer-1.0 \
|
||||
--buildsystem=qmake
|
||||
dh_auto_build --sourcedirectory=plugin/projection \
|
||||
--buildsystem=qmake
|
||||
dh_auto_build -O--buildsystem=cmake
|
||||
override_dh_auto_clean:
|
||||
dh_auto_clean --sourcedirectory=gstplayer-1.0 \
|
||||
--buildsystem=qmake
|
||||
dh_auto_clean --sourcedirectory=plugin/projection \
|
||||
--buildsystem=qmake
|
||||
dh_auto_clean -O--buildsystem=cmake
|
||||
dh_autoreconf_clean -O--buildsystem=cmake
|
||||
dh_clean -O--buildsystem=cmake
|
||||
#override_dh_autoreconf:
|
||||
# dh_autoreconf -- ./autogen.sh
|
||||
override_dh_installsystemd:
|
||||
dh_installsystemd --restart-after-upgrade miracle-wifid.service
|
|
@ -0,0 +1 @@
|
|||
3.0 (quilt)
|
|
@ -0,0 +1,2 @@
|
|||
#abort-on-upstream-changes
|
||||
#unapply-patches
|
|
@ -0,0 +1,2 @@
|
|||
# You must remove unused comment lines for the released package.
|
||||
version=3
|
|
@ -0,0 +1,54 @@
|
|||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2019-08-30T14:43:25
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui widgets multimedia multimediawidgets dbus
|
||||
|
||||
TARGET = castplayer
|
||||
TEMPLATE = app
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any feature of Qt which has been marked as deprecated (the exact warnings
|
||||
# depend on your compiler). Please consult the documentation of the
|
||||
# deprecated API in order to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
INCLUDEPATH += /usr/lib/gcc/x86_64-linux-gnu/9/include
|
||||
|
||||
TRANSLATIONS += zh_CN.ts \
|
||||
en_US.ts
|
||||
|
||||
# You can also make your code fail to compile if you use deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
CONFIG += c++11 \
|
||||
link_pkgconfig
|
||||
|
||||
PKGCONFIG += gstreamer-1.0 \
|
||||
gstreamer-video-1.0
|
||||
|
||||
SOURCES += \
|
||||
main.cpp \
|
||||
mobiletype.cpp \
|
||||
playwidget.cpp
|
||||
|
||||
# Default rules for deployment.
|
||||
qnx: target.path = /tmp/$${TARGET}/bin
|
||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
!isEmpty(target.path): INSTALLS += target
|
||||
|
||||
FORMS += \
|
||||
mobiletype.ui \
|
||||
playwidget.ui
|
||||
|
||||
HEADERS += \
|
||||
mobiletype.h \
|
||||
playwidget.h
|
||||
|
||||
RESOURCES += \
|
||||
pic.qrc \
|
||||
translator.qrc
|
|
@ -0,0 +1 @@
|
|||
<クdハ<>箆!ソ`。スン
|
|
@ -0,0 +1,122 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="zh_CN">
|
||||
<context>
|
||||
<name>MobileType</name>
|
||||
<message>
|
||||
<location filename="mobiletype.ui" line="26"/>
|
||||
<source>MobileType</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mobiletype.ui" line="50"/>
|
||||
<source>Mobiletype</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mobiletype.ui" line="76"/>
|
||||
<source>huawei</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mobiletype.ui" line="81"/>
|
||||
<source>xiaomi</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mobiletype.ui" line="86"/>
|
||||
<source>other</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mobiletype.ui" line="113"/>
|
||||
<source>Confirm</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mobiletype.ui" line="132"/>
|
||||
<source>Ignore</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<location filename="main.cpp" line="90"/>
|
||||
<source>huawei</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.cpp" line="94"/>
|
||||
<source>xiaomi</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.cpp" line="194"/>
|
||||
<source>projection</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.cpp" line="197"/>
|
||||
<source>Note:device can not support uibc</source>
|
||||
<oldsource>Note:the access device does not support control return.</oldsource>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.cpp" line="198"/>
|
||||
<source>Can't be controlled by keyboard/mouse.</source>
|
||||
<oldsource>Access device cannot be controlled using the keyboard and mouse.</oldsource>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>playWidget</name>
|
||||
<message>
|
||||
<location filename="playwidget.ui" line="17"/>
|
||||
<source>Form</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="playwidget.ui" line="76"/>
|
||||
<location filename="playwidget.cpp" line="774"/>
|
||||
<location filename="playwidget.cpp" line="802"/>
|
||||
<source>SD</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="playwidget.ui" line="96"/>
|
||||
<source>☆</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="playwidget.ui" line="116"/>
|
||||
<source>◁</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="playwidget.ui" line="136"/>
|
||||
<source>○</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="playwidget.ui" line="156"/>
|
||||
<source>□</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="playwidget.cpp" line="786"/>
|
||||
<source>HD</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="playwidget.cpp" line="789"/>
|
||||
<source>warning</source>
|
||||
<translation>警告</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="playwidget.cpp" line="789"/>
|
||||
<source>The current device does not support hard decoding</source>
|
||||
<translation type="unfinished">当前设备不支持硬解码</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
|
@ -0,0 +1,325 @@
|
|||
#include <glib.h>
|
||||
#include <gst/gst.h>
|
||||
#include <gst/video/videooverlay.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QWidget>
|
||||
#include <QtMultimediaWidgets/QVideoWidget>
|
||||
#include <QTimer>
|
||||
#include <QDebug>
|
||||
#include <QCommandLineParser>
|
||||
#include <QDBusInterface>
|
||||
#include <QProcess>
|
||||
#include <QStringList>
|
||||
#include "playwidget.h"
|
||||
#include <QTranslator>
|
||||
#include "mobiletype.h"
|
||||
#include <signal.h>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
|
||||
static WId winId;
|
||||
//hardsoft decode by default
|
||||
static QString decodeFlag="hard";
|
||||
static bool xvFlags = true; //部分显卡不支持xvimagesink
|
||||
|
||||
|
||||
void my_exit(int arg)
|
||||
{
|
||||
cout<<"closed"<<endl;
|
||||
qDebug()<<"player quit by signal kill term"<<endl;
|
||||
exit(0);
|
||||
}
|
||||
static GstBusSyncReply create_window(GstBus *bus, GstMessage *message, GstPipeline *pipeline)
|
||||
{
|
||||
if (!gst_is_video_overlay_prepare_window_handle_message(message))
|
||||
return GST_BUS_PASS;
|
||||
|
||||
qDebug() << "Received bus message";
|
||||
|
||||
gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(GST_MESSAGE_SRC(message)), winId);
|
||||
|
||||
gst_message_unref(message);
|
||||
|
||||
return GST_BUS_DROP;
|
||||
}
|
||||
|
||||
static void setenv()
|
||||
{
|
||||
QString LIST_VGA = "lspci";
|
||||
QString output="";
|
||||
|
||||
|
||||
QStringList sl={};
|
||||
QProcess proc ;
|
||||
proc.start(LIST_VGA);
|
||||
proc.waitForFinished();
|
||||
QString res=proc.readAllStandardOutput();
|
||||
if(res!=NULL&&res.contains("VGA"))
|
||||
{
|
||||
sl=res.split('\n');
|
||||
for(int i=0;i<sl.size();i++)
|
||||
{
|
||||
if(sl[i].contains("VGA"))
|
||||
{
|
||||
output+=sl[i]+'\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
qDebug()<<"set env";
|
||||
qDebug()<<output;
|
||||
|
||||
QString str = "Graphics";
|
||||
bool UHD = false;
|
||||
if(output.contains(str))
|
||||
{
|
||||
int pos = output.indexOf(str);
|
||||
QString str1 = output.mid(pos+9,1);
|
||||
if(str1 == "(")
|
||||
{
|
||||
UHD = true;
|
||||
}
|
||||
}
|
||||
if(output.contains("AMD"))
|
||||
{
|
||||
//remove hardsoft decode function on AMD Oland VGA
|
||||
if(output.contains("Oland"))
|
||||
{
|
||||
decodeFlag = "kylin";
|
||||
}
|
||||
else
|
||||
{
|
||||
qputenv("LIBVA_DRIVER_NAME", "radeonsi");
|
||||
qputenv("GST_VAAPI_ALL_DRIVERS", "1");
|
||||
}
|
||||
}
|
||||
else if(output.contains("Intel"))
|
||||
{
|
||||
if(UHD)
|
||||
{
|
||||
decodeFlag = "kylin";
|
||||
}else
|
||||
{
|
||||
qputenv("LIBVA_DRIVER_NAME", "i965");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
decodeFlag = "kylin";
|
||||
}
|
||||
|
||||
if(output.contains("Loongson") || output.contains("Renoir") || output.contains("Zhaoxin") || output.contains("0709")) //部分显卡不支持xvimagesink
|
||||
{
|
||||
xvFlags =false;
|
||||
qDebug()<<"current device cannot use xviamgesink";
|
||||
}
|
||||
qDebug()<<decodeFlag;
|
||||
qDebug()<<"lenove can not support"<<UHD;
|
||||
}
|
||||
|
||||
static void changeMobileType(QString type){
|
||||
int manufacturer;
|
||||
qDebug() << type;
|
||||
if (type == QObject::tr("huawei"))
|
||||
{
|
||||
manufacturer = 6;
|
||||
}
|
||||
else if (type == QObject::tr("xiaomi"))
|
||||
{
|
||||
manufacturer = 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
manufacturer = 8;
|
||||
}
|
||||
QDBusInterface *m_pServiceInterface = new QDBusInterface("org.freedesktop.miracleagent",
|
||||
"/org/freedesktop/miracleagent",
|
||||
"org.freedesktop.miracleagent.op",
|
||||
QDBusConnection::sessionBus());
|
||||
m_pServiceInterface->call("SetManufacturer",manufacturer);
|
||||
QString a1=QString("%1").arg(manufacturer);
|
||||
cout << a1.toLatin1().data() << endl;
|
||||
}
|
||||
|
||||
static void showChangeMobileTypeDialog(){
|
||||
MobileType * dialog = new MobileType();
|
||||
QObject::connect(dialog, &MobileType::sendMobileType, [=](QString type){
|
||||
changeMobileType (type);
|
||||
});
|
||||
dialog->exec();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Code to play rtsp stream on qt widgets
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#endif
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
#endif
|
||||
sigset(SIGTERM,my_exit);
|
||||
QApplication app(argc, argv);
|
||||
QTranslator translator;
|
||||
QLocale locale;
|
||||
if (locale.language() == QLocale::Chinese){
|
||||
translator.load(":/zh_CN.qm");
|
||||
app.installTranslator(&translator);
|
||||
}
|
||||
else if (locale.language() == QLocale::English){
|
||||
translator.load(":/en_US.qm");
|
||||
app.installTranslator(&translator);
|
||||
}
|
||||
|
||||
app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit ()));
|
||||
|
||||
setenv();
|
||||
|
||||
|
||||
gst_init (&argc, &argv);
|
||||
|
||||
QCommandLineParser parser;
|
||||
QCommandLineOption option_audio("a","enable audio support");
|
||||
QCommandLineOption option_scale("s","scale to resolution","split with x","scale");
|
||||
QCommandLineOption option_debug("d","debug level","debug","1");
|
||||
QCommandLineOption option_port("p","port for rtsp","port","1991");
|
||||
QCommandLineOption option_r("r","resolution","split with x","1920x1080");
|
||||
QCommandLineOption option_uibc("uibc","supported resolutions masks (CEA VESA HH)");
|
||||
QCommandLineOption option_hidc("hidc","enable hidc control back");
|
||||
QCommandLineOption option_kylinpc("kylinpc","kylinpc or not");
|
||||
|
||||
QCommandLineOption option_manufacturer("m","Confirm mobile type","manufacturer","5");
|
||||
|
||||
parser.addHelpOption();
|
||||
parser.addVersionOption();
|
||||
parser.addOption(option_audio);
|
||||
parser.addOption(option_scale);
|
||||
parser.addOption(option_port);
|
||||
parser.addOption(option_r);
|
||||
parser.addOption(option_debug);
|
||||
parser.addOption(option_uibc);
|
||||
parser.addOption(option_hidc);
|
||||
parser.addOption(option_kylinpc);
|
||||
|
||||
parser.addOption(option_manufacturer);
|
||||
|
||||
|
||||
parser.process(app);
|
||||
int audio=0;
|
||||
int scale=0;
|
||||
int uibc=1;
|
||||
int hidc=0;
|
||||
int resolution=0;
|
||||
int arg_width=1920;
|
||||
int arg_height=1080;
|
||||
int arg_port=888;
|
||||
int kylinpc = 0;
|
||||
int manufacturer = 5;
|
||||
|
||||
|
||||
if (parser.isSet(option_audio))
|
||||
{
|
||||
audio=1;
|
||||
}
|
||||
if (parser.isSet(option_uibc))
|
||||
{
|
||||
uibc=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
QDBusInterface interface( "org.freedesktop.Notifications",
|
||||
"/org/freedesktop/Notifications",
|
||||
"org.freedesktop.Notifications",
|
||||
QDBusConnection::sessionBus());
|
||||
QString appname = QObject::tr("projection");
|
||||
quint32 notify_id = 0;
|
||||
QString app_icon = "kylin-miracast";
|
||||
QString tilte = QObject::tr("Note:device can not support uibc");
|
||||
QString body = QObject::tr("Can't be controlled by keyboard/mouse.");
|
||||
qint32 timeout = -1;
|
||||
QStringList arry1;
|
||||
QVariantMap arry2;
|
||||
interface.call(QLatin1String("Notify"),appname,notify_id,app_icon,tilte,body,arry1,arry2,timeout);
|
||||
}
|
||||
if (parser.isSet(option_hidc))
|
||||
{
|
||||
hidc=1;
|
||||
}
|
||||
if (parser.isSet(option_r))
|
||||
{
|
||||
resolution=1;
|
||||
QStringList list = parser.value(option_r).split("x");
|
||||
//**************************************************************
|
||||
//**************************************************************
|
||||
//下一行要记得修改哦
|
||||
arg_width=list[0].toInt();
|
||||
arg_height=list[1].toInt();
|
||||
qDebug()<<arg_width <<" "<<arg_height;
|
||||
}
|
||||
if (parser.isSet(option_scale))
|
||||
{
|
||||
scale=1;
|
||||
QStringList list = parser.value(option_scale).split("x");
|
||||
//**************************************************************
|
||||
//**************************************************************
|
||||
//下一行要记得修改哦
|
||||
arg_width=list[0].toInt();
|
||||
arg_height=list[1].toInt();
|
||||
}
|
||||
if (parser.isSet(option_port))
|
||||
{
|
||||
arg_port=parser.value(option_port).toInt();
|
||||
qDebug()<<"port is"<<arg_port;
|
||||
}
|
||||
if (parser.isSet(option_debug))
|
||||
{
|
||||
qDebug()<<parser.value(option_debug);
|
||||
}
|
||||
if (parser.isSet(option_kylinpc))
|
||||
{
|
||||
kylinpc = 1;
|
||||
}
|
||||
|
||||
if (parser.isSet(option_manufacturer))
|
||||
{
|
||||
manufacturer = parser.value(option_manufacturer).toInt();
|
||||
qDebug()<<"manufacturer is"<<manufacturer;
|
||||
if (manufacturer == 5 && kylinpc == 0)
|
||||
{
|
||||
showChangeMobileTypeDialog();
|
||||
}
|
||||
else
|
||||
{
|
||||
QString a1=QString("%1").arg(manufacturer);
|
||||
cout << a1.toLatin1().data() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// prepare the ui
|
||||
playWidget window;
|
||||
if (locale.language() == QLocale::Chinese){
|
||||
window.setWindowTitle("投屏播放器");
|
||||
}
|
||||
else if (locale.language() == QLocale::English){
|
||||
window.setWindowTitle("MiracastPlayer");
|
||||
}
|
||||
window.resize(arg_width,arg_height);
|
||||
window.showFullScreen();
|
||||
window.setWidgetSize(arg_width,arg_height);
|
||||
window.setargv( audio, scale, uibc, hidc, resolution, arg_width, arg_height, arg_port,decodeFlag,kylinpc,xvFlags);
|
||||
window.init_mouse();
|
||||
window.init_keyboard();
|
||||
//window.setWindowFlags(Qt::FramelessWindowHint);
|
||||
window.show();
|
||||
|
||||
int ret = app.exec();
|
||||
window.hide();
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <gst/gst.h>
|
||||
#include <gst/video/videooverlay.h>
|
||||
|
||||
#include <QWidget>
|
||||
#include <QTimer>
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::MainWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete ui;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = nullptr);
|
||||
~MainWindow();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
|
@ -0,0 +1,24 @@
|
|||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QMenuBar" name="menuBar" />
|
||||
<widget class="QToolBar" name="mainToolBar" />
|
||||
<widget class="QWidget" name="centralWidget" />
|
||||
<widget class="QStatusBar" name="statusBar" />
|
||||
</widget>
|
||||
<layoutDefault spacing="6" margin="11" />
|
||||
<pixmapfunction></pixmapfunction>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,46 @@
|
|||
#include "mobiletype.h"
|
||||
#include "ui_mobiletype.h"
|
||||
|
||||
MobileType::MobileType(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::MobileType)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
QPalette pa;
|
||||
pa.setColor(QPalette::WindowText, Qt::red);
|
||||
ui->label->setPalette(pa);
|
||||
|
||||
QLocale locale;
|
||||
if (locale.language() == QLocale::Chinese){
|
||||
ui->ChangeMobileType->setText("请确认设备类型");
|
||||
ui->ignoreBtn->setText("取消");
|
||||
ui->label->setText("注意:重新更换设备型号需删除该历史设备记录,先关闭再开启投屏功能。");
|
||||
ui->label->setWordWrap(true);
|
||||
setWindowTitle("投屏");
|
||||
}
|
||||
else if (locale.language() == QLocale::English){
|
||||
ui->ChangeMobileType->setText("Please confirm the device type");
|
||||
ui->ignoreBtn->setText("Cancel");
|
||||
QString newStrMsg = "Note: to replace the device model again, you need to delete the historical device record. Turn off and then turn on the screen projection function.";
|
||||
QFontMetrics fontWidth(ui->label->font());//得到每个字符的宽度
|
||||
QString elideNote = fontWidth.elidedText(newStrMsg, Qt::ElideRight, 429);//最大宽度150像素
|
||||
ui->label->setText(elideNote);//显示省略好的字符串
|
||||
ui->label->setToolTip(newStrMsg);//设置tooltips
|
||||
setWindowTitle("cast");
|
||||
}
|
||||
|
||||
connect(ui->ignoreBtn, &QPushButton::clicked, [=]{
|
||||
close();
|
||||
});
|
||||
connect(ui->confirmBtn, &QPushButton::clicked, [=]{
|
||||
emit sendMobileType(ui->comboBox->currentText());
|
||||
close();
|
||||
});
|
||||
}
|
||||
|
||||
MobileType::~MobileType()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef MOBILETYPE_H
|
||||
#define MOBILETYPE_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
|
||||
namespace Ui {
|
||||
class MobileType;
|
||||
}
|
||||
|
||||
class MobileType : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MobileType(QWidget *parent = nullptr);
|
||||
~MobileType();
|
||||
|
||||
private:
|
||||
Ui::MobileType *ui;
|
||||
|
||||
Q_SIGNALS:
|
||||
void sendMobileType(QString name);
|
||||
};
|
||||
|
||||
#endif // MOBILETYPE_H
|
|
@ -0,0 +1,245 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MobileType</class>
|
||||
<widget class="QDialog" name="MobileType">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>520</width>
|
||||
<height>176</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>520</width>
|
||||
<height>176</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>520</width>
|
||||
<height>176</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>cast</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="pic.qrc">
|
||||
<normaloff>:/src/kylin-projection.svg</normaloff>:/src/kylin-projection.svg</iconset>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="2,3,2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="98,318">
|
||||
<property name="spacing">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>24</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>24</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="ChangeMobileType">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>318</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Please confirm the device type</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>98</width>
|
||||
<height>36</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>318</width>
|
||||
<height>36</height>
|
||||
</size>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>huawei</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>xiaomi</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>other</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>24</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>24</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>60</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Note: to replace the device model again, you need to delete the historical device record. Turn off and then turn on the screen projection function.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>24</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>24</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="ignoreBtn">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>33</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>33</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="confirmBtn">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>33</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>33</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Confirm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="pic.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,6 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>src/kylin-projection.svg</file>
|
||||
<file>src/kylin-projection.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,131 @@
|
|||
#ifndef PLAYWIDGET_H
|
||||
#define PLAYWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
#include <QMouseEvent>
|
||||
#include <QPalette>
|
||||
#include <gst/gst.h>
|
||||
#include <gst/video/videooverlay.h>
|
||||
#include <QCloseEvent>
|
||||
#include <QResizeEvent>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
namespace Ui {
|
||||
class playWidget;
|
||||
}
|
||||
|
||||
class playWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit playWidget(QWidget *parent = nullptr);
|
||||
~playWidget();
|
||||
void init();
|
||||
void initUI();
|
||||
void setWidgetSize(int x, int y);
|
||||
void init_mouse();
|
||||
void init_keyboard();
|
||||
static WId winID;
|
||||
|
||||
void setenv();
|
||||
void preparePipeline();
|
||||
bool setPlayerPipe(GstElement *pipe);
|
||||
void setargv(int audio, int scale, int uibc, int hidc, int resolution, int arg_width, int arg_height, int arg_port, QString decodeFlag, int kylinPc, bool xv);
|
||||
|
||||
int kylinPc;
|
||||
|
||||
|
||||
|
||||
private:
|
||||
Ui::playWidget *ui;
|
||||
int left_time=0;
|
||||
int reso=0;
|
||||
int uibc=1;
|
||||
int hidc=0;
|
||||
|
||||
const int cons_leftBtnPressed=0;
|
||||
const int cons_noBtnPressed=1;
|
||||
const int cons_wheelRoll=2; //滚轮滑动
|
||||
const int cons_keyPressed=2;
|
||||
const int cons_keyReleased=3;
|
||||
const int cons_nullBtn=0;
|
||||
const int cons_leftBtn=1;
|
||||
const int cons_midBtn=2;
|
||||
const int cons_rightBtn=4;
|
||||
int hid_key_event=0;
|
||||
int hid_mouse_event=1;
|
||||
|
||||
int window_width=0;
|
||||
int window_height=0;
|
||||
int widget_width=0;
|
||||
int widget_height=0;
|
||||
|
||||
int half_area_width=0;
|
||||
int half_area_height=0;
|
||||
int half_def_width=0;
|
||||
int half_def_height=0;
|
||||
int min_hor_pos=0;
|
||||
int max_hor_pos=0;
|
||||
int min_ver_pos=0;
|
||||
int max_ver_pos=0;
|
||||
int uibc_x=-1;
|
||||
int uibc_y=-1;
|
||||
int widget_show_flag=1;
|
||||
int circle_flag=0;
|
||||
|
||||
QString decodeFlag="hard";
|
||||
int audio=0;
|
||||
int scale=0;
|
||||
|
||||
int resolution=0;
|
||||
int arg_width=1920;
|
||||
int arg_height=1080;
|
||||
int arg_port=888;
|
||||
const gchar*hardPip;
|
||||
const gchar*softPip;
|
||||
GstElement *softPipeline;
|
||||
GstElement *hardPipeline;
|
||||
GstBus *bus;
|
||||
GstElement*currentPipe;
|
||||
QByteArray ba1;
|
||||
QByteArray ba;
|
||||
QPushButton *pushButton_allscreen;
|
||||
QPushButton *pushButton_changeDecode;
|
||||
QPushButton *pushButton_back;
|
||||
QPushButton *pushButton_fun;
|
||||
QPushButton *pushButton_home;
|
||||
QVBoxLayout*mLayout;
|
||||
int current_width = 0;
|
||||
int current_height = 0;
|
||||
bool xvFlags = true;
|
||||
bool updateFlag =false;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public slots:
|
||||
void time_update();
|
||||
void home_clicked();
|
||||
void back_clicked();
|
||||
void fun_clicked();
|
||||
void screen_clicked();
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void mouseReleaseEvent(QMouseEvent *event);
|
||||
void mouseMoveEvent(QMouseEvent *event);
|
||||
void mouseDoubleClickEvent(QMouseEvent *event);
|
||||
void wheelEvent(QWheelEvent * event);
|
||||
void keyPressEvent(QKeyEvent * event);
|
||||
void keyReleaseEvent(QKeyEvent * event);
|
||||
void circleMouse(QMouseEvent *e);
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
private slots:
|
||||
void on_pushButton_allscreen_2_clicked();
|
||||
void closeEvent(QCloseEvent *event);
|
||||
};
|
||||
|
||||
#endif // PLAYWIDGET_H
|
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>playWidget</class>
|
||||
<widget class="QWidget" name="playWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1920</width>
|
||||
<height>1080</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="mouseTracking">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="mouseTracking">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
Binary file not shown.
After Width: | Height: | Size: 441 B |
|
@ -0,0 +1 @@
|
|||
<svg id="投屏2.0_复制" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 96 96"><defs><linearGradient id="未命名的渐变_33" x1="48" y1="6" x2="48" y2="90" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#57ccff"/><stop offset="1" stop-color="#3081e2"/></linearGradient></defs><rect x="6" y="6" width="84" height="84" rx="9" fill="url(#未命名的渐变_33)"/><path d="M63.5,62A1.5,1.5,0,1,0,65,63.5,1.5,1.5,0,0,0,63.5,62Z" fill="#fff"/><path d="M69,39a2,2,0,0,1,2,2V65a2,2,0,0,1-2,2H57a2,2,0,0,1-2-2V41a2,2,0,0,1,2-2H69m0-2H57a4,4,0,0,0-4,4V65a4,4,0,0,0,4,4H69a4,4,0,0,0,4-4V41a4,4,0,0,0-4-4Z" fill="#fff"/><path d="M51,62H33.5a1.5,1.5,0,0,0,0,3H51V62Z" fill="#fff"/><polygon points="46 57 42 57 42 63 46 63 46 57 46 57" fill="#fff"/><path d="M26,55a2,2,0,0,1-2-2V31a2,2,0,0,1,2-2H62a2,2,0,0,1,2,2v4h3V31a5,5,0,0,0-5-5H26a5,5,0,0,0-5,5V53a5,5,0,0,0,5,5H51V55Z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 943 B |
|
@ -0,0 +1,6 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>zh_CN.qm</file>
|
||||
<file>en_US.qm</file>
|
||||
</qresource>
|
||||
</RCC>
|
Binary file not shown.
|
@ -0,0 +1,130 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="zh_CN" sourcelanguage="en">
|
||||
<context>
|
||||
<name>MobileType</name>
|
||||
<message>
|
||||
<source>MobileType</source>
|
||||
<translation type="vanished">手机类型</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mobiletype.ui" line="14"/>
|
||||
<source>cast</source>
|
||||
<translatorcomment>投屏</translatorcomment>
|
||||
<translation>投屏</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mobiletype.ui" line="81"/>
|
||||
<source>Please confirm the device type</source>
|
||||
<translation>请确认设备类型</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mobiletype.ui" line="107"/>
|
||||
<source>huawei</source>
|
||||
<translation>华为</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mobiletype.ui" line="112"/>
|
||||
<source>xiaomi</source>
|
||||
<translation>小米</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mobiletype.ui" line="117"/>
|
||||
<source>other</source>
|
||||
<translation>其他</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mobiletype.ui" line="147"/>
|
||||
<source>Note: to replace the device model again, you need to delete the historical device record. Turn off and then turn on the screen projection function.</source>
|
||||
<oldsource>Note: to replace the mobile phone model again, you need to delete the historical device record. Turn off and then turn on the screen projection function.</oldsource>
|
||||
<translation type="unfinished">注意:重新更换手机型号需删除该历史设备记录,先关闭再开启投屏功能。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mobiletype.ui" line="198"/>
|
||||
<source>Cancel</source>
|
||||
<translation>取消</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mobiletype.ui" line="217"/>
|
||||
<source>Confirm</source>
|
||||
<translation>确定</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save</source>
|
||||
<translation type="vanished">确定</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Ignore</source>
|
||||
<translation type="vanished">忽略</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Incorrect selection will affect the use</source>
|
||||
<translation type="vanished">如果误选会影响使用</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<location filename="main.cpp" line="118"/>
|
||||
<source>huawei</source>
|
||||
<translation>华为</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.cpp" line="122"/>
|
||||
<source>xiaomi</source>
|
||||
<translation>小米</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.cpp" line="234"/>
|
||||
<source>projection</source>
|
||||
<translation>投屏接收端</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.cpp" line="237"/>
|
||||
<source>Note:device can not support uibc</source>
|
||||
<oldsource>Note:the access device does not support control return.</oldsource>
|
||||
<translation>注意:设备不支持控制回传</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="main.cpp" line="238"/>
|
||||
<source>Can't be controlled by keyboard/mouse.</source>
|
||||
<oldsource>Access device cannot be controlled using the keyboard and mouse.</oldsource>
|
||||
<translation>无法使用键盘和鼠标控制设备</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>playWidget</name>
|
||||
<message>
|
||||
<location filename="playwidget.ui" line="17"/>
|
||||
<source>Form</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="playwidget.cpp" line="103"/>
|
||||
<location filename="playwidget.cpp" line="969"/>
|
||||
<location filename="playwidget.cpp" line="1001"/>
|
||||
<source>SD</source>
|
||||
<translation>软</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="playwidget.cpp" line="981"/>
|
||||
<source>HD</source>
|
||||
<translation>硬</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="playwidget.cpp" line="987"/>
|
||||
<source>warning</source>
|
||||
<translation>警告</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="playwidget.cpp" line="987"/>
|
||||
<source>The current device does not support hard decoding</source>
|
||||
<translation>当前设备不支持硬解码</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="playwidget.cpp" line="987"/>
|
||||
<source>Yes</source>
|
||||
<translation>确定</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
|
@ -0,0 +1,7 @@
|
|||
FROM docker.io/albfan/miraclecast-ci
|
||||
|
||||
COPY . ./
|
||||
|
||||
RUN rm -rf build-meson; \
|
||||
meson build-meson; \
|
||||
ninja -C build-meson
|
|
@ -0,0 +1,45 @@
|
|||
project('Miraclecast',
|
||||
'c',
|
||||
version: '1',
|
||||
meson_version: '>=0.39',
|
||||
default_options: ['buildtype=debugoptimized', 'c_std=gnu11']
|
||||
)
|
||||
|
||||
add_project_arguments('-D_GNU_SOURCE', language: 'c')
|
||||
|
||||
conf_data = configuration_data()
|
||||
conf_data.set_quoted('BUILD_BINDIR',
|
||||
join_paths(get_option('prefix'), get_option('bindir'))
|
||||
)
|
||||
conf_data.set_quoted('PACKAGE_STRING',
|
||||
'@0@ @1@'.format(meson.project_name(), meson.project_version())
|
||||
)
|
||||
configure_file(output: 'config.h',
|
||||
configuration: conf_data
|
||||
)
|
||||
|
||||
c_compiler = meson.get_compiler('c')
|
||||
readline = c_compiler.find_library('readline', required: true)
|
||||
if readline.found()
|
||||
add_project_arguments('-DHAVE_READLINE', language: 'c')
|
||||
endif
|
||||
|
||||
if get_option('build-enable-debug')
|
||||
add_project_arguments('-DBUILD_ENABLE_DEBUG', language: 'c')
|
||||
endif
|
||||
|
||||
if get_option('rely-udev')
|
||||
add_project_arguments('-DRELY_UDEV', language: 'c')
|
||||
endif
|
||||
|
||||
glib2 = dependency('glib-2.0')
|
||||
udev = dependency('libudev')
|
||||
libsystemd = dependency('libsystemd')
|
||||
|
||||
subdir('src')
|
||||
subdir('res')
|
||||
|
||||
if get_option('build-tests')
|
||||
subdir('test')
|
||||
endif
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
option('build-enable-debug',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
description: 'Enable Debug')
|
||||
option('rely-udev',
|
||||
type: 'boolean',
|
||||
value: false,
|
||||
description: 'Rely in udev tag to select device')
|
||||
option('build-tests',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
description: 'Enable TEST')
|
|
@ -0,0 +1,35 @@
|
|||
#include "drownlabel.h"
|
||||
#include "projection.h"
|
||||
|
||||
#define ICONSIZE 18,18
|
||||
DrownLabel::DrownLabel(QWidget * parent) : QLabel(parent)
|
||||
{
|
||||
setFixedSize(36,36);
|
||||
loadPixmap(isChecked);
|
||||
this->setProperty("useIconHighlightEffect", 0x2);
|
||||
}
|
||||
|
||||
DrownLabel::~DrownLabel()
|
||||
{
|
||||
|
||||
}
|
||||
void DrownLabel::setDropDownStatus(bool status)
|
||||
{
|
||||
isChecked = status;
|
||||
loadPixmap(isChecked);
|
||||
}
|
||||
|
||||
void DrownLabel::loadPixmap(bool isChecked)
|
||||
{
|
||||
if (isChecked) {
|
||||
setPixmap(QIcon::fromTheme("ukui-down-symbolic").pixmap(ICONSIZE));
|
||||
} else {
|
||||
setPixmap(QIcon::fromTheme("ukui-up-symbolic").pixmap(ICONSIZE));
|
||||
}
|
||||
}
|
||||
|
||||
void DrownLabel::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
emit labelClicked();
|
||||
QWidget::mouseReleaseEvent(event);
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef DROWNLABEL_H
|
||||
#define DROWNLABEL_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QLabel>
|
||||
#include <QWidget>
|
||||
#include <QMouseEvent>
|
||||
|
||||
class DrownLabel : public QLabel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DrownLabel(QWidget * parent = nullptr);
|
||||
~DrownLabel();
|
||||
void setDropDownStatus(bool status);
|
||||
bool isChecked = false;
|
||||
private:
|
||||
void loadPixmap(bool isChecked);
|
||||
protected:
|
||||
virtual void mouseReleaseEvent(QMouseEvent * event);
|
||||
|
||||
Q_SIGNALS:
|
||||
void labelClicked();
|
||||
};
|
||||
|
||||
#endif // DROWNLABEL_H
|
|
@ -0,0 +1,9 @@
|
|||
#LIBINTERFACE_NAME = $$qtLibraryTarget(drownlabel)
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/DrownLabel/drownlabel.cpp \
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/DrownLabel/drownlabel.h \
|
||||
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
#include "changeprojectionname.h"
|
||||
#include "ui_changeprojectionname.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
//extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed);
|
||||
|
||||
ChangeProjectionName::ChangeProjectionName(QWidget *parent)
|
||||
:
|
||||
QDialog(parent),
|
||||
ui(new Ui::ChangeProjectionName)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
//setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);
|
||||
// setWindowFlags(Qt::WindowCloseButtonHint);
|
||||
// setAttribute(Qt::WA_TranslucentBackground);
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
QPalette pa;
|
||||
pa.setColor(QPalette::WindowText, Qt::red);
|
||||
ui->tipLabel_2->setPalette(pa);
|
||||
ui->lineEdit->setMaxLength(32);
|
||||
ui->lineEdit->setAttribute(Qt::WA_InputMethodEnabled, false);
|
||||
|
||||
ui->saveBtn->setEnabled(false);
|
||||
QLocale locale;
|
||||
if (locale.language() == QLocale::English){
|
||||
QString newStrMsg = "Device Name";
|
||||
QFontMetrics fontWidth(ui->ChangeProjectionname->font());//得到每个字符的宽度
|
||||
QString elideNote = fontWidth.elidedText(newStrMsg, Qt::ElideRight, 74);//最大宽度74像素
|
||||
ui->ChangeProjectionname->setText(elideNote);//显示省略好的字符串
|
||||
ui->ChangeProjectionname->setToolTip(newStrMsg);//设置tooltips
|
||||
}
|
||||
|
||||
connect(ui->lineEdit, &QLineEdit::textChanged, this, [=](QString txt){
|
||||
if (txt.toLocal8Bit().length() > 31){
|
||||
ui->lineEdit->setFocusPolicy(Qt::NoFocus);
|
||||
QString StrMsg = tr("The length must be 1-32 characters");
|
||||
QFontMetrics fontWidth(ui->tipLabel_2->font());//得到每个字符的宽度
|
||||
QString elideNote_2 = fontWidth.elidedText(StrMsg, Qt::ElideRight, 298);//最大宽度74像素
|
||||
ui->tipLabel_2->setText(elideNote_2);
|
||||
ui->tipLabel_2->setToolTip(StrMsg);
|
||||
// ui->tipLabel_2->setText(tr("The length must be 1-32 characters"));
|
||||
// ui->saveBtn->setEnabled(false);
|
||||
}else {
|
||||
ui->tipLabel_2->setText(tr(""));
|
||||
}
|
||||
|
||||
if (!txt.isEmpty()){
|
||||
ui->saveBtn->setEnabled(true);
|
||||
} else {
|
||||
ui->saveBtn->setEnabled(false);
|
||||
}
|
||||
});
|
||||
|
||||
connect(ui->cancelBtn, &QPushButton::clicked, [=]{
|
||||
close();
|
||||
});
|
||||
|
||||
connect(ui->saveBtn, &QPushButton::clicked, [=]{
|
||||
emit sendNewProjectionName(ui->lineEdit->text());
|
||||
close();
|
||||
});
|
||||
}
|
||||
|
||||
ChangeProjectionName::~ChangeProjectionName()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
//void ChangeProjectionName::paintEvent(QPaintEvent *event) {
|
||||
// Q_UNUSED(event)
|
||||
|
||||
// QPainter p(this);
|
||||
// p.setRenderHint(QPainter::Antialiasing);
|
||||
// QPainterPath rectPath;
|
||||
// rectPath.addRoundedRect(this->rect().adjusted(10, 10, -10, -10), 6, 6);
|
||||
|
||||
// // 画一个黑底
|
||||
// QPixmap pixmap(this->rect().size());
|
||||
// pixmap.fill(Qt::transparent);
|
||||
// QPainter pixmapPainter(&pixmap);
|
||||
// pixmapPainter.setRenderHint(QPainter::Antialiasing);
|
||||
// pixmapPainter.setPen(Qt::transparent);
|
||||
// pixmapPainter.setBrush(Qt::black);
|
||||
// pixmapPainter.setOpacity(0.65);
|
||||
// pixmapPainter.drawPath(rectPath);
|
||||
// pixmapPainter.end();
|
||||
|
||||
// // 模糊这个黑底
|
||||
// QImage img = pixmap.toImage();
|
||||
// qt_blurImage(img, 10, false, false);
|
||||
|
||||
// // 挖掉中心
|
||||
// pixmap = QPixmap::fromImage(img);
|
||||
// QPainter pixmapPainter2(&pixmap);
|
||||
// pixmapPainter2.setRenderHint(QPainter::Antialiasing);
|
||||
// pixmapPainter2.setCompositionMode(QPainter::CompositionMode_Clear);
|
||||
// pixmapPainter2.setPen(Qt::transparent);
|
||||
// pixmapPainter2.setBrush(Qt::transparent);
|
||||
// pixmapPainter2.drawPath(rectPath);
|
||||
|
||||
// // 绘制阴影
|
||||
// p.drawPixmap(this->rect(), pixmap, pixmap.rect());
|
||||
|
||||
// // 绘制一个背景
|
||||
// p.save();
|
||||
// p.fillPath(rectPath,palette().color(QPalette::Base));
|
||||
// p.restore();
|
||||
//}
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef CHANGEPROJECTIONNAME_H
|
||||
#define CHANGEPROJECTIONNAME_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
|
||||
namespace Ui {
|
||||
class ChangeProjectionName;
|
||||
}
|
||||
|
||||
class ChangeProjectionName : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ChangeProjectionName(QWidget *parent = nullptr);
|
||||
~ChangeProjectionName();
|
||||
|
||||
private:
|
||||
Ui::ChangeProjectionName *ui;
|
||||
|
||||
//protected:
|
||||
// void paintEvent(QPaintEvent *);
|
||||
|
||||
Q_SIGNALS:
|
||||
void sendNewProjectionName(QString name);
|
||||
};
|
||||
|
||||
#endif // CHANGEUSERNAME_H
|
|
@ -0,0 +1,277 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ChangeProjectionName</class>
|
||||
<widget class="QDialog" name="ChangeProjectionName">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>420</width>
|
||||
<height>184</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>420</width>
|
||||
<height>184</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>420</width>
|
||||
<height>184</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Projection to this pc</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="pic.qrc">
|
||||
<normaloff>:/ukui-control-center.png</normaloff>:/ukui-control-center.png</iconset>
|
||||
</property>
|
||||
<property name="sizeGripEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>420</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>420</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>24</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>24</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="ChangeProjectionname">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>74</width>
|
||||
<height>36</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>74</width>
|
||||
<height>36</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Device Name</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>298</width>
|
||||
<height>36</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>298</width>
|
||||
<height>36</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="tipLabel">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>74</width>
|
||||
<height>36</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>74</width>
|
||||
<height>36</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="tipLabel_2">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>298</width>
|
||||
<height>36</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>298</width>
|
||||
<height>36</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<property name="spacing">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="cancelBtn">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>96</width>
|
||||
<height>36</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>33</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="saveBtn">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>96</width>
|
||||
<height>36</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>96</width>
|
||||
<height>36</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="pic.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,7 @@
|
|||
<RCC>
|
||||
<qresource prefix="/new/prefix1"/>
|
||||
<qresource prefix="/">
|
||||
<file>touping.png</file>
|
||||
<file>ukui-control-center.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
|
@ -0,0 +1,933 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
#include "projection.h"
|
||||
#include "ui_projection.h"
|
||||
#include <QProcess>
|
||||
#include <QMessageBox>
|
||||
#include <QIcon>
|
||||
#include <QDebug>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#define ITEMFIXEDHEIGH 58
|
||||
#define THEME_QT_SCHEMA "org.ukui.style"
|
||||
#define MODE_QT_KEY "style-name"
|
||||
|
||||
#define SYSTEM_CMD_ERROR -1
|
||||
enum {
|
||||
NOT_SUPPORT_P2P = 0,
|
||||
SUPPORT_P2P_WITHOUT_DEV,
|
||||
SUPPORT_P2P_PERFECT,
|
||||
OP_NO_RESPONSE,
|
||||
NO_SERVICE
|
||||
};
|
||||
|
||||
enum {
|
||||
PROJECTION_RUNNING = 256,
|
||||
DAEMON_NOT_RUNNING = 512
|
||||
};
|
||||
|
||||
Projection::Projection()
|
||||
{
|
||||
qDebug()<<"123456456";
|
||||
QTranslator *translator = new QTranslator(this);
|
||||
translator->load("/usr/share/projection/translations/" + QLocale::system().name());
|
||||
QApplication::installTranslator(translator);
|
||||
pluginName = tr("Projection");
|
||||
pluginType = DEVICES;
|
||||
ui = new Ui::Projection;
|
||||
pluginWidget = new QWidget;
|
||||
pluginWidget->setAttribute(Qt::WA_StyledBackground,true);
|
||||
pluginWidget->setAttribute(Qt::WA_DeleteOnClose);
|
||||
ui->setupUi(pluginWidget);
|
||||
QPalette pa;
|
||||
pa.setColor(QPalette::WindowText, Qt::red);
|
||||
ui->tipLabel->setPalette(pa);
|
||||
ui->tipLabel2->setPalette(pa);
|
||||
ui->tipLabel2->setFixedWidth(ui->widget_7->width()-ui->label_5->width()-48);
|
||||
projectionBtn = new KSwitchButton(pluginWidget);
|
||||
pincodeBtn = new KSwitchButton(pluginWidget);
|
||||
miracastBtn = new KSwitchButton(pluginWidget);
|
||||
dropDownLabel = new DrownLabel(pluginWidget);
|
||||
ui->horizontalLayout_12->addWidget(dropDownLabel);
|
||||
|
||||
// ui->pinframe->hide();
|
||||
init_button_status(get_process_status());
|
||||
// qDebug()<<"---- Projection contructed, then subscribe slot func ";
|
||||
connect(projectionBtn, SIGNAL(stateChanged(bool)), this, SLOT(projectionButtonClickSlots(bool)));
|
||||
connect(pincodeBtn, SIGNAL(stateChanged(bool)), this, SLOT(pincodeButtonClickSlots(bool)));
|
||||
// connect(miracastBtn, SIGNAL(stateChanged(bool)), this, SLOT(miracastsourceButtonClickSlots(bool)));
|
||||
connect(ui->pushButton, &QPushButton::clicked, this, [=](){
|
||||
pushButtonClickSlots();
|
||||
});
|
||||
connect(dropDownLabel, &DrownLabel::labelClicked, [=](){
|
||||
debusFileConfig();
|
||||
onDrownLabelClicked();
|
||||
});
|
||||
// m_pin = new QLabel(pluginWidget);
|
||||
// ui->label->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}");
|
||||
ui->label->setStyleSheet("QLabel{color: palette(windowText);}");
|
||||
//~ contents_path /projection/Open Projection
|
||||
ui->titleLabel->setStyleSheet("QLabel{color: palette(windowText);}");
|
||||
pa.setColor(QPalette::WindowText, Qt::gray);
|
||||
ui->label_2->setPalette(pa);
|
||||
ui->label_4->setPalette(pa);
|
||||
ui->pushButton->setEnabled(false);
|
||||
ui->pushButton->setStyleSheet("color: gray");
|
||||
ui->pushButton->setText(tr("Find device"));
|
||||
ui->titleLabel_3->setStyleSheet("QLabel{color:palette(windowText);}");
|
||||
|
||||
m_pServiceInterface = new QDBusInterface("org.freedesktop.miracleagent",
|
||||
"/org/freedesktop/miracleagent",
|
||||
"org.freedesktop.miracleagent.op",
|
||||
QDBusConnection::sessionBus());
|
||||
QString path=QDir::homePath()+"/.config/miracast.ini";
|
||||
QSettings *setting=new QSettings(path,QSettings::IniFormat);
|
||||
setting->beginGroup("projection");
|
||||
bool bo=setting->contains("host");
|
||||
qDebug()<<bo<<"bo";
|
||||
if (!bo) {
|
||||
QDBusInterface *hostInterface = new QDBusInterface("org.freedesktop.hostname1",
|
||||
"/org/freedesktop/hostname1",
|
||||
"org.freedesktop.hostname1",
|
||||
QDBusConnection::systemBus());
|
||||
hostName = hostInterface->property("Hostname").value<QString>();
|
||||
setting->setValue("host",hostName);
|
||||
setting->sync();
|
||||
setting->endGroup();
|
||||
initComponent();
|
||||
}else {
|
||||
hostName = setting->value("host").toString();
|
||||
}
|
||||
//ui->projectionNameWidget->setFixedHeight(40);
|
||||
// setLabelText(ui->projectionName,hostName);
|
||||
QFontMetrics fontMetrics(ui->projectionName->font());
|
||||
int fontSize = fontMetrics.width(hostName);
|
||||
if((ui->widget_9->width()-ui->titleLabel->width()-projectionBtn->width()-46) <= fontSize){
|
||||
ui->projectionName->setFixedWidth(ui->widget_9->width()-ui->titleLabel->width()-projectionBtn->width()-46);
|
||||
}
|
||||
if((ui->widget_9->width()-ui->titleLabel->width()-projectionBtn->width()-46) > fontSize){
|
||||
ui->projectionName->setFixedWidth(fontSize);
|
||||
}
|
||||
ui->projectionName->setText(hostName);
|
||||
getSystemFontFamily();//建立GSetting监听系统字体
|
||||
ui->projectionNameChange->setProperty("useIconHighlightEffect", 0x8);
|
||||
ui->projectionNameChange->setPixmap(QIcon::fromTheme("document-edit-symbolic").pixmap(ui->projectionNameChange->size()));
|
||||
ui->projectionNameWidget->installEventFilter(this);
|
||||
ui->horizontalLayout->addWidget(projectionBtn);
|
||||
ui->horizontalLayout_17->addWidget(pincodeBtn);
|
||||
ui->horizontalLayout_6->addWidget(miracastBtn);
|
||||
initComponent();
|
||||
debusFileConfig();
|
||||
ui->widget_4->installEventFilter(this);
|
||||
ui->widget_5->installEventFilter(this);
|
||||
ui->widget_6->installEventFilter(this);
|
||||
ui->widget_7->installEventFilter(this);
|
||||
ui->widget_9->installEventFilter(this);
|
||||
QLocale locale;
|
||||
if (locale.language() == QLocale::English){
|
||||
connect(this,&Projection::resize,[=](){
|
||||
setLabelText(ui->label_2,"Wireless LAN connection may be interrupted during projection.");
|
||||
setLabelText(ui->titleLabel_3,"You need to match the PIN code when projecting the screen to the pc");
|
||||
setLabelText(ui->label_3,"Open(PIN authentication is not supported temporarily.)");
|
||||
setLabelText(ui->label_4,"When enabled,the project to this PC feature stops.");
|
||||
});
|
||||
}
|
||||
}
|
||||
void Projection::debusFileConfig()
|
||||
{
|
||||
QDBusInterface*mInterface = new QDBusInterface("org.freedesktop.miracle.wifi",
|
||||
"/org/freedesktop/miracle/wifi/ui",
|
||||
"org.freedesktop.miracle.wifi.ui",
|
||||
QDBusConnection::systemBus());
|
||||
QDBusMessage result = mInterface->call("QueryConnectedDevice");
|
||||
|
||||
qDebug()<<"----------"<<result;
|
||||
deleteAllitemsOfLayout( ui->verticalLayout_2);
|
||||
|
||||
QList<QVariant> outArgs = result.arguments();
|
||||
QVariant first = outArgs.at(0);
|
||||
QMap<QString,QString>deviceName;
|
||||
const QDBusArgument &dbusArgs = first.value<QDBusArgument>();
|
||||
dbusArgs.beginMap();
|
||||
while (!dbusArgs.atEnd()) {
|
||||
QString key;
|
||||
QString value;
|
||||
dbusArgs.beginMapEntry();
|
||||
dbusArgs >> key >> value ;
|
||||
qDebug() << key<< "数值" <<value;
|
||||
deviceName.insert(key,value);
|
||||
dbusArgs.endMapEntry();
|
||||
}
|
||||
dbusArgs.endMap();
|
||||
|
||||
QMap<QString, QString>::iterator iter = deviceName.begin();
|
||||
while (iter != deviceName.end())
|
||||
{
|
||||
QString value = iter.value();
|
||||
QHBoxLayout *addLyt = new QHBoxLayout;
|
||||
addLyt->setContentsMargins(0,17,0,17);
|
||||
QLabel *iconLabel = new QLabel(ui->widget_2);
|
||||
QLabel *textLabel = new QLabel(ui->widget_2);
|
||||
QPushButton *iconBtn = new QPushButton(ui->widget_2);
|
||||
textLabel->setText(iter.key());
|
||||
iconLabel->setPixmap(QIcon::fromTheme("phone-apple-iphone-symbolic").pixmap(QSize(16,16)));
|
||||
iconLabel->setProperty("useIconHighlightEffect", 0x8);
|
||||
iconBtn->setMaximumSize(QSize(36,36));
|
||||
iconBtn->setIconSize(QSize(16, 16));
|
||||
iconBtn->setIcon(QIcon::fromTheme("edit-delete-symbolic"));
|
||||
iconBtn->setProperty("useIconHighlightEffect", 0x8);
|
||||
iconBtn->setProperty("isWindowButton", 0x1);
|
||||
iconBtn->setFlat(true);
|
||||
QPalette paletteLan = iconBtn->palette();
|
||||
paletteLan.setColor(QPalette::Highlight, Qt::transparent);
|
||||
paletteLan.setBrush(QPalette::Button, QBrush(QColor(1,1,1,0)));
|
||||
iconBtn->setPalette(paletteLan);
|
||||
addLyt->addItem(new QSpacerItem(16,10,QSizePolicy::Fixed));
|
||||
addLyt->addWidget(iconLabel);
|
||||
addLyt->addItem(new QSpacerItem(13,10,QSizePolicy::Fixed));
|
||||
addLyt->addWidget(textLabel);
|
||||
addLyt->addItem(new QSpacerItem(712,10,QSizePolicy::Expanding));
|
||||
addLyt->addWidget(iconBtn);
|
||||
addLyt->addItem(new QSpacerItem(16,10,QSizePolicy::Fixed));
|
||||
QFrame *line = new QFrame(ui->widget_2);
|
||||
line->setLineWidth(0);
|
||||
line->setFixedHeight(1);
|
||||
line->setFrameShape(QFrame::Shape::HLine);
|
||||
line->setStyleSheet("color: rgb(244, 244, 244);opacity:1;");
|
||||
ui->verticalLayout_2->addWidget(line);
|
||||
ui->verticalLayout_2->addLayout(addLyt);
|
||||
if (iter == deviceName.begin()){
|
||||
delete line;
|
||||
}
|
||||
connect(iconBtn, &QPushButton::clicked, this, [=] {
|
||||
|
||||
QDBusInterface*mInterface = new QDBusInterface("org.freedesktop.miracle.wifi",
|
||||
"/org/freedesktop/miracle/wifi/ui",
|
||||
"org.freedesktop.miracle.wifi.ui",
|
||||
QDBusConnection::systemBus());
|
||||
QDBusMessage result = mInterface->call("DeleteConnectedDevice",value);
|
||||
QList<QVariant> outArgs = result.arguments();
|
||||
bool res = outArgs.at(0).value<int>();
|
||||
if (!res){
|
||||
debusFileConfig();
|
||||
}
|
||||
});
|
||||
iter++;
|
||||
}
|
||||
ui->widget_2->update();
|
||||
}
|
||||
|
||||
void Projection::deleteAllitemsOfLayout(QLayout *layout)
|
||||
{
|
||||
QLayoutItem *child;
|
||||
while ((child = layout->takeAt(0)) != nullptr)
|
||||
{
|
||||
///setParent为NULL,防止删除之后界面不消失
|
||||
if(child->widget())
|
||||
{
|
||||
child->widget()->setParent(nullptr);
|
||||
}else if(child->layout()){
|
||||
deleteAllitemsOfLayout(child->layout());
|
||||
}
|
||||
delete child;
|
||||
}
|
||||
}
|
||||
|
||||
void Projection::changeProjectionName(QString name){
|
||||
qDebug() << name;
|
||||
QString path=QDir::homePath()+"/.config/miracast.ini";
|
||||
QSettings *setting=new QSettings(path,QSettings::IniFormat);
|
||||
setting->beginGroup("projection");
|
||||
setting->setValue("host",name);
|
||||
setting->sync();
|
||||
setting->endGroup();
|
||||
m_pServiceInterface->call("UiSetName",name);
|
||||
QFontMetrics fontMetrics(ui->projectionName->font());
|
||||
int fontSize = fontMetrics.width(name);
|
||||
if((ui->widget_9->width()-ui->titleLabel->width()-projectionBtn->width()-46) <= fontSize){
|
||||
ui->projectionName->setFixedWidth(ui->widget_9->width()-ui->titleLabel->width()-projectionBtn->width()-46);
|
||||
}
|
||||
if((ui->widget_9->width()-ui->titleLabel->width()-projectionBtn->width()-46) > fontSize){
|
||||
ui->projectionName->setFixedWidth(fontSize);
|
||||
}
|
||||
// setLabelText(ui->projectionName,name);
|
||||
ui->projectionName->setText(name);
|
||||
}
|
||||
|
||||
void Projection::getSystemFontFamily()
|
||||
{
|
||||
const QByteArray id("org.ukui.style");
|
||||
QGSettings * fontSetting = new QGSettings(id, QByteArray(), this);
|
||||
connect(fontSetting, &QGSettings::changed,[=](QString key) {
|
||||
if ("systemFont" == key || "systemFontSize" ==key) {
|
||||
QString path=QDir::homePath()+"/.config/miracast.ini";
|
||||
QSettings *setting=new QSettings(path,QSettings::IniFormat);
|
||||
setting->beginGroup("projection");
|
||||
QString name = setting->value("host").toString();
|
||||
setting->sync();
|
||||
setting->endGroup();
|
||||
QFontMetrics fontMetrics(ui->projectionName->font());
|
||||
int fontSize = fontMetrics.width(name);
|
||||
if((ui->widget_9->width()-ui->titleLabel->width()-projectionBtn->width()-46) <= fontSize){
|
||||
ui->projectionName->setFixedWidth(ui->widget_9->width()-ui->titleLabel->width()-projectionBtn->width()-46);
|
||||
}
|
||||
if((ui->widget_9->width()-ui->titleLabel->width()-projectionBtn->width()-46) > fontSize){
|
||||
ui->projectionName->setFixedWidth(fontSize);
|
||||
}
|
||||
// setLabelText(ui->projectionName,name);
|
||||
ui->projectionName->setText(name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Projection::showChangeProjectionNameDialog(){
|
||||
|
||||
ChangeProjectionName * dialog = new ChangeProjectionName();
|
||||
|
||||
connect(dialog, &ChangeProjectionName::sendNewProjectionName, [=](QString name){
|
||||
changeProjectionName(name);
|
||||
});
|
||||
dialog->exec();
|
||||
}
|
||||
|
||||
bool Projection::getWifiStatus() {
|
||||
QDBusInterface interface( "org.freedesktop.NetworkManager",
|
||||
"/org/freedesktop/NetworkManager",
|
||||
"org.freedesktop.DBus.Properties",
|
||||
QDBusConnection::systemBus() );
|
||||
// 获取当前wifi是否打开
|
||||
QDBusReply<QVariant> m_result = interface.call("Get", "org.freedesktop.NetworkManager", "WirelessEnabled");
|
||||
if (m_result.isValid()) {
|
||||
bool status = m_result.value().toBool();
|
||||
return status;
|
||||
} else {
|
||||
qDebug()<<"org.freedesktop.NetworkManager get invalid"<<endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Projection::setWifiStatus(bool status) {
|
||||
|
||||
QString wifiStatus = status ? "on" : "off";
|
||||
QString program = "nmcli";
|
||||
QStringList arg;
|
||||
arg << "radio" << "wifi" << wifiStatus;
|
||||
QProcess *nmcliCmd = new QProcess(this);
|
||||
nmcliCmd->start(program, arg);
|
||||
nmcliCmd->waitForStarted();
|
||||
}
|
||||
|
||||
void Projection::setLabelText(QLabel *label, QString text)
|
||||
{
|
||||
QFontMetrics fontMetrics(label->font());
|
||||
int fontSize = fontMetrics.width(text);
|
||||
if (fontSize > label->width()) {
|
||||
label->setText(fontMetrics.elidedText(text, Qt::ElideRight, label->width()));
|
||||
label->setToolTip(text);
|
||||
} else {
|
||||
label->setText(text);
|
||||
label->setToolTip("");
|
||||
}
|
||||
}
|
||||
|
||||
bool Projection::eventFilter(QObject *watched, QEvent *event){
|
||||
QLocale locale;
|
||||
QMouseEvent * mouseEvent = static_cast<QMouseEvent *>(event);
|
||||
if (watched == ui->projectionNameWidget){
|
||||
if (event->type() == QEvent::MouseButtonPress){
|
||||
if (mouseEvent->button() == Qt::LeftButton ){
|
||||
showChangeProjectionNameDialog();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (watched == ui->widget_9 ) {
|
||||
if (event->type() == QEvent::Resize) {
|
||||
QFontMetrics fontMetrics(ui->projectionName->font());
|
||||
int fontSize = fontMetrics.width(ui->projectionName->text());
|
||||
if((ui->widget_9->width()-ui->titleLabel->width()-projectionBtn->width()-46) <= fontSize){
|
||||
ui->projectionName->setFixedWidth(ui->widget_9->width()-ui->titleLabel->width()-projectionBtn->width()-46);
|
||||
emit resize();
|
||||
}
|
||||
if((ui->widget_9->width()-ui->titleLabel->width()-projectionBtn->width()-46) > fontSize){
|
||||
ui->projectionName->setFixedWidth(fontSize);
|
||||
emit resize();
|
||||
}
|
||||
ui->label_2->setFixedWidth(ui->widget_9->width()-106);
|
||||
emit resize();
|
||||
}
|
||||
}
|
||||
else if (watched == ui->widget_4 ) {
|
||||
if (event->type() == QEvent::Resize) {
|
||||
ui->titleLabel_3->setFixedWidth(ui->widget_4->width()-106);
|
||||
emit resize();
|
||||
}
|
||||
}
|
||||
else if (watched == ui->widget_5 ) {
|
||||
if (event->type() == QEvent::Resize) {
|
||||
ui->label_3->setFixedWidth(ui->widget_5->width()-246);
|
||||
ui->label_4->setFixedWidth(ui->widget_5->width()-246);
|
||||
emit resize();
|
||||
}
|
||||
}
|
||||
else if (watched == ui->widget_6 ) {
|
||||
if (event->type() == QEvent::Resize) {
|
||||
ui->tipLabel->setFixedWidth(ui->widget_5->width()-256);
|
||||
emit resize();
|
||||
}
|
||||
}
|
||||
else if (watched == ui->widget_7 ) {
|
||||
if (event->type() == QEvent::Resize && locale.language() == QLocale::English) {
|
||||
ui->tipLabel2->setFixedWidth(ui->widget_5->width()-326);
|
||||
emit resize();
|
||||
}
|
||||
else if (event->type() == QEvent::Resize && locale.language() == QLocale::Chinese) {
|
||||
ui->tipLabel2->setFixedWidth(ui->widget_5->width()-ui->label_5->width()-48);
|
||||
}
|
||||
}
|
||||
return QObject::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
void Projection::onDrownLabelClicked()
|
||||
{
|
||||
if (dropDownLabel->isChecked) {
|
||||
ui->widget_2->hide();
|
||||
dropDownLabel->setDropDownStatus(false);
|
||||
} else {
|
||||
ui->widget_2->show();
|
||||
dropDownLabel->setDropDownStatus(true);
|
||||
}
|
||||
}
|
||||
|
||||
void Projection::catchsignal()
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
m_pServiceInterface = new QDBusInterface("org.freedesktop.miracle.wifi",
|
||||
"/org/freedesktop/miracle/wifi/ui",
|
||||
"org.freedesktop.miracle.wifi.ui",
|
||||
QDBusConnection::systemBus());
|
||||
if (m_pServiceInterface->isValid()) {
|
||||
connect(m_pServiceInterface,SIGNAL(PinCode(QString, QString)),this,SLOT(projectionPinSlots(QString,QString)));
|
||||
return;
|
||||
}else {
|
||||
delete m_pServiceInterface;
|
||||
delaymsec(1000);
|
||||
}
|
||||
}
|
||||
\
|
||||
}
|
||||
void Projection::delaymsec(int msec)
|
||||
{
|
||||
QTime dieTime = QTime::currentTime().addMSecs(msec);
|
||||
while( QTime::currentTime() < dieTime )
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
|
||||
}
|
||||
|
||||
Projection::~Projection()
|
||||
{
|
||||
delete ui;
|
||||
delete m_pServiceInterface;
|
||||
}
|
||||
|
||||
QString Projection::plugini18nName(){
|
||||
QFile server("/usr/bin/miracle-wifid");
|
||||
QFile agent("/usr/bin/miracle-agent");
|
||||
|
||||
int projectionstatus;
|
||||
QDBusMessage result = m_pServiceInterface->call("PreCheck");
|
||||
QList<QVariant> outArgs = result.arguments();
|
||||
projectionstatus = outArgs.at(0).value<int>();
|
||||
|
||||
if(!server.exists() || !agent.exists() || NO_SERVICE == projectionstatus)
|
||||
return NULL;
|
||||
|
||||
return pluginName;
|
||||
}
|
||||
|
||||
int Projection::pluginTypes(){
|
||||
return pluginType;
|
||||
}
|
||||
|
||||
int Projection::get_process_status(void)
|
||||
{
|
||||
int res;
|
||||
|
||||
do{
|
||||
res = system("checkDaemonRunning.sh");
|
||||
}while(SYSTEM_CMD_ERROR == res);
|
||||
|
||||
return res;
|
||||
}
|
||||
int Projection::get_process_source_status(void)
|
||||
{
|
||||
QString path=QDir::homePath()+"/.config/miracastsource.ini";
|
||||
QSettings *setting=new QSettings(path,QSettings::IniFormat);
|
||||
setting->beginGroup("projection");
|
||||
QString method;
|
||||
|
||||
bool bo=setting->contains("miracastsource");
|
||||
if (!bo) {
|
||||
method = "false";
|
||||
return 0;
|
||||
}else {
|
||||
method = setting->value("miracastsource").toString();
|
||||
if (method == "true")
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Projection::init_button_status(int status)
|
||||
{
|
||||
// qDebug()<<"---- button init status "<<status;
|
||||
if (status == PROJECTION_RUNNING) {
|
||||
projectionBtn->setChecked(true);
|
||||
}
|
||||
else {
|
||||
projectionBtn->setChecked(false);//projection not switch-on, or daemon programs not running at all
|
||||
}
|
||||
}
|
||||
|
||||
void Projection::init_source_button_status(int status)
|
||||
{
|
||||
// qDebug()<<"---- button init status "<<status;
|
||||
if (status == 1) {
|
||||
// miracastBtn->setChecked(true);
|
||||
}
|
||||
else {
|
||||
// miracastBtn->setChecked(false);//projection not switch-on, or daemon programs not running at all
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int Projection::get_pin_button_status(void)
|
||||
{
|
||||
QString path=QDir::homePath()+"/.config/miracast.ini";
|
||||
QSettings *setting=new QSettings(path,QSettings::IniFormat);
|
||||
setting->beginGroup("projection");
|
||||
QString method;
|
||||
|
||||
bool bo=setting->contains("config_method");
|
||||
if (!bo) {
|
||||
method = "display";
|
||||
m_pServiceInterface->call("UiSetConfigMethods","display");
|
||||
return 1;
|
||||
}else {
|
||||
method = setting->value("config_method").toString();
|
||||
m_pServiceInterface->call("UiSetConfigMethods",method);
|
||||
if (method == "display")
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Projection::init_pin_button_status(int status)
|
||||
{
|
||||
qDebug() << status;
|
||||
if (status) {
|
||||
pincodeBtn->setChecked(true);
|
||||
}
|
||||
else {
|
||||
pincodeBtn->setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
QWidget *Projection::pluginUi(){
|
||||
int res;
|
||||
int projectionstatus;
|
||||
int source_res;
|
||||
int pin_res;
|
||||
|
||||
|
||||
res = get_process_status();
|
||||
source_res=get_process_source_status();
|
||||
pin_res = get_pin_button_status();
|
||||
|
||||
init_button_status(res);
|
||||
init_pin_button_status(pin_res);
|
||||
init_source_button_status(source_res);
|
||||
|
||||
if (res == DAEMON_NOT_RUNNING){
|
||||
projectionstatus = NO_SERVICE;
|
||||
}
|
||||
else{
|
||||
QDBusMessage result = m_pServiceInterface->call("PreCheck");
|
||||
QList<QVariant> outArgs = result.arguments();
|
||||
projectionstatus = outArgs.at(0).value<int>();
|
||||
qDebug() << "---->" << projectionstatus;
|
||||
}
|
||||
|
||||
ui->widget_3->show();
|
||||
ui->widget_4->show();
|
||||
ui->widget_5->hide();
|
||||
ui->widget_6->show();
|
||||
ui->widget_7->hide();
|
||||
ui->widget_9->show();
|
||||
ui->label->show();
|
||||
QLocale locale;
|
||||
if (locale.language() == QLocale::Chinese){
|
||||
ui->tipLabel->setText(tr("(No wireless network card is detected or the network card driver does not support it.)"));
|
||||
ui->tipLabel2->setText(tr("(No wireless network card is detected or the network card driver does not support it.)"));
|
||||
}
|
||||
else if (locale.language() == QLocale::English){
|
||||
setLabelText(ui->tipLabel,"(No wireless network card is detected or the network card driver does not support it.)");
|
||||
setLabelText(ui->tipLabel2,"(No wireless network card is detected or the network card driver does not support it.)");
|
||||
connect(this,&Projection::resize,[=](){
|
||||
setLabelText(ui->tipLabel,"(No wireless network card is detected or the network card driver does not support it.)");
|
||||
setLabelText(ui->tipLabel2,"(No wireless network card is detected or the network card driver does not support it.)");
|
||||
});
|
||||
}
|
||||
ui->tipLabel->show();
|
||||
ui->tipLabel2->show();
|
||||
if (dropDownLabel->isChecked){
|
||||
ui->widget_2->show();
|
||||
}
|
||||
else{
|
||||
ui->widget_2->hide();
|
||||
}
|
||||
|
||||
//First, we check whether service process is running
|
||||
if (NO_SERVICE == projectionstatus) {
|
||||
QLocale locale;
|
||||
if (locale.language() == QLocale::Chinese){
|
||||
ui->tipLabel->setText(tr("(No wireless network card is detected or the network card driver does not support it.)"));
|
||||
ui->tipLabel2->setText(tr("(No wireless network card is detected or the network card driver does not support it.)"));
|
||||
}
|
||||
else if (locale.language() == QLocale::English){
|
||||
setLabelText(ui->tipLabel,"(No wireless network card is detected or the network card driver does not support it.)");
|
||||
setLabelText(ui->tipLabel2,"(No wireless network card is detected or the network card driver does not support it.)");
|
||||
connect(this,&Projection::resize,[=](){
|
||||
setLabelText(ui->tipLabel,"(No wireless network card is detected or the network card driver does not support it.)");
|
||||
setLabelText(ui->tipLabel2,"(No wireless network card is detected or the network card driver does not support it.)");
|
||||
});
|
||||
}
|
||||
ui->tipLabel->show();
|
||||
ui->tipLabel2->show();
|
||||
projectionBtn->setChecked(false);
|
||||
// miracastBtn->setChecked(false);
|
||||
projectionBtn->setCheckable(false);
|
||||
// miracastBtn->setCheckable(false);
|
||||
}
|
||||
//Then let's check whether hardware is ok
|
||||
else if (NOT_SUPPORT_P2P == projectionstatus) {
|
||||
projectionBtn->setChecked(false);
|
||||
// miracastBtn->setChecked(false);
|
||||
projectionBtn->setCheckable(false);
|
||||
// miracastBtn->setCheckable(false);
|
||||
}
|
||||
else if (SUPPORT_P2P_PERFECT == projectionstatus) {
|
||||
if(getWifiStatus())
|
||||
{
|
||||
qDebug()<<"wifi is on now";
|
||||
ui->tipLabel->hide();
|
||||
ui->tipLabel2->hide();
|
||||
projectionBtn->setCheckable(true);
|
||||
// miracastBtn->setCheckable(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug()<<"wifi is off now";
|
||||
QLocale locale;
|
||||
if (locale.language() == QLocale::Chinese){
|
||||
ui->tipLabel->setText(tr("(WLAN is not turned on. You need to turn on WLAN to use this function.)"));
|
||||
ui->tipLabel2->setText(tr("(WLAN is not turned on. You need to turn on WLAN to use this function.)"));
|
||||
}
|
||||
else if (locale.language() == QLocale::English){
|
||||
setLabelText(ui->tipLabel,"(WLAN is not turned on. You need to turn on WLAN to use this function.)");
|
||||
setLabelText(ui->tipLabel2,"(WLAN is not turned on. You need to turn on WLAN to use this function.)");
|
||||
connect(this,&Projection::resize,[=](){
|
||||
setLabelText(ui->tipLabel,"(WLAN is not turned on. You need to turn on WLAN to use this function.)");
|
||||
setLabelText(ui->tipLabel2,"(WLAN is not turned on. You need to turn on WLAN to use this function.)");
|
||||
});
|
||||
}
|
||||
ui->tipLabel->show();
|
||||
ui->tipLabel2->show();
|
||||
projectionBtn->setChecked(false);
|
||||
// miracastBtn->setChecked(false);
|
||||
projectionBtn->setCheckable(false);
|
||||
// miracastBtn->setCheckable(false);
|
||||
ui->widget_6->update();
|
||||
ui->widget_7->update();
|
||||
}
|
||||
}
|
||||
else if (SUPPORT_P2P_WITHOUT_DEV == projectionstatus) {
|
||||
if(getWifiStatus())
|
||||
{
|
||||
qDebug()<<"wifi is on now";
|
||||
ui->tipLabel->hide();
|
||||
ui->tipLabel2->show();
|
||||
projectionBtn->setCheckable(true);
|
||||
// miracastBtn->setCheckable(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug()<<"wifi is off now";
|
||||
QLocale locale;
|
||||
if (locale.language() == QLocale::Chinese){
|
||||
ui->tipLabel->setText(tr("(WLAN is not turned on. You need to turn on WLAN to use this function.)"));
|
||||
ui->tipLabel2->setText(tr("(WLAN is not turned on. You need to turn on WLAN to use this function.)"));
|
||||
}
|
||||
else if (locale.language() == QLocale::English){
|
||||
setLabelText(ui->tipLabel,"(WLAN is not turned on. You need to turn on WLAN to use this function.)");
|
||||
setLabelText(ui->tipLabel2,"(WLAN is not turned on. You need to turn on WLAN to use this function.)");
|
||||
connect(this,&Projection::resize,[=](){
|
||||
setLabelText(ui->tipLabel,"(WLAN is not turned on. You need to turn on WLAN to use this function.)");
|
||||
setLabelText(ui->tipLabel2,"(WLAN is not turned on. You need to turn on WLAN to use this function.)");
|
||||
});
|
||||
}
|
||||
ui->tipLabel->show();
|
||||
ui->tipLabel2->show();
|
||||
projectionBtn->setChecked(false);
|
||||
projectionBtn->setCheckable(false);
|
||||
// miracastBtn->setCheckable(false);
|
||||
}
|
||||
}
|
||||
else if (OP_NO_RESPONSE == projectionstatus) {
|
||||
projectionBtn->setCheckable(false);
|
||||
// miracastBtn->setCheckable(false);
|
||||
}
|
||||
if (res == PROJECTION_RUNNING)//如果接收端已开启
|
||||
{
|
||||
// miracastBtn->setChecked(false);
|
||||
// miracastBtn->setCheckable(false);
|
||||
}
|
||||
if(source_res==1)//如果投射端已开启
|
||||
{
|
||||
projectionBtn->setChecked(false);
|
||||
projectionBtn->setCheckable(false);
|
||||
}
|
||||
|
||||
|
||||
//监听WLAN开关
|
||||
QDBusConnection::systemBus().connect(QString(), QString("/org/freedesktop/NetworkManager"), "org.freedesktop.NetworkManager", "PropertiesChanged", this, SLOT(netPropertiesChangeSlot(QMap<QString,QVariant>)));
|
||||
return pluginWidget;
|
||||
}
|
||||
void Projection::netPropertiesChangeSlot(QMap<QString, QVariant> property) {
|
||||
if (property.keys().contains("WirelessEnabled")) {
|
||||
qDebug()<<"WLAN status changed";
|
||||
pluginUi();
|
||||
}
|
||||
}
|
||||
|
||||
const QString Projection::name() const {
|
||||
return QStringLiteral("projection");
|
||||
}
|
||||
|
||||
bool Projection::isShowOnHomePage() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QIcon Projection::icon() const
|
||||
{
|
||||
return QIcon::fromTheme("ukui-miracast-symbolic");
|
||||
}
|
||||
|
||||
bool Projection::isEnable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void Projection::projectionPinSlots(QString type, QString pin) {
|
||||
if (type.contains("clear")) {
|
||||
//m_pin->clear();
|
||||
} else {
|
||||
qDebug()<<pin;
|
||||
//m_pin->setText(pin);
|
||||
}
|
||||
}
|
||||
|
||||
void Projection::projectionButtonClickSlots(bool status) {
|
||||
|
||||
int config_method = pinCodeStatus(2);
|
||||
|
||||
if (status){
|
||||
QDBusMessage result;
|
||||
if (config_method){
|
||||
result = m_pServiceInterface->call("Start",ui->projectionName->text(),"display");
|
||||
|
||||
}
|
||||
else{
|
||||
result = m_pServiceInterface->call("Start",ui->projectionName->text(),"pbc");
|
||||
}
|
||||
QList<QVariant> outArgs = result.arguments();
|
||||
int res = outArgs.at(0).value<int>();
|
||||
if(!res)
|
||||
{
|
||||
// miracastBtn->setCheckable(false);
|
||||
}
|
||||
} else {
|
||||
m_pServiceInterface->call("Stop");
|
||||
int projectionstatus;
|
||||
QDBusMessage result = m_pServiceInterface->call("PreCheck");
|
||||
QList<QVariant> outArgs = result.arguments();
|
||||
projectionstatus = outArgs.at(0).value<int>();
|
||||
if (SUPPORT_P2P_PERFECT == projectionstatus){
|
||||
// miracastBtn->setCheckable(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Projection::pincodeButtonClickSlots(bool status) {
|
||||
QDBusMessage result;
|
||||
QString path=QDir::homePath()+"/.config/miracast.ini";
|
||||
QSettings *setting=new QSettings(path,QSettings::IniFormat);
|
||||
setting->beginGroup("projection");
|
||||
|
||||
if (status){
|
||||
pinCodeStatus(1);
|
||||
result = m_pServiceInterface->call("UiSetConfigMethods","display");
|
||||
setting->setValue("config_method","display");
|
||||
} else {
|
||||
pinCodeStatus(0);
|
||||
result = m_pServiceInterface->call("UiSetConfigMethods","pbc");
|
||||
setting->setValue("config_method","pbc");
|
||||
}
|
||||
setting->sync();
|
||||
setting->endGroup();
|
||||
QList<QVariant> outArgs = result.arguments();
|
||||
int res = outArgs.at(0).value<int>();
|
||||
if(res)
|
||||
qDebug()<<"Fail.";
|
||||
else
|
||||
qDebug()<<"Success.";
|
||||
}
|
||||
|
||||
void Projection::pushButtonClickSlots() {
|
||||
|
||||
QDBusInterface interface_2( "com.operate.wirelessscreen",
|
||||
"/",
|
||||
"com.operate.wirelessscreen",
|
||||
QDBusConnection::sessionBus() );
|
||||
|
||||
|
||||
QDBusReply<int> m_result = interface_2.call("operate_wireless_screen",1);
|
||||
|
||||
if (m_result.isValid()) {
|
||||
qDebug()<<"open res is"<<m_result<<endl;
|
||||
} else {
|
||||
qDebug()<<"open failed"<<endl;
|
||||
}
|
||||
|
||||
if(m_result==1)
|
||||
{
|
||||
projectionBtn->setCheckable(false);
|
||||
}
|
||||
}
|
||||
|
||||
void Projection::miracastsourceButtonClickSlots(bool status)
|
||||
{
|
||||
QString path=QDir::homePath()+"/.config/miracastsource.ini";
|
||||
QSettings *setting=new QSettings(path,QSettings::IniFormat);
|
||||
setting->beginGroup("projection");
|
||||
|
||||
if (status)
|
||||
{
|
||||
ui->pushButton->setEnabled(true);
|
||||
QString styleSheetDark = QString ("background:rgba(44,50,57,%1);color:white;");
|
||||
QString styleSheetLight = QString ("background:rgba(255,255,255,%1);color:rgba(58,67,78,0.25);");
|
||||
QGSettings gsetting(QString("org.ukui.style").toLocal8Bit());
|
||||
if (gsetting.get("style-name").toString() != "ukui-light"){
|
||||
ui->pushButton->setStyleSheet(styleSheetLight);
|
||||
}
|
||||
else{
|
||||
ui->pushButton->setStyleSheet(styleSheetDark);
|
||||
}
|
||||
projectionBtn->setCheckable(false);
|
||||
setting->setValue("miracastsource","true");
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->pushButton->setEnabled(false);
|
||||
ui->pushButton->setStyleSheet("color: gray");
|
||||
projectionBtn->setCheckable(true);
|
||||
setting->setValue("miracastsource","false");
|
||||
|
||||
QDBusInterface interface_2( "com.operate.wirelessscreen",
|
||||
"/",
|
||||
"com.operate.wirelessscreen",
|
||||
QDBusConnection::sessionBus() );
|
||||
|
||||
interface_2.call("operate_wireless_screen",0);
|
||||
}
|
||||
setting->sync();
|
||||
setting->endGroup();
|
||||
}
|
||||
|
||||
int Projection::pinCodeStatus(int key)
|
||||
{
|
||||
if (key == 0){
|
||||
config_status = false;
|
||||
return 2;
|
||||
}
|
||||
else if (key == 1){
|
||||
config_status = true;
|
||||
return 2;
|
||||
}
|
||||
else{
|
||||
if (config_status)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Projection::initComponent(){
|
||||
|
||||
addWgt = new HoverWidget("");
|
||||
addWgt->setObjectName("addwgt");
|
||||
addWgt->setMinimumSize(QSize(580, 64));
|
||||
addWgt->setMaximumSize(QSize(16777215, 64));
|
||||
addWgt->setStyleSheet("HoverWidget#addwgt{background: palette(base); border-radius: 4px;}HoverWidget:hover:!pressed#addwgt{background: #2FB3E8; border-radius: 4px;}");
|
||||
|
||||
QHBoxLayout *addLyt = new QHBoxLayout;
|
||||
|
||||
QLabel * iconLabel = new QLabel();
|
||||
QLabel * textLabel = new QLabel(tr("Add Bluetooths"));
|
||||
QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12);
|
||||
iconLabel->setPixmap(pixgray);
|
||||
addLyt->addItem(new QSpacerItem(8,10,QSizePolicy::Fixed));
|
||||
addLyt->addWidget(iconLabel);
|
||||
addLyt->addItem(new QSpacerItem(16,10,QSizePolicy::Fixed));
|
||||
addLyt->addWidget(textLabel);
|
||||
addLyt->addStretch();
|
||||
addWgt->setLayout(addLyt);
|
||||
addWgt->hide();
|
||||
}
|
||||
|
||||
QString Projection::translationPath() const
|
||||
{
|
||||
return "/usr/share/projection/translations/%1.ts";
|
||||
}
|
||||
|
||||
void Projection::initSearchText()
|
||||
{
|
||||
//~ contents_path /projection/Open projection
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
#ifndef PROJECTION_H
|
||||
#define PROJECTION_H
|
||||
|
||||
|
||||
#include <QObject>
|
||||
#include <QtPlugin>
|
||||
#include <QTimer>
|
||||
#include <QtDBus>
|
||||
#include <QGSettings/QGSettings>
|
||||
#include <QLabel>
|
||||
#include <QRegExpValidator>
|
||||
#include <ukcc/widgets/hoverwidget.h>
|
||||
#include <ukcc/widgets/imageutil.h>
|
||||
#include <ukcc/widgets/switchbutton.h>
|
||||
#include "changeprojectionname.h"
|
||||
//#include <ukcc/widgets/hoverbtn.h>
|
||||
#include "kswitchbutton.h"
|
||||
using namespace kdk;
|
||||
|
||||
#include <ukcc/interface/interface.h>
|
||||
#include "../component/DrownLabel/drownlabel.h"
|
||||
|
||||
namespace Ui {
|
||||
class Projection;
|
||||
}
|
||||
|
||||
class Projection : public QObject, CommonInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID "org.ukcc.CommonInterface")
|
||||
Q_INTERFACES(CommonInterface)
|
||||
|
||||
public:
|
||||
Projection();
|
||||
~Projection();
|
||||
|
||||
QString plugini18nName() Q_DECL_OVERRIDE;
|
||||
int pluginTypes() Q_DECL_OVERRIDE;
|
||||
QWidget * pluginUi() Q_DECL_OVERRIDE;
|
||||
const QString name() const Q_DECL_OVERRIDE;
|
||||
bool isShowOnHomePage() const Q_DECL_OVERRIDE;
|
||||
QIcon icon() const Q_DECL_OVERRIDE;
|
||||
bool isEnable() const Q_DECL_OVERRIDE;
|
||||
QString translationPath() const Q_DECL_OVERRIDE;
|
||||
|
||||
bool getWifiStatus();
|
||||
void setWifiStatus(bool status);
|
||||
void debusFileConfig();
|
||||
void deleteAllitemsOfLayout(QLayout* layout);
|
||||
|
||||
public:
|
||||
void initComponent();
|
||||
void showChangeProjectionNameDialog();
|
||||
void changeProjectionName(QString name);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
private:
|
||||
Ui::Projection *ui;
|
||||
QString pluginName;
|
||||
int pluginType;
|
||||
QWidget * pluginWidget;
|
||||
HoverWidget * addWgt;
|
||||
KSwitchButton *projectionBtn;
|
||||
KSwitchButton *pincodeBtn;
|
||||
KSwitchButton *miracastBtn;
|
||||
DrownLabel *dropDownLabel = nullptr;
|
||||
QLabel *m_pin;
|
||||
bool enter = false;
|
||||
QString hostName;
|
||||
QMap<QString,QString>deviceName;
|
||||
|
||||
|
||||
private:
|
||||
QTimer * pTimer;
|
||||
QDBusInterface *m_pServiceInterface;
|
||||
bool m_bbluetoothStatus;
|
||||
QGSettings * qtSettings;
|
||||
bool m_autoclose = false;
|
||||
void catchsignal();
|
||||
void delaymsec(int msec);
|
||||
int get_process_status(void);
|
||||
int get_process_source_status(void);
|
||||
int get_pin_button_status(void);
|
||||
void init_button_status(int);
|
||||
void init_pin_button_status(int);
|
||||
void init_source_button_status(int);
|
||||
void initSearchText(); // 搜索翻译
|
||||
int pinCodeStatus(int);
|
||||
void setLabelText(QLabel *label,QString text);
|
||||
void getSystemFontFamily();
|
||||
bool key = true;
|
||||
bool config_status = false;
|
||||
|
||||
public slots:
|
||||
void projectionButtonClickSlots(bool status);
|
||||
void pincodeButtonClickSlots(bool status);
|
||||
void miracastsourceButtonClickSlots(bool status);
|
||||
void pushButtonClickSlots();
|
||||
void onDrownLabelClicked();
|
||||
void projectionPinSlots(QString type,QString pin);
|
||||
void netPropertiesChangeSlot(QMap<QString, QVariant> property);
|
||||
|
||||
Q_SIGNALS:
|
||||
void resize();
|
||||
};
|
||||
|
||||
#endif // PROJECTION_H
|
|
@ -0,0 +1,62 @@
|
|||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2019-02-28T14:09:42
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += widgets
|
||||
QT += core gui widgets dbus
|
||||
|
||||
TEMPLATE = lib
|
||||
CONFIG += plugin
|
||||
CONFIG += link_pkgconfig
|
||||
PKGCONFIG += gsettings-qt \
|
||||
kysdk-qtwidgets
|
||||
include(../component/drownlabel.pri)
|
||||
|
||||
LIBS += -lukcc
|
||||
|
||||
TARGET = $$qtLibraryTarget(projection)
|
||||
DESTDIR = ../..
|
||||
target.path = $$[QT_INSTALL_LIBS]/ukui-control-center
|
||||
|
||||
TRANSLATIONS += translations/zh_CN.ts \
|
||||
translations/en_US.ts
|
||||
|
||||
isEmpty(PREFIX) {
|
||||
PREFIX = /usr
|
||||
}
|
||||
|
||||
qm_files.path = $${PREFIX}/share/projection/translations
|
||||
qm_files.files = translations/*
|
||||
|
||||
CONFIG(release, debug|release) {
|
||||
!system($$PWD/translate_generation.sh): error("Failed to generate translation")
|
||||
}
|
||||
|
||||
INCLUDEPATH += \
|
||||
$$PROJECT_COMPONENTSOURCE \
|
||||
$$PROJECT_ROOTDIR \
|
||||
|
||||
INCLUDEPATH += /usr/lib/gcc/aarch64-linux-gnu/9/include/
|
||||
|
||||
|
||||
#DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
SOURCES += \
|
||||
projection.cpp \
|
||||
changeprojectionname.cpp
|
||||
|
||||
HEADERS += \
|
||||
projection.h \
|
||||
changeprojectionname.h
|
||||
|
||||
FORMS += \
|
||||
projection.ui \
|
||||
changeprojectionname.ui \
|
||||
|
||||
INSTALLS += target \
|
||||
qm_files \
|
||||
|
||||
RESOURCES += \
|
||||
pic.qrc
|
|
@ -0,0 +1,906 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Projection</class>
|
||||
<widget class="QWidget" name="Projection">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>820</width>
|
||||
<height>727</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Printer</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget_6" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_5">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Projection to the pc</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="tipLabel">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>(No wireless network card is detected or the network card driver does not support it.)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>394</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget_9" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>80</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>80</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<property name="spacing">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget_8" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="titleLabel">
|
||||
<property name="text">
|
||||
<string>Allow android phone or pc to be projected to the pc:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="projectionNameWidget" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="projectionName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="projectionNameChange">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>15</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>15</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Wireless LAN connection may be interrupted during projection.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>500</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(244, 244, 244);
|
||||
opacity:1;</string>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget_4" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>60</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>60</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_17">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="titleLabel_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>You need to match the PIN code when projecting the screen to the pc</string>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>535</width>
|
||||
<height>15</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(244, 244, 244);
|
||||
opacity:1;</string>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget_3" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>60</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>60</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="deviceLabel">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Historical equipment</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>663</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget_2" native="true">
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMaximumSize</enum>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget_7" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">border-right-color: rgb(85, 255, 127);</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_13">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_6">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_16">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Connect to wireless display</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="tipLabel2">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>(No wireless network card is detected or the network card driver does not support it.)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>394</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget_5" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>80</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>80</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame3">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<property name="spacing">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Open(PIN authentication is not supported temporarily.)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>When enabled,the project to this pc feature stops.</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Maximum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>380</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>136</width>
|
||||
<height>36</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>146</width>
|
||||
<height>36</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
|
@ -0,0 +1,15 @@
|
|||
#!/bin/bash
|
||||
|
||||
ts_list=(`ls translations/*.ts`)
|
||||
source /etc/os-release
|
||||
version=(`echo $ID`)
|
||||
|
||||
for ts in "${ts_list[@]}"
|
||||
do
|
||||
printf "\nprocess ${ts}\n"
|
||||
if [ "$version" == "fedora" ] || [ "$version" == "opensuse-leap" ] || [ "$version" == "opensuse-tumbleweed" ];then
|
||||
lrelease-qt5 "${ts}"
|
||||
else
|
||||
lrelease "${ts}"
|
||||
fi
|
||||
done
|
|
@ -0,0 +1,108 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="en_US">
|
||||
<context>
|
||||
<name>ChangeProjectionName</name>
|
||||
<message>
|
||||
<location filename="../changeprojectionname.ui" line="26"/>
|
||||
<source>Projection to this pc</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../changeprojectionname.ui" line="120"/>
|
||||
<source>Device Name</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../changeprojectionname.ui" line="225"/>
|
||||
<source>Cancel</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../changeprojectionname.ui" line="244"/>
|
||||
<source>Save</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../changeprojectionname.cpp" line="38"/>
|
||||
<source>The length must be 1-32 characters</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Projection</name>
|
||||
<message>
|
||||
<location filename="../projection.ui" line="101"/>
|
||||
<source>Projection to the pc</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.ui" line="117"/>
|
||||
<location filename="../projection.ui" line="719"/>
|
||||
<location filename="../projection.cpp" line="596"/>
|
||||
<location filename="../projection.cpp" line="597"/>
|
||||
<location filename="../projection.cpp" line="620"/>
|
||||
<location filename="../projection.cpp" line="621"/>
|
||||
<source>(No wireless network card is detected or the network card driver does not support it.)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.ui" line="241"/>
|
||||
<source>Allow android phone or pc to be projected to the pc:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.ui" line="326"/>
|
||||
<source>Wireless LAN connection may be interrupted during projection.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.ui" line="431"/>
|
||||
<source>You need to match the PIN code when projecting the screen to the pc</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.ui" line="531"/>
|
||||
<source>Historical equipment</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.ui" line="700"/>
|
||||
<source>Connect to wireless display</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.ui" line="822"/>
|
||||
<source>Open(PIN authentication is not supported temporarily.)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.ui" line="832"/>
|
||||
<source>When enabled,the project to this pc feature stops.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.cpp" line="52"/>
|
||||
<source>Projection</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.cpp" line="93"/>
|
||||
<source>Find device</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.cpp" line="659"/>
|
||||
<location filename="../projection.cpp" line="660"/>
|
||||
<location filename="../projection.cpp" line="694"/>
|
||||
<location filename="../projection.cpp" line="695"/>
|
||||
<source>(WLAN is not turned on. You need to turn on WLAN to use this function.)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.cpp" line="907"/>
|
||||
<source>Add Bluetooths</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
Binary file not shown.
|
@ -0,0 +1,363 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="zh_CN">
|
||||
<context>
|
||||
<name>ChangeProjectionName</name>
|
||||
<message>
|
||||
<source>Name is too long, change another one.</source>
|
||||
<translation type="vanished">名称过长,请更改</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Change Username</source>
|
||||
<translation type="vanished">修改用户名</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Change Name</source>
|
||||
<translation type="vanished">修改名称</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Projection to this computer</source>
|
||||
<translation type="vanished">投屏到此电脑</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../changeprojectionname.ui" line="26"/>
|
||||
<source>Projection to this pc</source>
|
||||
<translation>投屏到此电脑</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../changeprojectionname.ui" line="120"/>
|
||||
<source>Device Name</source>
|
||||
<translation>设备名</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Changename</source>
|
||||
<translation type="vanished">修改名称</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>ChangeProjectionname</source>
|
||||
<translation type="vanished">设备名称</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../changeprojectionname.ui" line="244"/>
|
||||
<source>Save</source>
|
||||
<translation>保存</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../changeprojectionname.ui" line="225"/>
|
||||
<source>Cancel</source>
|
||||
<translation>取消</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name is too long.</source>
|
||||
<translation type="vanished">名称过长</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The input character length exceeds the limit.</source>
|
||||
<translation type="vanished">输入字符长度超出限制</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../changeprojectionname.cpp" line="38"/>
|
||||
<source>The length must be 1-32 characters</source>
|
||||
<translation>长度必须为 1-32 个字符</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Projection</name>
|
||||
<message>
|
||||
<source>projection</source>
|
||||
<translation type="vanished">多屏协同</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Projection to this computer</source>
|
||||
<translation type="vanished">投屏到此电脑</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.cpp" line="52"/>
|
||||
<source>Projection</source>
|
||||
<translation>多屏协同</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.cpp" line="659"/>
|
||||
<location filename="../projection.cpp" line="660"/>
|
||||
<location filename="../projection.cpp" line="694"/>
|
||||
<location filename="../projection.cpp" line="695"/>
|
||||
<source>(WLAN is not turned on. You need to turn on WLAN to use this function.)</source>
|
||||
<translation>(WLAN未开启,使用此功能需开启WLAN。)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(No wireless network card is detected or the network card driver does not support it.).</source>
|
||||
<translation type="vanished">未检测到无线网卡或网卡驱动不可使用</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Allow Android phones or computers to be projected to this computer</source>
|
||||
<translation type="vanished">允许Andriod手机或电脑投屏到此电脑</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Projection to the computer</source>
|
||||
<translation type="vanished">投屏到此电脑</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Allow android phone or pc to be projected to the pc.</source>
|
||||
<translation type="vanished">允许安卓手机或电脑投屏到此电脑</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Wireless LAN transmission may be interrupted during projection</source>
|
||||
<translation type="vanished">投屏过程中可能会中断无线局域网络传输。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>You need to match the PIN code when projecting the screen to this computer</source>
|
||||
<translation type="vanished">投屏到这台电脑时需要匹配PIN码</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.ui" line="117"/>
|
||||
<location filename="../projection.ui" line="719"/>
|
||||
<location filename="../projection.cpp" line="596"/>
|
||||
<location filename="../projection.cpp" line="597"/>
|
||||
<location filename="../projection.cpp" line="620"/>
|
||||
<location filename="../projection.cpp" line="621"/>
|
||||
<source>(No wireless network card is detected or the network card driver does not support it.)</source>
|
||||
<translation>(未检测到无线网卡或网卡驱动不可用。)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PIN code authentication projection is not supported temporarily.</source>
|
||||
<translation type="vanished">暂不支持PIN码认证投射。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>You need to match the pin code when projecting the screen to this computer</source>
|
||||
<translation type="vanished">投屏到这台电脑时需要匹配pin码</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.ui" line="101"/>
|
||||
<source>Projection to the pc</source>
|
||||
<translation>投屏到此电脑</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Allow android phone or pc to be projected to the pc</source>
|
||||
<translation type="vanished">允许Android手机或电脑投屏到此电脑</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.ui" line="241"/>
|
||||
<source>Allow android phone or pc to be projected to the pc:</source>
|
||||
<translation>允许Andriod手机或电脑投屏到此电脑:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Wireless LAN transmission may be interrupted during projection.</source>
|
||||
<translation type="vanished">投屏过程中可能会中断无线局域网络连接。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.ui" line="326"/>
|
||||
<source>Wireless LAN connection may be interrupted during projection.</source>
|
||||
<translation>投屏过程中可能会中断无线局域网络连接。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.ui" line="431"/>
|
||||
<source>You need to match the PIN code when projecting the screen to the pc</source>
|
||||
<translation>投屏到这台电脑时需要匹配PIN码</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.ui" line="531"/>
|
||||
<source>Historical equipment</source>
|
||||
<translation>历史设备</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.ui" line="700"/>
|
||||
<source>Connect to wireless display</source>
|
||||
<translation>连接到无线显示器</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Open(PIN authentication and receiving end of SP1 version is not supported.)</source>
|
||||
<translation type="vanished">开启(此功能暂不支持PIN码认证和投射到SP1版本的接收端。)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Open(PIN authentication and receiving end of SP1 version is not supported temporarily.)</source>
|
||||
<translation type="vanished">开启(此功能暂不支持PIN码认证和投射到SP1版本的接收端。)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.ui" line="822"/>
|
||||
<source>Open(PIN authentication is not supported temporarily.)</source>
|
||||
<translation>开启(此功能暂不支持PIN码认证。)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.ui" line="832"/>
|
||||
<source>When enabled,the project to this pc feature stops.</source>
|
||||
<translation>启用后会停止“投屏到此电脑”。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Open(The function doesn't support pin code authentication temporarily.)</source>
|
||||
<translation type="vanished">开启(此功能暂不支持PIN码认证。)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Open(This function does not support PIN code authentication temporarily.)</source>
|
||||
<translation type="vanished">开启(此功能暂不支持PIN码认证。)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Open</source>
|
||||
<translation type="vanished">开启</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>When enabled, the project to this PC feature stops.PIN code authentication projection is not supported temporarily.</source>
|
||||
<translation type="vanished">启用后会停止“投影到此电脑”,暂不支持PIN码认证</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>When enabled, the project to this PC feature stops.</source>
|
||||
<translation type="vanished">启用后会停止“投屏到此电脑”功能。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>refreshBtn</source>
|
||||
<translation type="vanished">刷新</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Open projection</source>
|
||||
<translation type="vanished">开启多屏协同</translation>
|
||||
<extra-contents_path>/projection/Open projection</extra-contents_path>
|
||||
</message>
|
||||
<message>
|
||||
<source>Disable Pin Code</source>
|
||||
<translation type="vanished">禁用Pin码</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>refresh</source>
|
||||
<translation type="vanished">刷新</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete</source>
|
||||
<translation type="vanished">删除</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Failed to remove device</source>
|
||||
<translation type="vanished">删除设备失败</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Device deleted successfully</source>
|
||||
<translation type="vanished">删除设备成功</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Multi screen collaboration</source>
|
||||
<translation type="vanished">多屏协同</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.cpp" line="93"/>
|
||||
<source>Find device</source>
|
||||
<translation>查找设备</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please click refresh and try again</source>
|
||||
<translation type="vanished">请点击刷新后重新尝试</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>warning</source>
|
||||
<translation type="vanished">警告</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Yes</source>
|
||||
<translation type="vanished">确定</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please restart the screen projection button</source>
|
||||
<translation type="vanished">请重启投屏开关</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>tips</source>
|
||||
<translation type="vanished">提示</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please restart the screen projection switch button</source>
|
||||
<translation type="vanished">请重启投屏开关</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Receive terminal is </source>
|
||||
<translation type="vanished">接收端已</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Service exception,please restart the system</source>
|
||||
<translation type="vanished">服务异常,请重启系统</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>After deleting the device, you need to restart the projection to take effect</source>
|
||||
<translation type="vanished">删除设备后需要重启投屏才能生效</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please keep WLAN on;
|
||||
Wireless-network functions will be invalid when the screen projection on</source>
|
||||
<translation type="vanished">使用时请保持WLAN处于开启状态;开启投屏后,无线网络相关功能会失效</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please keep WLAN on;
|
||||
Wireless will be temporarily disconnected when the screen projection on</source>
|
||||
<translation type="vanished">使用时请保持WLAN处于开启状态;开启投屏会短暂中断无线连接</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>After opening the switch button,open the projection screen in the mobile phone drop-down menu,follow the prompts.See the user manual for details</source>
|
||||
<translation type="vanished">开启投屏后,在手机下拉菜单中打开投屏,根据提示操作。详见用户手册</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>List of connected devices</source>
|
||||
<translation type="vanished">已连接设备列表</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>It is recommended to restart the screen after deleting the device</source>
|
||||
<translation type="vanished">删除设备后需要重启投屏才能生效</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>WLAN is off, please turn on WLAN</source>
|
||||
<translation type="vanished">WLAN未开启,请打开WLAN开关</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Wireless network card is busy. Please try again later</source>
|
||||
<translation type="vanished">无线网卡繁忙,请稍后再试</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Projection is </source>
|
||||
<translation type="vanished">投屏功能已</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>on</source>
|
||||
<translation type="vanished">开启</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>off</source>
|
||||
<translation type="vanished">关闭</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The projection function is </source>
|
||||
<translation type="vanished">投屏功能已</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>tuen on</source>
|
||||
<translation type="vanished">打开</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>turn off</source>
|
||||
<translation type="vanished">关闭</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>turn on</source>
|
||||
<translation type="obsolete">打开</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Please enable or refresh the scan at the projection device</source>
|
||||
<translation type="vanished">请在投屏设备端开启或刷新扫描</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>You need to turn on the projection again</source>
|
||||
<translation type="vanished">需要投屏请再重新开启</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>You need to turn on the screen again</source>
|
||||
<translation type="vanished">需要投屏请再重新开启</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Failed to execute. Please reopen the page later</source>
|
||||
<translation type="vanished">执行失败,请再次打开该页面查看</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Projection Name</source>
|
||||
<translation type="vanished">投屏端名称</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../projection.cpp" line="907"/>
|
||||
<source>Add Bluetooths</source>
|
||||
<translation>添加蓝牙</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
|
@ -0,0 +1,48 @@
|
|||
execute_process(
|
||||
COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=system_bus_services_dir dbus-1
|
||||
OUTPUT_VARIABLE DBUS_SYSTEM_SERVICES_DIR
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
execute_process(
|
||||
COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=systemdsystemunitdir systemd
|
||||
OUTPUT_VARIABLE SYSTEMD_SYSTEM_UNIT_DIR
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
configure_file(
|
||||
miracle-wifid.service.cmake
|
||||
miracle-wifid.service
|
||||
)
|
||||
install(
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/miracle-wifid.service
|
||||
DESTINATION ${SYSTEMD_SYSTEM_UNIT_DIR}/
|
||||
)
|
||||
|
||||
install(
|
||||
CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${SYSTEMD_SYSTEM_UNIT_DIR}/miracle-wifid.service \$ENV{DESTDIR}${SYSTEMD_SYSTEM_UNIT_DIR}/dbus-org.freedesktop.miracle.wifi.service)"
|
||||
)
|
||||
|
||||
INSTALL(
|
||||
PROGRAMS uibc-viewer
|
||||
DESTINATION bin
|
||||
)
|
||||
|
||||
INSTALL(
|
||||
PROGRAMS checkhardware.sh checkDaemonRunning.sh checkFrontendRunning.sh execstart.sh recover_wpas.sh
|
||||
DESTINATION bin
|
||||
)
|
||||
|
||||
INSTALL(
|
||||
FILES org.freedesktop.miracle.conf
|
||||
DESTINATION ${SYSCONFDIR}/dbus-1/system.d
|
||||
)
|
||||
|
||||
INSTALL(
|
||||
FILES miracle-agent.desktop
|
||||
DESTINATION ${SYSCONFDIR}/xdg/autostart
|
||||
)
|
||||
|
||||
INSTALL(
|
||||
FILES miracle-wifid miracle-sinkctl miracle-wifictl
|
||||
DESTINATION ${DATADIR}/bash-completion/completions
|
||||
)
|
|
@ -0,0 +1,9 @@
|
|||
bin_SCRIPTS = miracle-gst gstplayer uibc-viewer miracle-omxplayer
|
||||
EXTRA_DIST = wpa.conf
|
||||
|
||||
dbuspolicydir=$(sysconfdir)/dbus-1/system.d
|
||||
dbuspolicy_DATA = org.freedesktop.miracle.conf
|
||||
|
||||
bashcompletiondir=${datadir}/bash-completion/completions
|
||||
bashcompletion_DATA=miracle-wifid miracle-sinkctl miracle-wifictl
|
||||
|
|
@ -0,0 +1,463 @@
|
|||
#!/usr/bin/python3 -u
|
||||
|
||||
|
||||
import gi
|
||||
import argparse
|
||||
import dbus
|
||||
import os
|
||||
|
||||
HOME_DIR = os.environ['HOME']
|
||||
if os.path.exists(HOME_DIR+'/.config/tpConfig.txt'):
|
||||
with open(HOME_DIR+'/.config/tpConfig.txt', 'r') as f:
|
||||
decodeFlag = f.read()
|
||||
else:
|
||||
decodeFlag = "kylin"
|
||||
|
||||
def setEnv():
|
||||
LIST_VGA = "lspci | grep VGA"
|
||||
output = os.popen(LIST_VGA).read()
|
||||
if "AMD" in output:
|
||||
os.putenv("LIBVA_DRIVER_NAME", "radeonsi")
|
||||
os.putenv("GST_VAAPI_ALL_DRIVERS", "1")
|
||||
elif "Intel" in output:
|
||||
os.putenv("LIBVA_DRIVER_NAME", "i965")
|
||||
else:
|
||||
# have no hardware, execute software decode
|
||||
decodeFlag = "kylin"
|
||||
|
||||
if decodeFlag == "hard":
|
||||
setEnv()
|
||||
|
||||
gi.require_version('Gst', '1.0')
|
||||
gi.require_version('Gtk', '3.0')
|
||||
gi.require_version('GstVideo', '1.0')
|
||||
gi.require_version('GdkX11', '3.0')
|
||||
|
||||
from gi.repository import GObject, Gst, Gtk, Gdk, GLib,GdkPixbuf
|
||||
|
||||
# Needed for window.get_xid(), xvimagesink.set_window_handle(), respectively:
|
||||
from gi.repository import GdkX11, GstVideo
|
||||
|
||||
# GObject.threads_init()
|
||||
Gst.init(None)
|
||||
|
||||
class Player(object):
|
||||
def __init__(self, **kwargs):
|
||||
|
||||
self.hidc = True
|
||||
|
||||
|
||||
self.cons_LeftBtnPressed = 0
|
||||
self.cons_NoBtnPressed = 1
|
||||
self.cons_KeyPressed = 2
|
||||
self.cons_KeyReleased = 3
|
||||
|
||||
self.cons_NullBtn = 0
|
||||
self.cons_LeftBtn = 1
|
||||
self.cons_MidBtn = 2
|
||||
self.cons_RightBtn = 4
|
||||
|
||||
self.hid_key_event = 0
|
||||
self.hid_mouse_event = 1
|
||||
|
||||
resolution = kwargs.get("resolution")
|
||||
if resolution:
|
||||
split = resolution.split("x")
|
||||
self.width = int(split[0])
|
||||
self.height = int(split[1])
|
||||
|
||||
scale = kwargs.get("scale")
|
||||
if scale:
|
||||
split = scale.split("x")
|
||||
self.width = int(split[0])
|
||||
self.height = int(split[1])
|
||||
|
||||
self.uibc_enabled = 0
|
||||
uibc_enabled = kwargs.get("uibc")
|
||||
if uibc_enabled:
|
||||
self.uibc_enabled = 1
|
||||
|
||||
debug = kwargs.get("debug")
|
||||
if debug:
|
||||
Gst.debug_set_active(True)
|
||||
Gst.debug_set_threshold_from_string(debug, True)
|
||||
|
||||
port = kwargs.get("port")
|
||||
|
||||
uri = kwargs.get("uri")
|
||||
|
||||
self.window = Gtk.Window()
|
||||
self.window.set_name('MiracastPlayer')
|
||||
self.window.set_title('MiracastPlayer')
|
||||
# self.window.connect('realize', self.realize_cbk)
|
||||
self.window.connect('destroy', self.quit)
|
||||
self.window.connect('delete_event', self.confirm)
|
||||
# self.window.connect('button-press-event', self.on_double_clicked)
|
||||
self.window.connect('button-press-event', self.on_mouse_pressed)
|
||||
self.window.connect('button-release-event', self.on_mouse_pressed)
|
||||
self.window.connect('motion-notify-event', self.on_mouse_moved)
|
||||
self.window.connect('key-press-event', self.on_key_pressed)
|
||||
self.window.connect('key-release-event', self.on_key_pressed)
|
||||
self.window.connect('scroll-event', self.on_scroll)
|
||||
|
||||
if os.path.exists('/usr/share/icons/ukui-icon-theme-fashion/128x128/apps/kylin-miracast.png'):
|
||||
img = GdkPixbuf.Pixbuf.new_from_file('/usr/share/icons/ukui-icon-theme-fashion/128x128/apps/kylin-miracast.png')
|
||||
self.window.set_icon(img)
|
||||
|
||||
# if hasattr(self,'width') and hasattr(self,'height'):
|
||||
self.window.set_default_size(self.width, self.height)
|
||||
|
||||
self.window.fullscreen()
|
||||
self.isFullScreen = True
|
||||
self.drawingarea = Gtk.DrawingArea()
|
||||
self.window.add(self.drawingarea)
|
||||
|
||||
_dbus = dbus.SessionBus()
|
||||
proxy = _dbus.get_object('org.gnome.SessionManager', '/org/gnome/SessionManager')
|
||||
# self.SessionManagerIface = dbus.Interface(proxy, 'org.gnome.SessionManager')
|
||||
self.Inhibit = proxy.get_dbus_method('Inhibit', 'org.gnome.SessionManager')
|
||||
self.Uninhibit = proxy.get_dbus_method('Uninhibit', 'org.gnome.SessionManager')
|
||||
self.sessmngCookie = 0
|
||||
|
||||
# if hasattr(self,'width') and hasattr(self,'height'):
|
||||
self.drawingarea.set_size_request(self.width,self.height)
|
||||
half_area_width = self.drawingarea.get_allocation().width / 2
|
||||
half_area_height = self.drawingarea.get_allocation().height / 2
|
||||
half_def_width = self.width / 2
|
||||
half_def_height = self.height / 2
|
||||
self.min_hor_pos = half_area_width - half_def_width
|
||||
self.max_hor_pos = half_area_width + half_def_width
|
||||
self.min_ver_pos = half_area_height - half_def_height
|
||||
self.max_ver_pos = half_area_height + half_def_height
|
||||
|
||||
self.drawingarea.add_events(Gdk.EventMask.BUTTON_PRESS_MASK|Gdk.EventMask.BUTTON_RELEASE_MASK)
|
||||
self.drawingarea.add_events(Gdk.EventMask.POINTER_MOTION_MASK)
|
||||
self.drawingarea.add_events(Gdk.EventMask.BUTTON1_MOTION_MASK)
|
||||
self.drawingarea.add_events(Gdk.EventMask.KEY_PRESS_MASK)
|
||||
self.drawingarea.add_events(Gdk.EventMask.SCROLL_MASK)
|
||||
|
||||
audio = kwargs.get("audio")
|
||||
|
||||
self.playbin = None
|
||||
|
||||
self.uibc_x = -1
|
||||
self.uibc_y = -1
|
||||
|
||||
#Create GStreamer pipeline
|
||||
if uri is not None:
|
||||
self.pipeline = Gst.Pipeline()
|
||||
|
||||
# Create GStreamer elements
|
||||
self.playbin = Gst.ElementFactory.make('playbin', "source")
|
||||
|
||||
if not uri.startswith("http://") or not uri.startswith("http://") or not uri.startswith("file://"):
|
||||
if not uri.startswith("/"):
|
||||
|
||||
uri = os.path.abspath(uri)
|
||||
uri = "file://"+uri
|
||||
|
||||
# Set properties
|
||||
self.playbin.set_property('uri', uri)
|
||||
|
||||
# Add playbin to the pipeline
|
||||
self.pipeline.add(self.playbin)
|
||||
else:
|
||||
gstcommand = "udpsrc port="+str(port)+" caps=\"application/x-rtp, media=video\" ! rtpjitterbuffer latency=20 ! rtpmp2tdepay ! tsdemux "
|
||||
|
||||
if audio:
|
||||
gstcommand += "name=demuxer demuxer. "
|
||||
|
||||
gstcommand += "! queue name=video_ch max-size-buffers=0 max-size-time=0 ! h264parse ! queue name=dec0 max-size-buffers=0 max-size-time=0 "
|
||||
|
||||
if "hard"==decodeFlag:
|
||||
gstcommand += "! vaapih264dec "
|
||||
else:
|
||||
gstcommand += "! avdec_h264 max-threads=0 skip-frame=1 output-corrupt=false "
|
||||
|
||||
gstcommand += "! videoconvert n-threads=0 !"
|
||||
|
||||
if scale:
|
||||
gstcommand += "videoscale method=1 ! video/x-raw,width="+str(self.width)+",height="+str(self.height)+" ! "
|
||||
|
||||
gstcommand += " autovideosink force-aspect-ratio=false sync=false async=false "
|
||||
|
||||
if audio:
|
||||
gstcommand += "demuxer. ! queue max-size-buffers=0 max-size-time=0 ! aacparse ! avdec_aac ! audioconvert ! audioresample ! autoaudiosink sync=false "
|
||||
|
||||
self.pipeline = Gst.parse_launch(gstcommand)
|
||||
|
||||
|
||||
# Create bus to get events from GStreamer pipeline
|
||||
self.bus = self.pipeline.get_bus()
|
||||
self.bus.add_signal_watch()
|
||||
self.bus.connect('message::eos', self.on_eos)
|
||||
self.bus.connect('message::error', self.on_error)
|
||||
|
||||
# This is needed to make the video output in our DrawingArea:
|
||||
self.bus.enable_sync_message_emission()
|
||||
self.bus.connect('sync-message::element', self.on_sync_message)
|
||||
self.bus.connect('message', self.on_message)
|
||||
|
||||
self.success = False
|
||||
|
||||
def start_cursor_timer(self):
|
||||
if(self.timer_tag == -1):
|
||||
self.timer_tag = GLib.timeout_add(3000, self.on_cursor_timer_out)
|
||||
|
||||
|
||||
def stop_cursor_timer(self):
|
||||
if(-1 != self.timer_tag):
|
||||
GLib.source_remove(self.timer_tag)
|
||||
self.timer_tag = -1
|
||||
|
||||
def on_cursor_timer_out(self):
|
||||
# print("HANDLE TIMER .....")
|
||||
self.hide_cursor(self.window)
|
||||
|
||||
def hide_cursor(self, window):
|
||||
if(self.cursor_hidden is False):
|
||||
cursor = Gdk.Cursor(Gdk.CursorType.BLANK_CURSOR)
|
||||
window.get_window().set_cursor(cursor)
|
||||
self.cursor_hidden = True
|
||||
|
||||
self.stop_cursor_timer()
|
||||
# print("hide cursor ............")
|
||||
|
||||
def show_cursor(self, widget):
|
||||
if(self.cursor_hidden is True):
|
||||
cursor = Gdk.Cursor(Gdk.CursorType.ARROW)
|
||||
widget.get_window().set_cursor(cursor)
|
||||
self.cursor_hidden = False
|
||||
|
||||
self.stop_cursor_timer()
|
||||
self.start_cursor_timer()
|
||||
# print("show cursor ............")
|
||||
|
||||
def calc_delta(self, oldval, newval):
|
||||
temp = newval - oldval
|
||||
if(temp > 127):
|
||||
temp = 127
|
||||
elif(temp < -127):
|
||||
temp = -127
|
||||
|
||||
if(temp < 0):
|
||||
temp += 2**8
|
||||
|
||||
return temp
|
||||
|
||||
def on_mouse_moved(self, widget, event):
|
||||
self.show_cursor(widget)
|
||||
|
||||
if(self.hidc is True):
|
||||
#mouse drag event
|
||||
if event.state & Gdk.ModifierType.BUTTON1_MASK:
|
||||
type = self.cons_LeftBtnPressed
|
||||
button = self.cons_LeftBtn #mouse left button
|
||||
else:
|
||||
type = self.cons_NoBtnPressed
|
||||
button = self.cons_NullBtn
|
||||
|
||||
uibc_x = int(event.x - self.min_hor_pos)
|
||||
uibc_y = int(event.y - self.min_ver_pos)
|
||||
delta_x = 0
|
||||
delta_y = 0
|
||||
|
||||
if(self.uibc_x >= 0 and self.uibc_y >= 0):
|
||||
delta_x = self.calc_delta(self.uibc_x, uibc_x)
|
||||
delta_y = self.calc_delta(self.uibc_y, uibc_y)
|
||||
|
||||
self.uibc_x = uibc_x
|
||||
self.uibc_y = uibc_y
|
||||
|
||||
print('{0},{1},{2},{3},{4}'.format(self.hid_mouse_event, type, button, delta_x, delta_y))
|
||||
|
||||
def on_mouse_pressed(self, widget, event):
|
||||
#double-click means quit fullscreen mode
|
||||
if event.type == Gdk.EventType._2BUTTON_PRESS:
|
||||
self.handle_double_clicked(widget, event)
|
||||
return
|
||||
|
||||
if(self.hidc is True):
|
||||
if event.type == Gdk.EventType.BUTTON_PRESS:
|
||||
type = self.cons_LeftBtnPressed
|
||||
else:
|
||||
type = self.cons_NoBtnPressed
|
||||
|
||||
if event.button == 1:
|
||||
button = self.cons_LeftBtn
|
||||
elif event.button == 2:
|
||||
button = self.cons_MidBtn
|
||||
if event.button == 3:
|
||||
button = self.cons_RightBtn
|
||||
|
||||
# uibc_x = int(event.x - self.min_hor_pos)
|
||||
# uibc_y = int(event.y - self.min_ver_pos)
|
||||
# delta_x = 0
|
||||
# delta_y = 0
|
||||
# if(self.uibc_x >= 0 and self.uibc_y >= 0):
|
||||
# delta_x = self.calc_delta(self.uibc_x, uibc_x)
|
||||
# delta_y = self.calc_delta(self.uibc_y, uibc_y)
|
||||
|
||||
# self.uibc_x = uibc_x
|
||||
# self.uibc_y = uibc_y
|
||||
|
||||
# print('1,{0},{1},{2},{3}'.format(type, button, delta_x, delta_y))
|
||||
print('{0},{1},{2},0,0'.format(self.hid_mouse_event, type, button))
|
||||
else:
|
||||
#<type>,<count>,<id>,<x>,<y>
|
||||
if event.type == Gdk.EventType.BUTTON_PRESS:
|
||||
type = 0
|
||||
else:
|
||||
type = 1
|
||||
|
||||
width = self.drawingarea.get_allocation().width
|
||||
height = self.drawingarea.get_allocation().height
|
||||
half_area_width = width / 2
|
||||
half_area_height = height / 2
|
||||
|
||||
half_def_width = self.width / 2
|
||||
half_def_height = self.height / 2
|
||||
|
||||
min_hor_pos = half_area_width - half_def_width
|
||||
max_hor_pos = half_area_width + half_def_width
|
||||
min_ver_pos = half_area_height - half_def_height
|
||||
max_ver_pos = half_area_height + half_def_height
|
||||
|
||||
pos_event_x = event.x
|
||||
pos_event_y = event.y
|
||||
|
||||
if self.min_hor_pos <= pos_event_x <= self.max_hor_pos and self.min_ver_pos <= pos_event_y <= self.max_ver_pos:
|
||||
uibc_x = int(pos_event_x - self.min_hor_pos)
|
||||
uibc_y = int(pos_event_y - self.min_ver_pos)
|
||||
print('{0},1,0,{1},{2}'.format(type, uibc_x , uibc_y))
|
||||
|
||||
def on_scroll(self, widget, event):
|
||||
if(self.hidc is True):
|
||||
#<mouse_type, press/release, button, x, y>
|
||||
if event.direction == Gdk.ScrollDirection.DOWN:
|
||||
scroll_step = -1
|
||||
elif event.direction == Gdk.ScrollDirection.UP:
|
||||
scroll_step = 1
|
||||
else:
|
||||
scroll_step = 0
|
||||
|
||||
if scroll_step != 0:
|
||||
print('1,1,4,0,0,{0}'.format(scroll_step))
|
||||
|
||||
|
||||
def on_key_pressed(self, widget, event):
|
||||
if(self.uibc_enabled):
|
||||
if(self.hidc is True):
|
||||
if event.type == Gdk.EventType.KEY_PRESS:
|
||||
print ("{0},{1},0x{2:04x}" .format(self.hid_key_event, self.cons_KeyPressed, event.keyval))
|
||||
elif event.type == Gdk.EventType.KEY_RELEASE:
|
||||
print ("{0},{1},0x{2:04x}" .format(self.hid_key_event, self.cons_KeyReleased, event.keyval))
|
||||
#<key_type, pressed/released, button>
|
||||
else:
|
||||
print("3,0x%04X,0x0000" % event.keyval)
|
||||
|
||||
if event.type == Gdk.EventType.KEY_PRESS:
|
||||
self.show_cursor(widget)
|
||||
|
||||
|
||||
def handle_double_clicked(self, widget, event):
|
||||
self.show_cursor(widget)
|
||||
if event.button == 1 and event.type == Gdk.EventType._2BUTTON_PRESS:
|
||||
if True == self.isFullScreen:
|
||||
self.window.unfullscreen()
|
||||
self.isFullScreen = False
|
||||
# self.SessionManagerIface.Uninhibit(self.sessmngCookie)
|
||||
self.Uninhibit(self.sessmngCookie)
|
||||
self.sessmngCookie = 0
|
||||
else:
|
||||
self.window.fullscreen()
|
||||
self.isFullScreen = True
|
||||
# self.sessmngCookie = self.SessionManagerIface.Inhibit("castplayer", 0, "full screen", 8)
|
||||
self.sessmngCookie = self.Inhibit("castplayer", 0, "full screen", 8)
|
||||
|
||||
def on_message(self, bus, message):
|
||||
if self.playbin:
|
||||
videoPad = self.playbin.emit("get-video-pad", 0)
|
||||
if videoPad and not self.success:
|
||||
videoPadCapabilities = videoPad.get_current_caps()
|
||||
if videoPadCapabilities:
|
||||
(self.success, self.videoWidth) = \
|
||||
videoPadCapabilities.get_structure(0).get_int("width")
|
||||
(self.success, self.videoHeight) = \
|
||||
videoPadCapabilities.get_structure(0).get_int("height")
|
||||
if self.success:
|
||||
print("{0} {1}".format(self.videoWidth, self.videoHeight))
|
||||
self.drawingarea.set_size_request(self.videoWidth, self.videoHeight)
|
||||
|
||||
def run(self):
|
||||
self.window.show_all()
|
||||
# You need to get the XID after window.show_all(). You shouldn't get it
|
||||
# in the on_sync_message() handler because threading issues will cause
|
||||
# segfaults there.
|
||||
window = self.drawingarea.get_property('window')
|
||||
if hasattr(window,'get_xid'):
|
||||
self.xid = self.drawingarea.get_property('window').get_xid()
|
||||
|
||||
self.pipeline.set_state(Gst.State.PLAYING)
|
||||
# self.sessmngCookie = self.SessionManagerIface.Inhibit("castplayer", 0, "full screen", 8)
|
||||
# self.sessmngCookie = self.Inhibit("castplayer", 0, "full screen", 8)
|
||||
# self.Uninhibit(0)
|
||||
self.cursor_hidden = False
|
||||
self.timer_tag = -1
|
||||
self.hide_cursor(self.window)
|
||||
Gtk.main()
|
||||
|
||||
def confirm(self, window, event=None):
|
||||
dialog = Gtk.MessageDialog(window, 0, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, "选择\"是\"将关闭窗口,连接会断开!\n选择\"否\"取消当前操作")
|
||||
resp = dialog.run()
|
||||
ret = False
|
||||
if resp == Gtk.ResponseType.NO:
|
||||
ret = True
|
||||
dialog.destroy()
|
||||
return ret
|
||||
|
||||
def quit(self, window):
|
||||
# self.Uninhibit(self.sessmngCookie)
|
||||
# self.sessmngCookie = 0
|
||||
self.pipeline.set_state(Gst.State.NULL)
|
||||
Gtk.main_quit()
|
||||
|
||||
def on_sync_message(self, bus, msg):
|
||||
if msg.get_structure().get_name() == 'prepare-window-handle':
|
||||
print(self.drawingarea.get_allocation())
|
||||
if hasattr(self,'xid'):
|
||||
msg.src.set_window_handle(self.xid)
|
||||
|
||||
def on_eos(self, bus, msg):
|
||||
print('on_eos(): seeking to start of video')
|
||||
self.pipeline.seek_simple(
|
||||
Gst.Format.TIME,
|
||||
Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT,
|
||||
0
|
||||
)
|
||||
def on_error(self, bus, msg):
|
||||
print('on_error():', msg.parse_error())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("uri", nargs="?", help="Uri to play")
|
||||
parser.add_argument("-v", "--version", help="Show package version")
|
||||
parser.add_argument("--log-level", metavar="lvl", help="Maximum level for log messages")
|
||||
parser.add_argument("-p", "--port", type=int, default=1991, help="Port for rtsp")
|
||||
parser.add_argument("-a", "--audio", dest="audio", action="store_true", help="Enable audio support")
|
||||
parser.add_argument("-s", "--scale", metavar="WxH", help="Scale to resolution")
|
||||
parser.add_argument("-d", "--debug", help="Debug")
|
||||
parser.add_argument("--uibc", type=int, help="Supported uibc-ctl:1 or 0")
|
||||
parser.add_argument("--res", metavar="n,n,n", help="Supported resolutions masks (CEA, VESA, HH)")
|
||||
# res
|
||||
# " default CEA %08X\n"
|
||||
# " default VESA %08X\n"
|
||||
# " default HH %08X\n"
|
||||
parser.add_argument("-r", "--resolution", help="Resolution")
|
||||
parser.set_defaults(audio=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
p = Player(**vars(args))
|
||||
p.run()
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/bash
|
||||
|
||||
#judge if daemon program is running
|
||||
AGT_PNUM=`ps -ef | grep 'miracle-agent' | grep -v grep | wc -l`
|
||||
SRV_PNUM=`ps -ef | grep 'miracle-wifid' | grep -v grep | wc -l`
|
||||
|
||||
if [ $AGT_PNUM -eq 0 ] || [ $SRV_PNUM -eq 0 ]
|
||||
then
|
||||
echo "miraclecast daemon not running"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
#judge if supplicant program is running
|
||||
PROG_PNUM=`ps -ef | grep 'wpa_supplicant -c' | grep -v grep | wc -l`
|
||||
|
||||
if [ $PROG_PNUM -gt 0 ]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/bash
|
||||
|
||||
#judge if frontend program is running
|
||||
PROG_PNUM=`ps -ef | grep 'miraclecast-frontend' | grep -v grep | wc -l`
|
||||
|
||||
if [ $PROG_PNUM -gt 0 ]
|
||||
then
|
||||
echo "miracast frontend is running"
|
||||
exit 1
|
||||
else
|
||||
echo "miracast frontend not running"
|
||||
fi
|
||||
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
#!/bin/bash
|
||||
|
||||
eval SCRIPT_DEBUG="\$$(basename $0 .sh | tr - _)_DEBUG"
|
||||
SCRIPT_DEBUG=${SCRIPT_DEBUG:--1}
|
||||
|
||||
if [ "$SCRIPT_DEBUG" -ge 1 ]
|
||||
then
|
||||
set -x
|
||||
fi
|
||||
if [ "$SCRIPT_DEBUG" -ge 10 ]
|
||||
then
|
||||
set -v
|
||||
fi
|
||||
|
||||
IFNAME=$1
|
||||
|
||||
##START of common funcs, moved to /home/$USR/.config/miracast latter
|
||||
LOOPBACK=772
|
||||
function find_choosable_networknames {
|
||||
for i in $( ls /sys/class/net )
|
||||
do
|
||||
if [ $( cat /sys/class/net/$i/type ) != $LOOPBACK ]
|
||||
then
|
||||
echo $i
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function find_wireless_network_interfaces {
|
||||
for i in $( find_choosable_networknames )
|
||||
do
|
||||
if [ -d /sys/class/net/$i/wireless ]
|
||||
then
|
||||
echo $i
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function find_physical_for_network_interface {
|
||||
PHY_INDEX=$(iw dev $1 info | grep wiphy | awk '{print $2}')
|
||||
if [ -n "$PHY_INDEX" ]
|
||||
then
|
||||
echo phy$PHY_INDEX
|
||||
fi
|
||||
}
|
||||
|
||||
function search_p2p_capabilities {
|
||||
WI_DEVICE=$1
|
||||
PHY_DEVICE=$(find_physical_for_network_interface $WI_DEVICE)
|
||||
SUCC=0
|
||||
FAIL=1
|
||||
|
||||
if [ -z "$PHY_DEVICE" ]
|
||||
then
|
||||
echo "cannot find physical device for $WI_DEVICE"
|
||||
return
|
||||
fi
|
||||
|
||||
if iw phy $PHY_DEVICE info | grep -Pzo "(?s)Supported interface modes.*Supported commands" | grep "P2P" &> /dev/null
|
||||
then
|
||||
echo $WI_DEVICE supports P2P
|
||||
else
|
||||
echo Sorry, $WI_DEVICE do not support P2P
|
||||
# exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function search_p2p_dev_capabilities {
|
||||
WI_DEVICE=$1
|
||||
PHY_DEVICE=$(find_physical_for_network_interface $WI_DEVICE)
|
||||
SUCC=0
|
||||
FAIL=1
|
||||
|
||||
if [ -z "$PHY_DEVICE" ]
|
||||
then
|
||||
echo "cannot find physical device for $WI_DEVICE"
|
||||
return
|
||||
fi
|
||||
|
||||
if iw phy $PHY_DEVICE info | grep -Pzo "(?s)Supported interface modes.*Supported commands" | grep "P2P-device" &> /dev/null
|
||||
then
|
||||
if udevadm info --query=all --path=/sys/class/net/$WI_DEVICE | grep "ID_NET_DRIVER" | grep -E "(8821ce|88x2ce)" &> /dev/null
|
||||
then
|
||||
echo Sorry, $WI_DEVICE do not support P2P-DEVICE
|
||||
else
|
||||
echo $WI_DEVICE supports P2P-DEVICE
|
||||
fi
|
||||
|
||||
else
|
||||
echo Sorry, $WI_DEVICE do not support P2P-DEVICE
|
||||
# exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function check_pci_wnic_vendor_support {
|
||||
WI_DEVICE=$1
|
||||
if udevadm info --query=all --path=/sys/class/net/$WI_DEVICE | grep "ID_NET_DRIVER" | grep -E "(8812au|8821cu)" &> /dev/null
|
||||
then
|
||||
echo "wireless card not ok"
|
||||
else
|
||||
echo "wireless card ok"
|
||||
fi
|
||||
}
|
||||
|
||||
##END of common funcs, moved to /home/$USR/.config/miracast latter
|
||||
|
||||
WIFI_COUNT=0
|
||||
WIFI_NAMES="$(find_wireless_network_interfaces)"
|
||||
if [ -n "$WIFI_NAMES" ]
|
||||
then
|
||||
WIFI_COUNT=$(echo "$WIFI_NAMES" | wc -l)
|
||||
fi
|
||||
|
||||
if [ 0 = $WIFI_COUNT ]
|
||||
then
|
||||
echo There is no wireless devices available
|
||||
exit 1
|
||||
elif [ 1 = $WIFI_COUNT ]
|
||||
then
|
||||
WIFI_NAME="$WIFI_NAMES"
|
||||
elif [ 2 -ge $WIFI_COUNT ]
|
||||
then
|
||||
echo Support Only one wireless card @v1.0
|
||||
fi
|
||||
|
||||
RTL8821CE=$(check_pci_wnic_vendor_support $IFNAME)
|
||||
echo $RTL8821CE
|
||||
TARGET="not"
|
||||
if [[ $RTL8821CE =~ $TARGET ]]
|
||||
then
|
||||
echo "RTL8821CE not support at present"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
RETSTR=$(search_p2p_capabilities $IFNAME)
|
||||
echo $RETSTR
|
||||
|
||||
if [[ $RETSTR =~ $TARGET ]]
|
||||
then
|
||||
echo "FAILURE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
P2PDEVSTR=$(search_p2p_dev_capabilities $IFNAME)
|
||||
echo $P2PDEVSTR
|
||||
|
||||
if [[ $P2PDEVSTR =~ $TARGET ]]
|
||||
then
|
||||
echo "network will be disabled while projection"
|
||||
exit 2
|
||||
else
|
||||
echo "p2p-device support, so wifi and widi at the same time"
|
||||
fi
|
||||
|
||||
AGENT_PNAME="miracle-agent"
|
||||
AGENT_PNUM=`ps -ef | grep $AGENT_PNAME | grep -v grep | wc -l`
|
||||
if [ $AGENT_PNUM -gt 0 ]
|
||||
then
|
||||
echo "SUCCESS"
|
||||
else
|
||||
echo "Agent not running!!! Quit..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,20 @@
|
|||
#!/bin/bash
|
||||
|
||||
hw_arch=$(uname -m)
|
||||
|
||||
echo $hw_arch|logger
|
||||
if [ $hw_arch = "loongarch64" ]
|
||||
then
|
||||
echo "gdb loongarch64"|logger
|
||||
gdb /usr/bin/miracle-wifid -batch -ex "set args --use-dev --log-level info --lazy-managed --config-methods display --wpa-loglevel trace" -ex "set logging file /home/execstart.gdb" -ex "set logging on" -ex "run" -ex "thread apply all backtrace" -ex "quit"
|
||||
echo "gdb loongarch64 success"|logger
|
||||
else
|
||||
echo "other arch"|logger
|
||||
/usr/bin/miracle-wifid \
|
||||
--use-dev \
|
||||
--log-level info \
|
||||
--lazy-managed \
|
||||
--config-methods display
|
||||
echo "other arch success"|logger
|
||||
fi
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/bin/bash
|
||||
|
||||
. miracle-utils.sh
|
||||
|
||||
kill_ubuntu_network_manager
|
||||
|
||||
WPA_PID=$(find_wpa_supplicant_pid)
|
||||
if [ -n "$WPA_PID" ]
|
||||
then
|
||||
echo killing existing wpa_supplicant connection
|
||||
sudo kill -9 $WPA_PID
|
||||
else
|
||||
echo cannot find wpa_supplicant connection to kill
|
||||
if [[ $_ == $0 ]]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,13 @@
|
|||
install_data(
|
||||
'org.freedesktop.miracle.conf',
|
||||
install_dir: join_paths(get_option('sysconfdir'), 'dbus-1', 'system.d')
|
||||
)
|
||||
|
||||
install_data('miracle-gst', 'gstplayer', 'uibc-viewer',
|
||||
install_dir: get_option('bindir'),
|
||||
install_mode: 'rwxr-xr-x')
|
||||
|
||||
install_data(
|
||||
'miracle-wifid', 'miracle-sinkctl', 'miracle-wifictl',
|
||||
install_dir: join_paths(get_option('datadir'), 'bash-completions', 'completions')
|
||||
)
|
|
@ -0,0 +1,13 @@
|
|||
[Desktop Entry]
|
||||
Name=miracle-agent-shell
|
||||
#comment=shell of miracleagent.service
|
||||
#Comment[zh_CN]=任务栏
|
||||
#Exec=systemctl --user enable miracle-agent.service && systemctl --user start miracle-agent.service
|
||||
Exec=/usr/bin/miracle-agent
|
||||
Terminal=false
|
||||
Type=Application
|
||||
#Icon=panel
|
||||
X-UKUI-AutoRestart=true
|
||||
#OnlyShowIn=UKUI
|
||||
NoDisplay=true
|
||||
#X-UKUI-Autostart-Phase=Panel
|
|
@ -0,0 +1,108 @@
|
|||
#!/bin/bash
|
||||
|
||||
function help {
|
||||
local scriptname="$(basename $0)"
|
||||
cat >&2 <<EOF
|
||||
|
||||
$scriptname [options]
|
||||
|
||||
play rtp stream
|
||||
|
||||
Options:
|
||||
-r Resolution
|
||||
-s <Width>x<height> Scale
|
||||
-d <level> Log level for gst
|
||||
-p <port> Port for stream
|
||||
-a Enables audio
|
||||
-h Show this help
|
||||
|
||||
Examples:
|
||||
|
||||
# play stream on port 7236
|
||||
$ $scriptname -p 7236
|
||||
# play stream with resolution 800x600
|
||||
$ $scriptname -s 800x600
|
||||
# play stream with audio
|
||||
$ $scriptname -a
|
||||
# play stream with debug level 3
|
||||
$ $scriptname -d 3
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
DEBUG='0'
|
||||
AUDIO='0'
|
||||
SCALE='0'
|
||||
|
||||
while getopts "r:d:as:p:h" optname
|
||||
do
|
||||
case "$optname" in
|
||||
"h")
|
||||
help
|
||||
exit 0
|
||||
;;
|
||||
"d")
|
||||
DEBUG=`echo ${OPTARG} | tr -d ' '`
|
||||
;;
|
||||
"r")
|
||||
RESOLUTION=`echo ${OPTARG} | tr -d ' '`
|
||||
;;
|
||||
"a")
|
||||
AUDIO='1'
|
||||
;;
|
||||
"p")
|
||||
PORT=`echo ${OPTARG} | tr -d ' '`
|
||||
;;
|
||||
"s")
|
||||
SCALE='1'
|
||||
WIDTH=`echo ${OPTARG} | tr -d ' ' | cut -dx -f 1`
|
||||
HEIGHT=`echo ${OPTARG} | tr -d ' ' | cut -dx -f 2`
|
||||
;;
|
||||
"?")
|
||||
echo "Unknown option $OPTARG"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown parameter $OPTARG"
|
||||
help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
RUN="/usr/bin/gst-launch-1.0 -v "
|
||||
if [ $DEBUG != '0' ]
|
||||
then
|
||||
RUN+="--gst-debug=${DEBUG} "
|
||||
fi
|
||||
|
||||
RUN+="udpsrc port=$PORT buffer-size=212992 caps=\"application/x-rtp, media=video\" ! rtpjitterbuffer latency=20 ! rtpmp2tdepay ! tsdemux "
|
||||
|
||||
if [ $AUDIO == '1' ]
|
||||
then
|
||||
RUN+="name=demuxer demuxer. "
|
||||
fi
|
||||
|
||||
# RUN+="! queue max-size-buffers=0 max-size-time=0 ! h264parse ! avdec_h264 ! videoconvert ! "
|
||||
# RUN+="! queue max-size-buffers=0 max-size-time=0 ! h264parse ! avdec_h264 ! videoconvert ! videorate ! video/x-raw,framerate=1/1 !"
|
||||
# RUN+="! queue max-size-buffers=0 max-size-time=0 ! h264parse ! avdec_h264 ! videoconvert ! videorate drop-only=true max-rate=2 !"
|
||||
#videoconvert n-threads=4 !
|
||||
RUN+="! queue name=video_ch max-size-buffers=0 max-size-time=0 ! h264parse ! queue name=dec0 max-size-buffers=0 max-size-time=0 ! avdec_h264 max-threads=4 skip-frame=1 output-corrupt=false ! videoconvert n-threads=4 !"
|
||||
#RUN+="! queue name=video_ch max-size-buffers=0 max-size-time=0 ! h264parse ! queue name=dec0 ! avdec_h264_omx_dec skip-frame=1 ! videoconvert n-threads=4 !"
|
||||
|
||||
if [ $SCALE == '1' ]
|
||||
then
|
||||
RUN+="videoscale method=1 ! video/x-raw,width=${WIDTH},height=${HEIGHT} ! "
|
||||
fi
|
||||
|
||||
#RUN+="glimagesinkelement sync=false "
|
||||
#RUN+="autovideosink sync=false async=false "
|
||||
#RUN+="v4l2sink sync=false "
|
||||
RUN+=" xvimagesink display=:0 force-aspect-ratio=false sync=false async=false "
|
||||
|
||||
if [ $AUDIO == '1' ]
|
||||
then
|
||||
RUN+="demuxer. ! queue name=audio_ch max-size-buffers=0 max-size-time=0 ! aacparse ! avdec_aac ! audioconvert ! audioresample ! autoaudiosink "
|
||||
fi
|
||||
|
||||
echo "running: $RUN"
|
||||
exec ${RUN}
|
|
@ -0,0 +1,69 @@
|
|||
#!/bin/bash
|
||||
|
||||
function help {
|
||||
local scriptname="$(basename $0)"
|
||||
cat >&2 <<EOF
|
||||
|
||||
$scriptname [options]
|
||||
|
||||
play rtp stream with omxplayer
|
||||
|
||||
Options:
|
||||
-r Resolution
|
||||
-s <Width>x<height> Scale
|
||||
-d <level> Log level for gst
|
||||
-p <port> Port for stream
|
||||
-a Enables audio
|
||||
-h Show this help
|
||||
|
||||
Examples:
|
||||
|
||||
# play stream on port 7236
|
||||
$ $scriptname -p 7236
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
DEBUG='0'
|
||||
AUDIO='0'
|
||||
SCALE='0'
|
||||
|
||||
while getopts "r:d:as:p:h" optname
|
||||
do
|
||||
case "$optname" in
|
||||
"h")
|
||||
help
|
||||
exit 0
|
||||
;;
|
||||
"d")
|
||||
DEBUG=`echo ${OPTARG} | tr -d ' '`
|
||||
;;
|
||||
"r")
|
||||
RESOLUTION=`echo ${OPTARG} | tr -d ' '`
|
||||
;;
|
||||
"a")
|
||||
AUDIO='1'
|
||||
;;
|
||||
"p")
|
||||
PORT=`echo ${OPTARG} | tr -d ' '`
|
||||
;;
|
||||
"s")
|
||||
SCALE='1'
|
||||
WIDTH=`echo ${OPTARG} | tr -d ' ' | cut -dx -f 1`
|
||||
HEIGHT=`echo ${OPTARG} | tr -d ' ' | cut -dx -f 2`
|
||||
;;
|
||||
"?")
|
||||
echo "Unknown option $OPTARG"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown parameter $OPTARG"
|
||||
help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
RUN="omxplayer -live -b -o hdmi rtp://@:$PORT"
|
||||
|
||||
echo "running: $RUN"
|
||||
exec ${RUN}
|
|
@ -0,0 +1,85 @@
|
|||
#
|
||||
# Autocompletion for miraclecast commands
|
||||
#
|
||||
# Maintainer: Alberto Fanjul <albertofanjul@gmail.com>
|
||||
#
|
||||
|
||||
function _miracle-sinkctl() {
|
||||
local cur prev
|
||||
|
||||
_get_comp_words_by_ref cur
|
||||
prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
|
||||
case "$prev" in
|
||||
--log-level)
|
||||
COMPREPLY=($(compgen -W 'fatal alert critical error warning notice info debug trace 1 2 3 4 5 6 7 8' -- "$cur"))
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
COMPREPLY=($(compgen -W "$(_parse_help miracle-sinkctl) $(_parse_short_help miracle-sinkctl)" -- "$cur"))
|
||||
}
|
||||
|
||||
_parse_short_help ()
|
||||
{
|
||||
eval local cmd=$( quote "$1" );
|
||||
local line;
|
||||
{
|
||||
case $cmd in
|
||||
-)
|
||||
cat
|
||||
;;
|
||||
*)
|
||||
LC_ALL=C "$( dequote "$cmd" )" ${2:---help} 2>&1
|
||||
;;
|
||||
esac
|
||||
} | while read -r line; do
|
||||
[[ $line == *([[:blank:]])-* ]] || continue;
|
||||
while [[ $line =~ ((^|[^-])-[A-Za-z0-9?][[:space:]]+)\[?[A-Z0-9]+\]? ]]; do
|
||||
line=${line/"${BASH_REMATCH[0]}"/"${BASH_REMATCH[1]}"};
|
||||
done;
|
||||
__parse_short_options "${line// or /, }";
|
||||
done
|
||||
}
|
||||
|
||||
__parse_short_options ()
|
||||
{
|
||||
local option option2 i IFS='
|
||||
,/|';
|
||||
option=;
|
||||
local -a array;
|
||||
read -a array <<< "$1";
|
||||
for i in "${array[@]}";
|
||||
do
|
||||
case "$i" in
|
||||
---*)
|
||||
break
|
||||
;;
|
||||
--?*)
|
||||
break
|
||||
;;
|
||||
-?*)
|
||||
option=$i;
|
||||
break
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac;
|
||||
done;
|
||||
[[ -n $option ]] || return;
|
||||
IFS='
|
||||
';
|
||||
if [[ $option =~ (\[((no|dont)-?)\]). ]]; then
|
||||
option2=${option/"${BASH_REMATCH[1]}"/};
|
||||
option2=${option2%%[<{().[]*};
|
||||
printf '%s\n' "${option2/=*/=}";
|
||||
option=${option/"${BASH_REMATCH[1]}"/"${BASH_REMATCH[2]}"};
|
||||
fi;
|
||||
option=${option%%[<{().[]*};
|
||||
printf '%s\n' "${option/=*/=}"
|
||||
}
|
||||
|
||||
complete -F _miracle-sinkctl miracle-sinkctl
|
||||
|
||||
# ex: filetype=sh
|
|
@ -0,0 +1,203 @@
|
|||
#http://lxr.linux.no/linux+v3.0/include/linux/if_arp.h#L67
|
||||
ARPHRD_LOOPBACK=772
|
||||
|
||||
#
|
||||
# Find all interfaces except loopback one
|
||||
#
|
||||
function find_choosable_networknames {
|
||||
for i in $( ls /sys/class/net )
|
||||
do
|
||||
if [ $( cat /sys/class/net/$i/type ) != $ARPHRD_LOOPBACK ]
|
||||
then
|
||||
echo $i
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
#
|
||||
# find wireless interfaces
|
||||
#
|
||||
function find_wireless_network_interfaces {
|
||||
for i in $( find_choosable_networknames )
|
||||
do
|
||||
if [ -d /sys/class/net/$i/wireless ]
|
||||
then
|
||||
echo $i
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
#
|
||||
# show pci slot
|
||||
#
|
||||
function show_pci_slot {
|
||||
basename $(readlink /sys/class/net/$1/device) | cut -d: -f2 | sed 's/^0*//'
|
||||
}
|
||||
|
||||
#
|
||||
# test if interface is connected
|
||||
#
|
||||
function is_interface_connected {
|
||||
test x$( cat /sys/class/net/$1/carrier 2>/dev/null) = x1
|
||||
}
|
||||
|
||||
#
|
||||
# find wireless pci slot
|
||||
#
|
||||
function find_wireless_pci_slot {
|
||||
for i in $( find_wireless_network_interfaces )
|
||||
do
|
||||
show_pci_slot $i
|
||||
done
|
||||
}
|
||||
|
||||
#
|
||||
# find wireless pci slot
|
||||
#
|
||||
function find_wireless_ifindex {
|
||||
for i in $( find_wireless_network_interfaces )
|
||||
do
|
||||
show_ifindex $i
|
||||
done
|
||||
}
|
||||
|
||||
#
|
||||
# find wireless connected interfaces
|
||||
#
|
||||
function find_wireless_connected_network_interfaces {
|
||||
for i in $( find_wireless_network_interfaces )
|
||||
do
|
||||
if is_interface_connected $i
|
||||
then
|
||||
echo $i
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
#
|
||||
# find physical for interface if exists
|
||||
#
|
||||
function find_physical_for_network_interface {
|
||||
PHY_INDEX=$(iw dev $1 info | grep wiphy | awk '{print $2}')
|
||||
if [ -n "$PHY_INDEX" ]
|
||||
then
|
||||
echo phy$PHY_INDEX
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# find interface index for interface
|
||||
#
|
||||
function show_ifindex {
|
||||
IF_INDEX=$(iw dev $1 info | grep ifindex | awk '{print $2}')
|
||||
if [ -n "$IF_INDEX" ]
|
||||
then
|
||||
echo $IF_INDEX
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Check interface for P2P capabilities
|
||||
#
|
||||
function search_p2p_capabilities {
|
||||
WI_DEVICE=$1
|
||||
PHY_DEVICE=$(find_physical_for_network_interface $WI_DEVICE)
|
||||
|
||||
if [ -z "$PHY_DEVICE" ]
|
||||
then
|
||||
echo "cannot find physical device for $WI_DEVICE"
|
||||
return
|
||||
fi
|
||||
|
||||
if iw phy $PHY_DEVICE info | grep -Pzo "(?s)Supported interface modes.*Supported commands" | grep "P2P" &> /dev/null
|
||||
then
|
||||
echo $WI_DEVICE supports P2P
|
||||
else
|
||||
echo Sorry, $WI_DEVICE do not support P2P
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# show wpa_supplicant command
|
||||
#
|
||||
function show_wpa_supplicant_process {
|
||||
ps -ef | grep "wpa_supplican[t] "
|
||||
}
|
||||
|
||||
#
|
||||
# show wpa_supplicant command
|
||||
#
|
||||
function show_wpa_supplicant_command {
|
||||
show_wpa_supplicant_process | awk '{print substr($0, index($0,$8))}'
|
||||
}
|
||||
|
||||
#
|
||||
# find wpa_supplicant pid
|
||||
#
|
||||
function find_wpa_supplicant_pid {
|
||||
show_wpa_supplicant_process | awk '{print $2}'
|
||||
}
|
||||
|
||||
#
|
||||
# checking if distro is archlinux
|
||||
#
|
||||
function check_archlinux_distro {
|
||||
test -f "/etc/arch-release"
|
||||
}
|
||||
#
|
||||
# checking if distro is ubuntu
|
||||
#
|
||||
function check_ubuntu_distro {
|
||||
cat /proc/version | grep -i ubuntu
|
||||
}
|
||||
#
|
||||
# checking if distro is debian
|
||||
#
|
||||
function check_debian_distro {
|
||||
cat /proc/version | grep -i debian
|
||||
}
|
||||
|
||||
#
|
||||
# ubuntu manager restarts automatically wpa_supplicant
|
||||
#
|
||||
function kill_ubuntu_network_manager {
|
||||
if check_ubuntu_distro || check_debian_distro
|
||||
then
|
||||
echo stopping NetworkManager
|
||||
sudo service NetworkManager stop
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# arch linux manager restarts automatically wpa_supplicant
|
||||
#
|
||||
function kill_archlinux_network_manager {
|
||||
if check_ubuntu_distro
|
||||
then
|
||||
echo stopping NetworkManager
|
||||
sudo systemctl stop Network.service
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# start ubuntu manager
|
||||
#
|
||||
function start_ubuntu_network_manager {
|
||||
if check_ubuntu_distro || check_debian_distro
|
||||
then
|
||||
echo starting NetworkManager
|
||||
sudo service NetworkManager start
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# start arch linux manager
|
||||
#
|
||||
function start_archlinux_network_manager {
|
||||
if check_archlinux_distro
|
||||
then
|
||||
echo starting NetworkManager
|
||||
sudo systemctl start Network.service
|
||||
fi
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
#!/bin/bash
|
||||
|
||||
function help {
|
||||
local scriptname="$(basename $0)"
|
||||
cat >&2 <<EOF
|
||||
|
||||
$scriptname [options]
|
||||
|
||||
play rtp stream with vlc
|
||||
|
||||
Options:
|
||||
-r Resolution
|
||||
-s <Width>x<height> Scale
|
||||
-d <level> Log level for gst
|
||||
-p <port> Port for stream
|
||||
-a Enables audio
|
||||
-h Show this help
|
||||
|
||||
Examples:
|
||||
|
||||
# play stream on port 7236
|
||||
$ $scriptname -p 7236
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
DEBUG='0'
|
||||
AUDIO='0'
|
||||
SCALE='0'
|
||||
|
||||
while getopts "r:d:as:p:h" optname
|
||||
do
|
||||
case "$optname" in
|
||||
"h")
|
||||
help
|
||||
exit 0
|
||||
;;
|
||||
"d")
|
||||
DEBUG=`echo ${OPTARG} | tr -d ' '`
|
||||
;;
|
||||
"r")
|
||||
RESOLUTION=`echo ${OPTARG} | tr -d ' '`
|
||||
;;
|
||||
"a")
|
||||
AUDIO='1'
|
||||
;;
|
||||
"p")
|
||||
PORT=`echo ${OPTARG} | tr -d ' '`
|
||||
;;
|
||||
"s")
|
||||
SCALE='1'
|
||||
WIDTH=`echo ${OPTARG} | tr -d ' ' | cut -dx -f 1`
|
||||
HEIGHT=`echo ${OPTARG} | tr -d ' ' | cut -dx -f 2`
|
||||
;;
|
||||
"?")
|
||||
echo "Unknown option $OPTARG"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown parameter $OPTARG"
|
||||
help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
RUN="vlc rtp://@:$PORT"
|
||||
|
||||
echo "running: $RUN"
|
||||
exec ${RUN}
|
|
@ -0,0 +1,85 @@
|
|||
#
|
||||
# Autocompletion for miracle-wifictl
|
||||
#
|
||||
# Maintainer: Alberto Fanjul <albertofanjul@gmail.com>
|
||||
#
|
||||
|
||||
function _miracle-wifictl() {
|
||||
local cur prev
|
||||
|
||||
_get_comp_words_by_ref cur
|
||||
prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
|
||||
case "$prev" in
|
||||
--log-level)
|
||||
COMPREPLY=($(compgen -W 'fatal alert critical error warning notice info debug trace 1 2 3 4 5 6 7 8' -- "$cur"))
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
COMPREPLY=($(compgen -W "$(_parse_help miracle-wifictl) $(_parse_short_help miracle-wifictl)" -- "$cur"))
|
||||
}
|
||||
|
||||
_parse_short_help ()
|
||||
{
|
||||
eval local cmd=$( quote "$1" );
|
||||
local line;
|
||||
{
|
||||
case $cmd in
|
||||
-)
|
||||
cat
|
||||
;;
|
||||
*)
|
||||
LC_ALL=C "$( dequote "$cmd" )" ${2:---help} 2>&1
|
||||
;;
|
||||
esac
|
||||
} | while read -r line; do
|
||||
[[ $line == *([[:blank:]])-* ]] || continue;
|
||||
while [[ $line =~ ((^|[^-])-[A-Za-z0-9?][[:space:]]+)\[?[A-Z0-9]+\]? ]]; do
|
||||
line=${line/"${BASH_REMATCH[0]}"/"${BASH_REMATCH[1]}"};
|
||||
done;
|
||||
__parse_short_options "${line// or /, }";
|
||||
done
|
||||
}
|
||||
|
||||
__parse_short_options ()
|
||||
{
|
||||
local option option2 i IFS='
|
||||
,/|';
|
||||
option=;
|
||||
local -a array;
|
||||
read -a array <<< "$1";
|
||||
for i in "${array[@]}";
|
||||
do
|
||||
case "$i" in
|
||||
---*)
|
||||
break
|
||||
;;
|
||||
--?*)
|
||||
break
|
||||
;;
|
||||
-?*)
|
||||
option=$i;
|
||||
break
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac;
|
||||
done;
|
||||
[[ -n $option ]] || return;
|
||||
IFS='
|
||||
';
|
||||
if [[ $option =~ (\[((no|dont)-?)\]). ]]; then
|
||||
option2=${option/"${BASH_REMATCH[1]}"/};
|
||||
option2=${option2%%[<{().[]*};
|
||||
printf '%s\n' "${option2/=*/=}";
|
||||
option=${option/"${BASH_REMATCH[1]}"/"${BASH_REMATCH[2]}"};
|
||||
fi;
|
||||
option=${option%%[<{().[]*};
|
||||
printf '%s\n' "${option/=*/=}"
|
||||
}
|
||||
|
||||
complete -F _miracle-wifictl miracle-wifictl
|
||||
|
||||
# ex: filetype=sh
|
|
@ -0,0 +1,95 @@
|
|||
#
|
||||
# Autocompletion for miracle-wifid
|
||||
#
|
||||
# Maintainer: Alberto Fanjul <albertofanjul@gmail.com>
|
||||
#
|
||||
|
||||
function _miracle-wifid() {
|
||||
local cur prev
|
||||
|
||||
_get_comp_words_by_ref cur
|
||||
prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
|
||||
case "$prev" in
|
||||
--config-methods)
|
||||
COMPREPLY=($(compgen -W 'pbc pin usba ethernet label display ext_nfc_token int_nfc_token nfc_interface push_button keypad virtual_display physical_display virtual_push_button physical_push_button' -- "$cur"))
|
||||
return 0
|
||||
;;
|
||||
--log-level)
|
||||
COMPREPLY=($(compgen -W 'fatal alert critical error warning notice info debug trace 1 2 3 4 5 6 7 8' -- "$cur"))
|
||||
return 0
|
||||
;;
|
||||
--wpa-loglevel)
|
||||
COMPREPLY=($(compgen -W 'fatal alert critical error warning notice info debug trace 1 2 3 4 5 6 7 8' -- "$cur"))
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
COMPREPLY=($(compgen -W "$(_parse_help miracle-wifid) $(_parse_short_help miracle-wifid)" -- "$cur"))
|
||||
}
|
||||
|
||||
|
||||
_parse_short_help ()
|
||||
{
|
||||
eval local cmd=$( quote "$1" );
|
||||
local line;
|
||||
{
|
||||
case $cmd in
|
||||
-)
|
||||
cat
|
||||
;;
|
||||
*)
|
||||
LC_ALL=C "$( dequote "$cmd" )" ${2:---help} 2>&1
|
||||
;;
|
||||
esac
|
||||
} | while read -r line; do
|
||||
[[ $line == *([[:blank:]])-* ]] || continue;
|
||||
while [[ $line =~ ((^|[^-])-[A-Za-z0-9?][[:space:]]+)\[?[A-Z0-9]+\]? ]]; do
|
||||
line=${line/"${BASH_REMATCH[0]}"/"${BASH_REMATCH[1]}"};
|
||||
done;
|
||||
__parse_short_options "${line// or /, }";
|
||||
done
|
||||
}
|
||||
|
||||
__parse_short_options ()
|
||||
{
|
||||
local option option2 i IFS='
|
||||
,/|';
|
||||
option=;
|
||||
local -a array;
|
||||
read -a array <<< "$1";
|
||||
for i in "${array[@]}";
|
||||
do
|
||||
case "$i" in
|
||||
---*)
|
||||
break
|
||||
;;
|
||||
--?*)
|
||||
break
|
||||
;;
|
||||
-?*)
|
||||
option=$i;
|
||||
break
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac;
|
||||
done;
|
||||
[[ -n $option ]] || return;
|
||||
IFS='
|
||||
';
|
||||
if [[ $option =~ (\[((no|dont)-?)\]). ]]; then
|
||||
option2=${option/"${BASH_REMATCH[1]}"/};
|
||||
option2=${option2%%[<{().[]*};
|
||||
printf '%s\n' "${option2/=*/=}";
|
||||
option=${option/"${BASH_REMATCH[1]}"/"${BASH_REMATCH[2]}"};
|
||||
fi;
|
||||
option=${option%%[<{().[]*};
|
||||
printf '%s\n' "${option/=*/=}"
|
||||
}
|
||||
|
||||
complete -F _miracle-wifid miracle-wifid
|
||||
|
||||
|
||||
# ex: filetype=sh
|
|
@ -0,0 +1,23 @@
|
|||
[Unit]
|
||||
Description=Miraclecast WiFi Daemon
|
||||
After=dbus.service
|
||||
Requires=network.target
|
||||
|
||||
[Service]
|
||||
BusName=org.freedesktop.miracle.wifi
|
||||
Environment=PATH=/sbin:/usr/bin
|
||||
# ExecStart=@CMAKE_INSTALL_PREFIX@/bin/miracle-wifid \
|
||||
# --use-dev \
|
||||
# --log-level info \
|
||||
# --lazy-managed \
|
||||
# --config-methods display \
|
||||
# --wpa-loglevel trace
|
||||
ExecStart=/usr/bin/execstart.sh
|
||||
ExecStop=/usr/bin/recover_wpas.sh
|
||||
#CapabilityBoundingSet=CAP_NET_ADMIN \
|
||||
# CAP_NET_BIND_SERVICE \
|
||||
# CAP_NET_RAW
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Alias=dbus-org.freedesktop.miracle.wifi.service
|
|
@ -0,0 +1,20 @@
|
|||
[Unit]
|
||||
Description=Miraclecast WiFi Daemon
|
||||
After=dbus.service
|
||||
Requires=network.target
|
||||
|
||||
[Service]
|
||||
BusName=@dbus_name_prefix@.wifi
|
||||
Environment=PATH=/sbin:/usr/bin
|
||||
ExecStart=@exec_path@/miracle-wifid \
|
||||
--use-dev \
|
||||
--log-level error \
|
||||
--lazy-managed \
|
||||
--config-methods display
|
||||
#CapabilityBoundingSet=CAP_NET_ADMIN \
|
||||
# CAP_NET_BIND_SERVICE \
|
||||
# CAP_NET_RAW
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Alias=dbus-@dbus_name_prefix@.wifi.service
|
|
@ -0,0 +1,18 @@
|
|||
FROM debian:buster-slim
|
||||
|
||||
RUN dpkg --add-architecture i386
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
build-essential \
|
||||
systemd \
|
||||
libglib2.0-dev \
|
||||
libreadline-dev \
|
||||
libudev-dev \
|
||||
libsystemd-dev \
|
||||
libusb-dev \
|
||||
automake \
|
||||
autoconf \
|
||||
libtool \
|
||||
cmake \
|
||||
meson
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
%global commit c3c868e523f450ad4f0d77f5484a3b61f08120b7
|
||||
%global shortcommit %(c=%{commit}; echo ${c:0:7})
|
||||
|
||||
Name: miraclecast
|
||||
Version: 1.0
|
||||
Release: 1.git%{shortcommit}%{?dist}
|
||||
Summary: Connect external monitors to your system via Wifi-Display
|
||||
License: LGPL
|
||||
URL: https://github.com/albfan/miraclecast
|
||||
Source0: https://github.com/albfan/miraclecast/archive/%{commit}/%{name}-%{shortcommit}.tar.gz
|
||||
BuildRequires: autoconf, automake, libtool
|
||||
BuildRequires: readline-devel, glib2-devel, systemd-devel
|
||||
|
||||
%description
|
||||
The MiracleCast project provides software to connect external monitors to your system via Wi-Fi. It is compatible to the Wifi-Display specification also known as Miracast. MiracleCast implements the Display-Source as well as Display-Sink side.
|
||||
|
||||
The Display-Source side allows you to connect external displays to your system and stream local content to the device. A lot of effort is put into making this as easy as connecting external displays via HDMI.
|
||||
|
||||
On the other hand, the Display-Sink side allows you to create wifi-capable external displays yourself. You can use it on your embedded devices or even on full desktops to allow other systems to use your device as external display.
|
||||
|
||||
|
||||
%prep
|
||||
%autosetup -n %{name}-%{shortcommit}
|
||||
|
||||
|
||||
%build
|
||||
mkdir build
|
||||
cd build
|
||||
../autogen.sh g --prefix=%{_prefix}
|
||||
%make_build
|
||||
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
cd build
|
||||
%make_install
|
||||
|
||||
|
||||
%files
|
||||
%license COPYING LICENSE_gdhcp LICENSE_htable LICENSE_lgpl
|
||||
%doc README.md
|
||||
%{_sysconfdir}/dbus-1/system.d/org.freedesktop.miracle.conf
|
||||
%{_bindir}/miracle-wifictl
|
||||
%{_bindir}/miracle-omxplayer
|
||||
%{_bindir}/miracle-gst
|
||||
%{_bindir}/miracle-sinkctl
|
||||
%{_bindir}/miracled
|
||||
%{_bindir}/miracle-dhcp
|
||||
%{_bindir}/miracle-uibcctl
|
||||
%{_bindir}/miracle-wifid
|
||||
%{_bindir}/gstplayer
|
||||
%{_bindir}/uibc-viewer
|
||||
%{_datadir}/bash-completion/completions/miracle-wifictl
|
||||
%{_datadir}/bash-completion/completions/miracle-sinkctl
|
||||
%{_datadir}/bash-completion/completions/miracle-wifid
|
||||
|
||||
|
||||
%changelog
|
||||
* Wed Nov 21 2018 Graham White
|
||||
- first build
|
|
@ -0,0 +1,24 @@
|
|||
This file can be used with the rpmbuild or mock commands to create a binary RPM. Tested and working on Fedora 28 x86\_64.
|
||||
|
||||
Example usage (for Fedora 28 systems):
|
||||
1. Create a tar.gz file of the source code and add the short name of the commit to the tar file, for the most recent commit at the time of writing this would be:
|
||||
* `git clone https://github.com/albfan/miraclecast.git miraclecast-c3c868e`
|
||||
* `tar -zcf miraclecast-c3c868e.tar.gz miraclecast-c3c868e`
|
||||
|
||||
2. Create a Source RPM
|
||||
* `rpmbuild -bs miraclecast.spec --define "_sourcedir $PWD"`
|
||||
|
||||
Then build the RPM with one of the following:
|
||||
|
||||
* Using mock (assuming you're in the dir where the .src.rpm file is):
|
||||
* `mock --arch=x86_64 -r fedora-28-x86_64 --resultdir=results miraclecast-1.0-1.gitc3c868e.fc28.src.rpm`
|
||||
|
||||
OR
|
||||
|
||||
* Using rpmbuild (assuming you're in the dir where the .src.rpm file is):
|
||||
* `rpmbuild -ra miraclecast-1.0-1.gitc3c868e.fc28.src.rpm`
|
||||
|
||||
OR
|
||||
|
||||
* Using rpmbuild (assuming you're in the dir where the .spec and .tar.gz files are):
|
||||
* `rpmbuild -bs miraclecast.spec --define "_sourcedir $PWD"``
|
|
@ -0,0 +1,57 @@
|
|||
#!/bin/bash
|
||||
|
||||
./kill-wpa.sh
|
||||
|
||||
. miracle-utils.sh
|
||||
|
||||
ETHER_NAMES=$(find_choosable_networknames)
|
||||
|
||||
ETHER_COUNT=$(echo "$ETHER_NAMES" | wc -l)
|
||||
|
||||
if [ 0 = $ETHER_COUNT ]
|
||||
then
|
||||
echo There is no net devices avaliable
|
||||
exit 1
|
||||
elif [ 1 = $ETHER_COUNT ]
|
||||
then
|
||||
ETHERNAME="$ETHER_NAMES"
|
||||
elif [ 2 -le $ETHER_COUNT ]
|
||||
then
|
||||
echo choose device for normal connection:
|
||||
QUIT="exit"
|
||||
select et_name in $ETHER_NAMES $QUIT
|
||||
do
|
||||
case $et_name
|
||||
in
|
||||
"$QUIT")
|
||||
exit
|
||||
;;
|
||||
"")
|
||||
if [ "$REPLY" = $QUIT ]
|
||||
then
|
||||
exit
|
||||
else
|
||||
echo unknow $REPLY
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
ETHERNAME=$et_name
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
# default path for config file
|
||||
CONFIG_FILE=${1:-/run/network/wpa_supplicant_${ETHERNAME}.conf}
|
||||
|
||||
|
||||
echo starting wpa_supplicant for normal connection
|
||||
if check_ubuntu_distro || check_debian_distro
|
||||
then
|
||||
start_ubuntu_network_manager
|
||||
sudo wpa_supplicant -B -u -s -O /var/run/wpa_supplicant
|
||||
else
|
||||
sudo wpa_supplicant -B -u -P /run/wpa_supplicant_${ETHERNAME}pid -i ${ETHERNAME} -D nl80211 -c$CONFIG_FILE
|
||||
fi
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
<?xml version="1.0"?> <!--*-nxml-*-->
|
||||
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
||||
|
||||
<!--
|
||||
This file is part of MiracleCast.
|
||||
-->
|
||||
|
||||
<busconfig>
|
||||
|
||||
<policy user="root">
|
||||
<allow own="org.freedesktop.miracle"/>
|
||||
<allow own="org.freedesktop.miracle.wifi"/>
|
||||
<allow send_destination="org.freedesktop.miracle"/>
|
||||
<allow send_destination="org.freedesktop.miracle.wifi"/>
|
||||
<allow receive_sender="org.freedesktop.miracle"/>
|
||||
<allow receive_sender="org.freedesktop.miracle.wifi"/>
|
||||
<allow receive_sender="org.freedesktop.miracleagent"/>
|
||||
<allow receive_sender="org.freedesktop.login1"/>
|
||||
|
||||
</policy>
|
||||
|
||||
<policy context="default">
|
||||
<deny send_destination="org.freedesktop.miracle"/>
|
||||
<deny send_destination="org.freedesktop.miracle.wifi"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.miracle"
|
||||
send_interface="org.freedesktop.DBus.Introspectable"/>
|
||||
<allow send_destination="org.freedesktop.miracle.wifi"
|
||||
send_interface="org.freedesktop.DBus.Introspectable"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.miracle"
|
||||
send_interface="org.freedesktop.DBus.Peer"/>
|
||||
<allow send_destination="org.freedesktop.miracle.wifi"
|
||||
send_interface="org.freedesktop.DBus.Peer"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.miracle"
|
||||
send_interface="org.freedesktop.DBus.ObjectManager"/>
|
||||
<allow send_destination="org.freedesktop.miracle.wifi"
|
||||
send_interface="org.freedesktop.DBus.ObjectManager"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.miracle"
|
||||
send_interface="org.freedesktop.DBus.Properties"
|
||||
send_member="Get"/>
|
||||
<allow send_destination="org.freedesktop.miracle.wifi"
|
||||
send_interface="org.freedesktop.DBus.Properties"
|
||||
send_member="Get"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.miracle"
|
||||
send_interface="org.freedesktop.DBus.Properties"
|
||||
send_member="GetAll"/>
|
||||
<allow send_destination="org.freedesktop.miracle.wifi"
|
||||
send_interface="org.freedesktop.DBus.Properties"
|
||||
send_member="GetAll"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.miracle.wifi"
|
||||
send_interface="org.freedesktop.miracle.wifi.ui"
|
||||
send_member="UsrDisconnect"/>
|
||||
<allow send_destination="org.freedesktop.miracle.wifi"
|
||||
send_interface="org.freedesktop.miracle.wifi.ui"
|
||||
send_member="ProjectionOp"/>
|
||||
<allow send_destination="org.freedesktop.miracle.wifi"
|
||||
send_interface="org.freedesktop.miracle.wifi.ui"
|
||||
send_member="HandShake"/>
|
||||
<allow send_destination="org.freedesktop.miracle.wifi"
|
||||
send_interface="org.freedesktop.miracle.wifi.ui"
|
||||
send_member="SetSinkName"/>
|
||||
<allow send_destination="org.freedesktop.miracle.wifi"
|
||||
send_interface="org.freedesktop.miracle.wifi.ui"
|
||||
send_member="SetSinkConfigMethods"/>
|
||||
<allow send_destination="org.freedesktop.miracle.wifi"
|
||||
send_interface="org.freedesktop.miracle.wifi.ui"
|
||||
send_member="QueryConnectedDevice"/>
|
||||
<allow send_destination="org.freedesktop.miracle.wifi"
|
||||
send_interface="org.freedesktop.miracle.wifi.ui"
|
||||
send_member="DeleteConnectedDevice"/>
|
||||
<allow send_destination="org.freedesktop.miracle.wifi"
|
||||
send_interface="org.freedesktop.miracle.wifi.ui"
|
||||
send_member="StartWpas"/>
|
||||
<allow send_destination="org.freedesktop.miracle.wifi"
|
||||
send_interface="org.freedesktop.miracle.wifi.ui"
|
||||
send_member="StopWpas"/>
|
||||
<allow send_destination="org.freedesktop.miracle.wifi"
|
||||
send_interface="org.freedesktop.miracle.wifi.ui"
|
||||
send_member="ResolutionUpdate"/>
|
||||
<allow send_destination="org.freedesktop.miracle.wifi"
|
||||
send_interface="org.freedesktop.miracle.wifi.ui"
|
||||
send_member="AgtStartR2Sess"/>
|
||||
<allow send_destination="org.freedesktop.miracle.wifi"
|
||||
send_interface="org.freedesktop.miracle.wifi.ui"
|
||||
send_member="QueryWpaStopped"/>
|
||||
<allow send_destination="org.freedesktop.miracle.wifi"
|
||||
send_interface="org.freedesktop.miracle.wifi.ui"
|
||||
send_member="SetManufacturer"/>
|
||||
<allow send_destination="org.freedesktop.miracle.wifi"
|
||||
send_interface="org.freedesktop.miracle.wifi.ui"
|
||||
send_member="QueryGroupInfo"/>
|
||||
<allow send_destination="org.freedesktop.miracle.wifi"
|
||||
send_interface="org.freedesktop.miracle.wifi.ui"
|
||||
send_member="userChosen"/>
|
||||
|
||||
<allow receive_sender="org.freedesktop.miracle"/>
|
||||
<allow receive_sender="org.freedesktop.miracle.wifi"/>
|
||||
<allow receive_sender="org.freedesktop.login1"/>
|
||||
</policy>
|
||||
|
||||
</busconfig>
|
|
@ -0,0 +1,107 @@
|
|||
#!/bin/bash
|
||||
|
||||
eval SCRIPT_DEBUG="\$$(basename $0 .sh | tr - _)_DEBUG"
|
||||
SCRIPT_DEBUG=${SCRIPT_DEBUG:--1}
|
||||
|
||||
if [ "$SCRIPT_DEBUG" -ge 1 ]
|
||||
then
|
||||
set -x
|
||||
fi
|
||||
if [ "$SCRIPT_DEBUG" -ge 10 ]
|
||||
then
|
||||
set -v
|
||||
fi
|
||||
|
||||
##START of common funcs, moved to /home/$USR/.config/miracast latter
|
||||
LOOPBACK=772
|
||||
function find_choosable_networknames {
|
||||
for i in $( ls /sys/class/net )
|
||||
do
|
||||
if [ $( cat /sys/class/net/$i/type ) != $LOOPBACK ]
|
||||
then
|
||||
echo $i
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function find_wireless_network_interfaces {
|
||||
for i in $( find_choosable_networknames )
|
||||
do
|
||||
if [ -d /sys/class/net/$i/wireless ]
|
||||
then
|
||||
echo $i
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function find_physical_for_network_interface {
|
||||
PHY_INDEX=$(iw dev $1 info | grep wiphy | awk '{print $2}')
|
||||
if [ -n "$PHY_INDEX" ]
|
||||
then
|
||||
echo phy$PHY_INDEX
|
||||
fi
|
||||
}
|
||||
|
||||
function search_p2p_capabilities {
|
||||
WI_DEVICE=$1
|
||||
PHY_DEVICE=$(find_physical_for_network_interface $WI_DEVICE)
|
||||
SUCC=0
|
||||
FAIL=1
|
||||
|
||||
if [ -z "$PHY_DEVICE" ]
|
||||
then
|
||||
echo "cannot find physical device for $WI_DEVICE"
|
||||
return
|
||||
fi
|
||||
|
||||
if iw phy $PHY_DEVICE info | grep -Pzo "(?s)Supported interface modes.*Supported commands" | grep "P2P" &> /dev/null
|
||||
then
|
||||
echo $WI_DEVICE supports P2P
|
||||
else
|
||||
echo Sorry, $WI_DEVICE do not support P2P
|
||||
# exit 1
|
||||
fi
|
||||
}
|
||||
##END of common funcs, moved to /home/$USR/.config/miracast latter
|
||||
|
||||
WIFI_COUNT=0
|
||||
WIFI_NAMES="$(find_wireless_network_interfaces)"
|
||||
if [ -n "$WIFI_NAMES" ]
|
||||
then
|
||||
WIFI_COUNT=$(echo "$WIFI_NAMES" | wc -l)
|
||||
fi
|
||||
|
||||
if [ 0 = $WIFI_COUNT ]
|
||||
then
|
||||
echo There is no wireless devices available
|
||||
exit 1
|
||||
elif [ 1 = $WIFI_COUNT ]
|
||||
then
|
||||
WIFI_NAME="$WIFI_NAMES"
|
||||
elif [ 2 -ge $WIFI_COUNT ]
|
||||
then
|
||||
echo Support Only one wireless card @v1.0
|
||||
fi
|
||||
|
||||
RETSTR=$(search_p2p_capabilities $WIFI_NAME)
|
||||
echo $RETSTR
|
||||
TARGET="not"
|
||||
|
||||
if [[ $RETSTR =~ $TARGET ]]
|
||||
then
|
||||
echo "FAILURE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
AGENT_PNAME="miracle-agent"
|
||||
AGENT_PNUM=`ps -ef | grep $AGENT_PNAME | grep -v grep | wc -l`
|
||||
if [ $AGENT_PNUM -gt 0 ]
|
||||
then
|
||||
echo "SUCCESS"
|
||||
else
|
||||
echo "Agent not running!!! Quit..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
nmcli device set $WIFI_NAME managed no
|
||||
systemctl restart miracle-wifid.service
|
|
@ -0,0 +1,58 @@
|
|||
#!/bin/bash
|
||||
|
||||
eval SCRIPT_DEBUG="\$$(basename $0 .sh | tr - _)_DEBUG"
|
||||
SCRIPT_DEBUG=${SCRIPT_DEBUG:--1}
|
||||
|
||||
if [ "$SCRIPT_DEBUG" -ge 1 ]
|
||||
then
|
||||
set -x
|
||||
fi
|
||||
if [ "$SCRIPT_DEBUG" -ge 10 ]
|
||||
then
|
||||
set -v
|
||||
fi
|
||||
|
||||
##common funcs, moved to /home/$USR/.config/miracast
|
||||
LOOPBACK=772
|
||||
function find_choosable_networknames {
|
||||
for i in $( ls /sys/class/net )
|
||||
do
|
||||
if [ $( cat /sys/class/net/$i/type ) != $LOOPBACK ]
|
||||
then
|
||||
echo $i
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function find_wireless_network_interfaces {
|
||||
for i in $( find_choosable_networknames )
|
||||
do
|
||||
if [ -d /sys/class/net/$i/wireless ]
|
||||
then
|
||||
echo $i
|
||||
fi
|
||||
done
|
||||
}
|
||||
##END of common funcs, moved to /home/$USR/.config/miracast
|
||||
|
||||
WIFI_COUNT=0
|
||||
WIFI_NAMES="$(find_wireless_network_interfaces)"
|
||||
if [ -n "$WIFI_NAMES" ]
|
||||
then
|
||||
WIFI_COUNT=$(echo "$WIFI_NAMES" | wc -l)
|
||||
fi
|
||||
|
||||
if [ 0 = $WIFI_COUNT ]
|
||||
then
|
||||
echo There is no wireless devices available
|
||||
exit 1
|
||||
elif [ 1 = $WIFI_COUNT ]
|
||||
then
|
||||
WIFI_NAME="$WIFI_NAMES"
|
||||
elif [ 2 -ge $WIFI_COUNT ]
|
||||
then
|
||||
echo Support Only one wireless card @v1.0
|
||||
fi
|
||||
|
||||
systemctl stop miracle-wifid.service
|
||||
nmcli device set $WIFI_NAME managed yes
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
sudo systemctl unmask wpa_supplicant.service
|
||||
sudo systemctl start wpa_supplicant.service
|
||||
echo "We recover wpa_supplicant.service !!!!!!!!!!!!!!!"
|
||||
|
|
@ -0,0 +1 @@
|
|||
ps -ef | grep wpa_supplican[t]
|
|
@ -0,0 +1,61 @@
|
|||
#!/bin/bash
|
||||
|
||||
eval SCRIPT_DEBUG="\$$(basename $0 .sh | tr - _)_DEBUG"
|
||||
SCRIPT_DEBUG=${SCRIPT_DEBUG:--1}
|
||||
|
||||
if [ "$SCRIPT_DEBUG" -ge 1 ]
|
||||
then
|
||||
set -x
|
||||
fi
|
||||
if [ "$SCRIPT_DEBUG" -ge 10 ]
|
||||
then
|
||||
set -v
|
||||
fi
|
||||
|
||||
. miracle-utils.sh
|
||||
|
||||
WIFI_COUNT=0
|
||||
WIFI_NAMES="$(find_wireless_network_interfaces)"
|
||||
if [ -n "$WIFI_NAMES" ]
|
||||
then
|
||||
WIFI_COUNT=$(echo "$WIFI_NAMES" | wc -l)
|
||||
fi
|
||||
|
||||
if [ 0 = $WIFI_COUNT ]
|
||||
then
|
||||
echo There is no wireless devices available
|
||||
exit 1
|
||||
elif [ 1 = $WIFI_COUNT ]
|
||||
then
|
||||
WIFI_NAME="$WIFI_NAMES"
|
||||
elif [ 2 -ge $WIFI_COUNT ]
|
||||
then
|
||||
echo Choose wireless device:
|
||||
PS3="device: "
|
||||
QUIT="exit"
|
||||
select wi_name in $WIFI_NAMES $QUIT
|
||||
do
|
||||
case $wi_name
|
||||
in
|
||||
"$QUIT")
|
||||
exit
|
||||
;;
|
||||
"")
|
||||
if [ "$REPLY" = $QUIT ]
|
||||
then
|
||||
exit
|
||||
else
|
||||
echo unknow $REPLY
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
WIFI_NAME=$wi_name
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
search_p2p_capabilities $WIFI_NAME
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue