cinnamon-control-center-6.4.1/0000775000175000017500000000000014724311620015204 5ustar fabiofabiocinnamon-control-center-6.4.1/debian/0000775000175000017500000000000014724311620016426 5ustar fabiofabiocinnamon-control-center-6.4.1/meson.build0000664000175000017500000001431014724311620017345 0ustar fabiofabioproject('cinnamon-control-center', 'c', version : '6.4.1', meson_version : '>=0.56.0') i18n = import('i18n') pkgconfig = import('pkgconfig') gnome = import('gnome') cc = meson.get_compiler('c') config = configuration_data() ############################################################################### # Project conf lib_ver = '1.0.0' gettext_package = meson.project_name() config.set_quoted('PACKAGE', meson.project_name()) config.set_quoted('VERSION', meson.project_version()) config.set_quoted('GETTEXT_PACKAGE', gettext_package) ############################################################################### # Dependencies math = cc.find_library('m') cinn_desktop= dependency('cinnamon-desktop', version: '>=4.6.0') cinn_menu = dependency('libcinnamon-menu-3.0') gtk = dependency('gtk+-3.0', version: '>=3.16.0') glib = dependency('glib-2.0', version: '>=2.44.0') gio_unix = dependency('gio-unix-2.0', version: '>=2.44.0') gudev_dep = dependency('gudev-1.0', version: '>= 232') libgnomekbd = dependency('libgnomekbd', version: '>=3.0.0') libgnomekbdui=dependency('libgnomekbdui', version: '>=3.0.0') libnotify = dependency('libnotify', version: '>=0.7.3') libx11 = dependency('x11') polkit_gobj = dependency('polkit-gobject-1',version: '>=0.103') libxklavier = dependency('libxklavier', version: '>=5.1') upower_glib_dep = dependency('upower-glib', version: '>= 0.99.8') config.set('HAVE_X11_EXTENSIONS_XKB_H', cc.has_header('X11/extensions/XKB.h')) ############################################################################### # This is a hard-dependency for the region and user-accounts panels isocodes = dependency('iso-codes') config.set_quoted('ISO_CODES_PREFIX', isocodes.get_variable(pkgconfig: 'prefix')) ############################################################################### # Network Manager stuff if get_option('networkmanager') libnm = dependency('libnm', version: '>=1.2.0') libnma = dependency('libnma',version: '>=1.2.0') else libnm = dependency('', required: false) libnma= dependency('', required: false) endif if get_option('modemmanager') if not get_option('networkmanager') error('*** NetworkManager is required by ModemManager ***') endif modemmanager = dependency('mm-glib', version: '>=0.7') else modemmanager = dependency('', required: false) endif config.set('BUILD_MODEM', modemmanager.found()) ############################################################################### # Color Management if get_option('color') colord = dependency('colord', version: '>=0.1.14') else colord = dependency('', required: false) endif ############################################################################### # Wacom Management if get_option('wacom') libwacom = dependency('libwacom', version: '>=0.7') libxi = dependency('xi', version: '>=1.2') else libwacom = dependency('', required: false) endif config.set('HAVE_WACOM_3D_STYLUS', libwacom.version().version_compare('>=0.27')) ############################################################################### # Directories # Relative paths panels_dir = get_option('libdir') / 'cinnamon-control-center-1' / 'panels' ui_dir = get_option('datadir') / meson.project_name() / 'ui' um_pix_dir = get_option('datadir') / meson.project_name() / 'pixmaps' menu_dir = get_option('sysconfdir') / 'xdg' / 'menus' panel_def_dir = get_option('datadir') / meson.project_name() / 'panels' desktop_dir = get_option('datadir') / 'applications' prefix = get_option('prefix') config.set_quoted('BINDIR', prefix / get_option('bindir')) config.set_quoted('SBINDIR', prefix / get_option('sbindir')) config.set_quoted('LIBLOCALEDIR', prefix / get_option('libdir') / 'locale') config.set_quoted('LOCALE_DIR', prefix / get_option('localedir')) config.set_quoted('CINNAMONLOCALEDIR', prefix / get_option('localedir')) config.set_quoted('DATADIR', prefix / get_option('datadir')) config.set_quoted('CINNAMONCC_DATA_DIR', prefix / get_option('datadir')) config.set_quoted('CINNAMONCC_UI_DIR', prefix / ui_dir) config.set_quoted('PANELS_DIR', prefix / panels_dir) config.set_quoted('MENUDIR', '/' / menu_dir) config.set_quoted('UIDIR', prefix / ui_dir) config.set_quoted('UM_PIXMAP_DIR', prefix / um_pix_dir) config.set_quoted('PANEL_DEF_DIR', prefix / panel_def_dir) ############################################################################### # Build options more_cflags = [ ] if get_option('warning_level').to_int() >=2 more_cflags += [ '-Wall', '-Wclobbered', '-Wempty-body', '-Wignored-qualifiers', '-Wmissing-field-initializers', '-Wmissing-parameter-type', '-Wold-style-declaration', '-Woverride-init', '-Wtype-limits', '-Wuninitialized', '-Wchar-subscripts', '-Wmissing-declarations', '-Wmissing-prototypes', '-Wnested-externs', '-Wpointer-arith', '-Wcast-align', '-Wsign-compare', ] endif if get_option('buildtype').contains('rel') more_cflags += '-Wp,-D_FORTIFY_SOURCE=2' endif if not get_option('deprecated_warnings') add_global_arguments([ '-Wno-deprecated-declarations', '-Wno-deprecated', '-Wno-declaration-after-statement', '-DGLIB_DISABLE_DEPRECATION_WARNINGS', ], language: 'c', ) endif meson.add_install_script('meson_install_schemas.py') add_project_arguments(cc.get_supported_arguments(more_cflags), language: 'c') configure_file( output: 'config.h', configuration: config, ) rootInclude = include_directories('.') subdir('po') subdir('shell') subdir('panels') subdir('install-scripts') final_message = [ '', '', '** NetworkManager (Network panel) : @0@'.format(libnm.found()), '** ModemManager support : @0@'.format(modemmanager.found()), '** Colord support (Color management panel) : @0@'.format(colord.found()), '** Wacom support (Wacom panel) : @0@'.format(libwacom.found()), '** Wayland support : @0@'.format(cc.has_header('gdk/gdkwayland.h', dependencies: gtk)), '', ] message('\n'.join(final_message)) cinnamon-control-center-6.4.1/generate_additional_files.py0000775000175000017500000000506614724311620022734 0ustar fabiofabio#!/usr/bin/python3 DOMAIN = "cinnamon-control-center" PATH = "/usr/share/locale" import os, gettext, sys from mintcommon import additionalfiles os.environ['LANGUAGE'] = "en_US.UTF-8" gettext.install(DOMAIN, PATH) prefix = """[Desktop Entry] Exec=cinnamon-settings color Icon=cs-color Terminal=false Type=Application StartupNotify=true Categories=GTK;Settings;X-Cinnamon-Settings-Panel;HardwareSettings OnlyShowIn=X-Cinnamon; X-Cinnamon-Settings-Panel=color """ additionalfiles.generate(DOMAIN, PATH, "./panels/color/cinnamon-color-panel.desktop", prefix, _("Color"), _("Color management settings"), "", keywords=_("Color, ICC, Profile, Calibrate, Printer, Display")) prefix = """[Desktop Entry] Exec=cinnamon-settings region Icon=cs-language Terminal=false Type=Application StartupNotify=true Categories=GTK;Settings;DesktopSettings;X-Cinnamon-Settings-Panel;X-Cinnamon-PersonalSettings OnlyShowIn=X-Cinnamon; X-Cinnamon-Settings-Panel=region NoDisplay=true """ additionalfiles.generate(DOMAIN, PATH, "./panels/region/cinnamon-region-panel.desktop", prefix, _("Region & Language"), _("Change your region and language settings"), "") prefix = """[Desktop Entry] Exec=cinnamon-settings display Icon=cs-display Terminal=false Type=Application StartupNotify=true Categories=GTK;Settings;HardwareSettings;X-Cinnamon-Settings-Panel; OnlyShowIn=X-Cinnamon; X-Cinnamon-Settings-Panel=display """ additionalfiles.generate(DOMAIN, PATH, "./panels/display/cinnamon-display-panel.desktop", prefix, _("Display"), _("Change resolution and position of monitors and projectors"), "", keywords=_("Panel, Projector, xrandr, Screen, Resolution, Refresh")) prefix = """[Desktop Entry] Exec=cinnamon-settings network Icon=cs-network Terminal=false Type=Application StartupNotify=true Categories=GTK;Settings;HardwareSettings;X-Cinnamon-Settings-Panel; OnlyShowIn=X-Cinnamon; X-Cinnamon-Settings-Panel=network """ additionalfiles.generate(DOMAIN, PATH, "./panels/network/cinnamon-network-panel.desktop", prefix, _("Network"), _("Network settings"), "", keywords=_("Network, Wireless, IP, LAN, Proxy, Internet, WiFi")) prefix = """[Desktop Entry] Exec=cinnamon-settings wacom Icon=cs-tablet Terminal=false Type=Application StartupNotify=true Categories=GNOME;GTK;Settings;HardwareSettings;X-Cinnamon-Settings-Panel; X-Cinnamon-Settings-Panel=wacom OnlyShowIn=X-Cinnamon; """ additionalfiles.generate(DOMAIN, PATH, "./panels/wacom/cinnamon-wacom-panel.desktop", prefix, _("Graphics Tablet"), _("Set button mappings and adjust stylus sensitivity for graphics tablets"), "", keywords=_("Tablet, Wacom, Stylus, Eraser, Mouse")) cinnamon-control-center-6.4.1/TODO0000664000175000017500000000000014724311620015662 0ustar fabiofabiocinnamon-control-center-6.4.1/.gitignore0000664000175000017500000000134214724311620017174 0ustar fabiofabiodebian/.debhelper debian/cinnamon-control-center-data.debhelper.log debian/cinnamon-control-center-data.substvars debian/cinnamon-control-center-data debian/cinnamon-control-center-dbg.debhelper.log debian/cinnamon-control-center-dbg.substvars debian/cinnamon-control-center-dbg debian/cinnamon-control-center.debhelper.log debian/cinnamon-control-center.substvars debian/cinnamon-control-center debian/debhelper-build-stamp debian/files debian/libcinnamon-control-center-dev.debhelper.log debian/libcinnamon-control-center-dev.substvars debian/libcinnamon-control-center-dev debian/libcinnamon-control-center1.debhelper.log debian/libcinnamon-control-center1.substvars debian/libcinnamon-control-center1 debian/tmp obj-x86_64-linux-gnu cinnamon-control-center-6.4.1/README0000664000175000017500000000242614724311620016070 0ustar fabiofabioCinnamon Control Center ==================== In the report please include the following information - Operating system and version For Linux, version of the C library How to reproduce the bug if possible If the bug was a crash, include the exact text that was printed out A stacktrace where possible [see below] How to get a stack trace - If the crash is reproducible, it is possible to get a stack trace and attach it to the bug report. The following steps are used to obtain a stack trace - Run the program in gdb [the GNU debugger] or any other debugger ie. gdb gnome-keyboard-properties Start the program ie. (gdb) run Reproduce the crash and the program will exit to the gdb prompt Get the back trace ie. (gdb) bt full Once you have the backtrace, copy and paste this either into the 'Comments' field or attach a file with it included. Patches - Patches should be submitted to bugzilla.gnome.org or emailed to the gnomecc-list@gnome.org list. If using bugzilla, attach the patch to a new bug report [or preferably, check to see if there is already a bug report that corresponds to your patch]. Bug reports containing patches should include the 'PATCH' keyword. Patches should be created using the unified diff form. ie. svn diff file-to-be-patched.c > patch.diff cinnamon-control-center-6.4.1/AUTHORS0000664000175000017500000000004414724311620016252 0ustar fabiofabioJonathan Blandford cinnamon-control-center-6.4.1/meson_install_schemas.py0000775000175000017500000000042614724311620022135 0ustar fabiofabio#!/usr/bin/python3 import os import subprocess schemadir = os.path.join(os.environ['MESON_INSTALL_PREFIX'], 'share', 'glib-2.0', 'schemas') if not os.environ.get('DESTDIR'): print('Compiling gsettings schemas...') subprocess.call(['glib-compile-schemas', schemadir]) cinnamon-control-center-6.4.1/COPYING0000664000175000017500000004325514724311620016250 0ustar fabiofabio GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 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. 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 Lesser 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. Copyright (C) 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 Street, 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. , 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 Lesser General Public License instead of this License. cinnamon-control-center-6.4.1/.github/0000775000175000017500000000000014724311620016544 5ustar fabiofabiocinnamon-control-center-6.4.1/.github/ISSUE_TEMPLATE.md0000664000175000017500000000036314724311620021253 0ustar fabiofabio ``` * cinnamon-control-center version * Distribution - (Mint 17.2, Arch, Fedora 25, etc...) * Graphics hardware *and* driver used * 32 or 64 bit ``` **Issue** **Steps to reproduce** **Expected behaviour** **Other information** cinnamon-control-center-6.4.1/.github/workflows/0000775000175000017500000000000014724311620020601 5ustar fabiofabiocinnamon-control-center-6.4.1/.github/workflows/build.yml0000664000175000017500000000115514724311620022425 0ustar fabiofabioname: Build on: push: branches: - master pull_request: branches: - master workflow_dispatch: inputs: debug_enabled: type: boolean description: 'Start an SSH server on failure.' required: false default: false jobs: build: uses: linuxmint/github-actions/.github/workflows/do-builds.yml@master with: commit_id: master ############################## Comma separated list - like 'linuxmint/xapp, linuxmint/cinnamon-desktop' dependencies: linuxmint/cinnamon-desktop, linuxmint/cinnamon-menus ############################## cinnamon-control-center-6.4.1/MAINTAINERS0000664000175000017500000000000014724311620016667 0ustar fabiofabiocinnamon-control-center-6.4.1/makepot0000775000175000017500000000072514724311620016576 0ustar fabiofabio#!/bin/bash for ui in $(find panels -name *.ui) do intltool-extract --type=gettext/glade $ui done xgettext --add-comments --language=C --from-code=UTF-8 \ --keyword=_ --keyword=C_:1c,2 --keyword=N_ --keyword=NC_:1c,2 \ --output=cinnamon-control-center.pot \ panels/*/*.c panels/*/*/*.c \ shell/*.c \ panels/*/*.ui.h panels/*/*/*.ui.h \ generate_additional_files.py rm -f panels/*/*.ui.h rm -f panels/*/*/*.ui.h cinnamon-control-center-6.4.1/install-scripts/0000775000175000017500000000000014724311620020337 5ustar fabiofabiocinnamon-control-center-6.4.1/install-scripts/meson.build0000664000175000017500000000100214724311620022472 0ustar fabiofabiolinks = [ 'cinnamon-display-panel.desktop', ] if colord.found() links += ['cinnamon-color-panel.desktop'] endif if libnm.found() links += ['cinnamon-network-panel.desktop'] endif if libwacom.found() links += ['cinnamon-wacom-panel.desktop'] endif if meson.version().version_compare('>=0.61.0') foreach link: links install_symlink(link, install_dir: panel_def_dir, pointing_to: '../../applications' / link ) endforeach else meson.add_install_script('desktop-file-links.py') endif cinnamon-control-center-6.4.1/install-scripts/desktop-file-links.py0000775000175000017500000000160614724311620024423 0ustar fabiofabio#!/usr/bin/python3 import os import subprocess # Symlinks desktop files to c-c-c's panel dir so the cinnamon-control-center binary can find the plugins. destdir_prefix = os.environ.get('MESON_INSTALL_DESTDIR_PREFIX') prefix = os.environ.get('MESON_INSTALL_PREFIX') source_location = os.path.join(prefix, "share", "applications") target_location = os.path.join(destdir_prefix, "share", "cinnamon-control-center", "panels") links = [ "cinnamon-color-panel.desktop", "cinnamon-display-panel.desktop", "cinnamon-network-panel.desktop", "cinnamon-wacom-panel.desktop" ] for link in links: orig_path = os.path.join(source_location, link) link_path = os.path.join(target_location, link) if os.path.lexists(link_path): print('%s already exists, skipping symlink creation' % link_path) continue subprocess.call(['ln', '-s', orig_path, link_path]) exit(0) cinnamon-control-center-6.4.1/README.md0000664000175000017500000000111614724311620016462 0ustar fabiofabioSettings need to be unified and consistent. At the moment configuration is split between an incomplete Cinnamon Settings and a heavily patched Gnome Control Center. One of these two tools need to be removed from the default installation and discontinued in the scope of the Cinnamon project. The other one needs to be able to load all modules, whether they're GNOME modules or Cinnamon settings modules. This git repository attempts to use Gnome Control Center as the start point for a unified control center. Similar efforts might take place with Cinnamon Settings as a starting point. cinnamon-control-center-6.4.1/cinnamon-control-center.pot0000664000175000017500000016702414724311620022500 0ustar fabiofabio# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-11-26 13:02+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" #. TRANSLATORS: this is where the user can click and import a profile #: panels/color/cc-color-panel.c:106 msgid "Other profile…" msgstr "" #. TRANSLATORS: this is a profile prefix to signify the #. * profile has been auto-generated for this hardware #: panels/color/cc-color-panel.c:119 msgid "Default: " msgstr "" #. TRANSLATORS: this is a profile prefix to signify the #. * profile his a standard space like AdobeRGB #: panels/color/cc-color-panel.c:125 msgid "Colorspace: " msgstr "" #. TRANSLATORS: this is a profile prefix to signify the #. * profile is a test profile #: panels/color/cc-color-panel.c:131 msgid "Test profile: " msgstr "" #. TRANSLATORS: this is when the profile should be set for all users #: panels/color/cc-color-panel.c:183 panels/color/color.ui.h:9 msgid "Set for all users" msgstr "" #. TRANSLATORS: this is when the profile should be set for all users #: panels/color/cc-color-panel.c:190 msgid "Create virtual device" msgstr "" #. TRANSLATORS: an ICC profile is a file containing colorspace data #: panels/color/cc-color-panel.c:225 msgid "Select ICC Profile File" msgstr "" #: panels/color/cc-color-panel.c:228 msgid "_Import" msgstr "" #. TRANSLATORS: filter name on the file->open dialog #: panels/color/cc-color-panel.c:239 msgid "Supported ICC profiles" msgstr "" #. TRANSLATORS: filter name on the file->open dialog #: panels/color/cc-color-panel.c:246 #: panels/network/wireless-security/eap-method-fast.c:417 msgid "All files" msgstr "" #. TRANSLATORS: this is the dialog title in the 'Add profile' UI #: panels/color/cc-color-panel.c:515 msgid "Available Profiles for Displays" msgstr "" #. TRANSLATORS: this is the dialog title in the 'Add profile' UI #: panels/color/cc-color-panel.c:519 msgid "Available Profiles for Scanners" msgstr "" #. TRANSLATORS: this is the dialog title in the 'Add profile' UI #: panels/color/cc-color-panel.c:523 msgid "Available Profiles for Printers" msgstr "" #. TRANSLATORS: this is the dialog title in the 'Add profile' UI #: panels/color/cc-color-panel.c:527 msgid "Available Profiles for Cameras" msgstr "" #. TRANSLATORS: this is the dialog title in the 'Add profile' UI #: panels/color/cc-color-panel.c:531 msgid "Available Profiles for Webcams" msgstr "" #. TRANSLATORS: this is the dialog title in the 'Add profile' UI #. * where the device type is not recognised #. Profiles that can be added to the device #: panels/color/cc-color-panel.c:536 panels/color/color.ui.h:2 msgid "Available Profiles" msgstr "" #. TRANSLATORS: column for device list #: panels/color/cc-color-panel.c:812 msgid "Device" msgstr "" #. TRANSLATORS: column for device list #: panels/color/cc-color-panel.c:847 msgid "Calibration" msgstr "" #. TRANSLATORS: this is when an auto-added profile cannot be removed #: panels/color/cc-color-panel.c:928 msgid "Cannot remove automatically added profile" msgstr "" #. TRANSLATORS: this is when there is no profile for the device #: panels/color/cc-color-panel.c:1258 msgid "No profile" msgstr "" #: panels/color/cc-color-panel.c:1287 #, c-format msgid "%i year" msgid_plural "%i years" msgstr[0] "" msgstr[1] "" #: panels/color/cc-color-panel.c:1298 #, c-format msgid "%i month" msgid_plural "%i months" msgstr[0] "" msgstr[1] "" #: panels/color/cc-color-panel.c:1309 #, c-format msgid "%i week" msgid_plural "%i weeks" msgstr[0] "" msgstr[1] "" #. fallback #: panels/color/cc-color-panel.c:1316 msgid "Less than 1 week" msgstr "" #: panels/color/cc-color-panel.c:1378 msgctxt "Colorspace fallback" msgid "Default RGB" msgstr "" #: panels/color/cc-color-panel.c:1383 msgctxt "Colorspace fallback" msgid "Default CMYK" msgstr "" #: panels/color/cc-color-panel.c:1388 msgctxt "Colorspace fallback" msgid "Default Gray" msgstr "" #: panels/color/cc-color-panel.c:1506 panels/color/cc-color-panel.c:1545 #: panels/color/cc-color-panel.c:1556 panels/color/cc-color-panel.c:1567 msgid "Uncalibrated" msgstr "" #: panels/color/cc-color-panel.c:1509 msgid "This device is not color managed." msgstr "" #: panels/color/cc-color-panel.c:1548 msgid "This device is using manufacturing calibrated data." msgstr "" #: panels/color/cc-color-panel.c:1559 msgid "" "This device does not have a profile suitable for whole-screen color " "correction." msgstr "" #: panels/color/cc-color-panel.c:1592 msgid "This device has an old profile that may no longer be accurate." msgstr "" #. TRANSLATORS: this is when the calibration profile age is not #. * specified as it has been autogenerated from the hardware #: panels/color/cc-color-panel.c:1620 msgid "Not specified" msgstr "" #. add the 'No devices detected' entry #: panels/color/cc-color-panel.c:1805 msgid "No devices supporting color management detected" msgstr "" #: panels/color/cc-color-panel.c:2034 msgctxt "Device kind" msgid "Display" msgstr "" #: panels/color/cc-color-panel.c:2036 msgctxt "Device kind" msgid "Scanner" msgstr "" #: panels/color/cc-color-panel.c:2038 msgctxt "Device kind" msgid "Printer" msgstr "" #: panels/color/cc-color-panel.c:2040 msgctxt "Device kind" msgid "Camera" msgstr "" #: panels/color/cc-color-panel.c:2042 msgctxt "Device kind" msgid "Webcam" msgstr "" #. Add some common languages first #: panels/common/cc-common-language.c:533 msgid "English" msgstr "" #: panels/common/cc-common-language.c:535 msgid "British English" msgstr "" #: panels/common/cc-common-language.c:538 msgid "German" msgstr "" #: panels/common/cc-common-language.c:541 msgid "French" msgstr "" #: panels/common/cc-common-language.c:544 msgid "Spanish" msgstr "" #: panels/common/cc-common-language.c:546 msgid "Chinese (simplified)" msgstr "" #: panels/common/cc-common-language.c:549 msgid "Russian" msgstr "" #: panels/common/cc-common-language.c:552 msgid "Arabic" msgstr "" #. Add some common regions #: panels/common/cc-common-language.c:580 msgid "United States" msgstr "" #: panels/common/cc-common-language.c:581 msgid "Germany" msgstr "" #: panels/common/cc-common-language.c:582 msgid "France" msgstr "" #: panels/common/cc-common-language.c:583 msgid "Spain" msgstr "" #: panels/common/cc-common-language.c:584 msgid "China" msgstr "" #: panels/common/cc-language-chooser.c:303 msgid "Select a region" msgstr "" #: panels/common/gdm-languages.c:781 msgid "Unspecified" msgstr "" #. Translators: this is the feature where what you see on your #. * laptop's screen is the same as your external projector. #. * Here, "Mirrored" is being used as an adjective. For example, #. * the Spanish translation could be "Pantallas en Espejo". #. #: panels/display/cc-display-labeler.c:369 #: panels/display/cc-display-panel.c:747 msgid "Mirrored Displays" msgstr "" #: panels/display/cc-display-panel.c:1149 msgid "Confirm reset to defaults" msgstr "" #: panels/display/cc-display-panel.c:1151 msgid "Cancel" msgstr "" #: panels/display/cc-display-panel.c:1151 msgid "Continue" msgstr "" #: panels/display/cc-display-panel.c:1164 msgid "" "This will remove all existing display configurations and reset the current " "layout." msgstr "" #: panels/display/cc-display-settings.c:107 msgctxt "Display rotation" msgid "Landscape" msgstr "" #: panels/display/cc-display-settings.c:110 msgctxt "Display rotation" msgid "Portrait Right" msgstr "" #: panels/display/cc-display-settings.c:113 msgctxt "Display rotation" msgid "Portrait Left" msgstr "" #: panels/display/cc-display-settings.c:116 msgctxt "Display rotation" msgid "Landscape (flipped)" msgstr "" #: panels/display/cc-display-settings.c:190 #, c-format msgid "%.2lf Hz" msgstr "" #: panels/display/cc-display-settings.c:471 msgid "Monitor scale" msgstr "" #: panels/display/cc-display-settings.c:475 #: panels/display/cc-display-settings.ui.h:4 msgid "User interface scale" msgstr "" #: panels/network/cc-network-panel.c:906 msgid "Network proxy" msgstr "" #. Translators: this is the title of the connection details #. * window for vpn connections, it is also used to display #. * vpn connections in the device list. #. #: panels/network/cc-network-panel.c:1085 panels/network/net-vpn.c:287 #: panels/network/net-vpn.c:444 #, c-format msgid "%s VPN" msgstr "" #: panels/network/cc-network-panel.c:1152 msgid "Oops, something has gone wrong. Please contact your software vendor." msgstr "" #: panels/network/cc-network-panel.c:1158 msgid "NetworkManager needs to be running." msgstr "" #. Translators: network device speed #: panels/network/net-device-ethernet.c:50 panels/network/net-device-wifi.c:549 #: panels/network/connection-editor/ce-page-details.c:153 #, c-format msgid "%d Mb/s" msgstr "" #: panels/network/net-device-ethernet.c:107 #: panels/network/net-device-wifi.c:477 msgid "never" msgstr "" #: panels/network/net-device-ethernet.c:117 #: panels/network/net-device-wifi.c:487 msgid "today" msgstr "" #: panels/network/net-device-ethernet.c:119 #: panels/network/net-device-wifi.c:489 msgid "yesterday" msgstr "" #: panels/network/net-device-ethernet.c:121 #: panels/network/net-device-wifi.c:491 #: panels/network/connection-editor/ce-page-details.c:104 #, c-format msgid "%i day ago" msgid_plural "%i days ago" msgstr[0] "" msgstr[1] "" #: panels/network/net-device-ethernet.c:158 panels/network/panel-common.c:679 #: panels/network/network-simple.ui.h:3 panels/network/network-wifi.ui.h:7 #: panels/network/connection-editor/details-page.ui.h:4 msgid "IPv4 Address" msgstr "" #: panels/network/net-device-ethernet.c:159 panels/network/panel-common.c:680 #: panels/network/network-mobile.ui.h:4 panels/network/network-simple.ui.h:4 #: panels/network/network-wifi.ui.h:8 #: panels/network/connection-editor/details-page.ui.h:5 msgid "IPv6 Address" msgstr "" #: panels/network/net-device-ethernet.c:161 #: panels/network/net-device-ethernet.c:163 panels/network/panel-common.c:682 #: panels/network/panel-common.c:684 panels/network/network-mobile.ui.h:3 msgid "IP Address" msgstr "" #: panels/network/net-device-ethernet.c:166 #: panels/network/network-simple.ui.h:2 panels/network/network-wifi.ui.h:9 #: panels/network/connection-editor/details-page.ui.h:6 msgid "Hardware Address" msgstr "" #: panels/network/net-device-ethernet.c:171 #: panels/network/net-device-ethernet.c:173 #: panels/network/net-device-ethernet.c:175 #: panels/network/network-mobile.ui.h:5 panels/network/network-simple.ui.h:5 #: panels/network/network-wifi.ui.h:10 #: panels/network/connection-editor/details-page.ui.h:7 msgid "Default Route" msgstr "" #: panels/network/net-device-ethernet.c:179 panels/network/panel-common.c:688 #: panels/network/network-mobile.ui.h:6 panels/network/network-simple.ui.h:6 #: panels/network/network-wifi.ui.h:11 #: panels/network/connection-editor/details-page.ui.h:8 msgid "DNS4" msgstr "" #: panels/network/net-device-ethernet.c:180 panels/network/panel-common.c:689 #: panels/network/network-mobile.ui.h:7 panels/network/network-simple.ui.h:7 #: panels/network/network-wifi.ui.h:12 #: panels/network/connection-editor/details-page.ui.h:9 msgid "DNS6" msgstr "" #: panels/network/net-device-ethernet.c:182 #: panels/network/net-device-ethernet.c:184 panels/network/panel-common.c:691 #: panels/network/panel-common.c:693 #: panels/network/connection-editor/ip4-page.ui.h:3 #: panels/network/connection-editor/ip6-page.ui.h:3 msgid "DNS" msgstr "" #: panels/network/net-device-ethernet.c:190 panels/network/network-wifi.ui.h:13 msgid "Last used" msgstr "" #. Translators: This is used as the title of the connection #. * details window for ethernet, if there is only a single #. * profile. It is also used to display ethernet in the #. * device list. #. #: panels/network/net-device-ethernet.c:292 #: panels/network/network-ethernet.ui.h:1 panels/network/network-simple.ui.h:1 msgid "Wired" msgstr "" #: panels/network/net-device-ethernet.c:360 #: panels/network/net-device-wifi.c:1751 panels/network/network-ethernet.ui.h:3 #: panels/network/network-mobile.ui.h:9 panels/network/network-simple.ui.h:9 #: panels/network/network-vpn.ui.h:7 msgid "Options…" msgstr "" #: panels/network/net-device-mobile.c:238 msgid "Add new connection" msgstr "" #. TRANSLATORS: this WEP WiFi security #: panels/network/net-device-wifi.c:215 panels/network/net-device-wifi.c:393 #: panels/network/connection-editor/ce-page-details.c:50 msgid "WEP" msgstr "" #. TRANSLATORS: this WPA WiFi security #: panels/network/net-device-wifi.c:219 panels/network/net-device-wifi.c:398 #: panels/network/connection-editor/ce-page-details.c:54 #: panels/network/network-wifi.ui.h:20 msgid "WPA" msgstr "" #. TRANSLATORS: this WPA WiFi security #: panels/network/net-device-wifi.c:223 #: panels/network/connection-editor/ce-page-details.c:58 msgid "WPA2" msgstr "" #. TRANSLATORS: this Enterprise WiFi security #: panels/network/net-device-wifi.c:228 #: panels/network/connection-editor/ce-page-details.c:63 msgid "Enterprise" msgstr "" #: panels/network/net-device-wifi.c:233 panels/network/net-device-wifi.c:383 #: panels/network/connection-editor/ce-page-details.c:68 msgctxt "Wifi security" msgid "None" msgstr "" #: panels/network/net-device-wifi.c:578 #: panels/network/connection-editor/ce-page-details.c:179 msgctxt "Signal strength" msgid "None" msgstr "" #: panels/network/net-device-wifi.c:580 #: panels/network/connection-editor/ce-page-details.c:181 msgctxt "Signal strength" msgid "Weak" msgstr "" #: panels/network/net-device-wifi.c:582 #: panels/network/connection-editor/ce-page-details.c:183 msgctxt "Signal strength" msgid "Ok" msgstr "" #: panels/network/net-device-wifi.c:584 #: panels/network/connection-editor/ce-page-details.c:185 msgctxt "Signal strength" msgid "Good" msgstr "" #: panels/network/net-device-wifi.c:586 #: panels/network/connection-editor/ce-page-details.c:187 msgctxt "Signal strength" msgid "Excellent" msgstr "" #: panels/network/net-device-wifi.c:1260 msgid "" "If you have a connection to the Internet other than wireless, you can set up " "a wireless hotspot to share the connection with others." msgstr "" #: panels/network/net-device-wifi.c:1264 #, c-format msgid "Switching on the wireless hotspot will disconnect you from %s." msgstr "" #: panels/network/net-device-wifi.c:1268 msgid "" "It is not possible to access the Internet through your wireless while the " "hotspot is active." msgstr "" #: panels/network/net-device-wifi.c:1350 msgid "Stop hotspot and disconnect any users?" msgstr "" #: panels/network/net-device-wifi.c:1352 panels/network/net-device-wifi.c:1592 #: panels/network/connection-editor/vpn-helpers.c:181 #: panels/network/connection-editor/vpn-helpers.c:310 #: panels/common/language-chooser.ui.h:2 panels/network/network-wifi.ui.h:1 #: panels/network/connection-editor/connection-editor.ui.h:1 msgid "_Cancel" msgstr "" #: panels/network/net-device-wifi.c:1353 msgid "_Stop Hotspot" msgstr "" #: panels/network/net-device-wifi.c:1454 msgid "System policy prohibits use as a Hotspot" msgstr "" #: panels/network/net-device-wifi.c:1457 msgid "Wireless device does not support Hotspot mode" msgstr "" #: panels/network/net-device-wifi.c:1589 msgid "" "Network details for the selected networks, including passwords and any " "custom configuration will be lost." msgstr "" #: panels/network/net-device-wifi.c:1593 panels/network/network-wifi.ui.h:43 #: panels/network/connection-editor/reset-page.ui.h:2 msgid "_Forget" msgstr "" #: panels/network/net-device-wifi.c:1899 msgid "History" msgstr "" #: panels/network/net-device-wifi.c:1903 panels/wacom/cc-wacom-page.c:467 #: panels/wacom/button-mapping.ui.h:2 msgid "_Close" msgstr "" #. translators: This is the label for the "Forget wireless network" functionality #: panels/network/net-device-wifi.c:1911 msgctxt "Wi-Fi Network" msgid "_Forget" msgstr "" #. TRANSLATORS: this is when the use leaves the PAC textbox blank #: panels/network/net-proxy.c:67 msgid "" "Web Proxy Autodiscovery is used when a Configuration URL is not provided." msgstr "" #. TRANSLATORS: WPAD is bad: if you enable it on an untrusted #. * network, then anyone else on that network can tell your #. * machine that it should proxy all of your web traffic #. * through them. #: panels/network/net-proxy.c:75 msgid "This is not recommended for untrusted public networks." msgstr "" #: panels/network/net-proxy.c:410 msgid "Proxy" msgstr "" #. TRANSLATORS: AP type #: panels/network/panel-common.c:123 msgid "Unknown" msgstr "" #. TRANSLATORS: AP type #: panels/network/panel-common.c:127 msgid "Ad-hoc" msgstr "" #. TRANSLATORS: AP type #: panels/network/panel-common.c:131 msgid "Infrastructure" msgstr "" #. TRANSLATORS: device status #. TRANSLATORS: VPN status #: panels/network/panel-common.c:147 panels/network/panel-common.c:201 msgid "Status unknown" msgstr "" #. TRANSLATORS: device status #: panels/network/panel-common.c:151 msgid "Unmanaged" msgstr "" #. TRANSLATORS: device status #: panels/network/panel-common.c:155 msgid "Unavailable" msgstr "" #. TRANSLATORS: device status #. TRANSLATORS: VPN status #: panels/network/panel-common.c:165 panels/network/panel-common.c:207 msgid "Connecting" msgstr "" #. TRANSLATORS: device status #. TRANSLATORS: VPN status #: panels/network/panel-common.c:169 panels/network/panel-common.c:211 msgid "Authentication required" msgstr "" #. TRANSLATORS: device status #. TRANSLATORS: VPN status #: panels/network/panel-common.c:173 panels/network/panel-common.c:215 msgid "Connected" msgstr "" #. TRANSLATORS: device status #: panels/network/panel-common.c:177 msgid "Disconnecting" msgstr "" #. TRANSLATORS: device status #. TRANSLATORS: VPN status #: panels/network/panel-common.c:181 panels/network/panel-common.c:219 msgid "Connection failed" msgstr "" #. TRANSLATORS: device status #. TRANSLATORS: VPN status #: panels/network/panel-common.c:185 panels/network/panel-common.c:227 msgid "Status unknown (missing)" msgstr "" #. TRANSLATORS: VPN status #: panels/network/panel-common.c:223 msgid "Not connected" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:248 msgid "Configuration failed" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:252 msgid "IP configuration failed" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:256 msgid "IP configuration expired" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:260 msgid "Secrets were required, but not provided" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:264 msgid "802.1x supplicant disconnected" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:268 msgid "802.1x supplicant configuration failed" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:272 msgid "802.1x supplicant failed" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:276 msgid "802.1x supplicant took too long to authenticate" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:280 msgid "PPP service failed to start" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:284 msgid "PPP service disconnected" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:288 msgid "PPP failed" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:292 msgid "DHCP client failed to start" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:296 msgid "DHCP client error" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:300 msgid "DHCP client failed" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:304 msgid "Shared connection service failed to start" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:308 msgid "Shared connection service failed" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:312 msgid "AutoIP service failed to start" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:316 msgid "AutoIP service error" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:320 msgid "AutoIP service failed" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:324 msgid "Line busy" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:328 msgid "No dial tone" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:332 msgid "No carrier could be established" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:336 msgid "Dialing request timed out" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:340 msgid "Dialing attempt failed" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:344 msgid "Modem initialization failed" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:348 msgid "Failed to select the specified APN" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:352 msgid "Not searching for networks" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:356 msgid "Network registration denied" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:360 msgid "Network registration timed out" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:364 msgid "Failed to register with the requested network" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:368 msgid "PIN check failed" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:372 msgid "Firmware for the device may be missing" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:376 msgid "Connection disappeared" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:380 msgid "Existing connection was assumed" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:384 msgid "Modem not found" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:388 msgid "Bluetooth connection failed" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:392 msgid "SIM Card not inserted" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:396 msgid "SIM Pin required" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:400 msgid "SIM Puk required" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:404 msgid "SIM wrong" msgstr "" #. TRANSLATORS: device status reason #: panels/network/panel-common.c:408 msgid "Connection dependency failed" msgstr "" #. TRANSLATORS: device status #: panels/network/panel-common.c:433 msgid "Firmware missing" msgstr "" #. TRANSLATORS: device status #: panels/network/panel-common.c:437 msgid "Cable unplugged" msgstr "" #: panels/region/cinnamon-region-panel-xkblt.c:208 msgid "Layout" msgstr "" #: panels/region/cinnamon-region-panel-xkbot.c:227 #: panels/wacom/wacom-stylus-page.ui.h:1 msgid "Default" msgstr "" #: panels/wacom/cc-wacom-button-row.c:248 #, c-format msgid "Button %d" msgstr "" #: panels/wacom/cc-wacom-mapping-panel.c:229 msgid "Output:" msgstr "" #. Keep ratio switch #: panels/wacom/cc-wacom-mapping-panel.c:241 msgid "Keep aspect ratio (letterbox):" msgstr "" #. Whole-desktop checkbox #: panels/wacom/cc-wacom-mapping-panel.c:252 msgid "Map to single monitor" msgstr "" #: panels/wacom/cc-wacom-nav-button.c:84 #, c-format msgid "%d of %d" msgstr "" #: panels/wacom/cc-wacom-page.c:464 msgid "Display Mapping" msgstr "" #: panels/wacom/cc-wacom-panel.c:666 panels/wacom/wacom-stylus-page.ui.h:9 msgid "Stylus" msgstr "" #: panels/wacom/cc-wacom-panel.c:669 msgid "Tablet" msgstr "" #: panels/wacom/cc-wacom-stylus-page.c:362 msgid "Button" msgstr "" #: panels/wacom/csd-wacom-key-shortcut-button.c:217 msgid "New shortcut…" msgstr "" #: panels/network/connection-editor/ce-page-8021x-security.c:101 #: panels/network/connection-editor/ce-page-security.c:459 #: panels/network/network-wifi.ui.h:6 #: panels/network/connection-editor/details-page.ui.h:3 msgid "Security" msgstr "" #: panels/network/connection-editor/ce-page.c:481 msgid "automatic" msgstr "" #: panels/network/connection-editor/ce-page.c:521 #, c-format msgid "Profile %d" msgstr "" #: panels/network/connection-editor/ce-page-details.c:89 msgid "Never" msgstr "" #: panels/network/connection-editor/ce-page-details.c:100 msgid "Today" msgstr "" #: panels/network/connection-editor/ce-page-details.c:102 msgid "Yesterday" msgstr "" #: panels/network/connection-editor/ce-page-details.c:225 #: panels/network/network-wifi.ui.h:47 msgid "Details" msgstr "" #: panels/network/connection-editor/ce-page-ethernet.c:215 #: panels/network/connection-editor/ce-page-vpn.c:226 #: panels/network/connection-editor/ce-page-wifi.c:227 #: panels/network/network-wifi.ui.h:48 msgid "Identity" msgstr "" #: panels/network/connection-editor/ce-page-ip4.c:202 #: panels/network/connection-editor/ce-page-ip4.c:461 #: panels/network/connection-editor/ce-page-ip6.c:180 #: panels/network/connection-editor/ce-page-ip6.c:427 msgid "Address" msgstr "" #: panels/network/connection-editor/ce-page-ip4.c:215 #: panels/network/connection-editor/ce-page-ip4.c:474 msgid "Netmask" msgstr "" #: panels/network/connection-editor/ce-page-ip4.c:229 #: panels/network/connection-editor/ce-page-ip4.c:487 #: panels/network/connection-editor/ce-page-ip6.c:206 #: panels/network/connection-editor/ce-page-ip6.c:453 #: panels/network/network-vpn.ui.h:2 msgid "Gateway" msgstr "" #: panels/network/connection-editor/ce-page-ip4.c:250 #: panels/network/connection-editor/ce-page-ip6.c:223 msgid "Delete Address" msgstr "" #: panels/network/connection-editor/ce-page-ip4.c:305 #: panels/network/connection-editor/ce-page-ip6.c:277 msgid "Add" msgstr "" #: panels/network/connection-editor/ce-page-ip4.c:368 #: panels/network/connection-editor/ce-page-ip6.c:334 msgid "Server" msgstr "" #: panels/network/connection-editor/ce-page-ip4.c:385 #: panels/network/connection-editor/ce-page-ip6.c:351 msgid "Delete DNS Server" msgstr "" #. Translators: Please see https://en.wikipedia.org/wiki/Metrics_(networking) #: panels/network/connection-editor/ce-page-ip4.c:501 #: panels/network/connection-editor/ce-page-ip6.c:467 msgctxt "network parameters" msgid "Metric" msgstr "" #: panels/network/connection-editor/ce-page-ip4.c:522 #: panels/network/connection-editor/ce-page-ip6.c:484 msgid "Delete Route" msgstr "" #: panels/network/connection-editor/ce-page-ip4.c:626 #: panels/network/network-wifi.ui.h:28 msgid "Automatic (DHCP)" msgstr "" #: panels/network/connection-editor/ce-page-ip4.c:630 #: panels/network/connection-editor/ce-page-ip6.c:592 #: panels/network/network-wifi.ui.h:27 msgid "Manual" msgstr "" #: panels/network/connection-editor/ce-page-ip4.c:634 #: panels/network/connection-editor/ce-page-ip6.c:596 msgid "Link-Local Only" msgstr "" #: panels/network/connection-editor/ce-page-ip4.c:980 #: panels/network/network-wifi.ui.h:49 msgid "IPv4" msgstr "" #: panels/network/connection-editor/ce-page-ip6.c:193 #: panels/network/connection-editor/ce-page-ip6.c:440 msgid "Prefix" msgstr "" #: panels/network/connection-editor/ce-page-ip6.c:584 #: panels/network/connection-editor/ethernet-page.ui.h:1 #: panels/network/connection-editor/ip4-page.ui.h:4 #: panels/network/connection-editor/ip6-page.ui.h:4 #: panels/network/wireless-security/eap-method-peap.ui.h:2 msgid "Automatic" msgstr "" #: panels/network/connection-editor/ce-page-ip6.c:588 msgid "Automatic, DHCP only" msgstr "" #: panels/network/connection-editor/ce-page-ip6.c:898 #: panels/network/network-wifi.ui.h:50 msgid "IPv6" msgstr "" #: panels/network/connection-editor/ce-page-reset.c:78 msgid "Reset" msgstr "" #: panels/network/connection-editor/ce-page-security.c:248 msgctxt "Wi-Fi/Ethernet security" msgid "None" msgstr "" #: panels/network/connection-editor/ce-page-security.c:271 msgid "WEP 40/128-bit Key (Hex or ASCII)" msgstr "" #: panels/network/connection-editor/ce-page-security.c:281 msgid "WEP 128-bit Passphrase" msgstr "" #: panels/network/connection-editor/ce-page-security.c:294 #: panels/network/wireless-security/wireless-security.c:463 msgid "LEAP" msgstr "" #: panels/network/connection-editor/ce-page-security.c:307 msgid "Dynamic WEP (802.1x)" msgstr "" #: panels/network/connection-editor/ce-page-security.c:321 msgid "WPA & WPA2 Personal" msgstr "" #: panels/network/connection-editor/ce-page-security.c:335 msgid "WPA & WPA2 Enterprise" msgstr "" #: panels/network/connection-editor/firewall-helpers.c:49 #: panels/network/connection-editor/firewall-helpers.c:118 msgctxt "Firewall zone" msgid "Default" msgstr "" #: panels/network/connection-editor/firewall-helpers.c:50 msgid "The zone defines the trust level of the connection" msgstr "" #: panels/network/connection-editor/net-connection-editor.c:295 msgid "Unable to open connection editor" msgstr "" #: panels/network/connection-editor/net-connection-editor.c:313 msgid "New Profile" msgstr "" #: panels/network/connection-editor/net-connection-editor.c:545 msgid "_Add" msgstr "" #: panels/network/connection-editor/net-connection-editor.c:634 msgid "VPN" msgstr "" #: panels/network/connection-editor/net-connection-editor.c:782 msgid "Import from file…" msgstr "" #: panels/network/connection-editor/net-connection-editor.c:816 msgid "Add VPN" msgstr "" #: panels/network/connection-editor/vpn-helpers.c:141 msgid "Cannot import VPN connection" msgstr "" #: panels/network/connection-editor/vpn-helpers.c:143 #, c-format msgid "" "The file ā€œ%sā€ could not be read or does not contain recognized VPN " "connection information\n" "\n" "Error: %s." msgstr "" #: panels/network/connection-editor/vpn-helpers.c:178 msgid "Select file to import" msgstr "" #: panels/network/connection-editor/vpn-helpers.c:182 msgid "_Open" msgstr "" #: panels/network/connection-editor/vpn-helpers.c:230 #, c-format msgid "A file named ā€œ%sā€ already exists." msgstr "" #: panels/network/connection-editor/vpn-helpers.c:232 msgid "_Replace" msgstr "" #: panels/network/connection-editor/vpn-helpers.c:234 #, c-format msgid "Do you want to replace %s with the VPN connection you are saving?" msgstr "" #: panels/network/connection-editor/vpn-helpers.c:270 msgid "Cannot export VPN connection" msgstr "" #: panels/network/connection-editor/vpn-helpers.c:272 #, c-format msgid "" "The VPN connection ā€œ%sā€ could not be exported to %s.\n" "\n" "Error: %s." msgstr "" #: panels/network/connection-editor/vpn-helpers.c:307 msgid "Export VPN connection" msgstr "" #: panels/network/connection-editor/vpn-helpers.c:311 msgid "_Save" msgstr "" #: panels/network/wireless-security/eap-method.c:69 msgid "undefined error in 802.1x security (wpa-eap)" msgstr "" #: panels/network/wireless-security/eap-method.c:245 msgid "no file selected" msgstr "" #: panels/network/wireless-security/eap-method.c:276 msgid "unspecified error validating eap-method file" msgstr "" #: panels/network/wireless-security/eap-method.c:321 msgid "DER, PEM, or PKCS#12 private keys (*.der, *.pem, *.p12, *.key)" msgstr "" #: panels/network/wireless-security/eap-method.c:324 msgid "DER or PEM certificates (*.der, *.pem, *.crt, *.cer)" msgstr "" #: panels/network/wireless-security/eap-method-fast.c:72 msgid "missing EAP-FAST PAC file" msgstr "" #: panels/network/wireless-security/eap-method-fast.c:268 #: panels/network/wireless-security/eap-method-peap.c:302 #: panels/network/wireless-security/eap-method-ttls.c:333 msgid "GTC" msgstr "" #: panels/network/wireless-security/eap-method-fast.c:283 #: panels/network/wireless-security/eap-method-peap.c:272 #: panels/network/wireless-security/eap-method-ttls.c:288 msgid "MSCHAPv2" msgstr "" #: panels/network/wireless-security/eap-method-fast.c:406 msgid "Choose a PAC file" msgstr "" #: panels/network/wireless-security/eap-method-fast.c:413 msgid "PAC files (*.pac)" msgstr "" #: panels/network/wireless-security/eap-method-leap.c:65 msgid "missing EAP-LEAP username" msgstr "" #: panels/network/wireless-security/eap-method-leap.c:74 msgid "missing EAP-LEAP password" msgstr "" #: panels/network/wireless-security/eap-method-peap.c:63 #, c-format msgid "invalid EAP-PEAP CA certificate: %s" msgstr "" #: panels/network/wireless-security/eap-method-peap.c:68 msgid "invalid EAP-PEAP CA certificate: no certificate specified" msgstr "" #: panels/network/wireless-security/eap-method-peap.c:287 #: panels/network/wireless-security/eap-method-ttls.c:318 #: panels/network/wireless-security/wireless-security.c:439 msgid "MD5" msgstr "" #: panels/network/wireless-security/eap-method-peap.c:381 #: panels/network/wireless-security/eap-method-tls.c:501 #: panels/network/wireless-security/eap-method-ttls.c:412 msgid "Choose a Certificate Authority certificate" msgstr "" #: panels/network/wireless-security/eap-method-simple.c:74 msgid "missing EAP username" msgstr "" #: panels/network/wireless-security/eap-method-simple.c:87 msgid "missing EAP password" msgstr "" #: panels/network/wireless-security/eap-method-tls.c:68 msgid "missing EAP-TLS identity" msgstr "" #: panels/network/wireless-security/eap-method-tls.c:77 #, c-format msgid "invalid EAP-TLS CA certificate: %s" msgstr "" #: panels/network/wireless-security/eap-method-tls.c:84 msgid "invalid EAP-TLS CA certificate: no certificate specified" msgstr "" #: panels/network/wireless-security/eap-method-tls.c:95 msgid "invalid EAP-TLS password: missing" msgstr "" #: panels/network/wireless-security/eap-method-tls.c:109 #, c-format msgid "invalid EAP-TLS private-key: %s" msgstr "" #: panels/network/wireless-security/eap-method-tls.c:119 #, c-format msgid "invalid EAP-TLS user-certificate: %s" msgstr "" #: panels/network/wireless-security/eap-method-tls.c:316 msgid "Unencrypted private keys are insecure" msgstr "" #: panels/network/wireless-security/eap-method-tls.c:319 msgid "" "The selected private key does not appear to be protected by a password. " "This could allow your security credentials to be compromised. Please select " "a password-protected private key.\n" "\n" "(You can password-protect your private key with openssl)" msgstr "" #: panels/network/wireless-security/eap-method-tls.c:495 msgid "Choose your personal certificate" msgstr "" #: panels/network/wireless-security/eap-method-tls.c:507 msgid "Choose your private key" msgstr "" #: panels/network/wireless-security/eap-method-ttls.c:63 #, c-format msgid "invalid EAP-TTLS CA certificate: %s" msgstr "" #: panels/network/wireless-security/eap-method-ttls.c:68 msgid "invalid EAP-TTLS CA certificate: no certificate specified" msgstr "" #: panels/network/wireless-security/eap-method-ttls.c:258 msgid "PAP" msgstr "" #: panels/network/wireless-security/eap-method-ttls.c:273 msgid "MSCHAP" msgstr "" #: panels/network/wireless-security/eap-method-ttls.c:303 msgid "CHAP" msgstr "" #: panels/network/wireless-security/wireless-security.c:87 msgid "Unknown error validating 802.1x security" msgstr "" #: panels/network/wireless-security/wireless-security.c:451 msgid "TLS" msgstr "" #: panels/network/wireless-security/wireless-security.c:475 msgid "PWD" msgstr "" #: panels/network/wireless-security/wireless-security.c:486 msgid "FAST" msgstr "" #: panels/network/wireless-security/wireless-security.c:497 msgid "Tunneled TLS" msgstr "" #: panels/network/wireless-security/wireless-security.c:508 msgid "Protected EAP (PEAP)" msgstr "" #: panels/network/wireless-security/ws-leap.c:63 msgid "missing leap-username" msgstr "" #: panels/network/wireless-security/ws-leap.c:74 msgid "missing leap-password" msgstr "" #: panels/network/wireless-security/ws-wep-key.c:107 msgid "missing wep-key" msgstr "" #: panels/network/wireless-security/ws-wep-key.c:116 #, c-format msgid "invalid wep-key: key with a length of %zu must contain only hex-digits" msgstr "" #: panels/network/wireless-security/ws-wep-key.c:124 #, c-format msgid "" "invalid wep-key: key with a length of %zu must contain only ascii characters" msgstr "" #: panels/network/wireless-security/ws-wep-key.c:130 #, c-format msgid "" "invalid wep-key: wrong key length %zu. A key must be either of length 5/13 " "(ascii) or 10/26 (hex)" msgstr "" #: panels/network/wireless-security/ws-wep-key.c:137 msgid "invalid wep-key: passphrase must be non-empty" msgstr "" #: panels/network/wireless-security/ws-wep-key.c:139 msgid "invalid wep-key: passphrase must be shorter than 64 characters" msgstr "" #: panels/network/wireless-security/ws-wpa-psk.c:70 #, c-format msgid "" "invalid wpa-psk: invalid key-length %zu. Must be [8,63] bytes or 64 hex " "digits" msgstr "" #: panels/network/wireless-security/ws-wpa-psk.c:79 msgid "invalid wpa-psk: cannot interpret key with 64 bytes as hex" msgstr "" #: shell/cc-shell-nav-bar.c:117 msgid "_All Settings" msgstr "" #: shell/control-center.c:58 msgid "Enable verbose mode" msgstr "" #: shell/control-center.c:59 msgid "Show the overview" msgstr "" #: shell/control-center.c:60 shell/control-center.c:61 #: shell/control-center.c:62 msgid "Show help options" msgstr "" #: shell/control-center.c:63 msgid "Panel to display" msgstr "" #: shell/control-center.c:85 msgid "- System Settings" msgstr "" #: shell/control-center.c:93 #, c-format msgid "" "%s\n" "Run '%s --help' to see a full list of available command line options.\n" msgstr "" #: shell/control-center.c:222 msgid "Help" msgstr "" #: shell/control-center.c:223 msgid "Quit" msgstr "" #. translators: This is the default hotspot name, need to be less than 32-bytes #: shell/hostname-helper.c:189 msgctxt "hotspot" msgid "Hotspot" msgstr "" #: panels/color/color.ui.h:3 generate_additional_files.py:23 msgid "Color" msgstr "" #: panels/color/color.ui.h:4 msgid "Each device needs an up to date color profile to be color managed." msgstr "" #: panels/color/color.ui.h:5 msgid "Add device" msgstr "" #: panels/color/color.ui.h:6 msgid "Add a virtual device" msgstr "" #: panels/color/color.ui.h:7 msgid "Delete device" msgstr "" #: panels/color/color.ui.h:8 msgid "Remove a device" msgstr "" #: panels/color/color.ui.h:10 msgid "Set this profile for all users on this computer" msgstr "" #: panels/color/color.ui.h:11 msgid "Add profile" msgstr "" #: panels/color/color.ui.h:12 msgid "Remove profile" msgstr "" #: panels/color/color.ui.h:13 msgid "View details" msgstr "" #: panels/color/color.ui.h:14 msgid "Device type:" msgstr "" #: panels/color/color.ui.h:15 msgid "Manufacturer:" msgstr "" #: panels/color/color.ui.h:16 msgid "Model:" msgstr "" #: panels/color/color.ui.h:17 msgid "" "Image files can be dragged on this window to auto-complete the above fields." msgstr "" #: panels/common/language-chooser.ui.h:1 msgid "Select a language" msgstr "" #: panels/common/language-chooser.ui.h:3 msgid "_Select" msgstr "" #: panels/display/cc-display-panel.ui.h:1 msgid "Display Arrangement" msgstr "" #: panels/display/cc-display-panel.ui.h:2 msgid "Set as Primary" msgstr "" #: panels/display/cc-display-panel.ui.h:3 msgid "Display Configuration" msgstr "" #: panels/display/cc-display-panel.ui.h:4 msgid "Join Displays" msgstr "" #: panels/display/cc-display-panel.ui.h:5 msgid "Mirror" msgstr "" #: panels/display/cc-display-panel.ui.h:6 msgid "Displays" msgstr "" #: panels/display/cc-display-panel.ui.h:7 msgid "Reset to Defaults" msgstr "" #: panels/display/cc-display-panel.ui.h:8 msgid "Cancel changes" msgstr "" #: panels/display/cc-display-panel.ui.h:9 msgid "Apply" msgstr "" #: panels/display/cc-display-settings.ui.h:1 msgid "Resolution" msgstr "" #: panels/display/cc-display-settings.ui.h:2 msgid "Refresh Rate" msgstr "" #: panels/display/cc-display-settings.ui.h:3 msgid "Rotation" msgstr "" #: panels/display/cc-display-settings.ui.h:5 msgid "Adjust for TV" msgstr "" #: panels/network/network-ethernet.ui.h:2 msgid "_Add Profile…" msgstr "" #: panels/network/network-mobile.ui.h:1 msgid "IMEI" msgstr "" #: panels/network/network-mobile.ui.h:2 msgid "Provider" msgstr "" #: panels/network/network-mobile.ui.h:8 generate_additional_files.py:63 msgid "Network" msgstr "" #: panels/network/network-proxy.ui.h:1 msgctxt "proxy method" msgid "None" msgstr "" #: panels/network/network-proxy.ui.h:2 msgctxt "proxy method" msgid "Manual" msgstr "" #: panels/network/network-proxy.ui.h:3 msgctxt "proxy method" msgid "Automatic" msgstr "" #: panels/network/network-proxy.ui.h:4 msgid "_Method" msgstr "" #: panels/network/network-proxy.ui.h:5 msgid "_Configuration URL" msgstr "" #: panels/network/network-proxy.ui.h:6 msgid "_HTTP Proxy" msgstr "" #: panels/network/network-proxy.ui.h:7 msgid "H_TTPS Proxy" msgstr "" #: panels/network/network-proxy.ui.h:8 msgid "_FTP Proxy" msgstr "" #: panels/network/network-proxy.ui.h:9 msgid "_Socks Host" msgstr "" #: panels/network/network-proxy.ui.h:10 msgid "_Ignore Hosts" msgstr "" #: panels/network/network-proxy.ui.h:11 msgid "HTTP proxy port" msgstr "" #: panels/network/network-proxy.ui.h:12 msgid "HTTPS proxy port" msgstr "" #: panels/network/network-proxy.ui.h:13 msgid "FTP proxy port" msgstr "" #: panels/network/network-proxy.ui.h:14 msgid "Socks proxy port" msgstr "" #: panels/network/network-simple.ui.h:8 msgid "Turn device off" msgstr "" #: panels/network/network.ui.h:1 msgid "Add Device" msgstr "" #: panels/network/network.ui.h:2 msgid "Remove Device" msgstr "" #: panels/network/network-vpn.ui.h:1 msgid "VPN Type" msgstr "" #: panels/network/network-vpn.ui.h:3 msgid "Group Name" msgstr "" #: panels/network/network-vpn.ui.h:4 msgid "Group Password" msgstr "" #: panels/network/network-vpn.ui.h:5 msgid "Username" msgstr "" #: panels/network/network-vpn.ui.h:6 msgid "Turn VPN connection off" msgstr "" #: panels/network/network-wifi.ui.h:2 #: panels/network/connection-editor/connection-editor.ui.h:2 msgid "_Apply" msgstr "" #: panels/network/network-wifi.ui.h:3 msgid "Automatic _Connect" msgstr "" #: panels/network/network-wifi.ui.h:4 #: panels/network/connection-editor/details-page.ui.h:1 msgid "Signal Strength" msgstr "" #: panels/network/network-wifi.ui.h:5 #: panels/network/connection-editor/details-page.ui.h:2 msgid "Link speed" msgstr "" #: panels/network/network-wifi.ui.h:14 msgid "details" msgstr "" #: panels/network/network-wifi.ui.h:15 #: panels/network/connection-editor/wifi-page.ui.h:1 msgid "_SSID" msgstr "" #: panels/network/network-wifi.ui.h:16 #: panels/network/connection-editor/wifi-page.ui.h:2 msgid "_BSSID" msgstr "" #: panels/network/network-wifi.ui.h:17 #: panels/network/connection-editor/security-page.ui.h:1 msgid "S_ecurity" msgstr "" #: panels/network/network-wifi.ui.h:18 #: panels/network/wireless-security/eap-method-leap.ui.h:2 #: panels/network/wireless-security/eap-method-simple.ui.h:2 #: panels/network/wireless-security/ws-leap.ui.h:2 #: panels/network/wireless-security/ws-wpa-psk.ui.h:1 msgid "_Password" msgstr "" #: panels/network/network-wifi.ui.h:19 #: panels/network/connection-editor/wifi-page.ui.h:3 msgid "My Home Network" msgstr "" #: panels/network/network-wifi.ui.h:21 msgid "None" msgstr "" #: panels/network/network-wifi.ui.h:22 msgid "Show P_assword" msgstr "" #: panels/network/network-wifi.ui.h:23 msgid "Make available to other users" msgstr "" #: panels/network/network-wifi.ui.h:24 msgid "identity" msgstr "" #: panels/network/network-wifi.ui.h:25 #: panels/network/connection-editor/ip4-page.ui.h:1 msgid "IPv_4" msgstr "" #: panels/network/network-wifi.ui.h:26 #: panels/network/connection-editor/ip4-page.ui.h:2 #: panels/network/connection-editor/ip6-page.ui.h:2 msgid "_Addresses" msgstr "" #: panels/network/network-wifi.ui.h:29 msgid "Automatic (DHCP) addresses only" msgstr "" #: panels/network/network-wifi.ui.h:30 msgid "Link-local only" msgstr "" #: panels/network/network-wifi.ui.h:31 msgid "Shared with other computers" msgstr "" #: panels/network/network-wifi.ui.h:32 panels/wacom/wacom-stylus-page.ui.h:6 msgid "Disabled" msgstr "" #: panels/network/network-wifi.ui.h:33 #: panels/network/connection-editor/ip4-page.ui.h:6 #: panels/network/connection-editor/ip6-page.ui.h:6 msgid "Routes" msgstr "" #: panels/network/network-wifi.ui.h:34 msgid "_Ignore automatically obtained routes" msgstr "" #: panels/network/network-wifi.ui.h:35 #: panels/network/connection-editor/ip4-page.ui.h:8 #: panels/network/connection-editor/ip6-page.ui.h:8 msgid "Use this connection _only for resources on its network" msgstr "" #: panels/network/network-wifi.ui.h:36 msgid "ipv4" msgstr "" #: panels/network/network-wifi.ui.h:37 #: panels/network/connection-editor/ip6-page.ui.h:1 msgid "IPv_6" msgstr "" #: panels/network/network-wifi.ui.h:38 msgid "ipv6" msgstr "" #: panels/network/network-wifi.ui.h:39 #: panels/network/connection-editor/ethernet-page.ui.h:11 #: panels/network/connection-editor/wifi-page.ui.h:4 msgid "_MAC Address" msgstr "" #: panels/network/network-wifi.ui.h:40 msgid "_Cloned MAC Address" msgstr "" #: panels/network/network-wifi.ui.h:41 msgid "hardware" msgstr "" #: panels/network/network-wifi.ui.h:42 #: panels/network/connection-editor/reset-page.ui.h:1 msgid "_Reset" msgstr "" #: panels/network/network-wifi.ui.h:44 msgid "" "Reset the settings for this connection to their defaults, but remember as a " "preferred connection." msgstr "" #: panels/network/network-wifi.ui.h:45 msgid "" "Remove all details relating to this network and do not try to automatically " "connect to it." msgstr "" #: panels/network/network-wifi.ui.h:46 msgid "reset" msgstr "" #: panels/network/network-wifi.ui.h:51 msgid "Hardware" msgstr "" #: panels/network/network-wifi.ui.h:52 msgctxt "tab" msgid "Reset" msgstr "" #: panels/network/network-wifi.ui.h:53 msgid "Wi-Fi Hotspot" msgstr "" #: panels/network/network-wifi.ui.h:54 msgid "_Turn On" msgstr "" #: panels/network/network-wifi.ui.h:55 msgid "Wi-Fi" msgstr "" #: panels/network/network-wifi.ui.h:56 msgid "Turn Wi-Fi off" msgstr "" #: panels/network/network-wifi.ui.h:57 msgid "_Use as Hotspot…" msgstr "" #: panels/network/network-wifi.ui.h:58 msgid "_Connect to Hidden Network…" msgstr "" #: panels/network/network-wifi.ui.h:59 msgid "_History" msgstr "" #: panels/network/network-wifi.ui.h:60 msgid "Switch off to connect to a Wi-Fi network" msgstr "" #: panels/network/network-wifi.ui.h:61 msgid "Network Name" msgstr "" #: panels/network/network-wifi.ui.h:62 msgid "Connected Devices" msgstr "" #: panels/network/network-wifi.ui.h:63 msgid "Security type" msgstr "" #: panels/network/network-wifi.ui.h:64 msgid "Password" msgstr "" #: panels/region/cinnamon-region-panel-layout-chooser.ui.h:1 msgid "Choose a Layout" msgstr "" #: panels/region/cinnamon-region-panel-layout-chooser.ui.h:2 msgid "Preview" msgstr "" #: panels/region/cinnamon-region-panel-layout-chooser.ui.h:3 msgid "Select an input source to add" msgstr "" #: panels/region/cinnamon-region-panel-options-dialog.ui.h:1 msgid "Keyboard Layout Options" msgstr "" #: panels/region/cinnamon-region-panel.ui.h:1 msgid "Region and Language" msgstr "" #: panels/region/cinnamon-region-panel.ui.h:2 msgid "Add Layout" msgstr "" #: panels/region/cinnamon-region-panel.ui.h:3 msgid "Remove Layout" msgstr "" #: panels/region/cinnamon-region-panel.ui.h:4 msgid "Move Up" msgstr "" #: panels/region/cinnamon-region-panel.ui.h:5 msgid "Move Down" msgstr "" #: panels/region/cinnamon-region-panel.ui.h:6 msgid "Preview Layout" msgstr "" #: panels/region/cinnamon-region-panel.ui.h:7 msgid "Include less-common layouts in the selection list" msgstr "" #: panels/region/cinnamon-region-panel.ui.h:8 msgid "Use the same layout for all windows" msgstr "" #: panels/region/cinnamon-region-panel.ui.h:9 msgid "Allow different layouts for individual windows" msgstr "" #: panels/region/cinnamon-region-panel.ui.h:10 msgid "New windows use the default layout" msgstr "" #: panels/region/cinnamon-region-panel.ui.h:11 msgid "New windows use the previous window's layout" msgstr "" #: panels/region/cinnamon-region-panel.ui.h:12 msgid "Display options" msgstr "" #: panels/region/cinnamon-region-panel.ui.h:13 msgid "Use a country flag, if available, to represent keyboard layouts" msgstr "" #: panels/region/cinnamon-region-panel.ui.h:14 msgid "" "Show the layout name instead of the group name when using text to represent " "a layout" msgstr "" #: panels/region/cinnamon-region-panel.ui.h:15 msgid "Prefer upper-case when using text to represent a layout" msgstr "" #: panels/region/cinnamon-region-panel.ui.h:16 msgid "_Options..." msgstr "" #: panels/region/cinnamon-region-panel.ui.h:17 msgid "View and edit keyboard layout options" msgstr "" #: panels/region/cinnamon-region-panel.ui.h:18 msgid "Reset to De_faults" msgstr "" #: panels/region/cinnamon-region-panel.ui.h:19 msgid "" "Replace the current keyboard layout settings with the\n" "default settings" msgstr "" #: panels/wacom/button-mapping.ui.h:1 msgid "Map Buttons" msgstr "" #: panels/wacom/button-mapping.ui.h:3 msgid "Map buttons to functions" msgstr "" #: panels/wacom/button-mapping.ui.h:4 msgid "" "To edit a shortcut, choose the ā€œSend Keystrokeā€ action, press the keyboard " "shortcut button and hold down the new keys or press Backspace to clear." msgstr "" #: panels/wacom/cinnamon-wacom-properties.ui.h:1 msgid "No tablet detected" msgstr "" #: panels/wacom/cinnamon-wacom-properties.ui.h:2 msgid "Please plug in or turn on your Wacom tablet" msgstr "" #: panels/wacom/cinnamon-wacom-properties.ui.h:3 msgid "Bluetooth Settings" msgstr "" #: panels/wacom/cinnamon-wacom-properties.ui.h:4 msgid "Wacom Tablet" msgstr "" #: panels/wacom/cinnamon-wacom-properties.ui.h:5 msgid "Tracking Mode" msgstr "" #: panels/wacom/cinnamon-wacom-properties.ui.h:6 msgid "Left-Handed Orientation" msgstr "" #: panels/wacom/cinnamon-wacom-properties.ui.h:7 msgid "Map to Monitor…" msgstr "" #: panels/wacom/cinnamon-wacom-properties.ui.h:8 msgid "Map Buttons…" msgstr "" #: panels/wacom/cinnamon-wacom-properties.ui.h:9 msgid "Calibrate…" msgstr "" #: panels/wacom/cinnamon-wacom-properties.ui.h:10 msgid "Adjust mouse settings" msgstr "" #: panels/wacom/cinnamon-wacom-properties.ui.h:11 msgid "Adjust display resolution" msgstr "" #: panels/wacom/cinnamon-wacom-properties.ui.h:12 msgid "Decouple Display" msgstr "" #: panels/wacom/cinnamon-wacom-properties.ui.h:13 msgid "Tablet (absolute)" msgstr "" #: panels/wacom/cinnamon-wacom-properties.ui.h:14 msgid "Touchpad (relative)" msgstr "" #: panels/wacom/wacom-stylus-page.ui.h:2 msgid "Middle Mouse Button Click" msgstr "" #: panels/wacom/wacom-stylus-page.ui.h:3 msgid "Right Mouse Button Click" msgstr "" #: panels/wacom/wacom-stylus-page.ui.h:4 msgid "Back" msgstr "" #: panels/wacom/wacom-stylus-page.ui.h:5 msgid "Forward" msgstr "" #: panels/wacom/wacom-stylus-page.ui.h:7 msgid "No stylus found" msgstr "" #: panels/wacom/wacom-stylus-page.ui.h:8 msgid "Please move your stylus to the proximity of the tablet to configure it" msgstr "" #: panels/wacom/wacom-stylus-page.ui.h:10 msgid "Eraser Pressure Feel" msgstr "" #: panels/wacom/wacom-stylus-page.ui.h:11 msgid "Soft" msgstr "" #: panels/wacom/wacom-stylus-page.ui.h:12 msgid "Firm" msgstr "" #: panels/wacom/wacom-stylus-page.ui.h:13 msgid "Top Button" msgstr "" #: panels/wacom/wacom-stylus-page.ui.h:14 msgid "Lower Button" msgstr "" #: panels/wacom/wacom-stylus-page.ui.h:15 msgid "Lowest Button" msgstr "" #: panels/wacom/wacom-stylus-page.ui.h:16 msgid "Tip Pressure Feel" msgstr "" #: panels/wacom/wacom-stylus-page.ui.h:17 msgid "Test Your _Settings" msgstr "" #: panels/network/connection-editor/8021x-security-page.ui.h:1 msgid "802.1x _Security" msgstr "" #: panels/network/connection-editor/8021x-security-page.ui.h:2 #: panels/network/connection-editor/security-page.ui.h:3 msgid "page 1" msgstr "" #: panels/network/connection-editor/8021x-security-page.ui.h:3 #: panels/network/connection-editor/security-page.ui.h:4 #: panels/network/wireless-security/eap-method-fast.ui.h:5 #: panels/network/wireless-security/eap-method-peap.ui.h:5 #: panels/network/wireless-security/eap-method-ttls.ui.h:2 msgid "Anony_mous identity" msgstr "" #: panels/network/connection-editor/8021x-security-page.ui.h:4 #: panels/network/connection-editor/security-page.ui.h:5 msgid "Inner _authentication" msgstr "" #: panels/network/connection-editor/8021x-security-page.ui.h:5 #: panels/network/connection-editor/security-page.ui.h:6 msgid "page 2" msgstr "" #: panels/network/connection-editor/details-page.ui.h:10 msgid "Last Used" msgstr "" #: panels/network/connection-editor/ethernet-page.ui.h:2 msgid "Twisted Pair (TP)" msgstr "" #: panels/network/connection-editor/ethernet-page.ui.h:3 msgid "Attachment Unit Interface (AUI)" msgstr "" #: panels/network/connection-editor/ethernet-page.ui.h:4 msgid "BNC" msgstr "" #: panels/network/connection-editor/ethernet-page.ui.h:5 msgid "Media Independent Interface (MII)" msgstr "" #: panels/network/connection-editor/ethernet-page.ui.h:6 msgid "10 Mb/s" msgstr "" #: panels/network/connection-editor/ethernet-page.ui.h:7 msgid "100 Mb/s" msgstr "" #: panels/network/connection-editor/ethernet-page.ui.h:8 msgid "1 Gb/s" msgstr "" #: panels/network/connection-editor/ethernet-page.ui.h:9 msgid "10 Gb/s" msgstr "" #: panels/network/connection-editor/ethernet-page.ui.h:10 #: panels/network/connection-editor/vpn-page.ui.h:1 msgid "_Name" msgstr "" #: panels/network/connection-editor/ethernet-page.ui.h:12 msgid "M_TU" msgstr "" #: panels/network/connection-editor/ethernet-page.ui.h:13 #: panels/network/connection-editor/wifi-page.ui.h:5 msgid "_Cloned Address" msgstr "" #: panels/network/connection-editor/ethernet-page.ui.h:14 msgid "bytes" msgstr "" #: panels/network/connection-editor/ethernet-page.ui.h:15 #: panels/network/connection-editor/vpn-page.ui.h:3 msgid "Make available to other _users" msgstr "" #: panels/network/connection-editor/ethernet-page.ui.h:16 #: panels/network/connection-editor/wifi-page.ui.h:7 msgid "Connect _automatically" msgstr "" #: panels/network/connection-editor/ethernet-page.ui.h:17 #: panels/network/connection-editor/security-page.ui.h:2 #: panels/network/connection-editor/vpn-page.ui.h:2 msgid "Firewall _Zone" msgstr "" #: panels/network/connection-editor/ip4-page.ui.h:5 #: panels/network/connection-editor/ip6-page.ui.h:5 msgid "Automatic DNS" msgstr "" #: panels/network/connection-editor/ip4-page.ui.h:7 #: panels/network/connection-editor/ip6-page.ui.h:7 msgid "Automatic Routes" msgstr "" #: panels/network/connection-editor/reset-page.ui.h:3 msgid "" "Reset the settings for this network, including passwords, but remember it as " "a preferred network" msgstr "" #: panels/network/connection-editor/reset-page.ui.h:4 msgid "" "Remove all details relating to this network and do not try to automatically " "connect" msgstr "" #: panels/network/connection-editor/vpn-page.ui.h:4 msgid "(Error: unable to load VPN connection editor)" msgstr "" #: panels/network/connection-editor/wifi-page.ui.h:6 msgid "Make available to _other users" msgstr "" #: panels/network/wireless-security/eap-method-fast.ui.h:1 #: panels/network/wireless-security/eap-method-peap.ui.h:1 #: panels/network/wireless-security/eap-method-ttls.ui.h:1 #: panels/network/wireless-security/ws-dynamic-wep.ui.h:1 #: panels/network/wireless-security/ws-wpa-eap.ui.h:1 msgid " " msgstr "" #: panels/network/wireless-security/eap-method-fast.ui.h:2 msgid "Anonymous" msgstr "" #: panels/network/wireless-security/eap-method-fast.ui.h:3 msgid "Authenticated" msgstr "" #: panels/network/wireless-security/eap-method-fast.ui.h:4 msgid "Both" msgstr "" #: panels/network/wireless-security/eap-method-fast.ui.h:6 msgid "PAC _file" msgstr "" #: panels/network/wireless-security/eap-method-fast.ui.h:7 #: panels/network/wireless-security/eap-method-peap.ui.h:8 #: panels/network/wireless-security/eap-method-ttls.ui.h:5 msgid "_Inner authentication" msgstr "" #: panels/network/wireless-security/eap-method-fast.ui.h:8 msgid "Allow automatic PAC pro_visioning" msgstr "" #: panels/network/wireless-security/eap-method-leap.ui.h:1 #: panels/network/wireless-security/eap-method-simple.ui.h:1 #: panels/network/wireless-security/ws-leap.ui.h:1 msgid "_Username" msgstr "" #: panels/network/wireless-security/eap-method-leap.ui.h:3 #: panels/network/wireless-security/eap-method-simple.ui.h:3 #: panels/network/wireless-security/eap-method-tls.ui.h:7 #: panels/network/wireless-security/ws-leap.ui.h:3 #: panels/network/wireless-security/ws-wpa-psk.ui.h:3 msgid "Sho_w password" msgstr "" #: panels/network/wireless-security/eap-method-peap.ui.h:3 msgid "Version 0" msgstr "" #: panels/network/wireless-security/eap-method-peap.ui.h:4 msgid "Version 1" msgstr "" #: panels/network/wireless-security/eap-method-peap.ui.h:6 #: panels/network/wireless-security/eap-method-tls.ui.h:3 #: panels/network/wireless-security/eap-method-ttls.ui.h:3 msgid "C_A certificate" msgstr "" #: panels/network/wireless-security/eap-method-peap.ui.h:7 #: panels/network/wireless-security/eap-method-tls.ui.h:4 #: panels/network/wireless-security/eap-method-ttls.ui.h:4 msgid "No CA certificate is _required" msgstr "" #: panels/network/wireless-security/eap-method-peap.ui.h:9 msgid "PEAP _version" msgstr "" #: panels/network/wireless-security/eap-method-tls.ui.h:1 msgid "I_dentity" msgstr "" #: panels/network/wireless-security/eap-method-tls.ui.h:2 msgid "_User certificate" msgstr "" #: panels/network/wireless-security/eap-method-tls.ui.h:5 msgid "Private _key" msgstr "" #: panels/network/wireless-security/eap-method-tls.ui.h:6 msgid "_Private key password" msgstr "" #: panels/network/wireless-security/ws-dynamic-wep.ui.h:2 #: panels/network/wireless-security/ws-wep-key.ui.h:9 #: panels/network/wireless-security/ws-wpa-eap.ui.h:2 msgid "Au_thentication" msgstr "" #: panels/network/wireless-security/ws-wep-key.ui.h:1 msgid "1 (Default)" msgstr "" #: panels/network/wireless-security/ws-wep-key.ui.h:2 msgid "2" msgstr "" #: panels/network/wireless-security/ws-wep-key.ui.h:3 msgid "3" msgstr "" #: panels/network/wireless-security/ws-wep-key.ui.h:4 msgid "4" msgstr "" #: panels/network/wireless-security/ws-wep-key.ui.h:5 msgid "Open System" msgstr "" #: panels/network/wireless-security/ws-wep-key.ui.h:6 msgid "Shared Key" msgstr "" #: panels/network/wireless-security/ws-wep-key.ui.h:7 msgid "_Key" msgstr "" #: panels/network/wireless-security/ws-wep-key.ui.h:8 msgid "Sho_w key" msgstr "" #: panels/network/wireless-security/ws-wep-key.ui.h:10 msgid "WEP inde_x" msgstr "" #: panels/network/wireless-security/ws-wpa-psk.ui.h:2 msgid "_Type" msgstr "" #: panels/wacom/calibrator/calibrator.ui.h:1 msgid "Screen Calibration" msgstr "" #: panels/wacom/calibrator/calibrator.ui.h:2 msgid "" "Please tap the target markers as they appear on screen to calibrate the " "tablet." msgstr "" #: panels/wacom/calibrator/calibrator.ui.h:3 msgid "Mis-click detected, restarting…" msgstr "" #: generate_additional_files.py:23 msgid "Color management settings" msgstr "" #: generate_additional_files.py:23 msgid "Color, ICC, Profile, Calibrate, Printer, Display" msgstr "" #: generate_additional_files.py:37 msgid "Region & Language" msgstr "" #: generate_additional_files.py:37 msgid "Change your region and language settings" msgstr "" #: generate_additional_files.py:50 msgid "Display" msgstr "" #: generate_additional_files.py:50 msgid "Change resolution and position of monitors and projectors" msgstr "" #: generate_additional_files.py:50 msgid "Panel, Projector, xrandr, Screen, Resolution, Refresh" msgstr "" #: generate_additional_files.py:63 msgid "Network settings" msgstr "" #: generate_additional_files.py:63 msgid "Network, Wireless, IP, LAN, Proxy, Internet, WiFi" msgstr "" #: generate_additional_files.py:76 msgid "Graphics Tablet" msgstr "" #: generate_additional_files.py:76 msgid "Set button mappings and adjust stylus sensitivity for graphics tablets" msgstr "" #: generate_additional_files.py:76 msgid "Tablet, Wacom, Stylus, Eraser, Mouse" msgstr "" cinnamon-control-center-6.4.1/panels/0000775000175000017500000000000014724311620016466 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/meson.build0000664000175000017500000000027314724311620020632 0ustar fabiofabio if colord.found() subdir('color') endif subdir('common') subdir('display') if libnm.found() subdir('network') endif subdir('region') if libwacom.found() subdir('wacom') endif cinnamon-control-center-6.4.1/panels/common/0000775000175000017500000000000014724311620017756 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/common/gdm-languages.c0000664000175000017500000012001714724311620022636 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright 2008 Red Hat, Inc, * 2007 William Jon McCann * * 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 Street - Suite 500, Boston, MA 02110-1335, USA. * * Written by : William Jon McCann * Ray Strode */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "gdm-languages.h" #include #ifndef __LC_LAST #define __LC_LAST 13 #endif #include "locarchive.h" #define ALIASES_FILE DATADIR "/gdm/locale.alias" #define ARCHIVE_FILE LIBLOCALEDIR "/locale-archive" #define SYSTEM_ARCHIVE_FILE "/usr/lib/locale/locale-archive" #define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes" #define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale" typedef struct _GdmLocale { char *id; char *name; char *language_code; char *territory_code; char *codeset; char *modifier; } GdmLocale; static GHashTable *gdm_languages_map; static GHashTable *gdm_territories_map; static GHashTable *gdm_available_locales_map; static GHashTable *gdm_language_count_map; static GHashTable *gdm_territory_count_map; static char * construct_language_name (const char *language, const char *territory, const char *codeset, const char *modifier); static gboolean language_name_is_valid (const char *language_name); static void gdm_locale_free (GdmLocale *locale) { if (locale == NULL) { return; } g_free (locale->id); g_free (locale->name); g_free (locale->codeset); g_free (locale->modifier); g_free (locale); } static char * normalize_codeset (const char *codeset) { char *normalized_codeset; const char *p; char *q; normalized_codeset = g_strdup (codeset); if (codeset != NULL) { for (p = codeset, q = normalized_codeset; *p != '\0'; p++) { if (*p == '-' || *p == '_') { continue; } *q = g_ascii_tolower (*p); q++; } *q = '\0'; } return normalized_codeset; } /* * According to http://en.wikipedia.org/wiki/Locale * locale names are of the form: * [language[_territory][.codeset][@modifier]] */ gboolean gdm_parse_language_name (const char *name, char **language_codep, char **territory_codep, char **codesetp, char **modifierp) { GRegex *re; GMatchInfo *match_info; gboolean res; GError *error; gchar *normalized_codeset = NULL; gchar *normalized_name = NULL; gboolean retval; match_info = NULL; retval = FALSE; error = NULL; re = g_regex_new ("^(?P[^_.@[:space:]]+)" "(_(?P[[:upper:]]+))?" "(\\.(?P[-_0-9a-zA-Z]+))?" "(@(?P[[:ascii:]]+))?$", 0, 0, &error); if (re == NULL) { g_warning ("%s", error->message); goto out; } if (!g_regex_match (re, name, 0, &match_info) || g_match_info_is_partial_match (match_info)) { g_warning ("locale '%s' isn't valid\n", name); goto out; } res = g_match_info_matches (match_info); if (! res) { g_warning ("Unable to parse locale: %s", name); goto out; } retval = TRUE; if (language_codep != NULL) { *language_codep = g_match_info_fetch_named (match_info, "language"); } if (territory_codep != NULL) { *territory_codep = g_match_info_fetch_named (match_info, "territory"); if (*territory_codep != NULL && *territory_codep[0] == '\0') { g_free (*territory_codep); *territory_codep = NULL; } } if (codesetp != NULL) { *codesetp = g_match_info_fetch_named (match_info, "codeset"); if (*codesetp != NULL && *codesetp[0] == '\0') { g_free (*codesetp); *codesetp = NULL; } } if (modifierp != NULL) { *modifierp = g_match_info_fetch_named (match_info, "modifier"); if (*modifierp != NULL && *modifierp[0] == '\0') { g_free (*modifierp); *modifierp = NULL; } } if (codesetp != NULL && *codesetp != NULL) { normalized_codeset = normalize_codeset (*codesetp); normalized_name = construct_language_name (language_codep ? *language_codep : NULL, territory_codep ? *territory_codep : NULL, normalized_codeset, modifierp ? *modifierp : NULL); if (language_name_is_valid (normalized_name)) { g_free (*codesetp); *codesetp = normalized_codeset; } else { g_free (normalized_codeset); } g_free (normalized_name); } out: g_match_info_free (match_info); g_regex_unref (re); return retval; } static char * construct_language_name (const char *language, const char *territory, const char *codeset, const char *modifier) { char *name; g_assert (language[0] != 0); g_assert (territory == NULL || territory[0] != 0); g_assert (codeset == NULL || codeset[0] != 0); g_assert (modifier == NULL || modifier[0] != 0); name = g_strdup_printf ("%s%s%s%s%s%s%s", language, territory != NULL? "_" : "", territory != NULL? territory : "", codeset != NULL? "." : "", codeset != NULL? codeset : "", modifier != NULL? "@" : "", modifier != NULL? modifier : ""); return name; } char * gdm_normalize_language_name (const char *name) { char *normalized_name; char *language_code; char *territory_code; char *codeset; char *modifier; if (name[0] == '\0') { return NULL; } gdm_parse_language_name (name, &language_code, &territory_code, &codeset, &modifier); normalized_name = construct_language_name (language_code, territory_code, codeset, modifier); g_free (language_code); g_free (territory_code); g_free (codeset); g_free (modifier); return normalized_name; } static gboolean language_name_is_valid (const char *language_name) { char *old_locale; gboolean is_valid; #ifdef WITH_INCOMPLETE_LOCALES int lc_type_id = LC_CTYPE; #else int lc_type_id = LC_MESSAGES; #endif old_locale = g_strdup (setlocale (lc_type_id, NULL)); is_valid = setlocale (lc_type_id, language_name) != NULL; setlocale (lc_type_id, old_locale); g_free (old_locale); return is_valid; } static void language_name_get_codeset_details (const char *language_name, char **pcodeset, gboolean *is_utf8) { char *old_locale; char *codeset; old_locale = g_strdup (setlocale (LC_CTYPE, NULL)); if (setlocale (LC_CTYPE, language_name) == NULL) { g_free (old_locale); return; } codeset = nl_langinfo (CODESET); if (pcodeset != NULL) { *pcodeset = g_strdup (codeset); } if (is_utf8 != NULL) { codeset = normalize_codeset (codeset); *is_utf8 = strcmp (codeset, "utf8") == 0; g_free (codeset); } setlocale (LC_CTYPE, old_locale); g_free (old_locale); } gboolean gdm_language_has_translations (const char *language_name) { GDir *dir; char *path; const char *name; gboolean has_translations; path = g_build_filename ("/usr/share/locale", language_name, "LC_MESSAGES", NULL); has_translations = FALSE; dir = g_dir_open (path, 0, NULL); g_free (path); if (dir == NULL) { goto out; } do { name = g_dir_read_name (dir); if (name == NULL) { break; } if (g_str_has_suffix (name, ".mo")) { has_translations = TRUE; break; } } while (name != NULL); g_dir_close (dir); out: return has_translations; } static gboolean add_locale (const char *language_name, gboolean utf8_only) { GdmLocale *locale; GdmLocale *old_locale; char *name; gboolean is_utf8 = FALSE; g_return_val_if_fail (language_name != NULL, FALSE); g_return_val_if_fail (*language_name != '\0', FALSE); language_name_get_codeset_details (language_name, NULL, &is_utf8); if (is_utf8) { name = g_strdup (language_name); } else if (utf8_only) { name = g_strdup_printf ("%s.utf8", language_name); language_name_get_codeset_details (name, NULL, &is_utf8); if (!is_utf8) { g_free (name); return FALSE; } } else { name = g_strdup (language_name); } if (!language_name_is_valid (name)) { g_debug ("Ignoring '%s' as a locale, since it's invalid", name); g_free (name); return FALSE; } locale = g_new0 (GdmLocale, 1); gdm_parse_language_name (name, &locale->language_code, &locale->territory_code, &locale->codeset, &locale->modifier); g_free (name); name = NULL; #ifdef WITH_INCOMPLETE_LOCALES if (utf8_only) { if (locale->territory_code == NULL || locale->modifier) { g_debug ("Ignoring '%s' as a locale, since it lacks territory code or modifier", name); gdm_locale_free (locale); return FALSE; } } #endif locale->id = construct_language_name (locale->language_code, locale->territory_code, NULL, locale->modifier); locale->name = construct_language_name (locale->language_code, locale->territory_code, locale->codeset, locale->modifier); #ifndef WITH_INCOMPLETE_LOCALES if (!gdm_language_has_translations (locale->name) && !gdm_language_has_translations (locale->id) && !gdm_language_has_translations (locale->language_code) && utf8_only) { g_debug ("Ignoring '%s' as a locale, since it lacks translations", locale->name); gdm_locale_free (locale); return FALSE; } #endif if (!utf8_only) { g_free (locale->id); locale->id = g_strdup (locale->name); } old_locale = g_hash_table_lookup (gdm_available_locales_map, locale->id); if (old_locale != NULL) { if (strlen (old_locale->name) > strlen (locale->name)) { gdm_locale_free (locale); return FALSE; } } g_hash_table_insert (gdm_available_locales_map, g_strdup (locale->id), locale); return TRUE; } struct nameent { char *name; uint32_t locrec_offset; }; static gboolean collect_locales_from_archive (void) { GMappedFile *mapped; GError *error; char *addr; struct locarhead *head; struct namehashent *namehashtab; struct nameent *names; uint32_t used; uint32_t cnt; gsize len; gboolean locales_collected; error = NULL; mapped = g_mapped_file_new (ARCHIVE_FILE, FALSE, &error); if (mapped == NULL) { mapped = g_mapped_file_new (SYSTEM_ARCHIVE_FILE, FALSE, NULL); if (mapped == NULL) { g_warning ("Mapping failed for %s: %s", ARCHIVE_FILE, error->message); g_error_free (error); return FALSE; } g_error_free (error); } locales_collected = FALSE; addr = g_mapped_file_get_contents (mapped); len = g_mapped_file_get_length (mapped); head = (struct locarhead *) addr; if (head->namehash_offset + head->namehash_size > len || head->string_offset + head->string_size > len || head->locrectab_offset + head->locrectab_size > len || head->sumhash_offset + head->sumhash_size > len) { goto out; } namehashtab = (struct namehashent *) (addr + head->namehash_offset); names = (struct nameent *) g_new0 (struct nameent, head->namehash_used); for (cnt = used = 0; cnt < head->namehash_size; ++cnt) { if (namehashtab[cnt].locrec_offset != 0) { names[used].name = addr + namehashtab[cnt].name_offset; names[used++].locrec_offset = namehashtab[cnt].locrec_offset; } } for (cnt = 0; cnt < used; ++cnt) { add_locale (names[cnt].name, TRUE); } g_free (names); locales_collected = TRUE; out: g_mapped_file_unref (mapped); return locales_collected; } static int select_dirs (const struct dirent *dirent) { int result = 0; if (strcmp (dirent->d_name, ".") != 0 && strcmp (dirent->d_name, "..") != 0) { mode_t mode = 0; #ifdef _DIRENT_HAVE_D_TYPE if (dirent->d_type != DT_UNKNOWN && dirent->d_type != DT_LNK) { mode = DTTOIF (dirent->d_type); } else #endif { struct stat st; char *path; path = g_build_filename (LIBLOCALEDIR, dirent->d_name, NULL); if (g_stat (path, &st) == 0) { mode = st.st_mode; } g_free (path); } result = S_ISDIR (mode); } return result; } static void collect_locales_from_directory (void) { struct dirent **dirents; int ndirents; int cnt; ndirents = scandir (LIBLOCALEDIR, &dirents, select_dirs, alphasort); for (cnt = 0; cnt < ndirents; ++cnt) { add_locale (dirents[cnt]->d_name, TRUE); } if (ndirents > 0) { free (dirents); } } static void collect_locales_from_locale_file (const char *locale_file) { FILE *langlist; char curline[256]; char *getsret; if (locale_file == NULL) return; langlist = fopen (locale_file, "r"); if (langlist == NULL) return; for (;;) { char *name; char *lang; char **lang_list; int i; getsret = fgets (curline, sizeof (curline), langlist); if (getsret == NULL) break; if (curline[0] <= ' ' || curline[0] == '#') continue; name = strtok (curline, " \t\r\n"); if (name == NULL) continue; lang = strtok (NULL, " \t\r\n"); if (lang == NULL) continue; lang_list = g_strsplit (lang, ",", -1); if (lang_list == NULL) continue; lang = NULL; for (i = 0; lang_list[i] != NULL; i++) { if (add_locale (lang_list[i], FALSE)) { break; } } g_strfreev (lang_list); } fclose (langlist); } static void count_languages_and_territories (void) { gpointer value; GHashTableIter iter; gdm_language_count_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); gdm_territory_count_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); g_hash_table_iter_init (&iter, gdm_available_locales_map); while (g_hash_table_iter_next (&iter, NULL, &value)) { GdmLocale *locale; locale = (GdmLocale *) value; if (locale->language_code != NULL) { int count; count = GPOINTER_TO_INT (g_hash_table_lookup (gdm_language_count_map, locale->language_code)); count++; g_hash_table_insert (gdm_language_count_map, g_strdup (locale->language_code), GINT_TO_POINTER (count)); } if (locale->territory_code != NULL) { int count; count = GPOINTER_TO_INT (g_hash_table_lookup (gdm_territory_count_map, locale->territory_code)); count++; g_hash_table_insert (gdm_territory_count_map, g_strdup (locale->territory_code), GINT_TO_POINTER (count)); } } } static void collect_locales (void) { if (gdm_available_locales_map == NULL) { gdm_available_locales_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) gdm_locale_free); } if (!collect_locales_from_archive ()) { #ifndef WITH_INCOMPLETE_LOCALES g_warning ("Could not read list of available locales from libc, " "guessing possible locales from available translations, " "but list may be incomplete!"); #endif } collect_locales_from_directory (); collect_locales_from_locale_file (ALIASES_FILE); count_languages_and_territories (); } static gint get_language_count (const char *language) { if (gdm_language_count_map == NULL) { collect_locales (); } return GPOINTER_TO_INT (g_hash_table_lookup (gdm_language_count_map, language)); } static gboolean is_unique_language (const char *language) { return get_language_count (language) == 1; } static gint get_territory_count (const char *territory) { if (gdm_territory_count_map == NULL) { collect_locales (); } return GPOINTER_TO_INT (g_hash_table_lookup (gdm_territory_count_map, territory)); } static gboolean is_unique_territory (const char *territory) { return get_territory_count (territory) == 1; } static gboolean is_fallback_language (const char *code) { const char *fallback_language_names[] = { "C", "POSIX", NULL }; int i; for (i = 0; fallback_language_names[i] != NULL; i++) { if (strcmp (code, fallback_language_names[i]) == 0) { return TRUE; } } return FALSE; } static const char * get_language (const char *code) { const char *name; int len; g_assert (code != NULL); if (is_fallback_language (code)) { return "Unspecified"; } len = strlen (code); if (len != 2 && len != 3) { return NULL; } name = (const char *) g_hash_table_lookup (gdm_languages_map, code); return name; } static char * get_first_item_in_semicolon_list (const char *list) { char **items; char *item; /* Some entries in iso codes have multiple values, separated * by semicolons. Not really sure which one to pick, so * we just arbitrarily pick the first one. */ items = g_strsplit (list, "; ", 2); item = g_strdup (items[0]); g_strfreev (items); return item; } static char * get_translated_language (const char *code, const char *locale) { const char *language; char *name; language = get_language (code); name = NULL; if (language != NULL) { const char *translated_name; char *old_locale; if (locale != NULL) { old_locale = g_strdup (setlocale (LC_MESSAGES, NULL)); setlocale (LC_MESSAGES, locale); } if (is_fallback_language (code)) { name = g_strdup (_("Unspecified")); } else { translated_name = dgettext ("iso_639", language); name = get_first_item_in_semicolon_list (translated_name); } if (locale != NULL) { setlocale (LC_MESSAGES, old_locale); g_free (old_locale); } } return name; } static const char * get_territory (const char *code) { const char *name; int len; g_assert (code != NULL); len = strlen (code); if (len != 2 && len != 3) { return NULL; } name = (const char *) g_hash_table_lookup (gdm_territories_map, code); return name; } static char * get_translated_territory (const char *code, const char *locale) { const char *territory; char *name; territory = get_territory (code); name = NULL; if (territory != NULL) { const char *translated_territory; char *old_locale; if (locale != NULL) { old_locale = g_strdup (setlocale (LC_MESSAGES, NULL)); setlocale (LC_MESSAGES, locale); } translated_territory = dgettext ("iso_3166", territory); name = get_first_item_in_semicolon_list (translated_territory); if (locale != NULL) { setlocale (LC_MESSAGES, old_locale); g_free (old_locale); } } return name; } static void languages_parse_start_tag (GMarkupParseContext *ctx, const char *element_name, const char **attr_names, const char **attr_values, gpointer user_data, GError **error) { const char *ccode_longB; const char *ccode_longT; const char *ccode; const char *ccode_id; const char *lang_name; if (! (g_str_equal (element_name, "iso_639_entry") || g_str_equal (element_name, "iso_639_3_entry")) || attr_names == NULL || attr_values == NULL) { return; } ccode = NULL; ccode_longB = NULL; ccode_longT = NULL; ccode_id = NULL; lang_name = NULL; while (*attr_names && *attr_values) { if (g_str_equal (*attr_names, "iso_639_1_code")) { /* skip if empty */ if (**attr_values) { if (strlen (*attr_values) != 2) { return; } ccode = *attr_values; } } else if (g_str_equal (*attr_names, "iso_639_2B_code")) { /* skip if empty */ if (**attr_values) { if (strlen (*attr_values) != 3) { return; } ccode_longB = *attr_values; } } else if (g_str_equal (*attr_names, "iso_639_2T_code")) { /* skip if empty */ if (**attr_values) { if (strlen (*attr_values) != 3) { return; } ccode_longT = *attr_values; } } else if (g_str_equal (*attr_names, "id")) { /* skip if empty */ if (**attr_values) { if (strlen (*attr_values) != 2 && strlen (*attr_values) != 3) { return; } ccode_id = *attr_values; } } else if (g_str_equal (*attr_names, "name")) { lang_name = *attr_values; } ++attr_names; ++attr_values; } if (lang_name == NULL) { return; } if (ccode != NULL) { g_hash_table_insert (gdm_languages_map, g_strdup (ccode), g_strdup (lang_name)); } if (ccode_longB != NULL) { g_hash_table_insert (gdm_languages_map, g_strdup (ccode_longB), g_strdup (lang_name)); } if (ccode_longT != NULL) { g_hash_table_insert (gdm_languages_map, g_strdup (ccode_longT), g_strdup (lang_name)); } if (ccode_id != NULL) { g_hash_table_insert (gdm_languages_map, g_strdup (ccode_id), g_strdup (lang_name)); } } static void territories_parse_start_tag (GMarkupParseContext *ctx, const char *element_name, const char **attr_names, const char **attr_values, gpointer user_data, GError **error) { const char *acode_2; const char *acode_3; const char *ncode; const char *territory_common_name; const char *territory_name; if (! g_str_equal (element_name, "iso_3166_entry") || attr_names == NULL || attr_values == NULL) { return; } acode_2 = NULL; acode_3 = NULL; ncode = NULL; territory_common_name = NULL; territory_name = NULL; while (*attr_names && *attr_values) { if (g_str_equal (*attr_names, "alpha_2_code")) { /* skip if empty */ if (**attr_values) { if (strlen (*attr_values) != 2) { return; } acode_2 = *attr_values; } } else if (g_str_equal (*attr_names, "alpha_3_code")) { /* skip if empty */ if (**attr_values) { if (strlen (*attr_values) != 3) { return; } acode_3 = *attr_values; } } else if (g_str_equal (*attr_names, "numeric_code")) { /* skip if empty */ if (**attr_values) { if (strlen (*attr_values) != 3) { return; } ncode = *attr_values; } } else if (g_str_equal (*attr_names, "common_name")) { /* skip if empty */ if (**attr_values) { territory_common_name = *attr_values; } } else if (g_str_equal (*attr_names, "name")) { territory_name = *attr_values; } ++attr_names; ++attr_values; } if (territory_common_name != NULL) { territory_name = territory_common_name; } if (territory_name == NULL) { return; } if (acode_2 != NULL) { g_hash_table_insert (gdm_territories_map, g_strdup (acode_2), g_strdup (territory_name)); } if (acode_3 != NULL) { g_hash_table_insert (gdm_territories_map, g_strdup (acode_3), g_strdup (territory_name)); } if (ncode != NULL) { g_hash_table_insert (gdm_territories_map, g_strdup (ncode), g_strdup (territory_name)); } } static void languages_variant_init (const char *variant) { GError *error; gboolean res; char *buf; gsize buf_len; char *filename; bindtextdomain (variant, ISO_CODES_LOCALESDIR); bind_textdomain_codeset (variant, "UTF-8"); error = NULL; filename = g_strdup_printf (ISO_CODES_DATADIR "/%s.xml", variant); res = g_file_get_contents (filename, &buf, &buf_len, &error); if (res) { GMarkupParseContext *ctx; GMarkupParser parser = { languages_parse_start_tag, NULL, NULL, NULL, NULL }; ctx = g_markup_parse_context_new (&parser, 0, NULL, NULL); error = NULL; res = g_markup_parse_context_parse (ctx, buf, buf_len, &error); if (! res) { g_warning ("Failed to parse '%s': %s\n", filename, error->message); g_error_free (error); g_free (filename); } g_markup_parse_context_free (ctx); g_free (buf); } else { g_warning ("Failed to load '%s': %s\n", filename, error->message); g_error_free (error); } } static void languages_init (void) { gdm_languages_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); languages_variant_init ("iso_639"); languages_variant_init ("iso_639_3"); } static void territories_init (void) { GError *error; gboolean res; char *buf; gsize buf_len; bindtextdomain ("iso_3166", ISO_CODES_LOCALESDIR); bind_textdomain_codeset ("iso_3166", "UTF-8"); gdm_territories_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); error = NULL; res = g_file_get_contents (ISO_CODES_DATADIR "/iso_3166.xml", &buf, &buf_len, &error); if (res) { GMarkupParseContext *ctx; GMarkupParser parser = { territories_parse_start_tag, NULL, NULL, NULL, NULL }; ctx = g_markup_parse_context_new (&parser, 0, NULL, NULL); error = NULL; res = g_markup_parse_context_parse (ctx, buf, buf_len, &error); if (! res) { g_warning ("Failed to parse '%s': %s\n", ISO_CODES_DATADIR "/iso_3166.xml", error->message); g_error_free (error); } g_markup_parse_context_free (ctx); g_free (buf); } else { g_warning ("Failed to load '%s': %s\n", ISO_CODES_DATADIR "/iso_3166.xml", error->message); g_error_free (error); } } char * gdm_get_language_from_name (const char *name, const char *locale) { GString *full_language; char *language_code; char *territory_code; char *codeset_code; char *langinfo_codeset; char *translated_language; char *translated_territory; char *modifier; gboolean is_utf8 = TRUE; g_return_val_if_fail (name != NULL, NULL); g_return_val_if_fail (*name != '\0', NULL); translated_territory = NULL; translated_language = NULL; langinfo_codeset = NULL; full_language = g_string_new (NULL); if (gdm_languages_map == NULL) { languages_init (); } if (gdm_territories_map == NULL) { territories_init (); } language_code = NULL; territory_code = NULL; codeset_code = NULL; modifier = NULL; gdm_parse_language_name (name, &language_code, &territory_code, &codeset_code, &modifier); if (language_code == NULL) { goto out; } translated_language = get_translated_language (language_code, locale); if (translated_language == NULL) { goto out; } full_language = g_string_append (full_language, translated_language); if (is_unique_language (language_code)) { goto out; } if (territory_code != NULL) { translated_territory = get_translated_territory (territory_code, locale); } if (translated_territory != NULL) { g_string_append_printf (full_language, " (%s)", translated_territory); } // language_name_get_codeset_details (name, &langinfo_codeset, &is_utf8); if (codeset_code == NULL && langinfo_codeset != NULL) { codeset_code = g_strdup (langinfo_codeset); } if (!is_utf8 && codeset_code) { g_string_append_printf (full_language, " [%s]", codeset_code); } if (modifier != NULL) { g_string_append_printf (full_language, " - %s", modifier); } out: g_free (language_code); g_free (territory_code); g_free (codeset_code); g_free (langinfo_codeset); g_free (translated_language); g_free (translated_territory); g_free (modifier); if (full_language->len == 0) { g_string_free (full_language, TRUE); return NULL; } return g_string_free (full_language, FALSE); } char * gdm_get_region_from_name (const char *name, const char *locale) { GString *full_name; char *language_code; char *territory_code; char *codeset_code; char *langinfo_codeset; char *translated_language; char *translated_territory; gboolean is_utf8 = TRUE; g_return_val_if_fail (name != NULL, NULL); g_return_val_if_fail (*name != '\0', NULL); translated_territory = NULL; translated_language = NULL; langinfo_codeset = NULL; full_name = g_string_new (NULL); if (gdm_languages_map == NULL) { languages_init (); } if (gdm_territories_map == NULL) { territories_init (); } language_code = NULL; territory_code = NULL; codeset_code = NULL; gdm_parse_language_name (name, &language_code, &territory_code, &codeset_code, NULL); if (territory_code == NULL) { goto out; } translated_territory = get_translated_territory (territory_code, locale); g_string_append (full_name, translated_territory); if (is_unique_territory (territory_code)) { goto out; } if (language_code != NULL) { translated_language = get_translated_language (language_code, locale); } if (translated_language != NULL) { g_string_append_printf (full_name, " (%s)", translated_language); } language_name_get_codeset_details (name, &langinfo_codeset, &is_utf8); if (codeset_code == NULL && langinfo_codeset != NULL) { codeset_code = g_strdup (langinfo_codeset); } if (!is_utf8 && codeset_code) { g_string_append_printf (full_name, " [%s]", codeset_code); } out: g_free (language_code); g_free (territory_code); g_free (codeset_code); g_free (langinfo_codeset); g_free (translated_language); g_free (translated_territory); if (full_name->len == 0) { g_string_free (full_name, TRUE); return NULL; } return g_string_free (full_name, FALSE); } char ** gdm_get_all_language_names (void) { GHashTableIter iter; gpointer key, value; GPtrArray *array; if (gdm_available_locales_map == NULL) { collect_locales (); } array = g_ptr_array_new (); g_hash_table_iter_init (&iter, gdm_available_locales_map); while (g_hash_table_iter_next (&iter, &key, &value)) { GdmLocale *locale; locale = (GdmLocale *) value; g_ptr_array_add (array, g_strdup (locale->name)); } g_ptr_array_add (array, NULL); return (char **) g_ptr_array_free (array, FALSE); } cinnamon-control-center-6.4.1/panels/common/meson.build0000664000175000017500000000356414724311620022130 0ustar fabiofabio panel_languages = static_library('language', 'cc-common-language.c', 'cc-language-chooser.c', 'gdm-languages.c', include_directories: rootInclude, dependencies: [ glib, gtk, ], ) list_languages = executable('list-languages', 'list-languages.c', include_directories: rootInclude, link_with: panel_languages, dependencies: [ glib, ], ) install_data('language-chooser.ui', install_dir: ui_dir, ) common_inc = include_directories('.') common_sources = [] enums = 'csd-common-enums' enums_header = files('csd-device-manager.h') common_sources += gnome.mkenums( enums + '.h', sources: enums_header, fhead: '#pragma once\n\n#include \n\nG_BEGIN_DECLS\n', fprod: '/* enumerations from "@filename@" */\n', vhead: 'GType @enum_name@_get_type (void) G_GNUC_CONST;\n#define CSD_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n', ftail: 'G_END_DECLS\n' ) common_sources += gnome.mkenums( enums + '.c', sources: enums_header, fhead: '#include "csd-device-manager.h"\n#include "csd-common-enums.h"\n', fprod: '\n/* enumerations from "@filename@" */', vhead: 'GType\n@enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G@Type@Value values[] = {', vprod: ' { @VALUENAME@, "@VALUENAME@", "@valuenick@" },', vtail: ' { 0, NULL, NULL }\n };\n etype = g_@type@_register_static ("@EnumName@", values);\n }\n return etype;\n}\n' ) csd_headers = [ 'csd-device-manager.h', 'csd-input-helper.h', ] csd_sources = [ 'csd-device-manager.c', 'csd-input-helper.c' ] sources = common_sources + files(csd_sources) deps = [ gudev_dep, glib, gio_unix, gtk, cinn_desktop ] libdevice = static_library( 'device', sources: sources, include_directories: rootInclude, dependencies: deps ) libdevice_dep = declare_dependency( include_directories: common_inc, link_with: libdevice ) cinnamon-control-center-6.4.1/panels/common/cc-common-language.c0000664000175000017500000004562514724311620023572 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright 2009-2010 Red Hat, Inc, * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Written by: Matthias Clasen */ #include "config.h" #include #include #include #include #include #include #include "cc-common-language.h" #include "gdm-languages.h" static gint cc_common_language_sort_languages (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer data) { char *ca, *cb; char *la, *lb; gboolean sa, ula; gboolean sb, ulb; gint result; gtk_tree_model_get (model, a, LOCALE_COL, &ca, DISPLAY_LOCALE_COL, &la, SEPARATOR_COL, &sa, USER_LANGUAGE, &ula, -1); gtk_tree_model_get (model, b, LOCALE_COL, &cb, DISPLAY_LOCALE_COL, &lb, SEPARATOR_COL, &sb, USER_LANGUAGE, &ulb, -1); /* Sort before and after separator first */ if (sa && sb) result = 0; else if (sa) result = ulb ? 1 : -1; else if (sb) result = ula ? -1 : 1; /* Sort user-languages first */ else if (ula != ulb) { if (ula) result = -1; else result = 1; } else if (!ca) result = 1; else if (!cb) result = -1; else result = strcmp (la, lb); g_free (ca); g_free (cb); g_free (la); g_free (lb); return result; } static gboolean iter_for_language (GtkTreeModel *model, const gchar *lang, GtkTreeIter *iter, gboolean region) { char *l; char *name; char *language; gtk_tree_model_get_iter_first (model, iter); do { gtk_tree_model_get (model, iter, LOCALE_COL, &l, -1); if (g_strcmp0 (l, lang) == 0) { g_free (l); return TRUE; } g_free (l); } while (gtk_tree_model_iter_next (model, iter)); name = gdm_normalize_language_name (lang); if (name != NULL) { if (region) { language = gdm_get_region_from_name (name, NULL); } else { language = gdm_get_language_from_name (name, NULL); } gtk_list_store_insert_with_values (GTK_LIST_STORE (model), iter, -1, LOCALE_COL, name, DISPLAY_LOCALE_COL, language, -1); g_free (name); g_free (language); return TRUE; } return FALSE; } gboolean cc_common_language_get_iter_for_language (GtkTreeModel *model, const gchar *lang, GtkTreeIter *iter) { return iter_for_language (model, lang, iter, FALSE); } gboolean cc_common_language_get_iter_for_region (GtkTreeModel *model, const gchar *lang, GtkTreeIter *iter) { return iter_for_language (model, lang, iter, TRUE); } gboolean cc_common_language_has_font (const gchar *locale) { const FcCharSet *charset; FcPattern *pattern; FcObjectSet *object_set; FcFontSet *font_set; gchar *language_code; gboolean is_displayable; is_displayable = FALSE; pattern = NULL; object_set = NULL; font_set = NULL; if (!gdm_parse_language_name (locale, &language_code, NULL, NULL, NULL)) return FALSE; charset = FcLangGetCharSet ((FcChar8 *) language_code); if (!charset) { /* fontconfig does not know about this language */ is_displayable = TRUE; } else { /* see if any fonts support rendering it */ pattern = FcPatternBuild (NULL, FC_LANG, FcTypeString, language_code, NULL); if (pattern == NULL) goto done; object_set = FcObjectSetCreate (); if (object_set == NULL) goto done; font_set = FcFontList (NULL, pattern, object_set); if (font_set == NULL) goto done; is_displayable = (font_set->nfont > 0); } done: if (font_set != NULL) FcFontSetDestroy (font_set); if (object_set != NULL) FcObjectSetDestroy (object_set); if (pattern != NULL) FcPatternDestroy (pattern); g_free (language_code); return is_displayable; } typedef struct { GtkListStore *store; GHashTable *user_langs; gchar **languages; gboolean regions; gint position; } AsyncLangData; static void async_lang_data_free (AsyncLangData *data) { g_object_unref (data->store); g_hash_table_unref (data->user_langs); g_strfreev (data->languages); g_free (data); } static gboolean add_one_language (gpointer d) { AsyncLangData *data = d; char *name; char *language; GtkTreeIter iter; if (data->languages[data->position] == NULL) { /* we are done */ async_lang_data_free (data); return FALSE; } name = gdm_normalize_language_name (data->languages[data->position]); if (g_hash_table_lookup (data->user_langs, name) != NULL) { g_free (name); goto next; } if (!cc_common_language_has_font (data->languages[data->position])) { g_free (name); goto next; } if (data->regions) { language = gdm_get_region_from_name (name, NULL); } else { language = gdm_get_language_from_name (name, NULL); } if (!language) { g_debug ("Ignoring '%s' as a locale, because we couldn't figure the language name", name); g_free (name); goto next; } /* Add separator between initial languages and new additions */ if (g_object_get_data (G_OBJECT (data->store), "needs-separator")) { GtkTreeIter iter; gtk_list_store_insert_with_values (GTK_LIST_STORE (data->store), &iter, -1, LOCALE_COL, NULL, DISPLAY_LOCALE_COL, "Don't show", SEPARATOR_COL, TRUE, USER_LANGUAGE, FALSE, -1); g_object_set_data (G_OBJECT (data->store), "needs-separator", NULL); } gtk_list_store_insert_with_values (data->store, &iter, -1, LOCALE_COL, name, DISPLAY_LOCALE_COL, language, -1); g_free (name); g_free (language); next: data->position++; return TRUE; } guint cc_common_language_add_available_languages (GtkListStore *store, gboolean regions, GHashTable *user_langs) { AsyncLangData *data; data = g_new0 (AsyncLangData, 1); data->store = g_object_ref (store); data->user_langs = g_hash_table_ref (user_langs); data->languages = gdm_get_all_language_names (); data->regions = regions; data->position = 0; return gdk_threads_add_idle (add_one_language, data); } gchar * cc_common_language_get_current_language (void) { gchar *language; const gchar *locale; locale = (const gchar *) setlocale (LC_MESSAGES, NULL); if (locale) language = gdm_normalize_language_name (locale); else language = NULL; return language; } static void languages_foreach_cb (gpointer key, gpointer value, gpointer user_data) { GtkListStore *store = (GtkListStore *) user_data; const char *locale = (const char *) key; const char *display_locale = (const char *) value; GtkTreeIter iter; gtk_list_store_insert_with_values (store, &iter, -1, LOCALE_COL, locale, DISPLAY_LOCALE_COL, display_locale, SEPARATOR_COL, FALSE, USER_LANGUAGE, TRUE, -1); } static gboolean separator_func (GtkTreeModel *model, GtkTreeIter *iter, gpointer data) { gboolean is_sep; gtk_tree_model_get (model, iter, SEPARATOR_COL, &is_sep, -1); return is_sep; } void cc_common_language_setup_list (GtkWidget *treeview, GHashTable *initial) { GtkCellRenderer *cell; GtkTreeViewColumn *column; GtkListStore *store; cell = gtk_cell_renderer_text_new (); g_object_set (cell, "width-chars", 40, "ellipsize", PANGO_ELLIPSIZE_END, NULL); column = gtk_tree_view_column_new_with_attributes (NULL, cell, "text", DISPLAY_LOCALE_COL, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); store = gtk_list_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN); gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (store), cc_common_language_sort_languages, NULL, NULL); gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING); gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW (treeview), separator_func, NULL, NULL); gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (store)); /* Add languages from the initial hashtable */ g_hash_table_foreach (initial, (GHFunc) languages_foreach_cb, store); /* Mark the need for a separator if we had any languages added */ if (initial != NULL && g_hash_table_size (initial) > 0) { g_object_set_data (G_OBJECT (store), "needs-separator", GINT_TO_POINTER (TRUE)); } } void cc_common_language_select_current_language (GtkTreeView *treeview) { GtkTreeModel *model; GtkTreeIter iter; gboolean cont; char *lang; gboolean found; lang = cc_common_language_get_current_language (); g_debug ("Trying to select lang '%s' in treeview", lang); model = gtk_tree_view_get_model (treeview); found = FALSE; cont = gtk_tree_model_get_iter_first (model, &iter); while (cont) { char *locale; gtk_tree_model_get (model, &iter, LOCALE_COL, &locale, -1); if (locale != NULL && g_str_equal (locale, lang)) { GtkTreeSelection *selection; g_debug ("Found '%s' in treeview", locale); found = TRUE; selection = gtk_tree_view_get_selection (treeview); gtk_tree_selection_select_iter (selection, &iter); g_free (locale); break; } g_free (locale); cont = gtk_tree_model_iter_next (model, &iter); } g_free (lang); if (found == FALSE) g_warning ("Could not find current language '%s' in the treeview", lang); } static void add_other_users_language (GHashTable *ht) { GVariant *variant; GVariantIter *vi; GError *error = NULL; const char *str; GDBusProxy *proxy; proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.freedesktop.Accounts", "/org/freedesktop/Accounts", "org.freedesktop.Accounts", NULL, NULL); if (proxy == NULL) return; variant = g_dbus_proxy_call_sync (proxy, "ListCachedUsers", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (variant == NULL) { g_warning ("Failed to list existing users: %s", error->message); g_error_free (error); g_object_unref (proxy); return; } g_variant_get (variant, "(ao)", &vi); while (g_variant_iter_loop (vi, "o", &str)) { GDBusProxy *user; GVariant *props; const char *lang; char *name; char *language; user = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.freedesktop.Accounts", str, "org.freedesktop.Accounts.User", NULL, &error); if (user == NULL) { g_warning ("Failed to get proxy for user '%s': %s", str, error->message); g_error_free (error); error = NULL; continue; } props = g_dbus_proxy_get_cached_property (user, "Language"); lang = g_variant_get_string (props, NULL); if (lang != NULL && *lang != '\0' && cc_common_language_has_font (lang) && gdm_language_has_translations (lang)) { name = gdm_normalize_language_name (lang); if (!g_hash_table_lookup (ht, name)) { language = gdm_get_language_from_name (name, NULL); g_hash_table_insert (ht, name, language); } else { g_free (name); } } g_variant_unref (props); g_object_unref (user); } g_variant_iter_free (vi); g_variant_unref (variant); g_object_unref (proxy); } GHashTable * cc_common_language_get_initial_languages (void) { GHashTable *ht; char *name; char *language; ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); /* Add some common languages first */ g_hash_table_insert (ht, g_strdup ("en_US.utf8"), g_strdup (_("English"))); if (gdm_language_has_translations ("en_GB")) g_hash_table_insert (ht, g_strdup ("en_GB.utf8"), g_strdup (_("British English"))); if (gdm_language_has_translations ("de") || gdm_language_has_translations ("de_DE")) g_hash_table_insert (ht, g_strdup ("de_DE.utf8"), g_strdup (_("German"))); if (gdm_language_has_translations ("fr") || gdm_language_has_translations ("fr_FR")) g_hash_table_insert (ht, g_strdup ("fr_FR.utf8"), g_strdup (_("French"))); if (gdm_language_has_translations ("es") || gdm_language_has_translations ("es_ES")) g_hash_table_insert (ht, g_strdup ("es_ES.utf8"), g_strdup (_("Spanish"))); if (gdm_language_has_translations ("zh_CN")) g_hash_table_insert (ht, g_strdup ("zh_CN.utf8"), g_strdup (_("Chinese (simplified)"))); if (gdm_language_has_translations ("ru") || gdm_language_has_translations ("ru_RU")) g_hash_table_insert (ht, g_strdup ("ru_RU.utf8"), g_strdup (_("Russian"))); if (gdm_language_has_translations ("ar") || gdm_language_has_translations ("ar_EG")) g_hash_table_insert (ht, g_strdup ("ar_EG.utf8"), g_strdup (_("Arabic"))); /* Add the languages used by other users on the system */ add_other_users_language (ht); /* Add current locale */ name = cc_common_language_get_current_language (); if (g_hash_table_lookup (ht, name) == NULL) { language = gdm_get_language_from_name (name, NULL); g_hash_table_insert (ht, name, language); } else { g_free (name); } return ht; } GHashTable * cc_common_language_get_initial_regions (const gchar *lang) { GHashTable *ht; char *language; gchar **langs; gint i; ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); /* Add some common regions */ g_hash_table_insert (ht, g_strdup ("en_US.utf8"), g_strdup (_("United States"))); g_hash_table_insert (ht, g_strdup ("de_DE.utf8"), g_strdup (_("Germany"))); g_hash_table_insert (ht, g_strdup ("fr_FR.utf8"), g_strdup (_("France"))); g_hash_table_insert (ht, g_strdup ("es_ES.utf8"), g_strdup (_("Spain"))); g_hash_table_insert (ht, g_strdup ("zh_CN.utf8"), g_strdup (_("China"))); gdm_parse_language_name (lang, &language, NULL, NULL, NULL); langs = gdm_get_all_language_names (); for (i = 0; langs[i]; i++) { gchar *l, *s; gdm_parse_language_name (langs[i], &l, NULL, NULL, NULL); if (g_strcmp0 (language, l) == 0) { if (!g_hash_table_lookup (ht, langs[i])) { s = gdm_get_region_from_name (langs[i], NULL); g_hash_table_insert (ht, g_strdup (langs[i]), s); } } g_free (l); } g_strfreev (langs); g_free (language); return ht; } cinnamon-control-center-6.4.1/panels/common/cc-language-chooser.h0000664000175000017500000000255414724311620023743 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright 2009-2010 Red Hat, Inc, * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Written by: Matthias Clasen */ #ifndef __CC_LANGUAGE_CHOOSER_H__ #define __CC_LANGUAGE_CHOOSER_H__ #include G_BEGIN_DECLS void cc_add_user_languages (GtkTreeModel *model); GtkWidget *cc_language_chooser_new (GtkWidget *parent, gboolean regions); void cc_language_chooser_clear_filter (GtkWidget *chooser); gchar *cc_language_chooser_get_language (GtkWidget *chooser); G_END_DECLS #endif cinnamon-control-center-6.4.1/panels/common/language-chooser.ui0000664000175000017500000001151214724311620023540 0ustar fabiofabio 400 5 True center-on-parent dialog system-users True vertical 6 10 10 True start Select a language 1 False False True True never automatic in True True False False False 2 True True True True edit-find-symbolic False False 3 False False True end _Cancel True True True True False False 0 _Select True True True True True False False 1 False end 0 cancel-button ok-button cinnamon-control-center-6.4.1/panels/common/csd-device-manager.h0000664000175000017500000000544214724311620023552 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2014 Carlos Garnacho * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #pragma once #include #include #include G_BEGIN_DECLS #define CSD_TYPE_DEVICE (csd_device_get_type ()) G_DECLARE_DERIVABLE_TYPE (CsdDevice, csd_device, CSD, DEVICE, GObject) #define CSD_TYPE_DEVICE_MANAGER (csd_device_manager_get_type ()) G_DECLARE_DERIVABLE_TYPE (CsdDeviceManager, csd_device_manager, CSD, DEVICE_MANAGER, GObject) typedef enum { CSD_DEVICE_TYPE_MOUSE = 1 << 0, CSD_DEVICE_TYPE_KEYBOARD = 1 << 1, CSD_DEVICE_TYPE_TOUCHPAD = 1 << 2, CSD_DEVICE_TYPE_TABLET = 1 << 3, CSD_DEVICE_TYPE_TOUCHSCREEN = 1 << 4, CSD_DEVICE_TYPE_PAD = 1 << 5 } CsdDeviceType; struct _CsdDeviceClass { GObjectClass parent_class; }; struct _CsdDeviceManagerClass { GObjectClass parent_class; GList * (* list_devices) (CsdDeviceManager *manager, CsdDeviceType type); void (* device_added) (CsdDeviceManager *manager, CsdDevice *device); void (* device_removed) (CsdDeviceManager *manager, CsdDevice *device); void (* device_changed) (CsdDeviceManager *manager, CsdDevice *device); CsdDevice * (* lookup_device) (CsdDeviceManager *manager, GdkDevice *gdk_device); }; CsdDeviceManager * csd_device_manager_get (void); GList * csd_device_manager_list_devices (CsdDeviceManager *manager, CsdDeviceType type); const gchar * csd_device_get_name (CsdDevice *device); CsdDeviceType csd_device_get_device_type (CsdDevice *device); void csd_device_get_device_ids (CsdDevice *device, const gchar **vendor, const gchar **product); GSettings * csd_device_get_settings (CsdDevice *device); const gchar * csd_device_get_device_file (CsdDevice *device); gboolean csd_device_get_dimensions (CsdDevice *device, guint *width, guint *height); CsdDevice * csd_device_manager_lookup_gdk_device (CsdDeviceManager *manager, GdkDevice *gdk_device); G_END_DECLS cinnamon-control-center-6.4.1/panels/common/locarchive.h0000664000175000017500000000434314724311620022252 0ustar fabiofabio/* Definitions for locale archive handling. Copyright (C) 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C 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. The GNU C 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 the GNU C Library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA. */ #ifndef _LOCARCHIVE_H #define _LOCARCHIVE_H 1 #include #define AR_MAGIC 0xde020109 struct locarhead { uint32_t magic; /* Serial number. */ uint32_t serial; /* Name hash table. */ uint32_t namehash_offset; uint32_t namehash_used; uint32_t namehash_size; /* String table. */ uint32_t string_offset; uint32_t string_used; uint32_t string_size; /* Table with locale records. */ uint32_t locrectab_offset; uint32_t locrectab_used; uint32_t locrectab_size; /* MD5 sum hash table. */ uint32_t sumhash_offset; uint32_t sumhash_used; uint32_t sumhash_size; }; struct namehashent { /* Hash value of the name. */ uint32_t hashval; /* Offset of the name in the string table. */ uint32_t name_offset; /* Offset of the locale record. */ uint32_t locrec_offset; }; struct sumhashent { /* MD5 sum. */ char sum[16]; /* Offset of the file in the archive. */ uint32_t file_offset; }; struct locrecent { uint32_t refs; /* # of namehashent records that point here */ struct { uint32_t offset; uint32_t len; } record[__LC_LAST]; }; struct locarhandle { int fd; void *addr; size_t len; }; /* In memory data for the locales with their checksums. */ typedef struct locale_category_data { off_t size; void *addr; char sum[16]; } locale_data_t[__LC_LAST]; #endif /* locarchive.h */ cinnamon-control-center-6.4.1/panels/common/gdm-languages.h0000664000175000017500000000347214724311620022650 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright 2008 Red Hat, Inc. * Copyright 2007 William Jon McCann * * 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 Street - Suite 500, Boston, MA 02110-1335, USA. * * Written by: Ray Strode * William Jon McCann */ #ifndef __GDM_LANGUAGES_H #define __GDM_LANGUAGES_H G_BEGIN_DECLS char * gdm_get_language_from_name (const char *name, const char *locale); char * gdm_get_region_from_name (const char *name, const char *locale); char ** gdm_get_all_language_names (void); gboolean gdm_parse_language_name (const char *name, char **language_codep, char **territory_codep, char **codesetp, char **modifierp); char * gdm_normalize_language_name (const char *name); gboolean gdm_language_has_translations (const char *language_name); G_END_DECLS #endif /* __GDM_LANGUAGE_CHOOSER_WIDGET_H */ cinnamon-control-center-6.4.1/panels/common/csd-input-helper.c0000664000175000017500000000555614724311620023320 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2010 Bastien Nocera * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include "config.h" #include #include #include #include #include #include #include "csd-input-helper.h" #include "csd-device-manager.h" static gboolean device_type_is_present (CsdDeviceType type) { g_autoptr(GList) l = csd_device_manager_list_devices (csd_device_manager_get (), type); return l != NULL; } gboolean touchscreen_is_present (void) { return device_type_is_present (CSD_DEVICE_TYPE_TOUCHSCREEN); } gboolean touchpad_is_present (void) { return device_type_is_present (CSD_DEVICE_TYPE_TOUCHPAD); } gboolean mouse_is_present (void) { return device_type_is_present (CSD_DEVICE_TYPE_MOUSE); } char * xdevice_get_device_node (int deviceid) { GdkDisplay *display; Atom prop; Atom act_type; int act_format; unsigned long nitems, bytes_after; unsigned char *data; char *ret; display = gdk_display_get_default (); gdk_display_sync (display); prop = XInternAtom (GDK_DISPLAY_XDISPLAY (display), "Device Node", False); if (!prop) return NULL; gdk_x11_display_error_trap_push (display); if (!XIGetProperty (GDK_DISPLAY_XDISPLAY (display), deviceid, prop, 0, 1000, False, AnyPropertyType, &act_type, &act_format, &nitems, &bytes_after, &data) == Success) { gdk_x11_display_error_trap_pop_ignored (display); return NULL; } if (gdk_x11_display_error_trap_pop (display)) goto out; if (nitems == 0) goto out; if (act_type != XA_STRING) goto out; /* Unknown string format */ if (act_format != 8) goto out; ret = g_strdup ((char *) data); XFree (data); return ret; out: XFree (data); return NULL; } cinnamon-control-center-6.4.1/panels/common/list-languages.c0000664000175000017500000000165214724311620023045 0ustar fabiofabio#include "config.h" #include #include #include #include #include "gdm-languages.h" int main (int argc, char **argv) { char **langs; guint i; setlocale (LC_ALL, NULL); textdomain (GETTEXT_PACKAGE); bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); g_type_init (); if (argc > 1) { guint i; for (i = 1; i < argc; i++) { char *lang, *norm; norm = gdm_normalize_language_name (argv[i]); lang = gdm_get_language_from_name (norm, NULL); g_print ("%s (norm: %s) == %s\n", argv[i], norm, lang); g_free (norm); g_free (lang); } return 0; } langs = gdm_get_all_language_names (); if (langs == NULL) { g_warning ("No languages found"); return 1; } for (i = 0; langs[i] != NULL; i++) g_print ("%s == %s\n", langs[i], gdm_get_language_from_name (langs[i], NULL)); g_strfreev (langs); return 0; } cinnamon-control-center-6.4.1/panels/common/csd-device-manager.c0000664000175000017500000004063414724311620023547 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2014 Red Hat * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Author: Carlos Garnacho */ #include "config.h" #include #include #include "csd-device-manager.h" #include "csd-common-enums.h" #include "csd-input-helper.h" #ifdef GDK_WINDOWING_X11 #include #endif #ifdef GDK_WINDOWING_WAYLAND #include #endif typedef struct { gchar *name; gchar *device_file; gchar *vendor_id; gchar *product_id; CsdDeviceType type; guint width; guint height; } CsdDevicePrivate; G_DEFINE_TYPE_WITH_PRIVATE (CsdDevice, csd_device, G_TYPE_OBJECT) typedef struct { GObject parent_instance; GHashTable *devices; GUdevClient *udev_client; } CsdDeviceManagerPrivate; enum { PROP_NAME = 1, PROP_DEVICE_FILE, PROP_VENDOR_ID, PROP_PRODUCT_ID, PROP_TYPE, PROP_WIDTH, PROP_HEIGHT }; enum { DEVICE_ADDED, DEVICE_REMOVED, DEVICE_CHANGED, N_SIGNALS }; /* Index matches CsdDeviceType */ const gchar *udev_ids[] = { "ID_INPUT_MOUSE", "ID_INPUT_KEYBOARD", "ID_INPUT_TOUCHPAD", "ID_INPUT_TABLET", "ID_INPUT_TOUCHSCREEN", "ID_INPUT_TABLET_PAD", }; static guint signals[N_SIGNALS] = { 0 }; G_DEFINE_TYPE_WITH_PRIVATE (CsdDeviceManager, csd_device_manager, G_TYPE_OBJECT) static void csd_device_init (CsdDevice *device) { } static void csd_device_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { CsdDevicePrivate *priv; priv = csd_device_get_instance_private (CSD_DEVICE (object)); switch (prop_id) { case PROP_NAME: priv->name = g_value_dup_string (value); break; case PROP_DEVICE_FILE: priv->device_file = g_value_dup_string (value); break; case PROP_VENDOR_ID: priv->vendor_id = g_value_dup_string (value); break; case PROP_PRODUCT_ID: priv->product_id = g_value_dup_string (value); break; case PROP_TYPE: priv->type = g_value_get_flags (value); break; case PROP_WIDTH: priv->width = g_value_get_uint (value); break; case PROP_HEIGHT: priv->height = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void csd_device_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { CsdDevicePrivate *priv; priv = csd_device_get_instance_private (CSD_DEVICE (object)); switch (prop_id) { case PROP_NAME: g_value_set_string (value, priv->name); break; case PROP_DEVICE_FILE: g_value_set_string (value, priv->device_file); break; case PROP_VENDOR_ID: g_value_set_string (value, priv->vendor_id); break; case PROP_PRODUCT_ID: g_value_set_string (value, priv->product_id); break; case PROP_TYPE: g_value_set_flags (value, priv->type); break; case PROP_WIDTH: g_value_set_uint (value, priv->width); break; case PROP_HEIGHT: g_value_set_uint (value, priv->height); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void csd_device_finalize (GObject *object) { CsdDevicePrivate *priv; priv = csd_device_get_instance_private (CSD_DEVICE (object)); g_free (priv->name); g_free (priv->vendor_id); g_free (priv->product_id); g_free (priv->device_file); G_OBJECT_CLASS (csd_device_parent_class)->finalize (object); } static void csd_device_class_init (CsdDeviceClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->set_property = csd_device_set_property; object_class->get_property = csd_device_get_property; object_class->finalize = csd_device_finalize; g_object_class_install_property (object_class, PROP_NAME, g_param_spec_string ("name", "Name", "Name", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, PROP_DEVICE_FILE, g_param_spec_string ("device-file", "Device file", "Device file", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, PROP_VENDOR_ID, g_param_spec_string ("vendor-id", "Vendor ID", "Vendor ID", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, PROP_PRODUCT_ID, g_param_spec_string ("product-id", "Product ID", "Product ID", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, PROP_TYPE, g_param_spec_flags ("type", "Device type", "Device type", CSD_TYPE_DEVICE_TYPE, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, PROP_WIDTH, g_param_spec_uint ("width", "Width", "Width", 0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, PROP_HEIGHT, g_param_spec_uint ("height", "Height", "Height", 0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } static void csd_device_manager_finalize (GObject *object) { CsdDeviceManager *manager = CSD_DEVICE_MANAGER (object); CsdDeviceManagerPrivate *priv = csd_device_manager_get_instance_private (manager); g_hash_table_destroy (priv->devices); g_object_unref (priv->udev_client); G_OBJECT_CLASS (csd_device_manager_parent_class)->finalize (object); } static GList * csd_device_manager_real_list_devices (CsdDeviceManager *manager, CsdDeviceType type) { CsdDeviceManagerPrivate *priv = csd_device_manager_get_instance_private (manager); CsdDeviceType device_type; GList *devices = NULL; GHashTableIter iter; CsdDevice *device; g_hash_table_iter_init (&iter, priv->devices); while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &device)) { device_type = csd_device_get_device_type (device); if ((device_type & type) == type) devices = g_list_prepend (devices, device); } return devices; } static CsdDevice * csd_device_manager_real_lookup_device (CsdDeviceManager *manager, GdkDevice *gdk_device) { CsdDeviceManagerPrivate *priv = csd_device_manager_get_instance_private (manager); GdkDisplay *display = gdk_device_get_display (gdk_device); const gchar *node_path = NULL; GHashTableIter iter; CsdDevice *device; #ifdef GDK_WINDOWING_X11 if (GDK_IS_X11_DISPLAY (display)) node_path = xdevice_get_device_node (gdk_x11_device_get_id (gdk_device)); #endif #ifdef GDK_WINDOWING_WAYLAND if (GDK_IS_WAYLAND_DISPLAY (display)) node_path = g_strdup (gdk_wayland_device_get_node_path (gdk_device)); #endif if (!node_path) return NULL; g_hash_table_iter_init (&iter, priv->devices); while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &device)) { if (g_strcmp0 (node_path, csd_device_get_device_file (device)) == 0) { return device; } } return NULL; } static void csd_device_manager_class_init (CsdDeviceManagerClass *klass) { CsdDeviceManagerClass *manager_class = CSD_DEVICE_MANAGER_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = csd_device_manager_finalize; manager_class->list_devices = csd_device_manager_real_list_devices; manager_class->lookup_device = csd_device_manager_real_lookup_device; signals[DEVICE_ADDED] = g_signal_new ("device-added", CSD_TYPE_DEVICE_MANAGER, G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (CsdDeviceManagerClass, device_added), NULL, NULL, NULL, G_TYPE_NONE, 1, CSD_TYPE_DEVICE | G_SIGNAL_TYPE_STATIC_SCOPE); signals[DEVICE_REMOVED] = g_signal_new ("device-removed", CSD_TYPE_DEVICE_MANAGER, G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (CsdDeviceManagerClass, device_removed), NULL, NULL, NULL, G_TYPE_NONE, 1, CSD_TYPE_DEVICE | G_SIGNAL_TYPE_STATIC_SCOPE); signals[DEVICE_CHANGED] = g_signal_new ("device-changed", CSD_TYPE_DEVICE_MANAGER, G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (CsdDeviceManagerClass, device_changed), NULL, NULL, NULL, G_TYPE_NONE, 1, CSD_TYPE_DEVICE | G_SIGNAL_TYPE_STATIC_SCOPE); } static CsdDeviceType udev_device_get_device_type (GUdevDevice *device) { CsdDeviceType type = 0; gint i; for (i = 0; i < G_N_ELEMENTS (udev_ids); i++) { if (g_udev_device_get_property_as_boolean (device, udev_ids[i])) type |= (1 << i); } return type; } static gboolean device_is_evdev (GUdevDevice *device) { const gchar *device_file; device_file = g_udev_device_get_device_file (device); if (!device_file || strstr (device_file, "/event") == NULL) return FALSE; return g_udev_device_get_property_as_boolean (device, "ID_INPUT"); } static CsdDevice * create_device (GUdevDevice *udev_device) { const gchar *vendor, *product, *name; guint width, height; g_autoptr(GUdevDevice) parent = NULL; parent = g_udev_device_get_parent (udev_device); g_assert (parent != NULL); name = g_udev_device_get_sysfs_attr (parent, "name"); vendor = g_udev_device_get_property (udev_device, "ID_VENDOR_ID"); product = g_udev_device_get_property (udev_device, "ID_MODEL_ID"); if (!vendor || !product) { vendor = g_udev_device_get_sysfs_attr (udev_device, "device/id/vendor"); product = g_udev_device_get_sysfs_attr (udev_device, "device/id/product"); } width = g_udev_device_get_property_as_int (udev_device, "ID_INPUT_WIDTH_MM"); height = g_udev_device_get_property_as_int (udev_device, "ID_INPUT_HEIGHT_MM"); return g_object_new (CSD_TYPE_DEVICE, "name", name, "device-file", g_udev_device_get_device_file (udev_device), "type", udev_device_get_device_type (udev_device), "vendor-id", vendor, "product-id", product, "width", width, "height", height, NULL); } static void add_device (CsdDeviceManager *manager, GUdevDevice *udev_device) { CsdDeviceManagerPrivate *priv = csd_device_manager_get_instance_private (manager); GUdevDevice *parent; CsdDevice *device; const gchar *syspath; parent = g_udev_device_get_parent (udev_device); if (!parent) return; device = create_device (udev_device); syspath = g_udev_device_get_sysfs_path (udev_device); g_hash_table_insert (priv->devices, g_strdup (syspath), device); g_signal_emit_by_name (manager, "device-added", device); } static void remove_device (CsdDeviceManager *manager, GUdevDevice *udev_device) { CsdDeviceManagerPrivate *priv = csd_device_manager_get_instance_private (manager); CsdDevice *device; const gchar *syspath; syspath = g_udev_device_get_sysfs_path (udev_device); device = g_hash_table_lookup (priv->devices, syspath); if (!device) return; g_hash_table_steal (priv->devices, syspath); g_signal_emit_by_name (manager, "device-removed", device); g_object_unref (device); } static void udev_event_cb (GUdevClient *client, gchar *action, GUdevDevice *device, CsdDeviceManager *manager) { if (!device_is_evdev (device)) return; if (g_strcmp0 (action, "add") == 0) { add_device (manager, device); } else if (g_strcmp0 (action, "remove") == 0) { remove_device (manager, device); } } static void csd_device_manager_init (CsdDeviceManager *manager) { CsdDeviceManagerPrivate *priv = csd_device_manager_get_instance_private (manager); const gchar *subsystems[] = { "input", NULL }; g_autoptr(GList) devices = NULL; GList *l; priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) g_object_unref); priv->udev_client = g_udev_client_new (subsystems); g_signal_connect (priv->udev_client, "uevent", G_CALLBACK (udev_event_cb), manager); devices = g_udev_client_query_by_subsystem (priv->udev_client, subsystems[0]); for (l = devices; l; l = l->next) { g_autoptr(GUdevDevice) device = l->data; if (device_is_evdev (device)) add_device (manager, device); } } CsdDeviceManager * csd_device_manager_get (void) { CsdDeviceManager *manager; GdkScreen *screen; screen = gdk_screen_get_default (); g_return_val_if_fail (screen != NULL, NULL); manager = g_object_get_data (G_OBJECT (screen), "csd-device-manager-data"); if (!manager) { manager = g_object_new (CSD_TYPE_DEVICE_MANAGER, NULL); g_object_set_data_full (G_OBJECT (screen), "csd-device-manager-data", manager, (GDestroyNotify) g_object_unref); } return manager; } GList * csd_device_manager_list_devices (CsdDeviceManager *manager, CsdDeviceType type) { g_return_val_if_fail (CSD_IS_DEVICE_MANAGER (manager), NULL); return CSD_DEVICE_MANAGER_GET_CLASS (manager)->list_devices (manager, type); } CsdDeviceType csd_device_get_device_type (CsdDevice *device) { CsdDevicePrivate *priv; g_return_val_if_fail (CSD_IS_DEVICE (device), 0); priv = csd_device_get_instance_private (device); return priv->type; } void csd_device_get_device_ids (CsdDevice *device, const gchar **vendor, const gchar **product) { CsdDevicePrivate *priv; g_return_if_fail (CSD_IS_DEVICE (device)); priv = csd_device_get_instance_private (device); if (vendor) *vendor = priv->vendor_id; if (product) *product = priv->product_id; } GSettings * csd_device_get_settings (CsdDevice *device) { const gchar *schema = NULL, *vendor, *product; CsdDeviceType type; g_autofree gchar *path = NULL; g_return_val_if_fail (CSD_IS_DEVICE (device), NULL); type = csd_device_get_device_type (device); if (type & (CSD_DEVICE_TYPE_TOUCHSCREEN | CSD_DEVICE_TYPE_TABLET)) { csd_device_get_device_ids (device, &vendor, &product); if (type & CSD_DEVICE_TYPE_TOUCHSCREEN) { schema = "org.cinnamon.desktop.peripherals.touchscreen"; path = g_strdup_printf ("/org/cinnamon/desktop/peripherals/touchscreens/%s:%s/", vendor, product); } else if (type & CSD_DEVICE_TYPE_TABLET) { schema = "org.cinnamon.desktop.peripherals.tablet"; path = g_strdup_printf ("/org/cinnamon/desktop/peripherals/tablets/%s:%s/", vendor, product); } } else if (type & (CSD_DEVICE_TYPE_MOUSE | CSD_DEVICE_TYPE_TOUCHPAD)) { schema = "org.cinnamon.desktop.peripherals.mouse"; } else if (type & CSD_DEVICE_TYPE_KEYBOARD) { schema = "org.cinnamon.desktop.peripherals.keyboard"; } else { return NULL; } if (path) { return g_settings_new_with_path (schema, path); } else { return g_settings_new (schema); } } const gchar * csd_device_get_name (CsdDevice *device) { CsdDevicePrivate *priv; g_return_val_if_fail (CSD_IS_DEVICE (device), NULL); priv = csd_device_get_instance_private (device); return priv->name; } const gchar * csd_device_get_device_file (CsdDevice *device) { CsdDevicePrivate *priv; g_return_val_if_fail (CSD_IS_DEVICE (device), NULL); priv = csd_device_get_instance_private (device); return priv->device_file; } gboolean csd_device_get_dimensions (CsdDevice *device, guint *width, guint *height) { CsdDevicePrivate *priv; g_return_val_if_fail (CSD_IS_DEVICE (device), FALSE); priv = csd_device_get_instance_private (device); if (width) *width = priv->width; if (height) *height = priv->height; return priv->width > 0 && priv->height > 0; } CsdDevice * csd_device_manager_lookup_gdk_device (CsdDeviceManager *manager, GdkDevice *gdk_device) { CsdDeviceManagerClass *klass; g_return_val_if_fail (CSD_IS_DEVICE_MANAGER (manager), NULL); g_return_val_if_fail (GDK_IS_DEVICE (gdk_device), NULL); klass = CSD_DEVICE_MANAGER_GET_CLASS (manager); if (!klass->lookup_device) return NULL; return klass->lookup_device (manager, gdk_device); } cinnamon-control-center-6.4.1/panels/common/cc-language-chooser.c0000664000175000017500000002567614724311620023750 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright 2009-2010 Red Hat, Inc, * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Written by: Matthias Clasen */ #include "config.h" #include #include #include #include #include #include #include #include "cc-language-chooser.h" #include "cc-common-language.h" #include "gdm-languages.h" gchar * cc_language_chooser_get_language (GtkWidget *chooser) { GtkTreeView *tv; GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter; gchar *lang; tv = (GtkTreeView *) g_object_get_data (G_OBJECT (chooser), "list"); selection = gtk_tree_view_get_selection (tv); gdk_threads_enter (); if (gtk_tree_selection_get_selected (selection, &model, &iter)) gtk_tree_model_get (model, &iter, LOCALE_COL, &lang, -1); else lang = NULL; gdk_threads_leave (); return lang; } void cc_language_chooser_clear_filter (GtkWidget *chooser) { GtkEntry *entry; entry = (GtkEntry *) g_object_get_data (G_OBJECT (chooser), "filter-entry"); gtk_entry_set_text (entry, ""); } static void row_activated (GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, GtkWidget *chooser) { gtk_dialog_response (GTK_DIALOG (chooser), GTK_RESPONSE_OK); } static void languages_foreach_cb (gpointer key, gpointer value, gpointer user_data) { GtkListStore *store = (GtkListStore *) user_data; const char *locale = (const char *) key; const char *display_locale = (const char *) value; GtkTreeIter iter; gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter, LOCALE_COL, locale, DISPLAY_LOCALE_COL, display_locale, -1); } void cc_add_user_languages (GtkTreeModel *model) { char *name; GtkTreeIter iter; GtkListStore *store = GTK_LIST_STORE (model); GHashTable *user_langs; const char *display; gtk_list_store_clear (store); user_langs = cc_common_language_get_initial_languages (); /* Add the current locale first */ // name = cc_common_language_get_current_language (); // display = g_hash_table_lookup (user_langs, name); name = g_strdup ("en"); display = gdm_get_language_from_name (name, NULL); gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter, LOCALE_COL, name, DISPLAY_LOCALE_COL, display, -1); if (g_hash_table_lookup (user_langs, name) != NULL) g_hash_table_remove (user_langs, name); g_free (name); /* The rest of the languages */ g_hash_table_foreach (user_langs, (GHFunc) languages_foreach_cb, store); /* And now the "Other..." selection */ // gtk_list_store_append (store, &iter); // gtk_list_store_set (store, &iter, LOCALE_COL, NULL, DISPLAY_LOCALE_COL, _("Other..."), -1); g_hash_table_destroy (user_langs); } static void remove_timeout (gpointer data, GObject *where_the_object_was) { guint timeout = GPOINTER_TO_UINT (data); if (timeout){ g_source_remove (timeout); } } static void remove_async (gpointer data) { guint async_id = GPOINTER_TO_UINT (data); if (async_id) { g_source_remove (async_id); } } static void selection_changed (GtkTreeSelection *selection, GtkWidget *chooser) { gtk_dialog_set_response_sensitive (GTK_DIALOG (chooser), GTK_RESPONSE_OK, gtk_tree_selection_get_selected (selection, NULL, NULL)); } static gboolean finish_language_chooser (gpointer user_data) { GtkWidget *chooser = (GtkWidget *) user_data; GtkWidget *list; GtkTreeModel *model; GtkWindow *parent; GHashTable *user_langs; guint timeout; guint async_id; GtkTreeSelection *selection; gboolean regions; /* Did we get called after the widget was destroyed? */ if (chooser == NULL) return FALSE; regions = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (chooser), "regions")); list = g_object_get_data (G_OBJECT (chooser), "list"); model = gtk_tree_view_get_model (GTK_TREE_VIEW (list)); model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model)); user_langs = g_object_get_data (G_OBJECT (chooser), "user-langs"); async_id = cc_common_language_add_available_languages (GTK_LIST_STORE (model), regions, user_langs); g_object_set_data_full (G_OBJECT (chooser), "language-async", GUINT_TO_POINTER (async_id), remove_async); parent = gtk_window_get_transient_for (GTK_WINDOW (chooser)); gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (parent)), NULL); g_object_set_data (G_OBJECT (chooser), "user-langs", NULL); timeout = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (chooser), "timeout")); g_object_weak_unref (G_OBJECT (chooser), (GWeakNotify) remove_timeout, GUINT_TO_POINTER (timeout)); /* And now listen for changes */ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list)); g_signal_connect (G_OBJECT (selection), "changed", G_CALLBACK (selection_changed), chooser); return FALSE; } static void filter_clear (GtkEntry *entry, GtkEntryIconPosition icon_pos, GdkEvent *event, gpointer user_data) { gtk_entry_set_text (entry, ""); } static void filter_changed (GtkWidget *entry, GParamSpec *pspec, GtkWidget *list) { const gchar *pattern; GtkTreeModel *filter_model; GtkTreeModel *model; pattern = gtk_entry_get_text (GTK_ENTRY (entry)); filter_model = gtk_tree_view_get_model (GTK_TREE_VIEW (list)); model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (filter_model)); if (g_strcmp0 (pattern, "") == 0) { g_object_set (G_OBJECT (entry), "secondary-icon-name", "edit-find-symbolic", "secondary-icon-activatable", FALSE, "secondary-icon-sensitive", FALSE, NULL); g_object_set_data_full (G_OBJECT (model), "filter-string", g_strdup (""), g_free); } else { g_object_set (G_OBJECT (entry), "secondary-icon-name", "edit-clear-symbolic", "secondary-icon-activatable", TRUE, "secondary-icon-sensitive", TRUE, NULL); g_object_set_data_full (G_OBJECT (model), "filter-string", g_utf8_casefold (pattern, -1), g_free); } gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter_model)); } static gboolean filter_languages (GtkTreeModel *model, GtkTreeIter *iter, gpointer data) { const gchar *filter_string; gchar *locale, *l; gboolean visible; filter_string = g_object_get_data (G_OBJECT (model), "filter-string"); if (filter_string == NULL) { return TRUE; } gdk_threads_enter (); gtk_tree_model_get (model, iter, DISPLAY_LOCALE_COL, &locale, -1); gdk_threads_leave (); l = g_utf8_casefold (locale, -1); visible = strstr (l, filter_string) != NULL; g_free (locale); g_free (l); return visible; } GtkWidget * cc_language_chooser_new (GtkWidget *parent, gboolean regions) { GtkBuilder *builder; const char *filename; GError *error = NULL; GtkWidget *chooser; GtkWidget *list; GtkWidget *button; GtkWidget *entry; GtkWidget *widget; GHashTable *user_langs; GdkCursor *cursor; guint timeout; GtkTreeModel *model; GtkTreeModel *filter_model; builder = gtk_builder_new (); filename = UIDIR "/language-chooser.ui"; if (!g_file_test (filename, G_FILE_TEST_EXISTS)) filename = "data/language-chooser.ui"; if (!gtk_builder_add_from_file (builder, filename, &error)) { g_warning ("failed to load language chooser: %s", error->message); g_error_free (error); return NULL; } chooser = (GtkWidget *) gtk_builder_get_object (builder, "dialog"); if (regions) { widget = (GtkWidget *) gtk_builder_get_object (builder, "title"); gtk_label_set_text (GTK_LABEL (widget), _("Select a region")); /* communicate the preference to finish_language_chooser() */ g_object_set_data (G_OBJECT (chooser), "regions", GINT_TO_POINTER (TRUE)); } list = (GtkWidget *) gtk_builder_get_object (builder, "language-list"); g_object_set_data (G_OBJECT (chooser), "list", list); g_signal_connect (list, "row-activated", G_CALLBACK (row_activated), chooser); button = (GtkWidget *) gtk_builder_get_object (builder, "ok-button"); gtk_widget_grab_default (button); entry = (GtkWidget *) gtk_builder_get_object (builder, "filter-entry"); g_object_set_data (G_OBJECT (chooser), "filter-entry", entry); g_signal_connect (entry, "notify::text", G_CALLBACK (filter_changed), list); g_signal_connect (entry, "icon-release", G_CALLBACK (filter_clear), NULL); gtk_widget_grab_focus (entry); user_langs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); cc_common_language_setup_list (list, user_langs); model = gtk_tree_view_get_model (GTK_TREE_VIEW (list)); filter_model = gtk_tree_model_filter_new (model, NULL); gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter_model), filter_languages, NULL, NULL); gtk_tree_view_set_model (GTK_TREE_VIEW (list), filter_model); /* Setup so that the list is added after the dialogue is shown */ cursor = gdk_cursor_new (GDK_WATCH); gdk_window_set_cursor (gtk_widget_get_window (parent), cursor); g_object_unref (cursor); gtk_window_set_transient_for (GTK_WINDOW (chooser), GTK_WINDOW (parent)); g_object_set_data_full (G_OBJECT (chooser), "user-langs", user_langs, (GDestroyNotify) g_hash_table_destroy); timeout = g_idle_add ((GSourceFunc) finish_language_chooser, chooser); g_object_set_data (G_OBJECT (chooser), "timeout", GUINT_TO_POINTER (timeout)); g_object_weak_ref (G_OBJECT (chooser), (GWeakNotify) remove_timeout, GUINT_TO_POINTER (timeout)); g_object_unref (builder); return chooser; } cinnamon-control-center-6.4.1/panels/common/cc-common-language.h0000664000175000017500000000414614724311620023570 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright 2009-2010 Red Hat, Inc, * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Written by: Matthias Clasen */ #ifndef __CC_COMMON_LANGUAGE_H__ #define __CC_COMMON_LANGUAGE_H__ #include G_BEGIN_DECLS enum { LOCALE_COL, DISPLAY_LOCALE_COL, SEPARATOR_COL, USER_LANGUAGE, NUM_COLS }; gboolean cc_common_language_get_iter_for_language (GtkTreeModel *model, const gchar *lang, GtkTreeIter *iter); gboolean cc_common_language_get_iter_for_region (GtkTreeModel *model, const gchar *lang, GtkTreeIter *iter); guint cc_common_language_add_available_languages (GtkListStore *store, gboolean regions, GHashTable *user_langs); gboolean cc_common_language_has_font (const gchar *locale); gchar *cc_common_language_get_current_language (void); GHashTable *cc_common_language_get_initial_languages (void); GHashTable *cc_common_language_get_initial_regions (const gchar *lang); void cc_common_language_setup_list (GtkWidget *treeview, GHashTable *initial); void cc_common_language_select_current_language (GtkTreeView *treeview); G_END_DECLS #endif cinnamon-control-center-6.4.1/panels/common/csd-input-helper.h0000664000175000017500000000202714724311620023313 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2010 Bastien Nocera * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ #pragma once G_BEGIN_DECLS #include gboolean touchpad_is_present (void); gboolean touchscreen_is_present (void); gboolean mouse_is_present (void); char * xdevice_get_device_node (int deviceid); G_END_DECLS cinnamon-control-center-6.4.1/panels/region/0000775000175000017500000000000014724311620017751 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/region/meson.build0000664000175000017500000000160714724311620022117 0ustar fabiofabio panel_region_sources = [ 'cc-region-panel.c', 'cinnamon-region-panel-xkb.c', 'cinnamon-region-panel-xkblt.c', 'cinnamon-region-panel-xkbltadd.c', 'cinnamon-region-panel-xkbot.c', 'cinnamon-region-panel-xkbpv.c', 'region-module.c', ] panel_region = shared_library('region', panel_region_sources, include_directories: rootInclude, link_with: [ libcinnamon_control_center, ], dependencies: [ glib, gtk, cinn_desktop, libgnomekbd, libgnomekbdui, libxklavier ], install: true, install_dir: panels_dir ) install_data([ 'cinnamon-region-panel-layout-chooser.ui', 'cinnamon-region-panel-options-dialog.ui', 'cinnamon-region-panel.ui', ], install_dir: ui_dir, ) # Region panel is imported as a page of cs_keyboard so no share/applications entry needed. install_data( 'cinnamon-region-panel.desktop', install_dir: panel_def_dir )cinnamon-control-center-6.4.1/panels/region/cinnamon-region-panel-layout-chooser.ui0000664000175000017500000002022114724311620027440 0ustar fabiofabio layout_list_model False False 5 Choose a Layout True center-on-parent dialog True False vertical 2 True False end Preview True True True False False False 0 True gtk-cancel True True True False False True False False end 1 gtk-add True True True False False True False False end 2 True False 5 6 True False 6 True False 0 Select an input source to add False False 0 True True never etched-in 450 250 True True filtered_layout_list_model False 0 True True 1 True True 0 True True • edit-find-symbolic False False False False end 1 True True 1 btnPreview btnOk btnCancel cinnamon-control-center-6.4.1/panels/region/region-module.c0000664000175000017500000000202514724311620022662 0ustar fabiofabio/* * Copyright (C) 2010 Intel, Inc * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Author: Sergey Udaltsov * */ #include #include "cc-region-panel.h" #include void g_io_module_load (GIOModule * module) { /* register the panel */ cc_region_panel_register (module); } void g_io_module_unload (GIOModule * module) { } cinnamon-control-center-6.4.1/panels/region/cinnamon-region-panel-xkblt.c0000664000175000017500000003106014724311620025417 0ustar fabiofabio/* cinnamon-region-panel-xkblt.c * Copyright (C) 2003-2007 Sergey V. Udaltsov * * Written by: Sergey V. Udaltsov * * 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, 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 Street - Suite 500, Boston, MA * 02110-1335, USA. */ #include #include #include #include #include #include "cinnamon-region-panel-xkb.h" enum { SEL_LAYOUT_TREE_COL_DESCRIPTION, SEL_LAYOUT_TREE_COL_ID, SEL_LAYOUT_TREE_COL_ENABLED, SEL_LAYOUT_N_COLS }; static int idx2select = -1; static int max_selected_layouts = -1; static GtkCellRenderer *text_renderer; static gboolean disable_buttons_sensibility_update = FALSE; static gboolean get_selected_iter (GtkBuilder *dialog, GtkTreeModel **model, GtkTreeIter *iter) { GtkTreeSelection *selection; selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (WID ("xkb_layouts_selected"))); return gtk_tree_selection_get_selected (selection, model, iter); } static void set_selected_path (GtkBuilder *dialog, GtkTreePath *path) { GtkTreeSelection *selection; selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (WID ("xkb_layouts_selected"))); gtk_tree_selection_select_path (selection, path); } static gint find_selected_layout_idx (GtkBuilder *dialog) { GtkTreeIter selected_iter; GtkTreeModel *model; GtkTreePath *path; gint *indices; gint rv; if (!get_selected_iter (dialog, &model, &selected_iter)) return -1; path = gtk_tree_model_get_path (model, &selected_iter); if (path == NULL) return -1; indices = gtk_tree_path_get_indices (path); rv = indices[0]; gtk_tree_path_free (path); return rv; } gchar ** xkb_layouts_get_selected_list (void) { gchar **retval; retval = g_settings_get_strv (xkb_keyboard_settings, GKBD_KEYBOARD_CONFIG_KEY_LAYOUTS); if (retval == NULL || retval[0] == NULL) { g_strfreev (retval); retval = g_strdupv (initial_config.layouts_variants); } return retval; } gint xkb_get_default_group () { return g_settings_get_int (xkb_desktop_settings, GKBD_DESKTOP_CONFIG_KEY_DEFAULT_GROUP); } void xkb_save_default_group (gint default_group) { g_settings_set_int (xkb_desktop_settings, GKBD_DESKTOP_CONFIG_KEY_DEFAULT_GROUP, default_group); } static void xkb_layouts_enable_disable_buttons (GtkBuilder * dialog) { GtkWidget *add_layout_btn = WID ("xkb_layouts_add"); GtkWidget *show_layout_btn = WID ("xkb_layouts_show"); GtkWidget *del_layout_btn = WID ("xkb_layouts_remove"); GtkWidget *selected_layouts_tree = WID ("xkb_layouts_selected"); GtkWidget *move_up_layout_btn = WID ("xkb_layouts_move_up"); GtkWidget *move_down_layout_btn = WID ("xkb_layouts_move_down"); GtkTreeSelection *s_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (selected_layouts_tree)); const int n_selected_selected_layouts = gtk_tree_selection_count_selected_rows (s_selection); GtkTreeModel *selected_layouts_model = gtk_tree_view_get_model (GTK_TREE_VIEW (selected_layouts_tree)); const int n_selected_layouts = gtk_tree_model_iter_n_children (selected_layouts_model, NULL); gint sidx = find_selected_layout_idx (dialog); if (disable_buttons_sensibility_update) return; gtk_widget_set_sensitive (add_layout_btn, (n_selected_layouts < max_selected_layouts || max_selected_layouts == 0)); gtk_widget_set_sensitive (del_layout_btn, (n_selected_layouts > 1) && (n_selected_selected_layouts > 0)); gtk_widget_set_sensitive (show_layout_btn, (n_selected_selected_layouts > 0)); gtk_widget_set_sensitive (move_up_layout_btn, sidx > 0); gtk_widget_set_sensitive (move_down_layout_btn, sidx >= 0 && sidx < (n_selected_layouts - 1)); } static void update_layouts_list (GtkTreeModel *model, GtkBuilder *dialog) { gboolean cont; GtkTreeIter iter; GPtrArray *array; array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_free); cont = gtk_tree_model_get_iter_first (model, &iter); while (cont) { char *id; gtk_tree_model_get (model, &iter, SEL_LAYOUT_TREE_COL_ID, &id, -1); g_ptr_array_add (array, id); cont = gtk_tree_model_iter_next (model, &iter); } g_ptr_array_add (array, NULL); xkb_layouts_set_selected_list (array->pdata); g_ptr_array_free (array, TRUE); xkb_layouts_enable_disable_buttons (dialog); } static void xkb_layouts_drag_end (GtkWidget *widget, GdkDragContext *drag_context, gpointer user_data) { update_layouts_list (gtk_tree_view_get_model (GTK_TREE_VIEW (widget)), GTK_BUILDER (user_data)); } void xkb_layouts_prepare_selected_tree (GtkBuilder * dialog) { GtkListStore *list_store; GtkWidget *tree_view = WID ("xkb_layouts_selected"); GtkTreeSelection *selection; GtkTreeViewColumn *desc_column; list_store = gtk_list_store_new (SEL_LAYOUT_N_COLS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN); text_renderer = GTK_CELL_RENDERER (gtk_cell_renderer_text_new ()); desc_column = gtk_tree_view_column_new_with_attributes (_("Layout"), text_renderer, "text", SEL_LAYOUT_TREE_COL_DESCRIPTION, "sensitive", SEL_LAYOUT_TREE_COL_ENABLED, NULL); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), GTK_TREE_MODEL (list_store)); gtk_tree_view_column_set_sizing (desc_column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_column_set_resizable (desc_column, TRUE); gtk_tree_view_column_set_expand (desc_column, TRUE); gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), desc_column); g_signal_connect_swapped (G_OBJECT (selection), "changed", G_CALLBACK (xkb_layouts_enable_disable_buttons), dialog); max_selected_layouts = xkl_engine_get_max_num_groups (engine); /* Setting up DnD */ gtk_tree_view_set_reorderable (GTK_TREE_VIEW (tree_view), TRUE); g_signal_connect (G_OBJECT (tree_view), "drag-end", G_CALLBACK (xkb_layouts_drag_end), dialog); } gchar * xkb_layout_description_utf8 (const gchar * visible) { char *l, *sl, *v, *sv; if (gkbd_keyboard_config_get_descriptions (config_registry, visible, &sl, &l, &sv, &v)) visible = gkbd_keyboard_config_format_full_description (l, v); return g_strstrip (g_strdup (visible)); } void xkb_layouts_fill_selected_tree (GtkBuilder * dialog) { gchar **layouts = xkb_layouts_get_selected_list (); guint i; GtkListStore *list_store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (WID ("xkb_layouts_selected")))); /* temporarily disable the buttons' status update */ disable_buttons_sensibility_update = TRUE; gtk_list_store_clear (list_store); for (i = 0; layouts != NULL && layouts[i] != NULL; i++) { char *cur_layout = layouts[i]; gchar *utf_visible = xkb_layout_description_utf8 (cur_layout); gtk_list_store_insert_with_values (list_store, NULL, G_MAXINT, SEL_LAYOUT_TREE_COL_DESCRIPTION, utf_visible, SEL_LAYOUT_TREE_COL_ID, cur_layout, SEL_LAYOUT_TREE_COL_ENABLED, i < max_selected_layouts, -1); g_free (utf_visible); } g_strfreev (layouts); /* enable the buttons' status update */ disable_buttons_sensibility_update = FALSE; if (idx2select != -1) { GtkTreeSelection *selection = gtk_tree_view_get_selection ((GTK_TREE_VIEW (WID ("xkb_layouts_selected")))); GtkTreePath *path = gtk_tree_path_new_from_indices (idx2select, -1); gtk_tree_selection_select_path (selection, path); gtk_tree_path_free (path); idx2select = -1; } else { /* if there is nothing to select - just enable/disable the buttons, otherwise it would be done by the selection change */ xkb_layouts_enable_disable_buttons (dialog); } } static void add_default_switcher_if_necessary () { gchar **layouts_list = xkb_layouts_get_selected_list(); gchar **options_list = xkb_options_get_selected_list (); gboolean was_appended; options_list = gkbd_keyboard_config_add_default_switch_option_if_necessary (layouts_list, options_list, &was_appended); if (was_appended) xkb_options_set_selected_list (options_list); g_strfreev (options_list); } static void chooser_response (GtkDialog *chooser, int response_id, GtkBuilder *dialog) { if (response_id == GTK_RESPONSE_OK) { char *id, *name; GtkListStore *list_store; list_store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (WID ("xkb_layouts_selected")))); id = xkb_layout_chooser_get_selected_id (chooser); name = xkb_layout_description_utf8 (id); gtk_list_store_insert_with_values (list_store, NULL, G_MAXINT, SEL_LAYOUT_TREE_COL_DESCRIPTION, name, SEL_LAYOUT_TREE_COL_ID, id, SEL_LAYOUT_TREE_COL_ENABLED, TRUE, -1); g_free (name); add_default_switcher_if_necessary (); update_layouts_list (GTK_TREE_MODEL (list_store), dialog); } xkb_layout_chooser_response (chooser, response_id); } static void add_selected_layout (GtkWidget * button, GtkBuilder * dialog) { GtkWidget *chooser; chooser = xkb_layout_choose (dialog); g_signal_connect (G_OBJECT (chooser), "response", G_CALLBACK (chooser_response), dialog); } static void show_selected_layout (GtkWidget * button, GtkBuilder * dialog) { gint idx = find_selected_layout_idx (dialog); if (idx != -1) { GtkWidget *parent = WID ("region_notebook"); GtkWidget *popup = gkbd_keyboard_drawing_dialog_new (); gkbd_keyboard_drawing_dialog_set_group (popup, config_registry, idx); gtk_window_set_transient_for (GTK_WINDOW (popup), GTK_WINDOW (gtk_widget_get_toplevel (parent))); gtk_widget_show_all (popup); } } static void remove_selected_layout (GtkWidget * button, GtkBuilder * dialog) { GtkTreeModel *model; GtkTreeIter iter; if (get_selected_iter (dialog, &model, &iter) == FALSE) return; gtk_list_store_remove (GTK_LIST_STORE (model), &iter); update_layouts_list (model, dialog); } static void move_up_selected_layout (GtkWidget * button, GtkBuilder * dialog) { GtkTreeModel *model; GtkTreeIter iter, prev; GtkTreePath *path; if (get_selected_iter (dialog, &model, &iter) == FALSE) return; prev = iter; if (!gtk_tree_model_iter_previous (model, &prev)) return; path = gtk_tree_model_get_path (model, &prev); gtk_list_store_swap (GTK_LIST_STORE (model), &iter, &prev); update_layouts_list (model, dialog); set_selected_path (dialog, path); gtk_tree_path_free (path); } static void move_down_selected_layout (GtkWidget * button, GtkBuilder * dialog) { GtkTreeModel *model; GtkTreeIter iter, next; GtkTreePath *path; if (get_selected_iter (dialog, &model, &iter) == FALSE) return; next = iter; if (!gtk_tree_model_iter_next (model, &next)) return; path = gtk_tree_model_get_path (model, &next); gtk_list_store_swap (GTK_LIST_STORE (model), &iter, &next); update_layouts_list (model, dialog); set_selected_path (dialog, path); gtk_tree_path_free (path); } void xkb_layouts_register_buttons_handlers (GtkBuilder * dialog) { g_signal_connect (G_OBJECT (WID ("xkb_layouts_add")), "clicked", G_CALLBACK (add_selected_layout), dialog); g_signal_connect (G_OBJECT (WID ("xkb_layouts_show")), "clicked", G_CALLBACK (show_selected_layout), dialog); g_signal_connect (G_OBJECT (WID ("xkb_layouts_remove")), "clicked", G_CALLBACK (remove_selected_layout), dialog); g_signal_connect (G_OBJECT (WID ("xkb_layouts_move_up")), "clicked", G_CALLBACK (move_up_selected_layout), dialog); g_signal_connect (G_OBJECT (WID ("xkb_layouts_move_down")), "clicked", G_CALLBACK (move_down_selected_layout), dialog); } static void xkb_layouts_update_list (GSettings * settings, gchar * key, GtkBuilder * dialog) { if (strcmp (key, GKBD_KEYBOARD_CONFIG_KEY_LAYOUTS) == 0) { xkb_layouts_fill_selected_tree (dialog); enable_disable_restoring (dialog); } } void xkb_layouts_register_conf_listener (GtkBuilder * dialog) { g_signal_connect (xkb_keyboard_settings, "changed", G_CALLBACK (xkb_layouts_update_list), dialog); } cinnamon-control-center-6.4.1/panels/region/cinnamon-region-panel-options-dialog.ui0000664000175000017500000000726314724311620027426 0ustar fabiofabio False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 Keyboard Layout Options center-on-parent 550 400 dialog True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK vertical 2 True True 5 out True False none True False False True 1 True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK end gtk-close True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK False True False False 1 button2 cinnamon-control-center-6.4.1/panels/region/cinnamon-region-panel.ui0000664000175000017500000007622614724311620024505 0ustar fabiofabio 100 2000 500 10 10 1 100000 1 1 10 10 110 30 10 10 100 2500 1000 200 200 500 0.5 10 10 900 0.5 10 10 3000 1800 10 10 10 1000 300 10 10 10 2000 300 10 10 1 100000 1 1 10 False 5 Region and Language 600 430 dialog True False vertical 2 False False True end 0 True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 12 True False 10 12 True False 12 True False True True in True True False True True 0 True False icons False 1 True False Add Layout True list-add-symbolic False True True False Remove Layout True list-remove-symbolic False True True False Move Up True go-up-symbolic False True True False Move Down True go-down-symbolic False True True False Preview Layout True input-keyboard-symbolic False True False True 1 True True 0 True False 12 True False 6 Include less-common layouts in the selection list True True False True True True 0 True False True True 1 Use the same layout for all windows True True False 0 True True True True 2 Allow different layouts for individual windows True True False 0 True True chk_same_group True True 3 True False 12 True False New windows use the default layout True True False 0 True True True True 0 New windows use the previous window's layout True True False 0 True True chk_new_windows_default_layout True True 1 True True 4 True False True True 5 True False Display options 0 True True 6 True False 12 True False Use a country flag, if available, to represent keyboard layouts True True False 0 True True True 0 Show the layout name instead of the group name when using text to represent a layout True True False 0 True True True 1 Prefer upper-case when using text to represent a layout True True False 0 True True True 2 True True 8 False False 0 True False True False 1 True False 6 end _Options... True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True View and edit keyboard layout options View and edit keyboard layout options True False False 0 Reset to De_faults True True True True Replace the current keyboard layout settings with the default settings Replace the current keyboard layout settings with the default settings True False False end 1 True False False 2 True True 1 True True 1 False False 0 False True 1 cinnamon-control-center-6.4.1/panels/region/cinnamon-region-panel-xkbpv.c0000664000175000017500000000637714724311620025442 0ustar fabiofabio/* cinnamon-region-panel-xkbpv.c * Copyright (C) 2003-2007 Sergey V. Udaltsov * * Written by: Sergey V. Udaltsov * * 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, 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 Street - Suite 500, Boston, MA * 02110-1335, USA. */ #include #include #include "cinnamon-region-panel-xkb.h" #ifdef HAVE_X11_EXTENSIONS_XKB_H #include "X11/XKBlib.h" /** * BAD STYLE: Taken from xklavier_private_xkb.h * Any ideas on architectural improvements are WELCOME */ extern gboolean xkl_xkb_config_native_prepare (XklEngine * engine, const XklConfigRec * data, XkbComponentNamesPtr component_names); extern void xkl_xkb_config_native_cleanup (XklEngine * engine, XkbComponentNamesPtr component_names); /* */ #endif static GkbdKeyboardDrawingGroupLevel groupsLevels[] = { {0, 1}, {0, 3}, {0, 0}, {0, 2} }; static GkbdKeyboardDrawingGroupLevel *pGroupsLevels[] = { groupsLevels, groupsLevels + 1, groupsLevels + 2, groupsLevels + 3 }; GtkWidget * xkb_layout_preview_create_widget (GtkBuilder * chooserDialog) { GtkWidget *kbdraw = gkbd_keyboard_drawing_new (); gkbd_keyboard_drawing_set_groups_levels (GKBD_KEYBOARD_DRAWING (kbdraw), pGroupsLevels); return kbdraw; } void xkb_layout_preview_set_drawing_layout (GtkWidget * kbdraw, const gchar * id) { #ifdef HAVE_X11_EXTENSIONS_XKB_H if (kbdraw != NULL) { if (id != NULL) { XklConfigRec *data; char **p, *layout, *variant; XkbComponentNamesRec component_names; data = xkl_config_rec_new (); if (xkl_config_rec_get_from_server (data, engine)) { if ((p = data->layouts) != NULL) g_strfreev (data->layouts); if ((p = data->variants) != NULL) g_strfreev (data->variants); data->layouts = g_new0 (char *, 2); data->variants = g_new0 (char *, 2); if (gkbd_keyboard_config_split_items (id, &layout, &variant) && variant != NULL) { data->layouts[0] = (layout == NULL) ? NULL : g_strdup (layout); data->variants[0] = (variant == NULL) ? NULL : g_strdup (variant); } else { data->layouts[0] = (id == NULL) ? NULL : g_strdup (id); data->variants[0] = NULL; } if (xkl_xkb_config_native_prepare (engine, data, &component_names)) { gkbd_keyboard_drawing_set_keyboard (GKBD_KEYBOARD_DRAWING (kbdraw), &component_names); xkl_xkb_config_native_cleanup (engine, &component_names); } } g_object_unref (G_OBJECT (data)); } else gkbd_keyboard_drawing_set_keyboard (GKBD_KEYBOARD_DRAWING (kbdraw), NULL); } #endif } cinnamon-control-center-6.4.1/panels/region/cc-region-panel.h0000664000175000017500000000370214724311620023067 0ustar fabiofabio/* * Copyright (C) 2010 Intel, Inc * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Author: Sergey Udaltsov * */ #ifndef _CC_REGION_PANEL_H #define _CC_REGION_PANEL_H #include G_BEGIN_DECLS #define CC_TYPE_REGION_PANEL cc_region_panel_get_type() #define CC_REGION_PANEL(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ CC_TYPE_REGION_PANEL, CcRegionPanel)) #define CC_REGION_PANEL_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), \ CC_TYPE_REGION_PANEL, CcRegionPanelClass)) #define CC_IS_REGION_PANEL(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ CC_TYPE_REGION_PANEL)) #define CC_IS_REGION_PANEL_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), \ CC_TYPE_REGION_PANEL)) #define CC_REGION_PANEL_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), \ CC_TYPE_REGION_PANEL, CcRegionPanelClass)) typedef struct _CcRegionPanel CcRegionPanel; typedef struct _CcRegionPanelClass CcRegionPanelClass; typedef struct _CcRegionPanelPrivate CcRegionPanelPrivate; struct _CcRegionPanel { CcPanel parent; CcRegionPanelPrivate *priv; }; struct _CcRegionPanelClass { CcPanelClass parent_class; }; GType cc_region_panel_get_type (void) G_GNUC_CONST; void cc_region_panel_register (GIOModule *module); G_END_DECLS #endif /* _CC_REGION_PANEL_H */ cinnamon-control-center-6.4.1/panels/region/cc-region-panel.c0000664000175000017500000000554414724311620023070 0ustar fabiofabio/* * Copyright (C) 2010 Intel, Inc * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Author: Sergey Udaltsov * */ #include "config.h" #include "cc-region-panel.h" #include #include #include "cinnamon-region-panel-xkb.h" G_DEFINE_DYNAMIC_TYPE (CcRegionPanel, cc_region_panel, CC_TYPE_PANEL) #define REGION_PANEL_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_REGION_PANEL, CcRegionPanelPrivate)) struct _CcRegionPanelPrivate { GtkBuilder *builder; }; static void cc_region_panel_finalize (GObject * object) { CcRegionPanel *panel; panel = CC_REGION_PANEL (object); if (panel->priv && panel->priv->builder) g_object_unref (panel->priv->builder); G_OBJECT_CLASS (cc_region_panel_parent_class)->finalize (object); } static void cc_region_panel_class_init (CcRegionPanelClass * klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); g_type_class_add_private (klass, sizeof (CcRegionPanelPrivate)); object_class->finalize = cc_region_panel_finalize; } static void cc_region_panel_class_finalize (CcRegionPanelClass * klass) { } static void cc_region_panel_init (CcRegionPanel * self) { CcRegionPanelPrivate *priv; GtkWidget *prefs_widget; const char *desktop; GError *error = NULL; priv = self->priv = REGION_PANEL_PRIVATE (self); desktop = g_getenv ("XDG_CURRENT_DESKTOP"); priv->builder = gtk_builder_new (); gtk_builder_add_from_file (priv->builder, CINNAMONCC_UI_DIR "/cinnamon-region-panel.ui", &error); if (error != NULL) { g_warning ("Error loading UI file: %s", error->message); g_error_free (error); return; } prefs_widget = (GtkWidget *) gtk_builder_get_object (priv->builder, "vbox1"); gtk_widget_set_size_request (GTK_WIDGET (prefs_widget), -1, 400); gtk_widget_reparent (prefs_widget, GTK_WIDGET (self)); setup_xkb_tabs (priv->builder); } void cc_region_panel_register (GIOModule * module) { textdomain (GETTEXT_PACKAGE); bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); cc_region_panel_register_type (G_TYPE_MODULE (module)); g_io_extension_point_implement (CC_SHELL_PANEL_EXTENSION_POINT, CC_TYPE_REGION_PANEL, "region", 0); } cinnamon-control-center-6.4.1/panels/region/cinnamon-region-panel-xkb.c0000664000175000017500000001653014724311620025064 0ustar fabiofabio/* cinnamon-region-panel-xkb.c * Copyright (C) 2003-2007 Sergey V. Udaltsov * * Written by: Sergey V. Udaltsov * * 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, 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 Street - Suite 500, Boston, MA * 02110-1335, USA. */ #include #include #include #include #include "cinnamon-region-panel-xkb.h" #include #define CINNAMON_DESKTOP_INTERFACE_SCHEMA "org.cinnamon.desktop.interface" #define CINNAMON_DESKTOP_FLAG_KEY "keyboard-layout-show-flags" #define CINNAMON_DESKTOP_VARIANT_KEY "keyboard-layout-prefer-variant-names" #define CINNAMON_DESKTOP_UPPER_CASE_KEY "keyboard-layout-use-upper" #define GKBD_CONFIG_KEY_LOAD_EXTRA_ITEMS "load-extra-items" // These were removed from the API of libgnomekbd in version 3.28 const gchar GKBD_DESKTOP_CONFIG_KEY_DEFAULT_GROUP[] = "default-group"; const gchar GKBD_DESKTOP_CONFIG_KEY_GROUP_PER_WINDOW[] = "group-per-window"; const gchar GKBD_KEYBOARD_CONFIG_KEY_LAYOUTS[] = "layouts"; const gchar GKBD_KEYBOARD_CONFIG_KEY_OPTIONS[] = "options"; XklEngine *engine; XklConfigRegistry *config_registry; GkbdKeyboardConfig initial_config; GkbdDesktopConfig desktop_config; GSettings *xkb_keyboard_settings; GSettings *xkb_desktop_settings; GSettings *cinnamon_desktop_settings; char * xci_desc_to_utf8 (const XklConfigItem * ci) { gchar *dd = g_strdup (ci->description); gchar *sd = g_strstrip (dd); gchar *rv = g_strdup (sd[0] == 0 ? ci->name : sd); g_free (dd); return rv; } static void reset_to_defaults (GtkWidget * button, GtkBuilder * dialog) { GkbdKeyboardConfig empty_kbd_config; gkbd_keyboard_config_init (&empty_kbd_config, engine); gkbd_keyboard_config_save (&empty_kbd_config); gkbd_keyboard_config_term (&empty_kbd_config); g_settings_reset (xkb_desktop_settings, GKBD_DESKTOP_CONFIG_KEY_DEFAULT_GROUP); /* all the rest is g-s-d's business */ } static void chk_new_windows_inherit_layout_toggled (GtkWidget * chk_new_windows_inherit_layout, GtkBuilder * dialog) { xkb_save_default_group (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (chk_new_windows_inherit_layout)) ? -1 : 0); } static void on_load_extra_items_toggled (GtkWidget *widget, gpointer user_data) { g_settings_set_boolean (xkb_desktop_settings, GKBD_CONFIG_KEY_LOAD_EXTRA_ITEMS, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))); gkbd_desktop_config_load (&desktop_config); xkl_config_registry_load (config_registry, desktop_config.load_extra_items); } void setup_xkb_tabs (GtkBuilder * dialog) { GtkWidget *widget; GtkStyleContext *context; GtkWidget *chk_new_windows_inherit_layout; chk_new_windows_inherit_layout = WID ("chk_new_windows_inherit_layout"); xkb_desktop_settings = g_settings_new (GKBD_DESKTOP_SCHEMA); xkb_keyboard_settings = g_settings_new (GKBD_KEYBOARD_SCHEMA); cinnamon_desktop_settings = g_settings_new (CINNAMON_DESKTOP_INTERFACE_SCHEMA); engine = xkl_engine_get_instance (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); config_registry = xkl_config_registry_get_instance (engine); gkbd_desktop_config_init (&desktop_config, engine); gkbd_desktop_config_load (&desktop_config); xkl_config_registry_load (config_registry, desktop_config.load_extra_items); gkbd_keyboard_config_init (&initial_config, engine); gkbd_keyboard_config_load_from_x_initial (&initial_config, NULL); /* Set initial state */ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("chk_separate_group_per_window")), g_settings_get_boolean (xkb_desktop_settings, GKBD_DESKTOP_CONFIG_KEY_GROUP_PER_WINDOW)); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chk_new_windows_inherit_layout), xkb_get_default_group () < 0); g_settings_bind (xkb_desktop_settings, GKBD_DESKTOP_CONFIG_KEY_GROUP_PER_WINDOW, WID ("chk_separate_group_per_window"), "active", G_SETTINGS_BIND_DEFAULT); g_settings_bind (xkb_desktop_settings, GKBD_DESKTOP_CONFIG_KEY_GROUP_PER_WINDOW, WID ("chk_new_windows_inherit_layout"), "sensitive", G_SETTINGS_BIND_DEFAULT); g_settings_bind (xkb_desktop_settings, GKBD_DESKTOP_CONFIG_KEY_GROUP_PER_WINDOW, WID ("chk_new_windows_default_layout"), "sensitive", G_SETTINGS_BIND_DEFAULT); g_settings_bind (cinnamon_desktop_settings, CINNAMON_DESKTOP_FLAG_KEY, WID ("country-flag-check"), "active", G_SETTINGS_BIND_DEFAULT); g_settings_bind (cinnamon_desktop_settings, CINNAMON_DESKTOP_VARIANT_KEY, WID ("prefer-variant-check"), "active", G_SETTINGS_BIND_DEFAULT); g_settings_bind (cinnamon_desktop_settings, CINNAMON_DESKTOP_UPPER_CASE_KEY, WID ("use-caps-check"), "active", G_SETTINGS_BIND_DEFAULT); xkb_layouts_prepare_selected_tree (dialog); xkb_layouts_fill_selected_tree (dialog); xkb_layouts_register_buttons_handlers (dialog); g_signal_connect (G_OBJECT (WID ("xkb_reset_to_defaults")), "clicked", G_CALLBACK (reset_to_defaults), dialog); g_signal_connect (G_OBJECT (chk_new_windows_inherit_layout), "toggled", G_CALLBACK (chk_new_windows_inherit_layout_toggled), dialog); g_signal_connect_swapped (G_OBJECT (WID ("xkb_layout_options")), "clicked", G_CALLBACK (xkb_options_popup_dialog), dialog); widget = WID ("load_extras_checkbox"); g_settings_bind (xkb_desktop_settings, GKBD_CONFIG_KEY_LOAD_EXTRA_ITEMS, widget, "active", G_SETTINGS_BIND_GET); g_signal_connect (widget, "toggled", G_CALLBACK (on_load_extra_items_toggled), dialog); xkb_layouts_register_conf_listener (dialog); xkb_options_register_conf_listener (dialog); enable_disable_restoring (dialog); /* Setup junction between toolbar and treeview */ widget = WID ("xkb_layouts_swindow"); context = gtk_widget_get_style_context (widget); gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM); widget = WID ("layouts-toolbar"); context = gtk_widget_get_style_context (widget); gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP); } void enable_disable_restoring (GtkBuilder * dialog) { GkbdKeyboardConfig gswic; gboolean enable; gkbd_keyboard_config_init (&gswic, engine); gkbd_keyboard_config_load (&gswic, NULL); enable = !gkbd_keyboard_config_equals (&gswic, &initial_config); gkbd_keyboard_config_term (&gswic); gtk_widget_set_sensitive (WID ("xkb_reset_to_defaults"), enable); } cinnamon-control-center-6.4.1/panels/region/cinnamon-region-panel.desktop0000664000175000017500000001612614724311620025532 0ustar fabiofabio[Desktop Entry] Exec=cinnamon-settings region Icon=cs-language Terminal=false Type=Application StartupNotify=true Categories=GTK;Settings;DesktopSettings;X-Cinnamon-Settings-Panel;X-Cinnamon-PersonalSettings OnlyShowIn=X-Cinnamon; X-Cinnamon-Settings-Panel=region NoDisplay=true Name=Region & Language Name[am]=įŠ įŠ«į‰£į‰¢ & į‰‹įŠ•į‰‹ Name[ar]=اللغة & المنطقة Name[ast]=Rexón y llingua Name[ay]=Suyumpi arumpi Name[az]=Bƶlgə ilə Dil Name[be]=Š ŃŠ³Ń–Ń‘Š½ і мова Name[be@latin]=Š ŃŠ³Ń–Ń‘Š½ і мова Name[bg]=Регион Šø език Name[br]=Bro ha yezh Name[bs]=Regija i jezik Name[ca]=Regió i idioma Name[ca@valencia]=Regió i idioma Name[cs]=Region a jazyk Name[cy]=Ardal ac Iaith Name[da]=Region og sprog Name[de]=Region und Sprache Name[el]=Περιοχή & Ī³Ī»ĻŽĻƒĻƒĪ± Name[eo]=Regio & lingvo Name[es]=Región e idioma Name[et]=Piirkond ja keel Name[eu]=Eskualdea eta hizkuntza Name[fa]=Ł†Ų§Ų­ŪŒŁ‡ و زبان Name[fi]=Alue ja kielet Name[fr]=Pays et langue Name[fr_CA]=RĆ©gion & langue Name[gd]=Dùthaich ⁊ cĆ nan Name[gl]=Rexión e idioma Name[he]=אזור ושפה Name[hi]=ą¤•ą„ą¤·ą„‡ą¤¤ą„ą¤° व भाषा Name[hr]=Regija i Jezik Name[hu]=Területi Ć©s nyelvi beĆ”llĆ­tĆ”sok Name[ia]=Region & Lingua Name[id]=Wilayah & Bahasa Name[ie]=Region e lingue Name[is]=Land & tungumĆ”l Name[it]=Regione e lingua Name[ja]=åœ°åŸŸćØčØ€čŖž Name[ka]=įƒ įƒ”įƒ’įƒ˜įƒįƒœįƒ˜ įƒ“įƒ įƒ”įƒœįƒ Name[kab]=Tamennaį¹­ & Tutlayt Name[kk]=Аймақ және тіл Name[ko]=지역 & ģ–øģ–“ Name[la]=Regio atque Lingua Name[lt]=Regionas ir kalba Name[lv]=ReÄ£ions un valoda Name[ms]=Wilayah & Bahasa Name[nb]=Region og sprĆ„k Name[nds]=Region & Sprache Name[nl]=Regio en taal Name[nn]=Region & SprĆ„k Name[oc]=PaĆ­s & lenga Name[pl]=Region i język Name[pt]=RegiĆ£o e Idioma Name[pt_BR]=RegiĆ£o & Idioma Name[ro]=Regiune și limbă Name[ru]=Регион Šø ŃŠ·Ń‹Šŗ Name[rue]=Реґіон тай бисіГа Name[sc]=Limba e regione Name[sk]=OblasÅ„ a jazyk Name[sl]=Področje in jezik Name[sq]=Krahina dhe Gjuha Name[sr]=ŠžŠ±Š»Š°ŃŃ‚ Šø језик Name[sr@latin]=Region i jezik Name[sv]=OmrĆ„de och sprĆ„k Name[ta]=ą®µą®ŸąÆą®Ÿą®¾ą®°ą®®ąÆ & மொஓி Name[tg]=Забон ва минтақа Name[th]=ภูดณภาคแคะภาษา Name[tr]=Bƶlge & Dil Name[uk]=Регіон і мова Name[ur]=علاقہ اور زبان Name[uz]=Regeon & Til Name[uz@cyrillic]=Regeon & Til Name[vi]=Khu vį»±c & NgĆ“n ngữ Name[zh_CN]=åŒŗåŸŸå’ŒčÆ­čØ€ Name[zh_HK]=åœ°å€å’ŒčŖžčØ€ Name[zh_TW]=åœ°å€čˆ‡čŖžčØ€ Comment=Change your region and language settings Comment[am]=የ įŠ įŠ«į‰£į‰¢ įŠ„įŠ“ į‰‹įŠ•į‰‹ įˆ›įˆ°įŠ“įŒƒ įˆ˜į‰€į‹ØįˆŖį‹« Comment[ar]=تغيير Ų„Ų¹ŲÆŲ§ŲÆŲ§ŲŖ اللغة ŁˆŲ§Ł„Ł…Ł†Ų·Ł‚Ų© Comment[ast]=Camuda los tos axustes de rexón y llingua Comment[ay]=Suyumpi arumpi mayjachaƱa Comment[az]=Ɩz bƶlgə, dil quruluşlarınızı dəyişin Comment[be]=Š—Š¼ŃŠ½Ń–Ń†ŃŒ Ń€ŃŠ³Ń–ŃŠ½Š°Š»ŃŒŠ½Ń‹Ń і Š¼Š¾ŃžŠ½Ń‹Ń налаГы Comment[be@latin]=Š—Š¼ŃŠ½Ń–Ń†ŃŒ Ń€ŃŠ³Ń–ŃŠ½Š°Š»ŃŒŠ½Ń‹Ń і Š¼Š¾ŃžŠ½Ń‹Ń налаГы Comment[bg]=ŠŸŃ€Š¾Š¼ŠµŠ½ŠµŃ‚Šµ своите регионални Šø езикови настройки Comment[br]=CheƱch arventennoù ar yezh hag ar bro Comment[bs]=Promijeni regionalne postavke i postavke jezika Comment[ca]=Canvieu els ajusts de la regió i de l'idioma Comment[ca@valencia]=Canvieu els parĆ metres de regió i idioma Comment[cs]=Změňte svÅÆj region a nastavenĆ­ jazyka Comment[cy]=Newid eich gosodiadau ardal ac iaith Comment[da]=Ɔndr indstillinger for sprog og region Comment[de]=Einstellungen für Region und Sprache Ƥndern Comment[el]=Αλλαγή ĻĻ…ĪøĪ¼ĪÆĻƒĪµĻ‰Ī½ της περιοχής και Ī³Ī»ĻŽĻƒĻƒĪ±Ļ‚ Comment[eo]=Ŝanĝi vian regionon kaj lingvajn agordojn Comment[es]=Cambiar la configuración de la región y el idioma Comment[et]=Sinu asukoha- ja keelesƤtete muutmine Comment[eu]=Aldatu zure eskualde eta hizkuntzaren ezarpenak Comment[fa]=تغییر ŲŖŁ†ŲøŪŒŁ…Ų§ŲŖ Ł†Ų§Ų­ŪŒŁ‡ و زبان Ų“Ł…Ų§ Comment[fi]=Muuta alue- ja kieliasetuksia Comment[fr]=Modifier les paramĆØtres de pays et de langue Comment[fr_CA]=Modifier vos paramĆØtres rĆ©gionaux et linguistiques Comment[gd]=Atharraich roghainnean do dhùthcha 's do chĆ nain Comment[gl]=Cambiar os axustes de rexión e idioma Comment[he]=שינוי הגדרות אזור ושפה Comment[hi]=ą¤•ą„ą¤·ą„‡ą¤¤ą„ą¤° व ą¤­ą¤¾ą¤·ą„€ą¤Æ ą¤øą„‡ą¤Ÿą¤æą¤‚ą¤—ą„ą¤ø ą¤¬ą¤¦ą¤²ą„‡ą¤‚ Comment[hr]=Promijenite vaÅ”u regiju i jezične postavke Comment[hu]=Területi Ć©s nyelvi beĆ”llĆ­tĆ”sok módosĆ­tĆ”sa Comment[ia]=Cambiar tu configurationes de region e lingua Comment[id]=Ubah pengaturan wilayah dan bahasa Anda Comment[ie]=Cambiar vor parametres de lingue e region Comment[is]=Stilltu landsvƦưiư þitt og tungumĆ”lastillingar Comment[it]=Cambia le impostazioni della tua regione e della lingua Comment[ja]=åœ°åŸŸćØčØ€čŖžć®čØ­å®šć‚’å¤‰ę›“ć—ć¾ć™ Comment[kab]=Beddel iÉ£ewwaren n tmennaį¹­-ik(m) d tutlayt-ik(m) Comment[kk]=Аймақ және тіл Š±Š°ŠæŃ‚Š°ŃƒŠ»Š°Ń€Ń‹Š½ Ó©Š·Š³ŠµŃ€Ń‚Ńƒ Comment[ko]=지역 ė° ģ–øģ–“ ģ„¤ģ •ģ„ ė°”źæ‰ė‹ˆė‹¤ Comment[la]=Configurationem regionis et linguae muta Comment[lt]=Keiskite savo regiono ir kalbos nustatymus Comment[lv]=MainÄ«t reÄ£iona un valodas iestatÄ«jums Comment[ms]=Ubah tetapan wilayah dan bahasa anda Comment[nb]=Endre region og sprĆ„kinnstillinger Comment[nds]=Region und Sprache Ƥndern Comment[nl]=Instellingen wijzigen voor regio en taal Comment[oc]=Modificar los paramĆØtres de paĆ­s e de lenga Comment[pl]=Zmiana ustawień regionu i języka Comment[pt]=Alterar definiƧƵes de regiĆ£o e de idioma Comment[pt_BR]=Alterar suas configuraƧƵes de regiĆ£o e idioma Comment[ro]=Schimbați setările de regiune și limbă Comment[ru]=Š˜Š·Š¼ŠµŠ½ŠøŃ‚ŃŒ Ń€ŠµŠ³ŠøŠ¾Š½Š°Š»ŃŒŠ½Ń‹Šµ Šø ŃŠ·Ń‹ŠŗŠ¾Š²Ń‹Šµ настройки Comment[rue]=ŠŸŠµŃ€ŠµŠ¼Ń–Š½ŠøŃ‚Šø свуй реґіон тай Š±ŠøŃŃ–Š“Ńƒ Comment[sk]=ZmeniÅ„ regionĆ”lne a jazykovĆ© nastavenia Comment[sl]=Spremeni svoje področne in jezikovne nastavitve Comment[sq]=NdĆ«rro parametrat e krahinĆ«s dhe tĆ« gjuhĆ«s Comment[sr]=Š˜Š·Š¼ŠµŠ½ŠøŃ‚Šµ ваша поГешавања региона Šø језика Comment[sr@latin]=Izmenite VaÅ”a podeÅ”avanja regiona i jezika Comment[sv]=Ƅndra instƤllningar fƶr din region och ditt sprĆ„k Comment[ta]=ą®‰ą®™ąÆą®•ą®³ąÆ ą®µą®ŸąÆą®Ÿą®¾ą®° ą®®ą®±ąÆą®±ąÆą®®ąÆ மொஓி ą®…ą®®ąÆˆą®ŖąÆą®ŖąÆą®•ą®³ąÆˆ ą®®ą®¾ą®±ąÆą®±ą®æ ą®…ą®®ąÆˆą®•ąÆą®•ą®µąÆą®®ąÆ Comment[tg]=Тағйир ГоГани танзимоти минтақа ва забони система Comment[th]=ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąø„ą¹ˆąø²ąø•ąø±ą¹‰ąø‡ą¹€ąøąøµą¹ˆąø¢ąø§ąøąø±ąøšąø ąø¹ąø”ąø“ąø ąø²ąø„ą¹ąø„ąø°ąø ąø²ąø©ąø²ąø‚ąø­ąø‡ąø„ąøøąø“ Comment[tr]=Bƶlge ve dil ayarlarını değiştirin Comment[uk]=Зміна Š½Š°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½ŃŒ Š’Š°ŃˆŠ¾Š³Š¾ Ń€ŠµŠ³Ń–Š¾Š½Ńƒ та мови Comment[ur]=اپنا علاقہ اور زبان کی ترتیبات ŲŖŲØŲÆŪŒŁ„ کریں Comment[uz]=Region va til moslamalarini oā€˜zgartirish Comment[uz@cyrillic]=Region va til moslamalarini oā€˜zgartirish Comment[vi]=Thay đổi cĆ i đặt khu vį»±c vĆ  ngĆ“n ngữ cį»§a bįŗ”n Comment[zh_CN]=ę›“ę”¹ę‚Øēš„åŒŗåŸŸå’ŒčÆ­čØ€č®¾ē½® Comment[zh_HK]=č®Šę›“ä½ ēš„åœ°å€å’ŒčŖžčØ€čØ­å®š Comment[zh_TW]=č®Šę›“ę‚Øēš„åœ°å€čˆ‡čŖžčØ€čØ­å®š cinnamon-control-center-6.4.1/panels/region/cinnamon-region-panel-xkb.h0000664000175000017500000000677614724311620025104 0ustar fabiofabio/* cinnamon-region-panel-xkb.h * Copyright (C) 2003-2007 Sergey V Udaltsov * * Written by Sergey V. Udaltsov * * 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, 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 Street - Suite 500, Boston, MA * 02110-1335, USA. */ #ifndef __GNOME_KEYBOARD_PROPERTY_XKB_H #define __GNOME_KEYBOARD_PROPERTY_XKB_H #include #include "libgnomekbd/gkbd-keyboard-config.h" #include "libgnomekbd/gkbd-util.h" G_BEGIN_DECLS #define CWID(s) GTK_WIDGET (gtk_builder_get_object (chooser_dialog, s)) #define WID(s) GTK_WIDGET (gtk_builder_get_object (dialog, s)) extern XklEngine *engine; extern XklConfigRegistry *config_registry; extern GSettings *xkb_keyboard_settings; extern GSettings *xkb_desktop_settings; extern GkbdKeyboardConfig initial_config; extern const gchar GKBD_DESKTOP_CONFIG_KEY_DEFAULT_GROUP[]; extern const gchar GKBD_DESKTOP_CONFIG_KEY_GROUP_PER_WINDOW[]; extern const gchar GKBD_KEYBOARD_CONFIG_KEY_LAYOUTS[]; extern const gchar GKBD_KEYBOARD_CONFIG_KEY_OPTIONS[]; extern void setup_xkb_tabs (GtkBuilder * dialog); extern void xkb_layouts_fill_selected_tree (GtkBuilder * dialog); extern void xkb_layouts_register_buttons_handlers (GtkBuilder * dialog); extern void xkb_layouts_register_conf_listener (GtkBuilder * dialog); extern void xkb_options_register_conf_listener (GtkBuilder * dialog); extern void xkb_layouts_prepare_selected_tree (GtkBuilder * dialog); extern void xkb_options_load_options (GtkBuilder * dialog); extern void xkb_options_popup_dialog (GtkBuilder * dialog); extern char *xci_desc_to_utf8 (const XklConfigItem * ci); extern gchar *xkb_layout_description_utf8 (const gchar * visible); extern void enable_disable_restoring (GtkBuilder * dialog); extern void preview_toggled (GtkBuilder * dialog, GtkWidget * button); extern GtkWidget *xkb_layout_choose (GtkBuilder * dialog); extern void xkb_layout_chooser_response (GtkDialog *dialog, gint response_id); extern gchar **xkb_layouts_get_selected_list (void); extern gchar **xkb_options_get_selected_list (void); #define xkb_layouts_set_selected_list(list) \ g_settings_set_strv (xkb_keyboard_settings, \ GKBD_KEYBOARD_CONFIG_KEY_LAYOUTS, \ (const gchar *const*)(list)) #define xkb_options_set_selected_list(list) \ g_settings_set_strv (xkb_keyboard_settings, \ GKBD_KEYBOARD_CONFIG_KEY_OPTIONS, \ (const gchar *const*)(list)) extern GtkWidget *xkb_layout_preview_create_widget (GtkBuilder * chooser_dialog); extern void xkb_layout_preview_update (GtkBuilder * chooser_dialog); extern void xkb_layout_preview_set_drawing_layout (GtkWidget * kbdraw, const gchar * id); extern gchar *xkb_layout_chooser_get_selected_id (GtkDialog *dialog); extern void xkb_save_default_group (gint group_no); extern gint xkb_get_default_group (void); G_END_DECLS #endif /* __GNOME_KEYBOARD_PROPERTY_XKB_H */ cinnamon-control-center-6.4.1/panels/region/cinnamon-region-panel-xkbltadd.c0000664000175000017500000003174114724311620026076 0ustar fabiofabio/* cinnamon-region-panel-xkbltadd.c * Copyright (C) 2007 Sergey V. Udaltsov * * Written by: Sergey V. Udaltsov * * 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, 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 Street - Suite 500, Boston, MA * 02110-1335, USA. */ #include #include #include #include #include "cinnamon-region-panel-xkb.h" enum { COMBO_BOX_MODEL_COL_SORT, COMBO_BOX_MODEL_COL_VISIBLE, COMBO_BOX_MODEL_COL_XKB_ID, COMBO_BOX_MODEL_COL_COUNTRY_DESC, COMBO_BOX_MODEL_COL_LANGUAGE_DESC }; static gchar **search_pattern_list = NULL; static GtkWidget *preview_dialog = NULL; static GRegex *left_bracket_regex = NULL; #define RESPONSE_PREVIEW 1 static void xkb_preview_destroy_callback (GtkWidget * widget) { preview_dialog = NULL; } static gboolean xkb_layout_chooser_selection_dupe (GtkDialog * dialog) { gchar *selected_id = (gchar *) xkb_layout_chooser_get_selected_id (dialog); gchar **layouts_list, **pl; gboolean rv = FALSE; if (selected_id == NULL) return rv; layouts_list = pl = xkb_layouts_get_selected_list (); while (pl && *pl) { if (!g_ascii_strcasecmp (*pl++, selected_id)) { rv = TRUE; break; } } g_strfreev (layouts_list); return rv; } void xkb_layout_chooser_response (GtkDialog * dialog, gint response) { switch (response) case GTK_RESPONSE_OK:{ /* Handled by the main code */ break; case RESPONSE_PREVIEW:{ gchar *selected_id = (gchar *) xkb_layout_chooser_get_selected_id (dialog); if (selected_id != NULL) { if (preview_dialog == NULL) { preview_dialog = gkbd_keyboard_drawing_dialog_new (); g_signal_connect (G_OBJECT (preview_dialog), "destroy", G_CALLBACK (xkb_preview_destroy_callback), NULL); /* Put into the separate group to avoid conflict with modal parent */ gtk_window_group_add_window (gtk_window_group_new (), GTK_WINDOW (preview_dialog)); }; gkbd_keyboard_drawing_dialog_set_layout (preview_dialog, config_registry, selected_id); gtk_widget_show_all (preview_dialog); } } return; } if (preview_dialog != NULL) { gtk_widget_destroy (preview_dialog); } if (search_pattern_list != NULL) { g_strfreev (search_pattern_list); search_pattern_list = NULL; } gtk_widget_destroy (GTK_WIDGET (dialog)); } static gchar * xkl_create_description_from_list (const XklConfigItem * item, const XklConfigItem * subitem, const gchar * prop_name, const gchar * (*desc_getter) (const gchar * code)) { gchar *rv = NULL, *code = NULL; gchar **list = NULL; const gchar *desc; if (subitem != NULL) list = (gchar **) (g_object_get_data (G_OBJECT (subitem), prop_name)); if (list == NULL || *list == 0) list = (gchar **) (g_object_get_data (G_OBJECT (item), prop_name)); /* First try the parent id as such */ desc = desc_getter (item->name); if (desc != NULL) { rv = g_utf8_strup (desc, -1); } else { code = g_utf8_strup (item->name, -1); desc = desc_getter (code); if (desc != NULL) { rv = g_utf8_strup (desc, -1); } g_free (code); } if (list == NULL || *list == 0) return rv; while (*list != 0) { code = *list++; desc = desc_getter (code); if (desc != NULL) { gchar *udesc = g_utf8_strup (desc, -1); if (rv == NULL) { rv = udesc; } else { gchar *orv = rv; rv = g_strdup_printf ("%s %s", rv, udesc); g_free (orv); g_free (udesc); } } } return rv; } static void xkl_layout_add_to_list (XklConfigRegistry * config, const XklConfigItem * item, const XklConfigItem * subitem, GtkBuilder * chooser_dialog) { GtkListStore *list_store = GTK_LIST_STORE (gtk_builder_get_object (chooser_dialog, "layout_list_model")); GtkTreeIter iter; gchar *utf_variant_name = subitem ? xkb_layout_description_utf8 (gkbd_keyboard_config_merge_items (item->name, subitem->name)) : xci_desc_to_utf8 (item); const gchar *xkb_id = subitem ? gkbd_keyboard_config_merge_items (item->name, subitem->name) : item->name; gchar *country_desc = xkl_create_description_from_list (item, subitem, XCI_PROP_COUNTRY_LIST, xkl_get_country_name); gchar *language_desc = xkl_create_description_from_list (item, subitem, XCI_PROP_LANGUAGE_LIST, xkl_get_language_name); gchar *tmp = utf_variant_name; utf_variant_name = g_regex_replace_literal (left_bracket_regex, tmp, -1, 0, "<", 0, NULL); g_free (tmp); if (subitem && g_object_get_data (G_OBJECT (subitem), XCI_PROP_EXTRA_ITEM)) { gchar *buf = g_strdup_printf ("%s", utf_variant_name); gtk_list_store_insert_with_values (list_store, &iter, -1, COMBO_BOX_MODEL_COL_SORT, utf_variant_name, COMBO_BOX_MODEL_COL_VISIBLE, buf, COMBO_BOX_MODEL_COL_XKB_ID, xkb_id, COMBO_BOX_MODEL_COL_COUNTRY_DESC, country_desc, COMBO_BOX_MODEL_COL_LANGUAGE_DESC, language_desc, -1); g_free (buf); } else gtk_list_store_insert_with_values (list_store, &iter, -1, COMBO_BOX_MODEL_COL_SORT, utf_variant_name, COMBO_BOX_MODEL_COL_VISIBLE, utf_variant_name, COMBO_BOX_MODEL_COL_XKB_ID, xkb_id, COMBO_BOX_MODEL_COL_COUNTRY_DESC, country_desc, COMBO_BOX_MODEL_COL_LANGUAGE_DESC, language_desc, -1); g_free (utf_variant_name); g_free (country_desc); g_free (language_desc); } static void xkb_layout_filter_clear (GtkEntry * entry, GtkEntryIconPosition icon_pos, GdkEvent * event, gpointer user_data) { gtk_entry_set_text (entry, ""); } static void xkb_layout_filter_changed (GtkBuilder * chooser_dialog) { GtkTreeModelFilter *filtered_model = GTK_TREE_MODEL_FILTER (gtk_builder_get_object (chooser_dialog, "filtered_layout_list_model")); GtkWidget *xkb_layout_filter = CWID ("xkb_layout_filter"); const gchar *pattern = gtk_entry_get_text (GTK_ENTRY (xkb_layout_filter)); gchar *upattern = g_utf8_strup (pattern, -1); if (!g_strcmp0 (pattern, "")) { g_object_set (G_OBJECT (xkb_layout_filter), "secondary-icon-name", "edit-find-symbolic", "secondary-icon-activatable", FALSE, "secondary-icon-sensitive", FALSE, NULL); } else { g_object_set (G_OBJECT (xkb_layout_filter), "secondary-icon-name", "edit-clear-symbolic", "secondary-icon-activatable", TRUE, "secondary-icon-sensitive", TRUE, NULL); } if (search_pattern_list != NULL) g_strfreev (search_pattern_list); search_pattern_list = g_strsplit (upattern, " ", -1); g_free (upattern); gtk_tree_model_filter_refilter (filtered_model); } static void xkb_layout_chooser_selection_changed (GtkTreeSelection * selection, GtkBuilder * chooser_dialog) { GList *selected_layouts = gtk_tree_selection_get_selected_rows (selection, NULL); GtkWidget *add_button = CWID ("btnOk"); GtkWidget *preview_button = CWID ("btnPreview"); gboolean anything_selected = g_list_length (selected_layouts) == 1; gboolean dupe = xkb_layout_chooser_selection_dupe (GTK_DIALOG (CWID ("xkb_layout_chooser"))); gtk_widget_set_sensitive (add_button, anything_selected && !dupe); gtk_widget_set_sensitive (preview_button, anything_selected); } static void xkb_layout_chooser_row_activated (GtkTreeView * tree_view, GtkTreePath * path, GtkTreeViewColumn * column, GtkBuilder * chooser_dialog) { GtkWidget *add_button = CWID ("btnOk"); GtkWidget *dialog = CWID ("xkb_layout_chooser"); if (gtk_widget_is_sensitive (add_button)) gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); } static gboolean xkb_filter_layouts (GtkTreeModel * model, GtkTreeIter * iter, gpointer data) { gchar *desc = NULL, *country_desc = NULL, *language_desc = NULL, **pattern; gboolean rv = TRUE; if (search_pattern_list == NULL || search_pattern_list[0] == NULL) return TRUE; gtk_tree_model_get (model, iter, COMBO_BOX_MODEL_COL_SORT, &desc, COMBO_BOX_MODEL_COL_COUNTRY_DESC, &country_desc, COMBO_BOX_MODEL_COL_LANGUAGE_DESC, &language_desc, -1); pattern = search_pattern_list; do { gboolean is_pattern_found = FALSE; gchar *udesc = g_utf8_strup (desc, -1); if (udesc != NULL && g_strstr_len (udesc, -1, *pattern)) { is_pattern_found = TRUE; } else if (country_desc != NULL && g_strstr_len (country_desc, -1, *pattern)) { is_pattern_found = TRUE; } else if (language_desc != NULL && g_strstr_len (language_desc, -1, *pattern)) { is_pattern_found = TRUE; } g_free (udesc); if (!is_pattern_found) { rv = FALSE; break; } } while (*++pattern != NULL); g_free (desc); g_free (country_desc); g_free (language_desc); return rv; } GtkWidget * xkb_layout_choose (GtkBuilder * dialog) { GtkBuilder *chooser_dialog = gtk_builder_new (); GtkWidget *chooser, *xkb_filtered_layouts_list, *xkb_layout_filter; GtkTreeViewColumn *visible_column; GtkTreeSelection *selection; GtkListStore *model; GtkTreeModelFilter *filtered_model; gtk_builder_add_from_file (chooser_dialog, CINNAMONCC_UI_DIR "/cinnamon-region-panel-layout-chooser.ui", NULL); chooser = CWID ("xkb_layout_chooser"); xkb_filtered_layouts_list = CWID ("xkb_filtered_layouts_list"); xkb_layout_filter = CWID ("xkb_layout_filter"); g_object_set_data (G_OBJECT (chooser), "xkb_filtered_layouts_list", xkb_filtered_layouts_list); visible_column = gtk_tree_view_column_new_with_attributes ("Layout", gtk_cell_renderer_text_new (), "markup", COMBO_BOX_MODEL_COL_VISIBLE, NULL); gtk_window_set_transient_for (GTK_WINDOW (chooser), GTK_WINDOW (gtk_widget_get_toplevel (WID ("region_notebook")))); gtk_tree_view_append_column (GTK_TREE_VIEW (xkb_filtered_layouts_list), visible_column); g_signal_connect_swapped (G_OBJECT (xkb_layout_filter), "notify::text", G_CALLBACK (xkb_layout_filter_changed), chooser_dialog); g_signal_connect (G_OBJECT (xkb_layout_filter), "icon-release", G_CALLBACK (xkb_layout_filter_clear), NULL); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (xkb_filtered_layouts_list)); g_signal_connect (G_OBJECT (selection), "changed", G_CALLBACK (xkb_layout_chooser_selection_changed), chooser_dialog); xkb_layout_chooser_selection_changed (selection, chooser_dialog); g_signal_connect (G_OBJECT (xkb_filtered_layouts_list), "row-activated", G_CALLBACK (xkb_layout_chooser_row_activated), chooser_dialog); filtered_model = GTK_TREE_MODEL_FILTER (gtk_builder_get_object (chooser_dialog, "filtered_layout_list_model")); model = GTK_LIST_STORE (gtk_builder_get_object (chooser_dialog, "layout_list_model")); left_bracket_regex = g_regex_new ("<", 0, 0, NULL); xkl_config_registry_search_by_pattern (config_registry, NULL, (TwoConfigItemsProcessFunc) (xkl_layout_add_to_list), chooser_dialog); g_regex_unref (left_bracket_regex); gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), COMBO_BOX_MODEL_COL_SORT, GTK_SORT_ASCENDING); gtk_tree_model_filter_set_visible_func (filtered_model, xkb_filter_layouts, NULL, NULL); gtk_widget_grab_focus (xkb_layout_filter); gtk_widget_show (chooser); return chooser; } gchar * xkb_layout_chooser_get_selected_id (GtkDialog * dialog) { GtkTreeModel *filtered_list_model; GtkWidget *xkb_filtered_layouts_list = g_object_get_data (G_OBJECT (dialog), "xkb_filtered_layouts_list"); GtkTreeIter viter; gchar *v_id; GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (xkb_filtered_layouts_list)); GList *selected_layouts = gtk_tree_selection_get_selected_rows (selection, &filtered_list_model); if (g_list_length (selected_layouts) != 1) return NULL; gtk_tree_model_get_iter (filtered_list_model, &viter, (GtkTreePath *) (selected_layouts->data)); g_list_foreach (selected_layouts, (GFunc) gtk_tree_path_free, NULL); g_list_free (selected_layouts); gtk_tree_model_get (filtered_list_model, &viter, COMBO_BOX_MODEL_COL_XKB_ID, &v_id, -1); return v_id; } cinnamon-control-center-6.4.1/panels/region/cinnamon-region-panel-xkbot.c0000664000175000017500000003622314724311620025430 0ustar fabiofabio/* cinnamon-region-panel-xkbot.c * Copyright (C) 2003-2007 Sergey V. Udaltsov * * Written by: Sergey V. Udaltsov * John Spray * * 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, 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 Street - Suite 500, Boston, MA * 02110-1335, USA. */ #include #include #include #include "cinnamon-region-panel-xkb.h" static GtkBuilder *chooser_dialog = NULL; static const char *current1st_level_id = NULL; static GSList *option_checks_list = NULL; static GtkWidget *current_none_radio = NULL; static GtkWidget *current_expander = NULL; static gboolean current_multi_select = FALSE; static GSList *current_radio_group = NULL; #define OPTION_ID_PROP "optionID" #define SELCOUNTER_PROP "selectionCounter" #define GCONFSTATE_PROP "gconfState" #define EXPANDERS_PROP "expandersList" gchar ** xkb_options_get_selected_list (void) { gchar **retval; retval = g_settings_get_strv (xkb_keyboard_settings, GKBD_KEYBOARD_CONFIG_KEY_OPTIONS); if (retval == NULL) { retval = g_strdupv (initial_config.options); } return retval; } /* Returns the selection counter of the expander (static current_expander) */ static int xkb_options_expander_selcounter_get (void) { return GPOINTER_TO_INT (g_object_get_data (G_OBJECT (current_expander), SELCOUNTER_PROP)); } /* Increments the selection counter in the expander (static current_expander) using the value (can be 0)*/ static void xkb_options_expander_selcounter_add (int value) { g_object_set_data (G_OBJECT (current_expander), SELCOUNTER_PROP, GINT_TO_POINTER (xkb_options_expander_selcounter_get () + value)); } /* Resets the seletion counter in the expander (static current_expander) */ static void xkb_options_expander_selcounter_reset (void) { g_object_set_data (G_OBJECT (current_expander), SELCOUNTER_PROP, GINT_TO_POINTER (0)); } /* Formats the expander (static current_expander), based on the selection counter */ static void xkb_options_expander_highlight (void) { char *utf_group_name = g_object_get_data (G_OBJECT (current_expander), "utfGroupName"); int counter = xkb_options_expander_selcounter_get (); if (utf_group_name != NULL) { gchar *titlemarkup = g_strconcat (counter > 0 ? "" : "", utf_group_name, "", NULL); gtk_expander_set_label (GTK_EXPANDER (current_expander), titlemarkup); g_free (titlemarkup); } } /* Add optionname from the backend's selection list if it's not already in there. */ static void xkb_options_select (gchar * optionname) { gboolean already_selected = FALSE; gchar **options_list; guint i; options_list = xkb_options_get_selected_list (); for (i = 0; options_list != NULL && options_list[i] != NULL; i++) { gchar *option = options_list[i]; if (!strcmp (option, optionname)) { already_selected = TRUE; break; } } if (!already_selected) { options_list = gkbd_strv_append (options_list, g_strdup (optionname)); xkb_options_set_selected_list (options_list); } g_strfreev (options_list); } /* Remove all occurrences of optionname from the backend's selection list */ static void xkb_options_deselect (gchar * optionname) { gchar **options_list = xkb_options_get_selected_list (); if (options_list != NULL) { gchar **option = options_list; while (*option != NULL) { gchar *id = *option; if (!strcmp (id, optionname)) { gkbd_strv_behead (option); } else option++; } xkb_options_set_selected_list (options_list); } g_strfreev (options_list); } /* Return true if optionname describes a string already in the backend's list of selected options */ static gboolean xkb_options_is_selected (gchar * optionname) { gboolean retval = FALSE; gchar **options_list = xkb_options_get_selected_list (); if (options_list != NULL) { gchar **option = options_list; while (*option != NULL) { if (!strcmp (*option, optionname)) { retval = TRUE; break; } option++; } } g_strfreev (options_list); return retval; } /* Make sure selected options stay visible when navigating with the keyboard */ static gboolean option_focused_cb (GtkWidget * widget, GdkEventFocus * event, gpointer data) { GtkScrolledWindow *win = GTK_SCROLLED_WINDOW (data); GtkAllocation alloc; GtkAdjustment *adj; gtk_widget_get_allocation (widget, &alloc); adj = gtk_scrolled_window_get_vadjustment (win); gtk_adjustment_clamp_page (adj, alloc.y, alloc.y + alloc.height); return FALSE; } /* Update xkb backend to reflect the new UI state */ static void option_toggled_cb (GtkWidget * checkbutton, gpointer data) { gpointer optionID = g_object_get_data (G_OBJECT (checkbutton), OPTION_ID_PROP); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton))) xkb_options_select (optionID); else xkb_options_deselect (optionID); } /* Add a check_button or radio_button to control a particular option This function makes particular use of the current... variables at the top of this file. */ static void xkb_options_add_option (XklConfigRegistry * config_registry, XklConfigItem * config_item, GtkBuilder * dialog) { GtkWidget *option_check; gchar *utf_option_name = xci_desc_to_utf8 (config_item); /* Copy this out because we'll load it into the widget with set_data */ gchar *full_option_name = g_strdup (gkbd_keyboard_config_merge_items (current1st_level_id, config_item->name)); gboolean initial_state; if (current_multi_select) option_check = gtk_check_button_new_with_label (utf_option_name); else { if (current_radio_group == NULL) { /* The first radio in a group is to be "Default", meaning none of the below options are to be included in the selected list. This is a HIG-compliant alternative to allowing no selection in the group. */ option_check = gtk_radio_button_new_with_label (current_radio_group, _("Default")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (option_check), TRUE); /* Make option name underscore - to enforce its first position in the list */ g_object_set_data_full (G_OBJECT (option_check), "utfOptionName", g_strdup (" "), g_free); option_checks_list = g_slist_append (option_checks_list, option_check); current_radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (option_check)); current_none_radio = option_check; g_signal_connect (option_check, "focus-in-event", G_CALLBACK (option_focused_cb), WID ("options_scroll")); } option_check = gtk_radio_button_new_with_label (current_radio_group, utf_option_name); current_radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (option_check)); g_object_set_data (G_OBJECT (option_check), "NoneRadio", current_none_radio); } initial_state = xkb_options_is_selected (full_option_name); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (option_check), initial_state); g_object_set_data_full (G_OBJECT (option_check), OPTION_ID_PROP, full_option_name, g_free); g_object_set_data_full (G_OBJECT (option_check), "utfOptionName", utf_option_name, g_free); g_signal_connect (option_check, "toggled", G_CALLBACK (option_toggled_cb), NULL); option_checks_list = g_slist_append (option_checks_list, option_check); g_signal_connect (option_check, "focus-in-event", G_CALLBACK (option_focused_cb), WID ("options_scroll")); xkb_options_expander_selcounter_add (initial_state); g_object_set_data (G_OBJECT (option_check), GCONFSTATE_PROP, GINT_TO_POINTER (initial_state)); } static gint xkb_option_checks_compare (GtkWidget * chk1, GtkWidget * chk2) { const gchar *t1 = g_object_get_data (G_OBJECT (chk1), "utfOptionName"); const gchar *t2 = g_object_get_data (G_OBJECT (chk2), "utfOptionName"); return g_utf8_collate (t1, t2); } /* Add a group of options: create title and layout widgets and then add widgets for all the options in the group. */ static void xkb_options_add_group (XklConfigRegistry * config_registry, XklConfigItem * config_item, GtkBuilder * dialog) { GtkWidget *align, *vbox, *option_check; gboolean allow_multiple_selection = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (config_item), XCI_PROP_ALLOW_MULTIPLE_SELECTION)); GSList *expanders_list = g_object_get_data (G_OBJECT (dialog), EXPANDERS_PROP); gchar *utf_group_name = xci_desc_to_utf8 (config_item); gchar *titlemarkup = g_strconcat ("", utf_group_name, "", NULL); current_expander = gtk_expander_new (titlemarkup); gtk_expander_set_use_markup (GTK_EXPANDER (current_expander), TRUE); g_object_set_data_full (G_OBJECT (current_expander), "utfGroupName", utf_group_name, g_free); g_object_set_data_full (G_OBJECT (current_expander), "groupId", g_strdup (config_item->name), g_free); g_free (titlemarkup); align = gtk_alignment_new (0, 0, 1, 1); gtk_alignment_set_padding (GTK_ALIGNMENT (align), 6, 12, 12, 0); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_box_set_homogeneous (GTK_BOX (vbox), TRUE); gtk_container_add (GTK_CONTAINER (align), vbox); gtk_container_add (GTK_CONTAINER (current_expander), align); current_multi_select = (gboolean) allow_multiple_selection; current_radio_group = NULL; current1st_level_id = config_item->name; option_checks_list = NULL; xkl_config_registry_foreach_option (config_registry, config_item->name, (ConfigItemProcessFunc) xkb_options_add_option, dialog); /* sort it */ option_checks_list = g_slist_sort (option_checks_list, (GCompareFunc) xkb_option_checks_compare); while (option_checks_list) { option_check = GTK_WIDGET (option_checks_list->data); gtk_box_pack_start (GTK_BOX (vbox), option_check, TRUE, TRUE, 0); option_checks_list = option_checks_list->next; } /* free it */ g_slist_free (option_checks_list); option_checks_list = NULL; xkb_options_expander_highlight (); expanders_list = g_slist_append (expanders_list, current_expander); g_object_set_data (G_OBJECT (dialog), EXPANDERS_PROP, expanders_list); g_signal_connect (current_expander, "focus-in-event", G_CALLBACK (option_focused_cb), WID ("options_scroll")); } static gint xkb_options_expanders_compare (GtkWidget * expander1, GtkWidget * expander2) { const gchar *t1 = g_object_get_data (G_OBJECT (expander1), "utfGroupName"); const gchar *t2 = g_object_get_data (G_OBJECT (expander2), "utfGroupName"); return g_utf8_collate (t1, t2); } /* Create widgets to represent the options made available by the backend */ void xkb_options_load_options (GtkBuilder * dialog) { GtkWidget *opts_vbox = WID ("options_vbox"); GtkWidget *dialog_vbox = WID ("dialog_vbox"); GtkWidget *options_scroll = WID ("options_scroll"); GtkWidget *expander; GSList *expanders_list; current1st_level_id = NULL; current_none_radio = NULL; current_multi_select = FALSE; current_radio_group = NULL; /* fill the list */ xkl_config_registry_foreach_option_group (config_registry, (ConfigItemProcessFunc) xkb_options_add_group, dialog); /* sort it */ expanders_list = g_object_get_data (G_OBJECT (dialog), EXPANDERS_PROP); expanders_list = g_slist_sort (expanders_list, (GCompareFunc) xkb_options_expanders_compare); g_object_set_data (G_OBJECT (dialog), EXPANDERS_PROP, expanders_list); while (expanders_list) { expander = GTK_WIDGET (expanders_list->data); gtk_box_pack_start (GTK_BOX (opts_vbox), expander, FALSE, FALSE, 0); expanders_list = expanders_list->next; } /* Somewhere in gtk3 the top vbox in dialog is made non-expandable */ gtk_box_set_child_packing (GTK_BOX (dialog_vbox), options_scroll, TRUE, TRUE, 0, GTK_PACK_START); gtk_widget_show_all (dialog_vbox); } static void chooser_response_cb (GtkDialog * dialog, gint response, gpointer data) { switch (response) { case GTK_RESPONSE_DELETE_EVENT: case GTK_RESPONSE_CLOSE: { /* just cleanup */ GSList *expanders_list = g_object_get_data (G_OBJECT (dialog), EXPANDERS_PROP); g_object_set_data (G_OBJECT (dialog), EXPANDERS_PROP, NULL); g_slist_free (expanders_list); gtk_widget_destroy (GTK_WIDGET (dialog)); chooser_dialog = NULL; } break; } } /* Create popup dialog */ void xkb_options_popup_dialog (GtkBuilder * dialog) { GtkWidget *chooser; chooser_dialog = gtk_builder_new (); gtk_builder_add_from_file (chooser_dialog, CINNAMONCC_UI_DIR "/cinnamon-region-panel-options-dialog.ui", NULL); chooser = CWID ("xkb_options_dialog"); gtk_window_set_transient_for (GTK_WINDOW (chooser), GTK_WINDOW (gtk_widget_get_toplevel (WID ("region_notebook")))); gtk_window_set_modal (GTK_WINDOW (chooser), TRUE); xkb_options_load_options (chooser_dialog); g_signal_connect (chooser, "response", G_CALLBACK (chooser_response_cb), dialog); gtk_widget_show (chooser); } /* Update selected option counters for a group-bound expander */ static void xkb_options_update_option_counters (XklConfigRegistry * config_registry, XklConfigItem * config_item) { gchar *full_option_name = g_strdup (gkbd_keyboard_config_merge_items (current1st_level_id, config_item->name)); gboolean current_state = xkb_options_is_selected (full_option_name); g_free (full_option_name); xkb_options_expander_selcounter_add (current_state); } /* Respond to a change in the xkb gconf settings */ static void xkb_options_update (GSettings * settings, gchar * key, GtkBuilder * dialog) { if (!strcmp (key, GKBD_KEYBOARD_CONFIG_KEY_OPTIONS)) { /* Updating options is handled by gconf notifies for each widget This is here to avoid calling it N_OPTIONS times for each gconf change. */ enable_disable_restoring (dialog); if (chooser_dialog != NULL) { GSList *expanders_list = g_object_get_data (G_OBJECT (chooser_dialog), EXPANDERS_PROP); while (expanders_list) { current_expander = GTK_WIDGET (expanders_list->data); gchar *group_id = g_object_get_data (G_OBJECT (current_expander), "groupId"); current1st_level_id = group_id; xkb_options_expander_selcounter_reset (); xkl_config_registry_foreach_option (config_registry, group_id, (ConfigItemProcessFunc) xkb_options_update_option_counters, current_expander); xkb_options_expander_highlight (); expanders_list = expanders_list->next; } } } } void xkb_options_register_conf_listener (GtkBuilder * dialog) { g_signal_connect (xkb_keyboard_settings, "changed", G_CALLBACK (xkb_options_update), dialog); } cinnamon-control-center-6.4.1/panels/network/0000775000175000017500000000000014724311620020157 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/network/network-wifi.ui0000664000175000017500000033243014724311620023150 0ustar fabiofabio False 5 False True 600 300 dialog False vertical 2 False end end _Cancel True True True True False True 2 _Apply True True True True False True 3 False True end 0 True False True True never in True True details_store False False 0 10 0 20 True True 0 True True False False True False vertical True False end center 6 True False Automatic _Connect True automatic_connect_switch False True 0 True True False True 1 False True 0 True False start 50 50 12 12 True True 10 6 True False True 1 Signal Strength 0 0 1 1 True True True 0 Weak True 1 0 1 1 True False 1 Link speed 0 1 1 1 True True 0 1Mb/sec True 1 1 1 1 True False 1 Security 0 2 1 1 True False 1 IPv4 Address 0 3 1 1 True False 1 0 IPv6 Address 0 4 1 1 True False 1 Hardware Address 0 5 1 1 True False 1 Default Route 0 6 1 1 True False 1 0 DNS4 0 7 1 1 True False 1 0 DNS6 0 8 1 1 True False 1 Last used 0 9 1 1 True True 0 WPA True 1 2 1 1 True True 0 127.0.0.1 True 1 3 1 1 True True 0 ::1 True 1 4 1 1 True True 0 AA:BB:CC:DD:55:66:77:88 True 1 5 1 1 True True 0 127.0.0.1 True 1 6 1 1 True True 0 0 127.0.0.1 True True 1 7 1 1 True True 0 0 ::1 True True 1 8 1 1 True True 0 today True 1 9 1 1 True True 1 True False details False True False 50 50 12 12 True True 10 6 True False 1 _SSID True entry_ssid 0 0 1 1 True False 1 _BSSID True entry_bssid 0 1 1 1 True False 1 S_ecurity True combo_sec 0 2 1 1 True False 1 _Password True entry_password 0 3 1 1 True True True ā— My Home Network 1 0 1 1 True True True ā— 1 1 1 1 True False True 0 1 WPA None 1 2 1 1 True True True False ā— blablabla 1 3 1 1 Show P_assword True True False center True 0 True 1 4 1 1 True False 0 4 1 1 Make available to other users True True False end True 0 True 1 5 1 1 1 True False identity 1 False True True never True False True False 20 20 10 10 vertical 10 True False True False IPv_4 True switch_ipv4_ipv4 False True 0 True True end True False True 1 False True 0 True False True False _Addresses True combo_ipv4_addresses False True 0 True False end True 0 1 Manual Automatic (DHCP) Automatic (DHCP) addresses only Link-local only Shared with other computers Disabled False True 1 False True 1 True False vertical True False Address section goes here False True 0 False True 2 True False 24 6 0 DNS4 False True 3 True False vertical True False DNS section goes here False True 0 False True 4 True False 24 6 0 Routes False True 5 True False vertical True False Routes section goes here False True 0 False True 6 _Ignore automatically obtained routes True True False True 0 True False True 7 Use this connection _only for resources on its network True True False True 0 True False True 8 2 True False ipv4 2 False True True never in True False True False vertical 10 True False True False IPv_6 True switch_ipv6_ipv6 False True 0 True True end True False True 1 False True 0 True False True False _Addresses True combo_ipv6_addresses False True 0 True False end True 0 1 Manual Automatic (DHCP) Automatic (DHCP) addresses only Link-local only Shared with other computers Disabled False True 1 False True 1 True False vertical True False Address section goes here False True 0 False True 2 True False 24 6 0 DNS6 False True 3 True False vertical True False DNS section goes here False True 0 False True 4 True False 24 6 0 Routes False True 5 True False vertical True False Routes section goes here False True 0 False True 6 _Ignore automatically obtained routes True True False True 0 True False True 7 Use this connection _only for resources on its network True True False True 0 True False True 8 3 True False ipv6 3 False True False 50 50 12 12 True True 10 6 True False 1 _MAC Address True label_hw_mac 0 0 1 1 True False 1 _Cloned MAC Address True entry_hw_cloned_mac 0 1 1 1 True False True 0 00:24:16:31:8G:7A True 1 0 1 1 True True True ā— 1 1 1 1 4 True False hardware 4 False True False 50 50 12 12 10 10 _Reset True True True start True 0 0 1 1 _Forget True True True start True 0 1 1 1 True False True 0 Reset the settings for this connection to their defaults, but remember as a preferred connection. True 40 1 0 1 1 True False True 0 Remove all details relating to this network and do not try to automatically connect to it. True 30 1 1 1 1 5 True False reset 5 False True True 1 True True 1 details_cancel_button details_apply_button Details 0 Identity 1 IPv4 2 IPv6 3 Hardware 4 Reset 5 False 5 False True True dialog False vertical 14 True False 5 12 True False network-wireless 6 False True 0 True False Wi-Fi Hotspot False True 1 False True 0 True False True 60 60 False True 1 False end _Cancel True True True True False True 0 _Turn On True True True True True True False True 1 False True end 2 hotspot-cancel-button hotspot-turn-on-button True True False False True False vertical True False 18 vertical True False 12 12 12 12 6 True False network-wireless 6 False True 0 True False True vertical True False 0 Wi-Fi False True 0 True False 0 Connected False True 1 False True 1 True True end center True Turn Wi-Fi off True True 2 True False 0 300 True True 12 12 True True never in True True 1 True True 0 True False 12 12 12 True 6 _Use as Hotspot… True True True start True False False 0 _Connect to Hidden Network… True True True center True True False 1 _History True True True end True False False 2 False True 1 True False list False True False 12 9 True False True False start center True vertical 3 True False 0 Wi-Fi Hotspot False True 0 True False 0 Switch off to connect to a Wi-Fi network False True 1 False True 0 True True end center False True 1 False True 0 True False center start 10 6 True True False 1 Network Name label_hotspot_network_name 0 0 1 1 True False 1 Connected Devices label_hotspot_connected 0 1 1 1 True False 1 Security type label_hotspot_security 0 2 1 1 True False 0 True 1 0 1 1 True False 0 True 1 1 1 1 True False 0 True 1 2 1 1 True False 1 Password label_hotspot_security_key 0 3 1 1 True False 0 True 1 3 1 1 True True 1 1 True False hotspot 1 False cinnamon-control-center-6.4.1/panels/network/cc-network-panel.c0000664000175000017500000014277214724311620023511 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2010-2012 Richard Hughes * Copyright (C) 2012 Thomas Bechtold * Copyright (C) 2013 Aleksander Morgado * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include #include #include "cc-network-panel.h" #include "cc-network-resources.h" #include #include "net-device.h" #ifdef BUILD_MODEM #include "net-device-mobile.h" #endif #include "net-device-wifi.h" #include "net-device-ethernet.h" #include "net-object.h" #include "net-proxy.h" #include "net-vpn.h" #include "panel-common.h" #include "network-dialogs.h" #include "connection-editor/net-connection-editor.h" #ifdef BUILD_MODEM #include #endif CC_PANEL_REGISTER (CcNetworkPanel, cc_network_panel) #define NETWORK_PANEL_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_NETWORK_PANEL, CcNetworkPanelPrivate)) typedef enum { OPERATION_NULL, OPERATION_SHOW_DEVICE, OPERATION_CREATE_WIFI, OPERATION_CONNECT_HIDDEN, OPERATION_CONNECT_8021X, OPERATION_CONNECT_MOBILE } CmdlineOperation; struct _CcNetworkPanelPrivate { GCancellable *cancellable; GtkBuilder *builder; GtkWidget *treeview; NMClient *client; #ifdef BUILD_MODEM MMManager *modem_manager; #else void *modem_manager; #endif gboolean updating_device; /* wireless dialog stuff */ CmdlineOperation arg_operation; gchar *arg_device; gchar *arg_access_point; gboolean operation_done; }; enum { PANEL_DEVICES_COLUMN_ICON, PANEL_DEVICES_COLUMN_OBJECT, PANEL_DEVICES_COLUMN_LAST }; enum { PROP_0, PROP_PARAMETERS }; static NetObject *find_in_model_by_id (CcNetworkPanel *panel, const gchar *id, GtkTreeIter *iter_out); static void handle_argv (CcNetworkPanel *panel); static void cc_network_panel_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { switch (property_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static CmdlineOperation cmdline_operation_from_string (const gchar *string) { if (g_strcmp0 (string, "create-wifi") == 0) return OPERATION_CREATE_WIFI; if (g_strcmp0 (string, "connect-hidden-wifi") == 0) return OPERATION_CONNECT_HIDDEN; if (g_strcmp0 (string, "connect-8021x-wifi") == 0) return OPERATION_CONNECT_8021X; if (g_strcmp0 (string, "connect-3g") == 0) return OPERATION_CONNECT_MOBILE; if (g_strcmp0 (string, "show-device") == 0) return OPERATION_SHOW_DEVICE; g_warning ("Invalid additional argument %s", string); return OPERATION_NULL; } static void reset_command_line_args (CcNetworkPanel *self) { self->priv->arg_operation = OPERATION_NULL; g_clear_pointer (&self->priv->arg_device, g_free); g_clear_pointer (&self->priv->arg_access_point, g_free); } static gboolean verify_argv (CcNetworkPanel *self, const char **args) { switch (self->priv->arg_operation) { case OPERATION_CONNECT_MOBILE: case OPERATION_CONNECT_8021X: case OPERATION_SHOW_DEVICE: if (self->priv->arg_device == NULL) { g_warning ("Operation %s requires an object path", args[0]); return FALSE; } default: return TRUE; } } static GPtrArray * variant_av_to_string_array (GVariant *array) { GVariantIter iter; GVariant *v; GPtrArray *strv; gsize count; count = g_variant_iter_init (&iter, array); strv = g_ptr_array_sized_new (count + 1); while (g_variant_iter_next (&iter, "v", &v)) { if (g_variant_is_of_type (v, G_VARIANT_TYPE_STRING)) g_ptr_array_add (strv, (gpointer *)g_variant_get_string (v, NULL)); g_variant_unref (v); } g_ptr_array_add (strv, NULL); /* NULL-terminate the strv data array */ return strv; } static void cc_network_panel_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { CcNetworkPanel *self = CC_NETWORK_PANEL (object); CcNetworkPanelPrivate *priv = self->priv; switch (property_id) { case PROP_PARAMETERS: { GVariant *parameters; reset_command_line_args (self); parameters = g_value_get_variant (value); if (parameters) { GPtrArray *array; const gchar **args; array = variant_av_to_string_array (parameters); args = (const gchar **) array->pdata; g_debug ("Invoked with operation %s", args[0]); if (args[0]) priv->arg_operation = cmdline_operation_from_string (args[0]); if (args[0] && args[1]) priv->arg_device = g_strdup (args[1]); if (args[0] && args[1] && args[2]) priv->arg_access_point = g_strdup (args[2]); if (verify_argv (self, (const char **) args) == FALSE) { reset_command_line_args (self); g_ptr_array_unref (array); return; } g_ptr_array_unref (array); g_debug ("Calling handle_argv() after setting property"); handle_argv (self); } break; } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void cc_network_panel_dispose (GObject *object) { CcNetworkPanelPrivate *priv = CC_NETWORK_PANEL (object)->priv; if (priv->cancellable != NULL) g_cancellable_cancel (priv->cancellable); g_clear_object (&priv->cancellable); g_clear_object (&priv->client); g_clear_object (&priv->modem_manager); g_clear_object (&priv->builder); G_OBJECT_CLASS (cc_network_panel_parent_class)->dispose (object); } static void cc_network_panel_finalize (GObject *object) { CcNetworkPanel *panel = CC_NETWORK_PANEL (object); reset_command_line_args (panel); G_OBJECT_CLASS (cc_network_panel_parent_class)->finalize (object); } static const char * cc_network_panel_get_help_uri (CcPanel *panel) { return "help:gnome-help/net"; } static void cc_network_panel_class_init (CcNetworkPanelClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); CcPanelClass *panel_class = CC_PANEL_CLASS (klass); g_type_class_add_private (klass, sizeof (CcNetworkPanelPrivate)); panel_class->get_help_uri = cc_network_panel_get_help_uri; object_class->get_property = cc_network_panel_get_property; object_class->set_property = cc_network_panel_set_property; object_class->dispose = cc_network_panel_dispose; object_class->finalize = cc_network_panel_finalize; g_object_class_override_property (object_class, PROP_PARAMETERS, "parameters"); } static NetObject * get_selected_object (CcNetworkPanel *panel) { GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter; NetObject *object = NULL; selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (panel->priv->treeview)); if (!gtk_tree_selection_get_selected (selection, &model, &iter)) { return NULL; } gtk_tree_model_get (model, &iter, PANEL_DEVICES_COLUMN_OBJECT, &object, -1); return object; } static void select_first_device (CcNetworkPanel *panel) { GtkTreePath *path; GtkTreeSelection *selection; selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (panel->priv->treeview)); /* select the first device */ path = gtk_tree_path_new_from_string ("0"); gtk_tree_selection_select_path (selection, path); gtk_tree_path_free (path); } static void select_tree_iter (CcNetworkPanel *panel, GtkTreeIter *iter) { GtkTreeSelection *selection; selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (panel->priv->treeview)); gtk_tree_selection_select_iter (selection, iter); } static void object_removed_cb (NetObject *object, CcNetworkPanel *panel) { gboolean ret; NetObject *object_tmp; GtkTreeIter iter; GtkTreeModel *model; GtkTreeSelection *selection; selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (panel->priv->treeview)); /* remove device from model */ model = GTK_TREE_MODEL (gtk_builder_get_object (panel->priv->builder, "liststore_devices")); ret = gtk_tree_model_get_iter_first (model, &iter); if (!ret) return; /* get the other elements */ do { gtk_tree_model_get (model, &iter, PANEL_DEVICES_COLUMN_OBJECT, &object_tmp, -1); if (g_strcmp0 (net_object_get_id (object), net_object_get_id (object_tmp)) == 0) { g_object_unref (object_tmp); if (gtk_list_store_remove (GTK_LIST_STORE (model), &iter)) { if (gtk_tree_model_get_iter_first (model, &iter)) gtk_tree_selection_select_iter (selection, &iter); } break; } g_object_unref (object_tmp); } while (gtk_tree_model_iter_next (model, &iter)); } GPtrArray * cc_network_panel_get_devices (CcNetworkPanel *panel) { GPtrArray *devices; GtkTreeModel *model; GtkTreeIter iter; NetObject *object; devices = g_ptr_array_new_with_free_func (g_object_unref); model = GTK_TREE_MODEL (gtk_builder_get_object (panel->priv->builder, "liststore_devices")); if (!gtk_tree_model_get_iter_first (model, &iter)) return devices; do { gtk_tree_model_get (model, &iter, PANEL_DEVICES_COLUMN_OBJECT, &object, -1); if (NET_IS_DEVICE (object)) g_ptr_array_add (devices, object); else g_object_unref (object); } while (gtk_tree_model_iter_next (model, &iter)); return devices; } static gint panel_net_object_get_sort_category (NetObject *net_object) { if (NET_IS_DEVICE (net_object)) { return panel_device_get_sort_category (net_device_get_nm_device (NET_DEVICE (net_object))); } else if (NET_IS_PROXY (net_object)) { return 9; } else if (NET_IS_VPN (net_object)) { return 5; } g_assert_not_reached (); } static gint panel_net_object_sort_func (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, void *data) { g_autoptr(NetObject) obj_a = NULL; g_autoptr(NetObject) obj_b = NULL; gint cat_a, cat_b; const char *title_a, *title_b; gtk_tree_model_get (model, a, PANEL_DEVICES_COLUMN_OBJECT, &obj_a, -1); gtk_tree_model_get (model, b, PANEL_DEVICES_COLUMN_OBJECT, &obj_b, -1); cat_a = panel_net_object_get_sort_category (obj_a); cat_b = panel_net_object_get_sort_category (obj_b); if (cat_a != cat_b) return cat_a - cat_b; title_a = net_object_get_title (obj_a); title_b = net_object_get_title (obj_b); if (title_a == title_b) return 0; if (title_a == NULL) return -1; if (title_b == NULL) return 1; return g_utf8_collate (title_a, title_b); } static void panel_net_object_notify_title_cb (NetObject *net_object, GParamSpec *pspec, CcNetworkPanel *panel) { GtkTreeIter iter; GtkListStore *liststore; if (!find_in_model_by_id (panel, net_object_get_id (net_object), &iter)) return; liststore = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder, "liststore_devices")); /* gtk_tree_model_row_changed would not cause the list store to resort. * Instead set the object column to the current value. * See https://bugzilla.gnome.org/show_bug.cgi?id=782737 */ gtk_list_store_set (liststore, &iter, PANEL_DEVICES_COLUMN_OBJECT, net_object, -1); } static void panel_refresh_device_titles (CcNetworkPanel *panel) { GPtrArray *ndarray, *nmdarray; NetDevice **devices; NMDevice **nm_devices, *nm_device; gchar **titles; gint i, num_devices; ndarray = cc_network_panel_get_devices (panel); if (!ndarray->len) { g_ptr_array_free (ndarray, TRUE); return; } nmdarray = g_ptr_array_new (); for (i = 0; i < ndarray->len; i++) { nm_device = net_device_get_nm_device (ndarray->pdata[i]); if (nm_device) g_ptr_array_add (nmdarray, nm_device); else g_ptr_array_remove_index (ndarray, i--); } devices = (NetDevice **)ndarray->pdata; nm_devices = (NMDevice **)nmdarray->pdata; num_devices = ndarray->len; titles = nm_device_disambiguate_names (nm_devices, num_devices); for (i = 0; i < num_devices; i++) { net_object_set_title (NET_OBJECT (devices[i]), titles[i]); g_free (titles[i]); } g_free (titles); g_ptr_array_free (ndarray, TRUE); g_ptr_array_free (nmdarray, TRUE); } static gboolean handle_argv_for_device (CcNetworkPanel *panel, NMDevice *device, GtkTreeIter *iter) { CcNetworkPanelPrivate *priv = panel->priv; NMDeviceType type; //GtkWidget *toplevel = cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (panel))); GtkWidget *toplevel = GTK_WIDGET(panel); if (priv->arg_operation == OPERATION_NULL) return TRUE; type = nm_device_get_device_type (device); if (type == NM_DEVICE_TYPE_WIFI && (priv->arg_operation == OPERATION_CREATE_WIFI || priv->arg_operation == OPERATION_CONNECT_HIDDEN)) { g_debug ("Selecting wifi device"); select_tree_iter (panel, iter); if (priv->arg_operation == OPERATION_CREATE_WIFI) cc_network_panel_create_wifi_network (toplevel, priv->client); else cc_network_panel_connect_to_hidden_network (toplevel, priv->client); reset_command_line_args (panel); /* done */ return TRUE; } else if (g_strcmp0 (nm_object_get_path (NM_OBJECT (device)), priv->arg_device) == 0) { if (priv->arg_operation == OPERATION_CONNECT_MOBILE) { cc_network_panel_connect_to_3g_network (toplevel, priv->client, device); reset_command_line_args (panel); /* done */ select_tree_iter (panel, iter); return TRUE; } else if (priv->arg_operation == OPERATION_CONNECT_8021X) { cc_network_panel_connect_to_8021x_network (toplevel, priv->client, device, priv->arg_access_point); reset_command_line_args (panel); /* done */ select_tree_iter (panel, iter); return TRUE; } else if (priv->arg_operation == OPERATION_SHOW_DEVICE) { select_tree_iter (panel, iter); reset_command_line_args (panel); /* done */ return TRUE; } } return FALSE; } static gboolean handle_argv_for_connection (CcNetworkPanel *panel, NMConnection *connection, GtkTreeIter *iter) { CcNetworkPanelPrivate *priv = panel->priv; if (priv->arg_operation == OPERATION_NULL) return TRUE; if (priv->arg_operation != OPERATION_SHOW_DEVICE) return FALSE; if (g_strcmp0 (nm_connection_get_path (connection), priv->arg_device) == 0) { reset_command_line_args (panel); select_tree_iter (panel, iter); return TRUE; } return FALSE; } static void handle_argv (CcNetworkPanel *panel) { GtkTreeModel *model; GtkTreeIter iter; gboolean ret; if (panel->priv->arg_operation == OPERATION_NULL) return; model = GTK_TREE_MODEL (gtk_builder_get_object (panel->priv->builder, "liststore_devices")); ret = gtk_tree_model_get_iter_first (model, &iter); while (ret) { GObject *object_tmp; NMDevice *device; NMConnection *connection; gboolean done = FALSE; gtk_tree_model_get (model, &iter, PANEL_DEVICES_COLUMN_OBJECT, &object_tmp, -1); if (NET_IS_DEVICE (object_tmp)) { g_object_get (object_tmp, "nm-device", &device, NULL); done = handle_argv_for_device (panel, device, &iter); g_object_unref (device); } else if (NET_IS_VPN (object_tmp)) { g_object_get (object_tmp, "connection", &connection, NULL); done = handle_argv_for_connection (panel, connection, &iter); g_object_unref (connection); } g_object_unref (object_tmp); if (done) return; ret = gtk_tree_model_iter_next (model, &iter); } g_debug ("Could not handle argv operation, no matching device yet?"); } static void state_changed_cb (NMDevice *device, NMDeviceState new_state, NMDeviceState old_state, NMDeviceStateReason reason, CcNetworkPanel *panel) { GtkListStore *store; GtkTreeIter iter; if (!find_in_model_by_id (panel, nm_device_get_udi (device), &iter)) { return; } store = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder, "liststore_devices")); gtk_list_store_set (store, &iter, PANEL_DEVICES_COLUMN_ICON, panel_device_to_icon_name (device, TRUE), -1); } static gboolean panel_add_device (CcNetworkPanel *panel, NMDevice *device) { GtkListStore *liststore_devices; GtkTreeIter iter; NMDeviceType type; NetDevice *net_device; CcNetworkPanelPrivate *priv = panel->priv; GtkNotebook *notebook; GtkSizeGroup *size_group; GType device_g_type; const char *udi; if (!nm_device_get_managed (device)) goto out; /* do we have an existing object with this id? */ udi = nm_device_get_udi (device); if (find_in_model_by_id (panel, udi, NULL) != NULL) goto out; type = nm_device_get_device_type (device); g_debug ("device %s type %i path %s", udi, type, nm_object_get_path (NM_OBJECT (device))); /* map the NMDeviceType to the GType, or ignore */ switch (type) { case NM_DEVICE_TYPE_ETHERNET: device_g_type = NET_TYPE_DEVICE_ETHERNET; break; #ifdef BUILD_MODEM case NM_DEVICE_TYPE_MODEM: device_g_type = NET_TYPE_DEVICE_MOBILE; break; #endif case NM_DEVICE_TYPE_WIFI: device_g_type = NET_TYPE_DEVICE_WIFI; break; /* not going to set up a cluster in GNOME */ case NM_DEVICE_TYPE_VETH: /* enterprise features */ case NM_DEVICE_TYPE_BOND: case NM_DEVICE_TYPE_TEAM: /* Don't need the libvirtd bridge */ case NM_DEVICE_TYPE_BRIDGE: /* Don't add VPN devices */ case NM_DEVICE_TYPE_TUN: goto out; default: device_g_type = NET_TYPE_DEVICE_SIMPLE; break; } /* create device */ net_device = g_object_new (device_g_type, "panel", panel, "removable", FALSE, "cancellable", panel->priv->cancellable, "client", panel->priv->client, "nm-device", device, "id", nm_device_get_udi (device), NULL); if (type == NM_DEVICE_TYPE_MODEM && g_str_has_prefix (nm_device_get_udi (device), "/org/freedesktop/ModemManager1/Modem/")) { GDBusObject *modem_object; if (priv->modem_manager == NULL) { g_warning ("Cannot grab information for modem at %s: No ModemManager support", nm_device_get_udi (device)); goto out; } modem_object = g_dbus_object_manager_get_object (G_DBUS_OBJECT_MANAGER (priv->modem_manager), nm_device_get_udi (device)); if (modem_object == NULL) { g_warning ("Cannot grab information for modem at %s: Not found", nm_device_get_udi (device)); goto out; } /* Set the modem object in the NetDeviceMobile */ g_object_set (net_device, "mm-object", modem_object, NULL); g_object_unref (modem_object); } /* add as a panel */ if (device_g_type != NET_TYPE_DEVICE) { notebook = GTK_NOTEBOOK (gtk_builder_get_object (panel->priv->builder, "notebook_types")); size_group = GTK_SIZE_GROUP (gtk_builder_get_object (panel->priv->builder, "sizegroup1")); net_object_add_to_notebook (NET_OBJECT (net_device), notebook, size_group); } liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (priv->builder, "liststore_devices")); g_signal_connect_object (net_device, "removed", G_CALLBACK (object_removed_cb), panel, 0); gtk_list_store_append (liststore_devices, &iter); gtk_list_store_set (liststore_devices, &iter, PANEL_DEVICES_COLUMN_ICON, panel_device_to_icon_name (device, TRUE), PANEL_DEVICES_COLUMN_OBJECT, net_device, -1); g_signal_connect (net_device, "notify::title", G_CALLBACK (panel_net_object_notify_title_cb), panel); g_object_unref (net_device); g_signal_connect (device, "state-changed", G_CALLBACK (state_changed_cb), panel); out: return FALSE; } static void panel_remove_device (CcNetworkPanel *panel, NMDevice *device) { gboolean ret; NetObject *object_tmp; GtkTreeIter iter; GtkTreeModel *model; /* remove device from model */ model = GTK_TREE_MODEL (gtk_builder_get_object (panel->priv->builder, "liststore_devices")); ret = gtk_tree_model_get_iter_first (model, &iter); if (!ret) return; /* get the other elements */ do { gtk_tree_model_get (model, &iter, PANEL_DEVICES_COLUMN_OBJECT, &object_tmp, -1); if (g_strcmp0 (net_object_get_id (object_tmp), nm_device_get_udi (device)) == 0) { gtk_list_store_remove (GTK_LIST_STORE (model), &iter); g_object_unref (object_tmp); break; } g_object_unref (object_tmp); } while (gtk_tree_model_iter_next (model, &iter)); } static void get_object_title (GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer data) { NetObject *object; gtk_tree_model_get (model, iter, PANEL_DEVICES_COLUMN_OBJECT, &object, -1); if (!object) return; g_object_set (cell, "text", net_object_get_title (object), NULL); g_object_unref (object); } static void panel_add_devices_columns (CcNetworkPanel *panel, GtkTreeView *treeview) { CcNetworkPanelPrivate *priv = panel->priv; GtkCellRenderer *renderer; GtkListStore *liststore_devices; GtkTreeViewColumn *column; /* image */ renderer = gtk_cell_renderer_pixbuf_new (); g_object_set (renderer, "width", 32, "xalign", 1.0, "stock-size", GTK_ICON_SIZE_MENU, "follow-state", TRUE, NULL); gtk_cell_renderer_set_padding (renderer, 4, 10); column = gtk_tree_view_column_new_with_attributes ("icon", renderer, "icon-name", PANEL_DEVICES_COLUMN_ICON, NULL); gtk_tree_view_append_column (treeview, column); /* column for text */ renderer = gtk_cell_renderer_text_new (); g_object_set (renderer, "wrap-mode", PANGO_WRAP_WORD, "ellipsize", PANGO_ELLIPSIZE_END, NULL); column = gtk_tree_view_column_new_with_attributes ("title", renderer, NULL); gtk_tree_view_column_set_cell_data_func (GTK_TREE_VIEW_COLUMN (column), renderer, get_object_title, NULL, NULL); gtk_tree_view_column_set_sort_column_id (column, PANEL_DEVICES_COLUMN_OBJECT); liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (priv->builder, "liststore_devices")); gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (liststore_devices), PANEL_DEVICES_COLUMN_OBJECT, panel_net_object_sort_func, NULL, NULL); gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (liststore_devices), PANEL_DEVICES_COLUMN_OBJECT, GTK_SORT_ASCENDING); gtk_tree_view_append_column (treeview, column); gtk_tree_view_column_set_expand (column, TRUE); } static void nm_devices_treeview_clicked_cb (GtkTreeSelection *selection, CcNetworkPanel *panel) { CcNetworkPanelPrivate *priv = panel->priv; const gchar *id_tmp; const gchar *needle; GList *l; GList *panels = NULL; GtkNotebook *notebook; GtkTreeIter iter; GtkTreeModel *model; GtkWidget *widget; guint i = 0; NetObject *object = NULL; if (!gtk_tree_selection_get_selected (selection, &model, &iter)) { g_debug ("no row selected"); goto out; } /* find the widget in the notebook that matches the object ID */ object = get_selected_object (panel); needle = net_object_get_id (object); notebook = GTK_NOTEBOOK (gtk_builder_get_object (priv->builder, "notebook_types")); panels = gtk_container_get_children (GTK_CONTAINER (notebook)); for (l = panels; l != NULL; l = l->next) { widget = GTK_WIDGET (l->data); id_tmp = g_object_get_data (G_OBJECT (widget), "NetObject::id"); if (g_strcmp0 (needle, id_tmp) == 0) { gtk_notebook_set_current_page (notebook, i); /* object is deletable? */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "remove_toolbutton")); gtk_widget_set_sensitive (widget, net_object_get_removable (object)); break; } i++; } g_object_unref (object); out: g_list_free (panels); } static void panel_add_proxy_device (CcNetworkPanel *panel) { GtkListStore *liststore_devices; GtkTreeIter iter; NetProxy *proxy; GtkNotebook *notebook; GtkSizeGroup *size_group; /* add proxy to notebook */ proxy = net_proxy_new (); notebook = GTK_NOTEBOOK (gtk_builder_get_object (panel->priv->builder, "notebook_types")); size_group = GTK_SIZE_GROUP (gtk_builder_get_object (panel->priv->builder, "sizegroup1")); net_object_add_to_notebook (NET_OBJECT (proxy), notebook, size_group); /* add proxy to device list */ liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder, "liststore_devices")); net_object_set_title (NET_OBJECT (proxy), _("Network proxy")); gtk_list_store_append (liststore_devices, &iter); gtk_list_store_set (liststore_devices, &iter, PANEL_DEVICES_COLUMN_ICON, "preferences-system-network-symbolic", PANEL_DEVICES_COLUMN_OBJECT, proxy, -1); /* NOTE: No connect to notify::title here as it is guaranteed to not * be changed by anyone.*/ g_object_unref (proxy); } static void connection_state_changed (NMActiveConnection *c, GParamSpec *pspec, CcNetworkPanel *panel) { } static void active_connections_changed (NMClient *client, GParamSpec *pspec, gpointer user_data) { CcNetworkPanel *panel = user_data; const GPtrArray *connections; int i, j; g_debug ("Active connections changed:"); connections = nm_client_get_active_connections (client); for (i = 0; connections && (i < connections->len); i++) { NMActiveConnection *connection; const GPtrArray *devices; connection = g_ptr_array_index (connections, i); g_debug (" %s", nm_object_get_path (NM_OBJECT (connection))); devices = nm_active_connection_get_devices (connection); for (j = 0; devices && j < devices->len; j++) g_debug (" %s", nm_device_get_udi (g_ptr_array_index (devices, j))); if (NM_IS_VPN_CONNECTION (connection)) g_debug (" VPN base connection: %s", nm_active_connection_get_specific_object_path (connection)); if (g_object_get_data (G_OBJECT (connection), "has-state-changed-handler") == NULL) { g_signal_connect_object (connection, "notify::state", G_CALLBACK (connection_state_changed), panel, 0); g_object_set_data (G_OBJECT (connection), "has-state-changed-handler", GINT_TO_POINTER (TRUE)); } } } static void device_added_cb (NMClient *client, NMDevice *device, CcNetworkPanel *panel) { g_debug ("New device added"); panel_add_device (panel, device); panel_refresh_device_titles (panel); } static void device_removed_cb (NMClient *client, NMDevice *device, CcNetworkPanel *panel) { g_debug ("Device removed"); panel_remove_device (panel, device); panel_refresh_device_titles (panel); } static void manager_running (NMClient *client, GParamSpec *pspec, gpointer user_data) { const GPtrArray *devices; int i; NMDevice *device_tmp; GtkListStore *liststore_devices; gboolean selected = FALSE; CcNetworkPanel *panel = CC_NETWORK_PANEL (user_data); /* clear all devices we added */ if (!nm_client_get_nm_running (client)) { g_debug ("NM disappeared"); liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder, "liststore_devices")); gtk_list_store_clear (liststore_devices); panel_add_proxy_device (panel); goto out; } g_debug ("coldplugging devices"); devices = nm_client_get_devices (client); if (devices == NULL) { g_debug ("No devices to add"); return; } for (i = 0; i < devices->len; i++) { device_tmp = g_ptr_array_index (devices, i); selected = panel_add_device (panel, device_tmp) || selected; } out: if (!selected) { /* select the first device */ select_first_device (panel); } panel_refresh_device_titles (panel); g_debug ("Calling handle_argv() after cold-plugging devices"); handle_argv (panel); } static NetObject * find_in_model_by_id (CcNetworkPanel *panel, const gchar *id, GtkTreeIter *iter_out) { gboolean ret; NetObject *object_tmp; GtkTreeIter iter; GtkTreeModel *model; NetObject *object = NULL; /* find in model */ model = GTK_TREE_MODEL (gtk_builder_get_object (panel->priv->builder, "liststore_devices")); ret = gtk_tree_model_get_iter_first (model, &iter); if (!ret) goto out; /* get the other elements */ ret = FALSE; do { gtk_tree_model_get (model, &iter, PANEL_DEVICES_COLUMN_OBJECT, &object_tmp, -1); if (object_tmp != NULL) { g_debug ("got %s", net_object_get_id (object_tmp)); if (g_strcmp0 (net_object_get_id (object_tmp), id) == 0) object = object_tmp; g_object_unref (object_tmp); } } while (object == NULL && gtk_tree_model_iter_next (model, &iter)); out: if (iter_out) *iter_out = iter; return object; } static void panel_add_vpn_device (CcNetworkPanel *panel, NMConnection *connection) { gchar *title; GtkListStore *liststore_devices; GtkTreeIter iter; NetVpn *net_vpn; const gchar *id; GtkNotebook *notebook; GtkSizeGroup *size_group; /* does already exist */ id = nm_connection_get_path (connection); if (find_in_model_by_id (panel, id, NULL) != NULL) return; /* add as a VPN object */ net_vpn = g_object_new (NET_TYPE_VPN, "panel", panel, "removable", TRUE, "id", id, "connection", connection, "client", panel->priv->client, NULL); g_signal_connect_object (net_vpn, "removed", G_CALLBACK (object_removed_cb), panel, 0); /* add as a panel */ notebook = GTK_NOTEBOOK (gtk_builder_get_object (panel->priv->builder, "notebook_types")); size_group = GTK_SIZE_GROUP (gtk_builder_get_object (panel->priv->builder, "sizegroup1")); net_object_add_to_notebook (NET_OBJECT (net_vpn), notebook, size_group); liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder, "liststore_devices")); title = g_strdup_printf (_("%s VPN"), nm_connection_get_id (connection)); net_object_set_title (NET_OBJECT (net_vpn), title); gtk_list_store_append (liststore_devices, &iter); gtk_list_store_set (liststore_devices, &iter, PANEL_DEVICES_COLUMN_ICON, "network-vpn-symbolic", PANEL_DEVICES_COLUMN_OBJECT, net_vpn, -1); g_signal_connect (net_vpn, "notify::title", G_CALLBACK (panel_net_object_notify_title_cb), panel); g_free (title); g_object_unref (net_vpn); } static void add_connection (CcNetworkPanel *panel, NMConnection *connection) { NMSettingConnection *s_con; const gchar *type, *iface; s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); type = nm_setting_connection_get_connection_type (s_con); iface = nm_connection_get_interface_name (connection); if (g_strcmp0 (type, "vpn") != 0 && iface == NULL) return; /* Don't add the libvirtd bridge to the UI */ if (g_strcmp0 (nm_setting_connection_get_interface_name (s_con), "virbr0") == 0) return; g_debug ("add %s/%s remote connection: %s", type, g_type_name_from_instance ((GTypeInstance*)connection), nm_connection_get_path (connection)); if (!iface) panel_add_vpn_device (panel, connection); } static void notify_connection_added_cb (NMClient *client, NMRemoteConnection *connection, CcNetworkPanel *panel) { add_connection (panel, NM_CONNECTION (connection)); } static void panel_check_network_manager_version (CcNetworkPanel *panel) { GtkWidget *box; GtkWidget *label; gchar *markup; const gchar *version; /* parse running version */ version = nm_client_get_version (panel->priv->client); if (version == NULL) { gtk_container_remove (GTK_CONTAINER (panel), gtk_bin_get_child (GTK_BIN (panel))); box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 20); gtk_box_set_homogeneous (GTK_BOX (box), TRUE); gtk_widget_set_vexpand (box, TRUE); gtk_container_add (GTK_CONTAINER (panel), box); label = gtk_label_new (_("Oops, something has gone wrong. Please contact your software vendor.")); gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); gtk_widget_set_valign (label, GTK_ALIGN_END); gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0); markup = g_strdup_printf ("%s", _("NetworkManager needs to be running.")); label = gtk_label_new (NULL); gtk_label_set_markup (GTK_LABEL (label), markup); gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); gtk_widget_set_valign (label, GTK_ALIGN_START); gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0); gtk_widget_show_all (box); g_free (markup); } else { manager_running (panel->priv->client, NULL, panel); } } static void editor_done (NetConnectionEditor *editor, gboolean success, gpointer user_data) { g_object_unref (editor); } static void add_connection_cb (GtkToolButton *button, CcNetworkPanel *panel) { NetConnectionEditor *editor; GtkWindow *toplevel; toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (panel))); editor = net_connection_editor_new (toplevel, NULL, NULL, NULL, panel->priv->client); g_signal_connect (editor, "done", G_CALLBACK (editor_done), panel); net_connection_editor_run (editor); } static void remove_connection (GtkToolButton *button, CcNetworkPanel *panel) { NetObject *object; /* get current device */ object = get_selected_object (panel); if (object == NULL) return; /* delete the object */ net_object_delete (object); g_object_unref (object); } static void on_toplevel_map (GtkWidget *widget, CcNetworkPanel *panel) { /* is the user compiling against a new version, but not running * the daemon? */ panel_check_network_manager_version (panel); } static void cc_network_panel_init (CcNetworkPanel *panel) { GError *error = NULL; GtkStyleContext *context; GtkTreeSelection *selection; GtkWidget *widget; GtkWidget *toplevel; GDBusConnection *system_bus; GtkCssProvider *provider; const GPtrArray *connections; guint i; panel->priv = NETWORK_PANEL_PRIVATE (panel); g_resources_register (cc_network_get_resource ()); panel->priv->builder = gtk_builder_new (); gtk_builder_add_from_resource (panel->priv->builder, "/org/cinnamon/control-center/network/network.ui", &error); if (error != NULL) { g_warning ("Could not load interface file: %s", error->message); g_error_free (error); return; } panel->priv->cancellable = g_cancellable_new (); panel->priv->treeview = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "treeview_devices")); panel_add_devices_columns (panel, GTK_TREE_VIEW (panel->priv->treeview)); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (panel->priv->treeview)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); g_signal_connect (selection, "changed", G_CALLBACK (nm_devices_treeview_clicked_cb), panel); widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "devices_scrolledwindow")); gtk_widget_set_size_request (widget, 200, -1); context = gtk_widget_get_style_context (widget); gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM); widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "devices_toolbar")); context = gtk_widget_get_style_context (widget); gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP); /* add the virtual proxy device */ panel_add_proxy_device (panel); /* use NetworkManager client */ panel->priv->client = nm_client_new (NULL, NULL); g_signal_connect (panel->priv->client, "notify::nm-running" , G_CALLBACK (manager_running), panel); g_signal_connect (panel->priv->client, "notify::active-connections", G_CALLBACK (active_connections_changed), panel); g_signal_connect (panel->priv->client, "device-added", G_CALLBACK (device_added_cb), panel); g_signal_connect (panel->priv->client, "device-removed", G_CALLBACK (device_removed_cb), panel); #ifdef BUILD_MODEM /* Setup ModemManager client */ system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); if (system_bus == NULL) { g_warning ("Error connecting to system D-Bus: %s", error->message); g_clear_error (&error); } else { panel->priv->modem_manager = mm_manager_new_sync (system_bus, G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, NULL, &error); if (panel->priv->modem_manager == NULL) { g_warning ("Error connecting to ModemManager: %s", error->message); g_clear_error (&error); } g_object_unref (system_bus); } #else panel->priv->modem_manager = NULL; #endif widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "add_toolbutton")); g_signal_connect (widget, "clicked", G_CALLBACK (add_connection_cb), panel); /* disable for now, until we actually show removable connections */ widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "remove_toolbutton")); g_signal_connect (widget, "clicked", G_CALLBACK (remove_connection), panel); /* add remote settings such as VPN settings as virtual devices */ g_signal_connect (panel->priv->client, NM_CLIENT_CONNECTION_ADDED, G_CALLBACK (notify_connection_added_cb), panel); toplevel = gtk_widget_get_toplevel (GTK_WIDGET (panel)); g_signal_connect_after (toplevel, "map", G_CALLBACK (on_toplevel_map), panel); /* hide implementation details */ widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "notebook_types")); gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE); widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "vbox1")); gtk_container_add (GTK_CONTAINER (panel), widget); provider = gtk_css_provider_new (); gtk_css_provider_load_from_data (provider, ".circular-button { border-radius: 20px; -gtk-outline-radius: 20px; }", -1, NULL); gtk_style_context_add_provider_for_screen (gdk_screen_get_default (), GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); g_object_unref (provider); /* Cold-plug existing connections */ connections = nm_client_get_connections (panel->priv->client); if (connections) { for (i = 0; i < connections->len; i++) add_connection (panel, connections->pdata[i]); } g_debug ("Calling handle_argv() after cold-plugging connections"); handle_argv (panel); } void cc_network_panel_register (GIOModule *module) { textdomain (GETTEXT_PACKAGE); bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); cc_network_panel_register_type (G_TYPE_MODULE (module)); g_io_extension_point_implement (CC_SHELL_PANEL_EXTENSION_POINT, CC_TYPE_NETWORK_PANEL, "network", 0); } cinnamon-control-center-6.4.1/panels/network/panel-common.h0000664000175000017500000000557714724311620022733 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2010 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef PANEL_COMMON_H #define PANEL_COMMON_H #include #include #include G_BEGIN_DECLS const gchar *panel_device_to_icon_name (NMDevice *device, gboolean symbolic); gint panel_device_get_sort_category (NMDevice *device); const gchar *panel_ap_mode_to_localized_string (NM80211Mode mode); const gchar *panel_vpn_state_to_localized_string (NMVpnConnectionState type); void panel_set_device_status (GtkBuilder *builder, const gchar *label_name, NMDevice *nm_device, const gchar *speed); gboolean panel_set_device_widget_details (GtkBuilder *builder, const gchar *widget_suffix, const gchar *value); gboolean panel_set_device_widget_header (GtkBuilder *builder, const gchar *widget_suffix, const gchar *value); void panel_set_device_widgets (GtkBuilder *builder, NMDevice *device); void panel_unset_device_widgets (GtkBuilder *builder); gchar *panel_get_ip4_address_as_string (NMIPConfig *config, const gchar *what); gchar *panel_get_dns_as_string (NMIPConfig *config); gchar *panel_get_ip6_address_as_string (NMIPConfig *config, const gchar *what); G_END_DECLS #endif /* PANEL_COMMON_H */ cinnamon-control-center-6.4.1/panels/network/meson.build0000664000175000017500000000201214724311620022314 0ustar fabiofabiosubdir('wireless-security') subdir('connection-editor') panel_network_sources = [ 'cc-network-panel.c', 'net-device-ethernet.c', 'net-device-simple.c', 'net-device-wifi.c', 'net-device.c', 'net-object.c', 'net-proxy.c', 'net-vpn.c', 'network-dialogs.c', 'network-module.c', 'panel-common.c', gnome.compile_resources('cc-network-resources', 'network.gresource.xml', c_name: 'cc_network', source_dir: meson.current_source_dir(), ), ] if modemmanager.found() panel_network_sources += 'net-device-mobile.c' endif panel_network = shared_library('network', panel_network_sources, include_directories: rootInclude, link_whole: [ libconnection_editor, ], link_with: [ libcinnamon_control_center, ], dependencies: [ glib, gtk, libnm, libnma, modemmanager, polkit_gobj, ], install: true, install_dir: panels_dir ) install_data('network.ui', install_dir: ui_dir, ) install_data( 'cinnamon-network-panel.desktop', install_dir: desktop_dir )cinnamon-control-center-6.4.1/panels/network/cc-network-panel.h0000664000175000017500000000412114724311620023477 0ustar fabiofabio/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- * * Copyright (C) 2010 Richard Hughes * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #ifndef _CC_NETWORK_PANEL_H #define _CC_NETWORK_PANEL_H #include G_BEGIN_DECLS #define CC_TYPE_NETWORK_PANEL cc_network_panel_get_type() #define CC_NETWORK_PANEL(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ CC_TYPE_NETWORK_PANEL, CcNetworkPanel)) #define CC_NETWORK_PANEL_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), \ CC_TYPE_NETWORK_PANEL, CcNetworkPanelClass)) #define CC_IS_NETWORK_PANEL(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ CC_TYPE_NETWORK_PANEL)) #define CC_IS_NETWORK_PANEL_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), \ CC_TYPE_NETWORK_PANEL)) #define CC_NETWORK_PANEL_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), \ CC_TYPE_NETWORK_PANEL, CcNetworkPanelClass)) typedef struct _CcNetworkPanel CcNetworkPanel; typedef struct _CcNetworkPanelClass CcNetworkPanelClass; typedef struct _CcNetworkPanelPrivate CcNetworkPanelPrivate; struct _CcNetworkPanel { CcPanel parent; CcNetworkPanelPrivate *priv; }; struct _CcNetworkPanelClass { CcPanelClass parent_class; }; GType cc_network_panel_get_type (void) G_GNUC_CONST; GPtrArray *cc_network_panel_get_devices (CcNetworkPanel *panel); void cc_network_panel_register (GIOModule *module); G_END_DECLS #endif /* _CC_NETWORK_PANEL_H */ cinnamon-control-center-6.4.1/panels/network/network.gresource.xml0000664000175000017500000000110214724311620024361 0ustar fabiofabio network.ui network-proxy.ui network-vpn.ui network-wifi.ui network-simple.ui network-mobile.ui network-ethernet.ui cinnamon-control-center-6.4.1/panels/network/net-vpn.c0000664000175000017500000005132514724311620021720 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2011-2012 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include "panel-common.h" #include "net-vpn.h" #include "connection-editor/net-connection-editor.h" #define NET_VPN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NET_TYPE_VPN, NetVpnPrivate)) struct _NetVpnPrivate { GtkBuilder *builder; NMConnection *connection; NMActiveConnection *active_connection; gchar *service_type; gboolean valid; gboolean updating_device; }; enum { PROP_0, PROP_CONNECTION, PROP_LAST }; G_DEFINE_TYPE (NetVpn, net_vpn, NET_TYPE_OBJECT) static void connection_vpn_state_changed_cb (NMVpnConnection *connection, NMVpnConnectionState state, #if NM_CHECK_VERSION(1,8,0) NMActiveConnectionStateReason reason, #else NMVpnConnectionStateReason reason, #endif NetVpn *vpn) { net_object_emit_changed (NET_OBJECT (vpn)); } static void connection_changed_cb (NMConnection *connection, NetVpn *vpn) { net_object_emit_changed (NET_OBJECT (vpn)); } static void connection_removed_cb (NMClient *client, NMConnection *connection, NetVpn *vpn) { NetVpnPrivate *priv = vpn->priv; if (priv->connection == connection) net_object_emit_removed (NET_OBJECT (vpn)); } static char * net_vpn_connection_to_type (NMConnection *connection) { const gchar *type, *p; type = nm_setting_vpn_get_service_type (nm_connection_get_setting_vpn (connection)); /* Go from "org.freedesktop.NetworkManager.vpnc" to "vpnc" for example */ p = strrchr (type, '.'); return g_strdup (p ? p + 1 : type); } static void net_vpn_set_connection (NetVpn *vpn, NMConnection *connection) { NetVpnPrivate *priv = vpn->priv; NMClient *client; /* * vpnc config example: * key=IKE DH Group, value=dh2 * key=xauth-password-type, value=ask * key=ipsec-secret-type, value=save * key=IPSec gateway, value=66.187.233.252 * key=NAT Traversal Mode, value=natt * key=IPSec ID, value=rh-vpn * key=Xauth username, value=rhughes */ priv->connection = g_object_ref (connection); client = net_object_get_client (NET_OBJECT (vpn)); g_signal_connect (client, NM_CLIENT_CONNECTION_REMOVED, G_CALLBACK (connection_removed_cb), vpn); g_signal_connect (connection, NM_CONNECTION_CHANGED, G_CALLBACK (connection_changed_cb), vpn); if (NM_IS_VPN_CONNECTION (priv->connection)) { g_signal_connect (priv->connection, NM_VPN_CONNECTION_VPN_STATE, G_CALLBACK (connection_vpn_state_changed_cb), vpn); } priv->service_type = net_vpn_connection_to_type (priv->connection); } static NMVpnConnectionState net_vpn_get_state (NetVpn *vpn) { NetVpnPrivate *priv = vpn->priv; if (!NM_IS_VPN_CONNECTION (priv->connection)) return NM_VPN_CONNECTION_STATE_DISCONNECTED; return nm_vpn_connection_get_vpn_state (NM_VPN_CONNECTION (priv->connection)); } /* VPN parameters can be found at: * http://git.gnome.org/browse/network-manager-openvpn/tree/src/nm-openvpn-service.h * http://git.gnome.org/browse/network-manager-vpnc/tree/src/nm-vpnc-service.h * http://git.gnome.org/browse/network-manager-pptp/tree/src/nm-pptp-service.h * http://git.gnome.org/browse/network-manager-openconnect/tree/src/nm-openconnect-service.h * http://git.gnome.org/browse/network-manager-openswan/tree/src/nm-openswan-service.h * See also 'properties' directory in these plugins. */ static const gchar * get_vpn_key_gateway (const char *vpn_type) { if (g_strcmp0 (vpn_type, "openvpn") == 0) return "remote"; if (g_strcmp0 (vpn_type, "vpnc") == 0) return "IPSec gateway"; if (g_strcmp0 (vpn_type, "pptp") == 0) return "gateway"; if (g_strcmp0 (vpn_type, "openconnect") == 0) return "gateway"; if (g_strcmp0 (vpn_type, "openswan") == 0) return "right"; return ""; } static const gchar * get_vpn_key_group (const char *vpn_type) { if (g_strcmp0 (vpn_type, "openvpn") == 0) return ""; if (g_strcmp0 (vpn_type, "vpnc") == 0) return "IPSec ID"; if (g_strcmp0 (vpn_type, "pptp") == 0) return ""; if (g_strcmp0 (vpn_type, "openconnect") == 0) return ""; if (g_strcmp0 (vpn_type, "openswan") == 0) return ""; return ""; } static const gchar * get_vpn_key_username (const char *vpn_type) { if (g_strcmp0 (vpn_type, "openvpn") == 0) return "username"; if (g_strcmp0 (vpn_type, "vpnc") == 0) return "Xauth username"; if (g_strcmp0 (vpn_type, "pptp") == 0) return "user"; if (g_strcmp0 (vpn_type, "openconnect") == 0) return "username"; if (g_strcmp0 (vpn_type, "openswan") == 0) return "leftxauthusername"; return ""; } static const gchar * get_vpn_key_group_password (const char *vpn_type) { if (g_strcmp0 (vpn_type, "openvpn") == 0) return ""; if (g_strcmp0 (vpn_type, "vpnc") == 0) return "Xauth password"; if (g_strcmp0 (vpn_type, "pptp") == 0) return ""; if (g_strcmp0 (vpn_type, "openconnect") == 0) return ""; if (g_strcmp0 (vpn_type, "openswan") == 0) return ""; return ""; } static const gchar * net_vpn_get_gateway (NetVpn *vpn) { NetVpnPrivate *priv = vpn->priv; const gchar *key; key = get_vpn_key_gateway (priv->service_type); return nm_setting_vpn_get_data_item (nm_connection_get_setting_vpn (priv->connection), key); } static const gchar * net_vpn_get_id (NetVpn *vpn) { NetVpnPrivate *priv = vpn->priv; const gchar *key; key = get_vpn_key_group (priv->service_type); return nm_setting_vpn_get_data_item (nm_connection_get_setting_vpn (priv->connection), key); } static const gchar * net_vpn_get_username (NetVpn *vpn) { NetVpnPrivate *priv = vpn->priv; const gchar *key; key = get_vpn_key_username (priv->service_type); return nm_setting_vpn_get_data_item (nm_connection_get_setting_vpn (priv->connection), key); } static const gchar * net_vpn_get_password (NetVpn *vpn) { NetVpnPrivate *priv = vpn->priv; const gchar *key; key = get_vpn_key_group_password (priv->service_type); return nm_setting_vpn_get_data_item (nm_connection_get_setting_vpn (priv->connection), key); } static void vpn_proxy_delete (NetObject *object) { NetVpn *vpn = NET_VPN (object); nm_remote_connection_delete_async (NM_REMOTE_CONNECTION (vpn->priv->connection), NULL, NULL, vpn); } static GtkWidget * vpn_proxy_add_to_notebook (NetObject *object, GtkNotebook *notebook, GtkSizeGroup *heading_size_group) { GtkWidget *widget; NetVpn *vpn = NET_VPN (object); /* add widgets to size group */ widget = GTK_WIDGET (gtk_builder_get_object (vpn->priv->builder, "heading_group_password")); gtk_size_group_add_widget (heading_size_group, widget); widget = GTK_WIDGET (gtk_builder_get_object (vpn->priv->builder, "vbox9")); gtk_notebook_append_page (notebook, widget, NULL); return widget; } static void nm_device_refresh_vpn_ui (NetVpn *vpn) { GtkWidget *widget; GtkWidget *sw; const gchar *status; NetVpnPrivate *priv = vpn->priv; const GPtrArray *acs; NMActiveConnection *a; gint i; NMVpnConnectionState state; gchar *title; NMClient *client; sw = GTK_WIDGET (gtk_builder_get_object (priv->builder, "device_off_switch")); gtk_widget_set_visible (sw, TRUE); /* update title */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_device")); /* Translators: this is the title of the connection details * window for vpn connections, it is also used to display * vpn connections in the device list. */ title = g_strdup_printf (_("%s VPN"), nm_connection_get_id (vpn->priv->connection)); net_object_set_title (NET_OBJECT (vpn), title); gtk_label_set_label (GTK_LABEL (widget), title); g_free (title); if (priv->active_connection) { g_signal_handlers_disconnect_by_func (vpn->priv->active_connection, nm_device_refresh_vpn_ui, vpn); g_clear_object (&priv->active_connection); } /* use status */ state = net_vpn_get_state (vpn); client = net_object_get_client (NET_OBJECT (vpn)); acs = nm_client_get_active_connections (client); if (acs != NULL) { const gchar *uuid; uuid = nm_connection_get_uuid (vpn->priv->connection); for (i = 0; i < acs->len; i++) { const gchar *auuid; a = (NMActiveConnection*)acs->pdata[i]; auuid = nm_active_connection_get_uuid (a); if (NM_IS_VPN_CONNECTION (a) && strcmp (auuid, uuid) == 0) { priv->active_connection = g_object_ref (a); g_signal_connect_swapped (a, "notify::vpn-state", G_CALLBACK (nm_device_refresh_vpn_ui), vpn); state = nm_vpn_connection_get_vpn_state (NM_VPN_CONNECTION (a)); break; } } } widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_status")); status = panel_vpn_state_to_localized_string (state); gtk_label_set_label (GTK_LABEL (widget), status); priv->updating_device = TRUE; gtk_switch_set_active (GTK_SWITCH (sw), state != NM_VPN_CONNECTION_STATE_FAILED && state != NM_VPN_CONNECTION_STATE_DISCONNECTED); priv->updating_device = FALSE; /* service type */ panel_set_device_widget_details (vpn->priv->builder, "service_type", vpn->priv->service_type); /* gateway */ panel_set_device_widget_details (vpn->priv->builder, "gateway", net_vpn_get_gateway (vpn)); /* groupname */ panel_set_device_widget_details (vpn->priv->builder, "group_name", net_vpn_get_id (vpn)); /* username */ panel_set_device_widget_details (vpn->priv->builder, "username", net_vpn_get_username (vpn)); /* password */ panel_set_device_widget_details (vpn->priv->builder, "group_password", net_vpn_get_password (vpn)); } static void nm_active_connections_changed (NetVpn *vpn) { nm_device_refresh_vpn_ui (vpn); } static void vpn_proxy_refresh (NetObject *object) { NetVpn *vpn = NET_VPN (object); nm_device_refresh_vpn_ui (vpn); } static void device_off_toggled (GtkSwitch *sw, GParamSpec *pspec, NetVpn *vpn) { const GPtrArray *acs; gboolean active; gint i; NMActiveConnection *a; NMClient *client; if (vpn->priv->updating_device) return; active = gtk_switch_get_active (sw); if (active) { client = net_object_get_client (NET_OBJECT (vpn)); nm_client_activate_connection_async (client, vpn->priv->connection, NULL, NULL, NULL, NULL, NULL); } else { const gchar *uuid; uuid = nm_connection_get_uuid (vpn->priv->connection); client = net_object_get_client (NET_OBJECT (vpn)); acs = nm_client_get_active_connections (client); for (i = 0; acs && i < acs->len; i++) { a = (NMActiveConnection*)acs->pdata[i]; if (strcmp (nm_active_connection_get_uuid (a), uuid) == 0) { nm_client_deactivate_connection (client, a, NULL, NULL); break; } } } } static void edit_connection (GtkButton *button, NetVpn *vpn) { net_object_edit (NET_OBJECT (vpn)); } static void editor_done (NetConnectionEditor *editor, gboolean success, NetVpn *vpn) { g_object_unref (editor); net_object_refresh (NET_OBJECT (vpn)); g_object_unref (vpn); } static void vpn_proxy_edit (NetObject *object) { NetVpn *vpn = NET_VPN (object); GtkWidget *button, *window; NetConnectionEditor *editor; NMClient *client; gchar *title; button = GTK_WIDGET (gtk_builder_get_object (vpn->priv->builder, "button_options")); window = gtk_widget_get_toplevel (button); client = net_object_get_client (object); editor = net_connection_editor_new (GTK_WINDOW (window), vpn->priv->connection, NULL, NULL, client); title = g_strdup_printf (_("%s VPN"), nm_connection_get_id (vpn->priv->connection)); net_connection_editor_set_title (editor, title); g_free (title); g_signal_connect (editor, "done", G_CALLBACK (editor_done), g_object_ref (vpn)); net_connection_editor_run (editor); } /** * net_vpn_get_property: **/ static void net_vpn_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NetVpn *vpn = NET_VPN (object); NetVpnPrivate *priv = vpn->priv; switch (prop_id) { case PROP_CONNECTION: g_value_set_object (value, priv->connection); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (vpn, prop_id, pspec); break; } } /** * net_vpn_set_property: **/ static void net_vpn_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NetVpn *vpn = NET_VPN (object); switch (prop_id) { case PROP_CONNECTION: net_vpn_set_connection (vpn, g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (vpn, prop_id, pspec); break; } } static void net_vpn_constructed (GObject *object) { NetVpn *vpn = NET_VPN (object); NMClient *client = net_object_get_client (NET_OBJECT (object)); G_OBJECT_CLASS (net_vpn_parent_class)->constructed (object); nm_device_refresh_vpn_ui (vpn); g_signal_connect_swapped (client, "notify::active-connections", G_CALLBACK (nm_active_connections_changed), vpn); } static void net_vpn_finalize (GObject *object) { NetVpn *vpn = NET_VPN (object); NetVpnPrivate *priv = vpn->priv; NMClient *client = net_object_get_client (NET_OBJECT (object)); if (client) { g_signal_handlers_disconnect_by_func (client, nm_active_connections_changed, vpn); } if (priv->active_connection) { g_signal_handlers_disconnect_by_func (priv->active_connection, nm_device_refresh_vpn_ui, vpn); g_object_unref (priv->active_connection); } g_signal_handlers_disconnect_by_func (priv->connection, connection_vpn_state_changed_cb, vpn); g_signal_handlers_disconnect_by_func (priv->connection, connection_removed_cb, vpn); g_signal_handlers_disconnect_by_func (priv->connection, connection_changed_cb, vpn); g_object_unref (priv->connection); g_free (priv->service_type); g_clear_object (&priv->builder); G_OBJECT_CLASS (net_vpn_parent_class)->finalize (object); } static void net_vpn_class_init (NetVpnClass *klass) { GParamSpec *pspec; GObjectClass *object_class = G_OBJECT_CLASS (klass); NetObjectClass *parent_class = NET_OBJECT_CLASS (klass); object_class->get_property = net_vpn_get_property; object_class->set_property = net_vpn_set_property; object_class->constructed = net_vpn_constructed; object_class->finalize = net_vpn_finalize; parent_class->add_to_notebook = vpn_proxy_add_to_notebook; parent_class->delete = vpn_proxy_delete; parent_class->refresh = vpn_proxy_refresh; parent_class->edit = vpn_proxy_edit; pspec = g_param_spec_object ("connection", NULL, NULL, NM_TYPE_CONNECTION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); g_object_class_install_property (object_class, PROP_CONNECTION, pspec); g_type_class_add_private (klass, sizeof (NetVpnPrivate)); } static void net_vpn_init (NetVpn *vpn) { GError *error = NULL; GtkWidget *widget; vpn->priv = NET_VPN_GET_PRIVATE (vpn); vpn->priv->builder = gtk_builder_new (); gtk_builder_add_from_resource (vpn->priv->builder, "/org/cinnamon/control-center/network/network-vpn.ui", &error); if (error != NULL) { g_warning ("Could not load interface file: %s", error->message); g_error_free (error); return; } widget = GTK_WIDGET (gtk_builder_get_object (vpn->priv->builder, "device_off_switch")); g_signal_connect (widget, "notify::active", G_CALLBACK (device_off_toggled), vpn); widget = GTK_WIDGET (gtk_builder_get_object (vpn->priv->builder, "button_options")); g_signal_connect (widget, "clicked", G_CALLBACK (edit_connection), vpn); } cinnamon-control-center-6.4.1/panels/network/net-device-mobile.c0000664000175000017500000011116414724311620023617 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2011-2012 Richard Hughes * Copyright (C) 2013 Aleksander Morgado * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include #include "panel-common.h" #include "network-dialogs.h" #include "net-device-mobile.h" #define NET_DEVICE_MOBILE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NET_TYPE_DEVICE_MOBILE, NetDeviceMobilePrivate)) static void nm_device_mobile_refresh_ui (NetDeviceMobile *device_mobile); struct _NetDeviceMobilePrivate { GtkBuilder *builder; gboolean updating_device; /* Old MM < 0.7 support */ GDBusProxy *gsm_proxy; GDBusProxy *cdma_proxy; /* New MM >= 0.7 support */ MMObject *mm_object; guint operator_name_updated; NMAMobileProvidersDatabase *mpd; }; enum { COLUMN_ID, COLUMN_TITLE, COLUMN_LAST }; enum { PROP_0, PROP_MODEM_OBJECT, PROP_LAST }; G_DEFINE_TYPE (NetDeviceMobile, net_device_mobile, NET_TYPE_DEVICE) static GtkWidget * device_mobile_proxy_add_to_notebook (NetObject *object, GtkNotebook *notebook, GtkSizeGroup *heading_size_group) { GtkWidget *widget; NetDeviceMobile *device_mobile = NET_DEVICE_MOBILE (object); /* add widgets to size group */ widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder, "heading_imei")); gtk_size_group_add_widget (heading_size_group, widget); widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder, "heading_network")); gtk_size_group_add_widget (heading_size_group, widget); widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder, "vbox7")); gtk_notebook_append_page (notebook, widget, NULL); return widget; } static void connection_activate_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; if (!nm_client_activate_connection_finish (NM_CLIENT (source_object), res, &error)) { /* failed to activate */ nm_device_mobile_refresh_ui (user_data); g_error_free (error); } } static void mobile_connection_changed_cb (GtkComboBox *combo_box, NetDeviceMobile *device_mobile) { gboolean ret; gchar *object_path = NULL; GtkTreeIter iter; GtkTreeModel *model; NMConnection *connection; NMDevice *device; NMClient *client; CcNetworkPanel *panel; GtkWidget *toplevel; if (device_mobile->priv->updating_device) goto out; ret = gtk_combo_box_get_active_iter (combo_box, &iter); if (!ret) goto out; device = net_device_get_nm_device (NET_DEVICE (device_mobile)); if (device == NULL) goto out; client = net_object_get_client (NET_OBJECT (device_mobile)); /* get entry */ model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); gtk_tree_model_get (model, &iter, COLUMN_ID, &object_path, -1); if (g_strcmp0 (object_path, NULL) == 0) { panel = net_object_get_panel (NET_OBJECT (device_mobile)); toplevel = cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (panel))); cc_network_panel_connect_to_3g_network (toplevel, client, device); goto out; } /* activate the connection */ g_debug ("try to switch to connection %s", object_path); connection = (NMConnection*) nm_client_get_connection_by_path (client, object_path); if (connection != NULL) { nm_device_disconnect (device, NULL, NULL); nm_client_activate_connection_async (client, connection, device, NULL, NULL, connection_activate_cb, device_mobile); goto out; } out: g_free (object_path); } static void mobilebb_enabled_toggled (NMClient *client, GParamSpec *pspec, NetDeviceMobile *device_mobile) { gboolean enabled = FALSE; GtkSwitch *sw; NMDevice *device; device = net_device_get_nm_device (NET_DEVICE (device_mobile)); if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_MODEM) return; if (nm_client_wwan_get_enabled (client)) { NMDeviceState state; state = nm_device_get_state (device); if (state == NM_DEVICE_STATE_UNKNOWN || state == NM_DEVICE_STATE_UNMANAGED || state == NM_DEVICE_STATE_UNAVAILABLE || state == NM_DEVICE_STATE_DISCONNECTED || state == NM_DEVICE_STATE_DEACTIVATING || state == NM_DEVICE_STATE_FAILED) { enabled = FALSE; } else { enabled = TRUE; } } sw = GTK_SWITCH (gtk_builder_get_object (device_mobile->priv->builder, "device_off_switch")); device_mobile->priv->updating_device = TRUE; gtk_switch_set_active (sw, enabled); device_mobile->priv->updating_device = FALSE; } static void device_add_device_connections (NetDeviceMobile *device_mobile, NMDevice *nm_device, GtkListStore *liststore, GtkComboBox *combobox) { NetDeviceMobilePrivate *priv = device_mobile->priv; GSList *list, *l; GtkTreeIter treeiter; NMActiveConnection *active_connection; NMConnection *connection; /* get the list of available connections for this device */ list = net_device_get_valid_connections (NET_DEVICE (device_mobile)); gtk_list_store_clear (liststore); active_connection = nm_device_get_active_connection (nm_device); for (l = list; l; l = g_slist_next (l)) { connection = NM_CONNECTION (l->data); gtk_list_store_append (liststore, &treeiter); gtk_list_store_set (liststore, &treeiter, COLUMN_ID, nm_connection_get_uuid (connection), COLUMN_TITLE, nm_connection_get_id (connection), -1); /* is this already activated? */ if (active_connection != NULL && g_strcmp0 (nm_connection_get_uuid (connection), nm_active_connection_get_uuid (active_connection)) == 0) { priv->updating_device = TRUE; gtk_combo_box_set_active_iter (combobox, &treeiter); priv->updating_device = FALSE; } } /* add new connection entry */ gtk_list_store_append (liststore, &treeiter); gtk_list_store_set (liststore, &treeiter, COLUMN_ID, NULL, COLUMN_TITLE, _("Add new connection"), -1); g_slist_free (list); } static void device_mobile_refresh_equipment_id (NetDeviceMobile *device_mobile) { const gchar *equipment_id = NULL; if (device_mobile->priv->mm_object != NULL) { MMModem *modem; /* Modem interface should always be present */ modem = mm_object_peek_modem (device_mobile->priv->mm_object); equipment_id = mm_modem_get_equipment_identifier (modem); /* Set equipment ID */ if (equipment_id != NULL) { g_debug ("[%s] Equipment ID set to '%s'", mm_object_get_path (device_mobile->priv->mm_object), equipment_id); } } else { /* Assume old MM handling */ equipment_id = g_object_get_data (G_OBJECT (device_mobile), "ControlCenter::EquipmentIdentifier"); } panel_set_device_widget_details (device_mobile->priv->builder, "imei", equipment_id); } static gchar * device_mobile_find_provider (NetDeviceMobile *device_mobile, const gchar *mccmnc, guint32 sid) { NMAMobileProvider *provider; GString *name = NULL; if (device_mobile->priv->mpd == NULL) { GError *error = NULL; /* Use defaults */ device_mobile->priv->mpd = nma_mobile_providers_database_new_sync (NULL, NULL, NULL, &error); if (device_mobile->priv->mpd == NULL) { g_debug ("Couldn't load mobile providers database: %s", error ? error->message : ""); g_clear_error (&error); return NULL; } } if (mccmnc != NULL) { provider = nma_mobile_providers_database_lookup_3gpp_mcc_mnc (device_mobile->priv->mpd, mccmnc); if (provider != NULL) name = g_string_new (nma_mobile_provider_get_name (provider)); } if (sid != 0) { provider = nma_mobile_providers_database_lookup_cdma_sid (device_mobile->priv->mpd, sid); if (provider != NULL) { if (name == NULL) name = g_string_new (nma_mobile_provider_get_name (provider)); else g_string_append_printf (name, ", %s", nma_mobile_provider_get_name (provider)); } } return (name != NULL ? g_string_free (name, FALSE) : NULL); } static void device_mobile_refresh_operator_name (NetDeviceMobile *device_mobile) { if (device_mobile->priv->mm_object != NULL) { gchar *operator_name = NULL; MMModem3gpp *modem_3gpp; MMModemCdma *modem_cdma; modem_3gpp = mm_object_peek_modem_3gpp (device_mobile->priv->mm_object); modem_cdma = mm_object_peek_modem_cdma (device_mobile->priv->mm_object); if (modem_3gpp != NULL) { const gchar *operator_name_unsafe; operator_name_unsafe = mm_modem_3gpp_get_operator_name (modem_3gpp); if (operator_name_unsafe != NULL && operator_name_unsafe[0] != '\0') operator_name = g_strescape (operator_name_unsafe, NULL); } /* If not directly given in the 3GPP interface, try to guess from * MCCMNC/SID */ if (operator_name == NULL) { const gchar *mccmnc = NULL; guint32 sid = 0; if (modem_3gpp != NULL) mccmnc = mm_modem_3gpp_get_operator_code (modem_3gpp); if (modem_cdma != NULL) sid = mm_modem_cdma_get_sid (modem_cdma); operator_name = device_mobile_find_provider (device_mobile, mccmnc, sid); } /* Set operator name */ if (operator_name != NULL) { g_debug ("[%s] Operator name set to '%s'", mm_object_get_path (device_mobile->priv->mm_object), operator_name); } panel_set_device_widget_details (device_mobile->priv->builder, "provider", operator_name); g_free (operator_name); } else { const gchar *gsm; const gchar *cdma; /* Assume old MM handling */ gsm = g_object_get_data (G_OBJECT (device_mobile), "ControlCenter::OperatorNameGsm"); cdma = g_object_get_data (G_OBJECT (device_mobile), "ControlCenter::OperatorNameCdma"); if (gsm != NULL && cdma != NULL) { gchar *both; both = g_strdup_printf ("%s, %s", gsm, cdma); panel_set_device_widget_details (device_mobile->priv->builder, "provider", both); g_free (both); } else if (gsm != NULL) { panel_set_device_widget_details (device_mobile->priv->builder, "provider", gsm); } else if (cdma != NULL) { panel_set_device_widget_details (device_mobile->priv->builder, "provider", cdma); } else { panel_set_device_widget_details (device_mobile->priv->builder, "provider", NULL); } } } static void nm_device_mobile_refresh_ui (NetDeviceMobile *device_mobile) { gboolean is_connected; GtkListStore *liststore; GtkWidget *widget; NetDeviceMobilePrivate *priv = device_mobile->priv; NMClient *client; NMDeviceModemCapabilities caps; NMDevice *nm_device; nm_device = net_device_get_nm_device (NET_DEVICE (device_mobile)); /* set device kind */ widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder, "label_device")); g_object_bind_property (device_mobile, "title", widget, "label", 0); /* set up the device on/off switch */ widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder, "device_off_switch")); gtk_widget_show (widget); client = net_object_get_client (NET_OBJECT (device_mobile)); mobilebb_enabled_toggled (client, NULL, device_mobile); /* set device state, with status */ panel_set_device_status (device_mobile->priv->builder, "label_status", nm_device, NULL); /* sensitive for other connection types if the device is currently connected */ widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder, "button_options")); is_connected = net_device_get_find_connection (NET_DEVICE (device_mobile)) != NULL; gtk_widget_set_sensitive (widget, is_connected); caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (nm_device)); if ((caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) || (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) || (caps & NM_DEVICE_MODEM_CAPABILITY_LTE)) { device_mobile_refresh_operator_name (device_mobile); device_mobile_refresh_equipment_id (device_mobile); } /* add possible connections to device */ liststore = GTK_LIST_STORE (gtk_builder_get_object (priv->builder, "liststore_mobile_connections")); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "combobox_network")); device_add_device_connections (device_mobile, nm_device, liststore, GTK_COMBO_BOX (widget)); /* set IP entries */ panel_set_device_widgets (priv->builder, nm_device); } static void device_mobile_refresh (NetObject *object) { NetDeviceMobile *device_mobile = NET_DEVICE_MOBILE (object); nm_device_mobile_refresh_ui (device_mobile); } static void device_off_toggled (GtkSwitch *sw, GParamSpec *pspec, NetDeviceMobile *device_mobile) { const GPtrArray *acs; gboolean active; gint i; NMActiveConnection *a; NMConnection *connection; NMClient *client; if (device_mobile->priv->updating_device) return; active = gtk_switch_get_active (sw); if (active) { client = net_object_get_client (NET_OBJECT (device_mobile)); connection = net_device_get_find_connection (NET_DEVICE (device_mobile)); if (connection == NULL) return; nm_client_activate_connection_async (client, connection, net_device_get_nm_device (NET_DEVICE (device_mobile)), NULL, NULL, NULL, NULL); } else { const gchar *uuid; connection = net_device_get_find_connection (NET_DEVICE (device_mobile)); if (connection == NULL) return; uuid = nm_connection_get_uuid (connection); client = net_object_get_client (NET_OBJECT (device_mobile)); acs = nm_client_get_active_connections (client); for (i = 0; acs && i < acs->len; i++) { a = (NMActiveConnection*)acs->pdata[i]; if (strcmp (nm_active_connection_get_uuid (a), uuid) == 0) { nm_client_deactivate_connection (client, a, NULL, NULL); break; } } } } static void edit_connection (GtkButton *button, NetDeviceMobile *device_mobile) { net_object_edit (NET_OBJECT (device_mobile)); } static void device_mobile_device_got_modem_manager_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; GVariant *result = NULL; GDBusProxy *proxy; NetDeviceMobile *device_mobile = (NetDeviceMobile *)user_data; proxy = g_dbus_proxy_new_for_bus_finish (res, &error); if (!proxy) { g_warning ("Error creating ModemManager proxy: %s", error->message); g_error_free (error); return; } /* get the IMEI */ result = g_dbus_proxy_get_cached_property (proxy, "EquipmentIdentifier"); /* save */ if (result) { g_object_set_data_full (G_OBJECT (device_mobile), "ControlCenter::EquipmentIdentifier", g_variant_dup_string (result, NULL), g_free); g_variant_unref (result); } device_mobile_refresh_equipment_id (device_mobile); g_object_unref (proxy); } static void device_mobile_save_operator_name (NetDeviceMobile *device_mobile, const gchar *field, const gchar *operator_name) { gchar *operator_name_safe = NULL; if (operator_name != NULL && operator_name[0] != '\0') operator_name_safe = g_strescape (operator_name, NULL); /* save */ g_object_set_data_full (G_OBJECT (device_mobile), field, operator_name_safe, g_free); /* refresh */ device_mobile_refresh_operator_name (device_mobile); } static void device_mobile_get_registration_info_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { gchar *operator_code = NULL; GError *error = NULL; guint registration_status; GVariant *result = NULL; gchar *operator_name = NULL; NetDeviceMobile *device_mobile = (NetDeviceMobile *)user_data; result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (result == NULL) { g_warning ("Error getting registration info: %s\n", error->message); g_error_free (error); return; } /* get values */ g_variant_get (result, "((uss))", ®istration_status, &operator_code, &operator_name); /* If none give, try to guess it */ if (operator_name == NULL || operator_name[0] == '\0') { g_free (operator_name); operator_name = device_mobile_find_provider (device_mobile, operator_code, 0); } /* save and refresh */ device_mobile_save_operator_name (device_mobile, "ControlCenter::OperatorNameGsm", operator_name); g_free (operator_name); g_free (operator_code); g_variant_unref (result); } static void device_mobile_gsm_signal_cb (GDBusProxy *proxy, gchar *sender_name, gchar *signal_name, GVariant *parameters, gpointer user_data) { guint registration_status = 0; gchar *operator_code = NULL; gchar *operator_name = NULL; NetDeviceMobile *device_mobile = (NetDeviceMobile *)user_data; if (!g_str_equal (signal_name, "RegistrationInfo")) return; g_variant_get (parameters, "(uss)", ®istration_status, &operator_code, &operator_name); /* If none given, try to guess it */ if (operator_name == NULL || operator_name[0] == '\0') { g_free (operator_name); operator_name = device_mobile_find_provider (device_mobile, operator_code, 0); } /* save and refresh */ device_mobile_save_operator_name (device_mobile, "ControlCenter::OperatorNameGsm", operator_name); g_free (operator_code); g_free (operator_name); } static void device_mobile_device_got_modem_manager_gsm_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; NetDeviceMobile *device_mobile = (NetDeviceMobile *)user_data; device_mobile->priv->gsm_proxy = g_dbus_proxy_new_for_bus_finish (res, &error); if (device_mobile->priv->gsm_proxy == NULL) { g_warning ("Error creating ModemManager GSM proxy: %s\n", error->message); g_error_free (error); return; } /* Setup value updates */ g_signal_connect (device_mobile->priv->gsm_proxy, "g-signal", G_CALLBACK (device_mobile_gsm_signal_cb), device_mobile); /* Load initial value */ g_dbus_proxy_call (device_mobile->priv->gsm_proxy, "GetRegistrationInfo", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, device_mobile_get_registration_info_cb, device_mobile); } static void device_mobile_get_serving_system_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { NetDeviceMobile *device_mobile = (NetDeviceMobile *)user_data; GVariant *result = NULL; GError *error = NULL; guint32 band_class; gchar *band; guint32 sid; gchar *operator_name; result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (result == NULL) { g_warning ("Error getting serving system: %s\n", error->message); g_error_free (error); return; } /* get values */ g_variant_get (result, "((usu))", &band_class, &band, &sid); operator_name = device_mobile_find_provider (device_mobile, NULL, sid); /* save and refresh */ device_mobile_save_operator_name (device_mobile, "ControlCenter::OperatorNameCdma", operator_name); g_free (band); g_variant_unref (result); } static void device_mobile_device_got_modem_manager_cdma_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; NetDeviceMobile *device_mobile = (NetDeviceMobile *)user_data; device_mobile->priv->cdma_proxy = g_dbus_proxy_new_for_bus_finish (res, &error); if (device_mobile->priv->cdma_proxy == NULL) { g_warning ("Error creating ModemManager CDMA proxy: %s\n", error->message); g_error_free (error); return; } /* Load initial value */ g_dbus_proxy_call (device_mobile->priv->cdma_proxy, "GetServingSystem", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, device_mobile_get_serving_system_cb, device_mobile); } static void net_device_mobile_constructed (GObject *object) { GCancellable *cancellable; NetDeviceMobile *device_mobile = NET_DEVICE_MOBILE (object); NMClient *client; NMDevice *device; NMDeviceModemCapabilities caps; G_OBJECT_CLASS (net_device_mobile_parent_class)->constructed (object); device = net_device_get_nm_device (NET_DEVICE (device_mobile)); cancellable = net_object_get_cancellable (NET_OBJECT (device_mobile)); caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device)); /* Only load proxies if we have broadband modems of the OLD ModemManager interface */ if (g_str_has_prefix (nm_device_get_udi (device), "/org/freedesktop/ModemManager/") && ((caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) || (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) || (caps & NM_DEVICE_MODEM_CAPABILITY_LTE))) { g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.freedesktop.ModemManager", nm_device_get_udi (device), "org.freedesktop.ModemManager.Modem", cancellable, device_mobile_device_got_modem_manager_cb, device_mobile); if ((caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) || (caps & NM_DEVICE_MODEM_CAPABILITY_LTE)) { g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.freedesktop.ModemManager", nm_device_get_udi (device), "org.freedesktop.ModemManager.Modem.Gsm.Network", cancellable, device_mobile_device_got_modem_manager_gsm_cb, device_mobile); } if (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) { g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.freedesktop.ModemManager", nm_device_get_udi (device), "org.freedesktop.ModemManager.Modem.Cdma", cancellable, device_mobile_device_got_modem_manager_cdma_cb, device_mobile); } } client = net_object_get_client (NET_OBJECT (device_mobile)); g_signal_connect_object (client, "notify::wwan-enabled", G_CALLBACK (mobilebb_enabled_toggled), device_mobile, 0); nm_device_mobile_refresh_ui (device_mobile); } static void operator_name_updated (MMModem3gpp *modem_3gpp_iface, GParamSpec *pspec, NetDeviceMobile *self) { device_mobile_refresh_operator_name (self); } static void net_device_mobile_setup_modem_object (NetDeviceMobile *self) { MMModem3gpp *modem_3gpp; if (self->priv->mm_object == NULL) return; /* Load equipment ID initially */ device_mobile_refresh_equipment_id (self); /* Follow changes in operator name and load initial values */ modem_3gpp = mm_object_peek_modem_3gpp (self->priv->mm_object); if (modem_3gpp != NULL) { g_assert (self->priv->operator_name_updated == 0); self->priv->operator_name_updated = g_signal_connect (modem_3gpp, "notify::operator-name", G_CALLBACK (operator_name_updated), self); device_mobile_refresh_operator_name (self); } } static void net_device_mobile_get_property (GObject *device_, guint prop_id, GValue *value, GParamSpec *pspec) { NetDeviceMobile *self = NET_DEVICE_MOBILE (device_); switch (prop_id) { case PROP_MODEM_OBJECT: g_value_set_object (value, self->priv->mm_object); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec); break; } } static void net_device_mobile_set_property (GObject *device_, guint prop_id, const GValue *value, GParamSpec *pspec) { NetDeviceMobile *self = NET_DEVICE_MOBILE (device_); switch (prop_id) { case PROP_MODEM_OBJECT: self->priv->mm_object = g_value_dup_object (value); net_device_mobile_setup_modem_object (self); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec); break; } } static void net_device_mobile_dispose (GObject *object) { NetDeviceMobile *device_mobile = NET_DEVICE_MOBILE (object); NetDeviceMobilePrivate *priv = device_mobile->priv; g_clear_object (&priv->builder); g_clear_object (&priv->gsm_proxy); g_clear_object (&priv->cdma_proxy); if (priv->operator_name_updated) { g_assert (priv->mm_object != NULL); g_signal_handler_disconnect (mm_object_peek_modem_3gpp (priv->mm_object), priv->operator_name_updated); priv->operator_name_updated = 0; } g_clear_object (&priv->mm_object); g_clear_object (&priv->mpd); G_OBJECT_CLASS (net_device_mobile_parent_class)->dispose (object); } static void net_device_mobile_class_init (NetDeviceMobileClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); NetObjectClass *parent_class = NET_OBJECT_CLASS (klass); object_class->dispose = net_device_mobile_dispose; object_class->constructed = net_device_mobile_constructed; object_class->get_property = net_device_mobile_get_property; object_class->set_property = net_device_mobile_set_property; parent_class->add_to_notebook = device_mobile_proxy_add_to_notebook; parent_class->refresh = device_mobile_refresh; g_type_class_add_private (klass, sizeof (NetDeviceMobilePrivate)); g_object_class_install_property (object_class, PROP_MODEM_OBJECT, g_param_spec_object ("mm-object", NULL, NULL, MM_TYPE_OBJECT, G_PARAM_READWRITE)); } static void net_device_mobile_init (NetDeviceMobile *device_mobile) { GError *error = NULL; GtkWidget *widget; GtkCellRenderer *renderer; GtkComboBox *combobox; device_mobile->priv = NET_DEVICE_MOBILE_GET_PRIVATE (device_mobile); device_mobile->priv->builder = gtk_builder_new (); gtk_builder_add_from_resource (device_mobile->priv->builder, "/org/cinnamon/control-center/network/network-mobile.ui", &error); if (error != NULL) { g_warning ("Could not load interface file: %s", error->message); g_error_free (error); return; } /* setup mobile combobox model */ combobox = GTK_COMBO_BOX (gtk_builder_get_object (device_mobile->priv->builder, "combobox_network")); g_signal_connect (combobox, "changed", G_CALLBACK (mobile_connection_changed_cb), device_mobile); renderer = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox), renderer, FALSE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer, "text", COLUMN_TITLE, NULL); widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder, "device_off_switch")); g_signal_connect (widget, "notify::active", G_CALLBACK (device_off_toggled), device_mobile); widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder, "button_options")); g_signal_connect (widget, "clicked", G_CALLBACK (edit_connection), device_mobile); } cinnamon-control-center-6.4.1/panels/network/net-device-mobile.h0000664000175000017500000000430014724311620023615 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2011-2012 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __NET_DEVICE_MOBILE_H #define __NET_DEVICE_MOBILE_H #include #include #include "net-device.h" G_BEGIN_DECLS #define NET_TYPE_DEVICE_MOBILE (net_device_mobile_get_type ()) #define NET_DEVICE_MOBILE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NET_TYPE_DEVICE_MOBILE, NetDeviceMobile)) #define NET_DEVICE_MOBILE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NET_TYPE_DEVICE_MOBILE, NetDeviceMobileClass)) #define NET_IS_DEVICE_MOBILE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NET_TYPE_DEVICE_MOBILE)) #define NET_IS_DEVICE_MOBILE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NET_TYPE_DEVICE_MOBILE)) #define NET_DEVICE_MOBILE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NET_TYPE_DEVICE_MOBILE, NetDeviceMobileClass)) typedef struct _NetDeviceMobilePrivate NetDeviceMobilePrivate; typedef struct _NetDeviceMobile NetDeviceMobile; typedef struct _NetDeviceMobileClass NetDeviceMobileClass; struct _NetDeviceMobile { NetDevice parent; NetDeviceMobilePrivate *priv; }; struct _NetDeviceMobileClass { NetDeviceClass parent_class; }; GType net_device_mobile_get_type (void); G_END_DECLS #endif /* __NET_DEVICE_MOBILE_H */ cinnamon-control-center-6.4.1/panels/network/network-simple.ui0000664000175000017500000004312314724311620023501 0ustar fabiofabio True False 12 6 True False start vertical 10 6 True False end start 1 48 network-wired 6 0 0 1 1 True False start True 3 True False 0 Wired end False False 0 True False 0 Cable unplugged False False 1 1 0 1 1 True False 20 vertical 10 6 True True False 1 Hardware Address label_mac 0 0 1 1 True False 1 IPv4 Address label_ipv4 0 1 1 1 True False 1 0 IPv6 Address label_ipv6 0 2 1 1 True False 1 Default Route label_route 0 3 1 1 True False 1 0 DNS4 label_dns4 0 4 1 1 True False 1 0 DNS6 label_dns6 0 5 1 1 True True 0 AA:BB:CC:DD:55:66:77:88 True 1 0 1 1 True True 0 127.0.0.1 True 1 1 1 1 True True 0 ::1 True 1 2 1 1 True True 0 127.0.0.1 True 1 3 1 1 True True 0 0 127.0.0.1 True True 1 4 1 1 True True 0 0 ::1 True True 1 5 1 1 0 1 3 1 True True end center Turn device off 2 0 1 1 True True 0 True False 12 vertical True True True end end True True True True False emblem-system-symbolic 1 Options… False True 0 True True 1 cinnamon-control-center-6.4.1/panels/network/network-dialogs.c0000664000175000017500000004255014724311620023442 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2011 Giovanni Campagna * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Portions of this code were taken from network-manager-applet. * Copyright 2008 - 2011 Red Hat, Inc. */ #include #include #include #include #include "network-dialogs.h" typedef struct { NMClient *client; } WirelessDialogClosure; typedef struct { NMClient *client; NMDevice *device; } MobileDialogClosure; static void wireless_dialog_closure_closure_notify (gpointer data, GClosure *gclosure) { WirelessDialogClosure *closure = data; g_object_unref (closure->client); g_slice_free (WirelessDialogClosure, data); } static void mobile_dialog_closure_free (gpointer data) { MobileDialogClosure *closure = data; g_object_unref (closure->client); g_object_unref (closure->device); g_slice_free (MobileDialogClosure, data); } static gboolean wifi_can_create_wifi_network (NMClient *client) { NMClientPermissionResult perm; /* FIXME: check WIFI_SHARE_PROTECTED too, and make the wireless dialog * handle the permissions as well so that admins can restrict open network * creation separately from protected network creation. */ perm = nm_client_get_permission_result (client, NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN); if (perm == NM_CLIENT_PERMISSION_RESULT_YES || perm == NM_CLIENT_PERMISSION_RESULT_AUTH) return TRUE; return FALSE; } static void activate_existing_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; if (!nm_client_activate_connection_finish (NM_CLIENT (source_object), res, &error)) { g_warning ("Failed to activate connection: (%d) %s", error->code, error->message); g_error_free (error); } } static void activate_new_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; if (!nm_client_add_and_activate_connection_finish (NM_CLIENT (source_object), res, &error)) { g_warning ("Failed to add new connection: (%d) %s", error->code, error->message); g_error_free (error); } } static void wireless_dialog_response_cb (GtkDialog *foo, gint response, gpointer user_data) { NMAWifiDialog *dialog = NMA_WIFI_DIALOG (foo); WirelessDialogClosure *closure = user_data; NMConnection *connection, *fuzzy_match = NULL; NMDevice *device; NMAccessPoint *ap; const GPtrArray *all; guint i; if (response != GTK_RESPONSE_OK) goto done; /* nma_wifi_dialog_get_connection() returns a connection with the * refcount incremented, so the caller must remember to unref it. */ connection = nma_wifi_dialog_get_connection (dialog, &device, &ap); g_assert (connection); g_assert (device); /* Find a similar connection and use that instead */ all = nm_client_get_connections (closure->client); for (i = 0; i < all->len; i++) { if (nm_connection_compare (connection, NM_CONNECTION (g_ptr_array_index (all, i)), (NM_SETTING_COMPARE_FLAG_FUZZY | NM_SETTING_COMPARE_FLAG_IGNORE_ID))) { fuzzy_match = NM_CONNECTION (g_ptr_array_index (all, i)); break; } } if (fuzzy_match) { nm_client_activate_connection_async (closure->client, fuzzy_match, device, ap ? nm_object_get_path (NM_OBJECT (ap)) : NULL, NULL, activate_existing_cb, NULL); } else { NMSetting *s_con; NMSettingWireless *s_wifi; const char *mode = NULL; /* Entirely new connection */ /* Don't autoconnect adhoc networks by default for now */ s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); if (s_wifi) mode = nm_setting_wireless_get_mode (s_wifi); if (g_strcmp0 (mode, "adhoc") == 0) { s_con = nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); if (!s_con) { s_con = nm_setting_connection_new (); nm_connection_add_setting (connection, s_con); } g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, NULL); } nm_client_add_and_activate_connection_async (closure->client, connection, device, ap ? nm_object_get_path (NM_OBJECT (ap)) : NULL, NULL, activate_new_cb, NULL); } /* Balance nma_wifi_dialog_get_connection() */ g_object_unref (connection); done: gtk_widget_hide (GTK_WIDGET (dialog)); gtk_widget_destroy (GTK_WIDGET (dialog)); } static void show_wireless_dialog (GtkWidget *toplevel, NMClient *client, GtkWidget *dialog) { WirelessDialogClosure *closure; g_debug ("About to parent and show a network dialog"); //g_assert (gtk_widget_is_toplevel (toplevel)); g_object_set (G_OBJECT (dialog), "modal", TRUE, "transient-for", toplevel, NULL); closure = g_slice_new (WirelessDialogClosure); closure->client = g_object_ref (client); g_signal_connect_data (dialog, "response", G_CALLBACK (wireless_dialog_response_cb), closure, wireless_dialog_closure_closure_notify, 0); g_object_bind_property (G_OBJECT (toplevel), "visible", G_OBJECT (dialog), "visible", G_BINDING_SYNC_CREATE); } void cc_network_panel_create_wifi_network (GtkWidget *toplevel, NMClient *client) { if (wifi_can_create_wifi_network (client)) { show_wireless_dialog (toplevel, client, nma_wifi_dialog_new_for_create (client)); } } void cc_network_panel_connect_to_hidden_network (GtkWidget *toplevel, NMClient *client) { g_debug ("connect to hidden wifi"); show_wireless_dialog (toplevel, client, nma_wifi_dialog_new_for_hidden (client)); } void cc_network_panel_connect_to_8021x_network (GtkWidget *toplevel, NMClient *client, NMDevice *device, const gchar *arg_access_point) { NMConnection *connection; NMSettingConnection *s_con; NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; NMSetting8021x *s_8021x; NM80211ApSecurityFlags wpa_flags, rsn_flags; GtkWidget *dialog; char *uuid; NMAccessPoint *ap; g_debug ("connect to 8021x wifi"); ap = nm_device_wifi_get_access_point_by_path (NM_DEVICE_WIFI (device), arg_access_point); if (ap == NULL) { g_warning ("didn't find access point with path %s", arg_access_point); return; } /* If the AP is WPA[2]-Enterprise then we need to set up a minimal 802.1x * setting and ask the user for more information. */ rsn_flags = nm_access_point_get_rsn_flags (ap); wpa_flags = nm_access_point_get_wpa_flags (ap); if (!(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) && !(wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) { g_warning ("Network panel loaded with connect-8021x-wifi but the " "access point does not support 802.1x"); return; } connection = nm_simple_connection_new (); /* Need a UUID for the "always ask" stuff in the Dialog of Doom */ s_con = (NMSettingConnection *) nm_setting_connection_new (); uuid = nm_utils_uuid_generate (); g_object_set (s_con, NM_SETTING_CONNECTION_UUID, uuid, NULL); g_free (uuid); nm_connection_add_setting (connection, NM_SETTING (s_con)); s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, nm_access_point_get_ssid (ap), NULL); s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", NULL); nm_connection_add_setting (connection, NM_SETTING (s_wsec)); s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); nm_setting_802_1x_add_eap_method (s_8021x, "ttls"); g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", NULL); nm_connection_add_setting (connection, NM_SETTING (s_8021x)); dialog = nma_wifi_dialog_new (client, connection, device, ap, FALSE); show_wireless_dialog (toplevel, client, dialog); } static void connect_3g (NMConnection *connection, gboolean canceled, gpointer user_data) { MobileDialogClosure *closure = user_data; if (canceled == FALSE) { g_return_if_fail (connection != NULL); /* Ask NM to add the new connection and activate it; NM will fill in the * missing details based on the specific object and the device. */ nm_client_add_and_activate_connection_async (closure->client, connection, closure->device, "/", NULL, activate_new_cb, NULL); } mobile_dialog_closure_free (closure); } static void cdma_mobile_wizard_done (NMAMobileWizard *wizard, gboolean canceled, NMAMobileWizardAccessMethod *method, gpointer user_data) { NMConnection *connection = NULL; if (!canceled && method) { NMSetting *setting; char *uuid, *id; if (method->devtype != NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) { g_warning ("Unexpected device type (not CDMA)."); canceled = TRUE; goto done; } connection = nm_simple_connection_new (); setting = nm_setting_cdma_new (); g_object_set (setting, NM_SETTING_CDMA_NUMBER, "#777", NM_SETTING_CDMA_USERNAME, method->username, NM_SETTING_CDMA_PASSWORD, method->password, NULL); nm_connection_add_setting (connection, setting); /* Default to IPv4 & IPv6 'automatic' addressing */ setting = nm_setting_ip4_config_new (); g_object_set (setting, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); nm_connection_add_setting (connection, setting); setting = nm_setting_ip6_config_new (); g_object_set (setting, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); nm_connection_add_setting (connection, setting); nm_connection_add_setting (connection, nm_setting_ppp_new ()); setting = nm_setting_connection_new (); if (method->plan_name) id = g_strdup_printf ("%s %s", method->provider_name, method->plan_name); else id = g_strdup_printf ("%s connection", method->provider_name); uuid = nm_utils_uuid_generate (); g_object_set (setting, NM_SETTING_CONNECTION_ID, id, NM_SETTING_CONNECTION_TYPE, NM_SETTING_CDMA_SETTING_NAME, NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, NM_SETTING_CONNECTION_UUID, uuid, NULL); g_free (uuid); g_free (id); nm_connection_add_setting (connection, setting); } done: connect_3g (connection, canceled, user_data); nma_mobile_wizard_destroy (wizard); } static void gsm_mobile_wizard_done (NMAMobileWizard *wizard, gboolean canceled, NMAMobileWizardAccessMethod *method, gpointer user_data) { NMConnection *connection = NULL; if (!canceled && method) { NMSetting *setting; char *uuid, *id; if (method->devtype != NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) { g_warning ("Unexpected device type (not GSM)."); canceled = TRUE; goto done; } connection = nm_simple_connection_new (); setting = nm_setting_gsm_new (); g_object_set (setting, NM_SETTING_GSM_NUMBER, "*99#", NM_SETTING_GSM_USERNAME, method->username, NM_SETTING_GSM_PASSWORD, method->password, NM_SETTING_GSM_APN, method->gsm_apn, NULL); nm_connection_add_setting (connection, setting); /* Default to IPv4 & IPv6 'automatic' addressing */ setting = nm_setting_ip4_config_new (); g_object_set (setting, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); nm_connection_add_setting (connection, setting); setting = nm_setting_ip6_config_new (); g_object_set (setting, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); nm_connection_add_setting (connection, setting); nm_connection_add_setting (connection, nm_setting_ppp_new ()); setting = nm_setting_connection_new (); if (method->plan_name) id = g_strdup_printf ("%s %s", method->provider_name, method->plan_name); else id = g_strdup_printf ("%s connection", method->provider_name); uuid = nm_utils_uuid_generate (); g_object_set (setting, NM_SETTING_CONNECTION_ID, id, NM_SETTING_CONNECTION_TYPE, NM_SETTING_GSM_SETTING_NAME, NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, NM_SETTING_CONNECTION_UUID, uuid, NULL); g_free (uuid); g_free (id); nm_connection_add_setting (connection, setting); } done: connect_3g (connection, canceled, user_data); nma_mobile_wizard_destroy (wizard); } static void toplevel_shown (GtkWindow *toplevel, GParamSpec *pspec, NMAMobileWizard *wizard) { gboolean visible = FALSE; g_object_get (G_OBJECT (toplevel), "visible", &visible, NULL); if (visible) nma_mobile_wizard_present (wizard); } static gboolean show_wizard_idle_cb (NMAMobileWizard *wizard) { nma_mobile_wizard_present (wizard); return FALSE; } void cc_network_panel_connect_to_3g_network (GtkWidget *toplevel, NMClient *client, NMDevice *device) { MobileDialogClosure *closure; NMAMobileWizard *wizard; NMDeviceModemCapabilities caps; gboolean visible = FALSE; g_debug ("connect to 3g"); if (!NM_IS_DEVICE_MODEM (device)) { g_warning ("Network panel loaded with connect-3g but the selected device" " is not a modem"); return; } closure = g_slice_new (MobileDialogClosure); closure->client = g_object_ref (client); closure->device = g_object_ref (device); g_type_ensure (NMA_TYPE_COUNTRY_INFO); g_type_ensure (NMA_TYPE_MOBILE_ACCESS_METHOD); g_type_ensure (NMA_TYPE_MOBILE_PROVIDER); caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device)); if (caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) { wizard = nma_mobile_wizard_new (GTK_WINDOW (toplevel), NULL, NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS, FALSE, gsm_mobile_wizard_done, closure); if (wizard == NULL) { g_warning ("failed to construct GSM wizard"); return; } } else if (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) { wizard = nma_mobile_wizard_new (GTK_WINDOW (toplevel), NULL, NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO, FALSE, cdma_mobile_wizard_done, closure); if (wizard == NULL) { g_warning ("failed to construct CDMA wizard"); return; } } else { g_warning ("Network panel loaded with connect-3g but the selected device" " does not support GSM or CDMA"); mobile_dialog_closure_free (closure); return; } g_object_get (G_OBJECT (toplevel), "visible", &visible, NULL); if (visible) { g_debug ("Scheduling showing the Mobile wizard"); g_idle_add ((GSourceFunc) show_wizard_idle_cb, wizard); } else { g_debug ("Will show wizard a bit later, toplevel is not visible"); g_signal_connect (G_OBJECT (toplevel), "notify::visible", G_CALLBACK (toplevel_shown), wizard); } } cinnamon-control-center-6.4.1/panels/network/net-device-simple.c0000664000175000017500000002570514724311620023646 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2011-2012 Richard Hughes * Copyright (C) 2012 Red Hat, Inc. * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include "panel-common.h" #include "net-device-simple.h" #define NET_DEVICE_SIMPLE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NET_TYPE_DEVICE_SIMPLE, NetDeviceSimplePrivate)) struct _NetDeviceSimplePrivate { GtkBuilder *builder; gboolean updating_device; }; G_DEFINE_TYPE (NetDeviceSimple, net_device_simple, NET_TYPE_DEVICE) static GtkWidget * device_simple_proxy_add_to_notebook (NetObject *object, GtkNotebook *notebook, GtkSizeGroup *heading_size_group) { GtkWidget *widget; NetDeviceSimple *device_simple = NET_DEVICE_SIMPLE (object); /* add widgets to size group */ widget = GTK_WIDGET (gtk_builder_get_object (device_simple->priv->builder, "heading_ipv4")); gtk_size_group_add_widget (heading_size_group, widget); widget = GTK_WIDGET (gtk_builder_get_object (device_simple->priv->builder, "vbox6")); gtk_notebook_append_page (notebook, widget, NULL); return widget; } static void update_off_switch_from_device_state (GtkSwitch *sw, NMDeviceState state, NetDeviceSimple *device_simple) { device_simple->priv->updating_device = TRUE; switch (state) { case NM_DEVICE_STATE_UNMANAGED: case NM_DEVICE_STATE_UNAVAILABLE: case NM_DEVICE_STATE_DISCONNECTED: case NM_DEVICE_STATE_DEACTIVATING: case NM_DEVICE_STATE_FAILED: gtk_switch_set_active (sw, FALSE); break; default: gtk_switch_set_active (sw, TRUE); break; } device_simple->priv->updating_device = FALSE; } static void nm_device_simple_refresh_ui (NetDeviceSimple *device_simple) { NetDeviceSimplePrivate *priv = device_simple->priv; const char *hwaddr; GtkWidget *widget; char *speed = NULL; NMDevice *nm_device; NMDeviceState state; nm_device = net_device_get_nm_device (NET_DEVICE (device_simple)); /* set device kind */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_device")); g_object_bind_property (device_simple, "title", widget, "label", 0); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "image_device")); gtk_image_set_from_icon_name (GTK_IMAGE (widget), panel_device_to_icon_name (nm_device, FALSE), GTK_ICON_SIZE_DIALOG); /* set up the device on/off switch */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "device_off_switch")); state = nm_device_get_state (nm_device); gtk_widget_set_visible (widget, state != NM_DEVICE_STATE_UNAVAILABLE && state != NM_DEVICE_STATE_UNMANAGED); update_off_switch_from_device_state (GTK_SWITCH (widget), state, device_simple); /* set up the Options button */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_options")); gtk_widget_set_visible (widget, state != NM_DEVICE_STATE_UNMANAGED); /* set device state, with status and optionally speed */ if (state != NM_DEVICE_STATE_UNAVAILABLE) speed = net_device_simple_get_speed (device_simple); panel_set_device_status (priv->builder, "label_status", nm_device, speed); /* device MAC */ hwaddr = nm_device_get_hw_address (nm_device); panel_set_device_widget_details (priv->builder, "mac", hwaddr); /* set IP entries */ panel_set_device_widgets (priv->builder, nm_device); } static void device_simple_refresh (NetObject *object) { NetDeviceSimple *device_simple = NET_DEVICE_SIMPLE (object); nm_device_simple_refresh_ui (device_simple); } static void device_off_toggled (GtkSwitch *sw, GParamSpec *pspec, NetDeviceSimple *device_simple) { const GPtrArray *acs; gboolean active; gint i; NMActiveConnection *a; NMConnection *connection; NMClient *client; if (device_simple->priv->updating_device) return; active = gtk_switch_get_active (sw); if (active) { client = net_object_get_client (NET_OBJECT (device_simple)); connection = net_device_get_find_connection (NET_DEVICE (device_simple)); if (connection == NULL) return; nm_client_activate_connection_async (client, connection, net_device_get_nm_device (NET_DEVICE (device_simple)), NULL, NULL, NULL, NULL); } else { const gchar *uuid; connection = net_device_get_find_connection (NET_DEVICE (device_simple)); if (connection == NULL) return; uuid = nm_connection_get_uuid (connection); client = net_object_get_client (NET_OBJECT (device_simple)); acs = nm_client_get_active_connections (client); for (i = 0; acs && i < acs->len; i++) { a = (NMActiveConnection*)acs->pdata[i]; if (strcmp (nm_active_connection_get_uuid (a), uuid) == 0) { nm_client_deactivate_connection (client, a, NULL, NULL); break; } } } } static void edit_connection (GtkButton *button, NetDeviceSimple *device_simple) { net_object_edit (NET_OBJECT (device_simple)); } static void net_device_simple_constructed (GObject *object) { NetDeviceSimple *device_simple = NET_DEVICE_SIMPLE (object); G_OBJECT_CLASS (net_device_simple_parent_class)->constructed (object); net_object_refresh (NET_OBJECT (device_simple)); } static void net_device_simple_finalize (GObject *object) { NetDeviceSimple *device_simple = NET_DEVICE_SIMPLE (object); NetDeviceSimplePrivate *priv = device_simple->priv; g_object_unref (priv->builder); G_OBJECT_CLASS (net_device_simple_parent_class)->finalize (object); } static char * device_simple_get_speed (NetDeviceSimple *simple) { return NULL; } static void net_device_simple_class_init (NetDeviceSimpleClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); NetObjectClass *parent_class = NET_OBJECT_CLASS (klass); NetDeviceSimpleClass *simple_class = NET_DEVICE_SIMPLE_CLASS (klass); object_class->finalize = net_device_simple_finalize; object_class->constructed = net_device_simple_constructed; parent_class->add_to_notebook = device_simple_proxy_add_to_notebook; parent_class->refresh = device_simple_refresh; simple_class->get_speed = device_simple_get_speed; g_type_class_add_private (klass, sizeof (NetDeviceSimplePrivate)); } static void net_device_simple_init (NetDeviceSimple *device_simple) { GError *error = NULL; GtkWidget *widget; device_simple->priv = NET_DEVICE_SIMPLE_GET_PRIVATE (device_simple); device_simple->priv->builder = gtk_builder_new (); gtk_builder_add_from_resource (device_simple->priv->builder, "/org/cinnamon/control-center/network/network-simple.ui", &error); if (error != NULL) { g_warning ("Could not load interface file: %s", error->message); g_error_free (error); return; } /* setup simple combobox model */ widget = GTK_WIDGET (gtk_builder_get_object (device_simple->priv->builder, "device_off_switch")); g_signal_connect (widget, "notify::active", G_CALLBACK (device_off_toggled), device_simple); widget = GTK_WIDGET (gtk_builder_get_object (device_simple->priv->builder, "button_options")); g_signal_connect (widget, "clicked", G_CALLBACK (edit_connection), device_simple); } char * net_device_simple_get_speed (NetDeviceSimple *device_simple) { NetDeviceSimpleClass *klass = NET_DEVICE_SIMPLE_GET_CLASS (device_simple); return klass->get_speed (device_simple); } void net_device_simple_add_row (NetDeviceSimple *device_simple, const char *label_string, const char *property_name) { NetDeviceSimplePrivate *priv = device_simple->priv; GtkGrid *grid; GtkWidget *label, *value; GtkStyleContext *context; gint top_attach; grid = GTK_GRID (gtk_builder_get_object (priv->builder, "grid")); label = gtk_label_new (label_string); gtk_widget_set_halign (label, GTK_ALIGN_END); gtk_container_add (GTK_CONTAINER (grid), label); context = gtk_widget_get_style_context (label); gtk_style_context_add_class (context, "dim-label"); gtk_widget_show (label); gtk_container_child_get (GTK_CONTAINER (grid), label, "top-attach", &top_attach, NULL); value = gtk_label_new (NULL); gtk_widget_set_halign (value, GTK_ALIGN_START); g_object_bind_property (device_simple, property_name, value, "label", 0); gtk_label_set_mnemonic_widget (GTK_LABEL (label), value); gtk_grid_attach (grid, value, 1, top_attach, 1, 1); gtk_widget_show (value); } cinnamon-control-center-6.4.1/panels/network/connection-editor/0000775000175000017500000000000014724311620023602 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/network/connection-editor/ce-page-ip4.c0000664000175000017500000011546614724311620025756 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Red Hat, Inc * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include #include #include "shell/list-box-helper.h" #include "ce-page-ip4.h" #include "ui-helpers.h" G_DEFINE_TYPE (CEPageIP4, ce_page_ip4, CE_TYPE_PAGE) enum { METHOD_COL_NAME, METHOD_COL_METHOD }; enum { IP4_METHOD_AUTO, IP4_METHOD_MANUAL, IP4_METHOD_LINK_LOCAL, IP4_METHOD_SHARED, IP4_METHOD_DISABLED }; static void method_changed (GtkComboBox *combo, CEPageIP4 *page) { gboolean addr_enabled; gboolean dns_enabled; gboolean routes_enabled; guint method; GtkWidget *widget; method = gtk_combo_box_get_active (combo); switch (method) { case IP4_METHOD_AUTO: addr_enabled = FALSE; dns_enabled = TRUE; routes_enabled = TRUE; break; case IP4_METHOD_MANUAL: addr_enabled = TRUE; dns_enabled = TRUE; routes_enabled = TRUE; break; case IP4_METHOD_LINK_LOCAL: default: addr_enabled = FALSE; dns_enabled = FALSE; routes_enabled = FALSE; break; } widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "address_section")); gtk_widget_set_visible (widget, addr_enabled); gtk_widget_set_sensitive (page->dns_list, dns_enabled); gtk_widget_set_sensitive (page->routes_list, routes_enabled); gtk_widget_set_sensitive (page->never_default, routes_enabled); ce_page_changed (CE_PAGE (page)); } static void switch_toggled (GObject *object, GParamSpec *pspec, CEPage *page) { ce_page_changed (page); } static void update_row_sensitivity (CEPageIP4 *page, GtkWidget *list) { GList *children, *l; gint rows = 0; children = gtk_container_get_children (GTK_CONTAINER (list)); for (l = children; l; l = l->next) { GtkWidget *row = l->data; GtkWidget *button; button = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "delete-button")); if (button != NULL) rows++; } for (l = children; l; l = l->next) { GtkWidget *row = l->data; GtkWidget *button; button = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "delete-button")); if (button != NULL) gtk_widget_set_sensitive (button, rows > 1); } g_list_free (children); } static void update_row_gateway_visibility (CEPageIP4 *page) { GList *children, *l; gint rows = 0; children = gtk_container_get_children (GTK_CONTAINER (page->address_list)); for (l = children; l; l = l->next) { GtkWidget *row = l->data; GtkWidget *label, *entry; label = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "gateway-label")); entry = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "gateway")); gtk_widget_set_visible (label, (rows == 0)); gtk_widget_set_visible (entry, (rows == 0)); rows++; } g_list_free (children); } static void remove_row (GtkButton *button, CEPageIP4 *page) { GtkWidget *list; GtkWidget *row; GtkWidget *row_box; row_box = gtk_widget_get_parent (GTK_WIDGET (button)); row = gtk_widget_get_parent (row_box); list = gtk_widget_get_parent (row); gtk_container_remove (GTK_CONTAINER (list), row); ce_page_changed (CE_PAGE (page)); update_row_sensitivity (page, list); if (list == page->address_list) update_row_gateway_visibility (page); } static gint sort_first_last (gconstpointer a, gconstpointer b, gpointer data) { gboolean afirst, bfirst, alast, blast; afirst = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (a), "first")); bfirst = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (b), "first")); alast = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (a), "last")); blast = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (b), "last")); if (afirst) return -1; if (bfirst) return 1; if (alast) return 1; if (blast) return -1; return 0; } static void add_address_row (CEPageIP4 *page, const gchar *address, const gchar *network, const gchar *gateway) { GtkWidget *row; GtkWidget *row_grid; GtkWidget *widget; GtkWidget *label; GtkWidget *delete_button; GtkWidget *image; row = gtk_list_box_row_new (); row_grid = gtk_grid_new (); label = gtk_label_new (_("Address")); gtk_widget_set_halign (label, GTK_ALIGN_END); gtk_grid_attach (GTK_GRID (row_grid), label, 1, 1, 1, 1); widget = gtk_entry_new (); gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); g_object_set_data (G_OBJECT (row), "address", widget); gtk_entry_set_text (GTK_ENTRY (widget), address); gtk_widget_set_margin_start (widget, 10); gtk_widget_set_margin_end (widget, 10); gtk_widget_set_hexpand (widget, TRUE); gtk_grid_attach (GTK_GRID (row_grid), widget, 2, 1, 1, 1); label = gtk_label_new (_("Netmask")); gtk_widget_set_halign (label, GTK_ALIGN_END); gtk_grid_attach (GTK_GRID (row_grid), label, 1, 2, 1, 1); widget = gtk_entry_new (); gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); g_object_set_data (G_OBJECT (row), "network", widget); gtk_entry_set_text (GTK_ENTRY (widget), network); gtk_widget_set_margin_start (widget, 10); gtk_widget_set_margin_end (widget, 10); gtk_widget_set_hexpand (widget, TRUE); gtk_grid_attach (GTK_GRID (row_grid), widget, 2, 2, 1, 1); label = gtk_label_new (_("Gateway")); gtk_widget_set_halign (label, GTK_ALIGN_END); gtk_grid_attach (GTK_GRID (row_grid), label, 1, 3, 1, 1); g_object_set_data (G_OBJECT (row), "gateway-label", label); widget = gtk_entry_new (); gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); g_object_set_data (G_OBJECT (row), "gateway", widget); gtk_entry_set_text (GTK_ENTRY (widget), gateway ? gateway : ""); gtk_widget_set_margin_start (widget, 10); gtk_widget_set_margin_end (widget, 10); gtk_widget_set_hexpand (widget, TRUE); gtk_grid_attach (GTK_GRID (row_grid), widget, 2, 3, 1, 1); gtk_widget_set_no_show_all (label, TRUE); gtk_widget_set_no_show_all (widget, FALSE); delete_button = gtk_button_new (); gtk_style_context_add_class (gtk_widget_get_style_context (delete_button), "image-button"); g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page); image = gtk_image_new_from_icon_name ("user-trash-symbolic", GTK_ICON_SIZE_MENU); atk_object_set_name (gtk_widget_get_accessible (delete_button), _("Delete Address")); gtk_button_set_image (GTK_BUTTON (delete_button), image); gtk_grid_attach (GTK_GRID (row_grid), delete_button, 3, 2, 1, 1); g_object_set_data (G_OBJECT (row), "delete-button", delete_button); gtk_grid_set_row_spacing (GTK_GRID (row_grid), 10); gtk_widget_set_margin_start (row_grid, 10); gtk_widget_set_margin_end (row_grid, 10); gtk_widget_set_margin_top (row_grid, 10); gtk_widget_set_margin_bottom (row_grid, 10); gtk_widget_set_halign (row_grid, GTK_ALIGN_FILL); gtk_container_add (GTK_CONTAINER (row), row_grid); gtk_widget_show_all (row); gtk_container_add (GTK_CONTAINER (page->address_list), row); update_row_gateway_visibility (page); update_row_sensitivity (page, page->address_list); } static void add_empty_address_row (CEPageIP4 *page) { add_address_row (page, "", "", ""); } static void add_section_toolbar (CEPageIP4 *page, GtkWidget *section, GCallback add_cb) { GtkWidget *toolbar; GtkToolItem *item; GtkStyleContext *context; GtkWidget *box; GtkWidget *button; GtkWidget *image; toolbar = gtk_toolbar_new (); gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS); gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_MENU); context = gtk_widget_get_style_context (toolbar); gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP); gtk_style_context_add_class (context, GTK_STYLE_CLASS_INLINE_TOOLBAR); gtk_container_add (GTK_CONTAINER (section), toolbar); item = gtk_separator_tool_item_new (); gtk_tool_item_set_expand (item, TRUE); gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (item), FALSE); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (item), 0); box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); item = gtk_tool_item_new (); gtk_container_add (GTK_CONTAINER (item), box); button = gtk_button_new (); g_signal_connect_swapped (button, "clicked", G_CALLBACK (add_cb), page); image = gtk_image_new_from_icon_name ("list-add-symbolic", GTK_ICON_SIZE_MENU); atk_object_set_name (gtk_widget_get_accessible (button), _("Add")); gtk_button_set_image (GTK_BUTTON (button), image); gtk_container_add (GTK_CONTAINER (box), button); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (item), 1); } static void add_address_section (CEPageIP4 *page) { GtkWidget *widget; GtkWidget *frame; GtkWidget *list; gint i; widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "address_section")); frame = gtk_frame_new (NULL); gtk_container_add (GTK_CONTAINER (widget), frame); page->address_list = list = gtk_list_box_new (); gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE); gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL); gtk_list_box_set_sort_func (GTK_LIST_BOX (list), (GtkListBoxSortFunc)sort_first_last, NULL, NULL); gtk_container_add (GTK_CONTAINER (frame), list); add_section_toolbar (page, widget, G_CALLBACK (add_empty_address_row)); for (i = 0; i < nm_setting_ip_config_get_num_addresses (page->setting); i++) { NMIPAddress *addr; struct in_addr tmp_addr; gchar network[INET_ADDRSTRLEN + 1]; addr = nm_setting_ip_config_get_address (page->setting, i); if (!addr) continue; tmp_addr.s_addr = nm_utils_ip4_prefix_to_netmask (nm_ip_address_get_prefix (addr)); (void) inet_ntop (AF_INET, &tmp_addr, &network[0], sizeof (network)); add_address_row (page, nm_ip_address_get_address (addr), network, i == 0 ? nm_setting_ip_config_get_gateway (page->setting) : ""); } if (nm_setting_ip_config_get_num_addresses (page->setting) == 0) add_empty_address_row (page); gtk_widget_show_all (widget); } static void add_dns_row (CEPageIP4 *page, const gchar *address) { GtkWidget *row; GtkWidget *row_box; GtkWidget *label; GtkWidget *widget; GtkWidget *delete_button; GtkWidget *image; row = gtk_list_box_row_new (); row_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); label = gtk_label_new (_("Server")); gtk_widget_set_halign (label, GTK_ALIGN_END); gtk_box_pack_start (GTK_BOX (row_box), label, FALSE, FALSE, 0); widget = gtk_entry_new (); gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); g_object_set_data (G_OBJECT (row), "address", widget); gtk_entry_set_text (GTK_ENTRY (widget), address); gtk_widget_set_margin_start (widget, 10); gtk_widget_set_margin_end (widget, 10); gtk_widget_set_hexpand (widget, TRUE); gtk_box_pack_start (GTK_BOX (row_box), widget, TRUE, TRUE, 0); delete_button = gtk_button_new (); gtk_style_context_add_class (gtk_widget_get_style_context (delete_button), "image-button"); g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page); image = gtk_image_new_from_icon_name ("user-trash-symbolic", GTK_ICON_SIZE_MENU); atk_object_set_name (gtk_widget_get_accessible (delete_button), _("Delete DNS Server")); gtk_button_set_image (GTK_BUTTON (delete_button), image); gtk_box_pack_start (GTK_BOX (row_box), delete_button, FALSE, FALSE, 0); g_object_set_data (G_OBJECT (row), "delete-button", delete_button); gtk_widget_set_margin_start (row_box, 10); gtk_widget_set_margin_end (row_box, 10); gtk_widget_set_margin_top (row_box, 10); gtk_widget_set_margin_bottom (row_box, 10); gtk_widget_set_halign (row_box, GTK_ALIGN_FILL); gtk_container_add (GTK_CONTAINER (row), row_box); gtk_widget_show_all (row); gtk_container_add (GTK_CONTAINER (page->dns_list), row); update_row_sensitivity (page, page->dns_list); } static void add_empty_dns_row (CEPageIP4 *page) { add_dns_row (page, ""); } static void add_dns_section (CEPageIP4 *page) { GtkWidget *widget; GtkWidget *frame; GtkWidget *list; gint i; widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "dns_section")); frame = gtk_frame_new (NULL); gtk_container_add (GTK_CONTAINER (widget), frame); page->dns_list = list = gtk_list_box_new (); gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE); gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL); gtk_list_box_set_sort_func (GTK_LIST_BOX (list), (GtkListBoxSortFunc)sort_first_last, NULL, NULL); gtk_container_add (GTK_CONTAINER (frame), list); page->auto_dns = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_dns_switch")); gtk_switch_set_active (page->auto_dns, !nm_setting_ip_config_get_ignore_auto_dns (page->setting)); g_signal_connect (page->auto_dns, "notify::active", G_CALLBACK (switch_toggled), page); add_section_toolbar (page, widget, G_CALLBACK (add_empty_dns_row)); for (i = 0; i < nm_setting_ip_config_get_num_dns (page->setting); i++) { const char *address; address = nm_setting_ip_config_get_dns (page->setting, i); add_dns_row (page, address); } if (nm_setting_ip_config_get_num_dns (page->setting) == 0) add_empty_dns_row (page); gtk_widget_show_all (widget); } static void add_route_row (CEPageIP4 *page, const gchar *address, const gchar *netmask, const gchar *gateway, gint metric) { GtkWidget *row; GtkWidget *row_grid; GtkWidget *label; GtkWidget *widget; GtkWidget *delete_button; GtkWidget *image; row = gtk_list_box_row_new (); row_grid = gtk_grid_new (); label = gtk_label_new (_("Address")); gtk_widget_set_halign (label, GTK_ALIGN_END); gtk_grid_attach (GTK_GRID (row_grid), label, 1, 1, 1, 1); widget = gtk_entry_new (); gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); g_object_set_data (G_OBJECT (row), "address", widget); gtk_entry_set_text (GTK_ENTRY (widget), address); gtk_widget_set_margin_start (widget, 10); gtk_widget_set_margin_end (widget, 10); gtk_widget_set_hexpand (widget, TRUE); gtk_grid_attach (GTK_GRID (row_grid), widget, 2, 1, 1, 1); label = gtk_label_new (_("Netmask")); gtk_widget_set_halign (label, GTK_ALIGN_END); gtk_grid_attach (GTK_GRID (row_grid), label, 1, 2, 1, 1); widget = gtk_entry_new (); gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); g_object_set_data (G_OBJECT (row), "netmask", widget); gtk_entry_set_text (GTK_ENTRY (widget), netmask); gtk_widget_set_margin_start (widget, 10); gtk_widget_set_margin_end (widget, 10); gtk_widget_set_hexpand (widget, TRUE); gtk_grid_attach (GTK_GRID (row_grid), widget, 2, 2, 1, 1); label = gtk_label_new (_("Gateway")); gtk_widget_set_halign (label, GTK_ALIGN_END); gtk_grid_attach (GTK_GRID (row_grid), label, 1, 3, 1, 1); widget = gtk_entry_new (); gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); g_object_set_data (G_OBJECT (row), "gateway", widget); gtk_entry_set_text (GTK_ENTRY (widget), gateway); gtk_widget_set_margin_start (widget, 10); gtk_widget_set_margin_end (widget, 10); gtk_widget_set_hexpand (widget, TRUE); gtk_grid_attach (GTK_GRID (row_grid), widget, 2, 3, 1, 1); /* Translators: Please see https://en.wikipedia.org/wiki/Metrics_(networking) */ label = gtk_label_new (C_("network parameters", "Metric")); gtk_widget_set_halign (label, GTK_ALIGN_END); gtk_grid_attach (GTK_GRID (row_grid), label, 1, 4, 1, 1); widget = gtk_entry_new (); gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); g_object_set_data (G_OBJECT (row), "metric", widget); if (metric >= 0) { gchar *s = g_strdup_printf ("%d", metric); gtk_entry_set_text (GTK_ENTRY (widget), s); g_free (s); } gtk_widget_set_margin_start (widget, 10); gtk_widget_set_margin_end (widget, 10); gtk_widget_set_hexpand (widget, TRUE); gtk_grid_attach (GTK_GRID (row_grid), widget, 2, 4, 1, 1); delete_button = gtk_button_new (); gtk_style_context_add_class (gtk_widget_get_style_context (delete_button), "image-button"); g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page); image = gtk_image_new_from_icon_name ("user-trash-symbolic", GTK_ICON_SIZE_MENU); atk_object_set_name (gtk_widget_get_accessible (delete_button), _("Delete Route")); gtk_button_set_image (GTK_BUTTON (delete_button), image); gtk_widget_set_halign (delete_button, GTK_ALIGN_CENTER); gtk_widget_set_valign (delete_button, GTK_ALIGN_CENTER); gtk_grid_attach (GTK_GRID (row_grid), delete_button, 3, 1, 1, 4); g_object_set_data (G_OBJECT (row), "delete-button", delete_button); gtk_grid_set_row_spacing (GTK_GRID (row_grid), 10); gtk_widget_set_margin_start (row_grid, 10); gtk_widget_set_margin_end (row_grid, 10); gtk_widget_set_margin_top (row_grid, 10); gtk_widget_set_margin_bottom (row_grid, 10); gtk_widget_set_halign (row_grid, GTK_ALIGN_FILL); gtk_container_add (GTK_CONTAINER (row), row_grid); gtk_widget_show_all (row); gtk_container_add (GTK_CONTAINER (page->routes_list), row); update_row_sensitivity (page, page->routes_list); } static void add_empty_route_row (CEPageIP4 *page) { add_route_row (page, "", "", "", -1); } static void add_routes_section (CEPageIP4 *page) { GtkWidget *widget; GtkWidget *frame; GtkWidget *list; gint i; widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_section")); frame = gtk_frame_new (NULL); gtk_container_add (GTK_CONTAINER (widget), frame); page->routes_list = list = gtk_list_box_new (); gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE); gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL); gtk_list_box_set_sort_func (GTK_LIST_BOX (list), (GtkListBoxSortFunc)sort_first_last, NULL, NULL); gtk_container_add (GTK_CONTAINER (frame), list); page->auto_routes = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_routes_switch")); gtk_switch_set_active (page->auto_routes, !nm_setting_ip_config_get_ignore_auto_routes (page->setting)); g_signal_connect (page->auto_routes, "notify::active", G_CALLBACK (switch_toggled), page); add_section_toolbar (page, widget, G_CALLBACK (add_empty_route_row)); for (i = 0; i < nm_setting_ip_config_get_num_routes (page->setting); i++) { NMIPRoute *route; struct in_addr tmp_addr; gchar netmask[INET_ADDRSTRLEN + 1]; route = nm_setting_ip_config_get_route (page->setting, i); if (!route) continue; tmp_addr.s_addr = nm_utils_ip4_prefix_to_netmask (nm_ip_route_get_prefix (route)); (void) inet_ntop (AF_INET, &tmp_addr, &netmask[0], sizeof (netmask)); add_route_row (page, nm_ip_route_get_dest (route), netmask, nm_ip_route_get_next_hop (route), nm_ip_route_get_metric (route)); } if (nm_setting_ip_config_get_num_routes (page->setting) == 0) add_empty_route_row (page); gtk_widget_show_all (widget); } static void connect_ip4_page (CEPageIP4 *page) { GtkWidget *content; const gchar *str_method; gboolean disabled; GtkListStore *store; GtkTreeIter iter; guint method; add_address_section (page); add_dns_section (page); add_routes_section (page); page->enabled = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "switch_enable")); g_signal_connect (page->enabled, "notify::active", G_CALLBACK (switch_toggled), page); str_method = nm_setting_ip_config_get_method (page->setting); disabled = g_strcmp0 (str_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0; gtk_switch_set_active (page->enabled, !disabled); g_signal_connect_swapped (page->enabled, "notify::active", G_CALLBACK (ce_page_changed), page); content = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "page_content")); g_object_bind_property (page->enabled, "active", content, "sensitive", G_BINDING_SYNC_CREATE); page->method = GTK_COMBO_BOX (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_addresses")); store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_UINT); gtk_list_store_insert_with_values (store, &iter, -1, METHOD_COL_NAME, _("Automatic (DHCP)"), METHOD_COL_METHOD, IP4_METHOD_AUTO, -1); gtk_list_store_insert_with_values (store, &iter, -1, METHOD_COL_NAME, _("Manual"), METHOD_COL_METHOD, IP4_METHOD_MANUAL, -1); gtk_list_store_insert_with_values (store, &iter, -1, METHOD_COL_NAME, _("Link-Local Only"), METHOD_COL_METHOD, IP4_METHOD_LINK_LOCAL, -1); gtk_combo_box_set_model (page->method, GTK_TREE_MODEL (store)); g_object_unref (G_OBJECT (store)); method = IP4_METHOD_AUTO; if (g_strcmp0 (str_method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL) == 0) { method = IP4_METHOD_LINK_LOCAL; } else if (g_strcmp0 (str_method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0) { method = IP4_METHOD_MANUAL; } else if (g_strcmp0 (str_method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) == 0) { method = IP4_METHOD_SHARED; } else if (g_strcmp0 (str_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) { method = IP4_METHOD_DISABLED; } page->never_default = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "never_default_check")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (page->never_default), nm_setting_ip_config_get_never_default (page->setting)); g_signal_connect_swapped (page->never_default, "toggled", G_CALLBACK (ce_page_changed), page); g_signal_connect (page->method, "changed", G_CALLBACK (method_changed), page); if (method != IP4_METHOD_SHARED && method != IP4_METHOD_DISABLED) gtk_combo_box_set_active (page->method, method); } static gboolean parse_netmask (const char *str, guint32 *prefix) { struct in_addr tmp_addr; glong tmp_prefix; errno = 0; /* Is it a prefix? */ if (!strchr (str, '.')) { tmp_prefix = strtol (str, NULL, 10); if (!errno && tmp_prefix >= 0 && tmp_prefix <= 32) { *prefix = tmp_prefix; return TRUE; } } /* Is it a netmask? */ if (inet_pton (AF_INET, str, &tmp_addr) > 0) { *prefix = nm_utils_ip4_netmask_to_prefix (tmp_addr.s_addr); return TRUE; } return FALSE; } static gboolean ui_to_setting (CEPageIP4 *page) { const gchar *method; gboolean ignore_auto_dns; gboolean ignore_auto_routes; gboolean never_default; GPtrArray *addresses = NULL; GPtrArray *dns_servers = NULL; GPtrArray *routes = NULL; GList *children, *l; gboolean ret = TRUE; const char *default_gateway = NULL; if (!gtk_switch_get_active (page->enabled)) { method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED; } else { switch (gtk_combo_box_get_active (page->method)) { case IP4_METHOD_MANUAL: method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL; break; case IP4_METHOD_LINK_LOCAL: method = NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL; break; default: case IP4_METHOD_AUTO: method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; break; } } addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref); if (g_str_equal (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) children = gtk_container_get_children (GTK_CONTAINER (page->address_list)); else children = NULL; for (l = children; l; l = l->next) { GtkWidget *row = l->data; GtkEntry *entry; GtkEntry *gateway_entry; const gchar *text_address; const gchar *text_netmask; const gchar *text_gateway = ""; NMIPAddress *addr; guint32 prefix; entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address")); if (!entry) continue; text_address = gtk_entry_get_text (entry); text_netmask = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "network"))); gateway_entry = g_object_get_data (G_OBJECT (row), "gateway"); if (gtk_widget_is_visible (GTK_WIDGET (gateway_entry))) text_gateway = gtk_entry_get_text (gateway_entry); if (!*text_address && !*text_netmask && !*text_gateway) { /* ignore empty rows */ widget_unset_error (GTK_WIDGET (entry)); widget_unset_error (g_object_get_data (G_OBJECT (row), "network")); widget_unset_error (GTK_WIDGET (gateway_entry)); continue; } if (!nm_utils_ipaddr_valid (AF_INET, text_address)) { widget_set_error (GTK_WIDGET (entry)); ret = FALSE; } else { widget_unset_error (GTK_WIDGET (entry)); } if (!parse_netmask (text_netmask, &prefix)) { widget_set_error (g_object_get_data (G_OBJECT (row), "network")); ret = FALSE; } else { widget_unset_error (g_object_get_data (G_OBJECT (row), "network")); } if (gtk_widget_is_visible (GTK_WIDGET (gateway_entry)) && *text_gateway && !nm_utils_ipaddr_valid (AF_INET, text_gateway)) { widget_set_error (g_object_get_data (G_OBJECT (row), "gateway")); ret = FALSE; } else { widget_unset_error (GTK_WIDGET (gateway_entry)); if (gtk_widget_is_visible (GTK_WIDGET (gateway_entry)) && *text_gateway) { g_assert (default_gateway == NULL); default_gateway = text_gateway; } } if (!ret) continue; addr = nm_ip_address_new (AF_INET, text_address, prefix, NULL); if (addr) g_ptr_array_add (addresses, addr); } g_list_free (children); if (addresses->len == 0) { g_ptr_array_free (addresses, TRUE); addresses = NULL; } dns_servers = g_ptr_array_new_with_free_func (g_free); if (g_str_equal (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) || g_str_equal (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) children = gtk_container_get_children (GTK_CONTAINER (page->dns_list)); else children = NULL; for (l = children; l; l = l->next) { GtkWidget *row = l->data; GtkEntry *entry; const gchar *text; entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address")); if (!entry) continue; text = gtk_entry_get_text (entry); if (!*text) { /* ignore empty rows */ widget_unset_error (GTK_WIDGET (entry)); continue; } if (text && !nm_utils_ipaddr_valid (AF_INET, text)) { widget_set_error (GTK_WIDGET (entry)); ret = FALSE; } else { widget_unset_error (GTK_WIDGET (entry)); g_ptr_array_add (dns_servers, g_strdup (text)); } } g_list_free (children); if (dns_servers->len == 0) { g_ptr_array_free (dns_servers, TRUE); dns_servers = NULL; } else { g_ptr_array_add (dns_servers, NULL); } routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_route_unref); if (g_str_equal (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) || g_str_equal (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) children = gtk_container_get_children (GTK_CONTAINER (page->routes_list)); else children = NULL; for (l = children; l; l = l->next) { GtkWidget *row = l->data; GtkEntry *entry; const gchar *text_address; const gchar *text_netmask; const gchar *text_gateway; const gchar *text_metric; gint64 metric; guint32 netmask; NMIPRoute *route; entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address")); if (!entry) continue; text_address = gtk_entry_get_text (entry); text_netmask = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "netmask"))); text_gateway = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "gateway"))); text_metric = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "metric"))); if (!*text_address && !*text_netmask && !*text_gateway && !*text_metric) { /* ignore empty rows */ continue; } if (text_address && !nm_utils_ipaddr_valid (AF_INET, text_address)) { widget_set_error (GTK_WIDGET (entry)); ret = FALSE; } else { widget_unset_error (GTK_WIDGET (entry)); } if (!parse_netmask (text_netmask, &netmask)) { widget_set_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "netmask"))); ret = FALSE; } else { widget_unset_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "netmask"))); } if (text_gateway && !nm_utils_ipaddr_valid (AF_INET, text_gateway)) { widget_set_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "gateway"))); ret = FALSE; } else { widget_unset_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "gateway"))); } metric = -1; if (*text_metric) { errno = 0; metric = g_ascii_strtoull (text_metric, NULL, 10); if (errno || metric < 0 || metric > G_MAXUINT32) { widget_set_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "metric"))); ret = FALSE; } else { widget_unset_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "metric"))); } } else { widget_unset_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "metric"))); } if (!ret) continue; route = nm_ip_route_new (AF_INET, text_address, netmask, text_gateway, metric, NULL); if (route) g_ptr_array_add (routes, route); } g_list_free (children); if (routes->len == 0) { g_ptr_array_free (routes, TRUE); routes = NULL; } if (!ret) goto out; ignore_auto_dns = !gtk_switch_get_active (page->auto_dns); ignore_auto_routes = !gtk_switch_get_active (page->auto_routes); never_default = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (page->never_default)); g_object_set (page->setting, NM_SETTING_IP_CONFIG_METHOD, method, NM_SETTING_IP_CONFIG_ADDRESSES, addresses, NM_SETTING_IP_CONFIG_GATEWAY, default_gateway, NM_SETTING_IP_CONFIG_DNS, dns_servers ? dns_servers->pdata : NULL, NM_SETTING_IP_CONFIG_ROUTES, routes, NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, ignore_auto_dns, NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, ignore_auto_routes, NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default, NULL); out: if (addresses) g_ptr_array_free (addresses, TRUE); if (dns_servers) g_ptr_array_free (dns_servers, TRUE); if (routes) g_ptr_array_free (routes, TRUE); return ret; } static gboolean validate (CEPage *page, NMConnection *connection, GError **error) { if (!ui_to_setting (CE_PAGE_IP4 (page))) return FALSE; return nm_setting_verify (NM_SETTING (CE_PAGE_IP4 (page)->setting), NULL, error); } static void ce_page_ip4_init (CEPageIP4 *page) { } static void ce_page_ip4_class_init (CEPageIP4Class *class) { CEPageClass *page_class= CE_PAGE_CLASS (class); page_class->validate = validate; } CEPage * ce_page_ip4_new (NMConnection *connection, NMClient *client) { CEPageIP4 *page; page = CE_PAGE_IP4 (ce_page_new (CE_TYPE_PAGE_IP4, connection, client, "/org/cinnamon/control-center/network/ip4-page.ui", _("IPv4"))); page->setting = nm_connection_get_setting_ip4_config (connection); if (!page->setting) { page->setting = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); nm_connection_add_setting (connection, NM_SETTING (page->setting)); } connect_ip4_page (page); return CE_PAGE (page); } cinnamon-control-center-6.4.1/panels/network/connection-editor/ce-page-security.h0000664000175000017500000000441614724311620027126 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Red Hat, Inc. * * Licensed under the GNU General Public License Version 2 * * 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 security. * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __CE_PAGE_SECURITY_H #define __CE_PAGE_SECURITY_H #include #include #include "ce-page.h" G_BEGIN_DECLS #define CE_TYPE_PAGE_SECURITY (ce_page_security_get_type ()) #define CE_PAGE_SECURITY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_SECURITY, CEPageSecurity)) #define CE_PAGE_SECURITY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_SECURITY, CEPageSecurityClass)) #define CE_IS_PAGE_SECURITY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_SECURITY)) #define CE_IS_PAGE_SECURITY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_SECURITY)) #define CE_PAGE_SECURITY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_SECURITY, CEPageSecurityClass)) typedef struct _CEPageSecurity CEPageSecurity; typedef struct _CEPageSecurityClass CEPageSecurityClass; struct _CEPageSecurity { CEPage parent; GtkComboBox *security_combo; GtkWidget *security_heading; GtkComboBox *firewall_combo; GtkWidget *firewall_heading; GtkSizeGroup *group; gboolean adhoc; }; struct _CEPageSecurityClass { CEPageClass parent_class; }; GType ce_page_security_get_type (void); CEPage *ce_page_security_new (NMConnection *connection, NMClient *client); G_END_DECLS #endif /* __CE_PAGE_SECURITY_H */ cinnamon-control-center-6.4.1/panels/network/connection-editor/ce-page-ip6.c0000664000175000017500000011127414724311620025751 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Red Hat, Inc * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include #include #include "shell/list-box-helper.h" #include "ce-page-ip6.h" #include "ui-helpers.h" G_DEFINE_TYPE (CEPageIP6, ce_page_ip6, CE_TYPE_PAGE) enum { METHOD_COL_NAME, METHOD_COL_METHOD }; enum { IP6_METHOD_AUTO, IP6_METHOD_DHCP, IP6_METHOD_MANUAL, IP6_METHOD_LINK_LOCAL, IP6_METHOD_SHARED, IP6_METHOD_IGNORE }; static void method_changed (GtkComboBox *combo, CEPageIP6 *page) { gboolean addr_enabled; gboolean dns_enabled; gboolean routes_enabled; guint method; GtkWidget *widget; method = gtk_combo_box_get_active (combo); switch (method) { case IP6_METHOD_AUTO: case IP6_METHOD_DHCP: addr_enabled = FALSE; dns_enabled = TRUE; routes_enabled = TRUE; break; case IP6_METHOD_MANUAL: addr_enabled = TRUE; dns_enabled = TRUE; routes_enabled = TRUE; break; case IP6_METHOD_LINK_LOCAL: default: addr_enabled = FALSE; dns_enabled = FALSE; routes_enabled = FALSE; break; } widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "address_section")); gtk_widget_set_visible (widget, addr_enabled); gtk_widget_set_sensitive (page->dns_list, dns_enabled); gtk_widget_set_sensitive (page->routes_list, routes_enabled); gtk_widget_set_sensitive (page->never_default, routes_enabled); ce_page_changed (CE_PAGE (page)); } static void switch_toggled (GObject *object, GParamSpec *pspec, CEPage *page) { ce_page_changed (page); } static void update_row_sensitivity (CEPageIP6 *page, GtkWidget *list) { GList *children, *l; gint rows = 0; children = gtk_container_get_children (GTK_CONTAINER (list)); for (l = children; l; l = l->next) { GtkWidget *row = l->data; GtkWidget *button; button = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "delete-button")); if (button != NULL) rows++; } for (l = children; l; l = l->next) { GtkWidget *row = l->data; GtkWidget *button; button = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "delete-button")); if (button != NULL) gtk_widget_set_sensitive (button, rows > 1); } g_list_free (children); } static void remove_row (GtkButton *button, CEPageIP6 *page) { GtkWidget *row; GtkWidget *row_box; GtkWidget *list; row_box = gtk_widget_get_parent (GTK_WIDGET (button)); row = gtk_widget_get_parent (row_box); list = gtk_widget_get_parent (row); gtk_container_remove (GTK_CONTAINER (list), row); ce_page_changed (CE_PAGE (page)); update_row_sensitivity (page, list); } static gint sort_first_last (gconstpointer a, gconstpointer b, gpointer data) { gboolean afirst, bfirst, alast, blast; afirst = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (a), "first")); bfirst = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (b), "first")); alast = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (a), "last")); blast = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (b), "last")); if (afirst) return -1; if (bfirst) return 1; if (alast) return 1; if (blast) return -1; return 0; } static void add_address_row (CEPageIP6 *page, const gchar *address, const gchar *network, const gchar *gateway) { GtkWidget *row; GtkWidget *row_grid; GtkWidget *label; GtkWidget *widget; GtkWidget *delete_button; GtkWidget *image; row = gtk_list_box_row_new (); row_grid = gtk_grid_new (); label = gtk_label_new (_("Address")); gtk_widget_set_halign (label, GTK_ALIGN_END); gtk_grid_attach (GTK_GRID (row_grid), label, 1, 1, 1, 1); widget = gtk_entry_new (); gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); g_object_set_data (G_OBJECT (row), "address", widget); gtk_entry_set_text (GTK_ENTRY (widget), address); gtk_widget_set_margin_start (widget, 10); gtk_widget_set_margin_end (widget, 10); gtk_widget_set_hexpand (widget, TRUE); gtk_grid_attach (GTK_GRID (row_grid), widget, 2, 1, 1, 1); label = gtk_label_new (_("Prefix")); gtk_widget_set_halign (label, GTK_ALIGN_END); gtk_grid_attach (GTK_GRID (row_grid), label, 1, 2, 1, 1); widget = gtk_entry_new (); gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); g_object_set_data (G_OBJECT (row), "prefix", widget); gtk_entry_set_text (GTK_ENTRY (widget), network); gtk_widget_set_margin_start (widget, 10); gtk_widget_set_margin_end (widget, 10); gtk_widget_set_hexpand (widget, TRUE); gtk_grid_attach (GTK_GRID (row_grid), widget, 2, 2, 1, 1); label = gtk_label_new (_("Gateway")); gtk_widget_set_halign (label, GTK_ALIGN_END); gtk_grid_attach (GTK_GRID (row_grid), label, 1, 3, 1, 1); widget = gtk_entry_new (); gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); g_object_set_data (G_OBJECT (row), "gateway", widget); gtk_entry_set_text (GTK_ENTRY (widget), gateway ? gateway : ""); gtk_widget_set_margin_start (widget, 10); gtk_widget_set_margin_end (widget, 10); gtk_widget_set_hexpand (widget, TRUE); gtk_grid_attach (GTK_GRID (row_grid), widget, 2, 3, 1, 1); delete_button = gtk_button_new (); gtk_style_context_add_class (gtk_widget_get_style_context (delete_button), "image-button"); g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page); image = gtk_image_new_from_icon_name ("user-trash-symbolic", GTK_ICON_SIZE_MENU); atk_object_set_name (gtk_widget_get_accessible (delete_button), _("Delete Address")); gtk_button_set_image (GTK_BUTTON (delete_button), image); gtk_grid_attach (GTK_GRID (row_grid), delete_button, 3, 2, 1, 1); g_object_set_data (G_OBJECT (row), "delete-button", delete_button); gtk_grid_set_row_spacing (GTK_GRID (row_grid), 10); gtk_widget_set_margin_start (row_grid, 10); gtk_widget_set_margin_end (row_grid, 10); gtk_widget_set_margin_top (row_grid, 10); gtk_widget_set_margin_bottom (row_grid, 10); gtk_widget_set_halign (row_grid, GTK_ALIGN_FILL); gtk_container_add (GTK_CONTAINER (row), row_grid); gtk_widget_show_all (row); gtk_container_add (GTK_CONTAINER (page->address_list), row); update_row_sensitivity (page, page->address_list); } static void add_empty_address_row (CEPageIP6 *page) { add_address_row (page, "", "", ""); } static void add_section_toolbar (CEPageIP6 *page, GtkWidget *section, GCallback add_cb) { GtkWidget *toolbar; GtkToolItem *item; GtkStyleContext *context; GtkWidget *box; GtkWidget *button; GtkWidget *image; toolbar = gtk_toolbar_new (); gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS); gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_MENU); context = gtk_widget_get_style_context (toolbar); gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP); gtk_style_context_add_class (context, GTK_STYLE_CLASS_INLINE_TOOLBAR); gtk_container_add (GTK_CONTAINER (section), toolbar); item = gtk_separator_tool_item_new (); gtk_tool_item_set_expand (item, TRUE); gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (item), FALSE); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (item), 0); box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); item = gtk_tool_item_new (); gtk_container_add (GTK_CONTAINER (item), box); button = gtk_button_new (); g_signal_connect_swapped (button, "clicked", G_CALLBACK (add_cb), page); image = gtk_image_new_from_icon_name ("list-add-symbolic", GTK_ICON_SIZE_MENU); atk_object_set_name (gtk_widget_get_accessible (button), _("Add")); gtk_button_set_image (GTK_BUTTON (button), image); gtk_container_add (GTK_CONTAINER (box), button); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (item), 1); } static void add_address_section (CEPageIP6 *page) { GtkWidget *widget; GtkWidget *frame; GtkWidget *list; gint i; widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "address_section")); frame = gtk_frame_new (NULL); gtk_container_add (GTK_CONTAINER (widget), frame); page->address_list = list = gtk_list_box_new (); gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE); gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL); gtk_list_box_set_sort_func (GTK_LIST_BOX (list), (GtkListBoxSortFunc)sort_first_last, NULL, NULL); gtk_container_add (GTK_CONTAINER (frame), list); add_section_toolbar (page, widget, G_CALLBACK (add_empty_address_row)); for (i = 0; i < nm_setting_ip_config_get_num_addresses (page->setting); i++) { NMIPAddress *addr; char *netmask; addr = nm_setting_ip_config_get_address (page->setting, i); netmask = g_strdup_printf ("%u", nm_ip_address_get_prefix (addr)); add_address_row (page, nm_ip_address_get_address (addr), netmask, i == 0 ? nm_setting_ip_config_get_gateway (page->setting) : NULL); g_free (netmask); } if (nm_setting_ip_config_get_num_addresses (page->setting) == 0) add_empty_address_row (page); gtk_widget_show_all (widget); } static void add_dns_row (CEPageIP6 *page, const gchar *address) { GtkWidget *row; GtkWidget *row_box; GtkWidget *label; GtkWidget *widget; GtkWidget *delete_button; GtkWidget *image; row = gtk_list_box_row_new (); gtk_widget_set_can_focus (row, FALSE); row_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); label = gtk_label_new (_("Server")); gtk_widget_set_halign (label, GTK_ALIGN_END); gtk_box_pack_start (GTK_BOX (row_box), label, FALSE, FALSE, 0); widget = gtk_entry_new (); gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); g_object_set_data (G_OBJECT (row), "address", widget); gtk_entry_set_text (GTK_ENTRY (widget), address); gtk_widget_set_margin_start (widget, 10); gtk_widget_set_margin_end (widget, 10); gtk_widget_set_hexpand (widget, TRUE); gtk_box_pack_start (GTK_BOX (row_box), widget, TRUE, TRUE, 0); delete_button = gtk_button_new (); gtk_style_context_add_class (gtk_widget_get_style_context (delete_button), "image-button"); g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page); image = gtk_image_new_from_icon_name ("user-trash-symbolic", GTK_ICON_SIZE_MENU); atk_object_set_name (gtk_widget_get_accessible (delete_button), _("Delete DNS Server")); gtk_button_set_image (GTK_BUTTON (delete_button), image); gtk_box_pack_start (GTK_BOX (row_box), delete_button, FALSE, FALSE, 0); g_object_set_data (G_OBJECT (row), "delete-button", delete_button); gtk_widget_set_margin_start (row_box, 10); gtk_widget_set_margin_end (row_box, 10); gtk_widget_set_margin_top (row_box, 10); gtk_widget_set_margin_bottom (row_box, 10); gtk_widget_set_halign (row_box, GTK_ALIGN_FILL); gtk_container_add (GTK_CONTAINER (row), row_box); gtk_widget_show_all (row); gtk_container_add (GTK_CONTAINER (page->dns_list), row); update_row_sensitivity (page, page->dns_list); } static void add_empty_dns_row (CEPageIP6 *page) { add_dns_row (page, ""); } static void add_dns_section (CEPageIP6 *page) { GtkWidget *widget; GtkWidget *frame; GtkWidget *list; gint i; widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "dns_section")); frame = gtk_frame_new (NULL); gtk_container_add (GTK_CONTAINER (widget), frame); page->dns_list = list = gtk_list_box_new (); gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE); gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL); gtk_list_box_set_sort_func (GTK_LIST_BOX (list), (GtkListBoxSortFunc)sort_first_last, NULL, NULL); gtk_container_add (GTK_CONTAINER (frame), list); page->auto_dns = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_dns_switch")); gtk_switch_set_active (page->auto_dns, !nm_setting_ip_config_get_ignore_auto_dns (page->setting)); g_signal_connect (page->auto_dns, "notify::active", G_CALLBACK (switch_toggled), page); add_section_toolbar (page, widget, G_CALLBACK (add_empty_dns_row)); for (i = 0; i < nm_setting_ip_config_get_num_dns (page->setting); i++) { const char *address; address = nm_setting_ip_config_get_dns (page->setting, i); add_dns_row (page, address); } if (nm_setting_ip_config_get_num_dns (page->setting) == 0) add_empty_dns_row (page); gtk_widget_show_all (widget); } static void add_route_row (CEPageIP6 *page, const gchar *address, const gchar *prefix, const gchar *gateway, const gchar *metric) { GtkWidget *row; GtkWidget *row_grid; GtkWidget *label; GtkWidget *widget; GtkWidget *delete_button; GtkWidget *image; row = gtk_list_box_row_new (); row_grid = gtk_grid_new (); label = gtk_label_new (_("Address")); gtk_widget_set_halign (label, GTK_ALIGN_END); gtk_grid_attach (GTK_GRID (row_grid), label, 1, 1, 1, 1); widget = gtk_entry_new (); gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); g_object_set_data (G_OBJECT (row), "address", widget); gtk_entry_set_text (GTK_ENTRY (widget), address); gtk_widget_set_margin_start (widget, 10); gtk_widget_set_margin_end (widget, 10); gtk_widget_set_hexpand (widget, TRUE); gtk_grid_attach (GTK_GRID (row_grid), widget, 2, 1, 1, 1); label = gtk_label_new (_("Prefix")); gtk_widget_set_halign (label, GTK_ALIGN_END); gtk_grid_attach (GTK_GRID (row_grid), label, 1, 2, 1, 1); widget = gtk_entry_new (); gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); g_object_set_data (G_OBJECT (row), "prefix", widget); gtk_entry_set_text (GTK_ENTRY (widget), prefix ? prefix : ""); gtk_widget_set_margin_start (widget, 10); gtk_widget_set_margin_end (widget, 10); gtk_widget_set_hexpand (widget, TRUE); gtk_grid_attach (GTK_GRID (row_grid), widget, 2, 2, 1, 1); label = gtk_label_new (_("Gateway")); gtk_widget_set_halign (label, GTK_ALIGN_END); gtk_grid_attach (GTK_GRID (row_grid), label, 1, 3, 1, 1); widget = gtk_entry_new (); gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); g_object_set_data (G_OBJECT (row), "gateway", widget); gtk_entry_set_text (GTK_ENTRY (widget), gateway); gtk_widget_set_margin_start (widget, 10); gtk_widget_set_margin_end (widget, 10); gtk_widget_set_hexpand (widget, TRUE); gtk_grid_attach (GTK_GRID (row_grid), widget, 2, 3, 1, 1); /* Translators: Please see https://en.wikipedia.org/wiki/Metrics_(networking) */ label = gtk_label_new (C_("network parameters", "Metric")); gtk_widget_set_halign (label, GTK_ALIGN_END); gtk_grid_attach (GTK_GRID (row_grid), label, 1, 4, 1, 1); widget = gtk_entry_new (); gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); g_object_set_data (G_OBJECT (row), "metric", widget); gtk_entry_set_text (GTK_ENTRY (widget), metric ? metric : ""); gtk_widget_set_margin_start (widget, 10); gtk_widget_set_margin_end (widget, 10); gtk_widget_set_hexpand (widget, TRUE); gtk_grid_attach (GTK_GRID (row_grid), widget, 2, 4, 1, 1); delete_button = gtk_button_new (); gtk_style_context_add_class (gtk_widget_get_style_context (delete_button), "image-button"); g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page); image = gtk_image_new_from_icon_name ("user-trash-symbolic", GTK_ICON_SIZE_MENU); atk_object_set_name (gtk_widget_get_accessible (delete_button), _("Delete Route")); gtk_button_set_image (GTK_BUTTON (delete_button), image); gtk_widget_set_halign (delete_button, GTK_ALIGN_CENTER); gtk_widget_set_valign (delete_button, GTK_ALIGN_CENTER); gtk_grid_attach (GTK_GRID (row_grid), delete_button, 3, 1, 1, 4); g_object_set_data (G_OBJECT (row), "delete-button", delete_button); gtk_grid_set_row_spacing (GTK_GRID (row_grid), 10); gtk_widget_set_margin_start (row_grid, 10); gtk_widget_set_margin_end (row_grid, 10); gtk_widget_set_margin_top (row_grid, 10); gtk_widget_set_margin_bottom (row_grid, 10); gtk_widget_set_halign (row_grid, GTK_ALIGN_FILL); gtk_container_add (GTK_CONTAINER (row), row_grid); gtk_widget_show_all (row); gtk_container_add (GTK_CONTAINER (page->routes_list), row); update_row_sensitivity (page, page->routes_list); } static void add_empty_route_row (CEPageIP6 *page) { add_route_row (page, "", NULL, "", NULL); } static void add_routes_section (CEPageIP6 *page) { GtkWidget *widget; GtkWidget *frame; GtkWidget *list; gint i; widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_section")); frame = gtk_frame_new (NULL); gtk_container_add (GTK_CONTAINER (widget), frame); page->routes_list = list = gtk_list_box_new (); gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE); gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL); gtk_list_box_set_sort_func (GTK_LIST_BOX (list), (GtkListBoxSortFunc)sort_first_last, NULL, NULL); gtk_container_add (GTK_CONTAINER (frame), list); page->auto_routes = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_routes_switch")); gtk_switch_set_active (page->auto_routes, !nm_setting_ip_config_get_ignore_auto_routes (page->setting)); g_signal_connect (page->auto_routes, "notify::active", G_CALLBACK (switch_toggled), page); add_section_toolbar (page, widget, G_CALLBACK (add_empty_route_row)); for (i = 0; i < nm_setting_ip_config_get_num_routes (page->setting); i++) { NMIPRoute *route; char *prefix, *metric; route = nm_setting_ip_config_get_route (page->setting, i); prefix = g_strdup_printf ("%u", nm_ip_route_get_prefix (route)); metric = g_strdup_printf ("%u", (guint32) MIN (0, nm_ip_route_get_metric (route))); add_route_row (page, nm_ip_route_get_dest (route), prefix, nm_ip_route_get_next_hop (route), metric); g_free (prefix); g_free (metric); } if (nm_setting_ip_config_get_num_routes (page->setting) == 0) add_empty_route_row (page); gtk_widget_show_all (widget); } static void connect_ip6_page (CEPageIP6 *page) { GtkWidget *content; const gchar *str_method; gboolean disabled; GtkListStore *store; GtkTreeIter iter; guint method; add_address_section (page); add_dns_section (page); add_routes_section (page); page->enabled = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "switch_enable")); g_signal_connect (page->enabled, "notify::active", G_CALLBACK (switch_toggled), page); str_method = nm_setting_ip_config_get_method (page->setting); disabled = g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0; gtk_switch_set_active (page->enabled, !disabled); g_signal_connect_swapped (page->enabled, "notify::active", G_CALLBACK (ce_page_changed), page); content = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "page_content")); g_object_bind_property (page->enabled, "active", content, "sensitive", G_BINDING_SYNC_CREATE); page->method = GTK_COMBO_BOX (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_addresses")); store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_UINT); gtk_list_store_insert_with_values (store, &iter, -1, METHOD_COL_NAME, _("Automatic"), METHOD_COL_METHOD, IP6_METHOD_AUTO, -1); gtk_list_store_insert_with_values (store, &iter, -1, METHOD_COL_NAME, _("Automatic, DHCP only"), METHOD_COL_METHOD, IP6_METHOD_DHCP, -1); gtk_list_store_insert_with_values (store, &iter, -1, METHOD_COL_NAME, _("Manual"), METHOD_COL_METHOD, IP6_METHOD_MANUAL, -1); gtk_list_store_insert_with_values (store, &iter, -1, METHOD_COL_NAME, _("Link-Local Only"), METHOD_COL_METHOD, IP6_METHOD_LINK_LOCAL, -1); gtk_combo_box_set_model (page->method, GTK_TREE_MODEL (store)); g_object_unref (G_OBJECT (store)); method = IP6_METHOD_AUTO; if (g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0) { method = IP6_METHOD_DHCP; } else if (g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0) { method = IP6_METHOD_LINK_LOCAL; } else if (g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0) { method = IP6_METHOD_MANUAL; } else if (g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_SHARED) == 0) { method = IP6_METHOD_SHARED; } else if (g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) { method = IP6_METHOD_IGNORE; } page->never_default = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "never_default_check")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (page->never_default), nm_setting_ip_config_get_never_default (page->setting)); g_signal_connect_swapped (page->never_default, "toggled", G_CALLBACK (ce_page_changed), page); g_signal_connect (page->method, "changed", G_CALLBACK (method_changed), page); if (method != IP6_METHOD_SHARED && method != IP6_METHOD_IGNORE) gtk_combo_box_set_active (page->method, method); } static gboolean ui_to_setting (CEPageIP6 *page) { const gchar *method; gboolean ignore_auto_dns; gboolean ignore_auto_routes; gboolean never_default; GList *children, *l; gboolean ret = TRUE; if (!gtk_switch_get_active (page->enabled)) { method = NM_SETTING_IP6_CONFIG_METHOD_IGNORE; } else { switch (gtk_combo_box_get_active (page->method)) { case IP6_METHOD_MANUAL: method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL; break; case IP6_METHOD_LINK_LOCAL: method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL; break; case IP6_METHOD_DHCP: method = NM_SETTING_IP6_CONFIG_METHOD_DHCP; break; default: case IP6_METHOD_AUTO: method = NM_SETTING_IP6_CONFIG_METHOD_AUTO; break; } } nm_setting_ip_config_clear_addresses (page->setting); if (g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { children = gtk_container_get_children (GTK_CONTAINER (page->address_list)); } else { g_object_set (G_OBJECT (page->setting), NM_SETTING_IP_CONFIG_GATEWAY, NULL, NULL); children = NULL; } for (l = children; l; l = l->next) { GtkWidget *row = l->data; GtkEntry *entry; const gchar *text_address; const gchar *text_prefix; const gchar *text_gateway; guint32 prefix; gchar *end; NMIPAddress *addr; gboolean have_gateway = FALSE; entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address")); if (!entry) continue; text_address = gtk_entry_get_text (entry); text_prefix = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "prefix"))); text_gateway = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "gateway"))); if (!*text_address && !*text_prefix && !*text_gateway) { /* ignore empty rows */ widget_unset_error (GTK_WIDGET (entry)); widget_unset_error (g_object_get_data (G_OBJECT (row), "prefix")); widget_unset_error (g_object_get_data (G_OBJECT (row), "gateway")); continue; } if (!text_address || !nm_utils_ipaddr_valid (AF_INET6, text_address)) { widget_set_error (GTK_WIDGET (entry)); ret = FALSE; } else { widget_unset_error (GTK_WIDGET (entry)); } prefix = strtoul (text_prefix, &end, 10); if (!end || *end || prefix == 0 || prefix > 128) { widget_set_error (g_object_get_data (G_OBJECT (row), "prefix")); ret = FALSE; } else { widget_unset_error (g_object_get_data (G_OBJECT (row), "prefix")); } if (text_gateway && !nm_utils_ipaddr_valid (AF_INET6, text_gateway)) { widget_set_error (g_object_get_data (G_OBJECT (row), "gateway")); ret = FALSE; } else { widget_unset_error (g_object_get_data (G_OBJECT (row), "gateway")); have_gateway = TRUE; } if (!ret) continue; addr = nm_ip_address_new (AF_INET6, text_address, prefix, NULL); if (have_gateway) g_object_set (G_OBJECT (page->setting), NM_SETTING_IP_CONFIG_GATEWAY, text_gateway, NULL); nm_setting_ip_config_add_address (page->setting, addr); } g_list_free (children); nm_setting_ip_config_clear_dns (page->setting); if (g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) || g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) || g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) children = gtk_container_get_children (GTK_CONTAINER (page->dns_list)); else children = NULL; for (l = children; l; l = l->next) { GtkWidget *row = l->data; GtkEntry *entry; const gchar *text; struct in6_addr tmp_addr; entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address")); if (!entry) continue; text = gtk_entry_get_text (entry); if (!*text) { /* ignore empty rows */ widget_unset_error (GTK_WIDGET (entry)); continue; } if (inet_pton (AF_INET6, text, &tmp_addr) <= 0) { widget_set_error (GTK_WIDGET (entry)); ret = FALSE; } else { widget_unset_error (GTK_WIDGET (entry)); nm_setting_ip_config_add_dns (page->setting, text); } } g_list_free (children); nm_setting_ip_config_clear_routes (page->setting); if (g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) || g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) || g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) children = gtk_container_get_children (GTK_CONTAINER (page->routes_list)); else children = NULL; for (l = children; l; l = l->next) { GtkWidget *row = l->data; GtkEntry *entry; const gchar *text_address; const gchar *text_prefix; const gchar *text_gateway; const gchar *text_metric; guint32 prefix, metric; gchar *end; NMIPRoute *route; entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address")); if (!entry) continue; text_address = gtk_entry_get_text (entry); text_prefix = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "prefix"))); text_gateway = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "gateway"))); text_metric = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "metric"))); if (!*text_address && !*text_prefix && !*text_gateway && !*text_metric) { /* ignore empty rows */ widget_unset_error (GTK_WIDGET (entry)); widget_unset_error (g_object_get_data (G_OBJECT (row), "prefix")); widget_unset_error (g_object_get_data (G_OBJECT (row), "gateway")); widget_unset_error (g_object_get_data (G_OBJECT (row), "metric")); continue; } if (!nm_utils_ipaddr_valid (AF_INET6, text_address)) { widget_set_error (GTK_WIDGET (entry)); ret = FALSE; } else { widget_unset_error (GTK_WIDGET (entry)); } prefix = strtoul (text_prefix, &end, 10); if (!end || *end || prefix == 0 || prefix > 128) { widget_set_error (g_object_get_data (G_OBJECT (row), "prefix")); ret = FALSE; } else { widget_unset_error (g_object_get_data (G_OBJECT (row), "prefix")); } if (!nm_utils_ipaddr_valid (AF_INET6, text_gateway)) { widget_set_error (g_object_get_data (G_OBJECT (row), "gateway")); ret = FALSE; } else { widget_unset_error (g_object_get_data (G_OBJECT (row), "gateway")); } metric = 0; if (*text_metric) { errno = 0; metric = strtoul (text_metric, NULL, 10); if (errno) { widget_set_error (g_object_get_data (G_OBJECT (row), "metric")); ret = FALSE; } else { widget_unset_error (g_object_get_data (G_OBJECT (row), "metric")); } } else { widget_unset_error (g_object_get_data (G_OBJECT (row), "metric")); } if (!ret) continue; route = nm_ip_route_new (AF_INET6, text_address, prefix, text_gateway, metric, NULL); nm_setting_ip_config_add_route (page->setting, route); nm_ip_route_unref (route); } g_list_free (children); if (!ret) goto out; ignore_auto_dns = !gtk_switch_get_active (page->auto_dns); ignore_auto_routes = !gtk_switch_get_active (page->auto_routes); never_default = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (page->never_default)); g_object_set (page->setting, NM_SETTING_IP_CONFIG_METHOD, method, NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, ignore_auto_dns, NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, ignore_auto_routes, NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default, NULL); out: return ret; } static gboolean validate (CEPage *page, NMConnection *connection, GError **error) { if (!ui_to_setting (CE_PAGE_IP6 (page))) return FALSE; return nm_setting_verify (NM_SETTING (CE_PAGE_IP6 (page)->setting), NULL, error); } static void ce_page_ip6_init (CEPageIP6 *page) { } static void ce_page_ip6_class_init (CEPageIP6Class *class) { CEPageClass *page_class= CE_PAGE_CLASS (class); page_class->validate = validate; } CEPage * ce_page_ip6_new (NMConnection *connection, NMClient *client) { CEPageIP6 *page; page = CE_PAGE_IP6 (ce_page_new (CE_TYPE_PAGE_IP6, connection, client, "/org/cinnamon/control-center/network/ip6-page.ui", _("IPv6"))); page->setting = nm_connection_get_setting_ip6_config (connection); if (!page->setting) { page->setting = NM_SETTING_IP_CONFIG (nm_setting_ip6_config_new ()); nm_connection_add_setting (connection, NM_SETTING (page->setting)); } connect_ip6_page (page); return CE_PAGE (page); } cinnamon-control-center-6.4.1/panels/network/connection-editor/connection-editor.ui0000664000175000017500000002235314724311620027571 0ustar fabiofabio False 5 False True 600 300 dialog False vertical 2 False end end _Cancel True True True True False True 0 _Apply True True True True False True 1 False True end 0 True True False False True False True True never in True True details_store False False False 10 0 20 True True 0 True True False False False True 1 True False page 1 False True False True False vertical 300 True False 0 in False True 0 True False 0 1 True False page 2 1 False True True 1 details_cancel_button details_apply_button cinnamon-control-center-6.4.1/panels/network/connection-editor/meson.build0000664000175000017500000000141014724311620025740 0ustar fabiofabio libconnection_editor_sources = [ 'ce-page-8021x-security.c', 'ce-page-details.c', 'ce-page-ethernet.c', 'ce-page-ip4.c', 'ce-page-ip6.c', 'ce-page-reset.c', 'ce-page-security.c', 'ce-page-vpn.c', 'ce-page-wifi.c', 'ce-page.c', 'firewall-helpers.c', 'net-connection-editor.c', 'ui-helpers.c', 'vpn-helpers.c', gnome.compile_resources('net-connection-editor-resources', 'connection-editor.gresource.xml', c_name: 'net_connection_editor', source_dir: meson.current_source_dir(), ), ] libconnection_editor = static_library('connection_editor', libconnection_editor_sources, include_directories: [ rootInclude, wireless_securityInclude ], link_whole: [ libwireless_security, ], dependencies: [ gtk, libnm, ], ) cinnamon-control-center-6.4.1/panels/network/connection-editor/ip6-page.ui0000664000175000017500000003516214724311620025560 0ustar fabiofabio True True never True False True False 20 20 10 10 vertical 10 True False True False IPv_6 True switch_enable False True 0 True True end True False True 1 False True 0 True False vertical 10 True False True False _Addresses True combo_addresses False True 0 True False end True 0 1 False True 1 False True 0 True False vertical False True 1 True False 24 6 6 True False 0 DNS False True 0 True False True 1 Automatic False True 1 True True end Automatic DNS False True 2 False True 2 True False vertical False True 3 True False 24 5 6 True False 0 Routes False True 0 True False True 1 Automatic False True 1 True True Automatic Routes False True 2 False True 4 True False vertical False True 5 Use this connection _only for resources on its network True True False True 0 True False True 7 False True 1 cinnamon-control-center-6.4.1/panels/network/connection-editor/wifi-page.ui0000664000175000017500000001567314724311620026025 0ustar fabiofabio True False 50 50 12 12 True True 10 6 True False 1 _SSID True entry_ssid 0 0 1 1 True False 1 _BSSID True combo_bssid 0 1 1 1 True True True ā— My Home Network True 1 0 1 1 True False 1 _MAC Address True combo_mac 0 2 1 1 True True True ā— True 1 3 1 1 True False _Cloned Address True entry_cloned_mac 0 3 1 1 True False True 0 1 1 1 1 1 True False True 0 1 1 2 1 1 Make available to _other users True True False True 0 True 0 6 2 1 Connect _automatically True True False end True True 0 True 0 5 2 1 cinnamon-control-center-6.4.1/panels/network/connection-editor/ce-page-ethernet.c0000664000175000017500000002142114724311620027063 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Red Hat, Inc * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include "firewall-helpers.h" #include "ce-page-ethernet.h" #include "ui-helpers.h" G_DEFINE_TYPE (CEPageEthernet, ce_page_ethernet, CE_TYPE_PAGE) static void all_user_changed (GtkToggleButton *b, CEPageEthernet *page) { gboolean all_users; NMSettingConnection *sc; sc = nm_connection_get_setting_connection (CE_PAGE (page)->connection); all_users = gtk_toggle_button_get_active (b); g_object_set (sc, "permissions", NULL, NULL); if (!all_users) nm_setting_connection_add_permission (sc, "user", g_get_user_name (), NULL); } static void mtu_changed (GtkSpinButton *mtu, CEPageEthernet *page) { if (gtk_spin_button_get_value_as_int (mtu) == 0) gtk_widget_hide (page->mtu_label); else gtk_widget_show (page->mtu_label); } static void connect_ethernet_page (CEPageEthernet *page) { NMSettingWired *setting = page->setting_wired; NMSettingConnection *sc; int mtu_def; char **mac_list; const char *s_mac_str; GtkWidget *widget; GtkWidget *heading; const gchar *name; const gchar *cloned_mac; name = nm_setting_connection_get_id (page->setting_connection); gtk_entry_set_text (page->name, name); /* Device MAC address */ mac_list = ce_page_get_mac_list (CE_PAGE (page)->client, NM_TYPE_DEVICE_ETHERNET, NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS); s_mac_str = nm_setting_wired_get_mac_address (setting); ce_page_setup_mac_combo (page->device_mac, s_mac_str, mac_list); g_strfreev (mac_list); g_signal_connect_swapped (page->device_mac, "changed", G_CALLBACK (ce_page_changed), page); /* Cloned MAC address */ cloned_mac = nm_setting_wired_get_cloned_mac_address (setting); gtk_entry_set_text (GTK_ENTRY (page->cloned_mac), cloned_mac ? cloned_mac : ""); g_signal_connect_swapped (page->cloned_mac, "changed", G_CALLBACK (ce_page_changed), page); /* MTU */ mtu_def = ce_get_property_default (NM_SETTING (setting), NM_SETTING_WIRED_MTU); g_signal_connect (page->mtu, "output", G_CALLBACK (ce_spin_output_with_default), GINT_TO_POINTER (mtu_def)); gtk_spin_button_set_value (page->mtu, (gdouble) nm_setting_wired_get_mtu (setting)); g_signal_connect (page->mtu, "value-changed", G_CALLBACK (mtu_changed), page); mtu_changed (page->mtu, page); g_signal_connect_swapped (page->name, "changed", G_CALLBACK (ce_page_changed), page); g_signal_connect_swapped (page->mtu, "value-changed", G_CALLBACK (ce_page_changed), page); widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_connect_check")); sc = nm_connection_get_setting_connection (CE_PAGE (page)->connection); g_object_bind_property (sc, "autoconnect", widget, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); g_signal_connect_swapped (widget, "toggled", G_CALLBACK (ce_page_changed), page); widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "all_user_check")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), nm_setting_connection_get_num_permissions (sc) == 0); g_signal_connect (widget, "toggled", G_CALLBACK (all_user_changed), page); g_signal_connect_swapped (widget, "toggled", G_CALLBACK (ce_page_changed), page); widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_zone")); heading = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "heading_zone")); firewall_ui_setup (sc, widget, heading, CE_PAGE (page)->cancellable); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); } static void ui_to_setting (CEPageEthernet *page) { gchar *device_mac = NULL; gchar *cloned_mac; const gchar *text; GtkWidget *entry; entry = gtk_bin_get_child (GTK_BIN (page->device_mac)); if (entry) { text = gtk_entry_get_text (GTK_ENTRY (entry)); device_mac = ce_page_trim_address (text); } text = gtk_entry_get_text (GTK_ENTRY (entry)); cloned_mac = ce_page_trim_address (text); g_object_set (page->setting_wired, NM_SETTING_WIRED_MAC_ADDRESS, device_mac, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, cloned_mac, NM_SETTING_WIRED_MTU, (guint32) gtk_spin_button_get_value_as_int (page->mtu), NULL); g_object_set (page->setting_connection, NM_SETTING_CONNECTION_ID, gtk_entry_get_text (page->name), NULL); entry = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_zone")); firewall_ui_to_setting (page->setting_connection, entry); g_free (cloned_mac); g_free (device_mac); } static gboolean validate (CEPage *page, NMConnection *connection, GError **error) { CEPageEthernet *self = CE_PAGE_ETHERNET (page); GtkWidget *entry; gboolean ret = TRUE; entry = gtk_bin_get_child (GTK_BIN (self->device_mac)); if (entry) { if (!ce_page_address_is_valid (gtk_entry_get_text (GTK_ENTRY (entry)))) { widget_set_error (entry); ret = FALSE; } else { widget_unset_error (entry); } } if (!ce_page_address_is_valid (gtk_entry_get_text (GTK_ENTRY (self->cloned_mac)))) { widget_set_error (GTK_WIDGET (self->cloned_mac)); ret = FALSE; } else { widget_unset_error (GTK_WIDGET (self->cloned_mac)); } if (!ret) return ret; ui_to_setting (self); return nm_setting_verify (NM_SETTING (self->setting_connection), NULL, error) && nm_setting_verify (NM_SETTING (self->setting_wired), NULL, error); } static void ce_page_ethernet_init (CEPageEthernet *page) { } static void ce_page_ethernet_class_init (CEPageEthernetClass *class) { CEPageClass *page_class= CE_PAGE_CLASS (class); page_class->validate = validate; } CEPage * ce_page_ethernet_new (NMConnection *connection, NMClient *client) { CEPageEthernet *page; page = CE_PAGE_ETHERNET (ce_page_new (CE_TYPE_PAGE_ETHERNET, connection, client, "/org/cinnamon/control-center/network/ethernet-page.ui", _("Identity"))); page->name = GTK_ENTRY (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_name")); page->device_mac = GTK_COMBO_BOX_TEXT (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_mac")); page->cloned_mac = GTK_ENTRY (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_cloned_mac")); page->mtu = GTK_SPIN_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "spin_mtu")); page->mtu_label = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "label_mtu")); page->setting_connection = nm_connection_get_setting_connection (connection); page->setting_wired = nm_connection_get_setting_wired (connection); connect_ethernet_page (page); return CE_PAGE (page); } cinnamon-control-center-6.4.1/panels/network/connection-editor/ce-page-security.c0000664000175000017500000004420514724311620027121 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Red Hat, Inc * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include "wireless-security.h" #include "ce-page-security.h" #include "firewall-helpers.h" G_DEFINE_TYPE (CEPageSecurity, ce_page_security, CE_TYPE_PAGE) enum { S_NAME_COLUMN, S_SEC_COLUMN, S_ADHOC_VALID_COLUMN }; static gboolean find_proto (NMSettingWirelessSecurity *sec, const char *item) { guint32 i; for (i = 0; i < nm_setting_wireless_security_get_num_protos (sec); i++) { if (!strcmp (item, nm_setting_wireless_security_get_proto (sec, i))) return TRUE; } return FALSE; } static NMUtilsSecurityType get_default_type_for_security (NMSettingWirelessSecurity *sec) { const char *key_mgmt, *auth_alg; g_return_val_if_fail (sec != NULL, NMU_SEC_NONE); key_mgmt = nm_setting_wireless_security_get_key_mgmt (sec); auth_alg = nm_setting_wireless_security_get_auth_alg (sec); /* No IEEE 802.1x */ if (!strcmp (key_mgmt, "none")) return NMU_SEC_STATIC_WEP; if (!strcmp (key_mgmt, "ieee8021x")) { if (auth_alg && !strcmp (auth_alg, "leap")) return NMU_SEC_LEAP; return NMU_SEC_DYNAMIC_WEP; } if ( !strcmp (key_mgmt, "wpa-none") || !strcmp (key_mgmt, "wpa-psk")) { if (find_proto (sec, "rsn")) return NMU_SEC_WPA2_PSK; else if (find_proto (sec, "wpa")) return NMU_SEC_WPA_PSK; else return NMU_SEC_WPA_PSK; } if (!strcmp (key_mgmt, "wpa-eap")) { if (find_proto (sec, "rsn")) return NMU_SEC_WPA2_ENTERPRISE; else if (find_proto (sec, "wpa")) return NMU_SEC_WPA_ENTERPRISE; else return NMU_SEC_WPA_ENTERPRISE; } return NMU_SEC_INVALID; } static WirelessSecurity * security_combo_get_active (CEPageSecurity *page) { GtkTreeIter iter; GtkTreeModel *model; WirelessSecurity *sec = NULL; model = gtk_combo_box_get_model (page->security_combo); gtk_combo_box_get_active_iter (page->security_combo, &iter); gtk_tree_model_get (model, &iter, S_SEC_COLUMN, &sec, -1); return sec; } static void wsec_size_group_clear (GtkSizeGroup *group) { GSList *children; GSList *iter; g_return_if_fail (group != NULL); children = gtk_size_group_get_widgets (group); for (iter = children; iter; iter = g_slist_next (iter)) gtk_size_group_remove_widget (group, GTK_WIDGET (iter->data)); } static void security_combo_changed (GtkComboBox *combo, gpointer user_data) { CEPageSecurity *page = CE_PAGE_SECURITY (user_data); GtkWidget *vbox; GList *l, *children; WirelessSecurity *sec; wsec_size_group_clear (page->group); vbox = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "vbox")); children = gtk_container_get_children (GTK_CONTAINER (vbox)); for (l = children; l; l = l->next) { gtk_container_remove (GTK_CONTAINER (vbox), GTK_WIDGET (l->data)); } sec = security_combo_get_active (page); if (sec) { GtkWidget *sec_widget; GtkWidget *parent; sec_widget = wireless_security_get_widget (sec); g_assert (sec_widget); parent = gtk_widget_get_parent (sec_widget); if (parent) gtk_container_remove (GTK_CONTAINER (parent), sec_widget); gtk_size_group_add_widget (page->group, page->security_heading); gtk_size_group_add_widget (page->group, page->firewall_heading); wireless_security_add_to_size_group (sec, page->group); gtk_container_add (GTK_CONTAINER (vbox), sec_widget); wireless_security_unref (sec); } ce_page_changed (CE_PAGE (page)); } static void stuff_changed_cb (WirelessSecurity *sec, gpointer user_data) { ce_page_changed (CE_PAGE (user_data)); } static void add_security_item (CEPageSecurity *page, WirelessSecurity *sec, GtkListStore *model, GtkTreeIter *iter, const char *text, gboolean adhoc_valid) { wireless_security_set_changed_notify (sec, stuff_changed_cb, page); gtk_list_store_append (model, iter); gtk_list_store_set (model, iter, S_NAME_COLUMN, text, S_SEC_COLUMN, sec, S_ADHOC_VALID_COLUMN, adhoc_valid, -1); wireless_security_unref (sec); } static void set_sensitive (GtkCellLayout *cell_layout, GtkCellRenderer *cell, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) { gboolean *adhoc = data; gboolean sensitive = TRUE, adhoc_valid = TRUE; gtk_tree_model_get (tree_model, iter, S_ADHOC_VALID_COLUMN, &adhoc_valid, -1); if (*adhoc && !adhoc_valid) sensitive = FALSE; g_object_set (cell, "sensitive", sensitive, NULL); } static void finish_setup (CEPageSecurity *page) { NMConnection *connection = CE_PAGE (page)->connection; NMSettingWireless *sw; NMSettingWirelessSecurity *sws; NMSettingConnection *sc; gboolean is_adhoc = FALSE; GtkListStore *sec_model; GtkTreeIter iter; const gchar *mode; guint32 dev_caps = 0; NMUtilsSecurityType default_type = NMU_SEC_NONE; int active = -1; int item = 0; GtkComboBox *combo; GtkCellRenderer *renderer; sw = nm_connection_get_setting_wireless (connection); g_assert (sw); page->group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); page->security_heading = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "heading_sec")); page->security_combo = combo = GTK_COMBO_BOX (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_sec")); dev_caps = NM_WIFI_DEVICE_CAP_CIPHER_WEP40 | NM_WIFI_DEVICE_CAP_CIPHER_WEP104 | NM_WIFI_DEVICE_CAP_CIPHER_TKIP | NM_WIFI_DEVICE_CAP_CIPHER_CCMP | NM_WIFI_DEVICE_CAP_WPA | NM_WIFI_DEVICE_CAP_RSN; mode = nm_setting_wireless_get_mode (sw); if (mode && !strcmp (mode, "adhoc")) is_adhoc = TRUE; page->adhoc = is_adhoc; sws = nm_connection_get_setting_wireless_security (connection); if (sws) default_type = get_default_type_for_security (sws); sec_model = gtk_list_store_new (3, G_TYPE_STRING, wireless_security_get_type (), G_TYPE_BOOLEAN); if (nm_utils_security_valid (NMU_SEC_NONE, dev_caps, FALSE, is_adhoc, 0, 0, 0)) { gtk_list_store_insert_with_values (sec_model, &iter, -1, S_NAME_COLUMN, C_("Wi-Fi/Ethernet security", "None"), S_ADHOC_VALID_COLUMN, TRUE, -1); if (default_type == NMU_SEC_NONE) active = item; item++; } if (nm_utils_security_valid (NMU_SEC_STATIC_WEP, dev_caps, FALSE, is_adhoc, 0, 0, 0)) { WirelessSecurityWEPKey *ws_wep; NMWepKeyType wep_type = NM_WEP_KEY_TYPE_KEY; if (default_type == NMU_SEC_STATIC_WEP) { sws = nm_connection_get_setting_wireless_security (connection); if (sws) wep_type = nm_setting_wireless_security_get_wep_key_type (sws); if (wep_type == NM_WEP_KEY_TYPE_UNKNOWN) wep_type = NM_WEP_KEY_TYPE_KEY; } ws_wep = ws_wep_key_new (connection, NM_WEP_KEY_TYPE_KEY, FALSE, FALSE); if (ws_wep) { add_security_item (page, WIRELESS_SECURITY (ws_wep), sec_model, &iter, _("WEP 40/128-bit Key (Hex or ASCII)"), TRUE); if ((active < 0) && (default_type == NMU_SEC_STATIC_WEP) && (wep_type == NM_WEP_KEY_TYPE_KEY)) active = item; item++; } ws_wep = ws_wep_key_new (connection, NM_WEP_KEY_TYPE_PASSPHRASE, FALSE, FALSE); if (ws_wep) { add_security_item (page, WIRELESS_SECURITY (ws_wep), sec_model, &iter, _("WEP 128-bit Passphrase"), TRUE); if ((active < 0) && (default_type == NMU_SEC_STATIC_WEP) && (wep_type == NM_WEP_KEY_TYPE_PASSPHRASE)) active = item; item++; } } if (nm_utils_security_valid (NMU_SEC_LEAP, dev_caps, FALSE, is_adhoc, 0, 0, 0)) { WirelessSecurityLEAP *ws_leap; ws_leap = ws_leap_new (connection, FALSE); if (ws_leap) { add_security_item (page, WIRELESS_SECURITY (ws_leap), sec_model, &iter, _("LEAP"), FALSE); if ((active < 0) && (default_type == NMU_SEC_LEAP)) active = item; item++; } } if (nm_utils_security_valid (NMU_SEC_DYNAMIC_WEP, dev_caps, FALSE, is_adhoc, 0, 0, 0)) { WirelessSecurityDynamicWEP *ws_dynamic_wep; ws_dynamic_wep = ws_dynamic_wep_new (connection, TRUE, FALSE); if (ws_dynamic_wep) { add_security_item (page, WIRELESS_SECURITY (ws_dynamic_wep), sec_model, &iter, _("Dynamic WEP (802.1x)"), FALSE); if ((active < 0) && (default_type == NMU_SEC_DYNAMIC_WEP)) active = item; item++; } } if (nm_utils_security_valid (NMU_SEC_WPA_PSK, dev_caps, FALSE, is_adhoc, 0, 0, 0) || nm_utils_security_valid (NMU_SEC_WPA2_PSK, dev_caps, FALSE, is_adhoc, 0, 0, 0)) { WirelessSecurityWPAPSK *ws_wpa_psk; ws_wpa_psk = ws_wpa_psk_new (connection, FALSE); if (ws_wpa_psk) { add_security_item (page, WIRELESS_SECURITY (ws_wpa_psk), sec_model, &iter, _("WPA & WPA2 Personal"), FALSE); if ((active < 0) && ((default_type == NMU_SEC_WPA_PSK) || (default_type == NMU_SEC_WPA2_PSK))) active = item; item++; } } if (nm_utils_security_valid (NMU_SEC_WPA_ENTERPRISE, dev_caps, FALSE, is_adhoc, 0, 0, 0) || nm_utils_security_valid (NMU_SEC_WPA2_ENTERPRISE, dev_caps, FALSE, is_adhoc, 0, 0, 0)) { WirelessSecurityWPAEAP *ws_wpa_eap; ws_wpa_eap = ws_wpa_eap_new (connection, TRUE, FALSE); if (ws_wpa_eap) { add_security_item (page, WIRELESS_SECURITY (ws_wpa_eap), sec_model, &iter, _("WPA & WPA2 Enterprise"), FALSE); if ((active < 0) && ((default_type == NMU_SEC_WPA_ENTERPRISE) || (default_type == NMU_SEC_WPA2_ENTERPRISE))) active = item; item++; } } gtk_combo_box_set_model (combo, GTK_TREE_MODEL (sec_model)); gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo)); renderer = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "text", S_NAME_COLUMN, NULL); gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo), renderer, set_sensitive, &page->adhoc, NULL); gtk_combo_box_set_active (combo, active < 0 ? 0 : (guint32) active); g_object_unref (G_OBJECT (sec_model)); page->security_combo = combo; page->firewall_heading = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "heading_zone")); page->firewall_combo = GTK_COMBO_BOX (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_zone")); sc = nm_connection_get_setting_connection (CE_PAGE (page)->connection); firewall_ui_setup (sc, GTK_WIDGET (page->firewall_combo), page->firewall_heading, CE_PAGE (page)->cancellable); g_signal_connect_swapped (page->firewall_combo, "changed", G_CALLBACK (ce_page_changed), page); security_combo_changed (combo, page); g_signal_connect (combo, "changed", G_CALLBACK (security_combo_changed), page); } static gboolean validate (CEPage *page, NMConnection *connection, GError **error) { NMSettingWireless *sw; NMSettingConnection *sc; WirelessSecurity *sec; gboolean valid = FALSE; const char *mode; sw = nm_connection_get_setting_wireless (connection); mode = nm_setting_wireless_get_mode (sw); if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC) == 0) CE_PAGE_SECURITY (page)->adhoc = TRUE; else CE_PAGE_SECURITY (page)->adhoc = FALSE; sec = security_combo_get_active (CE_PAGE_SECURITY (page)); if (sec) { GBytes *ssid = nm_setting_wireless_get_ssid (sw); if (ssid) { /* FIXME: get failed property and error out of wifi security objects */ valid = wireless_security_validate (sec, error); if (valid) wireless_security_fill_connection (sec, connection); } else { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_SETTING, "Missing SSID"); valid = FALSE; } if (CE_PAGE_SECURITY (page)->adhoc) { if (!wireless_security_adhoc_compatible (sec)) { if (valid) g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING, "Security not compatible with Ad-Hoc mode"); valid = FALSE; } } wireless_security_unref (sec); } else { /* No security, unencrypted */ nm_connection_remove_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); nm_connection_remove_setting (connection, NM_TYPE_SETTING_802_1X); valid = TRUE; } sc = nm_connection_get_setting_connection (connection); firewall_ui_to_setting (sc, GTK_WIDGET (CE_PAGE_SECURITY (page)->firewall_combo)); return valid; } static void ce_page_security_init (CEPageSecurity *page) { } static void dispose (GObject *object) { CEPageSecurity *page = CE_PAGE_SECURITY (object); g_clear_object (&page->group); G_OBJECT_CLASS (ce_page_security_parent_class)->dispose (object); } static void ce_page_security_class_init (CEPageSecurityClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); CEPageClass *page_class = CE_PAGE_CLASS (class); object_class->dispose = dispose; page_class->validate = validate; } CEPage * ce_page_security_new (NMConnection *connection, NMClient *client) { CEPageSecurity *page; NMUtilsSecurityType default_type = NMU_SEC_NONE; NMSettingWirelessSecurity *sws; page = CE_PAGE_SECURITY (ce_page_new (CE_TYPE_PAGE_SECURITY, connection, client, "/org/cinnamon/control-center/network/security-page.ui", _("Security"))); sws = nm_connection_get_setting_wireless_security (connection); if (sws) default_type = get_default_type_for_security (sws); if (default_type == NMU_SEC_STATIC_WEP || default_type == NMU_SEC_LEAP || default_type == NMU_SEC_WPA_PSK || default_type == NMU_SEC_WPA2_PSK) { CE_PAGE (page)->security_setting = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME; } if (default_type == NMU_SEC_DYNAMIC_WEP || default_type == NMU_SEC_WPA_ENTERPRISE || default_type == NMU_SEC_WPA2_ENTERPRISE) { CE_PAGE (page)->security_setting = NM_SETTING_802_1X_SETTING_NAME; } g_signal_connect (page, "initialized", G_CALLBACK (finish_setup), NULL); return CE_PAGE (page); } cinnamon-control-center-6.4.1/panels/network/connection-editor/vpn-page.ui0000664000175000017500000001200214724311620025651 0ustar fabiofabio True False 50 50 12 12 vertical 10 True False 6 True False 1 _Name True entry_name False True 0 True True ā— True True True 1 False True 0 True False 6 True False Firewall _Zone True combo_zone False True 0 True False 0 1 True True 1 False True 1 Make available to other _users True True False True 0 True False True 2 True False 0 (Error: unable to load VPN connection editor) False True 3 cinnamon-control-center-6.4.1/panels/network/connection-editor/firewall-helpers.h0000664000175000017500000000236014724311620027221 0ustar fabiofabio/* * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (C) Copyright 2013 Red Hat, Inc. */ #ifndef _FIREWALL_HELPERS_H_ #define _FIREWALL_HELPERS_H_ #include #include void firewall_ui_setup (NMSettingConnection *setting, GtkWidget *combo, GtkWidget *label, GCancellable *cancellable); void firewall_ui_to_setting (NMSettingConnection *setting, GtkWidget *combo); #endif /* _FIREWALL_HELPERS_H_ */ cinnamon-control-center-6.4.1/panels/network/connection-editor/ui-helpers.h0000664000175000017500000000167114724311620026035 0ustar fabiofabio/* * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (C) Copyright 2014 Red Hat, Inc. */ #ifndef _UI_HELPERS_H_ #define _UI_HELPERS_H_ #include void widget_set_error (GtkWidget *widget); void widget_unset_error (GtkWidget *widget); #endif /* _UI_HELPERS_H_ */ cinnamon-control-center-6.4.1/panels/network/connection-editor/ce-page-vpn.c0000664000175000017500000001733614724311620026062 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2013 Red Hat, Inc * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include "ce-page-vpn.h" #include "vpn-helpers.h" #include "firewall-helpers.h" G_DEFINE_TYPE (CEPageVpn, ce_page_vpn, CE_TYPE_PAGE) static void all_user_changed (GtkToggleButton *b, CEPageVpn *page) { gboolean all_users; NMSettingConnection *sc; sc = nm_connection_get_setting_connection (CE_PAGE (page)->connection); all_users = gtk_toggle_button_get_active (b); g_object_set (sc, "permissions", NULL, NULL); if (!all_users) nm_setting_connection_add_permission (sc, "user", g_get_user_name (), NULL); } /* Hack to make the plugin-provided editor widget fit in better with * the control center by changing * * Foo: [__________] * Bar baz: [__________] * * to * * Foo [__________] * Bar baz [__________] */ static void vpn_cinnamonify_editor (GtkWidget *widget) { if (GTK_IS_CONTAINER (widget)) { GList *children, *iter; children = gtk_container_get_children (GTK_CONTAINER (widget)); for (iter = children; iter; iter = iter->next) vpn_cinnamonify_editor (iter->data); g_list_free (children); } else if (GTK_IS_LABEL (widget)) { const char *text; gfloat xalign; char *newtext; int len; xalign = gtk_label_get_xalign (GTK_LABEL (widget)); if (xalign != 0.0) return; text = gtk_label_get_text (GTK_LABEL (widget)); len = strlen (text); if (len < 2 || text[len - 1] != ':') return; newtext = g_strndup (text, len - 1); gtk_label_set_text (GTK_LABEL (widget), newtext); g_free (newtext); gtk_label_set_xalign (GTK_LABEL (widget), 1.0); } } static void load_vpn_plugin (CEPageVpn *page, NMConnection *connection) { CEPage *parent = CE_PAGE (page); GtkWidget *ui_widget, *failure; GError *err = NULL; page->editor = nm_vpn_editor_plugin_get_editor (page->plugin, connection, &err); ui_widget = NULL; if (page->editor) ui_widget = GTK_WIDGET (nm_vpn_editor_get_widget (page->editor)); if (!ui_widget) { g_clear_object (&page->editor); page->plugin = NULL; g_warning ("Could not load editor VPN plugin for '%s' (%s).", nm_setting_vpn_get_service_type (nm_connection_get_setting_vpn (connection)), err ? err->message : "Unknown error"); g_error_free (err); return; } vpn_cinnamonify_editor (ui_widget); failure = GTK_WIDGET (gtk_builder_get_object (parent->builder, "failure_label")); gtk_widget_destroy (failure); gtk_box_pack_start (page->box, ui_widget, TRUE, TRUE, 0); gtk_widget_show_all (ui_widget); g_signal_connect_swapped (page->editor, "changed", G_CALLBACK (ce_page_changed), page); } static void connect_vpn_page (CEPageVpn *page) { const gchar *name; GtkWidget *widget; GtkWidget *heading; name = nm_setting_connection_get_id (page->setting_connection); gtk_entry_set_text (page->name, name); g_signal_connect_swapped (page->name, "changed", G_CALLBACK (ce_page_changed), page); widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "all_user_check")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), nm_setting_connection_get_num_permissions (page->setting_connection) == 0); g_signal_connect (widget, "toggled", G_CALLBACK (all_user_changed), page); widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_zone")); heading = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "heading_zone")); firewall_ui_setup (page->setting_connection, widget, heading, CE_PAGE (page)->cancellable); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); } static gboolean validate (CEPage *page, NMConnection *connection, GError **error) { CEPageVpn *self = CE_PAGE_VPN (page); GtkWidget *widget; g_object_set (self->setting_connection, NM_SETTING_CONNECTION_ID, gtk_entry_get_text (self->name), NULL); widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_zone")); firewall_ui_to_setting (self->setting_connection, widget); if (!nm_setting_verify (NM_SETTING (self->setting_connection), NULL, error)) return FALSE; if (!self->editor) return TRUE; return nm_vpn_editor_update_connection (self->editor, connection, error); } static void ce_page_vpn_init (CEPageVpn *page) { } static void dispose (GObject *object) { CEPageVpn *page = CE_PAGE_VPN (object); g_clear_object (&page->editor); G_OBJECT_CLASS (ce_page_vpn_parent_class)->dispose (object); } static void ce_page_vpn_class_init (CEPageVpnClass *class) { CEPageClass *page_class = CE_PAGE_CLASS (class); GObjectClass *object_class = G_OBJECT_CLASS (class); object_class->dispose = dispose; page_class->validate = validate; } static void finish_setup (CEPageVpn *page, gpointer unused, GError *error, gpointer user_data) { NMConnection *connection = CE_PAGE (page)->connection; const char *vpn_type; page->setting_connection = nm_connection_get_setting_connection (connection); page->setting_vpn = nm_connection_get_setting_vpn (connection); vpn_type = nm_setting_vpn_get_service_type (page->setting_vpn); page->plugin = vpn_get_plugin_by_service (vpn_type); if (page->plugin) load_vpn_plugin (page, connection); connect_vpn_page (page); } CEPage * ce_page_vpn_new (NMConnection *connection, NMClient *client) { CEPageVpn *page; page = CE_PAGE_VPN (ce_page_new (CE_TYPE_PAGE_VPN, connection, client, "/org/cinnamon/control-center/network/vpn-page.ui", _("Identity"))); page->name = GTK_ENTRY (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_name")); page->box = GTK_BOX (gtk_builder_get_object (CE_PAGE (page)->builder, "page")); g_signal_connect (page, "initialized", G_CALLBACK (finish_setup), NULL); CE_PAGE (page)->security_setting = NM_SETTING_VPN_SETTING_NAME; return CE_PAGE (page); } cinnamon-control-center-6.4.1/panels/network/connection-editor/ce-page-ip4.h0000664000175000017500000000436214724311620025753 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Red Hat, Inc. * * Licensed under the GNU General Public License Version 2 * * 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 ip4. * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __CE_PAGE_IP4_H #define __CE_PAGE_IP4_H #include #include #include "ce-page.h" G_BEGIN_DECLS #define CE_TYPE_PAGE_IP4 (ce_page_ip4_get_type ()) #define CE_PAGE_IP4(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_IP4, CEPageIP4)) #define CE_PAGE_IP4_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_IP4, CEPageIP4Class)) #define CE_IS_PAGE_IP4(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_IP4)) #define CE_IS_PAGE_IP4_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_IP4)) #define CE_PAGE_IP4_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_IP4, CEPageIP4Class)) typedef struct _CEPageIP4 CEPageIP4; typedef struct _CEPageIP4Class CEPageIP4Class; struct _CEPageIP4 { CEPage parent; NMSettingIPConfig *setting; GtkSwitch *enabled; GtkComboBox *method; GtkWidget *address_list; GtkSwitch *auto_dns; GtkWidget *dns_list; GtkSwitch *auto_routes; GtkWidget *routes_list; GtkWidget *never_default; }; struct _CEPageIP4Class { CEPageClass parent_class; }; GType ce_page_ip4_get_type (void); CEPage *ce_page_ip4_new (NMConnection *connection, NMClient *client); G_END_DECLS #endif /* __CE_PAGE_IP4_H */ cinnamon-control-center-6.4.1/panels/network/connection-editor/ce-page-8021x-security.h0000664000175000017500000000470214724311620027704 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Connection editor -- Connection editor for NetworkManager * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (C) Copyright 2008 - 2012 Red Hat, Inc. */ #ifndef __CE_PAGE_8021X_SECURITY_H #define __CE_PAGE_8021X_SECURITY_H #include #include "wireless-security.h" #include #include #include "ce-page.h" #define CE_TYPE_PAGE_8021X_SECURITY (ce_page_8021x_security_get_type ()) #define CE_PAGE_8021X_SECURITY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CE_TYPE_PAGE_8021X_SECURITY, CEPage8021xSecurity)) #define CE_PAGE_8021X_SECURITY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CE_TYPE_PAGE_8021X_SECURITY, CEPage8021xSecurityClass)) #define CE_IS_PAGE_8021X_SECURITY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CE_TYPE_PAGE_8021X_SECURITY)) #define CE_IS_PAGE_8021X_SECURITY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CE_TYPE_PAGE_8021X_SECURITY)) #define CE_PAGE_8021X_SECURITY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CE_TYPE_PAGE_8021X_SECURITY, CEPage8021xSecurityClass)) typedef struct CEPage8021xSecurity CEPage8021xSecurity; typedef struct CEPage8021xSecurityClass CEPage8021xSecurityClass; struct CEPage8021xSecurity { CEPage parent; GtkSwitch *enabled; GtkWidget *security_widget; WirelessSecurity *security; GtkSizeGroup *group; gboolean initial_have_8021x; }; struct CEPage8021xSecurityClass { CEPageClass parent; }; GType ce_page_8021x_security_get_type (void); CEPage *ce_page_8021x_security_new (NMConnection *connection, NMClient *client); #endif /* __CE_PAGE_8021X_SECURITY_H */ cinnamon-control-center-6.4.1/panels/network/connection-editor/security-page.ui0000664000175000017500000003011014724311620026715 0ustar fabiofabio True True False False True False 50 50 12 12 True True 10 6 True False 1 S_ecurity True combo_sec 0 0 1 1 True False True 1 0 1 1 True False vertical 0 1 2 1 True False 1 Firewall _Zone True combo_zone 0 2 1 1 True False True 0 1 1 2 1 1 True False page 1 False True False 50 50 12 12 10 6 True True ā— 35 1 0 1 1 True True ā— 1 1 1 1 True True ā— 1 2 1 1 True True ā— 1 3 1 1 True True ā— 1 4 1 1 True True ā— 1 5 1 1 True True ā— 1 6 1 1 True True ā— 1 7 1 1 True True ā— 1 8 1 1 True True ā— 1 9 1 1 True False Anony_mous identity True 0 0 1 1 True False Inner _authentication True 0 1 1 1 1 True False page 2 1 False cinnamon-control-center-6.4.1/panels/network/connection-editor/ce-page-details.h0000664000175000017500000000431214724311620026677 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Red Hat, Inc. * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __CE_PAGE_DETAILS_H #define __CE_PAGE_DETAILS_H #include #include #include "ce-page.h" G_BEGIN_DECLS #define CE_TYPE_PAGE_DETAILS (ce_page_details_get_type ()) #define CE_PAGE_DETAILS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_DETAILS, CEPageDetails)) #define CE_PAGE_DETAILS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_DETAILS, CEPageDetailsClass)) #define CE_IS_PAGE_DETAILS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_DETAILS)) #define CE_IS_PAGE_DETAILS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_DETAILS)) #define CE_PAGE_DETAILS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_DETAILS, CEPageDetailsClass)) typedef struct _CEPageDetails CEPageDetails; typedef struct _CEPageDetailsClass CEPageDetailsClass; struct _CEPageDetails { CEPage parent; NMDevice *device; NMAccessPoint *ap; }; struct _CEPageDetailsClass { CEPageClass parent_class; }; GType ce_page_details_get_type (void); CEPage *ce_page_details_new (NMConnection *connection, NMClient *client, NMDevice *device, NMAccessPoint *ap); G_END_DECLS #endif /* __CE_PAGE_DETAILS_H */ cinnamon-control-center-6.4.1/panels/network/connection-editor/ce-page-wifi.h0000664000175000017500000000376114724311620026217 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Red Hat, Inc. * * Licensed under the GNU General Public License Version 2 * * 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 wifi. * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __CE_PAGE_WIFI_H #define __CE_PAGE_WIFI_H #include #include #include "ce-page.h" G_BEGIN_DECLS #define CE_TYPE_PAGE_WIFI (ce_page_wifi_get_type ()) #define CE_PAGE_WIFI(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_WIFI, CEPageWifi)) #define CE_PAGE_WIFI_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_WIFI, CEPageWifiClass)) #define CE_IS_PAGE_WIFI(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_WIFI)) #define CE_IS_PAGE_WIFI_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_WIFI)) #define CE_PAGE_WIFI_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_WIFI, CEPageWifiClass)) typedef struct _CEPageWifi CEPageWifi; typedef struct _CEPageWifiClass CEPageWifiClass; struct _CEPageWifi { CEPage parent; NMSettingWireless *setting; }; struct _CEPageWifiClass { CEPageClass parent_class; }; GType ce_page_wifi_get_type (void); CEPage *ce_page_wifi_new (NMConnection *connection, NMClient *client); G_END_DECLS #endif /* __CE_PAGE_WIFI_H */ cinnamon-control-center-6.4.1/panels/network/connection-editor/reset-page.ui0000664000175000017500000000661614724311620026206 0ustar fabiofabio True False 50 50 12 12 20 20 _Reset True True True center True 0 0 1 1 _Forget True True True center True 0 1 1 1 True False True 0 Reset the settings for this network, including passwords, but remember it as a preferred network True 40 button_reset 1 0 1 1 True False True 0 Remove all details relating to this network and do not try to automatically connect True 30 button_forget 1 1 1 1 cinnamon-control-center-6.4.1/panels/network/connection-editor/ce-page-ethernet.h0000664000175000017500000000453614724311620027100 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Red Hat, Inc. * * Licensed under the GNU General Public License Version 2 * * 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 ethernet. * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __CE_PAGE_ETHERNET_H #define __CE_PAGE_ETHERNET_H #include #include #include #include "ce-page.h" G_BEGIN_DECLS #define CE_TYPE_PAGE_ETHERNET (ce_page_ethernet_get_type ()) #define CE_PAGE_ETHERNET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_ETHERNET, CEPageEthernet)) #define CE_PAGE_ETHERNET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_ETHERNET, CEPageEthernetClass)) #define CE_IS_PAGE_ETHERNET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_ETHERNET)) #define CE_IS_PAGE_ETHERNET_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_ETHERNET)) #define CE_PAGE_ETHERNET_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_ETHERNET, CEPageEthernetClass)) typedef struct _CEPageEthernet CEPageEthernet; typedef struct _CEPageEthernetClass CEPageEthernetClass; struct _CEPageEthernet { CEPage parent; NMSettingConnection *setting_connection; NMSettingWired *setting_wired; GtkEntry *name; GtkComboBoxText *device_mac; GtkEntry *cloned_mac; GtkSpinButton *mtu; GtkWidget *mtu_label; }; struct _CEPageEthernetClass { CEPageClass parent_class; }; GType ce_page_ethernet_get_type (void); CEPage *ce_page_ethernet_new (NMConnection *connection, NMClient *client); G_END_DECLS #endif /* __CE_PAGE_ETHERNET_H */ cinnamon-control-center-6.4.1/panels/network/connection-editor/ce-page-reset.c0000664000175000017500000000467514724311620026403 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Red Hat, Inc * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include "net-connection-editor.h" #include "ce-page-reset.h" G_DEFINE_TYPE (CEPageReset, ce_page_reset, CE_TYPE_PAGE) static void forget_cb (GtkButton *button, CEPageReset *page) { net_connection_editor_forget (page->editor); } static void reset_cb (GtkButton *button, CEPageReset *page) { net_connection_editor_reset (page->editor); } static void connect_reset_page (CEPageReset *page) { GtkWidget *widget; widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "button_forget")); g_signal_connect (widget, "clicked", G_CALLBACK (forget_cb), page); widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "button_reset")); g_signal_connect (widget, "clicked", G_CALLBACK (reset_cb), page); } static void ce_page_reset_init (CEPageReset *page) { } static void ce_page_reset_class_init (CEPageResetClass *class) { } CEPage * ce_page_reset_new (NMConnection *connection, NMClient *client, NetConnectionEditor *editor) { CEPageReset *page; page = CE_PAGE_RESET (ce_page_new (CE_TYPE_PAGE_RESET, connection, client, "/org/cinnamon/control-center/network/reset-page.ui", _("Reset"))); page->editor = editor; connect_reset_page (page); return CE_PAGE (page); } cinnamon-control-center-6.4.1/panels/network/connection-editor/ce-page-reset.h0000664000175000017500000000416414724311620026401 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Red Hat, Inc. * * Licensed under the GNU General Public License Version 2 * * 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 reset. * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __CE_PAGE_RESET_H #define __CE_PAGE_RESET_H #include #include #include "net-connection-editor.h" #include "ce-page.h" G_BEGIN_DECLS #define CE_TYPE_PAGE_RESET (ce_page_reset_get_type ()) #define CE_PAGE_RESET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_RESET, CEPageReset)) #define CE_PAGE_RESET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_RESET, CEPageResetClass)) #define CE_IS_PAGE_RESET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_RESET)) #define CE_IS_PAGE_RESET_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_RESET)) #define CE_PAGE_RESET_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_RESET, CEPageResetClass)) typedef struct _CEPageReset CEPageReset; typedef struct _CEPageResetClass CEPageResetClass; struct _CEPageReset { CEPage parent; NetConnectionEditor *editor; }; struct _CEPageResetClass { CEPageClass parent_class; }; GType ce_page_reset_get_type (void); CEPage *ce_page_reset_new (NMConnection *connection, NMClient *client, NetConnectionEditor *editor); G_END_DECLS #endif /* __CE_PAGE_RESET_H */ cinnamon-control-center-6.4.1/panels/network/connection-editor/net-connection-editor.h0000664000175000017500000000721514724311620030167 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Red Hat, Inc. * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __NET_CONNECTION_EDITOR_H #define __NET_CONNECTION_EDITOR_H #include #include #include G_BEGIN_DECLS #define NET_TYPE_CONNECTION_EDITOR (net_connection_editor_get_type ()) #define NET_CONNECTION_EDITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NET_TYPE_CONNECTION_EDITOR, NetConnectionEditor)) #define NET_CONNECTION_EDITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NET_TYPE_CONNECTION_EDITOR, NetConnectionEditorClass)) #define NET_IS_CONNECTION_EDITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NET_TYPE_CONNECTION_EDITOR)) #define NET_IS_CONNECTION_EDITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NET_TYPE_CONNECTION_EDITOR)) #define NET_CONNECTION_EDITOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NET_TYPE_CONNECTION_EDITOR, NetConnectionEditorClass)) typedef struct _NetConnectionEditor NetConnectionEditor; typedef struct _NetConnectionEditorClass NetConnectionEditorClass; struct _NetConnectionEditor { GObject parent; GtkWidget *parent_window; NMClient *client; NMDevice *device; NMConnection *connection; NMConnection *orig_connection; gboolean is_new_connection; gboolean is_changed; NMAccessPoint *ap; GtkBuilder *builder; GtkWidget *window; GSList *initializing_pages; GSList *pages; guint permission_id; NMClientPermissionResult can_modify; gboolean title_set; gboolean show_when_initialized; }; struct _NetConnectionEditorClass { GObjectClass parent_class; void (*done) (NetConnectionEditor *details, gboolean success); }; GType net_connection_editor_get_type (void); NetConnectionEditor *net_connection_editor_new (GtkWindow *parent_window, NMConnection *connection, NMDevice *device, NMAccessPoint *ap, NMClient *client); void net_connection_editor_set_title (NetConnectionEditor *editor, const gchar *title); void net_connection_editor_run (NetConnectionEditor *editor); void net_connection_editor_present (NetConnectionEditor *editor); void net_connection_editor_forget (NetConnectionEditor *editor); void net_connection_editor_reset (NetConnectionEditor *editor); G_END_DECLS #endif /* __NET_CONNECTION_EDITOR_H */ cinnamon-control-center-6.4.1/panels/network/connection-editor/ce-page-details.c0000664000175000017500000002041414724311620026673 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Red Hat, Inc * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include "../panel-common.h" #include "ce-page-details.h" G_DEFINE_TYPE (CEPageDetails, ce_page_details, CE_TYPE_PAGE) static gchar * get_ap_security_string (NMAccessPoint *ap) { NM80211ApSecurityFlags wpa_flags, rsn_flags; NM80211ApFlags flags; GString *str; flags = nm_access_point_get_flags (ap); wpa_flags = nm_access_point_get_wpa_flags (ap); rsn_flags = nm_access_point_get_rsn_flags (ap); str = g_string_new (""); if ((flags & NM_802_11_AP_FLAGS_PRIVACY) && (wpa_flags == NM_802_11_AP_SEC_NONE) && (rsn_flags == NM_802_11_AP_SEC_NONE)) { /* TRANSLATORS: this WEP WiFi security */ g_string_append_printf (str, "%s, ", _("WEP")); } if (wpa_flags != NM_802_11_AP_SEC_NONE) { /* TRANSLATORS: this WPA WiFi security */ g_string_append_printf (str, "%s, ", _("WPA")); } if (rsn_flags != NM_802_11_AP_SEC_NONE) { /* TRANSLATORS: this WPA WiFi security */ g_string_append_printf (str, "%s, ", _("WPA2")); } if ((wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) || (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) { /* TRANSLATORS: this Enterprise WiFi security */ g_string_append_printf (str, "%s, ", _("Enterprise")); } if (str->len > 0) g_string_set_size (str, str->len - 2); else { g_string_append (str, C_("Wifi security", "None")); } return g_string_free (str, FALSE); } static void update_last_used (CEPageDetails *page, NMConnection *connection) { gchar *last_used = NULL; GDateTime *now = NULL; GDateTime *then = NULL; gint days; GTimeSpan diff; guint64 timestamp; NMSettingConnection *s_con; s_con = nm_connection_get_setting_connection (connection); if (s_con == NULL) goto out; timestamp = nm_setting_connection_get_timestamp (s_con); if (timestamp == 0) { last_used = g_strdup (_("Never")); goto out; } /* calculate the amount of time that has elapsed */ now = g_date_time_new_now_utc (); then = g_date_time_new_from_unix_utc (timestamp); diff = g_date_time_difference (now, then); days = diff / G_TIME_SPAN_DAY; if (days == 0) last_used = g_strdup (_("Today")); else if (days == 1) last_used = g_strdup (_("Yesterday")); else last_used = g_strdup_printf (ngettext ("%i day ago", "%i days ago", days), days); out: panel_set_device_widget_details (CE_PAGE (page)->builder, "last_used", last_used); if (now != NULL) g_date_time_unref (now); if (then != NULL) g_date_time_unref (then); g_free (last_used); } static void connect_details_page (CEPageDetails *page) { guint speed; guint strength; NMDeviceState state; NMAccessPoint *active_ap; const gchar *str; gboolean device_is_active; if (NM_IS_DEVICE_WIFI (page->device)) active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (page->device)); else active_ap = NULL; state = page->device ? nm_device_get_state (page->device) : NM_DEVICE_STATE_DISCONNECTED; device_is_active = FALSE; speed = 0; if (active_ap && page->ap == active_ap && state != NM_DEVICE_STATE_UNAVAILABLE) { device_is_active = TRUE; if (NM_IS_DEVICE_WIFI (page->device)) speed = nm_device_wifi_get_bitrate (NM_DEVICE_WIFI (page->device)) / 1000; } else if (page->device) { NMActiveConnection *ac; const gchar *p1, *p2; ac = nm_device_get_active_connection (page->device); p1 = ac ? nm_active_connection_get_uuid (ac) : NULL; p2 = nm_connection_get_uuid (CE_PAGE (page)->connection); if (g_strcmp0 (p1, p2) == 0) { device_is_active = TRUE; if (NM_IS_DEVICE_WIFI (page->device)) speed = nm_device_wifi_get_bitrate (NM_DEVICE_WIFI (page->device)) / 1000; else if (NM_IS_DEVICE_ETHERNET (page->device)) speed = nm_device_ethernet_get_speed (NM_DEVICE_ETHERNET (page->device)); } } if (speed > 0) str = g_strdup_printf (_("%d Mb/s"), speed); else str = NULL; panel_set_device_widget_details (CE_PAGE (page)->builder, "speed", str); g_clear_pointer (&str, g_free); if (NM_IS_DEVICE_WIFI (page->device)) str = nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (page->device)); else if (NM_IS_DEVICE_ETHERNET (page->device)) str = nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (page->device)); panel_set_device_widget_details (CE_PAGE (page)->builder, "mac", str); str = NULL; if (device_is_active && active_ap) str = get_ap_security_string (active_ap); panel_set_device_widget_details (CE_PAGE (page)->builder, "security", str); g_clear_pointer (&str, g_free); strength = 0; if (page->ap != NULL) strength = nm_access_point_get_strength (page->ap); if (strength <= 0) str = NULL; else if (strength < 20) str = C_("Signal strength", "None"); else if (strength < 40) str = C_("Signal strength", "Weak"); else if (strength < 50) str = C_("Signal strength", "Ok"); else if (strength < 80) str = C_("Signal strength", "Good"); else str = C_("Signal strength", "Excellent"); panel_set_device_widget_details (CE_PAGE (page)->builder, "strength", str); /* set IP entries */ if (device_is_active) panel_set_device_widgets (CE_PAGE (page)->builder, page->device); else panel_unset_device_widgets (CE_PAGE (page)->builder); if (!device_is_active && CE_PAGE (page)->connection) update_last_used (page, CE_PAGE (page)->connection); else panel_set_device_widget_details (CE_PAGE (page)->builder, "last_used", NULL); } static void ce_page_details_init (CEPageDetails *page) { } static void ce_page_details_class_init (CEPageDetailsClass *class) { } CEPage * ce_page_details_new (NMConnection *connection, NMClient *client, NMDevice *device, NMAccessPoint *ap) { CEPageDetails *page; page = CE_PAGE_DETAILS (ce_page_new (CE_TYPE_PAGE_DETAILS, connection, client, "/org/cinnamon/control-center/network/details-page.ui", _("Details"))); page->device = device; page->ap = ap; connect_details_page (page); return CE_PAGE (page); } cinnamon-control-center-6.4.1/panels/network/connection-editor/ce-page-ip6.h0000664000175000017500000000436214724311620025755 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Red Hat, Inc. * * Licensed under the GNU General Public License Version 2 * * 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 ip6. * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __CE_PAGE_IP6_H #define __CE_PAGE_IP6_H #include #include #include "ce-page.h" G_BEGIN_DECLS #define CE_TYPE_PAGE_IP6 (ce_page_ip6_get_type ()) #define CE_PAGE_IP6(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_IP6, CEPageIP6)) #define CE_PAGE_IP6_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_IP6, CEPageIP6Class)) #define CE_IS_PAGE_IP6(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_IP6)) #define CE_IS_PAGE_IP6_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_IP6)) #define CE_PAGE_IP6_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_IP6, CEPageIP6Class)) typedef struct _CEPageIP6 CEPageIP6; typedef struct _CEPageIP6Class CEPageIP6Class; struct _CEPageIP6 { CEPage parent; NMSettingIPConfig *setting; GtkSwitch *enabled; GtkComboBox *method; GtkWidget *address_list; GtkSwitch *auto_dns; GtkWidget *dns_list; GtkSwitch *auto_routes; GtkWidget *routes_list; GtkWidget *never_default; }; struct _CEPageIP6Class { CEPageClass parent_class; }; GType ce_page_ip6_get_type (void); CEPage *ce_page_ip6_new (NMConnection *connection, NMClient *client); G_END_DECLS #endif /* __CE_PAGE_IP6_H */ cinnamon-control-center-6.4.1/panels/network/connection-editor/ce-page.h0000664000175000017500000001045014724311620025254 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Red Hat, Inc. * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __CE_PAGE_H #define __CE_PAGE_H #include #include #include G_BEGIN_DECLS #define CE_TYPE_PAGE (ce_page_get_type ()) #define CE_PAGE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE, CEPage)) #define CE_PAGE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE, CEPageClass)) #define CE_IS_PAGE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE)) #define CE_IS_PAGE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE)) #define CE_PAGE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE, CEPageClass)) typedef struct _CEPage CEPage; typedef struct _CEPageClass CEPageClass; struct _CEPage { GObject parent; gboolean initialized; GtkBuilder *builder; GtkWidget *page; gchar *title; const gchar *security_setting; NMConnection *connection; NMClient *client; GCancellable *cancellable; }; struct _CEPageClass { GObjectClass parent_class; gboolean (*validate) (CEPage *page, NMConnection *connection, GError **error); void (*changed) (CEPage *page); void (*initialized) (CEPage *page, GError *error); }; GType ce_page_get_type (void); GtkWidget *ce_page_get_page (CEPage *page); const gchar *ce_page_get_title (CEPage *page); const gchar *ce_page_get_security_setting (CEPage *page); gboolean ce_page_validate (CEPage *page, NMConnection *connection, GError **error); gboolean ce_page_get_initialized (CEPage *page); void ce_page_changed (CEPage *page); CEPage *ce_page_new (GType type, NMConnection *connection, NMClient *client, const gchar *ui_resource, const gchar *title); void ce_page_complete_init (CEPage *page, const gchar *setting_name, GVariant *variant, GError *error); gchar **ce_page_get_mac_list (NMClient *client, GType device_type, const gchar *mac_property); void ce_page_setup_mac_combo (GtkComboBoxText *combo, const gchar *current_mac, gchar **mac_list); gint ce_get_property_default (NMSetting *setting, const gchar *property_name); gint ce_spin_output_with_default (GtkSpinButton *spin, gpointer user_data); gboolean ce_page_address_is_valid (const gchar *addr); gchar *ce_page_trim_address (const gchar *addr); typedef enum { NAME_FORMAT_TYPE, NAME_FORMAT_PROFILE } NameFormat; gchar * ce_page_get_next_available_name (const GPtrArray *connections, NameFormat format, const gchar *type_name); G_END_DECLS #endif /* __CE_PAGE_H */ cinnamon-control-center-6.4.1/panels/network/connection-editor/details-page.ui0000664000175000017500000003201014724311620026474 0ustar fabiofabio True False start 50 50 12 12 True True 10 6 True False True 1 Signal Strength label_strength 0 0 1 1 True True True 0 Weak True 1 0 1 1 True False 1 Link speed label_speed 0 1 1 1 True True 0 1Mb/sec True 1 1 1 1 True False 1 Security label_security 0 2 1 1 True False 1 IPv4 Address label_ipv4 0 3 1 1 True False 1 0 IPv6 Address label_ipv6 0 4 1 1 True False 1 Hardware Address label_mac 0 5 1 1 True False 1 Default Route label_route 0 6 1 1 True False 1 0 DNS4 label_dns4 0 7 1 1 True False 1 0 DNS6 label_dns6 0 8 1 1 True False 1 Last Used label_last_used 0 8 1 1 True True 0 WPA True 1 2 1 1 True True 0 127.0.0.1 True 1 3 1 1 True True 0 ::1 True 1 4 1 1 True True 0 AA:BB:CC:DD:55:66:77:88 True 1 5 1 1 True True 0 127.0.0.1 True 1 6 1 1 True True 0 0 127.0.0.1 True True 1 7 1 1 True True 0 0 ::1 True True 1 8 1 1 True True 0 today True 1 8 1 1 cinnamon-control-center-6.4.1/panels/network/connection-editor/vpn-helpers.c0000664000175000017500000002747314724311620026226 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Connection editor -- Connection editor for NetworkManager * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (C) Copyright 2008 Red Hat, Inc. */ #include "config.h" #include #include #include #include #include #include #include "vpn-helpers.h" NMVpnEditorPlugin * vpn_get_plugin_by_service (const char *service) { NMVpnPluginInfo *plugin_info; g_return_val_if_fail (service != NULL, NULL); plugin_info = nm_vpn_plugin_info_list_find_by_service (vpn_get_plugins (), service); if (plugin_info) return nm_vpn_plugin_info_get_editor_plugin (plugin_info); return NULL; } static gint _sort_vpn_plugins (NMVpnPluginInfo *aa, NMVpnPluginInfo *bb) { return strcmp (nm_vpn_plugin_info_get_name (aa), nm_vpn_plugin_info_get_name (bb)); } GSList * vpn_get_plugins (void) { static gboolean plugins_loaded = FALSE; static GSList *plugins = NULL; GSList *p; if (G_LIKELY (plugins_loaded)) return plugins; plugins_loaded = TRUE; p = nm_vpn_plugin_info_list_load (); plugins = NULL; while (p) { NMVpnPluginInfo *plugin_info = NM_VPN_PLUGIN_INFO (p->data); GError *error = NULL; /* load the editor plugin, and preserve only those NMVpnPluginInfo that can * successfully load the plugin. */ if (nm_vpn_plugin_info_load_editor_plugin (plugin_info, &error)) plugins = g_slist_prepend (plugins, plugin_info); else { if ( !nm_vpn_plugin_info_get_plugin (plugin_info) && nm_vpn_plugin_info_lookup_property (plugin_info, NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME, "properties")) { g_message ("vpn: (%s,%s) cannot load legacy-only plugin", nm_vpn_plugin_info_get_name (plugin_info), nm_vpn_plugin_info_get_filename (plugin_info)); } else if (g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) { g_message ("vpn: (%s,%s) file \"%s\" not found. Did you install the client package?", nm_vpn_plugin_info_get_name (plugin_info), nm_vpn_plugin_info_get_filename (plugin_info), nm_vpn_plugin_info_get_plugin (plugin_info)); } else { g_warning ("vpn: (%s,%s) could not load plugin: %s", nm_vpn_plugin_info_get_name (plugin_info), nm_vpn_plugin_info_get_filename (plugin_info), error->message); } g_clear_error (&error); g_object_unref (plugin_info); } p = g_slist_delete_link (p, p); } /* sort the list of plugins alphabetically. */ plugins = g_slist_sort (plugins, (GCompareFunc) _sort_vpn_plugins); return plugins; } typedef struct { VpnImportCallback callback; gpointer user_data; } ActionInfo; static void import_vpn_from_file_cb (GtkWidget *dialog, gint response, gpointer user_data) { char *filename = NULL; ActionInfo *info = (ActionInfo *) user_data; NMConnection *connection = NULL; GError *error = NULL; GSList *iter; if (response != GTK_RESPONSE_ACCEPT) goto out; filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); if (!filename) { g_warning ("%s: didn't get a filename back from the chooser!", __func__); goto out; } for (iter = vpn_get_plugins (); !connection && iter; iter = iter->next) { NMVpnEditorPlugin *plugin; plugin = nm_vpn_plugin_info_get_editor_plugin (iter->data); g_clear_error (&error); connection = nm_vpn_editor_plugin_import (plugin, filename, &error); } if (!connection) { GtkWidget *err_dialog; char *bname = g_path_get_basename (filename); err_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Cannot import VPN connection")); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (err_dialog), _("The file ā€œ%sā€ could not be read or does not contain recognized VPN connection information\n\nError: %s."), bname, error ? error->message : "unknown error"); g_free (bname); g_signal_connect (err_dialog, "delete-event", G_CALLBACK (gtk_widget_destroy), NULL); g_signal_connect (err_dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); gtk_dialog_run (GTK_DIALOG (err_dialog)); } g_clear_error (&error); g_free (filename); out: gtk_widget_hide (dialog); gtk_widget_destroy (dialog); info->callback (connection, info->user_data); g_free (info); } static void destroy_import_chooser (GtkWidget *dialog, gpointer user_data) { ActionInfo *info = (ActionInfo *) user_data; gtk_widget_destroy (dialog); info->callback (NULL, info->user_data); g_free (info); } void vpn_import (GtkWindow *parent, VpnImportCallback callback, gpointer user_data) { GtkWidget *dialog; ActionInfo *info; const char *home_folder; dialog = gtk_file_chooser_dialog_new (_("Select file to import"), parent, GTK_FILE_CHOOSER_ACTION_OPEN, _("_Cancel"), GTK_RESPONSE_CANCEL, _("_Open"), GTK_RESPONSE_ACCEPT, NULL); gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); home_folder = g_get_home_dir (); gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), home_folder); info = g_malloc0 (sizeof (ActionInfo)); info->callback = callback; info->user_data = user_data; g_signal_connect (G_OBJECT (dialog), "close", G_CALLBACK (destroy_import_chooser), info); g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (import_vpn_from_file_cb), info); gtk_widget_show_all (dialog); gtk_window_present (GTK_WINDOW (dialog)); } static void export_vpn_to_file_cb (GtkWidget *dialog, gint response, gpointer user_data) { NMConnection *connection = NM_CONNECTION (user_data); char *filename = NULL; GError *error = NULL; NMVpnEditorPlugin *plugin; NMSettingConnection *s_con = NULL; NMSettingVpn *s_vpn = NULL; const char *service_type; const char *id = NULL; gboolean success = FALSE; if (response != GTK_RESPONSE_ACCEPT) goto out; filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); if (!filename) { g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "no filename"); goto done; } if (g_file_test (filename, G_FILE_TEST_EXISTS)) { int replace_response; GtkWidget *replace_dialog; char *bname; bname = g_path_get_basename (filename); replace_dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_CANCEL, _("A file named ā€œ%sā€ already exists."), bname); gtk_dialog_add_buttons (GTK_DIALOG (replace_dialog), _("_Replace"), GTK_RESPONSE_OK, NULL); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (replace_dialog), _("Do you want to replace %s with the VPN connection you are saving?"), bname); g_free (bname); replace_response = gtk_dialog_run (GTK_DIALOG (replace_dialog)); gtk_widget_destroy (replace_dialog); if (replace_response != GTK_RESPONSE_OK) goto out; } s_con = nm_connection_get_setting_connection (connection); id = s_con ? nm_setting_connection_get_id (s_con) : NULL; if (!id) { g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "connection setting invalid"); goto done; } s_vpn = nm_connection_get_setting_vpn (connection); service_type = s_vpn ? nm_setting_vpn_get_service_type (s_vpn) : NULL; if (!service_type) { g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "VPN setting invalid"); goto done; } plugin = vpn_get_plugin_by_service (service_type); if (plugin) success = nm_vpn_editor_plugin_export (plugin, filename, connection, &error); done: if (!success) { GtkWidget *err_dialog; char *bname = filename ? g_path_get_basename (filename) : g_strdup ("(none)"); err_dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Cannot export VPN connection")); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (err_dialog), _("The VPN connection ā€œ%sā€ could not be exported to %s.\n\nError: %s."), id ? id : "(unknown)", bname, error ? error->message : "unknown error"); g_free (bname); g_signal_connect (err_dialog, "delete-event", G_CALLBACK (gtk_widget_destroy), NULL); g_signal_connect (err_dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); gtk_widget_show_all (err_dialog); gtk_window_present (GTK_WINDOW (err_dialog)); } out: if (error) g_error_free (error); g_object_unref (connection); gtk_widget_hide (dialog); gtk_widget_destroy (dialog); } void vpn_export (NMConnection *connection) { GtkWidget *dialog; NMVpnEditorPlugin *plugin; NMSettingVpn *s_vpn = NULL; const char *service_type; const char *home_folder; s_vpn = nm_connection_get_setting_vpn (connection); service_type = s_vpn ? nm_setting_vpn_get_service_type (s_vpn) : NULL; if (!service_type) { g_warning ("%s: invalid VPN connection!", __func__); return; } dialog = gtk_file_chooser_dialog_new (_("Export VPN connection"), NULL, GTK_FILE_CHOOSER_ACTION_SAVE, _("_Cancel"), GTK_RESPONSE_CANCEL, _("_Save"), GTK_RESPONSE_ACCEPT, NULL); home_folder = g_get_home_dir (); gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), home_folder); plugin = vpn_get_plugin_by_service (service_type); if (plugin) { char *suggested = NULL; suggested = nm_vpn_editor_plugin_get_suggested_filename (plugin, connection); if (suggested) { gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), suggested); g_free (suggested); } } g_signal_connect (G_OBJECT (dialog), "close", G_CALLBACK (gtk_widget_destroy), NULL); g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (export_vpn_to_file_cb), g_object_ref (connection)); gtk_widget_show_all (dialog); gtk_window_present (GTK_WINDOW (dialog)); } gboolean vpn_supports_ipv6 (NMConnection *connection) { NMSettingVpn *s_vpn; const char *service_type; NMVpnEditorPlugin *plugin; guint32 capabilities; s_vpn = nm_connection_get_setting_vpn (connection); g_return_val_if_fail (s_vpn != NULL, FALSE); service_type = nm_setting_vpn_get_service_type (s_vpn); g_return_val_if_fail (service_type != NULL, FALSE); plugin = vpn_get_plugin_by_service (service_type); g_return_val_if_fail (plugin != NULL, FALSE); capabilities = nm_vpn_editor_plugin_get_capabilities (plugin); return (capabilities & NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6) != 0; } cinnamon-control-center-6.4.1/panels/network/connection-editor/ce-page-8021x-security.c0000664000175000017500000001362614724311620027704 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Connection editor -- Connection editor for NetworkManager * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (C) Copyright 2008 - 2012 Red Hat, Inc. */ #include "config.h" #include #include #include #include #include "wireless-security.h" #include "ce-page-ethernet.h" #include "ce-page-8021x-security.h" G_DEFINE_TYPE (CEPage8021xSecurity, ce_page_8021x_security, CE_TYPE_PAGE) static void enable_toggled (GObject *sw, GParamSpec *pspec, gpointer user_data) { CEPage8021xSecurity *page = CE_PAGE_8021X_SECURITY (user_data); gtk_widget_set_sensitive (page->security_widget, gtk_switch_get_active (page->enabled)); ce_page_changed (CE_PAGE (page)); } static void stuff_changed (WirelessSecurity *sec, gpointer user_data) { ce_page_changed (CE_PAGE (user_data)); } static void finish_setup (CEPage8021xSecurity *page, gpointer unused, GError *error, gpointer user_data) { GtkWidget *parent; GtkWidget *vbox; GtkWidget *heading; if (error) return; vbox = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "vbox")); heading = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "heading_sec")); page->group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); page->security = (WirelessSecurity *) ws_wpa_eap_new (CE_PAGE (page)->connection, TRUE, FALSE); if (!page->security) { g_warning ("Could not load 802.1x user interface."); return; } wireless_security_set_changed_notify (page->security, stuff_changed, page); page->security_widget = wireless_security_get_widget (page->security); parent = gtk_widget_get_parent (page->security_widget); if (parent) gtk_container_remove (GTK_CONTAINER (parent), page->security_widget); gtk_switch_set_active (page->enabled, page->initial_have_8021x); g_signal_connect (page->enabled, "notify::active", G_CALLBACK (enable_toggled), page); gtk_widget_set_sensitive (page->security_widget, page->initial_have_8021x); gtk_size_group_add_widget (page->group, heading); wireless_security_add_to_size_group (page->security, page->group); gtk_container_add (GTK_CONTAINER (vbox), page->security_widget); } CEPage * ce_page_8021x_security_new (NMConnection *connection, NMClient *client) { CEPage8021xSecurity *page; page = CE_PAGE_8021X_SECURITY (ce_page_new (CE_TYPE_PAGE_8021X_SECURITY, connection, client, "/org/cinnamon/control-center/network/8021x-security-page.ui", _("Security"))); if (nm_connection_get_setting_802_1x (connection)) page->initial_have_8021x = TRUE; page->enabled = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "8021x_switch")); g_signal_connect (page, "initialized", G_CALLBACK (finish_setup), NULL); if (page->initial_have_8021x) CE_PAGE (page)->security_setting = NM_SETTING_802_1X_SETTING_NAME; return CE_PAGE (page); } static gboolean validate (CEPage *cepage, NMConnection *connection, GError **error) { CEPage8021xSecurity *page = CE_PAGE_8021X_SECURITY (cepage); gboolean valid = TRUE; if (gtk_switch_get_active (page->enabled)) { NMConnection *tmp_connection; NMSetting *s_8021x; /* FIXME: get failed property and error out of wireless security objects */ valid = wireless_security_validate (page->security, error); if (valid) { NMSetting *s_con; /* Here's a nice hack to work around the fact that ws_802_1x_fill_connection needs wireless setting. */ tmp_connection = nm_simple_connection_new (); nm_connection_add_setting (tmp_connection, nm_setting_wireless_new ()); /* temp connection needs a 'connection' setting too, since most of * the EAP methods need the UUID for CA cert ignore stuff. */ s_con = nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); nm_connection_add_setting (tmp_connection, nm_setting_duplicate (s_con)); ws_802_1x_fill_connection (page->security, "wpa_eap_auth_combo", tmp_connection); s_8021x = nm_connection_get_setting (tmp_connection, NM_TYPE_SETTING_802_1X); nm_connection_add_setting (connection, NM_SETTING (g_object_ref (s_8021x))); g_object_unref (tmp_connection); } } else { nm_connection_remove_setting (connection, NM_TYPE_SETTING_802_1X); valid = TRUE; } return valid; } static void ce_page_8021x_security_init (CEPage8021xSecurity *page) { } static void dispose (GObject *object) { CEPage8021xSecurity *page = CE_PAGE_8021X_SECURITY (object); if (page->security) { wireless_security_unref (page->security); page->security = NULL; } g_clear_object (&page->group); G_OBJECT_CLASS (ce_page_8021x_security_parent_class)->dispose (object); } static void ce_page_8021x_security_class_init (CEPage8021xSecurityClass *security_class) { GObjectClass *object_class = G_OBJECT_CLASS (security_class); CEPageClass *parent_class = CE_PAGE_CLASS (security_class); /* virtual methods */ object_class->dispose = dispose; parent_class->validate = validate; } cinnamon-control-center-6.4.1/panels/network/connection-editor/ui-helpers.c0000664000175000017500000000231714724311620026026 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (C) Copyright 2014 Red Hat, Inc. */ #include "config.h" #include "ui-helpers.h" void widget_set_error (GtkWidget *widget) { g_return_if_fail (GTK_IS_WIDGET (widget)); gtk_style_context_add_class (gtk_widget_get_style_context (widget), "error"); } void widget_unset_error (GtkWidget *widget) { g_return_if_fail (GTK_IS_WIDGET (widget)); gtk_style_context_remove_class (gtk_widget_get_style_context (widget), "error"); } cinnamon-control-center-6.4.1/panels/network/connection-editor/net-connection-editor.c0000664000175000017500000010162114724311620030156 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Red Hat, Inc * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include "shell/list-box-helper.h" #include "net-connection-editor.h" #include "net-connection-editor-resources.h" #include "ce-page-details.h" #include "ce-page-wifi.h" #include "ce-page-ip4.h" #include "ce-page-ip6.h" #include "ce-page-security.h" #include "ce-page-reset.h" #include "ce-page-ethernet.h" #include "ce-page-8021x-security.h" #include "ce-page-vpn.h" #include "vpn-helpers.h" #include "eap-method.h" enum { DONE, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; G_DEFINE_TYPE (NetConnectionEditor, net_connection_editor, G_TYPE_OBJECT) static void page_changed (CEPage *page, gpointer user_data); static void selection_changed (GtkTreeSelection *selection, NetConnectionEditor *editor) { GtkWidget *widget; GtkTreeModel *model; GtkTreeIter iter; gint page; if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return; gtk_tree_model_get (model, &iter, 1, &page, -1); widget = GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_notebook")); gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), page); } static void cancel_editing (NetConnectionEditor *editor) { gtk_widget_hide (editor->window); g_signal_emit (editor, signals[DONE], 0, FALSE); } static void update_connection (NetConnectionEditor *editor) { GVariant *settings; settings = nm_connection_to_dbus (editor->connection, NM_CONNECTION_SERIALIZE_ALL); nm_connection_replace_settings (editor->orig_connection, settings, NULL); g_variant_unref (settings); } static void update_complete (NetConnectionEditor *editor, gboolean success) { gtk_widget_hide (editor->window); g_signal_emit (editor, signals[DONE], 0, success); } static void updated_connection_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { NetConnectionEditor *editor; GError *error = NULL; gboolean success = TRUE; if (!nm_remote_connection_commit_changes_finish (NM_REMOTE_CONNECTION (source_object), res, &error)) { g_warning ("Failed to commit changes: %s", error->message); success = FALSE; g_error_free (error); //return; FIXME return if cancelled } nm_connection_clear_secrets (NM_CONNECTION (source_object)); editor = user_data; update_complete (editor, success); } static void added_connection_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { NetConnectionEditor *editor; GError *error = NULL; gboolean success = TRUE; if (!nm_client_add_connection_finish (NM_CLIENT (source_object), res, &error)) { g_warning ("Failed to add connection: %s", error->message); success = FALSE; g_error_free (error); /* Leave the editor open */ // return; FIXME return if cancelled } editor = user_data; update_complete (editor, success); } static void apply_edits (NetConnectionEditor *editor) { update_connection (editor); eap_method_ca_cert_ignore_save (editor->connection); if (editor->is_new_connection) { nm_client_add_connection_async (editor->client, editor->orig_connection, TRUE, NULL, added_connection_cb, editor); } else { nm_remote_connection_commit_changes_async (NM_REMOTE_CONNECTION (editor->orig_connection), TRUE, NULL, updated_connection_cb, editor); } } static void net_connection_editor_init (NetConnectionEditor *editor) { GError *error = NULL; GtkTreeSelection *selection; editor->builder = gtk_builder_new (); gtk_builder_add_from_resource (editor->builder, "/org/cinnamon/control-center/network/connection-editor.ui", &error); if (error != NULL) { g_warning ("Could not load ui file: %s", error->message); g_error_free (error); return; } editor->window = GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_dialog")); selection = GTK_TREE_SELECTION (gtk_builder_get_object (editor->builder, "details_page_list_selection")); g_signal_connect (selection, "changed", G_CALLBACK (selection_changed), editor); } void net_connection_editor_run (NetConnectionEditor *editor) { GtkWidget *button; button = GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_cancel_button")); g_signal_connect_swapped (button, "clicked", G_CALLBACK (cancel_editing), editor); g_signal_connect_swapped (editor->window, "delete-event", G_CALLBACK (cancel_editing), editor); button = GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_apply_button")); g_signal_connect_swapped (button, "clicked", G_CALLBACK (apply_edits), editor); net_connection_editor_present (editor); } static void net_connection_editor_finalize (GObject *object) { NetConnectionEditor *editor = NET_CONNECTION_EDITOR (object); GSList *l; for (l = editor->pages; l != NULL; l = l->next) g_signal_handlers_disconnect_by_func (l->data, page_changed, editor); if (editor->permission_id > 0 && editor->client) g_signal_handler_disconnect (editor->client, editor->permission_id); g_clear_object (&editor->connection); g_clear_object (&editor->orig_connection); if (editor->window) { gtk_widget_destroy (editor->window); editor->window = NULL; } g_clear_object (&editor->parent_window); g_clear_object (&editor->builder); g_clear_object (&editor->device); g_clear_object (&editor->client); g_clear_object (&editor->ap); G_OBJECT_CLASS (net_connection_editor_parent_class)->finalize (object); } static void net_connection_editor_class_init (NetConnectionEditorClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); g_resources_register (net_connection_editor_get_resource ()); object_class->finalize = net_connection_editor_finalize; signals[DONE] = g_signal_new ("done", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NetConnectionEditorClass, done), NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); } static void net_connection_editor_error_dialog (NetConnectionEditor *editor, const char *primary_text, const char *secondary_text) { GtkWidget *dialog; GtkWindow *parent; if (gtk_widget_is_visible (editor->window)) parent = GTK_WINDOW (editor->window); else parent = GTK_WINDOW (editor->parent_window); dialog = gtk_message_dialog_new (parent, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", primary_text); if (secondary_text) { gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", secondary_text); } g_signal_connect (dialog, "delete-event", G_CALLBACK (gtk_widget_destroy), NULL); g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); gtk_dialog_run (GTK_DIALOG (dialog)); } static void net_connection_editor_do_fallback (NetConnectionEditor *editor, const gchar *type) { gchar *cmdline; GError *error = NULL; if (editor->is_new_connection) { cmdline = g_strdup_printf ("nm-connection-editor --type='%s' --create", type); } else { cmdline = g_strdup_printf ("nm-connection-editor --edit='%s'", nm_connection_get_uuid (editor->connection)); } g_spawn_command_line_async (cmdline, &error); g_free (cmdline); if (error) { net_connection_editor_error_dialog (editor, _("Unable to open connection editor"), error->message); g_error_free (error); } g_signal_emit (editor, signals[DONE], 0, FALSE); } static void net_connection_editor_update_title (NetConnectionEditor *editor) { gchar *id; if (editor->title_set) return; if (editor->is_new_connection) { if (editor->device) { id = g_strdup (_("New Profile")); } else { /* Leave it set to "Add New Connection" */ return; } } else { NMSettingWireless *sw; sw = nm_connection_get_setting_wireless (editor->connection); if (sw) { GBytes *ssid; ssid = nm_setting_wireless_get_ssid (sw); id = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid)); } else { id = g_strdup (nm_connection_get_id (editor->connection)); } } gtk_window_set_title (GTK_WINDOW (editor->window), id); g_free (id); } static gboolean editor_is_initialized (NetConnectionEditor *editor) { return editor->initializing_pages == NULL; } static void update_sensitivity (NetConnectionEditor *editor) { NMSettingConnection *sc; gboolean sensitive; GtkWidget *widget; GSList *l; if (!editor_is_initialized (editor)) return; sc = nm_connection_get_setting_connection (editor->connection); if (nm_setting_connection_get_read_only (sc)) { sensitive = FALSE; } else { sensitive = editor->can_modify; } for (l = editor->pages; l; l = l->next) { widget = ce_page_get_page (CE_PAGE (l->data)); gtk_widget_set_sensitive (widget, sensitive); } } static void validate (NetConnectionEditor *editor) { gboolean valid = FALSE; GSList *l; if (!editor_is_initialized (editor)) goto done; valid = TRUE; for (l = editor->pages; l; l = l->next) { GError *error = NULL; if (!ce_page_validate (CE_PAGE (l->data), editor->connection, &error)) { valid = FALSE; if (error) { g_debug ("Invalid setting %s: %s", ce_page_get_title (CE_PAGE (l->data)), error->message); g_error_free (error); } else { g_debug ("Invalid setting %s", ce_page_get_title (CE_PAGE (l->data))); } } } update_sensitivity (editor); done: gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_apply_button")), valid && editor->is_changed); } static void page_changed (CEPage *page, gpointer user_data) { NetConnectionEditor *editor= user_data; if (editor_is_initialized (editor)) editor->is_changed = TRUE; validate (editor); } static gboolean idle_validate (gpointer user_data) { validate (NET_CONNECTION_EDITOR (user_data)); return G_SOURCE_REMOVE; } static void recheck_initialization (NetConnectionEditor *editor) { GtkNotebook *notebook; if (!editor_is_initialized (editor)) return; notebook = GTK_NOTEBOOK (gtk_builder_get_object (editor->builder, "details_notebook")); gtk_notebook_set_current_page (notebook, 0); if (editor->show_when_initialized) gtk_window_present (GTK_WINDOW (editor->window)); g_idle_add (idle_validate, editor); } static void page_initialized (CEPage *page, GError *error, NetConnectionEditor *editor) { GtkNotebook *notebook; GtkWidget *widget; gint position; GList *children, *l; gint i; notebook = GTK_NOTEBOOK (gtk_builder_get_object (editor->builder, "details_notebook")); widget = ce_page_get_page (page); position = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (page), "position")); g_object_set_data (G_OBJECT (widget), "position", GINT_TO_POINTER (position)); children = gtk_container_get_children (GTK_CONTAINER (notebook)); for (l = children, i = 0; l; l = l->next, i++) { gint pos = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (l->data), "position")); if (pos > position) break; } g_list_free (children); gtk_notebook_insert_page (notebook, widget, NULL, i); editor->initializing_pages = g_slist_remove (editor->initializing_pages, page); editor->pages = g_slist_append (editor->pages, page); recheck_initialization (editor); } typedef struct { NetConnectionEditor *editor; CEPage *page; const gchar *setting_name; } GetSecretsInfo; static void get_secrets_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { NMRemoteConnection *connection; GetSecretsInfo *info = user_data; GError *error = NULL; GVariant *variant; connection = NM_REMOTE_CONNECTION (source_object); variant = nm_remote_connection_get_secrets_finish (connection, res, &error); if (!variant && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { g_error_free (error); g_free (info); return; } ce_page_complete_init (info->page, info->setting_name, variant, error); g_variant_unref (variant); g_free (info); } static void get_secrets_for_page (NetConnectionEditor *editor, CEPage *page, const gchar *setting_name) { GetSecretsInfo *info; info = g_new0 (GetSecretsInfo, 1); info->editor = editor; info->page = page; info->setting_name = setting_name; nm_remote_connection_get_secrets_async (NM_REMOTE_CONNECTION (editor->orig_connection), setting_name, NULL, //FIXME get_secrets_cb, info); } static void add_page (NetConnectionEditor *editor, CEPage *page) { GtkListStore *store; GtkTreeIter iter; const gchar *title; gint position; store = GTK_LIST_STORE (gtk_builder_get_object (editor->builder, "details_store")); title = ce_page_get_title (page); position = g_slist_length (editor->initializing_pages); g_object_set_data (G_OBJECT (page), "position", GINT_TO_POINTER (position)); gtk_list_store_insert_with_values (store, &iter, -1, 0, title, 1, position, -1); editor->initializing_pages = g_slist_append (editor->initializing_pages, page); g_signal_connect (page, "changed", G_CALLBACK (page_changed), editor); g_signal_connect (page, "initialized", G_CALLBACK (page_initialized), editor); } static void net_connection_editor_set_connection (NetConnectionEditor *editor, NMConnection *connection) { GSList *pages, *l; NMSettingConnection *sc; const gchar *type; GtkTreeSelection *selection; GtkTreePath *path; editor->is_new_connection = !nm_client_get_connection_by_uuid (editor->client, nm_connection_get_uuid (connection)); if (editor->is_new_connection) { GtkWidget *button; button = GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_apply_button")); gtk_button_set_label (GTK_BUTTON (button), _("_Add")); editor->is_changed = TRUE; } editor->connection = nm_simple_connection_new_clone (connection); editor->orig_connection = g_object_ref (connection); net_connection_editor_update_title (editor); eap_method_ca_cert_ignore_load (editor->connection); sc = nm_connection_get_setting_connection (connection); type = nm_setting_connection_get_connection_type (sc); if (!editor->is_new_connection) add_page (editor, ce_page_details_new (editor->connection, editor->client, editor->device, editor->ap)); if (strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME) == 0) add_page (editor, ce_page_security_new (editor->connection, editor->client)); else if (strcmp (type, NM_SETTING_WIRED_SETTING_NAME) == 0) add_page (editor, ce_page_8021x_security_new (editor->connection, editor->client)); if (strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME) == 0) add_page (editor, ce_page_wifi_new (editor->connection, editor->client)); else if (strcmp (type, NM_SETTING_WIRED_SETTING_NAME) == 0) add_page (editor, ce_page_ethernet_new (editor->connection, editor->client)); else if (strcmp (type, NM_SETTING_VPN_SETTING_NAME) == 0) add_page (editor, ce_page_vpn_new (editor->connection, editor->client)); else { /* Unsupported type */ net_connection_editor_do_fallback (editor, type); return; } add_page (editor, ce_page_ip4_new (editor->connection, editor->client)); add_page (editor, ce_page_ip6_new (editor->connection, editor->client)); if (!editor->is_new_connection) add_page (editor, ce_page_reset_new (editor->connection, editor->client, editor)); pages = g_slist_copy (editor->initializing_pages); for (l = pages; l; l = l->next) { CEPage *page = l->data; const gchar *security_setting; security_setting = ce_page_get_security_setting (page); if (!security_setting || editor->is_new_connection) { ce_page_complete_init (page, NULL, NULL, NULL); } else { get_secrets_for_page (editor, page, security_setting); } } g_slist_free (pages); selection = GTK_TREE_SELECTION (gtk_builder_get_object (editor->builder, "details_page_list_selection")); path = gtk_tree_path_new_first (); gtk_tree_selection_select_path (selection, path); gtk_tree_path_free (path); } static NMConnection * complete_vpn_connection (NetConnectionEditor *editor, NMConnection *connection) { NMSettingConnection *s_con; NMSetting *s_type; if (!connection) connection = nm_simple_connection_new (); s_con = nm_connection_get_setting_connection (connection); if (!s_con) { s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); nm_connection_add_setting (connection, NM_SETTING (s_con)); } if (!nm_setting_connection_get_uuid (s_con)) { gchar *uuid = nm_utils_uuid_generate (); g_object_set (s_con, NM_SETTING_CONNECTION_UUID, uuid, NULL); g_free (uuid); } if (!nm_setting_connection_get_id (s_con)) { const GPtrArray *connections; gchar *id; connections = nm_client_get_connections (editor->client); id = ce_page_get_next_available_name (connections, NAME_FORMAT_TYPE, _("VPN")); g_object_set (s_con, NM_SETTING_CONNECTION_ID, id, NULL); g_free (id); } s_type = nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN); if (!s_type) { s_type = g_object_new (NM_TYPE_SETTING_VPN, NULL); nm_connection_add_setting (connection, s_type); } if (!nm_setting_connection_get_connection_type (s_con)) { g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, nm_setting_get_name (s_type), NULL); } return connection; } static void finish_add_connection (NetConnectionEditor *editor, NMConnection *connection) { GtkNotebook *notebook; GtkBin *frame; frame = GTK_BIN (gtk_builder_get_object (editor->builder, "details_add_connection_frame")); gtk_widget_destroy (gtk_bin_get_child (frame)); notebook = GTK_NOTEBOOK (gtk_builder_get_object (editor->builder, "details_toplevel_notebook")); gtk_notebook_set_current_page (notebook, 0); gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_apply_button"))); if (connection) net_connection_editor_set_connection (editor, connection); } static void vpn_import_complete (NMConnection *connection, gpointer user_data) { NetConnectionEditor *editor = user_data; if (!connection) { /* The import code shows its own error dialogs. */ g_signal_emit (editor, signals[DONE], 0, FALSE); return; } complete_vpn_connection (editor, connection); finish_add_connection (editor, connection); } static void vpn_type_activated (GtkListBox *list, GtkWidget *row, NetConnectionEditor *editor) { const char *service_name = g_object_get_data (G_OBJECT (row), "service_name"); NMConnection *connection; NMSettingVpn *s_vpn; NMSettingConnection *s_con; if (!strcmp (service_name, "import")) { vpn_import (GTK_WINDOW (editor->window), vpn_import_complete, editor); return; } connection = complete_vpn_connection (editor, NULL); s_vpn = nm_connection_get_setting_vpn (connection); g_object_set (s_vpn, NM_SETTING_VPN_SERVICE_TYPE, service_name, NULL); /* Mark the connection as private to this user, and non-autoconnect */ s_con = nm_connection_get_setting_connection (connection); g_object_set (s_con, NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, NULL); nm_setting_connection_add_permission (s_con, "user", g_get_user_name (), NULL); finish_add_connection (editor, connection); } static void select_vpn_type (NetConnectionEditor *editor, GtkListBox *list) { GSList *vpn_plugins, *iter; GList *l; GList *children; GtkWidget *row, *row_box; GtkWidget *name_label, *desc_label; /* Get the available VPN types */ vpn_plugins = vpn_get_plugins (); /* Remove the previous menu contents */ children = gtk_container_get_children (GTK_CONTAINER (list)); for (l = children; l != NULL; l = l->next) gtk_widget_destroy (l->data); /* Add the VPN types */ for (iter = vpn_plugins; iter; iter = iter->next) { NMVpnEditorPlugin *plugin = nm_vpn_plugin_info_get_editor_plugin (iter->data); char *name, *desc, *desc_markup, *service_name; GtkStyleContext *context; g_object_get (plugin, NM_VPN_EDITOR_PLUGIN_NAME, &name, NM_VPN_EDITOR_PLUGIN_DESCRIPTION, &desc, NM_VPN_EDITOR_PLUGIN_SERVICE, &service_name, NULL); desc_markup = g_markup_printf_escaped ("%s", desc); row = gtk_list_box_row_new (); row_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_widget_set_margin_start (row_box, 12); gtk_widget_set_margin_end (row_box, 12); gtk_widget_set_margin_top (row_box, 12); gtk_widget_set_margin_bottom (row_box, 12); name_label = gtk_label_new (name); gtk_widget_set_halign (name_label, GTK_ALIGN_START); gtk_box_pack_start (GTK_BOX (row_box), name_label, FALSE, TRUE, 0); desc_label = gtk_label_new (NULL); gtk_label_set_markup (GTK_LABEL (desc_label), desc_markup); gtk_label_set_line_wrap (GTK_LABEL (desc_label), TRUE); gtk_widget_set_halign (desc_label, GTK_ALIGN_START); context = gtk_widget_get_style_context (desc_label); gtk_style_context_add_class (context, "dim-label"); gtk_box_pack_start (GTK_BOX (row_box), desc_label, FALSE, TRUE, 0); g_free (name); g_free (desc); g_free (desc_markup); gtk_container_add (GTK_CONTAINER (row), row_box); gtk_widget_show_all (row); g_object_set_data_full (G_OBJECT (row), "service_name", service_name, g_free); gtk_container_add (GTK_CONTAINER (list), row); } /* Import */ row = gtk_list_box_row_new (); row_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_widget_set_margin_start (row_box, 12); gtk_widget_set_margin_end (row_box, 12); gtk_widget_set_margin_top (row_box, 12); gtk_widget_set_margin_bottom (row_box, 12); name_label = gtk_label_new (_("Import from file…")); gtk_widget_set_halign (name_label, GTK_ALIGN_START); gtk_box_pack_start (GTK_BOX (row_box), name_label, FALSE, TRUE, 0); gtk_container_add (GTK_CONTAINER (row), row_box); gtk_widget_show_all (row); g_object_set_data (G_OBJECT (row), "service_name", "import"); gtk_container_add (GTK_CONTAINER (list), row); g_signal_connect (list, "row-activated", G_CALLBACK (vpn_type_activated), editor); } static void net_connection_editor_add_connection (NetConnectionEditor *editor) { GtkNotebook *notebook; GtkContainer *frame; GtkListBox *list; notebook = GTK_NOTEBOOK (gtk_builder_get_object (editor->builder, "details_toplevel_notebook")); frame = GTK_CONTAINER (gtk_builder_get_object (editor->builder, "details_add_connection_frame")); list = GTK_LIST_BOX (gtk_list_box_new ()); gtk_list_box_set_selection_mode (list, GTK_SELECTION_NONE); gtk_list_box_set_header_func (list, cc_list_box_update_header_func, NULL, NULL); select_vpn_type (editor, list); gtk_widget_show_all (GTK_WIDGET (list)); gtk_container_add (frame, GTK_WIDGET (list)); gtk_notebook_set_current_page (notebook, 1); gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_apply_button"))); gtk_window_set_title (GTK_WINDOW (editor->window), _("Add VPN")); } static void permission_changed (NMClient *client, NMClientPermission permission, NMClientPermissionResult result, NetConnectionEditor *editor) { if (permission != NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM) return; if (result == NM_CLIENT_PERMISSION_RESULT_YES || result == NM_CLIENT_PERMISSION_RESULT_AUTH) editor->can_modify = TRUE; else editor->can_modify = FALSE; validate (editor); } NetConnectionEditor * net_connection_editor_new (GtkWindow *parent_window, NMConnection *connection, NMDevice *device, NMAccessPoint *ap, NMClient *client) { NetConnectionEditor *editor; editor = g_object_new (NET_TYPE_CONNECTION_EDITOR, NULL); if (parent_window) { editor->parent_window = GTK_WIDGET (g_object_ref (parent_window)); gtk_window_set_transient_for (GTK_WINDOW (editor->window), parent_window); } if (ap) editor->ap = g_object_ref (ap); if (device) editor->device = g_object_ref (device); editor->client = g_object_ref (client); editor->can_modify = nm_client_get_permission_result (client, NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM); editor->permission_id = g_signal_connect (editor->client, "permission-changed", G_CALLBACK (permission_changed), editor); if (connection) net_connection_editor_set_connection (editor, connection); else net_connection_editor_add_connection (editor); return editor; } void net_connection_editor_present (NetConnectionEditor *editor) { if (!editor_is_initialized (editor)) { editor->show_when_initialized = TRUE; return; } gtk_window_present (GTK_WINDOW (editor->window)); } static void forgotten_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { NMRemoteConnection *connection = NM_REMOTE_CONNECTION (source_object); NetConnectionEditor *editor = user_data; GError *error = NULL; if (!nm_remote_connection_delete_finish (connection, res, &error)) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("Failed to delete connection %s: %s", nm_connection_get_id (NM_CONNECTION (connection)), error->message); g_error_free (error); return; } cancel_editing (editor); } void net_connection_editor_forget (NetConnectionEditor *editor) { nm_remote_connection_delete_async (NM_REMOTE_CONNECTION (editor->orig_connection), NULL, forgotten_cb, editor); } void net_connection_editor_reset (NetConnectionEditor *editor) { GVariant *settings; settings = nm_connection_to_dbus (editor->orig_connection, NM_CONNECTION_SERIALIZE_ALL); nm_connection_replace_settings (editor->connection, settings, NULL); g_variant_unref (settings); } void net_connection_editor_set_title (NetConnectionEditor *editor, const gchar *title) { gtk_window_set_title (GTK_WINDOW (editor->window), title); editor->title_set = TRUE; } cinnamon-control-center-6.4.1/panels/network/connection-editor/ce-page-vpn.h0000664000175000017500000000416014724311620026056 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2013 Red Hat, Inc. * * Licensed under the GNU General Public License Version 2 * * 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 vpn. * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __CE_PAGE_VPN_H #define __CE_PAGE_VPN_H #include #include #include #include "ce-page.h" G_BEGIN_DECLS #define CE_TYPE_PAGE_VPN (ce_page_vpn_get_type ()) #define CE_PAGE_VPN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_VPN, CEPageVpn)) #define CE_PAGE_VPN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_VPN, CEPageVpnClass)) #define CE_IS_PAGE_VPN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_VPN)) #define CE_IS_PAGE_VPN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_VPN)) #define CE_PAGE_VPN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_VPN, CEPageVpnClass)) typedef struct _CEPageVpn CEPageVpn; typedef struct _CEPageVpnClass CEPageVpnClass; struct _CEPageVpn { CEPage parent; NMSettingConnection *setting_connection; NMSettingVpn *setting_vpn; GtkEntry *name; GtkBox *box; NMVpnEditorPlugin *plugin; NMVpnEditor *editor; }; struct _CEPageVpnClass { CEPageClass parent_class; }; GType ce_page_vpn_get_type (void); CEPage *ce_page_vpn_new (NMConnection *connection, NMClient *client); G_END_DECLS #endif /* __CE_PAGE_VPN_H */ cinnamon-control-center-6.4.1/panels/network/connection-editor/ce-page.c0000664000175000017500000003767214724311620025266 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Red Hat, Inc * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include #include "ce-page.h" G_DEFINE_ABSTRACT_TYPE (CEPage, ce_page, G_TYPE_OBJECT) enum { PROP_0, PROP_CONNECTION, PROP_INITIALIZED, }; enum { CHANGED, INITIALIZED, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; gboolean ce_page_validate (CEPage *page, NMConnection *connection, GError **error) { g_return_val_if_fail (CE_IS_PAGE (page), FALSE); g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); if (CE_PAGE_GET_CLASS (page)->validate) return CE_PAGE_GET_CLASS (page)->validate (page, connection, error); return TRUE; } static void dispose (GObject *object) { CEPage *self = CE_PAGE (object); g_clear_object (&self->page); g_clear_object (&self->builder); g_clear_object (&self->connection); G_OBJECT_CLASS (ce_page_parent_class)->dispose (object); } static void finalize (GObject *object) { CEPage *self = CE_PAGE (object); g_free (self->title); if (self->cancellable) { g_cancellable_cancel (self->cancellable); g_object_unref (self->cancellable); } G_OBJECT_CLASS (ce_page_parent_class)->finalize (object); } GtkWidget * ce_page_get_page (CEPage *self) { g_return_val_if_fail (CE_IS_PAGE (self), NULL); return self->page; } const char * ce_page_get_title (CEPage *self) { g_return_val_if_fail (CE_IS_PAGE (self), NULL); return self->title; } gboolean ce_page_get_initialized (CEPage *self) { g_return_val_if_fail (CE_IS_PAGE (self), FALSE); return self->initialized; } void ce_page_changed (CEPage *self) { g_return_if_fail (CE_IS_PAGE (self)); g_signal_emit (self, signals[CHANGED], 0); } static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { CEPage *self = CE_PAGE (object); switch (prop_id) { case PROP_CONNECTION: g_value_set_object (value, self->connection); break; case PROP_INITIALIZED: g_value_set_boolean (value, self->initialized); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { CEPage *self = CE_PAGE (object); switch (prop_id) { case PROP_CONNECTION: if (self->connection) g_object_unref (self->connection); self->connection = g_value_dup_object (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void ce_page_init (CEPage *self) { self->builder = gtk_builder_new (); self->cancellable = g_cancellable_new (); } static void ce_page_class_init (CEPageClass *page_class) { GObjectClass *object_class = G_OBJECT_CLASS (page_class); /* virtual methods */ object_class->dispose = dispose; object_class->finalize = finalize; object_class->get_property = get_property; object_class->set_property = set_property; /* Properties */ g_object_class_install_property (object_class, PROP_CONNECTION, g_param_spec_object ("connection", "Connection", "Connection", NM_TYPE_CONNECTION, G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, PROP_INITIALIZED, g_param_spec_boolean ("initialized", "Initialized", "Initialized", FALSE, G_PARAM_READABLE)); signals[CHANGED] = g_signal_new ("changed", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (CEPageClass, changed), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals[INITIALIZED] = g_signal_new ("initialized", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (CEPageClass, initialized), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); } CEPage * ce_page_new (GType type, NMConnection *connection, NMClient *client, const gchar *ui_resource, const gchar *title) { CEPage *page; GError *error = NULL; page = CE_PAGE (g_object_new (type, "connection", connection, NULL)); page->title = g_strdup (title); page->client = client; if (ui_resource) { if (!gtk_builder_add_from_resource (page->builder, ui_resource, &error)) { g_warning ("Couldn't load builder file: %s", error->message); g_error_free (error); g_object_unref (page); return NULL; } page->page = GTK_WIDGET (gtk_builder_get_object (page->builder, "page")); if (!page->page) { g_warning ("Couldn't load page widget from %s", ui_resource); g_object_unref (page); return NULL; } g_object_ref_sink (page->page); } return page; } static void emit_initialized (CEPage *page, GError *error) { page->initialized = TRUE; g_signal_emit (page, signals[INITIALIZED], 0, error); g_clear_error (&error); } void ce_page_complete_init (CEPage *page, const gchar *setting_name, GVariant *secrets, GError *error) { GError *update_error = NULL; GVariant *setting_dict; gboolean ignore_error = FALSE; g_return_if_fail (page != NULL); g_return_if_fail (CE_IS_PAGE (page)); if (error) { ignore_error = g_error_matches (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND) || g_error_matches (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_NO_SECRETS); } /* Ignore missing settings errors */ if (error && !ignore_error) { emit_initialized (page, error); return; } else if (!setting_name || !secrets || g_variant_n_children (secrets) == 0) { /* Success, no secrets */ emit_initialized (page, NULL); return; } g_assert (setting_name); g_assert (secrets); setting_dict = g_variant_lookup_value (secrets, setting_name, NM_VARIANT_TYPE_SETTING); if (!setting_dict) { /* Success, no secrets */ emit_initialized (page, NULL); return; } g_variant_unref (setting_dict); /* Update the connection with the new secrets */ if (nm_connection_update_secrets (page->connection, setting_name, secrets, &update_error)) { /* Success */ emit_initialized (page, NULL); return; } g_warning ("Failed to update connection secrets due to an unknown error."); emit_initialized (page, NULL); } gchar ** ce_page_get_mac_list (NMClient *client, GType device_type, const gchar *mac_property) { const GPtrArray *devices; GPtrArray *macs; int i; macs = g_ptr_array_new (); devices = nm_client_get_devices (client); for (i = 0; devices && (i < devices->len); i++) { NMDevice *dev = g_ptr_array_index (devices, i); const char *iface; char *mac, *item; if (!G_TYPE_CHECK_INSTANCE_TYPE (dev, device_type)) continue; g_object_get (G_OBJECT (dev), mac_property, &mac, NULL); iface = nm_device_get_iface (NM_DEVICE (dev)); item = g_strdup_printf ("%s (%s)", mac, iface); g_free (mac); g_ptr_array_add (macs, item); } g_ptr_array_add (macs, NULL); return (char **)g_ptr_array_free (macs, FALSE); } void ce_page_setup_mac_combo (GtkComboBoxText *combo, const gchar *current_mac, gchar **mac_list) { gchar **m, *active_mac = NULL; gint current_mac_len; GtkWidget *entry; if (current_mac) current_mac_len = strlen (current_mac); else current_mac_len = -1; for (m= mac_list; m && *m; m++) { gtk_combo_box_text_append_text (combo, *m); if (current_mac && g_ascii_strncasecmp (*m, current_mac, current_mac_len) == 0 && ((*m)[current_mac_len] == '\0' || (*m)[current_mac_len] == ' ')) active_mac = *m; } if (current_mac) { if (!active_mac) { gtk_combo_box_text_prepend_text (combo, current_mac); } entry = gtk_bin_get_child (GTK_BIN (combo)); if (entry) gtk_entry_set_text (GTK_ENTRY (entry), active_mac ? active_mac : current_mac); } } gchar * ce_page_trim_address (const gchar *addr) { char *space; if (!addr || *addr == '\0') return NULL; space = strchr (addr, ' '); if (space != NULL) return g_strndup (addr, space - addr); return g_strdup (addr); } gboolean ce_page_address_is_valid (const gchar *addr) { guint8 invalid_addr[4][ETH_ALEN] = { {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x44, 0x44, 0x44, 0x44, 0x44, 0x44}, {0x00, 0x30, 0xb4, 0x00, 0x00, 0x00}, /* prism54 dummy MAC */ }; guint8 addr_bin[ETH_ALEN]; char *trimmed_addr; guint i; if (!addr || *addr == '\0') return TRUE; trimmed_addr = ce_page_trim_address (addr); if (!nm_utils_hwaddr_valid (trimmed_addr, -1)) { g_free (trimmed_addr); return FALSE; } if (!nm_utils_hwaddr_aton (trimmed_addr, addr_bin, ETH_ALEN)) { g_free (trimmed_addr); return FALSE; } g_free (trimmed_addr); /* Check for multicast address */ if ((((guint8 *) addr_bin)[0]) & 0x01) return FALSE; for (i = 0; i < G_N_ELEMENTS (invalid_addr); i++) { if (nm_utils_hwaddr_matches (addr_bin, ETH_ALEN, invalid_addr[i], ETH_ALEN)) return FALSE; } return TRUE; } const gchar * ce_page_get_security_setting (CEPage *page) { return page->security_setting; } gint ce_get_property_default (NMSetting *setting, const gchar *property_name) { GParamSpec *spec; GValue value = { 0, }; spec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), property_name); g_return_val_if_fail (spec != NULL, -1); g_value_init (&value, spec->value_type); g_param_value_set_default (spec, &value); if (G_VALUE_HOLDS_CHAR (&value)) return (int) g_value_get_schar (&value); else if (G_VALUE_HOLDS_INT (&value)) return g_value_get_int (&value); else if (G_VALUE_HOLDS_INT64 (&value)) return (int) g_value_get_int64 (&value); else if (G_VALUE_HOLDS_LONG (&value)) return (int) g_value_get_long (&value); else if (G_VALUE_HOLDS_UINT (&value)) return (int) g_value_get_uint (&value); else if (G_VALUE_HOLDS_UINT64 (&value)) return (int) g_value_get_uint64 (&value); else if (G_VALUE_HOLDS_ULONG (&value)) return (int) g_value_get_ulong (&value); else if (G_VALUE_HOLDS_UCHAR (&value)) return (int) g_value_get_uchar (&value); g_return_val_if_fail (FALSE, 0); return 0; } gint ce_spin_output_with_default (GtkSpinButton *spin, gpointer user_data) { gint defvalue = GPOINTER_TO_INT (user_data); gint val; gchar *buf = NULL; val = gtk_spin_button_get_value_as_int (spin); if (val == defvalue) buf = g_strdup (_("automatic")); else buf = g_strdup_printf ("%d", val); if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin)))) gtk_entry_set_text (GTK_ENTRY (spin), buf); g_free (buf); return TRUE; } gchar * ce_page_get_next_available_name (const GPtrArray *connections, NameFormat format, const gchar *type_name) { GSList *names = NULL, *l; gchar *cname = NULL; gint i = 0; guint con_idx; for (con_idx = 0; con_idx < connections->len; con_idx++) { NMConnection *connection = g_ptr_array_index (connections, con_idx); const gchar *id; id = nm_connection_get_id (connection); g_assert (id); names = g_slist_append (names, (gpointer) id); } /* Find the next available unique connection name */ while (!cname && (i++ < 10000)) { gchar *temp; gboolean found = FALSE; switch (format) { case NAME_FORMAT_TYPE: temp = g_strdup_printf ("%s %d", type_name, i); break; case NAME_FORMAT_PROFILE: temp = g_strdup_printf (_("Profile %d"), i); break; default: g_assert_not_reached (); } for (l = names; l; l = l->next) { if (!strcmp (l->data, temp)) { found = TRUE; break; } } if (!found) cname = temp; else g_free (temp); } g_slist_free (names); return cname; } cinnamon-control-center-6.4.1/panels/network/connection-editor/firewall-helpers.c0000664000175000017500000001024714724311620027217 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (C) Copyright 2013 Red Hat, Inc. */ #include "config.h" #include #include #include "firewall-helpers.h" typedef struct { gchar *zone; GtkWidget *combo; GtkWidget *label; } GetZonesReplyData; static void get_zones_reply (GObject *source, GAsyncResult *res, gpointer user_data) { GDBusConnection *bus = G_DBUS_CONNECTION (source); GetZonesReplyData *d = user_data; GVariant *ret; GError *error = NULL; const gchar **zones; gint idx; gint i; ret = g_dbus_connection_call_finish (bus, res, &error); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (d->combo), C_("Firewall zone", "Default")); gtk_widget_set_tooltip_text (d->combo, _("The zone defines the trust level of the connection")); idx = 0; if (error) { gtk_widget_hide (d->combo); gtk_widget_hide (d->label); g_error_free (error); } else { gtk_widget_show (d->combo); gtk_widget_show (d->label); g_variant_get (ret, "(^a&s)", &zones); for (i = 0; zones[i]; i++) { gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (d->combo), zones[i]); if (g_strcmp0 (d->zone, zones[i]) == 0) idx = i + 1; } if (d->zone && idx == 0) { gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (d->combo), d->zone); idx = i + 1; } g_variant_unref (ret); } gtk_combo_box_set_active (GTK_COMBO_BOX (d->combo), idx); g_free (d->zone); g_free (d); } void firewall_ui_setup (NMSettingConnection *setting, GtkWidget *combo, GtkWidget *label, GCancellable *cancellable) { GDBusConnection *bus; GetZonesReplyData *d; bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL); d = g_new0 (GetZonesReplyData, 1); d->zone = g_strdup (nm_setting_connection_get_zone (setting)); d->combo = combo; d->label = label; g_dbus_connection_call (bus, "org.fedoraproject.FirewallD1", "/org/fedoraproject/FirewallD1", "org.fedoraproject.FirewallD1.zone", "getZones", NULL, NULL, 0, G_MAXINT, cancellable, get_zones_reply, d); g_object_unref (bus); } void firewall_ui_to_setting (NMSettingConnection *setting, GtkWidget *combo) { gchar *zone; zone = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (combo)); if (g_strcmp0 (zone, C_("Firewall zone", "Default")) == 0) { g_free (zone); zone = NULL; } g_object_set (setting, NM_SETTING_CONNECTION_ZONE, zone, NULL); g_free (zone); } cinnamon-control-center-6.4.1/panels/network/connection-editor/ip4-page.ui0000664000175000017500000003516214724311620025556 0ustar fabiofabio True True never True False True False 20 20 10 10 vertical 10 True False True False IPv_4 True switch_enable False True 0 True True end True False True 1 False True 0 True False vertical 10 True False True False _Addresses True combo_addresses False True 0 True False end True 0 1 False True 1 False True 0 True False vertical False True 1 True False 24 6 6 True False 0 DNS False True 0 True False True 1 Automatic False True 1 True True end Automatic DNS False True 2 False True 2 True False vertical False True 3 True False 24 5 6 True False 0 Routes False True 0 True False True 1 Automatic False True 1 True True Automatic Routes False True 2 False True 4 True False vertical False True 5 Use this connection _only for resources on its network True True False True 0 True False True 7 False True 1 cinnamon-control-center-6.4.1/panels/network/connection-editor/ce-page-wifi.c0000664000175000017500000002146214724311620026210 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Red Hat, Inc * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include "ce-page-wifi.h" #include "ui-helpers.h" G_DEFINE_TYPE (CEPageWifi, ce_page_wifi, CE_TYPE_PAGE) static void all_user_changed (GtkToggleButton *b, CEPageWifi *page) { gboolean all_users; NMSettingConnection *sc; sc = nm_connection_get_setting_connection (CE_PAGE (page)->connection); all_users = gtk_toggle_button_get_active (b); g_object_set (sc, "permissions", NULL, NULL); if (!all_users) nm_setting_connection_add_permission (sc, "user", g_get_user_name (), NULL); } static void connect_wifi_page (CEPageWifi *page) { NMSettingConnection *sc; GtkWidget *widget; GBytes *ssid; gchar *utf8_ssid; GPtrArray *bssid_array; gchar **bssid_list; const char *s_bssid_str; gchar **mac_list; const gchar *s_mac_str; const gchar *cloned_mac; gint i; widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_ssid")); ssid = nm_setting_wireless_get_ssid (page->setting); if (ssid) utf8_ssid = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid)); else utf8_ssid = g_strdup (""); gtk_entry_set_text (GTK_ENTRY (widget), utf8_ssid); g_free (utf8_ssid); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_bssid")); bssid_array = g_ptr_array_new (); for (i = 0; i < nm_setting_wireless_get_num_seen_bssids (page->setting); i++) { g_ptr_array_add (bssid_array, g_strdup (nm_setting_wireless_get_seen_bssid (page->setting, i))); } g_ptr_array_add (bssid_array, NULL); bssid_list = (gchar **) g_ptr_array_free (bssid_array, FALSE); s_bssid_str = nm_setting_wireless_get_bssid (page->setting); ce_page_setup_mac_combo (GTK_COMBO_BOX_TEXT (widget), s_bssid_str, bssid_list); g_strfreev (bssid_list); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_mac")); mac_list = ce_page_get_mac_list (CE_PAGE (page)->client, NM_TYPE_DEVICE_WIFI, NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS); s_mac_str = nm_setting_wireless_get_mac_address (page->setting); ce_page_setup_mac_combo (GTK_COMBO_BOX_TEXT (widget), s_mac_str, mac_list); g_strfreev (mac_list); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_cloned_mac")); cloned_mac = nm_setting_wireless_get_cloned_mac_address (page->setting); gtk_entry_set_text (GTK_ENTRY (widget), cloned_mac ? cloned_mac : ""); g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_connect_check")); sc = nm_connection_get_setting_connection (CE_PAGE (page)->connection); g_object_bind_property (sc, "autoconnect", widget, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); g_signal_connect_swapped (widget, "toggled", G_CALLBACK (ce_page_changed), page); widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "all_user_check")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), nm_setting_connection_get_num_permissions (sc) == 0); g_signal_connect (widget, "toggled", G_CALLBACK (all_user_changed), page); g_signal_connect_swapped (widget, "toggled", G_CALLBACK (ce_page_changed), page); widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_zone")); } static void ui_to_setting (CEPageWifi *page) { GBytes *ssid; const gchar *utf8_ssid, *bssid; GtkWidget *entry; char *device_mac, *cloned_mac; entry = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_ssid")); utf8_ssid = gtk_entry_get_text (GTK_ENTRY (entry)); if (!utf8_ssid || !*utf8_ssid) ssid = NULL; else { ssid = g_bytes_new_static (utf8_ssid, strlen (utf8_ssid)); } entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_bssid"))); bssid = gtk_entry_get_text (GTK_ENTRY (entry)); if (*bssid == '\0') bssid = NULL; entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_mac"))); device_mac = ce_page_trim_address (gtk_entry_get_text (GTK_ENTRY (entry))); entry = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_cloned_mac")); cloned_mac = ce_page_trim_address (gtk_entry_get_text (GTK_ENTRY (entry))); g_object_set (page->setting, NM_SETTING_WIRELESS_SSID, ssid, NM_SETTING_WIRELESS_BSSID, bssid, NM_SETTING_WIRELESS_MAC_ADDRESS, device_mac, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, cloned_mac, NULL); if (ssid) g_bytes_unref (ssid); g_free (cloned_mac); g_free (device_mac); } static gboolean validate (CEPage *page, NMConnection *connection, GError **error) { GtkWidget *entry; gboolean ret = TRUE; entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (page->builder, "combo_bssid"))); if (!ce_page_address_is_valid (gtk_entry_get_text (GTK_ENTRY (entry)))) { widget_set_error (entry); ret = FALSE; } else { widget_unset_error (entry); } entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (page->builder, "combo_mac"))); if (!ce_page_address_is_valid (gtk_entry_get_text (GTK_ENTRY (entry)))) { widget_set_error (entry); ret = FALSE; } else { widget_unset_error (entry); } entry = GTK_WIDGET (gtk_builder_get_object (page->builder, "entry_cloned_mac")); if (!ce_page_address_is_valid (gtk_entry_get_text (GTK_ENTRY (entry)))) { widget_set_error (entry); ret = FALSE; } else { widget_unset_error (entry); } if (!ret) return ret; ui_to_setting (CE_PAGE_WIFI (page)); return ret; } static void ce_page_wifi_init (CEPageWifi *page) { } static void ce_page_wifi_class_init (CEPageWifiClass *class) { CEPageClass *page_class= CE_PAGE_CLASS (class); page_class->validate = validate; } CEPage * ce_page_wifi_new (NMConnection *connection, NMClient *client) { CEPageWifi *page; page = CE_PAGE_WIFI (ce_page_new (CE_TYPE_PAGE_WIFI, connection, client, "/org/cinnamon/control-center/network/wifi-page.ui", _("Identity"))); page->setting = nm_connection_get_setting_wireless (connection); connect_wifi_page (page); return CE_PAGE (page); } cinnamon-control-center-6.4.1/panels/network/connection-editor/8021x-security-page.ui0000664000175000017500000002550314724311620027507 0ustar fabiofabio True True False False True False 50 50 12 12 True True 10 6 True False 1 802.1x _Security True 8021x_switch 0 0 1 1 True True start True 1 0 1 1 True False vertical 0 1 2 1 True False page 1 False True False 50 50 12 12 10 6 True True ā— 35 1 0 1 1 True True ā— 1 1 1 1 True True ā— 1 2 1 1 True True ā— 1 3 1 1 True True ā— 1 4 1 1 True True ā— 1 5 1 1 True True ā— 1 6 1 1 True True ā— 1 7 1 1 True True ā— 1 8 1 1 True True ā— 1 9 1 1 True False Anony_mous identity True 0 0 1 1 True False Inner _authentication True 0 1 1 1 1 True False page 2 1 False cinnamon-control-center-6.4.1/panels/network/connection-editor/vpn-helpers.h0000664000175000017500000000267714724311620026232 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Connection editor -- Connection editor for NetworkManager * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (C) Copyright 2008 Red Hat, Inc. */ #ifndef _VPN_HELPERS_H_ #define _VPN_HELPERS_H_ #include #include #include GSList *vpn_get_plugins (void); NMVpnEditorPlugin *vpn_get_plugin_by_service (const char *service); typedef void (*VpnImportCallback) (NMConnection *connection, gpointer user_data); void vpn_import (GtkWindow *parent, VpnImportCallback callback, gpointer user_data); void vpn_export (NMConnection *connection); gboolean vpn_supports_ipv6 (NMConnection *connection); #endif /* _VPN_HELPERS_H_ */ cinnamon-control-center-6.4.1/panels/network/connection-editor/ethernet-page.ui0000664000175000017500000002514414724311620026677 0ustar fabiofabio 10000 1 10 Automatic Twisted Pair (TP) Attachment Unit Interface (AUI) BNC Media Independent Interface (MII) Automatic 10 Mb/s 100 Mb/s 1 Gb/s 10 Gb/s True False 50 50 12 12 True True 10 6 True False 1 _Name True entry_name 0 0 1 1 True True ā— 1 0 1 1 True False 1 _MAC Address True combo_mac 0 1 1 1 True False True 0 1 1 1 1 1 True True True ā— True 1 2 1 1 True False 1 M_TU True spin_mtu 0 3 1 1 True False center 1 _Cloned Address True entry_cloned_mac 0 2 1 1 True False bytes 2 3 1 1 True True ā— True adjustment1 1 3 1 1 True False 2 0 1 1 Make available to other _users True True False True 0 True 0 6 2 1 Connect _automatically True True False end True True 0 True 0 5 2 1 True False 1 Firewall _Zone True combo_zone 0 4 1 1 True False 0 1 1 4 1 1 cinnamon-control-center-6.4.1/panels/network/connection-editor/connection-editor.gresource.xml0000664000175000017500000000136614724311620031752 0ustar fabiofabio 8021x-security-page.ui connection-editor.ui details-page.ui ethernet-page.ui ip4-page.ui ip6-page.ui reset-page.ui security-page.ui vpn-page.ui wifi-page.ui cinnamon-control-center-6.4.1/panels/network/panel-common.c0000664000175000017500000006444714724311620022727 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2010 Richard Hughes * Copyright (C) 2012 Thomas Bechtold * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include "panel-common.h" /** * panel_device_to_icon_name: **/ const gchar * panel_device_to_icon_name (NMDevice *device, gboolean symbolic) { const gchar *value = NULL; NMDeviceState state; NMDeviceModemCapabilities caps; switch (nm_device_get_device_type (device)) { case NM_DEVICE_TYPE_ETHERNET: state = nm_device_get_state (device); if (state <= NM_DEVICE_STATE_DISCONNECTED) { value = symbolic ? "network-wired-disconnected-symbolic" : "network-wired-disconnected"; } else { value = symbolic ? "network-wired-symbolic" : "network-wired"; } break; case NM_DEVICE_TYPE_WIFI: case NM_DEVICE_TYPE_BT: case NM_DEVICE_TYPE_OLPC_MESH: value = symbolic ? "network-wireless-signal-excellent-symbolic" : "network-wireless"; break; case NM_DEVICE_TYPE_MODEM: caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device)); if ((caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) || (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)) { value = symbolic ? "network-cellular-signal-excellent-symbolic" : "network-cellular"; break; } /* fall thru */ default: value = symbolic ? "network-idle-symbolic" : "network-idle"; break; } return value; } /** * panel_device_get_sort_category: * * Try to return order of approximate connection speed. * But sort wifi first, since that's the common case. **/ gint panel_device_get_sort_category (NMDevice *device) { gint value = 0; NMDeviceModemCapabilities caps; switch (nm_device_get_device_type (device)) { case NM_DEVICE_TYPE_ETHERNET: value = 2; break; case NM_DEVICE_TYPE_WIFI: value = 1; break; case NM_DEVICE_TYPE_MODEM: caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device)); if ((caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) || (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)) { value = 3; } break; case NM_DEVICE_TYPE_BT: value = 4; break; case NM_DEVICE_TYPE_OLPC_MESH: value = 5; break; default: value = 6; break; } return value; } /** * panel_ap_mode_to_localized_string: **/ const gchar * panel_ap_mode_to_localized_string (NM80211Mode mode) { const gchar *value = NULL; switch (mode) { case NM_802_11_MODE_UNKNOWN: /* TRANSLATORS: AP type */ value = _("Unknown"); break; case NM_802_11_MODE_ADHOC: /* TRANSLATORS: AP type */ value = _("Ad-hoc"); break; case NM_802_11_MODE_INFRA: /* TRANSLATORS: AP type */ value = _("Infrastructure"); break; default: break; } return value; } static const gchar * device_state_to_localized_string (NMDeviceState state) { const gchar *value = NULL; switch (state) { case NM_DEVICE_STATE_UNKNOWN: /* TRANSLATORS: device status */ value = _("Status unknown"); break; case NM_DEVICE_STATE_UNMANAGED: /* TRANSLATORS: device status */ value = _("Unmanaged"); break; case NM_DEVICE_STATE_UNAVAILABLE: /* TRANSLATORS: device status */ value = _("Unavailable"); break; case NM_DEVICE_STATE_DISCONNECTED: value = NULL; break; case NM_DEVICE_STATE_PREPARE: case NM_DEVICE_STATE_CONFIG: case NM_DEVICE_STATE_IP_CONFIG: case NM_DEVICE_STATE_IP_CHECK: /* TRANSLATORS: device status */ value = _("Connecting"); break; case NM_DEVICE_STATE_NEED_AUTH: /* TRANSLATORS: device status */ value = _("Authentication required"); break; case NM_DEVICE_STATE_ACTIVATED: /* TRANSLATORS: device status */ value = _("Connected"); break; case NM_DEVICE_STATE_DEACTIVATING: /* TRANSLATORS: device status */ value = _("Disconnecting"); break; case NM_DEVICE_STATE_FAILED: /* TRANSLATORS: device status */ value = _("Connection failed"); break; default: /* TRANSLATORS: device status */ value = _("Status unknown (missing)"); break; } return value; } /** * panel_vpn_state_to_localized_string: **/ const gchar * panel_vpn_state_to_localized_string (NMVpnConnectionState type) { const gchar *value = NULL; switch (type) { case NM_DEVICE_STATE_UNKNOWN: /* TRANSLATORS: VPN status */ value = _("Status unknown"); break; case NM_VPN_CONNECTION_STATE_PREPARE: case NM_VPN_CONNECTION_STATE_CONNECT: case NM_VPN_CONNECTION_STATE_IP_CONFIG_GET: /* TRANSLATORS: VPN status */ value = _("Connecting"); break; case NM_VPN_CONNECTION_STATE_NEED_AUTH: /* TRANSLATORS: VPN status */ value = _("Authentication required"); break; case NM_VPN_CONNECTION_STATE_ACTIVATED: /* TRANSLATORS: VPN status */ value = _("Connected"); break; case NM_VPN_CONNECTION_STATE_FAILED: /* TRANSLATORS: VPN status */ value = _("Connection failed"); break; case NM_VPN_CONNECTION_STATE_DISCONNECTED: /* TRANSLATORS: VPN status */ value = _("Not connected"); break; default: /* TRANSLATORS: VPN status */ value = _("Status unknown (missing)"); break; } return value; } static const gchar * device_state_reason_to_localized_string (NMDevice *device) { const gchar *value = NULL; NMDeviceStateReason state_reason; /* This only covers NMDeviceStateReasons that explain why a connection * failed / can't be attempted, and aren't redundant with the state * (eg, NM_DEVICE_STATE_REASON_CARRIER). */ state_reason = nm_device_get_state_reason (device); switch (state_reason) { case NM_DEVICE_STATE_REASON_CONFIG_FAILED: /* TRANSLATORS: device status reason */ value = _("Configuration failed"); break; case NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE: /* TRANSLATORS: device status reason */ value = _("IP configuration failed"); break; case NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED: /* TRANSLATORS: device status reason */ value = _("IP configuration expired"); break; case NM_DEVICE_STATE_REASON_NO_SECRETS: /* TRANSLATORS: device status reason */ value = _("Secrets were required, but not provided"); break; case NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT: /* TRANSLATORS: device status reason */ value = _("802.1x supplicant disconnected"); break; case NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED: /* TRANSLATORS: device status reason */ value = _("802.1x supplicant configuration failed"); break; case NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED: /* TRANSLATORS: device status reason */ value = _("802.1x supplicant failed"); break; case NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT: /* TRANSLATORS: device status reason */ value = _("802.1x supplicant took too long to authenticate"); break; case NM_DEVICE_STATE_REASON_PPP_START_FAILED: /* TRANSLATORS: device status reason */ value = _("PPP service failed to start"); break; case NM_DEVICE_STATE_REASON_PPP_DISCONNECT: /* TRANSLATORS: device status reason */ value = _("PPP service disconnected"); break; case NM_DEVICE_STATE_REASON_PPP_FAILED: /* TRANSLATORS: device status reason */ value = _("PPP failed"); break; case NM_DEVICE_STATE_REASON_DHCP_START_FAILED: /* TRANSLATORS: device status reason */ value = _("DHCP client failed to start"); break; case NM_DEVICE_STATE_REASON_DHCP_ERROR: /* TRANSLATORS: device status reason */ value = _("DHCP client error"); break; case NM_DEVICE_STATE_REASON_DHCP_FAILED: /* TRANSLATORS: device status reason */ value = _("DHCP client failed"); break; case NM_DEVICE_STATE_REASON_SHARED_START_FAILED: /* TRANSLATORS: device status reason */ value = _("Shared connection service failed to start"); break; case NM_DEVICE_STATE_REASON_SHARED_FAILED: /* TRANSLATORS: device status reason */ value = _("Shared connection service failed"); break; case NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED: /* TRANSLATORS: device status reason */ value = _("AutoIP service failed to start"); break; case NM_DEVICE_STATE_REASON_AUTOIP_ERROR: /* TRANSLATORS: device status reason */ value = _("AutoIP service error"); break; case NM_DEVICE_STATE_REASON_AUTOIP_FAILED: /* TRANSLATORS: device status reason */ value = _("AutoIP service failed"); break; case NM_DEVICE_STATE_REASON_MODEM_BUSY: /* TRANSLATORS: device status reason */ value = _("Line busy"); break; case NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE: /* TRANSLATORS: device status reason */ value = _("No dial tone"); break; case NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER: /* TRANSLATORS: device status reason */ value = _("No carrier could be established"); break; case NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT: /* TRANSLATORS: device status reason */ value = _("Dialing request timed out"); break; case NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED: /* TRANSLATORS: device status reason */ value = _("Dialing attempt failed"); break; case NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED: /* TRANSLATORS: device status reason */ value = _("Modem initialization failed"); break; case NM_DEVICE_STATE_REASON_GSM_APN_FAILED: /* TRANSLATORS: device status reason */ value = _("Failed to select the specified APN"); break; case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING: /* TRANSLATORS: device status reason */ value = _("Not searching for networks"); break; case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED: /* TRANSLATORS: device status reason */ value = _("Network registration denied"); break; case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT: /* TRANSLATORS: device status reason */ value = _("Network registration timed out"); break; case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED: /* TRANSLATORS: device status reason */ value = _("Failed to register with the requested network"); break; case NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED: /* TRANSLATORS: device status reason */ value = _("PIN check failed"); break; case NM_DEVICE_STATE_REASON_FIRMWARE_MISSING: /* TRANSLATORS: device status reason */ value = _("Firmware for the device may be missing"); break; case NM_DEVICE_STATE_REASON_CONNECTION_REMOVED: /* TRANSLATORS: device status reason */ value = _("Connection disappeared"); break; case NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED: /* TRANSLATORS: device status reason */ value = _("Existing connection was assumed"); break; case NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND: /* TRANSLATORS: device status reason */ value = _("Modem not found"); break; case NM_DEVICE_STATE_REASON_BT_FAILED: /* TRANSLATORS: device status reason */ value = _("Bluetooth connection failed"); break; case NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED: /* TRANSLATORS: device status reason */ value = _("SIM Card not inserted"); break; case NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED: /* TRANSLATORS: device status reason */ value = _("SIM Pin required"); break; case NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED: /* TRANSLATORS: device status reason */ value = _("SIM Puk required"); break; case NM_DEVICE_STATE_REASON_GSM_SIM_WRONG: /* TRANSLATORS: device status reason */ value = _("SIM wrong"); break; case NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED: /* TRANSLATORS: device status reason */ value = _("Connection dependency failed"); break; default: /* no StateReason to show */ value = ""; break; } return value; } static gchar * device_status_to_localized_string (NMDevice *nm_device, const gchar *speed) { NMDeviceState state; GString *string; const gchar *state_str = NULL, *reason_str = NULL; string = g_string_new (NULL); state = nm_device_get_state (nm_device); if (state == NM_DEVICE_STATE_UNAVAILABLE) { if (nm_device_get_firmware_missing (nm_device)) { /* TRANSLATORS: device status */ state_str = _("Firmware missing"); } else if (NM_IS_DEVICE_ETHERNET (nm_device) && !nm_device_ethernet_get_carrier (NM_DEVICE_ETHERNET (nm_device))) { /* TRANSLATORS: device status */ state_str = _("Cable unplugged"); } } if (!state_str) state_str = device_state_to_localized_string (state); if (state_str) g_string_append (string, state_str); if (state > NM_DEVICE_STATE_UNAVAILABLE && speed) { if (string->len) g_string_append (string, " - "); g_string_append (string, speed); } else if (state == NM_DEVICE_STATE_UNAVAILABLE || state == NM_DEVICE_STATE_DISCONNECTED || state == NM_DEVICE_STATE_DEACTIVATING || state == NM_DEVICE_STATE_FAILED) { reason_str = device_state_reason_to_localized_string (nm_device); if (*reason_str) { if (string->len) g_string_append (string, " - "); g_string_append (string, reason_str); } } return g_string_free (string, FALSE); } void panel_set_device_status (GtkBuilder *builder, const gchar *label_name, NMDevice *nm_device, const gchar *speed) { GtkLabel *label; gchar *status; label = GTK_LABEL (gtk_builder_get_object (builder, label_name)); status = device_status_to_localized_string (nm_device, speed); gtk_label_set_label (label, status); g_free (status); } gboolean panel_set_device_widget_details (GtkBuilder *builder, const gchar *widget_suffix, const gchar *value) { gchar *heading_id; gchar *label_id; GtkWidget *heading; GtkWidget *widget; /* hide the row if there is no value */ heading_id = g_strdup_printf ("heading_%s", widget_suffix); label_id = g_strdup_printf ("label_%s", widget_suffix); heading = GTK_WIDGET (gtk_builder_get_object (builder, heading_id)); widget = GTK_WIDGET (gtk_builder_get_object (builder, label_id)); if (heading == NULL || widget == NULL) { g_critical ("no widgets %s, %s found", heading_id, label_id); return FALSE; } g_free (heading_id); g_free (label_id); if (value == NULL) { gtk_widget_hide (heading); gtk_widget_hide (widget); } else { /* there exists a value */ gtk_widget_show (heading); gtk_widget_show (widget); gtk_label_set_label (GTK_LABEL (widget), value); gtk_label_set_max_width_chars (GTK_LABEL (widget), 50); gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END); } return TRUE; } gboolean panel_set_device_widget_header (GtkBuilder *builder, const gchar *widget_suffix, const gchar *heading) { gchar *label_id = NULL; GtkWidget *widget; label_id = g_strdup_printf ("heading_%s", widget_suffix); widget = GTK_WIDGET (gtk_builder_get_object (builder, label_id)); if (widget == NULL) { g_critical ("no widget %s found", label_id); return FALSE; } gtk_label_set_label (GTK_LABEL (widget), heading); g_free (label_id); return TRUE; } gchar * panel_get_ip4_address_as_string (NMIPConfig *ip4_config, const char *what) { const gchar *str = NULL; /* we only care about one address */ if (!strcmp (what, "address")) { GPtrArray *array; NMIPAddress *address; array = nm_ip_config_get_addresses (ip4_config); if (array->len < 1) goto out; address = array->pdata[0]; str = nm_ip_address_get_address (address); } else if (!strcmp (what, "gateway")) { str = nm_ip_config_get_gateway (ip4_config); } out: return g_strdup (str); } gchar * panel_get_dns_as_string (NMIPConfig *ip_config) { const char *const *arrc; arrc = nm_ip_config_get_nameservers (ip_config); if (*arrc != NULL) return g_strjoinv (" ", (char **) arrc); return NULL; } gchar * panel_get_ip6_address_as_string (NMIPConfig *ip6_config, const char *what) { gchar *str = NULL; if (!strcmp (what, "address")) { g_autoptr(GPtrArray) ipv6 = NULL; GPtrArray *addresses; addresses = nm_ip_config_get_addresses (ip6_config); if (addresses->len == 0 ) { return str; } ipv6 = g_ptr_array_sized_new (addresses->len + 1); for (int i = 0; i < addresses->len; i++) { g_ptr_array_add (ipv6, (char *) nm_ip_address_get_address (g_ptr_array_index (addresses, i))); } g_ptr_array_add (ipv6, NULL); str = g_strjoinv ("\n", (char **) ipv6->pdata); } else if (!strcmp (what, "gateway")) { str = g_strdup (nm_ip_config_get_gateway (ip6_config)); } return str; } void panel_set_device_widgets (GtkBuilder *builder, NMDevice *device) { NMIPConfig *ip4_config = NULL; NMIPConfig *ip6_config = NULL; gboolean has_ip4; gboolean has_ip6; gchar *ip4_dns = NULL; gchar *ip6_dns = NULL; gchar *str_tmp; /* get IPv4 parameters */ ip4_config = nm_device_get_ip4_config (device); if (ip4_config != NULL) { /* IPv4 address */ str_tmp = panel_get_ip4_address_as_string (ip4_config, "address"); panel_set_device_widget_details (builder, "ipv4", str_tmp); has_ip4 = str_tmp != NULL; g_free (str_tmp); /* IPv4 DNS */ ip4_dns = panel_get_dns_as_string (ip4_config); panel_set_device_widget_details (builder, "dns4", ip4_dns); /* IPv4 route */ str_tmp = panel_get_ip4_address_as_string (ip4_config, "gateway"); panel_set_device_widget_details (builder, "route", str_tmp); g_free (str_tmp); } else { /* IPv4 address */ panel_set_device_widget_details (builder, "ipv4", NULL); has_ip4 = FALSE; /* IPv4 DNS */ panel_set_device_widget_details (builder, "dns4", NULL); /* IPv4 route */ panel_set_device_widget_details (builder, "route", NULL); } /* get IPv6 parameters */ ip6_config = nm_device_get_ip6_config (device); if (ip6_config != NULL) { str_tmp = panel_get_ip6_address_as_string (ip6_config, "address"); panel_set_device_widget_details (builder, "ipv6", str_tmp); has_ip6 = str_tmp != NULL; g_free (str_tmp); /* IPv6 DNS */ ip6_dns = panel_get_dns_as_string (ip6_config); panel_set_device_widget_details (builder, "dns6", ip6_dns); } else { panel_set_device_widget_details (builder, "ipv6", NULL); has_ip6 = FALSE; /* IPv6 DNS */ panel_set_device_widget_details (builder, "dns6", NULL); } if (has_ip4 && has_ip6) { panel_set_device_widget_header (builder, "ipv4", _("IPv4 Address")); panel_set_device_widget_header (builder, "ipv6", _("IPv6 Address")); } else if (has_ip4) { panel_set_device_widget_header (builder, "ipv4", _("IP Address")); } else if (has_ip6) { panel_set_device_widget_header (builder, "ipv6", _("IP Address")); } if (ip4_dns && ip6_dns) { panel_set_device_widget_header (builder, "dns4", _("DNS4")); panel_set_device_widget_header (builder, "dns6", _("DNS6")); } else if (ip4_dns) { panel_set_device_widget_header (builder, "dns4", _("DNS")); } else if (ip6_dns) { panel_set_device_widget_header (builder, "dns6", _("DNS")); } g_free (ip4_dns); g_free (ip6_dns); } void panel_unset_device_widgets (GtkBuilder *builder) { panel_set_device_widget_details (builder, "ipv4", NULL); panel_set_device_widget_details (builder, "ipv6", NULL); panel_set_device_widget_details (builder, "dns4", NULL); panel_set_device_widget_details (builder, "dns6", NULL); panel_set_device_widget_details (builder, "route", NULL); } cinnamon-control-center-6.4.1/panels/network/network-module.c0000664000175000017500000000165514724311620023306 0ustar fabiofabio/* * Copyright (C) 2011 Red Hat, Inc * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include #include "cc-network-panel.h" #include void g_io_module_load (GIOModule *module) { /* register the panel */ cc_network_panel_register (module); } void g_io_module_unload (GIOModule *module) { } cinnamon-control-center-6.4.1/panels/network/network-proxy.ui0000664000175000017500000005117214724311620023374 0ustar fabiofabio 65535 1 65535 1 65535 1 65535 1 None 0 Manual 1 Automatic 2 True False start 12 10 6 True False end start 2 0 1 1 True False 1 _Method True combobox_proxy_mode 0 1 1 1 True False 0 1 liststore_proxy_method 1 1 2 1 True False 1 _Configuration URL True entry_proxy_url 0 2 1 1 True True ā— True 1 2 2 1 True False 1 _HTTP Proxy True entry_proxy_http 0 3 1 1 True False 1 H_TTPS Proxy True entry_proxy_https 0 4 1 1 True False 1 _FTP Proxy True entry_proxy_ftp 0 5 1 1 True False 1 _Socks Host True entry_proxy_socks 0 6 1 1 True False 1 _Ignore Hosts True entry_proxy_ignore 0 7 1 1 False False 0 WPAD warning… True 50 0 8 3 1 True True ā— True 1 3 1 1 True True ā— 1 True adjustment_proxy_port_http HTTP proxy port 2 3 1 1 True True ā— True 1 4 1 1 True True ā— True 1 5 1 1 True True ā— True 1 6 1 1 True True ā— True 1 7 2 1 True True ā— 1 True adjustment_proxy_port_https HTTPS proxy port 2 4 1 1 True True ā— 1 True adjustment_proxy_port_ftp FTP proxy port 2 5 1 1 True True ā— 1 True adjustment_proxy_port_socks Socks proxy port 2 6 1 1 True False 6 True False end start 1 48 preferences-system-network 6 False True 0 True False start True 3 True False 0 Proxy end False False 0 True False 0 Not connected False False 1 False True 1 True True end center False True 2 0 0 3 1 cinnamon-control-center-6.4.1/panels/network/wireless-security/0000775000175000017500000000000014724311620023661 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/network/wireless-security/eap-method-fast.c0000664000175000017500000003723314724311620027013 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* vim: set ft=c ts=4 sts=4 sw=4 noexpandtab smartindent: */ /* EAP-FAST authentication method (RFC4851) * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2012 - 2014 Red Hat, Inc. */ #include "nm-default.h" #include #include #include "eap-method.h" #include "wireless-security.h" #include "utils.h" #include "helpers.h" #define I_NAME_COLUMN 0 #define I_METHOD_COLUMN 1 struct _EAPMethodFAST { EAPMethod parent; GtkSizeGroup *size_group; WirelessSecurity *sec_parent; gboolean is_editor; }; static void destroy (EAPMethod *parent) { EAPMethodFAST *method = (EAPMethodFAST *) parent; if (method->size_group) g_object_unref (method->size_group); } static gboolean validate (EAPMethod *parent, GError **error) { GtkWidget *widget; GtkTreeModel *model; GtkTreeIter iter; EAPMethod *eap = NULL; const char *file; gboolean provisioning; gboolean valid = TRUE; widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_checkbutton")); g_assert (widget); provisioning = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_file_button")); g_assert (widget); file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); if (!provisioning && !file) { widget_set_error (widget); g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing EAP-FAST PAC file")); valid = FALSE; } else widget_unset_error (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_combo")); g_assert (widget); model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); g_assert (eap); valid = eap_method_validate (eap, valid ? error : NULL) && valid; eap_method_unref (eap); return valid; } static void add_to_size_group (EAPMethod *parent, GtkSizeGroup *group) { EAPMethodFAST *method = (EAPMethodFAST *) parent; GtkWidget *widget; GtkTreeModel *model; GtkTreeIter iter; EAPMethod *eap; if (method->size_group) g_object_unref (method->size_group); method->size_group = g_object_ref (group); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_anon_identity_label")); g_assert (widget); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_file_label")); g_assert (widget); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_checkbutton")); g_assert (widget); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_label")); g_assert (widget); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_combo")); g_assert (widget); model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); g_assert (eap); eap_method_add_to_size_group (eap, group); eap_method_unref (eap); } static void fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFlags flags) { NMSetting8021x *s_8021x; GtkWidget *widget; const char *text; char *filename; EAPMethod *eap = NULL; GtkTreeModel *model; GtkTreeIter iter; gboolean enabled; int pac_provisioning = 0; s_8021x = nm_connection_get_setting_802_1x (connection); g_assert (s_8021x); nm_setting_802_1x_add_eap_method (s_8021x, "fast"); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_anon_identity_entry")); g_assert (widget); text = gtk_entry_get_text (GTK_ENTRY (widget)); if (text && strlen (text)) g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, text, NULL); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_file_button")); g_assert (widget); filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); g_object_set (s_8021x, NM_SETTING_802_1X_PAC_FILE, filename, NULL); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_checkbutton")); enabled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); if (!enabled) g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, "0", NULL); else { widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_combo")); pac_provisioning = gtk_combo_box_get_active (GTK_COMBO_BOX (widget)); switch (pac_provisioning) { case 0: /* Anonymous */ g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, "1", NULL); break; case 1: /* Authenticated */ g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, "2", NULL); break; case 2: /* Both - anonymous and authenticated */ g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, "3", NULL); break; default: /* Should not happen */ g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, "1", NULL); break; } } widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_combo")); model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); g_assert (eap); eap_method_fill_connection (eap, connection, flags); eap_method_unref (eap); } static void inner_auth_combo_changed_cb (GtkWidget *combo, gpointer user_data) { EAPMethod *parent = (EAPMethod *) user_data; EAPMethodFAST *method = (EAPMethodFAST *) parent; GtkWidget *vbox; EAPMethod *eap = NULL; GList *elt, *children; GtkTreeModel *model; GtkTreeIter iter; GtkWidget *eap_widget; vbox = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_vbox")); g_assert (vbox); /* Remove any previous wireless security widgets */ children = gtk_container_get_children (GTK_CONTAINER (vbox)); for (elt = children; elt; elt = g_list_next (elt)) gtk_container_remove (GTK_CONTAINER (vbox), GTK_WIDGET (elt->data)); g_list_free (children); model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo)); gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter); gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); g_assert (eap); eap_widget = eap_method_get_widget (eap); g_assert (eap_widget); gtk_widget_unparent (eap_widget); if (method->size_group) eap_method_add_to_size_group (eap, method->size_group); gtk_container_add (GTK_CONTAINER (vbox), eap_widget); eap_method_unref (eap); wireless_security_changed_cb (combo, method->sec_parent); } static GtkWidget * inner_auth_combo_init (EAPMethodFAST *method, NMConnection *connection, NMSetting8021x *s_8021x, gboolean secrets_only) { EAPMethod *parent = (EAPMethod *) method; GtkWidget *combo; GtkListStore *auth_model; GtkTreeIter iter; EAPMethodSimple *em_gtc; EAPMethodSimple *em_mschap_v2; guint32 active = 0; const char *phase2_auth = NULL; EAPMethodSimpleFlags simple_flags; auth_model = gtk_list_store_new (2, G_TYPE_STRING, eap_method_get_type ()); if (s_8021x) { if (nm_setting_802_1x_get_phase2_auth (s_8021x)) phase2_auth = nm_setting_802_1x_get_phase2_auth (s_8021x); else if (nm_setting_802_1x_get_phase2_autheap (s_8021x)) phase2_auth = nm_setting_802_1x_get_phase2_autheap (s_8021x); } simple_flags = EAP_METHOD_SIMPLE_FLAG_PHASE2; if (method->is_editor) simple_flags |= EAP_METHOD_SIMPLE_FLAG_IS_EDITOR; if (secrets_only) simple_flags |= EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY; em_gtc = eap_method_simple_new (method->sec_parent, connection, EAP_METHOD_SIMPLE_TYPE_GTC, simple_flags); gtk_list_store_append (auth_model, &iter); gtk_list_store_set (auth_model, &iter, I_NAME_COLUMN, _("GTC"), I_METHOD_COLUMN, em_gtc, -1); eap_method_unref (EAP_METHOD (em_gtc)); /* Check for defaulting to GTC */ if (phase2_auth && !strcasecmp (phase2_auth, "gtc")) active = 0; em_mschap_v2 = eap_method_simple_new (method->sec_parent, connection, EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2, simple_flags); gtk_list_store_append (auth_model, &iter); gtk_list_store_set (auth_model, &iter, I_NAME_COLUMN, _("MSCHAPv2"), I_METHOD_COLUMN, em_mschap_v2, -1); eap_method_unref (EAP_METHOD (em_mschap_v2)); /* Check for defaulting to MSCHAPv2 */ if (phase2_auth && !strcasecmp (phase2_auth, "mschapv2")) active = 1; combo = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_combo")); g_assert (combo); gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (auth_model)); g_object_unref (G_OBJECT (auth_model)); gtk_combo_box_set_active (GTK_COMBO_BOX (combo), active); g_signal_connect (G_OBJECT (combo), "changed", (GCallback) inner_auth_combo_changed_cb, method); return combo; } static void update_secrets (EAPMethod *parent, NMConnection *connection) { eap_method_phase2_update_secrets_helper (parent, connection, "eap_fast_inner_auth_combo", I_METHOD_COLUMN); } static void pac_toggled_cb (GtkWidget *widget, gpointer user_data) { EAPMethod *parent = (EAPMethod *) user_data; EAPMethodFAST *method = (EAPMethodFAST *) parent; gboolean enabled = FALSE; GtkWidget *provision_combo; provision_combo = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_combo")); g_return_if_fail (provision_combo); enabled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); gtk_widget_set_sensitive (provision_combo, enabled); wireless_security_changed_cb (widget, method->sec_parent); } EAPMethodFAST * eap_method_fast_new (WirelessSecurity *ws_parent, NMConnection *connection, gboolean is_editor, gboolean secrets_only) { EAPMethod *parent; EAPMethodFAST *method; GtkWidget *widget; GtkFileFilter *filter; NMSetting8021x *s_8021x = NULL; const char *filename; gboolean provisioning_enabled = TRUE; parent = eap_method_init (sizeof (EAPMethodFAST), validate, add_to_size_group, fill_connection, update_secrets, destroy, "/org/cinnamon/control-center/network/eap-method-fast.ui", "eap_fast_notebook", "eap_fast_anon_identity_entry", FALSE); if (!parent) return NULL; parent->password_flags_name = NM_SETTING_802_1X_PASSWORD; method = (EAPMethodFAST *) parent; method->sec_parent = ws_parent; method->is_editor = is_editor; if (connection) s_8021x = nm_connection_get_setting_802_1x (connection); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_combo")); g_assert (widget); gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0); if (s_8021x) { const char *fast_prov; fast_prov = nm_setting_802_1x_get_phase1_fast_provisioning (s_8021x); if (fast_prov) { if (!strcmp (fast_prov, "0")) provisioning_enabled = FALSE; else if (!strcmp (fast_prov, "1")) gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0); else if (!strcmp (fast_prov, "2")) gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1); else if (!strcmp (fast_prov, "3")) gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 2); } } gtk_widget_set_sensitive (widget, provisioning_enabled); g_signal_connect (G_OBJECT (widget), "changed", (GCallback) wireless_security_changed_cb, ws_parent); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_checkbutton")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), provisioning_enabled); g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (pac_toggled_cb), parent); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_anon_identity_entry")); if (s_8021x && nm_setting_802_1x_get_anonymous_identity (s_8021x)) gtk_entry_set_text (GTK_ENTRY (widget), nm_setting_802_1x_get_anonymous_identity (s_8021x)); g_signal_connect (G_OBJECT (widget), "changed", (GCallback) wireless_security_changed_cb, ws_parent); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_file_button")); g_assert (widget); gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (widget), TRUE); gtk_file_chooser_button_set_title (GTK_FILE_CHOOSER_BUTTON (widget), _("Choose a PAC file")); g_signal_connect (G_OBJECT (widget), "selection-changed", (GCallback) wireless_security_changed_cb, ws_parent); filter = gtk_file_filter_new (); gtk_file_filter_add_pattern (filter, "*.pac"); gtk_file_filter_set_name (filter, _("PAC files (*.pac)")); gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (widget), filter); filter = gtk_file_filter_new (); gtk_file_filter_add_pattern (filter, "*"); gtk_file_filter_set_name (filter, _("All files")); gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (widget), filter); if (connection && s_8021x) { filename = nm_setting_802_1x_get_pac_file (s_8021x); if (filename) gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename); } widget = inner_auth_combo_init (method, connection, s_8021x, secrets_only); inner_auth_combo_changed_cb (widget, (gpointer) method); if (secrets_only) { widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_anon_identity_label")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_anon_identity_entry")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_checkbutton")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_combo")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_file_label")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_file_button")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_label")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_combo")); gtk_widget_hide (widget); } return method; } cinnamon-control-center-6.4.1/panels/network/wireless-security/eap-method-simple.c0000664000175000017500000003224614724311620027346 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2007 - 2014 Red Hat, Inc. */ #include "nm-default.h" #include #include #include "eap-method.h" #include "wireless-security.h" #include "helpers.h" #include "nma-ui-utils.h" #include "utils.h" struct _EAPMethodSimple { EAPMethod parent; WirelessSecurity *ws_parent; EAPMethodSimpleType type; EAPMethodSimpleFlags flags; GtkEntry *username_entry; GtkEntry *password_entry; GtkToggleButton *show_password; guint idle_func_id; }; static void show_toggled_cb (GtkToggleButton *button, EAPMethodSimple *method) { gboolean visible; visible = gtk_toggle_button_get_active (button); gtk_entry_set_visibility (method->password_entry, visible); } static gboolean always_ask_selected (GtkEntry *passwd_entry) { return !!( nma_utils_menu_to_secret_flags (GTK_WIDGET (passwd_entry)) & NM_SETTING_SECRET_FLAG_NOT_SAVED); } static gboolean validate (EAPMethod *parent, GError **error) { EAPMethodSimple *method = (EAPMethodSimple *)parent; const char *text; gboolean ret = TRUE; text = gtk_entry_get_text (method->username_entry); if (!text || !strlen (text)) { widget_set_error (GTK_WIDGET (method->username_entry)); g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing EAP username")); ret = FALSE; } else widget_unset_error (GTK_WIDGET (method->username_entry)); /* Check if the password should always be requested */ if (always_ask_selected (method->password_entry)) widget_unset_error (GTK_WIDGET (method->password_entry)); else { text = gtk_entry_get_text (method->password_entry); if (!text || !strlen (text)) { widget_set_error (GTK_WIDGET (method->password_entry)); if (ret) { g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing EAP password")); ret = FALSE; } } else widget_unset_error (GTK_WIDGET (method->password_entry)); } return ret; } static void add_to_size_group (EAPMethod *parent, GtkSizeGroup *group) { GtkWidget *widget; widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_username_label")); g_assert (widget); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_password_label")); g_assert (widget); gtk_size_group_add_widget (group, widget); } typedef struct { const char *name; gboolean autheap_allowed; } EapType; /* Indexed by EAP_METHOD_SIMPLE_TYPE_* */ static const EapType eap_table[EAP_METHOD_SIMPLE_TYPE_LAST] = { [EAP_METHOD_SIMPLE_TYPE_PAP] = { "pap", FALSE }, [EAP_METHOD_SIMPLE_TYPE_MSCHAP] = { "mschap", FALSE }, [EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2] = { "mschapv2", TRUE }, [EAP_METHOD_SIMPLE_TYPE_MD5] = { "md5", TRUE }, [EAP_METHOD_SIMPLE_TYPE_PWD] = { "pwd", TRUE }, [EAP_METHOD_SIMPLE_TYPE_CHAP] = { "chap", FALSE }, [EAP_METHOD_SIMPLE_TYPE_GTC] = { "gtc", TRUE }, }; static void fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFlags prev_flags) { EAPMethodSimple *method = (EAPMethodSimple *) parent; NMSetting8021x *s_8021x; gboolean not_saved = FALSE; NMSettingSecretFlags flags; const EapType *eap_type; s_8021x = nm_connection_get_setting_802_1x (connection); g_assert (s_8021x); /* If this is the main EAP method, clear any existing methods because the * user-selected on will replace it. */ if (parent->phase2 == FALSE) nm_setting_802_1x_clear_eap_methods (s_8021x); eap_type = &eap_table[method->type]; if (parent->phase2) { /* If the outer EAP method (TLS, TTLS, PEAP, etc) allows inner/phase2 * EAP methods (which only TTLS allows) *and* the inner/phase2 method * supports being an inner EAP method, then set PHASE2_AUTHEAP. * Otherwise the inner/phase2 method goes into PHASE2_AUTH. */ if ((method->flags & EAP_METHOD_SIMPLE_FLAG_AUTHEAP_ALLOWED) && eap_type->autheap_allowed) { g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, eap_type->name, NULL); g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, NULL, NULL); } else { g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, eap_type->name, NULL); g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, NULL, NULL); } } else nm_setting_802_1x_add_eap_method (s_8021x, eap_type->name); g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, gtk_entry_get_text (method->username_entry), NULL); /* Save the password always ask setting */ not_saved = always_ask_selected (method->password_entry); flags = nma_utils_menu_to_secret_flags (GTK_WIDGET (method->password_entry)); nm_setting_set_secret_flags (NM_SETTING (s_8021x), NM_SETTING_802_1X_PASSWORD, flags, NULL); /* Fill the connection's password if we're in the applet so that it'll get * back to NM. From the editor though, since the connection isn't going * back to NM in response to a GetSecrets() call, we don't save it if the * user checked "Always Ask". */ if (!(method->flags & EAP_METHOD_SIMPLE_FLAG_IS_EDITOR) || not_saved == FALSE) g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD, gtk_entry_get_text (method->password_entry), NULL); /* Update secret flags and popup when editing the connection */ if (!(method->flags & EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY)) { GtkWidget *passwd_entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_password_entry")); g_assert (passwd_entry); nma_utils_update_password_storage (passwd_entry, flags, NM_SETTING (s_8021x), parent->password_flags_name); } } static void update_secrets (EAPMethod *parent, NMConnection *connection) { helper_fill_secret_entry (connection, parent->builder, "eap_simple_password_entry", NM_TYPE_SETTING_802_1X, (HelperSecretFunc) nm_setting_802_1x_get_password); } static gboolean stuff_changed (EAPMethodSimple *method) { wireless_security_changed_cb (NULL, method->ws_parent); method->idle_func_id = 0; return FALSE; } static void password_storage_changed (GObject *entry, GParamSpec *pspec, EAPMethodSimple *method) { gboolean always_ask; gboolean secrets_only = method->flags & EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY; always_ask = always_ask_selected (method->password_entry); if (always_ask && !secrets_only) { /* we always clear this button and do not restore it * (because we want to hide the password). */ gtk_toggle_button_set_active (method->show_password, FALSE); } gtk_widget_set_sensitive (GTK_WIDGET (method->show_password), !always_ask || secrets_only); if (!method->idle_func_id) method->idle_func_id = g_idle_add ((GSourceFunc) stuff_changed, method); } /* Set the UI fields for user, password, always_ask and show_password to the * values as provided by method->ws_parent. */ static void set_userpass_ui (EAPMethodSimple *method) { if (method->ws_parent->username) gtk_entry_set_text (method->username_entry, method->ws_parent->username); else gtk_entry_set_text (method->username_entry, ""); if (method->ws_parent->password && !method->ws_parent->always_ask) gtk_entry_set_text (method->password_entry, method->ws_parent->password); else gtk_entry_set_text (method->password_entry, ""); gtk_toggle_button_set_active (method->show_password, method->ws_parent->show_password); password_storage_changed (NULL, NULL, method); } static void widgets_realized (GtkWidget *widget, EAPMethodSimple *method) { set_userpass_ui (method); } static void widgets_unrealized (GtkWidget *widget, EAPMethodSimple *method) { wireless_security_set_userpass (method->ws_parent, gtk_entry_get_text (method->username_entry), gtk_entry_get_text (method->password_entry), always_ask_selected (method->password_entry), gtk_toggle_button_get_active (method->show_password)); } static void destroy (EAPMethod *parent) { EAPMethodSimple *method = (EAPMethodSimple *) parent; GtkWidget *widget; widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_notebook")); g_assert (widget); g_signal_handlers_disconnect_by_func (G_OBJECT (widget), (GCallback) widgets_realized, method); g_signal_handlers_disconnect_by_func (G_OBJECT (widget), (GCallback) widgets_unrealized, method); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_password_entry")); g_assert (widget); g_signal_handlers_disconnect_by_func (G_OBJECT (widget), (GCallback) password_storage_changed, method); if (method->idle_func_id > 0) { g_source_remove (method->idle_func_id); method->idle_func_id = 0; } wireless_security_unref (method->ws_parent); } EAPMethodSimple * eap_method_simple_new (WirelessSecurity *ws_parent, NMConnection *connection, EAPMethodSimpleType type, EAPMethodSimpleFlags flags) { EAPMethod *parent; EAPMethodSimple *method; GtkWidget *widget; NMSetting8021x *s_8021x = NULL; parent = eap_method_init (sizeof (EAPMethodSimple), validate, add_to_size_group, fill_connection, update_secrets, destroy, "/org/cinnamon/control-center/network/eap-method-simple.ui", "eap_simple_notebook", "eap_simple_username_entry", flags & EAP_METHOD_SIMPLE_FLAG_PHASE2); if (!parent) return NULL; parent->password_flags_name = NM_SETTING_802_1X_PASSWORD; method = (EAPMethodSimple *) parent; method->ws_parent = wireless_security_ref (ws_parent); method->flags = flags; method->type = type; g_assert (type < EAP_METHOD_SIMPLE_TYPE_LAST); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_notebook")); g_assert (widget); g_signal_connect (G_OBJECT (widget), "realize", (GCallback) widgets_realized, method); g_signal_connect (G_OBJECT (widget), "unrealize", (GCallback) widgets_unrealized, method); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_username_entry")); g_assert (widget); method->username_entry = GTK_ENTRY (widget); g_signal_connect (G_OBJECT (widget), "changed", (GCallback) wireless_security_changed_cb, ws_parent); if (method->flags & EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY) gtk_widget_set_sensitive (widget, FALSE); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_password_entry")); g_assert (widget); method->password_entry = GTK_ENTRY (widget); g_signal_connect (G_OBJECT (widget), "changed", (GCallback) wireless_security_changed_cb, ws_parent); /* Create password-storage popup menu for password entry under entry's secondary icon */ if (connection) s_8021x = nm_connection_get_setting_802_1x (connection); nma_utils_setup_password_storage (widget, 0, (NMSetting *) s_8021x, parent->password_flags_name, FALSE, flags & EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY); g_signal_connect (method->password_entry, "notify::secondary-icon-name", G_CALLBACK (password_storage_changed), method); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_eapsimple")); g_assert (widget); method->show_password = GTK_TOGGLE_BUTTON (widget); g_signal_connect (G_OBJECT (widget), "toggled", (GCallback) show_toggled_cb, method); /* Initialize the UI fields with the security settings from method->ws_parent. * This will be done again when the widget gets realized. It must be done here as well, * because the outer dialog will ask to 'validate' the connection before the security tab * is shown/realized (to enable the 'Apply' button). * As 'validate' accesses the contents of the UI fields, they must be initialized now, even * if the widgets are not yet visible. */ set_userpass_ui (method); return method; } cinnamon-control-center-6.4.1/panels/network/wireless-security/eap-method-ttls.c0000664000175000017500000004027014724311620027037 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2007 - 2014 Red Hat, Inc. */ #include "nm-default.h" #include #include #include "eap-method.h" #include "wireless-security.h" #include "utils.h" #define I_NAME_COLUMN 0 #define I_METHOD_COLUMN 1 struct _EAPMethodTTLS { EAPMethod parent; GtkSizeGroup *size_group; WirelessSecurity *sec_parent; gboolean is_editor; }; static void destroy (EAPMethod *parent) { EAPMethodTTLS *method = (EAPMethodTTLS *) parent; if (method->size_group) g_object_unref (method->size_group); } static gboolean validate (EAPMethod *parent, GError **error) { GtkWidget *widget; GtkTreeModel *model; GtkTreeIter iter; EAPMethod *eap = NULL; gboolean valid = FALSE; GError *local = NULL; if (!eap_method_validate_filepicker (parent->builder, "eap_ttls_ca_cert_button", TYPE_CA_CERT, NULL, NULL, &local)) { g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-TTLS CA certificate: %s"), local->message); g_clear_error (&local); return FALSE; } if (eap_method_ca_cert_required (parent->builder, "eap_ttls_ca_cert_not_required_checkbox", "eap_ttls_ca_cert_button")) { g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-TTLS CA certificate: no certificate specified")); return FALSE; } widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_combo")); g_assert (widget); model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); g_assert (eap); valid = eap_method_validate (eap, error); eap_method_unref (eap); return valid; } static void ca_cert_not_required_toggled (GtkWidget *ignored, gpointer user_data) { EAPMethod *parent = user_data; eap_method_ca_cert_not_required_toggled (parent->builder, "eap_ttls_ca_cert_not_required_checkbox", "eap_ttls_ca_cert_button"); } static void add_to_size_group (EAPMethod *parent, GtkSizeGroup *group) { EAPMethodTTLS *method = (EAPMethodTTLS *) parent; GtkWidget *widget; GtkTreeModel *model; GtkTreeIter iter; EAPMethod *eap; if (method->size_group) g_object_unref (method->size_group); method->size_group = g_object_ref (group); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_ca_cert_not_required_checkbox")); g_assert (widget); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_anon_identity_label")); g_assert (widget); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_ca_cert_label")); g_assert (widget); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_label")); g_assert (widget); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_combo")); g_assert (widget); model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); g_assert (eap); eap_method_add_to_size_group (eap, group); eap_method_unref (eap); } static void fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFlags flags) { NMSetting8021x *s_8021x; NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; GtkWidget *widget; const char *text; char *filename; EAPMethod *eap = NULL; GtkTreeModel *model; GtkTreeIter iter; GError *error = NULL; gboolean ca_cert_error = FALSE; s_8021x = nm_connection_get_setting_802_1x (connection); g_assert (s_8021x); nm_setting_802_1x_add_eap_method (s_8021x, "ttls"); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_anon_identity_entry")); g_assert (widget); text = gtk_entry_get_text (GTK_ENTRY (widget)); if (text && strlen (text)) g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, text, NULL); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_ca_cert_button")); g_assert (widget); filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); if (!nm_setting_802_1x_set_ca_cert (s_8021x, filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) { g_warning ("Couldn't read CA certificate '%s': %s", filename, error ? error->message : "(unknown)"); g_clear_error (&error); ca_cert_error = TRUE; } eap_method_ca_cert_ignore_set (parent, connection, filename, ca_cert_error); g_free (filename); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_combo")); model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); g_assert (eap); eap_method_fill_connection (eap, connection, flags); eap_method_unref (eap); } static void inner_auth_combo_changed_cb (GtkWidget *combo, gpointer user_data) { EAPMethod *parent = (EAPMethod *) user_data; EAPMethodTTLS *method = (EAPMethodTTLS *) parent; GtkWidget *vbox; EAPMethod *eap = NULL; GList *elt, *children; GtkTreeModel *model; GtkTreeIter iter; GtkWidget *eap_widget; vbox = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_vbox")); g_assert (vbox); /* Remove any previous wireless security widgets */ children = gtk_container_get_children (GTK_CONTAINER (vbox)); for (elt = children; elt; elt = g_list_next (elt)) gtk_container_remove (GTK_CONTAINER (vbox), GTK_WIDGET (elt->data)); g_list_free (children); model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo)); gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter); gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); g_assert (eap); eap_widget = eap_method_get_widget (eap); g_assert (eap_widget); gtk_widget_unparent (eap_widget); if (method->size_group) eap_method_add_to_size_group (eap, method->size_group); gtk_container_add (GTK_CONTAINER (vbox), eap_widget); eap_method_unref (eap); wireless_security_changed_cb (combo, method->sec_parent); } static GtkWidget * inner_auth_combo_init (EAPMethodTTLS *method, NMConnection *connection, NMSetting8021x *s_8021x, gboolean secrets_only) { EAPMethod *parent = (EAPMethod *) method; GtkWidget *combo; GtkListStore *auth_model; GtkTreeIter iter; EAPMethodSimple *em_pap; EAPMethodSimple *em_mschap; EAPMethodSimple *em_mschap_v2; EAPMethodSimple *em_chap; EAPMethodSimple *em_md5; EAPMethodSimple *em_gtc; guint32 active = 0; const char *phase2_auth = NULL; EAPMethodSimpleFlags simple_flags; auth_model = gtk_list_store_new (2, G_TYPE_STRING, eap_method_get_type ()); if (s_8021x) { if (nm_setting_802_1x_get_phase2_auth (s_8021x)) phase2_auth = nm_setting_802_1x_get_phase2_auth (s_8021x); else if (nm_setting_802_1x_get_phase2_autheap (s_8021x)) phase2_auth = nm_setting_802_1x_get_phase2_autheap (s_8021x); } simple_flags = EAP_METHOD_SIMPLE_FLAG_PHASE2 | EAP_METHOD_SIMPLE_FLAG_AUTHEAP_ALLOWED; if (method->is_editor) simple_flags |= EAP_METHOD_SIMPLE_FLAG_IS_EDITOR; if (secrets_only) simple_flags |= EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY; em_pap = eap_method_simple_new (method->sec_parent, connection, EAP_METHOD_SIMPLE_TYPE_PAP, simple_flags); gtk_list_store_append (auth_model, &iter); gtk_list_store_set (auth_model, &iter, I_NAME_COLUMN, _("PAP"), I_METHOD_COLUMN, em_pap, -1); eap_method_unref (EAP_METHOD (em_pap)); /* Check for defaulting to PAP */ if (phase2_auth && !strcasecmp (phase2_auth, "pap")) active = 0; em_mschap = eap_method_simple_new (method->sec_parent, connection, EAP_METHOD_SIMPLE_TYPE_MSCHAP, simple_flags); gtk_list_store_append (auth_model, &iter); gtk_list_store_set (auth_model, &iter, I_NAME_COLUMN, _("MSCHAP"), I_METHOD_COLUMN, em_mschap, -1); eap_method_unref (EAP_METHOD (em_mschap)); /* Check for defaulting to MSCHAP */ if (phase2_auth && !strcasecmp (phase2_auth, "mschap")) active = 1; em_mschap_v2 = eap_method_simple_new (method->sec_parent, connection, EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2, simple_flags); gtk_list_store_append (auth_model, &iter); gtk_list_store_set (auth_model, &iter, I_NAME_COLUMN, _("MSCHAPv2"), I_METHOD_COLUMN, em_mschap_v2, -1); eap_method_unref (EAP_METHOD (em_mschap_v2)); /* Check for defaulting to MSCHAPv2 */ if (phase2_auth && !strcasecmp (phase2_auth, "mschapv2")) active = 2; em_chap = eap_method_simple_new (method->sec_parent, connection, EAP_METHOD_SIMPLE_TYPE_CHAP, simple_flags); gtk_list_store_append (auth_model, &iter); gtk_list_store_set (auth_model, &iter, I_NAME_COLUMN, _("CHAP"), I_METHOD_COLUMN, em_chap, -1); eap_method_unref (EAP_METHOD (em_chap)); /* Check for defaulting to CHAP */ if (phase2_auth && !strcasecmp (phase2_auth, "chap")) active = 3; em_md5 = eap_method_simple_new (method->sec_parent, connection, EAP_METHOD_SIMPLE_TYPE_MD5, simple_flags); gtk_list_store_append (auth_model, &iter); gtk_list_store_set (auth_model, &iter, I_NAME_COLUMN, _("MD5"), I_METHOD_COLUMN, em_md5, -1); eap_method_unref (EAP_METHOD (em_md5)); /* Check for defaulting to MD5 */ if (phase2_auth && !strcasecmp (phase2_auth, "md5")) active = 4; em_gtc = eap_method_simple_new (method->sec_parent, connection, EAP_METHOD_SIMPLE_TYPE_GTC, simple_flags); gtk_list_store_append (auth_model, &iter); gtk_list_store_set (auth_model, &iter, I_NAME_COLUMN, _("GTC"), I_METHOD_COLUMN, em_gtc, -1); eap_method_unref (EAP_METHOD (em_gtc)); /* Check for defaulting to GTC */ if (phase2_auth && !strcasecmp (phase2_auth, "gtc")) active = 5; combo = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_combo")); g_assert (combo); gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (auth_model)); g_object_unref (G_OBJECT (auth_model)); gtk_combo_box_set_active (GTK_COMBO_BOX (combo), active); g_signal_connect (G_OBJECT (combo), "changed", (GCallback) inner_auth_combo_changed_cb, method); return combo; } static void update_secrets (EAPMethod *parent, NMConnection *connection) { eap_method_phase2_update_secrets_helper (parent, connection, "eap_ttls_inner_auth_combo", I_METHOD_COLUMN); } EAPMethodTTLS * eap_method_ttls_new (WirelessSecurity *ws_parent, NMConnection *connection, gboolean is_editor, gboolean secrets_only) { EAPMethod *parent; EAPMethodTTLS *method; GtkWidget *widget, *widget_ca_not_required_checkbox; GtkFileFilter *filter; NMSetting8021x *s_8021x = NULL; const char *filename; parent = eap_method_init (sizeof (EAPMethodTTLS), validate, add_to_size_group, fill_connection, update_secrets, destroy, "/org/cinnamon/control-center/network/eap-method-ttls.ui", "eap_ttls_notebook", "eap_ttls_anon_identity_entry", FALSE); if (!parent) return NULL; parent->password_flags_name = NM_SETTING_802_1X_PASSWORD; method = (EAPMethodTTLS *) parent; method->sec_parent = ws_parent; method->is_editor = is_editor; if (connection) s_8021x = nm_connection_get_setting_802_1x (connection); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_ca_cert_not_required_checkbox")); g_assert (widget); g_signal_connect (G_OBJECT (widget), "toggled", (GCallback) ca_cert_not_required_toggled, parent); g_signal_connect (G_OBJECT (widget), "toggled", (GCallback) wireless_security_changed_cb, ws_parent); widget_ca_not_required_checkbox = widget; widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_ca_cert_button")); g_assert (widget); gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (widget), TRUE); gtk_file_chooser_button_set_title (GTK_FILE_CHOOSER_BUTTON (widget), _("Choose a Certificate Authority certificate")); g_signal_connect (G_OBJECT (widget), "selection-changed", (GCallback) wireless_security_changed_cb, ws_parent); filter = eap_method_default_file_chooser_filter_new (FALSE); gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (widget), filter); if (connection && s_8021x) { filename = NULL; if (nm_setting_802_1x_get_ca_cert_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH) { filename = nm_setting_802_1x_get_ca_cert_path (s_8021x); if (filename) gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename); } gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget_ca_not_required_checkbox), !filename && eap_method_ca_cert_ignore_get (parent, connection)); } widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_anon_identity_entry")); if (s_8021x && nm_setting_802_1x_get_anonymous_identity (s_8021x)) gtk_entry_set_text (GTK_ENTRY (widget), nm_setting_802_1x_get_anonymous_identity (s_8021x)); g_signal_connect (G_OBJECT (widget), "changed", (GCallback) wireless_security_changed_cb, ws_parent); widget = inner_auth_combo_init (method, connection, s_8021x, secrets_only); inner_auth_combo_changed_cb (widget, (gpointer) method); if (secrets_only) { widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_anon_identity_label")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_anon_identity_entry")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_ca_cert_label")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_ca_cert_button")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_ca_cert_not_required_checkbox")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_label")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_combo")); gtk_widget_hide (widget); } return method; } cinnamon-control-center-6.4.1/panels/network/wireless-security/eap-method-tls.h0000664000175000017500000000247214724311620026662 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (C) Copyright 2007 - 2010 Red Hat, Inc. */ #ifndef EAP_METHOD_TLS_H #define EAP_METHOD_TLS_H #include "wireless-security.h" typedef struct _EAPMethodTLS EAPMethodTLS; EAPMethodTLS *eap_method_tls_new (WirelessSecurity *ws_parent, NMConnection *connection, gboolean phase2, gboolean secrets_only); #endif /* EAP_METHOD_TLS_H */ cinnamon-control-center-6.4.1/panels/network/wireless-security/wireless-security.h0000664000175000017500000001360114724311620027535 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2007 - 2014 Red Hat, Inc. */ #ifndef WIRELESS_SECURITY_H #define WIRELESS_SECURITY_H #include #include typedef struct _WirelessSecurity WirelessSecurity; typedef void (*WSChangedFunc) (WirelessSecurity *sec, gpointer user_data); typedef void (*WSAddToSizeGroupFunc) (WirelessSecurity *sec, GtkSizeGroup *group); typedef void (*WSFillConnectionFunc) (WirelessSecurity *sec, NMConnection *connection); typedef void (*WSUpdateSecretsFunc) (WirelessSecurity *sec, NMConnection *connection); typedef void (*WSDestroyFunc) (WirelessSecurity *sec); typedef gboolean (*WSValidateFunc) (WirelessSecurity *sec, GError **error); typedef GtkWidget * (*WSNagUserFunc) (WirelessSecurity *sec); struct _WirelessSecurity { guint32 refcount; gsize obj_size; GtkBuilder *builder; GtkWidget *ui_widget; WSChangedFunc changed_notify; gpointer changed_notify_data; const char *default_field; gboolean adhoc_compatible; gboolean hotspot_compatible; char *username, *password; gboolean always_ask, show_password; WSAddToSizeGroupFunc add_to_size_group; WSFillConnectionFunc fill_connection; WSUpdateSecretsFunc update_secrets; WSValidateFunc validate; WSDestroyFunc destroy; }; #define WIRELESS_SECURITY(x) ((WirelessSecurity *) x) GtkWidget *wireless_security_get_widget (WirelessSecurity *sec); void wireless_security_set_changed_notify (WirelessSecurity *sec, WSChangedFunc func, gpointer user_data); gboolean wireless_security_validate (WirelessSecurity *sec, GError **error); void wireless_security_add_to_size_group (WirelessSecurity *sec, GtkSizeGroup *group); void wireless_security_fill_connection (WirelessSecurity *sec, NMConnection *connection); void wireless_security_update_secrets (WirelessSecurity *sec, NMConnection *connection); gboolean wireless_security_adhoc_compatible (WirelessSecurity *sec); gboolean wireless_security_hotspot_compatible (WirelessSecurity *sec); void wireless_security_set_userpass (WirelessSecurity *sec, const char *user, const char *password, gboolean always_ask, gboolean show_password); void wireless_security_set_userpass_802_1x (WirelessSecurity *sec, NMConnection *connection); WirelessSecurity *wireless_security_ref (WirelessSecurity *sec); void wireless_security_unref (WirelessSecurity *sec); GType wireless_security_get_type (void); /* Below for internal use only */ #include "ws-wep-key.h" #include "ws-wpa-psk.h" #include "ws-leap.h" #include "ws-wpa-eap.h" #include "ws-dynamic-wep.h" WirelessSecurity *wireless_security_init (gsize obj_size, WSValidateFunc validate, WSAddToSizeGroupFunc add_to_size_group, WSFillConnectionFunc fill_connection, WSUpdateSecretsFunc update_secrets, WSDestroyFunc destroy, const char *ui_resource, const char *ui_widget_name, const char *default_field); void wireless_security_changed_cb (GtkWidget *entry, gpointer user_data); void wireless_security_clear_ciphers (NMConnection *connection); #define AUTH_NAME_COLUMN 0 #define AUTH_METHOD_COLUMN 1 GtkWidget *ws_802_1x_auth_combo_init (WirelessSecurity *sec, const char *combo_name, const char *combo_label, GCallback auth_combo_changed_cb, NMConnection *connection, gboolean is_editor, gboolean secrets_only); void ws_802_1x_auth_combo_changed (GtkWidget *combo, WirelessSecurity *sec, const char *vbox_name, GtkSizeGroup *size_group); gboolean ws_802_1x_validate (WirelessSecurity *sec, const char *combo_name, GError **error); void ws_802_1x_add_to_size_group (WirelessSecurity *sec, GtkSizeGroup *size_group, const char *label_name, const char *combo_name); void ws_802_1x_fill_connection (WirelessSecurity *sec, const char *combo_name, NMConnection *connection); void ws_802_1x_update_secrets (WirelessSecurity *sec, const char *combo_name, NMConnection *connection); #endif /* WIRELESS_SECURITY_H */ cinnamon-control-center-6.4.1/panels/network/wireless-security/meson.build0000664000175000017500000000147414724311620026031 0ustar fabiofabiowireless_securityInclude = include_directories('.') libwireless_security_sources = [ 'eap-method-fast.c', 'eap-method-leap.c', 'eap-method-peap.c', 'eap-method-simple.c', 'eap-method-tls.c', 'eap-method-ttls.c', 'eap-method.c', 'helpers.c', 'utils.c', 'wireless-security.c', 'ws-dynamic-wep.c', 'ws-leap.c', 'ws-wep-key.c', 'ws-wpa-eap.c', 'ws-wpa-psk.c', gnome.compile_resources('wireless-security-resources', 'wireless-security.gresource.xml', c_name: 'wireless_security', source_dir: meson.current_source_dir(), ), ] libwireless_security = static_library('wireless_security', libwireless_security_sources, include_directories: rootInclude, dependencies: [ gtk, libnm, libnma, ], ) run_target('update-from-nma', command: find_program('update_from_nma.sh')) cinnamon-control-center-6.4.1/panels/network/wireless-security/eap-method-fast.h0000664000175000017500000000251114724311620027007 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* vim: set ft=c ts=4 sts=4 sw=4 noexpandtab smartindent: */ /* EAP-FAST authentication method (RFC4851) * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (C) Copyright 2012 Red Hat, Inc. */ #ifndef EAP_METHOD_FAST_H #define EAP_METHOD_FAST_H #include "wireless-security.h" typedef struct _EAPMethodFAST EAPMethodFAST; EAPMethodFAST *eap_method_fast_new (WirelessSecurity *ws_parent, NMConnection *connection, gboolean is_editor, gboolean secrets_only); #endif /* EAP_METHOD_FAST_H */ cinnamon-control-center-6.4.1/panels/network/wireless-security/ws-dynamic-wep.c0000664000175000017500000001016114724311620026670 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2007 - 2014 Red Hat, Inc. */ #include "nm-default.h" #include #include #include "wireless-security.h" #include "eap-method.h" struct _WirelessSecurityDynamicWEP { WirelessSecurity parent; GtkSizeGroup *size_group; }; static void destroy (WirelessSecurity *parent) { WirelessSecurityDynamicWEP *sec = (WirelessSecurityDynamicWEP *) parent; if (sec->size_group) g_object_unref (sec->size_group); } static gboolean validate (WirelessSecurity *parent, GError **error) { return ws_802_1x_validate (parent, "dynamic_wep_auth_combo", error); } static void add_to_size_group (WirelessSecurity *parent, GtkSizeGroup *group) { WirelessSecurityDynamicWEP *sec = (WirelessSecurityDynamicWEP *) parent; if (sec->size_group) g_object_unref (sec->size_group); sec->size_group = g_object_ref (group); ws_802_1x_add_to_size_group (parent, sec->size_group, "dynamic_wep_auth_label", "dynamic_wep_auth_combo"); } static void fill_connection (WirelessSecurity *parent, NMConnection *connection) { NMSettingWirelessSecurity *s_wireless_sec; ws_802_1x_fill_connection (parent, "dynamic_wep_auth_combo", connection); s_wireless_sec = nm_connection_get_setting_wireless_security (connection); g_assert (s_wireless_sec); g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", NULL); } static void auth_combo_changed_cb (GtkWidget *combo, gpointer user_data) { WirelessSecurity *parent = WIRELESS_SECURITY (user_data); WirelessSecurityDynamicWEP *sec = (WirelessSecurityDynamicWEP *) parent; ws_802_1x_auth_combo_changed (combo, parent, "dynamic_wep_method_vbox", sec->size_group); } static void update_secrets (WirelessSecurity *parent, NMConnection *connection) { ws_802_1x_update_secrets (parent, "dynamic_wep_auth_combo", connection); } WirelessSecurityDynamicWEP * ws_dynamic_wep_new (NMConnection *connection, gboolean is_editor, gboolean secrets_only) { WirelessSecurity *parent; GtkWidget *widget; parent = wireless_security_init (sizeof (WirelessSecurityDynamicWEP), validate, add_to_size_group, fill_connection, update_secrets, destroy, "/org/cinnamon/control-center/network/ws-dynamic-wep.ui", "dynamic_wep_notebook", NULL); if (!parent) return NULL; parent->adhoc_compatible = FALSE; parent->hotspot_compatible = FALSE; widget = ws_802_1x_auth_combo_init (parent, "dynamic_wep_auth_combo", "dynamic_wep_auth_label", (GCallback) auth_combo_changed_cb, connection, is_editor, secrets_only); auth_combo_changed_cb (widget, (gpointer) parent); return (WirelessSecurityDynamicWEP *) parent; } cinnamon-control-center-6.4.1/panels/network/wireless-security/ws-leap.h0000664000175000017500000000217614724311620025410 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2007 - 2014 Red Hat, Inc. */ #ifndef WS_LEAP_H #define WS_LEAP_H typedef struct _WirelessSecurityLEAP WirelessSecurityLEAP; WirelessSecurityLEAP * ws_leap_new (NMConnection *connection, gboolean secrets_only); #endif /* WS_LEAP_H */ cinnamon-control-center-6.4.1/panels/network/wireless-security/ws-wpa-eap.c0000664000175000017500000001001114724311620025777 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2007 - 2014 Red Hat, Inc. */ #include "nm-default.h" #include #include #include "wireless-security.h" #include "eap-method.h" struct _WirelessSecurityWPAEAP { WirelessSecurity parent; GtkSizeGroup *size_group; }; static void destroy (WirelessSecurity *parent) { WirelessSecurityWPAEAP *sec = (WirelessSecurityWPAEAP *) parent; if (sec->size_group) g_object_unref (sec->size_group); } static gboolean validate (WirelessSecurity *parent, GError **error) { return ws_802_1x_validate (parent, "wpa_eap_auth_combo", error); } static void add_to_size_group (WirelessSecurity *parent, GtkSizeGroup *group) { WirelessSecurityWPAEAP *sec = (WirelessSecurityWPAEAP *) parent; if (sec->size_group) g_object_unref (sec->size_group); sec->size_group = g_object_ref (group); ws_802_1x_add_to_size_group (parent, sec->size_group, "wpa_eap_auth_label", "wpa_eap_auth_combo"); } static void fill_connection (WirelessSecurity *parent, NMConnection *connection) { NMSettingWirelessSecurity *s_wireless_sec; ws_802_1x_fill_connection (parent, "wpa_eap_auth_combo", connection); s_wireless_sec = nm_connection_get_setting_wireless_security (connection); g_assert (s_wireless_sec); g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", NULL); } static void auth_combo_changed_cb (GtkWidget *combo, gpointer user_data) { WirelessSecurity *parent = WIRELESS_SECURITY (user_data); WirelessSecurityWPAEAP *sec = (WirelessSecurityWPAEAP *) parent; ws_802_1x_auth_combo_changed (combo, parent, "wpa_eap_method_vbox", sec->size_group); } static void update_secrets (WirelessSecurity *parent, NMConnection *connection) { ws_802_1x_update_secrets (parent, "wpa_eap_auth_combo", connection); } WirelessSecurityWPAEAP * ws_wpa_eap_new (NMConnection *connection, gboolean is_editor, gboolean secrets_only) { WirelessSecurity *parent; GtkWidget *widget; parent = wireless_security_init (sizeof (WirelessSecurityWPAEAP), validate, add_to_size_group, fill_connection, update_secrets, destroy, "/org/cinnamon/control-center/network/ws-wpa-eap.ui", "wpa_eap_notebook", NULL); if (!parent) return NULL; parent->adhoc_compatible = FALSE; parent->hotspot_compatible = FALSE; widget = ws_802_1x_auth_combo_init (parent, "wpa_eap_auth_combo", "wpa_eap_auth_label", (GCallback) auth_combo_changed_cb, connection, is_editor, secrets_only); auth_combo_changed_cb (widget, parent); return (WirelessSecurityWPAEAP *) parent; } cinnamon-control-center-6.4.1/panels/network/wireless-security/eap-method-tls.ui0000664000175000017500000002243014724311620027044 0ustar fabiofabio True False False False True False start 6 2 6 6 True False 1 I_dentity True eap_tls_identity_entry GTK_FILL True True True 1 2 True False 1 _User certificate True eap_tls_user_cert_button 1 2 GTK_FILL True False 1 C_A certificate True eap_tls_ca_cert_button 2 3 GTK_FILL True False 1 2 2 3 GTK_FILL GTK_FILL No CA certificate is _required True True False True True 1 2 3 4 GTK_FILL True False 1 Private _key True eap_tls_private_key_button 4 5 GTK_FILL True False 1 2 4 5 GTK_FILL GTK_FILL True False 1 _Private key password True eap_tls_private_key_password_entry 5 6 GTK_FILL True True False True 1 2 5 6 Sho_w password True True False True True 1 2 6 7 GTK_FILL True False 1 2 1 2 GTK_FILL GTK_FILL True False False cinnamon-control-center-6.4.1/panels/network/wireless-security/eap-method-tls.c0000664000175000017500000005343214724311620026657 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2007 - 2014 Red Hat, Inc. */ #include "nm-default.h" #include #include #include "eap-method.h" #include "wireless-security.h" #include "helpers.h" #include "nma-ui-utils.h" #include "utils.h" struct _EAPMethodTLS { EAPMethod parent; gboolean editing_connection; }; static void show_toggled_cb (GtkCheckButton *button, EAPMethod *method) { GtkWidget *widget; gboolean visible; widget = GTK_WIDGET (gtk_builder_get_object (method->builder, "eap_tls_private_key_password_entry")); g_assert (widget); visible = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); gtk_entry_set_visibility (GTK_ENTRY (widget), visible); } static gboolean validate (EAPMethod *parent, GError **error) { NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; GtkWidget *widget; const char *password, *identity; GError *local = NULL; gboolean ret = TRUE; widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_identity_entry")); g_assert (widget); identity = gtk_entry_get_text (GTK_ENTRY (widget)); if (!identity || !strlen (identity)) { widget_set_error (widget); g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing EAP-TLS identity")); ret = FALSE; } else { widget_unset_error (widget); } if (!eap_method_validate_filepicker (parent->builder, "eap_tls_ca_cert_button", TYPE_CA_CERT, NULL, NULL, &local)) { widget_set_error (GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_button"))); if (ret) { g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-TLS CA certificate: %s"), local->message); ret = FALSE; } g_clear_error (&local); } else if (eap_method_ca_cert_required (parent->builder, "eap_tls_ca_cert_not_required_checkbox", "eap_tls_ca_cert_button")) { widget_set_error (GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_button"))); if (ret) { g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-TLS CA certificate: no certificate specified")); ret = FALSE; } } widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_password_entry")); g_assert (widget); password = gtk_entry_get_text (GTK_ENTRY (widget)); if (!password || !strlen (password)) { widget_set_error (widget); if (ret) { g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-TLS password: missing")); ret = FALSE; } } else { widget_unset_error (widget); } if (!eap_method_validate_filepicker (parent->builder, "eap_tls_private_key_button", TYPE_PRIVATE_KEY, password, &format, &local)) { if (ret) { g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-TLS private-key: %s"), local->message); ret = FALSE; } g_clear_error (&local); widget_set_error (GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_button"))); } if (format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) { if (!eap_method_validate_filepicker (parent->builder, "eap_tls_user_cert_button", TYPE_CLIENT_CERT, NULL, NULL, &local)) { if (ret) { g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-TLS user-certificate: %s"), local->message); ret = FALSE; } g_clear_error (&local); widget_set_error (GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_button"))); } } return ret; } static void ca_cert_not_required_toggled (GtkWidget *ignored, gpointer user_data) { EAPMethod *parent = user_data; eap_method_ca_cert_not_required_toggled (parent->builder, "eap_tls_ca_cert_not_required_checkbox", "eap_tls_ca_cert_button"); } static void add_to_size_group (EAPMethod *parent, GtkSizeGroup *group) { GtkWidget *widget; widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_not_required_checkbox")); g_assert (widget); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_identity_label")); g_assert (widget); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_label")); g_assert (widget); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_label")); g_assert (widget); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_label")); g_assert (widget); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_password_label")); g_assert (widget); gtk_size_group_add_widget (group, widget); } static void fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFlags flags) { EAPMethodTLS *method = (EAPMethodTLS *) parent; NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; NMSetting8021x *s_8021x; NMSettingSecretFlags secret_flags; GtkWidget *widget, *passwd_entry; char *ca_filename, *pk_filename, *cc_filename; const char *password = NULL; GError *error = NULL; gboolean ca_cert_error = FALSE; s_8021x = nm_connection_get_setting_802_1x (connection); g_assert (s_8021x); if (parent->phase2) g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, "tls", NULL); else nm_setting_802_1x_add_eap_method (s_8021x, "tls"); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_identity_entry")); g_assert (widget); g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, gtk_entry_get_text (GTK_ENTRY (widget)), NULL); /* TLS private key */ widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_password_entry")); g_assert (widget); password = gtk_entry_get_text (GTK_ENTRY (widget)); g_assert (password); passwd_entry = widget; widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_button")); g_assert (widget); pk_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); g_assert (pk_filename); if (parent->phase2) { if (!nm_setting_802_1x_set_phase2_private_key (s_8021x, pk_filename, password, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) { g_warning ("Couldn't read phase2 private key '%s': %s", pk_filename, error ? error->message : "(unknown)"); g_clear_error (&error); } } else { if (!nm_setting_802_1x_set_private_key (s_8021x, pk_filename, password, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) { g_warning ("Couldn't read private key '%s': %s", pk_filename, error ? error->message : "(unknown)"); g_clear_error (&error); } } g_free (pk_filename); /* Save 802.1X password flags to the connection */ secret_flags = nma_utils_menu_to_secret_flags (passwd_entry); nm_setting_set_secret_flags (NM_SETTING (s_8021x), parent->password_flags_name, secret_flags, NULL); /* Update secret flags and popup when editing the connection */ if (method->editing_connection) { nma_utils_update_password_storage (passwd_entry, secret_flags, NM_SETTING (s_8021x), parent->password_flags_name); } /* TLS client certificate */ if (format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) { /* If the key is pkcs#12 nm_setting_802_1x_set_private_key() already * set the client certificate for us. */ widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_button")); g_assert (widget); cc_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); g_assert (cc_filename); format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; if (parent->phase2) { if (!nm_setting_802_1x_set_phase2_client_cert (s_8021x, cc_filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) { g_warning ("Couldn't read phase2 client certificate '%s': %s", cc_filename, error ? error->message : "(unknown)"); g_clear_error (&error); } } else { if (!nm_setting_802_1x_set_client_cert (s_8021x, cc_filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) { g_warning ("Couldn't read client certificate '%s': %s", cc_filename, error ? error->message : "(unknown)"); g_clear_error (&error); } } g_free (cc_filename); } /* TLS CA certificate */ widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_button")); g_assert (widget); ca_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; if (parent->phase2) { if (!nm_setting_802_1x_set_phase2_ca_cert (s_8021x, ca_filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) { g_warning ("Couldn't read phase2 CA certificate '%s': %s", ca_filename, error ? error->message : "(unknown)"); g_clear_error (&error); ca_cert_error = TRUE; } } else { if (!nm_setting_802_1x_set_ca_cert (s_8021x, ca_filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) { g_warning ("Couldn't read CA certificate '%s': %s", ca_filename, error ? error->message : "(unknown)"); g_clear_error (&error); ca_cert_error = TRUE; } } eap_method_ca_cert_ignore_set (parent, connection, ca_filename, ca_cert_error); g_free (ca_filename); } static void private_key_picker_helper (EAPMethod *parent, const char *filename, gboolean changed) { NMSetting8021x *setting; NMSetting8021xCKFormat cert_format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; const char *password; GtkWidget *widget; widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_password_entry")); g_assert (widget); password = gtk_entry_get_text (GTK_ENTRY (widget)); setting = (NMSetting8021x *) nm_setting_802_1x_new (); nm_setting_802_1x_set_private_key (setting, filename, password, NM_SETTING_802_1X_CK_SCHEME_PATH, &cert_format, NULL); g_object_unref (setting); /* With PKCS#12, the client cert must be the same as the private key */ widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_button")); if (cert_format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) { gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (widget)); gtk_widget_set_sensitive (widget, FALSE); } else if (changed) gtk_widget_set_sensitive (widget, TRUE); /* Warn the user if the private key is unencrypted */ if (!eap_method_is_encrypted_private_key (filename)) { GtkWidget *dialog; GtkWidget *toplevel; GtkWindow *parent_window = NULL; toplevel = gtk_widget_get_toplevel (parent->ui_widget); if (gtk_widget_is_toplevel (toplevel)) parent_window = GTK_WINDOW (toplevel); dialog = gtk_message_dialog_new (parent_window, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "%s", _("Unencrypted private keys are insecure")); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", _("The selected private key does not appear to be protected by a password. This could allow your security credentials to be compromised. Please select a password-protected private key.\n\n(You can password-protect your private key with openssl)")); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); } } static void private_key_picker_file_set_cb (GtkWidget *chooser, gpointer user_data) { EAPMethod *parent = (EAPMethod *) user_data; char *filename; filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser)); if (filename) private_key_picker_helper (parent, filename, TRUE); g_free (filename); } static void reset_filter (GtkWidget *widget, GParamSpec *spec, gpointer user_data) { if (!gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (widget))) { g_signal_handlers_block_by_func (widget, reset_filter, user_data); gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (widget), GTK_FILE_FILTER (user_data)); g_signal_handlers_unblock_by_func (widget, reset_filter, user_data); } } typedef const char * (*PathFunc) (NMSetting8021x *setting); typedef NMSetting8021xCKScheme (*SchemeFunc) (NMSetting8021x *setting); static void setup_filepicker (GtkBuilder *builder, const char *name, const char *title, WirelessSecurity *ws_parent, EAPMethod *parent, NMSetting8021x *s_8021x, SchemeFunc scheme_func, PathFunc path_func, gboolean privkey, gboolean client_cert) { GtkWidget *widget; GtkFileFilter *filter; const char *filename = NULL; widget = GTK_WIDGET (gtk_builder_get_object (builder, name)); g_assert (widget); gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (widget), TRUE); gtk_file_chooser_button_set_title (GTK_FILE_CHOOSER_BUTTON (widget), title); if (s_8021x && path_func && scheme_func) { if (scheme_func (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH) { filename = path_func (s_8021x); if (filename) gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename); } } /* Connect a special handler for private keys to intercept PKCS#12 key types * and desensitize the user cert button. */ if (privkey) { g_signal_connect (G_OBJECT (widget), "selection-changed", (GCallback) private_key_picker_file_set_cb, parent); if (filename) private_key_picker_helper (parent, filename, FALSE); } g_signal_connect (G_OBJECT (widget), "selection-changed", (GCallback) wireless_security_changed_cb, ws_parent); filter = eap_method_default_file_chooser_filter_new (privkey); gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (widget), filter); /* For some reason, GTK+ calls set_current_filter (..., NULL) from * gtkfilechooserdefault.c::show_and_select_files_finished_loading() on our * dialog; so force-reset the filter to what we want it to be whenever * it gets cleared. */ if (client_cert) g_signal_connect (G_OBJECT (widget), "notify::filter", (GCallback) reset_filter, filter); } static void update_secrets (EAPMethod *parent, NMConnection *connection) { NMSetting8021x *s_8021x; HelperSecretFunc password_func; SchemeFunc scheme_func; PathFunc path_func; const char *filename; GtkWidget *widget; if (parent->phase2) { password_func = (HelperSecretFunc) nm_setting_802_1x_get_phase2_private_key_password; scheme_func = nm_setting_802_1x_get_phase2_private_key_scheme; path_func = nm_setting_802_1x_get_phase2_private_key_path; } else { password_func = (HelperSecretFunc) nm_setting_802_1x_get_private_key_password; scheme_func = nm_setting_802_1x_get_private_key_scheme; path_func = nm_setting_802_1x_get_private_key_path; } helper_fill_secret_entry (connection, parent->builder, "eap_tls_private_key_password_entry", NM_TYPE_SETTING_802_1X, password_func); /* Set the private key filepicker button path if we have a private key */ s_8021x = nm_connection_get_setting_802_1x (connection); if (s_8021x && (scheme_func (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH)) { filename = path_func (s_8021x); if (filename) { widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_button")); g_assert (widget); gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename); } } } EAPMethodTLS * eap_method_tls_new (WirelessSecurity *ws_parent, NMConnection *connection, gboolean phase2, gboolean secrets_only) { EAPMethodTLS *method; EAPMethod *parent; GtkWidget *widget; NMSetting8021x *s_8021x = NULL; gboolean ca_not_required = FALSE; parent = eap_method_init (sizeof (EAPMethodTLS), validate, add_to_size_group, fill_connection, update_secrets, NULL, "/org/cinnamon/control-center/network/eap-method-tls.ui", "eap_tls_notebook", "eap_tls_identity_entry", phase2); if (!parent) return NULL; parent->password_flags_name = phase2 ? NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD : NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD; method = (EAPMethodTLS *) parent; method->editing_connection = secrets_only ? FALSE : TRUE; if (connection) s_8021x = nm_connection_get_setting_802_1x (connection); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_not_required_checkbox")); g_assert (widget); g_signal_connect (G_OBJECT (widget), "toggled", (GCallback) ca_cert_not_required_toggled, parent); g_signal_connect (G_OBJECT (widget), "toggled", (GCallback) wireless_security_changed_cb, ws_parent); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_identity_entry")); g_assert (widget); g_signal_connect (G_OBJECT (widget), "changed", (GCallback) wireless_security_changed_cb, ws_parent); if (s_8021x && nm_setting_802_1x_get_identity (s_8021x)) gtk_entry_set_text (GTK_ENTRY (widget), nm_setting_802_1x_get_identity (s_8021x)); setup_filepicker (parent->builder, "eap_tls_user_cert_button", _("Choose your personal certificate"), ws_parent, parent, s_8021x, phase2 ? nm_setting_802_1x_get_phase2_client_cert_scheme : nm_setting_802_1x_get_client_cert_scheme, phase2 ? nm_setting_802_1x_get_phase2_client_cert_path : nm_setting_802_1x_get_client_cert_path, FALSE, TRUE); setup_filepicker (parent->builder, "eap_tls_ca_cert_button", _("Choose a Certificate Authority certificate"), ws_parent, parent, s_8021x, phase2 ? nm_setting_802_1x_get_phase2_ca_cert_scheme : nm_setting_802_1x_get_ca_cert_scheme, phase2 ? nm_setting_802_1x_get_phase2_ca_cert_path : nm_setting_802_1x_get_ca_cert_path, FALSE, FALSE); setup_filepicker (parent->builder, "eap_tls_private_key_button", _("Choose your private key"), ws_parent, parent, s_8021x, phase2 ? nm_setting_802_1x_get_phase2_private_key_scheme : nm_setting_802_1x_get_private_key_scheme, phase2 ? nm_setting_802_1x_get_phase2_private_key_path : nm_setting_802_1x_get_private_key_path, TRUE, FALSE); if (connection && eap_method_ca_cert_ignore_get (parent, connection)) { widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_button")); ca_not_required = !gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); } widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_not_required_checkbox")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), ca_not_required); /* Fill secrets, if any */ if (connection) update_secrets (parent, connection); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_password_entry")); g_assert (widget); g_signal_connect (G_OBJECT (widget), "changed", (GCallback) wireless_security_changed_cb, ws_parent); /* Create password-storage popup menu for password entry under entry's secondary icon */ nma_utils_setup_password_storage (widget, 0, (NMSetting *) s_8021x, parent->password_flags_name, FALSE, secrets_only); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_eaptls")); g_assert (widget); g_signal_connect (G_OBJECT (widget), "toggled", (GCallback) show_toggled_cb, parent); if (secrets_only) { widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_identity_entry")); gtk_widget_set_sensitive (widget, FALSE); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_label")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_button")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_label")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_button")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_label")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_button")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_not_required_checkbox")); gtk_widget_hide (widget); } return method; } cinnamon-control-center-6.4.1/panels/network/wireless-security/eap-method-peap.h0000664000175000017500000000251214724311620027000 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (C) Copyright 2007 - 2010 Red Hat, Inc. */ #ifndef EAP_METHOD_PEAP_H #define EAP_METHOD_PEAP_H #include "wireless-security.h" typedef struct _EAPMethodPEAP EAPMethodPEAP; EAPMethodPEAP *eap_method_peap_new (WirelessSecurity *ws_parent, NMConnection *connection, gboolean is_editor, gboolean secrets_only); #endif /* EAP_METHOD_PEAP_H */ cinnamon-control-center-6.4.1/panels/network/wireless-security/helpers.c0000664000175000017500000000327614724311620025477 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2009 - 2014 Red Hat, Inc. */ #include "nm-default.h" #include "helpers.h" void helper_fill_secret_entry (NMConnection *connection, GtkBuilder *builder, const char *entry_name, GType setting_type, HelperSecretFunc func) { GtkWidget *widget; NMSetting *setting; const char *tmp; g_return_if_fail (connection != NULL); g_return_if_fail (builder != NULL); g_return_if_fail (entry_name != NULL); g_return_if_fail (func != NULL); setting = nm_connection_get_setting (connection, setting_type); if (setting) { tmp = (*func) (setting); if (tmp) { widget = GTK_WIDGET (gtk_builder_get_object (builder, entry_name)); g_assert (widget); gtk_entry_set_text (GTK_ENTRY (widget), tmp); } } } cinnamon-control-center-6.4.1/panels/network/wireless-security/eap-method-leap.c0000664000175000017500000002202214724311620026765 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2007 - 2014 Red Hat, Inc. */ #include "nm-default.h" #include #include #include "eap-method.h" #include "wireless-security.h" #include "helpers.h" #include "nma-ui-utils.h" #include "utils.h" struct _EAPMethodLEAP { EAPMethod parent; WirelessSecurity *ws_parent; gboolean editing_connection; GtkEntry *username_entry; GtkEntry *password_entry; GtkToggleButton *show_password; }; static void show_toggled_cb (GtkToggleButton *button, EAPMethodLEAP *method) { gboolean visible; visible = gtk_toggle_button_get_active (button); gtk_entry_set_visibility (method->password_entry, visible); } static gboolean validate (EAPMethod *parent, GError **error) { EAPMethodLEAP *method = (EAPMethodLEAP *)parent; const char *text; gboolean ret = TRUE; text = gtk_entry_get_text (method->username_entry); if (!text || !strlen (text)) { widget_set_error (GTK_WIDGET (method->username_entry)); g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing EAP-LEAP username")); ret = FALSE; } else widget_unset_error (GTK_WIDGET (method->username_entry)); text = gtk_entry_get_text (method->password_entry); if (!text || !strlen (text)) { widget_set_error (GTK_WIDGET (method->password_entry)); if (ret) { g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing EAP-LEAP password")); ret = FALSE; } } else widget_unset_error (GTK_WIDGET (method->password_entry)); return ret; } static void add_to_size_group (EAPMethod *parent, GtkSizeGroup *group) { GtkWidget *widget; widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_username_label")); g_assert (widget); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_password_label")); g_assert (widget); gtk_size_group_add_widget (group, widget); } static void fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFlags flags) { EAPMethodLEAP *method = (EAPMethodLEAP *) parent; NMSetting8021x *s_8021x; NMSettingSecretFlags secret_flags; GtkWidget *passwd_entry; s_8021x = nm_connection_get_setting_802_1x (connection); g_assert (s_8021x); nm_setting_802_1x_add_eap_method (s_8021x, "leap"); g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, gtk_entry_get_text (method->username_entry), NULL); g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD, gtk_entry_get_text (method->password_entry), NULL); passwd_entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_password_entry")); g_assert (passwd_entry); /* Save 802.1X password flags to the connection */ secret_flags = nma_utils_menu_to_secret_flags (passwd_entry); nm_setting_set_secret_flags (NM_SETTING (s_8021x), parent->password_flags_name, secret_flags, NULL); /* Update secret flags and popup when editing the connection */ if (method->editing_connection) nma_utils_update_password_storage (passwd_entry, secret_flags, NM_SETTING (s_8021x), parent->password_flags_name); } static void update_secrets (EAPMethod *parent, NMConnection *connection) { helper_fill_secret_entry (connection, parent->builder, "eap_leap_password_entry", NM_TYPE_SETTING_802_1X, (HelperSecretFunc) nm_setting_802_1x_get_password); } /* Set the UI fields for user, password and show_password to the * values as provided by method->ws_parent. */ static void set_userpass_ui (EAPMethodLEAP *method) { if (method->ws_parent->username) gtk_entry_set_text (method->username_entry, method->ws_parent->username); else gtk_entry_set_text (method->username_entry, ""); if (method->ws_parent->password && !method->ws_parent->always_ask) gtk_entry_set_text (method->password_entry, method->ws_parent->password); else gtk_entry_set_text (method->password_entry, ""); gtk_toggle_button_set_active (method->show_password, method->ws_parent->show_password); } static void widgets_realized (GtkWidget *widget, EAPMethodLEAP *method) { set_userpass_ui (method); } static void widgets_unrealized (GtkWidget *widget, EAPMethodLEAP *method) { wireless_security_set_userpass (method->ws_parent, gtk_entry_get_text (method->username_entry), gtk_entry_get_text (method->password_entry), (gboolean) -1, gtk_toggle_button_get_active (method->show_password)); } static void destroy (EAPMethod *parent) { EAPMethodLEAP *method = (EAPMethodLEAP *) parent; GtkWidget *widget; widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_notebook")); g_assert (widget); g_signal_handlers_disconnect_by_func (G_OBJECT (widget), (GCallback) widgets_realized, method); g_signal_handlers_disconnect_by_func (G_OBJECT (widget), (GCallback) widgets_unrealized, method); wireless_security_unref (method->ws_parent); } EAPMethodLEAP * eap_method_leap_new (WirelessSecurity *ws_parent, NMConnection *connection, gboolean secrets_only) { EAPMethodLEAP *method; EAPMethod *parent; GtkWidget *widget; NMSetting8021x *s_8021x = NULL; parent = eap_method_init (sizeof (EAPMethodLEAP), validate, add_to_size_group, fill_connection, update_secrets, destroy, "/org/cinnamon/control-center/network/eap-method-leap.ui", "eap_leap_notebook", "eap_leap_username_entry", FALSE); if (!parent) return NULL; parent->password_flags_name = NM_SETTING_802_1X_PASSWORD; method = (EAPMethodLEAP *) parent; method->editing_connection = secrets_only ? FALSE : TRUE; method->ws_parent = wireless_security_ref (ws_parent); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_notebook")); g_assert (widget); g_signal_connect (G_OBJECT (widget), "realize", (GCallback) widgets_realized, method); g_signal_connect (G_OBJECT (widget), "unrealize", (GCallback) widgets_unrealized, method); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_username_entry")); g_assert (widget); method->username_entry = GTK_ENTRY (widget); g_signal_connect (G_OBJECT (widget), "changed", (GCallback) wireless_security_changed_cb, ws_parent); if (secrets_only) gtk_widget_set_sensitive (widget, FALSE); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_password_entry")); g_assert (widget); method->password_entry = GTK_ENTRY (widget); g_signal_connect (G_OBJECT (widget), "changed", (GCallback) wireless_security_changed_cb, ws_parent); /* Create password-storage popup menu for password entry under entry's secondary icon */ if (connection) s_8021x = nm_connection_get_setting_802_1x (connection); nma_utils_setup_password_storage (widget, 0, (NMSetting *) s_8021x, parent->password_flags_name, FALSE, secrets_only); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_eapleap")); g_assert (widget); method->show_password = GTK_TOGGLE_BUTTON (widget); g_signal_connect (G_OBJECT (widget), "toggled", (GCallback) show_toggled_cb, parent); /* Initialize the UI fields with the security settings from method->ws_parent. * This will be done again when the widget gets realized. It must be done here as well, * because the outer dialog will ask to 'validate' the connection before the security tab * is shown/realized (to enable the 'Apply' button). * As 'validate' accesses the contents of the UI fields, they must be initialized now, even * if the widgets are not yet visible. */ set_userpass_ui (method); return method; } cinnamon-control-center-6.4.1/panels/network/wireless-security/ws-wpa-psk.h0000664000175000017500000000222014724311620026037 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2007 - 2014 Red Hat, Inc. */ #ifndef WS_WPA_PSK_H #define WS_WPA_PSK_H typedef struct _WirelessSecurityWPAPSK WirelessSecurityWPAPSK; WirelessSecurityWPAPSK * ws_wpa_psk_new (NMConnection *connection, gboolean secrets_only); #endif /* WS_WEP_KEY_H */ cinnamon-control-center-6.4.1/panels/network/wireless-security/eap-method-leap.h0000664000175000017500000000242214724311620026774 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (C) Copyright 2007 - 2010 Red Hat, Inc. */ #ifndef EAP_METHOD_LEAP_H #define EAP_METHOD_LEAP_H #include "wireless-security.h" typedef struct _EAPMethodLEAP EAPMethodLEAP; EAPMethodLEAP *eap_method_leap_new (WirelessSecurity *ws_parent, NMConnection *connection, gboolean secrets_only); #endif /* EAP_METHOD_LEAP_H */ cinnamon-control-center-6.4.1/panels/network/wireless-security/ws-leap.ui0000664000175000017500000001054514724311620025575 0ustar fabiofabio True False False False True False start 3 2 6 6 True False 1 _Username True leap_username_entry GTK_FILL True False 1 _Password True leap_password_entry 1 2 GTK_FILL True True False True 1 2 1 2 Sho_w password True True False True True 1 2 2 3 GTK_FILL True True True 1 2 True False False cinnamon-control-center-6.4.1/panels/network/wireless-security/ws-dynamic-wep.h0000664000175000017500000000243714724311620026704 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2007 - 2014 Red Hat, Inc. */ #ifndef WS_DYNAMIC_WEP_H #define WS_DYNAMIC_WEP_H typedef struct _WirelessSecurityDynamicWEP WirelessSecurityDynamicWEP; WirelessSecurityDynamicWEP *ws_dynamic_wep_new (NMConnection *connection, gboolean is_editor, gboolean secrets_only); #endif /* WS_DYNAMIC_WEP_H */ cinnamon-control-center-6.4.1/panels/network/wireless-security/ws-wep-key.ui0000664000175000017500000001663714724311620026245 0ustar fabiofabio 1 (Default) 2 3 4 Open System Shared Key True False False False True False 4 2 6 6 True False 1 _Key True wep_key_entry GTK_FILL True True 64 False True 1 2 True False 0 1 2 GTK_FILL Sho_w key True True False True True 1 2 1 2 GTK_FILL True False 1 Au_thentication True auth_method_combo 3 4 GTK_FILL True False model3 0 1 2 3 4 GTK_FILL GTK_FILL True False 1 WEP inde_x True key_index_combo 2 3 GTK_FILL True False model4 0 1 2 2 3 GTK_FILL GTK_FILL True False False cinnamon-control-center-6.4.1/panels/network/wireless-security/eap-method.c0000664000175000017500000003720514724311620026057 0ustar fabiofabio/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2007 - 2014 Red Hat, Inc. */ #include "nm-default.h" #include #include #include #include #include #include "eap-method.h" #include "nm-utils.h" #include "utils.h" #include "helpers.h" GType eap_method_get_type (void) { static GType type_id = 0; if (!type_id) { type_id = g_boxed_type_register_static ("CcEAPMethod", (GBoxedCopyFunc) eap_method_ref, (GBoxedFreeFunc) eap_method_unref); } return type_id; } GtkWidget * eap_method_get_widget (EAPMethod *method) { g_return_val_if_fail (method != NULL, NULL); return method->ui_widget; } gboolean eap_method_validate (EAPMethod *method, GError **error) { gboolean result; g_return_val_if_fail (method != NULL, FALSE); g_assert (method->validate); result = (*(method->validate)) (method, error); if (!result && error && !*error) g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("undefined error in 802.1x security (wpa-eap)")); return result; } void eap_method_add_to_size_group (EAPMethod *method, GtkSizeGroup *group) { g_return_if_fail (method != NULL); g_return_if_fail (group != NULL); g_assert (method->add_to_size_group); return (*(method->add_to_size_group)) (method, group); } void eap_method_fill_connection (EAPMethod *method, NMConnection *connection, NMSettingSecretFlags flags) { g_return_if_fail (method != NULL); g_return_if_fail (connection != NULL); g_assert (method->fill_connection); return (*(method->fill_connection)) (method, connection, flags); } void eap_method_update_secrets (EAPMethod *method, NMConnection *connection) { g_return_if_fail (method != NULL); g_return_if_fail (connection != NULL); if (method->update_secrets) method->update_secrets (method, connection); } void eap_method_phase2_update_secrets_helper (EAPMethod *method, NMConnection *connection, const char *combo_name, guint32 column) { GtkWidget *combo; GtkTreeIter iter; GtkTreeModel *model; g_return_if_fail (method != NULL); g_return_if_fail (connection != NULL); g_return_if_fail (combo_name != NULL); combo = GTK_WIDGET (gtk_builder_get_object (method->builder, combo_name)); g_assert (combo); /* Let each EAP phase2 method try to update its secrets */ model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo)); if (gtk_tree_model_get_iter_first (model, &iter)) { do { EAPMethod *eap = NULL; gtk_tree_model_get (model, &iter, column, &eap, -1); if (eap) { eap_method_update_secrets (eap, connection); eap_method_unref (eap); } } while (gtk_tree_model_iter_next (model, &iter)); } } EAPMethod * eap_method_init (gsize obj_size, EMValidateFunc validate, EMAddToSizeGroupFunc add_to_size_group, EMFillConnectionFunc fill_connection, EMUpdateSecretsFunc update_secrets, EMDestroyFunc destroy, const char *ui_resource, const char *ui_widget_name, const char *default_field, gboolean phase2) { EAPMethod *method; GError *error = NULL; g_return_val_if_fail (obj_size > 0, NULL); g_return_val_if_fail (ui_resource != NULL, NULL); g_return_val_if_fail (ui_widget_name != NULL, NULL); method = g_slice_alloc0 (obj_size); g_assert (method); method->refcount = 1; method->obj_size = obj_size; method->validate = validate; method->add_to_size_group = add_to_size_group; method->fill_connection = fill_connection; method->update_secrets = update_secrets; method->default_field = default_field; method->phase2 = phase2; method->builder = gtk_builder_new (); if (!gtk_builder_add_from_resource (method->builder, ui_resource, &error)) { g_warning ("Couldn't load UI builder file %s: %s", ui_resource, error->message); eap_method_unref (method); return NULL; } method->ui_widget = GTK_WIDGET (gtk_builder_get_object (method->builder, ui_widget_name)); if (!method->ui_widget) { g_warning ("Couldn't load UI widget '%s' from UI file %s", ui_widget_name, ui_resource); eap_method_unref (method); return NULL; } g_object_ref_sink (method->ui_widget); method->destroy = destroy; return method; } EAPMethod * eap_method_ref (EAPMethod *method) { g_return_val_if_fail (method != NULL, NULL); g_return_val_if_fail (method->refcount > 0, NULL); method->refcount++; return method; } void eap_method_unref (EAPMethod *method) { g_return_if_fail (method != NULL); g_return_if_fail (method->refcount > 0); method->refcount--; if (method->refcount == 0) { if (method->destroy) method->destroy (method); if (method->builder) g_object_unref (method->builder); if (method->ui_widget) g_object_unref (method->ui_widget); g_slice_free1 (method->obj_size, method); } } gboolean eap_method_validate_filepicker (GtkBuilder *builder, const char *name, guint32 item_type, const char *password, NMSetting8021xCKFormat *out_format, GError **error) { GtkWidget *widget; char *filename; NMSetting8021x *setting; gboolean success = TRUE; if (item_type == TYPE_PRIVATE_KEY) { if (!password || *password == '\0') success = FALSE; } widget = GTK_WIDGET (gtk_builder_get_object (builder, name)); g_assert (widget); filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); if (!filename) { if (item_type != TYPE_CA_CERT) { success = FALSE; g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("no file selected")); } goto out; } if (!g_file_test (filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { success = FALSE; goto out; } setting = (NMSetting8021x *) nm_setting_802_1x_new (); success = FALSE; if (item_type == TYPE_PRIVATE_KEY) { if (nm_setting_802_1x_set_private_key (setting, filename, password, NM_SETTING_802_1X_CK_SCHEME_PATH, out_format, error)) success = TRUE; } else if (item_type == TYPE_CLIENT_CERT) { if (nm_setting_802_1x_set_client_cert (setting, filename, NM_SETTING_802_1X_CK_SCHEME_PATH, out_format, error)) success = TRUE; } else if (item_type == TYPE_CA_CERT) { if (nm_setting_802_1x_set_ca_cert (setting, filename, NM_SETTING_802_1X_CK_SCHEME_PATH, out_format, error)) success = TRUE; } else g_warning ("%s: invalid item type %d.", __func__, item_type); g_object_unref (setting); out: g_free (filename); if (!success && error && !*error) g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("unspecified error validating eap-method file")); if (success) widget_unset_error (widget); else widget_set_error (widget); return success; } static gboolean default_filter_privkey (const GtkFileFilterInfo *filter_info, gpointer user_data) { gboolean require_encrypted = !!user_data; gboolean is_encrypted; if (!filter_info->filename) return FALSE; is_encrypted = FALSE; if (!nm_utils_file_is_private_key (filter_info->filename, &is_encrypted)) return FALSE; return require_encrypted ? is_encrypted : TRUE; } static gboolean default_filter_cert (const GtkFileFilterInfo *filter_info, gpointer user_data) { if (!filter_info->filename) return FALSE; if (!nm_utils_file_is_certificate (filter_info->filename)) return FALSE; return TRUE; } GtkFileFilter * eap_method_default_file_chooser_filter_new (gboolean privkey) { GtkFileFilter *filter; filter = gtk_file_filter_new (); if (privkey) { gtk_file_filter_add_custom (filter, GTK_FILE_FILTER_FILENAME, default_filter_privkey, NULL, NULL); gtk_file_filter_set_name (filter, _("DER, PEM, or PKCS#12 private keys (*.der, *.pem, *.p12, *.key)")); } else { gtk_file_filter_add_custom (filter, GTK_FILE_FILTER_FILENAME, default_filter_cert, NULL, NULL); gtk_file_filter_set_name (filter, _("DER or PEM certificates (*.der, *.pem, *.crt, *.cer)")); } return filter; } gboolean eap_method_is_encrypted_private_key (const char *path) { GtkFileFilterInfo info = { .filename = path }; return default_filter_privkey (&info, (gpointer) TRUE); } /* Some methods (PEAP, TLS, TTLS) require a CA certificate. The user can choose * not to provide such a certificate. This method whether the checkbox * id_ca_cert_not_required_checkbutton is checked or id_ca_cert_chooser has a certificate * selected. */ gboolean eap_method_ca_cert_required (GtkBuilder *builder, const char *id_ca_cert_not_required_checkbutton, const char *id_ca_cert_chooser) { char *filename; GtkWidget *widget; g_assert (builder && id_ca_cert_not_required_checkbutton && id_ca_cert_chooser); widget = GTK_WIDGET (gtk_builder_get_object (builder, id_ca_cert_not_required_checkbutton)); g_assert (widget && GTK_IS_TOGGLE_BUTTON (widget)); if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) { widget = GTK_WIDGET (gtk_builder_get_object (builder, id_ca_cert_chooser)); g_assert (widget && GTK_IS_FILE_CHOOSER (widget)); filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); if (!filename) return TRUE; g_free (filename); } return FALSE; } void eap_method_ca_cert_not_required_toggled (GtkBuilder *builder, const char *id_ca_cert_not_required_checkbutton, const char *id_ca_cert_chooser) { char *filename, *filename_old; gboolean is_not_required; GtkWidget *widget; g_assert (builder && id_ca_cert_not_required_checkbutton && id_ca_cert_chooser); widget = GTK_WIDGET (gtk_builder_get_object (builder, id_ca_cert_not_required_checkbutton)); g_assert (widget && GTK_IS_TOGGLE_BUTTON (widget)); is_not_required = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); widget = GTK_WIDGET (gtk_builder_get_object (builder, id_ca_cert_chooser)); g_assert (widget && GTK_IS_FILE_CHOOSER (widget)); filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); filename_old = g_object_steal_data (G_OBJECT (widget), "filename-old"); if (is_not_required) { g_free (filename_old); filename_old = filename; filename = NULL; } else { g_free (filename); filename = filename_old; filename_old = NULL; } gtk_widget_set_sensitive (widget, !is_not_required); if (filename) gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename); else gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (widget)); g_free (filename); g_object_set_data_full (G_OBJECT (widget), "filename-old", filename_old, g_free); } /* Used as both GSettings keys and GObject data tags */ #define IGNORE_CA_CERT_TAG "ignore-ca-cert" #define IGNORE_PHASE2_CA_CERT_TAG "ignore-phase2-ca-cert" /** * eap_method_ca_cert_ignore_set: * @method: the #EAPMethod object * @connection: the #NMConnection * @filename: the certificate file, if any * @ca_cert_error: %TRUE if an error was encountered loading the given CA * certificate, %FALSE if not or if a CA certificate is not present * * Updates the connection's CA cert ignore value to %TRUE if the "CA certificate * not required" checkbox is checked. If @ca_cert_error is %TRUE, then the * connection's CA cert ignore value will always be set to %FALSE, because it * means that the user selected an invalid certificate (thus he does not want to * ignore the CA cert).. */ void eap_method_ca_cert_ignore_set (EAPMethod *method, NMConnection *connection, const char *filename, gboolean ca_cert_error) { NMSetting8021x *s_8021x; gboolean ignore; s_8021x = nm_connection_get_setting_802_1x (connection); if (s_8021x) { ignore = !ca_cert_error && filename == NULL; g_object_set_data (G_OBJECT (s_8021x), method->phase2 ? IGNORE_PHASE2_CA_CERT_TAG : IGNORE_CA_CERT_TAG, GUINT_TO_POINTER (ignore)); } } /** * eap_method_ca_cert_ignore_get: * @method: the #EAPMethod object * @connection: the #NMConnection * * Returns: %TRUE if a missing CA certificate can be ignored, %FALSE if a CA * certificate should be required for the connection to be valid. */ gboolean eap_method_ca_cert_ignore_get (EAPMethod *method, NMConnection *connection) { NMSetting8021x *s_8021x; s_8021x = nm_connection_get_setting_802_1x (connection); if (s_8021x) { return !!g_object_get_data (G_OBJECT (s_8021x), method->phase2 ? IGNORE_PHASE2_CA_CERT_TAG : IGNORE_CA_CERT_TAG); } return FALSE; } static GSettings * _get_ca_ignore_settings (NMConnection *connection) { GSettings *settings; char *path = NULL; const char *uuid; g_return_val_if_fail (connection, NULL); uuid = nm_connection_get_uuid (connection); g_return_val_if_fail (uuid && *uuid, NULL); path = g_strdup_printf ("/org/gnome/nm-applet/eap/%s/", uuid); settings = g_settings_new_with_path ("org.gnome.nm-applet.eap", path); g_free (path); return settings; } /** * eap_method_ca_cert_ignore_save: * @connection: the connection for which to save CA cert ignore values to GSettings * * Reads the CA cert ignore tags from the 802.1x setting GObject data and saves * then to GSettings if present, using the connection UUID as the index. */ void eap_method_ca_cert_ignore_save (NMConnection *connection) { NMSetting8021x *s_8021x; GSettings *settings; gboolean ignore = FALSE, phase2_ignore = FALSE; g_return_if_fail (connection); s_8021x = nm_connection_get_setting_802_1x (connection); if (s_8021x) { ignore = !!g_object_get_data (G_OBJECT (s_8021x), IGNORE_CA_CERT_TAG); phase2_ignore = !!g_object_get_data (G_OBJECT (s_8021x), IGNORE_PHASE2_CA_CERT_TAG); } settings = _get_ca_ignore_settings (connection); if (!settings) return; g_settings_set_boolean (settings, IGNORE_CA_CERT_TAG, ignore); g_settings_set_boolean (settings, IGNORE_PHASE2_CA_CERT_TAG, phase2_ignore); g_object_unref (settings); } /** * eap_method_ca_cert_ignore_load: * @connection: the connection for which to load CA cert ignore values to GSettings * * Reads the CA cert ignore tags from the 802.1x setting GObject data and saves * then to GSettings if present, using the connection UUID as the index. */ void eap_method_ca_cert_ignore_load (NMConnection *connection) { GSettings *settings; NMSetting8021x *s_8021x; gboolean ignore, phase2_ignore; g_return_if_fail (connection); s_8021x = nm_connection_get_setting_802_1x (connection); if (!s_8021x) return; settings = _get_ca_ignore_settings (connection); if (!settings) return; ignore = g_settings_get_boolean (settings, IGNORE_CA_CERT_TAG); phase2_ignore = g_settings_get_boolean (settings, IGNORE_PHASE2_CA_CERT_TAG); g_object_set_data (G_OBJECT (s_8021x), IGNORE_CA_CERT_TAG, GUINT_TO_POINTER (ignore)); g_object_set_data (G_OBJECT (s_8021x), IGNORE_PHASE2_CA_CERT_TAG, GUINT_TO_POINTER (phase2_ignore)); g_object_unref (settings); } cinnamon-control-center-6.4.1/panels/network/wireless-security/helpers.h0000664000175000017500000000254214724311620025477 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2009 - 2014 Red Hat, Inc. */ #ifndef _HELPERS_H_ #define _HELPERS_H_ #include #include typedef const char * (*HelperSecretFunc)(NMSetting *); void helper_fill_secret_entry (NMConnection *connection, GtkBuilder *builder, const char *entry_name, GType setting_type, HelperSecretFunc func); #endif /* _HELPERS_H_ */ cinnamon-control-center-6.4.1/panels/network/wireless-security/ws-wpa-eap.h0000664000175000017500000000236614724311620026022 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2007 - 2014 Red Hat, Inc. */ #ifndef WS_WPA_EAP_H #define WS_WPA_EAP_H typedef struct _WirelessSecurityWPAEAP WirelessSecurityWPAEAP; WirelessSecurityWPAEAP * ws_wpa_eap_new (NMConnection *connection, gboolean is_editor, gboolean secrets_only); #endif /* WS_WPA_EAP_H */ cinnamon-control-center-6.4.1/panels/network/wireless-security/wireless-security.gresource.xml0000664000175000017500000000150114724311620032077 0ustar fabiofabio eap-method-leap.ui eap-method-fast.ui eap-method-peap.ui eap-method-simple.ui eap-method-tls.ui eap-method-ttls.ui ws-dynamic-wep.ui ws-leap.ui ws-wep-key.ui ws-wpa-eap.ui ws-wpa-psk.ui cinnamon-control-center-6.4.1/panels/network/wireless-security/eap-method-ttls.ui0000664000175000017500000001536714724311620027243 0ustar fabiofabio True False False False True False 4 2 6 6 True False 1 Anony_mous identity True eap_ttls_anon_identity_entry GTK_FILL True True True 1 2 True False 1 C_A certificate True eap_ttls_ca_cert_button 1 2 GTK_FILL True False 1 2 1 2 GTK_FILL GTK_FILL No CA certificate is _required True True False True True 1 2 2 3 GTK_FILL True False 1 _Inner authentication True eap_ttls_inner_auth_combo 3 4 GTK_FILL True False model6 0 1 2 3 4 GTK_FILL GTK_FILL True False 6 2 4 5 GTK_FILL True False False cinnamon-control-center-6.4.1/panels/network/wireless-security/nm-default.h0000664000175000017500000000267114724311620026074 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager -- Network link manager * * 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 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. * * (C) Copyright 2015 Red Hat, Inc. */ #ifndef __NM_DEFAULT_H__ #define __NM_DEFAULT_H__ /*****************************************************************************/ /* always include these headers for our internal source files. */ #ifndef ___CONFIG_H__ #define ___CONFIG_H__ #include #endif #include #include /*****************************************************************************/ #include #include /*****************************************************************************/ #endif /* __NM_DEFAULT_H__ */ cinnamon-control-center-6.4.1/panels/network/wireless-security/eap-method-peap.ui0000664000175000017500000002127214724311620027172 0ustar fabiofabio Automatic Version 0 Version 1 True False False False True False 5 2 6 6 True False 1 Anony_mous identity True eap_peap_anon_identity_entry GTK_FILL True True True 1 2 True False 1 C_A certificate True eap_peap_ca_cert_button 1 2 GTK_FILL True False 1 2 1 2 GTK_FILL GTK_FILL No CA certificate is _required True True False True True 1 2 2 3 GTK_FILL True False 2 5 6 GTK_FILL True False 1 _Inner authentication True eap_peap_inner_auth_combo 4 5 GTK_FILL True False model8 0 1 2 4 5 GTK_FILL GTK_FILL True False 1 PEAP _version True eap_peap_version_combo 3 4 GTK_FILL True False model9 0 1 2 3 4 GTK_FILL GTK_FILL True False False cinnamon-control-center-6.4.1/panels/network/wireless-security/eap-method-peap.c0000664000175000017500000003770114724311620027003 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2007 - 2014 Red Hat, Inc. */ #include "nm-default.h" #include #include #include "eap-method.h" #include "wireless-security.h" #include "utils.h" #define I_NAME_COLUMN 0 #define I_METHOD_COLUMN 1 struct _EAPMethodPEAP { EAPMethod parent; GtkSizeGroup *size_group; WirelessSecurity *sec_parent; gboolean is_editor; }; static void destroy (EAPMethod *parent) { EAPMethodPEAP *method = (EAPMethodPEAP *) parent; if (method->size_group) g_object_unref (method->size_group); } static gboolean validate (EAPMethod *parent, GError **error) { GtkWidget *widget; GtkTreeModel *model; GtkTreeIter iter; EAPMethod *eap = NULL; gboolean valid = FALSE; GError *local = NULL; if (!eap_method_validate_filepicker (parent->builder, "eap_peap_ca_cert_button", TYPE_CA_CERT, NULL, NULL, &local)) { g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-PEAP CA certificate: %s"), local->message); g_clear_error (&local); return FALSE; } if (eap_method_ca_cert_required (parent->builder, "eap_peap_ca_cert_not_required_checkbox", "eap_peap_ca_cert_button")) { g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-PEAP CA certificate: no certificate specified")); return FALSE; } widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_combo")); g_assert (widget); model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); g_assert (eap); valid = eap_method_validate (eap, error); eap_method_unref (eap); return valid; } static void ca_cert_not_required_toggled (GtkWidget *ignored, gpointer user_data) { EAPMethod *parent = user_data; eap_method_ca_cert_not_required_toggled (parent->builder, "eap_peap_ca_cert_not_required_checkbox", "eap_peap_ca_cert_button"); } static void add_to_size_group (EAPMethod *parent, GtkSizeGroup *group) { EAPMethodPEAP *method = (EAPMethodPEAP *) parent; GtkWidget *widget; GtkTreeModel *model; GtkTreeIter iter; EAPMethod *eap; if (method->size_group) g_object_unref (method->size_group); method->size_group = g_object_ref (group); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_ca_cert_not_required_checkbox")); g_assert (widget); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_anon_identity_label")); g_assert (widget); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_ca_cert_label")); g_assert (widget); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_version_label")); g_assert (widget); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_label")); g_assert (widget); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_combo")); g_assert (widget); model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); g_assert (eap); eap_method_add_to_size_group (eap, group); eap_method_unref (eap); } static void fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFlags flags) { NMSetting8021x *s_8021x; NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; GtkWidget *widget; const char *text; char *filename; EAPMethod *eap = NULL; GtkTreeModel *model; GtkTreeIter iter; int peapver_active = 0; GError *error = NULL; gboolean ca_cert_error = FALSE; s_8021x = nm_connection_get_setting_802_1x (connection); g_assert (s_8021x); nm_setting_802_1x_add_eap_method (s_8021x, "peap"); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_anon_identity_entry")); g_assert (widget); text = gtk_entry_get_text (GTK_ENTRY (widget)); if (text && strlen (text)) g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, text, NULL); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_ca_cert_button")); g_assert (widget); filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); if (!nm_setting_802_1x_set_ca_cert (s_8021x, filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) { g_warning ("Couldn't read CA certificate '%s': %s", filename, error ? error->message : "(unknown)"); g_clear_error (&error); ca_cert_error = TRUE; } eap_method_ca_cert_ignore_set (parent, connection, filename, ca_cert_error); g_free (filename); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_version_combo")); peapver_active = gtk_combo_box_get_active (GTK_COMBO_BOX (widget)); switch (peapver_active) { case 1: /* PEAP v0 */ g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_PEAPVER, "0", NULL); break; case 2: /* PEAP v1 */ g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_PEAPVER, "1", NULL); break; default: /* Automatic */ g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_PEAPVER, NULL, NULL); break; } widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_combo")); model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); g_assert (eap); eap_method_fill_connection (eap, connection, flags); eap_method_unref (eap); } static void inner_auth_combo_changed_cb (GtkWidget *combo, gpointer user_data) { EAPMethod *parent = (EAPMethod *) user_data; EAPMethodPEAP *method = (EAPMethodPEAP *) parent; GtkWidget *vbox; EAPMethod *eap = NULL; GList *elt, *children; GtkTreeModel *model; GtkTreeIter iter; GtkWidget *eap_widget; vbox = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_vbox")); g_assert (vbox); /* Remove any previous wireless security widgets */ children = gtk_container_get_children (GTK_CONTAINER (vbox)); for (elt = children; elt; elt = g_list_next (elt)) gtk_container_remove (GTK_CONTAINER (vbox), GTK_WIDGET (elt->data)); model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo)); gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter); gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); g_assert (eap); eap_widget = eap_method_get_widget (eap); g_assert (eap_widget); gtk_widget_unparent (eap_widget); if (method->size_group) eap_method_add_to_size_group (eap, method->size_group); gtk_container_add (GTK_CONTAINER (vbox), eap_widget); eap_method_unref (eap); wireless_security_changed_cb (combo, method->sec_parent); } static GtkWidget * inner_auth_combo_init (EAPMethodPEAP *method, NMConnection *connection, NMSetting8021x *s_8021x, gboolean secrets_only) { EAPMethod *parent = (EAPMethod *) method; GtkWidget *combo; GtkListStore *auth_model; GtkTreeIter iter; EAPMethodSimple *em_mschap_v2; EAPMethodSimple *em_md5; EAPMethodSimple *em_gtc; guint32 active = 0; const char *phase2_auth = NULL; EAPMethodSimpleFlags simple_flags; auth_model = gtk_list_store_new (2, G_TYPE_STRING, eap_method_get_type ()); if (s_8021x) { if (nm_setting_802_1x_get_phase2_auth (s_8021x)) phase2_auth = nm_setting_802_1x_get_phase2_auth (s_8021x); else if (nm_setting_802_1x_get_phase2_autheap (s_8021x)) phase2_auth = nm_setting_802_1x_get_phase2_autheap (s_8021x); } simple_flags = EAP_METHOD_SIMPLE_FLAG_PHASE2; if (method->is_editor) simple_flags |= EAP_METHOD_SIMPLE_FLAG_IS_EDITOR; if (secrets_only) simple_flags |= EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY; em_mschap_v2 = eap_method_simple_new (method->sec_parent, connection, EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2, simple_flags); gtk_list_store_append (auth_model, &iter); gtk_list_store_set (auth_model, &iter, I_NAME_COLUMN, _("MSCHAPv2"), I_METHOD_COLUMN, em_mschap_v2, -1); eap_method_unref (EAP_METHOD (em_mschap_v2)); /* Check for defaulting to MSCHAPv2 */ if (phase2_auth && !strcasecmp (phase2_auth, "mschapv2")) active = 0; em_md5 = eap_method_simple_new (method->sec_parent, connection, EAP_METHOD_SIMPLE_TYPE_MD5, simple_flags); gtk_list_store_append (auth_model, &iter); gtk_list_store_set (auth_model, &iter, I_NAME_COLUMN, _("MD5"), I_METHOD_COLUMN, em_md5, -1); eap_method_unref (EAP_METHOD (em_md5)); /* Check for defaulting to MD5 */ if (phase2_auth && !strcasecmp (phase2_auth, "md5")) active = 1; em_gtc = eap_method_simple_new (method->sec_parent, connection, EAP_METHOD_SIMPLE_TYPE_GTC, simple_flags); gtk_list_store_append (auth_model, &iter); gtk_list_store_set (auth_model, &iter, I_NAME_COLUMN, _("GTC"), I_METHOD_COLUMN, em_gtc, -1); eap_method_unref (EAP_METHOD (em_gtc)); /* Check for defaulting to GTC */ if (phase2_auth && !strcasecmp (phase2_auth, "gtc")) active = 2; combo = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_combo")); g_assert (combo); gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (auth_model)); g_object_unref (G_OBJECT (auth_model)); gtk_combo_box_set_active (GTK_COMBO_BOX (combo), active); g_signal_connect (G_OBJECT (combo), "changed", (GCallback) inner_auth_combo_changed_cb, method); return combo; } static void update_secrets (EAPMethod *parent, NMConnection *connection) { eap_method_phase2_update_secrets_helper (parent, connection, "eap_peap_inner_auth_combo", I_METHOD_COLUMN); } EAPMethodPEAP * eap_method_peap_new (WirelessSecurity *ws_parent, NMConnection *connection, gboolean is_editor, gboolean secrets_only) { EAPMethod *parent; EAPMethodPEAP *method; GtkWidget *widget, *widget_ca_not_required_checkbox; GtkFileFilter *filter; NMSetting8021x *s_8021x = NULL; const char *filename; parent = eap_method_init (sizeof (EAPMethodPEAP), validate, add_to_size_group, fill_connection, update_secrets, destroy, "/org/cinnamon/control-center/network/eap-method-peap.ui", "eap_peap_notebook", "eap_peap_anon_identity_entry", FALSE); if (!parent) return NULL; parent->password_flags_name = NM_SETTING_802_1X_PASSWORD; method = (EAPMethodPEAP *) parent; method->sec_parent = ws_parent; method->is_editor = is_editor; if (connection) s_8021x = nm_connection_get_setting_802_1x (connection); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_ca_cert_not_required_checkbox")); g_assert (widget); g_signal_connect (G_OBJECT (widget), "toggled", (GCallback) ca_cert_not_required_toggled, parent); g_signal_connect (G_OBJECT (widget), "toggled", (GCallback) wireless_security_changed_cb, ws_parent); widget_ca_not_required_checkbox = widget; widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_ca_cert_button")); g_assert (widget); gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (widget), TRUE); gtk_file_chooser_button_set_title (GTK_FILE_CHOOSER_BUTTON (widget), _("Choose a Certificate Authority certificate")); g_signal_connect (G_OBJECT (widget), "selection-changed", (GCallback) wireless_security_changed_cb, ws_parent); filter = eap_method_default_file_chooser_filter_new (FALSE); gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (widget), filter); if (connection && s_8021x) { filename = NULL; if (nm_setting_802_1x_get_ca_cert_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH) { filename = nm_setting_802_1x_get_ca_cert_path (s_8021x); if (filename) gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename); } gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget_ca_not_required_checkbox), !filename && eap_method_ca_cert_ignore_get (parent, connection)); } widget = inner_auth_combo_init (method, connection, s_8021x, secrets_only); inner_auth_combo_changed_cb (widget, (gpointer) method); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_version_combo")); g_assert (widget); gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0); if (s_8021x) { const char *peapver; peapver = nm_setting_802_1x_get_phase1_peapver (s_8021x); if (peapver) { /* Index 0 is "Automatic" */ if (!strcmp (peapver, "0")) gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1); else if (!strcmp (peapver, "1")) gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 2); } } g_signal_connect (G_OBJECT (widget), "changed", (GCallback) wireless_security_changed_cb, ws_parent); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_anon_identity_entry")); if (s_8021x && nm_setting_802_1x_get_anonymous_identity (s_8021x)) gtk_entry_set_text (GTK_ENTRY (widget), nm_setting_802_1x_get_anonymous_identity (s_8021x)); g_signal_connect (G_OBJECT (widget), "changed", (GCallback) wireless_security_changed_cb, ws_parent); if (secrets_only) { widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_anon_identity_label")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_anon_identity_entry")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_ca_cert_label")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_ca_cert_button")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_ca_cert_not_required_checkbox")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_label")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_combo")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_version_label")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_version_combo")); gtk_widget_hide (widget); } return method; } cinnamon-control-center-6.4.1/panels/network/wireless-security/utils.h0000664000175000017500000000312714724311620025175 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2007 - 2015 Red Hat, Inc. */ #include #include gboolean utils_char_is_ascii_print (char character); #define NMA_ERROR (g_quark_from_static_string ("nma-error-quark")) typedef enum { NMA_ERROR_GENERIC } NMAError; typedef gboolean (*UtilsFilterGtkEditableFunc) (char character); gboolean utils_filter_editable_on_insert_text (GtkEditable *editable, const gchar *text, gint length, gint *position, void *user_data, UtilsFilterGtkEditableFunc validate_character, gpointer block_func); extern void widget_set_error (GtkWidget *widget); extern void widget_unset_error (GtkWidget *widget); cinnamon-control-center-6.4.1/panels/network/wireless-security/eap-method.h0000664000175000017500000001174514724311620026065 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2007 - 2014 Red Hat, Inc. */ #ifndef EAP_METHOD_H #define EAP_METHOD_H #include #include typedef struct _EAPMethod EAPMethod; typedef void (*EMAddToSizeGroupFunc) (EAPMethod *method, GtkSizeGroup *group); typedef void (*EMFillConnectionFunc) (EAPMethod *method, NMConnection *connection, NMSettingSecretFlags flags); typedef void (*EMUpdateSecretsFunc) (EAPMethod *method, NMConnection *connection); typedef void (*EMDestroyFunc) (EAPMethod *method); typedef gboolean (*EMValidateFunc) (EAPMethod *method, GError **error); struct _EAPMethod { guint32 refcount; gsize obj_size; GtkBuilder *builder; GtkWidget *ui_widget; const char *default_field; const char *password_flags_name; gboolean phase2; gboolean secrets_only; EMAddToSizeGroupFunc add_to_size_group; EMFillConnectionFunc fill_connection; EMUpdateSecretsFunc update_secrets; EMValidateFunc validate; EMDestroyFunc destroy; }; #define EAP_METHOD(x) ((EAPMethod *) x) GtkWidget *eap_method_get_widget (EAPMethod *method); gboolean eap_method_validate (EAPMethod *method, GError **error); void eap_method_add_to_size_group (EAPMethod *method, GtkSizeGroup *group); void eap_method_fill_connection (EAPMethod *method, NMConnection *connection, NMSettingSecretFlags flags); void eap_method_update_secrets (EAPMethod *method, NMConnection *connection); EAPMethod *eap_method_ref (EAPMethod *method); void eap_method_unref (EAPMethod *method); GType eap_method_get_type (void); /* Below for internal use only */ #include "eap-method-tls.h" #include "eap-method-leap.h" #include "eap-method-fast.h" #include "eap-method-ttls.h" #include "eap-method-peap.h" #include "eap-method-simple.h" EAPMethod *eap_method_init (gsize obj_size, EMValidateFunc validate, EMAddToSizeGroupFunc add_to_size_group, EMFillConnectionFunc fill_connection, EMUpdateSecretsFunc update_secrets, EMDestroyFunc destroy, const char *ui_resource, const char *ui_widget_name, const char *default_field, gboolean phase2); GtkFileFilter * eap_method_default_file_chooser_filter_new (gboolean privkey); gboolean eap_method_is_encrypted_private_key (const char *path); #define TYPE_CLIENT_CERT 0 #define TYPE_CA_CERT 1 #define TYPE_PRIVATE_KEY 2 gboolean eap_method_validate_filepicker (GtkBuilder *builder, const char *name, guint32 item_type, const char *password, NMSetting8021xCKFormat *out_format, GError **error); void eap_method_phase2_update_secrets_helper (EAPMethod *method, NMConnection *connection, const char *combo_name, guint32 column); gboolean eap_method_ca_cert_required (GtkBuilder *builder, const char *id_ca_cert_is_not_required_checkbox, const char *id_ca_cert_chooser); void eap_method_ca_cert_not_required_toggled (GtkBuilder *builder, const char *id_ca_cert_is_not_required_checkbox, const char *id_ca_cert_chooser); void eap_method_ca_cert_ignore_set (EAPMethod *method, NMConnection *connection, const char *filename, gboolean ca_cert_error); gboolean eap_method_ca_cert_ignore_get (EAPMethod *method, NMConnection *connection); void eap_method_ca_cert_ignore_save (NMConnection *connection); void eap_method_ca_cert_ignore_load (NMConnection *connection); #endif /* EAP_METHOD_H */ cinnamon-control-center-6.4.1/panels/network/wireless-security/eap-method-leap.ui0000664000175000017500000001050314724311620027161 0ustar fabiofabio True False False False True False start 3 2 6 6 True False 1 _Username True eap_leap_username_entry GTK_FILL True False 1 _Password True eap_leap_password_entry 1 2 GTK_FILL True True False True 1 2 1 2 Sho_w password True True False True True 1 2 2 3 GTK_FILL True True 1 2 True False False cinnamon-control-center-6.4.1/panels/network/wireless-security/eap-method-simple.h0000664000175000017500000000437614724311620027356 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (C) Copyright 2007 - 2010 Red Hat, Inc. */ #ifndef EAP_METHOD_SIMPLE_H #define EAP_METHOD_SIMPLE_H #include "wireless-security.h" typedef enum { /* NOTE: when updating this table, also update eap_methods[] */ EAP_METHOD_SIMPLE_TYPE_PAP = 0, EAP_METHOD_SIMPLE_TYPE_MSCHAP, EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2, EAP_METHOD_SIMPLE_TYPE_MD5, EAP_METHOD_SIMPLE_TYPE_PWD, EAP_METHOD_SIMPLE_TYPE_CHAP, EAP_METHOD_SIMPLE_TYPE_GTC, /* Boundary value, do not use */ EAP_METHOD_SIMPLE_TYPE_LAST } EAPMethodSimpleType; typedef enum { EAP_METHOD_SIMPLE_FLAG_NONE = 0x00, /* Indicates the EAP method is an inner/phase2 method */ EAP_METHOD_SIMPLE_FLAG_PHASE2 = 0x01, /* Set by TTLS to indicate that inner/phase2 EAP is allowed */ EAP_METHOD_SIMPLE_FLAG_AUTHEAP_ALLOWED = 0x02, /* Set from nm-connection-editor or the GNOME network panel */ EAP_METHOD_SIMPLE_FLAG_IS_EDITOR = 0x04, /* Set to indicate that this request is only for secrets */ EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY = 0x08 } EAPMethodSimpleFlags; typedef struct _EAPMethodSimple EAPMethodSimple; EAPMethodSimple *eap_method_simple_new (WirelessSecurity *ws_parent, NMConnection *connection, EAPMethodSimpleType type, EAPMethodSimpleFlags flags); #endif /* EAP_METHOD_SIMPLE_H */ ././@LongLink0000644000000000000000000000015600000000000011605 Lustar rootrootcinnamon-control-center-6.4.1/panels/network/wireless-security/nm-connection-editor-ui-to-network-panel.patchcinnamon-control-center-6.4.1/panels/network/wireless-security/nm-connection-editor-ui-to-network-pa0000664000175000017500000006513114724311620032765 0ustar fabiofabiodiff --git a/panels/network/wireless-security/eap-method-fast.ui b/panels/network/wireless-security/eap-method-fast.ui index 4b19a66..5307ddb 100644 --- a/panels/network/wireless-security/eap-method-fast.ui +++ b/panels/network/wireless-security/eap-method-fast.ui @@ -46,8 +46,8 @@ True False - 0 - Anony_mous identity: + 1 + Anony_mous identity True eap_fast_anon_identity_entry @@ -72,8 +72,8 @@ True False - 0 - PAC _file: + 1 + PAC _file True eap_fast_pac_file_button @@ -117,8 +117,8 @@ True False - 0 - _Inner authentication: + 1 + _Inner authentication True eap_fast_inner_auth_combo diff --git a/panels/network/wireless-security/eap-method-leap.ui b/panels/network/wireless-security/eap-method-leap.ui index 1d1f23d..d4c0625 100644 --- a/panels/network/wireless-security/eap-method-leap.ui +++ b/panels/network/wireless-security/eap-method-leap.ui @@ -22,8 +22,8 @@ True False - 0 - _Username: + 1 + _Username True eap_leap_username_entry @@ -36,8 +36,8 @@ True False - 0 - _Password: + 1 + _Password True eap_leap_password_entry diff --git a/panels/network/wireless-security/eap-method-peap.ui b/panels/network/wireless-security/eap-method-peap.ui index a97123a..2f8b8cd 100644 --- a/panels/network/wireless-security/eap-method-peap.ui +++ b/panels/network/wireless-security/eap-method-peap.ui @@ -46,8 +46,8 @@ True False - 0 - Anony_mous identity: + 1 + Anony_mous identity True eap_peap_anon_identity_entry @@ -72,8 +72,8 @@ True False - 0 - C_A certificate: + 1 + C_A certificate True eap_peap_ca_cert_button @@ -135,8 +135,8 @@ True False - 0 - _Inner authentication: + 1 + _Inner authentication True eap_peap_inner_auth_combo @@ -172,8 +172,8 @@ True False - 0 - PEAP _version: + 1 + PEAP _version True eap_peap_version_combo diff --git a/panels/network/wireless-security/eap-method-simple.ui b/panels/network/wireless-security/eap-method-simple.ui index b3318e4..7d95d28 100644 --- a/panels/network/wireless-security/eap-method-simple.ui +++ b/panels/network/wireless-security/eap-method-simple.ui @@ -22,8 +22,8 @@ True False - 0 - _Username: + 1 + _Username True eap_simple_username_entry @@ -36,8 +36,8 @@ True False - 0 - _Password: + 1 + _Password True eap_simple_password_entry diff --git a/panels/network/wireless-security/eap-method-tls.ui b/panels/network/wireless-security/eap-method-tls.ui index 5557593..3c6291b 100644 --- a/panels/network/wireless-security/eap-method-tls.ui +++ b/panels/network/wireless-security/eap-method-tls.ui @@ -22,8 +22,8 @@ True False - 0 - I_dentity: + 1 + I_dentity True eap_tls_identity_entry @@ -48,8 +48,8 @@ True False - 0 - _User certificate: + 1 + _User certificate True eap_tls_user_cert_button @@ -64,8 +64,8 @@ True False - 0 - C_A certificate: + 1 + C_A certificate True eap_tls_ca_cert_button @@ -112,8 +112,8 @@ True False - 0 - Private _key: + 1 + Private _key True eap_tls_private_key_button @@ -142,8 +142,8 @@ True False - 0 - _Private key password: + 1 + _Private key password True eap_tls_private_key_password_entry diff --git a/panels/network/wireless-security/eap-method-ttls.ui b/panels/network/wireless-security/eap-method-ttls.ui index ce00c26..70db9ed 100644 --- a/panels/network/wireless-security/eap-method-ttls.ui +++ b/panels/network/wireless-security/eap-method-ttls.ui @@ -29,8 +29,8 @@ True False - 0 - Anony_mous identity: + 1 + Anony_mous identity True eap_ttls_anon_identity_entry @@ -55,8 +55,8 @@ True False - 0 - C_A certificate: + 1 + C_A certificate True eap_ttls_ca_cert_button @@ -103,8 +103,8 @@ True False - 0 - _Inner authentication: + 1 + _Inner authentication True eap_ttls_inner_auth_combo diff --git a/panels/network/wireless-security/ws-dynamic-wep.ui b/panels/network/wireless-security/ws-dynamic-wep.ui index 4bd8520..cf31f12 100644 --- a/panels/network/wireless-security/ws-dynamic-wep.ui +++ b/panels/network/wireless-security/ws-dynamic-wep.ui @@ -35,8 +35,8 @@ True False - 0 - Au_thentication: + 1 + Au_thentication True dynamic_wep_auth_combo diff --git a/panels/network/wireless-security/ws-leap.ui b/panels/network/wireless-security/ws-leap.ui index dc936ad..b4d9bec 100644 --- a/panels/network/wireless-security/ws-leap.ui +++ b/panels/network/wireless-security/ws-leap.ui @@ -22,8 +22,8 @@ True False - 0 - _Username: + 1 + _Username True leap_username_entry @@ -36,8 +36,8 @@ True False - 0 - _Password: + 1 + _Password True leap_password_entry diff --git a/panels/network/wireless-security/ws-wep-key.ui b/panels/network/wireless-security/ws-wep-key.ui index 62b11a5..c0e5f55 100644 --- a/panels/network/wireless-security/ws-wep-key.ui +++ b/panels/network/wireless-security/ws-wep-key.ui @@ -52,8 +52,8 @@ True False - 0 - _Key: + 1 + _Key True wep_key_entry @@ -111,8 +111,8 @@ True False - 0 - Au_thentication: + 1 + Au_thentication True auth_method_combo @@ -148,8 +148,8 @@ True False - 0 - WEP inde_x: + 1 + WEP inde_x True key_index_combo diff --git a/panels/network/wireless-security/ws-wpa-eap.ui b/panels/network/wireless-security/ws-wpa-eap.ui index 2da2148..942af88 100644 --- a/panels/network/wireless-security/ws-wpa-eap.ui +++ b/panels/network/wireless-security/ws-wpa-eap.ui @@ -29,8 +29,8 @@ True False - 0 - Au_thentication: + 1 + Au_thentication True wpa_eap_auth_combo diff --git a/panels/network/wireless-security/ws-wpa-psk.ui b/panels/network/wireless-security/ws-wpa-psk.ui index 4ec6909..b34720a 100644 --- a/panels/network/wireless-security/ws-wpa-psk.ui +++ b/panels/network/wireless-security/ws-wpa-psk.ui @@ -18,8 +18,8 @@ True False - 0 - _Password: + 1 + _Password True wpa_psk_entry @@ -46,8 +46,8 @@ True False - 0 - _Type: + 1 + _Type True wpa_psk_type_combo diff --git a/panels/network/wireless-security/eap-method-fast.ui b/panels/network/wireless-security/eap-method-fast.ui index 5307ddb..36e74c3 100644 --- a/panels/network/wireless-security/eap-method-fast.ui +++ b/panels/network/wireless-security/eap-method-fast.ui @@ -40,7 +40,7 @@ False 5 2 - 12 + 6 6 diff --git a/panels/network/wireless-security/eap-method-leap.ui b/panels/network/wireless-security/eap-method-leap.ui index d4c0625..c4de1dc 100644 --- a/panels/network/wireless-security/eap-method-leap.ui +++ b/panels/network/wireless-security/eap-method-leap.ui @@ -13,7 +13,7 @@ start 3 2 - 12 + 6 6 diff --git a/panels/network/wireless-security/eap-method-peap.ui b/panels/network/wireless-security/eap-method-peap.ui index 2f8b8cd..d16e00a 100644 --- a/panels/network/wireless-security/eap-method-peap.ui +++ b/panels/network/wireless-security/eap-method-peap.ui @@ -40,7 +40,7 @@ False 5 2 - 12 + 6 6 diff --git a/panels/network/wireless-security/eap-method-simple.ui b/panels/network/wireless-security/eap-method-simple.ui index 7d95d28..af00cb9 100644 --- a/panels/network/wireless-security/eap-method-simple.ui +++ b/panels/network/wireless-security/eap-method-simple.ui @@ -13,7 +13,7 @@ start 3 2 - 12 + 6 6 diff --git a/panels/network/wireless-security/eap-method-tls.ui b/panels/network/wireless-security/eap-method-tls.ui index 3c6291b..0079715 100644 --- a/panels/network/wireless-security/eap-method-tls.ui +++ b/panels/network/wireless-security/eap-method-tls.ui @@ -13,7 +13,7 @@ start 6 2 - 12 + 6 6 diff --git a/panels/network/wireless-security/eap-method-ttls.ui b/panels/network/wireless-security/eap-method-ttls.ui index 70db9ed..df942d9 100644 --- a/panels/network/wireless-security/eap-method-ttls.ui +++ b/panels/network/wireless-security/eap-method-ttls.ui @@ -23,7 +23,7 @@ False 4 2 - 12 + 6 6 diff --git a/panels/network/wireless-security/ws-dynamic-wep.ui b/panels/network/wireless-security/ws-dynamic-wep.ui index cf31f12..d6bc12b 100644 --- a/panels/network/wireless-security/ws-dynamic-wep.ui +++ b/panels/network/wireless-security/ws-dynamic-wep.ui @@ -23,7 +23,7 @@ False 3 2 - 12 + 6 6 diff --git a/panels/network/wireless-security/ws-leap.ui b/panels/network/wireless-security/ws-leap.ui index b4d9bec..06cb645 100644 --- a/panels/network/wireless-security/ws-leap.ui +++ b/panels/network/wireless-security/ws-leap.ui @@ -13,7 +13,7 @@ start 3 2 - 12 + 6 6 diff --git a/panels/network/wireless-security/ws-wep-key.ui b/panels/network/wireless-security/ws-wep-key.ui index c0e5f55..a4e14dc 100644 --- a/panels/network/wireless-security/ws-wep-key.ui +++ b/panels/network/wireless-security/ws-wep-key.ui @@ -46,7 +46,7 @@ False 4 2 - 12 + 6 6 diff --git a/panels/network/wireless-security/ws-wpa-eap.ui b/panels/network/wireless-security/ws-wpa-eap.ui index 942af88..5d71936 100644 --- a/panels/network/wireless-security/ws-wpa-eap.ui +++ b/panels/network/wireless-security/ws-wpa-eap.ui @@ -23,7 +23,7 @@ False 2 2 - 12 + 6 6 diff --git a/panels/network/wireless-security/ws-wpa-psk.ui b/panels/network/wireless-security/ws-wpa-psk.ui index b34720a..3c689d3 100644 --- a/panels/network/wireless-security/ws-wpa-psk.ui +++ b/panels/network/wireless-security/ws-wpa-psk.ui @@ -12,7 +12,7 @@ False 3 2 - 12 + 6 6 cinnamon-control-center-6.4.1/panels/network/wireless-security/eap-method-fast.ui0000664000175000017500000001755014724311620027206 0ustar fabiofabio Anonymous Authenticated Both True False False False True False 5 2 6 6 True False 1 Anony_mous identity True eap_fast_anon_identity_entry GTK_FILL True True True 1 2 True False 1 PAC _file True eap_fast_pac_file_button 2 3 GTK_FILL True False 1 2 2 3 GTK_FILL GTK_FILL True False 2 4 5 GTK_FILL True False 1 _Inner authentication True eap_fast_inner_auth_combo 3 4 GTK_FILL True False model8 0 1 2 3 4 GTK_FILL GTK_FILL Allow automatic PAC pro_visioning True True False True True 1 2 GTK_FILL True False model9 0 1 2 1 2 GTK_FILL GTK_FILL True False False ././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrootcinnamon-control-center-6.4.1/panels/network/wireless-security/nm-connection-editor-to-network-panel.patchcinnamon-control-center-6.4.1/panels/network/wireless-security/nm-connection-editor-to-network-panel0000664000175000017500000003460514724311620033053 0ustar fabiofabiodiff --git a/panels/network/wireless-security/eap-method-fast.c b/panels/network/wireless-security/eap-method-fast.c index 69b8a86..be5578d 100644 --- a/panels/network/wireless-security/eap-method-fast.c +++ b/panels/network/wireless-security/eap-method-fast.c @@ -351,7 +351,7 @@ eap_method_fast_new (WirelessSecurity *ws_parent, fill_connection, update_secrets, destroy, - UIDIR "/eap-method-fast.ui", + "/org/cinnamon/control-center/network/eap-method-fast.ui", "eap_fast_notebook", "eap_fast_anon_identity_entry", FALSE); diff --git a/panels/network/wireless-security/eap-method-leap.c b/panels/network/wireless-security/eap-method-leap.c index 5fbdd86..6163468 100644 --- a/panels/network/wireless-security/eap-method-leap.c +++ b/panels/network/wireless-security/eap-method-leap.c @@ -204,7 +204,7 @@ eap_method_leap_new (WirelessSecurity *ws_parent, fill_connection, update_secrets, destroy, - UIDIR "/eap-method-leap.ui", + "/org/cinnamon/control-center/network/eap-method-leap.ui", "eap_leap_notebook", "eap_leap_username_entry", FALSE); diff --git a/panels/network/wireless-security/eap-method-peap.c b/panels/network/wireless-security/eap-method-peap.c index 6462ef2..7f87541 100644 --- a/panels/network/wireless-security/eap-method-peap.c +++ b/panels/network/wireless-security/eap-method-peap.c @@ -349,7 +349,7 @@ eap_method_peap_new (WirelessSecurity *ws_parent, fill_connection, update_secrets, destroy, - UIDIR "/eap-method-peap.ui", + "/org/cinnamon/control-center/network/eap-method-peap.ui", "eap_peap_notebook", "eap_peap_anon_identity_entry", FALSE); diff --git a/panels/network/wireless-security/eap-method-simple.c b/panels/network/wireless-security/eap-method-simple.c index 0f72029..f9fd473 100644 --- a/panels/network/wireless-security/eap-method-simple.c +++ b/panels/network/wireless-security/eap-method-simple.c @@ -307,7 +307,7 @@ eap_method_simple_new (WirelessSecurity *ws_parent, fill_connection, update_secrets, destroy, - UIDIR "/eap-method-simple.ui", + "/org/cinnamon/control-center/network/eap-method-simple.ui", "eap_simple_notebook", "eap_simple_username_entry", flags & EAP_METHOD_SIMPLE_FLAG_PHASE2); diff --git a/panels/network/wireless-security/eap-method-tls.c b/panels/network/wireless-security/eap-method-tls.c index 8f33d83..587c399 100644 --- a/panels/network/wireless-security/eap-method-tls.c +++ b/panels/network/wireless-security/eap-method-tls.c @@ -453,7 +453,7 @@ eap_method_tls_new (WirelessSecurity *ws_parent, fill_connection, update_secrets, NULL, - UIDIR "/eap-method-tls.ui", + "/org/cinnamon/control-center/network/eap-method-tls.ui", "eap_tls_notebook", "eap_tls_identity_entry", phase2); diff --git a/panels/network/wireless-security/eap-method-ttls.c b/panels/network/wireless-security/eap-method-ttls.c index 789f0fa..ef02529 100644 --- a/panels/network/wireless-security/eap-method-ttls.c +++ b/panels/network/wireless-security/eap-method-ttls.c @@ -380,7 +380,7 @@ eap_method_ttls_new (WirelessSecurity *ws_parent, fill_connection, update_secrets, destroy, - UIDIR "/eap-method-ttls.ui", + "/org/cinnamon/control-center/network/eap-method-ttls.ui", "eap_ttls_notebook", "eap_ttls_anon_identity_entry", FALSE); diff --git a/panels/network/wireless-security/eap-method.c b/panels/network/wireless-security/eap-method.c index 90efea1..6ec4849 100644 --- a/panels/network/wireless-security/eap-method.c +++ b/panels/network/wireless-security/eap-method.c @@ -34,7 +34,19 @@ #include "utils.h" #include "helpers.h" -G_DEFINE_BOXED_TYPE (EAPMethod, eap_method, eap_method_ref, eap_method_unref) +GType +eap_method_get_type (void) +{ + static GType type_id = 0; + + if (!type_id) { + type_id = g_boxed_type_register_static ("CcEAPMethod", + (GBoxedCopyFunc) eap_method_ref, + (GBoxedFreeFunc) eap_method_unref); + } + + return type_id; +} GtkWidget * eap_method_get_widget (EAPMethod *method) @@ -129,7 +141,7 @@ eap_method_init (gsize obj_size, EMFillConnectionFunc fill_connection, EMUpdateSecretsFunc update_secrets, EMDestroyFunc destroy, - const char *ui_file, + const char *ui_resource, const char *ui_widget_name, const char *default_field, gboolean phase2) @@ -138,7 +150,7 @@ eap_method_init (gsize obj_size, GError *error = NULL; g_return_val_if_fail (obj_size > 0, NULL); - g_return_val_if_fail (ui_file != NULL, NULL); + g_return_val_if_fail (ui_resource != NULL, NULL); g_return_val_if_fail (ui_widget_name != NULL, NULL); method = g_slice_alloc0 (obj_size); @@ -154,9 +166,9 @@ eap_method_init (gsize obj_size, method->phase2 = phase2; method->builder = gtk_builder_new (); - if (!gtk_builder_add_from_file (method->builder, ui_file, &error)) { + if (!gtk_builder_add_from_resource (method->builder, ui_resource, &error)) { g_warning ("Couldn't load UI builder file %s: %s", - ui_file, error->message); + ui_resource, error->message); eap_method_unref (method); return NULL; } @@ -164,7 +176,7 @@ eap_method_init (gsize obj_size, method->ui_widget = GTK_WIDGET (gtk_builder_get_object (method->builder, ui_widget_name)); if (!method->ui_widget) { g_warning ("Couldn't load UI widget '%s' from UI file %s", - ui_widget_name, ui_file); + ui_widget_name, ui_resource); eap_method_unref (method); return NULL; } diff --git a/panels/network/wireless-security/eap-method.h b/panels/network/wireless-security/eap-method.h index 84c1c78..de287e3 100644 --- a/panels/network/wireless-security/eap-method.h +++ b/panels/network/wireless-security/eap-method.h @@ -99,7 +99,7 @@ EAPMethod *eap_method_init (gsize obj_size, EMFillConnectionFunc fill_connection, EMUpdateSecretsFunc update_secrets, EMDestroyFunc destroy, - const char *ui_file, + const char *ui_resource, const char *ui_widget_name, const char *default_field, gboolean phase2); diff --git a/panels/network/wireless-security/wireless-security.c b/panels/network/wireless-security/wireless-security.c index 23b8a27..bd233b0 100644 --- a/panels/network/wireless-security/wireless-security.c +++ b/panels/network/wireless-security/wireless-security.c @@ -25,10 +25,25 @@ #include #include "wireless-security.h" +#include "wireless-security-resources.h" #include "eap-method.h" #include "utils.h" -G_DEFINE_BOXED_TYPE (WirelessSecurity, wireless_security, wireless_security_ref, wireless_security_unref) +GType +wireless_security_get_type (void) +{ + static GType type_id = 0; + + if (!type_id) { + g_resources_register (wireless_security_get_resource ()); + + type_id = g_boxed_type_register_static ("CcWirelessSecurity", + (GBoxedCopyFunc) wireless_security_ref, + (GBoxedFreeFunc) wireless_security_unref); + } + + return type_id; +} GtkWidget * wireless_security_get_widget (WirelessSecurity *sec) @@ -146,7 +161,7 @@ wireless_security_init (gsize obj_size, WSFillConnectionFunc fill_connection, WSUpdateSecretsFunc update_secrets, WSDestroyFunc destroy, - const char *ui_file, + const char *ui_resource, const char *ui_widget_name, const char *default_field) { @@ -154,7 +169,7 @@ wireless_security_init (gsize obj_size, GError *error = NULL; g_return_val_if_fail (obj_size > 0, NULL); - g_return_val_if_fail (ui_file != NULL, NULL); + g_return_val_if_fail (ui_resource != NULL, NULL); g_return_val_if_fail (ui_widget_name != NULL, NULL); sec = g_slice_alloc0 (obj_size); @@ -170,9 +185,9 @@ wireless_security_init (gsize obj_size, sec->default_field = default_field; sec->builder = gtk_builder_new (); - if (!gtk_builder_add_from_file (sec->builder, ui_file, &error)) { + if (!gtk_builder_add_from_resource (sec->builder, ui_resource, &error)) { g_warning ("Couldn't load UI builder file %s: %s", - ui_file, error->message); + ui_resource, error->message); g_error_free (error); wireless_security_unref (sec); return NULL; @@ -181,7 +196,7 @@ wireless_security_init (gsize obj_size, sec->ui_widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, ui_widget_name)); if (!sec->ui_widget) { g_warning ("Couldn't load UI widget '%s' from UI file %s", - ui_widget_name, ui_file); + ui_widget_name, ui_resource); wireless_security_unref (sec); return NULL; } diff --git a/panels/network/wireless-security/wireless-security.h b/panels/network/wireless-security/wireless-security.h index e9bcf63..3d56fa3 100644 --- a/panels/network/wireless-security/wireless-security.h +++ b/panels/network/wireless-security/wireless-security.h @@ -23,6 +23,8 @@ #ifndef WIRELESS_SECURITY_H #define WIRELESS_SECURITY_H +#define LIBNM_GLIB_BUILD + #include #include @@ -118,7 +120,7 @@ WirelessSecurity *wireless_security_init (gsize obj_size, WSFillConnectionFunc fill_connection, WSUpdateSecretsFunc update_secrets, WSDestroyFunc destroy, - const char *ui_file, + const char *ui_resource, const char *ui_widget_name, const char *default_field); diff --git a/panels/network/wireless-security/ws-dynamic-wep.c b/panels/network/wireless-security/ws-dynamic-wep.c index db55119..0192d24 100644 --- a/panels/network/wireless-security/ws-dynamic-wep.c +++ b/panels/network/wireless-security/ws-dynamic-wep.c @@ -109,7 +109,7 @@ ws_dynamic_wep_new (NMConnection *connection, fill_connection, update_secrets, destroy, - UIDIR "/ws-dynamic-wep.ui", + "/org/cinnamon/control-center/network/ws-dynamic-wep.ui", "dynamic_wep_notebook", NULL); if (!parent) diff --git a/panels/network/wireless-security/ws-leap.c b/panels/network/wireless-security/ws-leap.c index 2b8b615..3a0f60c 100644 --- a/panels/network/wireless-security/ws-leap.c +++ b/panels/network/wireless-security/ws-leap.c @@ -155,7 +155,7 @@ ws_leap_new (NMConnection *connection, gboolean secrets_only) fill_connection, update_secrets, NULL, - UIDIR "/ws-leap.ui", + "/org/cinnamon/control-center/network/ws-leap.ui", "leap_notebook", "leap_username_entry"); if (!parent) diff --git a/panels/network/wireless-security/ws-wep-key.c b/panels/network/wireless-security/ws-wep-key.c index 045ac4b..cd7dbac 100644 --- a/panels/network/wireless-security/ws-wep-key.c +++ b/panels/network/wireless-security/ws-wep-key.c @@ -264,7 +264,7 @@ ws_wep_key_new (NMConnection *connection, fill_connection, update_secrets, destroy, - UIDIR "/ws-wep-key.ui", + "/org/cinnamon/control-center/network/ws-wep-key.ui", "wep_key_notebook", "wep_key_entry"); if (!parent) diff --git a/panels/network/wireless-security/ws-wpa-eap.c b/panels/network/wireless-security/ws-wpa-eap.c index d83218d..7db42df 100644 --- a/panels/network/wireless-security/ws-wpa-eap.c +++ b/panels/network/wireless-security/ws-wpa-eap.c @@ -110,7 +110,7 @@ ws_wpa_eap_new (NMConnection *connection, fill_connection, update_secrets, destroy, - UIDIR "/ws-wpa-eap.ui", + "/org/cinnamon/control-center/network/ws-wpa-eap.ui", "wpa_eap_notebook", NULL); if (!parent) diff --git a/panels/network/wireless-security/ws-wpa-psk.c b/panels/network/wireless-security/ws-wpa-psk.c index e56f348..4be28f2 100644 --- a/panels/network/wireless-security/ws-wpa-psk.c +++ b/panels/network/wireless-security/ws-wpa-psk.c @@ -182,7 +182,7 @@ ws_wpa_psk_new (NMConnection *connection, gboolean secrets_only) fill_connection, update_secrets, NULL, - UIDIR "/ws-wpa-psk.ui", + "/org/cinnamon/control-center/network/ws-wpa-psk.ui", "wpa_psk_notebook", "wpa_psk_entry"); if (!parent) cinnamon-control-center-6.4.1/panels/network/wireless-security/eap-method-simple.ui0000664000175000017500000001150314724311620027532 0ustar fabiofabio True False False False True False start 3 2 6 6 True False 1 _Username True eap_simple_username_entry GTK_FILL True False 1 _Password True eap_simple_password_entry 1 2 GTK_FILL True True False True 1 2 1 2 True True True 1 2 True False Sho_w password True True False True True True True 0 1 2 2 3 True False False cinnamon-control-center-6.4.1/panels/network/wireless-security/ws-dynamic-wep.ui0000664000175000017500000000642414724311620027072 0ustar fabiofabio True False False False True False 3 2 6 6 True False 1 Au_thentication True dynamic_wep_auth_combo GTK_FILL True False model7 0 1 2 GTK_FILL True False 6 2 1 2 GTK_FILL True False False cinnamon-control-center-6.4.1/panels/network/wireless-security/ws-wpa-eap.ui0000664000175000017500000000614214724311620026204 0ustar fabiofabio True False False False True False 2 2 6 6 True False 1 Au_thentication True wpa_eap_auth_combo GTK_FILL True False model5 0 1 2 GTK_FILL True False 2 1 2 GTK_FILL True False False cinnamon-control-center-6.4.1/panels/network/wireless-security/ws-leap.c0000664000175000017500000001632314724311620025402 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2007 - 2014 Red Hat, Inc. */ #include "nm-default.h" #include #include "wireless-security.h" #include "helpers.h" #include "nma-ui-utils.h" #include "utils.h" struct _WirelessSecurityLEAP { WirelessSecurity parent; gboolean editing_connection; const char *password_flags_name; }; static void show_toggled_cb (GtkCheckButton *button, WirelessSecurity *sec) { GtkWidget *widget; gboolean visible; widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, "leap_password_entry")); g_assert (widget); visible = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); gtk_entry_set_visibility (GTK_ENTRY (widget), visible); } static gboolean validate (WirelessSecurity *parent, GError **error) { GtkWidget *entry; const char *text; gboolean ret = TRUE; entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_username_entry")); g_assert (entry); text = gtk_entry_get_text (GTK_ENTRY (entry)); if (!text || !strlen (text)) { widget_set_error (entry); g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing leap-username")); ret = FALSE; } else widget_unset_error (entry); entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_password_entry")); g_assert (entry); text = gtk_entry_get_text (GTK_ENTRY (entry)); if (!text || !strlen (text)) { widget_set_error (entry); if (ret) { g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing leap-password")); ret = FALSE; } } else widget_unset_error (entry); return ret; } static void add_to_size_group (WirelessSecurity *parent, GtkSizeGroup *group) { GtkWidget *widget; widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_username_label")); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_password_label")); gtk_size_group_add_widget (group, widget); } static void fill_connection (WirelessSecurity *parent, NMConnection *connection) { WirelessSecurityLEAP *sec = (WirelessSecurityLEAP *) parent; NMSettingWirelessSecurity *s_wireless_sec; NMSettingSecretFlags secret_flags; GtkWidget *widget, *passwd_entry; const char *leap_password = NULL, *leap_username = NULL; /* Blow away the old security setting by adding a clear one */ s_wireless_sec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); nm_connection_add_setting (connection, (NMSetting *) s_wireless_sec); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_username_entry")); leap_username = gtk_entry_get_text (GTK_ENTRY (widget)); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_password_entry")); passwd_entry = widget; leap_password = gtk_entry_get_text (GTK_ENTRY (widget)); g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, leap_username, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, leap_password, NULL); /* Save LEAP_PASSWORD_FLAGS to the connection */ secret_flags = nma_utils_menu_to_secret_flags (passwd_entry); nm_setting_set_secret_flags (NM_SETTING (s_wireless_sec), sec->password_flags_name, secret_flags, NULL); /* Update secret flags and popup when editing the connection */ if (sec->editing_connection) nma_utils_update_password_storage (passwd_entry, secret_flags, NM_SETTING (s_wireless_sec), sec->password_flags_name); } static void update_secrets (WirelessSecurity *parent, NMConnection *connection) { helper_fill_secret_entry (connection, parent->builder, "leap_password_entry", NM_TYPE_SETTING_WIRELESS_SECURITY, (HelperSecretFunc) nm_setting_wireless_security_get_leap_password); } WirelessSecurityLEAP * ws_leap_new (NMConnection *connection, gboolean secrets_only) { WirelessSecurity *parent; WirelessSecurityLEAP *sec; GtkWidget *widget; NMSettingWirelessSecurity *wsec = NULL; parent = wireless_security_init (sizeof (WirelessSecurityLEAP), validate, add_to_size_group, fill_connection, update_secrets, NULL, "/org/cinnamon/control-center/network/ws-leap.ui", "leap_notebook", "leap_username_entry"); if (!parent) return NULL; if (connection) { wsec = nm_connection_get_setting_wireless_security (connection); if (wsec) { const char *auth_alg; /* Ignore if wireless security doesn't specify LEAP */ auth_alg = nm_setting_wireless_security_get_auth_alg (wsec); if (!auth_alg || strcmp (auth_alg, "leap")) wsec = NULL; } } parent->adhoc_compatible = FALSE; parent->hotspot_compatible = FALSE; sec = (WirelessSecurityLEAP *) parent; sec->editing_connection = secrets_only ? FALSE : TRUE; sec->password_flags_name = NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD; widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_password_entry")); g_assert (widget); g_signal_connect (G_OBJECT (widget), "changed", (GCallback) wireless_security_changed_cb, sec); /* Create password-storage popup menu for password entry under entry's secondary icon */ nma_utils_setup_password_storage (widget, 0, (NMSetting *) wsec, sec->password_flags_name, FALSE, secrets_only); if (wsec) update_secrets (WIRELESS_SECURITY (sec), connection); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_username_entry")); g_assert (widget); g_signal_connect (G_OBJECT (widget), "changed", (GCallback) wireless_security_changed_cb, sec); if (wsec) gtk_entry_set_text (GTK_ENTRY (widget), nm_setting_wireless_security_get_leap_username (wsec)); if (secrets_only) gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_leap")); g_assert (widget); g_signal_connect (G_OBJECT (widget), "toggled", (GCallback) show_toggled_cb, sec); return sec; } cinnamon-control-center-6.4.1/panels/network/wireless-security/ws-wpa-psk.c0000664000175000017500000001727514724311620026052 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2007 - 2014 Red Hat, Inc. */ #include "nm-default.h" #include #include #include "wireless-security.h" #include "helpers.h" #include "nma-ui-utils.h" #include "utils.h" #define WPA_PMK_LEN 32 struct _WirelessSecurityWPAPSK { WirelessSecurity parent; gboolean editing_connection; const char *password_flags_name; }; static void show_toggled_cb (GtkCheckButton *button, WirelessSecurity *sec) { GtkWidget *widget; gboolean visible; widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, "wpa_psk_entry")); g_assert (widget); visible = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); gtk_entry_set_visibility (GTK_ENTRY (widget), visible); } static gboolean validate (WirelessSecurity *parent, GError **error) { GtkWidget *entry; const char *key; gsize len; int i; entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wpa_psk_entry")); g_assert (entry); key = gtk_entry_get_text (GTK_ENTRY (entry)); len = key ? strlen (key) : 0; if ((len < 8) || (len > 64)) { widget_set_error (entry); g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid wpa-psk: invalid key-length %zu. Must be [8,63] bytes or 64 hex digits"), len); return FALSE; } if (len == 64) { /* Hex PSK */ for (i = 0; i < len; i++) { if (!isxdigit (key[i])) { widget_set_error (entry); g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid wpa-psk: cannot interpret key with 64 bytes as hex")); return FALSE; } } } widget_unset_error (entry); /* passphrase can be between 8 and 63 characters inclusive */ return TRUE; } static void add_to_size_group (WirelessSecurity *parent, GtkSizeGroup *group) { GtkWidget *widget; widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wpa_psk_type_label")); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wpa_psk_label")); gtk_size_group_add_widget (group, widget); } static void fill_connection (WirelessSecurity *parent, NMConnection *connection) { WirelessSecurityWPAPSK *wpa_psk = (WirelessSecurityWPAPSK *) parent; GtkWidget *widget, *passwd_entry; const char *key; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wireless_sec; NMSettingSecretFlags secret_flags; const char *mode; gboolean is_adhoc = FALSE; s_wireless = nm_connection_get_setting_wireless (connection); g_assert (s_wireless); mode = nm_setting_wireless_get_mode (s_wireless); if (mode && !strcmp (mode, "adhoc")) is_adhoc = TRUE; /* Blow away the old security setting by adding a clear one */ s_wireless_sec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); nm_connection_add_setting (connection, (NMSetting *) s_wireless_sec); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wpa_psk_entry")); passwd_entry = widget; key = gtk_entry_get_text (GTK_ENTRY (widget)); g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_PSK, key, NULL); /* Save PSK_FLAGS to the connection */ secret_flags = nma_utils_menu_to_secret_flags (passwd_entry); nm_setting_set_secret_flags (NM_SETTING (s_wireless_sec), NM_SETTING_WIRELESS_SECURITY_PSK, secret_flags, NULL); /* Update secret flags and popup when editing the connection */ if (wpa_psk->editing_connection) nma_utils_update_password_storage (passwd_entry, secret_flags, NM_SETTING (s_wireless_sec), wpa_psk->password_flags_name); wireless_security_clear_ciphers (connection); if (is_adhoc) { /* Ad-Hoc settings as specified by the supplicant */ g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-none", NULL); nm_setting_wireless_security_add_proto (s_wireless_sec, "wpa"); nm_setting_wireless_security_add_pairwise (s_wireless_sec, "none"); /* Ad-hoc can only have _one_ group cipher... default to TKIP to be more * compatible for now. Maybe we'll support selecting CCMP later. */ nm_setting_wireless_security_add_group (s_wireless_sec, "tkip"); } else { g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", NULL); /* Just leave ciphers and protocol empty, the supplicant will * figure that out magically based on the AP IEs and card capabilities. */ } } static void update_secrets (WirelessSecurity *parent, NMConnection *connection) { helper_fill_secret_entry (connection, parent->builder, "wpa_psk_entry", NM_TYPE_SETTING_WIRELESS_SECURITY, (HelperSecretFunc) nm_setting_wireless_security_get_psk); } WirelessSecurityWPAPSK * ws_wpa_psk_new (NMConnection *connection, gboolean secrets_only) { WirelessSecurity *parent; WirelessSecurityWPAPSK *sec; NMSetting *setting = NULL; GtkWidget *widget; parent = wireless_security_init (sizeof (WirelessSecurityWPAPSK), validate, add_to_size_group, fill_connection, update_secrets, NULL, "/org/cinnamon/control-center/network/ws-wpa-psk.ui", "wpa_psk_notebook", "wpa_psk_entry"); if (!parent) return NULL; parent->adhoc_compatible = FALSE; sec = (WirelessSecurityWPAPSK *) parent; sec->editing_connection = secrets_only ? FALSE : TRUE; sec->password_flags_name = NM_SETTING_WIRELESS_SECURITY_PSK; widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wpa_psk_entry")); g_assert (widget); g_signal_connect (G_OBJECT (widget), "changed", (GCallback) wireless_security_changed_cb, sec); gtk_entry_set_width_chars (GTK_ENTRY (widget), 28); /* Create password-storage popup menu for password entry under entry's secondary icon */ if (connection) setting = (NMSetting *) nm_connection_get_setting_wireless_security (connection); nma_utils_setup_password_storage (widget, 0, setting, sec->password_flags_name, FALSE, secrets_only); /* Fill secrets, if any */ if (connection) update_secrets (WIRELESS_SECURITY (sec), connection); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_wpa")); g_assert (widget); g_signal_connect (G_OBJECT (widget), "toggled", (GCallback) show_toggled_cb, sec); /* Hide WPA/RSN for now since this can be autodetected by NM and the * supplicant when connecting to the AP. */ widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wpa_psk_type_combo")); g_assert (widget); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wpa_psk_type_label")); g_assert (widget); gtk_widget_hide (widget); return sec; } cinnamon-control-center-6.4.1/panels/network/wireless-security/utils.c0000664000175000017500000000500714724311620025167 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2007 - 2015 Red Hat, Inc. */ #include #include #include "nm-default.h" #include "utils.h" /** * Filters the characters from a text that was just input into GtkEditable. * Returns FALSE, if after filtering no characters were left. TRUE means, * that valid characters were added and the content of the GtkEditable changed. **/ gboolean utils_filter_editable_on_insert_text (GtkEditable *editable, const gchar *text, gint length, gint *position, void *user_data, UtilsFilterGtkEditableFunc validate_character, gpointer block_func) { int i, count = 0; gchar *result = g_new (gchar, length+1); for (i = 0; i < length; i++) { if (validate_character (text[i])) result[count++] = text[i]; } result[count] = 0; if (count > 0) { if (block_func) { g_signal_handlers_block_by_func (G_OBJECT (editable), G_CALLBACK (block_func), user_data); } gtk_editable_insert_text (editable, result, count, position); if (block_func) { g_signal_handlers_unblock_by_func (G_OBJECT (editable), G_CALLBACK (block_func), user_data); } } g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text"); g_free (result); return count > 0; } gboolean utils_char_is_ascii_print (char character) { return g_ascii_isprint (character); } cinnamon-control-center-6.4.1/panels/network/wireless-security/ws-wep-key.h0000664000175000017500000000246114724311620026045 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2007 - 2014 Red Hat, Inc. */ #ifndef WS_WEP_KEY_H #define WS_WEP_KEY_H typedef struct _WirelessSecurityWEPKey WirelessSecurityWEPKey; WirelessSecurityWEPKey *ws_wep_key_new (NMConnection *connection, NMWepKeyType type, gboolean adhoc_create, gboolean secrets_only); #endif /* WS_WEP_KEY_H */ cinnamon-control-center-6.4.1/panels/network/wireless-security/update_from_nma.sh0000775000175000017500000000120314724311620027354 0ustar fabiofabio#!/bin/bash WIRELESS_SECURITY_DIR=${top_srcdir}/../network-manager-applet/src/wireless-security FILES="${NM_APPLET_SOURCES}" \ DIR="${WIRELESS_SECURITY_DIR}" \ ${top_srcdir}/update-from-gsd.sh patch -p4 < ${srcdir}/nm-connection-editor-to-network-panel.patch git add ${NM_APPLET_SOURCES} git commit -m "network: Update wireless-security from network-manager-applet" FILES="${resource_files}" \ DIR="${WIRELESS_SECURITY_DIR}" \ ${top_srcdir}/update-from-gsd.sh patch -p4 < $(srcdir)/nm-connection-editor-ui-to-network-panel.patch git add ${resource_files} git commit -m "network: Update wireless-security UI from network-manager-applet" cinnamon-control-center-6.4.1/panels/network/wireless-security/wireless-security.c0000664000175000017500000004376414724311620027545 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2007 - 2014 Red Hat, Inc. */ #include "nm-default.h" #include #include "wireless-security.h" #include "wireless-security-resources.h" #include "eap-method.h" #include "utils.h" GType wireless_security_get_type (void) { static GType type_id = 0; if (!type_id) { g_resources_register (wireless_security_get_resource ()); type_id = g_boxed_type_register_static ("CcWirelessSecurity", (GBoxedCopyFunc) wireless_security_ref, (GBoxedFreeFunc) wireless_security_unref); } return type_id; } GtkWidget * wireless_security_get_widget (WirelessSecurity *sec) { g_return_val_if_fail (sec != NULL, NULL); return sec->ui_widget; } void wireless_security_set_changed_notify (WirelessSecurity *sec, WSChangedFunc func, gpointer user_data) { g_return_if_fail (sec != NULL); sec->changed_notify = func; sec->changed_notify_data = user_data; } void wireless_security_changed_cb (GtkWidget *ignored, gpointer user_data) { WirelessSecurity *sec = WIRELESS_SECURITY (user_data); if (sec->changed_notify) (*(sec->changed_notify)) (sec, sec->changed_notify_data); } gboolean wireless_security_validate (WirelessSecurity *sec, GError **error) { gboolean result; g_return_val_if_fail (sec != NULL, FALSE); g_return_val_if_fail (!error || !*error, FALSE); g_assert (sec->validate); result = (*(sec->validate)) (sec, error); if (!result && error && !*error) g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("Unknown error validating 802.1x security")); return result; } void wireless_security_add_to_size_group (WirelessSecurity *sec, GtkSizeGroup *group) { g_return_if_fail (sec != NULL); g_return_if_fail (group != NULL); g_assert (sec->add_to_size_group); return (*(sec->add_to_size_group)) (sec, group); } void wireless_security_fill_connection (WirelessSecurity *sec, NMConnection *connection) { g_return_if_fail (sec != NULL); g_return_if_fail (connection != NULL); g_assert (sec->fill_connection); return (*(sec->fill_connection)) (sec, connection); } void wireless_security_update_secrets (WirelessSecurity *sec, NMConnection *connection) { g_return_if_fail (sec != NULL); g_return_if_fail (connection != NULL); if (sec->update_secrets) sec->update_secrets (sec, connection); } WirelessSecurity * wireless_security_ref (WirelessSecurity *sec) { g_return_val_if_fail (sec != NULL, NULL); g_return_val_if_fail (sec->refcount > 0, NULL); sec->refcount++; return sec; } void wireless_security_unref (WirelessSecurity *sec) { g_return_if_fail (sec != NULL); g_return_if_fail (sec->refcount > 0); sec->refcount--; if (sec->refcount == 0) { if (sec->destroy) sec->destroy (sec); g_free (sec->username); if (sec->password) { memset (sec->password, 0, strlen (sec->password)); g_free (sec->password); } if (sec->builder) g_object_unref (sec->builder); if (sec->ui_widget) g_object_unref (sec->ui_widget); g_slice_free1 (sec->obj_size, sec); } } WirelessSecurity * wireless_security_init (gsize obj_size, WSValidateFunc validate, WSAddToSizeGroupFunc add_to_size_group, WSFillConnectionFunc fill_connection, WSUpdateSecretsFunc update_secrets, WSDestroyFunc destroy, const char *ui_resource, const char *ui_widget_name, const char *default_field) { WirelessSecurity *sec; GError *error = NULL; g_return_val_if_fail (obj_size > 0, NULL); g_return_val_if_fail (ui_resource != NULL, NULL); g_return_val_if_fail (ui_widget_name != NULL, NULL); sec = g_slice_alloc0 (obj_size); g_assert (sec); sec->refcount = 1; sec->obj_size = obj_size; sec->validate = validate; sec->add_to_size_group = add_to_size_group; sec->fill_connection = fill_connection; sec->update_secrets = update_secrets; sec->default_field = default_field; sec->builder = gtk_builder_new (); if (!gtk_builder_add_from_resource (sec->builder, ui_resource, &error)) { g_warning ("Couldn't load UI builder file %s: %s", ui_resource, error->message); g_error_free (error); wireless_security_unref (sec); return NULL; } sec->ui_widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, ui_widget_name)); if (!sec->ui_widget) { g_warning ("Couldn't load UI widget '%s' from UI file %s", ui_widget_name, ui_resource); wireless_security_unref (sec); return NULL; } g_object_ref_sink (sec->ui_widget); sec->destroy = destroy; sec->adhoc_compatible = TRUE; sec->hotspot_compatible = TRUE; return sec; } gboolean wireless_security_adhoc_compatible (WirelessSecurity *sec) { g_return_val_if_fail (sec != NULL, FALSE); return sec->adhoc_compatible; } gboolean wireless_security_hotspot_compatible (WirelessSecurity *sec) { g_return_val_if_fail (sec != NULL, FALSE); return sec->hotspot_compatible; } void wireless_security_set_userpass (WirelessSecurity *sec, const char *user, const char *password, gboolean always_ask, gboolean show_password) { g_free (sec->username); sec->username = g_strdup (user); if (sec->password) { memset (sec->password, 0, strlen (sec->password)); g_free (sec->password); } sec->password = g_strdup (password); if (always_ask != (gboolean) -1) sec->always_ask = always_ask; sec->show_password = show_password; } void wireless_security_set_userpass_802_1x (WirelessSecurity *sec, NMConnection *connection) { const char *user = NULL, *password = NULL; gboolean always_ask = FALSE, show_password = FALSE; NMSetting8021x *setting; NMSettingSecretFlags flags; if (!connection) goto set; setting = nm_connection_get_setting_802_1x (connection); if (!setting) goto set; user = nm_setting_802_1x_get_identity (setting); password = nm_setting_802_1x_get_password (setting); if (nm_setting_get_secret_flags (NM_SETTING (setting), NM_SETTING_802_1X_PASSWORD, &flags, NULL)) always_ask = !!(flags & NM_SETTING_SECRET_FLAG_NOT_SAVED); set: wireless_security_set_userpass (sec, user, password, always_ask, show_password); } void wireless_security_clear_ciphers (NMConnection *connection) { NMSettingWirelessSecurity *s_wireless_sec; g_return_if_fail (connection != NULL); s_wireless_sec = nm_connection_get_setting_wireless_security (connection); g_assert (s_wireless_sec); nm_setting_wireless_security_clear_protos (s_wireless_sec); nm_setting_wireless_security_clear_pairwise (s_wireless_sec); nm_setting_wireless_security_clear_groups (s_wireless_sec); } void ws_802_1x_add_to_size_group (WirelessSecurity *sec, GtkSizeGroup *size_group, const char *label_name, const char *combo_name) { GtkWidget *widget; GtkTreeModel *model; GtkTreeIter iter; EAPMethod *eap; widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, label_name)); g_assert (widget); gtk_size_group_add_widget (size_group, widget); widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, combo_name)); g_assert (widget); model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); gtk_tree_model_get (model, &iter, AUTH_METHOD_COLUMN, &eap, -1); g_assert (eap); eap_method_add_to_size_group (eap, size_group); eap_method_unref (eap); } gboolean ws_802_1x_validate (WirelessSecurity *sec, const char *combo_name, GError **error) { GtkWidget *widget; GtkTreeModel *model; GtkTreeIter iter; EAPMethod *eap = NULL; gboolean valid = FALSE; widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, combo_name)); g_assert (widget); model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); gtk_tree_model_get (model, &iter, AUTH_METHOD_COLUMN, &eap, -1); g_assert (eap); valid = eap_method_validate (eap, error); eap_method_unref (eap); return valid; } void ws_802_1x_auth_combo_changed (GtkWidget *combo, WirelessSecurity *sec, const char *vbox_name, GtkSizeGroup *size_group) { GtkWidget *vbox; EAPMethod *eap = NULL; GList *elt, *children; GtkTreeModel *model; GtkTreeIter iter; GtkWidget *eap_widget; GtkWidget *eap_default_widget = NULL; vbox = GTK_WIDGET (gtk_builder_get_object (sec->builder, vbox_name)); g_assert (vbox); /* Remove any previous wireless security widgets */ children = gtk_container_get_children (GTK_CONTAINER (vbox)); for (elt = children; elt; elt = g_list_next (elt)) gtk_container_remove (GTK_CONTAINER (vbox), GTK_WIDGET (elt->data)); model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo)); gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter); gtk_tree_model_get (model, &iter, AUTH_METHOD_COLUMN, &eap, -1); g_assert (eap); eap_widget = eap_method_get_widget (eap); g_assert (eap_widget); gtk_widget_unparent (eap_widget); if (size_group) eap_method_add_to_size_group (eap, size_group); gtk_container_add (GTK_CONTAINER (vbox), eap_widget); /* Refocus the EAP method's default widget */ if (eap->default_field) { eap_default_widget = GTK_WIDGET (gtk_builder_get_object (eap->builder, eap->default_field)); if (eap_default_widget) gtk_widget_grab_focus (eap_default_widget); } eap_method_unref (eap); wireless_security_changed_cb (combo, WIRELESS_SECURITY (sec)); } GtkWidget * ws_802_1x_auth_combo_init (WirelessSecurity *sec, const char *combo_name, const char *combo_label, GCallback auth_combo_changed_cb, NMConnection *connection, gboolean is_editor, gboolean secrets_only) { GtkWidget *combo, *widget; GtkListStore *auth_model; GtkTreeIter iter; EAPMethodSimple *em_md5; EAPMethodTLS *em_tls; EAPMethodLEAP *em_leap; EAPMethodSimple *em_pwd; EAPMethodFAST *em_fast; EAPMethodTTLS *em_ttls; EAPMethodPEAP *em_peap; const char *default_method = NULL, *ctype = NULL; int active = -1, item = 0; gboolean wired = FALSE; EAPMethodSimpleFlags simple_flags = EAP_METHOD_SIMPLE_FLAG_NONE; /* Grab the default EAP method out of the security object */ if (connection) { NMSettingConnection *s_con; NMSetting8021x *s_8021x; s_con = nm_connection_get_setting_connection (connection); if (s_con) ctype = nm_setting_connection_get_connection_type (s_con); if ( (g_strcmp0 (ctype, NM_SETTING_WIRED_SETTING_NAME) == 0) || nm_connection_get_setting_wired (connection)) wired = TRUE; s_8021x = nm_connection_get_setting_802_1x (connection); if (s_8021x && nm_setting_802_1x_get_num_eap_methods (s_8021x)) default_method = nm_setting_802_1x_get_eap_method (s_8021x, 0); } /* initialize WirelessSecurity userpass from connection (clear if no connection) */ wireless_security_set_userpass_802_1x (sec, connection); auth_model = gtk_list_store_new (2, G_TYPE_STRING, eap_method_get_type ()); if (is_editor) simple_flags |= EAP_METHOD_SIMPLE_FLAG_IS_EDITOR; if (secrets_only) simple_flags |= EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY; if (wired) { em_md5 = eap_method_simple_new (sec, connection, EAP_METHOD_SIMPLE_TYPE_MD5, simple_flags); gtk_list_store_append (auth_model, &iter); gtk_list_store_set (auth_model, &iter, AUTH_NAME_COLUMN, _("MD5"), AUTH_METHOD_COLUMN, em_md5, -1); eap_method_unref (EAP_METHOD (em_md5)); if (default_method && (active < 0) && !strcmp (default_method, "md5")) active = item; item++; } em_tls = eap_method_tls_new (sec, connection, FALSE, secrets_only); gtk_list_store_append (auth_model, &iter); gtk_list_store_set (auth_model, &iter, AUTH_NAME_COLUMN, _("TLS"), AUTH_METHOD_COLUMN, em_tls, -1); eap_method_unref (EAP_METHOD (em_tls)); if (default_method && (active < 0) && !strcmp (default_method, "tls")) active = item; item++; if (!wired) { em_leap = eap_method_leap_new (sec, connection, secrets_only); gtk_list_store_append (auth_model, &iter); gtk_list_store_set (auth_model, &iter, AUTH_NAME_COLUMN, _("LEAP"), AUTH_METHOD_COLUMN, em_leap, -1); eap_method_unref (EAP_METHOD (em_leap)); if (default_method && (active < 0) && !strcmp (default_method, "leap")) active = item; item++; } em_pwd = eap_method_simple_new (sec, connection, EAP_METHOD_SIMPLE_TYPE_PWD, simple_flags); gtk_list_store_append (auth_model, &iter); gtk_list_store_set (auth_model, &iter, AUTH_NAME_COLUMN, _("PWD"), AUTH_METHOD_COLUMN, em_pwd, -1); eap_method_unref (EAP_METHOD (em_pwd)); if (default_method && (active < 0) && !strcmp (default_method, "pwd")) active = item; item++; em_fast = eap_method_fast_new (sec, connection, is_editor, secrets_only); gtk_list_store_append (auth_model, &iter); gtk_list_store_set (auth_model, &iter, AUTH_NAME_COLUMN, _("FAST"), AUTH_METHOD_COLUMN, em_fast, -1); eap_method_unref (EAP_METHOD (em_fast)); if (default_method && (active < 0) && !strcmp (default_method, "fast")) active = item; item++; em_ttls = eap_method_ttls_new (sec, connection, is_editor, secrets_only); gtk_list_store_append (auth_model, &iter); gtk_list_store_set (auth_model, &iter, AUTH_NAME_COLUMN, _("Tunneled TLS"), AUTH_METHOD_COLUMN, em_ttls, -1); eap_method_unref (EAP_METHOD (em_ttls)); if (default_method && (active < 0) && !strcmp (default_method, "ttls")) active = item; item++; em_peap = eap_method_peap_new (sec, connection, is_editor, secrets_only); gtk_list_store_append (auth_model, &iter); gtk_list_store_set (auth_model, &iter, AUTH_NAME_COLUMN, _("Protected EAP (PEAP)"), AUTH_METHOD_COLUMN, em_peap, -1); eap_method_unref (EAP_METHOD (em_peap)); if (default_method && (active < 0) && !strcmp (default_method, "peap")) active = item; item++; combo = GTK_WIDGET (gtk_builder_get_object (sec->builder, combo_name)); g_assert (combo); gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (auth_model)); g_object_unref (G_OBJECT (auth_model)); gtk_combo_box_set_active (GTK_COMBO_BOX (combo), active < 0 ? 0 : (guint32) active); g_signal_connect (G_OBJECT (combo), "changed", auth_combo_changed_cb, sec); if (secrets_only) { gtk_widget_hide (combo); widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, combo_label)); gtk_widget_hide (widget); } return combo; } void ws_802_1x_fill_connection (WirelessSecurity *sec, const char *combo_name, NMConnection *connection) { GtkWidget *widget; NMSettingWirelessSecurity *s_wireless_sec; NMSetting8021x *s_8021x; NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; EAPMethod *eap = NULL; GtkTreeModel *model; GtkTreeIter iter; /* Get the EAPMethod object */ widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, combo_name)); model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); gtk_tree_model_get (model, &iter, AUTH_METHOD_COLUMN, &eap, -1); g_assert (eap); /* Get previous password flags, if any. Otherwise default to agent-owned secrets */ s_8021x = nm_connection_get_setting_802_1x (connection); if (s_8021x) nm_setting_get_secret_flags (NM_SETTING (s_8021x), eap->password_flags_name, &secret_flags, NULL); else secret_flags = NM_SETTING_SECRET_FLAG_AGENT_OWNED; /* Blow away the old wireless security setting by adding a clear one */ s_wireless_sec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); nm_connection_add_setting (connection, (NMSetting *) s_wireless_sec); /* Blow away the old 802.1x setting by adding a clear one */ s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); nm_connection_add_setting (connection, (NMSetting *) s_8021x); eap_method_fill_connection (eap, connection, secret_flags); eap_method_unref (eap); } void ws_802_1x_update_secrets (WirelessSecurity *sec, const char *combo_name, NMConnection *connection) { GtkWidget *widget; EAPMethod *eap = NULL; GtkTreeModel *model; GtkTreeIter iter; g_return_if_fail (sec != NULL); g_return_if_fail (combo_name != NULL); g_return_if_fail (connection != NULL); widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, combo_name)); g_return_if_fail (widget != NULL); model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); /* Let each EAP method try to update its secrets */ if (gtk_tree_model_get_iter_first (model, &iter)) { do { gtk_tree_model_get (model, &iter, AUTH_METHOD_COLUMN, &eap, -1); if (eap) { eap_method_update_secrets (eap, connection); eap_method_unref (eap); } } while (gtk_tree_model_iter_next (model, &iter)); } } cinnamon-control-center-6.4.1/panels/network/wireless-security/eap-method-ttls.h0000664000175000017500000000251114724311620027040 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (C) Copyright 2007 - 2010 Red Hat, Inc. */ #ifndef EAP_METHOD_TTLS_H #define EAP_METHOD_TTLS_H #include "wireless-security.h" typedef struct _EAPMethodTTLS EAPMethodTTLS; EAPMethodTTLS *eap_method_ttls_new (WirelessSecurity *ws_parent, NMConnection *connection, gboolean is_editor, gboolean secrets_only); #endif /* EAP_METHOD_TLS_H */ cinnamon-control-center-6.4.1/panels/network/wireless-security/ws-wep-key.c0000664000175000017500000003027514724311620026044 0ustar fabiofabio/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager Applet -- allow user control over networking * * Dan Williams * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright 2007 - 2014 Red Hat, Inc. */ #include "nm-default.h" #include #include "wireless-security.h" #include "utils.h" #include "helpers.h" #include "nma-ui-utils.h" struct _WirelessSecurityWEPKey { WirelessSecurity parent; gboolean editing_connection; const char *password_flags_name; NMWepKeyType type; char keys[4][65]; guint8 cur_index; }; static void show_toggled_cb (GtkCheckButton *button, WirelessSecurity *sec) { GtkWidget *widget; gboolean visible; widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, "wep_key_entry")); g_assert (widget); visible = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); gtk_entry_set_visibility (GTK_ENTRY (widget), visible); } static void key_index_combo_changed_cb (GtkWidget *combo, WirelessSecurity *parent) { WirelessSecurityWEPKey *sec = (WirelessSecurityWEPKey *) parent; GtkWidget *entry; const char *key; int key_index; /* Save WEP key for old key index */ entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wep_key_entry")); key = gtk_entry_get_text (GTK_ENTRY (entry)); if (key) g_strlcpy (sec->keys[sec->cur_index], key, sizeof (sec->keys[sec->cur_index])); else memset (sec->keys[sec->cur_index], 0, sizeof (sec->keys[sec->cur_index])); key_index = gtk_combo_box_get_active (GTK_COMBO_BOX (combo)); g_return_if_fail (key_index <= 3); g_return_if_fail (key_index >= 0); /* Populate entry with key from new index */ gtk_entry_set_text (GTK_ENTRY (entry), sec->keys[key_index]); sec->cur_index = key_index; wireless_security_changed_cb (combo, parent); } static void destroy (WirelessSecurity *parent) { WirelessSecurityWEPKey *sec = (WirelessSecurityWEPKey *) parent; int i; for (i = 0; i < 4; i++) memset (sec->keys[i], 0, sizeof (sec->keys[i])); } static gboolean validate (WirelessSecurity *parent, GError **error) { WirelessSecurityWEPKey *sec = (WirelessSecurityWEPKey *) parent; GtkWidget *entry; const char *key; int i; entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wep_key_entry")); g_assert (entry); key = gtk_entry_get_text (GTK_ENTRY (entry)); if (!key) { widget_set_error (entry); g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing wep-key")); return FALSE; } if (sec->type == NM_WEP_KEY_TYPE_KEY) { if ((strlen (key) == 10) || (strlen (key) == 26)) { for (i = 0; i < strlen (key); i++) { if (!g_ascii_isxdigit (key[i])) { widget_set_error (entry); g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid wep-key: key with a length of %zu must contain only hex-digits"), strlen (key)); return FALSE; } } } else if ((strlen (key) == 5) || (strlen (key) == 13)) { for (i = 0; i < strlen (key); i++) { if (!utils_char_is_ascii_print (key[i])) { widget_set_error (entry); g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid wep-key: key with a length of %zu must contain only ascii characters"), strlen (key)); return FALSE; } } } else { widget_set_error (entry); g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid wep-key: wrong key length %zu. A key must be either of length 5/13 (ascii) or 10/26 (hex)"), strlen (key)); return FALSE; } } else if (sec->type == NM_WEP_KEY_TYPE_PASSPHRASE) { if (!*key || (strlen (key) > 64)) { widget_set_error (entry); if (!*key) g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid wep-key: passphrase must be non-empty")); else g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid wep-key: passphrase must be shorter than 64 characters")); return FALSE; } } widget_unset_error (entry); return TRUE; } static void add_to_size_group (WirelessSecurity *parent, GtkSizeGroup *group) { GtkWidget *widget; widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "auth_method_label")); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wep_key_label")); gtk_size_group_add_widget (group, widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "key_index_label")); gtk_size_group_add_widget (group, widget); } static void fill_connection (WirelessSecurity *parent, NMConnection *connection) { WirelessSecurityWEPKey *sec = (WirelessSecurityWEPKey *) parent; NMSettingWirelessSecurity *s_wsec; NMSettingSecretFlags secret_flags; GtkWidget *widget, *passwd_entry; gint auth_alg; const char *key; int i; widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "auth_method_combo")); auth_alg = gtk_combo_box_get_active (GTK_COMBO_BOX (widget)); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wep_key_entry")); passwd_entry = widget; key = gtk_entry_get_text (GTK_ENTRY (widget)); g_strlcpy (sec->keys[sec->cur_index], key, sizeof (sec->keys[sec->cur_index])); /* Blow away the old security setting by adding a clear one */ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); nm_connection_add_setting (connection, (NMSetting *) s_wsec); g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, sec->cur_index, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, (auth_alg == 1) ? "shared" : "open", NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, sec->type, NULL); for (i = 0; i < 4; i++) { if (strlen (sec->keys[i])) nm_setting_wireless_security_set_wep_key (s_wsec, i, sec->keys[i]); } /* Save WEP_KEY_FLAGS to the connection */ secret_flags = nma_utils_menu_to_secret_flags (passwd_entry); g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, secret_flags, NULL); /* Update secret flags and popup when editing the connection */ if (sec->editing_connection) nma_utils_update_password_storage (passwd_entry, secret_flags, NM_SETTING (s_wsec), sec->password_flags_name); } static void wep_entry_filter_cb (GtkEditable *editable, gchar *text, gint length, gint *position, gpointer data) { WirelessSecurityWEPKey *sec = (WirelessSecurityWEPKey *) data; if (sec->type == NM_WEP_KEY_TYPE_KEY) { utils_filter_editable_on_insert_text (editable, text, length, position, data, utils_char_is_ascii_print, wep_entry_filter_cb); } } static void update_secrets (WirelessSecurity *parent, NMConnection *connection) { WirelessSecurityWEPKey *sec = (WirelessSecurityWEPKey *) parent; NMSettingWirelessSecurity *s_wsec; GtkWidget *widget; const char *tmp; int i; s_wsec = nm_connection_get_setting_wireless_security (connection); for (i = 0; s_wsec && i < 4; i++) { tmp = nm_setting_wireless_security_get_wep_key (s_wsec, i); if (tmp) g_strlcpy (sec->keys[i], tmp, sizeof (sec->keys[i])); } widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wep_key_entry")); if (strlen (sec->keys[sec->cur_index])) gtk_entry_set_text (GTK_ENTRY (widget), sec->keys[sec->cur_index]); } WirelessSecurityWEPKey * ws_wep_key_new (NMConnection *connection, NMWepKeyType type, gboolean adhoc_create, gboolean secrets_only) { WirelessSecurity *parent; WirelessSecurityWEPKey *sec; GtkWidget *widget; NMSettingWirelessSecurity *s_wsec = NULL; NMSetting *setting = NULL; guint8 default_key_idx = 0; gboolean is_adhoc = adhoc_create; gboolean is_shared_key = FALSE; parent = wireless_security_init (sizeof (WirelessSecurityWEPKey), validate, add_to_size_group, fill_connection, update_secrets, destroy, "/org/cinnamon/control-center/network/ws-wep-key.ui", "wep_key_notebook", "wep_key_entry"); if (!parent) return NULL; sec = (WirelessSecurityWEPKey *) parent; sec->editing_connection = secrets_only ? FALSE : TRUE; sec->password_flags_name = NM_SETTING_WIRELESS_SECURITY_WEP_KEY0; sec->type = type; widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wep_key_entry")); g_assert (widget); gtk_entry_set_width_chars (GTK_ENTRY (widget), 28); /* Create password-storage popup menu for password entry under entry's secondary icon */ if (connection) setting = (NMSetting *) nm_connection_get_setting_wireless_security (connection); nma_utils_setup_password_storage (widget, 0, setting, sec->password_flags_name, FALSE, secrets_only); if (connection) { NMSettingWireless *s_wireless; const char *mode, *auth_alg; s_wireless = nm_connection_get_setting_wireless (connection); mode = s_wireless ? nm_setting_wireless_get_mode (s_wireless) : NULL; if (mode && !strcmp (mode, "adhoc")) is_adhoc = TRUE; s_wsec = nm_connection_get_setting_wireless_security (connection); if (s_wsec) { auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); if (auth_alg && !strcmp (auth_alg, "shared")) is_shared_key = TRUE; } } g_signal_connect (G_OBJECT (widget), "changed", (GCallback) wireless_security_changed_cb, sec); g_signal_connect (G_OBJECT (widget), "insert-text", (GCallback) wep_entry_filter_cb, sec); if (sec->type == NM_WEP_KEY_TYPE_KEY) gtk_entry_set_max_length (GTK_ENTRY (widget), 26); else if (sec->type == NM_WEP_KEY_TYPE_PASSPHRASE) gtk_entry_set_max_length (GTK_ENTRY (widget), 64); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "key_index_combo")); if (connection && s_wsec) default_key_idx = nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec); gtk_combo_box_set_active (GTK_COMBO_BOX (widget), default_key_idx); sec->cur_index = default_key_idx; g_signal_connect (G_OBJECT (widget), "changed", (GCallback) key_index_combo_changed_cb, sec); /* Key index is useless with adhoc networks */ if (is_adhoc || secrets_only) { gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "key_index_label")); gtk_widget_hide (widget); } /* Fill the key entry with the key for that index */ if (connection) update_secrets (WIRELESS_SECURITY (sec), connection); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_wep")); g_assert (widget); g_signal_connect (G_OBJECT (widget), "toggled", (GCallback) show_toggled_cb, sec); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "auth_method_combo")); gtk_combo_box_set_active (GTK_COMBO_BOX (widget), is_shared_key ? 1 : 0); g_signal_connect (G_OBJECT (widget), "changed", (GCallback) wireless_security_changed_cb, sec); /* Don't show auth method for adhoc (which always uses open-system) or * when in "simple" mode. */ if (is_adhoc || secrets_only) { /* Ad-Hoc connections can't use Shared Key auth */ if (is_adhoc) gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "auth_method_label")); gtk_widget_hide (widget); } return sec; } cinnamon-control-center-6.4.1/panels/network/wireless-security/ws-wpa-psk.ui0000664000175000017500000001136514724311620026237 0ustar fabiofabio True False False False True False 3 2 6 6 True False 1 _Password True wpa_psk_entry GTK_FILL True True 64 False True 1 2 True False 1 _Type True wpa_psk_type_combo 2 3 GTK_FILL True False 0 1 2 GTK_FILL Sho_w password True True False True True 1 2 1 2 GTK_FILL True False 1 2 2 3 GTK_FILL True False False cinnamon-control-center-6.4.1/panels/network/net-device-wifi.h0000664000175000017500000000412614724311620023312 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2011-2012 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __NET_DEVICE_WIFI_H #define __NET_DEVICE_WIFI_H #include #include "net-device.h" G_BEGIN_DECLS #define NET_TYPE_DEVICE_WIFI (net_device_wifi_get_type ()) #define NET_DEVICE_WIFI(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NET_TYPE_DEVICE_WIFI, NetDeviceWifi)) #define NET_DEVICE_WIFI_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NET_TYPE_DEVICE_WIFI, NetDeviceWifiClass)) #define NET_IS_DEVICE_WIFI(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NET_TYPE_DEVICE_WIFI)) #define NET_IS_DEVICE_WIFI_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NET_TYPE_DEVICE_WIFI)) #define NET_DEVICE_WIFI_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NET_TYPE_DEVICE_WIFI, NetDeviceWifiClass)) typedef struct _NetDeviceWifiPrivate NetDeviceWifiPrivate; typedef struct _NetDeviceWifi NetDeviceWifi; typedef struct _NetDeviceWifiClass NetDeviceWifiClass; struct _NetDeviceWifi { NetDevice parent; NetDeviceWifiPrivate *priv; }; struct _NetDeviceWifiClass { NetDeviceClass parent_class; }; GType net_device_wifi_get_type (void); G_END_DECLS #endif /* __NET_DEVICE_WIFI_H */ cinnamon-control-center-6.4.1/panels/network/net-proxy.c0000664000175000017500000004255114724311620022277 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2011-2012 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include "net-proxy.h" #define NET_PROXY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NET_TYPE_PROXY, NetProxyPrivate)) struct _NetProxyPrivate { GSettings *settings; GtkBuilder *builder; }; G_DEFINE_TYPE (NetProxy, net_proxy, NET_TYPE_OBJECT) static void check_wpad_warning (NetProxy *proxy) { GtkWidget *widget; gchar *autoconfig_url = NULL; GString *string = NULL; gboolean ret = FALSE; guint mode; string = g_string_new (""); /* check we're using 'Automatic' */ mode = g_settings_get_enum (proxy->priv->settings, "mode"); if (mode != 2) goto out; /* see if the PAC is blank */ autoconfig_url = g_settings_get_string (proxy->priv->settings, "autoconfig-url"); ret = autoconfig_url == NULL || autoconfig_url[0] == '\0'; if (!ret) goto out; g_string_append (string, ""); /* TRANSLATORS: this is when the use leaves the PAC textbox blank */ g_string_append (string, _("Web Proxy Autodiscovery is used when a Configuration URL is not provided.")); g_string_append (string, "\n"); /* TRANSLATORS: WPAD is bad: if you enable it on an untrusted * network, then anyone else on that network can tell your * machine that it should proxy all of your web traffic * through them. */ g_string_append (string, _("This is not recommended for untrusted public networks.")); g_string_append (string, ""); out: widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "label_proxy_warning")); gtk_label_set_markup (GTK_LABEL (widget), string->str); gtk_widget_set_visible (widget, (string->len > 0)); g_free (autoconfig_url); g_string_free (string, TRUE); } static void settings_changed_cb (GSettings *settings, const gchar *key, NetProxy *proxy) { check_wpad_warning (proxy); } static void panel_proxy_mode_combo_setup_widgets (NetProxy *proxy, guint value) { GtkWidget *widget; /* hide or show the PAC text box */ widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "heading_proxy_url")); gtk_widget_set_visible (widget, value == 2); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "entry_proxy_url")); gtk_widget_set_visible (widget, value == 2); /* hide or show the manual entry text boxes */ widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "heading_proxy_http")); gtk_widget_set_visible (widget, value == 1); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "entry_proxy_http")); gtk_widget_set_visible (widget, value == 1); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "spinbutton_proxy_http")); gtk_widget_set_visible (widget, value == 1); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "heading_proxy_https")); gtk_widget_set_visible (widget, value == 1); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "entry_proxy_https")); gtk_widget_set_visible (widget, value == 1); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "spinbutton_proxy_https")); gtk_widget_set_visible (widget, value == 1); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "heading_proxy_ftp")); gtk_widget_set_visible (widget, value == 1); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "entry_proxy_ftp")); gtk_widget_set_visible (widget, value == 1); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "spinbutton_proxy_ftp")); gtk_widget_set_visible (widget, value == 1); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "heading_proxy_socks")); gtk_widget_set_visible (widget, value == 1); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "entry_proxy_socks")); gtk_widget_set_visible (widget, value == 1); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "spinbutton_proxy_socks")); gtk_widget_set_visible (widget, value == 1); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "heading_proxy_ignore")); gtk_widget_set_visible (widget, value == 1); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "entry_proxy_ignore")); gtk_widget_set_visible (widget, value == 1); /* perhaps show the wpad warning */ check_wpad_warning (proxy); } static void panel_set_value_for_combo (NetProxy *proxy, GtkComboBox *combo_box, gint value) { gboolean ret; gint value_tmp; GtkTreeIter iter; GtkTreeModel *model; /* get entry */ model = gtk_combo_box_get_model (combo_box); ret = gtk_tree_model_get_iter_first (model, &iter); if (!ret) return; /* try to make the UI match the setting */ do { gtk_tree_model_get (model, &iter, 1, &value_tmp, -1); if (value == value_tmp) { gtk_combo_box_set_active_iter (combo_box, &iter); break; } } while (gtk_tree_model_iter_next (model, &iter)); /* hide or show the correct widgets */ panel_proxy_mode_combo_setup_widgets (proxy, value); } static void panel_proxy_mode_combo_changed_cb (GtkWidget *widget, NetProxy *proxy) { gboolean ret; gint value; GtkTreeIter iter; GtkTreeModel *model; /* no selection */ ret = gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); if (!ret) return; /* get entry */ model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); gtk_tree_model_get (model, &iter, 1, &value, -1); /* set */ g_settings_set_enum (proxy->priv->settings, "mode", value); /* hide or show the correct widgets */ panel_proxy_mode_combo_setup_widgets (proxy, value); } static GtkWidget * net_proxy_add_to_notebook (NetObject *object, GtkNotebook *notebook, GtkSizeGroup *heading_size_group) { GtkWidget *widget; NetProxy *proxy = NET_PROXY (object); /* add widgets to size group */ widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "heading_proxy_method")); gtk_size_group_add_widget (heading_size_group, widget); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "grid5")); gtk_notebook_append_page (notebook, widget, NULL); return widget; } static void net_proxy_finalize (GObject *object) { NetProxy *proxy = NET_PROXY (object); NetProxyPrivate *priv = proxy->priv; g_clear_object (&priv->settings); g_clear_object (&priv->builder); G_OBJECT_CLASS (net_proxy_parent_class)->finalize (object); } static void net_proxy_class_init (NetProxyClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); NetObjectClass *parent_class = NET_OBJECT_CLASS (klass); object_class->finalize = net_proxy_finalize; parent_class->add_to_notebook = net_proxy_add_to_notebook; g_type_class_add_private (klass, sizeof (NetProxyPrivate)); } static gboolean get_ignore_hosts (GValue *value, GVariant *variant, gpointer user_data) { GVariantIter iter; const gchar *s; gchar **av, **p; gsize n; n = g_variant_iter_init (&iter, variant); p = av = g_new0 (gchar *, n + 1); while (g_variant_iter_next (&iter, "&s", &s)) if (s[0] != '\0') { *p = (gchar *) s; ++p; } g_value_take_string (value, g_strjoinv (", ", av)); g_free (av); return TRUE; } static GVariant * set_ignore_hosts (const GValue *value, const GVariantType *expected_type, gpointer user_data) { GVariantBuilder builder; const gchar *sv; gchar **av, **p; sv = g_value_get_string (value); av = g_strsplit_set (sv, ", ", 0); g_variant_builder_init (&builder, G_VARIANT_TYPE_STRING_ARRAY); for (p = av; *p; ++p) { if (*p[0] != '\0') g_variant_builder_add (&builder, "s", *p); } g_strfreev (av); return g_variant_builder_end (&builder); } static void net_proxy_init (NetProxy *proxy) { GError *error = NULL; gint value; GSettings *settings_tmp; GtkAdjustment *adjustment; GtkWidget *widget; proxy->priv = NET_PROXY_GET_PRIVATE (proxy); proxy->priv->builder = gtk_builder_new (); gtk_builder_add_from_resource (proxy->priv->builder, "/org/cinnamon/control-center/network/network-proxy.ui", &error); if (error != NULL) { g_warning ("Could not load interface file: %s", error->message); g_error_free (error); return; } proxy->priv->settings = g_settings_new ("org.gnome.system.proxy"); g_signal_connect (proxy->priv->settings, "changed", G_CALLBACK (settings_changed_cb), proxy); /* actions */ value = g_settings_get_enum (proxy->priv->settings, "mode"); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "combobox_proxy_mode")); panel_set_value_for_combo (proxy, GTK_COMBO_BOX (widget), value); g_signal_connect (widget, "changed", G_CALLBACK (panel_proxy_mode_combo_changed_cb), proxy); /* bind the proxy values */ widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "entry_proxy_url")); g_settings_bind (proxy->priv->settings, "autoconfig-url", widget, "text", G_SETTINGS_BIND_DEFAULT); /* bind the HTTP proxy values */ settings_tmp = g_settings_get_child (proxy->priv->settings, "http"); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "entry_proxy_http")); g_settings_bind (settings_tmp, "host", widget, "text", G_SETTINGS_BIND_DEFAULT); adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (proxy->priv->builder, "adjustment_proxy_port_http")); g_settings_bind (settings_tmp, "port", adjustment, "value", G_SETTINGS_BIND_DEFAULT); g_object_unref (settings_tmp); /* bind the HTTPS proxy values */ settings_tmp = g_settings_get_child (proxy->priv->settings, "https"); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "entry_proxy_https")); g_settings_bind (settings_tmp, "host", widget, "text", G_SETTINGS_BIND_DEFAULT); adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (proxy->priv->builder, "adjustment_proxy_port_https")); g_settings_bind (settings_tmp, "port", adjustment, "value", G_SETTINGS_BIND_DEFAULT); g_object_unref (settings_tmp); /* bind the FTP proxy values */ settings_tmp = g_settings_get_child (proxy->priv->settings, "ftp"); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "entry_proxy_ftp")); g_settings_bind (settings_tmp, "host", widget, "text", G_SETTINGS_BIND_DEFAULT); adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (proxy->priv->builder, "adjustment_proxy_port_ftp")); g_settings_bind (settings_tmp, "port", adjustment, "value", G_SETTINGS_BIND_DEFAULT); g_object_unref (settings_tmp); /* bind the SOCKS proxy values */ settings_tmp = g_settings_get_child (proxy->priv->settings, "socks"); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "entry_proxy_socks")); g_settings_bind (settings_tmp, "host", widget, "text", G_SETTINGS_BIND_DEFAULT); adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (proxy->priv->builder, "adjustment_proxy_port_socks")); g_settings_bind (settings_tmp, "port", adjustment, "value", G_SETTINGS_BIND_DEFAULT); g_object_unref (settings_tmp); /* set header to something sane */ widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "image_proxy_device")); gtk_image_set_from_icon_name (GTK_IMAGE (widget), "preferences-system-network", GTK_ICON_SIZE_DIALOG); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "label_proxy_device")); gtk_label_set_label (GTK_LABEL (widget), _("Proxy")); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "label_proxy_status")); gtk_label_set_label (GTK_LABEL (widget), ""); /* bind the proxy ignore hosts */ widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "entry_proxy_ignore")); g_settings_bind_with_mapping (proxy->priv->settings, "ignore-hosts", widget, "text", G_SETTINGS_BIND_DEFAULT, get_ignore_hosts, set_ignore_hosts, NULL, NULL); /* hide the switch until we get some more detail in the mockup */ widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "device_proxy_off_switch")); if (widget != NULL) gtk_widget_hide (widget); } NetProxy * net_proxy_new (void) { NetProxy *proxy; proxy = g_object_new (NET_TYPE_PROXY, "removable", FALSE, "id", "proxy", NULL); return NET_PROXY (proxy); } cinnamon-control-center-6.4.1/panels/network/net-device-ethernet.h0000664000175000017500000000453014724311620024171 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2012 Red Hat, Inc. * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __NET_DEVICE_ETHERNET_H #define __NET_DEVICE_ETHERNET_H #include #include "net-device-simple.h" G_BEGIN_DECLS #define NET_TYPE_DEVICE_ETHERNET (net_device_ethernet_get_type ()) #define NET_DEVICE_ETHERNET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NET_TYPE_DEVICE_ETHERNET, NetDeviceEthernet)) #define NET_DEVICE_ETHERNET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NET_TYPE_DEVICE_ETHERNET, NetDeviceEthernetClass)) #define NET_IS_DEVICE_ETHERNET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NET_TYPE_DEVICE_ETHERNET)) #define NET_IS_DEVICE_ETHERNET_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NET_TYPE_DEVICE_ETHERNET)) #define NET_DEVICE_ETHERNET_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NET_TYPE_DEVICE_ETHERNET, NetDeviceEthernetClass)) typedef struct _NetDeviceEthernetPrivate NetDeviceEthernetPrivate; typedef struct _NetDeviceEthernet NetDeviceEthernet; typedef struct _NetDeviceEthernetClass NetDeviceEthernetClass; struct _NetDeviceEthernet { NetDeviceSimple parent; GtkBuilder *builder; GtkWidget *list; GtkWidget *scrolled_window; GtkWidget *details; GtkWidget *details_button; GtkWidget *add_profile_button; gboolean updating_device; GHashTable *connections; }; struct _NetDeviceEthernetClass { NetDeviceSimpleClass parent_class; }; GType net_device_ethernet_get_type (void); G_END_DECLS #endif /* __NET_DEVICE_ETHERNET_H */ cinnamon-control-center-6.4.1/panels/network/net-device-wifi.c0000664000175000017500000024436514724311620023320 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2011-2012 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include #include "shell/list-box-helper.h" #include "shell/hostname-helper.h" #include "network-dialogs.h" #include "panel-common.h" #include "connection-editor/net-connection-editor.h" #include "net-device-wifi.h" #define NET_DEVICE_WIFI_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NET_TYPE_DEVICE_WIFI, NetDeviceWifiPrivate)) typedef enum { NM_AP_SEC_UNKNOWN, NM_AP_SEC_NONE, NM_AP_SEC_WEP, NM_AP_SEC_WPA, NM_AP_SEC_WPA2 } NMAccessPointSecurity; static void nm_device_wifi_refresh_ui (NetDeviceWifi *device_wifi); static void show_wifi_list (NetDeviceWifi *device_wifi); static void populate_ap_list (NetDeviceWifi *device_wifi); static void show_hotspot_ui (NetDeviceWifi *device_wifi); struct _NetDeviceWifiPrivate { GtkBuilder *builder; GtkWidget *details_dialog; GtkWidget *hotspot_dialog; GtkSwitch *hotspot_switch; gboolean updating_device; gchar *selected_ssid_title; gchar *selected_connection_id; gchar *selected_ap_id; }; G_DEFINE_TYPE (NetDeviceWifi, net_device_wifi, NET_TYPE_DEVICE) enum { COLUMN_CONNECTION_ID, COLUMN_ACCESS_POINT_ID, COLUMN_TITLE, COLUMN_SORT, COLUMN_STRENGTH, COLUMN_MODE, COLUMN_SECURITY, COLUMN_ACTIVE, COLUMN_AP_IN_RANGE, COLUMN_AP_OUT_OF_RANGE, COLUMN_AP_IS_SAVED, COLUMN_LAST }; static GtkWidget * device_wifi_proxy_add_to_notebook (NetObject *object, GtkNotebook *notebook, GtkSizeGroup *heading_size_group) { GtkWidget *widget; NetDeviceWifi *device_wifi = NET_DEVICE_WIFI (object); /* add widgets to size group */ widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "heading_ipv4")); gtk_size_group_add_widget (heading_size_group, widget); widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "notebook_view")); gtk_notebook_append_page (notebook, widget, NULL); return widget; } static guint get_access_point_security (NMAccessPoint *ap) { NM80211ApFlags flags; NM80211ApSecurityFlags wpa_flags; NM80211ApSecurityFlags rsn_flags; guint type; flags = nm_access_point_get_flags (ap); wpa_flags = nm_access_point_get_wpa_flags (ap); rsn_flags = nm_access_point_get_rsn_flags (ap); if (!(flags & NM_802_11_AP_FLAGS_PRIVACY) && wpa_flags == NM_802_11_AP_SEC_NONE && rsn_flags == NM_802_11_AP_SEC_NONE) type = NM_AP_SEC_NONE; else if ((flags & NM_802_11_AP_FLAGS_PRIVACY) && wpa_flags == NM_802_11_AP_SEC_NONE && rsn_flags == NM_802_11_AP_SEC_NONE) type = NM_AP_SEC_WEP; else if (!(flags & NM_802_11_AP_FLAGS_PRIVACY) && wpa_flags != NM_802_11_AP_SEC_NONE && rsn_flags != NM_802_11_AP_SEC_NONE) type = NM_AP_SEC_WPA; else type = NM_AP_SEC_WPA2; return type; } static GPtrArray * panel_get_strongest_unique_aps (const GPtrArray *aps) { GBytes *ssid, *ssid_tmp; GPtrArray *aps_unique = NULL; gboolean add_ap; guint i; guint j; NMAccessPoint *ap; NMAccessPoint *ap_tmp; /* we will have multiple entries for typical hotspots, just * filter to the one with the strongest signal */ aps_unique = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); if (aps != NULL) for (i = 0; i < aps->len; i++) { ap = NM_ACCESS_POINT (g_ptr_array_index (aps, i)); /* Hidden SSIDs don't get shown in the list */ ssid = nm_access_point_get_ssid (ap); if (!ssid) continue; add_ap = TRUE; /* get already added list */ for (j=0; jlen; j++) { ap_tmp = NM_ACCESS_POINT (g_ptr_array_index (aps_unique, j)); ssid_tmp = nm_access_point_get_ssid (ap_tmp); g_assert (ssid_tmp); /* is this the same type and data? */ if (nm_utils_same_ssid (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid), g_bytes_get_data (ssid_tmp, NULL), g_bytes_get_size (ssid_tmp), TRUE)) { g_debug ("found duplicate: %s", nm_utils_escape_ssid (g_bytes_get_data (ssid_tmp, NULL), g_bytes_get_size (ssid_tmp))); /* the new access point is stronger */ if (nm_access_point_get_strength (ap) > nm_access_point_get_strength (ap_tmp)) { g_debug ("removing %s", nm_utils_escape_ssid (g_bytes_get_data (ssid_tmp, NULL), g_bytes_get_size (ssid_tmp))); g_ptr_array_remove (aps_unique, ap_tmp); add_ap = TRUE; } else { add_ap = FALSE; } break; } } if (add_ap) { g_debug ("adding %s", nm_utils_escape_ssid (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid))); g_ptr_array_add (aps_unique, g_object_ref (ap)); } } return aps_unique; } static gchar * get_ap_security_string (NMAccessPoint *ap) { NM80211ApSecurityFlags wpa_flags, rsn_flags; NM80211ApFlags flags; GString *str; flags = nm_access_point_get_flags (ap); wpa_flags = nm_access_point_get_wpa_flags (ap); rsn_flags = nm_access_point_get_rsn_flags (ap); str = g_string_new (""); if ((flags & NM_802_11_AP_FLAGS_PRIVACY) && (wpa_flags == NM_802_11_AP_SEC_NONE) && (rsn_flags == NM_802_11_AP_SEC_NONE)) { /* TRANSLATORS: this WEP WiFi security */ g_string_append_printf (str, "%s, ", _("WEP")); } if (wpa_flags != NM_802_11_AP_SEC_NONE) { /* TRANSLATORS: this WPA WiFi security */ g_string_append_printf (str, "%s, ", _("WPA")); } if (rsn_flags != NM_802_11_AP_SEC_NONE) { /* TRANSLATORS: this WPA WiFi security */ g_string_append_printf (str, "%s, ", _("WPA2")); } if ((wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) || (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) { /* TRANSLATORS: this Enterprise WiFi security */ g_string_append_printf (str, "%s, ", _("Enterprise")); } if (str->len > 0) g_string_set_size (str, str->len - 2); else { g_string_append (str, C_("Wifi security", "None")); } return g_string_free (str, FALSE); } static void net_device_wifi_access_point_changed (NMDeviceWifi *nm_device_wifi, NMAccessPoint *ap, gpointer user_data) { NetDeviceWifi *device_wifi; device_wifi = NET_DEVICE_WIFI (user_data); populate_ap_list (device_wifi); } static void wireless_enabled_toggled (NMClient *client, GParamSpec *pspec, NetDeviceWifi *device_wifi) { gboolean enabled; GtkSwitch *sw; NMDevice *device; device = net_device_get_nm_device (NET_DEVICE (device_wifi)); if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_WIFI) return; enabled = nm_client_wireless_get_enabled (client); sw = GTK_SWITCH (gtk_builder_get_object (device_wifi->priv->builder, "device_off_switch")); device_wifi->priv->updating_device = TRUE; gtk_switch_set_active (sw, enabled); device_wifi->priv->updating_device = FALSE; } static NMConnection * find_connection_for_device (NetDeviceWifi *device_wifi, NMDevice *device) { NetDevice *tmp; NMConnection *connection; NMClient *client; client = net_object_get_client (NET_OBJECT (device_wifi)); tmp = g_object_new (NET_TYPE_DEVICE, "client", client, "nm-device", device, NULL); connection = net_device_get_find_connection (tmp); g_object_unref (tmp); return connection; } static gboolean connection_is_shared (NMConnection *c) { NMSettingIPConfig *s_ip4; s_ip4 = nm_connection_get_setting_ip4_config (c); if (g_strcmp0 (nm_setting_ip_config_get_method (s_ip4), NM_SETTING_IP4_CONFIG_METHOD_SHARED) != 0) { return FALSE; } return TRUE; } static gboolean device_is_hotspot (NetDeviceWifi *device_wifi) { NMConnection *c; NMDevice *device; device = net_device_get_nm_device (NET_DEVICE (device_wifi)); if (nm_device_get_active_connection (device) == NULL) return FALSE; c = find_connection_for_device (device_wifi, device); if (c == NULL) return FALSE; return connection_is_shared (c); } static GBytes * device_get_hotspot_ssid (NetDeviceWifi *device_wifi, NMDevice *device) { NMConnection *c; NMSettingWireless *sw; c = find_connection_for_device (device_wifi, device); if (c == NULL) { return FALSE; } sw = nm_connection_get_setting_wireless (c); return nm_setting_wireless_get_ssid (sw); } static void get_secrets_cb (GObject *source_object, GAsyncResult *res, gpointer data) { NetDeviceWifi *device_wifi = data; GVariant *secrets; GError *error = NULL; secrets = nm_remote_connection_get_secrets_finish (NM_REMOTE_CONNECTION (source_object), res, &error); if (!secrets) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("Could not get secrets: %s", error->message); g_error_free (error); //FIXME ignore cancelled return; } nm_connection_update_secrets (NM_CONNECTION (source_object), NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, secrets, NULL); nm_device_wifi_refresh_ui (device_wifi); } static void device_get_hotspot_security_details (NetDeviceWifi *device_wifi, NMDevice *device, gchar **secret, gchar **security) { NMConnection *c; NMSettingWirelessSecurity *sws; const gchar *key_mgmt; const gchar *tmp_secret; const gchar *tmp_security; c = find_connection_for_device (device_wifi, device); if (c == NULL) return; sws = nm_connection_get_setting_wireless_security (c); if (sws == NULL) return; tmp_secret = NULL; tmp_security = C_("Wifi security", "None"); /* Key management values: * "none" = WEP * "wpa-none" = WPAv1 Ad-Hoc mode (not supported in NM >= 0.9.4) * "wpa-psk" = WPAv2 Ad-Hoc mode (eg IBSS RSN) and AP-mode WPA v1 and v2 */ key_mgmt = nm_setting_wireless_security_get_key_mgmt (sws); if (strcmp (key_mgmt, "none") == 0) { tmp_secret = nm_setting_wireless_security_get_wep_key (sws, 0); tmp_security = _("WEP"); } else if (strcmp (key_mgmt, "wpa-none") == 0 || strcmp (key_mgmt, "wpa-psk") == 0) { tmp_secret = nm_setting_wireless_security_get_psk (sws); tmp_security = _("WPA"); } else { g_warning ("unhandled security key-mgmt: %s", key_mgmt); } /* If we don't have secrets, request them from NM and bail. * We'll refresh the UI when secrets arrive. */ if (tmp_secret == NULL) { nm_remote_connection_get_secrets_async ((NMRemoteConnection*)c, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NULL, get_secrets_cb, device_wifi); return; } if (secret) *secret = g_strdup (tmp_secret); if (security) *security = g_strdup (tmp_security); } static void nm_device_wifi_refresh_hotspot (NetDeviceWifi *device_wifi) { GBytes *ssid; gchar *hotspot_secret = NULL; gchar *hotspot_security = NULL; gchar *hotspot_ssid = NULL; NMDevice *nm_device; /* refresh hotspot ui */ nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi)); ssid = device_get_hotspot_ssid (device_wifi, nm_device); if (ssid) hotspot_ssid = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid)); device_get_hotspot_security_details (device_wifi, nm_device, &hotspot_secret, &hotspot_security); g_debug ("Refreshing hotspot labels to name: '%s', security key: '%s', security: '%s'", hotspot_ssid, hotspot_secret, hotspot_security); panel_set_device_widget_details (device_wifi->priv->builder, "hotspot_network_name", hotspot_ssid); panel_set_device_widget_details (device_wifi->priv->builder, "hotspot_security_key", hotspot_secret); panel_set_device_widget_details (device_wifi->priv->builder, "hotspot_security", hotspot_security); panel_set_device_widget_details (device_wifi->priv->builder, "hotspot_connected", NULL); g_free (hotspot_secret); g_free (hotspot_security); g_free (hotspot_ssid); } static void update_last_used (NetDeviceWifi *device_wifi, NMConnection *connection) { gchar *last_used = NULL; GDateTime *now = NULL; GDateTime *then = NULL; gint days; GTimeSpan diff; guint64 timestamp; NMSettingConnection *s_con; s_con = nm_connection_get_setting_connection (connection); if (s_con == NULL) goto out; timestamp = nm_setting_connection_get_timestamp (s_con); if (timestamp == 0) { last_used = g_strdup (_("never")); goto out; } /* calculate the amount of time that has elapsed */ now = g_date_time_new_now_utc (); then = g_date_time_new_from_unix_utc (timestamp); diff = g_date_time_difference (now, then); days = diff / G_TIME_SPAN_DAY; if (days == 0) last_used = g_strdup (_("today")); else if (days == 1) last_used = g_strdup (_("yesterday")); else last_used = g_strdup_printf (ngettext ("%i day ago", "%i days ago", days), days); out: panel_set_device_widget_details (device_wifi->priv->builder, "last_used", last_used); if (now != NULL) g_date_time_unref (now); if (then != NULL) g_date_time_unref (then); g_free (last_used); } static void nm_device_wifi_refresh_ui (NetDeviceWifi *device_wifi) { const gchar *str; gboolean is_hotspot; gchar *str_tmp = NULL; gint strength = 0; guint speed = 0; NMAccessPoint *active_ap; NMDevice *nm_device; NMDeviceState state; NMClient *client; NMAccessPoint *ap; NMConnection *connection; NetDeviceWifiPrivate *priv = device_wifi->priv; GtkWidget *dialog; is_hotspot = device_is_hotspot (device_wifi); if (is_hotspot) { nm_device_wifi_refresh_hotspot (device_wifi); show_hotspot_ui (device_wifi); return; } nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi)); dialog = device_wifi->priv->details_dialog; ap = g_object_get_data (G_OBJECT (dialog), "ap"); connection = g_object_get_data (G_OBJECT (dialog), "connection"); active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (nm_device)); state = nm_device_get_state (nm_device); /* keep this in sync with the signal handler setup in cc_network_panel_init */ client = net_object_get_client (NET_OBJECT (device_wifi)); wireless_enabled_toggled (client, NULL, device_wifi); if (ap != active_ap) speed = 0; else if (state != NM_DEVICE_STATE_UNAVAILABLE) speed = nm_device_wifi_get_bitrate (NM_DEVICE_WIFI (nm_device)); speed /= 1000; if (speed > 0) { /* Translators: network device speed */ str_tmp = g_strdup_printf (_("%d Mb/s"), speed); } panel_set_device_widget_details (device_wifi->priv->builder, "speed", str_tmp); /* device MAC */ str = nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (nm_device)); panel_set_device_widget_details (device_wifi->priv->builder, "mac", str); /* security */ if (ap != active_ap) str_tmp = NULL; else if (active_ap != NULL) str_tmp = get_ap_security_string (active_ap); panel_set_device_widget_details (device_wifi->priv->builder, "security", str_tmp); g_free (str_tmp); /* signal strength */ if (ap != NULL) strength = nm_access_point_get_strength (ap); else strength = 0; if (strength <= 0) str = NULL; else if (strength < 20) str = C_("Signal strength", "None"); else if (strength < 40) str = C_("Signal strength", "Weak"); else if (strength < 50) str = C_("Signal strength", "Ok"); else if (strength < 80) str = C_("Signal strength", "Good"); else str = C_("Signal strength", "Excellent"); panel_set_device_widget_details (device_wifi->priv->builder, "strength", str); /* device MAC */ if (ap != active_ap) str = NULL; else str = nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (nm_device)); panel_set_device_widget_details (priv->builder, "mac", str); /* set IP entries */ if (ap != active_ap) panel_unset_device_widgets (priv->builder); else panel_set_device_widgets (priv->builder, nm_device); if (ap != active_ap && connection) update_last_used (device_wifi, connection); else panel_set_device_widget_details (priv->builder, "last_used", NULL); panel_set_device_status (priv->builder, "heading_status", nm_device, NULL); /* update list of APs */ show_wifi_list (device_wifi); populate_ap_list (device_wifi); } static void device_wifi_refresh (NetObject *object) { NetDeviceWifi *device_wifi = NET_DEVICE_WIFI (object); nm_device_wifi_refresh_ui (device_wifi); } static void device_off_toggled (GtkSwitch *sw, GParamSpec *pspec, NetDeviceWifi *device_wifi) { NMClient *client; gboolean active; if (device_wifi->priv->updating_device) return; client = net_object_get_client (NET_OBJECT (device_wifi)); active = gtk_switch_get_active (sw); nm_client_wireless_set_enabled (client, active); } static void connect_to_hidden_network (NetDeviceWifi *device_wifi) { NMClient *client; GList *windows = gtk_window_list_toplevels (); GtkWidget *toplevel = GTK_WIDGET (windows->data); client = net_object_get_client (NET_OBJECT (device_wifi)); cc_network_panel_connect_to_hidden_network (toplevel, client); g_list_free (windows); } static void connection_add_activate_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { NMActiveConnection *conn; GError *error = NULL; conn = nm_client_add_and_activate_connection_finish (NM_CLIENT (source_object), res, &error); if (!conn) { //FIXME cancelled nm_device_wifi_refresh_ui (user_data); /* failed to activate */ g_debug ("Failed to add and activate connection '%d': %s", error->code, error->message); g_error_free (error); return; } } static void connection_activate_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; if (!nm_client_activate_connection_finish (NM_CLIENT (source_object), res, &error)) { //FIXME cancelled nm_device_wifi_refresh_ui (user_data); /* failed to activate */ g_debug ("Failed to add and activate connection '%d': %s", error->code, error->message); g_error_free (error); return; } } static gboolean is_8021x (NMDevice *device, const char *ap_object_path) { NM80211ApSecurityFlags wpa_flags, rsn_flags; NMAccessPoint *ap; ap = nm_device_wifi_get_access_point_by_path (NM_DEVICE_WIFI (device), ap_object_path); if (!ap) return FALSE; rsn_flags = nm_access_point_get_rsn_flags (ap); if (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) return TRUE; wpa_flags = nm_access_point_get_wpa_flags (ap); if (wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) return TRUE; return FALSE; } static void wireless_try_to_connect (NetDeviceWifi *device_wifi, GBytes *ssid, const gchar *ap_object_path) { GBytes *match_ssid; const gchar *ssid_target; GSList *list, *l; NMConnection *connection_activate = NULL; NMDevice *device; NMSettingWireless *setting_wireless; NMClient *client; if (device_wifi->priv->updating_device) goto out; if (ap_object_path == NULL || ap_object_path[0] == 0) goto out; device = net_device_get_nm_device (NET_DEVICE (device_wifi)); if (device == NULL) goto out; ssid_target = nm_utils_escape_ssid ((gpointer) g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid)); g_debug ("try to connect to WIFI network %s [%s]", ssid_target, ap_object_path); /* look for an existing connection we can use */ list = net_device_get_valid_connections (NET_DEVICE (device_wifi)); g_debug ("%i suitable remote connections to check", g_slist_length (list)); for (l = list; l; l = g_slist_next (l)) { NMConnection *connection; connection = NM_CONNECTION (l->data); setting_wireless = nm_connection_get_setting_wireless (connection); if (!NM_IS_SETTING_WIRELESS (setting_wireless)) continue; match_ssid = nm_setting_wireless_get_ssid (setting_wireless); if (match_ssid == NULL) continue; if (g_bytes_equal (ssid, match_ssid)) { g_debug ("we found an existing connection %s to activate!", nm_connection_get_id (connection)); connection_activate = connection; break; } } g_slist_free (list); /* activate the connection */ client = net_object_get_client (NET_OBJECT (device_wifi)); if (connection_activate != NULL) { nm_client_activate_connection_async (client, connection_activate, device, NULL, NULL, connection_activate_cb, device_wifi); goto out; } /* create one, as it's missing */ g_debug ("no existing connection found for %s, creating", ssid_target); if (!is_8021x (device, ap_object_path)) { GPermission *permission; gboolean allowed_to_share = FALSE; NMConnection *partial = NULL; permission = polkit_permission_new_sync ("org.freedesktop.NetworkManager.settings.modify.system", NULL, NULL, NULL); if (permission) { allowed_to_share = g_permission_get_allowed (permission); g_object_unref (permission); } if (!allowed_to_share) { NMSettingConnection *s_con; s_con = (NMSettingConnection *)nm_setting_connection_new (); nm_setting_connection_add_permission (s_con, "user", g_get_user_name (), NULL); partial = nm_simple_connection_new (); nm_connection_add_setting (partial, NM_SETTING (s_con)); } g_debug ("no existing connection found for %s, creating and activating one", ssid_target); nm_client_add_and_activate_connection_async (client, partial, device, ap_object_path, NULL, connection_add_activate_cb, device_wifi); if (!allowed_to_share) g_object_unref (partial); } else { CcNetworkPanel *panel; GVariantBuilder *builder; GVariant *parameters; g_debug ("no existing connection found for %s, creating", ssid_target); builder = g_variant_builder_new (G_VARIANT_TYPE ("av")); g_variant_builder_add (builder, "v", g_variant_new_string ("connect-8021x-wifi")); g_variant_builder_add (builder, "v", g_variant_new_string (nm_object_get_path (NM_OBJECT (device)))); g_variant_builder_add (builder, "v", g_variant_new_string (ap_object_path)); parameters = g_variant_new ("av", builder); panel = net_object_get_panel (NET_OBJECT (device_wifi)); g_object_set (G_OBJECT (panel), "parameters", parameters, NULL); g_variant_builder_unref (builder); } out: return; } static gchar * get_hostname (void) { GDBusConnection *bus; GVariant *res; GVariant *inner; gchar *str; GError *error; error = NULL; bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); if (bus == NULL) { g_warning ("Failed to get system bus connection: %s", error->message); g_error_free (error); return NULL; } res = g_dbus_connection_call_sync (bus, "org.freedesktop.hostname1", "/org/freedesktop/hostname1", "org.freedesktop.DBus.Properties", "Get", g_variant_new ("(ss)", "org.freedesktop.hostname1", "PrettyHostname"), (GVariantType*)"(v)", G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); g_object_unref (bus); if (res == NULL) { g_warning ("Getting pretty hostname failed: %s", error->message); g_error_free (error); } str = NULL; if (res != NULL) { g_variant_get (res, "(v)", &inner); str = g_variant_dup_string (inner, NULL); g_variant_unref (res); } return str; } static GBytes * generate_ssid_for_hotspot (NetDeviceWifi *device_wifi) { GBytes *ssid_bytes; gchar *hostname, *ssid; hostname = get_hostname (); ssid = pretty_hostname_to_ssid (hostname); g_free (hostname); ssid_bytes = g_bytes_new_with_free_func (ssid, strlen (ssid), g_free, NULL); return ssid_bytes; } #define WPA_PASSKEY_SIZE 8 static void set_wpa_key (NMSettingWirelessSecurity *sws) { /* generate a 8-chars ASCII WPA key */ char key[WPA_PASSKEY_SIZE + 1]; guint i; for (i = 0; i < WPA_PASSKEY_SIZE; i++) { gint c; c = g_random_int_range (33, 126); /* too many non alphanumeric characters are hard to remember for humans */ while (!g_ascii_isalnum (c)) c = g_random_int_range (33, 126); key[i] = (gchar) c; } key[WPA_PASSKEY_SIZE] = '\0'; g_object_set (sws, "key-mgmt", "wpa-psk", "psk", key, NULL); } static void set_wep_key (NMSettingWirelessSecurity *sws) { gchar key[11]; gint i; const gchar *hexdigits = "0123456789abcdef"; /* generate a 10-digit hex WEP key */ for (i = 0; i < 10; i++) { gint digit; digit = g_random_int_range (0, 16); key[i] = hexdigits[digit]; } key[10] = 0; g_object_set (sws, "key-mgmt", "none", "wep-key0", key, "wep-key-type", NM_WEP_KEY_TYPE_KEY, NULL); } static gboolean is_hotspot_connection (NMConnection *connection) { NMSettingConnection *sc; NMSettingWireless *sw; NMSettingIPConfig *sip; NMSetting *setting; sc = nm_connection_get_setting_connection (connection); if (g_strcmp0 (nm_setting_connection_get_connection_type (sc), "802-11-wireless") != 0) { return FALSE; } sw = nm_connection_get_setting_wireless (connection); if (g_strcmp0 (nm_setting_wireless_get_mode (sw), "adhoc") != 0 && g_strcmp0 (nm_setting_wireless_get_mode (sw), "ap") != 0) { return FALSE; } setting = nm_connection_get_setting_by_name (connection, NM_SETTING_WIRELESS_SETTING_NAME); if (!setting) return FALSE; sip = nm_connection_get_setting_ip4_config (connection); if (g_strcmp0 (nm_setting_ip_config_get_method (sip), "shared") != 0) { return FALSE; } return TRUE; } static void show_hotspot_ui (NetDeviceWifi *device_wifi) { GtkWidget *widget; /* show hotspot tab */ widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "notebook_view")); gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 1); /* force switch to on as this succeeded */ device_wifi->priv->updating_device = TRUE; gtk_switch_set_active (device_wifi->priv->hotspot_switch, TRUE); device_wifi->priv->updating_device = FALSE; } static void activate_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; if (nm_client_activate_connection_finish (NM_CLIENT (source_object), res, &error) == NULL) { g_warning ("Failed to add new connection: (%d) %s", error->code, error->message); g_error_free (error); return; } /* show hotspot tab */ nm_device_wifi_refresh_ui (user_data); } static void activate_new_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { NMActiveConnection *conn; GError *error = NULL; conn = nm_client_add_and_activate_connection_finish (NM_CLIENT (source_object), res, &error); if (!conn) { g_warning ("Failed to add new connection: (%d) %s", error->code, error->message); g_error_free (error); return; } /* show hotspot tab */ nm_device_wifi_refresh_ui (user_data); } static NMConnection * net_device_wifi_get_hotspot_connection (NetDeviceWifi *device_wifi) { GSList *connections, *l; NMConnection *c = NULL; connections = net_device_get_valid_connections (NET_DEVICE (device_wifi)); for (l = connections; l; l = l->next) { NMConnection *tmp = l->data; if (is_hotspot_connection (tmp)) { c = tmp; break; } } g_slist_free (connections); return c; } static void overwrite_ssid_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; NMClient *client; NMRemoteConnection *connection; NMDevice *device; NMConnection *c; NetDeviceWifi *device_wifi; connection = NM_REMOTE_CONNECTION (source_object); if (!nm_remote_connection_commit_changes_finish (connection, res, &error)) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("Failed to save hotspot's settings to disk: %s", error->message); g_error_free (error); return; } device_wifi = user_data; device = net_device_get_nm_device (NET_DEVICE (device_wifi)); client = net_object_get_client (NET_OBJECT (device_wifi)); c = net_device_wifi_get_hotspot_connection (device_wifi); g_debug ("activate existing hotspot connection\n"); nm_client_activate_connection_async (client, c, device, NULL, NULL, activate_cb, device_wifi); } static void start_shared_connection (NetDeviceWifi *device_wifi) { NMConnection *c; NMSettingConnection *sc; NMSettingWireless *sw; NMSettingIP4Config *sip; NMSettingWirelessSecurity *sws; NMDevice *device; GBytes *ssid; const gchar *str_mac; struct ether_addr *bin_mac; NMClient *client; const char *mode; NMDeviceWifiCapabilities caps; device = net_device_get_nm_device (NET_DEVICE (device_wifi)); g_assert (nm_device_get_device_type (device) == NM_DEVICE_TYPE_WIFI); c = net_device_wifi_get_hotspot_connection (device_wifi); ssid = generate_ssid_for_hotspot (device_wifi); client = net_object_get_client (NET_OBJECT (device_wifi)); if (c != NULL) { NMSettingWireless *sw; const char *c_path; NMRemoteConnection *connection; sw = nm_connection_get_setting_wireless (c); g_object_set (sw, "ssid", ssid, NULL); g_bytes_unref (ssid); c_path = nm_connection_get_path (c); connection = nm_client_get_connection_by_path (client, c_path); g_debug ("overwriting ssid to %s", (char *) g_bytes_get_data (ssid, NULL)); nm_remote_connection_commit_changes_async (connection, TRUE, NULL, overwrite_ssid_cb, device_wifi); return; } g_debug ("create new hotspot connection with SSID '%s'", (char *) g_bytes_get_data (ssid, NULL)); c = nm_simple_connection_new (); sc = (NMSettingConnection *)nm_setting_connection_new (); g_object_set (sc, "type", "802-11-wireless", "id", "Hotspot", "autoconnect", FALSE, NULL); nm_connection_add_setting (c, (NMSetting *)sc); sw = (NMSettingWireless *)nm_setting_wireless_new (); /* Use real AP mode if the device supports it */ caps = nm_device_wifi_get_capabilities (NM_DEVICE_WIFI (device)); if (caps & NM_WIFI_DEVICE_CAP_AP) mode = NM_SETTING_WIRELESS_MODE_AP; else mode = NM_SETTING_WIRELESS_MODE_ADHOC; g_object_set (sw, "mode", mode, NULL); str_mac = nm_device_wifi_get_permanent_hw_address (NM_DEVICE_WIFI (device)); bin_mac = ether_aton (str_mac); if (bin_mac) { GByteArray *hw_address; hw_address = g_byte_array_sized_new (ETH_ALEN); g_byte_array_append (hw_address, bin_mac->ether_addr_octet, ETH_ALEN); g_object_set (sw, "mac-address", hw_address, NULL); g_byte_array_unref (hw_address); } nm_connection_add_setting (c, (NMSetting *)sw); sip = (NMSettingIP4Config*) nm_setting_ip4_config_new (); g_object_set (sip, "method", "shared", NULL); nm_connection_add_setting (c, (NMSetting *)sip); g_object_set (sw, "ssid", ssid, NULL); g_bytes_unref (ssid); sws = (NMSettingWirelessSecurity*) nm_setting_wireless_security_new (); if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_AP) == 0) { if (caps & NM_WIFI_DEVICE_CAP_RSN) { set_wpa_key (sws); nm_setting_wireless_security_add_proto (sws, "rsn"); nm_setting_wireless_security_add_pairwise (sws, "ccmp"); nm_setting_wireless_security_add_group (sws, "ccmp"); } else if (caps & NM_WIFI_DEVICE_CAP_WPA) { set_wpa_key (sws); nm_setting_wireless_security_add_proto (sws, "wpa"); nm_setting_wireless_security_add_pairwise (sws, "tkip"); nm_setting_wireless_security_add_group (sws, "tkip"); } else { set_wep_key (sws); } } else { set_wep_key (sws); } nm_connection_add_setting (c, (NMSetting *)sws); nm_client_add_and_activate_connection_async (client, c, device, NULL, NULL, activate_new_cb, device_wifi); g_object_unref (c); } static void start_hotspot_response_cb (GtkWidget *dialog, gint response, NetDeviceWifi *device_wifi) { if (response == GTK_RESPONSE_OK) { start_shared_connection (device_wifi); } gtk_widget_hide (dialog); } static void start_hotspot (GtkButton *button, NetDeviceWifi *device_wifi) { NMDevice *device; const GPtrArray *connections; gchar *active_ssid; NMClient *client; GtkWidget *dialog; GtkWidget *window; GtkWidget *widget; GString *str; active_ssid = NULL; client = net_object_get_client (NET_OBJECT (device_wifi)); device = net_device_get_nm_device (NET_DEVICE (device_wifi)); connections = nm_client_get_active_connections (client); if (connections) { gint i; for (i = 0; i < connections->len; i++) { NMActiveConnection *c; const GPtrArray *devices; c = (NMActiveConnection *)connections->pdata[i]; devices = nm_active_connection_get_devices (c); if (devices && devices->pdata[0] == device) { NMAccessPoint *ap; GBytes *ssid; ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (device)); ssid = nm_access_point_get_ssid (ap); active_ssid = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid)); break; } } } window = gtk_widget_get_toplevel (GTK_WIDGET (button)); dialog = device_wifi->priv->hotspot_dialog; gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window)); str = g_string_new (_("If you have a connection to the Internet other than wireless, you can set up a wireless hotspot to share the connection with others.")); g_string_append (str, "\n\n"); if (active_ssid) { g_string_append_printf (str, _("Switching on the wireless hotspot will disconnect you from %s."), active_ssid); g_string_append (str, " "); } g_string_append (str, _("It is not possible to access the Internet through your wireless while the hotspot is active.")); widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "hotspot-dialog-content")); gtk_label_set_markup (GTK_LABEL (widget), str->str); g_string_free (str, TRUE); g_signal_connect (dialog, "response", G_CALLBACK (start_hotspot_response_cb), device_wifi); g_signal_connect (dialog, "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), NULL); gtk_window_present (GTK_WINDOW (dialog)); g_free (active_ssid); } static void stop_shared_connection (NetDeviceWifi *device_wifi) { const GPtrArray *connections; const GPtrArray *devices; NMDevice *device; gint i; NMActiveConnection *c; NMClient *client; gboolean found = FALSE; device = net_device_get_nm_device (NET_DEVICE (device_wifi)); client = net_object_get_client (NET_OBJECT (device_wifi)); connections = nm_client_get_active_connections (client); for (i = 0; connections && i < connections->len; i++) { c = (NMActiveConnection *)connections->pdata[i]; devices = nm_active_connection_get_devices (c); if (devices && devices->pdata[0] == device) { nm_client_deactivate_connection (client, c, NULL, NULL); found = TRUE; break; } } if (!found) { g_warning ("Could not stop hotspot connection as no connection attached to the device could be found."); device_wifi->priv->updating_device = TRUE; gtk_switch_set_active (device_wifi->priv->hotspot_switch, TRUE); device_wifi->priv->updating_device = FALSE; return; } nm_device_wifi_refresh_ui (device_wifi); } static void stop_hotspot_response_cb (GtkWidget *dialog, gint response, NetDeviceWifi *device_wifi) { if (response == GTK_RESPONSE_OK) { stop_shared_connection (device_wifi); } else { device_wifi->priv->updating_device = TRUE; gtk_switch_set_active (device_wifi->priv->hotspot_switch, TRUE); device_wifi->priv->updating_device = FALSE; } gtk_widget_destroy (dialog); } static void switch_hotspot_changed_cb (GtkSwitch *sw, GParamSpec *pspec, NetDeviceWifi *device_wifi) { GtkWidget *dialog; GtkWidget *window; CcNetworkPanel *panel; if (device_wifi->priv->updating_device) return; panel = net_object_get_panel (NET_OBJECT (device_wifi)); window = gtk_widget_get_toplevel (GTK_WIDGET (panel)); dialog = gtk_message_dialog_new (GTK_WINDOW (window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_OTHER, GTK_BUTTONS_NONE, _("Stop hotspot and disconnect any users?")); gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("_Cancel"), GTK_RESPONSE_CANCEL, _("_Stop Hotspot"), GTK_RESPONSE_OK, NULL); g_signal_connect (dialog, "response", G_CALLBACK (stop_hotspot_response_cb), device_wifi); gtk_window_present (GTK_WINDOW (dialog)); } static void show_wifi_list (NetDeviceWifi *device_wifi) { GtkWidget *widget; widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "notebook_view")); gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 0); } static void client_connection_added_cb (NMClient *client, NMRemoteConnection *connection, NetDeviceWifi *device_wifi) { gboolean is_hotspot; /* go straight to the hotspot UI */ is_hotspot = device_is_hotspot (device_wifi); if (is_hotspot) { nm_device_wifi_refresh_hotspot (device_wifi); show_hotspot_ui (device_wifi); return; } populate_ap_list (device_wifi); show_wifi_list (device_wifi); } static void client_connection_removed_cb (NMClient *client, NMRemoteConnection *connection, NetDeviceWifi *device_wifi) { GtkWidget *swin; GtkWidget *list; GList *rows, *l; const char *uuid; uuid = nm_connection_get_uuid (NM_CONNECTION (connection)); swin = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "scrolledwindow_list")); list = gtk_bin_get_child (GTK_BIN (gtk_bin_get_child (GTK_BIN (swin)))); rows = gtk_container_get_children (GTK_CONTAINER (list)); for (l = rows; l != NULL; l = l->next) { GtkWidget *row = l->data; NMConnection *connection; const char *uuid_r; connection = g_object_get_data (G_OBJECT (row), "connection"); if (!connection) continue; uuid_r = nm_connection_get_uuid (connection); if (g_strcmp0 (uuid_r, uuid) == 0) { gtk_widget_destroy (row); break; } } g_list_free (rows); } static void net_device_wifi_constructed (GObject *object) { NetDeviceWifi *device_wifi = NET_DEVICE_WIFI (object); NMClient *client; NMClientPermissionResult perm; NMDevice *nm_device; NMDeviceWifiCapabilities caps; GtkWidget *widget; G_OBJECT_CLASS (net_device_wifi_parent_class)->constructed (object); client = net_object_get_client (NET_OBJECT (device_wifi)); g_signal_connect_object (client, "notify::wireless-enabled", G_CALLBACK (wireless_enabled_toggled), device_wifi, 0); nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi)); g_signal_connect_object (nm_device, "access-point-added", G_CALLBACK (net_device_wifi_access_point_changed), device_wifi, 0); g_signal_connect_object (nm_device, "access-point-removed", G_CALLBACK (net_device_wifi_access_point_changed), device_wifi, 0); /* only enable the button if the user can create a hotspot */ widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "start_hotspot_button")); perm = nm_client_get_permission_result (client, NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN); caps = nm_device_wifi_get_capabilities (NM_DEVICE_WIFI (nm_device)); if (perm != NM_CLIENT_PERMISSION_RESULT_YES && perm != NM_CLIENT_PERMISSION_RESULT_AUTH && perm != NM_CLIENT_PERMISSION_RESULT_UNKNOWN) { gtk_widget_set_tooltip_text (widget, _("System policy prohibits use as a Hotspot")); gtk_widget_set_sensitive (widget, FALSE); } else if (!(caps & (NM_WIFI_DEVICE_CAP_AP | NM_WIFI_DEVICE_CAP_ADHOC))) { gtk_widget_set_tooltip_text (widget, _("Wireless device does not support Hotspot mode")); gtk_widget_set_sensitive (widget, FALSE); } else gtk_widget_set_sensitive (widget, TRUE); g_signal_connect (client, NM_CLIENT_CONNECTION_ADDED, G_CALLBACK (client_connection_added_cb), device_wifi); g_signal_connect (client, NM_CLIENT_CONNECTION_REMOVED, G_CALLBACK (client_connection_removed_cb), device_wifi); widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "heading_list")); g_object_bind_property (device_wifi, "title", widget, "label", 0); nm_device_wifi_refresh_ui (device_wifi); } static void net_device_wifi_finalize (GObject *object) { NetDeviceWifi *device_wifi = NET_DEVICE_WIFI (object); NetDeviceWifiPrivate *priv = device_wifi->priv; g_clear_pointer (&priv->details_dialog, gtk_widget_destroy); g_clear_pointer (&priv->hotspot_dialog, gtk_widget_destroy); g_object_unref (priv->builder); g_free (priv->selected_ssid_title); g_free (priv->selected_connection_id); g_free (priv->selected_ap_id); G_OBJECT_CLASS (net_device_wifi_parent_class)->finalize (object); } static void device_wifi_edit (NetObject *object) { const gchar *uuid; gchar *cmdline; GError *error = NULL; NetDeviceWifi *device = NET_DEVICE_WIFI (object); NMClient *client; NMRemoteConnection *connection; client = net_object_get_client (object); connection = nm_client_get_connection_by_path (client, device->priv->selected_connection_id); if (connection == NULL) { g_warning ("failed to get remote connection"); return; } uuid = nm_connection_get_uuid (NM_CONNECTION (connection)); cmdline = g_strdup_printf ("nm-connection-editor --edit %s", uuid); g_debug ("Launching '%s'\n", cmdline); if (!g_spawn_command_line_async (cmdline, &error)) { g_warning ("Failed to launch nm-connection-editor: %s", error->message); g_error_free (error); } g_free (cmdline); } static void net_device_wifi_class_init (NetDeviceWifiClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); NetObjectClass *parent_class = NET_OBJECT_CLASS (klass); object_class->finalize = net_device_wifi_finalize; object_class->constructed = net_device_wifi_constructed; parent_class->add_to_notebook = device_wifi_proxy_add_to_notebook; parent_class->refresh = device_wifi_refresh; parent_class->edit = device_wifi_edit; g_type_class_add_private (klass, sizeof (NetDeviceWifiPrivate)); } static void really_forgotten (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; if (!nm_remote_connection_delete_finish (NM_REMOTE_CONNECTION (source_object), res, &error)) { g_warning ("failed to delete connection %s: %s", nm_object_get_path (NM_OBJECT (source_object)), error->message); g_error_free (error); return; } /* remove the entry from the list */ populate_ap_list (user_data); } static void really_forget (GtkDialog *dialog, gint response, gpointer data) { GtkWidget *forget = data; GtkWidget *row; GList *rows; GList *r; NMRemoteConnection *connection; NetDeviceWifi *device_wifi; gtk_widget_destroy (GTK_WIDGET (dialog)); if (response != GTK_RESPONSE_OK) return; device_wifi = NET_DEVICE_WIFI (g_object_get_data (G_OBJECT (forget), "net")); rows = g_object_steal_data (G_OBJECT (forget), "rows"); for (r = rows; r; r = r->next) { row = r->data; connection = g_object_get_data (G_OBJECT (row), "connection"); //FIXME cancellable nm_remote_connection_delete_async (connection, NULL, really_forgotten, device_wifi); gtk_widget_destroy (row); } g_list_free (rows); } static void forget_selected (GtkButton *forget, NetDeviceWifi *device_wifi) { GtkWidget *window; GtkWidget *dialog; window = gtk_widget_get_toplevel (GTK_WIDGET (forget)); dialog = gtk_message_dialog_new (GTK_WINDOW (window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_OTHER, GTK_BUTTONS_NONE, NULL); gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), _("Network details for the selected networks, including passwords and any custom configuration will be lost.")); gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("_Cancel"), GTK_RESPONSE_CANCEL, _("_Forget"), GTK_RESPONSE_OK, NULL); g_signal_connect (dialog, "response", G_CALLBACK (really_forget), forget); gtk_window_present (GTK_WINDOW (dialog)); } static void check_toggled (GtkToggleButton *check, GtkWidget *forget) { gboolean active; GtkWidget *row; GList *rows; row = gtk_widget_get_ancestor (GTK_WIDGET (check), GTK_TYPE_LIST_BOX_ROW); active = gtk_toggle_button_get_active (check); rows = g_object_steal_data (G_OBJECT (forget), "rows"); if (active) { rows = g_list_prepend (rows, row); } else { rows = g_list_remove (rows, row); } g_object_set_data_full (G_OBJECT (forget), "rows", rows, (GDestroyNotify)g_list_free); gtk_widget_set_sensitive (forget, rows != NULL); } static void update_forget (GtkWidget *forget, gpointer row) { GList *rows; rows = g_object_steal_data (G_OBJECT (forget), "rows"); rows = g_list_remove (rows, row); g_object_set_data_full (G_OBJECT (forget), "rows", rows, (GDestroyNotify)g_list_free); gtk_widget_set_sensitive (forget, rows != NULL); } static void make_row (GtkSizeGroup *rows, GtkSizeGroup *icons, GtkWidget *forget, NMDevice *device, NMConnection *connection, NMAccessPoint *ap, NMAccessPoint *active_ap, GtkWidget **row_out, GtkWidget **check_out, GtkWidget **edit_out) { GtkWidget *row, *row_box; GtkWidget *widget; GtkWidget *box; GtkWidget *button_stack; GtkWidget *image; gchar *title; gboolean active; gboolean in_range; gboolean connecting; guint security; guint strength; GBytes *ssid; const gchar *icon_name; guint64 timestamp; NMDeviceState state; g_assert (connection || ap); state = nm_device_get_state (device); if (connection != NULL) { NMSettingWireless *sw; NMSettingConnection *sc; sw = nm_connection_get_setting_wireless (connection); ssid = nm_setting_wireless_get_ssid (sw); sc = nm_connection_get_setting_connection (connection); timestamp = nm_setting_connection_get_timestamp (sc); } else { ssid = nm_access_point_get_ssid (ap); timestamp = 0; } if (ap != NULL) { in_range = TRUE; active = (ap == active_ap) && (state == NM_DEVICE_STATE_ACTIVATED); connecting = (ap == active_ap) && (state == NM_DEVICE_STATE_PREPARE || state == NM_DEVICE_STATE_CONFIG || state == NM_DEVICE_STATE_IP_CONFIG || state == NM_DEVICE_STATE_IP_CHECK || state == NM_DEVICE_STATE_NEED_AUTH); security = get_access_point_security (ap); strength = nm_access_point_get_strength (ap); } else { in_range = FALSE; active = FALSE; connecting = FALSE; security = 0; strength = 0; } row = gtk_list_box_row_new (); gtk_size_group_add_widget (rows, row); row_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); gtk_widget_set_margin_start (row_box, 12); gtk_widget_set_margin_end (row_box, 12); gtk_container_add (GTK_CONTAINER (row), row_box); button_stack = gtk_stack_new (); gtk_widget_show (button_stack); widget = gtk_label_new (""); gtk_widget_show (widget); gtk_container_add (GTK_CONTAINER (button_stack), widget); widget = NULL; if (forget) { widget = gtk_check_button_new (); g_signal_connect (widget, "toggled", G_CALLBACK (check_toggled), forget); gtk_widget_set_halign (widget, GTK_ALIGN_CENTER); gtk_widget_set_valign (widget, GTK_ALIGN_CENTER); gtk_box_pack_start (GTK_BOX (row_box), widget, FALSE, FALSE, 0); g_signal_connect_object (row, "destroy", G_CALLBACK (update_forget), forget, G_CONNECT_SWAPPED); } if (check_out) *check_out = widget; title = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid)); widget = gtk_label_new (title); g_free (title); gtk_widget_set_margin_top (widget, 12); gtk_widget_set_margin_bottom (widget, 12); gtk_box_pack_start (GTK_BOX (row_box), widget, FALSE, FALSE, 0); if (active) { widget = gtk_image_new_from_icon_name ("object-select-symbolic", GTK_ICON_SIZE_MENU); gtk_widget_set_halign (widget, GTK_ALIGN_CENTER); gtk_widget_set_valign (widget, GTK_ALIGN_CENTER); gtk_box_pack_start (GTK_BOX (row_box), widget, FALSE, FALSE, 0); } gtk_box_pack_start (GTK_BOX (row_box), gtk_label_new (""), TRUE, FALSE, 0); widget = NULL; image = gtk_image_new_from_icon_name ("emblem-system-symbolic", GTK_ICON_SIZE_MENU); gtk_widget_show (image); widget = gtk_button_new (); gtk_style_context_add_class (gtk_widget_get_style_context (widget), "image-button"); gtk_style_context_add_class (gtk_widget_get_style_context (widget), "circular-button"); gtk_widget_show (widget); gtk_container_add (GTK_CONTAINER (widget), image); gtk_widget_set_halign (widget, GTK_ALIGN_CENTER); gtk_widget_set_valign (widget, GTK_ALIGN_CENTER); atk_object_set_name (gtk_widget_get_accessible (widget), _("Options…")); gtk_stack_add_named (GTK_STACK (button_stack), widget, "button"); g_object_set_data (G_OBJECT (row), "edit", widget); if (connection) gtk_stack_set_visible_child_name (GTK_STACK (button_stack), "button"); gtk_box_pack_start (GTK_BOX (row_box), button_stack, FALSE, FALSE, 0); g_object_set_data (G_OBJECT (row), "button_stack", button_stack); if (edit_out) *edit_out = widget; widget = gtk_spinner_new (); gtk_spinner_start (GTK_SPINNER (widget)); gtk_widget_show (widget); gtk_widget_set_halign (widget, GTK_ALIGN_CENTER); gtk_widget_set_valign (widget, GTK_ALIGN_CENTER); gtk_stack_add_named (GTK_STACK (button_stack), widget, "spinner"); if (connecting) gtk_stack_set_visible_child_name (GTK_STACK (button_stack), "spinner"); box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_set_homogeneous (GTK_BOX (box), TRUE); gtk_size_group_add_widget (icons, box); gtk_box_pack_start (GTK_BOX (row_box), box, FALSE, FALSE, 0); if (in_range) { if (security != NM_AP_SEC_UNKNOWN && security != NM_AP_SEC_NONE) { widget = gtk_image_new_from_icon_name ("network-wireless-encrypted-symbolic", GTK_ICON_SIZE_MENU); } else { widget = gtk_label_new (""); } gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0); if (strength < 20) icon_name = "network-wireless-signal-none-symbolic"; else if (strength < 40) icon_name = "network-wireless-signal-weak-symbolic"; else if (strength < 50) icon_name = "network-wireless-signal-ok-symbolic"; else if (strength < 80) icon_name = "network-wireless-signal-good-symbolic"; else icon_name = "network-wireless-signal-excellent-symbolic"; widget = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU); gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0); } gtk_widget_show_all (row); g_object_set_data (G_OBJECT (row), "ap", ap); if (connection) g_object_set_data (G_OBJECT (row), "connection", connection); g_object_set_data (G_OBJECT (row), "timestamp", GUINT_TO_POINTER (timestamp)); g_object_set_data (G_OBJECT (row), "active", GUINT_TO_POINTER (active)); g_object_set_data (G_OBJECT (row), "strength", GUINT_TO_POINTER (strength)); *row_out = row; } static gint history_sort (gconstpointer a, gconstpointer b, gpointer data) { guint64 ta, tb; ta = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (a), "timestamp")); tb = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (b), "timestamp")); if (ta > tb) return -1; if (tb > ta) return 1; return 0; } static gint ap_sort (gconstpointer a, gconstpointer b, gpointer data) { guint sa, sb; sa = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (a), "strength")); sb = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (b), "strength")); if (sa > sb) return -1; if (sb > sa) return 1; return 0; } static void editor_done (NetConnectionEditor *editor, gboolean success, NetDeviceWifi *device_wifi) { g_object_unref (editor); } static void show_details_for_row (GtkButton *button, NetDeviceWifi *device_wifi) { GtkWidget *row; NMConnection *connection; NMAccessPoint *ap; GtkWidget *window; NetConnectionEditor *editor; NMClient *client; NMDevice *device; window = gtk_widget_get_toplevel (GTK_WIDGET (button)); row = GTK_WIDGET (g_object_get_data (G_OBJECT (button), "row")); connection = NM_CONNECTION (g_object_get_data (G_OBJECT (row), "connection")); ap = NM_ACCESS_POINT (g_object_get_data (G_OBJECT (row), "ap")); device = net_device_get_nm_device (NET_DEVICE (device_wifi)); client = net_object_get_client (NET_OBJECT (device_wifi)); editor = net_connection_editor_new (GTK_WINDOW (window), connection, device, ap, client); g_signal_connect (editor, "done", G_CALLBACK (editor_done), device_wifi); net_connection_editor_run (editor); } static void open_history (NetDeviceWifi *device_wifi) { GtkWidget *dialog; GtkWidget *window; CcNetworkPanel *panel; GtkWidget *button; GtkWidget *forget; GtkWidget *swin; GSList *connections; GSList *l; const GPtrArray *aps; GPtrArray *aps_unique = NULL; NMAccessPoint *active_ap; guint i; NMDevice *nm_device; GtkWidget *list; GtkWidget *row; GtkSizeGroup *rows; GtkSizeGroup *icons; dialog = gtk_dialog_new (); panel = net_object_get_panel (NET_OBJECT (device_wifi)); window = gtk_widget_get_toplevel (GTK_WIDGET (panel)); gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window)); gtk_window_set_title (GTK_WINDOW (dialog), _("History")); gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 400); button = gtk_button_new_with_mnemonic (_("_Close")); gtk_widget_set_can_default (button, TRUE); gtk_widget_show (button); gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, 0); g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), dialog); /* translators: This is the label for the "Forget wireless network" functionality */ forget = gtk_button_new_with_mnemonic (C_("Wi-Fi Network", "_Forget")); gtk_widget_show (forget); gtk_widget_set_sensitive (forget, FALSE); gtk_dialog_add_action_widget (GTK_DIALOG (dialog), forget, 0); g_signal_connect (forget, "clicked", G_CALLBACK (forget_selected), device_wifi); gtk_container_child_set (GTK_CONTAINER (gtk_widget_get_parent (forget)), forget, "secondary", TRUE, NULL); g_object_set_data (G_OBJECT (forget), "net", device_wifi); swin = gtk_scrolled_window_new (NULL, NULL); gtk_widget_show (swin); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin), GTK_SHADOW_IN); gtk_widget_set_margin_start (swin, 50); gtk_widget_set_margin_end (swin, 50); gtk_widget_set_margin_top (swin, 12); gtk_widget_set_margin_bottom (swin, 12); gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), swin, TRUE, TRUE, 0); list = GTK_WIDGET (gtk_list_box_new ()); gtk_widget_show (list); gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE); gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL); gtk_list_box_set_sort_func (GTK_LIST_BOX (list), (GtkListBoxSortFunc)history_sort, NULL, NULL); gtk_container_add (GTK_CONTAINER (swin), list); rows = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL); icons = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); g_object_set_data_full (G_OBJECT (list), "rows", rows, g_object_unref); g_object_set_data_full (G_OBJECT (list), "icons", icons, g_object_unref); nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi)); connections = net_device_get_valid_connections (NET_DEVICE (device_wifi)); aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (nm_device)); aps_unique = panel_get_strongest_unique_aps (aps); active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (nm_device)); for (l = connections; l; l = l->next) { NMConnection *connection = l->data; NMAccessPoint *ap = NULL; NMSetting *setting; GBytes *ssid; if (connection_is_shared (connection)) continue; setting = nm_connection_get_setting_by_name (connection, NM_SETTING_WIRELESS_SETTING_NAME); ssid = nm_setting_wireless_get_ssid (NM_SETTING_WIRELESS (setting)); for (i = 0; i < aps_unique->len; i++) { GBytes *ssid_ap; ap = NM_ACCESS_POINT (g_ptr_array_index (aps_unique, i)); ssid_ap = nm_access_point_get_ssid (ap); if (nm_utils_same_ssid (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid), g_bytes_get_data (ssid_ap, NULL), g_bytes_get_size (ssid_ap), TRUE)) break; ap = NULL; } make_row (rows, icons, forget, nm_device, connection, ap, active_ap, &row, NULL, &button); gtk_container_add (GTK_CONTAINER (list), row); if (button) { g_signal_connect (button, "clicked", G_CALLBACK (show_details_for_row), device_wifi); g_object_set_data (G_OBJECT (button), "row", row); } } g_slist_free (connections); g_ptr_array_free (aps_unique, TRUE); gtk_window_present (GTK_WINDOW (dialog)); } static void populate_ap_list (NetDeviceWifi *device_wifi) { GtkWidget *swin; GtkWidget *list; GtkSizeGroup *rows; GtkSizeGroup *icons; NMDevice *nm_device; GSList *connections; GSList *l; const GPtrArray *aps; GPtrArray *aps_unique = NULL; NMAccessPoint *active_ap; guint i; GtkWidget *row; GtkWidget *button; GList *children, *child; swin = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "scrolledwindow_list")); list = gtk_bin_get_child (GTK_BIN (gtk_bin_get_child (GTK_BIN (swin)))); children = gtk_container_get_children (GTK_CONTAINER (list)); for (child = children; child; child = child->next) { gtk_container_remove (GTK_CONTAINER (list), GTK_WIDGET (child->data)); } g_list_free (children); rows = GTK_SIZE_GROUP (g_object_get_data (G_OBJECT (list), "rows")); icons = GTK_SIZE_GROUP (g_object_get_data (G_OBJECT (list), "icons")); nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi)); connections = net_device_get_valid_connections (NET_DEVICE (device_wifi)); aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (nm_device)); aps_unique = panel_get_strongest_unique_aps (aps); active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (nm_device)); for (i = 0; i < aps_unique->len; i++) { GBytes *ssid_ap; NMAccessPoint *ap; NMConnection *connection = NULL; ap = NM_ACCESS_POINT (g_ptr_array_index (aps_unique, i)); ssid_ap = nm_access_point_get_ssid (ap); for (l = connections; l; l = l->next) { connection = l->data; NMSetting *setting; GBytes *ssid; if (connection_is_shared (connection)) { connection = NULL; continue; } setting = nm_connection_get_setting_by_name (connection, NM_SETTING_WIRELESS_SETTING_NAME); ssid = nm_setting_wireless_get_ssid (NM_SETTING_WIRELESS (setting)); if (nm_utils_same_ssid (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid), g_bytes_get_data (ssid_ap, NULL), g_bytes_get_size (ssid_ap), TRUE)) break; connection = NULL; } make_row (rows, icons, NULL, nm_device, connection, ap, active_ap, &row, NULL, &button); gtk_container_add (GTK_CONTAINER (list), row); if (button) { g_signal_connect (button, "clicked", G_CALLBACK (show_details_for_row), device_wifi); g_object_set_data (G_OBJECT (button), "row", row); } } g_slist_free (connections); g_ptr_array_free (aps_unique, TRUE); } static void ap_activated (GtkListBox *list, GtkListBoxRow *row, NetDeviceWifi *device_wifi) { NMConnection *connection; NMAccessPoint *ap; NMClient *client; NMDevice *nm_device; GtkWidget *edit; GtkWidget *stack; connection = NM_CONNECTION (g_object_get_data (G_OBJECT (row), "connection")); ap = NM_ACCESS_POINT (g_object_get_data (G_OBJECT (row), "ap")); edit = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "edit")); stack = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "button_stack")); if (ap != NULL) { if (connection != NULL) { gtk_widget_hide (edit); client = net_object_get_client (NET_OBJECT (device_wifi)); nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi)); nm_client_activate_connection_async (client, connection, nm_device, NULL, NULL, connection_activate_cb, device_wifi); } else { GBytes *ssid; const gchar *object_path; gtk_stack_set_visible_child_name (GTK_STACK (stack), "spinner"); ssid = nm_access_point_get_ssid (ap); object_path = nm_object_get_path (NM_OBJECT (ap)); wireless_try_to_connect (device_wifi, ssid, object_path); } } } static void net_device_wifi_init (NetDeviceWifi *device_wifi) { GError *error = NULL; GtkWidget *widget; GtkWidget *swin; GtkWidget *list; GtkSizeGroup *rows; GtkSizeGroup *icons; device_wifi->priv = NET_DEVICE_WIFI_GET_PRIVATE (device_wifi); device_wifi->priv->builder = gtk_builder_new (); gtk_builder_add_from_resource (device_wifi->priv->builder, "/org/cinnamon/control-center/network/network-wifi.ui", &error); if (error != NULL) { g_warning ("Could not load interface file: %s", error->message); g_error_free (error); return; } widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "details_dialog")); device_wifi->priv->details_dialog = widget; widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "hotspot-dialog")); device_wifi->priv->hotspot_dialog = widget; /* setup wifi views */ widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "device_off_switch")); g_signal_connect (widget, "notify::active", G_CALLBACK (device_off_toggled), device_wifi); swin = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "scrolledwindow_list")); list = GTK_WIDGET (gtk_list_box_new ()); gtk_widget_show (list); gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE); gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL); gtk_list_box_set_sort_func (GTK_LIST_BOX (list), (GtkListBoxSortFunc)ap_sort, NULL, NULL); gtk_container_add (GTK_CONTAINER (swin), list); g_signal_connect (list, "row-activated", G_CALLBACK (ap_activated), device_wifi); rows = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL); icons = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); g_object_set_data_full (G_OBJECT (list), "rows", rows, g_object_unref); g_object_set_data_full (G_OBJECT (list), "icons", icons, g_object_unref); /* setup view */ widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "notebook_view")); gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE); gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 0); widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "start_hotspot_button")); g_signal_connect (widget, "clicked", G_CALLBACK (start_hotspot), device_wifi); widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "connect_hidden_button")); g_signal_connect_swapped (widget, "clicked", G_CALLBACK (connect_to_hidden_network), device_wifi); widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "history_button")); g_signal_connect_swapped (widget, "clicked", G_CALLBACK (open_history), device_wifi); widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "switch_hotspot_off")); device_wifi->priv->hotspot_switch = GTK_SWITCH (widget); g_signal_connect (widget, "notify::active", G_CALLBACK (switch_hotspot_changed_cb), device_wifi); } cinnamon-control-center-6.4.1/panels/network/network-dialogs.h0000664000175000017500000000333214724311620023442 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2011 Giovanni Campagna * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef _NETWORK_DIALOGS_H #define _NETWORK_DIALOGS_H #include #include void cc_network_panel_create_wifi_network (GtkWidget *toplevel, NMClient *client); void cc_network_panel_connect_to_hidden_network (GtkWidget *toplevel, NMClient *client); void cc_network_panel_connect_to_8021x_network (GtkWidget *toplevel, NMClient *client, NMDevice *device, const gchar *arg_access_point); void cc_network_panel_connect_to_3g_network (GtkWidget *toplevel, NMClient *client, NMDevice *device); #endif /* _NETWORK_DIALOGS_H */ cinnamon-control-center-6.4.1/panels/network/network-vpn.ui0000664000175000017500000003760514724311620023023 0ustar fabiofabio True False 12 6 True False start 10 6 True False 1 VPN Type label_service_type 0 1 1 1 True False 1 Gateway label_gateway 0 2 1 1 True False 1 Group Name label_group_name 0 3 1 1 True False 1 Group Password label_group_password 0 4 1 1 True False 1 Username label_username 0 5 1 1 True True 0 openvpn True 1 1 2 1 True True 0 AA:BB:CC:DD:55:66:77:88 end 24 True 1 2 2 1 True True 0 SEKRIT True 1 3 2 1 True True 0 ********** True 1 4 2 1 True True 0 smithy True 1 5 2 1 True False end start 2 0 1 1 True False True 6 True False end start 1 48 network-vpn 6 False True 0 True False start True True False 0 VPN end False False 0 True False 0 Not connected False False 1 True True 1 True True end center Turn VPN connection off False True 2 0 0 3 1 True True 0 True False True True True end end True True True True False emblem-system-symbolic 1 Options… False True end 0 True True 1 cinnamon-control-center-6.4.1/panels/network/net-object.h0000664000175000017500000001061014724311620022360 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2011 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __NET_OBJECT_H #define __NET_OBJECT_H #include #include #include #include "cc-network-panel.h" G_BEGIN_DECLS #define NET_TYPE_OBJECT (net_object_get_type ()) #define NET_OBJECT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NET_TYPE_OBJECT, NetObject)) #define NET_OBJECT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NET_TYPE_OBJECT, NetObjectClass)) #define NET_IS_OBJECT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NET_TYPE_OBJECT)) #define NET_IS_OBJECT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NET_TYPE_OBJECT)) #define NET_OBJECT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NET_TYPE_OBJECT, NetObjectClass)) typedef struct _NetObjectPrivate NetObjectPrivate; typedef struct _NetObject NetObject; typedef struct _NetObjectClass NetObjectClass; G_DEFINE_AUTOPTR_CLEANUP_FUNC (NetObject, g_object_unref) struct _NetObject { GObject parent; NetObjectPrivate *priv; }; struct _NetObjectClass { GObjectClass parent_class; /* vtable */ GtkWidget *(*add_to_notebook) (NetObject *object, GtkNotebook *notebook, GtkSizeGroup *heading_size_group); void (*delete) (NetObject *object); void (*refresh) (NetObject *object); void (*edit) (NetObject *object); /* signal */ void (* changed) (NetObject *object); void (* removed) (NetObject *object); }; GType net_object_get_type (void); const gchar *net_object_get_id (NetObject *object); void net_object_set_id (NetObject *object, const gchar *id); const gchar *net_object_get_title (NetObject *object); void net_object_set_title (NetObject *object, const gchar *title); NMClient *net_object_get_client (NetObject *object); GCancellable *net_object_get_cancellable (NetObject *object); CcNetworkPanel *net_object_get_panel (NetObject *object); void net_object_emit_changed (NetObject *object); void net_object_emit_removed (NetObject *object); void net_object_delete (NetObject *object); void net_object_refresh (NetObject *object); void net_object_edit (NetObject *object); GtkWidget *net_object_add_to_notebook (NetObject *object, GtkNotebook *notebook, GtkSizeGroup *heading_size_group); gboolean net_object_get_removable (NetObject *object); void net_object_set_removable (NetObject *object, gboolean removable); G_END_DECLS #endif /* __NET_OBJECT_H */ cinnamon-control-center-6.4.1/panels/network/cinnamon-network-panel.desktop0000664000175000017500000001742414724311620026150 0ustar fabiofabio[Desktop Entry] Exec=cinnamon-settings network Icon=cs-network Terminal=false Type=Application StartupNotify=true Categories=GTK;Settings;HardwareSettings;X-Cinnamon-Settings-Panel; OnlyShowIn=X-Cinnamon; X-Cinnamon-Settings-Panel=network Name=Network Name[am]=įŠ”į‰µį‹Žįˆ­įŠ­ Name[ar]=Ų§Ł„Ų“ŲØŁƒŲ© Name[ast]=Rede Name[ay]=Llika Name[az]=Tor işi Name[be]=Детка Name[be@latin]=Детка Name[bg]=ŠœŃ€ŠµŠ¶Š° Name[br]=Rouedad Name[bs]=Mreža Name[ca]=Xarxa Name[ca@valencia]=Xarxa Name[cs]=SĆ­Å„ Name[cy]=Rhwydwaith Name[da]=NetvƦrk Name[de]=Netzwerk Name[el]=Δίκτυο Name[eo]=Reto Name[es]=Red Name[et]=VƵrk Name[eu]=Sarea Name[fa]=ؓبکه Name[fi]=Verkko Name[fr]=RĆ©seau Name[fr_CA]=RĆ©seau Name[gd]=LƬonra Name[gl]=Rede Name[he]=רשת Name[hi]=ą¤Øą„‡ą¤Ÿą¤µą¤°ą„ą¤• Name[hr]=Mreža Name[hu]=HĆ”lózat Name[ia]=Rete Name[id]=Jaringan Name[ie]=Rete Name[is]=Netkerfi Name[it]=Rete Name[ja]=ćƒćƒƒćƒˆćƒÆćƒ¼ć‚Æ Name[ka]=įƒ„įƒ”įƒ”įƒšįƒ˜ Name[kab]=Aįŗ“eįøįøa Name[kk]=Желі Name[km]=įž”įžŽįŸ’įžįž¶įž‰ Name[ko]=ė„¤ķŠøģ›Œķ¬ Name[ku]=Tor Name[la]=Rete Name[lt]=Tinklas Name[lv]=TÄ«kls Name[ms]=Rangkaian Name[nb]=Nettverk Name[nds]=Netzwerk Name[nl]=Netwerk Name[nn]=Nettverk Name[oc]=Ret Name[pa]=ąØØą©ˆą©±ąØŸąØµąØ°ąØ• Name[pl]=Sieć Name[pt]=Rede Name[pt_BR]=Rede Name[ro]=Rețea Name[ru]=Š”ŠµŃ‚ŃŒ Name[rue]=ŠœŃ€ŠµŠ¶Š° Name[sc]=Retza Name[sk]=SieÅ„ Name[sl]=Omrežje Name[sq]=Rrjeti Name[sr]=ŠœŃ€ŠµŠ¶Š° Name[sr@latin]=Mreža Name[sv]=NƤtverk Name[ta]=ą®µą®²ąÆˆą®Æą®®ąÆˆą®ŖąÆą®ŖąÆ Name[tg]=Шабака Name[th]=ąø£ąø°ąøšąøšą¹€ąø„ąø£ąø·ąø­ąø‚ą¹ˆąø²ąø¢ Name[tr]=Ağ Name[uk]=ŠœŠµŃ€ŠµŠ¶Š° Name[ur]=Ł†ŪŒŁ¹ ورک Name[uz]=Tarmoq Name[uz@cyrillic]=Tarmoq Name[vi]=Mįŗ”ng Name[zh_CN]=ē½‘ē»œ Name[zh_HK]=網絔 Name[zh_TW]=網路 Comment=Network settings Comment[am]=የ įŠ”į‰µį‹Žįˆ­įŠ­ įˆ›įˆ°įŠ“įŒƒ Comment[ar]=Ų„Ų¹ŲÆŲ§ŲÆŲ§ŲŖ Ų§Ł„Ų“ŲØŁƒŲ© Comment[ast]=Axustes de rede Comment[ay]=Llikan mayjachawi Comment[az]=Tor işi quruluşları Comment[be]=ŠŠ°Š»Š°Š“Ń‹ сеткі Comment[be@latin]=ŠŠ°Š»Š°Š“Ń‹ сеткі Comment[bg]=ŠœŃ€ŠµŠ¶Š¾Š²Šø настройки Comment[br]=Arventennoù ar rouedad Comment[bs]=Mrežne postavke Comment[ca]=Ajusts de la xarxa Comment[ca@valencia]=ParĆ metres de la xarxa Comment[cs]=NastavenĆ­ sĆ­tě Comment[cy]=Gosodiadau rhwydwaith Comment[da]=NetvƦrksindstillinger Comment[de]=Netzwerkeinstellungen Comment[el]=Ī”Ļ…ĪøĪ¼ĪÆĻƒĪµĪ¹Ļ‚ του Ī“Ī¹ĪŗĻ„ĻĪæĻ… Comment[eo]=Retagordoj Comment[es]=Configuración de la red Comment[et]=VƵrguseaded Comment[eu]=Sareko ezarpenak Comment[fa]=ŲŖŁ†ŲøŪŒŁ…Ų§ŲŖ ؓبکه Comment[fi]=Verkon asetukset Comment[fr]=ParamĆØtres rĆ©seau Comment[fr_CA]=ParamĆØtres du rĆ©seau Comment[gd]=Roghainnean an lƬonraidh Comment[gl]=Axustes da rede Comment[he]=הגדרות רשת Comment[hi]=ą¤Øą„‡ą¤Ÿą¤µą¤°ą„ą¤• ą¤øą„‡ą¤Ÿą¤æą¤‚ą¤—ą„ą¤ø Comment[hr]=Mrežne postavke Comment[hu]=HĆ”lózati beĆ”llĆ­tĆ”sok Comment[ia]=Configurationes de rete Comment[id]=Pengaturan jaringan Comment[ie]=Parametres de rete Comment[is]=Netstillingar Comment[it]=Impostazioni di rete Comment[ja]=ćƒćƒƒćƒˆćƒÆćƒ¼ć‚Æć®čØ­å®š Comment[ka]=įƒ„įƒ”įƒ”įƒšįƒ˜įƒ” įƒ›įƒįƒ įƒ’įƒ”įƒ‘įƒ Comment[kab]=IÉ£ewwaren uzeį¹­į¹­a Comment[kk]=Желі Š±Š°ŠæŃ‚Š°ŃƒŠ»Š°Ń€Ń‹ Comment[ko]=ė„¤ķŠøģ›Œķ¬ 설정 Comment[ku]=MĆ®hengĆŖn torĆŖ Comment[la]=Configuratio retis Comment[lt]=Tinklo nustatymai Comment[lv]=TÄ«kla iestatÄ«jumi Comment[ms]=Tetapan rangkaian Comment[nb]=Nettverksinnstillinger Comment[nds]=Netzwerkeinstellungen Comment[nl]=Netwerkinstellingen Comment[nn]=Nettverk innstillingar Comment[oc]=ParamĆØtres de la ret Comment[pl]=Ustawienia sieci Comment[pt]=DefiniƧƵes de rede Comment[pt_BR]=ConfiguraƧƵes de Rede Comment[ro]=Setări rețea Comment[ru]=ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø сети Comment[sc]=SĆØberos de sa retza Comment[sk]=Nastavenie siete Comment[sl]=Omrežne nastavitve Comment[sq]=Parametrat e rrjetit Comment[sr]=ПоГешавања мреже Comment[sr@latin]=PodeÅ”avanja mreže Comment[sv]=NƤtverksinstƤllningar Comment[ta]=பிணைய ą®…ą®®ąÆˆą®ŖąÆą®ŖąÆą®•ą®³ąÆ Comment[tg]=Танзимоти шабака Comment[th]=ąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø²ą¹€ąø„ąø£ąø·ąø­ąø‚ą¹ˆąø²ąø¢ Comment[tr]=Ağ ayarları Comment[uk]=ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń мережі Comment[ur]=Ł†ŪŒŁ¹ ورک کی ترتیبات Comment[uz]=Tarmoq moslamalari Comment[uz@cyrillic]=Tarmoq moslamalari Comment[vi]=CĆ i đặt mįŗ”ng Comment[zh_CN]=ē½‘ē»œč®¾ē½® Comment[zh_HK]=網絔設定 Comment[zh_TW]=網路設定 Keywords=Network;Wireless;IP;LAN;Proxy;Internet;WiFi; Keywords[ast]=Rede;InalĆ”mbrica;IP;LAN;Proxy;Internet;WiFi; Keywords[be]=сетка;Š±ŠµŃŠæŃ€Š°Š²Š°Š“Š½Š°Ń;ŠæŃ€Š°Š²Š°Š“Š½Š°Ń;IP;LAN;проксі;Ń–Š½Ń‚ŃŃ€Š½ŃŃ‚;WiFi; Keywords[be@latin]=сетка;Š±ŠµŃŠæŃ€Š°Š²Š°Š“Š½Š°Ń;ŠæŃ€Š°Š²Š°Š“Š½Š°Ń;IP;LAN;проксі;Ń–Š½Ń‚ŃŃ€Š½ŃŃ‚;WiFi; Keywords[br]=Rouedad;Diorjal;IP;LAN;Proksi;Internet;Wi-Fi; Keywords[ca]=Xarxa;Sense fil;IP;LAN;Proxy;Internet;WiFi; Keywords[ca@valencia]=Xarxa;Sense fil;IP;LAN;Proxy;Internet;WiFi; Keywords[cs]=SĆ­Å„;bezdrĆ”tovĆ”;IP;LAN;proxy;Internet;WiFi; Keywords[cy]=Rhwydwaith;Diwifr;IP;Dirprwy;Rhyngrwyd;WiFi; Keywords[da]=NetvƦrk;TrĆ„dlĆøs;IP;LAN;Proxy;Internet;Wi-fi; Keywords[de]=Network;Wireless;IP;LAN;Proxy;Internet;WiFi;Netzwerk;drahtlos;Vermittlung;WLAN; Keywords[el]=Δίκτυο;Ī‘ĻƒĻĻĪ¼Ī±Ļ„Īæ;IP;LAN;Proxy;ΔιαΓίκτυο;WiFi; Keywords[eo]=Reto;Sendrata;Interreta protokolo;Loka reto;Prokurilo;Interreto;Vifio; Keywords[es]=Red;InalĆ”mbrico;IP;LAN;Proxy;Internet;WiFi; Keywords[et]=VƵrk;traadita ühendus;IP;LAN;puhverserver;Internet;WiFi; Keywords[eu]=Sarea;Haririk gabekoa;IP;LAN;Proxy;Internet;WiFi; Keywords[fa]=Ų“ŲØŚ©Ł‡ŲŒ ŲØŪŒā€ŒŲ³ŪŒŁ…ŲŒ IP، LAN، پروکسی، Ų§ŪŒŁ†ŲŖŲ±Ł†ŲŖŲŒ ŁˆŲ§ŪŒā€ŒŁŲ§ŪŒ; Keywords[fi]=Verkko;Langaton;IP;LAN;VƤlityspalvelin;Internet;WiFi; Keywords[fr]=RĆ©seau;Sans-fil;IP;LAN;Proxy;Internet;WiFi; Keywords[fr_CA]=RĆ©seau;Sans-fil;IP;LAN;Proxy;Internet;WiFi; Keywords[he]=רשת;אל־חוטי;IP;LN;×ž×Ŗ×•×•×š;×ž×Ø×©×Ŗ×Ŗ;WiFi; Keywords[hi]=ą¤Øą„‡ą¤Ÿą¤µą¤°ą„ą¤•;ą¤µą¤¾ą¤Æą¤°ą¤²ą„‡ą¤ø;ą¤†ą¤ˆą¤Ŗą„€;ą¤²ą„ˆą¤Ø;ą¤Ŗą„ą¤°ą„‰ą¤•ą„ą¤øą„€;ą¤‡ą¤‚ą¤Ÿą¤°ą¤Øą„‡ą¤Ÿ;वाईफाई; Keywords[hr]=Mreža;Bežična mreža;IP;LAN;Proxy;Internet;WiFi; Keywords[hu]=HĆ”lózat;VezetĆ©k nĆ©lküli;Wi-Fi;Wifi;IP;LAN;SzĆ©les sĆ”v;SzĆ©lessĆ”v;DNS;Network;Wireless;IP;LAN;Proxy;Internet; Keywords[ia]=Rete;Sin filos;IP;LAN;Proxy;Internet;WiFi; Keywords[id]=Jaringan;Nirkabel;IP;LAN;Proxy;Internet;WiFi; Keywords[is]=Netkerfi;ƞrƔưlaust;IP;LAN;Milliþjónn;Internet;WiFi; Keywords[it]=Rete;Wireless;IP;LAN;Proxy;Internet;WiFi; Keywords[ja]=Network;Wireless;IP;LAN;Proxy;Internet;WiFi;ćƒćƒƒćƒˆćƒÆćƒ¼ć‚Æ;ćƒÆć‚¤ćƒ¤ćƒ¬ć‚¹;ćƒ—ćƒ­ć‚­ć‚·;ć‚¤ćƒ³ć‚æćƒ¼ćƒćƒƒćƒˆ; Keywords[ko]=ė„¤ķŠøģ›Œķ¬;묓선;IP;LAN;ķ”„ė”ģ‹œ;ģøķ„°ė„·;WiFi; Keywords[nb]=Nettverk;TrĆ„dlĆøs;IP;LAN;Proxy;Internett;WiFi; Keywords[nl]=Netwerk;Draadloos;IP;LAN;Proxy;Internet;WiFi; Keywords[oc]=Ret;Sens fil;LAN;Proxy;Internet;WiFi; Keywords[pl]=Sieć;Bezprzewodowa;IP;LAN;Proxy;Internet;WiFi; Keywords[pt]=Rede;Sem fios;IP;LAN;Proxy;Internet;WiFi; Keywords[pt_BR]=Rede;Sem fio;IP;LAN;Proxy;Internet;WiFi; Keywords[ro]=Rețea;Wireless;IP;LAN;Proxy;Internet;WiFi; Keywords[ru]=Š”ŠµŃ‚ŃŒ;Š‘ŠµŃŠæŃ€Š¾Š²Š¾Š“Š½Š°Ń ŃŠ²ŃŠ·ŃŒ;IP;Š›Š¾ŠŗŠ°Š»ŃŒŠ½Š°Ń ŃŠµŃ‚ŃŒ;ŠŸŃ€Š¾ŠŗŃŠø;интернет;Š‘ŠµŃŠæŃ€Š¾Š²Š¾Š“Š½Š°Ń ŃŠµŃ‚ŃŒ; Keywords[sk]=SieÅ„;BezdrĆ“tovĆ© pripojenie;IP;LAN;Proxy;Internet;WiFi; Keywords[sl]=Omrežje;brezžično;IP;LAN;internet;wifi;posredovalni strežnik; Keywords[sv]=NƤtverk;TrĆ„dlƶst;IP;LAN;Proxy;Internet;TrĆ„dlƶst nƤtverk; Keywords[tr]=Ağ;Kablosuz;IP;LAN;Vekil;Internet;Kablosuz ağ; Keywords[uk]=ŠœŠµŃ€ŠµŠ¶Š°;БезГротові мережі;IP;Š›Š¾ŠŗŠ°Š»ŃŒŠ½Š° мережа;ŠŸŃ€Š¾ŠŗŃŃ–;Інтернет;WiFi; Keywords[uz]=Tarmoq;Simsiz;IP;LAN;Proksi;Internet;WiFi; Keywords[uz@cyrillic]=Tarmoq;Simsiz;IP;LAN;Proksi;Internet;WiFi; Keywords[vi]=Mįŗ”ng;KhĆ“ng dĆ¢y;IP;LAN;Proxy;Internet;WiFi; Keywords[zh_TW]=網路;ē„”ē·šē¶²č·Æ;IP;å€åŸŸē¶±č·Æ;代理;ē¶²éš›ē¶²č·Æ;WiFi; cinnamon-control-center-6.4.1/panels/network/net-device-ethernet.c0000664000175000017500000006051414724311620024170 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2011-2012 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include "panel-common.h" #include "shell/list-box-helper.h" #include "connection-editor/net-connection-editor.h" #include "connection-editor/ce-page.h" #include "net-device-ethernet.h" G_DEFINE_TYPE (NetDeviceEthernet, net_device_ethernet, NET_TYPE_DEVICE_SIMPLE) static char * device_ethernet_get_speed (NetDeviceSimple *device_simple) { NMDevice *nm_device; guint speed; nm_device = net_device_get_nm_device (NET_DEVICE (device_simple)); speed = nm_device_ethernet_get_speed (NM_DEVICE_ETHERNET (nm_device)); if (speed > 0) { /* Translators: network device speed */ return g_strdup_printf (_("%d Mb/s"), speed); } else return NULL; } static GtkWidget * device_ethernet_add_to_notebook (NetObject *object, GtkNotebook *notebook, GtkSizeGroup *heading_size_group) { NetDeviceEthernet *device = NET_DEVICE_ETHERNET (object); GtkWidget *vbox; vbox = GTK_WIDGET (gtk_builder_get_object (device->builder, "vbox6")); gtk_notebook_append_page (notebook, vbox, NULL); return vbox; } static void add_details_row (GtkWidget *details, gint top, const gchar *heading, const gchar *value) { GtkWidget *heading_label; GtkWidget *value_label; heading_label = gtk_label_new (heading); gtk_style_context_add_class (gtk_widget_get_style_context (heading_label), "dim-label"); gtk_widget_set_halign (heading_label, GTK_ALIGN_END); gtk_widget_set_valign (heading_label, GTK_ALIGN_START); gtk_widget_set_hexpand (heading_label, TRUE); gtk_grid_attach (GTK_GRID (details), heading_label, 0, top, 1, 1); value_label = gtk_label_new (value); gtk_widget_set_halign (value_label, GTK_ALIGN_START); gtk_widget_set_hexpand (value_label, TRUE); gtk_label_set_mnemonic_widget (GTK_LABEL (heading_label), value_label); gtk_grid_attach (GTK_GRID (details), value_label, 1, top, 1, 1); } static gchar * get_last_used_string (NMConnection *connection) { gchar *last_used = NULL; GDateTime *now = NULL; GDateTime *then = NULL; gint days; GTimeSpan diff; guint64 timestamp; NMSettingConnection *s_con; s_con = nm_connection_get_setting_connection (connection); if (s_con == NULL) goto out; timestamp = nm_setting_connection_get_timestamp (s_con); if (timestamp == 0) { last_used = g_strdup (_("never")); goto out; } /* calculate the amount of time that has elapsed */ now = g_date_time_new_now_utc (); then = g_date_time_new_from_unix_utc (timestamp); diff = g_date_time_difference (now, then); days = diff / G_TIME_SPAN_DAY; if (days == 0) last_used = g_strdup (_("today")); else if (days == 1) last_used = g_strdup (_("yesterday")); else last_used = g_strdup_printf (ngettext ("%i day ago", "%i days ago", days), days); out: if (now != NULL) g_date_time_unref (now); if (then != NULL) g_date_time_unref (then); return last_used; } static void add_details (GtkWidget *details, NMDevice *device, NMConnection *connection) { NMIPConfig *ip4_config = NULL; NMIPConfig *ip6_config = NULL; g_autofree gchar *ip4_address = NULL; g_autofree gchar *ip4_route = NULL; g_autofree gchar *ip4_dns = NULL; g_autofree gchar *ip6_address = NULL; g_autofree gchar *ip6_route = NULL; g_autofree gchar *ip6_dns = NULL; gint i = 0; ip4_config = nm_device_get_ip4_config (device); if (ip4_config) { ip4_address = panel_get_ip4_address_as_string (ip4_config, "address"); ip4_route = panel_get_ip4_address_as_string (ip4_config, "gateway"); ip4_dns = panel_get_dns_as_string (ip4_config); } ip6_config = nm_device_get_ip6_config (device); if (ip6_config) { ip6_address = panel_get_ip6_address_as_string (ip6_config, "address"); ip6_route = panel_get_ip6_address_as_string (ip6_config, "gateway"); ip6_dns = panel_get_dns_as_string (ip6_config); } if (ip4_address && ip6_address) { add_details_row (details, i++, _("IPv4 Address"), ip4_address); add_details_row (details, i++, _("IPv6 Address"), ip6_address); } else if (ip4_address) { add_details_row (details, i++, _("IP Address"), ip4_address); } else if (ip6_address) { add_details_row (details, i++, _("IP Address"), ip6_address); } add_details_row (details, i++, _("Hardware Address"), nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (device))); if (ip4_route && ip6_route) { g_autofree gchar *ip_routes = g_strjoin ("\n", ip4_route, ip6_route, NULL); add_details_row (details, i++, _("Default Route"), ip_routes); } else if (ip4_route) { add_details_row (details, i++, _("Default Route"), ip4_route); } else if (ip6_route) { add_details_row (details, i++, _("Default Route"), ip6_route); } if (ip4_dns && ip6_dns) { add_details_row (details, i++, _("DNS4"), ip4_dns); add_details_row (details, i++, _("DNS6"), ip6_dns); } else if (ip4_dns) { add_details_row (details, i++, _("DNS"), ip4_dns); } else if (ip6_dns) { add_details_row (details, i++, _("DNS"), ip6_dns); } if (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED) { g_autofree gchar *last_used = NULL; last_used = get_last_used_string (connection); add_details_row (details, i++, _("Last used"), last_used); } } static void populate_ui (NetDeviceEthernet *device); static gboolean device_state_to_off_switch (NMDeviceState state) { switch (state) { case NM_DEVICE_STATE_UNMANAGED: case NM_DEVICE_STATE_UNAVAILABLE: case NM_DEVICE_STATE_DISCONNECTED: case NM_DEVICE_STATE_DEACTIVATING: case NM_DEVICE_STATE_FAILED: return FALSE; default: return TRUE; } } static void device_ethernet_refresh_ui (NetDeviceEthernet *device) { NMDevice *nm_device; NMDeviceState state; GtkWidget *widget; g_autofree gchar *speed = NULL; nm_device = net_device_get_nm_device (NET_DEVICE (device)); widget = GTK_WIDGET (gtk_builder_get_object (device->builder, "label_device")); gtk_label_set_label (GTK_LABEL (widget), net_object_get_title (NET_OBJECT (device))); widget = GTK_WIDGET (gtk_builder_get_object (device->builder, "image_device")); gtk_image_set_from_icon_name (GTK_IMAGE (widget), panel_device_to_icon_name (nm_device, FALSE), GTK_ICON_SIZE_DIALOG); widget = GTK_WIDGET (gtk_builder_get_object (device->builder, "device_off_switch")); state = nm_device_get_state (nm_device); gtk_widget_set_visible (widget, state != NM_DEVICE_STATE_UNAVAILABLE && state != NM_DEVICE_STATE_UNMANAGED); device->updating_device = TRUE; gtk_switch_set_active (GTK_SWITCH (widget), device_state_to_off_switch (state)); device->updating_device = FALSE; if (state != NM_DEVICE_STATE_UNAVAILABLE) speed = net_device_simple_get_speed (NET_DEVICE_SIMPLE (device)); panel_set_device_status (device->builder, "label_status", nm_device, speed); populate_ui (device); } static void editor_done (NetConnectionEditor *editor, gboolean success, NetDeviceEthernet *device) { g_object_unref (editor); device_ethernet_refresh_ui (device); } static void show_details (GtkButton *button, NetDeviceEthernet *device, const gchar *title) { GtkWidget *row; NMConnection *connection; GtkWidget *window; NetConnectionEditor *editor; NMClient *client; NMDevice *nmdev; window = gtk_widget_get_toplevel (GTK_WIDGET (button)); row = GTK_WIDGET (g_object_get_data (G_OBJECT (button), "row")); connection = NM_CONNECTION (g_object_get_data (G_OBJECT (row), "connection")); nmdev = net_device_get_nm_device (NET_DEVICE (device)); client = net_object_get_client (NET_OBJECT (device)); editor = net_connection_editor_new (GTK_WINDOW (window), connection, nmdev, NULL, client); if (title) net_connection_editor_set_title (editor, title); g_signal_connect (editor, "done", G_CALLBACK (editor_done), device); net_connection_editor_run (editor); } static void show_details_for_row (GtkButton *button, NetDeviceEthernet *device) { show_details (button, device, NULL); } static void show_details_for_wired (GtkButton *button, NetDeviceEthernet *device) { /* Translators: This is used as the title of the connection * details window for ethernet, if there is only a single * profile. It is also used to display ethernet in the * device list. */ show_details (button, device, _("Wired")); } static void add_row (NetDeviceEthernet *device, NMConnection *connection) { GtkWidget *row; GtkWidget *widget; GtkWidget *box; GtkWidget *details; NMDevice *nmdev; NMActiveConnection *aconn; gboolean active; GtkWidget *image; active = FALSE; nmdev = net_device_get_nm_device (NET_DEVICE (device)); aconn = nm_device_get_active_connection (nmdev); if (aconn) { const gchar *uuid1, *uuid2; uuid1 = nm_active_connection_get_uuid (aconn); uuid2 = nm_connection_get_uuid (connection); active = g_strcmp0 (uuid1, uuid2) == 0; } row = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start (GTK_BOX (row), box, FALSE, TRUE, 0); widget = gtk_label_new (nm_connection_get_id (connection)); gtk_widget_set_margin_start (widget, 12); gtk_widget_set_margin_end (widget, 12); gtk_widget_set_margin_top (widget, 12); gtk_widget_set_margin_bottom (widget, 12); gtk_box_pack_start (GTK_BOX (box), widget, FALSE, TRUE, 0); if (active) { widget = gtk_image_new_from_icon_name ("object-select-symbolic", GTK_ICON_SIZE_MENU); gtk_widget_set_halign (widget, GTK_ALIGN_CENTER); gtk_widget_set_valign (widget, GTK_ALIGN_CENTER); gtk_box_pack_start (GTK_BOX (box), widget, FALSE, TRUE, 0); details = gtk_grid_new (); gtk_grid_set_row_spacing (GTK_GRID (details), 10); gtk_grid_set_column_spacing (GTK_GRID (details), 10); gtk_box_pack_start (GTK_BOX (row), details, FALSE, TRUE, 0); add_details (details, nmdev, connection); } /* filler */ widget = gtk_label_new (""); gtk_widget_set_hexpand (widget, TRUE); gtk_box_pack_start (GTK_BOX (box), widget, TRUE, TRUE, 0); image = gtk_image_new_from_icon_name ("emblem-system-symbolic", GTK_ICON_SIZE_MENU); gtk_widget_show (image); widget = gtk_button_new (); gtk_style_context_add_class (gtk_widget_get_style_context (widget), "image-button"); gtk_widget_set_margin_start (widget, 12); gtk_widget_set_margin_end (widget, 12); gtk_widget_set_margin_top (widget, 12); gtk_widget_set_margin_bottom (widget, 12); gtk_widget_show (widget); gtk_container_add (GTK_CONTAINER (widget), image); gtk_widget_set_halign (widget, GTK_ALIGN_CENTER); gtk_widget_set_valign (widget, GTK_ALIGN_CENTER); atk_object_set_name (gtk_widget_get_accessible (widget), _("Options…")); gtk_box_pack_start (GTK_BOX (box), widget, FALSE, TRUE, 0); g_object_set_data (G_OBJECT (row), "edit", widget); g_object_set_data (G_OBJECT (widget), "row", row); g_signal_connect (widget, "clicked", G_CALLBACK (show_details_for_row), device); gtk_widget_show_all (row); g_object_set_data (G_OBJECT (row), "connection", connection); gtk_container_add (GTK_CONTAINER (device->list), row); } static void connection_removed (NMClient *client, NMRemoteConnection *connection, NetDeviceEthernet *device) { if (g_hash_table_remove (device->connections, connection)) device_ethernet_refresh_ui (device); } static void populate_ui (NetDeviceEthernet *device) { GList *children, *c; GSList *connections, *l; NMConnection *connection; gint n_connections; children = gtk_container_get_children (GTK_CONTAINER (device->list)); for (c = children; c; c = c->next) { gtk_container_remove (GTK_CONTAINER (device->list), c->data); } g_list_free (children); children = gtk_container_get_children (GTK_CONTAINER (device->details)); for (c = children; c; c = c->next) { gtk_container_remove (GTK_CONTAINER (device->details), c->data); } g_list_free (children); connections = net_device_get_valid_connections (NET_DEVICE (device)); for (l = connections; l; l = l->next) { NMConnection *connection = l->data; if (!g_hash_table_contains (device->connections, connection)) { g_hash_table_add (device->connections, connection); } } n_connections = g_slist_length (connections); if (n_connections > 4) { gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (device->scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_widget_set_vexpand (device->scrolled_window, TRUE); } else { gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (device->scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_NEVER); gtk_widget_set_vexpand (device->scrolled_window, FALSE); } if (n_connections > 1) { gtk_widget_hide (device->details); gtk_widget_hide (device->details_button); for (l = connections; l; l = l->next) { NMConnection *connection = l->data; add_row (device, connection); } gtk_widget_show (device->scrolled_window); } else if (n_connections == 1) { connection = connections->data; gtk_widget_hide (device->scrolled_window); add_details (device->details, net_device_get_nm_device (NET_DEVICE (device)), connection); gtk_widget_show_all (device->details); gtk_widget_show (device->details_button); g_object_set_data (G_OBJECT (device->details_button), "row", device->details_button); g_object_set_data (G_OBJECT (device->details_button), "connection", connection); } else { gtk_widget_hide (device->scrolled_window); gtk_widget_hide (device->details); gtk_widget_hide (device->details_button); } g_slist_free (connections); } static void client_connection_added_cb (NMClient *client, NMRemoteConnection *connection, NetDeviceEthernet *device) { device_ethernet_refresh_ui (device); } static void add_profile (GtkButton *button, NetDeviceEthernet *device) { NMConnection *connection; NMSettingConnection *sc; gchar *uuid, *id; NetConnectionEditor *editor; GtkWidget *window; NMClient *client; NMDevice *nmdev; const GPtrArray *connections; connection = nm_simple_connection_new (); sc = NM_SETTING_CONNECTION (nm_setting_connection_new ()); nm_connection_add_setting (connection, NM_SETTING (sc)); uuid = nm_utils_uuid_generate (); client = net_object_get_client (NET_OBJECT (device)); connections = nm_client_get_connections (client); id = ce_page_get_next_available_name (connections, NAME_FORMAT_PROFILE, NULL); g_object_set (sc, NM_SETTING_CONNECTION_UUID, uuid, NM_SETTING_CONNECTION_ID, id, NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NULL); nm_connection_add_setting (connection, nm_setting_wired_new ()); g_free (uuid); g_free (id); window = gtk_widget_get_toplevel (GTK_WIDGET (button)); nmdev = net_device_get_nm_device (NET_DEVICE (device)); editor = net_connection_editor_new (GTK_WINDOW (window), connection, nmdev, NULL, client); g_signal_connect (editor, "done", G_CALLBACK (editor_done), device); net_connection_editor_run (editor); } static void device_off_toggled (GtkSwitch *sw, GParamSpec *pspec, NetDeviceEthernet *device) { NMClient *client; NMDevice *nm_device; NMConnection *connection; if (device->updating_device) return; client = net_object_get_client (NET_OBJECT (device)); nm_device = net_device_get_nm_device (NET_DEVICE (device)); if (gtk_switch_get_active (sw)) { connection = net_device_get_find_connection (NET_DEVICE (device)); if (connection != NULL) { nm_client_activate_connection_async (client, connection, nm_device, NULL, NULL, NULL, NULL); } } else { nm_device_disconnect (nm_device, NULL, NULL); } } static void device_title_changed (NetDeviceEthernet *device, GParamSpec *pspec, gpointer user_data) { device_ethernet_refresh_ui (device); } static void connection_activated (GtkListBox *list, GtkListBoxRow *row, NetDeviceEthernet *device) { NMClient *client; NMDevice *nm_device; NMConnection *connection; client = net_object_get_client (NET_OBJECT (device)); nm_device = net_device_get_nm_device (NET_DEVICE (device)); if (!NM_IS_DEVICE_ETHERNET (nm_device) || !nm_device_ethernet_get_carrier (NM_DEVICE_ETHERNET (nm_device))) return; connection = NM_CONNECTION (g_object_get_data (G_OBJECT (gtk_bin_get_child (GTK_BIN (row))), "connection")); nm_client_activate_connection_async (client, connection, nm_device, NULL, NULL, NULL, NULL); } static void device_ethernet_constructed (GObject *object) { NetDeviceEthernet *device = NET_DEVICE_ETHERNET (object); NMClient *client; GtkWidget *list; GtkWidget *swin; GtkWidget *widget; widget = GTK_WIDGET (gtk_builder_get_object (device->builder, "device_off_switch")); g_signal_connect (widget, "notify::active", G_CALLBACK (device_off_toggled), device); device->scrolled_window = swin = GTK_WIDGET (gtk_builder_get_object (device->builder, "list")); device->list = list = GTK_WIDGET (gtk_list_box_new ()); gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE); gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL); gtk_container_add (GTK_CONTAINER (swin), list); g_signal_connect (list, "row-activated", G_CALLBACK (connection_activated), device); gtk_widget_show (list); device->details = GTK_WIDGET (gtk_builder_get_object (device->builder, "details")); device->details_button = GTK_WIDGET (gtk_builder_get_object (device->builder, "details_button")); g_signal_connect (device->details_button, "clicked", G_CALLBACK (show_details_for_wired), device); device->add_profile_button = GTK_WIDGET (gtk_builder_get_object (device->builder, "add_profile_button")); g_signal_connect (device->add_profile_button, "clicked", G_CALLBACK (add_profile), device); client = net_object_get_client (NET_OBJECT (object)); g_signal_connect (client, NM_CLIENT_CONNECTION_ADDED, G_CALLBACK (client_connection_added_cb), object); g_signal_connect_object (client, NM_CLIENT_CONNECTION_REMOVED, G_CALLBACK (connection_removed), device, 0); device_ethernet_refresh_ui (device); } static void device_ethernet_finalize (GObject *object) { NetDeviceEthernet *device = NET_DEVICE_ETHERNET (object); g_object_unref (device->builder); g_hash_table_destroy (device->connections); G_OBJECT_CLASS (net_device_ethernet_parent_class)->finalize (object); } static void device_ethernet_refresh (NetObject *object) { NetDeviceEthernet *device = NET_DEVICE_ETHERNET (object); device_ethernet_refresh_ui (device); } static void net_device_ethernet_class_init (NetDeviceEthernetClass *klass) { NetDeviceSimpleClass *simple_class = NET_DEVICE_SIMPLE_CLASS (klass); NetObjectClass *obj_class = NET_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); simple_class->get_speed = device_ethernet_get_speed; obj_class->refresh = device_ethernet_refresh; obj_class->add_to_notebook = device_ethernet_add_to_notebook; object_class->constructed = device_ethernet_constructed; object_class->finalize = device_ethernet_finalize; } static void net_device_ethernet_init (NetDeviceEthernet *device) { GError *error = NULL; device->builder = gtk_builder_new (); gtk_builder_add_from_resource (device->builder, "/org/cinnamon/control-center/network/network-ethernet.ui", &error); if (error != NULL) { g_warning ("Could not load interface file: %s", error->message); g_error_free (error); return; } device->connections = g_hash_table_new (NULL, NULL); g_signal_connect (device, "notify::title", G_CALLBACK (device_title_changed), NULL); } cinnamon-control-center-6.4.1/panels/network/net-device.h0000664000175000017500000000456714724311620022367 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2011 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __NET_DEVICE_H #define __NET_DEVICE_H #include #include #include "net-object.h" G_BEGIN_DECLS #define NET_TYPE_DEVICE (net_device_get_type ()) #define NET_DEVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NET_TYPE_DEVICE, NetDevice)) #define NET_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NET_TYPE_DEVICE, NetDeviceClass)) #define NET_IS_DEVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NET_TYPE_DEVICE)) #define NET_IS_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NET_TYPE_DEVICE)) #define NET_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NET_TYPE_DEVICE, NetDeviceClass)) typedef struct _NetDevicePrivate NetDevicePrivate; typedef struct _NetDevice NetDevice; typedef struct _NetDeviceClass NetDeviceClass; struct _NetDevice { NetObject parent; NetDevicePrivate *priv; }; struct _NetDeviceClass { NetObjectClass parent_class; NMConnection * (*get_find_connection) (NetDevice *device); }; GType net_device_get_type (void); NetDevice *net_device_new (void); NMDevice *net_device_get_nm_device (NetDevice *device); NMConnection *net_device_get_find_connection (NetDevice *device); GSList *net_device_get_valid_connections (NetDevice *device); G_END_DECLS #endif /* __NET_DEVICE_H */ cinnamon-control-center-6.4.1/panels/network/net-device-simple.h0000664000175000017500000000504314724311620023644 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2011-2012 Richard Hughes * Copyright (C) 2012 Red Hat, Inc. * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __NET_DEVICE_SIMPLE_H #define __NET_DEVICE_SIMPLE_H #include #include "net-device.h" G_BEGIN_DECLS #define NET_TYPE_DEVICE_SIMPLE (net_device_simple_get_type ()) #define NET_DEVICE_SIMPLE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NET_TYPE_DEVICE_SIMPLE, NetDeviceSimple)) #define NET_DEVICE_SIMPLE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NET_TYPE_DEVICE_SIMPLE, NetDeviceSimpleClass)) #define NET_IS_DEVICE_SIMPLE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NET_TYPE_DEVICE_SIMPLE)) #define NET_IS_DEVICE_SIMPLE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NET_TYPE_DEVICE_SIMPLE)) #define NET_DEVICE_SIMPLE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NET_TYPE_DEVICE_SIMPLE, NetDeviceSimpleClass)) typedef struct _NetDeviceSimplePrivate NetDeviceSimplePrivate; typedef struct _NetDeviceSimple NetDeviceSimple; typedef struct _NetDeviceSimpleClass NetDeviceSimpleClass; struct _NetDeviceSimple { NetDevice parent; NetDeviceSimplePrivate *priv; }; struct _NetDeviceSimpleClass { NetDeviceClass parent_class; char *(*get_speed) (NetDeviceSimple *device_simple); }; GType net_device_simple_get_type (void); char *net_device_simple_get_speed (NetDeviceSimple *device_simple); void net_device_simple_add_row (NetDeviceSimple *device_simple, const char *label, const char *property_name); G_END_DECLS #endif /* __NET_DEVICE_SIMPLE_H */ cinnamon-control-center-6.4.1/panels/network/network.ui0000664000175000017500000001755314724311620022222 0ustar fabiofabio 65535 1 65535 1 65535 1 65535 1 True False 12 550 6 6 6 6 True False 3 True False 6 True False 12 12 12 True True never in True True liststore_devices False 2 False True True 0 True False icons False 1 False True False False Add Device True list-add-symbolic False True False True False False Remove Device True list-remove-symbolic False True False True 1 True True 0 True True False True True 1 True True 0 True True 0 cinnamon-control-center-6.4.1/panels/network/net-proxy.h0000664000175000017500000000400714724311620022276 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2011-2012 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __NET_PROXY_H #define __NET_PROXY_H #include #include "net-object.h" G_BEGIN_DECLS #define NET_TYPE_PROXY (net_proxy_get_type ()) #define NET_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NET_TYPE_PROXY, NetProxy)) #define NET_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NET_TYPE_PROXY, NetProxyClass)) #define NET_IS_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NET_TYPE_PROXY)) #define NET_IS_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NET_TYPE_PROXY)) #define NET_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NET_TYPE_PROXY, NetProxyClass)) typedef struct _NetProxyPrivate NetProxyPrivate; typedef struct _NetProxy NetProxy; typedef struct _NetProxyClass NetProxyClass; struct _NetProxy { NetObject parent; NetProxyPrivate *priv; }; struct _NetProxyClass { NetObjectClass parent_class; }; GType net_proxy_get_type (void); NetProxy *net_proxy_new (void); G_END_DECLS #endif /* __NET_PROXY_H */ cinnamon-control-center-6.4.1/panels/network/net-device.c0000664000175000017500000002665314724311620022362 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2011 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include #include "net-device.h" #define NET_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NET_TYPE_DEVICE, NetDevicePrivate)) struct _NetDevicePrivate { NMDevice *nm_device; guint changed_id; }; enum { PROP_0, PROP_DEVICE, PROP_LAST }; G_DEFINE_TYPE (NetDevice, net_device, NET_TYPE_OBJECT) /* return value must be freed by caller with g_free() */ static gchar * get_mac_address_of_connection (NMConnection *connection) { if (!connection) return NULL; /* check the connection type */ if (nm_connection_is_type (connection, NM_SETTING_WIRELESS_SETTING_NAME)) { /* check wireless settings */ NMSettingWireless *s_wireless = nm_connection_get_setting_wireless (connection); if (!s_wireless) return NULL; return g_strdup (nm_setting_wireless_get_mac_address (s_wireless)); } else if (nm_connection_is_type (connection, NM_SETTING_WIRED_SETTING_NAME)) { /* check wired settings */ NMSettingWired *s_wired = nm_connection_get_setting_wired (connection); if (!s_wired) return NULL; return g_strdup (nm_setting_wired_get_mac_address (s_wired)); } /* no MAC address found */ return NULL; } /* return value must not be freed! */ static const gchar * get_mac_address_of_device (NMDevice *device) { const gchar *mac = NULL; switch (nm_device_get_device_type (device)) { case NM_DEVICE_TYPE_WIFI: { NMDeviceWifi *device_wifi = NM_DEVICE_WIFI (device); mac = nm_device_wifi_get_hw_address (device_wifi); break; } case NM_DEVICE_TYPE_ETHERNET: { NMDeviceEthernet *device_ethernet = NM_DEVICE_ETHERNET (device); mac = nm_device_ethernet_get_hw_address (device_ethernet); break; } default: break; } /* no MAC address found */ return mac; } /* returns TRUE if both MACs are equal */ static gboolean compare_mac_device_with_mac_connection (NMDevice *device, NMConnection *connection) { const gchar *mac_dev = NULL; gchar *mac_conn = NULL; mac_dev = get_mac_address_of_device (device); if (mac_dev != NULL) { mac_conn = get_mac_address_of_connection (connection); if (mac_conn) { /* compare both MACs */ if (g_strcmp0 (mac_dev, mac_conn) == 0) { g_free (mac_conn); return TRUE; } g_free (mac_conn); } } return FALSE; } static NMConnection * net_device_real_get_find_connection (NetDevice *device) { GSList *list, *iterator; NMConnection *connection = NULL; NMActiveConnection *ac; /* is the device available in a active connection? */ ac = nm_device_get_active_connection (device->priv->nm_device); if (ac) return (NMConnection*) nm_active_connection_get_connection (ac); /* not found in active connections - check all available connections */ list = net_device_get_valid_connections (device); if (list != NULL) { /* if list has only one connection, use this connection */ if (g_slist_length (list) == 1) { connection = list->data; goto out; } /* is there connection with the MAC address of the device? */ for (iterator = list; iterator; iterator = iterator->next) { connection = iterator->data; if (compare_mac_device_with_mac_connection (device->priv->nm_device, connection)) { goto out; } } } /* no connection found for the given device */ connection = NULL; out: g_slist_free (list); return connection; } NMConnection * net_device_get_find_connection (NetDevice *device) { return NET_DEVICE_GET_CLASS (device)->get_find_connection (device); } static void state_changed_cb (NMDevice *device, NMDeviceState new_state, NMDeviceState old_state, NMDeviceStateReason reason, NetDevice *net_device) { net_object_emit_changed (NET_OBJECT (net_device)); net_object_refresh (NET_OBJECT (net_device)); } NMDevice * net_device_get_nm_device (NetDevice *device) { g_return_val_if_fail (NET_IS_DEVICE (device), NULL); return device->priv->nm_device; } static void net_device_edit (NetObject *object) { const gchar *uuid; gchar *cmdline; GError *error = NULL; NetDevice *device = NET_DEVICE (object); NMConnection *connection; connection = net_device_get_find_connection (device); uuid = nm_connection_get_uuid (connection); cmdline = g_strdup_printf ("nm-connection-editor --edit %s", uuid); g_debug ("Launching '%s'\n", cmdline); if (!g_spawn_command_line_async (cmdline, &error)) { g_warning ("Failed to launch nm-connection-editor: %s", error->message); g_error_free (error); } g_free (cmdline); } /** * net_device_get_property: **/ static void net_device_get_property (GObject *device_, guint prop_id, GValue *value, GParamSpec *pspec) { NetDevice *net_device = NET_DEVICE (device_); NetDevicePrivate *priv = net_device->priv; switch (prop_id) { case PROP_DEVICE: g_value_set_object (value, priv->nm_device); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (net_device, prop_id, pspec); break; } } /** * net_device_set_property: **/ static void net_device_set_property (GObject *device_, guint prop_id, const GValue *value, GParamSpec *pspec) { NetDevice *net_device = NET_DEVICE (device_); NetDevicePrivate *priv = net_device->priv; switch (prop_id) { case PROP_DEVICE: if (priv->changed_id != 0) { g_signal_handler_disconnect (priv->nm_device, priv->changed_id); } priv->nm_device = g_value_dup_object (value); if (priv->nm_device) { priv->changed_id = g_signal_connect (priv->nm_device, "state-changed", G_CALLBACK (state_changed_cb), net_device); } else priv->changed_id = 0; break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (net_device, prop_id, pspec); break; } } static void net_device_finalize (GObject *object) { NetDevice *device = NET_DEVICE (object); NetDevicePrivate *priv = device->priv; if (priv->changed_id != 0) { g_signal_handler_disconnect (priv->nm_device, priv->changed_id); } if (priv->nm_device != NULL) g_object_unref (priv->nm_device); G_OBJECT_CLASS (net_device_parent_class)->finalize (object); } static void net_device_class_init (NetDeviceClass *klass) { GParamSpec *pspec; GObjectClass *object_class = G_OBJECT_CLASS (klass); NetObjectClass *parent_class = NET_OBJECT_CLASS (klass); object_class->finalize = net_device_finalize; object_class->get_property = net_device_get_property; object_class->set_property = net_device_set_property; parent_class->edit = net_device_edit; klass->get_find_connection = net_device_real_get_find_connection; pspec = g_param_spec_object ("nm-device", NULL, NULL, NM_TYPE_DEVICE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); g_object_class_install_property (object_class, PROP_DEVICE, pspec); g_type_class_add_private (klass, sizeof (NetDevicePrivate)); } static void net_device_init (NetDevice *device) { device->priv = NET_DEVICE_GET_PRIVATE (device); } NetDevice * net_device_new (void) { NetDevice *device; device = g_object_new (NET_TYPE_DEVICE, "removable", FALSE, NULL); return NET_DEVICE (device); } GSList * net_device_get_valid_connections (NetDevice *device) { GSList *valid; NMConnection *connection; NMSettingConnection *s_con; NMActiveConnection *active_connection; const char *active_uuid; const GPtrArray *all; GPtrArray *filtered; guint i; all = nm_client_get_connections (net_object_get_client (NET_OBJECT (device))); filtered = nm_device_filter_connections (net_device_get_nm_device (device), all); active_connection = nm_device_get_active_connection (net_device_get_nm_device (device)); active_uuid = active_connection ? nm_active_connection_get_uuid (active_connection) : NULL; valid = NULL; for (i = 0; i < filtered->len; i++) { connection = g_ptr_array_index (filtered, i); s_con = nm_connection_get_setting_connection (connection); if (!s_con) continue; if (nm_setting_connection_get_master (s_con) && g_strcmp0 (nm_setting_connection_get_uuid (s_con), active_uuid) != 0) continue; valid = g_slist_prepend (valid, connection); } g_ptr_array_free (filtered, FALSE); return g_slist_reverse (valid); } cinnamon-control-center-6.4.1/panels/network/network-ethernet.ui0000664000175000017500000002222614724311620024027 0ustar fabiofabio True False emblem-system-symbolic 1 True False 12 True False vertical 6 True False end start 1 48 network-wired 6 0 0 1 1 True False start True True False 0 Wired end False False 0 True False 0 Cable unplugged False False 1 1 0 1 1 True True 12 True never in 0 1 3 1 True False 12 True True 10 10 0 2 3 1 True True end center True 2 0 1 1 True True 0 True False 18 _Add Profile… True True True start True True True 0 True True True end image1 Options… True True 1 False True 1 cinnamon-control-center-6.4.1/panels/network/net-object.c0000664000175000017500000002567714724311620022376 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2011 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include "net-object.h" #define NET_OBJECT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NET_TYPE_OBJECT, NetObjectPrivate)) struct _NetObjectPrivate { gchar *id; gchar *title; gboolean removable; GCancellable *cancellable; NMClient *client; CcNetworkPanel *panel; }; enum { PROP_0, PROP_ID, PROP_TITLE, PROP_REMOVABLE, PROP_CLIENT, PROP_CANCELLABLE, PROP_PANEL, PROP_LAST }; enum { SIGNAL_CHANGED, SIGNAL_REMOVED, SIGNAL_LAST }; static guint signals[SIGNAL_LAST] = { 0 }; G_DEFINE_TYPE (NetObject, net_object, G_TYPE_OBJECT) void net_object_emit_changed (NetObject *object) { g_return_if_fail (NET_IS_OBJECT (object)); g_debug ("NetObject: %s emit 'changed'", object->priv->id); g_signal_emit (object, signals[SIGNAL_CHANGED], 0); } void net_object_emit_removed (NetObject *object) { g_return_if_fail (NET_IS_OBJECT (object)); g_debug ("NetObject: %s emit 'removed'", object->priv->id); g_signal_emit (object, signals[SIGNAL_REMOVED], 0); } const gchar * net_object_get_id (NetObject *object) { g_return_val_if_fail (NET_IS_OBJECT (object), NULL); return object->priv->id; } void net_object_set_id (NetObject *object, const gchar *id) { g_return_if_fail (NET_IS_OBJECT (object)); g_clear_pointer (&object->priv->id, g_free); object->priv->id = g_strdup (id); g_object_notify (G_OBJECT (object), "id"); } gboolean net_object_get_removable (NetObject *object) { g_return_val_if_fail (NET_IS_OBJECT (object), FALSE); return object->priv->removable; } const gchar * net_object_get_title (NetObject *object) { g_return_val_if_fail (NET_IS_OBJECT (object), NULL); return object->priv->title; } void net_object_set_title (NetObject *object, const gchar *title) { g_return_if_fail (NET_IS_OBJECT (object)); g_clear_pointer (&object->priv->title, g_free); object->priv->title = g_strdup (title); g_object_notify (G_OBJECT (object), "title"); } NMClient * net_object_get_client (NetObject *object) { g_return_val_if_fail (NET_IS_OBJECT (object), NULL); return object->priv->client; } GCancellable * net_object_get_cancellable (NetObject *object) { g_return_val_if_fail (NET_IS_OBJECT (object), NULL); return object->priv->cancellable; } CcNetworkPanel * net_object_get_panel (NetObject *object) { g_return_val_if_fail (NET_IS_OBJECT (object), NULL); return object->priv->panel; } GtkWidget * net_object_add_to_notebook (NetObject *object, GtkNotebook *notebook, GtkSizeGroup *heading_size_group) { GtkWidget *widget; NetObjectClass *klass = NET_OBJECT_GET_CLASS (object); if (klass->add_to_notebook != NULL) { widget = klass->add_to_notebook (object, notebook, heading_size_group); g_object_set_data_full (G_OBJECT (widget), "NetObject::id", g_strdup (object->priv->id), g_free); return widget; } g_debug ("no klass->add_to_notebook for %s", object->priv->id); return NULL; } void net_object_delete (NetObject *object) { NetObjectClass *klass = NET_OBJECT_GET_CLASS (object); if (klass->delete != NULL) klass->delete (object); } void net_object_refresh (NetObject *object) { NetObjectClass *klass = NET_OBJECT_GET_CLASS (object); if (klass->refresh != NULL) klass->refresh (object); } void net_object_edit (NetObject *object) { NetObjectClass *klass = NET_OBJECT_GET_CLASS (object); if (klass->edit != NULL) klass->edit (object); } /** * net_object_get_property: **/ static void net_object_get_property (GObject *object_, guint prop_id, GValue *value, GParamSpec *pspec) { NetObject *object = NET_OBJECT (object_); NetObjectPrivate *priv = object->priv; switch (prop_id) { case PROP_ID: g_value_set_string (value, priv->id); break; case PROP_TITLE: g_value_set_string (value, priv->title); break; case PROP_REMOVABLE: g_value_set_boolean (value, priv->removable); break; case PROP_CLIENT: g_value_set_pointer (value, priv->client); break; case PROP_CANCELLABLE: g_value_set_object (value, priv->cancellable); break; case PROP_PANEL: g_value_set_pointer (value, priv->panel); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } /** * net_object_set_property: **/ static void net_object_set_property (GObject *object_, guint prop_id, const GValue *value, GParamSpec *pspec) { NetObject *object = NET_OBJECT (object_); NetObjectPrivate *priv = object->priv; switch (prop_id) { case PROP_ID: g_free (priv->id); priv->id = g_strdup (g_value_get_string (value)); break; case PROP_TITLE: g_free (priv->title); priv->title = g_strdup (g_value_get_string (value)); break; case PROP_REMOVABLE: priv->removable = g_value_get_boolean (value); break; case PROP_CLIENT: priv->client = g_value_get_pointer (value); if (priv->client) g_object_add_weak_pointer (G_OBJECT (priv->client), (gpointer *) (&priv->client)); break; case PROP_CANCELLABLE: g_assert (!priv->cancellable); priv->cancellable = g_value_dup_object (value); break; case PROP_PANEL: g_assert (!priv->panel); priv->panel = g_value_get_pointer (value); if (priv->panel) g_object_add_weak_pointer (G_OBJECT (priv->panel), (gpointer *) (&priv->panel)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void net_object_finalize (GObject *object) { NetObject *nm_object = NET_OBJECT (object); NetObjectPrivate *priv = nm_object->priv; g_free (priv->id); g_free (priv->title); if (priv->cancellable != NULL) g_object_unref (priv->cancellable); if (priv->client) g_object_remove_weak_pointer (G_OBJECT (priv->client), (gpointer *) (&priv->client)); if (priv->panel) g_object_remove_weak_pointer (G_OBJECT (priv->panel), (gpointer *) (&priv->panel)); G_OBJECT_CLASS (net_object_parent_class)->finalize (object); } static void net_object_class_init (NetObjectClass *klass) { GParamSpec *pspec; GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = net_object_finalize; object_class->get_property = net_object_get_property; object_class->set_property = net_object_set_property; pspec = g_param_spec_string ("id", NULL, NULL, NULL, G_PARAM_READWRITE); g_object_class_install_property (object_class, PROP_ID, pspec); pspec = g_param_spec_string ("title", NULL, NULL, NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); g_object_class_install_property (object_class, PROP_TITLE, pspec); pspec = g_param_spec_boolean ("removable", NULL, NULL, TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); g_object_class_install_property (object_class, PROP_REMOVABLE, pspec); pspec = g_param_spec_pointer ("client", NULL, NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); g_object_class_install_property (object_class, PROP_CLIENT, pspec); pspec = g_param_spec_object ("cancellable", NULL, NULL, G_TYPE_CANCELLABLE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); g_object_class_install_property (object_class, PROP_CANCELLABLE, pspec); pspec = g_param_spec_pointer ("panel", NULL, NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); g_object_class_install_property (object_class, PROP_PANEL, pspec); signals[SIGNAL_CHANGED] = g_signal_new ("changed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (NetObjectClass, changed), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals[SIGNAL_REMOVED] = g_signal_new ("removed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (NetObjectClass, changed), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); g_type_class_add_private (klass, sizeof (NetObjectPrivate)); } static void net_object_init (NetObject *object) { object->priv = NET_OBJECT_GET_PRIVATE (object); } cinnamon-control-center-6.4.1/panels/network/net-vpn.h0000664000175000017500000000364614724311620021730 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2011 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __NET_VPN_H #define __NET_VPN_H #include #include #include "net-object.h" G_BEGIN_DECLS #define NET_TYPE_VPN (net_vpn_get_type ()) #define NET_VPN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NET_TYPE_VPN, NetVpn)) #define NET_VPN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NET_TYPE_VPN, NetVpnClass)) #define NET_IS_VPN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NET_TYPE_VPN)) #define NET_IS_VPN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NET_TYPE_VPN)) #define NET_VPN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NET_TYPE_VPN, NetVpnClass)) typedef struct _NetVpnPrivate NetVpnPrivate; typedef struct _NetVpn NetVpn; typedef struct _NetVpnClass NetVpnClass; struct _NetVpn { NetObject parent; NetVpnPrivate *priv; }; struct _NetVpnClass { NetObjectClass parent_class; }; GType net_vpn_get_type (void); G_END_DECLS #endif /* __NET_VPN_H */ cinnamon-control-center-6.4.1/panels/network/network-mobile.ui0000664000175000017500000004644414724311620023470 0ustar fabiofabio True False 12 6 True False start 10 6 True False 1 IMEI label_imei 0 1 1 1 True False 1 Provider label_provider 0 3 1 1 True False 0 1234567890 True 1 1 2 1 True False 0 SuperTel Supremo True 1 3 2 1 True False 0 127.0.0.1 True 1 4 2 1 True False 0 True 1 5 2 1 True False 0 True 1 6 2 1 True False 0 0 True True 1 7 2 1 True False 0 0 True True 1 8 2 1 True False end start 2 0 1 1 True False 1 IP Address 0 4 1 1 True False 1 0 IPv6 Address 0 5 1 1 True False 1 Default Route 0 6 1 1 True False 1 0 DNS4 0 7 1 1 True False 1 0 DNS6 0 8 1 1 True False 1 Network 0 2 1 1 True False liststore_mobile_connections 1 1 2 1 1 True False 6 True False end start 1 48 network-cellular-connected 6 False True 0 True False start True 3 True False 0 Mobile Broadband end False False 0 True False 0 Not connected False False 1 False True 1 True True end center False True 2 0 0 3 1 False True 0 True False 1 1 0 0 12 True True True True True False emblem-system-symbolic 1 Options… True True end 1 cinnamon-control-center-6.4.1/panels/wacom/0000775000175000017500000000000014724311620017574 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/wacom/cc-wacom-nav-button.h0000664000175000017500000000176014724311620023535 0ustar fabiofabio/* * Copyright Ā© 2011 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Authors: Bastien Nocera */ #pragma once #include G_BEGIN_DECLS #define CC_TYPE_WACOM_NAV_BUTTON (cc_wacom_nav_button_get_type ()) G_DECLARE_FINAL_TYPE (CcWacomNavButton, cc_wacom_nav_button, CC, WACOM_NAV_BUTTON, GtkBox) GtkWidget * cc_wacom_nav_button_new (void); G_END_DECLS cinnamon-control-center-6.4.1/panels/wacom/cc-wacom-device.h0000664000175000017500000000430514724311620022675 0ustar fabiofabio/* * Copyright Ā© 2016 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Authors: Carlos Garnacho * */ #pragma once #include "config.h" #include #include #include "csd-device-manager.h" #include "cc-wacom-output-manager.h" #define CC_TYPE_WACOM_DEVICE (cc_wacom_device_get_type ()) G_DECLARE_FINAL_TYPE (CcWacomDevice, cc_wacom_device, CC, WACOM_DEVICE, GObject) WacomDeviceDatabase * cc_wacom_device_database_get (void); CcWacomDevice * cc_wacom_device_new (CsdDevice *device); CcWacomDevice * cc_wacom_device_new_fake (const gchar *name); const gchar * cc_wacom_device_get_name (CcWacomDevice *device); const gchar * cc_wacom_device_get_icon_name (CcWacomDevice *device); gboolean cc_wacom_device_is_reversible (CcWacomDevice *device); WacomIntegrationFlags cc_wacom_device_get_integration_flags (CcWacomDevice *device); CsdDevice * cc_wacom_device_get_device (CcWacomDevice *device); GSettings * cc_wacom_device_get_settings (CcWacomDevice *device); const gint * cc_wacom_device_get_supported_tools (CcWacomDevice *device, gint *n_tools); MonitorInfo * cc_wacom_device_get_monitor (CcWacomDevice *device); void cc_wacom_device_set_monitor (CcWacomDevice *device, MonitorInfo *monitor); guint cc_wacom_device_get_num_buttons (CcWacomDevice *wacom_device); GSettings * cc_wacom_device_get_button_settings (CcWacomDevice *device, guint button); cinnamon-control-center-6.4.1/panels/wacom/button-mapping.ui0000664000175000017500000001474014724311620023105 0ustar fabiofabio 600 450 False 5 Map Buttons False True 600 450 dialog True False vertical 2 True False end _Close False True True True False False True False False 3 False True end 0 True False 6 True False 0 12 Map buttons to functions False True 0 True False 5 True True never in True True True True 1 True False 5 12 True False 0 To edit a shortcut, choose the ā€œSend Keystrokeā€ action, press the keyboard shortcut button and hold down the new keys or press Backspace to clear. fill True True True 0 False True 2 True True 1 close_button cinnamon-control-center-6.4.1/panels/wacom/cc-wacom-button-row.h0000664000175000017500000000326114724311620023556 0ustar fabiofabio/* * Copyright Ā© 2013 Red Hat, Inc. * * Authors: Joaquim Rocha * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ #pragma once #include #include G_BEGIN_DECLS #define CC_WACOM_TYPE_BUTTON_ROW (cc_wacom_button_row_get_type ()) G_DECLARE_FINAL_TYPE (CcWacomButtonRow, cc_wacom_button_row, CC, WACOM_BUTTON_ROW, GtkListBoxRow) static struct { CDesktopPadButtonAction action_type; const gchar *action_name; } action_table[] = { // FIXME // { C_DESKTOP_PAD_BUTTON_ACTION_NONE, NC_("Wacom action-type", "Application defined") }, { C_DESKTOP_PAD_BUTTON_ACTION_NONE, NC_("Wacom action-type", "None") }, { C_DESKTOP_PAD_BUTTON_ACTION_KEYBINDING, NC_("Wacom action-type", "Send Keystroke") }, { C_DESKTOP_PAD_BUTTON_ACTION_SWITCH_MONITOR, NC_("Wacom action-type", "Switch Monitor") }, { C_DESKTOP_PAD_BUTTON_ACTION_HELP, NC_("Wacom action-type", "Show On-Screen Help") } }; GtkWidget * cc_wacom_button_row_new (guint button, GSettings *settings); G_END_DECLS cinnamon-control-center-6.4.1/panels/wacom/calibrator/0000775000175000017500000000000014724311620021716 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/wacom/calibrator/meson.build0000664000175000017500000000133214724311620024057 0ustar fabiofabiocalibrator_inc = include_directories('.') common_sources = files( 'calibrator.c', 'calibrator-gui.c', 'cc-clock.c', ) calibrator_deps = deps + [math] libwacom_calibrator = static_library( 'wacom-calibrator', sources: common_sources, include_directories: rootInclude, dependencies: calibrator_deps, c_args: more_cflags ) libwacom_calibrator_test = static_library( 'wacom-calibrator-test', sources: common_sources, include_directories: rootInclude, dependencies: calibrator_deps, c_args: test_cflags ) sources = common_sources + wacom_gresource + files('main.c') executable( 'test-calibrator', sources, include_directories: rootInclude, dependencies: calibrator_deps, c_args: more_cflags ) cinnamon-control-center-6.4.1/panels/wacom/calibrator/cc-clock.c0000664000175000017500000001604214724311620023543 0ustar fabiofabio/* * Copyright Ā© 2018 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Authors: Joaquim Rocha * Carlos Garnacho */ #include "config.h" #include "cc-clock.h" #include #define CLOCK_RADIUS 50 #define CLOCK_LINE_WIDTH 10 #define CLOCK_LINE_PADDING 10 #define EXTRA_SPACE 2 typedef struct _CcClock CcClock; struct _CcClock { GtkWidget parent_instance; guint duration; gint64 start_time; gboolean running; }; enum { PROP_DURATION = 1, N_PROPS }; static GParamSpec *props[N_PROPS] = { 0, }; enum { FINISHED, N_SIGNALS }; static guint signals[N_SIGNALS] = { 0, }; G_DEFINE_TYPE (CcClock, cc_clock, GTK_TYPE_WIDGET) static gint64 cc_clock_get_time_diff (CcClock *clock) { GdkFrameClock *frame_clock; gint64 current_time; frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (clock)); current_time = gdk_frame_clock_get_frame_time (frame_clock); return current_time - clock->start_time; } static gdouble cc_clock_get_angle (CcClock *clock) { gint64 time_diff; time_diff = cc_clock_get_time_diff (clock); if (time_diff > clock->duration * 1000) return 360; return ((gdouble) time_diff / (clock->duration * 1000)) * 360; } static gboolean cc_clock_draw (GtkWidget *widget, cairo_t *cr) { GtkAllocation allocation; gdouble angle; gtk_widget_get_allocation (widget, &allocation); angle = cc_clock_get_angle (CC_CLOCK (widget)); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); /* Draw the clock background */ cairo_arc (cr, allocation.width / 2, allocation.height / 2, CLOCK_RADIUS / 2, 0.0, 2.0 * M_PI); cairo_set_source_rgb (cr, 0.5, 0.5, 0.5); cairo_fill_preserve (cr); cairo_stroke (cr); cairo_set_line_width (cr, CLOCK_LINE_WIDTH); cairo_arc (cr, allocation.width / 2, allocation.height / 2, (CLOCK_RADIUS - CLOCK_LINE_WIDTH - CLOCK_LINE_PADDING) / 2, 3 * M_PI_2, 3 * M_PI_2 + angle * M_PI / 180.0); cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); cairo_stroke (cr); return TRUE; } static void cc_clock_stop (CcClock *clock) { GdkFrameClock *frame_clock; if (!clock->running) return; frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (clock)); gdk_frame_clock_end_updating (frame_clock); clock->running = FALSE; } static void on_frame_clock_update (CcClock *clock) { gint64 time_diff; if (!clock->running) return; time_diff = cc_clock_get_time_diff (clock); if (time_diff > clock->duration * 1000) { g_signal_emit (clock, signals[FINISHED], 0); cc_clock_stop (clock); } gtk_widget_queue_draw (GTK_WIDGET (clock)); } static void cc_clock_map (GtkWidget *widget) { GdkFrameClock *frame_clock; GTK_WIDGET_CLASS (cc_clock_parent_class)->map (widget); frame_clock = gtk_widget_get_frame_clock (widget); g_signal_connect_object (frame_clock, "update", G_CALLBACK (on_frame_clock_update), widget, G_CONNECT_SWAPPED); cc_clock_reset (CC_CLOCK (widget)); } static void cc_clock_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { CcClock *clock = CC_CLOCK (object); switch (prop_id) { case PROP_DURATION: clock->duration = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void cc_clock_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { CcClock *clock = CC_CLOCK (object); switch (prop_id) { case PROP_DURATION: g_value_set_uint (value, clock->duration); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void cc_clock_get_preferred_width (GtkWidget *widget, gint *minimum, gint *natural) { if (minimum) *minimum = CLOCK_RADIUS + EXTRA_SPACE; if (natural) *natural = CLOCK_RADIUS + EXTRA_SPACE; } static void cc_clock_get_preferred_height (GtkWidget *widget, gint *minimum, gint *natural) { if (minimum) *minimum = CLOCK_RADIUS + EXTRA_SPACE; if (natural) *natural = CLOCK_RADIUS + EXTRA_SPACE; } static void cc_clock_class_init (CcClockClass *klass) { GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->set_property = cc_clock_set_property; object_class->get_property = cc_clock_get_property; widget_class->map = cc_clock_map; widget_class->draw = cc_clock_draw; widget_class->get_preferred_width = cc_clock_get_preferred_width; widget_class->get_preferred_height = cc_clock_get_preferred_height; signals[FINISHED] = g_signal_new ("finished", CC_TYPE_CLOCK, G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); props[PROP_DURATION] = g_param_spec_uint ("duration", "Duration", "Duration", 0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_properties (object_class, N_PROPS, props); } static void cc_clock_init (CcClock *clock) { gtk_widget_set_has_window (GTK_WIDGET (clock), FALSE); } GtkWidget * cc_clock_new (guint duration) { return g_object_new (CC_TYPE_CLOCK, "duration", duration, NULL); } void cc_clock_reset (CcClock *clock) { GdkFrameClock *frame_clock; if (!gtk_widget_get_mapped (GTK_WIDGET (clock))) return; frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (clock)); cc_clock_stop (clock); clock->running = TRUE; clock->start_time = g_get_monotonic_time (); gdk_frame_clock_begin_updating (frame_clock); } void cc_clock_set_duration (CcClock *clock, guint duration) { clock->duration = duration; g_object_notify (G_OBJECT (clock), "duration"); cc_clock_reset (clock); } guint cc_clock_get_duration (CcClock *clock) { return clock->duration; } cinnamon-control-center-6.4.1/panels/wacom/calibrator/calibrator.ui0000664000175000017500000002137214724311620024404 0ustar fabiofabio calibrator True 0 True True True True vertical True vertical True True 1 True vertical True 300 title True Screen Calibration True 300 subtitle True Please tap the target markers as they appear on screen to calibrate the tablet. 1 True crossfade 500 error True Mis-click detected, restarting… 2 True 2 0 0 8 8 target 100 100 True True False 0 0 2 2 target 100 100 True True False 6 0 2 2 target 100 100 True True False 0 6 2 2 target 100 100 True True False 6 6 2 2 True none 0 0 0 8 8 page0 True 300 emblem-ok-symbolic page1 1 vertical cinnamon-control-center-6.4.1/panels/wacom/calibrator/main.c0000664000175000017500000003453614724311620023021 0ustar fabiofabio/* * Copyright (c) 2009 Tias Guns * Copyright (c) 2009 Soren Hauberg * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include "config.h" #include #include #include #include #include #include #include "calibrator-gui.h" #include "calibrator.h" /** * find a calibratable touchscreen device (using XInput) * * if pre_device is NULL, the last calibratable device is selected. * retuns number of devices found, * the data of the device is returned in the last 3 function parameters */ static int find_device(const char* pre_device, gboolean verbose, gboolean list_devices, XID* device_id, const char** device_name, XYinfo* device_axis) { gboolean pre_device_is_id = TRUE; int found = 0; Display* display = XOpenDisplay(NULL); if (display == NULL) { fprintf(stderr, "Unable to connect to X server\n"); exit(1); } int xi_opcode, event, error; if (!XQueryExtension(display, "XInputExtension", &xi_opcode, &event, &error)) { fprintf(stderr, "X Input extension not available.\n"); exit(1); } /* verbose, get Xi version */ if (verbose) { XExtensionVersion *version = XGetExtensionVersion(display, INAME); if (version && (version != (XExtensionVersion*) NoSuchExtension)) { printf("DEBUG: %s version is %i.%i\n", INAME, version->major_version, version->minor_version); XFree(version); } } if (pre_device != NULL) { /* check whether the pre_device is an ID (only digits) */ int len = strlen(pre_device); int loop; for (loop=0; loopuse == IsXKeyboard || list->use == IsXPointer) /* virtual master device */ continue; /* if we are looking for a specific device */ if (pre_device != NULL) { if ((pre_device_is_id && list->id == (XID) atoi(pre_device)) || (!pre_device_is_id && strcmp(list->name, pre_device) == 0)) { /* OK, fall through */ } else { /* skip, not this device */ continue; } } XAnyClassPtr any = (XAnyClassPtr) (list->inputclassinfo); int j; for (j=0; jnum_classes; j++) { if (any->class == ValuatorClass) { XValuatorInfoPtr V = (XValuatorInfoPtr) any; XAxisInfoPtr ax = (XAxisInfoPtr) V->axes; if (V->mode != Absolute) { if (verbose) printf("DEBUG: Skipping device '%s' id=%i, does not report Absolute events.\n", list->name, (int)list->id); } else if (V->num_axes < 2 || (ax[0].min_value == -1 && ax[0].max_value == -1) || (ax[1].min_value == -1 && ax[1].max_value == -1)) { if (verbose) printf("DEBUG: Skipping device '%s' id=%i, does not have two calibratable axes.\n", list->name, (int)list->id); } else { /* a calibratable device (has 2 axis valuators) */ found++; *device_id = list->id; *device_name = g_strdup(list->name); device_axis->x_min = ax[0].min_value; device_axis->x_max = ax[0].max_value; device_axis->y_min = ax[1].min_value; device_axis->y_max = ax[1].max_value; if (list_devices) printf("Device \"%s\" id=%i\n", *device_name, (int)*device_id); } } /* * Increment 'any' to point to the next item in the linked * list. The length is in bytes, so 'any' must be cast to * a character pointer before being incremented. */ any = (XAnyClassPtr) ((char *) any + any->length); } } XFreeDeviceList(slist); XCloseDisplay(display); return found; } static void usage(char* cmd, unsigned thr_misclick) { fprintf(stderr, "Usage: %s [-h|--help] [-v|--verbose] [--list] [--device ] [--precalib ] [--misclick ] [--output-type ] [--fake]\n", cmd); fprintf(stderr, "\t-h, --help: print this help message\n"); fprintf(stderr, "\t-v, --verbose: print debug messages during the process\n"); fprintf(stderr, "\t--list: list calibratable input devices and quit\n"); fprintf(stderr, "\t--device : select a specific device to calibrate\n"); fprintf(stderr, "\t--precalib: manually provide the current calibration setting (eg. the values in xorg.conf)\n"); fprintf(stderr, "\t--misclick: set the misclick threshold (0=off, default: %i pixels)\n", thr_misclick); fprintf(stderr, "\t--fake: emulate a fake device (for testing purposes)\n"); } static struct Calib* CalibratorXorgPrint(const char* const device_name0, const XYinfo *axis0, const gboolean verbose0, const int thr_misclick, const int thr_doubleclick) { struct Calib* c = (struct Calib*)calloc(1, sizeof(struct Calib)); c->threshold_misclick = thr_misclick; c->threshold_doubleclick = thr_doubleclick; printf("Calibrating standard Xorg driver \"%s\"\n", device_name0); printf("\tcurrent calibration values: min_x=%lf, max_x=%lf and min_y=%lf, max_y=%lf\n", axis0->x_min, axis0->x_max, axis0->y_min, axis0->y_max); printf("\tIf these values are estimated wrong, either supply it manually with the --precalib option, or run the 'get_precalib.sh' script to automatically get it (through HAL).\n"); return c; } static struct Calib* main_common(int argc, char** argv) { gboolean verbose = FALSE; gboolean list_devices = FALSE; gboolean fake = FALSE; gboolean precalib = FALSE; XYinfo pre_axis = {-1, -1, -1, -1}; const char* pre_device = NULL; unsigned thr_misclick = 15; unsigned thr_doubleclick = 7; /* parse input */ if (argc > 1) { int i; for (i=1; i!=argc; i++) { /* Display help ? */ if (strcmp("-h", argv[i]) == 0 || strcmp("--help", argv[i]) == 0) { fprintf(stderr, "xinput_calibratior, v%s\n\n", "0.0.0"); usage(argv[0], thr_misclick); exit(0); } else /* Verbose output ? */ if (strcmp("-v", argv[i]) == 0 || strcmp("--verbose", argv[i]) == 0) { verbose = TRUE; } else /* Just list devices ? */ if (strcmp("--list", argv[i]) == 0) { list_devices = TRUE; } else /* Select specific device ? */ if (strcmp("--device", argv[i]) == 0) { if (argc > i+1) pre_device = argv[++i]; else { fprintf(stderr, "Error: --device needs a device name or id as argument; use --list to list the calibratable input devices.\n\n"); usage(argv[0], thr_misclick); exit(1); } } else /* Get pre-calibration ? */ if (strcmp("--precalib", argv[i]) == 0) { precalib = TRUE; if (argc > i+1) pre_axis.x_min = atoi(argv[++i]); if (argc > i+1) pre_axis.x_max = atoi(argv[++i]); if (argc > i+1) pre_axis.y_min = atoi(argv[++i]); if (argc > i+1) pre_axis.y_max = atoi(argv[++i]); } else /* Get mis-click threshold ? */ if (strcmp("--misclick", argv[i]) == 0) { if (argc > i+1) thr_misclick = atoi(argv[++i]); else { fprintf(stderr, "Error: --misclick needs a number (the pixel threshold) as argument. Set to 0 to disable mis-click detection.\n\n"); usage(argv[0], thr_misclick); exit(1); } } else /* Fake calibratable device ? */ if (strcmp("--fake", argv[i]) == 0) { fake = TRUE; } /* unknown option */ else { fprintf(stderr, "Unknown option: %s\n\n", argv[i]); usage(argv[0], thr_misclick); exit(0); } } } /* Choose the device to calibrate */ XID device_id = (XID) -1; const char* device_name = NULL; XYinfo device_axis = {-1, -1, -1, -1}; if (fake) { /* Fake a calibratable device */ device_name = "Fake_device"; device_axis.x_min=0; device_axis.x_max=1000; device_axis.y_min=0; device_axis.y_max=1000; if (verbose) { printf("DEBUG: Faking device: %s\n", device_name); } } else { /* Find the right device */ int nr_found = find_device(pre_device, verbose, list_devices, &device_id, &device_name, &device_axis); if (list_devices) { /* printed the list in find_device */ if (nr_found == 0) printf("No calibratable devices found.\n"); exit(0); } if (nr_found == 0) { if (pre_device == NULL) fprintf (stderr, "Error: No calibratable devices found.\n"); else fprintf (stderr, "Error: Device \"%s\" not found; use --list to list the calibratable input devices.\n", pre_device); exit(1); } else if (nr_found > 1) { printf ("Warning: multiple calibratable devices found, calibrating last one (%s)\n\tuse --device to select another one.\n", device_name); } if (verbose) { printf("DEBUG: Selected device: %s\n", device_name); } } /* override min/max XY from command line ? */ if (precalib) { if (pre_axis.x_min != -1) device_axis.x_min = pre_axis.x_min; if (pre_axis.x_max != -1) device_axis.x_max = pre_axis.x_max; if (pre_axis.y_min != -1) device_axis.y_min = pre_axis.y_min; if (pre_axis.y_max != -1) device_axis.y_max = pre_axis.y_max; if (verbose) { printf("DEBUG: Setting precalibration: %lf, %lf, %lf, %lf\n", device_axis.x_min, device_axis.x_max, device_axis.y_min, device_axis.y_max); } } /* lastly, presume a standard Xorg driver (evtouch, mutouch, ...) */ return CalibratorXorgPrint(device_name, &device_axis, verbose, thr_misclick, thr_doubleclick); } static gboolean output_xorgconfd(const XYinfo new_axis, int swap_xy, int new_swap_xy) { const char* sysfs_name = "!!Name_Of_TouchScreen!!"; /* xorg.conf.d snippet */ printf(" copy the snippet below into '/etc/X11/xorg.conf.d/99-calibration.conf'\n"); printf("Section \"InputClass\"\n"); printf(" Identifier \"calibration\"\n"); printf(" MatchProduct \"%s\"\n", sysfs_name); printf(" Option \"MinX\" \"%lf\"\n", new_axis.x_min); printf(" Option \"MaxX\" \"%lf\"\n", new_axis.x_max); printf(" Option \"MinY\" \"%lf\"\n", new_axis.y_min); printf(" Option \"MaxY\" \"%lf\"\n", new_axis.y_max); if (swap_xy != 0) printf(" Option \"SwapXY\" \"%d\" # unless it was already set to 1\n", new_swap_xy); printf("EndSection\n"); return TRUE; } static gboolean finish_data(const XYinfo new_axis, int swap_xy) { gboolean success = TRUE; /* we suppose the previous 'swap_xy' value was 0 */ /* (unfortunately there is no way to verify this (yet)) */ int new_swap_xy = swap_xy; printf("\n\n--> Making the calibration permanent <--\n"); success &= output_xorgconfd(new_axis, swap_xy, new_swap_xy); return success; } static void calibration_finished_cb (CalibArea *area, gpointer user_data) { gboolean success; XYinfo axis; gboolean swap_xy; success = calib_area_finish (area); if (success) { calib_area_get_axis (area, &axis, &swap_xy); success = finish_data (axis, swap_xy); } else fprintf(stderr, "Error: unable to apply or save configuration values\n"); gtk_main_quit (); } int main(int argc, char** argv) { struct Calib* calibrator = main_common(argc, argv); CalibArea *calib_area; bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); gtk_init (&argc, &argv); g_setenv ("G_MESSAGES_DEBUG", "all", TRUE); calib_area = calib_area_new (NULL, 0, /* monitor */ NULL, /* NULL to accept input from any device */ calibration_finished_cb, NULL, calibrator->threshold_doubleclick, calibrator->threshold_misclick); gtk_main (); calib_area_free (calib_area); free(calibrator); return 0; } cinnamon-control-center-6.4.1/panels/wacom/calibrator/calibrator.css0000664000175000017500000000154014724311620024552 0ustar fabiofabio#calibrator { background-color: #000; } #calibrator * { color: #fff; } #calibrator label { font-size: larger; } #calibrator #title { font-weight: bold; color: #888; } #calibrator #error { font-weight: bold; } #calibrator #target { background-image: url('target.svg'); background-repeat: no-repeat; background-position: 50% 50%; } @keyframes target-enabled-animation { 0% { background-size: 0px } 90% { background-size: 120px } 100% { background-size: 100px } } @keyframes target-disabled-animation { 0% { background-size: 100px } 100% { background-size: 0px } } #calibrator #target:not(disabled) { animation: target-enabled-animation 1 ease 0.5s; background-size: 100px; } #calibrator #target:disabled { animation: target-disabled-animation 1 ease 0.2s; background-size: 0px; } cinnamon-control-center-6.4.1/panels/wacom/calibrator/calibrator.h0000664000175000017500000000617014724311620024215 0ustar fabiofabio/* * Copyright (c) 2009 Tias Guns * Copyright (c) 2009 Soren Hauberg * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #pragma once #include #include "calibrator-gui.h" G_BEGIN_DECLS /* * Number of blocks. We partition the screen into 'num_blocks' x 'num_blocks' * rectangles of equal size. We then ask the user to press points that are * located at the corner closes to the center of the four blocks in the corners * of the screen. The following ascii art illustrates the situation. We partition * the screen into 8 blocks in each direction. We then let the user press the * points marked with 'O'. * * +--+--+--+--+--+--+--+--+ * | | | | | | | | | * +--O--+--+--+--+--+--O--+ * | | | | | | | | | * +--+--+--+--+--+--+--+--+ * | | | | | | | | | * +--+--+--+--+--+--+--+--+ * | | | | | | | | | * +--+--+--+--+--+--+--+--+ * | | | | | | | | | * +--+--+--+--+--+--+--+--+ * | | | | | | | | | * +--+--+--+--+--+--+--+--+ * | | | | | | | | | * +--O--+--+--+--+--+--O--+ * | | | | | | | | | * +--+--+--+--+--+--+--+--+ */ #define NUM_BLOCKS 8 /* Names of the points */ enum { UL = 0, /* Upper-left */ UR = 1, /* Upper-right */ LL = 2, /* Lower-left */ LR = 3 /* Lower-right */ }; struct Calib { /* Geometry of the calibration window */ GdkRectangle geometry; /* nr of clicks registered */ int num_clicks; /* click coordinates */ int clicked_x[4], clicked_y[4]; /* Threshold to keep the same point from being clicked twice. * Set to zero if you don't want this check */ int threshold_doubleclick; /* Threshold to detect mis-clicks (clicks not along axes) * A lower value forces more precise calibration * Set to zero if you don't want this check */ int threshold_misclick; }; void reset (struct Calib *c); gboolean add_click (struct Calib *c, int x, int y); gboolean finish (struct Calib *c, XYinfo *new_axis, gboolean *swap); G_END_DECLS cinnamon-control-center-6.4.1/panels/wacom/calibrator/cc-clock.h0000664000175000017500000000233014724311620023543 0ustar fabiofabio/* * Copyright Ā© 2018 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Author: Carlos Garnacho */ #pragma once #include #include G_BEGIN_DECLS #define CC_TYPE_CLOCK (cc_clock_get_type ()) G_DECLARE_FINAL_TYPE (CcClock, cc_clock, CC, CLOCK, GtkWidget) GtkWidget * cc_clock_new (guint duration); void cc_clock_reset (CcClock *clock); void cc_clock_set_duration (CcClock *clock, guint duration); guint cc_clock_get_duration (CcClock *clock); GType cc_clock_get_type (void); G_END_DECLS cinnamon-control-center-6.4.1/panels/wacom/calibrator/target.svg0000664000175000017500000000552014724311620023727 0ustar fabiofabio image/svg+xml cinnamon-control-center-6.4.1/panels/wacom/calibrator/COPYING0000664000175000017500000000224414724311620022753 0ustar fabiofabioCopyright (c) 2010 Tias Guns and others See the respective files for detailed copyright information. Source code: MIT/X11 License ------------ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. cinnamon-control-center-6.4.1/panels/wacom/calibrator/calibrator.c0000664000175000017500000001330614724311620024207 0ustar fabiofabio/* * Copyright (c) 2009 Tias Guns * Copyright (c) 2009 Soren Hauberg * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include #include "calibrator.h" #define SWAP(valtype,x,y) \ G_STMT_START { \ valtype t; t = (x); x = (y); y = t; \ } G_STMT_END /* reset clicks */ void reset (struct Calib *c) { c->num_clicks = 0; } /* check whether the coordinates are along the respective axis */ static gboolean along_axis (struct Calib *c, int xy, int x0, int y0) { return ((abs(xy - x0) <= c->threshold_misclick) || (abs(xy - y0) <= c->threshold_misclick)); } /* add a click with the given coordinates */ gboolean add_click (struct Calib *c, int x, int y) { g_debug ("Trying to add click (%d, %d)", x, y); /* Double-click detection */ if (c->threshold_doubleclick > 0 && c->num_clicks > 0) { int i = c->num_clicks-1; while (i >= 0) { if (abs(x - c->clicked_x[i]) <= c->threshold_doubleclick && abs(y - c->clicked_y[i]) <= c->threshold_doubleclick) { g_debug ("Detected double-click, ignoring"); return FALSE; } i--; } } /* Mis-click detection */ if (c->threshold_misclick > 0 && c->num_clicks > 0) { gboolean misclick = TRUE; if (c->num_clicks == 1) { /* check that along one axis of first point */ if (along_axis(c, x,c->clicked_x[0],c->clicked_y[0]) || along_axis(c, y,c->clicked_x[0],c->clicked_y[0])) { misclick = FALSE; } } else if (c->num_clicks == 2) { /* check that along other axis of first point than second point */ if ((along_axis(c, y,c->clicked_x[0],c->clicked_y[0]) && along_axis(c, c->clicked_x[1],c->clicked_x[0],c->clicked_y[0])) || (along_axis(c, x,c->clicked_x[0],c->clicked_y[0]) && along_axis(c, c->clicked_y[1],c->clicked_x[0],c->clicked_y[0]))) { misclick = FALSE; } } else if (c->num_clicks == 3) { /* check that along both axis of second and third point */ if ((along_axis(c, x,c->clicked_x[1],c->clicked_y[1]) && along_axis(c, y,c->clicked_x[2],c->clicked_y[2])) || (along_axis(c, y,c->clicked_x[1],c->clicked_y[1]) && along_axis(c, x,c->clicked_x[2],c->clicked_y[2]))) { misclick = FALSE; } } if (misclick) { g_debug ("Detected misclick, resetting"); reset(c); return FALSE; } } g_debug ("Click (%d, %d) added", x, y); c->clicked_x[c->num_clicks] = x; c->clicked_y[c->num_clicks] = y; c->num_clicks++; return TRUE; } /* calculate and apply the calibration */ gboolean finish (struct Calib *c, XYinfo *new_axis, gboolean *swap) { gboolean swap_xy; float scale_x; float scale_y; float delta_x; float delta_y; XYinfo axis = {-1, -1, -1, -1}; if (c->num_clicks != 4) return FALSE; /* Should x and y be swapped? If the device and output are wider * towards different axes, swapping must be performed * * FIXME: Would be even better to know the actual output orientation, * not just the direction. */ swap_xy = (c->geometry.width < c->geometry.height); /* Compute the scale to transform from pixel positions to [0..1]. */ scale_x = 1 / (float)c->geometry.width; scale_y = 1 / (float)c->geometry.height; axis.x_min = ((((c->clicked_x[UL] + c->clicked_x[LL]) / 2)) * scale_x); axis.x_max = ((((c->clicked_x[UR] + c->clicked_x[LR]) / 2)) * scale_x); axis.y_min = ((((c->clicked_y[UL] + c->clicked_y[UR]) / 2)) * scale_y); axis.y_max = ((((c->clicked_y[LL] + c->clicked_y[LR]) / 2)) * scale_y); /* Add/subtract the offset that comes from not having the points in the * corners (using the same coordinate system they are currently in) */ delta_x = (axis.x_max - axis.x_min) / (float)(NUM_BLOCKS - 2); axis.x_min -= delta_x; axis.x_max += delta_x; delta_y = (axis.y_max - axis.y_min) / (float)(NUM_BLOCKS - 2); axis.y_min -= delta_y; axis.y_max += delta_y; /* If x and y has to be swapped we also have to swap the parameters */ if (swap_xy) { SWAP (gdouble, axis.x_min, axis.y_min); SWAP (gdouble, axis.x_max, axis.y_max); } *new_axis = axis; *swap = swap_xy; return TRUE; } cinnamon-control-center-6.4.1/panels/wacom/calibrator/calibrator-gui.c0000664000175000017500000003137014724311620024772 0ustar fabiofabio/* * Copyright Ā© 2013 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Author: Carlos Garnacho * (based on previous work by Joaquim Rocha, Tias Guns and Soren Hauberg) */ #include "config.h" #include #include #include #include #include #include #include "calibrator.h" #include "calibrator-gui.h" #include "cc-clock.h" struct CalibArea { struct Calib calibrator; XYinfo axis; gboolean swap; gboolean success; GdkDevice *device; double X[4], Y[4]; int display_width, display_height; GtkWidget *window; GtkBuilder *builder; GtkWidget *error_revealer; GtkWidget *clock; GtkCssProvider *style_provider; FinishCallback callback; gpointer user_data; }; /* Timeout parameters */ #define MAX_TIME 15000 /* 15000 = 15 sec */ #define END_TIME 750 /* 750 = 0.75 sec */ static void set_display_size (CalibArea *calib_area, int width, int height) { int delta_x; int delta_y; calib_area->display_width = width; calib_area->display_height = height; /* Compute absolute circle centers */ delta_x = calib_area->display_width/NUM_BLOCKS; delta_y = calib_area->display_height/NUM_BLOCKS; calib_area->X[UL] = delta_x; calib_area->Y[UL] = delta_y; calib_area->X[UR] = calib_area->display_width - delta_x - 1; calib_area->Y[UR] = delta_y; calib_area->X[LL] = delta_x; calib_area->Y[LL] = calib_area->display_height - delta_y - 1; calib_area->X[LR] = calib_area->display_width - delta_x - 1; calib_area->Y[LR] = calib_area->display_height - delta_y - 1; /* reset calibration if already started */ reset (&calib_area->calibrator); } static void calib_area_notify_finish (CalibArea *area) { gtk_widget_hide (area->window); (*area->callback) (area, area->user_data); } static gboolean on_delete_event (GtkWidget *widget, GdkEvent *event, CalibArea *area) { calib_area_notify_finish (area); return TRUE; } static gboolean calib_area_finish_idle_cb (CalibArea *area) { calib_area_notify_finish (area); return FALSE; } static void set_success (CalibArea *area) { GtkWidget *stack; stack = GTK_WIDGET (gtk_builder_get_object (area->builder, "stack")); gtk_stack_set_visible_child_name (GTK_STACK (stack), "page1"); } static void set_calibration_status (CalibArea *area) { area->success = finish (&area->calibrator, &area->axis, &area->swap); if (area->success) { set_success (area); g_timeout_add (END_TIME, (GSourceFunc) calib_area_finish_idle_cb, area); } else { g_idle_add ((GSourceFunc) calib_area_finish_idle_cb, area); } } static void show_error_message (CalibArea *area) { gtk_revealer_set_reveal_child (GTK_REVEALER (area->error_revealer), TRUE); } static void hide_error_message (CalibArea *area) { gtk_revealer_set_reveal_child (GTK_REVEALER (area->error_revealer), FALSE); } static void set_active_target (CalibArea *area, int n_target) { GtkWidget *targets[] = { GTK_WIDGET (gtk_builder_get_object (area->builder, "target1")), GTK_WIDGET (gtk_builder_get_object (area->builder, "target2")), GTK_WIDGET (gtk_builder_get_object (area->builder, "target3")), GTK_WIDGET (gtk_builder_get_object (area->builder, "target4")), }; int i; for (i = 0; i < G_N_ELEMENTS (targets); i++) gtk_widget_set_sensitive (targets[i], i == n_target); } static void on_gesture_press (GtkGestureMultiPress *gesture, guint n_press, gdouble x, gdouble y, CalibArea *area) { gint num_clicks; gboolean success; GdkDevice *source; GdkEvent *event; if (area->success) return; event = gtk_get_current_event (); source = gdk_event_get_source_device ((GdkEvent *) event); gdk_event_free (event); /* Check matching device if a device was provided */ if (area->device && area->device != source) { g_debug ("Ignoring input from device %s", gdk_device_get_name (source)); return; } /* Handle click */ /* FIXME: reset clock */ success = add_click(&area->calibrator, (int) x, (int) y); num_clicks = area->calibrator.num_clicks; if (!success && num_clicks == 0) show_error_message (area); else hide_error_message (area); /* Are we done yet? */ if (num_clicks >= 4) { set_calibration_status (area); return; } set_active_target (area, num_clicks); } static gboolean on_key_release_event (GtkWidget *widget, GdkEventKey *event, CalibArea *area) { if (area->success || event->keyval != GDK_KEY_Escape) return GDK_EVENT_PROPAGATE; calib_area_notify_finish (area); return GDK_EVENT_STOP; } static gboolean on_focus_out_event (GtkWidget *widget, GdkEvent *event, CalibArea *area) { if (area->success) return FALSE; /* If the calibrator window loses focus, simply bail out... */ calib_area_notify_finish (area); return FALSE; } static void on_clock_finished (CcClock *clock, CalibArea *area) { set_calibration_status (area); } static void on_title_revealed (CalibArea *area) { GtkWidget *revealer; revealer = GTK_WIDGET (gtk_builder_get_object (area->builder, "subtitle_revealer")); gtk_revealer_set_reveal_child (GTK_REVEALER (revealer), TRUE); } static gboolean on_fullscreen (GtkWindow *window, GdkEventWindowState *event, CalibArea *area) { GtkWidget *revealer; if ((event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) == 0) return FALSE; revealer = GTK_WIDGET (gtk_builder_get_object (area->builder, "title_revealer")); g_signal_connect_swapped (revealer, "notify::child-revealed", G_CALLBACK (on_title_revealed), area); gtk_revealer_set_reveal_child (GTK_REVEALER (revealer), TRUE); set_active_target (area, 0); return FALSE; } static void on_size_allocate (GtkWidget *widget, GtkAllocation *allocation, CalibArea *area) { set_display_size (area, allocation->width, allocation->height); } /** * Creates the windows and other objects required to do calibration * under GTK. When the window is closed (timed out, calibration finished * or user cancellation), callback will be called, where you should call * calib_area_finish(). */ CalibArea * calib_area_new (GdkScreen *screen, int n_monitor, GdkDevice *device, FinishCallback callback, gpointer user_data, int threshold_doubleclick, int threshold_misclick) { CalibArea *calib_area; GdkRectangle rect; GdkVisual *visual; GdkMonitor *monitor; #ifndef FAKE_AREA GdkWindow *window; g_autoptr(GdkCursor) cursor = NULL; #endif /* FAKE_AREA */ GtkGesture *press; g_return_val_if_fail (callback, NULL); g_type_ensure (CC_TYPE_CLOCK); calib_area = g_new0 (CalibArea, 1); calib_area->callback = callback; calib_area->user_data = user_data; calib_area->device = device; calib_area->calibrator.threshold_doubleclick = threshold_doubleclick; calib_area->calibrator.threshold_misclick = threshold_misclick; calib_area->builder = gtk_builder_new_from_resource ("/org/cinnamon/control-center/wacom/calibrator/calibrator.ui"); calib_area->window = GTK_WIDGET (gtk_builder_get_object (calib_area->builder, "window")); calib_area->error_revealer = GTK_WIDGET (gtk_builder_get_object (calib_area->builder, "error_revealer")); calib_area->clock = GTK_WIDGET (gtk_builder_get_object (calib_area->builder, "clock")); calib_area->style_provider = gtk_css_provider_new (); gtk_css_provider_load_from_resource (calib_area->style_provider, "/org/cinnamon/control-center/wacom/calibrator/calibrator.css"); gtk_style_context_add_provider_for_screen (gtk_widget_get_screen (calib_area->window), GTK_STYLE_PROVIDER (calib_area->style_provider), GTK_STYLE_PROVIDER_PRIORITY_USER); cc_clock_set_duration (CC_CLOCK (calib_area->clock), MAX_TIME); g_signal_connect (calib_area->clock, "finished", G_CALLBACK (on_clock_finished), calib_area); #ifndef FAKE_AREA /* No cursor */ gtk_widget_realize (calib_area->window); window = gtk_widget_get_window (calib_area->window); cursor = gdk_cursor_new_for_display (gdk_display_get_default (), GDK_BLANK_CURSOR); gdk_window_set_cursor (window, cursor); gtk_widget_set_can_focus (calib_area->window, TRUE); gtk_window_set_keep_above (GTK_WINDOW (calib_area->window), TRUE); #endif /* FAKE_AREA */ /* Move to correct screen */ if (screen == NULL) screen = gdk_screen_get_default (); monitor = gdk_display_get_monitor (gdk_screen_get_display (screen), n_monitor); gdk_monitor_get_geometry (monitor, &rect); calib_area->calibrator.geometry = rect; g_signal_connect (calib_area->window, "key-release-event", G_CALLBACK (on_key_release_event), calib_area); g_signal_connect (calib_area->window, "delete-event", G_CALLBACK (on_delete_event), calib_area); g_signal_connect (calib_area->window, "focus-out-event", G_CALLBACK(on_focus_out_event), calib_area); g_signal_connect (calib_area->window, "window-state-event", G_CALLBACK (on_fullscreen), calib_area); g_signal_connect (calib_area->window, "size-allocate", G_CALLBACK (on_size_allocate), calib_area); press = gtk_gesture_multi_press_new (calib_area->window); gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (press), GDK_BUTTON_PRIMARY); g_signal_connect (press, "pressed", G_CALLBACK (on_gesture_press), calib_area); gtk_window_fullscreen_on_monitor (GTK_WINDOW (calib_area->window), screen, n_monitor); visual = gdk_screen_get_rgba_visual (screen); if (visual != NULL) gtk_widget_set_visual (GTK_WIDGET (calib_area->window), visual); gtk_widget_show (calib_area->window); return calib_area; } /* Finishes the calibration. Note that CalibArea * needs to be destroyed with calib_area_free() afterwards */ gboolean calib_area_finish (CalibArea *area) { g_return_val_if_fail (area != NULL, FALSE); if (area->success) g_debug ("Final calibration: %f, %f, %f, %f\n", area->axis.x_min, area->axis.y_min, area->axis.x_max, area->axis.y_max); else g_debug ("Calibration was aborted or timed out"); return area->success; } void calib_area_free (CalibArea *area) { g_return_if_fail (area != NULL); gtk_style_context_remove_provider_for_screen (gtk_widget_get_screen (area->window), GTK_STYLE_PROVIDER (area->style_provider)); gtk_widget_destroy (area->window); g_free (area); } void calib_area_get_display_size (CalibArea *area, gint *width, gint *height) { g_return_if_fail (area != NULL); *width = area->display_width; *height = area->display_height; } void calib_area_get_axis (CalibArea *area, XYinfo *new_axis, gboolean *swap_xy) { g_return_if_fail (area != NULL); *new_axis = area->axis; *swap_xy = area->swap; } void calib_area_get_padding (CalibArea *area, XYinfo *padding) { g_return_if_fail (area != NULL); /* min/max values are monitor coordinates scaled to be between * 0 and 1, padding starts at 0 on "the edge", and positive * values grow towards the center of the rectangle. */ padding->x_min = area->axis.x_min; padding->y_min = area->axis.y_min; padding->x_max = 1 - area->axis.x_max; padding->y_max = 1 - area->axis.y_max; } cinnamon-control-center-6.4.1/panels/wacom/calibrator/calibrator-gui.h0000664000175000017500000000416514724311620025001 0ustar fabiofabio/* * Copyright (c) 2009 Tias Guns * Copyright (c) 2009 Soren Hauberg * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #pragma once #include G_BEGIN_DECLS /* struct to hold min/max info of the X and Y axis */ typedef struct { gdouble x_min; gdouble x_max; gdouble y_min; gdouble y_max; } XYinfo; typedef struct CalibArea CalibArea; typedef void (*FinishCallback) (CalibArea *area, gpointer user_data); CalibArea * calib_area_new (GdkScreen *screen, int monitor, GdkDevice *device, FinishCallback callback, gpointer user_data, int threshold_doubleclick, int threshold_misclick); gboolean calib_area_finish (CalibArea *area); void calib_area_free (CalibArea *area); void calib_area_get_display_size (CalibArea *area, gint *width, gint *height); void calib_area_get_axis (CalibArea *area, XYinfo *new_axis, gboolean *swap_xy); void calib_area_get_padding (CalibArea *area, XYinfo *padding); G_END_DECLS cinnamon-control-center-6.4.1/panels/wacom/wacom-stylus-3btn-no-eraser.svg0000664000175000017500000001275414724311620025532 0ustar fabiofabio image/svg+xml cinnamon-control-center-6.4.1/panels/wacom/meson.build0000664000175000017500000000416214724311620021741 0ustar fabiofabiodeps = [ libwacom, cinn_desktop, gtk, libx11, libxi ] muffin_display_iface_sources = gnome.gdbus_codegen( 'muffin-display-config', 'muffin-display-config.xml', namespace: 'MetaDBus', interface_prefix: 'org.cinnamon.Muffin' ) test_cflags = more_cflags + ['-DFAKE_AREA'] wacom_gresource = gnome.compile_resources( 'cc-wacom-resources', 'cinnamon-wacom.gresource.xml', source_dir : '.', c_name : 'cc_wacom', dependencies : resource_data, export : true ) subdir('calibrator') install_data( 'cinnamon-wacom-panel.desktop', install_dir: desktop_dir ) common_sources = [ muffin_display_iface_sources, 'cc-tablet-tool-map.c', 'cc-wacom-button-row.c', 'cc-wacom-device.c', 'cc-wacom-mapping-panel.c', 'cc-wacom-nav-button.c', 'cc-wacom-output-manager.c', 'cc-wacom-page.c', 'cc-wacom-stylus-page.c', 'cc-wacom-tool.c', 'csd-wacom-key-shortcut-button.c' ] resource_data = files( 'calibrator/calibrator.ui', 'calibrator/calibrator.css', 'calibrator/target.svg', 'button-mapping.ui', 'cinnamon-wacom-properties.ui', 'wacom-stylus-3btn.svg', 'wacom-stylus-3btn-no-eraser.svg', 'wacom-stylus-airbrush.svg', 'wacom-stylus-art-pen.svg', 'wacom-stylus-classic.svg', 'wacom-stylus-inking.svg', 'wacom-stylus-no-eraser.svg', 'wacom-stylus-page.ui', 'wacom-stylus.svg', 'wacom-tablet-cintiq.svg', 'wacom-tablet-pc.svg', 'wacom-tablet.svg' ) common_sources += wacom_gresource sources = common_sources + files( 'cc-wacom-panel.c', 'cc-drawing-area.c', 'wacom-module.c' ) deps += libdevice_dep incs = [ rootInclude, calibrator_inc ] panel_wacom = shared_library('wacom-properties', sources : sources, include_directories : incs, dependencies : deps, link_whole : [ libwacom_calibrator ], link_with: [libcinnamon_control_center], install: true, install_dir: panels_dir ) sources += 'test-wacom.c' executable('test-wacom', sources, include_directories : incs, dependencies : deps, c_args : test_cflags, link_with : [ libwacom_calibrator_test, libcinnamon_control_center ] ) cinnamon-control-center-6.4.1/panels/wacom/cc-wacom-output-manager.h0000664000175000017500000000356514724311620024415 0ustar fabiofabio/* * Copyright Ā© 2016 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Authors: Carlos Garnacho * */ #pragma once #include "config.h" #include #define CC_TYPE_WACOM_OUTPUT_MANAGER (cc_wacom_output_manager_get_type ()) G_DECLARE_FINAL_TYPE (CcWacomOutputManager, cc_wacom_output_manager, CC, WACOM_OUTPUT_MANAGER, GObject) typedef struct { gchar *connector_name; gchar *display_name; gchar *vendor; gchar *product; gchar *serial; gint x; gint y; gboolean primary; gboolean builtin; } MonitorInfo; CcWacomOutputManager * cc_wacom_output_manager_get (void); MonitorInfo * cc_wacom_output_manager_get_monitor (CcWacomOutputManager *monitors); void cc_wacom_output_manager_set_monitor (CcWacomOutputManager *monitors, MonitorInfo *monitor); GList * cc_wacom_output_manager_get_all_monitors (CcWacomOutputManager *monitors); void cc_wacom_output_manager_refresh_monitors (CcWacomOutputManager *monitors); gboolean monitor_info_cmp (MonitorInfo *a, MonitorInfo *b); void monitor_info_spew (MonitorInfo *info); cinnamon-control-center-6.4.1/panels/wacom/cinnamon-wacom-properties.ui0000664000175000017500000005106414724311620025241 0ustar fabiofabio True False vertical True False False False True False True False True True vertical True False False end True 96 input-tablet-symbolic 0 False True 0 True False False No tablet detected center 1 False False 1 True False start True Please plug in or turn on your Wacom tablet center 0 False True 2 Bluetooth Settings False True True True True center center none False True 3 0 0 3 3 True False Plugin False True False 10 10 True False start center Wacom Tablet 0 0 2 True False center start wacom-tablet.svg 0 1 True False 16 16 vertical 10 10 True False end center Tracking Mode 0 0 True False True liststore-tabletmode 1 0 True False end center Left-Handed Orientation 0 1 False True True start center 1 1 True False start 10 Map to Monitor… False True True True False True end 0 Map Buttons… False True True True False True end 1 Calibrate… False True True False True end 2 1 2 Adjust mouse settings False True True True start start none 1 3 Adjust display resolution False True True True start start none 1 3 True False end center Decouple Display 0 4 True True start center True 1 4 Map to Monitor… False True True True start 1 6 1 1 True False end crossfade 100 1 0 1 True False Wacom 1 False True True 0 0 Tablet (absolute) 1 Touchpad (relative) cinnamon-control-center-6.4.1/panels/wacom/wacom-stylus-3btn.svg0000664000175000017500000001363414724311620023637 0ustar fabiofabio image/svg+xml cinnamon-control-center-6.4.1/panels/wacom/cc-wacom-page.h0000664000175000017500000000300414724311620022345 0ustar fabiofabio/* * Copyright Ā© 2011 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Authors: Peter Hutterer * Bastien Nocera */ #pragma once #include #include "cc-wacom-panel.h" #include "cc-wacom-device.h" G_BEGIN_DECLS #define CC_TYPE_WACOM_PAGE (cc_wacom_page_get_type ()) G_DECLARE_FINAL_TYPE (CcWacomPage, cc_wacom_page, CC, WACOM_PAGE, GtkBox) GtkWidget * cc_wacom_page_new (CcWacomPanel *panel, CcWacomDevice *stylus, CcWacomDevice *pad); gboolean cc_wacom_page_update_tools (CcWacomPage *page, CcWacomDevice *stylus, CcWacomDevice *pad); void cc_wacom_page_set_navigation (CcWacomPage *page, GtkNotebook *notebook, gboolean ignore_first_page); void cc_wacom_page_calibrate (CcWacomPage *page); gboolean cc_wacom_page_can_calibrate (CcWacomPage *page); G_END_DECLS cinnamon-control-center-6.4.1/panels/wacom/test-wacom.c0000664000175000017500000000704014724311620022024 0ustar fabiofabio #include "config.h" #include #include "cc-wacom-page.h" #define FIXED_WIDTH 675 // void // cc_wacom_panel_switch_to_panel (CcWacomPanel *self, const char *panel) // { // g_message ("Should launch %s preferences here", panel); // } // GDBusProxy * // cc_wacom_panel_get_gsd_wacom_bus_proxy (CcWacomPanel *self) // { // g_message ("Should get the g-s-d wacom dbus proxy here"); // return NULL; // } static void add_page (GList *devices, GtkWidget *notebook) { GtkWidget *widget; CcWacomDevice *stylus, *eraser, *pad; GList *l; if (devices == NULL) return; stylus = eraser = pad = NULL; for (l = devices; l ; l = l->next) { stylus = l->data; } g_list_free (devices); widget = cc_wacom_page_new (NULL, stylus, pad); cc_wacom_page_set_navigation (CC_WACOM_PAGE (widget), GTK_NOTEBOOK (notebook), FALSE); gtk_notebook_append_page (GTK_NOTEBOOK (notebook), widget, NULL); gtk_widget_show (widget); } static gboolean delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data) { gtk_main_quit (); return FALSE; } static GList * create_fake_cintiq (void) { CcWacomDevice *device; GList *devices; device = cc_wacom_device_new_fake ("Wacom Cintiq 21UX2"); devices = g_list_prepend (NULL, device); return devices; } static GList * create_fake_bt (void) { CcWacomDevice *device; GList *devices; device = cc_wacom_device_new_fake ("Wacom Graphire Wireless"); devices = g_list_prepend (NULL, device); return devices; } static GList * create_fake_x201 (void) { CcWacomDevice *device; GList *devices; device = cc_wacom_device_new_fake ("Wacom Serial Tablet WACf004"); devices = g_list_prepend (NULL, device); return devices; } static GList * create_fake_intuos4 (void) { CcWacomDevice *device; GList *devices; device = cc_wacom_device_new_fake ("Wacom Intuos4 6x9"); devices = g_list_prepend (NULL, device); return devices; } static GList * create_fake_h610pro (void) { CcWacomDevice *device; GList *devices; device = cc_wacom_device_new_fake ("Huion H610 Pro"); devices = g_list_prepend (NULL, device); return devices; } int main (int argc, char **argv) { GtkWidget *window, *notebook; GList *devices; bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_resizable (GTK_WINDOW (window), FALSE); gtk_window_set_default_size (GTK_WINDOW (window), FIXED_WIDTH, -1); g_signal_connect (G_OBJECT (window), "delete-event", G_CALLBACK (delete_event_cb), NULL); notebook = gtk_notebook_new (); gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE); gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), FALSE); gtk_widget_set_vexpand (notebook, TRUE); gtk_container_set_border_width (GTK_CONTAINER (notebook), 24); gtk_container_add (GTK_CONTAINER (window), notebook); gtk_widget_show (notebook); devices = create_fake_intuos4 (); add_page (devices, notebook); devices = create_fake_cintiq (); add_page (devices, notebook); devices = create_fake_bt (); add_page (devices, notebook); devices = create_fake_x201 (); add_page (devices, notebook); devices = create_fake_h610pro (); add_page (devices, notebook); gtk_widget_show (window); gtk_main (); return 0; } cinnamon-control-center-6.4.1/panels/wacom/wacom-stylus-classic.svg0000664000175000017500000001155414724311620024411 0ustar fabiofabio image/svg+xml cinnamon-control-center-6.4.1/panels/wacom/cinnamon-wacom.gresource.xml0000664000175000017500000000166014724311620025224 0ustar fabiofabio cinnamon-wacom-properties.ui wacom-stylus-page.ui button-mapping.ui calibrator/calibrator.ui calibrator/calibrator.css calibrator/target.svg wacom-tablet.svg wacom-stylus.svg wacom-stylus-3btn-no-eraser.svg wacom-stylus-3btn.svg wacom-stylus-no-eraser.svg wacom-stylus-airbrush.svg wacom-stylus-inking.svg wacom-stylus-art-pen.svg wacom-stylus-classic.svg wacom-tablet-cintiq.svg wacom-tablet-pc.svg cinnamon-control-center-6.4.1/panels/wacom/wacom-tablet.svg0000664000175000017500000000533614724311620022703 0ustar fabiofabio image/svg+xml cinnamon-control-center-6.4.1/panels/wacom/cc-wacom-stylus-page.c0000664000175000017500000003507114724311620023712 0ustar fabiofabio/* * Copyright Ā© 2011 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Authors: Peter Hutterer * Bastien Nocera * */ #include #include #include "cc-wacom-stylus-page.h" #include "cc-wacom-nav-button.h" #include "cc-drawing-area.h" #include #include #include #define WID(x) (GtkWidget *) gtk_builder_get_object (page->builder, x) #define CWID(x) (GtkContainer *) gtk_builder_get_object (page->builder, x) struct _CcWacomStylusPage { GtkBox parent_instance; CcWacomTool *stylus; GtkBuilder *builder; GtkWidget *nav; GSettings *stylus_settings; GtkWidget *test_draw_area; }; G_DEFINE_TYPE (CcWacomStylusPage, cc_wacom_stylus_page, GTK_TYPE_BOX) /* Button combo box storage columns */ enum { BUTTONNUMBER_COLUMN, BUTTONNAME_COLUMN, N_BUTTONCOLUMNS }; /* GSettings stores pressurecurve as 4 values like the driver. We map slider * scale to these values given the array below. These settings were taken from * wacomcpl, where they've been around for years. */ #define N_PRESSURE_CURVES 7 static const gint32 PRESSURE_CURVES[N_PRESSURE_CURVES][4] = { { 0, 75, 25, 100 }, /* soft */ { 0, 50, 50, 100 }, { 0, 25, 75, 100 }, { 0, 0, 100, 100 }, /* neutral */ { 25, 0, 100, 75 }, { 50, 0, 100, 50 }, { 75, 0, 100, 25 } /* firm */ }; static void set_pressurecurve (GtkRange *range, GSettings *settings, const gchar *key) { gint slider_val = gtk_range_get_value (range); GVariant *values[4], *array; int i; for (i = 0; i < G_N_ELEMENTS (values); i++) values[i] = g_variant_new_int32 (PRESSURE_CURVES[slider_val][i]); array = g_variant_new_array (G_VARIANT_TYPE_INT32, values, G_N_ELEMENTS (values)); g_settings_set_value (settings, key, array); } static void tip_feel_value_changed_cb (GtkRange *range, gpointer user_data) { CcWacomStylusPage *page = CC_WACOM_STYLUS_PAGE(user_data); set_pressurecurve (range, page->stylus_settings, "pressure-curve"); } static void eraser_feel_value_changed_cb (GtkRange *range, gpointer user_data) { CcWacomStylusPage *page = CC_WACOM_STYLUS_PAGE(user_data); set_pressurecurve (range, page->stylus_settings, "eraser-pressure-curve"); } static void set_feel_from_gsettings (GtkAdjustment *adjustment, GSettings *settings, const gchar *key) { GVariant *variant; const gint32 *values; gsize nvalues; int i; variant = g_settings_get_value (settings, key); values = g_variant_get_fixed_array (variant, &nvalues, sizeof (gint32)); if (nvalues != 4) { g_warning ("Invalid pressure curve format, expected 4 values (got %"G_GSIZE_FORMAT")", nvalues); return; } for (i = 0; i < N_PRESSURE_CURVES; i++) { if (memcmp (PRESSURE_CURVES[i], values, sizeof (gint32) * 4) == 0) { gtk_adjustment_set_value (adjustment, i); break; } } } static void set_button_mapping_from_gsettings (GtkComboBox *combo, GSettings* settings, const gchar *key) { CDesktopStylusButtonAction action; GtkTreeModel *model; GtkTreeIter iter; gboolean valid; action = g_settings_get_enum (settings, key); model = gtk_combo_box_get_model (combo); valid = gtk_tree_model_get_iter_first (model, &iter); while (valid) { gint button; gtk_tree_model_get (model, &iter, BUTTONNUMBER_COLUMN, &button, -1); /* Currently button values match logical X buttons. If we * introduce things like double-click, this code must * change. Recommendation: use negative buttons numbers for * special ones. */ if (button == action) { gtk_combo_box_set_active_iter (combo, &iter); break; } valid = gtk_tree_model_iter_next (model, &iter); } } static void button_changed_cb (GtkComboBox *combo, gpointer user_data) { CcWacomStylusPage *page = CC_WACOM_STYLUS_PAGE(user_data); GtkTreeIter iter; GtkListStore *liststore; gint mapping_b2, mapping_b3, mapping_b4; if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (WID ("combo-bottombutton")), &iter)) return; liststore = GTK_LIST_STORE (WID ("liststore-buttons")); gtk_tree_model_get (GTK_TREE_MODEL (liststore), &iter, BUTTONNUMBER_COLUMN, &mapping_b2, -1); if (cc_wacom_tool_get_num_buttons (page->stylus) > 1) { if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (WID ("combo-topbutton")), &iter)) return; gtk_tree_model_get (GTK_TREE_MODEL (liststore), &iter, BUTTONNUMBER_COLUMN, &mapping_b3, -1); } else { mapping_b3 = 0; } if (cc_wacom_tool_get_num_buttons (page->stylus) > 2) { if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (WID ("combo-thirdbutton")), &iter)) return; gtk_tree_model_get (GTK_TREE_MODEL (liststore), &iter, BUTTONNUMBER_COLUMN, &mapping_b4, -1); } else { mapping_b4 = 0; } g_settings_set_enum (page->stylus_settings, "button-action", mapping_b2); g_settings_set_enum (page->stylus_settings, "secondary-button-action", mapping_b3); g_settings_set_enum (page->stylus_settings, "tertiary-button-action", mapping_b4); } static void combobox_text_cellrenderer (GtkComboBox *combo, int name_column) { GtkCellRenderer *renderer; renderer = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "text", BUTTONNAME_COLUMN, NULL); } /* Boilerplate code goes below */ static void cc_wacom_stylus_page_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { switch (property_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void cc_wacom_stylus_page_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { switch (property_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void cc_wacom_stylus_page_dispose (GObject *object) { CcWacomStylusPage *page = CC_WACOM_STYLUS_PAGE (object); g_clear_object (&page->builder); G_OBJECT_CLASS (cc_wacom_stylus_page_parent_class)->dispose (object); } static void cc_wacom_stylus_page_class_init (CcWacomStylusPageClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->get_property = cc_wacom_stylus_page_get_property; object_class->set_property = cc_wacom_stylus_page_set_property; object_class->dispose = cc_wacom_stylus_page_dispose; } static void add_marks (GtkScale *scale) { gint i; for (i = 0; i < N_PRESSURE_CURVES; i++) gtk_scale_add_mark (scale, i, GTK_POS_BOTTOM, NULL); } static void cc_wacom_stylus_page_init (CcWacomStylusPage *page) { g_autoptr(GError) error = NULL; GtkComboBox *combo; GtkWidget *box; char *objects[] = { "stylus-grid", "liststore-buttons", "adjustment-tip-feel", "adjustment-eraser-feel", NULL }; page->builder = gtk_builder_new (); gtk_builder_add_objects_from_resource (page->builder, "/org/cinnamon/control-center/wacom/wacom-stylus-page.ui", objects, &error); if (error != NULL) { g_warning ("Error loading UI file: %s", error->message); return; } box = WID ("stylus-grid"); gtk_container_add (GTK_CONTAINER (page), box); gtk_widget_set_vexpand (GTK_WIDGET (box), TRUE); add_marks (GTK_SCALE (WID ("scale-tip-feel"))); add_marks (GTK_SCALE (WID ("scale-eraser-feel"))); g_signal_connect (WID ("scale-tip-feel"), "value-changed", G_CALLBACK (tip_feel_value_changed_cb), page); g_signal_connect (WID ("scale-eraser-feel"), "value-changed", G_CALLBACK (eraser_feel_value_changed_cb), page); combo = GTK_COMBO_BOX (WID ("combo-topbutton")); combobox_text_cellrenderer (combo, BUTTONNAME_COLUMN); g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (button_changed_cb), page); combo = GTK_COMBO_BOX (WID ("combo-bottombutton")); combobox_text_cellrenderer (combo, BUTTONNAME_COLUMN); g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (button_changed_cb), page); combo = GTK_COMBO_BOX (WID ("combo-thirdbutton")); combobox_text_cellrenderer (combo, BUTTONNAME_COLUMN); g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (button_changed_cb), page); page->nav = cc_wacom_nav_button_new (); gtk_widget_set_halign (page->nav, GTK_ALIGN_END); gtk_widget_set_margin_start (page->nav, 10); gtk_widget_show (page->nav); gtk_container_add (CWID ("navigation-placeholder"), page->nav); } static void set_icon_name (CcWacomStylusPage *page, const char *widget_name, const char *icon_name) { g_autofree gchar *resource = NULL; resource = g_strdup_printf ("/org/cinnamon/control-center/wacom/%s.svg", icon_name); gtk_image_set_from_resource (GTK_IMAGE (WID (widget_name)), resource); } /* Different types of layout for the stylus config */ enum { LAYOUT_NORMAL, /* eraser, 2 buttons, tip */ LAYOUT_INKING, /* tip */ LAYOUT_AIRBRUSH, /* eraser, 1 button, tip */ LAYOUT_GENERIC_2_BUTTONS_NO_ERASER, /* 2 buttons, tip, no eraser */ LAYOUT_3DPEN, /* 3 buttons, tip, no eraser */ LAYOUT_OTHER }; static void remove_buttons (CcWacomStylusPage *page, int n) { if (n < 3) { gtk_widget_destroy (WID ("combo-thirdbutton")); gtk_widget_destroy (WID ("label-third-button")); } if (n < 2) { gtk_widget_destroy (WID ("combo-topbutton")); gtk_widget_destroy (WID ("label-top-button")); gtk_label_set_text (GTK_LABEL (WID ("label-lower-button")), _("Button")); } if (n < 1) { gtk_widget_destroy (WID ("combo-bottombutton")); gtk_widget_destroy (WID ("label-lower-button")); } } static void remove_eraser (CcWacomStylusPage *page) { gtk_widget_destroy (WID ("eraser-box")); gtk_widget_destroy (WID ("label-eraser-feel")); } static void update_stylus_ui (CcWacomStylusPage *page, int layout) { switch (layout) { case LAYOUT_NORMAL: remove_buttons (page, 2); break; case LAYOUT_INKING: remove_buttons (page, 0); remove_eraser (page); gtk_container_child_set (CWID ("stylus-controls-grid"), WID ("label-tip-feel"), "top_attach", 0, NULL); gtk_container_child_set (CWID ("stylus-controls-grid"), WID ("box-tip-feel"), "top_attach", 0, NULL); break; case LAYOUT_AIRBRUSH: remove_buttons (page, 1); gtk_container_child_set (CWID ("stylus-controls-grid"), WID ("label-lower-button"), "top_attach", 1, NULL); gtk_container_child_set (CWID ("stylus-controls-grid"), WID ("combo-bottombutton"), "top_attach", 1, NULL); gtk_container_child_set (CWID ("stylus-controls-grid"), WID ("label-tip-feel"), "top_attach", 2, NULL); gtk_container_child_set (CWID ("stylus-controls-grid"), WID ("box-tip-feel"), "top_attach", 2, NULL); break; case LAYOUT_GENERIC_2_BUTTONS_NO_ERASER: remove_buttons (page, 2); remove_eraser (page); break; case LAYOUT_3DPEN: remove_buttons (page, 3); remove_eraser (page); break; case LAYOUT_OTHER: /* We already warn about it in cc_wacom_stylus_page_new () */ break; } } GtkWidget * cc_wacom_stylus_page_new (CcWacomTool *stylus) { CcWacomStylusPage *page; guint num_buttons; int layout; gboolean has_eraser; g_return_val_if_fail (CC_IS_WACOM_TOOL (stylus), NULL); page = g_object_new (CC_TYPE_WACOM_STYLUS_PAGE, NULL); page->stylus = stylus; /* Icon */ set_icon_name (page, "image-stylus", cc_wacom_tool_get_icon_name (stylus)); /* Settings */ page->stylus_settings = cc_wacom_tool_get_settings (stylus); has_eraser = cc_wacom_tool_get_has_eraser (stylus); /* Stylus name */ gtk_label_set_text (GTK_LABEL (WID ("label-stylus")), cc_wacom_tool_get_name (stylus)); num_buttons = cc_wacom_tool_get_num_buttons (stylus); if (num_buttons == 0 && !has_eraser) layout = LAYOUT_INKING; else if (num_buttons == 2 && has_eraser) layout = LAYOUT_NORMAL; else if (num_buttons == 1 && has_eraser) layout = LAYOUT_AIRBRUSH; else if (num_buttons == 2 && !has_eraser) layout = LAYOUT_GENERIC_2_BUTTONS_NO_ERASER; else if (num_buttons == 3 && !has_eraser) layout = LAYOUT_3DPEN; else { layout = LAYOUT_OTHER; remove_buttons (page, num_buttons); /* Gray out eraser if not available */ gtk_widget_set_sensitive (WID ("eraser-box"), has_eraser); gtk_widget_set_sensitive (WID ("label-eraser-feel"), has_eraser); g_warning ("The layout of this page is not known, %d buttons, %s eraser", num_buttons, has_eraser ? "with" : "without"); } update_stylus_ui (page, layout); if (num_buttons >= 3) set_button_mapping_from_gsettings (GTK_COMBO_BOX (WID ("combo-thirdbutton")), page->stylus_settings, "tertiary-button-action"); if (num_buttons >= 2) set_button_mapping_from_gsettings (GTK_COMBO_BOX (WID ("combo-topbutton")), page->stylus_settings, "secondary-button-action"); if (num_buttons >= 1) set_button_mapping_from_gsettings (GTK_COMBO_BOX (WID ("combo-bottombutton")), page->stylus_settings, "button-action"); set_feel_from_gsettings (GTK_ADJUSTMENT (WID ("adjustment-tip-feel")), page->stylus_settings, "pressure-curve"); if (has_eraser) set_feel_from_gsettings (GTK_ADJUSTMENT (WID ("adjustment-eraser-feel")), page->stylus_settings, "eraser-pressure-curve"); page->test_draw_area = cc_drawing_area_new (); gtk_widget_set_size_request (page->test_draw_area, 400, 300); gtk_box_pack_start (GTK_BOX (WID ("test_box")), page->test_draw_area, TRUE, TRUE, 6); gtk_widget_show (page->test_draw_area); return GTK_WIDGET (page); } CcWacomTool * cc_wacom_stylus_page_get_tool (CcWacomStylusPage *page) { return page->stylus; } void cc_wacom_stylus_page_set_navigation (CcWacomStylusPage *page, GtkNotebook *notebook) { g_return_if_fail (CC_IS_WACOM_STYLUS_PAGE (page)); g_object_set (G_OBJECT (page->nav), "notebook", notebook, "ignore-first", TRUE, NULL); } cinnamon-control-center-6.4.1/panels/wacom/cc-wacom-device.c0000664000175000017500000002156614724311620022700 0ustar fabiofabio/* * Copyright Ā© 2016 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Authors: Carlos Garnacho * */ #include "config.h" #include #include "cc-wacom-device.h" #include "muffin-display-config.h" enum { PROP_0, PROP_DEVICE, N_PROPS }; GParamSpec *props[N_PROPS] = { 0 }; typedef struct _CcWacomDevice CcWacomDevice; struct _CcWacomDevice { GObject parent_instance; CsdDevice *device; WacomDevice *wdevice; MetaDBusDisplayConfig *proxy; GList *monitors; }; static void cc_wacom_device_initable_iface_init (GInitableIface *iface); G_DEFINE_TYPE_WITH_CODE (CcWacomDevice, cc_wacom_device, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, cc_wacom_device_initable_iface_init)) // G_DEFINE_TYPE (CcWacomDevice, cc_wacom_device, G_TYPE_OBJECT) enum { MONITORS_CHANGED, N_SIGNALS, }; WacomDeviceDatabase * cc_wacom_device_database_get (void) { static WacomDeviceDatabase *db = NULL; if (g_once_init_enter (&db)) { gpointer p = libwacom_database_new (); g_once_init_leave (&db, p); } return db; } static void cc_wacom_device_init (CcWacomDevice *device) { } static void cc_wacom_device_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { CcWacomDevice *device = CC_WACOM_DEVICE (object); switch (prop_id) { case PROP_DEVICE: device->device = g_value_get_object (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void cc_wacom_device_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { CcWacomDevice *device = CC_WACOM_DEVICE (object); switch (prop_id) { case PROP_DEVICE: g_value_set_object (value, device->device); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void cc_wacom_device_finalize (GObject *object) { CcWacomDevice *device = CC_WACOM_DEVICE (object); g_clear_pointer (&device->wdevice, libwacom_destroy); G_OBJECT_CLASS (cc_wacom_device_parent_class)->finalize (object); } static void cc_wacom_device_class_init (CcWacomDeviceClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); // object_class->constructed = cc_wacom_device_constructed; object_class->set_property = cc_wacom_device_set_property; object_class->get_property = cc_wacom_device_get_property; object_class->finalize = cc_wacom_device_finalize; props[PROP_DEVICE] = g_param_spec_object ("device", "device", "device", CSD_TYPE_DEVICE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_properties (object_class, N_PROPS, props); } static gboolean cc_wacom_device_initable_init (GInitable *initable, GCancellable *cancellable, GError **error) { CcWacomDevice *device = CC_WACOM_DEVICE (initable); WacomDeviceDatabase *wacom_db; const gchar *node_path; wacom_db = cc_wacom_device_database_get (); node_path = csd_device_get_device_file (device->device); device->wdevice = libwacom_new_from_path (wacom_db, node_path, FALSE, NULL); if (!device->wdevice) { g_set_error (error, 0, 0, "Tablet description not found"); return FALSE; } return TRUE; } static void cc_wacom_device_initable_iface_init (GInitableIface *iface) { iface->init = cc_wacom_device_initable_init; } CcWacomDevice * cc_wacom_device_new (CsdDevice *device) { return g_initable_new (CC_TYPE_WACOM_DEVICE, NULL, NULL, "device", device, NULL); } CcWacomDevice * cc_wacom_device_new_fake (const gchar *name) { CcWacomDevice *device; WacomDevice *wacom_device; device = g_object_new (CC_TYPE_WACOM_DEVICE, NULL); wacom_device = libwacom_new_from_name (cc_wacom_device_database_get(), name, NULL); if (wacom_device == NULL) return NULL; device->wdevice = wacom_device; return device; } const gchar * cc_wacom_device_get_name (CcWacomDevice *device) { g_return_val_if_fail (CC_IS_WACOM_DEVICE (device), NULL); return libwacom_get_name (device->wdevice); } const gchar * cc_wacom_device_get_icon_name (CcWacomDevice *device) { WacomIntegrationFlags integration_flags; g_return_val_if_fail (CC_IS_WACOM_DEVICE (device), NULL); integration_flags = libwacom_get_integration_flags (device->wdevice); if (integration_flags & WACOM_DEVICE_INTEGRATED_SYSTEM) { return "wacom-tablet-pc"; } else if (integration_flags & WACOM_DEVICE_INTEGRATED_DISPLAY) { return "wacom-tablet-cintiq"; } else { return "wacom-tablet"; } } gboolean cc_wacom_device_is_reversible (CcWacomDevice *device) { g_return_val_if_fail (CC_IS_WACOM_DEVICE (device), FALSE); return libwacom_is_reversible (device->wdevice); } WacomIntegrationFlags cc_wacom_device_get_integration_flags (CcWacomDevice *device) { g_return_val_if_fail (CC_IS_WACOM_DEVICE (device), 0); return libwacom_get_integration_flags (device->wdevice); } CsdDevice * cc_wacom_device_get_device (CcWacomDevice *device) { g_return_val_if_fail (CC_IS_WACOM_DEVICE (device), NULL); return device->device; } GSettings * cc_wacom_device_get_settings (CcWacomDevice *device) { g_return_val_if_fail (CC_IS_WACOM_DEVICE (device), NULL); return csd_device_get_settings (device->device); } const gint * cc_wacom_device_get_supported_tools (CcWacomDevice *device, gint *n_tools) { *n_tools = 0; g_return_val_if_fail (CC_IS_WACOM_DEVICE (device), NULL); return libwacom_get_supported_styli (device->wdevice, n_tools); } static MonitorInfo * find_monitor (CcWacomDevice *device) { GList *monitors, *l; g_autoptr(GSettings) settings = NULL; g_autoptr(GVariant) variant = NULL; g_autofree const gchar **edid = NULL; gsize n; settings = cc_wacom_device_get_settings (device); variant = g_settings_get_value (settings, "output"); edid = g_variant_get_strv (variant, &n); if (n != 3) { g_critical ("Expected 'output' key to store %d values; got %"G_GSIZE_FORMAT".", 3, n); return NULL; } if (strlen (edid[0]) == 0 || strlen (edid[1]) == 0 || strlen (edid[2]) == 0) return NULL; monitors = cc_wacom_output_manager_get_all_monitors (cc_wacom_output_manager_get ()); for (l = monitors; l != NULL; l = l->next) { MonitorInfo *info = (MonitorInfo *) l->data; if (g_strcmp0 (info->vendor, edid[0]) == 0 && g_strcmp0 (info->product, edid[1]) == 0 && g_strcmp0 (info->serial, edid[2]) == 0) return info; } return NULL; } MonitorInfo * cc_wacom_device_get_monitor (CcWacomDevice *device) { MonitorInfo *monitor; g_return_val_if_fail (CC_IS_WACOM_DEVICE (device), NULL); monitor = find_monitor (device); if (monitor == NULL) { return NULL; } return monitor; } void cc_wacom_device_set_monitor (CcWacomDevice *device, MonitorInfo *monitor) { g_autoptr(GSettings) settings = NULL; const gchar *values[] = { "", "", "", NULL }; g_return_if_fail (CC_IS_WACOM_DEVICE (device)); settings = cc_wacom_device_get_settings (device); if (monitor != NULL) { values[0] = monitor->vendor; values[1] = monitor->product; values[2] = monitor->serial; } g_settings_set_strv (settings, "output", values); } guint cc_wacom_device_get_num_buttons (CcWacomDevice *device) { g_return_val_if_fail (CC_IS_WACOM_DEVICE (device), 0); return libwacom_get_num_buttons (device->wdevice); } GSettings * cc_wacom_device_get_button_settings (CcWacomDevice *device, guint button) { g_autoptr(GSettings) tablet_settings = NULL; GSettings *settings; g_autofree gchar *path = NULL; g_autofree gchar *button_path = NULL; g_return_val_if_fail (CC_IS_WACOM_DEVICE (device), NULL); if (button > cc_wacom_device_get_num_buttons (device)) return NULL; tablet_settings = cc_wacom_device_get_settings (device); g_object_get (tablet_settings, "path", &path, NULL); button_path = g_strdup_printf ("%sbutton%c/", path, 'A' + button); settings = g_settings_new_with_path ("org.cinnamon.desktop.peripherals.tablet.pad-button", button_path); return settings; } cinnamon-control-center-6.4.1/panels/wacom/cc-wacom-tool.c0000664000175000017500000001620614724311620022411 0ustar fabiofabio/* * Copyright Ā© 2016 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Authors: Carlos Garnacho * */ #include "config.h" #include "cc-wacom-tool.h" enum { PROP_0, PROP_SERIAL, PROP_ID, PROP_DEVICE, N_PROPS }; static GParamSpec *props[N_PROPS] = { 0 }; typedef struct _CcWacomTool CcWacomTool; struct _CcWacomTool { GObject parent_instance; guint64 serial; guint64 id; CcWacomDevice *device; /* Only set for tools with no serial */ GSettings *settings; const WacomStylus *wstylus; }; static void cc_wacom_tool_initable_iface_init (GInitableIface *iface); G_DEFINE_TYPE_WITH_CODE (CcWacomTool, cc_wacom_tool, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, cc_wacom_tool_initable_iface_init)) static void cc_wacom_tool_init (CcWacomTool *tool) { } static void cc_wacom_tool_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { CcWacomTool *tool = CC_WACOM_TOOL (object); switch (prop_id) { case PROP_SERIAL: tool->serial = g_value_get_uint64 (value); break; case PROP_ID: tool->id = g_value_get_uint64 (value); break; case PROP_DEVICE: tool->device = g_value_get_object (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void cc_wacom_tool_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { CcWacomTool *tool = CC_WACOM_TOOL (object); switch (prop_id) { case PROP_SERIAL: g_value_set_uint64 (value, tool->serial); break; case PROP_ID: g_value_set_uint64 (value, tool->id); break; case PROP_DEVICE: g_value_set_object (value, tool->device); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void cc_wacom_tool_finalize (GObject *object) { CcWacomTool *tool = CC_WACOM_TOOL (object); g_clear_object (&tool->settings); G_OBJECT_CLASS (cc_wacom_tool_parent_class)->finalize (object); } static void cc_wacom_tool_class_init (CcWacomToolClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->set_property = cc_wacom_tool_set_property; object_class->get_property = cc_wacom_tool_get_property; object_class->finalize = cc_wacom_tool_finalize; props[PROP_SERIAL] = g_param_spec_uint64 ("serial", "serial", "serial", 0, G_MAXUINT64, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); props[PROP_ID] = g_param_spec_uint64 ("id", "id", "id", 0, G_MAXUINT64, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); props[PROP_DEVICE] = g_param_spec_object ("device", "device", "device", CC_TYPE_WACOM_DEVICE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_properties (object_class, N_PROPS, props); } static gboolean cc_wacom_tool_initable_init (GInitable *initable, GCancellable *cancellable, GError **error) { CcWacomTool *tool = CC_WACOM_TOOL (initable); WacomDeviceDatabase *wacom_db; gchar *path; wacom_db = cc_wacom_device_database_get (); if (tool->id == 0 && tool->device) { const gint *ids; gint n_supported; ids = cc_wacom_device_get_supported_tools (tool->device, &n_supported); if (n_supported > 0) tool->id = ids[0]; } if (tool->id == 0) tool->wstylus = libwacom_stylus_get_for_id (wacom_db, 0xfffff); else tool->wstylus = libwacom_stylus_get_for_id (wacom_db, tool->id); if (!tool->wstylus) { g_set_error (error, 0, 0, "Stylus description not found"); return FALSE; } if (tool->serial == 0) { const gchar *vendor, *product; CsdDevice *csd_device; csd_device = cc_wacom_device_get_device (tool->device); csd_device_get_device_ids (csd_device, &vendor, &product); path = g_strdup_printf ("/org/cinnamon/desktop/peripherals/stylus/default-%s:%s/", vendor, product); } else { path = g_strdup_printf ("/org/cinnamon/desktop/peripherals/stylus/%lx/", tool->serial); } tool->settings = g_settings_new_with_path ("org.cinnamon.desktop.peripherals.tablet.stylus", path); g_free (path); return TRUE; } static void cc_wacom_tool_initable_iface_init (GInitableIface *iface) { iface->init = cc_wacom_tool_initable_init; } CcWacomTool * cc_wacom_tool_new (guint64 serial, guint64 id, CcWacomDevice *device) { g_return_val_if_fail (serial != 0 || CC_IS_WACOM_DEVICE (device), NULL); return g_initable_new (CC_TYPE_WACOM_TOOL, NULL, NULL, "serial", serial, "id", id, "device", device, NULL); } guint64 cc_wacom_tool_get_serial (CcWacomTool *tool) { g_return_val_if_fail (CC_IS_WACOM_TOOL (tool), 0); return tool->serial; } guint64 cc_wacom_tool_get_id (CcWacomTool *tool) { g_return_val_if_fail (CC_IS_WACOM_TOOL (tool), 0); return tool->id; } const gchar * cc_wacom_tool_get_name (CcWacomTool *tool) { g_return_val_if_fail (CC_IS_WACOM_TOOL (tool), NULL); return libwacom_stylus_get_name (tool->wstylus); } static const char * get_icon_name_from_type (const WacomStylus *wstylus) { WacomStylusType type = libwacom_stylus_get_type (wstylus); switch (type) { case WSTYLUS_INKING: case WSTYLUS_STROKE: /* The stroke pen is the same as the inking pen with * a different nib */ return "wacom-stylus-inking"; case WSTYLUS_AIRBRUSH: return "wacom-stylus-airbrush"; case WSTYLUS_MARKER: return "wacom-stylus-art-pen"; case WSTYLUS_CLASSIC: return "wacom-stylus-classic"; #ifdef HAVE_WACOM_3D_STYLUS case WSTYLUS_3D: return "wacom-stylus-3btn-no-eraser"; #endif default: if (!libwacom_stylus_has_eraser (wstylus)) { if (libwacom_stylus_get_num_buttons (wstylus) >= 3) return "wacom-stylus-3btn-no-eraser"; else return "wacom-stylus-no-eraser"; } else { if (libwacom_stylus_get_num_buttons (wstylus) >= 3) return "wacom-stylus-3btn"; else return "wacom-stylus"; } } } const gchar * cc_wacom_tool_get_icon_name (CcWacomTool *tool) { g_return_val_if_fail (CC_IS_WACOM_TOOL (tool), NULL); return get_icon_name_from_type (tool->wstylus); } GSettings * cc_wacom_tool_get_settings (CcWacomTool *tool) { g_return_val_if_fail (CC_IS_WACOM_TOOL (tool), NULL); return tool->settings; } guint cc_wacom_tool_get_num_buttons (CcWacomTool *tool) { g_return_val_if_fail (CC_IS_WACOM_TOOL (tool), 0); return libwacom_stylus_get_num_buttons (tool->wstylus); } gboolean cc_wacom_tool_get_has_eraser (CcWacomTool *tool) { g_return_val_if_fail (CC_IS_WACOM_TOOL (tool), FALSE); return libwacom_stylus_has_eraser (tool->wstylus); } cinnamon-control-center-6.4.1/panels/wacom/cc-wacom-page.c0000664000175000017500000006136214724311620022353 0ustar fabiofabio/* * Copyright Ā© 2011 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Authors: Peter Hutterer * Bastien Nocera * */ #include #ifdef FAKE_AREA #include #endif /* FAKE_AREA */ #include #include #ifdef GDK_WINDOWING_X11 #include #endif #ifdef GDK_WINDOWING_WAYLAND #include #endif #include "cc-wacom-device.h" #include "cc-wacom-button-row.h" #include "cc-wacom-page.h" #include "cc-wacom-nav-button.h" #include "cc-wacom-mapping-panel.h" #include "cc-wacom-stylus-page.h" #include "cc-wacom-output-manager.h" #include "calibrator-gui.h" #include "csd-input-helper.h" #include #define WID(x) (GtkWidget *) gtk_builder_get_object (page->builder, x) #define CWID(x) (GtkContainer *) gtk_builder_get_object (page->builder, x) #define MWID(x) (GtkWidget *) gtk_builder_get_object (page->mapping_builder, x) #define THRESHOLD_MISCLICK 15 #define THRESHOLD_DOUBLECLICK 7 enum { MAPPING_DESCRIPTION_COLUMN, MAPPING_TYPE_COLUMN, MAPPING_BUTTON_COLUMN, MAPPING_BUTTON_DIRECTION, MAPPING_N_COLUMNS }; struct _CcWacomPage { GtkBox parent_instance; CcWacomPanel *panel; CcWacomDevice *stylus; CcWacomDevice *pad; GtkBuilder *builder; GtkWidget *nav; GtkWidget *notebook; CalibArea *area; GSettings *wacom_settings; GtkSizeGroup *header_group; /* Button mapping */ GtkBuilder *mapping_builder; GtkWidget *button_map; GtkListStore *action_store; /* Display mapping */ GtkWidget *mapping; GtkWidget *dialog; GCancellable *cancellable; }; G_DEFINE_TYPE (CcWacomPage, cc_wacom_page, GTK_TYPE_BOX) /* Button combo box storage columns */ enum { BUTTONNUMBER_COLUMN, BUTTONNAME_COLUMN, N_BUTTONCOLUMNS }; /* Tablet mode combo box storage columns */ enum { MODENUMBER_COLUMN, MODELABEL_COLUMN, N_MODECOLUMNS }; /* Tablet mode options - keep in sync with .ui */ enum { MODE_ABSOLUTE, /* stylus + eraser absolute */ MODE_RELATIVE, /* stylus + eraser relative */ }; /* Different types of layout for the tablet config */ enum { LAYOUT_NORMAL, /* tracking mode, button mapping */ LAYOUT_REVERSIBLE, /* tracking mode, button mapping, left-hand orientation */ LAYOUT_SCREEN /* button mapping, calibration, display resolution */ }; static void update_tablet_ui (CcWacomPage *page, int layout); static int get_layout_type (CcWacomDevice *device) { int layout; if (cc_wacom_device_get_integration_flags (device) & (WACOM_DEVICE_INTEGRATED_DISPLAY | WACOM_DEVICE_INTEGRATED_SYSTEM)) layout = LAYOUT_SCREEN; else if (cc_wacom_device_is_reversible (device)) layout = LAYOUT_REVERSIBLE; else layout = LAYOUT_NORMAL; return layout; } static void set_calibration (CcWacomDevice *device, const gint display_width, const gint display_height, gdouble *cal, gsize ncal, GSettings *settings) { GVariant *current; /* current calibration */ GVariant *array; /* new calibration */ g_autofree GVariant **tmp = NULL; gsize nvalues; gint i; current = g_settings_get_value (settings, "area"); g_variant_get_fixed_array (current, &nvalues, sizeof (gdouble)); if ((ncal != 4) || (nvalues != 4)) { g_warning("Unable set set device calibration property. Got %"G_GSIZE_FORMAT" items to put in %"G_GSIZE_FORMAT" slots; expected %d items.\n", ncal, nvalues, 4); return; } tmp = g_malloc (nvalues * sizeof (GVariant*)); for (i = 0; i < ncal; i++) tmp[i] = g_variant_new_double (cal[i]); array = g_variant_new_array (G_VARIANT_TYPE_DOUBLE, tmp, nvalues); g_settings_set_value (settings, "area", array); g_debug ("Setting area to %f, %f, %f, %f (left/right/top/bottom) (last used resolution: %d x %d)", cal[0], cal[1], cal[2], cal[3], display_width, display_height); } static void finish_calibration (CalibArea *area, gpointer user_data) { CcWacomPage *page = (CcWacomPage *) user_data; XYinfo axis; gdouble cal[4]; gint display_width, display_height; if (calib_area_finish (area)) { calib_area_get_padding (area, &axis); cal[0] = axis.x_min; cal[1] = axis.x_max; cal[2] = axis.y_min; cal[3] = axis.y_max; calib_area_get_display_size (area, &display_width, &display_height); set_calibration (page->stylus, display_width, display_height, cal, 4, page->wacom_settings); } else { /* Reset the old values */ GVariant *old_calibration; old_calibration = g_object_get_data (G_OBJECT (page), "old-calibration"); g_settings_set_value (page->wacom_settings, "area", old_calibration); g_object_set_data (G_OBJECT (page), "old-calibration", NULL); } calib_area_free (area); page->area = NULL; gtk_widget_set_sensitive (WID ("button-calibrate"), TRUE); } static GdkDevice * cc_wacom_page_get_gdk_device (CcWacomPage *page) { CsdDevice *csd_device; GdkDevice *gdk_device = NULL; GdkDisplay *display; GdkSeat *seat; g_autoptr(GList) slaves = NULL; GList *l; csd_device = cc_wacom_device_get_device (page->stylus); g_return_val_if_fail (CSD_IS_DEVICE (csd_device), NULL); display = gtk_widget_get_display (GTK_WIDGET (page)); seat = gdk_display_get_default_seat (display); slaves = gdk_seat_get_slaves (seat, GDK_SEAT_CAPABILITY_TABLET_STYLUS); for (l = slaves; l && !gdk_device; l = l->next) { g_autofree gchar *device_node = NULL; if (gdk_device_get_source (l->data) != GDK_SOURCE_PEN) continue; #ifdef GDK_WINDOWING_X11 if (GDK_IS_X11_DISPLAY (display)) device_node = xdevice_get_device_node (gdk_x11_device_get_id (l->data)); #endif #ifdef GDK_WINDOWING_WAYLAND if (GDK_IS_WAYLAND_DISPLAY (display)) device_node = g_strdup (gdk_wayland_device_get_node_path (l->data)); #endif if (g_strcmp0 (device_node, csd_device_get_device_file (csd_device)) == 0) gdk_device = l->data; } return gdk_device; } static gboolean run_calibration (CcWacomPage *page, GVariant *old_calibration, gdouble *cal, GdkMonitor *monitor) { GdkDisplay *display = gdk_monitor_get_display (monitor); gint i, n_monitor = 0; g_assert (page->area == NULL); for (i = 0; i < gdk_display_get_n_monitors (display); i++) { if (monitor == gdk_display_get_monitor (display, i)) { n_monitor = i; break; } } page->area = calib_area_new (NULL, n_monitor, cc_wacom_page_get_gdk_device (page), finish_calibration, page, THRESHOLD_MISCLICK, THRESHOLD_DOUBLECLICK); g_object_set_data_full (G_OBJECT (page), "old-calibration", old_calibration, (GDestroyNotify) g_variant_unref); return FALSE; } static void calibrate (CcWacomPage *page) { int i; GVariant *old_calibration, *array; g_autofree GVariant **tmp = NULL; g_autofree gdouble *calibration = NULL; gsize ncal; GdkMonitor *monitor = NULL; GdkScreen *screen; g_autoptr(GError) error = NULL; MonitorInfo *info; screen = gdk_screen_get_default (); if (error) { g_warning ("Could not connect to display manager: %s", error->message); return; } info = cc_wacom_device_get_monitor (page->stylus); if (info) { monitor = gdk_display_get_monitor_at_point (gdk_screen_get_display (screen), info->x, info->y); } if (!monitor) { /* The display the tablet should be mapped to could not be located. * This shouldn't happen if the EDID data is good... */ g_critical("Output associated with the tablet is not connected. Unable to calibrate."); return; } old_calibration = g_settings_get_value (page->wacom_settings, "area"); g_variant_get_fixed_array (old_calibration, &ncal, sizeof (gdouble)); if (ncal != 4) { g_warning("Device calibration property has wrong length. Got %"G_GSIZE_FORMAT" items; expected %d.\n", ncal, 4); return; } calibration = g_new0 (gdouble, ncal); /* Reset the current values, to avoid old calibrations * from interfering with the calibration */ tmp = g_malloc (ncal * sizeof (GVariant*)); for (i = 0; i < ncal; i++) { calibration[i] = 0.0; tmp[i] = g_variant_new_double (calibration[i]); } array = g_variant_new_array (G_VARIANT_TYPE_DOUBLE, tmp, ncal); g_settings_set_value (page->wacom_settings, "area", array); run_calibration (page, old_calibration, calibration, monitor); gtk_widget_set_sensitive (WID ("button-calibrate"), FALSE); } static void calibrate_button_clicked_cb (GtkButton *button, CcWacomPage *page) { calibrate (page); } /* This avoids us crashing when a newer version of * gnome-control-center has been used, and we load up an * old one, as the action type if unknown to the old g-c-c */ static gboolean action_type_is_valid (CDesktopPadButtonAction action) { if (action >= G_N_ELEMENTS (action_table)) return FALSE; return TRUE; } static void create_row_from_button (GtkWidget *list_box, guint button, GSettings *settings) { GtkWidget *row; row = cc_wacom_button_row_new (button, settings); gtk_container_add (GTK_CONTAINER (list_box), row); gtk_widget_show (row); } static void setup_button_mapping (CcWacomPage *page) { CDesktopPadButtonAction action; GtkWidget *list_box; guint i, n_buttons; GSettings *settings; list_box = MWID ("shortcuts_list"); n_buttons = cc_wacom_device_get_num_buttons (page->pad); for (i = 0; i < n_buttons; i++) { settings = cc_wacom_device_get_button_settings (page->pad, i); if (!settings) continue; action = g_settings_get_enum (settings, "action"); if (!action_type_is_valid (action)) continue; create_row_from_button (list_box, i, settings); } } static void button_mapping_dialog_closed (GtkDialog *dialog, int response_id, CcWacomPage *page) { gtk_widget_destroy (MWID ("button-mapping-dialog")); g_clear_object (&page->mapping_builder); } static void show_button_mapping_dialog (CcWacomPage *page) { GtkWidget *toplevel; g_autoptr(GError) error = NULL; GtkWidget *dialog; g_assert (page->mapping_builder == NULL); page->mapping_builder = gtk_builder_new (); gtk_builder_add_from_resource (page->mapping_builder, "/org/cinnamon/control-center/wacom/button-mapping.ui", &error); if (error != NULL) { g_warning ("Error loading UI file: %s", error->message); g_clear_object (&page->mapping_builder); return; } setup_button_mapping (page); dialog = MWID ("button-mapping-dialog"); toplevel = gtk_widget_get_toplevel (GTK_WIDGET (page)); gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (toplevel)); gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (button_mapping_dialog_closed), page); gtk_widget_show (dialog); page->button_map = dialog; g_object_add_weak_pointer (G_OBJECT (dialog), (gpointer *) &page->button_map); } static void map_buttons_button_clicked_cb (GtkButton *button, CcWacomPage *page) { show_button_mapping_dialog (page); } static void display_mapping_dialog_closed (GtkDialog *dialog, int response_id, CcWacomPage *page) { int layout; gtk_widget_destroy (page->dialog); page->dialog = NULL; page->mapping = NULL; layout = get_layout_type (page->stylus); update_tablet_ui (page, layout); } static void display_mapping_button_clicked_cb (GtkButton *button, CcWacomPage *page) { g_assert (page->mapping == NULL); page->dialog = gtk_dialog_new_with_buttons (_("Display Mapping"), GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (page))), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, _("_Close"), GTK_RESPONSE_ACCEPT, NULL); page->mapping = cc_wacom_mapping_panel_new (); cc_wacom_mapping_panel_set_device (CC_WACOM_MAPPING_PANEL (page->mapping), page->stylus); gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (page->dialog))), page->mapping); g_signal_connect (G_OBJECT (page->dialog), "response", G_CALLBACK (display_mapping_dialog_closed), page); gtk_widget_show_all (page->dialog); g_object_add_weak_pointer (G_OBJECT (page->mapping), (gpointer *) &page->dialog); } static void tabletmode_changed_cb (GtkComboBox *combo, gpointer user_data) { CcWacomPage *page = CC_WACOM_PAGE (user_data); GtkListStore *liststore; GtkTreeIter iter; gint mode; if (!gtk_combo_box_get_active_iter (combo, &iter)) return; liststore = GTK_LIST_STORE (WID ("liststore-tabletmode")); gtk_tree_model_get (GTK_TREE_MODEL (liststore), &iter, MODENUMBER_COLUMN, &mode, -1); g_settings_set_enum (page->wacom_settings, "mapping", mode); } static void left_handed_toggled_cb (GtkSwitch *sw, GParamSpec *pspec, gpointer *user_data) { CcWacomPage *page = CC_WACOM_PAGE (user_data); gboolean left_handed; left_handed = gtk_switch_get_active (sw); g_settings_set_boolean (page->wacom_settings, "left-handed", left_handed); } static void set_left_handed_from_gsettings (CcWacomPage *page) { gboolean left_handed; left_handed = g_settings_get_boolean (page->wacom_settings, "left-handed"); gtk_switch_set_active (GTK_SWITCH (WID ("switch-left-handed")), left_handed); } static void set_mode_from_gsettings (GtkComboBox *combo, CcWacomPage *page) { CDesktopTabletMapping mapping; mapping = g_settings_get_enum (page->wacom_settings, "mapping"); /* this must be kept in sync with the .ui file */ gtk_combo_box_set_active (combo, mapping); } static void update_display_decoupled_sensitivity (CcWacomPage *page, gboolean active) { if (get_layout_type (page->stylus) != LAYOUT_SCREEN) return; gtk_widget_set_sensitive (WID ("label-trackingmode"), active); gtk_widget_set_sensitive (WID ("combo-tabletmode"), active); gtk_widget_set_sensitive (WID ("display-mapping-button-2"), active); gtk_widget_set_sensitive (WID ("button-calibrate"), !active); } static void set_display_decoupled_from_gsettings (GtkSwitch *sw, CcWacomPage *page) { g_auto(GStrv) output = g_settings_get_strv (page->wacom_settings, "output"); gboolean active = output != NULL && g_strcmp0 (output[0], "") != 0; gtk_switch_set_active (sw, active); update_display_decoupled_sensitivity (page, active); } static void combobox_text_cellrenderer (GtkComboBox *combo, int name_column) { GtkCellRenderer *renderer; renderer = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "text", BUTTONNAME_COLUMN, NULL); } static gboolean display_clicked_cb (GtkButton *button, CcWacomPage *page) { g_spawn_command_line_async ("cinnamon-settings display", NULL); return TRUE; } static gboolean mouse_clicked_cb (GtkButton *button, CcWacomPage *page) { g_spawn_command_line_async ("cinnamon-settings mouse", NULL); return TRUE; } static void decouple_display_toggled_cb (GtkSwitch *sw, GParamSpec *pspec, CcWacomPage *page) { gboolean active = gtk_switch_get_active (sw); update_display_decoupled_sensitivity (page, active); if (!active) { cc_wacom_device_set_monitor (page->stylus, NULL); } else { GList *monitors, *l; MonitorInfo *monitor = NULL; monitors = cc_wacom_output_manager_get_all_monitors (cc_wacom_output_manager_get ()); for (l = monitors; l != NULL; l = l->next) { monitor = (MonitorInfo *) l->data; if (monitor->builtin) { break; } } if (monitor == NULL) { monitor = (MonitorInfo *) monitors->data; } cc_wacom_device_set_monitor (page->stylus, monitor); } } /* Boilerplate code goes below */ static void cc_wacom_page_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { switch (property_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void cc_wacom_page_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { switch (property_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void cc_wacom_page_dispose (GObject *object) { CcWacomPage *self = CC_WACOM_PAGE (object); g_cancellable_cancel (self->cancellable); g_clear_object (&self->cancellable); g_clear_pointer (&self->area, calib_area_free); g_clear_pointer (&self->button_map, gtk_widget_destroy); g_clear_pointer (&self->dialog, gtk_widget_destroy); g_clear_object (&self->builder); g_clear_object (&self->header_group); self->panel = NULL; G_OBJECT_CLASS (cc_wacom_page_parent_class)->dispose (object); } static void cc_wacom_page_class_init (CcWacomPageClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->get_property = cc_wacom_page_get_property; object_class->set_property = cc_wacom_page_set_property; object_class->dispose = cc_wacom_page_dispose; } static void remove_link_padding (GtkWidget *widget) { g_autoptr(GtkCssProvider) provider = NULL; provider = gtk_css_provider_new (); gtk_css_provider_load_from_data (GTK_CSS_PROVIDER (provider), ".link { padding: 0px; }", -1, NULL); gtk_style_context_add_provider (gtk_widget_get_style_context (widget), GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); } static void cc_wacom_page_init (CcWacomPage *page) { g_autoptr(GError) error = NULL; GtkComboBox *combo; GtkWidget *box; GtkSwitch *sw; char *objects[] = { "main-grid", "liststore-tabletmode", "liststore-buttons", "adjustment-tip-feel", "adjustment-eraser-feel", NULL }; page->builder = gtk_builder_new (); gtk_builder_add_objects_from_resource (page->builder, "/org/cinnamon/control-center/wacom/cinnamon-wacom-properties.ui", objects, &error); if (error != NULL) { g_warning ("Error loading UI file: %s", error->message); return; } box = WID ("main-grid"); gtk_container_add (GTK_CONTAINER (page), box); gtk_widget_set_vexpand (GTK_WIDGET (box), TRUE); g_signal_connect (WID ("button-calibrate"), "clicked", G_CALLBACK (calibrate_button_clicked_cb), page); g_signal_connect (WID ("map-buttons-button"), "clicked", G_CALLBACK (map_buttons_button_clicked_cb), page); combo = GTK_COMBO_BOX (WID ("combo-tabletmode")); combobox_text_cellrenderer (combo, MODELABEL_COLUMN); g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (tabletmode_changed_cb), page); sw = GTK_SWITCH (WID ("switch-left-handed")); g_signal_connect (G_OBJECT (sw), "notify::active", G_CALLBACK (left_handed_toggled_cb), page); g_signal_connect (G_OBJECT (WID ("display-link")), "activate-link", G_CALLBACK (display_clicked_cb), page); remove_link_padding (WID ("display-link")); g_signal_connect (G_OBJECT (WID ("mouse-link")), "activate-link", G_CALLBACK (mouse_clicked_cb), page); remove_link_padding (WID ("mouse-link")); g_signal_connect (G_OBJECT (WID ("display-mapping-button")), "clicked", G_CALLBACK (display_mapping_button_clicked_cb), page); g_signal_connect (G_OBJECT (WID ("display-mapping-button-2")), "clicked", G_CALLBACK (display_mapping_button_clicked_cb), page); g_signal_connect (WID ("switch-decouple-display"), "notify::active", G_CALLBACK (decouple_display_toggled_cb), page); page->nav = cc_wacom_nav_button_new (); gtk_widget_set_halign (page->nav, GTK_ALIGN_END); gtk_widget_set_margin_start (page->nav, 10); gtk_widget_show (page->nav); gtk_container_add (CWID ("navigation-placeholder"), page->nav); page->cancellable = g_cancellable_new (); } static void set_icon_name (CcWacomPage *page, const char *widget_name, const char *icon_name) { g_autofree gchar *resource = NULL; resource = g_strdup_printf ("/org/cinnamon/control-center/wacom/%s.svg", icon_name); gtk_image_set_from_resource (GTK_IMAGE (WID (widget_name)), resource); } static void remove_left_handed (CcWacomPage *page) { gtk_widget_destroy (WID ("label-left-handed")); gtk_widget_destroy (WID ("switch-left-handed")); } static void remove_display_link (CcWacomPage *page) { gtk_widget_destroy (WID ("display-link")); } static void remove_mouse_link (CcWacomPage *page) { gtk_widget_destroy (WID ("mouse-link")); } static void remove_decouple_options (CcWacomPage *page) { gtk_widget_destroy (WID ("label-decouple-display")); gtk_widget_destroy (WID ("switch-decouple-display")); gtk_widget_destroy (WID ("display-mapping-button-2")); } static gboolean has_monitor (CcWacomPage *page) { WacomIntegrationFlags integration_flags; integration_flags = cc_wacom_device_get_integration_flags (page->stylus); return ((integration_flags & (WACOM_DEVICE_INTEGRATED_DISPLAY | WACOM_DEVICE_INTEGRATED_SYSTEM)) != 0); } static void update_tablet_ui (CcWacomPage *page, int layout) { WacomIntegrationFlags integration_flags; integration_flags = cc_wacom_device_get_integration_flags (page->stylus); if ((integration_flags & (WACOM_DEVICE_INTEGRATED_DISPLAY | WACOM_DEVICE_INTEGRATED_SYSTEM)) != 0) { /* FIXME: Check we've got a puck, or a corresponding touchpad device */ remove_mouse_link (page); } /* Hide the pad buttons if no pad is present */ gtk_widget_set_visible (WID ("map-buttons-button"), page->pad != NULL); switch (layout) { case LAYOUT_NORMAL: remove_left_handed (page); remove_display_link (page); remove_decouple_options (page); break; case LAYOUT_REVERSIBLE: remove_display_link (page); remove_decouple_options (page); break; case LAYOUT_SCREEN: remove_left_handed (page); gtk_widget_destroy (WID ("display-mapping-button")); gtk_widget_show (WID ("button-calibrate")); gtk_widget_set_sensitive (WID ("button-calibrate"), has_monitor (page)); gtk_container_child_set (CWID ("main-controls-grid"), WID ("label-trackingmode"), "top_attach", 5, NULL); gtk_container_child_set (CWID ("main-controls-grid"), WID ("combo-tabletmode"), "top_attach", 5, NULL); break; default: g_assert_not_reached (); } } gboolean cc_wacom_page_update_tools (CcWacomPage *page, CcWacomDevice *stylus, CcWacomDevice *pad) { int layout; gboolean changed; /* Type of layout */ layout = get_layout_type (stylus); changed = (page->stylus != stylus || page->pad != pad); if (!changed) return FALSE; page->stylus = stylus; page->pad = pad; update_tablet_ui (CC_WACOM_PAGE (page), layout); return TRUE; } GtkWidget * cc_wacom_page_new (CcWacomPanel *panel, CcWacomDevice *stylus, CcWacomDevice *pad) { CcWacomPage *page; g_return_val_if_fail (CC_IS_WACOM_DEVICE (stylus), NULL); g_return_val_if_fail (!pad || CC_IS_WACOM_DEVICE (pad), NULL); page = g_object_new (CC_TYPE_WACOM_PAGE, NULL); page->panel = panel; cc_wacom_page_update_tools (page, stylus, pad); /* FIXME move this to construct */ page->wacom_settings = cc_wacom_device_get_settings (stylus); set_mode_from_gsettings (GTK_COMBO_BOX (WID ("combo-tabletmode")), page); if (get_layout_type (page->stylus) == LAYOUT_SCREEN) set_display_decoupled_from_gsettings (GTK_SWITCH (WID ("switch-decouple-display")), page); /* Tablet name */ gtk_label_set_text (GTK_LABEL (WID ("label-tabletmodel")), cc_wacom_device_get_name (stylus)); /* Left-handedness */ if (cc_wacom_device_is_reversible (stylus)) set_left_handed_from_gsettings (page); /* Tablet icon */ set_icon_name (page, "image-tablet", cc_wacom_device_get_icon_name (stylus)); return GTK_WIDGET (page); } void cc_wacom_page_set_navigation (CcWacomPage *page, GtkNotebook *notebook, gboolean ignore_first_page) { g_return_if_fail (CC_IS_WACOM_PAGE (page)); g_object_set (G_OBJECT (page->nav), "notebook", notebook, "ignore-first", ignore_first_page, NULL); } void cc_wacom_page_calibrate (CcWacomPage *page) { g_return_if_fail (CC_IS_WACOM_PAGE (page)); calibrate (page); } gboolean cc_wacom_page_can_calibrate (CcWacomPage *page) { g_return_val_if_fail (CC_IS_WACOM_PAGE (page), FALSE); return has_monitor (page); } cinnamon-control-center-6.4.1/panels/wacom/cc-wacom-panel.c0000664000175000017500000004740514724311620022540 0ustar fabiofabio/* * Copyright Ā© 2011 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Authors: Peter Hutterer * Bastien Nocera * */ #include #include #include #include // #include "shell/cc-application.h" // #include "shell/cc-debug.h" #include "cc-wacom-panel.h" #include "cc-wacom-page.h" #include "cc-wacom-stylus-page.h" #include "cc-wacom-resources.h" #include "cc-tablet-tool-map.h" #include "csd-device-manager.h" #ifdef GDK_WINDOWING_WAYLAND #include #endif #define WID(x) (GtkWidget *) gtk_builder_get_object (self->builder, x) struct _CcWacomPanel { CcPanel parent_instance; GtkBuilder *builder; GtkWidget *stack; GtkWidget *switcher; GtkWidget *tablet_notebook; GtkWidget *stylus_notebook; GHashTable *devices; /* key=CsdDevice, value=CcWacomDevice */ GHashTable *pages; /* key=device name, value=GtkWidget */ GHashTable *stylus_pages; /* key=CcWacomTool, value=GtkWidget */ CsdDeviceManager *manager; guint device_added_id; guint device_removed_id; CcTabletToolMap *tablet_tool_map; /* DBus */ GDBusProxy *proxy; }; CC_PANEL_REGISTER (CcWacomPanel, cc_wacom_panel) typedef struct { const char *name; CcWacomDevice *stylus; CcWacomDevice *pad; } Tablet; enum { WACOM_PAGE = -1, PLUG_IN_PAGE = 0, }; enum { PROP_0, PROP_PARAMETERS }; static CcWacomPage * set_device_page (CcWacomPanel *self, const gchar *device_name) { CcWacomPage *page; gint current; if (device_name == NULL) return NULL; /* Choose correct device */ page = g_hash_table_lookup (self->pages, device_name); if (page == NULL) { g_warning ("Failed to find device '%s', supplied in the command line.", device_name); return page; } current = gtk_notebook_page_num (GTK_NOTEBOOK (self->tablet_notebook), GTK_WIDGET (page)); gtk_notebook_set_current_page (GTK_NOTEBOOK (self->tablet_notebook), current); return page; } static void run_operation_from_params (CcWacomPanel *self, GVariant *parameters) { g_autoptr(GVariant) v = NULL; g_autoptr(GVariant) v2 = NULL; CcWacomPage *page; const gchar *operation = NULL; const gchar *device_name = NULL; gint n_params; n_params = g_variant_n_children (parameters); g_variant_get_child (parameters, n_params - 1, "v", &v); device_name = g_variant_get_string (v, NULL); if (!g_variant_is_of_type (v, G_VARIANT_TYPE_STRING)) { g_warning ("Wrong type for the second argument GVariant, expected 's' but got '%s'", g_variant_get_type_string (v)); return; } switch (n_params) { case 3: page = set_device_page (self, device_name); if (page == NULL) return; g_variant_get_child (parameters, 1, "v", &v2); if (!g_variant_is_of_type (v2, G_VARIANT_TYPE_STRING)) { g_warning ("Wrong type for the operation name argument. A string is expected."); break; } operation = g_variant_get_string (v2, NULL); if (g_strcmp0 (operation, "run-calibration") == 0) { if (cc_wacom_page_can_calibrate (page)) cc_wacom_page_calibrate (page); else g_warning ("The device %s cannot be calibrated.", device_name); } else { g_warning ("Ignoring unrecognized operation '%s'", operation); } case 2: set_device_page (self, device_name); break; case 1: g_assert_not_reached (); default: g_warning ("Unexpected number of parameters found: %d. Request ignored.", n_params); } } /* Boilerplate code goes below */ static void cc_wacom_panel_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { switch (property_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void cc_wacom_panel_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { CcWacomPanel *self; self = CC_WACOM_PANEL (object); switch (property_id) { case PROP_PARAMETERS: { GVariant *parameters; parameters = g_value_get_variant (value); if (parameters == NULL || g_variant_n_children (parameters) <= 1) return; run_operation_from_params (self, parameters); break; } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void cc_wacom_panel_dispose (GObject *object) { CcWacomPanel *self = CC_WACOM_PANEL (object); g_clear_object (&self->builder); if (self->manager) { g_signal_handler_disconnect (self->manager, self->device_added_id); g_signal_handler_disconnect (self->manager, self->device_removed_id); self->manager = NULL; } g_clear_pointer (&self->devices, g_hash_table_unref); g_clear_object (&self->proxy); g_clear_pointer (&self->pages, g_hash_table_unref); g_clear_pointer (&self->stylus_pages, g_hash_table_unref); G_OBJECT_CLASS (cc_wacom_panel_parent_class)->dispose (object); } static void check_remove_stylus_pages (CcWacomPanel *self) { GHashTableIter iter; CcWacomDevice *device; CcWacomTool *tool; GtkWidget *page; GList *tools; g_autoptr(GList) total = NULL; /* First. Iterate known devices and get the tools */ g_hash_table_iter_init (&iter, self->devices); while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &device)) { tools = cc_tablet_tool_map_list_tools (self->tablet_tool_map, device); total = g_list_concat (total, tools); } /* Second. Iterate through stylus pages and remove the ones whose * tool is no longer in the list. */ g_hash_table_iter_init (&iter, self->stylus_pages); while (g_hash_table_iter_next (&iter, (gpointer*) &tool, (gpointer*) &page)) { if (g_list_find (total, tool)) continue; gtk_widget_destroy (page); g_hash_table_iter_remove (&iter); } } static gboolean add_stylus (CcWacomPanel *self, CcWacomTool *tool) { GtkWidget *page; if (g_hash_table_lookup (self->stylus_pages, tool)) return FALSE; page = cc_wacom_stylus_page_new (tool); cc_wacom_stylus_page_set_navigation (CC_WACOM_STYLUS_PAGE (page), GTK_NOTEBOOK (self->stylus_notebook)); gtk_widget_show (page); gtk_notebook_append_page (GTK_NOTEBOOK (self->stylus_notebook), page, NULL); g_hash_table_insert (self->stylus_pages, tool, page); if (gtk_notebook_get_current_page (GTK_NOTEBOOK (self->stylus_notebook)) == 0) gtk_notebook_set_current_page (GTK_NOTEBOOK (self->stylus_notebook), 1); return TRUE; } static void update_current_tool (CcWacomPanel *panel, GdkDevice *device, GdkDeviceTool *tool) { CsdDeviceManager *device_manager; CcWacomDevice *wacom_device; CcWacomTool *stylus; CsdDevice *csd_device; guint64 serial, id; gboolean added; if (!tool) return; /* Work our way to the CcWacomDevice */ device_manager = csd_device_manager_get (); csd_device = csd_device_manager_lookup_gdk_device (device_manager, device); if (!csd_device) return; wacom_device = g_hash_table_lookup (panel->devices, csd_device); if (!wacom_device) return; /* Check whether we already know this tool, nothing to do then */ serial = gdk_device_tool_get_serial (tool); /* The wacom driver sends serial-less tools with a serial of * 1, libinput uses 0. No device exists with serial 1, let's reset * it here so everything else works as expected. */ if (serial == 1) serial = 0; stylus = cc_tablet_tool_map_lookup_tool (panel->tablet_tool_map, wacom_device, serial); if (!stylus) { id = gdk_device_tool_get_hardware_id (tool); /* The wacom driver sends a hw id of 0x2 for stylus and 0xa * for eraser for devices that don't have a true HW id. * Reset those to 0 so we can use the same code-paths * libinput uses. * The touch ID is 0x3, let's ignore that because we don't * have a touch tool and it only happens when the wacom * driver handles the touch device. */ if (id == 0x2 || id == 0xa) id = 0; else if (id == 0x3) return; stylus = cc_wacom_tool_new (serial, id, wacom_device); if (!stylus) return; } added = add_stylus (panel, stylus); if (added) { if (panel->stylus_notebook == gtk_stack_get_visible_child (GTK_STACK (panel->stack))) { GtkWidget *widget; gint page; widget = g_hash_table_lookup (panel->stylus_pages, stylus); page = gtk_notebook_page_num (GTK_NOTEBOOK (panel->stylus_notebook), widget); gtk_notebook_set_current_page (GTK_NOTEBOOK (panel->stylus_notebook), page); } else { gtk_container_child_set (GTK_CONTAINER (panel->stack), panel->stylus_notebook, "needs-attention", TRUE, NULL); } } cc_tablet_tool_map_add_relation (panel->tablet_tool_map, wacom_device, stylus); } static gboolean on_event (GtkWidget *widget, GdkEvent *event, CcWacomPanel *panel) { if (event->type == GDK_MOTION_NOTIFY) { update_current_tool (panel, gdk_event_get_source_device (event), gdk_event_get_device_tool (event)); } return GDK_EVENT_PROPAGATE; } static void cc_wacom_panel_realized (GtkWidget *widget) { GTK_WIDGET_CLASS (cc_wacom_panel_parent_class)->realize (widget); CcWacomPanel *self = CC_WACOM_PANEL (widget); g_signal_connect_object (gtk_widget_get_toplevel (GTK_WIDGET (self)), "event", G_CALLBACK (on_event), self, 0); } static void cc_wacom_panel_class_init (CcWacomPanelClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); object_class->get_property = cc_wacom_panel_get_property; object_class->set_property = cc_wacom_panel_set_property; object_class->dispose = cc_wacom_panel_dispose; widget_class->realize = cc_wacom_panel_realized; g_object_class_override_property (object_class, PROP_PARAMETERS, "parameters"); } static void remove_page (GtkNotebook *notebook, GtkWidget *widget) { int num_pages, i; num_pages = gtk_notebook_get_n_pages (notebook); g_return_if_fail (num_pages > 1); for (i = 1; i < num_pages; i++) { if (gtk_notebook_get_nth_page (notebook, i) == widget) { gtk_notebook_remove_page (notebook, i); return; } } } static void update_current_page (CcWacomPanel *self, CcWacomDevice *removed_device) { GHashTable *ht; g_autoptr(GList) tablets = NULL; GList *l; gboolean changed; GHashTableIter iter; CsdDevice *csd_device; CcWacomDevice *device; changed = FALSE; ht = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free); if (removed_device) { Tablet *tablet = g_new0 (Tablet, 1); tablet->name = cc_wacom_device_get_name (removed_device); g_hash_table_insert (ht, (gpointer) tablet->name, tablet); } g_hash_table_iter_init (&iter, self->devices); while (g_hash_table_iter_next (&iter, (gpointer*) &csd_device, (gpointer*) &device)) { Tablet *tablet; CsdDeviceType device_type; device_type = csd_device_get_device_type (csd_device); tablet = g_hash_table_lookup (ht, cc_wacom_device_get_name (device)); if (tablet == NULL) { tablet = g_new0 (Tablet, 1); tablet->name = cc_wacom_device_get_name (device); g_hash_table_insert (ht, (gpointer) tablet->name, tablet); } if (device_type & CSD_DEVICE_TYPE_PAD) { tablet->pad = device; } else if (device_type & CSD_DEVICE_TYPE_TABLET) { tablet->stylus = device; } } /* We now have a list of Tablet structs, * see which ones are full tablets */ tablets = g_hash_table_get_values (ht); for (l = tablets; l; l = l->next) { Tablet *tablet; GtkWidget *page; tablet = l->data; if (tablet->stylus == NULL) { page = g_hash_table_lookup (self->pages, tablet->name); if (page != NULL) { remove_page (GTK_NOTEBOOK (self->tablet_notebook), page); g_hash_table_remove (self->pages, tablet->name); changed = TRUE; } continue; } /* this code is called once the stylus is set up, but the pad does not exist yet */ page = g_hash_table_lookup (self->pages, tablet->name); if (page == NULL) { page = cc_wacom_page_new (self, tablet->stylus, tablet->pad); cc_wacom_page_set_navigation (CC_WACOM_PAGE (page), GTK_NOTEBOOK (self->tablet_notebook), TRUE); gtk_widget_show (page); gtk_notebook_append_page (GTK_NOTEBOOK (self->tablet_notebook), page, NULL); g_hash_table_insert (self->pages, g_strdup (tablet->name), page); changed = TRUE; } else { cc_wacom_page_update_tools (CC_WACOM_PAGE (page), tablet->stylus, tablet->pad); } } g_hash_table_destroy (ht); if (changed == TRUE) { int num_pages; num_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (self->tablet_notebook)); if (num_pages > 1) gtk_notebook_set_current_page (GTK_NOTEBOOK (self->tablet_notebook), 1); } } static void monitor_config_changed (CcWacomOutputManager *manager, CcWacomPanel *panel) { update_current_page (panel, NULL); } static void add_known_device (CcWacomPanel *self, CsdDevice *csd_device) { CcWacomDevice *device; CsdDeviceType device_type; device_type = csd_device_get_device_type (csd_device); if ((device_type & CSD_DEVICE_TYPE_TABLET) == 0) return; if ((device_type & (CSD_DEVICE_TYPE_TOUCHSCREEN | CSD_DEVICE_TYPE_TOUCHPAD)) != 0) { return; } device = cc_wacom_device_new (csd_device); if (!device) return; g_hash_table_insert (self->devices, csd_device, device); /* Only trigger tool lookup on pen devices */ if ((device_type & CSD_DEVICE_TYPE_TABLET) != 0) { g_autoptr(GList) tools = NULL; GList *l; tools = cc_tablet_tool_map_list_tools (self->tablet_tool_map, device); for (l = tools; l != NULL; l = l->next) { add_stylus (self, l->data); } } } static void device_removed_cb (CsdDeviceManager *manager, CsdDevice *csd_device, CcWacomPanel *self) { g_autoptr(CcWacomDevice) device = NULL; device = g_hash_table_lookup (self->devices, csd_device); if (!device) return; g_hash_table_steal (self->devices, csd_device); update_current_page (self, device); check_remove_stylus_pages (self); } static void device_added_cb (CsdDeviceManager *manager, CsdDevice *device, CcWacomPanel *self) { add_known_device (self, device); update_current_page (self, NULL); } static void enbiggen_label (GtkLabel *label) { const char *str; g_autofree char *new_str = NULL; str = gtk_label_get_text (label); new_str = g_strdup_printf ("%s", str); gtk_label_set_markup (label, new_str); } static void on_stack_visible_child_notify_cb (GObject *object, GParamSpec *pspec, CcWacomPanel *panel) { GtkWidget *child; child = gtk_stack_get_visible_child (GTK_STACK (object)); if (child == panel->stylus_notebook) { gtk_container_child_set (GTK_CONTAINER (panel->stack), panel->stylus_notebook, "needs-attention", FALSE, NULL); } } static gboolean link_activated (GtkLinkButton *button, CcWacomPanel *self) { g_spawn_command_line_async ("blueman-manager", NULL); return TRUE; } static void cc_wacom_panel_init (CcWacomPanel *self) { GtkWidget *widget; g_autoptr(GList) devices = NULL; GList *l; g_autoptr(GError) error = NULL; char *objects[] = { "main-box", "no-stylus-page", NULL }; g_resources_register (cc_wacom_get_resource ()); self->builder = gtk_builder_new (); gtk_builder_add_objects_from_resource (self->builder, "/org/cinnamon/control-center/wacom/cinnamon-wacom-properties.ui", objects, &error); gtk_builder_add_objects_from_resource (self->builder, "/org/cinnamon/control-center/wacom/wacom-stylus-page.ui", objects, &error); if (error != NULL) { g_warning ("Error loading UI file: %s", error->message); return; } self->tablet_tool_map = cc_tablet_tool_map_new (); /* Stack + Switcher */ self->stack = gtk_stack_new (); g_object_set (G_OBJECT (self->stack), "margin-top", 30, "margin-end", 30, "margin-start", 30, "margin-bottom", 30, NULL); g_signal_connect (self->stack, "notify::visible-child", G_CALLBACK (on_stack_visible_child_notify_cb), self); self->switcher = gtk_stack_switcher_new (); gtk_stack_switcher_set_stack (GTK_STACK_SWITCHER (self->switcher), GTK_STACK (self->stack)); gtk_widget_show (self->switcher); gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (self->stack)); gtk_widget_show (self->stack); self->tablet_notebook = gtk_notebook_new (); gtk_widget_show (self->tablet_notebook); gtk_notebook_set_show_tabs (GTK_NOTEBOOK (self->tablet_notebook), FALSE); gtk_notebook_set_show_border (GTK_NOTEBOOK (self->tablet_notebook), FALSE); gtk_widget_set_vexpand (self->tablet_notebook, TRUE); self->stylus_notebook = gtk_notebook_new (); gtk_widget_show (self->stylus_notebook); gtk_notebook_set_show_tabs (GTK_NOTEBOOK (self->stylus_notebook), FALSE); gtk_notebook_set_show_border (GTK_NOTEBOOK (self->stylus_notebook), FALSE); gtk_container_set_border_width (GTK_CONTAINER (self->stylus_notebook), 0); gtk_widget_set_vexpand (self->stylus_notebook, TRUE); gtk_stack_add_titled (GTK_STACK (self->stack), self->stylus_notebook, "stylus", _("Stylus")); gtk_stack_add_titled (GTK_STACK (self->stack), self->tablet_notebook, "tablet", _("Tablet")); /* No styli page */ widget = WID ("no-stylus-page"); enbiggen_label (GTK_LABEL (WID ("no-stylus-label1"))); gtk_notebook_append_page (GTK_NOTEBOOK (self->stylus_notebook), widget, NULL); /* No tablets page */ widget = WID ("main-box"); enbiggen_label (GTK_LABEL (WID ("advice-label1"))); gtk_notebook_append_page (GTK_NOTEBOOK (self->tablet_notebook), widget, NULL); g_signal_connect (cc_wacom_output_manager_get (), "monitors-changed", G_CALLBACK (monitor_config_changed), self); g_signal_connect (G_OBJECT (WID ("linkbutton")), "activate-link", G_CALLBACK (link_activated), self); gchar *path = g_find_program_in_path ("blueman-manager"); gtk_widget_set_visible (WID ("linkbutton"), path != NULL); g_free (path); self->devices = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref); self->pages = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); self->stylus_pages = g_hash_table_new (NULL, NULL); self->manager = csd_device_manager_get (); self->device_added_id = g_signal_connect (G_OBJECT (self->manager), "device-added", G_CALLBACK (device_added_cb), self); self->device_removed_id = g_signal_connect (G_OBJECT (self->manager), "device-removed", G_CALLBACK (device_removed_cb), self); devices = csd_device_manager_list_devices (self->manager, CSD_DEVICE_TYPE_TABLET); for (l = devices; l ; l = l->next) add_known_device (self, l->data); update_current_page (self, NULL); } void cc_wacom_panel_register (GIOModule *module) { cc_wacom_panel_register_type (G_TYPE_MODULE (module)); textdomain (GETTEXT_PACKAGE); bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); g_io_extension_point_implement (CC_SHELL_PANEL_EXTENSION_POINT, CC_TYPE_WACOM_PANEL, "wacom", 0); } cinnamon-control-center-6.4.1/panels/wacom/cc-wacom-tool.h0000664000175000017500000000311614724311620022412 0ustar fabiofabio/* * Copyright Ā© 2016 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Authors: Carlos Garnacho * */ #pragma once #include "config.h" #include "csd-device-manager.h" #include "cc-wacom-device.h" #include #define CC_TYPE_WACOM_TOOL (cc_wacom_tool_get_type ()) G_DECLARE_FINAL_TYPE (CcWacomTool, cc_wacom_tool, CC, WACOM_TOOL, GObject) CcWacomTool * cc_wacom_tool_new (guint64 serial, guint64 id, CcWacomDevice *device); guint64 cc_wacom_tool_get_serial (CcWacomTool *tool); guint64 cc_wacom_tool_get_id (CcWacomTool *tool); const gchar * cc_wacom_tool_get_name (CcWacomTool *tool); const gchar * cc_wacom_tool_get_icon_name (CcWacomTool *tool); GSettings * cc_wacom_tool_get_settings (CcWacomTool *tool); guint cc_wacom_tool_get_num_buttons (CcWacomTool *tool); gboolean cc_wacom_tool_get_has_eraser (CcWacomTool *tool); cinnamon-control-center-6.4.1/panels/wacom/cc-tablet-tool-map.c0000664000175000017500000002413314724311620023327 0ustar fabiofabio/* * Copyright Ā© 2016 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Authors: Carlos Garnacho * */ #include "config.h" #include "cc-tablet-tool-map.h" #define KEY_TOOL_ID "ID" #define KEY_DEVICE_STYLI "Styli" #define GENERIC_STYLUS "generic" typedef struct _CcTabletToolMap CcTabletToolMap; struct _CcTabletToolMap { GObject parent_instance; GKeyFile *tablets; GKeyFile *tools; GHashTable *tool_map; GHashTable *tablet_map; GHashTable *no_serial_tool_map; gchar *tablet_path; gchar *tool_path; }; G_DEFINE_TYPE (CcTabletToolMap, cc_tablet_tool_map, G_TYPE_OBJECT) static void load_keyfiles (CcTabletToolMap *map) { g_autoptr(GError) devices_error = NULL; g_autoptr(GError) tools_error = NULL; g_autofree gchar *dir = NULL; dir = g_build_filename (g_get_user_cache_dir (), "cinnamon-control-center", "wacom", NULL); if (g_mkdir_with_parents (dir, 0700) < 0) { g_warning ("Could not create directory '%s', expect stylus mapping oddities: %m", dir); return; } map->tablet_path = g_build_filename (dir, "devices", NULL); g_key_file_load_from_file (map->tablets, map->tablet_path, G_KEY_FILE_NONE, &devices_error); if (devices_error && !g_error_matches (devices_error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) { g_warning ("Could not load tablets keyfile '%s': %s", map->tablet_path, devices_error->message); } map->tool_path = g_build_filename (dir, "tools", NULL); g_key_file_load_from_file (map->tools, map->tool_path, G_KEY_FILE_NONE, &tools_error); if (tools_error && !g_error_matches (tools_error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) { g_warning ("Could not load tools keyfile '%s': %s", map->tool_path, tools_error->message); } } static void cache_tools (CcTabletToolMap *map) { g_auto(GStrv) serials = NULL; gsize n_serials, i; serials = g_key_file_get_groups (map->tools, &n_serials); for (i = 0; i < n_serials; i++) { g_autofree gchar *str = NULL; gchar *end; guint64 serial, id; g_autoptr(GError) error = NULL; CcWacomTool *tool; serial = g_ascii_strtoull (serials[i], &end, 16); if (*end != '\0') { g_warning ("Invalid tool serial %s", serials[i]); continue; } str = g_key_file_get_string (map->tools, serials[i], KEY_TOOL_ID, &error); if (str == NULL) { g_warning ("Could not get cached ID for tool with serial %s: %s", serials[i], error->message); continue; } id = g_ascii_strtoull (str, &end, 16); if (*end != '\0') { g_warning ("Invalid tool ID %s", str); continue; } tool = cc_wacom_tool_new (serial, id, NULL); g_hash_table_insert (map->tool_map, g_strdup (serials[i]), tool); } } static void cache_devices (CcTabletToolMap *map) { gchar **ids; gsize n_ids, i; ids = g_key_file_get_groups (map->tablets, &n_ids); for (i = 0; i < n_ids; i++) { gchar **styli; gsize n_styli, j; g_autoptr(GError) error = NULL; GList *tools = NULL; styli = g_key_file_get_string_list (map->tablets, ids[i], KEY_DEVICE_STYLI, &n_styli, &error); if (styli == NULL) { g_warning ("Could not get cached styli for with ID %s: %s", ids[i], error->message); continue; } for (j = 0; j < n_styli; j++) { CcWacomTool *tool; if (g_str_equal (styli[j], GENERIC_STYLUS)) { /* We don't have a CsdDevice yet to create the * serial=0 CcWacomTool, insert a NULL and defer * to device lookups. */ g_hash_table_insert (map->no_serial_tool_map, g_strdup (ids[i]), NULL); } tool = g_hash_table_lookup (map->tool_map, styli[j]); if (tool) tools = g_list_prepend (tools, tool); } if (tools) { g_hash_table_insert (map->tablet_map, g_strdup (ids[i]), tools); } g_strfreev (styli); } g_strfreev (ids); } static void cc_tablet_tool_map_finalize (GObject *object) { CcTabletToolMap *map = CC_TABLET_TOOL_MAP (object); g_key_file_unref (map->tools); g_key_file_unref (map->tablets); g_hash_table_destroy (map->tool_map); g_hash_table_destroy (map->tablet_map); g_hash_table_destroy (map->no_serial_tool_map); g_free (map->tablet_path); g_free (map->tool_path); G_OBJECT_CLASS (cc_tablet_tool_map_parent_class)->finalize (object); } static void null_safe_unref (gpointer data) { if (data != NULL) g_object_unref (data); } static void cc_tablet_tool_map_init (CcTabletToolMap *map) { map->tablets = g_key_file_new (); map->tools = g_key_file_new (); map->tool_map = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) g_object_unref); map->tablet_map = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) g_list_free); map->no_serial_tool_map = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) null_safe_unref); load_keyfiles (map); cache_tools (map); cache_devices (map); } static void cc_tablet_tool_map_class_init (CcTabletToolMapClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = cc_tablet_tool_map_finalize; } CcTabletToolMap * cc_tablet_tool_map_new (void) { return g_object_new (CC_TYPE_TABLET_TOOL_MAP, NULL); } static gchar * get_device_key (CcWacomDevice *device) { const gchar *vendor, *product; CsdDevice *csd_device; csd_device = cc_wacom_device_get_device (device); csd_device_get_device_ids (csd_device, &vendor, &product); return g_strdup_printf ("%s:%s", vendor, product); } static gchar * get_tool_key (guint64 serial) { return g_strdup_printf ("%lx", serial); } GList * cc_tablet_tool_map_list_tools (CcTabletToolMap *map, CcWacomDevice *device) { CcWacomTool *no_serial_tool; GList *styli; g_autofree gchar *key = NULL; g_return_val_if_fail (CC_IS_TABLET_TOOL_MAP (map), NULL); g_return_val_if_fail (CC_IS_WACOM_DEVICE (device), NULL); key = get_device_key (device); styli = g_list_copy (g_hash_table_lookup (map->tablet_map, key)); if (g_hash_table_lookup_extended (map->no_serial_tool_map, key, NULL, (gpointer) &no_serial_tool)) { if (!no_serial_tool) { no_serial_tool = cc_wacom_tool_new (0, 0, device); g_hash_table_replace (map->no_serial_tool_map, g_strdup (key), no_serial_tool); } styli = g_list_prepend (styli, no_serial_tool); } return styli; } CcWacomTool * cc_tablet_tool_map_lookup_tool (CcTabletToolMap *map, CcWacomDevice *device, guint64 serial) { CcWacomTool *tool = NULL; g_autofree gchar *key = NULL; g_return_val_if_fail (CC_IS_TABLET_TOOL_MAP (map), FALSE); g_return_val_if_fail (CC_IS_WACOM_DEVICE (device), FALSE); if (serial == 0) { key = get_device_key (device); tool = g_hash_table_lookup (map->no_serial_tool_map, key); } else { key = get_tool_key (serial); tool = g_hash_table_lookup (map->tool_map, key); } return tool; } static void keyfile_add_device_stylus (CcTabletToolMap *map, const gchar *device_key, const gchar *tool_key) { g_autoptr(GArray) array = NULL; g_auto(GStrv) styli = NULL; gsize n_styli; array = g_array_new (FALSE, FALSE, sizeof (gchar *)); styli = g_key_file_get_string_list (map->tablets, device_key, KEY_DEVICE_STYLI, &n_styli, NULL); if (styli) { g_array_append_vals (array, styli, n_styli); } g_array_append_val (array, tool_key); g_key_file_set_string_list (map->tablets, device_key, KEY_DEVICE_STYLI, (const gchar **) array->data, array->len); } static void keyfile_add_stylus (CcTabletToolMap *map, const gchar *tool_key, guint64 id) { g_autofree gchar *str = NULL; /* Also works for IDs */ str = get_tool_key (id); g_key_file_set_string (map->tools, tool_key, KEY_TOOL_ID, str); } void cc_tablet_tool_map_add_relation (CcTabletToolMap *map, CcWacomDevice *device, CcWacomTool *tool) { gboolean tablets_changed = FALSE, tools_changed = FALSE; gboolean new_tool_without_serial = FALSE; g_autofree gchar *tool_key = NULL; g_autofree gchar *device_key = NULL; guint64 serial, id; GList *styli; g_return_if_fail (CC_IS_TABLET_TOOL_MAP (map)); g_return_if_fail (CC_IS_WACOM_DEVICE (device)); g_return_if_fail (CC_IS_WACOM_TOOL (tool)); serial = cc_wacom_tool_get_serial (tool); id = cc_wacom_tool_get_id (tool); device_key = get_device_key (device); if (serial == 0) { tool_key = g_strdup (GENERIC_STYLUS); if (!g_hash_table_contains (map->no_serial_tool_map, device_key)) { g_hash_table_insert (map->no_serial_tool_map, g_strdup (device_key), g_object_ref (tool)); new_tool_without_serial = TRUE; } } else { tool_key = get_tool_key (serial); if (!g_hash_table_contains (map->tool_map, tool_key)) { keyfile_add_stylus (map, tool_key, id); tools_changed = TRUE; g_hash_table_insert (map->tool_map, g_strdup (tool_key), g_object_ref (tool)); } } styli = g_hash_table_lookup (map->tablet_map, device_key); if (!g_list_find (styli, tool)) { styli = g_list_prepend (styli, tool); g_hash_table_replace (map->tablet_map, g_strdup (device_key), g_list_copy (styli)); if (serial || new_tool_without_serial) { tablets_changed = TRUE; keyfile_add_device_stylus (map, device_key, tool_key); } } if (tools_changed) { g_autoptr(GError) error = NULL; if (!g_key_file_save_to_file (map->tools, map->tool_path, &error)) { g_warning ("Error saving tools keyfile: %s", error->message); } } if (tablets_changed) { g_autoptr(GError) error = NULL; if (!g_key_file_save_to_file (map->tablets, map->tablet_path, &error)) { g_warning ("Error saving tablets keyfile: %s", error->message); } } } cinnamon-control-center-6.4.1/panels/wacom/csd-wacom-key-shortcut-button.h0000664000175000017500000000257314724311620025601 0ustar fabiofabio/* * csd-wacom-key-shortcut-button.h * * Copyright Ā© 2013 Red Hat, Inc. * * Author: Joaquim Rocha * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ #pragma once #include G_BEGIN_DECLS #define CSD_WACOM_TYPE_KEY_SHORTCUT_BUTTON (csd_wacom_key_shortcut_button_get_type ()) G_DECLARE_FINAL_TYPE (CsdWacomKeyShortcutButton, csd_wacom_key_shortcut_button, CSD, WACOM_KEY_SHORTCUT_BUTTON, GtkButton) GType csd_wacom_key_shortcut_button_mode_type (void) G_GNUC_CONST; #define CSD_WACOM_TYPE_KEY_SHORTCUT_BUTTON_MODE (csd_wacom_key_shortcut_button_mode_type ()) typedef enum { CSD_WACOM_KEY_SHORTCUT_BUTTON_MODE_OTHER, CSD_WACOM_KEY_SHORTCUT_BUTTON_MODE_ALL } CsdWacomKeyShortcutButtonMode; GtkWidget * csd_wacom_key_shortcut_button_new (void); cinnamon-control-center-6.4.1/panels/wacom/csd-wacom-key-shortcut-button.c0000664000175000017500000004040614724311620025571 0ustar fabiofabio/* * csd-wacom-key-shortcut-button.c * * Copyright Ā© 2013 Red Hat, Inc. * * Author: Joaquim Rocha * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ #include "config.h" #include #include "csd-wacom-key-shortcut-button.h" /** * SECTION:csd-wacom-key-shortcut-button * @short_description: A button which captures and displays a keyboard shortcut * @title: CsdWacomKeyShortcutButton * * CsdWacomKeyShortcutButton is a button which, when clicked, captures a keyboard * shortcut and displays it. * It works in a similar way to #GtkCellRendererAccel but, being a #GtkWidget, * can be added to e.g. containers. */ #define DEFAULT_CANCEL_KEY GDK_KEY_Escape #define DEFAULT_CLEAR_KEY GDK_KEY_BackSpace enum { KEY_SHORTCUT_EDITED, KEY_SHORTCUT_CLEARED, LAST_SIGNAL }; enum { PROP_0, PROP_SHORTCUT_KEY_VAL, PROP_SHORTCUT_KEY_MODS, PROP_SHORTCUT_MODE, PROP_SHORTCUT_CANCEL_KEY, PROP_SHORTCUT_CLEAR_KEY, N_PROPERTIES }; struct _CsdWacomKeyShortcutButton { GtkButton parent_instance; gboolean editing_mode; GdkSeat *grab_seat; guint keyval; guint keycode; GdkModifierType mods; /* Temporary shortcut info used for allowing * modifier-only shortcuts */ guint tmp_shortcut_keyval; GdkModifierType tmp_shortcut_mods; guint32 tmp_shortcut_time; CsdWacomKeyShortcutButtonMode mode; guint cancel_keyval; guint clear_keyval; }; G_DEFINE_TYPE (CsdWacomKeyShortcutButton, csd_wacom_key_shortcut_button, GTK_TYPE_BUTTON); static guint signals[LAST_SIGNAL] = { 0 }; static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, }; static void csd_wacom_key_shortcut_button_changed (CsdWacomKeyShortcutButton *self); static void csd_wacom_key_shortcut_button_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { CsdWacomKeyShortcutButton *self = CSD_WACOM_KEY_SHORTCUT_BUTTON (object); gboolean changed = FALSE; switch (property_id) { case PROP_SHORTCUT_KEY_VAL: self->keyval = g_value_get_uint (value); changed = TRUE; break; case PROP_SHORTCUT_KEY_MODS: self->mods = g_value_get_uint (value); changed = TRUE; break; case PROP_SHORTCUT_MODE: self->mode = g_value_get_enum (value); break; case PROP_SHORTCUT_CANCEL_KEY: self->cancel_keyval = g_value_get_uint (value); break; case PROP_SHORTCUT_CLEAR_KEY: self->clear_keyval = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } if (changed) csd_wacom_key_shortcut_button_changed (self); } static void csd_wacom_key_shortcut_button_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { CsdWacomKeyShortcutButton *self = CSD_WACOM_KEY_SHORTCUT_BUTTON (object); switch (property_id) { case PROP_SHORTCUT_KEY_VAL: g_value_set_uint (value, self->keyval); break; case PROP_SHORTCUT_KEY_MODS: g_value_set_uint (value, self->mods); break; case PROP_SHORTCUT_MODE: g_value_set_enum (value, self->mode); break; case PROP_SHORTCUT_CANCEL_KEY: g_value_set_uint (value, self->cancel_keyval); break; case PROP_SHORTCUT_CLEAR_KEY: g_value_set_uint (value, self->clear_keyval); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void csd_wacom_key_shortcut_set_editing_mode (CsdWacomKeyShortcutButton *self, GdkEvent *event) { GdkWindow *window; GdkSeat *seat; self->editing_mode = TRUE; csd_wacom_key_shortcut_button_changed (self); window = gtk_widget_get_window (GTK_WIDGET (self)); g_return_if_fail (window != NULL); seat = gdk_event_get_seat (event); if (gdk_seat_grab (seat, window, GDK_SEAT_CAPABILITY_ALL, FALSE, NULL, event, NULL, NULL) != GDK_GRAB_SUCCESS) return; gtk_widget_grab_focus (GTK_WIDGET (self)); self->grab_seat = seat; } static void csd_wacom_key_shortcut_remove_editing_mode (CsdWacomKeyShortcutButton *self) { self->editing_mode = FALSE; self->editing_mode = FALSE; if (self->grab_seat) { gdk_seat_ungrab (self->grab_seat); self->grab_seat = NULL; } self->tmp_shortcut_keyval = 0; self->tmp_shortcut_mods = 0; self->tmp_shortcut_time = 0; } static void csd_wacom_key_shortcut_button_changed (CsdWacomKeyShortcutButton *self) { g_autofree gchar *text = NULL; if (self->editing_mode) { gtk_button_set_label (GTK_BUTTON (self), _("New shortcut…")); gtk_widget_set_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_ACTIVE | GTK_STATE_FLAG_PRELIGHT, FALSE); return; } if (self->keyval == 0 && self->mods == 0) { gtk_button_set_label (GTK_BUTTON (self), ""); return; } text = gtk_accelerator_get_label (self->keyval, self->mods); gtk_button_set_label (GTK_BUTTON (self), text); } static void csd_wacom_key_shortcut_button_activate (GtkButton *self) { csd_wacom_key_shortcut_set_editing_mode (CSD_WACOM_KEY_SHORTCUT_BUTTON (self), NULL); GTK_BUTTON_CLASS (csd_wacom_key_shortcut_button_parent_class)->activate (self); } static void csd_wacom_key_shortcut_button_init (CsdWacomKeyShortcutButton *self) { gtk_button_set_relief (GTK_BUTTON (self), GTK_RELIEF_NONE); self->cancel_keyval = DEFAULT_CANCEL_KEY; self->clear_keyval = DEFAULT_CLEAR_KEY; } static void key_shortcut_finished_editing (CsdWacomKeyShortcutButton *self, guint32 time) { gdk_seat_ungrab (self->grab_seat); self->grab_seat = NULL; self->editing_mode = FALSE; csd_wacom_key_shortcut_remove_editing_mode (self); csd_wacom_key_shortcut_button_changed (self); } static gboolean csd_wacom_key_shortcut_button_key_release (GtkWidget *widget, GdkEventKey *event) { CsdWacomKeyShortcutButton *self = CSD_WACOM_KEY_SHORTCUT_BUTTON (widget); if (self->tmp_shortcut_keyval == 0) { GTK_WIDGET_CLASS (csd_wacom_key_shortcut_button_parent_class)->key_release_event (widget, event); return FALSE; } self->keyval = self->tmp_shortcut_keyval; self->mods = self->tmp_shortcut_mods; key_shortcut_finished_editing (self, self->tmp_shortcut_time); g_signal_emit (self, signals[KEY_SHORTCUT_EDITED], 0); return TRUE; } static gboolean csd_wacom_key_shortcut_button_key_press (GtkWidget *widget, GdkEventKey *event) { /* This code is based on the gtk_cell_renderer_accel_start_editing */ CsdWacomKeyShortcutButton *self = CSD_WACOM_KEY_SHORTCUT_BUTTON (widget); GdkModifierType mods = 0; guint shortcut_keyval; guint keyval; gboolean edited; gboolean cleared; /* GTK and OTHER modes don't allow modifier keyvals */ if (event->is_modifier && self->mode != CSD_WACOM_KEY_SHORTCUT_BUTTON_MODE_ALL) return TRUE; if (!self->editing_mode) { GTK_WIDGET_CLASS (csd_wacom_key_shortcut_button_parent_class)->key_press_event (widget, event); return FALSE; } edited = FALSE; cleared = FALSE; mods = event->state; keyval = event->keyval; if (keyval == GDK_KEY_Sys_Req && (mods & GDK_MOD1_MASK) != 0) { /* HACK: we don't want to use SysRq as a keybinding (but we do * want Alt+Print), so we avoid translation from Alt+Print to SysRq */ keyval = GDK_KEY_Print; } shortcut_keyval = gdk_keyval_to_lower (keyval); if (shortcut_keyval == GDK_KEY_ISO_Left_Tab) shortcut_keyval = GDK_KEY_Tab; mods &= gtk_accelerator_get_default_mod_mask (); /* Put shift back if it changed the case of the key, not otherwise. */ if (shortcut_keyval != keyval) mods |= GDK_SHIFT_MASK; if (mods == 0) { if (keyval == self->cancel_keyval) { /* cancel the edition */ goto out; } else if (keyval == self->clear_keyval) { /* clear the current shortcut */ cleared = TRUE; goto out; } } self->tmp_shortcut_keyval = 0; self->tmp_shortcut_mods = 0; self->tmp_shortcut_time = 0; if (event->is_modifier) { /* when the user presses a non-modifier key, it readily assigns the * shortcut but since we also support modifiers-only shortcuts, we * cannot assign the shortcut right when the user presses a modifier * key because the user might assign e.g. Alt, Alt+Ctrl, Alt+Ctrl+Shift, etc. * So, we keep track of the pressed shortcut's (keyval, mods and time) if * it is a modifier shortcut and assign them when a key-release happens */ self->tmp_shortcut_keyval = shortcut_keyval; self->tmp_shortcut_mods = mods; self->tmp_shortcut_time = event->time; return TRUE; } edited = TRUE; out: if (edited) { self->keyval = shortcut_keyval; self->mods = mods; } if (cleared) { self->keyval = 0; self->mods = 0; } key_shortcut_finished_editing (CSD_WACOM_KEY_SHORTCUT_BUTTON (widget), event->time); if (edited) g_signal_emit (self, signals[KEY_SHORTCUT_EDITED], 0); else if (cleared) g_signal_emit (self, signals[KEY_SHORTCUT_CLEARED], 0); return TRUE; } static gboolean csd_wacom_key_shortcut_button_button_press (GtkWidget *widget, GdkEventButton *event) { CsdWacomKeyShortcutButton *self; self = CSD_WACOM_KEY_SHORTCUT_BUTTON (widget); if (self->editing_mode) return TRUE; csd_wacom_key_shortcut_set_editing_mode (self, NULL); GTK_WIDGET_CLASS (csd_wacom_key_shortcut_button_parent_class)->button_press_event (widget, event); return TRUE; } static void csd_wacom_key_shortcut_button_unrealize (GtkWidget *widget) { CsdWacomKeyShortcutButton *self; self = CSD_WACOM_KEY_SHORTCUT_BUTTON (widget); csd_wacom_key_shortcut_remove_editing_mode (self); GTK_WIDGET_CLASS (csd_wacom_key_shortcut_button_parent_class)->unrealize (widget); } static void csd_wacom_key_shortcut_button_class_init (CsdWacomKeyShortcutButtonClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); GtkButtonClass *button_class = GTK_BUTTON_CLASS (klass); gobject_class->set_property = csd_wacom_key_shortcut_button_set_property; gobject_class->get_property = csd_wacom_key_shortcut_button_get_property; obj_properties[PROP_SHORTCUT_KEY_VAL] = g_param_spec_uint ("key-value", "The key value", "The key value of the shortcut currently set", 0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); obj_properties[PROP_SHORTCUT_KEY_MODS] = g_param_spec_uint ("key-mods", "The key modifiers", "The key modifiers of the shortcut currently set", 0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); obj_properties[PROP_SHORTCUT_CANCEL_KEY] = g_param_spec_uint ("cancel-key", "The cancel key", "The key which cancels the edition of the shortcut", 0, G_MAXUINT, DEFAULT_CANCEL_KEY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); obj_properties[PROP_SHORTCUT_CLEAR_KEY] = g_param_spec_uint ("clear-key", "The clear key", "The key which clears the currently set shortcut", 0, G_MAXUINT, DEFAULT_CLEAR_KEY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * CsdWacomKeyShortcutButton:mode: * * Determines which type of keys are allowed in the captured shortcuts. * %CSD_WACOM_KEY_SHORTCUT_BUTTON_MODE_ALL is the same as * %CSD_WACOM_KEY_SHORTCUT_BUTTON_MODE_OTHER but allows shortcuts composed of * only modifier keys. */ obj_properties[PROP_SHORTCUT_MODE] = g_param_spec_enum ("mode", "The shortcut mode", "The mode with which the shortcuts are captured", CSD_WACOM_TYPE_KEY_SHORTCUT_BUTTON_MODE, CSD_WACOM_KEY_SHORTCUT_BUTTON_MODE_OTHER, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (gobject_class, N_PROPERTIES, obj_properties); widget_class->key_press_event = csd_wacom_key_shortcut_button_key_press; widget_class->button_press_event = csd_wacom_key_shortcut_button_button_press; widget_class->key_release_event = csd_wacom_key_shortcut_button_key_release; widget_class->unrealize = csd_wacom_key_shortcut_button_unrealize; button_class->activate = csd_wacom_key_shortcut_button_activate; /** * CsdWacomKeyShortcutButton::key-shortcut-edited: * @keyshortcutbutton: the #CsdWacomKeyShortcutButton * * Emitted when the key shortcut of the @keyshortcutbutton is edited. * * The new shortcut can be retrieved by using the #CsdWacomKeyShortcutButton:key-value * and #CsdWacomKeyShortcutButton:key-mods properties. */ signals[KEY_SHORTCUT_EDITED] = g_signal_new ("key-shortcut-edited", CSD_WACOM_TYPE_KEY_SHORTCUT_BUTTON, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); /** * CsdWacomKeyShortcutButton::key-shortcut-cleared: * @keyshortcutbutton: the #CsdWacomKeyShortcutButton * * Emitted when the key shortcut of the @keyshortcutbutton is cleared. */ signals[KEY_SHORTCUT_CLEARED] = g_signal_new ("key-shortcut-cleared", CSD_WACOM_TYPE_KEY_SHORTCUT_BUTTON, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } /** * csd_wacom_key_shortcut_button_new: * * Creates a new #CsdWacomKeyShortcutButton. * * Returns: a new #CsdWacomKeyShortcutButton object. * * Since: 3.10 */ GtkWidget * csd_wacom_key_shortcut_button_new (void) { return g_object_new (CSD_WACOM_TYPE_KEY_SHORTCUT_BUTTON, NULL); } GType csd_wacom_key_shortcut_button_mode_type (void) { static GType enum_type_id = 0; if (G_UNLIKELY (!enum_type_id)) { static const GEnumValue values[] = { { CSD_WACOM_KEY_SHORTCUT_BUTTON_MODE_OTHER, "OTHER", "other" }, { CSD_WACOM_KEY_SHORTCUT_BUTTON_MODE_ALL, "ALL", "all" }, { 0, NULL, NULL } }; enum_type_id = g_enum_register_static ("CsdWacomKeyShortcutButtonMode", values); } return enum_type_id; } cinnamon-control-center-6.4.1/panels/wacom/wacom-stylus-inking.svg0000664000175000017500000000717514724311620024253 0ustar fabiofabio image/svg+xml cinnamon-control-center-6.4.1/panels/wacom/cc-wacom-mapping-panel.c0000664000175000017500000002464214724311620024167 0ustar fabiofabio/* * Copyright Ā© 2012 Wacom. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Authors: Jason Gerecke * */ #include #include #include #include #include "cc-wacom-device.h" #include "cc-wacom-mapping-panel.h" #include "muffin-display-config.h" struct _CcWacomMappingPanel { GtkBox parent_instance; CcWacomDevice *device; GtkWidget *label; GtkWidget *combobox; GtkWidget *checkbutton; GtkWidget *aspectlabel; GtkWidget *aspectswitch; int init_name_watch_id; }; G_DEFINE_TYPE (CcWacomMappingPanel, cc_wacom_mapping_panel, GTK_TYPE_BOX) enum { MONITOR_NAME_COLUMN, MONITOR_INFO_COLUMN, MONITOR_NUM_COLUMNS }; static void combobox_changed_cb (GtkWidget *widget, CcWacomMappingPanel *self); static void checkbutton_toggled_cb (GtkWidget *widget, CcWacomMappingPanel *self); static void aspectswitch_toggled_cb (GtkWidget *widget, GParamSpec *pspec, CcWacomMappingPanel *self); static void set_combobox_sensitive (CcWacomMappingPanel *self, gboolean sensitive) { gtk_widget_set_sensitive (GTK_WIDGET(self->combobox), sensitive); gtk_widget_set_sensitive (GTK_WIDGET(self->label), sensitive); gtk_widget_set_sensitive (GTK_WIDGET(self->aspectswitch), sensitive); gtk_widget_set_sensitive (GTK_WIDGET(self->aspectlabel), sensitive); } /* Update the display of available monitors based on the latest * information from RandR. At the moment the chooser is just a * a combobox crudely listing available outputs. The UI mockup * has something more akin to the Display panel, with the ability * to do rubber-band selection of multiple outputs (note: the * g-s-d backend can only handle a single output at the moment) */ static void update_monitor_chooser (CcWacomMappingPanel *self) { g_autoptr(GtkListStore) store = NULL; MonitorInfo *cur_info; GList *monitors, *l; GSettings *settings; store = gtk_list_store_new (MONITOR_NUM_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER); gtk_combo_box_set_model (GTK_COMBO_BOX(self->combobox), GTK_TREE_MODEL(store)); if (self->device == NULL) { set_combobox_sensitive (self, FALSE); return; } settings = cc_wacom_device_get_settings (self->device); cur_info = cc_wacom_device_get_monitor (self->device); g_signal_handlers_block_by_func (G_OBJECT (self->checkbutton), checkbutton_toggled_cb, self); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(self->checkbutton), cur_info != NULL); g_signal_handlers_unblock_by_func (G_OBJECT (self->checkbutton), checkbutton_toggled_cb, self); g_signal_handlers_block_by_func (G_OBJECT (self->aspectswitch), aspectswitch_toggled_cb, self); gtk_switch_set_active (GTK_SWITCH(self->aspectswitch), g_settings_get_boolean (settings, "keep-aspect")); g_signal_handlers_unblock_by_func (G_OBJECT (self->aspectswitch), aspectswitch_toggled_cb, self); monitors = cc_wacom_output_manager_get_all_monitors(cc_wacom_output_manager_get ()); for (l = monitors; l != NULL; l = l->next) { MonitorInfo *monitor; GtkTreeIter iter; g_autofree gchar *text = NULL; monitor = (MonitorInfo *) l->data; monitor_info_spew (monitor); text = g_strdup_printf ("%s (%s)", monitor->connector_name, monitor->display_name); gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter, MONITOR_NAME_COLUMN, text, MONITOR_INFO_COLUMN, monitor, -1); if (cur_info == NULL || monitor_info_cmp (cur_info, monitor)) { g_signal_handlers_block_by_func (G_OBJECT (self->combobox), combobox_changed_cb, self); gtk_combo_box_set_active_iter (GTK_COMBO_BOX(self->combobox), &iter); g_signal_handlers_unblock_by_func (G_OBJECT (self->combobox), combobox_changed_cb, self); } } set_combobox_sensitive (self, cur_info != NULL); } static void update_ui (CcWacomMappingPanel *self) { if (self->device == NULL) { gtk_widget_set_sensitive (GTK_WIDGET(self->checkbutton), FALSE); gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON(self->checkbutton), TRUE); } else { gboolean is_screen_tablet; is_screen_tablet = cc_wacom_device_get_integration_flags (self->device) & WACOM_DEVICE_INTEGRATED_DISPLAY; gtk_widget_set_sensitive (GTK_WIDGET(self->checkbutton), !is_screen_tablet); gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON(self->checkbutton), FALSE); } update_monitor_chooser (self); } static void update_mapping (CcWacomMappingPanel *self) { MonitorInfo *monitor = NULL; if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->checkbutton))) { GtkTreeIter iter; GtkTreeModel *model; char *name; model = gtk_combo_box_get_model (GTK_COMBO_BOX (self->combobox)); if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (self->combobox), &iter)) { g_warning ("Map to single monitor checked, but no screen selected."); return; } gtk_tree_model_get (model, &iter, MONITOR_NAME_COLUMN, &name, MONITOR_INFO_COLUMN, &monitor, -1); } cc_wacom_device_set_monitor (self->device, monitor); } void cc_wacom_mapping_panel_set_device (CcWacomMappingPanel *self, CcWacomDevice *device) { self->device = device; update_ui (self); } static void checkbutton_toggled_cb (GtkWidget *widget, CcWacomMappingPanel *self) { gboolean active; active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); set_combobox_sensitive (self, active); if (!active) gtk_switch_set_active (GTK_SWITCH(self->aspectswitch), FALSE); update_mapping (self); } static void aspectswitch_toggled_cb (GtkWidget *widget, GParamSpec *pspec, CcWacomMappingPanel *self) { GSettings *settings; settings = cc_wacom_device_get_settings (self->device); g_settings_set_boolean (settings, "keep-aspect", gtk_switch_get_active (GTK_SWITCH (widget))); } static void combobox_changed_cb (GtkWidget *widget, CcWacomMappingPanel *self) { update_mapping (self); } static void cc_wacom_mapping_panel_init (CcWacomMappingPanel *self) { GtkWidget *vbox, *grid; GtkCellRenderer *renderer; g_autoptr(GError) error = NULL; g_signal_connect_swapped (cc_wacom_output_manager_get (), "monitors-changed", G_CALLBACK (update_monitor_chooser), self); vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); gtk_container_add (GTK_CONTAINER (self), vbox); gtk_container_set_border_width (GTK_CONTAINER (self), 12); gtk_widget_set_vexpand (GTK_WIDGET (vbox), TRUE); gtk_widget_set_hexpand (GTK_WIDGET (vbox), TRUE); /* Output Combobox */ grid = gtk_grid_new(); gtk_grid_set_row_spacing (GTK_GRID (grid), 10); gtk_grid_set_column_spacing (GTK_GRID (grid), 10); self->label = gtk_label_new (_("Output:")); gtk_widget_set_halign (self->label, GTK_ALIGN_END); self->combobox = gtk_combo_box_new (); g_signal_connect (G_OBJECT (self->combobox), "changed", G_CALLBACK (combobox_changed_cb), self); renderer = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT(self->combobox), renderer, TRUE); gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT(self->combobox), renderer, "text", 0); gtk_grid_attach (GTK_GRID(grid), GTK_WIDGET(self->label), 0, 0, 1, 1); gtk_grid_attach (GTK_GRID(grid), GTK_WIDGET(self->combobox), 1, 0, 1, 1); /* Keep ratio switch */ self->aspectlabel = gtk_label_new (_("Keep aspect ratio (letterbox):")); gtk_widget_set_halign (self->aspectlabel, GTK_ALIGN_END); self->aspectswitch = gtk_switch_new (); gtk_widget_set_halign (self->aspectswitch, GTK_ALIGN_START); gtk_switch_set_active (GTK_SWITCH (self->aspectswitch), FALSE); g_signal_connect (GTK_SWITCH (self->aspectswitch), "notify::active", G_CALLBACK (aspectswitch_toggled_cb), self); gtk_grid_attach (GTK_GRID(grid), GTK_WIDGET(self->aspectlabel), 0, 1, 1, 1); gtk_grid_attach (GTK_GRID(grid), GTK_WIDGET(self->aspectswitch), 1, 1, 1, 1); /* Whole-desktop checkbox */ self->checkbutton = gtk_check_button_new_with_label (_("Map to single monitor")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->checkbutton), FALSE); g_signal_connect (G_OBJECT (self->checkbutton), "toggled", G_CALLBACK (checkbutton_toggled_cb), self); gtk_box_pack_start (GTK_BOX(vbox), GTK_WIDGET(self->checkbutton), FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX(vbox), GTK_WIDGET(grid), FALSE, FALSE, 8); /* Update display */ cc_wacom_mapping_panel_set_device (self, NULL); gtk_widget_show_all(GTK_WIDGET(self)); } GtkWidget * cc_wacom_mapping_panel_new (void) { CcWacomMappingPanel *panel; panel = CC_WACOM_MAPPING_PANEL(g_object_new (CC_TYPE_WACOM_MAPPING_PANEL, NULL)); panel->device = NULL; return GTK_WIDGET(panel); } static void cc_wacom_mapping_panel_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { switch (property_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void cc_wacom_mapping_panel_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { switch (property_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void cc_wacom_mapping_panel_dispose (GObject *object) { G_OBJECT_CLASS (cc_wacom_mapping_panel_parent_class)->dispose (object); } static void cc_wacom_mapping_panel_class_init (CcWacomMappingPanelClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->get_property = cc_wacom_mapping_panel_get_property; object_class->set_property = cc_wacom_mapping_panel_set_property; object_class->dispose = cc_wacom_mapping_panel_dispose; } cinnamon-control-center-6.4.1/panels/wacom/wacom.gresource.xml0000664000175000017500000000027014724311620023420 0ustar fabiofabio tablet-layout.css cinnamon-control-center-6.4.1/panels/wacom/wacom-tablet-pc.svg0000664000175000017500000000542214724311620023277 0ustar fabiofabio image/svg+xml cinnamon-control-center-6.4.1/panels/wacom/cc-wacom-panel.h0000664000175000017500000000362114724311620022535 0ustar fabiofabio/* * Copyright Ā© 2011 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Authors: Peter Hutterer * Bastien Nocera */ #ifndef _CC_WACOM_PANEL_H #define _CC_WACOM_PANEL_H #include G_BEGIN_DECLS #define CC_TYPE_WACOM_PANEL cc_wacom_panel_get_type() #define CC_WACOM_PANEL(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ CC_TYPE_WACOM_PANEL, CcWacomPanel)) #define CC_WACOM_PANEL_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), \ CC_TYPE_WACOM_PANEL, CcWacomPanelClass)) #define CC_IS_WACOM_PANEL(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ CC_TYPE_WACOM_PANEL)) #define CC_IS_WACOM_PANEL_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), \ CC_TYPE_WACOM_PANEL)) #define CC_WACOM_PANEL_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), \ CC_TYPE_WACOM_PANEL, CcWacomPanelClass)) typedef struct _CcWacomPanel CcWacomPanel; typedef struct _CcWacomPanelClass CcWacomPanelClass; typedef struct _CcWacomPanelPrivate CcWacomPanelPrivate; struct _CcWacomPanelClass { CcPanelClass parent_class; }; GType cc_wacom_panel_get_type (void) G_GNUC_CONST; void cc_wacom_panel_register (GIOModule *module); G_END_DECLS #endif /* _CC_WACOM_PANEL_H */ cinnamon-control-center-6.4.1/panels/wacom/cinnamon-wacom-panel.desktop0000664000175000017500000002704014724311620025175 0ustar fabiofabio[Desktop Entry] Exec=cinnamon-settings wacom Icon=cs-tablet Terminal=false Type=Application StartupNotify=true Categories=GNOME;GTK;Settings;HardwareSettings;X-Cinnamon-Settings-Panel; X-Cinnamon-Settings-Panel=wacom OnlyShowIn=X-Cinnamon; Name=Graphics Tablet Name[am]=įŒįˆ«įŠįŠ­įˆµ į‰³į‰„įˆŒį‰µ Name[ar]=جهاز Ų§Ł„Ų±Ų³ŁˆŁ…Ų§ŲŖ Ų§Ł„Ł„ŁˆŲ­ŁŠ Name[ast]=Tableta de grĆ”fica Name[ay]=Jamuqamp tableta Name[az]=Gƶrüntü Taxtası Name[be]=Графічны ŠæŠ»Š°Š½ŃˆŃŃ‚ Name[be@latin]=Графічны ŠæŠ»Š°Š½ŃˆŃŃ‚ Name[bg]=Графичен таблет Name[bs]=Grafički tablet Name[ca]=Tauleta grĆ fica Name[ca@valencia]=Tauleta grĆ fica Name[cs]=Grafický tablet Name[cy]=Tabled Graffig Name[da]=Tegneplade Name[de]=Grafiktablett Name[el]=Επιφάνεια Αφής Name[eo]=Desegna tabuleto Name[es]=Tableta grĆ”fica Name[et]=Tahvli graafika Name[eu]=Taula grafikoa Name[fa]=تبلت گرافیک Name[fi]=Piirtoalusta Name[fr]=Tablette graphique Name[fr_CA]=Tablette graphique Name[gd]=Tablaid grafaigeachd Name[gl]=Tableta grĆ”fica Name[he]=לוח מגע גרפי Name[hi]=ą¤—ą„ą¤°ą¤¾ą„žą¤æą¤•ą„ą¤ø ą¤Ÿą„ˆą¤¬ą¤²ą„‡ą¤Ÿ Name[hr]=Grafički tablet Name[hu]=DigitalizĆ”ló tĆ”bla Name[ia]=Tabletta graphic Name[id]=Tablet Grafis Name[ie]=Grafical tabulette Name[is]=Teiknitafla Name[it]=Tavoletta grafica Name[ja]=ć‚°ćƒ©ćƒ•ć‚£ćƒƒć‚Æć‚æćƒ–ćƒ¬ćƒƒćƒˆ Name[ka]=įƒ’įƒ įƒįƒ¤įƒ˜įƒ™įƒ£įƒšįƒ˜ įƒ¢įƒįƒ‘įƒšįƒ”įƒ¢įƒ˜ Name[kab]=Tafelwit tudlift Name[kk]=Графикалық ŠŸŠ»Š°Š½ŃˆŠµŃ‚ Name[ko]=ź·øėž˜ķ”½ ķƒœėø”ė¦æ Name[la]=Tabella Graphica Name[lt]=Grafinė planÅ”etė Name[lv]=Grafiskā planÅ”ete Name[ms]=Tablet Grafik Name[nb]=Tegnebrett Name[nds]=Grafik-Tablett Name[nl]=Grafische tablet Name[oc]=Tauleta grafica Name[pl]=Tablet graficzny Name[pt]=Tablet Name[pt_BR]=Mesa Digitalizadora Name[ro]=Tabletă grafică Name[ru]=Графический ŠæŠ»Š°Š½ŃˆŠµŃ‚ Name[sc]=Tauledda grĆ fica Name[sk]=Grafický tablet Name[sl]=Grafična tablica Name[sr]=Таблица за Ń†Ń€Ń‚Š°ŃšŠµ Name[sr@latin]=Grafička tabla Name[sv]=Ritplatta Name[ta]=ą®µą®°ąÆˆą®•ą®²ąÆˆ ą®¤ąÆ†ą®¾ą®ŸąÆą®¤ą®ŸąÆą®ŸąÆ Name[tg]=ŠŸŠ»Š°Š½ŃˆŠµŃ‚Šø графикӣ Name[th]=ą¹ąø—ą¹‡ąøšą¹€ąø„ą¹‡ąø•ąøąø£ąø²ąøŸąø“ąø Name[tr]=Grafik Tablet Name[uk]=Графічний ŠæŠ»Š°Š½ŃˆŠµŃ‚ Name[ur]=گرافکس Ł¹ŪŒŲØŁ„ŪŒŁ¹ Name[uz]=Grafik Planshet Name[uz@cyrillic]=Grafik Planshet Name[vi]=BĆ n vįŗ½ Đồ hoįŗ” Name[zh_CN]=ē»˜å›¾ęæ Name[zh_HK]=ē¹Ŗåœ–ęæ Name[zh_TW]=ē¹Ŗåœ–å¹³ęæ Comment=Set button mappings and adjust stylus sensitivity for graphics tablets Comment[am]=የ į‰įˆį įŠ«įˆ­į‰³ įˆ›įˆ°įŠ“įŒƒ įŠ„įŠ“ įˆ›įˆµį‰°įŠ«įŠØį‹« stylus sensitivity for graphics tablets Comment[ar]=ŲŖŲ¹ŁŠŁŠŁ† Ł…Ų®Ų·Ų·Ų§ŲŖ الأزرار وضبط حساسية القلم لأجهزة Ų§Ł„Ų±Ų³ŁˆŁ…Ų§ŲŖ Ų§Ł„Ł„ŁˆŲ­ŁŠŲ© Comment[ast]=Configurar el mapĆ©u de botones y axustar la sensibilidĆ” del llapiceru nes tabletes grĆ”fiques Comment[ay]=Wutunanak uƱacht'ayaƱa ukhamaraki lapisan turpa mayjachaƱa jamuqampi tabletanakataki Comment[az]=Gƶrüntü taxtaları üçün düymə bildirmələrini qur, iynə duyarlılığını ayarla Comment[be]=ŠŸŃ€Ń‹Š·Š½Š°Ń‡ŃŠ½Š½Šµ кнопак і Š·Š¼ŃŠ½ŠµŠ½Š½Šµ Š°Š“Ń‡ŃƒŠ²Š°Š»ŃŒŠ½Š°ŃŃ†Ń– ŠæŃŃ€Š° графічных ŠæŠ»Š°Š½ŃˆŃŃ‚Š°Ńž Comment[be@latin]=ŠŸŃ€Ń‹Š·Š½Š°Ń‡ŃŠ½Š½Šµ кнопак і Š·Š¼ŃŠ½ŠµŠ½Š½Šµ Š°Š“Ń‡ŃƒŠ²Š°Š»ŃŒŠ½Š°ŃŃ†Ń– ŠæŃŃ€Š° графічных ŠæŠ»Š°Š½ŃˆŃŃ‚Š°Ńž Comment[bg]=ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠ° на Š±ŃƒŃ‚оните Šø Ń‡ŃƒŠ²ŃŃ‚Š²ŠøŃ‚ŠµŠ»Š½Š¾ŃŃ‚Ń‚Š° на ŃŃ‚ŠøŠ»ŃƒŃŠ° Ń‡ŃƒŠ²ŃŃ‚Š²ŠøŃ‚ŠµŠ»Š½Š¾ŃŃ‚ за графичните таблети Comment[ca]=Establiu l'assignació dels botons i ajusteu la sensitivitat del llapis per a les tauletes grĆ fiques Comment[ca@valencia]=Estableix el mapa de botons i ajusta la sensitivitat del llapis per a tauletes grĆ fiques Comment[cs]=Nastavit mapovĆ”nĆ­ tlačƭtek a přizpÅÆsobit citlivost grafických tabletÅÆ Comment[cy]=Gosod mapio botymau a newid sensitifrwydd yr ysgrifbin ar gyfer tabledi graffig Comment[da]=Angiv tildeling af knapper og justĆ©r fĆølsomhed for digital pen til tegneplader Comment[de]=Knopfzuordnung einstellen und die Empfindlichkeit des Stiftes für Grafiktabletts einstellen Comment[el]=ĪŸĻĪ¹ĻƒĪ¼ĻŒĻ‚ Ī±Ļ€ĪµĪ¹ĪŗĪæĪ½ĪÆĻƒĪµĻ‰Ī½ ĪŗĪæĻ…Ī¼Ļ€Ī¹ĻŽĪ½ και ĻĻĪøĪ¼Ī¹ĻƒĪ· ĪµĻ…Ī±Ī¹ĻƒĪøĪ·ĻƒĪÆĪ±Ļ‚ γραφίΓας (stylus) για ταμπλέτες Ī³ĻĪ±Ļ†Ī¹ĪŗĻŽĪ½ Comment[eo]=Agordi butonajn mapigojn kaj ĝustigi grifelan sentivecon por desegnaj tabuletoj Comment[es]=Asigne los botones y ajuste la sensibilidad del lĆ”piz óptico de las tabletas grĆ”ficas Comment[et]=Digitaallaudade nuppude vastavuse ja kirjapulga tundlikkuse muutmine Comment[eu]=Ezarri botoi-mapatzea eta doitu arkatzaren sentikortasuna taula grafikoentzako Comment[fa]=ŲŖŁ†ŲøŪŒŁ… Ų¬Ų§ŪŒŚÆŲ§Ł‡ Ś©Ł„ŪŒŲÆā€ŒŁ‡Ų§ و ŲŖŁ†ŲøŪŒŁ… حساسیت قلم برای تبلت گرافیک Comment[fi]=Aseta piirtopƶydƤn painikkeet ja kynƤn herkkyys Comment[fr]=Associer les boutons et ajuster la sensibilitĆ© du stylet des tablettes graphiques Comment[fr_CA]=Associer les boutons et ajuster la sensibilitĆ© du stylet des tablettes graphiques Comment[gd]=Suidhich mapadh nam putanan is cuir air gleus mothalachd an staidhleis airson tablaidean grafaigeachd Comment[gl]=Estabeleza a asignación de botóns e axuste a sensibilidade do seu lapis dixital nas tabletas grĆ”ficas Comment[he]=הגדרת מיפוי לחצנים ×•×”×Ŗ××ž×Ŗ רגישות העט ×œ×œ×•×—×•×Ŗ מגע ×’×Ø×¤×™×™× Comment[hi]=ą¤—ą„ą¤°ą¤¾ą„žą¤æą¤•ą„ą¤ø ą¤Ÿą„ˆą¤¬ą¤²ą„‡ą¤Ÿ ą¤¹ą„‡ą¤¤ą„ बटन ą¤•ą¤¾ą¤°ą„ą¤Æ ą¤øą„‡ą¤Ÿ व ą¤øą„ą¤Ÿą¤¾ą¤‡ą¤²ą¤ø ą¤øą¤‚ą¤µą„‡ą¤¦ą¤Øą¤¶ą„€ą¤²ą¤¤ą¤¾ ą¤øą¤®ą¤¾ą¤Æą„‹ą¤œą¤æą¤¤ ą¤•ą¤°ą„‡ą¤‚ Comment[hr]=Postavi tipke mapiranja i prilagodi osjetljivost igle grafičkih tableta Comment[hu]=RajztĆ”blĆ”k gomblekĆ©pezĆ©seinek beĆ”llĆ­tĆ”sa Ć©s a stylus Ć©rzĆ©kenysĆ©gĆ©nek módosĆ­tĆ”sa Comment[ia]=Configurar le mappas del buttones e adjustar le sensitivitate del stilo pro le tablettas graphic Comment[id]=Tata pemetaan tombol dan atur kepekaan stylus bagi tablet grafis Comment[is]=Stilltu hnappavƶrpun og aưlagaưu nƦmni snertipenna fyrir teikniborư Comment[it]=Imposta la mappatura dei pulsanti e regola la sensibilitĆ  del pennino per tavolette grafiche Comment[ja]=ć‚°ćƒ©ćƒ•ć‚£ćƒƒć‚Æć‚æćƒ–ćƒ¬ćƒƒćƒˆć®ćƒœć‚æćƒ³å‰²ć‚Šå½“ć¦ć‚„ć€ć‚¹ć‚æć‚¤ćƒ©ć‚¹ę„Ÿåŗ¦ć‚’čŖæę•“ć—ć¾ć™ Comment[kab]=Sireg tiqfalin u sgaddi aįø„ulfu n imru di tfelwin tudlifin Comment[kk]=Графикалық ŠæŠ»Š°Š½ŃˆŠµŃ‚Ń‚ŠµŃ€ ŅÆŃˆŃ–Š½ батырмалар сәйкестіктерін және ŃŃ‚ŠøŠ»ŃƒŃ сезімталГылығын Š±Š°ŠæŃ‚Š°Ńƒ Comment[ko]=ź·øėž˜ķ”½ ķƒœėø”ė¦æģ˜ ė²„ķŠ¼ģ„ 매핑 ķ•˜ź³  ģŠ¤ķƒ€ģ¼ėŸ¬ģŠ¤ģ˜ ź°ė„ė„¼ ģ”°ģ ˆķ•©ė‹ˆė‹¤. Comment[lt]=Nustatykite mygtukų susiejimus ir pritaikykite pieÅ”tuko jautrumą grafinėms planÅ”etėms Comment[nb]=Sett knappekartlegging og tilpass stylyssensitivitet for grafikkbrett Comment[nl]=Knoptoewijzingen instellen en gevoeligheid bijstellen van stylus voor grafische tabletten Comment[oc]=Associar los botons e ajustar la sensibilitat de l'estilet de las tauletas graficas Comment[pl]=Ustawienie mapowania przycisków i dostosowanie wrażliwości rysika dla tabletów graficznych Comment[pt]=Definir mapeamento dos botƵes e ajustar a sensibilidade das canetas dos tablets Comment[pt_BR]=Definir botƵes e ajustar sensibilidade da caneta para mesas digitalizadoras Comment[ro]=Setați alocarea butoanelor și ajustați sensibilitatea stylusului tabletei grafice Comment[ru]=Установка ŠæŃ€ŠøŠ²ŃŠ·ŠŗŠø кнопок Šø настройка Ń‡ŃƒŠ²ŃŃ‚Š²ŠøŃ‚ŠµŠ»ŃŒŠ½Š¾ŃŃ‚Šø пера Š“Š»Ń графических ŠæŠ»Š°Š½ŃˆŠµŃ‚Š¾Š² Comment[sk]=Nastavuje priradenie tlačidiel a upravuje citlivosÅ„ pera grafických tabletov Comment[sl]=Nastavite preslikave gumbov in prilagodite občutljivost pisala za grafične tablice Comment[sr]=ПоГеси пречице ГугмаГи Šø осетљивост писаљке графичким таблицама Comment[sr@latin]=Postavite mapiranje dugmadi i podesite osetljivost digitalne olovke grafičkih tabli Comment[sv]=StƤll in knappmappningar och justera kƤnslighet fƶr styluspenna till ritplattor Comment[th]=ąøąø³ąø«ąø™ąø”ąøœąø±ąø‡ąø›ąøøą¹ˆąø”ą¹ąø„ąø°ąø›ąø£ąø±ąøšąø„ąø§ąø²ąø”ąø•ąø­ąøšąøŖąø™ąø­ąø‡ąø›ąø²ąøąøąø²ąøŠąøµą¹‰ąøŖąø³ąø«ąø£ąø±ąøšą¹ąø—ą¹‡ąøšą¹€ąø„ą¹‡ąø•ąøąø£ąø²ąøŸąø“ąøąøŖą¹Œ Comment[tr]=Grafik tabletler iƧin düğme eşleştirmelerini ve kalem (stylus) duyarlılığını ayarla. Comment[uk]=Визначити ŠæŃ€ŠøŠ²ā€™ŃŠ·ŠŗŃƒ кнопок і ŃŠŗŠ¾Ń€ŠøŠ³ŃƒŠ²Š°Ń‚Šø Ń‡ŃƒŃ‚Š»ŠøŠ²Ń–ŃŃ‚ŃŒ сенсора Š“Š»Ń графічних ŠæŠ»Š°Š½ŃˆŠµŃ‚Ń–Š² Comment[uz]=Grafik planshet uchun tugma joylarini oā€˜rnatish va pero sezgirligini moslash Comment[uz@cyrillic]=Grafik planshet uchun tugma joylarini oā€˜rnatish va pero sezgirligini moslash Comment[vi]=Ɓnh xįŗ” nĆŗt vĆ  điều chỉnh độ nhįŗ”y bĆŗt bĆ n vįŗ½ Comment[zh_CN]=č®¾ē½®ē»˜å›¾ęæēš„ęŒ‰é”®ę˜ å°„å’Œēµę•åŗ¦ Comment[zh_HK]=čØ­å®šē¹Ŗåœ–ęæēš„ęŒ‰éˆ•å°ę‡‰äø¦čŖæę•“č§øęŽ§ē­†ēš„éˆę•åŗ¦ Comment[zh_TW]=čØ­å®šē¹Ŗåœ–å¹³ęæēš„ęŒ‰éµå°ę‡‰äø¦čŖæę•“č§øęŽ§ē­†ēš„éˆę•åŗ¦ Keywords=Tablet;Wacom;Stylus;Eraser;Mouse; Keywords[ast]=Tablet;Wacom;Llapiceru tautil;Borrador;Mur; Keywords[be]=ŠæŠ»Š°Š½ŃˆŃŃ‚;Wacom;ŠæŃŃ€Š¾;гумка;Š¼Ń‹Ńˆ; Keywords[be@latin]=ŠæŠ»Š°Š½ŃˆŃŃ‚;Wacom;ŠæŃŃ€Š¾;гумка;Š¼Ń‹Ńˆ; Keywords[ca]=Tauleta;Wacom;Llapis òptic;goma d'esborrar;RatolĆ­; Keywords[ca@valencia]=Tauleta;Wacom;Llapis òptic;goma d'esborrar;RatolĆ­; Keywords[cs]=Tablet;Wacom;stylus;guma;myÅ”; Keywords[cy]=Tabled;Wacoom;pwyntil;Rhwbiwr;Llygoden; Keywords[da]=Tegneplade;Wacom;Pen;Stylus;ViskelƦder;Slette;Mus; Keywords[de]=Tablet;Wacom;Stylus;Eraser;Mouse;Maus; Keywords[el]=Ταμπλέτα;Wacom;Πένα;Ī“ĻŒĪ¼Ī±;Ποντίκι; Keywords[eo]=Tabulkomputilo;Wacom;Grifelo;Gumo;Muso; Keywords[es]=Tableta;Wacom;LĆ”piz tĆ”ctil;Borrador;Ratón; Keywords[et]=Tahvelarvuti;Wacom;Stylus;Kustutaja;Hiir; Keywords[eu]=Tableta;Wacom;Arkatz optikoa;Borragoma;Sagua; Keywords[fa]=ŲŖŲØŁ„ŲŖŲŒ Wacom، Ł‚Ł„Ł…ŲŒ Ł¾Ų§Ś©ā€ŒŚ©Ł†ŲŒ Ł…Ų§ŁˆŲ³; Keywords[fi]=Piirtoalusta;Wacom;KynƤ;Pyyhekumi;Hiiri; Keywords[fr]=Tablette;Wacom;Stylet;Gomme;Souris; Keywords[fr_CA]=Tablette;Wacom;Stylet;Gomme;Souris; Keywords[he]=מחשב־לוח;Wacom;הטילוה;מחק;עכבר; Keywords[hi]=ą¤Ÿą„ˆą¤¬ą¤²ą„‡ą¤Ÿ;Wacom;ą¤øą„ą¤Ÿą¤¾ą¤‡ą¤²ą¤ø;ą¤‡ą¤°ą„‡ą¤œą¤¼ą¤°;माउस; Keywords[hr]=Tablet;Wacom;Pisaljak;Brisaljka;MiÅ”; Keywords[hu]=RajztĆ”bla;Wacom;Toll;RadĆ­r;EgĆ©r;Tablet;Stylus;Eraser;Mouse; Keywords[ia]=Tabletta;Wacom;Stilo;Eradicator;Mus; Keywords[id]=Tablet;Wacom;Stylus;Penghapus;Mouse; Keywords[is]=Tafla;Wacom;Teiknipenni;Útstrokari;MĆŗs; Keywords[it]=Tavoletta;Wacom;Penna;Gomma;Mouse; Keywords[ja]=Tablet;Wacom;Stylus;Eraser;Mouse;ć‚æćƒ–ćƒ¬ćƒƒćƒˆ;ć‚¹ć‚æć‚¤ćƒ©ć‚¹;ę¶ˆć—ć‚“ćƒ ;ćƒžć‚¦ć‚¹; Keywords[ko]=ķƒœėø”ė¦æ;Wacom;ģŠ¤ķƒ€ģ¼ėŸ¬ģŠ¤;ģ§€ģš°ź°œ;마우스; Keywords[nb]=Tegnebrett;Wacom;Stylus;ViskelƦr;Mus; Keywords[nl]=Tablet;Wacom;Pen;Eraser;Muis; Keywords[oc]=Tauleta;Wacom;Estilet;Goma;Mirga; Keywords[pl]=Tablet;Wacom;Rysik;Gumka;Mysz; Keywords[pt]=Tablet;Wacom;Caneta;Borracha;Rato; Keywords[pt_BR]=Tablet;Wacom;Stylus;Apagar;Mouse; Keywords[ro]=Tabletă;Wacom;Stylus;Radieră;Maus; Keywords[ru]=ŠŸŠ»Š°Š½ŃˆŠµŃ‚;Wacom;Š”Ń‚ŠøŠ»ŃƒŃ;Дтёрка;ŠœŃ‹ŃˆŃŒ;Электронное перо;Š ŃƒŃ‡ŠŗŠ°; Keywords[sk]=Tablet;Wacom;stylus;guma;myÅ”; Keywords[sl]=Tablica;Wacom;pisalo;radirka;miÅ”ka; Keywords[sv]=Ritplatta;Wacom;Stylus;Raderare;Mus; Keywords[tr]=Tablet;Wacom;Tuş Kalemi;Silici;Fare; Keywords[uk]=ŠŸŠ»Š°Š½ŃˆŠµŃ‚;Wacom;Š”Ń‚ŠøŠ»ŃƒŃ;Дтирач;Миша; Keywords[uz]=Planshet;Wacom;Stylus;Eraser;Sichqoncha; Keywords[uz@cyrillic]=Planshet;Wacom;Stylus;Eraser;Sichqoncha; Keywords[vi]=MĆ”y tĆ­nh bįŗ£ng;Wacom;bĆŗt stylus;tįŗ©y;chuį»™t; Keywords[zh_TW]=č§øęŽ§ęæ;Wacom;手寫筆;ę©”ēš®ę“¦;滑鼠; cinnamon-control-center-6.4.1/panels/wacom/wacom-stylus-art-pen.svg0000664000175000017500000001276714724311620024345 0ustar fabiofabio image/svg+xml cinnamon-control-center-6.4.1/panels/wacom/cc-drawing-area.h0000664000175000017500000000173514724311620022677 0ustar fabiofabio/* * Copyright Ā© 2016 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Author: Carlos Garnacho */ #pragma once #include G_BEGIN_DECLS #define CC_TYPE_DRAWING_AREA (cc_drawing_area_get_type ()) G_DECLARE_FINAL_TYPE (CcDrawingArea, cc_drawing_area, CC, DRAWING_AREA, GtkEventBox) GtkWidget *cc_drawing_area_new (void); G_END_DECLS cinnamon-control-center-6.4.1/panels/wacom/wacom-stylus-page.ui0000664000175000017500000004647714724311620023536 0ustar fabiofabio 6 1 3 6 1 3 0 Default 1 Middle Mouse Button Click 2 Right Mouse Button Click 3 Back 4 Forward 5 Disabled stylus-notebook True True False False True False vertical True False end True 96 input-tablet-symbolic 0 False True 0 True False No stylus found False True 1 True False start True Please move your stylus to the proximity of the tablet to configure it center True 30 False True 2 True False True 10 10 True False start center Stylus 0 0 2 True False end start wacom-stylus.svg 0 1 True False 16 12 True vertical 6 10 True False end center Eraser Pressure Feel right 0 0 True False True 10 True False Soft False True 0 True True center adjustment-eraser-feel 0 0 False True True 1 True False Firm False True 2 1 0 True False end center Top Button right 0 1 True False center liststore-buttons 1 1 True False end center Lower Button right 0 2 True False center liststore-buttons 1 2 True False end center Lowest Button right 0 3 True False center liststore-buttons 1 3 True False end center Tip Pressure Feel right 0 4 True False 10 True False Soft False True 0 True True True adjustment-tip-feel 0 0 False True True 1 True False Firm False True 2 1 4 1 1 True False end crossfade 100 1 0 True False vertical True False Test Your _Settings True False True 0 0 2 3 1 cinnamon-control-center-6.4.1/panels/wacom/cc-wacom-button-row.c0000664000175000017500000002123414724311620023551 0ustar fabiofabio/* * Copyright Ā© 2013 Red Hat, Inc. * * Authors: Joaquim Rocha * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ #include #include #include "csd-wacom-key-shortcut-button.h" #include "cc-wacom-button-row.h" #define ACTION_KEY "action" #define KEYBINDING_KEY "keybinding" #define WACOM_C(x) g_dpgettext2(NULL, "Wacom action-type", x) enum { ACTION_NAME_COLUMN, ACTION_TYPE_COLUMN, ACTION_N_COLUMNS }; struct _CcWacomButtonRow { GtkListBoxRow parent_instance; guint button; GSettings *settings; GtkDirectionType direction; GtkComboBox *action_combo; CsdWacomKeyShortcutButton *key_shortcut_button; }; G_DEFINE_TYPE (CcWacomButtonRow, cc_wacom_button_row, GTK_TYPE_LIST_BOX_ROW) static GtkWidget * create_actions_combo (void) { GtkListStore *model; GtkTreeIter iter; GtkWidget *combo; GtkCellRenderer *renderer; gint i; model = gtk_list_store_new (ACTION_N_COLUMNS, G_TYPE_STRING, G_TYPE_INT); for (i = 0; i < G_N_ELEMENTS (action_table); i++) { gtk_list_store_append (model, &iter); gtk_list_store_set (model, &iter, ACTION_NAME_COLUMN, WACOM_C(action_table[i].action_name), ACTION_TYPE_COLUMN, action_table[i].action_type, -1); } combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (model)); renderer = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "text", ACTION_NAME_COLUMN, NULL); return combo; } static void cc_wacom_button_row_update_shortcut (CcWacomButtonRow *row, CDesktopPadButtonAction action_type) { guint keyval; GdkModifierType mask; g_autofree gchar *shortcut = NULL; if (action_type != C_DESKTOP_PAD_BUTTON_ACTION_KEYBINDING) return; shortcut = g_settings_get_string (row->settings, KEYBINDING_KEY); if (shortcut != NULL) { gtk_accelerator_parse (shortcut, &keyval, &mask); g_object_set (row->key_shortcut_button, "key-value", keyval, "key-mods", mask, NULL); } } static void cc_wacom_button_row_update_action (CcWacomButtonRow *row, CDesktopPadButtonAction action_type) { GtkTreeIter iter; gboolean iter_valid; CDesktopPadButtonAction current_action_type, real_action_type; GtkTreeModel *model; model = gtk_combo_box_get_model (row->action_combo); real_action_type = action_type; for (iter_valid = gtk_tree_model_get_iter_first (model, &iter); iter_valid; iter_valid = gtk_tree_model_iter_next (model, &iter)) { gtk_tree_model_get (model, &iter, ACTION_TYPE_COLUMN, ¤t_action_type, -1); if (current_action_type == real_action_type) { gtk_combo_box_set_active_iter (row->action_combo, &iter); break; } } } static void cc_wacom_button_row_update (CcWacomButtonRow *row) { CDesktopPadButtonAction current_action_type; current_action_type = g_settings_get_enum (row->settings, ACTION_KEY); cc_wacom_button_row_update_shortcut (row, current_action_type); cc_wacom_button_row_update_action (row, current_action_type); gtk_widget_set_sensitive (GTK_WIDGET (row->key_shortcut_button), current_action_type == C_DESKTOP_PAD_BUTTON_ACTION_KEYBINDING); } static void change_button_action_type (CcWacomButtonRow *row, CDesktopPadButtonAction type) { g_settings_set_enum (row->settings, ACTION_KEY, type); gtk_widget_set_sensitive (GTK_WIDGET (row->key_shortcut_button), type == C_DESKTOP_PAD_BUTTON_ACTION_KEYBINDING); } static void on_key_shortcut_edited (CsdWacomKeyShortcutButton *shortcut_button, CcWacomButtonRow *row) { g_autofree gchar *custom_key = NULL; guint keyval; GdkModifierType mask; change_button_action_type (row, C_DESKTOP_PAD_BUTTON_ACTION_KEYBINDING); g_object_get (row->key_shortcut_button, "key-value", &keyval, "key-mods", &mask, NULL); mask &= ~GDK_LOCK_MASK; custom_key = gtk_accelerator_name (keyval, mask); g_settings_set_string (row->settings, KEYBINDING_KEY, custom_key); } static void on_key_shortcut_cleared (CsdWacomKeyShortcutButton *key_shortcut_button, CcWacomButtonRow *row) { change_button_action_type (row, C_DESKTOP_PAD_BUTTON_ACTION_NONE); cc_wacom_button_row_update_action (row, C_DESKTOP_PAD_BUTTON_ACTION_NONE); } static void on_row_action_combo_box_changed (GtkComboBox *combo, CcWacomButtonRow *row) { CDesktopPadButtonAction type; GtkTreeModel *model; GtkListBox *list_box; GtkTreeIter iter; if (!gtk_combo_box_get_active_iter (combo, &iter)) return; /* Select the row where we changed the combo box (if not yet selected) */ list_box = GTK_LIST_BOX (gtk_widget_get_parent (GTK_WIDGET (row))); if (list_box && gtk_list_box_get_selected_row (list_box) != GTK_LIST_BOX_ROW (row)) gtk_list_box_select_row (list_box, GTK_LIST_BOX_ROW (row)); model = gtk_combo_box_get_model (combo); gtk_tree_model_get (model, &iter, ACTION_TYPE_COLUMN, &type, -1); change_button_action_type (row, type); } static gboolean on_key_shortcut_button_press_event (CsdWacomKeyShortcutButton *button, GdkEventButton *event, GtkListBoxRow *row) { GtkListBox *list_box; /* Select the row where we pressed the button (if not yet selected) */ list_box = GTK_LIST_BOX (gtk_widget_get_parent (GTK_WIDGET (row))); if (list_box && gtk_list_box_get_selected_row (list_box) != row) gtk_list_box_select_row (list_box, row); return FALSE; } static void cc_wacom_button_row_class_init (CcWacomButtonRowClass *button_row_class) { } static void cc_wacom_button_row_init (CcWacomButtonRow *button_row) { } GtkWidget * cc_wacom_button_row_new (guint button, GSettings *settings) { CcWacomButtonRow *row; GtkWidget *grid, *combo, *label, *shortcut_button; g_autofree gchar *name = NULL; row = CC_WACOM_BUTTON_ROW (g_object_new (CC_WACOM_TYPE_BUTTON_ROW, NULL)); row->button = button; row->settings = g_object_ref (settings); grid = gtk_grid_new (); gtk_widget_show (grid); gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE); gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE); name = g_strdup_printf (_("Button %d"), button); label = gtk_label_new (name); g_object_set (label, "halign", GTK_ALIGN_START, NULL); gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1); gtk_widget_show (label); combo = create_actions_combo (); gtk_grid_attach (GTK_GRID (grid), combo, 1, 0, 1, 1); gtk_widget_show (combo); row->action_combo = GTK_COMBO_BOX (combo); g_signal_connect (combo, "changed", G_CALLBACK (on_row_action_combo_box_changed), row); shortcut_button = csd_wacom_key_shortcut_button_new (); g_object_set (shortcut_button, "mode", CSD_WACOM_KEY_SHORTCUT_BUTTON_MODE_ALL, NULL); gtk_grid_attach (GTK_GRID (grid), shortcut_button, 2, 0, 1, 1); gtk_widget_show (shortcut_button); row->key_shortcut_button = CSD_WACOM_KEY_SHORTCUT_BUTTON (shortcut_button); g_signal_connect (shortcut_button, "key-shortcut-cleared", G_CALLBACK (on_key_shortcut_cleared), row); g_signal_connect (shortcut_button, "key-shortcut-edited", G_CALLBACK (on_key_shortcut_edited), row); g_signal_connect (shortcut_button, "button-press-event", G_CALLBACK (on_key_shortcut_button_press_event), row); gtk_container_add (GTK_CONTAINER (row), grid); cc_wacom_button_row_update (CC_WACOM_BUTTON_ROW (row)); return GTK_WIDGET (row); } cinnamon-control-center-6.4.1/panels/wacom/cc-wacom-output-manager.c0000664000175000017500000002401314724311620024377 0ustar fabiofabio/* * Copyright Ā© 2016 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Authors: Carlos Garnacho * */ #include "config.h" #include #include "cc-wacom-output-manager.h" #include "muffin-display-config.h" typedef struct _CcWacomOutputManager CcWacomOutputManager; struct _CcWacomOutputManager { GObject parent_instance; MetaDBusDisplayConfig *proxy; GList *monitors; }; G_DEFINE_TYPE (CcWacomOutputManager, cc_wacom_output_manager, G_TYPE_OBJECT) enum { MONITORS_CHANGED, N_SIGNALS, }; static guint cc_wacom_output_manager_signals[N_SIGNALS] = { 0 }; static void monitor_info_free (MonitorInfo *info) { g_free (info->connector_name); g_free (info->display_name); g_free (info->vendor); g_free (info->product); g_free (info->serial); g_slice_free (MonitorInfo, info); } gboolean monitor_info_cmp (MonitorInfo *a, MonitorInfo *b) { return (g_strcmp0 (a->vendor, b->vendor) == 0 && g_strcmp0 (a->product, b->product) == 0 && g_strcmp0 (a->serial, b->serial) == 0); } void monitor_info_spew (MonitorInfo *info) { g_printerr ("connector: %s, display_name: %s, vendor: %s, product: %s, serial: %s\n" "x_origin: %d, y_origin: %d, primary? %d, builtin? %d\n", info->connector_name, info->display_name, info->vendor, info->product, info->serial, info->x, info->y, info->primary, info->builtin); } #define MODE_BASE_FORMAT "siiddad" #define MODE_FORMAT "(" MODE_BASE_FORMAT "a{sv})" #define MODES_FORMAT "a" MODE_FORMAT #define MONITOR_SPEC_FORMAT "(ssss)" #define MONITOR_FORMAT "(" MONITOR_SPEC_FORMAT MODES_FORMAT "a{sv})" #define MONITORS_FORMAT "a" MONITOR_FORMAT #define LOGICAL_MONITOR_MONITORS_FORMAT "a" MONITOR_SPEC_FORMAT #define LOGICAL_MONITOR_FORMAT "(iidub" LOGICAL_MONITOR_MONITORS_FORMAT "a{sv})" #define LOGICAL_MONITORS_FORMAT "a" LOGICAL_MONITOR_FORMAT static void update_monitor_infos (CcWacomOutputManager *manager, GVariant *monitors, GVariant *logical_monitors) { GList *new_monitors = NULL; GVariantIter m_iter; g_variant_iter_init (&m_iter, monitors); while (TRUE) { g_autoptr(GVariant) variant = NULL; if (!g_variant_iter_next (&m_iter, "@"MONITOR_FORMAT, &variant)) break; gchar *connector_name, *vendor, *product, *serial; g_autoptr(GVariantIter) modes = NULL; g_autoptr(GVariantIter) props = NULL; g_variant_get (variant, MONITOR_FORMAT, &connector_name, &vendor, &product, &serial, &modes, &props); MonitorInfo *info = g_slice_new0 (MonitorInfo); info->connector_name = connector_name; info->vendor = vendor; info->product = product; info->serial = serial; while (TRUE) { const char *s; g_autoptr(GVariant) v = NULL; if (!g_variant_iter_next (props, "{&sv}", &s, &v)) break; if (g_str_equal (s, "display-name")) { g_variant_get (v, "s", &info->display_name); } if (g_str_equal (s, "is-builtin")) { g_variant_get (v, "b", &info->builtin); } } GVariantIter l_iter; g_variant_iter_init (&l_iter, logical_monitors); while (TRUE) { g_autoptr(GVariant) variant = NULL; g_autoptr(GVariantIter) monitor_specs = NULL; const gchar *lconnector, *lvendor, *lproduct, *lserial; gint x, y; gboolean primary; gboolean found_one = FALSE; if (!g_variant_iter_next (&l_iter, "@"LOGICAL_MONITOR_FORMAT, &variant)) break; g_variant_get (variant, LOGICAL_MONITOR_FORMAT, &x, &y, NULL, NULL, &primary, &monitor_specs, NULL); while (g_variant_iter_next (monitor_specs, "(&s&s&s&s)", &lconnector, &lvendor, &lproduct, &lserial)) { if (g_strcmp0 (info->connector_name, lconnector) == 0 && g_strcmp0 (info->vendor, lvendor) == 0 && g_strcmp0 (info->product, lproduct) == 0 && g_strcmp0 (info->serial, lserial) == 0) { info->x = x; info->y = y; info->primary = primary; found_one = TRUE; break; } } // Only check the first logical monitor - we're only looking for the origin x, y of the physical one. if (found_one) break; } new_monitors = g_list_append (new_monitors, info); } manager->monitors = new_monitors; } static void update_from_muffin (CcWacomOutputManager *manager) { if (manager->monitors != NULL) { g_list_free_full (g_steal_pointer (&manager->monitors), (GDestroyNotify) monitor_info_free); } if (g_dbus_proxy_get_name_owner (G_DBUS_PROXY (manager->proxy)) != NULL) { GVariant *monitors, *logical_monitors, *properties; guint serial; GError *error = NULL; if (meta_dbus_display_config_call_get_current_state_sync (manager->proxy, &serial, &monitors, &logical_monitors, &properties, NULL, &error)) { update_monitor_infos (manager, monitors, logical_monitors); g_variant_unref (monitors); g_variant_unref (logical_monitors); g_variant_unref (properties); } else { g_critical ("GetCurrentState failed (%d): %s\n", error->code, error->message); } } else { g_critical ("Is Cinnamon running??"); } g_signal_emit (manager, cc_wacom_output_manager_signals[MONITORS_CHANGED], 0); } static void muffin_state_changed (gpointer data) { g_return_if_fail (CC_IS_WACOM_OUTPUT_MANAGER (data)); CcWacomOutputManager *manager = CC_WACOM_OUTPUT_MANAGER (data); update_from_muffin (manager); } static void cc_wacom_output_manager_constructed (GObject *object) { G_OBJECT_CLASS (cc_wacom_output_manager_parent_class)->constructed (object); CcWacomOutputManager *manager = CC_WACOM_OUTPUT_MANAGER (object); GError *error = NULL; manager->proxy = meta_dbus_display_config_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, "org.cinnamon.Muffin.DisplayConfig", "/org/cinnamon/Muffin/DisplayConfig", NULL, &error); if (manager->proxy == NULL) { if (error != NULL) { g_critical ("No connection to session bus: (%d) %s", error->code, error->message); return; } } g_signal_connect_object (manager->proxy, "notify::g-name-owner", G_CALLBACK (muffin_state_changed), manager, G_CONNECT_SWAPPED); g_signal_connect_object (META_DBUS_DISPLAY_CONFIG (manager->proxy), "monitors-changed", G_CALLBACK (muffin_state_changed), manager, G_CONNECT_SWAPPED); update_from_muffin (CC_WACOM_OUTPUT_MANAGER (object)); } static void cc_wacom_output_manager_init (CcWacomOutputManager *manage) { } static void cc_wacom_output_manager_finalize (GObject *object) { CcWacomOutputManager *manager = CC_WACOM_OUTPUT_MANAGER (object); if (manager->monitors != NULL) { g_list_free_full (g_steal_pointer (&manager->monitors), (GDestroyNotify) monitor_info_free); } G_OBJECT_CLASS (cc_wacom_output_manager_parent_class)->finalize (object); } static void cc_wacom_output_manager_class_init (CcWacomOutputManagerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->constructed = cc_wacom_output_manager_constructed; object_class->finalize = cc_wacom_output_manager_finalize; cc_wacom_output_manager_signals[MONITORS_CHANGED] = g_signal_new ("monitors-changed", CC_TYPE_WACOM_OUTPUT_MANAGER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } CcWacomOutputManager * cc_wacom_output_manager_get (void) { static CcWacomOutputManager *singleton = NULL; if (singleton == NULL) { singleton = g_object_new (CC_TYPE_WACOM_OUTPUT_MANAGER, NULL); } return singleton; } GList * cc_wacom_output_manager_get_all_monitors (CcWacomOutputManager *manager) { g_return_val_if_fail (CC_IS_WACOM_OUTPUT_MANAGER (manager), NULL); return manager->monitors; } void cc_wacom_output_manager_refresh_monitors (CcWacomOutputManager *manager) { g_return_if_fail (CC_IS_WACOM_OUTPUT_MANAGER (manager)); update_from_muffin (manager); } cinnamon-control-center-6.4.1/panels/wacom/cc-drawing-area.c0000664000175000017500000001300614724311620022664 0ustar fabiofabio/* * Copyright Ā© 2016 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Author: Carlos Garnacho */ #include "config.h" #include #include "cc-drawing-area.h" typedef struct _CcDrawingArea CcDrawingArea; struct _CcDrawingArea { GtkEventBox parent; GdkDevice *current_device; cairo_surface_t *surface; cairo_t *cr; }; G_DEFINE_TYPE (CcDrawingArea, cc_drawing_area, GTK_TYPE_EVENT_BOX) static void ensure_drawing_surface (CcDrawingArea *area, gint width, gint height) { if (!area->surface || cairo_image_surface_get_width (area->surface) != width || cairo_image_surface_get_height (area->surface) != height) { cairo_surface_t *surface; surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); if (area->surface) { cairo_t *cr; cr = cairo_create (surface); cairo_set_source_surface (cr, area->surface, 0, 0); cairo_paint (cr); cairo_surface_destroy (area->surface); cairo_destroy (area->cr); cairo_destroy (cr); } area->surface = surface; area->cr = cairo_create (surface); } } static void cc_drawing_area_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { CcDrawingArea *area = CC_DRAWING_AREA (widget); ensure_drawing_surface (area, allocation->width, allocation->height); GTK_WIDGET_CLASS (cc_drawing_area_parent_class)->size_allocate (widget, allocation); } static void cc_drawing_area_map (GtkWidget *widget) { GtkAllocation allocation; GTK_WIDGET_CLASS (cc_drawing_area_parent_class)->map (widget); gtk_widget_get_allocation (widget, &allocation); ensure_drawing_surface (CC_DRAWING_AREA (widget), allocation.width, allocation.height); } static void cc_drawing_area_unmap (GtkWidget *widget) { CcDrawingArea *area = CC_DRAWING_AREA (widget); if (area->cr) { cairo_destroy (area->cr); area->cr = NULL; } if (area->surface) { cairo_surface_destroy (area->surface); area->surface = NULL; } GTK_WIDGET_CLASS (cc_drawing_area_parent_class)->unmap (widget); } static gboolean cc_drawing_area_draw (GtkWidget *widget, cairo_t *cr) { CcDrawingArea *area = CC_DRAWING_AREA (widget); GtkAllocation allocation; GTK_WIDGET_CLASS (cc_drawing_area_parent_class)->draw (widget, cr); gtk_widget_get_allocation (widget, &allocation); cairo_set_source_rgb (cr, 1, 1, 1); cairo_paint (cr); cairo_set_source_surface (cr, area->surface, 0, 0); cairo_paint (cr); cairo_set_source_rgb (cr, 0.6, 0.6, 0.6); cairo_rectangle (cr, 0, 0, allocation.width, allocation.height); cairo_stroke (cr); return FALSE; } static gboolean cc_drawing_area_event (GtkWidget *widget, GdkEvent *event) { CcDrawingArea *area = CC_DRAWING_AREA (widget); GdkInputSource source; GdkDeviceTool *tool; GdkDevice *device; device = gdk_event_get_source_device (event); if (!device) return GDK_EVENT_PROPAGATE; source = gdk_device_get_source (device); tool = gdk_event_get_device_tool (event); if (source != GDK_SOURCE_PEN && source != GDK_SOURCE_ERASER) return GDK_EVENT_PROPAGATE; if (area->current_device && area->current_device != device) return GDK_EVENT_PROPAGATE; if (event->type == GDK_BUTTON_PRESS && event->button.button == 1 && !area->current_device) { area->current_device = device; } else if (event->type == GDK_BUTTON_RELEASE && event->button.button == 1 && area->current_device) { cairo_new_path (area->cr); area->current_device = NULL; } else if (event->type == GDK_MOTION_NOTIFY && event->motion.state & GDK_BUTTON1_MASK) { gdouble x, y, pressure; gdk_event_get_coords (event, &x, &y); gdk_event_get_axis (event, GDK_AXIS_PRESSURE, &pressure); if (gdk_device_tool_get_tool_type (tool) == GDK_DEVICE_TOOL_TYPE_ERASER) { cairo_set_line_width (area->cr, 10 * pressure); cairo_set_operator (area->cr, CAIRO_OPERATOR_DEST_OUT); } else { cairo_set_line_width (area->cr, 4 * pressure); cairo_set_operator (area->cr, CAIRO_OPERATOR_SATURATE); } cairo_set_source_rgba (area->cr, 0, 0, 0, pressure); cairo_line_to (area->cr, x, y); cairo_stroke (area->cr); cairo_move_to (area->cr, x, y); gtk_widget_queue_draw (widget); return GDK_EVENT_STOP; } return GDK_EVENT_PROPAGATE; } static void cc_drawing_area_class_init (CcDrawingAreaClass *klass) { GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); widget_class->size_allocate = cc_drawing_area_size_allocate; widget_class->draw = cc_drawing_area_draw; widget_class->event = cc_drawing_area_event; widget_class->map = cc_drawing_area_map; widget_class->unmap = cc_drawing_area_unmap; } static void cc_drawing_area_init (CcDrawingArea *area) { gtk_event_box_set_above_child (GTK_EVENT_BOX (area), TRUE); gtk_widget_add_events (GTK_WIDGET (area), GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK); } GtkWidget * cc_drawing_area_new (void) { return g_object_new (CC_TYPE_DRAWING_AREA, NULL); } cinnamon-control-center-6.4.1/panels/wacom/wacom-stylus-airbrush.svg0000664000175000017500000000777214724311620024616 0ustar fabiofabio image/svg+xml cinnamon-control-center-6.4.1/panels/wacom/muffin-display-config.xml0000664000175000017500000004072714724311620024522 0ustar fabiofabio cinnamon-control-center-6.4.1/panels/wacom/cc-wacom-stylus-page.h0000664000175000017500000000240214724311620023707 0ustar fabiofabio/* * Copyright Ā© 2011 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Authors: Peter Hutterer * Bastien Nocera */ #pragma once #include #include "cc-wacom-tool.h" G_BEGIN_DECLS #define CC_TYPE_WACOM_STYLUS_PAGE (cc_wacom_stylus_page_get_type ()) G_DECLARE_FINAL_TYPE (CcWacomStylusPage, cc_wacom_stylus_page, CC, WACOM_STYLUS_PAGE, GtkBox) GtkWidget * cc_wacom_stylus_page_new (CcWacomTool *stylus); CcWacomTool * cc_wacom_stylus_page_get_tool (CcWacomStylusPage *page); void cc_wacom_stylus_page_set_navigation (CcWacomStylusPage *page, GtkNotebook *notebook); G_END_DECLS cinnamon-control-center-6.4.1/panels/wacom/cc-tablet-tool-map.h0000664000175000017500000000271214724311620023333 0ustar fabiofabio/* * Copyright Ā© 2016 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Authors: Carlos Garnacho * */ #pragma once #include "config.h" #include #include "cc-wacom-device.h" #include "cc-wacom-tool.h" G_BEGIN_DECLS #define CC_TYPE_TABLET_TOOL_MAP (cc_tablet_tool_map_get_type ()) G_DECLARE_FINAL_TYPE (CcTabletToolMap, cc_tablet_tool_map, CC, TABLET_TOOL_MAP, GObject) CcTabletToolMap * cc_tablet_tool_map_new (void); GList * cc_tablet_tool_map_list_tools (CcTabletToolMap *map, CcWacomDevice *device); CcWacomTool * cc_tablet_tool_map_lookup_tool (CcTabletToolMap *map, CcWacomDevice *device, guint64 serial); void cc_tablet_tool_map_add_relation (CcTabletToolMap *map, CcWacomDevice *device, CcWacomTool *tool); G_END_DECLS cinnamon-control-center-6.4.1/panels/wacom/cc-wacom-nav-button.c0000664000175000017500000001573514724311620023537 0ustar fabiofabio/* * Copyright Ā© 2011 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Authors: Bastien Nocera * */ #include #include #include #include "cc-wacom-nav-button.h" struct _CcWacomNavButton { GtkBox parent_instance; GtkNotebook *notebook; GtkWidget *label; GtkWidget *prev; GtkWidget *next; guint page_added_id; guint page_removed_id; guint page_switched_id; gboolean ignore_first_page; }; G_DEFINE_TYPE (CcWacomNavButton, cc_wacom_nav_button, GTK_TYPE_BOX) enum { PROP_0, PROP_NOTEBOOK, PROP_IGNORE_FIRST }; static void cc_wacom_nav_button_update (CcWacomNavButton *nav) { int num_pages; int current_page; char *text; if (nav->notebook == NULL) { gtk_widget_hide (GTK_WIDGET (nav)); return; } num_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (nav->notebook)); if (num_pages == 0) return; if (nav->ignore_first_page && num_pages == 1) return; if (nav->ignore_first_page) num_pages--; g_assert (num_pages >= 1); gtk_revealer_set_reveal_child (GTK_REVEALER (gtk_widget_get_parent (GTK_WIDGET (nav))), num_pages > 1); current_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (nav->notebook)); if (current_page < 0) return; if (nav->ignore_first_page) current_page--; gtk_widget_set_sensitive (nav->prev, current_page == 0 ? FALSE : TRUE); gtk_widget_set_sensitive (nav->next, current_page + 1 == num_pages ? FALSE : TRUE); text = g_strdup_printf (_("%d of %d"), current_page + 1, num_pages); gtk_label_set_text (GTK_LABEL (nav->label), text); } static void pages_changed (GtkNotebook *notebook, GtkWidget *child, guint page_num, CcWacomNavButton *nav) { cc_wacom_nav_button_update (nav); } static void page_switched (GtkNotebook *notebook, GParamSpec *pspec, CcWacomNavButton *nav) { cc_wacom_nav_button_update (nav); } static void next_clicked (GtkButton *button, CcWacomNavButton *nav) { int current_page; current_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (nav->notebook)); current_page++; gtk_notebook_set_current_page (GTK_NOTEBOOK (nav->notebook), current_page); } static void prev_clicked (GtkButton *button, CcWacomNavButton *nav) { int current_page; current_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (nav->notebook)); current_page--; gtk_notebook_set_current_page (GTK_NOTEBOOK (nav->notebook), current_page--); } static void cc_wacom_nav_button_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { CcWacomNavButton *nav = CC_WACOM_NAV_BUTTON (object); switch (property_id) { case PROP_NOTEBOOK: if (nav->notebook) { g_signal_handler_disconnect (nav->notebook, nav->page_added_id); g_signal_handler_disconnect (nav->notebook, nav->page_removed_id); g_signal_handler_disconnect (nav->notebook, nav->page_switched_id); } g_clear_object (&nav->notebook); nav->notebook = g_value_dup_object (value); nav->page_added_id = g_signal_connect (G_OBJECT (nav->notebook), "page-added", G_CALLBACK (pages_changed), nav); nav->page_removed_id = g_signal_connect (G_OBJECT (nav->notebook), "page-removed", G_CALLBACK (pages_changed), nav); nav->page_switched_id = g_signal_connect (G_OBJECT (nav->notebook), "notify::page", G_CALLBACK (page_switched), nav); cc_wacom_nav_button_update (nav); break; case PROP_IGNORE_FIRST: nav->ignore_first_page = g_value_get_boolean (value); cc_wacom_nav_button_update (nav); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void cc_wacom_nav_button_dispose (GObject *object) { CcWacomNavButton *self = CC_WACOM_NAV_BUTTON (object); if (self->notebook) { g_signal_handler_disconnect (self->notebook, self->page_added_id); self->page_added_id = 0; g_signal_handler_disconnect (self->notebook, self->page_removed_id); self->page_removed_id = 0; g_signal_handler_disconnect (self->notebook, self->page_switched_id); self->page_switched_id = 0; g_clear_object (&self->notebook); } G_OBJECT_CLASS (cc_wacom_nav_button_parent_class)->dispose (object); } static void cc_wacom_nav_button_class_init (CcWacomNavButtonClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->set_property = cc_wacom_nav_button_set_property; object_class->dispose = cc_wacom_nav_button_dispose; g_object_class_install_property (object_class, PROP_NOTEBOOK, g_param_spec_object ("notebook", "notebook", "notebook", GTK_TYPE_NOTEBOOK, G_PARAM_WRITABLE)); g_object_class_install_property (object_class, PROP_IGNORE_FIRST, g_param_spec_boolean ("ignore-first", "ignore-first", "ignore-first", FALSE, G_PARAM_WRITABLE)); } static void cc_wacom_nav_button_init (CcWacomNavButton *self) { GtkStyleContext *context; GtkWidget *image, *box; /* Label */ self->label = gtk_label_new (NULL); gtk_style_context_add_class (gtk_widget_get_style_context (self->label), "dim-label"); gtk_box_pack_start (GTK_BOX (self), self->label, FALSE, FALSE, 8); box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); context = gtk_widget_get_style_context (GTK_WIDGET (box)); gtk_style_context_add_class (context, GTK_STYLE_CLASS_LINKED); gtk_box_pack_start (GTK_BOX (self), box, FALSE, FALSE, 0); /* Prev button */ self->prev = gtk_button_new (); image = gtk_image_new_from_icon_name ("go-previous-symbolic", GTK_ICON_SIZE_MENU); gtk_container_add (GTK_CONTAINER (self->prev), image); g_signal_connect (G_OBJECT (self->prev), "clicked", G_CALLBACK (prev_clicked), self); gtk_widget_set_valign (self->prev, GTK_ALIGN_CENTER); /* Next button */ self->next = gtk_button_new (); image = gtk_image_new_from_icon_name ("go-next-symbolic", GTK_ICON_SIZE_MENU); gtk_container_add (GTK_CONTAINER (self->next), image); g_signal_connect (G_OBJECT (self->next), "clicked", G_CALLBACK (next_clicked), self); gtk_widget_set_valign (self->next, GTK_ALIGN_CENTER); gtk_box_pack_start (GTK_BOX (box), self->prev, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (box), self->next, FALSE, FALSE, 0); gtk_widget_show (self->label); gtk_widget_show_all (box); } GtkWidget * cc_wacom_nav_button_new (void) { return GTK_WIDGET (g_object_new (CC_TYPE_WACOM_NAV_BUTTON, NULL)); } cinnamon-control-center-6.4.1/panels/wacom/wacom-stylus.svg0000664000175000017500000001231014724311620022761 0ustar fabiofabio image/svg+xml cinnamon-control-center-6.4.1/panels/wacom/cc-wacom-mapping-panel.h0000664000175000017500000000224714724311620024171 0ustar fabiofabio/* * Copyright Ā© 2012 Wacom. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Authors: Jason Gerecke * */ #pragma once #include #include "cc-wacom-device.h" G_BEGIN_DECLS #define CC_TYPE_WACOM_MAPPING_PANEL (cc_wacom_mapping_panel_get_type ()) G_DECLARE_FINAL_TYPE (CcWacomMappingPanel, cc_wacom_mapping_panel, CC, WACOM_MAPPING_PANEL, GtkBox) GtkWidget * cc_wacom_mapping_panel_new (void); void cc_wacom_mapping_panel_set_device (CcWacomMappingPanel *self, CcWacomDevice *device); G_END_DECLS cinnamon-control-center-6.4.1/panels/wacom/wacom-stylus-no-eraser.svg0000664000175000017500000001142614724311620024661 0ustar fabiofabio image/svg+xml cinnamon-control-center-6.4.1/panels/wacom/wacom-module.c0000664000175000017500000000203114724311620022325 0ustar fabiofabio/* * Copyright Ā© Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Author: Peter Hutterer * */ #include #include "cc-wacom-panel.h" #include void g_io_module_load (GIOModule *module) { /* register the panel */ cc_wacom_panel_register (module); } void g_io_module_unload (GIOModule *module) { } cinnamon-control-center-6.4.1/panels/wacom/wacom-tablet-cintiq.svg0000664000175000017500000000600314724311620024160 0ustar fabiofabio image/svg+xml cinnamon-control-center-6.4.1/panels/color/0000775000175000017500000000000014724311620017604 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/color/meson.build0000664000175000017500000000070514724311620021750 0ustar fabiofabiosubdir('icons') panel_color_sources = [ 'cc-color-panel.c', 'color-module.c', ] panel_color = shared_library('color', panel_color_sources, include_directories: rootInclude, link_with: [ libcinnamon_control_center, ], dependencies: [ gtk, colord ], install: true, install_dir: panels_dir ) install_data('color.ui', install_dir: ui_dir, ) install_data( 'cinnamon-color-panel.desktop', install_dir: desktop_dir ) cinnamon-control-center-6.4.1/panels/color/icons/0000775000175000017500000000000014724311620020717 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/color/icons/scalable/0000775000175000017500000000000014724311620022465 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/color/icons/scalable/cinnamon-preferences-color.svg0000664000175000017500000030762514724311620030440 0ustar fabiofabio image/svg+xml Lapo Calamandrei keyboard keys configure cinnamon-control-center-6.4.1/panels/color/icons/meson.build0000664000175000017500000000044514724311620023064 0ustar fabiofabio color_icon_sizes = [ '16x16', '22x22', '24x24', '32x32', '48x48', '64x64', '256x256', 'scalable', ] foreach size : color_icon_sizes install_subdir(size, strip_directory: true, install_dir: get_option('datadir') / 'icons' / 'hicolor' / size / 'apps', ) endforeach cinnamon-control-center-6.4.1/panels/color/icons/24x24/0000775000175000017500000000000014724311620021502 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/color/icons/24x24/cinnamon-preferences-color.png0000664000175000017500000000303214724311620027423 0ustar fabiofabio‰PNG  IHDRąw=ųsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›ī<tEXtAuthorLapo Calamandreiߑ*tIDATH‰­–ilTUĒ’÷½éėĢōĶŅ™é0t„Ą@­,¶…¶@)ZC!F؂ņĮ”Ååƒ1ā—Œ[Š(hĄ(EL@Kk …RZ”„tX¦„t™„Š}”3oŽ›yó®PE”DOr“{“sĪ/g¹÷PJ1ŽURRĀ<Ž>„„RŠG‰ÓéŌĘńÜ.…ŅU Ų«½żVnnq葆˜ń(©yv³Ž`|!';7Ī 7®$żĒ汚`eÕev6¢¬R@›j«/œ-((ą¾5/k¾‘Ü~*ó'8SS%õū']»ęžæ kI4E>“lŁóž‡ŹŖĖģ¬L;¬ ¶h 0*KR(J)\&“9+#õfÜØwtÉåøŚnõöv7†8Ō±jFÆ3p>æ—@‰LY¾¼øė^€źŽQVY­öčfh©VFŲ–‡ž¾ŽEK‰ŒīD‚•HK}GĆó|ŽŻfgÕ5pŒ¢4AlmmY ąĆ{}ŽW“)•ihŅ7K@ö.A;@ų8d”„5"*ŌAÆ3Ą’$3õŅԌ¬G”FŠ?Ų/wzümcSt ¶śĀYI Eƶl0“³”ų/@ś¶rĶē(Ö J“‡~DĶšz ɗa‰É†*” 1(„’ō[ķC„põōõRnÅNµą' ržk؄iI“ŽŠÄ2&Ä=fńŪŠįiE”eÉņłcżƒ-))ÓéŌzo¶½BšLęÄɓ“øXK*HŒJW@Q%IN"GÜ&X¹|ÄÄpLX”,¼V»Åu¹ŃŚŅ|źtFF®|·Č÷…Qo\ćHwhøśČĒæDĄå„ŖĢgĮŲż ĮĀA#Äx±$ Ż£aźŽ `Rų,Lr‘&'g%ŖŖNm¼Õ‰šśŻ6=YUv;'+OĒīų ŅĮƒ¢×ƒ˜Lwöv†uč[œ —Õ‹!\ÄPÄ ōBˆŽ 'lĀÓŚ·ń«óČš«ė6š)„Š (!?·“ŗ×8¶¾©‰[°r]¢EŠ“ž‰óœeįm²bņŒBÄĒ®D‚õŗéļ0p6¤ń9pč ‘Ā墲²\ Ē3/ÖJ)œN§–Õ²[X…n3™Ģ1Ži35<ÆĆÉĆUh8u „!ŠŪĢ8-°(X8Ć! Š…3ē°  —źCD ‡Øų ²““™RŖÜw“wļŽ­˜h«šį˜™Mön’:#‚”ÄDŌµõcaÖTÄYķPŠ ÅĘ„SŠķ¹ŖŌżq®±āäŁõ­~æ÷jmķ0„Ty Mććć%@qŲ¬vŁs ¢ "0DīŅl4uŻÉ³ĖķCĮĢ„(„°ŒĆµ>¤„¦3,«JĪČøråܹĮæ?ą8¶P£Ö*¾–.t{z˜> ėK^Į‚åy(GĢ›fĘę„éHµĘĮŪ'`@TA£V³…D){ī{‹¢TžkŠby ﯃%ÉÆ·“nódö“‰øÖÖ‹ŁŽ‰€Æ½•¾”7 ‰vØ9f³…õz}O(żW@Ź”Oū{’$‰}ż}²pEˆJaÉ?2225v w ōņg„ąbcƒčnq»ėźÓ4 ›`N`Æ·¶°WŻīЇF°ś¹Õū÷ļŸźnn^ŪåóŻ(-=[WT”­! ®āāl¼¼lęgNÄ÷ūNÓÕÕÆe:2/ņ3^'ĖÕr½ĀÓ|Ć=0®õ»½{¾r?*öōtÓ#G‘>ŻńŃGNŽy<¶Ŗˆ’$TµÕē÷ĻóbH•—WžŁŽœœ<<>Ūǘ0Óóóu(.f’שāæČŸ ß*¢Āø“IEND®B`‚cinnamon-control-center-6.4.1/panels/color/icons/48x48/0000775000175000017500000000000014724311620021516 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/color/icons/48x48/cinnamon-preferences-color.png0000664000175000017500000001040114724311620027435 0ustar fabiofabio‰PNG  IHDR00Wł‡sBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›ī<tEXtAuthorLapo Calamandreiߑ*[IDAThÕZip\Օžī[ŗūõŽ­}õ" ŁĘ6¶…ķ ±1`/“!QĄ1–!3@ •Ź`&• ©„P.Ā–±„`"Ę`–/ņ*[¶lٲdk—ZźV«„VoÆūõė·Üł!Y‹µŲ&ęǜŖWÕõ޹ēœļŽ{¶{›PJń’™øoJpCćÉU„p¦§éśsóf-ųĖ7”‡|+ŠŠpf)xģ-ĢafYžIŒĒ×.^xƞ«­‹¹Śy#73_0%99Ył‚Į`|młņåWÅ)„Wõ©;W{gckCŒRJć¾Ē©č{”RJicK}b÷Ż÷`hÕÆÖsÕœkŖ;‰†©*7Ń`=Oƒõ,U“ 4 ѓgŽŸ+++㯦¾«ŗ…Ī«-”ŠKlV;¤Ą UŖA ülV!3žü·'ēBČÕŅ9åžll<•«2쳄’» A§¢*Ūž~:·ø¬u"~Ź0?qŚŻ,hJģ£į÷©Ų§°čøiL~^ī£åå及._]}`† ŗ†aų»”ėE”Ņ÷†žįęÅ7w}-Ć=o·XĢpgs)%•‰…ˆńȋ MuMJJłåus} @@i¹Óī2(± ŗ4 Y ©čv¤»ļā{z{¾wźŌ)nrōÄįU,˼ 3ܼ —nWš`4 čņv>ŃģĖ#„ÜE' —SGŠõ™é¹ß{ ĀĄž·ŲHDcįėzūżļŌ7Sjźį…s®’¤ŖŖJ°ŚMy‚ÉŒÄĄN0\.@øA|T…"~ ‹s#š1éŅ Bˆ÷ȱ·³,ū¦ĮĄ» r§[ÓÓ2@VĻA¦2fL›Ķł{żkoZw“@ģŠ‚€¦©v.1łķÕ ÖL°„«a»ń)8f^g‰‰QK§·}[Cć™}i1<‘!¼¦x@ė(A€®vƒ‹Å¦>t’†>÷³Ē¾ –YU2ó‹ÓįFLmA­ų'ō¦ö#©÷c‰że”خŒ^ĘJ‰SJõ‹mœ„“"&FŸ5Ļ\΁@ÅԚ­POžģģu°Ü² sJ®ż=· „‚«œVw TUüće©AP]‚Ķbį³2ŅŸ––”ęēD½ÕŃ_Į'ļ0øKpČ4ÜOOŽP”Č8¹@SF!US?‰DĆ šŲ¢£‘AoŪłƒõŠ¼Œģōl~Fa1c·9LšźĆ(·CŗŅ—3+)*e ó ņ6> j’°ńfø± §Ē—¬onŽg±XbĶž%̟½Ø:„ČńxBwĆĆļ‰5°f”B©~©’¹&š€ÕbUŗ'•GÕnŲm˜Ģ@mlڤ÷L6X" ó Ž„ &DłĖ;Fe2™—ŹzJI½ŲšĘŁ’•`ņŹ@`rŽaŅŗŖ!æū}čm Œ„±°é`ø\0\6ėa, Œ’ęĆ±čæ Øœ™˜˜ 0ąįąf!Ū° ĶmĶrk{Ē» ¢ų+++'^Ņ˚b·ˆbLOŹų[ž,óI!Ø{ †dpi ¬` ca \Ąē”!±I=8n<‰ĶD©łQˆqĮž>śÉĒ»>¤¢šlū\€²²²„œRžomo޳³×½ęŽńŹv{ōX“c[AˆyI<Ś”/ ė˜L0Ä0Ž#ǰ 9†[PS{\nļō¼å ų:źėėթ컬Rbé¢^QU„­  V¾&­hÄx“0»”ź@mŻ Öo'#,ä /ulp į`bŅĮ€žnfó0Ēņŗ½ Gŗ·nżėšHōN5ū— 1ńę×ŗ½]ŗLYšk6¼` €ąĻÜ„–‚Ąo4^Ģć@Ą#ę[ŽThimŅžžmDŗźėė'uŽa)“5455‡ u02»VÓŌŁf³U5 6Ż!ŲmvčŽ(ū*O” ōY&čłxŗūÄ€Į,Ėcpqó ĄėėN‚z4b–kTe‡¦-wŽygēeØ®9²ša˜ēuŖĻOOĖDš+ŻdµŲĄ²,€†ĆŠ› ÄĘC9ų[čžŗ,"ø“ź"”Öóœ«0Ϲ,Œšõt£¶®V”‰VINżōŽõ÷V Ø:yh īƒiÓ…ĢŒl¢wu!łśėPvķĒĮäåE¹§7P±{÷įwzC6“®Oœ8”ŒĖ„ęŚkÆåžzźńUY9ŁM¦ļp<Ē„9ŻŌåvŻ®4Ęfµc ĀīæļC48a§‡Ż‹:\+Üī‰™ŁĄaÕ¢l¤ŪGĀčéńѾ¾ŽdgW'£ėŗKG›š›·W8±_“"ż”ŅP}}½z”Ę4B˜ņņrŅŲŲhŗõŽ;ŠW,»ł^ĮbųYŁ‚% £³xū·ļ!%„`sYq±ŽE%ō–a0wVō‹Ti:E$”@0pŲøb49Š}•{©ßēµ²źČ'ĶĶm²ŖŠ¼¢DKKK“ōāŚhŅ–r!!‰3gĪŌŻqūņ…¹…šÅla¶żńC$¢ @2!Ćd6+9ŻŠŌ§×tńøĮ,Œį‹Ėƒ>%„T||¬nž†¢™Åz,]ŠpźĢÓsęĢŃ***(zśōé gśŅż„tĒgŪ@)]2sF1æūAųŚzFŒ%Hq J„ģéŁčŻŠ‘ĒDnŚ RÄ$Ŗ6b“o@ĀŽŗę^;5Me’ōĮõ:„TŸģHå²TVVr ažT¶h‰„óœ5•µćx’ń$¢1LŲ‹x4>!!Ėļü."²Žh<…DR…ŖR¤qIE(&#•°ra8v¼Z ’P°«ÖĢĢ,øŻnƂ²łB¦“ń’8ŽŪtMI©ĶÓŌ…–ŗ6$D Rbl)ąĢpāžgļFAIĀ¢ QReĀ ōG$Dā2$YEXL!Ļ-ą¾eӑfé(€hBŖQ“śE“õŠø¾l±ąv9Ÿ+++cæ6€Šó†äfgåāą§G†ß‹aāŠJ”,(½’¾V·‘hĪÉW=Ż! €Ą©øołtĢĪ·C§įø‚”:²„ö×÷”°`ŒFcŚmwܶ|ŖĆą)J×äēMću]Gćɦ1ßn;VžųV|’'kŃšŃÆöģT;:ŚŌL—łāo˜²\f“w“iŸ}ž‰ÖŽÖ¤’Ӓ<¬¹>™Ž±ŻZ“/UÓqMÉ,Ža³ž ¼¼|R;§<™cöīœģcGC'’  Ė`Ɯéųöź0gÉ,ˆqŸł© G 9¹Ólµžų:޵:­F„bc뫉‡EąŃČ}}ż[>ųŻS§OƼu„šōŗR4tEqš\Zż"RŖŽ戢™Å܉“5_>E‘‹­+"šˆ ĻÜ…Ņ…%0™M `’}É.o¼Žž·?ܾ㭲„óū{?„龞88–€R@ÕtL˲<]üĪ/ž÷ošVņĢ­·>ž·mżu~A–”-5=r{’І&_ ”N§ ŗ¦f™33„¾‰Āé%ī¬Čg ēėĖēĻ]@$)–ö&ŚŽŽ–GBšæ'šŽ®ż‡žīļķm„‰D¼©Üųī·śĆįPīāYŁŲSć#iÉģl„Ā!PF:zśggŚŌ/žuóĖ?žųŪ‘Hō©.ē ›Ķn˜=kŽ0}ś Ęn³ćč±*¤Rj ””Ē`ŗæ2J2łŸm­­Žó +Åb‡<ŽŹƒUĒvG%©‡Šā˜ŗdĖŪo}ŃÖŽzߊ²łÜļŽ?mØv`ĮвihjŖÕĀ‘ŲȲˆĮ²€B^(//’MqqńjŸ×ūCAnS5Õ®ėzmŻŁóÆŗŒĘČDĘ_Ą† !ß[»~½»½„E€Ä¤l6&šŸŸŸ:2A]¢$å×ėėėī.[“˜ūÖµ98\甕f!Ć)ąćŗ3JSKĖv›Ķ=vč·DŁ^^^žQww·Įét¦uõ÷ ĆDŽ;–ųzCĀ !A UlS4=ņČ'ž¼åõ~ŸĻkyhͼaƛÆ·²,œ>S_]TPšL׊O‰āŅI’”R$ Ö$Sž’€,%’ėpÕ”ųÜéøµ¬Ė`Aq>(u{{>„Æ¢¢ā’rFéœņ&žŖ_<÷÷GŽ"ūóŽŽvĖc’¼Šéé€Ļļ“<¼O&£—2źJčŖßŌoŚ“I•ņc_ķŁ™0 #Ųõ՗IO§gs 鸜ćĀ+”oäæšū?žīI–a_(ėļķ}gOåį7­Ćł}ūö}Ķ#‰é7n456zŅbz\„¢:{öģ„ĪūŠ’£_ 6ē;IEND®B`‚cinnamon-control-center-6.4.1/panels/color/icons/64x64/0000775000175000017500000000000014724311620021512 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/color/icons/64x64/cinnamon-preferences-color.png0000664000175000017500000001337314724311620027444 0ustar fabiofabio‰PNG  IHDR@@ŖiqŽsRGB®ĪébKGD’’’ ½§“ pHYs × ×B(›xtIMEŚ8ž@ōš{IDATxŚķZyx\Õu’ŻūŽ›}$Ķh³ĘŚlI–%ŪņĢ’°Ä†“|MSˆ[NCŚ“Mi¶†%$$ IŪŠ8MI Ņ4ā.)H$fńŠ7Ł–wI¶µYŅģófŽzļéo$ېҚĘn>Źł>ż”'ŻūŽłs~g¹xGŽ‘wä9288ié€Õ«ÆF{{ū’ņłÜ#¶m“ćŲ”LNžtźyccćŪ_łT*µŹq2 “J†I®ėҦ͛o;w”’’…õ‹ÅbڲL™xŽ2'H¦iŹL&cØiœ¹ˆæ­•ĻdŅ·m› “hxg- ļØ$Ć$r‡^yåÕÆĻnė ½Ķ­ÆgLӔ™Ń„“»@'wRĆkÉ4M™J§MÕ3;»Ļ«œ——%““H&“æ­ŖZĮĻJ'o¢ŠX·ągŃHÄ’äSOßPSüʐLN¼„—ŌŌŌĀļ÷DdåžGŒŒœ03AJI= \ß»mW0¾x>ūąäɓČ岊®ž3 ƒō¢~,N~k```Ł’d½¢šHhĢLƅ¢zŹ3\¬ō= ųX}}ŻE-ķķÕµ.WßlÆįįóÓéԚB”Š_,)Imų§oŻķ™ß}nĖēóėĒ!Ć4É4M²m›,Ė"]× “³īūߋ¼~ĶŠŠR©äJ˲Ød84ü(¹”Ü{źgä5P©¤“e™ōČcė?ѳdytjżöķŪ›7椄RÉ;t½¶,‹lŪ&Ó4É0L²,‹Ž|€æaŊsŠ¢\źŗ.Šū~ŒĀ+÷ĮĪO@*>ØŖ‰Užōū«ž 011ńx`Z¦¦&ØŖv5c Nį9ų1p-E› EK€k3 Ŗ`ēŸØknēe™\.0³”š€eMØétś.\fG£_S­Š‘%+ż©G0yBĮwˆGĒsź9@wēœ_ÖÜ‚ĀČü];ō_¬m–¦ ‹żé7ޘ?~üĦ֩Ŗr”$‚kīW` Ąˆƒ+!sĘjŖ« ōūFĘR”LNŽ“hŃ„N$ž g*×F_ę»ģGĆ+ńäč"ģĢß EŃĄ9§L6ÓW—h® ų\åœ@D(ęX ė·Ą8 a½ģw"wG% Oü)ģRŒ+4sfā®t:}xժ뢌±% ĀŲ†r˜Ryć2 s7BįPgM}}4NķŒD¢÷s®’åŲ:łe<>4‡Ż{@Į1D"104G®ēœķŻ×÷‹™‰¹Ņ/Ļ€³"łóŚųÖm{W}ČÆū üG~Uń”‘\X< ߊ/#tÅ砐CB©ŖŖā ¹£ó )Yõ©7—׌ŽU aĄ²L;j ó³ż™±·š÷Š€Ŗ)ąÜ[č:g)Ž[’\iāź÷_»2—ĻĢźéŃ懎Š9 }}żŅqœ Œł–ü!ĒS€1@a ¾ŖˆTT€m¾¹µĮĪ3Šėŗ` ‘@§ĮNSXPDž§łż~ŸåęŲĻĘ>„AēAÄ*Ä pęķC€ćŲh ]b.ŽŽŚ·’$ō³Qž¬ " ¹o`E«`ū¢䙓Eg€3…3ų4Įā č÷-‡3~`ŚÜD%Oe’  0éiD–ē’Œ!oŸĄ „ōĆšCį ĮĒ+ĖĖ%„ķC[Å5`Œ±—_Żø¾¹„Ńq-2Īi!ÄCSSĖ,ĖJĮ¶Čæņ+p\€"õS’*oŖr ¤ĘwWĀņRWźĮ”Z(Ś (jøš€¢Ōƒ«q01į„ō"R”jŒ3P@ĪP†ķ8čŽÜA„ÓéŅ_Ž|ū³RR6eŒ8ē„ĪrŸg ,|łĶp*[ ‰ƒŹŹ³Óā[e„`8ė©?ƒ(L‚k €)å rüpÓĄŌ™°DÆå>‡P( Eå`^ŗc€ōāœB +‚y±›ĄŲ+ÆnüvūģYŽ"7>0Bg«Ė[®œ2™ĢH h°Žn`īVĆ €³ÓøĢüQI0X%ųļ“Bq{ĮłéĮH Ž…mš- ƒ«€C9H0œV Ć,aa諘¾Œ&&'s=K–ÆloiŸ˜°G‡‡wĖóāw}õ+¹ˆ˜æó*ȹ€4Śˆ,Xų#`DPą—Yø[öž"ĄÓ²@8"ĘĮ}yp`ŒĆĒcąŠ@å Ip]‰.@Sä*{lżæ}yv[«m2‘~+Ź’Æ<FFG­ŽWß ‰_{1‚Ö8T>ełČ:Jl—ZüTØy©`wØ”€ ĪY$OqKf@$! × āŹś' p»vļ~qÕu¾½®¦v8k–&ķßCē€ćĒ£„„eś÷t: UĀ.¢pĻ2„T‚©g4ķŗS_&$P ž«Ģ=õŪYÜhŠŹĄĖ\2ķöR ä$a]\Y÷$üjŅ™“Ž8³ńI'#>Eź¶8wŻąTüŹ+/j”Pąr¹ģƅBžØ®( V10-„ČŸæ +Ü—r:Åk1ā±x$™LöŽŪ84|ā{[vīŗžÖĻ}6w|ń¦_æLNN¬ ŸPUõrĪē Ŗ V¶˜ČfĮ+*Ą8ƒ¾ž#ŠĘ÷BåÜ#FvŠ…‚Yų–L°Œp‚ęÄ@eå]W ą6撦o`(99D“*8AäLc`¦eA× 'ĘĒļ_¼xécæŅéŌ§żžĄMÓDDRӘĢēa½ų"œŽ^ȃ!Ą, Œ1°pØØO4C„”u$įg œJ ¦!X&Ą `Œ°Ł×ˆpPWl‘ƒRHX®‹é",Y…”u {AAcŌ:ŠšęŠ,®y?Āj ‚ŁÄ9gł\Žł«E=‹Öœć㨯Ÿdjņŗ` ų/>Ÿ?*„ Ņ4f<õŒ‡‚ܶ žÖV(~æēڌyłš,8÷˜‚ ˆö4ŌF¾P-x™ \ 8]@6įljp4ĶĖ‹®tQpR/–0¦AŒ¼½`ŗy8dx!Ā*s¾n§‘7rh ]€‰æĄEµ«!™Cš¦±L6mō÷żōE^ņŻ©s‡įįį7÷€L&½6Ž|BJIä÷³Ņŗu(­Y­T‚ZVZ©ÆŸ.R¦ŅˆĄėź^WßH²Ņ9Ūźu(Ŗ×żŲ•@’10ĄJĀAŚ“0¤ƅŸś“rųŲŅ€)ņe°§Ų•`Š ‘$ƒėŗŠd×4ż-V&ž.,RU•ķ?Š÷ļ‹.¾€ųoC X,W/æŒüĶ7Ć_,BółĄĖ–&)”44 ĢVg€Ąėź~õóhŠ| —ąTUPŌĄ+×V@—Żqa’ē †ČĮ•Ųė¾Ģ‘&Jnö ąĄ„éēTN®ćĀ/bųhŪwŠSó>˜f ÕÕ5‹/ß½k‡{śzõ ˆCinon†ģķiŚt’V„ˆ @ĀRśŻśõjœ(…QÜ~ *k{Į+zĮƒż`§ŅĘwłÆv?ćÆD€+]Ģō·¢>4 ‚+_©¾,€7 “ÉÜQ]]}—Æ„…jž}–Y›6”ų•Æ€ķß-Ą„œnŽNÓŅ«i§ž•=A•'ąĒ¾Ŗ6Œką+»®Ć8DɆRŗŠy eA”Żp}Ļž“Óś ‚$é…ĆnKå ˜Ž‰™¾łø~ĪŻ˜æ$„d›6mz¤£k®FÄé”žķæļā /¼æ¦¦v6bĮ ³vļ†ńŠCpžy¾Š ؑēåį#‹ÅE)s‚Äøʆx'ŅĮā•ļ’éb0‡[Y––|*Ą`¹6 ‘ƒī†[õ,ą›c CęąHÓSS]5!gCø„eńßNJ7”£ņ"X²DŲńĒF[’ų]ė}|s¼Ŗr²XTʎÜģž·\pŁ{µm/żĀ÷čśõŗų¢ æT[SŪŹ9'( c>¬ķŪįīŽ Ń×K&Aŗƒ%ąõuŲ0!q(ڈ8gP5P’µŠo”­£ AŸ ĪŻvAÄ \Ą•ÜŠ«hj݃¼;ŽQ£¶Ōą•ˆŖõØÖšŃ^Œ–šĢ½Ž“ !Hø.łÉs?½ļKw~ķ¹®ĪNG2wR‘ČīŚ9d'ßÜ.æürlŲ°Mõ¬¶„ĘæsŪFß]k¾~Ł•+V|“qfćū£ŃØĘ9÷l Ŗ ŠƽóÄ(±īė߇«[PÅK“ŠŖ@ hH+ŒU5€‹W"ƀ+å4Ćțśø _1 •Aßt¬IHrˆ1ʄė"M‹žĮŸ>żĢ3O~ē»ėvĢÓįJ‰”m»Ł¼•¶FŽōÓ¼yóŠ××wv•`żĀ9¬V©ōOžLĒGż_žź__|ÉEĖÆhhH,­ˆFŪb±X¦iŽįÉŠ8»ūqƒ”rÖ8ó’±pØzd äU’ŠŃŁ‚@¹’÷*KšB ĀDĪÄĒŽŪŒ–š Ą¶-šL&“ŁlvphxøwƆ—7®}ą_vĶéč 0P„y(\§āøµ÷Ą żZš”šźŁ¬®&ʵPĄ/ø8zÜo–ŠĮ±į½‘H$”Må°öóßFĄDEČ8GˆYØ ©p%Aøŗéž:;aŽģ]U82%?ߛ„½ū¢K¾ŃwģH¬«ķ­ß)xK Ž GĀb?ś×ŸĄ§łß@x` ŅȦs0m7Žŗc“łņŒ½. F“:žlE+ņ%¹’ć–œ:@óź ĘŠT<¾y‚ˆÕÖŌhO>öČKŒĪ+••U_“DōÜ£?ƒm8®xcaJAWŲøńó†ĻÆbx2Ćva;ސp\ Ó(Z.†' ŠT†O^Õ ÓvįJ I4Ķ`Œ†ķ" )ųįÖQ€= |r,y¢ŗ³grĪ<~ö­ŽF*|œs¶į©—”) Š…DFŽüOHī>óĶO¢ŖŗŒ1–‹’å¢P²‘Ó-äŠō’ Óra»žÉ+B*¾š{ķ^¹ģŠr©ėåĆŠTŽ_ö„Õńj<ōķo’‰ź Ļ9³ZŗP‹ß"„¤-/n$c^žÖsE8¶AÓ4Ń8'Ļ~óSE‚ӝZĄ§xs°éœĻąõū^9ģńGČļŠ  `8RB7\Ų®(ß*ah 6ō„@õĢ_šĒ}Ū·ųšŪZł9ąŽļüS(Ž,flē†]ЦŗDņš’l:ĆŠq퟿¹m5•#™œĢ8®"BeŲ» xĘŁ`yj Ŗ "8®ƒ‘Ń‘qĪ>¶¢ ×_܀dŽDް!$AJ 4•cėŃ,TĪX¢!Ńų»×^Ū®ŖÓĪūöoƕ—_yƒßē‡ū·öŗ1éĀ“Løjõ |uŻ_”{YŁ–»vnlmm[‘N„tWH4ĻØšfƒ§µ¶ "Bk¢ ®HNNŚs:ę\¹õµm?6,óš¢ō‡«ÕĀr\č¦GH ‡ĒtXŽD ćoųŠ5B‰ŗsĄüī  G?(„¤½[öAHE£„¶E³°ś¶ėš'žWüŽ„$\“ćcś½÷ŻwėŖė>ņéH<ž’$öøBbns HŹ×ĻL)ŠŁ‡+$ EżHm¢E^qŁ«|ųĮUC#CiĒ%¬ģ©„µ“½¬³ėČmHIx­?"¢ööö•{öķóϬØ<+Æ>«ė$Ŗ¦uK)Y0Ā'æöqĢ{W·WōI¶å°‰ÉqėՍ›žł37ßžhSs“ŁP_;q"ƒ“eYĄŲÅŻ³jńąsŽD§g RŠÅ"ę¶T—ļ 﩯«3Zf–~šż'ž¹ł37æųčśG>õ®eļŗ½aF"²Øµ’–ĢŖd gč=žŸœ…‚ĮŲ„@ÜWGūœp@&›žwĪ9Śŗg”sŃŽ‹¢®ćh’‘ƒ>üŠ=K.|÷ßóŽ›Mcä˜9==™t†GNüDŗ..īi†®ėČé&²ŗ…¬n!_4‘ĖšžÅ³ ¤Ą–­Ū6)7Kłز}“ŻŅؐ’Ę7ļ¾{NGgĖƏ|ļSčĶ p$”»1J]˜ƒ?kļšęš8«ņž¬{-Ū¶Ü_ƾ&›ĶŪ»oßK÷Ž’ĻĻ„f&Éd–Ļ„Š9sōšyśkddˆŖć5øż¾ēńJ_\ńŒ ]ĖŚ+pĻ-Wcbró]°lÖģÖć%}ņäTėŹšŗņźŖ``÷¦ķ¶īކ;n»åšī®ī÷UVTtōöæzó­_ü‡`80&eØÆw‹8't…EųT%šŪŖźjk@ :ŗ0SåEg÷¾Cæ² ;p°ļŃę¦Öė÷a¼ę„"Ž)YŅqϧ/ĒņłĶ“c׎ ūŲ'ž²"čß¹c{ńWķ³tÉBęŲLåĮpšŲĄ€?›J;»»B¾°Ļ6&śz_3ĪbčfĆv©±3F³†QdGåĮĆY zÓµx ‘h¼ał‚4×ų1YņŒTUpłŅŁ(š6{žłžG#FѕÖµĻŽ½Ąę:³ÄX"W|~?wM)śönµµó09هßH9ŚdH/źņÅ-ū©ūśµ4ļśū裗zI×uyąĄžŒŖźéYŗ¼6TūĶ»*ūæśńOŃ?xäV)%»bYfל‘Øāųķ‹ēūł/yW÷\‚ ½”ŹŽ®räČ”zQ—»öŠÖŽ#žõīĻ+ā‹ē/»0ŃŲŅüö».?%/æš4öīßóG®ć°Ž–:Ģok€$ɞzś?ÖtvvøŒĖĢšńowłåK?’ś±ćƒtüų1zņ©>žhn_ҳģĀó—,`ēū[Ų’ €J@­éčźö‡BSÄÉŻŪvŲoęĶ` G‹(®ń)$™&{ē®n{{;Ž=ŠwäyGĪ›ü'Ņ‘É. É:IEND®B`‚cinnamon-control-center-6.4.1/panels/color/icons/16x16/0000775000175000017500000000000014724311620021504 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/color/icons/16x16/cinnamon-preferences-color.png0000664000175000017500000000150514724311620027430 0ustar fabiofabio‰PNG  IHDRó’asBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›ī<tEXtAuthorLapo Calamandreiߑ*ŸIDAT8u“ohMqĘ?æsĪŻīYŪXöOžĢŸµ™m”Ō(ź°ɋQ^x#äß )Ś+^H!i‰¤QŹŻĢVMf\„)Ś—;qvf÷œÆw÷Z\Ļ»ßļy¾OOĻ÷÷S"B6„Ū[×+ÅuM©ķĖ‚²éT6ƒp8<ĶČååĀ ŗ¦ÓŻóŠNz£ +¬5Ń’ÜļlŪćzŽ©4Q9»*Yn^1Ž6‰¾Š ”rSS XĮfD!Ü{Ų–ńˆG‘xq]W\וįa[Āķ!7 åŠŚų8¦ßÄ>¤pN×#?3÷#ŽW:‡šøŸßo¢”Ó42hėh«M‹µŅ¼X”‘+cŠ•ŲĢ÷dś, Ć7źņ« @_j-Ś¢iŚĶšź:£° PéušŽÜÅ|…W‰¢<śs”ŠØdÉċʤ¤øŌˆ} ¾}ß÷E…ŪC²øa)Ę„Ė8gĻži·ŲĘ·ä=į½utśDܱ3ÜŚ)‡ LŚG×£NŒ±&’Yå;»‚«Æ7įŽYĻpÅnČ{ś—"5£Śīµn4 ­„¶¦>Ƭt²ś1ō“ G/2Š£wb—0ÆvåE~v®¬$ßo’ś…ēŃ^Ļ;Ø­h ^óF“‹#Ńg ąü‘śc”N-!įĖ#1ō“² ~¾9œkķąY¤'éŗÉÕĖ­•g4€@`õ‹t°ĮŸ)Ÿ^ʎꭙ°»VUR^ä'6ä¤ßŽņ)³ė` ŽćpāVó?}äū öƛ“ŅŒ8ˆˆB„øŒŅõvœHŸ««ęŗŪÖÖ냟cD¢½®ˆhŗ¦·,ˁ’¦™F‘… ņ}99T‘ł_hélÉjėl¾ēZ‹-=ųĘ\kĮā]Mf&kXmŽŗO«—’ōxī-8ϵŠs|‡A0tv1ŲŽÕņ˦¦&ȃ²d–Ōš!0: u“V‹Ķh¶Ū¾s9œœØÆyņŌé:·^§?Ę3œ­;YŻšMäŚ)p:›œ |67ožLX,Šž€[‰D”‘„¦•qłÓģŒÜŪų±Ś½y t©{qę‹ĻGF¦XĶ;õz!7/g®l³ŚA™†ŗOjǽżīžX·ńŌ  W zJ“8¢_īä1;É*efäĢä9Ż>UMĢ—L2ćg‰č"`L6KµY³s .\(„÷P\Š zF‚cKnźuŅį˜:•pi·!~üeŒ’9††päĻ—r³ēp0m¼>–œ¼ż’;‹Ęä!R\§²f>ź8Cht•œ¾)€¼¼¼cxÅćs)ŗĻØcˆW’ń}aŃs`Z`„A5ģv+zŌ·šÉČF„µ^D†C~mķ­QWŸēŻ”įš„›¢  +c!ŔŻObĖ‚ęn„Zł4L ŗ”ĖĪ<8!ŹōE@äg€€C”ü+Œ ųžhEłū»ZėėūoĄįpØ 5±¹ēāłˆšŻķąsļŸPķoAüųĖą &9HœO­›ą‡LćdV£¹„)z¶½ćՑĮĮʝt³_‚ęęę¢K¬"„{TÓ“•:€¼ģ|IL„ŪW 6rYEA÷ŠzØ|ˆ¼­B/Ę5?Ą¦s Pž5¢ ACÓéXx4Dx^×ŽæGضæ¤dCļuõõõ¢d1¾F-±˜-Ōj±ĖŁ AĄB!ŠŃQY@¢öEhīy:øé9ˆĶļ×¾ C̃8 #Ėų(ģŗåPāAx,ŗTP šĆćuG\®‹„1&,\VR²)\>ŒLVżƒŽųXnö#?†ząbµµˆ“¶‚Ųķ€Į0A+IV<č= ž  AÖI3£Ęõ{h,ˆÓ(†Õ>Ģēćö¤ÕX^Xjŗcį"ŌØłžĒyĄ¶+ ““5ś²gĻ™.užƒņĢ3`ŠrµI23īj«péé!PfZqqI.äށx(†c®+~ č…+Ļ'ā™ür$Eēć£cGB„O–%1ĘØ{»ßļży~Q‘^޳jy9āµµ n7_Q3²ŠfĶĀ€¢Įs! )lR“b Ö*„Čī+ $Ø WH)…ĻĄń†ÕĮ”£‹-J0HcØm©µB%£léōéiŗdū4Ål‚AŠ@LQ Y¬ØŖėDwū%Č6zID£0 9Ó ™%„£ ä§Ė(^ĄaœĀĄK° 鹘Ÿæ/ö&Ī÷œ×"ŠŅüžį#/}|šhcŒ~m öŽæHÓāOŁĢÖU„'3ģV;[ą(ŌĒ£Ź_}žĮ 9õø‚¹čŠpH¶a–ŒxbbŹŅl"Ö-›ŃPSW­śż^NÓąņł}5Nē…ź¶Žö¦Éäź­©‰^iĀ/ķįU7h"„p•*¶‰Fń7<§ÓļżĒÕ␖•†Jļ84 ų†¬/Č@·o¢o|#ć(?Շ +gƒ2Ŗ¹}ž7÷ģ­ü«NӆZZZBģšÓoŅQMMŽ"ĖæpĢ] Ū[öĘP:±CK²ĖKīƒö•ĻŹķYL³Nō e@»;„#gś±tq±˜–šņ䦍š››G®-žŖyÖjKYœąÄ§@5Š``¶’Ł£ˆh_÷+*+ĪDŠÕˆą˜ JN:ĄtfĻŹ@˜¬Ī¤%Ėfņ±h¬³­ć\÷MĄź‡^±s×Ī¢ŠšłāŖćµMŽ@ /Ålö¶ž>x矻ö\r]¼ķūwvsbķŠ9čéś<Öļ÷Պ„ mŽüŅ(€ŸnŻŗu›ÉlXŪ×ēkisvJ‚Š7Y-0Ęni½ńĪŁoļŽ„ØŖŹźŪ½,WŁĪ7_‹®ß°žq\>[neŻņŤlCY/eōŲ±Ŗ£±LÅяŽØEitž»Š4ٜßȦt7TǵŅK.× .Wß¦ąšš‘ź“õo %¹n9‰ŻŖd_]øĀĀāT””šSĶqŻÅäm’ˆi„L“YkIEND®B`‚cinnamon-control-center-6.4.1/panels/color/icons/22x22/0000775000175000017500000000000014724311620021476 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/color/icons/22x22/cinnamon-preferences-color.png0000664000175000017500000000277314724311620027432 0ustar fabiofabio‰PNG  IHDRÄ“l;sBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›ī<tEXtAuthorLapo Calamandreiߑ*UIDAT8•kL“WĒ’ē}_Ąöm_h …ZuE&eX¦x™bœ›ŁĘķ‹ĖLÜęmdqɶ3Ė–]’M³‹Y2nœKÜ"x āä>A.rӖR …R.½ŠėŪ³LB¢äłtĪ’—ó<Ļ’<‡PJ1×*¾S,DIaX_bYö77ė;œ»>×=§3ß>,)P(”[ׯŻ­TØöš”'ęә}ć›7ƧF² -a?-eY–ćb0“ö¹l!2~щ§Pżw•ßėÓ ‚fŅōl”Y!‘^ČŻ–ŪśDpYYŁb&*Ņ«]ø˜øŻ.æŪķāĄµJ½,m‰‰÷XwAžŌ5tY“ž!ūŠCčä2AAj6›ĀAˆś¼—ó,ĄÜLM8ńUu‚&’Ę{%4l3^ĈӹR©P!É X|"†Q!†QĀ ū}“čóMYvīŽ- fsrVʙ-ÖOKW'&i—,ŅEE+“ %"ƒ !`ü2ˆKxōÉć n0„Ćrž=ÄGeA"å1"Ę3ß¹×֚ZW[_i4%Ņ“J„jWZrj SQšł‹p·¶‚²,ø›Ą¦ŒN#čQ" "š$Ć<įĀĮOAé1čx#R—nŒÉ[¹ ·««÷ ¬aūHye‰kuÖ:9÷Ż÷N7R@”Źéœ4Œh•ĶÉ@GĀ&Ł:Œ‡¦]å`JœœīQŅ!l–EŃÕ¢‰żūl*R^Yņ#/•½µ\Ÿ!‘ö>@ø®ā½{ ¢ˆ~]ÅX„ “Ż =ø(?¤IÕp07Ą)²5ŠĒn†2² 7ŹKż«µšĢĻW HSSSŌčŲš^†Į—r¹ I×gš±B®Ÿ+EG}'C _˜€*³i&| ĄZ½ —«a¶”±©~Źf³aŅå9{łZɉšŠ g4CNWUUżāp:o'Ž9³‡:P[ŅA!ŠG$v:`5"V£…H)J[ģŠ%Čą“Ū"–žžö+•ļ±Zķ---“”R:c·y!”>£NHBŃékųšLz±qĒz“ŽŚ{š‚! Ž€0‚KµV$ė–2˦Ē¦ęęę śßŒ˜'ŚT[y^¶Ü·Ā14Ч )8ųõ~¬Žš–a0:įĒ2Č\‡‚ķ©Šk Žł0āeĮó2b`±m¶gf…Ó„R>F™Ø@Įńƒˆ¢`¶˜ÄhY›©_ˆ¶v¬J×Ā1ź@gg‡øĆĘ¾bŌ€eb…XV$ČPü88D.ö÷÷}ęõx¼Ī1' …&ü~æÕėń<»!39ęÜջؐ™Œš}]]]Mķ) ! •2!bµösmķmeO|Ņłłłƒ”Õ>4›Ž6ŻmŽłÅńVŻoļŽm2›č:ƒļęg#KŸ³ÉDnŻ®;rąķƋģC¶œÖö֏kk²ļ™zfƒÉ|_әs§¾‹UXµfA}Cßd6]ųõRŃķ55cséø¹6 ģ§ڧģĮ+W‹ßt{ÜWKŹo}ÓQ[;1Ÿ”Ņ’ˆĮ`ąe9_ü FŸué€ģ!IEND®B`‚cinnamon-control-center-6.4.1/panels/color/icons/256x256/0000775000175000017500000000000014724311620021660 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/color/icons/256x256/cinnamon-preferences-color.png0000664000175000017500000012717414724311620027617 0ustar fabiofabio‰PNG  IHDR\rØfsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›ī<tEXtAuthorLapo Calamandreiߑ* IDATxœģ}yœ$U•īw—ˆČ„²–®Nŗ¦QADlGńŃ*Ž J“āŠč‡Į£ØM·e’(„š<ł|Ž;ļü·æPu!Īō4åsss=/ Ė„](”’ 5óÆ]’N?å± @”bןя *»?ŅöǁėŗXµjÕ_vŲ”ż$£Žė^,iĻ čné@—ÉōōęŽć®0Öhļžū ·CÖ=‰¼€Ųś#zŪP)}½å8v‰°ę²īŪßńö7*©¹Ī Ÿ¦=/ Ū„]&JŃ÷SJć9żJ}Ę.!*vż5e˜  Ō&?‰v…C†4^Ą‘‡v8!ʤćĪk/`]©—čVé@Éäää1Žć¬µÉævīææš?õõ‰å½±<„»P)}±åxvFĄqō÷÷Æ8÷­o;UsŹįœšyĻėUv±ō ‹„|˜1Nė¬üPŽõžéGbŸĖ#ؕžPaj?öžMĻ€ēÆ=ń­€rŒąĢöźŗYzŠ%²cĒŽ,cģ5ŗź„ ,iĢ’Źæ/±ī‘²SšÄž€žœ€™ ,”2ń-ǵēpĪqŠAÅē½čŧ¬”C)᩺€&'£'Oé@—H6ė½›1ž%dńųaģƒ)ėn@ĄŽ›Æ,~ :ł¹–‰Bd ˜ń2ōuÆł«·„p@:uJy&Sf•b‘®[·®éh=yŗKŗD”o15’qŽͱ’o üMŚ­4(  #XCI’$ jÕÉ+ZŽmøĪ9ĒĮŖU‡ž9%ą>”C§ĀļŸžfårYcO/ čé@ČÄÄÄĒq޶­æ”²…øÆ–>§Ży›łī°²€ öp¦> >ݚ4iFB8ēčė+ ¾åĶ’|B§„p^%<›Ķ²^J°ū¤] œÓó !1ł×N”¬ ¬üw:ļDńõ—ōķö1„” @X{ u’QøĮ9‡ć:XūüēŸEIĄ ą0Fyµź°^J°ū¤] „Š×iāv$’*„ÆØ[™mØÄź# ĢÖ±§€$c°0ńé–1Ų)AĪ8V®XqŠ”QB8„„»nYd`OŗD–ōĶ"‹ČŸzl{+ćććĒqĪWėųæ3łWŸł–®óo*ü“Å·ÅV~‘6Y.ü¬-DĄ9ņ¹\įŸžńĶ/ CŹ(§ŲĶC—³²?²d`||¼85UśŅŌŌäļgf¦ēgggf¦¦¦vLLģ¾q×®]>“yóń8ė¬8Ś%„ŠnøÉŽĆ’9‰żI¤ˆMä_å. |żéO—õMŽ—ŹŽ/̟źfæ0ŸĻŻ„Ļ-Yę+5%Pzą 0Z!Ń,?’LüI‘€–:MØW¤Ņ J‚eĒ<ꞌĪĢ@l4(—Ėųéõ׿ēņÆ|ż€V ń+ŖS…Bć BEa;vlżkƜ7;ŽóRĪy?„ ”QŠČ£2 ¦ŚeÕz±”õF•ŹĀŽŻć»Ī¾ą‚‹ī,•J²X,J–t3833ӛ]×]å8nĖź·ķÄ4»H@@B )Eį½ÕjõŪ·o’ÖÅ_\z:€Įäääd2Ž{Ēc\_Š”9ÆĻżåm ʒ)¾©ńķŜRĘcŅž€”@fłŃ·2Ż4Äl†XXXĄƒ?rćæ¼ē‚*ŠŖ$~Uq^Éų~@°~żz?¢¢lٲ%ćyĪY9ŪqœS9ēYĘĢĢI=…š‚=G¾BT«U,TŹ_ßś?/üųĒæ¹¹ææ!ęēēűĒ+– t-LNN^īyŽ9žēÅŹoÖ¼7ēd\<卓B@ˆ0 „¤l47ž·~łĖ_~åź«Æ®YØü]Ą™™éžēĄ¹Ji|~¶Ģn9¢rm2ĆϚōCضš ś›”$)ōļBÄ=Ėžń›Ō&ęZJ)Q­U±k×ŲŲŁoyĖ_K„j„±Š¬Ņj£AjœĻ6žXaĄĪŪĪ¢”æÓóܓ(å®n‘Ī`z&Ų^a|źV»Ś±¹ĖŅĀB„Éҽoųū7ž ‚ ¬V«”^9yT¢ĖA +`÷īŻ'e³ŁŪ=ĻcŽćÄ–Żœ‹BkcL±hˆŲ3R"‚šļ7®/•ę?ł’xöżķbAąĪÜÜ\Åђ8[&7Š ŻōĆ*걋}@Šöz˜:ówi~¤© ;Bó©ķLP«Õ077§.üą‡OųM“Ģ0`Ė–-+=Ļ{ēģMŽć 3Ę@%­Jo§NŪ]Ɩė!A`n~lząāw]xŃרē5äĢLŠh4‚„]™pēJ¦„eœv]qŲ«ā†a˜ ʘ®uĻdįyø®‡L&›ķėėŻźÕ+×_żĻ6^qÅo?üšĆ3k×®eėÖ­c0Ū€!.•ĘO'„8é¹’é7ØŽ %&$dŠÄžƇ2ۘKfÕč÷jÓßoŻ.R¦(@^uĘéė„,¤”œ3“ ˆJƒŸŅk³sēÖæ(ģČēsļÉårƞ—ēeń2pŻ(Œ‰=}σ ˆWIŽ“ŲD«Y.ķšÕ«/Z{Ā ¹µZčws¹ß±cėʔ§-];vģXĘ;¦™ģ_³YŒū‚ čøž Ēq‘Ėåśā…¾oģŚkæ’ļwĪ9ƒĒw[·n=+J/>•@@żŪ[i·ŲGmęŪ©)æö‘Uüßā{ˆĀ UИ’Ń"cŌ„ĮG¬^}*c’22JwėœÕėZÆ×Ÿ*å`;vl{W©4±³Æoągł|ž4×Ķ0£ų±ŅGG“R" Āų¾īI长Ļņ’IP2^&ūŖÓO?=`,“ÉųžRŹ`›7o¦ø¤{×Kģ:š<žrB±Ć~Ż1!„óĄBąpŁl™Lžē!“Ɇ†–½ėĢ?ÅÖo¼ž²sĪ9gxÓ¦MO9PŹÖ3.l³ 7R”åZaC |„-uå+@łJP~0(?$zæ”Ā—ƒšįh›ÖJ2 „Ē ÖīD3’Å01ö²įįć„d”†”±€2Ÿ×Y__6 ņ$-$ßµkĒ»Ē …žĖ²ŁÜ!®ėA+¾ĪyŹ–ŅļłyHŽ”H7¦yÓk/‹Åóf„p<•˹œs>U(°u£Ż»^b×€”² ­]ēŖ8é×0ućGQ}č&ČFeŸöÕ Äa‚= &“ÉD@ēer…žw¼āÆŲrżõ7žēyē·bƆ |ķŚµģÉĮŽ;²œó£Œņ·½a 0¾Ōč +€Ņ,÷LäÖž=h¦õ!h“.씲Œćø~üćÓŲÄŲæ¼ķßvƆ bķŚµrżš5{”Ņću˜“ę9Rćš3äÅų§ ¬Ķl„owPSo• H1Öńz˜Ł…žĀ‘R2ʤdDRxķ£‚NM­&gu,FFFŚnæmŪ¶c³Y÷Ŗl6æ–s'j=–(>!ˆź3Ś÷?l)lž»[Ź×c2ŲIj'9ĄÕEODA(Šį̳ŚīĖÜ' ˆ0ĝwÜu“’ H*•bÄTҾOŹŚÓŁ#Š=ݤ«ĄÄÓRŹ”’'Ł-pŌ©Ø^ Šōj8)ݐ ˆķ·”¾ķ6Ōnx°ā¹šŽ ņö&°¾ā¢céœsų¾JéĮ«]=ņĆžčö»ļŻųöĻ|ņ“›Ū“I×­“£££ €ŠĘŻņĄB_œT€œ°śzŠ.Nčģé©L„JSæ÷!üĶ`īšdJÅŻ‰(„ČårĖ•”T2F opV•Œė˜Rޱ±±!ņ‹ł|īM®ė2mńy[WO¢ ˆ*6Ļ]‡- 7`Śæ„z.ź? ¢©dTšD )pPīÄ6×#"•Ī-T*•ߎq÷NÅ9į‚„@˜„(EÄGųō•®"/Œ²’kŪ"“ 2GÆqr:M†¤&#ŗdÖ!§€½2€ŽÆ‡’ßĀŌ'ŽDé+Æ@żį’Žć˜„1ačĮd 2™ śū />ķä“7\}õ•Ÿ}ыž¼o ĄMśmˆĀŃŃŃ „t€ĶJT7‚@¤ęš§®ĄbÕęļĶ™Ŗ@$}•„¶…ŪŚl“x`/ćxās†™”” F9÷Y6ėSß÷Is«°±±ē8ߙĶõ½%“É2×Õ‰ŠLī~oŅwÕūpĖösqķ–“ń»ŁbVżĢ Į Ī)øĆąp Ę # Q[5J((Óc?rš•-ū޳LR! LMM=¾č`ŗTŗ ŒT*µļ™z~ =怯>)5+ĪĢ—g‘Ņ˜•ryōć˜÷ ŪnCł›ÆĘÄæ=óæś,TŲXtLģ%µ²Ł,²Ł,<Ļs†‡‹o’ŲĒŽ÷Č>sé«cĪŽl–µĖ<ėYG€.šž«ü&5߈)ęŁG4Õ8Ä|f~(Ö6tܖR Ź(^šü'™¤! ™pMź.ĮO<üĢŻ»ĒīĻåņ—g2ŁA×qį8NTugұ{¶ś Ģ\‹ėžųkÜ4özLˆ_ƒ9g‰Ņ;ś•q=6])=Õ„A[…ž¦ Oęœ ųA€mŪ·Å5Ń€€ŖA©Ŗ0¦ P(t•ėo¤+ࢋ.Śˆ°$„Š«ćځ@ö¹Æi)‹5ᣉ7ĄŒ`ĆĪ6æžĻ?€Ņ憙‘ó fwt—BLŠH\är9xž‡\.7|ųk®łĮ~pł‰‡’w]—›$TÜ ģŽķÄÆmŒ\Ēіd½ßĆćiœ›K Öe摎ŪRJĮ(Ć”‡¬|¦”ŒJÉ©# \—¤Ńh-[Žt^_ߊĘ\.’'R|;o±8æĪą·ć’†k15²ŁRtęR0ĪĄ™©QŠ o,?”ŃTqėɝŚrūڇaˆz½®®æįē?„( E©”1É|.š']׍ē‰tt)ŒhŌ7k/ s;ńõPŌ‰§» “ Ģūų',Cüī›˜ŗōY˜śę™§·vŸR*PJ“×#Ė— æį³łšś÷æ’żĒEwĖÄõ„šõtޘ(lݰ9ĪDĘ,y؟Ģćgˆ…„Jģl{žśļZᆆ†Ö(„g‚”2/ éi§Öwó-7’d``š ™LÖK+~2!k1½©†SøuēųįÖÓšxõ*H^w˜V|‡3ķī3NĮåĘā“hź/mQ~DõG¾®õ2Ä ¤k &&&¶=ņč–Bˆ”JJ©d!“œū’±²*•e±Xģ*Å7Ņ•€‘U«Õ®²óĮķ€f ĄŹ’rWŪŖd֜Q ›(ŒA6ØGnĄō§Ēō5o…X˜ģ8L!FKXąŗśśśxыNŗż;ß¹ģü+j.gƆ œRr,!:FÕcmaĀŹ§g%ĶaĮ^‹6ėÅ\3Q† J6% Œ”Pč[Ķ•"Jq"… ļ}ļ{_pŽyļøw ą•®ėF$KYżÅ?UÜ5ö1\·õtģl\ęp—;‰ĀsFĄĘ(% ,"OĶĢHÓ …ŲŖ@xXŽåŁćZŽ»’a€†ßĄ¶mŪnÕ'J„T†‚ɐ Ńh8r!“‘ž·MµĻq<ż„ėĄøX—^zé/…ģx±-xÜ«S@²#¤”%„üŃ+7ļ 0ėä}ßÅ䧎Įģu@Վc6“Qżp’0—˹‡¶źß®¹ęšėĪ8ćŒaĻ[åPJ2ēB¢€©}ÕT#ķ£Ūé½żµC¶ņ+¤Ā&3ĻĄÆŽžŽ$ź6¢ „( …Ā Å‘RŅĻ~źSļ^·ī“õõЦŸ‰õ÷Äī+bĆÄńĆ'Öasż» ŽÆ?Šń3?$jšAāŲžY{=<éz­„Õ¬ČœŅrl›{ ƒz7Żü«Ÿ* %„\Jį!2™Pxå²Ģd2 ]Xt!D¢fff¤ļ润vŠ÷Ā7AĀĢļnĶ…›ˆ”–[mHCX€@õ«! QCxĒQśä1(’ĻgÕ>)$„D£ŃˆĒjfŗ®‡ĮĮĮÓĪ;ļ¼ū®ŗźŅæp·Hi’h¶Aż”č\-·ßjŸ¤4aJa=!µē”5‹Fś …üé/{Åź«ÆųŹ·ŸóœćĪĶēūXkéībV_į”ékpķć§į”ŹW^Õ®>,¼!ō8ć›OIĢęSŖ-æ™ĢDšö­›ž(ŻłHG¼¦õüķ¹a€É©©± ļ±ū/¤ąR„”+|ßł|^°Ūā {###šżŚwuĖÆĪ@ūYž,}ӁØÄņxIņcB…ŲźE²3“‰0äp29xŽ‹ą®/cņ²¢¶é†Žć6ÓR2ĢårČf³čėė|Ę3žu ēœŁk’5‹“IĪž¤ÖvŁ÷KšIDƛ˜k'§ŏžhұŒ1ds9¼÷Żļüö”‡öģl.3üö÷:ÉīźF\æõ,ü¾üEHg^»÷&®ēĢŃŹ® =ķęS)=!±—¢ļ›ĆXē¢”ŌŹĶ1€•ł“ZĘajĀ0DąŲ¾cēm@"÷_H.¤rC‘‘”ēy²T*ÉQ’wņ] ŅŖŸ’ü¦ !|)©8Ļ~UŅ쀙’N&ćzśHóĀĒįšRˆŒĄÉĮÉ ‚2NޘEõ'ļÄō÷Ļ阔”)¢ń<ŁlŽć³7К’NGē™&üģsy²Bšõ'ŗ.RĢ”ł9—JB*]ģpł|žg28|ļ”_©w_Š;J’!›FĘń÷–ĆuÜ(Ę×®>£ś‡Fn>‰Ż|@'ōˆ¾q©č‘])ućO„€¢ógĪ]oź:~}Ūo®'"T„JI#÷Ÿ‡Rxa(jµšš<ÆkŻ K uĶ5×ų¾Ü­ojgč;é-V•›Ššŗå®YÆy/ĘŗÄ5ĢĖĮݬΐt‘Ż|3¦¾šŌm?x+S@ć8ń”c›…nŁNΤĖu­ń=%!€eˌ§dtK†³mN$ł¾™4e÷g\ĢźOÕÄŪž;żA9"מĮa²Ī0\ž‹b{¹÷4mķ#Å'±Ū–\C»Ö_J*¬é’ė–ńėo ‘fff&}ŪOB”TJʄtT(„ }?+ņł¼,‹2:Ļ®nŒ‹ŖŃØ}æŻl9[ųš`čČ8 hć ŲX0eOŒGąeAóĖA9"¶ŁĪÄiD•k’ 3?ü(‘^hƈ©°•]J{Ķ+aˆ©6 µßbé“M YN»ż¤¤k“… —į¶Żē#dSŗx‡SšØPǤń‰=5ĄāBØˆļ‰‚sKłŖ²XŻ’²Ö”›É?aˆ†ßĄö;ļŒ>W”Rɤ\pŗ”Čåa:‚ņ, IDAT„’ŗRł.ŒŒØG}ü;a¦x§9ōī³’*&ĢŻ’hr;hP Ü6×hŌGĶājś_ö’ Ø?Ö+XÓEn'õ  ™ōg@ŖØČ†qHżšŚŹß{3fzѓ;o9½Ń/q¼ęæc””E,ZŗmSŪūqFŒ»żļ÷“ߥÆĘŽŽ€Žƒq§ōhT±§Ż}£Ų†ą(8<:ÖĀš·ą¤ń”ŠŠÄ¤R"*3ĄńĆļhs=’°Ė|ģŽ½{×’ņ–‡… J *„dB.„+„ļ‡"“Ét½ūt1D¢F‹E5;;÷ļABˆĪaķ+‚õņ”ņŪ³ßģ“—õ É ^!ž[“1J¾gy±ņGÆäßĒŌ7ĻÜć܂Ž'¬Ŗ‰ņŚńśSńŚ1z÷ŚŅʽ€X"ī7»>„Ē*ßs$(' ŌŖÓęhR/ŖŚ‹6&Ä“vwą±APóȒ6X­ ē@/OØ(бbö9­§nY’F½Ž‡~čĒŃēŠDT(¤ 3_L ]ļžŻĄČˆ:ūģ³Gæ±#µ&@;2šåļ‡0lp“āŚöH“’]øł–żÅd!±<€x»¤¢Šęŗ{#¦.%ÄBūŹŗÅD‰j’¾D[ŅūI‰F›S‹ŸpUļø]' e7ļx;JįoĄ9Ü}ĪM½>a$VtSa~‡ł‡K‡“'I*ßo®I¤ģ:ö”4ĶDž=ųę–1ŚEWA`~~¾ńŻk~šc­üR2&…ķž×ė‘/•d·»’@—€q½ …‚ŖVėWģ 2‡ŸR<ŗ‘{āž›4Q,ęA€Ģ ądŚ v7Sæ&¤TäĪŚ”@<ļ ¼3_=Įī‡÷éœ j4›£lū¦‚ūršZXĀM;ތ ē$ŖÕ׳ņH”ĆGlį£" (k|KØBĄ4(Ö““ŚŽłērG¶/ž1ż:6?ńÄÓ3³ !BĶžK)¤R”p…š3”Čd¢ź?t·ūt9D¢F‹EuĒw|!|ߞXŅv†ą‹Ļ‡TzLŪĶU‘KI¬Šd'ŪńĄ©PĄśŠXĆ 4Ļ/ˆCsW¾¶cŖši)jĻ :`¦žnŽõV„tR»śó™ĻĢł~ć¦=ՙ÷ōfØĢ2lāR1o¦8­næ-ķ@»† ™Ę,  pdÕkĻAåžoļåÉf;x…„ānˆŗw;HÕ@Įlæøģ\ø ·īžg(V‰ā}盂ĆšŪ{Śź'ž¼ńŹ:ŁWķ č ĮŽŪŒŅG7V!% æ4Ü ĖZ‚µ„”"„ P(ØŻS„Od³¹WQJ‰ŻQ7%„Į9ńw|>(’XZ NŹ+čĻ÷u@‰Ø)QL(č÷± ш‹õ_^1» ż§`ńż³œĪ_Fū$zĄ „ke ¦8‰•½ÕSJD=z%RPJ&`hG;„B–<:;‚Må’ćį$.߄ԸüZõÓl¾ł|_Æ·‡öƗsQĘ¢T$ DāžÆpO…ĒŪ\cżCŌjUÜwļ}߈’”J) ćEB"Uؔół²ō¼īg’, ĄččØzćėßxO½^æŪ¬Ó)%8šŹ‹!Ż~MŖ¦‡Že€(Õ÷dļ®i­e‡q5”•!ŠŽĀ{¾±Ē4!AP„z ¬”Ź–²~ŚBrнž““ nŚ!.ɂŠ<)l”Ač(ÉÅ_{H‹Ą¦©+ńĄüW@cå·ęåå'¦-—‚“ÕoåœŖ\pŅgY’ČPIaH†?[Ńz]ķŲæ^Æc¢Tšüƕ߹‘¢@ˆbQģB!TXĖēE©TŠ{:.>²ī%T±X”ÓÓ3™E>U‡{D½<¼SŽ»’"Z[d‡¢½ķłļɑ6œ‚ł^;^Ąž\ĈßåŪ¾ŌqŸÜ;Ä)‚ŠAš…²R^ū"‹éEÖŽ”Pŗ`ĆzÕ 6Ša#`Kłx“r•f÷I¦ėFĶBbåO®Ģ¾e-šā*;ögČh€Yš#Ŗł—:ž?4sśœC[w™Šż«X’»õWD *)•P\…J©P* ”¾z] ,‰ŲßȒ39ht“Ø^żźWß^Æ×ī5ÓN;UöŸž~ˆlQ+>d† iõ ŚÜī½vW£/6Göz~Ö Cų·}µ~–삐ä<čŒŲõ fvąS!)ņ”ęACŚ^ĻRõ>Ü7ó™Ųņ3šöP¦É>Ķō›1ʎ’„]v&łc”÷WCā‚0©  <¼ą ÷·9G½33M{bb÷ōßśīOć¼?“B*'T„śś4ł·^OżķŗÖ_dI@"#j``@NL”>$„€Œ2훆rä_~"ėŸؓÖj£`mžŌ}ŗūŲC”Vå›å@ śóĮ»?5v€šŌnc]%O”Y² ŃX“WPHŽ«ŒįĪÉ‚0”Ó|‘ņ3cłŃŖüń¬Ė½ŽEԚ!µü ś $‹X Gę_‹,_Ö²Ocż}ßGµVÅļī½÷ŪBH)DØØŠäŸR*T@*“Šī’’‘%Ę X_(Ø×½ī¢›źõڃ{, zń; ś‡rsP<§' 5e’<É6žZÆ$r’˜ć€ē—ĮÉäPżé’ƒ˜Ę£’§t°ķXTŪAļ»(U¬”Ø>‡Bź»”Ŗį®ŅÅ Žå4JušĘ‘ņGn?”H„ųö{Ø"„·C %‰(õGeÖōŽ–]˜~„¦ģ·T*Ķ~ćW’ČXÉ˜ą ” )üįü2_D„æKĘśKb•r~~öbŻ[¾³}Æś8ą D"¬Œ’Šf ¢³°æb¬5vN€qŠü XnØćčīDAs?x¤Ÿ,pJXBPŚćŠ3OV:„Ž@yJ Ü9ń!6‡,ļCΆ˳Q“+ę'&²æL"ń¶Jg1t²‹~8ØĢAH‰c o§ķė8¤ŌM?Ŗ• 6l¼÷Ūś+„BŠr@`*’–łgdI€]xƹ璬Ѩ?†ÉśšöŖ3Fņ'œ 9ø&¶žvÓ½O“‚O…ž‘Ų­¦z’Q~„yq}5ÆÕqĢ_{^¬•„¦§žšŠH[ė'1®ä—ų‘Ņ%K§Ż=ńoØŖķ:ÆĻō¢©.ļ‡Ē–głŸ\š/-©čĢܟČeS2†<¬Ą ĖĻms~zRIŌu”&KsW|ūŪ#ĶÖ €@ö÷7bė’$†’“”%‘ØŃŃQ•/•äųų®wérN±xqŠ+/b°5Ü‹ģĄŽ aHn9ąä41}žšY€L?‚¹Ÿ\ É.¾&V$Cšy OŖ%8:7‚tX”PļpĄ}“_ŌŲ·ē2ń>%”0xt.ĶF'ōŌ(•(‘ųŽH„ŪĆ © „.žyīŠ;£:ˆV‘R!š}T*Üqēo/÷«Hb)YA †óóóbt“ø¤Č?#K P,åkŽsĮ-•JõöTYs*č3_•ö,Mųƒ„<’ŠZ[%”yOITĪõĄöß zļµp²Ļ‚"Ž5 ¦1ķļų¬øß¼Ä@żÉ;»«ė1Öø)®čcŒĘē]åGJršH’S£ü†ąŒ\½æčŸRPńd)śé1m~:kŠÕZ [·mŻü­«¾{ƒmż ½õ_•Ķ²ä ’Ų xšĮĻ ‚ĄßÓŖ3ƒó„™įT %āŅ÷v”Ąž q zž½”OœrK~„Mį@ć7_†(O€°֙6éüžŠh|óGf’$Épßō—ō¼ż(Ö'„Äõü͵Äøšč@ėŽ÷uh*ż^ŖÄõ79)%dØ „‡SžD‡STR š”Ėeõć_÷É8ļÅž:ž§„õ–.‘pĪ'>±}~~ökAÄ+Š“O ŗ(üĶē ¢å£Ķ”aćj‰nķw¬MHfpsÖgH)q\#½7­Ź ˜¬£|ćE üš0Ł„ z2ŗÖÄ-ŲYĀĮĘÉĖ X9®ģ‹Cųh MÆąpé č~VŪ®?ˆ‚R–ė/%””qĆ)Ž<֚öÓū"”@µZĮ¦¼å×·ßõ(!”"”Jʤ !!Ōj€`©[`‰@R¤½€/|įKj4ź“{źœ9ād°ē¼6IšP@YŠ[Dģ’ø×ęoH”4ŁKbM@KB=Ńt`‹°ģØ’{ fF¤ķö›sže+0¬×%½Q̇/­bf>5,ķ#mĪ}I›*½„õOY”0@ŽÅQżÆīø3]ōSGir²öÕÆė?“õ'JJ%' „śõ8ö–¼õ–(i.ąĒ7Ö'KSļ‚pėŠ žå'ęÖS†ŲE11°7u@rĆmOJ5+¾ńāę"HB@ÜT§…ˆ¬qīØ¦÷@ŠGÕ.]éĒ’øŸ6õ#Kżßr|Nśą\óŚJJł#`‰41®ōS–ņ™ĮÉ+?Ö~_‰*Õ*ī¾ēīoīŽ=Q"T”)”«žüP?„>€`ٲeKŽśK"Q£££rø\’š’pM„R¹oOż@ Æłxda"¦i v÷„ƒd‡MŅŪÖÖҧųՔ SÓ`DśG’RąęćļqLķ‘j‡ķC)ąaŅĮü¤'?Ń?&ןĢ9²’ǧ$ N:÷X0盲ü–ņė”ā9žR(ˆPḁ^t¶ŸµZ Ūwnßył×®ü> ;żJÉ€€PźJ}AHAØ'ż,mė,q0^@”PPs$|ģ±s|æ!ģ®»ķ@Ą[u"ų Ļ Ū Į~oµyG„‚dUžÖA›m­Ģ@ō;EŅG€Ļ+`ƉÉ=Ž€¤÷cR “š0ļę“å·¢2ßdÆdŸ }Ɂ·ćßuSv­Oō7 ³*“”:å7ÄNĄšWµžR¤üRJŌėuĢĶĻŖnøéS „DHɤ $ ”ś`Ģ ę-ėæ”•Xā`dttTLLČK>ųĮū¦§§ž#!Ā0\48ćĆPĖž‘ŌĄāŠ'[$a*#—ččöw[ƒHʰĘķÅāՊd„Õm7ćé„;€dūč½ÅćlŠRžh©mb¬?"÷œÄĒŚ[m᤭×&EB1駔&ü„TBBD¬?“ż8yåæ¶=†¹æ¾ļcaaļ½÷Ē’}ÓĶ÷!$”T*ĪC8H@}Ņ`¾*Ó` ĆįrYŒŽŽ.ÉŸfYņ`¼€5kÖČR©$Ļ<ó¬](—7ī)+B0ō¦’B˜-j>Ą*ŠA  įė®[Xg+·ØÅW }œd ˆ®6&ÖŚŚ<ķ©4µł±n&#7ū1•‡tœøOæĖõ'iŁ7ځ€Ó~¦­ā”© L¾?ŹĢ˜‰>”‚’^²ņ2ø¬Šŗ÷hÖ¢!Ŗµ*¶nŪŗķ3ŸżŅē¢ŃğR*$!õ a>@)y07w0ķ¾–ŗõ0222¢V­Z%ŠÅbxŪm·’m­V«. Šģ†ĪžĻĒ}S„ ڃx6źŪQ »n¬æA{ s6Čé¦ćķµ‘“’œÖóš EÉéӓx؞āKĢź»–ėƞD?‰²ķN^ŁŹ/“ę*Šū„$8ių#phs>ś$MĮĻää¤åU×¼_” ńǹ ‚€ŅŠÆÓ†ÆT9čļoˆ‰%Óīko䀻_@©T’ŸśŌ§vķŲµć|ß÷•ž0“Ų²bG ’ŗĖF¤ ø\io@QÄkµHū,M”%U ˜iĔįżh­@”“XśŲmW×É£²„Gå½±`ńüM®’žf8’ĒhĖÆ¤V~X=„ł ćމmV÷µ×$ō>Źóóøõ×·~ać½÷ķ"DHʘ’ 嫐ŌoDğ”2˜ŸŸė ė QĒ{¬Øzhų¦wżßNNĪüȬĖ×q).Ž'#sĘĒ‚Ä `ÖHU’J–„z²BšŒ¶årS$©BVĀqĀ‘Zó é“ZB˜aO€¬*9fx6Z…—ĘīæiQöÅX’½J2`ČĄśĄR~a”_Jū‡ Gd_Ū1ßo&ūč”_=ōŠ]ß¼ņšŸDII„Īł!Ō§”7 ń§żF–>ńgĖ‘Ø‘‘501!—I^|ń‡Ī­T+»„XĢ ŠZ’Žėąœt®® ˆųa)Rœ>(m÷ćj M±}ücˆĄØ6 ¼æi?͌d§cZślłUåL/ŲA“xŚirāy {‰}ń÷"ōa$ %iŹņ‹Čõņ …"?'Ļļ°OÕś Ōź5ŒĶ~įĖ_»D+搄JÉ£&ć J>­ŗž@†åˆų³å€€øiȚ5r~~^<üšĆÕū7=ųĘ „)0I}æiūĀKß rĢ_ TéP@(ŒCńLŖ@Ēu_»ŪÅģŃEā šąoé°æE”2®%€÷<”Ż\D4š~mˆ?“ih7ä=€@ģ1D.æŽG&Žł…LŚz©HłóähœrpēbŸx}æP V«©Ÿżü™(•jŗÅ7•Jń@@kųĘ|)Ż ^ƇK„Ļ’¾Ź±ŒŒØb±(æųÕÆuäa‡>'Āķ¾Ö̌CƒÆłŌŹu#Qe-0Ā Ś I,+מ0dMĒn‰ē£ßć” ăš½OyžmĀ{æĶŁ‹GeæžŃÅü:õ‡ŲķŠŹŪ,zœō“z ’äł•T $HŖ ?‘((YÄŗƒ?×ę"4C \.OÆ:dåźSN~ŃądÜčƒÄg>ó –E~$āĻr„;lóęĶĒf2ī õ|JłqŒ±£8g+”!Œ3PBŪ4 ± QģOEˆŁļ½Ų~‡nķķŗ`¹”¤Ń',²ĪbČ{t÷#ģ±+ŽO+ xĒ“r÷i“$]<ĄŠą”L/ŪM©X;lƒö±öōXÅĻ]„” ¼BYC=,C ]š ž:/=ō‹šéJl{~ąĆo4P«×QÆ×QoŌD­R›®V+ŪkõŚĆå…Ź}•ZåĪ®»aƆ õU«jĘż7#2c\ņŹ±äą±Ēó<Ļ;ƒ1öjĒį/aŒI)ezź*”’Ę“fĄŪwŽŪŠwøDs?»ņ÷#ą}Ć`œƒ+6Gā ŪŹHö ŚI“MģYX¬æŒŚš‡ < ’J”ƒQ„ˆnŒAL½®Y DB) ČQŌõbU/Ÿ“õę,5Š$ķgŸW‹Vå·­¾¹˜Ź|QE„¾Jéę¬R¢Ģ >DØ0@Ēi‡|„ģy6”pÓė_)…0 ¢ō”B ()źÖń²V«mÆÕ«·/T~¶cė×’ä'æ®XŽ@źL–" ,`Ū¶m{)ēōo\×YǹūLB)×é+šRvóČŚļmiåØÜł5„æ» "Y ŲöšH6»ČgRgķ¼„" $ó@’̃·2ńfāŚśęEĮø”Ŗ2Äoɐ^ч18\gØmżć>f‹ ½ƒ`¦óŚ„ƒ¹¾v3)$BŁ@µ1‡CŻW“]Šc1i×ö q!‘Œ'ÉØ¤X0ŠAˆ¹ł¹'µŚ­•Jõŗ[o½ż¦x 12rœ.1WĶ:§īWž®€-[¶ ŗ.ū'Ēq’ēüxJ™G(ŻxóP“»j#öywNŖE•ŠŹŃxäfŌnžØl$E:4ń@šÖč±-č¾A/,åę*ŖÉÉ~ srÓn­c6‡5Rˆf¼ Śac†ō£ŗ §Ц}¦®‘åį¤ŅD%æG.?¤i¼"u¼Æ  æ8,ūWxöŠ÷ņ¤Åxsö«ŠęJ“¦ a֒”R" C„"„Cz£T*Ģ/ĢždēöŻ’yłå—‹EÕŗ ŗĘĘĘr„Č7sĪß̘óĘ£”éõHéŪ¹ņķ}oĪyo”H2ģ~T~zX0Ÿtńö€„mM¹Ļ‹YRū°ōIÓRÅ\ĄÉCŃhę"".?ął¦ŲϾ„¤Ræ%E©?½¢DŠÖ5ńG,Õ·9v`żš²śJoĻčS€T†éWq?B†cĪĆŖĀKöź>ķ­Ų`Š ńø•‚RŒ„"D†SóåŁM³só߯¶eĒ7®øāŠé„OkXæ~½sŲa‡¼^)śVĻsO¦Œ¹ĘʳhbŠķņéŗ~c“.±ū.jÆņų͐˜Ēüµē‚Õ&ā"ڱG€čżŽ:1ø}Ė$uŠ\@)“\džgqfHĄ|¼Md±ĖŌM>Ķ─‰@U h“é韦w$)ļ‚(«sQņE)õŚ}Jčt„V~"3xž²`8ūģ–mžPb ˆ}/“ŅhƒAų‚ æF£.fgg6ĪĪ—Æ¾ķW·]9::ŗŠ ŗž–°sēĪc‡˜söĪŻ,cځęœĮX})VŹ'£šFڳž¤q( ˜’ń»€ŅƒiO "ćź>s *āēĢ>ŪĒ” Žć0NŠ]Åg* d^ ½*x³¢Zæ+wĖaH×Õ yZ‹y° IR-™Š Yń#w%^·W&V_*]Óo<Ćxań#Č;IæĆ?ö³i/ĮÖģMb1 žńż* ĮģģĢM»Ē'?žŃ~ōīB” 4ŒŲŠÓ žV0>¾ó,Ɯ Ēy>ēœhמÅÖ¾ł†Ų¤ĪžJjQūmBNM!,• §¦ Źe°eĖĄŠE°åĖAX穾•{¾’īo€Ézœ«Ć‹0”µ"t¤(ń4Ŗ • 0`~p49ŹŚ¾Iƒ€)įāa¾ ޱžĢ„SH&#”ŖU£ż®b01o,w?£J¹üˆI?…ƒ½ÓńÜåē“=kM*“˜oL L¢LĆeyō;ĖQšĀ€S§ķŚŁ®O»gdqßĖ/ķŻčgO Bų~FõF Ó3SLOO~žź+æ÷­M›6ł…BAY‹‰<-½‚?9lٲeŠó¼ Ēy›ćš"c 2óØžłN’^’m½$Æ6*šg`O¼WїM$•‰”DȞš€MĀü'×ćpe/«Ÿ3^™±Qże³¼W Ŗh$ĒnV|+˜Äś*šAöX“{øĀńĖŽ…jč扳 «>„š˜ƒ/kej˜mŒ”.«ńąSēbŻSN<8$‡eįŃ<²“ÅģŁæĻ8}ĪŠ"ĻEś“ŽršāšŒhņ0@½^‡ųhŌė˜/ĻĶOMN~ļĮ±ķŸüāĒ>½«X,ŹfÆąé2(•J}RŠO8Žó6Ī c ś‡Zn~”¾Qŗ|ĘĪĪ q×]šļ½ā‘G ĒĘ@Źe‹ÉŽÜ½hJ\źst°„€';(eŲęH!@?ŌŃ!h’0&‹~&Oi0ˆ>Ž?¤™Įȟ7;G¬o±'€¤0Ȁ€³®©©±bŃ6wį ‡2mż“ĀŸä\m­Ō¤ ¢!؄ T†7QÖžÓe½ę} jvWk(‹)('€P;ŌŃļźį|Y‰ŃBÅŌ‰– I6N*fM -`ČY…ƒ³ĻÄį…ńŒ”cŠ]Łę·ŠŸŚ3ŠĻ«-a Ńšįū Ōź5T+ įxiü‡ozģ‚ĻžóćOG ų£ĄśõėU«¹Ųu½wsīōQFĮ#kßLčķiEŸv"kUŌnøµ›o†xüqJ%Z«.źj“Ut`ō·Ž+ČfAółŌw”żW¹éW@fBØc§įō‡1)˜KϚ½šé‡āžV’&śCY‡3mĢm2P xV`ćĒ”pń_Īi“¬7ÓŻš)ž#Ņ*_ĶE÷%éŲ›ŠJB hV]I„JĻč«!¶ĻWŠ@UÄO41”Ö9 å£ĪtŽ‹T&“yœUŚHŌJ IDATź$&&”\ä1č¬Ās‡ĻĄI…¼;”œk3ÉŃęų,;å,„€ļūØ×kØÕj˜/Ļłcććß¾ėŽß~ą›ßüęģĄĄ€\³f|:ĮČ®]»Ž›ÉxpgČ (ē<„ų¦8c_Ę%vķBł?@ćę›!}Īšpģ¶J-ö½©’ŒłNō7wźżż€ėĘߑŃv±'€(Õ €ųčź SzŁ/ÓīŪ€@ĄÉ€f )åo'6{}@öÅMć¾æI0ļõ1{_Ńq©īń/4`Ģ«$$|1)_Zń•’Q%‰PJčM(…R„Š©Z][ņäD22ņ‹…§üQ`llģŸ‡ŌuŻ•œėSśÕV|ƒģŻxüß’åļ’‚ŪģŲ³¶”1šb1QnXʹč`½ZihĻ6śÜ:®"tٲÖg1ŽĶUJįĶńl²RzĮ‘3`Åz*Mh‡ HvY bĶciŽ…›@Hķ}8/؃D¢ļݭЀˣÜ“ūߜ:hŗ-¾\€”¾>„AP(™¬Óż.$0WÆ£T«!‘ÅG˜-˜ÖØŹy„¢Öž˜÷ŠXųD"܊ł Ų aŅ“śKõ°‚j0½Šˆ¢$0č‚göŸ†SV¼Ē Ś<ҶBŃ@Ą™a,⦤µzµZ333 »Ęv}žĒ?¼ņŅ[nYØ LČõkÖHü €ą cccÆåœ}ĘuŻ#Ē!ŽÓŖųa(öjŖ^Głź«Q¶n;ŌPcå õ<ŠĮĮ$•mŪlŁc‹ ¤@ĄžN»”ø.ŠßߞP): ²éŚĘ}Wd„GĻ‚ Ö5 ņ¢÷ŌɂdśZ”žZ³C8öFSšLĄ9<C`NrlāĖįpŖ—łbŒŠøæ@ĀDZ hŽ!rN+>4¹' ~ ­ųeßG©R…/%š=żfoF’­É׎^BYG5œėč‘)ėfŁNKRķżšŚ(٦!jØś3P‘Ź*™Ü+%uw¢!ē0¼Øųz¼|Õ¹Čw ›…sĪyt¾BŌė5TkUŌŖULĻLĻlßµõßæō¹Ė?æyóęp``ąŲ¹sē1žē|×q½µ&FjUü½wõ÷ߏņå—#øõVŠFCר‰Õ|gBX6 R(Dä•~€©mmš­ŗń 2؝ Ąl¤)ž7{ 69$aōƒ„bŅL|„k¦Įś}ó Œ€ē†S‹‡Ść¶ “ÉŲ " €÷Ā䤔SĢxyæFėü±…:œ¼ŅćŠ)=_VŹZdķ©„PØ&ėuŌ°éāYąklņ6uŻ£7€„ĄB0Łöš§7JĄ å,X^@’”P@ØĢ“É—"ąP29gĶófŹĮ3 §āōCĻDZĖ^ŚyL– ˆ{†!jõjµ*Ŗ• &J;ŻüųŪæüł/ß2??/ŠÅb“&Įžją»wļžwĻsĻēœ;ŒéoŽ‹öJń…Ąü•W¢ö½ļAmŻ+ŗ±öFéi“;Oūśbmvį›-zĖsŽĢ“’ĻŁ6 [,r>±ņ§¾nžX+m0XAxä,h.s2`™BĢ 0³K‰šAAYÆ*r’…ųĖ{JČrŻń—kėÆ+,­4›5x]h¤•^F±øT Ō‚¹Čā+ŌĆSµ:‚ ±š$ ­(„³,u:ŒjD X'Śü±é¢6]Œś‚$`{ P˜ów'·P%?*Ś‘4 aĄ@* šCń¢āėqĘaļ†ĒŪ…xX„Äŗw. CŌė5,,, ¼PV;¶o½į¶Ūī<÷æųÅTI—¢?ośŽ|c7dĖ5“QUÉHłČƒÓ^‚GśpŚAoĆ_qA‡‚$k˜Ńė”Q©TPšÜ]¾’¾ß½ö²ĖžóŽłeĖÄp¹,l¢š©§&&žXAißĻóęÜI¹ūŗG[ؗsރ”ƹ•/˜˜H¬=!Ś5µ¬½Mā”éw28ź8É=·¼€§āŹ‘Ąqö};ūųĶ×܄ˆ@€Ё„¹ĮŹy`Y”émbž Ś”’ōnā0@%Kœ ˆå€ó<ż½-2’×NuśOϤL®%ļD’LL/@ik*…²ßĄdmÕ°ŚāŹ7…ńŻ°½”…pRū¾”}ü” –|¦PöKķdGZł‡-!āyR“‡Y:ˆ—|^¹ś]`{č_Š RJTkUĢĻĻabb¼~Ēśßžyõׯ¾- ĆpnnN¬Zµ*īYųT‚ĄS»wßœĶę^ęŗ.4Łg–dŅĢžž¤ņ“Ÿ |ŁeĄ®]`$y ć~tŠVßÄ×)‚ļ’³÷Žqr]åŻų÷œsĖōmZՕ,[–›Œ±‘»-wL L $ä%É yß$@ ‰Ć›„’|ŽH8šBw Įvd\‚-¹ČMV—,­FŚ6ķ–S~œsī½3;+ķjWʒ½šŁŁ™{ϹsŸö}!m!720źŽ(źééė’|ŠĻb !”ż(—œ@2…xA r°ź‰Ä H-ū»%i~” p/Õ{‚ö#v]]ōc¦ž$ƒ6‰%Q‰šPåø #4ćR)p¢%kķū“ڼSŪō"œ|BE3’ą4©ķ‡@ÜęÄĻ„Œe 2—¦C ‚"ĄÕKž7®\ś[“,ŖN¢”¶ńL†Łm;¶ꦿ{]µ:ьcš0Ü !0k°{÷Ž+ŠÅņ]žēĆ7¦±õoEĶ’üOL|ö³ ;vLbś6pZ¾nKę8hŽžl‰ ¤v÷\‰“§Ļēœ!ū:D•Ä@(G ¾H>߉ $‚@2و¬T/ÅcμdĘ_ŅļŸ*Hb„޹Å")Јb4y¬xHzRėž0µüĮØÅ'«ÖÜ4Cu>.ĆTpe„X‡“Y™ßeśØL»ų [ˆ7} —,žÕCž?k Ōė5 ļĘĆėś»æü»ųźy!&&¢pٲxØÕšS!0릠Œ¹æB©Fłé1ėžū1|Żu˜ųЇ@wī„Ć„“~Ś€æ¬0°Œ’ uó5WdĒóĪ1%ßb¢ĪÓsXĢþīMä‘ß2€Ü‹€ó ‡‹ą!KB~É̤Ģo§‰`Té*B[’+„D¤$%)”³Ų„ĪŲ«6[ŲY«aēD £a€PSȀ„ĮY7ģbīĻ!Qrä„:€DS`W#ģŚ,.Ŗ4°J˜®k¶ūe@MīÅlū]üńĆÆĆśįļōüœó„o …" …śūūÆp(Ķ{”ęP©xžŽ–»k×.¶vķŚ9»Ā³¶•)ŹŌŌŪōŻ©ˆæōöä#ė×ó“Į±ą^Fė'éŗYĶĆ(]ż6:’ąH;KŒµŸKerēŃ@¦Rš›yČķ9Ø­¼ČĮē5€ž4ĻSŸH³ōʁqåB* *)8UŚÆ—:#. £LjL vāth÷vwŸ@‘Y+£ƒ9ā ¬³×;ó ™ü<ݼ½?UŪu¢‘™©‚|¾²éąĒ;’ļ?łŸ0T^ÕuBˆ$JP(ŃŪÓ{‚CiŽGrRŖˆ2ÕÓÓ#·lŁ¢Pk·aV~ÖW•2ē$ĘX$龞Ń/ {®ŗ üį‡SFĻ0?3?–łi£·…üFGŚx9Ȝ'»÷6« ó;ö#¦ {Ü'ĒēCī*‚×HN a,ƒšƒ&|©B ”Ķ8Āžf ;ĘDZc¢Ž‘V€Čą6„ >`„€Ź2„yBްvÜGЦqgČHV(äZ%ł)ęŗŁŁŠ  »[ńéĒÆĄ÷^¼ Ru·’­u]„R¹|Ś)§ ¹‚łĀu}B¤ė8Ž3>>ŸĪ•0+ `÷īŻC…B¾œ õu’ ģ¾ńFD=ĒüXF¶÷ĶŽŠę¹Õrʾ†i`GGś&y¹ĄTūµŲ‡‰-lŒˆR vAw! ! d…#˜_ĄžńćŠČmBØ"„RD„ÉFI¼1są uuķÕō™gvtdÆżt÷Üb™(‚żZT’žŠčC€«?Łń9lØž]żT¼ymĒ· ”R ę88唓ĪyęŁg‡”'D¹M׍{zö±jµ%ŁZ³{÷īY¾ü8 ة杜?ž#T’#P;v$/+Ćä6ōE(J3±[ćēc˜ŅNŸV&„õˆÓtöŃQ·ŠĮ¶z½Ų›«`Ō) Nó#[/€“ÆĮ)ģõö‚ų/Aåv€ČČ}µŪp•C|źŠ¢yhfU”3„iķ!Į Ö%M_KĘĀ„5?ķfSæo]yÓ$ęĻ®E‡%FöŒNøp %m4œ ź‰ƒ J±v­Ā,šĢJœ}öŁ­½Ć/ķ‘R-鬤ĖRīu«1ōӟbō3ŸAóė_×Ķ6\ŗ.ƒ€I I)˜ŃpöśQꛎ ŃŽsN3,M>lB‡³”I/&™×’އāąÅBväū1ā”Œ5qj%Ń" ĶZ E6"Ė`łł üTŠVåķüm€æ ІI‚•Ź\ŹI.p²ŒéÕr̆:ė*ęš*,“ŪĖĻaA-¦ˆL 5•ä (IqŽą;šĪ“?ŸuĻ$DæWg ņē?¶Q2FW NĢõhčµ(,#k|g–ūž5(…x’óx‰ė:°m»’Ģ6¤ā8ś?ń ”ŽśVŒ}źSė׃šę"%„1e-0hŁŽL!²‚łˆ €#|&dMGس3cP)…ax¾8»r}˜p‹™ÉĦÉI& 7 ¢ D…@ ZYńź`aˆŽ@¹{!żm€·@Ė.±ó²VYRå8 ­ćK‚#+d¦Ź2TŠ Ż|fCŁG©Żiźl‚” Ė gām+ž'öœ?å4v`ó8°_³Ł „:LRĀJdD}€ŒÆœ›}ĻZAų Ÿ+\+„Ōu唦‘€.7‚wŅI˜’o’†ąŃG1ńéOƒ?żt‚ü+ Z™^yĄ$lęµ,Yw∐>‡¦æ(„’P§-ŹZ#ŌƦÜvåzQw ŗD™hýme„hĶ©t}lĖń‡ŗÕ75øŗŠ{ Dpš ^PDęĮā„=p†”üķPŽNõtц!¤Q} s˜RÜ ›#a Ō¶¾¦īmŃ&Õńh’Õų’$9JĢ÷Wā-Ēż^;ļšC.RŻ)ŽcŌź5 ļŪ÷bŗļwŽĆõ'|ēĢĖ”—`xFAAHF£ńńqõš£~£ó½”R0µ Ą9ƒƒ³¾Łg->żéOüłŸźO˜ćü-!€ėzi’tĮ…"wūķhŽ}7źŸż,Ķm6R@Ņ:-°Y€¶ØĒš¼‰0Čhé#b Ģ„čņŠcĶųFY ±+ßé0PŠL[3Ūō$2™1¢ółA¢Zƒ`€ Õ„ēU’ Ą,¹P%HQu§¢rP$T ČH¼48 Ņ{Źœī™\Ś``įNaŠ™?0’sv "ŪŁ¬M­g˜öŽ22@—Ę··–=l1®[śøhŃō¦Y^QŹ0½Ž‘‘xjćÓ÷>ųĄ£€¢Ø ‚Ŗ€*'gW^apVWĄ€ļ¬Z„ž¹į­Ÿ’īwæ}|’Ą‡„pŻ“R ŪĀū`Tøā ®øžõæū;ČŻ»Ó^~0!8„S ŸIŹŌ$'rrŖ0pŠ*Ą)'!«H/¢“SŒ03K Į6RĄĘ¾„õĖt›nju¾1÷-s[“<»•:é€:+$ńśf£JOO{$SXD xJä‚8! bėŃa2Ź_ „§A©gAņOCŗ/(IR~jc ¶'™…v~)S}3u:Ž“uQģ9UęmJČ“±ˆł«1ĢŽ$µ:­$ć’ŗ(ØÄń†”ßĆeCæ1­bĀųPIgįz£‘‘xņé'7|łęÆ’Bˆ"”JB„äT ø²^&Ņv(ą“™]“n—i6‰DDĆždõźÕ €ū’ų^øhĮŸņ…¼ėŗp]Æ­5Ņt„Ę÷¾‡Ś¾ņŅKķ)Įś¼©5`~·.)—A …6 ‹%“ķö0¬„)ūtR—ė:éž7ļ‘*mņxq>ž.!ȗQ,ėóh¦ĻhūdßöČķ‚DAēé+%!¤Ą‹•…ą™RÕ”ć—Ću(‡&ø‹©•…Ö¦ĄB€p „j”)ź !X2’$Tn@²™‹Ö IĶŗ “܆ĢEŹŗG5¾ļŠ—?…I]%i¢,ą•|_$ւ€rQ± @hEō,AÅöCÖC嶤i³Plć-³“æ-˰€aPŌłžö Ū¹õęN^&@gAfpū"—1j¦#P"Ģ×eģą% ˆb8¾x.._üA¼nšM˜YĘ·‘1!¢0B³ÕÄųų6o~qĖmwüč’<¾įé­QR I…t©ŠņĮšB°V>†¾ļĒėÖ­“j–ččœdÕŖUcĢ-‹~Č’Į‡’×µ§æfÕMż}}Kr9ŽėĀs½Tbf‚@ÖėØ}õ«n¹Ų½»­zHĒBSßėėĖh Ō:P@×ö`ČüŽŁ¬S0×Õ= )d4fvĮ™ß“D'{|„’b^öž€qædöBč½y¾‹\>—ī?³æd!°;ōP U§€żÅAB“÷Š .˜‡8LC‰ŗAi{ 2  B “D !@"1 H ³¼ųs÷¤å¶iźlĶp›$Hå*@‹wł2 Õžēl—ą¬k•n"żc(ZhĘcÉ߬?Æ)dæĢqöĄ[qͲ”gŗó:"Fv¼X³ŁD­^ĆīŻ»kė{ä+ßśÖm·D Ā•TR¦„RŠN"įØ@(Õņ„lA9ŖŃʍ§ ą;r¶µs&Ö¬YCwķŚÅ,XąAą‡”ęJsš{æ÷ŽÓO;õĆ}żżƒł\ĪōGsŪĄÓ€¶ j7ß ±~=h³™ąÄ±ĮĮ„‰³½Ūrč³ƒlT”KˆÆķB@śūŪ„G6ō˜ģ'#Ld&za™sæWÄż}+PĶõ€_?Z?_ļ P)ĄisNŚōɒ  MńLŗōn)/FääŒ@āO/]>ĒapXy”” ķtYĘjD͘ƒsĆ)$XŠ 1€’„P,„t·C–œ*e¦ uhüģ™ŗŲšM9.ƒ®š@§vד‰Žf~!a|ėŚc†·xƙļ¦8JK*‡äp|įl\¶ųƒ8sš˜ e5¾”2™PÆ×±gxOcƏū[ß¾ć߃ ŒRRI(•R*į(ÅcB#ŹDHć8"ߏēE0<œ–/Ÿ«’ą9i’Å<Ļs¤”nE¾š<ßå̧”ä>žńß{ĻɧœōĮŽŽ¾ŽœŸK€BŚ‘_?£õ(…Ö}÷”uūķˆžs Z”ī‚@›_;ŁH€ĀŒū`ö‚ƒe5ŠMG}?y_šųd֟ev³Nū÷&qqļĄ‰x©0Č`šłķļfµ„Ąqņł<–±&m‡–“jKzīž”¶ö-GŪø]Ļ[8ˆR±Ē±Ń¢[„Łė“\4“qē AĢ“1åŅśÄD@!aĄZzÄ8 @ų› K÷¬f·¦…2EĘ)Č\cūŃŻz‘ķ‹H–e>«&’ÕjņÄõP€m镀zPhFcy|®Hūqbé"œ=xĪ|ć!»ūt£,ćs£h4źŲ»wO°aƓ·|ėÖ۾ڜhFWRRIQR*A™€+Ä1”4bœ‡±ļn†b±é”³…xxŽ pę%ż÷ˆń÷­ļm™\Ćzś5Ļ÷ąznj>g¬f•9~Öü—f"ĻØSĄ¾Ź"Ų°!ģź¤B¾œĒąą˜Cą˜™€z^*“ė¢Ļ¢3 ńäÄ Į"ä¦w "@[ N]»¤^ŗ(<™n ćn({.h .Tˆ&˾=9q›†ĻšüŖż Y÷%µdŅ‹W ×Y‚S{/Ē ށåå×įp©“ńĆ0D­^þź¾č©§žŗć»ß’ĮĶ##£-€(!ø¢FćSʄ”R(˜)ÅŌqB„4AĄ­éÆ÷õŹÖŅÕ«·Šå2+åÜUqģQĄURzŽ×ŪS)|äw?ō?WžøāĘJ¹’ĻץŽ›‹¦bl ­»īBōŌS[¶ĆĆ a˜ą‰5Š)ģėhwŚĢOJuk0“3y’Æn™Š|&" ÷,:{ż~Óy×Z'™½&X…‘9$½A rÅe jžmH@kž+l/ĶGč•u‰±=^ņ…”斡aT[ éhpbpŠ™(­˜ė‘_ŁV»ęxVćJcFė¶dʬ+‚$!@›@n3dļwVÓßÕ×,ŪąŠ^–@L ’M$ hę‹H"R_ ©H[ĶPā™˜ØRrčqcA~%–ĻĄk®FŸæ³!+|„‚ßĄÕų‰Ożä–ļ’č‹ūöUėWBE)•BHIJ)ī(Å#„FyGM †ćD½”ĘRJE·š˜ęęP©øé¦›Čŗuėč®]»XOOsĒQJ¹ „ܜ”^ß%Pī ĖėłĄūßżįć_~}O„Rņ}®ēéu™&!sE¢ZՃBŸz |óf`ļ^ VÓaE½“Ž™NŅ0³{½*×Õ¾¾I>JŒŌBdįB°å˱­w ī{vqČĶMM3Q‹Œ é°8 Ņ§P”łR>µ’ģŚŅ»\k]‹ž+‰H›ūŽO: Y#'0°`>ŠE? Śį vZ‘łfAD \ ĆO $ń³­¶U‰im¼ c©tz NˆÄÉĒ¢0š0†ƒMv£)Ęt—»C Ōā0mKĢz²V•ِ=`@V’|M>)¢ĒY‚…ł•XV:'õ\ˆyłćftßLEVŪ+(ĪĒzJp£Ł@µŗ/|ž…M÷ÜvĒ’y×®ŻcYO„”²ƒń=X)4Œ ĘŌć˜7›KxOĻ>;BlN™˜cŌ`k×®%[¶hk 22Ā\×uøś'ļJxŹW)ūļ’õ÷ŽpŹÉ'½{޼yĒņyxžŸ4K“8Į‘h÷„šMˆ}ū öļ‡Ų·jdr’~ȱ1 Vƒš˜šMØ(ń} TŅĄĄŲ‚ }}éO?Ųüł ¾0ńƒÆż;6ķJĀz©ÆotkĀd4õySW?‰ÅĻ(ņyß$E%Ū…É˜iO™øŪŹCˆ¼|ę|éń­9 ,^¶žĆR7€=-ˆh&Žb .-0š 2+Ō ›§;±   +ĘŠÆ?µŸ20iæGźžœ %P•dBpp.†š­ĘĒĒåę-›žxō±Ēæ~ׯ÷?fµ=!DB•JJ„RŠ3&b+1BĀ" s^äQ¤xæäĘ7NÕģŃž©čˆĪĢ `-Y³¦JŖÕ*­T*lbĀg® ‡q(øYAąā,;aØ’ļxŪ»—.]zĶąĄ¼!ß÷‰ēłp\sL7Ū#gLs“^»÷÷ć±{7¤ "ŃŁūÄLęÉFŚA°Ä®?)ĄĶ{š<×0ˆ1³„ B±³w9£ĘIEĵæ.Ń;Š‹žJ))“P ¹ęB¦§W ³pdŽm§üi‹@YÄAĮō&Š–€¶¤Šė>qAoæp(=Ö/ł³ę½’ŗÅ}Lj¢-ŹŪ;¼wßę-›v÷Ż÷cė¶ķ#mŒO©”ĘĒ—R ĒQ\Eą–ń•"1„NĹJæZ­Ź—{>ąĖ2øM¬]KÖT-b€Ė(g_xį²Ė.½ämK—-½¼æÆQĪĻĮ󼶙kٟ—“²ē»ćkwāŧ^4LoT&®Ÿ‹†ńÅ|؎;YŹśž”Qø9ŒŃł×Œ%°+?ˆf¾7‰»Ob\•2%cK†i`’‚øŠ?‘,׀“ÖŁMčuŒ>u ģł$T‚čĪėś|ó*ŽwéRø}Y@’¶e˜^ B-8O˜¾ŁlbļŽ=¶mŪv’Ļ~ōV›µ—Õö„J)•LJ!R»Jqų$V‰„T\)+E㨢x)ÄųųøųE ^&œ¬C¬Ž²…A@*• ”N>ļ2BĘ]JKN€¦[ Ō •r !åÄ”²Ė.}żŠ5k.|ėŅ%KÖōööĻ÷Ķ0Ēuį0§ ”"J鶚Å)HüµūS­S„V@‚d¬¬0ø€”šńŠ9†÷]ŗåü‘šŅ–³© O”Ū¢sĮ†!Ā D+h”ZŻ7¶mǶYæį¶‡Ö?ž@\ Ćō DYm/„ŒI”€X)O3?h,„≩Ÿ0ž|ń‹ ¼Ģ 9iA0>>N©µš¬ęōPź„”:PŹ„q(%NLˆĆ(gBPvÅeæś¬³®\²dńłżż'•Źå¼kRŽŪŠ4£…;\šĘ‡CZßśüw11VÓĢOˆy@l†_Źü‰9nµ’ Ī• ŹF»2-Į”‚"Ōa)õa¢²$;C¬mÓéw.„BsĄu±pį (£:=˜YIÓč\6$8-!cʓŒ[±dāhœ_I! 戹ÄÆ\†%żÓ(¼šźÜŒž1ėm™ŗZˇQ„( Ńjµ0>1īŽ»y×®Ż<µń¹{yōɁBDÓ[¦'4ÕöB*įH)¤«øb©Ļ±”’ Qę­b,²?;óĻ\«—! 9łA\ƒF£A]×uĻc¬AĘ“ˆhčPB‡SŹ%LĮ(„ģŚ«Æ<ķŒ×žzŁ¢‹Ī7oą„B”ą¹®§X@(ÓYwŚņfź>ģŻ9ŒÆ’Ķ7Ą(ƒć¹)ŚoriӔŽTłĪŹ銞:¾®S%¤’ˆ„ÄóóVĢ×ÓH:dÅZćv ˆR¦KŽ[Œ\΃ėP0JR+€f„äL¬€6³Śž+ń-żB@²ˆ)AcpŌj“žĖ±|ĆeŒÕœ€RĒqFāÄ%‘Ćcœka@…`’IJ©ĒnxÓµg._±ā¼¾ŽåRiY”Xœ_*óŽėh¦u]x® ×ó4°8 įł'6į{’|+pÅJIC}Ęǧ ÓdLžĆŠś–²Ś?Õ¬ö×7ø„ÄĶcwļRŹ2 EYó?{D$„J=E̟? ė(ōč0+Ģ”l†^Š[Lµ›ĪūŠ$Ö@{ü^’.@(\ ri§+¼ńĢA\rj÷ŗ“ĻŖ>ŽcDaˆ0 Åā8FĒØ7źĮųųÄž±ń±]££#[¶oŪõųƒ?äŃf³%:„(*¤ä„(J…¤‚JɘąBČ,Ó;B é+.¤ä9)yåETQÜÆÕäDæ(V«rppPŖW ć[zEKķQ5k֐Z­F¬{Šh4h>ŸgM×eN£įDŽĆ„‹‹)Ę8cœ2mp&%£LJ*£RJ „ČI+—W^{ʧ-]|Ź@ߥIóęĶ;~Ń¢EKśūś<Ēq§%æ~ųõŸ@I˜"Šb¹×s0IóŪfōu„ŒöOÓŽŪµ?W›z—ƒ;&aØ«łßyÜl‰”åK‘ó8Œ‚Q€–LDKݧéZ“…”źR¢«@©€z+FlAaĄA).:„oZ½čŠ—IéŽŗūŖĆńöŪ÷ģŽZ=pąÅ={÷¼šĢó›Ÿßµż„QkĪķĢRH ¢3õØRP*)RHG0&¤fxGĆō1ē"' <Źq‘‹"ØT*‰¶/—ĖjŻą śEłų‡¢W”°Dڹ¬]»–TU†ĖHOĻ>Ķår,ŠņŌqˆ9s‡9c1‹˜Ć™‚3N)s˜ V (Ē!RJŖ”"åRŃūāžļ-CK†<Ļ;¤ŲņĢV|ć¾ %`Ld=Ž„9Ź•"ŗ„ϖڵĘÄ5ą•2Ś’Ė愞„¦OI-€ƒ<#¤B±RÅóR+ ‹iD ±f"ŚNkäbj‰„±B+Ęd·aM.tØš«ēć’.¹Y’J"Ž"lݾµö‡ŸųäŪ«ūǚś/i&Q„E8Qœ¤~}–į¹`Ņq¤ąœJ&¤®w…Ģ)Ī9ω(ā"—‹D”E.W“Źe9•¶×{~å1ŪĖ4źff¤2@}ē;ߑėÖ­“7®ågUāŠ©’сåŠóZa±V‰Ņ¦¬³&ŠjĀq„D 0ŽX”7g ŚHS*“…“2ųć?üČ'śūūŲ4śüU_Śo~į»mĢÆ„¢ˆ'i½ö›ž‹o<éG—XśČŁ”€½e[£®™?ÉĪ›’TĘ%Ń]Ÿ˜@ņ ŲØT"|Ū{hv;Lˆ=&A$“ßĻØ¾¶ŌąÓUŠw>¾ĻģŖüøŠ«æo üž÷æ÷O@!„’9ąR$ęœD‚Ґ18 -©ŠR -ŚTi‚ņ"Ö Ž¬5„ JƆ¬³fNŹV±V.ŹåØFāsć×ņuėÖŁ“]Õq/æāčit£N«ø k×n$[L(1 —‘ĮĮ1Śh4hX.ÓRŠĄóX.Šhč8ĢēœĘŽĆ\īRįrŹbŹ~ó7ż W^uŁēz*½Äó¼I„ÉYj֛ųĀ'愠źa°f ¬…@@)A±\ŌQ‡YųūŻČęŗ·WżI% •Ā>·„}•E „MßüĻ\ŪæŗŒøXĢcŃā:¼˜€” é £¤Ć Ȅüf°/… TˆM;y Ь% ”sˆĀ‡®^>etĄbA`xx/n»żöĻ|ē{wÜ!„ĢQ\)‡KīH)‚2&g2f\ŗĀ±KE2ö<įs.Ļ“n«%[Å¢šk5Y,åßWÅjUęr9U.—Õŗuƒ xåkūntŌ€,M% ŖÕj‚š”!2P«Ń8 a¹AKA@£(OółˆĘ±OƾnĶü÷½ė?Ÿ7o~)ēēp0 @/|ņKÆNh` ¦Œ—h Mw2U…A©XœÜ÷0ČšFšóÆ$ѦŗĪ ņÆžė? īĢ̒̉’™PX¼tÅb,Į“FNz”Õ“<Ć“āH”%8’02)u¶ TZ} —|ōĶ'¢œėž'`Ć{µz Ūwl ’é‹_~×ÓĻlŚÄ1į4"„FŅS\*Å-³»‘')m*Ėšuߗ~=/s¹š,—Ėr×®]ŹśōڼŽV¦ĻŅQ)²t0aV ‘0 I£Ń Bō“’Ęß®[øpńźB¾˜ŒdžŠ¾ņW_ĆīĶ{’ʤ:ĮĒ ä6SĘ(?¢ ›x”?~P–łįm» %%æŲćWp 8„801»„A§ŖK”’PŠ#ēūX|ÜJŪ†“%™Ś žąB”I¶!ƒ¦³‘® ‰% 1²OńŃ7ƄėtߟR qctlĻ<óŌ¶OžŁg× Žtƒˆń”F„xEĀ÷}YĻē%QÅbQś¾ÆvķŚ„|ßWVĖk¦_„€›€£œé³tŌ €,‘É\œ°Ā¾š÷Ÿ\ŗōøO‹å¤āp*śžĶ·į釞MŠ~JlbŃärå¬Łļśryļ°÷ŅöTūé^ü š|ßq Ō5VÉTÉ?‡:”ѼRA))9.B¹T€Ć„mĄIŠLŅ™-I©Š E‚-t #÷’„!®d›XŲėį]{ĀŪŃ×) ģ?PÅż÷ß’ĶĻ}ńĖ.–'s­Ąć!§4.°ąev˜Šįͱ¦9¦@'u<°nõŠŅåVŹĒ÷}Bó·“īżĮżø÷¶ūŪ™ßśü  FėęóēŠyøī̇ˆ“™žę…nI?RIģČõa<ßPJ@;ś Lū¤¶–_RB*Ļs±tł2ģ² dV€R@3C?3BĄ>7f4}ø¹±X5TÄ{.Y:Å94Šl6°gĻKņ¶ŪnżļŽń£{]™kE9°F#l6›¼#9Ē~Łć³LņŠŒĢ©śŃžĮ˜7xK±Pt\ĻÓŚrŠ{vŪóŪń³ŪļK›efĄ>ż˜~h*Ą/l|ę]›Ūü~½2-«5ĢZ#Fs½š[’Łż ĪØl–O[ĀO†MĀqŗ©‡Ō#ŪĪc…ĄōĶ€ źdžĢ:’6æFŠŚź¢ ŚsØĪV|zg÷?w ė9l/‰\.žzÉ„—žķ Ė—Tb‡ipø\¦œsR.—³!»ĪŪę˜e~ą“dÉEŻŪÓ·Äv"D›–Ä9Ē÷¾t+€“ŖO7ĒH;łX {0“_)… čtŪiR³öÆ õ)¤Å3PąPŲQ4)Ū«Ńł™\żĮ¤›® ÉŁ ģŪ‡ ŒĶ¤[;COfš}ču¦BėŠB Œt©®I6”<ƒ°•R$®cŒܹa&Z¼ūΈQW*–14““÷moż•OAr€ėā ŠZ­–,ųXgųNzÕ€G}`Y„§÷·|?×düMõMßś•;Мh™Ō^¦Ķ~J’Ń\€f|{Ÿģv—R"hLOXÓæķµ¬Ö×ö ”Ā.§„˜éĢĆć6Ó’Ś)۔ĺ8€ī °g÷NS; ‘Š2ĄŹ&č*?’Éī›zÆQ,‰C[EmBĄ®Š ¢›•0¢K™„¾ņ_Ūr,×uP)Wpź)«ŽxÕež.„ļ)]Ēqœå2[³f pĢa×Q@ÆĖ•æZ,½l¼æ›ößōäf<³ž¹$>AFM›D½0=6B YkBšƒOøµZŌčüLÖō3ƒžz0’+·­'ŹOsUŻ)ײG  äIlzś„Ķ<+ Sįb×;łĄ­P"œKd…@*œˆ±Ģ÷BmSнcžkćž)ŽC@)ƒļēŠß×O×\rŃ_K—ūĀSJ¹Å*œjµJ×®]ūŖb~ąU"z蔫{zz/÷ż(Õ \7K/cÜņ•ŪSŠ4É|±7@ŚÓ4I)…V#@u7UŪC~égģ0ĢeĄ Ė“tc+œō ’™­©cHlećˆi?ÖČ^x.Ń}šT‘6F”2b£KĮO3ąÓœ ™RšŃHŒhJ’®—@g RJqדUŒÖćīG"ŽĆP,±bŊ“ßõĪ·¾ÕåĢBx® '—Ė9[¶lyÕYÆ@*½„/åóønšėßM|÷Ė· h„@RĻO2č¶=Śį…¼ģ9ƒf€ uüķ`d†ń­éƋe.zćŲy ”™3YD¦ćƍĪ”ŅVß$Į“Ōęį‘®?{”īå'Ņ =%Mč&‚`ӆ  $ŠÄ pĪ “ą $ķ¤¬£2¶•9ąP ‚Æ®Ū1õ …ļēŠSéÅź×žõ±žžŽ²®/ ‘7Žį ĘbJ:꥜GśxO„÷8ßĻ™>¤ė„ā<‹MOlnCżan.ɍמ;LŠĆ­zŠnkg›ćÆ’O»ż.X:ˆ³.z-ö5»ß2(2‡:gjķægĒ^<»ž9š˜#ŠxŅÕ×fū͵é?)x`s¤ˆæäZń:V¾vĪæź¼¶cŌA¦üÖ./#f{Ėf÷LR6Sh„ķ!¶3–Upö =h…\čÖ]H:śŲhF›%0ėėi]•,Ļ&)P±0›»GlŲ6Öõ„„č.N„b +O<ńĢ _öšõL gLŗ=ūö±WƒpL €BÉ’t>_š<Ļ?HŲOį{_¾Ö܏Z„Šé暲Ł~³&•ņ¦5ż³Y~H†zhzŃń‹pķ×LZw£%¼© ·’$evö MZt€X‹€M¾L#Ą5Ɲ3Ž«čzÓŗK …lõb"Śņ¦»ŽÉ@,”tķ5ZŒvgŒ€1Šo=ųŅŌG%®ē”·ŅG.ŗč‚()=å I‚Ē,s›[·n]oo„÷Żv¦ąTaæ-ĻnĆÖg¶gü~ Ø@†¬&œ5[eœž¬œ0Gf¢P ½ó{ńīßæ1żx†‘Fk­$æųS³S­GCāZšH ÄŲ;ZėźF½óā! 䥄Lšx ˜ŁJWd³IRö;„ ŅåyZńh„ĀX˜&­0iĀZ°48~öl÷b!J4P(±rÅŹÕžwöipinR§22ĀLĄ1ks TŹ’y±Xņ}Ļ„4) m'…ļß|»Év§‰ÉƔB³ÖŅLoCń³żŚĶ1²…3ZėŪ¼~ÓńĘ“öŹ—rųµægŹEūG­˜h„h…B%Į·9 ½Y©€0˜hE›ha¢"c“¦(ø€ß¼j9z .¤PmB@J;„ĆāVL‘Œ8¼„Zk"ā&Ř njż|F€ŪÖļņ4„ų¾Žž>rŃEž>”r””K¤tół<;Ö­€cjcėÖ­+õöõ¼ß;ņ’ŌƱgė€d|~cBK.Šj†‰²9\ž·ńš¶²^ØL­ÕģŹhžB%_’ų{Q(¦śęźĻA™ƒR`Šø&Ńö4ķą`ēEŸJ2č†A ŅÉĒę»LݘVfĄŻS ™CĮ÷}ōõö‘ó/8ūw!N§p¬FŽ-P*}Ą÷sIĪ7ķ’Ņö=Ų½ł„¤Ä&ū$ž¤a¬(ˆ6Ɲ?ŃśöŃjłÄN;ś&ćŖ”ĀŅ•CųĶ?żņÅÜ!ĻÄ1H“tŽ—ŻļÓG8ųńŪŽE@ O£–‡Q‚½įxœ¾¬ !tė.!m_æŌ%P\Ą<’ōµC‘n'ĘwĀ¢ ™3B^Ļõ–ĄśĶcmǰ†1X@±Pĉǯ¼øÆ§§L7k«cFü÷Æ{C¹TYä:iÜ_ˆN“UįĒßŗ Ieæ¹¹³)æ‰^% Q! ŗ§”v£¬&Kõ›@˜ßĪä39žÆ¹p~õ£ļ:hWā,¢¢ų’^?ŸF-?¼ėõCX³ŖBIp®€H)µKø?€RŅ>‰ļ'H'śoW¢L/A“„±Ó—™Ų€ˆŽę¤%ĆĄO6ģKOÕqLBu”ŠĄĄ {ķuW½§ ŸOq ZnjČŹós9Ųé>ŻL’f#Ąó¼J l÷ܤ-ڵ‘A3Dv/1M>„²æ 9ž²~/d2Ve2ü.}ó…øž}×ĶhŸūE݃¶ōvś·ĢĪ\€_9wt;o!T’# ė”.:Źpcr)Išż‹” Ą¶KƔ“ꀐ¤XˆŠ#^ ¦ŲÉ,•pʊ•7PBøŒR§^§NOĻ>¶ś“Ž pß}÷ VŹ•K\Ē…ėź^ńŻĢ’{nY—4åŠÉ#4Ńū¶ø„tqü[aG ƕVėۘ>T& Hi€>ėóė½ł×ÆĆ%×½~Ę{õ}§#Ü79æa6ŌÖ ÕīĶsיłķrΊ^üĘåĖĄØĪŠćB$Źŗ¶ļæĢTAjō4™ˆ”0æD#Œ;z j!$°M”ZL€$ŻŅo]æ·ūB ĄC.—ĆŅ„Ē-¼ä‚ Ī„„8D)—1āŌs96>>NcĖ 8&@.G?–ĖX.—Ó­¾&…žō-ōšŻh„ŲöųĖž3ņjŠÆ7l…šaĘŪL?k$I/Ę÷oū$¼œƒ÷|ōx͹«oÆ®c„OÖܘ«0`†ģeIĀ! žat8€ńæßøyŸA™tōµQI;TuXŹžZ§'„Å]„ž­ą4æ'EB4£ĘžŽ9` 0ƒĻõQ.•qÖėĪx?‰įĄ€|£Įé±V)xL€b¹ē½¾gÓ~;Ķ}³<ö³ĒŃo¦šžčξI}‰BWퟄ(ˆŠØ5“jÓh IDATü}ĖzÖXµZ?Õų:N/L†ß²“—āßžm,[1tŲ{-ųŚĀ±UqmķøęŒR+ åą†`i^ŁĆ'~y%N*źöŽĘÖPé0P™ä čóĘRŸ?•˜,Ņ­a`ŗ k‹€BHąĪĒfPŪ5čœK÷ј8€rcĪĄośvtųGG½xą{/+Kó]×M€“Nó_xąĒ?OĄ! ūh ”ˆķG?5)(šˆ£Qk„ŚŹ ūIŚ«TPģ3!>Ē£øīWÆÅ{’ÓBśF…‚‡¤óN{œqØŻ“& óėǜēĪźč#xĻ%KńŽK†ą2Ė ©§’f\ėBI(‘@Żh~•iÅŌu–ƒiB`§}k—Ąv ²aĮ‡_Ÿrū„Pxž‡ŽŽ~ē’KVßāP ' ŌÉåj¬18H׬Yó’ €W ¹¾÷~Ļõįyz OźKV_šˆcē‹»Ó:hmocĒŚ-'S²Qz³i7AÄõń:x̵Ÿoāūv\—Ų©™Ńń ńįæų-œuŃkēd愜—±>ڵįŌ;˜Ł£uéPČwŸÅ7Ó£Ÿ6TĀݰ+äō”.Į%’©?ö§ŽŅIML•™źĀ¬ @› °€uėˆéd-?FFėՉ(»¤äIH°XÄńĖ–_E œ˜‡Qź4sj5z,%õ X(^ćznRõ— żŁūāńž€āRI˜¤@žńĄ){£)}óŲēVŪ !Иh l…IL_š¬> ā\żöĖńėų^+ÅCģĀ`2ķ4UJ¾ž„R ɊsøiµŹBŃ&P:ČØ3‹»! „HĆ{é;åTĻ”ųĄĒį.cŚĒ·™‹kÄcn2M×”LZ1‹ĄŻöOĢFr 3MšJ@‰Āŗgöw ”!ŸĻchhŁIóTJ„h,Ą –€ĒHHšØwßw÷„Ry~÷Ž?©ļśŲ}PČ[&  ü³VA6!Å yo3óõ` .9šõ&źµ:„і\2€’łēÄyWœsˆčćq.E‚0@ĢĶŽ)„@„˜K= „©,x9ĖūŅųŽŹŲ©“”P.ųł˜DEhµšh☷#ūSŠ™Ė+ųÄ/Ÿˆåƒ>„Ø·bŒÕcD\芔4X“8‹łĶ#0ĆJ”^£µī²W‚ĄD}-öC žÜ61嚈IīéķeÆ?’‚_¢uŸy÷*\æz\G!6¹±©-ą\fĄBˆD ĶĄ4×D'‘LBšŲ¶)¢ČDzzŻĖ/æąJF9c”27rXęéąąŲ1į̬ū !×/üšēz$[öŪ-&¾łé­)*Œ4„«”J¤€Lš-@¤J­KJéŚ{Fpö„gįś÷]‡|1?­õ*˜\ś˜£ŽØc’žŖZ’Čś[¾ü/’ö9!„āœ+J©ŻĪy|BÖ¼ĻRĪwQĪ;Ø©yN2ēl“ŒĆ¹/­9ō™(NZ68łż”Tˆā££c»@!k­Vš¹śź^Żī7¬Ysé -Yź÷T*š}„ŚÖėŻŽ¦‰ąŚ×-Ą•gĢĒ-æ„ūžAĢ$ŃS©RÉ<›،{g[;š#„ĀĢ Hóž—FC4#Ž‚7™ !pC±XĉĒ­ōŽ‚Chą0³F# Q%nĄŃ:TōØ…|įĻėÖó/ż6?»­z Œ0“[ƒ9Onõ$ɤ-“Кߘ•®ļāŒóWįļŗ=ż=ÓZ§=¦Qb¢6;wLüčĪ’ü³»ļłŁ£QBÅ“T*1>>ńēü2©$€ī™w‹śKØķÖŻyˆ,“žxJ‡½fN©įl=źÄ P że/cį“_)-ŲFĘF·DB•J( žżŪ~|Ū¦·üüW~åśĻŸtāI'ō÷õ#Ÿ/€9̌\?øĶā:o»p ®[½·><Œ‡7"ŒØ2­ĄĢ,ō!¦ÓØA„Ž „šąó£øņ5‚M“N Īcٲågņy·„‘"ŌQ„8q¹L›Ćеk%ōhń£’ŽJpēwVVžtĀéŽćŌü_Ļ#šØ}Qk3‰l€K’›śØYRƒM=ƒe\ų†óqéuƇćNļ’„u1Ńl6166ŠĻ>żųĶ7’ū'ŒŒŌ9ø¢’Ję8BJ%8=0ņ$ēܤݼŠå‹{ńĀī ¤w¶2"Ķ›‡g•¶”Цæ‰`É`/¦bU„Ā(āźČf!ø¢ŒIE ā˜PÄĻmÜ“õƟ’Ģ›~ķ7~õ^wÖźwō÷ Šr© ĻóĮK»1„ ¾ƒw¾~ n¼x ī}f?ī~j?Ŗ‘Tha Ø©ńČ Ą^H%-“ip<²ylJ@ļłčļĻ]rń9’ōžuw)B‰ę„ ¶PŅ5ÕY—&…utT €bŃ»Ń÷sĢu;“ڽę6lJMyŽÓB =¾m}\źÓĄ °ģ¤!\qƬ:ū“­ĻšūB“Z-Ōė5ģܹsģ¾ļ’üm·żä®DėS&©£„RœSŠ„Ä/ģŚžˆͦ.»]µb!~ņšŽ$PAģϬ¼Ńö{X)“ZkىKū§Ü«qcŪ®ŻĻB”R‚ĮјFB*.Įēžé_žäņĖžūīeÆæä3'®XybOO/ ff#5cŪ¹J¬9m֜6›÷6pū£{ńĀž8˜Ņ‚ŃTĄ†„ūʆµ0ŲZm"ę ®3łÜ„PŻ3°Pĉ+–æįĒ?„’傰Љ'ėo4hķ(wŽJąēü7LYłg¾‚įŻUŒVĒĢ4`3aGŚWāF" ģ®Ź@§œu.Ė„˜·pŽŒÖ•5÷Ć0D£QGµZå?±įÖ’÷Æßüē0 c€()…¤ŒI„Ą9W 1!qD'|ā‰gʃ ÕRR­ŽN«OŌĻM2{Z°‘ÄŚ9< Ą2=± IR Ē׬˜ š˜żrÓ /l%ŗĄB2)¹PŠ ĘĆ“=`€B©gJ…G·Žįü•Ż;1Q3EhĮĀŧS*X¬”C u¼Ąaa¹L›ĆĆGµpT €œŸ?ŪqŻI£¾³ßĄs?—˜ÆRQP%!‰…ĒHšlC€ž}8uõÉ8’Źó°hŁ‚ÆĒŚBÄQŒfK›ūĻ>÷܆[nżį_=’¦½VėSJ%SŠ(NHL¢ˆ’P*)Bāz³¾‡óxT¾+3TJyr -n&r*šĘܝ)h…‚‚Į:+‰@ā5+» „ēo6›ÄQ”ÉįH„b®€øé8‘ŪjI.JÄq±ŹSžµo~ūk?¹óžŪŽqć/’ÉŖU§æipp>+—µ[ą0§Ż-8k•óŽ~Į¼ż‚%©ĒX÷LOl«aßD™ŗ Ö#e-xvwķ Ąó}Ģœ_.õźńˆpʈ27=04DÖT«dŻ“Æō+‹Ž:pū·—O]pņ’ä&µŚļ’mĻoOĢyj,’'Äéēž† Æ:ļ}ų¦"«ń-ŗß ZØ×jŲ¾s{uŻĻīū›’ųž‡:_JĮ 8$‹€(†RS4ō„Œ eĒ1oµš/ ĪWh7 {¤vA_[÷5Ūp bŠeōĆL,ĖüŅ<·-ēx]°e0Ž(Š06>ŗG¢(8'Ź…J¹h‰¦ēÅ9ʄ”¤ęå…ˆœ”ņĄqńł/}åcēœsĘWÆŗģŠæ:éēNķééE±P4ųM¶LSæö—\ÜpībÜp.P 8ī{öŻ2†Ż£”ŌƒmøŠtmī6B,%Ęņ…=SΒé]÷ż§$‘£(u”氁ZÖLdє¢U–ĄQ'ņMv™ėŗÄ&’“]ļĢÓ›wÕqbĒ”X²b1Ī8ļtœwå¹(2?jjc|Īźõ†‡‡›žxüŪ’ž·|-ŠbpHI%eLJ©„CgLʈIL€(¤$!‘*’H:åx< En|\atoG×H)A©źźŸ°ø[÷6*µD3žĢįį&"’„„Ż% ”§ü¤”abļŽ½O!BQŹ$•’_{_$Wu„łŻ{ßĖ„²²J*9Å¢BHBT˜„ĄŲmcLŁm¼m\ž¶§£=ĶtOĻø§ĒaGĢŽ™ ӞhÜć·gŗĒöŒglÓ^  VƒŪl Œem‰Ņ¾”Rµgę[ī=ēĢ÷²*%Ŗ$Ą”R~ D)+3_ę;ß9÷œļœćˆtŽ:Ɛ¦–.„ģīŻāFG©£«‹HkVŹ8Ń“ėžŻųŪßlüŌu×ä—\|ń—–Ÿµ|é¢īEČē;ń3š<óŖ‰Š9ķ? ķ? ”e<ńĀÖļ˜ÄČhĪ%ĖK™½cõ® Ć?ƒ3ĻXz©Öō DeŒQ”gĀ8«JĖjZŽ”QK“ŅŠŚ@©d§ŽŃÉæ8ŠŌźxė…ēąģ·.Ē9kVįÜ W#“[ø™å•`Öš)ÉģGaˆjµŠ£Ŗ6løó§wžó?MO×cĄ ³f„=a֊œÖž#X« c0¬1Q”eX0[8g§¦¦huo/”·ÓćcwÄq|“#š-s+/]…_­ß ķ5ƒŅ†ų¤“ÖŠ¼Ā{s¶z˜xEāä8cc‹žó’Ó`Ųŗuä1„”ƒhćDiĶ*öXK3ł¼t:Ä«śśøR©p„RįB”ĄZ3M²&0; vkzßO6tĻ]×öcŸ¾hMßæ[¾|Å鍈Ą÷30ĘĢå^„ŸĶłļæ°„÷_X‚cĮ‹ūg°e_/Ö°óP »×±¢4æŅQ!Ł(œõs]ĢF{ ŽM”Ż™[®ūŌP ęZŽXDĻö|5ÜMĻd3øéū_}]^o¶,Ęb‚³a`¦:ƒ÷Oox~Óķ?Zū“0 ݬį+#"B Š”ÖŽXY@YhCėXXY€bk¹Z nÉĢ õ÷÷sć*•J/æę‚±žÅK–p†ĆQølĶYˆ¢“u ĻĻĀó2š}o6‘¦“nÄ„‰č¦é<}ōZ2°ĄQr}ŽŲ9Dzųč{Ö̒٤ْÉɉč©õĻn„5k+6¬½˜µĪr„²ˆūū;×'ƒƒƒ222"SSK¹£cū¾Oœˆv"ā†~z×O†äŸļųäu×\wÉÅ~įģ³V.[Ō½łŽd3™“tųŹŖóĮÓ }½]čė=^æFŠT« 5|QlX‹ņ“{&’šv½:_Ó{y³Ńrą";윃sߟ?<~=Š(‰9Ų8NBżZūöļ›|nĆó?ŗū§IØoq„įkMPLŽČ)„c,t#ż{”'WŅykm…V Äåįaž„°” .Ąæ™ž\Åчs¹< ēOč]“z)~³åČX,  91Ž9ńū+øŲFĘNö, 3Ī*ubqńHĻŲ1 ¢0āƒ¶@Z§ C;Fč3õd8›Ż-C蛿Õ H„BR(x:›%=ęH)ķ Ä‰Hęε÷ßqēŚ_Żõ±kß÷ŃKūū’råņĖ»ŗŗŃŃQ@²ųÕKużæ?EūlÄgcT&Ę·yž("Öhd „ީΈ"U©TZ2ŠrpĶ5Ÿ|īŁē†«]]Ż¹\vvČĒėŃ ?Ū€$£O”œoėõfff°{÷®7m¾ćε÷ŽCĬ”f%G¾&rŹf ­B×Ū‘†ūÖZ‡eĖ\|č÷õõĶzEQJ)Üx#¦~vū/ā8üpŅ[oęµå¼s5~³éD{€0”čD '’hwgĆ¢cÕÕę s]sä÷® {xt3˜ abļ¾żĆJ9њXŒŲcķGŒńŖų¹œ4Źd ćPJ”\.3"ąhļ^īīīfĻóØŖµ³ėP±"ėßu÷CwŻu÷C÷]sõUWõ]tž «W­¾xq÷b]č,"—Ķ”ŃŅh÷}=Įˆ¢333Ų²qėć"¢D<å t¬HI'©8ŽU6»p«ō‰Œ–"€FėåÄųįotw/śĻł\™LZi^ŪĄü#Œž L ē,‚0DPÆćšŲįhūKŪ’õ£OÜśō³w$Y}'J)QڰsĆš ‹uh닲eEŲfElh­«•J®P©poįõ›=FƒĘMü,Š¢o3üJzxēyøłū„ēźö‡6ʁĒŃŚ6r™sĆL µW®™÷×%1ŌėulݼõēĢ$ššqäüN¾ļ“2Ęę$ņ”ó6`—¹ēžGøēžGY½Ŗ÷ō«Žż§ēÆ~ėGO?żŒīb±+e2šŒIóCæ;HŚä4SĘę-›×mݲm<~ZSŹ2+C¤@£=øÕŠRŠ0Ž’ųŽÆŽšgŸ’ŁLöÜE‹z µ†1ęØq`Ē|¦T –*ö˜@Ī!Œ"„a€z½Ž=ūöģaėÖµwß}ߌéé ,ˆ”h­Y#ĢBZ)mˆXœœÖmŹu+Ņm­]WWYkiĄåM›fŻģ1BEyąö]pњƒ==o9=ćg0ߎ¬ļįÜŽÅxa÷4D'…m•Ŗ^IK€J‰#łLŅw Éōtf±złŅ¾ Fl-Ę'Ęėæ}~Ėv„”8(1šX³qŽą(åņRiNVpÄsĢEG ˆø§§‡ĘĒĒļūع,ą“.x×2ŪGöīyiĒŠMZŁÆ}äƒųšŪ޶ęW®8§Æ««K är9$Ÿ™c3 _}6]ÕZ »÷ģ®ß>t×ß&’ā`”!ʊh-bŒä^¶€¦uŠRŠĄÄÄæ°mŪg …'ń¼ĪĪ"“ѳۀ¶«¹Ÿ&£'‚sQ!ŒŅlžĮvļŽóųSė‡ļyęhoƌ™Y‘!&&b߉ˆĖ@Y(ceEŖ.1ün×ÕQµq6›„M›ś82Ü?Ö5øajb]Ē×åó ÓŌÉ،«śĻʖŻĻ%ŸT÷ RqбéĻ•‚’Ę(²„D„J—žęüo.M$FQˆżū÷½˜<„4keÉy[ĻćB„ĀC„łµöMßϼĒJ‰ Rår3–¹ęēµ¶œĄg’Ž_=p÷/īš¾³–-[zÅ»ßń‰•gŸż‡ĖzĻZŻŻŻm:: ČåņČd20ŚĢź ŽG'ÕZ•Ź(yģ±’Y9<>ÅJ‰8ˆ6Ä¢ ĆęŖ‘LgFŅ(§eĪž “$ĄßŻōwžėĶ_¹‘Ežf‰³¦³P„ē{ŠM ”Ģ®äj2ś P­Veļž½»vīÜõȓO®æ÷…­#ž>¹”•L¤X)ĶD cˆ(IR9QÖ²°:,P·DE×0|k§)Žs²½æŸ·½rĆŸÅŠL}ęć?£ąŗ"!ʛ7pĶ•ąŪkŸM Ś*D54O"ĒL ŠdüHŒ?C ĀųлΛ’÷Rõ_Ō±gļž'9cD±ņĮˆ}Ņ:"Ü|ž?Ž>`pP**\,–tJĘc$£ŗEÄgĄß³’¾Ū~¼öŪ¤õ’)ŽŻ}ÕW\»źģģ=ė¬5‹-ņ Čåē"mtŚŲü”&‘8ŽQ™Į”Ź(Ö=µī—÷ŽūнJ餓 EĚ1åEˆ318P”Ė//½ŗļ÷j±÷ŪČØĖ.»ĢXk37ÜpĆe—\zŃ÷–±le”Š™äLRk½uQ7’9nļ¾½ŪFFv<üą#żāąžŹŌŃFÆ439%Ś""6†‰Ų#_ı/JYqÄģH)›‹;ČZø®®ˆ¦§§)—ĖÉšŖU }ųkŗ1”Rś–[n)|ąź÷īķ]žéČfēĪ!yŹ?śėb×”Źó”Œ­= q†^ø0-„™&Y0Ytd÷’Ćæž×[21źõFv¼${ó×>±gļĮ Ź’Ö‘@×a\“®wA6›µår™åXŻMó_ć…Õ@„¢*•Š.•Jz||Üų¾ļ…™Œ15å)%¾ÖÉ­‚§”õŒÖ†H›ī®bž}ļśŠźU+>Ņ»|łE=‹z2łd³É¹¤l:§(¢Ó3SŁ12ł`łŃ›)?±.1&8„TĢ‚ ƒø †ÅØÄ›śśCCÜjŠr@ĆK‹Eٹtė­·>÷ƵÅwń/nųė•gÆüó®®ī|##œfńłŠ”C‡U*[öģŻ³ī”xbr*„³ †Į§į}ĆÓ;'lŒ!b!O@¬”ƒvN1;ē‘8*ˆė\4ŁÓA…J…³ŁoźėK<Ž< ¾W{©O?żtż’·æķÉŅ[–¾7—Ķ„ .š 2 ńÆ»j žžöõPbęĪż"ŽÜ{ų2q½Ā9€ĘBĘU—®˜?T–$ū„vļŁõŅž‡'•RBJ³ÖÄŹ€TģČčXē’ć^|Ó±CCRNˆ@*&"žīé”%33:WĢ™éimØ{¢µ§Ņž}OąMNWķ]?æļNf³6_Ģe®z÷\µāģeWžV:żm„RiY”Pš-åĪ9LNMʛ·l~š¶Ūļžļõz)"a­Y!²pPŚBŪ KD®«+¢l¶Ōnz£Qą ††ŲZćĹčė_ūö-Z‡ß¼ā}ィ÷ĢeZk„>]yģ7럟šš:b±ŸRJąybɑFOD¬ČóA,Ī <ŒƒĒĪ„bßEEKaD£Å"ŖU^p¹aųÆŃćχ”!ąśėĒæWļ­æ·ŠY„1ŽQGłä%®’Ć‹š­Ÿ #&N’ĢP:‘ö%ažQšAŅ/©Š2 ż“I› ĘēÆyū¼ļ)ŃEjµ*¶oŪńˆ’óæ%›„ØØ^Ńł’x8Ģjtt”ŗ»»),mn¦C)Æ®”§Bķ)ĻčØA&ØĘńż<ō "}æ1¬½\.óö‹.øØ«{ŃRĻÓŁĆcć{~óŌš&øFNC‰¤ _ć”UZĒŚPÄŠqM©Ų„”³ÖR__ßń’ŗ',Z’Q@ßą =óĢ3*K=*(Ōu6ŹØĒ^÷<3m3š“!­“ĄH:f”hEL¤Óš^“E¤A;‡Ų'äĉXŅ`ēŖyźģ` ¢ˆ …ˆ«£Fw7Ƥ¼iÓ£ˆ^ߛ`Hzhńm«ĪYż‹-Īł¾ß¤ œ{™Œļአ—įįgöA˜ “ “„`Ŗœ“£I7‘>‡šģq@„±śĢn,?㨩ĘCE`ć“SSüčćėīQä!-ģ‰GJ<2¹˜0¾Ŗó’ń0€䑑F„¢ŠÉńĄņySgc€Ąˆö R2ykće,{ĀŠ>ńä³ė4‘ĻS̬!Jyéõ’R¬±Öā`=RQ¬8ņ‹\&cĆZÉ­XnE p-;He½½½T+Į‰ļĒŁ,…Ģ* _ Čph˜CmLČĘ„Ś˜Š0‡ž `‘@ ź¢T]”­+åÕ`LM“®iÕøjźZ×Ć0 ;;)ĶĒDd³Ł¬ķļļwĆĆĆT.— M%½×ÓųÓē’_|1®Œz, ‚“>?V’O®y{:t³éOźŻ!Ķ}©?sbŸFē_c»Ń§Žß4娾žļŲµc{„26MJ é$üg_³ø8Ž©P(p±X|Ż=£4€ ńšš0õõõēū~<66uvRh­ @ąHZy šIDATĄlźĘÄ5Ńŗ¦”WÓŚÕ ]M9ScAØŗa™½WHėˆÓ{…˜C–LĄ@@Y¾sa&“‰JZŪ%KfØQµhEļ“hĢEår™ÜNßGmŅtE¢X‘6ĘJ >ŸĀ0 £¢ €z]<ƦTT “®©¦{‘©)×X©z‡Rõs Ć0ŚēŪÄųW1€–Ėś–&ąHčļļwDdGółŲŌjQTTAP©ÕUŌDjuõÄqäā8\“hQH£]±ļū żGżł…7^kēĪīą”Ń‚ ĶŖ4RpżÕ#ē)°øTŹ›Aół©ēWs$I”b|žŚł“ Ģ‚:vģܱebbŖÖ’a"É9¢8Ī7‡’ox]¼™€$ĒŠÅ(ĒaĒA·ēÕ1{ÆdkJ5õnĻ«‡a‹ÅˆˆģŠpĆĆĆ“^Éo>“ģ ć@# ąß§śčØėķU+DQ¤¤štoļŽfå–ō÷wŹŠŠ;øÉφfŸ÷Møœ£!åRI>½’ą-笜¹®ŲY„g Ō<-ĀYßĆĒÆ<·?¼uÖ E8öŪ‚YÅ`B‰ńCļ8’ œ}ęĆ?Sļ?==… Ļnü f’”’š_;'9v!˜‚Joļļ|S•qĶß]RμCCsMcBcšĻččØr½½ Έ"äq ›oļ^éīīf²©©Ņs‚Üæ3ZNt,!0˜®nJ[5„¤.Ż|f<ā8ѾŲfįÓM·|uÚóŽv^w×¢“ū-yLó®‡1®żŅZķłPŚ‡Ņ‰:*}|ś3A؁ÉB±Å¾:ø 8r˜žšĀóŸ’/_¹łSŠˆEąHėČJy5 Ø[kß÷ćÄKž˜†rŌ>æWpÆ\ŠäN¼{äwĮI4pD©GłqēDE#ŗ)‹ršš”o.ļ­žC”£0Ūär4:r|źŖóńĆ_m†°†R’N ‚¤£Ć’gN¼æĄ„+.<óŽ_f—nټå@ )%’L’%Ī(§bq"EW(Dóv’Hxytp¼{儊_W“|`>Č«Ą›ż^_)Źå’üüŽ{’ßįƕé0 ÓAØó'ėžüś?@gŽ$[Ä”±ŻXfC’Äū#ž”ćK’ņ½ ¾6 # CŒv<üųm‰\:9ū³ē;qDā‚‚„J„Āåרž{3p2Ž+Æ'%œœ’‘‘wšą¾Õė58·šņ¬ļašż}MJ›j˜g_˜0ŠĪxĖĀ«ĪČjõ¶n{įéC‡*U"'š˜™ yĢÄ".Ī9ŹĪĢš™żoćwG›Z¬öp±(/m?|óääEq„…§ 7|ü謙ōœĻ˜)ż’dµ¹0Į׌/~īŖ_;ūajjėŸśķīž#­™P6Ėģ Dnŗ§‡Ž¬ģÆ mh%”Ė|ė­ß9øļĄŽ‡ėõ¹¤¾?ĻC=Ļąsŗp®Ė“³¾0„™aĀ._‰Ņ¢…G¤3źõ:^yi×śį ›%™™|_33»0,R”Rįr¹Ü2įmh4ę‚0H* DŸłą%8­+ ”Äų…,DyųĀg޳ą‹4†cLLLąŃǟųÉx4%ĢBžē98(e‰Ä…aų†JŪxżŠ&€B#X.•ä;ßłžī]»G~V­V(„š—Ÿy×ģ¤&‚8‹Ļ}čbtęēe-"‰÷Æ×°õÅ­/<łäoŸixc’É8¢”eĄvv²+/müžŃ&€VÄŠtwwó³[6’DZ±J†į1£€½{ ŽŃwfāż)ĘŹ3»šgŸ|ׂO/"Ćcćcxä׿žf³÷ń ¬ ²NÄAŠHž½Ŗ‘_mœh@‹”¬ZµŠoūŽmwīłŃĢĢ4Č-ĄWžā#Čg5“üĶæżČ‚“qŖæj­Š-/lŁøž©ē6Ļēż°Ņ_šük£Ń&€ÅP<óōĘ’T9|(8^.ą-‹;ńWt%>ūįKpފÓ|^ ŒBLLŒKłįĒžžHļ/³ŽŸ”²ÖZ×\śk‡’­‡“ŖąTA£?`ÕŖU|ēĘ.¾“ļ»oYRś÷¹l&;Ļ‘Ÿ¾ś2/ģ¬g½u·lzęŁē7oSŠDiĆZQ²EÅZĒēÜXO­Hw‰·æ5юZIpˆłŲC7=X ‚:ˆiĮ(ĢĖF‹ĻADĘĘ˃<ņĶ—{X„uģDœµÖ-™™”¶š§µŃ&€Es.ą‰_VŖ»v½ōµÉ©IÄQ„×āŒE’ øSӓxöłēݼeŪNRN“1äyā°Ģ·R¶IöŪöž-Œ6“8QĄ7æń­ÆļŽ»s[µ:ēģĖIą8«ńˆÕZ{öģ©ß~ē]_”hÖLÄ,’,Cix’ (õžmå_‹£M-Œę(`jj)mŽžā cㇹŌĮ“pBšhP:éwl| >ńÄ’š›Ŗ9QzNņ+ĄŽÕŖUķ³’I€6œhDwüÓĆ/¼°łcØõ“eXōђnĄ ƒćŲ°į¹-÷üüž»d 2³”YļoL,ZŪ†÷oåYųmĢ”M-Žę( R©šĶ7ż·æŚ“e敏(ŖµÄQG.Qr2#™įœElcTk3Ø>„›6ģūßßūį—%Ģij‰æ4ō—𲳫/[ꌎ’äĮI5šTEcnąĄĄ€Ž¢Č²Aö?üé¾~޹ē’ÉāÅ=^.—G6›…g<&BĒĆ:&''eĆĘēׯvūŻ;>19ĶL¬!Xg6‘/DtŻ9d2AĄžČóžŚxuhĄI„”Āą ¾`ófcŒń©PČ^żžw®9oõŖz–”.ėYÜsNW±« ØV«Q„rxĻĮу›·lŁö˧Ö?»Q)'DÉFd8å\Ģ> ²ĢAĆ(ŹŪžžN7Ō‚[pۘm8‰ ”Ņzo>oĢČt¦£Cē¬ęŒRyLöœ¾•geM¦kƦ­»!¢DD„æ'PJ˜˜—Ōū™ČcPEQ±XŒøV_…ÕʑhĄI„ę£Ąö(ņO‹ćŒµŁ¬ļG9ņ¼¬°—Q_k2ĢFKJJ)њ˜Ł œR66” cĻF¾µ”1&`‡W­b“½’I…vš$Bs»šiqģXߏ"ꎀ€”sHé2LO$h,KeAŖ³Ru›”Š·…™m†IāÆmü'ŚĄI†¹„ƒś‚ 6›®®.Ć̾ˆų5_¾gŒ!"a?b!ß'GDYfĄ6ž„ačśśśeævč’”œd˜3Š!ŽŌ×Gq»|>‡aę˜ń¼šŠüšh] µ­EĘU#Ļ«ŖČÆ9„źD„a1Ģd2qŪųO~“#€“ĶkŅt„RѵRI/™™ŃaXŌn‘U‹œ›ÕV«y6f\zzzØR©p©TāR©$éVäö˜ļ“m8‰ŃLƒƒƒŖR©Ø™™†”Š¢HįÜs“ݶ ŁlVr¹œ‹EI ¶ĖÆmü'/Śp ąåĖ0o7©Į¦6-ĄچŹ M§ŌB³ĄR“žŌB›ŚhćF» ŠF§0ŚŠF§0ŚŠF§0ŚŠF§0ŚŠF§0ŚŠF§0ŚŠF§0ŚŠF§0ŚŠF§0ŚŠF§0ž?¢reG9UĘŃIEND®B`‚cinnamon-control-center-6.4.1/panels/color/cc-color-panel.c0000664000175000017500000023350314724311620022554 0ustar fabiofabio/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- * * Copyright (C) 2010 Red Hat, Inc * Copyright (C) 2011 Richard Hughes * * 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 Street - Suite 500, Boston, MA 02110-1335, USA. * */ #include #include #include #include #include #include #include "cc-color-panel.h" #define WID(b, w) (GtkWidget *) gtk_builder_get_object (b, w) CC_PANEL_REGISTER (CcColorPanel, cc_color_panel) #define COLOR_PANEL_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_COLOR_PANEL, CcColorPanelPrivate)) struct _CcColorPanelPrivate { CdClient *client; CdDevice *current_device; CdSensor *sensor; GCancellable *cancellable; GDBusProxy *proxy; GSettings *settings; GtkBuilder *builder; GtkTreeStore *list_store_devices; GtkWidget *main_window; }; enum { GCM_PREFS_COLUMN_DEVICE_PATH, GCM_PREFS_COLUMN_SORT, GCM_PREFS_COLUMN_ICON, GCM_PREFS_COLUMN_TITLE, GCM_PREFS_COLUMN_DEVICE, GCM_PREFS_COLUMN_PROFILE, GCM_PREFS_COLUMN_STATUS, GCM_PREFS_COLUMN_STATUS_IMAGE, GCM_PREFS_COLUMN_TOOLTIP, GCM_PREFS_COLUMN_RADIO_ACTIVE, GCM_PREFS_COLUMN_RADIO_VISIBLE, GCM_PREFS_COLUMN_NUM_COLUMNS }; enum { GCM_PREFS_COMBO_COLUMN_TEXT, GCM_PREFS_COMBO_COLUMN_PROFILE, GCM_PREFS_COMBO_COLUMN_TYPE, GCM_PREFS_COMBO_COLUMN_NUM_COLUMNS }; typedef enum { GCM_PREFS_ENTRY_TYPE_PROFILE, GCM_PREFS_ENTRY_TYPE_IMPORT } GcmPrefsEntryType; #define GCM_SETTINGS_SCHEMA "org.cinnamon.settings-daemon.plugins.color" #define GCM_SETTINGS_RECALIBRATE_PRINTER_THRESHOLD "recalibrate-printer-threshold" #define GCM_SETTINGS_RECALIBRATE_DISPLAY_THRESHOLD "recalibrate-display-threshold" /* max number of devices and profiles to cause auto-expand at startup */ #define GCM_PREFS_MAX_DEVICES_PROFILES_EXPANDED 5 static void gcm_prefs_device_add_cb (GtkWidget *widget, CcColorPanel *prefs); static void gcm_prefs_combobox_add_profile (GtkWidget *widget, CdProfile *profile, GcmPrefsEntryType entry_type, GtkTreeIter *iter) { const gchar *id; GtkTreeModel *model; GtkTreeIter iter_tmp; GString *string; /* iter is optional */ if (iter == NULL) iter = &iter_tmp; /* use description */ if (entry_type == GCM_PREFS_ENTRY_TYPE_IMPORT) { /* TRANSLATORS: this is where the user can click and import a profile */ string = g_string_new (_("Other profile…")); } else { string = g_string_new (cd_profile_get_title (profile)); /* any source prefix? */ id = cd_profile_get_metadata_item (profile, CD_PROFILE_METADATA_DATA_SOURCE); if (g_strcmp0 (id, CD_PROFILE_METADATA_DATA_SOURCE_EDID) == 0) { /* TRANSLATORS: this is a profile prefix to signify the * profile has been auto-generated for this hardware */ g_string_prepend (string, _("Default: ")); } if (g_strcmp0 (id, CD_PROFILE_METADATA_DATA_SOURCE_STANDARD) == 0) { /* TRANSLATORS: this is a profile prefix to signify the * profile his a standard space like AdobeRGB */ g_string_prepend (string, _("Colorspace: ")); } if (g_strcmp0 (id, CD_PROFILE_METADATA_DATA_SOURCE_TEST) == 0) { /* TRANSLATORS: this is a profile prefix to signify the * profile is a test profile */ g_string_prepend (string, _("Test profile: ")); } } /* also add profile */ model = gtk_combo_box_get_model (GTK_COMBO_BOX(widget)); gtk_list_store_append (GTK_LIST_STORE(model), iter); gtk_list_store_set (GTK_LIST_STORE(model), iter, GCM_PREFS_COMBO_COLUMN_TEXT, string->str, GCM_PREFS_COMBO_COLUMN_PROFILE, profile, GCM_PREFS_COMBO_COLUMN_TYPE, entry_type, -1); g_string_free (string, TRUE); } static void gcm_prefs_default_cb (GtkWidget *widget, CcColorPanel *prefs) { CdProfile *profile; gboolean ret; GError *error = NULL; CcColorPanelPrivate *priv = prefs->priv; /* TODO: check if the profile is already systemwide */ profile = cd_device_get_default_profile (priv->current_device); if (profile == NULL) goto out; /* install somewhere out of $HOME */ ret = cd_profile_install_system_wide_sync (profile, priv->cancellable, &error); if (!ret) { g_warning ("failed to set profile system-wide: %s", error->message); g_error_free (error); goto out; } out: if (profile != NULL) g_object_unref (profile); } static void gcm_prefs_treeview_popup_menu (CcColorPanel *prefs, GtkWidget *treeview) { GtkWidget *menu, *menuitem; menu = gtk_menu_new (); /* TRANSLATORS: this is when the profile should be set for all users */ menuitem = gtk_menu_item_new_with_label (_("Set for all users")); g_signal_connect (menuitem, "activate", G_CALLBACK (gcm_prefs_default_cb), prefs); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); /* TRANSLATORS: this is when the profile should be set for all users */ menuitem = gtk_menu_item_new_with_label (_("Create virtual device")); g_signal_connect (menuitem, "activate", G_CALLBACK (gcm_prefs_device_add_cb), prefs); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); gtk_widget_show_all (menu); /* Note: gdk_event_get_time() accepts a NULL argument */ gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, gdk_event_get_time (NULL)); } static gboolean gcm_prefs_treeview_popup_menu_cb (GtkWidget *treeview, CcColorPanel *prefs) { if (prefs->priv->current_device == NULL) return FALSE; gcm_prefs_treeview_popup_menu (prefs, treeview); return TRUE; /* we handled this */ } static GFile * gcm_prefs_file_chooser_get_icc_profile (CcColorPanel *prefs) { GtkWindow *window; GtkWidget *dialog; GFile *file = NULL; GtkFileFilter *filter; CcColorPanelPrivate *priv = prefs->priv; /* create new dialog */ window = GTK_WINDOW(gtk_builder_get_object (priv->builder, "dialog_assign")); /* TRANSLATORS: an ICC profile is a file containing colorspace data */ dialog = gtk_file_chooser_dialog_new (_("Select ICC Profile File"), window, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, _("_Import"), GTK_RESPONSE_ACCEPT, NULL); gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(dialog), g_get_home_dir ()); gtk_file_chooser_set_create_folders (GTK_FILE_CHOOSER(dialog), FALSE); gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER(dialog), FALSE); /* setup the filter */ filter = gtk_file_filter_new (); gtk_file_filter_add_mime_type (filter, "application/vnd.iccprofile"); /* TRANSLATORS: filter name on the file->open dialog */ gtk_file_filter_set_name (filter, _("Supported ICC profiles")); gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(dialog), filter); /* setup the all files filter */ filter = gtk_file_filter_new (); gtk_file_filter_add_pattern (filter, "*"); /* TRANSLATORS: filter name on the file->open dialog */ gtk_file_filter_set_name (filter, _("All files")); gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(dialog), filter); /* did user choose file */ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER(dialog)); /* we're done */ gtk_widget_destroy (dialog); /* or NULL for missing */ return file; } static void install_gcm (void) { g_autofree gchar *apturl = g_find_program_in_path ("apturl"); if (apturl != NULL) { g_spawn_command_line_async ("apturl apt://gnome-color-manager", NULL); } } static void gcm_prefs_run_maybe_install (guint xid, gchar *filename, GPtrArray *argv) { gboolean ret; GError *error = NULL; ret = g_spawn_async (NULL, (gchar**) argv->pdata, NULL, 0, NULL, NULL, NULL, &error); if (!ret) { if ((error->domain == g_spawn_error_quark ()) && (error->code == G_SPAWN_ERROR_NOENT)) { install_gcm (); } else { g_warning ("failed to run command: %s", error->message); } g_error_free (error); } } static void gcm_prefs_device_add_cb (GtkWidget *widget, CcColorPanel *prefs) { CcColorPanelPrivate *priv = prefs->priv; /* show ui */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "dialog_virtual")); gtk_widget_show (widget); gtk_window_set_transient_for (GTK_WINDOW (widget), GTK_WINDOW (priv->main_window)); /* clear entries */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "combobox_virtual_type")); gtk_combo_box_set_active (GTK_COMBO_BOX(widget), 0); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "entry_virtual_model")); gtk_entry_set_text (GTK_ENTRY (widget), ""); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "entry_virtual_manufacturer")); gtk_entry_set_text (GTK_ENTRY (widget), ""); } static gboolean gcm_prefs_is_profile_suitable_for_device (CdProfile *profile, CdDevice *device) { const gchar *data_source; CdProfileKind profile_kind_tmp; CdProfileKind profile_kind; CdColorspace profile_colorspace; CdColorspace device_colorspace = 0; gboolean ret = FALSE; CdDeviceKind device_kind; /* not the right colorspace */ device_colorspace = cd_device_get_colorspace (device); profile_colorspace = cd_profile_get_colorspace (profile); if (device_colorspace != profile_colorspace) goto out; /* not the correct kind */ device_kind = cd_device_get_kind (device); profile_kind_tmp = cd_profile_get_kind (profile); profile_kind = cd_device_kind_to_profile_kind (device_kind); if (profile_kind_tmp != profile_kind) goto out; /* ignore the colorspace profiles */ data_source = cd_profile_get_metadata_item (profile, CD_PROFILE_METADATA_DATA_SOURCE); if (g_strcmp0 (data_source, CD_PROFILE_METADATA_DATA_SOURCE_STANDARD) == 0) goto out; /* success */ ret = TRUE; out: return ret; } static gint gcm_prefs_combo_sort_func_cb (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data) { gint type_a, type_b; gchar *text_a; gchar *text_b; gint retval; /* get data from model */ gtk_tree_model_get (model, a, GCM_PREFS_COMBO_COLUMN_TYPE, &type_a, GCM_PREFS_COMBO_COLUMN_TEXT, &text_a, -1); gtk_tree_model_get (model, b, GCM_PREFS_COMBO_COLUMN_TYPE, &type_b, GCM_PREFS_COMBO_COLUMN_TEXT, &text_b, -1); /* prefer normal type profiles over the 'Other Profile...' entry */ if (type_a < type_b) retval = -1; else if (type_a > type_b) retval = 1; else retval = g_strcmp0 (text_a, text_b); g_free (text_a); g_free (text_b); return retval; } static gboolean gcm_prefs_combo_set_default_cb (gpointer user_data) { GtkWidget *widget = GTK_WIDGET (user_data); gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0); return FALSE; } static gboolean gcm_prefs_profile_exists_in_array (GPtrArray *array, CdProfile *profile) { CdProfile *profile_tmp; guint i; for (i = 0; i < array->len; i++) { profile_tmp = g_ptr_array_index (array, i); if (cd_profile_equal (profile, profile_tmp)) return TRUE; } return FALSE; } static void gcm_prefs_add_profiles_suitable_for_devices (CcColorPanel *prefs, GtkWidget *widget, GPtrArray *profiles) { CdProfile *profile_tmp; gboolean ret; GError *error = NULL; GPtrArray *profile_array = NULL; GtkTreeIter iter; GtkTreeModel *model; guint i; CcColorPanelPrivate *priv = prefs->priv; /* clear existing entries */ model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); gtk_list_store_clear (GTK_LIST_STORE (model)); gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), GCM_PREFS_COMBO_COLUMN_TEXT, GTK_SORT_ASCENDING); gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (model), GCM_PREFS_COMBO_COLUMN_TEXT, gcm_prefs_combo_sort_func_cb, model, NULL); /* get profiles */ profile_array = cd_client_get_profiles_sync (priv->client, priv->cancellable, &error); if (profile_array == NULL) { g_warning ("failed to get profiles: %s", error->message); g_error_free (error); goto out; } /* add profiles of the right kind */ for (i = 0; i < profile_array->len; i++) { profile_tmp = g_ptr_array_index (profile_array, i); /* get properties */ ret = cd_profile_connect_sync (profile_tmp, priv->cancellable, &error); if (!ret) { g_warning ("failed to get profile: %s", error->message); g_error_free (error); goto out; } /* don't add any of the already added profiles */ if (profiles != NULL) { if (gcm_prefs_profile_exists_in_array (profiles, profile_tmp)) continue; } /* only add correct types */ ret = gcm_prefs_is_profile_suitable_for_device (profile_tmp, priv->current_device); if (!ret) continue; /* ignore profiles from other user accounts */ if (!cd_profile_has_access (profile_tmp)) continue; /* add */ gcm_prefs_combobox_add_profile (widget, profile_tmp, GCM_PREFS_ENTRY_TYPE_PROFILE, &iter); } /* add a import entry */ gcm_prefs_combobox_add_profile (widget, NULL, GCM_PREFS_ENTRY_TYPE_IMPORT, NULL); g_idle_add (gcm_prefs_combo_set_default_cb, widget); out: if (profile_array != NULL) g_ptr_array_unref (profile_array); } static void gcm_prefs_profile_add_cb (GtkWidget *widget, CcColorPanel *prefs) { const gchar *title; GPtrArray *profiles; CcColorPanelPrivate *priv = prefs->priv; /* add profiles of the right kind */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "combobox_profile")); profiles = cd_device_get_profiles (priv->current_device); gcm_prefs_add_profiles_suitable_for_devices (prefs, widget, profiles); /* set the title */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_assign_title")); switch (cd_device_get_kind (priv->current_device)) { case CD_DEVICE_KIND_DISPLAY: /* TRANSLATORS: this is the dialog title in the 'Add profile' UI */ title = _("Available Profiles for Displays"); break; case CD_DEVICE_KIND_SCANNER: /* TRANSLATORS: this is the dialog title in the 'Add profile' UI */ title = _("Available Profiles for Scanners"); break; case CD_DEVICE_KIND_PRINTER: /* TRANSLATORS: this is the dialog title in the 'Add profile' UI */ title = _("Available Profiles for Printers"); break; case CD_DEVICE_KIND_CAMERA: /* TRANSLATORS: this is the dialog title in the 'Add profile' UI */ title = _("Available Profiles for Cameras"); break; case CD_DEVICE_KIND_WEBCAM: /* TRANSLATORS: this is the dialog title in the 'Add profile' UI */ title = _("Available Profiles for Webcams"); break; default: /* TRANSLATORS: this is the dialog title in the 'Add profile' UI * where the device type is not recognised */ title = _("Available Profiles"); break; } gtk_label_set_label (GTK_LABEL (widget), title); /* show the dialog */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "dialog_assign")); gtk_widget_show (widget); gtk_window_set_transient_for (GTK_WINDOW (widget), GTK_WINDOW (priv->main_window)); if (profiles != NULL) g_ptr_array_unref (profiles); } static void gcm_prefs_profile_remove_cb (GtkWidget *widget, CcColorPanel *prefs) { GtkTreeIter iter; GtkTreeSelection *selection; GtkTreeModel *model; gboolean ret = FALSE; CdProfile *profile = NULL; GError *error = NULL; CcColorPanelPrivate *priv = prefs->priv; /* get the selected row */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "treeview_devices")); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)); if (!gtk_tree_selection_get_selected (selection, &model, &iter)) goto out; /* if the profile is default, then we'll have to make the first profile default */ gtk_tree_model_get (model, &iter, GCM_PREFS_COLUMN_PROFILE, &profile, -1); /* just remove it, the list store will get ::changed */ ret = cd_device_remove_profile_sync (priv->current_device, profile, priv->cancellable, &error); if (!ret) { g_warning ("failed to remove profile: %s", error->message); g_error_free (error); goto out; } out: if (profile != NULL) g_object_unref (profile); return; } static void gcm_prefs_make_profile_default_cb (GObject *object, GAsyncResult *res, gpointer user_data) { CdDevice *device = CD_DEVICE (object); gboolean ret = FALSE; GError *error = NULL; ret = cd_device_make_profile_default_finish (device, res, &error); if (!ret) { g_warning ("failed to set default profile on %s: %s", cd_device_get_id (device), error->message); g_error_free (error); } } static void gcm_prefs_profile_make_default_internal (CcColorPanel *prefs, GtkTreeModel *model, GtkTreeIter *iter_selected) { CdDevice *device; CdProfile *profile; CcColorPanelPrivate *priv = prefs->priv; /* get currentlt selected item */ gtk_tree_model_get (model, iter_selected, GCM_PREFS_COLUMN_DEVICE, &device, GCM_PREFS_COLUMN_PROFILE, &profile, -1); if (profile == NULL || device == NULL) goto out; /* just set it default */ g_debug ("setting %s default on %s", cd_profile_get_id (profile), cd_device_get_id (device)); cd_device_make_profile_default (device, profile, priv->cancellable, gcm_prefs_make_profile_default_cb, prefs); out: if (profile != NULL) g_object_unref (profile); if (device != NULL) g_object_unref (device); } static void gcm_prefs_profile_view_cb (GtkWidget *widget, CcColorPanel *prefs) { CdProfile *profile = NULL; GtkTreeIter iter; GtkTreeModel *model; GtkTreeSelection *selection; gchar *options = NULL; gchar *viewer_filename; GPtrArray *argv = NULL; guint xid; CcColorPanelPrivate *priv = prefs->priv; /* get the selected row */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "treeview_devices")); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)); if (!gtk_tree_selection_get_selected (selection, &model, &iter)) g_assert_not_reached (); /* get currentlt selected item */ gtk_tree_model_get (model, &iter, GCM_PREFS_COLUMN_PROFILE, &profile, -1); /* get xid */ xid = gdk_x11_window_get_xid (gtk_widget_get_window (GTK_WIDGET (priv->main_window))); viewer_filename = g_build_filename (BINDIR, "gcm-viewer", NULL); /* open up gcm-viewer as a info pane */ argv = g_ptr_array_new_with_free_func (g_free); g_ptr_array_add (argv, viewer_filename); g_ptr_array_add (argv, g_strdup ("--profile")); g_ptr_array_add (argv, g_strdup (cd_profile_get_id (profile))); g_ptr_array_add (argv, g_strdup ("--parent-window")); g_ptr_array_add (argv, g_strdup_printf ("%i", xid)); g_ptr_array_add (argv, NULL); gcm_prefs_run_maybe_install (xid, viewer_filename, argv); g_ptr_array_unref (argv); g_free (options); if (profile != NULL) g_object_unref (profile); } static void gcm_prefs_button_assign_cancel_cb (GtkWidget *widget, CcColorPanel *prefs) { CcColorPanelPrivate *priv = prefs->priv; widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "dialog_assign")); gtk_widget_hide (widget); } static void gcm_prefs_button_assign_ok_cb (GtkWidget *widget, CcColorPanel *prefs) { GtkTreeIter iter; GtkTreeModel *model; CdProfile *profile = NULL; gboolean ret = FALSE; GError *error = NULL; CcColorPanelPrivate *priv = prefs->priv; /* hide window */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "dialog_assign")); gtk_widget_hide (widget); /* get entry */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "combobox_profile")); ret = gtk_combo_box_get_active_iter (GTK_COMBO_BOX(widget), &iter); if (!ret) goto out; model = gtk_combo_box_get_model (GTK_COMBO_BOX(widget)); gtk_tree_model_get (model, &iter, GCM_PREFS_COMBO_COLUMN_PROFILE, &profile, -1); if (profile == NULL) { g_warning ("failed to get the active profile"); goto out; } /* just add it, the list store will get ::changed */ ret = cd_device_add_profile_sync (priv->current_device, CD_DEVICE_RELATION_HARD, profile, priv->cancellable, &error); if (!ret) { g_warning ("failed to add: %s", error->message); g_error_free (error); goto out; } /* make it default */ cd_device_make_profile_default (priv->current_device, profile, priv->cancellable, gcm_prefs_make_profile_default_cb, prefs); out: if (profile != NULL) g_object_unref (profile); } static gboolean gcm_prefs_profile_delete_event_cb (GtkWidget *widget, GdkEvent *event, CcColorPanel *prefs) { gcm_prefs_button_assign_cancel_cb (widget, prefs); return TRUE; } static void gcm_prefs_delete_cb (GtkWidget *widget, CcColorPanel *prefs) { gboolean ret = FALSE; GError *error = NULL; CcColorPanelPrivate *priv = prefs->priv; /* try to delete device */ ret = cd_client_delete_device_sync (priv->client, priv->current_device, priv->cancellable, &error); if (!ret) { g_warning ("failed to delete device: %s", error->message); g_error_free (error); } } static void gcm_prefs_treeview_renderer_toggled (GtkCellRendererToggle *cell, const gchar *path, CcColorPanel *prefs) { gboolean ret; GtkTreeModel *model; GtkTreeIter iter; CcColorPanelPrivate *priv = prefs->priv; model = GTK_TREE_MODEL (priv->list_store_devices); ret = gtk_tree_model_get_iter_from_string (model, &iter, path); if (!ret) return; gcm_prefs_profile_make_default_internal (prefs, model, &iter); } static void gcm_prefs_add_devices_columns (CcColorPanel *prefs, GtkTreeView *treeview) { GtkCellRenderer *renderer; GtkTreeViewColumn *column; CcColorPanelPrivate *priv = prefs->priv; gtk_tree_view_set_headers_visible (treeview, TRUE); /* --- column for device image and device title --- */ column = gtk_tree_view_column_new (); gtk_tree_view_column_set_expand (column, TRUE); /* TRANSLATORS: column for device list */ gtk_tree_view_column_set_title (column, _("Device")); /* image */ renderer = gtk_cell_renderer_pixbuf_new (); g_object_set (renderer, "stock-size", GTK_ICON_SIZE_MENU, NULL); gtk_tree_view_column_pack_start (column, renderer, FALSE); gtk_tree_view_column_add_attribute (column, renderer, "icon-name", GCM_PREFS_COLUMN_ICON); /* option */ renderer = gtk_cell_renderer_toggle_new (); g_signal_connect (renderer, "toggled", G_CALLBACK (gcm_prefs_treeview_renderer_toggled), prefs); g_object_set (renderer, "radio", TRUE, NULL); gtk_tree_view_column_pack_start (column, renderer, FALSE); gtk_tree_view_column_add_attribute (column, renderer, "active", GCM_PREFS_COLUMN_RADIO_ACTIVE); gtk_tree_view_column_add_attribute (column, renderer, "visible", GCM_PREFS_COLUMN_RADIO_VISIBLE); /* text */ renderer = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, renderer, TRUE); gtk_tree_view_column_add_attribute (column, renderer, "markup", GCM_PREFS_COLUMN_TITLE); gtk_tree_view_column_set_expand (column, TRUE); gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (priv->list_store_devices), GCM_PREFS_COLUMN_SORT, GTK_SORT_DESCENDING); gtk_tree_view_append_column (treeview, GTK_TREE_VIEW_COLUMN(column)); /* --- column for device status --- */ column = gtk_tree_view_column_new (); gtk_tree_view_column_set_expand (column, TRUE); /* TRANSLATORS: column for device list */ gtk_tree_view_column_set_title (column, _("Calibration")); /* image */ renderer = gtk_cell_renderer_pixbuf_new (); g_object_set (renderer, "stock-size", GTK_ICON_SIZE_MENU, NULL); gtk_tree_view_column_pack_start (column, renderer, FALSE); gtk_tree_view_column_add_attribute (column, renderer, "icon-name", GCM_PREFS_COLUMN_STATUS_IMAGE); /* text */ renderer = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, renderer, TRUE); gtk_tree_view_column_add_attribute (column, renderer, "markup", GCM_PREFS_COLUMN_STATUS); gtk_tree_view_column_set_expand (column, FALSE); gtk_tree_view_append_column (treeview, GTK_TREE_VIEW_COLUMN(column)); /* tooltip */ gtk_tree_view_set_tooltip_column (treeview, GCM_PREFS_COLUMN_TOOLTIP); } static void gcm_prefs_device_clicked (CcColorPanel *prefs, CdDevice *device) { GtkWidget *widget; CdDeviceMode device_mode; CcColorPanelPrivate *priv = prefs->priv; if (device == NULL) g_assert_not_reached (); /* get current device */ if (priv->current_device != NULL) g_object_unref (priv->current_device); priv->current_device = g_object_ref (device); /* we have a new device */ g_debug ("selected device is: %s", cd_device_get_id (device)); /* make sure selectable */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "combobox_profile")); gtk_widget_set_sensitive (widget, TRUE); /* can we delete this device? */ device_mode = cd_device_get_mode (priv->current_device); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "toolbutton_device_remove")); gtk_widget_set_visible (widget, device_mode == CD_DEVICE_MODE_VIRTUAL); } static void gcm_prefs_profile_clicked (CcColorPanel *prefs, CdProfile *profile, CdDevice *device) { GtkWidget *widget; CdDeviceRelation relation; CcColorPanelPrivate *priv = prefs->priv; /* get profile */ g_debug ("selected profile = %s", cd_profile_get_filename (profile)); /* find the profile relationship */ relation = cd_device_get_profile_relation_sync (device, profile, NULL, NULL); /* we can only remove hard relationships */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "toolbutton_profile_remove")); if (relation == CD_DEVICE_RELATION_HARD) { gtk_widget_set_tooltip_text (widget, ""); gtk_widget_set_sensitive (widget, TRUE); } else { /* TRANSLATORS: this is when an auto-added profile cannot be removed */ gtk_widget_set_tooltip_text (widget, _("Cannot remove automatically added profile")); gtk_widget_set_sensitive (widget, FALSE); } /* allow getting profile info */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "toolbutton_profile_view")); if (cd_profile_get_filename (profile) != NULL) { gtk_widget_set_sensitive (widget, TRUE); } else gtk_widget_set_sensitive (widget, FALSE); /* hide device specific stuff */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "toolbutton_device_remove")); gtk_widget_set_visible (widget, FALSE); } static void gcm_prefs_devices_treeview_clicked_cb (GtkTreeSelection *selection, CcColorPanel *prefs) { GtkTreeModel *model; GtkTreeIter iter; CdDevice *device = NULL; CdProfile *profile = NULL; GtkWidget *widget; CcColorPanelPrivate *priv = prefs->priv; /* get selection */ if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return; gtk_tree_model_get (model, &iter, GCM_PREFS_COLUMN_DEVICE, &device, GCM_PREFS_COLUMN_PROFILE, &profile, -1); /* device actions */ if (device != NULL) gcm_prefs_device_clicked (prefs, device); if (profile != NULL) gcm_prefs_profile_clicked (prefs, profile, device); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "toolbutton_device_default")); gtk_widget_set_visible (widget, profile != NULL); if (profile) gtk_widget_set_sensitive (widget, !cd_profile_get_is_system_wide (profile)); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "toolbutton_device_add")); gtk_widget_set_visible (widget, FALSE); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "toolbutton_profile_add")); gtk_widget_set_visible (widget, device != NULL); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "toolbutton_profile_view")); gtk_widget_set_visible (widget, profile != NULL); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "toolbutton_profile_remove")); gtk_widget_set_visible (widget, profile != NULL); /* if no buttons then hide toolbar */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "toolbar_devices")); gtk_widget_set_visible (widget, profile != NULL || device != NULL); if (device != NULL) g_object_unref (device); if (profile != NULL) g_object_unref (profile); } static void gcm_prefs_treeview_row_activated_cb (GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, CcColorPanel *prefs) { GtkTreeModel *model; GtkTreeIter iter; gboolean ret; CcColorPanelPrivate *priv = prefs->priv; /* get the iter */ model = GTK_TREE_MODEL (priv->list_store_devices); ret = gtk_tree_model_get_iter (model, &iter, path); if (!ret) return; /* make this profile the default */ gcm_prefs_profile_make_default_internal (prefs, model, &iter); } static const gchar * gcm_prefs_device_kind_to_sort (CdDeviceKind kind) { if (kind == CD_DEVICE_KIND_DISPLAY) return "4"; if (kind == CD_DEVICE_KIND_SCANNER) return "3"; if (kind == CD_DEVICE_KIND_CAMERA) return "2"; if (kind == CD_DEVICE_KIND_PRINTER) return "1"; return "0"; } static gchar * gcm_device_get_title (CdDevice *device) { const gchar *model; const gchar *vendor; GString *string; /* try to get a nice string suitable for display */ vendor = cd_device_get_vendor (device); model = cd_device_get_model (device); string = g_string_new (""); if (vendor != NULL && model != NULL) { g_string_append_printf (string, "%s - %s", vendor, model); goto out; } /* just model */ if (model != NULL) { g_string_append (string, model); goto out; } /* just vendor */ if (vendor != NULL) { g_string_append (string, vendor); goto out; } /* fallback to id */ g_string_append (string, cd_device_get_id (device)); out: return g_string_free (string, FALSE); } static void gcm_prefs_set_combo_simple_text (GtkWidget *combo_box) { GtkCellRenderer *renderer; GtkListStore *store; store = gtk_list_store_new (GCM_PREFS_COMBO_COLUMN_NUM_COLUMNS, G_TYPE_STRING, CD_TYPE_PROFILE, G_TYPE_UINT); gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (store)); g_object_unref (store); renderer = gtk_cell_renderer_text_new (); g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, "wrap-mode", PANGO_WRAP_WORD_CHAR, NULL); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), renderer, TRUE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), renderer, "text", GCM_PREFS_COMBO_COLUMN_TEXT, NULL); } static void gcm_prefs_profile_combo_changed_cb (GtkWidget *widget, CcColorPanel *prefs) { GFile *file = NULL; GError *error = NULL; gboolean ret; CdProfile *profile = NULL; GtkTreeIter iter; GtkTreeModel *model; GcmPrefsEntryType entry_type; CcColorPanelPrivate *priv = prefs->priv; /* no devices */ if (priv->current_device == NULL) return; /* no selection */ ret = gtk_combo_box_get_active_iter (GTK_COMBO_BOX(widget), &iter); if (!ret) return; /* get entry */ model = gtk_combo_box_get_model (GTK_COMBO_BOX(widget)); gtk_tree_model_get (model, &iter, GCM_PREFS_COMBO_COLUMN_TYPE, &entry_type, -1); /* import */ if (entry_type == GCM_PREFS_ENTRY_TYPE_IMPORT) { file = gcm_prefs_file_chooser_get_icc_profile (prefs); if (file == NULL) { g_warning ("failed to get ICC file"); gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0); /* if we've got no other existing profiles to choose, then * just close the assign dialog */ gtk_combo_box_get_active_iter (GTK_COMBO_BOX(widget), &iter); gtk_tree_model_get (model, &iter, GCM_PREFS_COMBO_COLUMN_TYPE, &entry_type, -1); if (entry_type == GCM_PREFS_ENTRY_TYPE_IMPORT) { widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "dialog_assign")); gtk_widget_hide (widget); } goto out; } profile = cd_client_import_profile_sync (priv->client, file, priv->cancellable, &error); if (profile == NULL) { g_warning ("failed to get imported profile: %s", error->message); g_error_free (error); goto out; } /* add to combobox */ gtk_list_store_append (GTK_LIST_STORE(model), &iter); gtk_list_store_set (GTK_LIST_STORE(model), &iter, GCM_PREFS_COMBO_COLUMN_PROFILE, profile, -1); gtk_combo_box_set_active_iter (GTK_COMBO_BOX (widget), &iter); } out: if (file != NULL) g_object_unref (file); if (profile != NULL) g_object_unref (profile); } static void gcm_prefs_sensor_coldplug (CcColorPanel *prefs) { GPtrArray *sensors; GError *error = NULL; gboolean ret; CcColorPanelPrivate *priv = prefs->priv; /* unref old */ if (priv->sensor != NULL) { g_object_unref (priv->sensor); priv->sensor = NULL; } /* no present */ sensors = cd_client_get_sensors_sync (priv->client, NULL, &error); if (sensors == NULL) { g_warning ("%s", error->message); g_error_free (error); goto out; } if (sensors->len == 0) goto out; /* save a copy of the sensor */ priv->sensor = g_object_ref (g_ptr_array_index (sensors, 0)); /* connect to the sensor */ ret = cd_sensor_connect_sync (priv->sensor, NULL, &error); if (!ret) { g_warning ("%s", error->message); g_error_free (error); goto out; } out: if (sensors != NULL) g_ptr_array_unref (sensors); } static void gcm_prefs_client_sensor_changed_cb (CdClient *client, CdSensor *sensor, CcColorPanel *prefs) { gcm_prefs_sensor_coldplug (prefs); } static const gchar * gcm_prefs_device_kind_to_icon_name (CdDeviceKind kind) { switch (kind) { case CD_DEVICE_KIND_DISPLAY: return "video-display"; case CD_DEVICE_KIND_SCANNER: return "scanner"; case CD_DEVICE_KIND_PRINTER: return "printer"; case CD_DEVICE_KIND_CAMERA: return "camera-photo"; case CD_DEVICE_KIND_WEBCAM: return "camera-web"; default: return "image-missing"; } } static GString * gcm_prefs_get_profile_age_as_string (CdProfile *profile) { const gchar *id; gint64 age; GString *string = NULL; if (profile == NULL) { /* TRANSLATORS: this is when there is no profile for the device */ string = g_string_new (_("No profile")); goto out; } /* don't show details for EDID, colorspace or test profiles */ id = cd_profile_get_metadata_item (profile, CD_PROFILE_METADATA_DATA_SOURCE); if (g_strcmp0 (id, CD_PROFILE_METADATA_DATA_SOURCE_EDID) == 0) goto out; if (g_strcmp0 (id, CD_PROFILE_METADATA_DATA_SOURCE_STANDARD) == 0) goto out; if (g_strcmp0 (id, CD_PROFILE_METADATA_DATA_SOURCE_TEST) == 0) goto out; /* days */ age = cd_profile_get_age (profile); if (age == 0) { string = g_string_new (NULL); goto out; } age /= 60 * 60 * 24; string = g_string_new (""); /* approximate years */ if (age > 365) { age /= 365; g_string_append_printf (string, ngettext ( "%i year", "%i years", age), (guint) age); goto out; } /* approximate months */ if (age > 30) { age /= 30; g_string_append_printf (string, ngettext ( "%i month", "%i months", age), (guint) age); goto out; } /* approximate weeks */ if (age > 7) { age /= 7; g_string_append_printf (string, ngettext ( "%i week", "%i weeks", age), (guint) age); goto out; } /* fallback */ g_string_append_printf (string, _("Less than 1 week")); out: return string; } static gchar * gcm_prefs_get_profile_created_for_sort (CdProfile *profile) { gint64 created; gchar *string = NULL; GDateTime *dt = NULL; /* get profile age */ created = cd_profile_get_created (profile); if (created == 0) goto out; dt = g_date_time_new_from_unix_utc (created); /* note: this is not shown in the UI, just used for sorting */ string = g_date_time_format (dt, "%Y%m%d"); out: if (dt != NULL) g_date_time_unref (dt); return string; } static gchar * gcm_prefs_get_profile_title (CcColorPanel *prefs, CdProfile *profile) { CdColorspace colorspace; const gchar *title; gchar *string; gboolean ret; GError *error = NULL; CcColorPanelPrivate *priv = prefs->priv; g_return_val_if_fail (profile != NULL, NULL); string = NULL; /* get properties */ ret = cd_profile_connect_sync (profile, priv->cancellable, &error); if (!ret) { g_warning ("failed to get profile: %s", error->message); g_error_free (error); goto out; } /* add profile description */ title = cd_profile_get_title (profile); if (title != NULL) { string = g_markup_escape_text (title, -1); goto out; } /* some meta profiles do not have ICC profiles */ colorspace = cd_profile_get_colorspace (profile); if (colorspace == CD_COLORSPACE_RGB) { string = g_strdup (C_("Colorspace fallback", "Default RGB")); goto out; } if (colorspace == CD_COLORSPACE_CMYK) { string = g_strdup (C_("Colorspace fallback", "Default CMYK")); goto out; } if (colorspace == CD_COLORSPACE_GRAY) { string = g_strdup (C_("Colorspace fallback", "Default Gray")); goto out; } /* fall back to ID, ick */ string = g_strdup (cd_profile_get_id (profile)); out: return string; } static void gcm_prefs_device_remove_profiles_phase1 (CcColorPanel *prefs, GtkTreeIter *parent) { GtkTreeIter iter; GtkTreeModel *model; gboolean ret; CcColorPanelPrivate *priv = prefs->priv; /* get first element */ model = GTK_TREE_MODEL (priv->list_store_devices); ret = gtk_tree_model_iter_children (model, &iter, parent); if (!ret) return; /* mark to be removed */ do { gtk_tree_store_set (priv->list_store_devices, &iter, GCM_PREFS_COLUMN_DEVICE_PATH, NULL, -1); } while (gtk_tree_model_iter_next (model, &iter)); } static void gcm_prefs_device_remove_profiles_phase2 (CcColorPanel *prefs, GtkTreeIter *parent) { GtkTreeIter iter; GtkTreeModel *model; gchar *id_tmp; gboolean ret; CcColorPanelPrivate *priv = prefs->priv; /* get first element */ model = GTK_TREE_MODEL (priv->list_store_devices); ret = gtk_tree_model_iter_children (model, &iter, parent); if (!ret) return; /* remove the other elements */ do { gtk_tree_model_get (model, &iter, GCM_PREFS_COLUMN_DEVICE_PATH, &id_tmp, -1); if (id_tmp == NULL) ret = gtk_tree_store_remove (priv->list_store_devices, &iter); else ret = gtk_tree_model_iter_next (model, &iter); g_free (id_tmp); } while (ret); } static GtkTreeIter * get_iter_for_profile (GtkTreeModel *model, CdProfile *profile, GtkTreeIter *parent) { const gchar *id; gboolean ret; GtkTreeIter iter; CdProfile *profile_tmp; /* get first element */ ret = gtk_tree_model_iter_children (model, &iter, parent); if (!ret) return NULL; /* remove the other elements */ id = cd_profile_get_id (profile); while (ret) { gtk_tree_model_get (model, &iter, GCM_PREFS_COLUMN_PROFILE, &profile_tmp, -1); if (g_strcmp0 (id, cd_profile_get_id (profile_tmp)) == 0) { g_object_unref (profile_tmp); return gtk_tree_iter_copy (&iter); } g_object_unref (profile_tmp); ret = gtk_tree_model_iter_next (model, &iter); } return NULL; } static void gcm_prefs_device_set_model_by_iter (CcColorPanel *prefs, CdDevice *device, GtkTreeIter *iter) { GString *status = NULL; const gchar *status_image = NULL; const gchar *tooltip = NULL; CdProfile *profile = NULL; gint age; GPtrArray *profiles = NULL; CdProfile *profile_tmp; guint i; gchar *title_tmp; GString *date_tmp; gchar *sort_tmp; GtkTreeIter iter_tmp; GtkTreeIter *iter_tmp_p; guint threshold = 0; gboolean ret; GError *error = NULL; CcColorPanelPrivate *priv = prefs->priv; /* set status */ profile = cd_device_get_default_profile (device); if (profile == NULL) { status = g_string_new (_("Uncalibrated")); g_string_prepend (status, ""); g_string_append (status, ""); tooltip = _("This device is not color managed."); goto skip; } /* get properties */ ret = cd_profile_connect_sync (profile, priv->cancellable, &error); if (!ret) { g_warning ("failed to get profile: %s", error->message); g_error_free (error); goto out; } /* ignore profiles from other user accounts */ if (!cd_profile_has_access (profile)) { /* only print the filename if it exists */ if (cd_profile_get_filename (profile) != NULL) { g_warning ("%s is not usable by this user", cd_profile_get_filename (profile)); } else { g_warning ("%s is not usable by this user", cd_profile_get_id (profile)); } goto out; } /* autogenerated printer defaults */ if (cd_device_get_kind (device) == CD_DEVICE_KIND_PRINTER && cd_profile_get_filename (profile) == NULL) { status = g_string_new (_("Uncalibrated")); g_string_prepend (status, ""); g_string_append (status, ""); tooltip = _("This device is using manufacturing calibrated data."); goto skip; } /* autogenerated profiles are crap */ if (cd_profile_get_kind (profile) == CD_PROFILE_KIND_DISPLAY_DEVICE && !cd_profile_get_has_vcgt (profile)) { status = g_string_new (_("Uncalibrated")); g_string_prepend (status, ""); g_string_append (status, ""); tooltip = _("This device does not have a profile suitable for whole-screen color correction."); goto skip; } /* yay! */ status = gcm_prefs_get_profile_age_as_string (profile); if (status == NULL) { status = g_string_new (_("Uncalibrated")); g_string_prepend (status, ""); g_string_append (status, ""); } /* greater than the calibration threshold for the device type */ age = cd_profile_get_age (profile); age /= 60 * 60 * 24; if (cd_device_get_kind (device) == CD_DEVICE_KIND_DISPLAY) { g_settings_get (priv->settings, GCM_SETTINGS_RECALIBRATE_DISPLAY_THRESHOLD, "u", &threshold); } else if (cd_device_get_kind (device) == CD_DEVICE_KIND_DISPLAY) { g_settings_get (priv->settings, GCM_SETTINGS_RECALIBRATE_PRINTER_THRESHOLD, "u", &threshold); } if (threshold > 0 && age > threshold) { status_image = "dialog-warning-symbolic"; tooltip = _("This device has an old profile that may no longer be accurate."); } skip: /* save to store */ gtk_tree_store_set (priv->list_store_devices, iter, GCM_PREFS_COLUMN_STATUS, status->str, GCM_PREFS_COLUMN_STATUS_IMAGE, status_image, GCM_PREFS_COLUMN_TOOLTIP, tooltip, -1); /* remove old profiles */ gcm_prefs_device_remove_profiles_phase1 (prefs, iter); /* add profiles */ profiles = cd_device_get_profiles (device); if (profiles == NULL) goto out; for (i = 0; i < profiles->len; i++) { profile_tmp = g_ptr_array_index (profiles, i); title_tmp = gcm_prefs_get_profile_title (prefs, profile_tmp); /* get profile age */ date_tmp = gcm_prefs_get_profile_age_as_string (profile_tmp); if (date_tmp == NULL) { /* TRANSLATORS: this is when the calibration profile age is not * specified as it has been autogenerated from the hardware */ date_tmp = g_string_new (_("Not specified")); g_string_prepend (date_tmp, ""); g_string_append (date_tmp, ""); } sort_tmp = gcm_prefs_get_profile_created_for_sort (profile_tmp); /* get an existing profile, or create a new one */ iter_tmp_p = get_iter_for_profile (GTK_TREE_MODEL (priv->list_store_devices), profile_tmp, iter); if (iter_tmp_p == NULL) gtk_tree_store_append (priv->list_store_devices, &iter_tmp, iter); gtk_tree_store_set (priv->list_store_devices, iter_tmp_p ? iter_tmp_p : &iter_tmp, GCM_PREFS_COLUMN_DEVICE, device, GCM_PREFS_COLUMN_PROFILE, profile_tmp, GCM_PREFS_COLUMN_DEVICE_PATH, cd_device_get_object_path (device), GCM_PREFS_COLUMN_SORT, sort_tmp, GCM_PREFS_COLUMN_STATUS, date_tmp->str, GCM_PREFS_COLUMN_TITLE, title_tmp, GCM_PREFS_COLUMN_RADIO_VISIBLE, TRUE, GCM_PREFS_COLUMN_RADIO_ACTIVE, i==0, -1); if (iter_tmp_p != NULL) gtk_tree_iter_free (iter_tmp_p); g_free (title_tmp); g_free (sort_tmp); g_string_free (date_tmp, TRUE); } /* remove old profiles that no longer exist */ gcm_prefs_device_remove_profiles_phase2 (prefs, iter); out: if (status != NULL) g_string_free (status, TRUE); if (profiles != NULL) g_ptr_array_unref (profiles); if (profile != NULL) g_object_unref (profile); } static void gcm_prefs_device_changed_cb (CdDevice *device, CcColorPanel *prefs) { const gchar *id; gboolean ret; gchar *id_tmp; GtkTreeIter iter; GtkTreeModel *model; CcColorPanelPrivate *priv = prefs->priv; /* get first element */ model = GTK_TREE_MODEL (priv->list_store_devices); ret = gtk_tree_model_get_iter_first (model, &iter); if (!ret) return; /* get the other elements */ id = cd_device_get_object_path (device); do { gtk_tree_model_get (model, &iter, GCM_PREFS_COLUMN_DEVICE_PATH, &id_tmp, -1); if (g_strcmp0 (id_tmp, id) == 0) { /* populate device */ gcm_prefs_device_set_model_by_iter (prefs, device, &iter); } g_free (id_tmp); } while (gtk_tree_model_iter_next (model, &iter)); } static void gcm_prefs_add_device (CcColorPanel *prefs, CdDevice *device) { gboolean ret; GError *error = NULL; CdDeviceKind kind; const gchar *icon_name; const gchar *id; gchar *sort = NULL; gchar *title = NULL; GtkTreeIter parent; CcColorPanelPrivate *priv = prefs->priv; /* get device properties */ ret = cd_device_connect_sync (device, priv->cancellable, &error); if (!ret) { g_warning ("failed to connect to the device: %s", error->message); g_error_free (error); goto out; } /* get icon */ kind = cd_device_get_kind (device); icon_name = gcm_prefs_device_kind_to_icon_name (kind); /* italic for non-connected devices */ title = gcm_device_get_title (device); /* create sort order */ sort = g_strdup_printf ("%s%s", gcm_prefs_device_kind_to_sort (kind), title); /* watch for changes to update the status icons */ g_signal_connect (device, "changed", G_CALLBACK (gcm_prefs_device_changed_cb), prefs); /* add to list */ id = cd_device_get_object_path (device); g_debug ("add %s to device list", id); gtk_tree_store_append (priv->list_store_devices, &parent, NULL); gtk_tree_store_set (priv->list_store_devices, &parent, GCM_PREFS_COLUMN_DEVICE, device, GCM_PREFS_COLUMN_DEVICE_PATH, id, GCM_PREFS_COLUMN_SORT, sort, GCM_PREFS_COLUMN_TITLE, title, GCM_PREFS_COLUMN_ICON, icon_name, -1); gcm_prefs_device_set_model_by_iter (prefs, device, &parent); out: g_free (sort); g_free (title); } static void gcm_prefs_remove_device (CcColorPanel *prefs, CdDevice *cd_device) { GtkTreeIter iter; GtkTreeModel *model; const gchar *id; gchar *id_tmp; gboolean ret; CdDevice *device_tmp; CcColorPanelPrivate *priv = prefs->priv; /* remove */ id = cd_device_get_object_path (cd_device); /* get first element */ model = GTK_TREE_MODEL (priv->list_store_devices); ret = gtk_tree_model_get_iter_first (model, &iter); if (!ret) return; /* get the other elements */ do { gtk_tree_model_get (model, &iter, GCM_PREFS_COLUMN_DEVICE_PATH, &id_tmp, -1); if (g_strcmp0 (id_tmp, id) == 0) { gtk_tree_model_get (model, &iter, GCM_PREFS_COLUMN_DEVICE, &device_tmp, -1); g_signal_handlers_disconnect_by_func (device_tmp, G_CALLBACK (gcm_prefs_device_changed_cb), prefs); gtk_tree_store_remove (GTK_TREE_STORE (model), &iter); g_free (id_tmp); g_object_unref (device_tmp); break; } g_free (id_tmp); } while (gtk_tree_model_iter_next (model, &iter)); } static void gcm_prefs_update_device_list_extra_entry (CcColorPanel *prefs) { CcColorPanelPrivate *priv = prefs->priv; gboolean ret; gchar *id_tmp; gchar *title = NULL; GtkTreeIter iter; /* select the first device */ ret = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->list_store_devices), &iter); if (!ret) { /* add the 'No devices detected' entry */ title = g_strdup_printf ("%s", _("No devices supporting color management detected")); gtk_tree_store_append (priv->list_store_devices, &iter, NULL); gtk_tree_store_set (priv->list_store_devices, &iter, GCM_PREFS_COLUMN_RADIO_VISIBLE, FALSE, GCM_PREFS_COLUMN_TITLE, title, -1); g_free (title); return; } /* remove the 'No devices detected' entry */ do { gtk_tree_model_get (GTK_TREE_MODEL (priv->list_store_devices), &iter, GCM_PREFS_COLUMN_DEVICE_PATH, &id_tmp, -1); if (id_tmp == NULL) { gtk_tree_store_remove (priv->list_store_devices, &iter); break; } g_free (id_tmp); } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->list_store_devices), &iter)); } static void gcm_prefs_device_added_cb (CdClient *client, CdDevice *device, CcColorPanel *prefs) { /* add the device */ gcm_prefs_add_device (prefs, device); /* ensure we're not showing the 'No devices detected' entry */ gcm_prefs_update_device_list_extra_entry (prefs); } static void gcm_prefs_changed_cb (CdClient *client, CdDevice *device, CcColorPanel *prefs) { g_debug ("changed: %s (doing nothing)", cd_device_get_id (device)); } static void gcm_prefs_device_removed_cb (CdClient *client, CdDevice *device, CcColorPanel *prefs) { GtkTreeIter iter; GtkTreeSelection *selection; GtkWidget *widget; gboolean ret; CcColorPanelPrivate *priv = prefs->priv; /* remove from the UI */ gcm_prefs_remove_device (prefs, device); /* ensure we showing the 'No devices detected' entry if required */ gcm_prefs_update_device_list_extra_entry (prefs); /* select the first device */ ret = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->list_store_devices), &iter); if (!ret) return; /* click it */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "treeview_devices")); gtk_tree_view_set_model (GTK_TREE_VIEW (widget), GTK_TREE_MODEL (priv->list_store_devices)); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)); gtk_tree_selection_select_iter (selection, &iter); } static gboolean gcm_prefs_tree_model_count_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data) { guint *i = (guint *) user_data; (*i)++; return FALSE; } static void gcm_prefs_get_devices_cb (GObject *object, GAsyncResult *res, gpointer user_data) { CcColorPanel *prefs = (CcColorPanel *) user_data; CdClient *client = CD_CLIENT (object); CdDevice *device; GError *error = NULL; GPtrArray *devices; GtkTreePath *path; GtkWidget *widget; guint i; guint devices_and_profiles = 0; CcColorPanelPrivate *priv = prefs->priv; /* get devices and add them */ devices = cd_client_get_devices_finish (client, res, &error); if (devices == NULL) { g_warning ("failed to add connected devices: %s", error->message); g_error_free (error); goto out; } for (i = 0; i < devices->len; i++) { device = g_ptr_array_index (devices, i); gcm_prefs_add_device (prefs, device); } /* ensure we show the 'No devices detected' entry if empty */ gcm_prefs_update_device_list_extra_entry (prefs); /* set the cursor on the first device */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "treeview_devices")); path = gtk_tree_path_new_from_string ("0"); gtk_tree_view_set_cursor (GTK_TREE_VIEW (widget), path, NULL, FALSE); gtk_tree_path_free (path); /* if we have only a few devices and profiles expand the treeview * devices so they can all be seen */ gtk_tree_model_foreach (GTK_TREE_MODEL (priv->list_store_devices), gcm_prefs_tree_model_count_cb, &devices_and_profiles); if (devices_and_profiles <= GCM_PREFS_MAX_DEVICES_PROFILES_EXPANDED) gtk_tree_view_expand_all (GTK_TREE_VIEW (widget)); out: if (devices != NULL) g_ptr_array_unref (devices); } static void gcm_prefs_button_virtual_add_cb (GtkWidget *widget, CcColorPanel *prefs) { CdDeviceKind device_kind; CdDevice *device; const gchar *model; const gchar *manufacturer; gchar *device_id; GError *error = NULL; GHashTable *device_props; CcColorPanelPrivate *priv = prefs->priv; /* get device details */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "combobox_virtual_type")); device_kind = gtk_combo_box_get_active (GTK_COMBO_BOX(widget)) + 2; widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "entry_virtual_model")); model = gtk_entry_get_text (GTK_ENTRY (widget)); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "entry_virtual_manufacturer")); manufacturer = gtk_entry_get_text (GTK_ENTRY (widget)); /* create device */ device_id = g_strdup_printf ("%s-%s-%s", cd_device_kind_to_string (device_kind), manufacturer, model); device_props = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); g_hash_table_insert (device_props, g_strdup ("Kind"), g_strdup (cd_device_kind_to_string (device_kind))); g_hash_table_insert (device_props, g_strdup ("Mode"), g_strdup (cd_device_mode_to_string (CD_DEVICE_MODE_VIRTUAL))); g_hash_table_insert (device_props, g_strdup ("Colorspace"), g_strdup (cd_colorspace_to_string (CD_COLORSPACE_RGB))); g_hash_table_insert (device_props, g_strdup ("Model"), g_strdup (model)); g_hash_table_insert (device_props, g_strdup ("Vendor"), g_strdup (manufacturer)); device = cd_client_create_device_sync (priv->client, device_id, CD_OBJECT_SCOPE_DISK, device_props, priv->cancellable, &error); if (device == NULL) { g_warning ("Failed to add create virtual device: %s", error->message); g_error_free (error); goto out; } out: g_hash_table_unref (device_props); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "dialog_virtual")); gtk_widget_hide (widget); g_free (device_id); } static void gcm_prefs_button_virtual_cancel_cb (GtkWidget *widget, CcColorPanel *prefs) { CcColorPanelPrivate *priv = prefs->priv; widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "dialog_virtual")); gtk_widget_hide (widget); } static gboolean gcm_prefs_virtual_delete_event_cb (GtkWidget *widget, GdkEvent *event, CcColorPanel *prefs) { gcm_prefs_button_virtual_cancel_cb (widget, prefs); return TRUE; } static const gchar * cd_device_kind_to_localised_string (CdDeviceKind device_kind) { if (device_kind == CD_DEVICE_KIND_DISPLAY) return C_("Device kind", "Display"); if (device_kind == CD_DEVICE_KIND_SCANNER) return C_("Device kind", "Scanner"); if (device_kind == CD_DEVICE_KIND_PRINTER) return C_("Device kind", "Printer"); if (device_kind == CD_DEVICE_KIND_CAMERA) return C_("Device kind", "Camera"); if (device_kind == CD_DEVICE_KIND_WEBCAM) return C_("Device kind", "Webcam"); return NULL; } static void gcm_prefs_setup_virtual_combobox (GtkWidget *widget) { guint i; const gchar *text; for (i=CD_DEVICE_KIND_SCANNER; ipriv; ret = cd_client_connect_finish (priv->client, res, &error); if (!ret) { g_warning ("failed to connect to colord: %s", error->message); g_error_free (error); return; } /* set calibrate button sensitivity */ gcm_prefs_sensor_coldplug (prefs); /* get devices */ cd_client_get_devices (priv->client, priv->cancellable, gcm_prefs_get_devices_cb, prefs); } static void gcm_prefs_window_realize_cb (GtkWidget *widget, CcColorPanel *prefs) { prefs->priv->main_window = gtk_widget_get_toplevel (widget); } static const char * cc_color_panel_get_help_uri (CcPanel *panel) { if (!g_strcmp0(g_getenv("XDG_CURRENT_DESKTOP"), "Unity")) return "help:ubuntu-help/color"; else return "help:gnome-help/color"; } static void cc_color_panel_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { switch (property_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void cc_color_panel_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { switch (property_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void cc_color_panel_dispose (GObject *object) { CcColorPanelPrivate *priv = CC_COLOR_PANEL (object)->priv; if (priv->settings) { g_object_unref (priv->settings); priv->settings = NULL; } if (priv->cancellable != NULL) { g_cancellable_cancel (priv->cancellable); g_object_unref (priv->cancellable); priv->cancellable = NULL; } if (priv->builder != NULL) { g_object_unref (priv->builder); priv->builder = NULL; } if (priv->client != NULL) { g_object_unref (priv->client); priv->client = NULL; } if (priv->current_device != NULL) { g_object_unref (priv->current_device); priv->current_device = NULL; } if (priv->sensor != NULL) { g_object_unref (priv->sensor); priv->sensor = NULL; } G_OBJECT_CLASS (cc_color_panel_parent_class)->dispose (object); } static void cc_color_panel_finalize (GObject *object) { G_OBJECT_CLASS (cc_color_panel_parent_class)->finalize (object); } static void cc_color_panel_class_init (CcColorPanelClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); CcPanelClass *panel_class = CC_PANEL_CLASS (klass); g_type_class_add_private (klass, sizeof (CcColorPanelPrivate)); panel_class->get_help_uri = cc_color_panel_get_help_uri; object_class->get_property = cc_color_panel_get_property; object_class->set_property = cc_color_panel_set_property; object_class->dispose = cc_color_panel_dispose; object_class->finalize = cc_color_panel_finalize; } static void cc_color_panel_init (CcColorPanel *prefs) { CcColorPanelPrivate *priv; GError *error = NULL; GtkStyleContext *context; GtkTreeSelection *selection; GtkWidget *widget; priv = prefs->priv = COLOR_PANEL_PRIVATE (prefs); priv->builder = gtk_builder_new (); gtk_builder_add_from_file (priv->builder, CINNAMONCC_UI_DIR "/color.ui", &error); if (error != NULL) { g_warning ("Could not load interface file: %s", error->message); g_error_free (error); return; } priv->cancellable = g_cancellable_new (); /* setup defaults */ priv->settings = g_settings_new (GCM_SETTINGS_SCHEMA); /* create list stores */ priv->list_store_devices = gtk_tree_store_new (GCM_PREFS_COLUMN_NUM_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, CD_TYPE_DEVICE, CD_TYPE_PROFILE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN); /* assign buttons */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "toolbutton_profile_add")); g_signal_connect (widget, "clicked", G_CALLBACK (gcm_prefs_profile_add_cb), prefs); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "toolbutton_profile_remove")); g_signal_connect (widget, "clicked", G_CALLBACK (gcm_prefs_profile_remove_cb), prefs); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "toolbutton_profile_view")); g_signal_connect (widget, "clicked", G_CALLBACK (gcm_prefs_profile_view_cb), prefs); /* create device tree view */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "treeview_devices")); gtk_tree_view_set_model (GTK_TREE_VIEW (widget), GTK_TREE_MODEL (priv->list_store_devices)); gtk_tree_view_set_enable_tree_lines (GTK_TREE_VIEW (widget), TRUE); gtk_tree_view_set_level_indentation (GTK_TREE_VIEW (widget), 0); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)); g_signal_connect (selection, "changed", G_CALLBACK (gcm_prefs_devices_treeview_clicked_cb), prefs); g_signal_connect (GTK_TREE_VIEW (widget), "row-activated", G_CALLBACK (gcm_prefs_treeview_row_activated_cb), prefs); g_signal_connect (GTK_TREE_VIEW (widget), "popup-menu", G_CALLBACK (gcm_prefs_treeview_popup_menu_cb), prefs); /* add columns to the tree view */ gcm_prefs_add_devices_columns (prefs, GTK_TREE_VIEW (widget)); /* force to be at least ~6 rows high */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "scrolledwindow_devices")); gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (widget), 200); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "toolbutton_device_default")); g_signal_connect (widget, "clicked", G_CALLBACK (gcm_prefs_default_cb), prefs); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "toolbutton_device_remove")); g_signal_connect (widget, "clicked", G_CALLBACK (gcm_prefs_delete_cb), prefs); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "toolbutton_device_add")); g_signal_connect (widget, "clicked", G_CALLBACK (gcm_prefs_device_add_cb), prefs); /* make devices toolbar sexy */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "scrolledwindow_devices")); context = gtk_widget_get_style_context (widget); gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "toolbar_devices")); context = gtk_widget_get_style_context (widget); gtk_style_context_add_class (context, GTK_STYLE_CLASS_INLINE_TOOLBAR); gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP); /* set up virtual dialog */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "dialog_virtual")); g_signal_connect (widget, "delete-event", G_CALLBACK (gcm_prefs_virtual_delete_event_cb), prefs); g_signal_connect (widget, "drag-data-received", G_CALLBACK (gcm_prefs_virtual_drag_data_received_cb), prefs); gcm_prefs_setup_drag_and_drop (widget); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_virtual_add")); g_signal_connect (widget, "clicked", G_CALLBACK (gcm_prefs_button_virtual_add_cb), prefs); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_virtual_cancel")); g_signal_connect (widget, "clicked", G_CALLBACK (gcm_prefs_button_virtual_cancel_cb), prefs); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "combobox_virtual_type")); gcm_prefs_setup_virtual_combobox (widget); /* set up assign dialog */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "dialog_assign")); g_signal_connect (widget, "delete-event", G_CALLBACK (gcm_prefs_profile_delete_event_cb), prefs); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_assign_cancel")); g_signal_connect (widget, "clicked", G_CALLBACK (gcm_prefs_button_assign_cancel_cb), prefs); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_assign_ok")); g_signal_connect (widget, "clicked", G_CALLBACK (gcm_prefs_button_assign_ok_cb), prefs); /* setup icc profiles list */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "combobox_profile")); gcm_prefs_set_combo_simple_text (widget); gtk_widget_set_sensitive (widget, FALSE); g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (gcm_prefs_profile_combo_changed_cb), prefs); /* use a device client array */ priv->client = cd_client_new (); g_signal_connect (priv->client, "device-added", G_CALLBACK (gcm_prefs_device_added_cb), prefs); g_signal_connect (priv->client, "device-removed", G_CALLBACK (gcm_prefs_device_removed_cb), prefs); g_signal_connect (priv->client, "changed", G_CALLBACK (gcm_prefs_changed_cb), prefs); /* connect to colord */ cd_client_connect (priv->client, priv->cancellable, gcm_prefs_connect_cb, prefs); /* use the color sensor */ g_signal_connect (priv->client, "sensor-added", G_CALLBACK (gcm_prefs_client_sensor_changed_cb), prefs); g_signal_connect (priv->client, "sensor-removed", G_CALLBACK (gcm_prefs_client_sensor_changed_cb), prefs); widget = WID (priv->builder, "dialog-vbox1"); gtk_widget_reparent (widget, (GtkWidget *) prefs); g_signal_connect (widget, "realize", G_CALLBACK (gcm_prefs_window_realize_cb), prefs); } void cc_color_panel_register (GIOModule *module) { textdomain (GETTEXT_PACKAGE); bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); cc_color_panel_register_type (G_TYPE_MODULE (module)); g_io_extension_point_implement (CC_SHELL_PANEL_EXTENSION_POINT, CC_TYPE_COLOR_PANEL, "color", 0); } cinnamon-control-center-6.4.1/panels/color/color-module.c0000664000175000017500000000214514724311620022353 0ustar fabiofabio/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- * * Copyright (C) 2010 Red Hat, Inc * Copyright (C) 2011 Richard Hughes * * 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 Street - Suite 500, Boston, MA 02110-1335, USA. * * */ #include #include "cc-color-panel.h" #include void g_io_module_load (GIOModule *module) { /* register the panel */ cc_color_panel_register (module); } void g_io_module_unload (GIOModule *module) { } cinnamon-control-center-6.4.1/panels/color/color.ui0000664000175000017500000007050414724311620021267 0ustar fabiofabio False 5 False True center-on-parent True gnome-color-manager dialog True True dialog_prefs True False vertical 2 True False end gtk-cancel True True True False True False False 0 gtk-add True True True False True False False 1 False True end 0 True False 9 True False True False Available Profiles False False 0 False False 0 True False 5 False True 1 False True 1 button_assign_cancel button_assign_ok False 12 Color center preferences-system True False 15 vertical 12 True False 9 True False 0 Each device needs an up to date color profile to be color managed. True False False 0 True False True True 1 False False 0 True False True True in True True True True 0 True False False 1 True False False True False Add device True False True Add a virtual device False True False True 0 Delete device True False True Remove a device False True False True 1 Set for all users False True Set this profile for all users on this computer False True False True 2 True True False False True False Add profile True False False True False True 0 Remove profile False False True False True 1 View details False False True False True 2 False False True 1 False True 1 False 15 False True center-on-parent True gnome-color-manager dialog True True dialog_prefs True False vertical 2 True False end gtk-cancel True True True False True False False 0 gtk-add True True True False True False False 1 False True end 0 True False 9 True False 3 2 6 9 True False True False Device type: False True 0 GTK_FILL GTK_FILL True False 0 1 2 True False True False Manufacturer: False True 0 1 2 GTK_FILL GTK_FILL True False True False Model: False True 0 2 3 GTK_FILL GTK_FILL True True ā— 1 2 1 2 True True ā— 1 2 2 3 False False 0 True False 12 True False gtk-dialog-info 6 False True 0 True False True False Image files can be dragged on this window to auto-complete the above fields. True True True 0 False True 1 False False 1 True True 1 button_virtual_cancel button_virtual_add cinnamon-control-center-6.4.1/panels/color/cinnamon-color-panel.desktop0000664000175000017500000002006514724311620025215 0ustar fabiofabio[Desktop Entry] Exec=cinnamon-settings color Icon=cs-color Terminal=false Type=Application StartupNotify=true Categories=GTK;Settings;X-Cinnamon-Settings-Panel;HardwareSettings OnlyShowIn=X-Cinnamon; X-Cinnamon-Settings-Panel=color Name=Color Name[am]=į‰€įˆˆįˆ Name[ar]=Ų§Ł„Ł„ŁˆŁ† Name[ay]=Sami Name[az]=Tüs Name[be]=ŠšŠ¾Š»ŠµŃ€ Name[be@latin]=ŠšŠ¾Š»ŠµŃ€ Name[bg]=Š¦Š²ŃŃ‚ Name[br]=Livioù Name[bs]=Boja Name[cs]=Barva Name[cy]=Lliw Name[da]=Farve Name[de]=Farbe Name[el]=Ī§ĻĻ‰Ī¼Ī±Ļ„Ī¹ĻƒĪ¼ĻŒĻ‚ Name[en_CA]=Colour Name[en_GB]=Colour Name[eo]=Koloro Name[et]=VƤrv Name[eu]=Kolorea Name[fa]=رنگ Name[fi]=VƤri Name[fr]=Couleur Name[fr_CA]=Couleur Name[gd]=Dath Name[gl]=Cor Name[he]=צבע Name[hi]=रंग Name[hr]=Boja Name[hu]=SzĆ­n Name[id]=Warna Name[is]=Litur Name[it]=Colore Name[ja]=色 Name[ka]=įƒ¤įƒ”įƒ įƒ˜ Name[kab]=Ini Name[kk]=Түс Name[km]=įž–įžŽįŸŒ Name[ko]=ģƒ‰ź¹” Name[ku]=Reng Name[lt]=Spalva Name[lv]=Krāsa Name[ms]=Warna Name[nb]=Farge Name[nds]=Farbe Name[nl]=Kleur Name[nn]=Farge Name[pa]=ਰੰਗ Name[pl]=Kolor Name[pt]=Cor Name[pt_BR]=Cor Name[ro]=Culoare Name[ru]=Цвет Name[rue]=Цвіт Name[sc]=Colores Name[sk]=Farba Name[sl]=Barva Name[sq]=Ngjyra Name[sr]=Š‘Š¾Ń˜Š° Name[sr@latin]=Boja Name[sv]=FƤrg Name[ta]=ą®µą®£ąÆą®£ą®®ąÆ Name[tg]=Ранг Name[th]=ąøŖąøµ Name[tr]=Renk Name[uk]=ŠšŠ¾Š»Ń–Ń€ Name[ur]=رنگ Name[uz]=Rang Name[uz@cyrillic]=Rang Name[vi]=MĆ u sįŗÆc Name[zh_CN]=色彩 Name[zh_HK]=é”č‰² Name[zh_TW]=é”č‰² Comment=Color management settings Comment[am]=የ į‰€įˆˆįˆ įŠ įˆµį‰°į‹³į‹³įˆŖ įˆ›įˆ°įŠ“įŒƒ Comment[ar]=Ų„Ų¹ŲÆŲ§ŲÆŲ§ŲŖ Ų„ŲÆŲ§Ų±Ų© Ų§Ł„Ł„ŁˆŁ† Comment[ast]=Axustes de l'alministración de color Comment[ay]=Sami irpaw mayjachawi Comment[az]=Tüs yƶnətim quruluşları Comment[be]=ŠŠ°Š»Š°Š“Ń‹ ŠŗŠ¾Š»ŠµŃ€Š°Ńž Comment[be@latin]=ŠŠ°Š»Š°Š“Ń‹ ŠŗŠ¾Š»ŠµŃ€Š°Ńž Comment[bg]=ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠ° на цвета Comment[bs]=PodeÅ”avanja upravljanja bojom Comment[ca]=Ajusts de gestió del color Comment[ca@valencia]=ParĆ metres de gestió del color Comment[cs]=NastavenĆ­ sprĆ”vy barev Comment[cy]=Gosodiadau rheoli lliw Comment[da]=Farvestyringsindstillinger Comment[de]=Einstellungen der Farbverwaltung Comment[el]=Ī”Ļ…ĪøĪ¼ĪÆĻƒĪµĪ¹Ļ‚ για τη Ī“Ī¹Ī±Ļ‡ĪµĪÆĻĪ¹ĻƒĪ· χρωμάτων Comment[en_CA]=Colour management settings Comment[en_GB]=Colour management settings Comment[eo]=Ŝanĝi administrad-agordojn Comment[es]=Configuración de la gestión de color Comment[et]=VƤrvihalduse seaded Comment[eu]=Kolore-kudeaketaren ezarpenak Comment[fa]=ŲŖŁ†ŲøŪŒŁ…Ų§ŲŖ Ł…ŲÆŪŒŲ±ŪŒŲŖ رنگ Comment[fi]=VƤrien hallinta Comment[fr]=Gestion des couleurs Comment[fr_CA]=ParamĆØtres de gestion des couleurs Comment[gd]=Roghainnean stiùireadh nan dathan Comment[gl]=Axustes da xestión da cor Comment[he]=הגדרות ניהול צבע Comment[hi]=रंग ą¤Ŗą„ą¤°ą¤¬ą¤‚ą¤§ą¤Ø ą¤øą„‡ą¤Ÿą¤æą¤‚ą¤—ą„ą¤ø Comment[hr]=Postavke upravljanja bojom Comment[hu]=SzĆ­nkezelĆ©si beĆ”llĆ­tĆ”sok Comment[ia]=Configurationes del gestion de color Comment[id]=Pengaturan manajemen warna Comment[is]=Stillingar litastýringar Comment[it]=Impostazioni di gestione del colore Comment[ja]=č‰²ē®”ē†ć®čØ­å®š Comment[kab]=IÉ£ewwaren usefrek n yiniten Comment[kk]=Түстер Š±Š°ŃŅ›Š°Ń€Ńƒ Š±Š°ŠæŃ‚Š°ŃƒŠ»Š°Ń€Ń‹ Comment[ko]=ģƒ‰ ꓀리 설정 Comment[la]=Configuratio colorum Comment[lt]=Spalvų derinimo nustatymai Comment[lv]=Krāsu pārvaldÄ«bas iestatÄ«jumi Comment[ms]=Tetapan pengurusan warna Comment[nb]=FargehĆ„ndteringsinnstillinger Comment[nl]=Kleurbeheerinstellingen Comment[oc]=ParamĆØtres de gestion de las colors Comment[pa]=ਰੰਗ ąØ®ą©ˆąØØą©‡ąØœąØ®ą©ˆąØ‚ąØŸ ąØøą©ˆąØŸąØæą©°ąØ— Comment[pl]=Ustawienia zarządzania kolorami Comment[pt]=DefiniƧƵes da gestĆ£o de cores Comment[pt_BR]=ConfiguraƧƵes de gerenciamento de cores Comment[ro]=Setări gestiune culori Comment[ru]=ŠŠ°ŃŃ‚Ń€Š¾Š¹ŠŗŠø ŃƒŠæŃ€Š°Š²Š»ŠµŠ½ŠøŃ цветом Comment[sk]=Nastavenia sprĆ”vy farieb Comment[sl]=Nastavitve upravljanja barv Comment[sq]=Parametrat e menaxhimit tĆ« ngjyrĆ«s Comment[sr]=ПоГешавања ŃƒŠæŃ€Š°Š²Ń™Š°ŃšŠ° бојом Comment[sr@latin]=PodeÅ”avanja upravljanja bojom Comment[sv]=InstƤllningar fƶr fƤrghantering Comment[ta]=நிற ą®®ąÆ‡ą®²ą®¾ą®£ąÆą®®ąÆˆ ą®…ą®®ąÆˆą®ŖąÆą®ŖąÆą®•ą®³ąÆ Comment[tg]=Танзимоти ŠøŠ“Š¾Ń€Š°ŠŗŃƒŠ½ŠøŠø ранг Comment[th]=ąø•ąø±ą¹‰ąø‡ąø„ą¹ˆąø²ąøąø²ąø£ąøˆąø±ąø”ąøąø²ąø£ąøŖąøµ Comment[tr]=Renk yƶnetimi ayarları Comment[uk]=ŠŠ°Š»Š°ŃˆŃ‚ŃƒŠ²Š°Š½Š½Ń ŠŗŠµŃ€ŃƒŠ²Š°Š½Š½Ń ŠŗŠ¾Š»ŃŒŠ¾Ń€Š¾Š¼ Comment[ur]=رنگ کے انتظام کی ترتیبات Comment[uz]=Ranglarni boshqarish moslamalari Comment[uz@cyrillic]=Ranglarni boshqarish moslamalari Comment[vi]=CĆ i đặt quįŗ£n lý mĆ u Comment[zh_CN]=色彩箔理设置 Comment[zh_HK]=é”č‰²ē®”ē†čØ­å®š Comment[zh_TW]=é”č‰²ē®”ē†čØ­å®š Keywords=Color;ICC;Profile;Calibrate;Printer;Display; Keywords[ast]=Collor;ICC;Perfil;Calibrar;Imprentadora;Pantalla; Keywords[be]=колер;ŠæŃ€Š¾Ń„Ń–Š»ŃŒ;ŠŗŠ°Š»Ń–Š±Ń€Š¾ŃžŠŗŠ°;прынтар;Š“Ń‹ŃŠæŠ»ŃŠ¹; Keywords[be@latin]=колер;ŠæŃ€Š¾Ń„Ń–Š»ŃŒ;ŠŗŠ°Š»Ń–Š±Ń€Š¾ŃžŠŗŠ°;прынтар;Š“Ń‹ŃŠæŠ»ŃŠ¹; Keywords[ca]=Color;ICC;Perfil;Calibrar;Impressora;Pantalla; Keywords[ca@valencia]=Color;ICC;Perfil;Calibrar;Impressora;Pantalla; Keywords[cs]=Barva;ICC;profil;kalibrace;tisk;displeje; Keywords[cy]=Lliw;ICC;Proffil;Calibro;Argraffydd;Dangosydd; Keywords[da]=Farve;ICC;Profil;Kalibrere;Printer;SkƦrm; Keywords[de]=Color;ICC;Profile;Calibrate;Printer;Display;Farbe;Kalibrieren;Drucker;Bildschirm;Anzeige; Keywords[el]=Ī§ĻĻŽĪ¼Ī±;ICC;Προφίλ;Ī’Ī±ĪøĪ¼ĪæĪ½ĻŒĪ¼Ī·ĻƒĪ·;Εκτυπωτής;Οθόνη; Keywords[en_GB]=Colour;ICC;Profile;Calibrate;Printer;Display; Keywords[eo]=Koloro;ICC;Profilo;Kalibri;Presilo;Ekrano; Keywords[es]=Color;ICC;Perfil;Calibrar;Impresora;Pantalla; Keywords[et]=VƤrv;ICC;profiil;kalibreerimine;printer;ekraan; Keywords[eu]=Kolorea;ICC;Profila;Kalibratu;Inprimagailua;Pantaila; Keywords[fa]=Ų±Ł†ŚÆŲŒ ICC ، Ł¾Ų±ŁˆŁŲ§ŪŒŁ„ŲŒ Ś©Ų§Ł„ŪŒŲØŲ±Ł‡ Ś©Ų±ŲÆŁ†ŲŒ Ł¾Ų±ŪŒŁ†ŲŖŲ±ŲŒ Ł†Ł…Ų§ŪŒŲ“ŚÆŲ±; Keywords[fi]=VƤri;ICC;Profiili;Kalibrointi;Tulostin;NƤyttƶ; Keywords[fr]=Couleur;ICC;Profil;Calibrer;Imprimante;Affichage; Keywords[fr_CA]=Couleur;ICC;Profil;Calibrer;Imprimante;Affichage; Keywords[he]=צבע;ICC;×¤×Ø×•×¤×™×œ;כיול;×ž×“×¤×”×Ŗ;תצוגה; Keywords[hi]=रंग;ą¤†ą¤ˆą¤øą„€ą¤øą„€;ą¤Ŗą„ą¤°ą„‹ą¤«ą¤¾ą¤‡ą¤²;ą¤•ą„ˆą¤²ą¤æą¤¬ą„ą¤°ą„‡ą¤Ÿ;ą¤Ŗą„ą¤°ą¤æą¤‚ą¤Ÿą¤°;ą¤”ą¤æą¤øą„ą¤Ŗą„ą¤²ą„‡; Keywords[hr]=Boja;ICC;Profil;Kalibracija;Pisač;Zaslon; Keywords[hu]=SzĆ­n;ICC;SzĆ­nek;ProfilozĆ”s;KalibrĆ”lĆ”s;Nyomtató;Kijelző;Color;Profile;Calibrate;Printer;Display; Keywords[ia]=Color;ICC;Profilo;Calibrar;Imprimitor;Visualisation; Keywords[id]=Warna;ICC;Profil;Kalibrasi;Printer;Tampilan; Keywords[is]=Litur;ICC;Litasniư;Kvarưa;Prentari;SkjĆ”r; Keywords[it]=Colore;ICC;Profilo;Calibrazione;Stampante;Schermo; Keywords[ja]=Color;ICC;Profile;Calibrate;Printer;Display;ć‚«ćƒ©ćƒ¼;色;ćƒ—ćƒ­ćƒ•ć‚”ć‚¤ćƒ«;ć‚­ćƒ£ćƒŖćƒ–ćƒ¬ćƒ¼ć‚·ćƒ§ćƒ³;較正;ćƒ—ćƒŖćƒ³ć‚æćƒ¼;ćƒ‡ć‚£ć‚¹ćƒ—ćƒ¬ć‚¤; Keywords[ko]=ģƒ‰ģƒ;ICC;ķ”„ė”œķ•„;볓정;프린터;ė””ģŠ¤ķ”Œė ˆģ“; Keywords[nb]=Farge;ICC;Profil;Kalibrer;Printer;Skjerm; Keywords[nl]=Kleur;ICC;Profiel;Calibreren;Printer;Beeldscherm; Keywords[oc]=Color;ICC;Perfil;Calibrar;Imprimenta;Afichatge; Keywords[pl]=Kolor;ICC;Profil;Kalibracja;Drukarka;Wyświetlacz; Keywords[pt]=Cor;ICC;Perfil;Calibrar;Impressora;EcrĆ£; Keywords[pt_BR]=Cor;ICC;Perfil;Calibrar;Impressora;Exibir; Keywords[ro]=Culoare;ICC;Profil;Calibrare;Imprimantă;Afișare; Keywords[ru]=Цвет;ICC;ŠŸŃ€Š¾Ń„ŠøŠ»ŃŒ;ŠšŠ°Š»ŠøŠ±Ń€Š¾Š²Š°Ń‚ŃŒ;ŠŸŃ€ŠøŠ½Ń‚ŠµŃ€;Экран; Keywords[rue]=Цвіт;ICC;ŠŸŃ€Š¾Ń„Ń–Š»;ŠœŃƒŃŃ‚Ń€Š¾Š²Š°Ń‚Šø;ŠŸŃ€Ń–Š½Ń‚ŠµŃ€;Екран; Keywords[sk]=Farba;ICC;Profil;KalibrĆ”cia;Tlačiareň;Displej; Keywords[sl]=Barva;ICC;profil;kalibriraj;tiskalnik;zaslon; Keywords[sv]=FƤrg;ICC;Profil;Kalibrera;Skrivare;SkƤrm; Keywords[tr]=Renk;ICC;Profil;Kalibrasyon;Yazıcı;Gƶrüntü; Keywords[uk]=ŠšŠ¾Š»Ń–Ń€;ICC;ŠŸŃ€Š¾Ń„Ń–Š»ŃŒ;ŠšŠ°Š»Ń–Š±Ń€ŃƒŠ²Š°Š½Š½Ń;ŠŸŃ€ŠøŠ½Ń‚ŠµŃ€;Дисплей; Keywords[uz]=Rang;ICC;Profil;Kalibrlash;Printer;Displey; Keywords[uz@cyrillic]=Rang;ICC;Profil;Kalibrlash;Printer;Displey; Keywords[vi]=MĆ u sįŗÆc;ICC;Hồ sĘ”;Hiệu chỉnh;MĆ”y in;MĆ n hƬnh hiển thị; Keywords[zh_TW]=色彩;ICC;čØ­å®šęŖ”;栔正;å°č”Øę©Ÿ;čž¢å¹•; cinnamon-control-center-6.4.1/panels/color/cc-color-panel.h0000664000175000017500000000376414724311620022565 0ustar fabiofabio/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- * * Copyright (C) 2010 Red Hat, Inc * Copyright (C) 2011 Richard Hughes * * 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 Street - Suite 500, Boston, MA 02110-1335, USA. * */ #ifndef _CC_COLOR_PANEL_H #define _CC_COLOR_PANEL_H #include G_BEGIN_DECLS #define CC_TYPE_COLOR_PANEL cc_color_panel_get_type() #define CC_COLOR_PANEL(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ CC_TYPE_COLOR_PANEL, CcColorPanel)) #define CC_COLOR_PANEL_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), \ CC_TYPE_COLOR_PANEL, CcColorPanelClass)) #define CC_IS_COLOR_PANEL(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ CC_TYPE_COLOR_PANEL)) #define CC_IS_COLOR_PANEL_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), \ CC_TYPE_COLOR_PANEL)) #define CC_COLOR_PANEL_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), \ CC_TYPE_COLOR_PANEL, CcColorPanelClass)) typedef struct _CcColorPanel CcColorPanel; typedef struct _CcColorPanelClass CcColorPanelClass; typedef struct _CcColorPanelPrivate CcColorPanelPrivate; struct _CcColorPanel { CcPanel parent; CcColorPanelPrivate *priv; }; struct _CcColorPanelClass { CcPanelClass parent_class; }; GType cc_color_panel_get_type (void) G_GNUC_CONST; void cc_color_panel_register (GIOModule *module); G_END_DECLS #endif /* _CC_COLOR_PANEL_H */ cinnamon-control-center-6.4.1/panels/display/0000775000175000017500000000000014724311620020133 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/display/meson.build0000664000175000017500000000204714724311620022300 0ustar fabiofabiosources = files( 'cc-display-panel.c', 'cc-display-arrangement.c', 'cc-display-config.c', 'cc-display-config-dbus.c', 'cc-display-config-manager-dbus.c', 'cc-display-config-manager.c', 'cc-display-settings.c', 'cc-display-labeler.c', 'display-module.c' ) resource_data = files( 'cc-display-panel.ui', 'cc-display-settings.ui' ) sources += gnome.compile_resources( 'cc-display-resources', 'display.gresource.xml', c_name: 'cc_display', dependencies: resource_data, export: true ) deps = [ colord, cinn_desktop, math, upower_glib_dep, cinn_desktop, libx11, glib ] install_data('org.cinnamon.control-center.display.gschema.xml', install_dir: join_paths(get_option('datadir'), 'glib-2.0', 'schemas') ) panel_display = shared_library( 'display', link_with: libcinnamon_control_center, sources: sources, include_directories: [ rootInclude ], dependencies: deps, install: true, install_dir: panels_dir ) install_data( 'cinnamon-display-panel.desktop', install_dir: desktop_dir ) subdir('icons') cinnamon-control-center-6.4.1/panels/display/display-arrangement.css0000664000175000017500000000131714724311620024615 0ustar fabiofabio .display-arrangement { background-color: #8b8b8b; } .display-arrangement.monitor { border: solid 1px @borders; margin: 0px 0px 1px 1px; background: @theme_bg_color; padding: 0.4em; } .display-arrangement.monitor.primary { border-bottom: 0.4em solid black; } .display-arrangement.monitor:selected { border: solid .2em black; } .display-arrangement.monitor.primary:selected { border-top: solid .2em black; border-left: solid .2em black; border-right: solid .2em black; border-bottom: 0.4em solid black; } .display-arrangement.monitor-label { font-size: larger; font-weight: bold; border-radius: 0.3em; padding-right: 0.2em; padding-left: 0.2em; color: #fff; background: #000; } cinnamon-control-center-6.4.1/panels/display/cc-display-panel.h0000664000175000017500000000340214724311620023430 0ustar fabiofabio/* * Copyright (C) 2010 Intel, Inc * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * Author: Thomas Wood * */ #pragma once #include G_BEGIN_DECLS #define CC_TYPE_DISPLAY_PANEL (cc_display_panel_get_type ()) #define CC_DISPLAY_PANEL(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ CC_TYPE_DISPLAY_PANEL, CcDisplayPanel)) #define CC_DISPLAY_PANEL_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), \ CC_TYPE_DISPLAY_PANEL, CcDisplayPanelClass)) #define CC_IS_DISPLAY_PANEL(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ CC_TYPE_DISPLAY_PANEL)) #define CC_IS_DISPLAY_PANEL_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), \ CC_TYPE_DISPLAY_PANEL)) #define CC_DISPLAY_PANEL_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), \ CC_TYPE_DISPLAY_PANEL, CcDisplayPanelClass)) typedef struct _CcDisplayPanel CcDisplayPanel; typedef struct _CcDisplayPanelClass CcDisplayPanelClass; typedef struct _CcDisplayPanelPrivate CcDisplayPanelPrivate; struct _CcDisplayPanelClass { CcPanelClass parent_class; }; GType cc_display_panel_get_type (void) G_GNUC_CONST; void cc_display_panel_register (GIOModule *module); G_END_DECLS cinnamon-control-center-6.4.1/panels/display/cc-display-config-dbus.c0000664000175000017500000014376014724311620024540 0ustar fabiofabio/* * Copyright (C) 2017 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #include "cc-display-config-dbus.h" #define MODE_BASE_FORMAT "siiddad" #define MODE_FORMAT "(" MODE_BASE_FORMAT "a{sv})" #define MODES_FORMAT "a" MODE_FORMAT #define MONITOR_SPEC_FORMAT "(ssss)" #define MONITOR_FORMAT "(" MONITOR_SPEC_FORMAT MODES_FORMAT "a{sv})" #define MONITORS_FORMAT "a" MONITOR_FORMAT #define LOGICAL_MONITOR_MONITORS_FORMAT "a" MONITOR_SPEC_FORMAT #define LOGICAL_MONITOR_FORMAT "(iidub" LOGICAL_MONITOR_MONITORS_FORMAT "a{sv})" #define LOGICAL_MONITORS_FORMAT "a" LOGICAL_MONITOR_FORMAT #define CURRENT_STATE_FORMAT "(u" MONITORS_FORMAT LOGICAL_MONITORS_FORMAT "a{sv})" typedef enum _CcDisplayModeFlags { MODE_PREFERRED = 1 << 0, MODE_CURRENT = 1 << 1, MODE_INTERLACED = 1 << 2, } CcDisplayModeFlags; struct _CcDisplayModeDBus { CcDisplayMode parent_instance; char *id; int width; int height; double refresh_rate; double preferred_scale; GArray *supported_scales; guint32 flags; }; G_DEFINE_TYPE (CcDisplayModeDBus, cc_display_mode_dbus, CC_TYPE_DISPLAY_MODE) static gboolean cc_display_mode_dbus_equal (const CcDisplayModeDBus *m1, const CcDisplayModeDBus *m2) { if (!m1 && !m2) return TRUE; else if (!m1 || !m2) return FALSE; return m1->width == m2->width && m1->height == m2->height && m1->refresh_rate == m2->refresh_rate && (m1->flags & MODE_INTERLACED) == (m2->flags & MODE_INTERLACED); } static void cc_display_mode_dbus_get_resolution (CcDisplayMode *pself, int *w, int *h) { CcDisplayModeDBus *self = CC_DISPLAY_MODE_DBUS (pself); if (w) *w = self->width; if (h) *h = self->height; } static const double * cc_display_mode_dbus_get_supported_scales (CcDisplayMode *pself) { CcDisplayModeDBus *self = CC_DISPLAY_MODE_DBUS (pself); return (const double *) self->supported_scales->data; } static double cc_display_mode_dbus_get_preferred_scale (CcDisplayMode *pself) { CcDisplayModeDBus *self = CC_DISPLAY_MODE_DBUS (pself); return self->preferred_scale; } static gboolean cc_display_mode_dbus_is_supported_scale (CcDisplayMode *pself, double scale) { CcDisplayModeDBus *self = CC_DISPLAY_MODE_DBUS (pself); guint i; for (i = 0; i < self->supported_scales->len; i++) if (g_array_index (self->supported_scales, double, i) == scale) return TRUE; return FALSE; } static gboolean cc_display_mode_dbus_is_interlaced (CcDisplayMode *pself) { CcDisplayModeDBus *self = CC_DISPLAY_MODE_DBUS (pself); return !!(self->flags & MODE_INTERLACED); } static int cc_display_mode_dbus_get_freq (CcDisplayMode *pself) { CcDisplayModeDBus *self = CC_DISPLAY_MODE_DBUS (pself); return self->refresh_rate; } static double cc_display_mode_dbus_get_freq_f (CcDisplayMode *pself) { CcDisplayModeDBus *self = CC_DISPLAY_MODE_DBUS (pself); return self->refresh_rate; } static void cc_display_mode_dbus_init (CcDisplayModeDBus *self) { self->supported_scales = g_array_new (TRUE, TRUE, sizeof (double)); } static void cc_display_mode_dbus_finalize (GObject *object) { CcDisplayModeDBus *self = CC_DISPLAY_MODE_DBUS (object); g_free (self->id); g_array_free (self->supported_scales, TRUE); G_OBJECT_CLASS (cc_display_mode_dbus_parent_class)->finalize (object); } static void cc_display_mode_dbus_class_init (CcDisplayModeDBusClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); CcDisplayModeClass *parent_class = CC_DISPLAY_MODE_CLASS (klass); gobject_class->finalize = cc_display_mode_dbus_finalize; parent_class->get_resolution = cc_display_mode_dbus_get_resolution; parent_class->get_supported_scales = cc_display_mode_dbus_get_supported_scales; parent_class->get_preferred_scale = cc_display_mode_dbus_get_preferred_scale; parent_class->is_interlaced = cc_display_mode_dbus_is_interlaced; parent_class->get_freq = cc_display_mode_dbus_get_freq; parent_class->get_freq_f = cc_display_mode_dbus_get_freq_f; } static CcDisplayModeDBus * cc_display_mode_dbus_new (GVariant *variant) { double d; g_autoptr(GVariantIter) scales_iter = NULL; g_autoptr(GVariant) properties_variant = NULL; gboolean is_current; gboolean is_preferred; gboolean is_interlaced; CcDisplayModeDBus *self = g_object_new (CC_TYPE_DISPLAY_MODE_DBUS, NULL); g_variant_get (variant, "(" MODE_BASE_FORMAT "@a{sv})", &self->id, &self->width, &self->height, &self->refresh_rate, &self->preferred_scale, &scales_iter, &properties_variant); while (g_variant_iter_next (scales_iter, "d", &d)) g_array_append_val (self->supported_scales, d); if (!g_variant_lookup (properties_variant, "is-current", "b", &is_current)) is_current = FALSE; if (!g_variant_lookup (properties_variant, "is-preferred", "b", &is_preferred)) is_preferred = FALSE; if (!g_variant_lookup (properties_variant, "is-interlaced", "b", &is_interlaced)) is_interlaced = FALSE; if (is_current) self->flags |= MODE_CURRENT; if (is_preferred) self->flags |= MODE_PREFERRED; if (is_interlaced) self->flags |= MODE_INTERLACED; return self; } #define CC_TYPE_DISPLAY_LOGICAL_MONITOR (cc_display_logical_monitor_get_type ()) G_DECLARE_FINAL_TYPE (CcDisplayLogicalMonitor, cc_display_logical_monitor, CC, DISPLAY_LOGICAL_MONITOR, GObject) struct _CcDisplayLogicalMonitor { GObject parent_instance; int x; int y; double scale; CcDisplayRotation rotation; gboolean primary; GHashTable *monitors; }; G_DEFINE_TYPE (CcDisplayLogicalMonitor, cc_display_logical_monitor, G_TYPE_OBJECT) static gboolean cc_display_logical_monitor_equal (const CcDisplayLogicalMonitor *m1, const CcDisplayLogicalMonitor *m2) { if (!m1 && !m2) return TRUE; else if (!m1 || !m2) return FALSE; return m1->x == m2->x && m1->y == m2->y && m1->scale == m2->scale && m1->rotation == m2->rotation && m1->primary == m2->primary; } static void cc_display_logical_monitor_init (CcDisplayLogicalMonitor *self) { self->scale = 1.0; self->monitors = g_hash_table_new (NULL, NULL); } static void cc_display_logical_monitor_finalize (GObject *object) { CcDisplayLogicalMonitor *self = CC_DISPLAY_LOGICAL_MONITOR (object); g_warn_if_fail (g_hash_table_size (self->monitors) == 0); g_clear_pointer (&self->monitors, g_hash_table_destroy); G_OBJECT_CLASS (cc_display_logical_monitor_parent_class)->finalize (object); } static void cc_display_logical_monitor_class_init (CcDisplayLogicalMonitorClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); gobject_class->finalize = cc_display_logical_monitor_finalize; } typedef enum _CcDisplayMonitorUnderscanning { UNDERSCANNING_UNSUPPORTED = 0, UNDERSCANNING_DISABLED, UNDERSCANNING_ENABLED } CcDisplayMonitorUnderscanning; struct _CcDisplayMonitorDBus { CcDisplayMonitor parent_instance; CcDisplayConfigDBus *config; gchar *connector_name; gchar *vendor_name; gchar *product_name; gchar *product_serial; gchar *display_name; int width_mm; int height_mm; gboolean builtin; CcDisplayMonitorUnderscanning underscanning; int max_width; int max_height; GList *modes; CcDisplayMode *current_mode; CcDisplayMode *preferred_mode; CcDisplayLogicalMonitor *logical_monitor; }; G_DEFINE_TYPE (CcDisplayMonitorDBus, cc_display_monitor_dbus, CC_TYPE_DISPLAY_MONITOR) static void register_logical_monitor (CcDisplayConfigDBus *self, CcDisplayLogicalMonitor *logical_monitor); static void cc_display_config_dbus_set_primary (CcDisplayConfigDBus *self, CcDisplayMonitorDBus *new_primary); static void cc_display_config_dbus_unset_primary (CcDisplayConfigDBus *self, CcDisplayMonitorDBus *old_primary); static void cc_display_config_dbus_ensure_non_offset_coords (CcDisplayConfigDBus *self); static void cc_display_config_dbus_append_right (CcDisplayConfigDBus *self, CcDisplayLogicalMonitor *monitor); static void cc_display_config_dbus_make_linear (CcDisplayConfigDBus *self); static const char * cc_display_monitor_dbus_get_display_name (CcDisplayMonitor *pself) { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself); if (self->display_name) return self->display_name; return self->connector_name; } static const char * cc_display_monitor_dbus_get_connector_name (CcDisplayMonitor *pself) { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself); return self->connector_name; } static gboolean cc_display_monitor_dbus_is_builtin (CcDisplayMonitor *pself) { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself); return self->builtin; } static gboolean cc_display_monitor_dbus_is_primary (CcDisplayMonitor *pself) { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself); if (self->logical_monitor) return self->logical_monitor->primary; return FALSE; } static void cc_display_monitor_dbus_set_primary (CcDisplayMonitor *pself, gboolean primary) { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself); if (primary) cc_display_config_dbus_set_primary (self->config, self); else cc_display_config_dbus_unset_primary (self->config, self); } static gboolean cc_display_monitor_dbus_is_active (CcDisplayMonitor *pself) { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself); return self->logical_monitor != NULL; } static void cc_display_monitor_dbus_set_logical_monitor (CcDisplayMonitorDBus *self, CcDisplayLogicalMonitor *logical_monitor) { gboolean was_primary = FALSE; if (self->logical_monitor) { was_primary = self->logical_monitor->primary; if (was_primary) cc_display_config_dbus_unset_primary (self->config, self); g_hash_table_remove (self->logical_monitor->monitors, self); g_object_unref (self->logical_monitor); } self->logical_monitor = logical_monitor; if (self->logical_monitor) { g_hash_table_add (self->logical_monitor->monitors, self); g_object_ref (self->logical_monitor); /* unset primary with NULL will select this monitor if it is the only one.*/ if (was_primary) cc_display_config_dbus_set_primary (self->config, self); else cc_display_config_dbus_unset_primary (self->config, NULL); } } static void cc_display_monitor_dbus_set_active (CcDisplayMonitor *pself, gboolean active) { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself); if (!self->current_mode && active) { if (self->preferred_mode) self->current_mode = self->preferred_mode; else if (self->modes) self->current_mode = (CcDisplayMode *) self->modes->data; else g_warning ("Couldn't find a mode to activate monitor at %s", self->connector_name); } if (!self->logical_monitor && active) { CcDisplayLogicalMonitor *logical_monitor; logical_monitor = g_object_new (CC_TYPE_DISPLAY_LOGICAL_MONITOR, NULL); cc_display_monitor_dbus_set_logical_monitor (self, logical_monitor); cc_display_config_dbus_append_right (self->config, logical_monitor); register_logical_monitor (self->config, logical_monitor); } else if (self->logical_monitor && !active) { cc_display_monitor_dbus_set_logical_monitor (self, NULL); } g_signal_emit_by_name (self, "active"); } static CcDisplayRotation cc_display_monitor_dbus_get_rotation (CcDisplayMonitor *pself) { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself); if (self->logical_monitor) return self->logical_monitor->rotation; return CC_DISPLAY_ROTATION_NONE; } static void cc_display_monitor_dbus_set_rotation (CcDisplayMonitor *pself, CcDisplayRotation rotation) { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself); if (!self->logical_monitor) return; if (self->logical_monitor->rotation != rotation) { self->logical_monitor->rotation = rotation; g_signal_emit_by_name (self, "rotation"); } } static gboolean cc_display_monitor_dbus_supports_rotation (CcDisplayMonitor *pself, CcDisplayRotation rotation) { return TRUE; } static void cc_display_monitor_dbus_get_physical_size (CcDisplayMonitor *pself, int *w, int *h) { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself); if (w) *w = self->width_mm; if (h) *h = self->height_mm; } static void cc_display_monitor_dbus_get_geometry (CcDisplayMonitor *pself, int *x, int *y, int *w, int *h) { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself); CcDisplayMode *mode = NULL; if (self->logical_monitor) { if (x) *x = self->logical_monitor->x; if (y) *y = self->logical_monitor->y; } else { if (x) *x = -1; if (y) *y = -1; } if (self->current_mode) mode = self->current_mode; else if (self->preferred_mode) mode = self->preferred_mode; else if (self->modes) mode = CC_DISPLAY_MODE (self->modes->data); if (mode) cc_display_mode_get_resolution (mode, w, h); else { g_warning ("Monitor at %s has no modes?", self->connector_name); if (w) *w = -1; if (h) *h = -1; } } static CcDisplayMode * cc_display_monitor_dbus_get_mode (CcDisplayMonitor *pself) { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself); return self->current_mode; } static CcDisplayMode * cc_display_monitor_dbus_get_preferred_mode (CcDisplayMonitor *pself) { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself); return self->preferred_mode; } static guint32 cc_display_monitor_dbus_get_id (CcDisplayMonitor *pself) { return 0; } static GList * cc_display_monitor_dbus_get_modes (CcDisplayMonitor *pself) { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself); return self->modes; } static gboolean cc_display_monitor_dbus_supports_underscanning (CcDisplayMonitor *pself) { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself); return self->underscanning != UNDERSCANNING_UNSUPPORTED; } static gboolean cc_display_monitor_dbus_get_underscanning (CcDisplayMonitor *pself) { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself); return self->underscanning == UNDERSCANNING_ENABLED; } static void cc_display_monitor_dbus_set_underscanning (CcDisplayMonitor *pself, gboolean underscanning) { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself); if (self->underscanning == UNDERSCANNING_UNSUPPORTED) return; if (underscanning) self->underscanning = UNDERSCANNING_ENABLED; else self->underscanning = UNDERSCANNING_DISABLED; } static CcDisplayMode * cc_display_monitor_dbus_get_closest_mode (CcDisplayMonitorDBus *self, CcDisplayModeDBus *mode) { CcDisplayModeDBus *best = NULL; GList *l; for (l = self->modes; l != NULL; l = l->next) { CcDisplayModeDBus *similar = l->data; if (similar->width != mode->width || similar->height != mode->height) continue; if (similar->refresh_rate == mode->refresh_rate && (similar->flags & MODE_INTERLACED) == (mode->flags & MODE_INTERLACED)) { best = similar; break; } /* There might be a better heuristic. */ if (!best || best->refresh_rate < similar->refresh_rate) { best = similar; continue; } } return CC_DISPLAY_MODE (best); } static void cc_display_monitor_dbus_set_mode (CcDisplayMonitor *pself, CcDisplayMode *new_mode) { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself); CcDisplayMode *mode; g_return_if_fail (new_mode != NULL); mode = cc_display_monitor_dbus_get_closest_mode (self, CC_DISPLAY_MODE_DBUS (new_mode)); self->current_mode = mode; if (!cc_display_mode_dbus_is_supported_scale (mode, cc_display_monitor_get_scale (pself))) cc_display_monitor_set_scale (pself, cc_display_mode_get_preferred_scale (mode)); g_signal_emit_by_name (self, "mode"); } static void cc_display_monitor_dbus_set_position (CcDisplayMonitor *pself, int x, int y) { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself); if (self->logical_monitor) { gboolean notify = FALSE; if (self->logical_monitor->x != x || self->logical_monitor->y != y) notify = TRUE; self->logical_monitor->x = x; self->logical_monitor->y = y; if (notify) g_signal_emit_by_name (self, "position-changed"); } } static double cc_display_monitor_dbus_get_scale (CcDisplayMonitor *pself) { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself); if (self->logical_monitor) return self->logical_monitor->scale; return 1.0; } static void cc_display_monitor_dbus_set_scale (CcDisplayMonitor *pself, double scale) { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (pself); if (!self->current_mode) return; if (!cc_display_mode_dbus_is_supported_scale (self->current_mode, scale)) return; if (!self->logical_monitor) return; if (self->logical_monitor->scale != scale) { self->logical_monitor->scale = scale; g_signal_emit_by_name (self, "scale"); } } static void cc_display_monitor_dbus_init (CcDisplayMonitorDBus *self) { self->underscanning = UNDERSCANNING_UNSUPPORTED; self->max_width = G_MAXINT; self->max_height = G_MAXINT; } static void cc_display_monitor_dbus_finalize (GObject *object) { CcDisplayMonitorDBus *self = CC_DISPLAY_MONITOR_DBUS (object); g_free (self->connector_name); g_free (self->vendor_name); g_free (self->product_name); g_free (self->product_serial); g_free (self->display_name); g_list_foreach (self->modes, (GFunc) g_object_unref, NULL); g_clear_pointer (&self->modes, g_list_free); if (self->logical_monitor) { g_hash_table_remove (self->logical_monitor->monitors, self); g_object_unref (self->logical_monitor); } G_OBJECT_CLASS (cc_display_monitor_dbus_parent_class)->finalize (object); } static void cc_display_monitor_dbus_class_init (CcDisplayMonitorDBusClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); CcDisplayMonitorClass *parent_class = CC_DISPLAY_MONITOR_CLASS (klass); gobject_class->finalize = cc_display_monitor_dbus_finalize; parent_class->get_display_name = cc_display_monitor_dbus_get_display_name; parent_class->get_connector_name = cc_display_monitor_dbus_get_connector_name; parent_class->is_builtin = cc_display_monitor_dbus_is_builtin; parent_class->is_primary = cc_display_monitor_dbus_is_primary; parent_class->set_primary = cc_display_monitor_dbus_set_primary; parent_class->is_active = cc_display_monitor_dbus_is_active; parent_class->set_active = cc_display_monitor_dbus_set_active; parent_class->get_rotation = cc_display_monitor_dbus_get_rotation; parent_class->set_rotation = cc_display_monitor_dbus_set_rotation; parent_class->supports_rotation = cc_display_monitor_dbus_supports_rotation; parent_class->get_physical_size = cc_display_monitor_dbus_get_physical_size; parent_class->get_geometry = cc_display_monitor_dbus_get_geometry; parent_class->get_mode = cc_display_monitor_dbus_get_mode; parent_class->get_preferred_mode = cc_display_monitor_dbus_get_preferred_mode; parent_class->get_id = cc_display_monitor_dbus_get_id; parent_class->get_modes = cc_display_monitor_dbus_get_modes; parent_class->supports_underscanning = cc_display_monitor_dbus_supports_underscanning; parent_class->get_underscanning = cc_display_monitor_dbus_get_underscanning; parent_class->set_underscanning = cc_display_monitor_dbus_set_underscanning; parent_class->set_mode = cc_display_monitor_dbus_set_mode; parent_class->set_position = cc_display_monitor_dbus_set_position; parent_class->get_scale = cc_display_monitor_dbus_get_scale; parent_class->set_scale = cc_display_monitor_dbus_set_scale; } static void construct_modes (CcDisplayMonitorDBus *self, GVariantIter *modes) { CcDisplayModeDBus *mode; while (TRUE) { g_autoptr(GVariant) variant = NULL; if (!g_variant_iter_next (modes, "@"MODE_FORMAT, &variant)) break; mode = cc_display_mode_dbus_new (variant); self->modes = g_list_prepend (self->modes, mode); if (mode->flags & MODE_PREFERRED) self->preferred_mode = CC_DISPLAY_MODE (mode); if (mode->flags & MODE_CURRENT) self->current_mode = CC_DISPLAY_MODE (mode); } } static CcDisplayMonitorDBus * cc_display_monitor_dbus_new (GVariant *variant, CcDisplayConfigDBus *config) { CcDisplayMonitorDBus *self = g_object_new (CC_TYPE_DISPLAY_MONITOR_DBUS, NULL); gchar *s1, *s2, *s3, *s4; g_autoptr(GVariantIter) modes = NULL; g_autoptr(GVariantIter) props = NULL; self->config = config; g_variant_get (variant, MONITOR_FORMAT, &s1, &s2, &s3, &s4, &modes, &props); self->connector_name = s1; self->vendor_name = s2; self->product_name = s3; self->product_serial = s4; construct_modes (self, modes); while (TRUE) { const char *s; g_autoptr(GVariant) v = NULL; if (!g_variant_iter_next (props, "{&sv}", &s, &v)) break; if (g_str_equal (s, "width-mm")) { g_variant_get (v, "i", &self->width_mm); } else if (g_str_equal (s, "height-mm")) { g_variant_get (v, "i", &self->height_mm); } else if (g_str_equal (s, "is-underscanning")) { gboolean underscanning = FALSE; g_variant_get (v, "b", &underscanning); if (underscanning) self->underscanning = UNDERSCANNING_ENABLED; else self->underscanning = UNDERSCANNING_DISABLED; } else if (g_str_equal (s, "max-screen-size")) { g_variant_get (v, "ii", &self->max_width, &self->max_height); } else if (g_str_equal (s, "is-builtin")) { g_variant_get (v, "b", &self->builtin); } else if (g_str_equal (s, "display-name")) { g_variant_get (v, "s", &self->display_name); } } return self; } typedef enum _CcDisplayLayoutMode { CC_DISPLAY_LAYOUT_MODE_LOGICAL = 1, CC_DISPLAY_LAYOUT_MODE_PHYSICAL = 2, CC_DISPLAY_LAYOUT_MODE_GLOBAL_UI_LOGICAL = 3 } CcDisplayLayoutMode; typedef enum _CcDisplayConfigMethod { CC_DISPLAY_CONFIG_METHOD_VERIFY = 0, CC_DISPLAY_CONFIG_METHOD_TEMPORARY = 1, CC_DISPLAY_CONFIG_METHOD_PERSISTENT = 2 } CcDisplayConfigMethod; struct _CcDisplayConfigDBus { CcDisplayConfig parent_instance; GVariant *state; GDBusConnection *connection; int min_width; int min_height; guint32 serial; gboolean supports_mirroring; gboolean supports_changing_layout_mode; gboolean global_scale_required; CcDisplayLayoutMode layout_mode; gint legacy_ui_scale; GList *monitors; CcDisplayMonitorDBus *primary; GHashTable *logical_monitors; GList *clone_modes; }; G_DEFINE_TYPE (CcDisplayConfigDBus, cc_display_config_dbus, CC_TYPE_DISPLAY_CONFIG) enum { PROP_0, PROP_STATE, PROP_CONNECTION, }; static GList * cc_display_config_dbus_get_monitors (CcDisplayConfig *pself) { CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (pself); return self->monitors; } static GVariant * build_monitors_variant (GHashTable *monitors) { GVariantBuilder builder; GHashTableIter iter; CcDisplayMonitorDBus *monitor; g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); g_hash_table_iter_init (&iter, monitors); while (g_hash_table_iter_next (&iter, (void **) &monitor, NULL)) { GVariantBuilder props_builder; CcDisplayModeDBus *mode_dbus; if (!monitor->current_mode) continue; g_variant_builder_init (&props_builder, G_VARIANT_TYPE ("a{sv}")); g_variant_builder_add (&props_builder, "{sv}", "underscanning", g_variant_new_boolean (monitor->underscanning == UNDERSCANNING_ENABLED)); mode_dbus = CC_DISPLAY_MODE_DBUS (monitor->current_mode); g_variant_builder_add (&builder, "(ss@*)", monitor->connector_name, mode_dbus->id, g_variant_builder_end (&props_builder)); } return g_variant_builder_end (&builder); } static GVariant * build_logical_monitors_parameter (CcDisplayConfigDBus *self) { GVariantBuilder builder; GHashTableIter iter; CcDisplayLogicalMonitor *logical_monitor; g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(iiduba(ssa{sv}))")); g_hash_table_iter_init (&iter, self->logical_monitors); while (g_hash_table_iter_next (&iter, (void **) &logical_monitor, NULL)) g_variant_builder_add (&builder, "(iidub@*)", logical_monitor->x, logical_monitor->y, logical_monitor->scale, logical_monitor->rotation, logical_monitor->primary, build_monitors_variant (logical_monitor->monitors)); return g_variant_builder_end (&builder); } static GVariant * build_apply_parameters (CcDisplayConfigDBus *self, CcDisplayConfigMethod method) { GVariantBuilder props_builder; g_variant_builder_init (&props_builder, G_VARIANT_TYPE ("a{sv}")); if (self->supports_changing_layout_mode) g_variant_builder_add (&props_builder, "{sv}", "layout-mode", g_variant_new_uint32 (self->layout_mode)); return g_variant_new ("(uu@*@*)", self->serial, method, build_logical_monitors_parameter (self), g_variant_builder_end (&props_builder)); } static gboolean config_apply (CcDisplayConfigDBus *self, CcDisplayConfigMethod method, GError **error) { g_autoptr(GVariant) retval = NULL; cc_display_config_dbus_ensure_non_offset_coords (self); retval = g_dbus_connection_call_sync (self->connection, "org.cinnamon.Muffin.DisplayConfig", "/org/cinnamon/Muffin/DisplayConfig", "org.cinnamon.Muffin.DisplayConfig", "ApplyMonitorsConfig", build_apply_parameters (self, method), NULL, G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, NULL, error); return retval != NULL; } static gboolean cc_display_config_dbus_is_applicable (CcDisplayConfig *pself) { CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (pself); g_autoptr(GError) error = NULL; if (!config_apply (self, CC_DISPLAY_CONFIG_METHOD_VERIFY, &error)) { g_warning ("Config not applicable: %s", error->message); return FALSE; } else { return TRUE; } } static CcDisplayMonitorDBus * monitor_from_spec (CcDisplayConfigDBus *self, const gchar *connector, const gchar *vendor, const gchar *product, const gchar *serial) { GList *l; for (l = self->monitors; l != NULL; l = l->next) { CcDisplayMonitorDBus *m = l->data; if (g_str_equal (m->connector_name, connector) && g_str_equal (m->vendor_name, vendor) && g_str_equal (m->product_name, product) && g_str_equal (m->product_serial, serial)) return m; } return NULL; } static gboolean cc_display_config_dbus_equal (CcDisplayConfig *pself, CcDisplayConfig *pother) { CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (pself); CcDisplayConfigDBus *other = CC_DISPLAY_CONFIG_DBUS (pother); GList *l; g_return_val_if_fail (pself, FALSE); g_return_val_if_fail (pother, FALSE); if (self->layout_mode != other->layout_mode) return FALSE; cc_display_config_dbus_ensure_non_offset_coords (self); cc_display_config_dbus_ensure_non_offset_coords (other); for (l = self->monitors; l != NULL; l = l->next) { CcDisplayMonitorDBus *m1 = l->data; CcDisplayMonitorDBus *m2 = monitor_from_spec (other, m1->connector_name, m1->vendor_name, m1->product_name, m1->product_serial); if (!m2) return FALSE; if (m1->underscanning != m2->underscanning) return FALSE; if (!cc_display_logical_monitor_equal (m1->logical_monitor, m2->logical_monitor)) return FALSE; /* Modes should not be compared if both monitors have no logical monitor. */ if (m1->logical_monitor == NULL && m2->logical_monitor == NULL) continue; if (!cc_display_mode_dbus_equal (CC_DISPLAY_MODE_DBUS (m1->current_mode), CC_DISPLAY_MODE_DBUS (m2->current_mode))) return FALSE; } return TRUE; } static void cc_display_config_dbus_set_primary (CcDisplayConfigDBus *self, CcDisplayMonitorDBus *new_primary) { if (self->primary == new_primary) return; if (!new_primary->logical_monitor) return; if (self->primary && self->primary->logical_monitor) { self->primary->logical_monitor->primary = FALSE; g_signal_emit_by_name (self->primary, "primary"); } self->primary = new_primary; self->primary->logical_monitor->primary = TRUE; g_signal_emit_by_name (self->primary, "primary"); g_signal_emit_by_name (self, "primary"); } static void cc_display_config_dbus_unset_primary (CcDisplayConfigDBus *self, CcDisplayMonitorDBus *old_primary) { GList *l; if (self->primary != old_primary) return; for (l = self->monitors; l != NULL; l = l->next) { CcDisplayMonitorDBus *monitor = l->data; if (monitor->logical_monitor && monitor != old_primary) { cc_display_config_dbus_set_primary (self, monitor); break; } } if (self->primary == old_primary) self->primary = NULL; } static gboolean cc_display_config_dbus_is_cloning (CcDisplayConfig *pself) { CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (pself); guint n_active_monitors = 0; GList *l; for (l = self->monitors; l != NULL; l = l->next) if (cc_display_monitor_is_active (CC_DISPLAY_MONITOR (l->data))) n_active_monitors += 1; return n_active_monitors > 1 && g_hash_table_size (self->logical_monitors) == 1; } static void cc_display_config_dbus_set_cloning (CcDisplayConfig *pself, gboolean clone) { CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (pself); gboolean is_cloning = cc_display_config_is_cloning (pself); CcDisplayLogicalMonitor *logical_monitor; GList *l; if (clone && !is_cloning) { logical_monitor = g_object_new (CC_TYPE_DISPLAY_LOGICAL_MONITOR, NULL); for (l = self->monitors; l != NULL; l = l->next) cc_display_monitor_dbus_set_logical_monitor (CC_DISPLAY_MONITOR_DBUS (l->data), logical_monitor); register_logical_monitor (self, logical_monitor); } else if (!clone && is_cloning) { for (l = self->monitors; l != NULL; l = l->next) { logical_monitor = g_object_new (CC_TYPE_DISPLAY_LOGICAL_MONITOR, NULL); cc_display_monitor_dbus_set_logical_monitor (CC_DISPLAY_MONITOR_DBUS (l->data), logical_monitor); register_logical_monitor (self, logical_monitor); } cc_display_config_dbus_make_linear (self); } } static GList * cc_display_config_dbus_get_cloning_modes (CcDisplayConfig *pself) { CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (pself); return self->clone_modes; } static gboolean cc_display_config_dbus_apply (CcDisplayConfig *pself, GError **error) { CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (pself); return config_apply (self, CC_DISPLAY_CONFIG_METHOD_PERSISTENT, error); } static gboolean cc_display_config_dbus_is_layout_logical (CcDisplayConfig *pself) { CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (pself); return self->layout_mode == CC_DISPLAY_LAYOUT_MODE_LOGICAL || self->layout_mode == CC_DISPLAY_LAYOUT_MODE_GLOBAL_UI_LOGICAL; } static gboolean cc_display_config_dbus_layout_use_ui_scale (CcDisplayConfig *pself) { CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (pself); return self->layout_mode == CC_DISPLAY_LAYOUT_MODE_GLOBAL_UI_LOGICAL; } static gint cc_display_config_dbus_get_legacy_ui_scale (CcDisplayConfig *pself) { CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (pself); return self->legacy_ui_scale; } static gboolean is_scaled_mode_allowed (CcDisplayConfigDBus *self, CcDisplayMode *pmode, double scale) { gint width, height; CcDisplayModeDBus *mode = CC_DISPLAY_MODE_DBUS (pmode); if (!cc_display_mode_dbus_is_supported_scale (pmode, scale)) return FALSE; /* Do the math as if the monitor is always in landscape mode. */ width = round (mode->width / scale); height = round (mode->height / scale); return (MAX (width, height) >= self->min_width && MIN (width, height) >= self->min_height); } static gboolean is_scale_allowed_by_active_monitors (CcDisplayConfigDBus *self, CcDisplayMode *mode, double scale) { GList *l; for (l = self->monitors; l != NULL; l = l->next) { CcDisplayMonitorDBus *m = CC_DISPLAY_MONITOR_DBUS (l->data); if (!cc_display_monitor_is_active (CC_DISPLAY_MONITOR (m))) continue; if (!is_scaled_mode_allowed (self, m->current_mode, scale)) return FALSE; if (!is_scaled_mode_allowed (self, mode, scale)) return FALSE; } return TRUE; } static void cc_display_config_dbus_set_minimum_size (CcDisplayConfig *pself, int width, int height) { CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (pself); g_assert (width >= 0 && height >= 0); self->min_width = width; self->min_height = height; } static gboolean cc_display_config_dbus_is_scaled_mode_valid (CcDisplayConfig *pself, CcDisplayMode *mode, double scale) { CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (pself); if (self->global_scale_required || cc_display_config_is_cloning (pself)) return is_scale_allowed_by_active_monitors (self, mode, scale); return is_scaled_mode_allowed (self, mode, scale); } static void cc_display_config_dbus_init (CcDisplayConfigDBus *self) { self->serial = 0; self->supports_mirroring = TRUE; self->supports_changing_layout_mode = FALSE; self->global_scale_required = FALSE; self->layout_mode = CC_DISPLAY_LAYOUT_MODE_LOGICAL; self->logical_monitors = g_hash_table_new (NULL, NULL); } static void gather_clone_modes (CcDisplayConfigDBus *self) { guint n_monitors = g_list_length (self->monitors); CcDisplayMonitorDBus *monitor; GList *l; if (n_monitors < 2) return; monitor = self->monitors->data; for (l = monitor->modes; l != NULL; l = l->next) { CcDisplayModeDBus *mode = l->data; gboolean valid = TRUE; GList *ll; for (ll = self->monitors->next; ll != NULL; ll = ll->next) { CcDisplayMonitorDBus *other_monitor = ll->data; if (!cc_display_monitor_dbus_get_closest_mode (other_monitor, mode)) { valid = FALSE; break; } } if (valid) self->clone_modes = g_list_prepend (self->clone_modes, mode); } } static void remove_logical_monitor (gpointer data, GObject *object) { CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (data); g_hash_table_remove (self->logical_monitors, object); } static void register_logical_monitor (CcDisplayConfigDBus *self, CcDisplayLogicalMonitor *logical_monitor) { g_hash_table_add (self->logical_monitors, logical_monitor); g_object_weak_ref (G_OBJECT (logical_monitor), remove_logical_monitor, self); g_object_unref (logical_monitor); } static void apply_global_scale_requirement (CcDisplayConfigDBus *self, CcDisplayMonitor *monitor) { GList *l; double scale = cc_display_monitor_get_scale (monitor); for (l = self->monitors; l != NULL; l = l->next) { CcDisplayMonitor *m = l->data; if (m != monitor) cc_display_monitor_set_scale (m, scale); } } static void construct_monitors (CcDisplayConfigDBus *self, GVariantIter *monitors, GVariantIter *logical_monitors) { while (TRUE) { CcDisplayMonitorDBus *monitor; g_autoptr(GVariant) variant = NULL; if (!g_variant_iter_next (monitors, "@"MONITOR_FORMAT, &variant)) break; monitor = cc_display_monitor_dbus_new (variant, self); self->monitors = g_list_prepend (self->monitors, monitor); if (self->global_scale_required) g_signal_connect_object (monitor, "scale", G_CALLBACK (apply_global_scale_requirement), self, G_CONNECT_SWAPPED); } while (TRUE) { g_autoptr(GVariant) variant = NULL; CcDisplayLogicalMonitor *logical_monitor; g_autoptr(GVariantIter) monitor_specs = NULL; const gchar *s1, *s2, *s3, *s4; gboolean primary; if (!g_variant_iter_next (logical_monitors, "@"LOGICAL_MONITOR_FORMAT, &variant)) break; logical_monitor = g_object_new (CC_TYPE_DISPLAY_LOGICAL_MONITOR, NULL); g_variant_get (variant, LOGICAL_MONITOR_FORMAT, &logical_monitor->x, &logical_monitor->y, &logical_monitor->scale, &logical_monitor->rotation, &primary, &monitor_specs, NULL); while (g_variant_iter_next (monitor_specs, "(&s&s&s&s)", &s1, &s2, &s3, &s4)) { CcDisplayMonitorDBus *m = monitor_from_spec (self, s1, s2, s3, s4); if (!m) { g_warning ("Couldn't find monitor given spec: %s, %s, %s, %s", s1, s2, s3, s4); continue; } cc_display_monitor_dbus_set_logical_monitor (m, logical_monitor); } if (g_hash_table_size (logical_monitor->monitors) > 0) { if (primary) { CcDisplayMonitorDBus *m = NULL; GHashTableIter iter; g_hash_table_iter_init (&iter, logical_monitor->monitors); g_hash_table_iter_next (&iter, (void **) &m, NULL); cc_display_config_dbus_set_primary (self, m); } } else { g_warning ("Got an empty logical monitor, ignoring"); } register_logical_monitor (self, logical_monitor); } gather_clone_modes (self); } static void cc_display_config_dbus_constructed (GObject *object) { CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (object); g_autoptr(GVariantIter) monitors = NULL; g_autoptr(GVariantIter) logical_monitors = NULL; g_autoptr(GVariantIter) props = NULL; g_variant_get (self->state, CURRENT_STATE_FORMAT, &self->serial, &monitors, &logical_monitors, &props); while (TRUE) { const char *s; g_autoptr(GVariant) v = NULL; if (!g_variant_iter_next (props, "{&sv}", &s, &v)) break; if (g_str_equal (s, "supports-mirroring")) { g_variant_get (v, "b", &self->supports_mirroring); } else if (g_str_equal (s, "supports-changing-layout-mode")) { g_variant_get (v, "b", &self->supports_changing_layout_mode); } else if (g_str_equal (s, "global-scale-required")) { g_variant_get (v, "b", &self->global_scale_required); } else if (g_str_equal (s, "legacy-ui-scaling-factor")) { g_variant_get (v, "i", &self->legacy_ui_scale); } else if (g_str_equal (s, "layout-mode")) { guint32 u = 0; g_variant_get (v, "u", &u); if (u >= CC_DISPLAY_LAYOUT_MODE_LOGICAL && u <= CC_DISPLAY_LAYOUT_MODE_GLOBAL_UI_LOGICAL) self->layout_mode = u; } } construct_monitors (self, monitors, logical_monitors); G_OBJECT_CLASS (cc_display_config_dbus_parent_class)->constructed (object); } static void cc_display_config_dbus_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (object); switch (prop_id) { case PROP_STATE: self->state = g_value_dup_variant (value); break; case PROP_CONNECTION: self->connection = g_value_dup_object (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void cc_display_config_dbus_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (object); switch (prop_id) { case PROP_STATE: g_value_set_variant (value, self->state); break; case PROP_CONNECTION: g_value_set_object (value, self->connection); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void cc_display_config_dbus_finalize (GObject *object) { CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (object); g_clear_pointer (&self->state, g_variant_unref); g_clear_object (&self->connection); g_list_foreach (self->monitors, (GFunc) g_object_unref, NULL); g_clear_pointer (&self->monitors, g_list_free); g_clear_pointer (&self->logical_monitors, g_hash_table_destroy); g_clear_pointer (&self->clone_modes, g_list_free); G_OBJECT_CLASS (cc_display_config_dbus_parent_class)->finalize (object); } static void cc_display_config_dbus_class_init (CcDisplayConfigDBusClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); CcDisplayConfigClass *parent_class = CC_DISPLAY_CONFIG_CLASS (klass); GParamSpec *pspec; gobject_class->constructed = cc_display_config_dbus_constructed; gobject_class->set_property = cc_display_config_dbus_set_property; gobject_class->get_property = cc_display_config_dbus_get_property; gobject_class->finalize = cc_display_config_dbus_finalize; parent_class->get_monitors = cc_display_config_dbus_get_monitors; parent_class->is_applicable = cc_display_config_dbus_is_applicable; parent_class->equal = cc_display_config_dbus_equal; parent_class->apply = cc_display_config_dbus_apply; parent_class->is_cloning = cc_display_config_dbus_is_cloning; parent_class->set_cloning = cc_display_config_dbus_set_cloning; parent_class->get_cloning_modes = cc_display_config_dbus_get_cloning_modes; parent_class->is_layout_logical = cc_display_config_dbus_is_layout_logical; parent_class->is_scaled_mode_valid = cc_display_config_dbus_is_scaled_mode_valid; parent_class->set_minimum_size = cc_display_config_dbus_set_minimum_size; parent_class->layout_use_ui_scale = cc_display_config_dbus_layout_use_ui_scale; parent_class->get_legacy_ui_scale = cc_display_config_dbus_get_legacy_ui_scale; pspec = g_param_spec_variant ("state", "GVariant", "GVariant", G_VARIANT_TYPE (CURRENT_STATE_FORMAT), NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_STATE, pspec); pspec = g_param_spec_object ("connection", "GDBusConnection", "GDBusConnection", G_TYPE_DBUS_CONNECTION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROP_CONNECTION, pspec); } static gint sort_x_axis (gconstpointer a, gconstpointer b) { const CcDisplayLogicalMonitor *ma = a; const CcDisplayLogicalMonitor *mb = b; return ma->x - mb->x; } static gint sort_y_axis (gconstpointer a, gconstpointer b) { const CcDisplayLogicalMonitor *ma = a; const CcDisplayLogicalMonitor *mb = b; return ma->y - mb->y; } static void add_x_delta (gpointer d1, gpointer d2) { CcDisplayLogicalMonitor *m = d1; int delta = GPOINTER_TO_INT (d2); m->x += delta; } static gboolean logical_monitor_is_rotated (CcDisplayLogicalMonitor *lm) { switch (lm->rotation) { case CC_DISPLAY_ROTATION_90: case CC_DISPLAY_ROTATION_270: case CC_DISPLAY_ROTATION_90_FLIPPED: case CC_DISPLAY_ROTATION_270_FLIPPED: return TRUE; default: return FALSE; } } static double get_maximum_scale (CcDisplayConfig *config) { GList *outputs, *l; double max_scale = 1.0; outputs = cc_display_config_get_monitors (config); for (l = outputs; l; l = l->next) { CcDisplayMonitor *output = l->data; if (!cc_display_monitor_is_useful (output)) continue; max_scale = MAX (max_scale, cc_display_monitor_get_scale (output)); } return max_scale; } static int logical_monitor_width (CcDisplayLogicalMonitor *lm) { CcDisplayMonitorDBus *monitor; CcDisplayModeDBus *mode; GHashTableIter iter; int width; g_hash_table_iter_init (&iter, lm->monitors); g_hash_table_iter_next (&iter, (void **) &monitor, NULL); mode = CC_DISPLAY_MODE_DBUS (monitor->current_mode); if (logical_monitor_is_rotated (lm)) width = mode ? mode->height : 0; else width = mode ? mode->width : 0; if (monitor->config->layout_mode == CC_DISPLAY_LAYOUT_MODE_LOGICAL) return round (width / lm->scale); if (monitor->config->layout_mode == CC_DISPLAY_LAYOUT_MODE_GLOBAL_UI_LOGICAL) { double max_scale = get_maximum_scale(CC_DISPLAY_CONFIG (monitor->config)); return round ((width * ceil (max_scale)) / lm->scale); } else return width; } static void add_y_delta (gpointer d1, gpointer d2) { CcDisplayLogicalMonitor *m = d1; int delta = GPOINTER_TO_INT (d2); m->y += delta; } static void cc_display_config_dbus_ensure_non_offset_coords (CcDisplayConfigDBus *self) { GList *x_axis, *y_axis; CcDisplayLogicalMonitor *m; if (g_hash_table_size (self->logical_monitors) == 0) return; x_axis = g_hash_table_get_keys (self->logical_monitors); x_axis = g_list_sort (x_axis, sort_x_axis); y_axis = g_hash_table_get_keys (self->logical_monitors); y_axis = g_list_sort (y_axis, sort_y_axis); m = x_axis->data; if (m->x != 0) g_list_foreach (x_axis, add_x_delta, GINT_TO_POINTER (- m->x)); m = y_axis->data; if (m->y != 0) g_list_foreach (y_axis, add_y_delta, GINT_TO_POINTER (- m->y)); g_list_free (x_axis); g_list_free (y_axis); } static void cc_display_config_dbus_append_right (CcDisplayConfigDBus *self, CcDisplayLogicalMonitor *monitor) { GList *x_axis; CcDisplayLogicalMonitor *last; if (g_hash_table_size (self->logical_monitors) == 0) { monitor->x = 0; monitor->y = 0; return; } x_axis = g_hash_table_get_keys (self->logical_monitors); x_axis = g_list_sort (x_axis, sort_x_axis); last = g_list_last (x_axis)->data; monitor->x = last->x + logical_monitor_width (last); monitor->y = last->y; g_list_free (x_axis); } static void cc_display_config_dbus_make_linear (CcDisplayConfigDBus *self) { CcDisplayLogicalMonitor *primary; GList *logical_monitors, *l; int x; if (self->primary && self->primary->logical_monitor) { primary = self->primary->logical_monitor; primary->x = primary->y = 0; x = logical_monitor_width (primary); } else { primary = NULL; x = 0; } logical_monitors = g_hash_table_get_keys (self->logical_monitors); for (l = logical_monitors; l != NULL; l = l->next) { CcDisplayLogicalMonitor *m = l->data; if (m == primary) continue; m->x = x; m->y = 0; x += logical_monitor_width (m); } g_list_free (logical_monitors); } cinnamon-control-center-6.4.1/panels/display/icons/0000775000175000017500000000000014724311620021246 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/display/icons/scalable/0000775000175000017500000000000014724311620023014 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/display/icons/scalable/cinnamon-preferences-desktop-display.svg0000664000175000017500000004573714724311620032770 0ustar fabiofabio image/svg+xml Change Resolution Jakub Steiner display resolution video Andreas Nilsson Luca Ferretti <elle.uca@libero.it> http://www.gnome.org cinnamon-control-center-6.4.1/panels/display/icons/meson.build0000664000175000017500000000040414724311620023406 0ustar fabiofabiodisplay_icon_sizes = [ '16x16', '22x22', '24x24', '32x32', 'scalable' ] foreach size : display_icon_sizes install_subdir(size, strip_directory: true, install_dir: get_option('datadir') / 'icons' / 'hicolor' / size / 'apps', ) endforeach cinnamon-control-center-6.4.1/panels/display/icons/24x24/0000775000175000017500000000000014724311620022031 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/display/icons/24x24/cinnamon-preferences-desktop-display.png0000664000175000017500000000161514724311620031755 0ustar fabiofabio‰PNG  IHDRąw=ųbKGDłC» pHYs × ×B(›xtIMEÖ !˜“HIDATHǽ–Mh\U€æwļ}“`BŅ,ŠDœ]¬Ī®;Akˆ6”E7œ-FŠ„OźJQ1”“ˆÅ.ŗĢB:ş¬ĮV‘i”ZH©““³Čß»3oīqńī¼™$ƟśąpĪ{¼{¾ósļyžĒ+øoN£čä×I’¼z0’!ßĻF;åū| [·Ŗ©sZ¦Īi±¶!q\ߖX[—ååÕ$ŠN €iįœ/¹r”›7O=½ķŠÆLOė–¬³ņ…"_¼5Ī7×ßM‹(āuHGu„­ƒ”üķdĒ; ZF§ĒZ­L¾PdxßGˆ"~Ī„÷"āµļ;ünXkSC"Āź½‹ä E^Ü÷1"ē"Į!Ī­·q[Dœ×MaaöfyéńO,z/Npā.…Öc»5Ą˜0ŠLÓ%`aö rč‰OĮI;Kē²’­,/Q­V™›ŸŪȚÜÕÕå×:€‰«o0ĀöBFųŒ ?ŅH:Ö։浬ōZ©­3h:Ƒ'ϬĖäš3§¹w÷.KKKŌmŒR ķEy@+ĄæĪĄ7tĻ#»QZćœCiC˜ĖAcŠ|”H‰q>æ8Į?O—M8—p{~Žž]Cō āęėō?ō  ¼ĢŹÆŁ9) Mü­ćœZ^ŸA.—i2ķ<üvł”?Ošk“ļųhæ<ī#( Mlyāė®—©ÆxÖ“w‘įŃēQJ’§ńśŻĮ¶ŻA«öŖÆóCØT®288ø#c“R©ljņh¹|ét¹|i'?£«ų¦g­Tzū—½{4ĘŠ)JiĀ0DkĶĢĢĢOĒŽ½w`ƒst®»)t÷öö†'N|0iL8Š××·k’ž§“R­µw u[OO’˜,.VļX[Ǝ½óœwŽ,`MGōŻ@ĻŃ£c GŽNśūūĶæ©Ćšš Ų]«ÕÖÖVļDŃń‡}ĄÉŗm 4}œ=ū„ŁFĶ[kjĄŹĘ„>‹®zØń¢}tM/ĪkėeŋõČ}’Uł¶Ś¾čdŒ6ĢIEND®B`‚cinnamon-control-center-6.4.1/panels/display/icons/16x16/0000775000175000017500000000000014724311620022033 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/display/icons/16x16/cinnamon-preferences-desktop-display.png0000664000175000017500000000114514724311620031755 0ustar fabiofabio‰PNG  IHDRó’abKGDłC» pHYs × ×B(›xtIMEÖ 6± ÷ņIDAT8Ė•’ĻkA†ŸMš&”±I!£ęāQ VZü āAŌC’²…@`iÄS©˜@õšāMAň`ՋUšmŚ”=ˆøkµjgzŲ$Ø©Ę¾šĮĢĄ÷š¾ß7ą+Qƚŗ^55;”œ™¹ü°ÕjMĄ,ٜM½ZÖw—’jŽF£„ēySS§łŗ8 @6gæ(—ƕߊZńķÓm²9›W·vs®rųÆĶ÷ļŌüJ)’U+“Ö¬¬‘ĶŁĢåĖÜx~¶ÆłĮ£…ŽYX–ģ8Ų­i.­õ g]ūg  }›h­1 ĮŚr«ā¹ķv»: ü]ż ń¾xh…RŠŌŽ=¤÷§HH Ə:ŁœĶłÉ›Ūŗ”śÉ‡ÕįÄ$įä šÆ_2œ<ÅŠ®“¼{ZŁ"{ō&«/®ƒ†7O*™ļ;‚· Ą`.’¬0§¤»«Bģō'cüzqœŅŅųųX³ŃX9&„@J‰iš½Źdöµēēk+ŽSū-ĄōōE[)I„R£±Ų(¦)0M „DĖ’Aąˆć”ņŽS¬ō†čGŠWŠÅ‚N$’Įx<žyd$ęF"7 ¹–e¹¦)]­ ³Pø €rŸ€Ré’ ujĀĄś&ķИ­IEND®B`‚cinnamon-control-center-6.4.1/panels/display/icons/32x32/0000775000175000017500000000000014724311620022027 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/display/icons/32x32/cinnamon-preferences-desktop-display.png0000664000175000017500000000310214724311620031744 0ustar fabiofabio‰PNG  IHDR szzōbKGD’’’ ½§“tIMEÖ  jéV†äIDATX…½–kp”ÕĒļy÷Źn’+ q"ĘTA.– PŃŃNUd“g:#żÖĪtŹū”ŌQÉLū„T¦ĆL/c[ŌQTŹŲ*BBj  H0”Ėl"…ÉBĀfwóŽĪ釯l6ŁĶÅŹųŸ9³ļyęœēł?·³dįOĻė[łš!²7šĘė{;<ū’ŲŽļė" ģڵĖkKćweńŸ~Æféj†"H·#õņ[nб„ać‡oźń§ŚŌ~Óą(ó¹¶onÜÖŲOĖŖG©¬9Ééļęī÷PÓšķy+Wjī3š¦y#‘Ė[Ž>°’%ąiWJ(¾Æt÷J*«ØdĶęķōtī 2pĘ{~ī“‘\+¹25!…RP[['\B#yżCź–µ°°¬šžŽ`p¬•ØuēŒjGbY&ńx2-™J#‹@~"Ą™‘'1N¼Ē•ČyīZ’žĄB’#š×³~Ėč9ŗąµĖ\ŒmĘQ cÜ ‘LL&±m#‚3RO#izč~˜³‘ žy`77®GńÆĒÄIœbÕ½[inŖ¢±h/FüCCC\½v•X,–1žém;s H=0ÅsÉ Wb~šõ M„Ā÷a&Ī‘ˆžƒ„«(-[Œ§ūŽĖ‘Kęņkö(„@ILĖŹ¬h¼˜Eįäéky’÷HŹš¶æ~„`Šaͦļ²fłZėzš3“[sE@””D*(l{2wJ)’¶M×@+µĆIĘ_fEėŹ«ŪHÜčķ VoxŒ…}]:9vžf`ÖäPJ¢”J¢©$–¾=É|zJƒ¾ORUūW~ 31@|ų0w¬£tQ~O'=Ć\­ŹŅ?ŅA×›kG„#B:"ß9©—Eą+ ćņV”ø¤™µ·į;ö7ĪE¢æt{ځ¹R J9t½»“š·£¤ƒR’¾“ēi×””ƒ’’³§ -/O’œ;;LØiŸŸ‹²¬aA«7>AĮ‰NJ]:Ó:s ” ‰ķ8ųK¢¢>Ģ‚Ņj©‚¬\z•@Ł¢ŒĒ•ć×)¬,ŹxTeß¤Øŗ0õ-cU"Uć+Z·P\rŠB߇ |śEėŸÉ%066††äż}ķH„”kż½zę ®9ōĻŚ ‡žć"k/3{]HĪ~’Ū`ŗ\īł1>WN% Yµõ –ebŪ¹-4µxŌ4y¾W>ŸLĆåŅ …–Ó3°g’€ćؾśśey.ż?˜}6ÓuŽe“¤ń“ß¼ōėßś|ŽŁ›öĮ7L…|ę1UģüÕĪÖO{Ouµ„[¼.— Ē:Bt]G×u„ŠŅæ©ż±ī®DĶāŹÕĻ>ūó¾¹ōĻś_`&“›C”ŁÜÜ<Ř®ėhډl2:7F¢rdtō~`Ny#ŠŃѱÄćÓ_@ÓīšVóĄę- Tv4MĖZ „Č“ŪĘāqžz`Eæm[GQćĻķŲŃ><™‰ˆī}åĻ=RJu+‹ÅTĒ/_ų;P äŒÕŁ)p“jĪ‚”/†ī¼„Ūķ™é”˜¦†hJ€1@bł@:%R:ŽW^{õ+Ÿ_ZwNʧ ܤĀä<¤ę…/7O…Lė°Hq²ŠŁ”UćӉä}ž %t¾šnIEND®B`‚cinnamon-control-center-6.4.1/panels/display/icons/22x22/0000775000175000017500000000000014724311620022025 5ustar fabiofabiocinnamon-control-center-6.4.1/panels/display/icons/22x22/cinnamon-preferences-desktop-display.png0000664000175000017500000000154214724311620031750 0ustar fabiofabio‰PNG  IHDRÄ“l;bKGD’’’ ½§“ pHYs × ×B(›xtIMEÖ "żŠ„ēļIDAT8Ė­”OhWĄóŽ›M0!b¢B‘®R µī­g’„ع"ķU…ī‚•¦ˆāŠ=µŚbA/zš˜CQŠ’SSØ¶Čź!ŲZB,›Šī!ĘģģĪ~_óvv× HȃoŽīĢo~ļ›÷=HFĄ: X<{=Žć/öeæć—ŁāzqoÅāY;’sg³ȍVQÕµYPÆĒsēĪ[ ¢ ›Ės’f7_^üdĶŖ÷§§-€ˆ¢jśG6—ēŅWüüų›¤ņŖ>€¶}må @U¹}g*½ĒT« XUX©Ü&›Ė3¼ć{TUÆ*"É\UżO­9ÆUĻ$ĘQ2SAUyõāŁ\ž;~@UUAT¤óY VoÜUfŸ¦šƒžGS[¢ˆz°$/«U£Õ`ēĀLĆļˆ€…ŁSų”?‚hkU"ii–_.Q.—™›Ÿė;€®®.’Œ¤[mņįFøĀų?qó1źqL½^#ŠjT«+ii­1«›ąö1ņŃ€óŃŻ—yńü9KKKŌ¢*ʬćĮM±Nc’”¶¼æ c-"‚±Ž0“śÆdsy LpįÖHŅ oĘ"1’ĶĻѳqˆžC<}ņ˜žĶŸ³aą3ž”¤ū¼04łVhƼLŒ3™ hƒłG7@įÆ{}XM$švߛ𦅔É7vhMz°sŽm{1ʶśžŚ÷ī¾ÖuCk‚Ī]Q*=dppp]޵R©”›GĖė|m+7m§ …±?·o’`Š9G{c Ćk-333æŸ8ńķ§ÆA&0t÷öö†§OŸ™r.čėėŪøk×ĒÖ‹µÖC¬måééßāÅÅņ³(Ŗ•ĒĒæŽć”u r޲č9~||įšįŃøææß½Ėz‡‡÷;`S„RXYyõ¬X<µÕ‹ĘM@Ć[sõź5·†š6ŸyØĖ͇޺«-‡že·õ6 āsäcŁGÄ’„tŪ4·† IEND®B`‚cinnamon-control-center-6.4.1/panels/display/cc-display-config-manager.h0000664000175000017500000000256114724311620025213 0ustar fabiofabio/* * Copyright (C) 2016 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #pragma once #include #include "cc-display-config.h" G_BEGIN_DECLS #define CC_TYPE_DISPLAY_CONFIG_MANAGER (cc_display_config_manager_get_type ()) G_DECLARE_DERIVABLE_TYPE (CcDisplayConfigManager, cc_display_config_manager, CC, DISPLAY_CONFIG_MANAGER, GObject) struct _CcDisplayConfigManagerClass { GObjectClass parent_class; CcDisplayConfig * (*get_current) (CcDisplayConfigManager *self); }; CcDisplayConfig * cc_display_config_manager_get_current (CcDisplayConfigManager *self); void _cc_display_config_manager_emit_changed (CcDisplayConfigManager *self); G_END_DECLS cinnamon-control-center-6.4.1/panels/display/cc-display-arrangement.c0000664000175000017500000010204514724311620024632 0ustar fabiofabio/* cc-display-arrangement.c * * Copyright (C) 2007, 2008, 2017 Red Hat, Inc. * Copyright (C) 2013 Intel, Inc. * * Written by: Benjamin Berg * * 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, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ #include #include "cc-display-arrangement.h" #include "cc-display-config.h" #include "cc-display-labeler.h" struct _CcDisplayArrangement { GtkDrawingArea object; CcDisplayConfig *config; cairo_matrix_t to_widget; cairo_matrix_t to_actual; gboolean drag_active; CcDisplayMonitor *selected_output; CcDisplayMonitor *prelit_output; /* Starting position of cursor inside the monitor. */ gdouble drag_anchor_x; gdouble drag_anchor_y; guint major_snap_distance; }; typedef struct _CcDisplayArrangement CcDisplayArrangement; enum { PROP_0, PROP_CONFIG, PROP_SELECTED_OUTPUT, PROP_LAST }; typedef enum { SNAP_DIR_NONE = 0, SNAP_DIR_X = 1 << 0, SNAP_DIR_Y = 1 << 1, SNAP_DIR_BOTH = (SNAP_DIR_X | SNAP_DIR_Y), } SnapDirection; typedef struct { cairo_matrix_t to_widget; guint major_snap_distance; gdouble dist_x; gdouble dist_y; gint mon_x; gint mon_y; SnapDirection snapped; } SnapData; #define MARGIN_PX 0 #define MARGIN_MON 0.66 #define MAJOR_SNAP_DISTANCE 25 #define MINOR_SNAP_DISTANCE 5 #define MIN_OVERLAP 25 G_DEFINE_TYPE (CcDisplayArrangement, cc_display_arrangement, GTK_TYPE_DRAWING_AREA) static GParamSpec *props[PROP_LAST]; static void apply_rotation_to_geometry (CcDisplayMonitor *output, int *w, int *h) { CcDisplayRotation rotation; rotation = cc_display_monitor_get_rotation (output); if ((rotation == CC_DISPLAY_ROTATION_90) || (rotation == CC_DISPLAY_ROTATION_270)) { int tmp; tmp = *h; *h = *w; *w = tmp; } } /* get_geometry */ static void get_scaled_geometry (CcDisplayConfig *config, CcDisplayMonitor *output, double max_scale, int *x, int *y, int *w, int *h) { if (cc_display_monitor_is_active (output)) { cc_display_monitor_get_geometry (output, x, y, w, h); } else { cc_display_monitor_get_geometry (output, x, y, NULL, NULL); CcDisplayMode *mode = cc_display_monitor_get_preferred_mode(output); if (!mode) mode = CC_DISPLAY_MODE (cc_display_monitor_get_modes(output)->data); cc_display_mode_get_resolution (mode, w, h); } if (cc_display_config_is_layout_logical (config)) { double scale = cc_display_monitor_get_scale (output); if (cc_display_config_layout_use_ui_scale (config)) scale /= ceil (max_scale); *w = round (*w / scale); *h = round (*h / scale); } apply_rotation_to_geometry (output, w, h); } static void get_bounding_box (CcDisplayConfig *config, gint *x1, gint *y1, gint *x2, gint *y2, gint *max_w, gint *max_h) { GList *outputs, *l; gdouble max_scale; g_assert (x1 && y1 && x2 && y2); *x1 = *y1 = G_MAXINT; *x2 = *y2 = G_MININT; *max_w = 0; *max_h = 0; max_scale = cc_display_config_get_maximum_scaling (config); outputs = cc_display_config_get_monitors (config); for (l = outputs; l; l = l->next) { CcDisplayMonitor *output = l->data; int x, y, w, h; if (!cc_display_monitor_is_useful (output)) continue; get_scaled_geometry (config, output, max_scale, &x, &y, &w, &h); *x1 = MIN (*x1, x); *y1 = MIN (*y1, y); *x2 = MAX (*x2, x + w); *y2 = MAX (*y2, y + h); *max_w = MAX (*max_w, w); *max_h = MAX (*max_h, h); } } static void monitor_get_drawing_rect (CcDisplayArrangement *self, CcDisplayMonitor *output, gint *x1, gint *y1, gint *x2, gint *y2) { gdouble x, y; gdouble max_scale; max_scale = cc_display_config_get_maximum_scaling (self->config); get_scaled_geometry (self->config, output, max_scale, x1, y1, x2, y2); /* get_scaled_geometry returns the width and height */ *x2 = *x1 + *x2; *y2 = *y1 + *y2; x = *x1; y = *y1; cairo_matrix_transform_point (&self->to_widget, &x, &y); *x1 = round (x); *y1 = round (y); x = *x2; y = *y2; cairo_matrix_transform_point (&self->to_widget, &x, &y); *x2 = round (x); *y2 = round (y); } static void get_snap_distance (SnapData *snap_data, gint mon_x, gint mon_y, gint new_x, gint new_y, gdouble *dist_x, gdouble *dist_y) { gdouble local_dist_x, local_dist_y; local_dist_x = ABS (mon_x - new_x); local_dist_y = ABS (mon_y - new_y); cairo_matrix_transform_distance (&snap_data->to_widget, &local_dist_x, &local_dist_y); if (dist_x) *dist_x = local_dist_x; if (dist_y) *dist_y = local_dist_y; } static void maybe_update_snap (SnapData *snap_data, gint mon_x, gint mon_y, gint new_x, gint new_y, SnapDirection snapped, SnapDirection major_axis, gint minor_unlimited) { SnapDirection update_snap = SNAP_DIR_NONE; gdouble dist_x, dist_y; gdouble dist; get_snap_distance (snap_data, mon_x, mon_y, new_x, new_y, &dist_x, &dist_y); dist = MAX (dist_x, dist_y); /* Snap by the variable max snap distance on the major axis, ensure the * minor axis is below the minimum snapping distance (often just zero). */ switch (major_axis) { case SNAP_DIR_X: if (dist_x > snap_data->major_snap_distance) return; if (dist_y > MINOR_SNAP_DISTANCE) { if (new_y > mon_y && minor_unlimited <= 0) return; if (new_y < mon_y && minor_unlimited >= 0) return; } break; case SNAP_DIR_Y: if (dist_y > snap_data->major_snap_distance) return; if (dist_x > MINOR_SNAP_DISTANCE) { if (new_x > mon_x && minor_unlimited <= 0) return; if (new_x < mon_x && minor_unlimited >= 0) return; } break; default: g_assert_not_reached(); } if (snapped == SNAP_DIR_BOTH) { if (snap_data->snapped == SNAP_DIR_NONE) update_snap = SNAP_DIR_BOTH; /* Update, if this is closer on the main axis. */ if (((major_axis == SNAP_DIR_X) && (dist_x < snap_data->dist_x)) || ((major_axis == SNAP_DIR_Y) && (dist_y < snap_data->dist_y))) { update_snap = SNAP_DIR_BOTH; } /* Also update if we were only snapping in one direction earlier and it * is better or equally good. */ if ((snap_data->snapped == SNAP_DIR_X && (dist <= snap_data->dist_x)) || (snap_data->snapped == SNAP_DIR_Y && (dist <= snap_data->dist_y))) { update_snap = SNAP_DIR_BOTH; } /* Also allow a minor axis to be added if the first axis remains identical. */ if (((snap_data->snapped == SNAP_DIR_X) && (major_axis == SNAP_DIR_X) && (new_x == snap_data->mon_x)) || ((snap_data->snapped == SNAP_DIR_Y) && (major_axis == SNAP_DIR_Y) && (new_y == snap_data->mon_y))) { update_snap = SNAP_DIR_BOTH; } } else if (snapped == SNAP_DIR_X) { if (dist_x < snap_data->dist_x || (snap_data->snapped & SNAP_DIR_X) == SNAP_DIR_NONE) update_snap = SNAP_DIR_X; } else if (snapped == SNAP_DIR_Y) { if (dist_y < snap_data->dist_y || (snap_data->snapped & SNAP_DIR_Y) == SNAP_DIR_NONE) update_snap = SNAP_DIR_Y; } else { g_assert_not_reached (); } if (update_snap & SNAP_DIR_X) { snap_data->dist_x = dist_x; snap_data->mon_x = new_x; snap_data->snapped = snap_data->snapped | SNAP_DIR_X; } if (update_snap & SNAP_DIR_Y) { snap_data->dist_y = dist_y; snap_data->mon_y = new_y; snap_data->snapped = snap_data->snapped | SNAP_DIR_Y; } } static void find_best_snapping (CcDisplayConfig *config, CcDisplayMonitor *snap_output, SnapData *snap_data) { GList *outputs, *l; gint x1, y1, x2, y2; gint w, h; double max_scale; g_assert (snap_data != NULL); max_scale = cc_display_config_get_maximum_scaling (config); get_scaled_geometry (config, snap_output, max_scale, &x1, &y1, &w, &h); x2 = x1 + w; y2 = y1 + h; #define OVERLAP(_s1, _s2, _t1, _t2) ((_s1) <= (_t2) && (_t1) <= (_s2)) outputs = cc_display_config_get_monitors (config); for (l = outputs; l; l = l->next) { CcDisplayMonitor *output = l->data; gint _x1, _y1, _x2, _y2, _h, _w; gint bottom_snap_pos; gint top_snap_pos; gint left_snap_pos; gint right_snap_pos; gdouble dist_x, dist_y; gdouble max_scale; gdouble tmp; if (output == snap_output) continue; if (!cc_display_monitor_is_useful (output)) continue; max_scale = cc_display_config_get_maximum_scaling (config); get_scaled_geometry (config, output, max_scale, &_x1, &_y1, &_w, &_h); _x2 = _x1 + _w; _y2 = _y1 + _h; top_snap_pos = _y1 - h; bottom_snap_pos = _y2; left_snap_pos = _x1 - w; right_snap_pos = _x2; dist_y = 9999; /* overlap on the X axis */ if (OVERLAP (x1, x2, _x1, _x2)) { get_snap_distance (snap_data, x1, y1, x1, top_snap_pos, NULL, &dist_y); get_snap_distance (snap_data, x1, y1, x1, bottom_snap_pos, NULL, &tmp); dist_y = MIN(dist_y, tmp); } dist_x = 9999; /* overlap on the Y axis */ if (OVERLAP (y1, y2, _y1, _y2)) { get_snap_distance (snap_data, x1, y1, left_snap_pos, y1, &dist_x, NULL); get_snap_distance (snap_data, x1, y1, right_snap_pos, y1, &tmp, NULL); dist_x = MIN(dist_x, tmp); } /* We only snap horizontally or vertically to an edge of the same monitor */ if (dist_y < dist_x) { maybe_update_snap (snap_data, x1, y1, x1, top_snap_pos, SNAP_DIR_Y, SNAP_DIR_Y, 0); maybe_update_snap (snap_data, x1, y1, x1, bottom_snap_pos, SNAP_DIR_Y, SNAP_DIR_Y, 0); } else if (dist_x < 9999) { maybe_update_snap (snap_data, x1, y1, left_snap_pos, y1, SNAP_DIR_X, SNAP_DIR_X, 0); maybe_update_snap (snap_data, x1, y1, right_snap_pos, y1, SNAP_DIR_X, SNAP_DIR_X, 0); } /* Left/right edge identical on the top */ maybe_update_snap (snap_data, x1, y1, _x1, top_snap_pos, SNAP_DIR_BOTH, SNAP_DIR_Y, 0); maybe_update_snap (snap_data, x1, y1, _x2 - w, top_snap_pos, SNAP_DIR_BOTH, SNAP_DIR_Y, 0); /* Left/right edge identical on the bottom */ maybe_update_snap (snap_data, x1, y1, _x1, bottom_snap_pos, SNAP_DIR_BOTH, SNAP_DIR_Y, 0); maybe_update_snap (snap_data, x1, y1, _x2 - w, bottom_snap_pos, SNAP_DIR_BOTH, SNAP_DIR_Y, 0); /* Top/bottom edge identical on the left */ maybe_update_snap (snap_data, x1, y1, left_snap_pos, _y1, SNAP_DIR_BOTH, SNAP_DIR_X, 0); maybe_update_snap (snap_data, x1, y1, left_snap_pos, _y2 - h, SNAP_DIR_BOTH, SNAP_DIR_X, 0); /* Top/bottom edge identical on the right */ maybe_update_snap (snap_data, x1, y1, right_snap_pos, _y1, SNAP_DIR_BOTH, SNAP_DIR_X, 0); maybe_update_snap (snap_data, x1, y1, right_snap_pos, _y2 - h, SNAP_DIR_BOTH, SNAP_DIR_X, 0); /* If snapping is infinite, then add snapping points with minimal overlap * to prevent detachment. * This is similar to the above but simply re-defines the snapping pos * to have only minimal overlap */ if (snap_data->major_snap_distance == G_MAXUINT) { /* Hanging over the left/right edge on the top */ maybe_update_snap (snap_data, x1, y1, _x1 - w + MIN_OVERLAP, top_snap_pos, SNAP_DIR_BOTH, SNAP_DIR_Y, 1); maybe_update_snap (snap_data, x1, y1, _x2 - MIN_OVERLAP, top_snap_pos, SNAP_DIR_BOTH, SNAP_DIR_Y, -1); /* Left/right edge identical on the bottom */ maybe_update_snap (snap_data, x1, y1, _x1 - w + MIN_OVERLAP, bottom_snap_pos, SNAP_DIR_BOTH, SNAP_DIR_Y, 1); maybe_update_snap (snap_data, x1, y1, _x2 - MIN_OVERLAP, bottom_snap_pos, SNAP_DIR_BOTH, SNAP_DIR_Y, -1); /* Top/bottom edge identical on the left */ maybe_update_snap (snap_data, x1, y1, left_snap_pos, _y1 - h + MIN_OVERLAP, SNAP_DIR_BOTH, SNAP_DIR_X, 1); maybe_update_snap (snap_data, x1, y1, left_snap_pos, _y2 - MIN_OVERLAP, SNAP_DIR_BOTH, SNAP_DIR_X, -1); /* Top/bottom edge identical on the right */ maybe_update_snap (snap_data, x1, y1, right_snap_pos, _y1 - h + MIN_OVERLAP, SNAP_DIR_BOTH, SNAP_DIR_X, 1); maybe_update_snap (snap_data, x1, y1, right_snap_pos, _y2 - MIN_OVERLAP, SNAP_DIR_BOTH, SNAP_DIR_X, -1); } } #undef OVERLAP } static void cc_display_arrangement_update_matrices (CcDisplayArrangement *self) { GtkAllocation allocation; gdouble scale, scale_h, scale_w; gint x1, y1, x2, y2, max_w, max_h; g_assert (self->config); /* Do not update the matrices while the user is dragging things around. */ if (self->drag_active) return; get_bounding_box (self->config, &x1, &y1, &x2, &y2, &max_w, &max_h); gtk_widget_get_allocation (GTK_WIDGET (self), &allocation); scale_h = (gdouble) (allocation.width - 2 * MARGIN_PX) / (x2 - x1 + max_w * 2 * MARGIN_MON); scale_w = (gdouble) (allocation.height - 2 * MARGIN_PX) / (y2 - y1 + max_h * 2 * MARGIN_MON); scale = MIN (scale_h, scale_w); cairo_matrix_init_identity (&self->to_widget); cairo_matrix_translate (&self->to_widget, allocation.width / 2.0, allocation.height / 2.0); cairo_matrix_scale (&self->to_widget, scale, scale); cairo_matrix_translate (&self->to_widget, - (x1 + x2) / 2.0, - (y1 + y2) / 2.0); self->to_actual = self->to_widget; cairo_matrix_invert (&self->to_actual); } static CcDisplayMonitor* cc_display_arrangement_find_monitor_at (CcDisplayArrangement *self, gint x, gint y) { g_autoptr(GList) outputs = NULL; GList *l; outputs = g_list_copy (cc_display_config_get_monitors (self->config)); if (self->selected_output) outputs = g_list_prepend (outputs, self->selected_output); for (l = outputs; l; l = l->next) { CcDisplayMonitor *output = l->data; gint x1, y1, x2, y2; if (!cc_display_monitor_is_usable (output)) continue; if (!cc_display_monitor_is_active (output)) { cc_display_monitor_get_disabled_geometry (output, &x1, &y1, &x2, &y2); } else { monitor_get_drawing_rect (self, output, &x1, &y1, &x2, &y2); } if (x >= x1 && x <= x2 && y >= y1 && y <= y2) return output; } return NULL; } static void cc_display_arrangement_update_cursor (CcDisplayArrangement *self, gboolean dragable) { g_autoptr(GdkCursor) cursor = NULL; GdkWindow *window; if (dragable) cursor = gdk_cursor_new_for_display (gtk_widget_get_display (GTK_WIDGET (self)), GDK_FLEUR); else cursor = NULL; window = gtk_widget_get_window (GTK_WIDGET (self)); if (window) gdk_window_set_cursor (window, cursor); } static void on_output_changed_cb (CcDisplayArrangement *self, CcDisplayMonitor *output) { if (cc_display_config_count_useful_monitors (self->config) > 2) self->major_snap_distance = MAJOR_SNAP_DISTANCE; else self->major_snap_distance = G_MAXUINT; gtk_widget_queue_draw (GTK_WIDGET (self)); } static gint sort_outputs_by_disabled (gconstpointer a, gconstpointer b) { CcDisplayMonitor *ma = CC_DISPLAY_MONITOR ((gpointer) a); CcDisplayMonitor *mb = CC_DISPLAY_MONITOR ((gpointer) b); if (!cc_display_monitor_is_active (ma) && cc_display_monitor_is_active (mb)) return -1; if (cc_display_monitor_is_active (ma) && !cc_display_monitor_is_active (mb)) return 1; return cc_display_monitor_get_ui_number ((gpointer) a) < cc_display_monitor_get_ui_number ((gpointer) b) ? -1 : 1; } static gboolean cc_display_arrangement_draw (GtkWidget *widget, cairo_t *cr) { CcDisplayArrangement *self = CC_DISPLAY_ARRANGEMENT (widget); GtkStyleContext *context = gtk_widget_get_style_context (widget); g_autoptr(GList) outputs = NULL; GList *l; gint last_disabled_x = 0; if (!self->config) return FALSE; cc_display_arrangement_update_matrices (self); gtk_style_context_save (context); gtk_style_context_add_class (context, "display-arrangement"); cairo_save (cr); gtk_render_background (context, cr, 0, 0, gtk_widget_get_allocated_width (widget), gtk_widget_get_allocated_height (widget)); cairo_restore (cr); /* Draw in reverse order so that hit detection matches visual. Also pull * the selected output to the back. */ outputs = g_list_copy (cc_display_config_get_monitors (self->config)); outputs = g_list_sort (outputs, (GCompareFunc) sort_outputs_by_disabled); if (cc_display_monitor_is_active (self->selected_output)) { outputs = g_list_remove (outputs, self->selected_output); if (self->selected_output != NULL) outputs = g_list_prepend (outputs, self->selected_output); } outputs = g_list_reverse (outputs); for (l = outputs; l; l = l->next) { CcDisplayMonitor *output = l->data; GtkStateFlags state = GTK_STATE_FLAG_NORMAL; GtkBorder border, padding, margin; GdkRGBA bg_rgba; gint x1, y1, x2, y2; gint w, h; gint ui_number, color_index; if (!cc_display_monitor_is_usable (output)) continue; gtk_style_context_save (context); cairo_save (cr); gtk_style_context_add_class (context, "monitor"); if (output == self->selected_output) state |= GTK_STATE_FLAG_SELECTED; if (output == self->prelit_output) state |= GTK_STATE_FLAG_PRELIGHT; gtk_style_context_set_state (context, state); if (cc_display_monitor_is_primary (output) || cc_display_config_is_cloning (self->config)) gtk_style_context_add_class (context, "primary"); monitor_get_drawing_rect (self, output, &x1, &y1, &x2, &y2); w = x2 - x1; h = y2 - y1; if (!cc_display_monitor_is_active (output)) { h = 50; w = h * 1.77; cairo_translate (cr, last_disabled_x, 0); cc_display_monitor_set_disabled_geometry (output, last_disabled_x, 0, w, h); last_disabled_x += w; } else { cairo_translate (cr, x1, y1); } gtk_style_context_get_margin (context, state, &margin); cairo_translate (cr, margin.left, margin.top); w -= margin.left + margin.right; h -= margin.top + margin.bottom; cairo_save (cr); /* Set in cc-display-panel.c */ ui_number = cc_display_monitor_get_ui_number (output); color_index = ui_number - 1; // ui_numbers start at 1, our color index is 0-based. gchar *rgba_str; g_signal_emit_by_name (G_OBJECT (widget), "get-output-color", color_index, &rgba_str); if (gdk_rgba_parse (&bg_rgba, rgba_str)) { if (!cc_display_monitor_is_active (output)) { bg_rgba.alpha = 0.35; } gdk_cairo_set_source_rgba (cr, &bg_rgba); } g_free (rgba_str); cairo_rectangle (cr, 0, 0, w, h); cairo_fill (cr); cairo_restore (cr); gtk_render_frame (context, cr, 0, 0, w, h); gtk_style_context_get_border (context, state, &border); gtk_style_context_get_padding (context, state, &padding); w -= border.left + border.right + padding.left + padding.right; h -= border.top + border.bottom + padding.top + padding.bottom; cairo_translate (cr, border.left + padding.left, border.top + padding.top); if (ui_number > 0) { PangoLayout *layout; PangoFontDescription *font = NULL; g_autofree gchar *number_str = NULL; PangoRectangle extents; GdkRGBA color; gdouble text_width, text_padding; gtk_style_context_add_class (context, "monitor-label"); gtk_style_context_remove_class (context, "monitor"); gtk_style_context_get_border (context, state, &border); gtk_style_context_get_padding (context, state, &padding); gtk_style_context_get_margin (context, state, &margin); cairo_translate (cr, margin.left, margin.top); number_str = g_strdup_printf ("%d", ui_number); gtk_style_context_get (context, state, "font", &font, NULL); layout = gtk_widget_create_pango_layout (GTK_WIDGET (self), number_str); pango_layout_set_font_description (layout, font); pango_font_description_free (font); pango_layout_get_extents (layout, NULL, &extents); h = (extents.height - extents.y) / PANGO_SCALE; text_width = (extents.width - extents.x) / PANGO_SCALE; w = MAX (text_width, h - padding.left - padding.right); text_padding = w - text_width; w += border.left + border.right + padding.left + padding.right; h += border.top + border.bottom + padding.top + padding.bottom; gtk_render_background (context, cr, 0, 0, w, h); gtk_render_frame (context, cr, 0, 0, w, h); cairo_translate (cr, border.left + padding.left, border.top + padding.top); cairo_translate (cr, extents.x + text_padding / 2, 0); gtk_style_context_get_color (context, state, &color); gdk_cairo_set_source_rgba (cr, &color); gtk_render_layout (context, cr, 0, 0, layout); g_object_unref (layout); } gtk_style_context_restore (context); cairo_restore (cr); } gtk_style_context_restore (context); return TRUE; } static gboolean cc_display_arrangement_button_press_event (GtkWidget *widget, GdkEventButton *event) { CcDisplayArrangement *self = CC_DISPLAY_ARRANGEMENT (widget); CcDisplayMonitor *output; gdouble event_x, event_y; gint mon_x, mon_y; if (!self->config) return FALSE; /* Only handle normal presses of the left mouse button. */ if (event->button != 1 || event->type != GDK_BUTTON_PRESS) return FALSE; g_return_val_if_fail (self->drag_active == FALSE, FALSE); output = cc_display_arrangement_find_monitor_at (self, event->x, event->y); if (!output) return FALSE; if (!cc_display_monitor_is_active (output)) { cc_display_arrangement_set_selected_output (self, output); return FALSE; } event_x = event->x; event_y = event->y; cairo_matrix_transform_point (&self->to_actual, &event_x, &event_y); cc_display_monitor_get_geometry (output, &mon_x, &mon_y, NULL, NULL); cc_display_arrangement_set_selected_output (self, output); if (cc_display_config_count_useful_monitors (self->config) > 1) { self->drag_active = TRUE; self->drag_anchor_x = event_x - mon_x; self->drag_anchor_y = event_y - mon_y; } return TRUE; } static gboolean cc_display_arrangement_button_release_event (GtkWidget *widget, GdkEventButton *event) { CcDisplayArrangement *self = CC_DISPLAY_ARRANGEMENT (widget); CcDisplayMonitor *output; if (!self->config) return FALSE; /* Only handle left mouse button */ if (event->button != 1) return FALSE; if (!self->drag_active) return FALSE; self->drag_active = FALSE; output = cc_display_arrangement_find_monitor_at (self, event->x, event->y); cc_display_arrangement_update_cursor (self, output != NULL); /* And queue a redraw to recenter everything */ gtk_widget_queue_draw (widget); g_signal_emit_by_name (G_OBJECT (widget), "updated"); return TRUE; } static gboolean cc_display_arrangement_motion_notify_event (GtkWidget *widget, GdkEventMotion *event) { CcDisplayArrangement *self = CC_DISPLAY_ARRANGEMENT (widget); gdouble event_x, event_y; gint mon_x, mon_y; SnapData snap_data; if (!self->config) return FALSE; if (cc_display_config_count_useful_monitors (self->config) <= 1) return FALSE; if (!self->drag_active) { CcDisplayMonitor *output; output = cc_display_arrangement_find_monitor_at (self, event->x, event->y); if (output != NULL && !cc_display_monitor_is_active (output)) return FALSE; cc_display_arrangement_update_cursor (self, output != NULL); if (self->prelit_output != output) gtk_widget_queue_draw (widget); self->prelit_output = output; return FALSE; } g_assert (self->selected_output); event_x = event->x; event_y = event->y; cairo_matrix_transform_point (&self->to_actual, &event_x, &event_y); mon_x = round (event_x - self->drag_anchor_x); mon_y = round (event_y - self->drag_anchor_y); /* The monitor is now at the location as if there was no snapping whatsoever. */ snap_data.snapped = SNAP_DIR_NONE; snap_data.mon_x = mon_x; snap_data.mon_y = mon_y; snap_data.dist_x = 0; snap_data.dist_y = 0; snap_data.to_widget = self->to_widget; snap_data.major_snap_distance = self->major_snap_distance; cc_display_monitor_set_position (self->selected_output, mon_x, mon_y); find_best_snapping (self->config, self->selected_output, &snap_data); cc_display_monitor_set_position (self->selected_output, snap_data.mon_x, snap_data.mon_y); return TRUE; } static void cc_display_arrangement_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { CcDisplayArrangement *self = CC_DISPLAY_ARRANGEMENT (object); switch (prop_id) { case PROP_CONFIG: g_value_set_object (value, self->config); break; case PROP_SELECTED_OUTPUT: g_value_set_object (value, self->selected_output); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void cc_display_arrangement_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { CcDisplayArrangement *obj = CC_DISPLAY_ARRANGEMENT (object); switch (prop_id) { case PROP_CONFIG: cc_display_arrangement_set_config (obj, g_value_get_object (value)); break; case PROP_SELECTED_OUTPUT: cc_display_arrangement_set_selected_output (obj, g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void cc_display_arrangement_finalize (GObject *object) { CcDisplayArrangement *self = CC_DISPLAY_ARRANGEMENT (object); g_clear_object (&self->config); G_OBJECT_CLASS (cc_display_arrangement_parent_class)->finalize (object); } static void cc_display_arrangement_class_init (CcDisplayArrangementClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); gobject_class->finalize = cc_display_arrangement_finalize; gobject_class->get_property = cc_display_arrangement_get_property; gobject_class->set_property = cc_display_arrangement_set_property; widget_class->draw = cc_display_arrangement_draw; widget_class->button_press_event = cc_display_arrangement_button_press_event; widget_class->button_release_event = cc_display_arrangement_button_release_event; widget_class->motion_notify_event = cc_display_arrangement_motion_notify_event; props[PROP_CONFIG] = g_param_spec_object ("config", "Display Config", "The display configuration to work with", CC_TYPE_DISPLAY_CONFIG, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); props[PROP_SELECTED_OUTPUT] = g_param_spec_object ("selected-output", "Selected Output", "The output that is currently selected on the configuration", CC_TYPE_DISPLAY_MONITOR, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (gobject_class, PROP_LAST, props); g_signal_new ("updated", CC_TYPE_DISPLAY_ARRANGEMENT, G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); g_signal_new ("get-output-color", CC_TYPE_DISPLAY_ARRANGEMENT, G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_STRING, 1, G_TYPE_INT); } static void cc_display_arrangement_init (CcDisplayArrangement *self) { /* XXX: Do we need to listen to touch events here? */ gtk_widget_add_events (GTK_WIDGET (self), GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK); self->major_snap_distance = MAJOR_SNAP_DISTANCE; } CcDisplayArrangement* cc_display_arrangement_new (CcDisplayConfig *config) { return g_object_new (CC_TYPE_DISPLAY_ARRANGEMENT, "config", config, NULL); } CcDisplayConfig* cc_display_arrangement_get_config (CcDisplayArrangement *self) { return self->config; } void cc_display_arrangement_set_config (CcDisplayArrangement *self, CcDisplayConfig *config) { const gchar *signals[] = { "rotation", "mode", "primary", "active", "scale", "position-changed", "is-usable" }; GList *outputs, *l; guint i; if (self->config) { outputs = cc_display_config_get_monitors (self->config); for (l = outputs; l; l = l->next) { CcDisplayMonitor *output = l->data; g_signal_handlers_disconnect_by_data (output, self); } } g_clear_object (&self->config); self->drag_active = FALSE; /* Listen to all the signals */ if (config) { self->config = g_object_ref (config); outputs = cc_display_config_get_monitors (self->config); for (l = outputs; l; l = l->next) { CcDisplayMonitor *output = l->data; for (i = 0; i < G_N_ELEMENTS (signals); ++i) g_signal_connect_object (output, signals[i], G_CALLBACK (on_output_changed_cb), self, G_CONNECT_SWAPPED); } } cc_display_arrangement_set_selected_output (self, NULL); g_object_notify_by_pspec (G_OBJECT (self), props[PROP_CONFIG]); } CcDisplayMonitor* cc_display_arrangement_get_selected_output (CcDisplayArrangement *self) { return self->selected_output; } void cc_display_arrangement_set_selected_output (CcDisplayArrangement *self, CcDisplayMonitor *output) { g_return_if_fail (self->drag_active == FALSE); /* XXX: Could check that it actually belongs to the right config object. */ self->selected_output = output; gtk_widget_queue_draw (GTK_WIDGET (self)); g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SELECTED_OUTPUT]); } void cc_display_config_snap_output (CcDisplayConfig *config, CcDisplayMonitor *output) { SnapData snap_data; gint x, y, w, h; gdouble max_scale; if (!cc_display_monitor_is_useful (output)) return; if (cc_display_config_count_useful_monitors (config) <= 1) return; max_scale = cc_display_config_get_maximum_scaling (config); get_scaled_geometry (config, output, max_scale, &x, &y, &w, &h); snap_data.snapped = SNAP_DIR_NONE; snap_data.mon_x = x; snap_data.mon_y = y; snap_data.dist_x = 0; snap_data.dist_y = 0; cairo_matrix_init_identity (&snap_data.to_widget); snap_data.major_snap_distance = G_MAXUINT; find_best_snapping (config, output, &snap_data); cc_display_monitor_set_position (output, snap_data.mon_x, snap_data.mon_y); } cinnamon-control-center-6.4.1/panels/display/org.cinnamon.control-center.display.gschema.xml0000664000175000017500000000050514724311620031254 0ustar fabiofabio false no longer used - see org.cinnamon.muffin:experimental-features cinnamon-control-center-6.4.1/panels/display/cc-display-panel.c0000664000175000017500000012254714724311620023437 0ustar fabiofabio/* * Copyright (C) 2007, 2008 Red Hat, Inc. * Copyright (C) 2013 Intel, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include "cc-display-panel.h" #include #include #include #include #include #include #ifdef GDK_WINDOWING_WAYLAND #include #endif #include #include "cc-display-config-manager-dbus.h" #include "cc-display-config.h" #include "cc-display-arrangement.h" #include "cc-display-resources.h" #include "cc-display-settings.h" #include "cc-display-labeler.h" /* The minimum supported size for the panel * Note that WIDTH is assumed to be the larger size and we accept portrait * mode too effectively (in principle we should probably restrict the rotation * setting in that case). */ #define MINIMUM_WIDTH 740 #define MINIMUM_HEIGHT 530 #define PANEL_PADDING 32 #define SECTION_PADDING 32 #define HEADING_PADDING 12 #define WID(s) GTK_WIDGET (gtk_builder_get_object (self->builder, s)) typedef enum { CC_DISPLAY_CONFIG_JOIN, CC_DISPLAY_CONFIG_CLONE, CC_DISPLAY_CONFIG_INVALID_NONE, } CcDisplayConfigType; #define CC_DISPLAY_CONFIG_LAST_VALID CC_DISPLAY_CONFIG_CLONE struct _CcDisplayPanel { CcPanel parent_instance; CcDisplayConfigManager *manager; CcDisplayConfig *current_config; CcDisplayMonitor *current_output; GDBusProxy *cinnamon_proxy; gint rebuilding_counter; CcDisplayArrangement *arrangement; CcDisplaySettings *settings; guint focus_id; UpClient *up_client; gboolean lid_is_closed; guint sensor_watch_id; GDBusProxy *iio_sensor_proxy; gboolean has_accelerometer; GtkBuilder *builder; GtkWidget *apply_button; GtkWidget *defaults_button; GtkWidget *cancel_button; GtkListStore *output_selection_list; GdkRGBA *palette; gint n_outputs; GtkWidget *arrangement_frame; GtkWidget *arrangement_bin; GtkWidget *config_type_join; GtkWidget *config_type_mirror; GtkWidget *config_type_revealer; GtkWidget *display_settings_frame; GtkWidget *output_enabled_switch; GtkWidget *output_selection_combo; GtkWidget *primary_display_toggle; GtkWidget *stack_switcher; GCancellable *cancellable; GSettings *muffin_settings; CcDisplayLabeler *labeler; }; CC_PANEL_REGISTER (CcDisplayPanel, cc_display_panel) #ifdef GDK_WINDOWING_WAYLAND #define WAYLAND_SESSION() (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default())) #else #define WAYLAND_SESSION() (FALSE) #endif static void update_bottom_buttons (CcDisplayPanel *panel); static void apply_current_configuration (CcDisplayPanel *self); static void reset_current_config (CcDisplayPanel *panel); static void rebuild_ui (CcDisplayPanel *panel); static void regenerate_palette (CcDisplayPanel *panel, gint n_outputs); static void set_current_output (CcDisplayPanel *panel, CcDisplayMonitor *output, gboolean force); static gchar *get_color_string_for_output (CcDisplayPanel *panel, gint index); static gchar *get_output_color (GObject *source, gint index, CcDisplayPanel *self); static CcDisplayConfigType config_get_current_type (CcDisplayPanel *panel) { guint n_active_outputs; GList *outputs, *l; outputs = cc_display_config_get_ui_sorted_monitors (panel->current_config); n_active_outputs = 0; for (l = outputs; l; l = l->next) { CcDisplayMonitor *output = l->data; if (cc_display_monitor_is_useful (output)) n_active_outputs += 1; } if (n_active_outputs == 0) return CC_DISPLAY_CONFIG_INVALID_NONE; if (cc_display_config_is_cloning (panel->current_config)) return CC_DISPLAY_CONFIG_CLONE; return CC_DISPLAY_CONFIG_JOIN; } static CcDisplayConfigType cc_panel_get_selected_type (CcDisplayPanel *panel) { if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (panel->config_type_join))) return CC_DISPLAY_CONFIG_JOIN; else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (panel->config_type_mirror))) return CC_DISPLAY_CONFIG_CLONE; else g_assert_not_reached (); } static void config_ensure_of_type (CcDisplayPanel *panel, CcDisplayConfigType type) { CcDisplayConfigType current_type = config_get_current_type (panel); GList *outputs, *l; CcDisplayMonitor *current_primary = NULL; gdouble old_primary_scale = -1; /* Do not do anything if the current detected configuration type is * identitcal to what we expect. */ if (type == current_type) return; reset_current_config (panel); outputs = cc_display_config_get_ui_sorted_monitors (panel->current_config); for (l = outputs; l; l = l->next) { CcDisplayMonitor *output = l->data; if (cc_display_monitor_is_primary (output)) { current_primary = output; old_primary_scale = cc_display_monitor_get_scale (current_primary); break; } } switch (type) { case CC_DISPLAY_CONFIG_JOIN: g_debug ("Creating new join or single config"); /* Enable all usable outputs * Note that this might result in invalid configurations as we * we might not be able to drive all attached monitors. */ cc_display_config_set_cloning (panel->current_config, FALSE); if (g_list_length (outputs) == 1) { for (l = outputs; l; l = l->next) { CcDisplayMonitor *output = l->data; /* Select the current primary output as the active one */ if (cc_display_monitor_is_primary (output)) { cc_display_monitor_set_active (output, TRUE); cc_display_monitor_set_mode (output, cc_display_monitor_get_preferred_mode (output)); set_current_output (panel, output, FALSE); } else { cc_display_monitor_set_active (output, FALSE); cc_display_monitor_set_mode (output, cc_display_monitor_get_preferred_mode (output)); } } gtk_widget_set_sensitive (panel->output_enabled_switch, FALSE); } else { for (l = outputs; l; l = l->next) { CcDisplayMonitor *output = l->data; gdouble scale; CcDisplayMode *mode; mode = cc_display_monitor_get_preferred_mode (output); /* If the monitor was active, try using the current scale, otherwise * try picking the preferred scale. */ if (cc_display_monitor_is_active (output)) scale = cc_display_monitor_get_scale (output); else scale = cc_display_mode_get_preferred_scale (mode); /* If we cannot use the current/preferred scale, try to fall back to * the previously scale of the primary monitor instead. * This is not guaranteed to result in a valid configuration! */ if (!cc_display_config_is_scaled_mode_valid (panel->current_config, mode, scale)) { if (current_primary && cc_display_config_is_scaled_mode_valid (panel->current_config, mode, old_primary_scale)) scale = old_primary_scale; } cc_display_monitor_set_active (output, cc_display_monitor_is_usable (output)); cc_display_monitor_set_mode (output, mode); cc_display_monitor_set_scale (output, scale); } gtk_widget_set_sensitive (panel->output_enabled_switch, TRUE); } break; case CC_DISPLAY_CONFIG_CLONE: { g_debug ("Creating new clone config"); gdouble scale; GList *modes = cc_display_config_get_cloning_modes (panel->current_config); gint bw, bh; CcDisplayMode *best = NULL; /* Turn on cloning and select the best mode we can find by default */ cc_display_config_set_cloning (panel->current_config, TRUE); while (modes) { CcDisplayMode *mode = modes->data; gint w, h; cc_display_mode_get_resolution (mode, &w, &h); if (best == NULL || (bw*bh < w*h)) { best = mode; cc_display_mode_get_resolution (best, &bw, &bh); } modes = modes->next; } /* Take the preferred scale by default, */ scale = cc_display_mode_get_preferred_scale (best); /* but prefer the old primary scale if that is valid. */ if (current_primary && cc_display_config_is_scaled_mode_valid (panel->current_config, best, old_primary_scale)) scale = old_primary_scale; for (l = outputs; l; l = l->next) { CcDisplayMonitor *output = l->data; cc_display_monitor_set_mode (output, best); cc_display_monitor_set_scale (output, scale); } gtk_widget_set_sensitive (panel->output_enabled_switch, FALSE); } break; default: g_assert_not_reached (); } rebuild_ui (panel); } static void cc_panel_set_selected_type (CcDisplayPanel *panel, CcDisplayConfigType type) { switch (type) { case CC_DISPLAY_CONFIG_JOIN: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (panel->config_type_join), TRUE); break; case CC_DISPLAY_CONFIG_CLONE: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (panel->config_type_mirror), TRUE); break; default: g_assert_not_reached (); } config_ensure_of_type (panel, type); } static void hide_labels_dbus (CcDisplayPanel *self) { if (!self->cinnamon_proxy) return; g_dbus_proxy_call (self->cinnamon_proxy, "HideMonitorLabels", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); } static void show_labels_dbus (CcDisplayPanel *self) { GList *outputs, *l; GVariantBuilder builder; gint number = 0; if (!self->cinnamon_proxy || !self->current_config) return; outputs = cc_display_config_get_ui_sorted_monitors (self->current_config); if (!outputs) return; g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE); g_variant_builder_open (&builder, G_VARIANT_TYPE_ARRAY); gint color_index = 0; for (l = outputs, color_index = 0; l != NULL; l = l->next, color_index++) { CcDisplayMonitor *output = l->data; number = cc_display_monitor_get_ui_number (output); if (number == 0) continue; GVariant *var; g_autofree gchar *color_str = get_color_string_for_output (self, color_index); var = g_variant_new ("(ibss)", number, cc_display_config_is_cloning (self->current_config), cc_display_monitor_get_display_name (output), color_str); g_variant_builder_add (&builder, "{sv}", cc_display_monitor_get_connector_name (output), var); } g_variant_builder_close (&builder); if (number < 1) { g_variant_builder_clear (&builder); return; } g_dbus_proxy_call (self->cinnamon_proxy, "ShowMonitorLabels", g_variant_builder_end (&builder), G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); } static void hide_labels (CcDisplayPanel *self) { if (WAYLAND_SESSION ()) { hide_labels_dbus (self); } else { if (self->labeler) { cc_display_labeler_hide (self->labeler); } } } static void show_labels (CcDisplayPanel *self) { if (WAYLAND_SESSION ()) { show_labels_dbus (self); } else { if (self->labeler) { cc_display_labeler_hide (self->labeler); g_object_unref (self->labeler); } self->labeler = cc_display_labeler_new (self->current_config); g_signal_connect_object (self->labeler, "get-output-color", G_CALLBACK (get_output_color), self, 0); cc_display_labeler_show (self->labeler); } } static void widget_visible_changed (GtkWidget *widget, gpointer user_data) { CcDisplayPanel *self = CC_DISPLAY_PANEL (widget); if (gtk_widget_get_visible (widget) && self->current_config != NULL) { show_labels (self); } else { hide_labels (self); } } static void ensure_monitor_labels (CcDisplayPanel *self) { widget_visible_changed (GTK_WIDGET (self), self); } static void cc_display_panel_dispose (GObject *object) { CcDisplayPanel *self = CC_DISPLAY_PANEL (object); if (self->sensor_watch_id > 0) { g_bus_unwatch_name (self->sensor_watch_id); self->sensor_watch_id = 0; } g_clear_object (&self->iio_sensor_proxy); g_clear_object (&self->manager); g_clear_object (&self->current_config); g_clear_object (&self->up_client); g_clear_object (&self->cinnamon_proxy); g_clear_object (&self->muffin_settings); g_clear_object (&self->labeler); g_clear_pointer (&self->palette, g_free); g_clear_object (&self->output_selection_list); g_clear_object (&self->builder); g_signal_handlers_disconnect_by_func (self, widget_visible_changed, NULL); G_OBJECT_CLASS (cc_display_panel_parent_class)->dispose (object); } static void on_arrangement_selected_ouptut_changed_cb (CcDisplayPanel *panel) { set_current_output (panel, cc_display_arrangement_get_selected_output (panel->arrangement), FALSE); } static void on_monitor_settings_updated_cb (CcDisplayPanel *panel, CcDisplayMonitor *monitor, CcDisplaySettings *settings) { if (monitor) cc_display_config_snap_output (panel->current_config, monitor); update_bottom_buttons (panel); } static void on_config_type_toggled_cb (CcDisplayPanel *panel, GtkRadioButton *btn) { CcDisplayConfigType type; if (panel->rebuilding_counter > 0) return; if (!panel->current_config) return; if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (btn))) return; type = cc_panel_get_selected_type (panel); config_ensure_of_type (panel, type); } static void on_output_enabled_active_changed_cb (CcDisplayPanel *panel) { gboolean active; if (!panel->current_output) return; active = gtk_switch_get_active (GTK_SWITCH (panel->output_enabled_switch)); if (cc_display_monitor_is_active (panel->current_output) == active) return; cc_display_monitor_set_active (panel->current_output, active); /* Prevent the invalid configuration of disabling the last monitor * by switching on a different one. */ if (config_get_current_type (panel) == CC_DISPLAY_CONFIG_INVALID_NONE) { GList *outputs, *l; outputs = cc_display_config_get_ui_sorted_monitors (panel->current_config); for (l = outputs; l; l = l->next) { CcDisplayMonitor *output = CC_DISPLAY_MONITOR (l->data); if (output == panel->current_output) continue; if (!cc_display_monitor_is_usable (output)) continue; cc_display_monitor_set_active (output, TRUE); cc_display_monitor_set_primary (output, TRUE); break; } } /* Changing the active state requires a UI rebuild. */ rebuild_ui (panel); } static void on_output_selection_combo_changed_cb (CcDisplayPanel *panel) { GtkTreeIter iter; g_autoptr(CcDisplayMonitor) output = NULL; if (!panel->current_config) return; if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (panel->output_selection_combo), &iter)) return; gtk_tree_model_get (GTK_TREE_MODEL (panel->output_selection_list), &iter, 1, &output, -1); set_current_output (panel, output, FALSE); } static void primary_display_toggle_toggled_cb (GtkToggleButton *button, CcDisplayPanel *panel) { if (panel->rebuilding_counter > 0) return; if (cc_display_monitor_is_primary (panel->current_output)) { return; } cc_display_monitor_set_primary (panel->current_output, TRUE); // rebuild_ui (panel); update_bottom_buttons (panel); gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE); } static void cc_display_panel_constructed (GObject *object) { G_OBJECT_CLASS (cc_display_panel_parent_class)->constructed (object); } static void cc_display_panel_class_init (CcDisplayPanelClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->constructed = cc_display_panel_constructed; object_class->dispose = cc_display_panel_dispose; } static void set_current_output (CcDisplayPanel *panel, CcDisplayMonitor *output, gboolean force) { GtkTreeIter iter; gboolean changed; GList *outputs; /* Note, this function is also called if the internal UI needs updating after a rebuild. */ changed = (output != panel->current_output); if (!changed && !force) return; panel->rebuilding_counter++; panel->current_output = output; outputs = cc_display_config_get_ui_sorted_monitors (panel->current_config); if (panel->current_output) { gtk_switch_set_active (GTK_SWITCH (panel->output_enabled_switch), cc_display_monitor_is_active (panel->current_output)); gtk_widget_set_sensitive (GTK_WIDGET (panel->output_enabled_switch), cc_display_monitor_is_usable (panel->current_output) && config_get_current_type (panel) == CC_DISPLAY_CONFIG_JOIN && g_list_length (outputs) > 1); gtk_widget_set_sensitive (GTK_WIDGET (panel->primary_display_toggle), !cc_display_monitor_is_primary (panel->current_output) && cc_display_monitor_is_active (panel->current_output)); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (panel->primary_display_toggle), cc_display_monitor_is_primary (panel->current_output)); } else { gtk_switch_set_active (GTK_SWITCH (panel->output_enabled_switch), FALSE); gtk_widget_set_sensitive (GTK_WIDGET (panel->output_enabled_switch), FALSE); gtk_widget_set_sensitive (GTK_WIDGET (panel->primary_display_toggle), FALSE); } gtk_tree_model_get_iter_first (GTK_TREE_MODEL (panel->output_selection_list), &iter); while (gtk_list_store_iter_is_valid (panel->output_selection_list, &iter)) { g_autoptr(CcDisplayMonitor) o = NULL; gtk_tree_model_get (GTK_TREE_MODEL (panel->output_selection_list), &iter, 1, &o, -1); if (o == panel->current_output) { gtk_combo_box_set_active_iter (GTK_COMBO_BOX (panel->output_selection_combo), &iter); break; } gtk_tree_model_iter_next (GTK_TREE_MODEL (panel->output_selection_list), &iter); } if (changed) { cc_display_settings_set_selected_output (panel->settings, panel->current_output); cc_display_arrangement_set_selected_output (panel->arrangement, panel->current_output); } panel->rebuilding_counter--; } static void rebuild_ui (CcDisplayPanel *panel) { guint n_outputs, n_active_outputs, n_usable_outputs; GList *outputs, *l; CcDisplayConfigType type; gboolean cloned = FALSE; gint index = 0; panel->rebuilding_counter++; gtk_list_store_clear (panel->output_selection_list); if (!panel->current_config) { panel->rebuilding_counter--; return; } cloned = config_get_current_type (panel); n_active_outputs = 0; n_usable_outputs = 0; outputs = cc_display_config_get_ui_sorted_monitors (panel->current_config); regenerate_palette (panel, g_list_length (outputs)); ensure_monitor_labels (panel); for (l = outputs, index = 0; l; l = l->next, index++) { GtkTreeIter iter; CcDisplayMonitor *output = l->data; GdkPixbuf *pixbuf; GdkRGBA color; guint32 pixel = 0; const gchar *label; pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 20, 20); gchar *color_string = get_color_string_for_output (panel, index); gdk_rgba_parse (&color, color_string); g_free (color_string); pixel = pixel + ((int) (color.red * 255) << 24); pixel = pixel + ((int) (color.green * 255) << 16); pixel = pixel + ((int) (color.blue * 255) << 8); pixel = pixel + ((int) (color.alpha * 255)); if (cloned) { label = _("Mirrored Displays"); } else { label = cc_display_monitor_get_ui_number_name (output); } gdk_pixbuf_fill (pixbuf, pixel); gtk_list_store_append (panel->output_selection_list, &iter); gtk_list_store_set (panel->output_selection_list, &iter, 0, label, 1, output, 2, pixbuf, -1); g_object_unref (pixbuf); if (!cc_display_monitor_is_usable (output)) continue; n_usable_outputs += 1; if (cc_display_monitor_is_active (output)) { /* Ensure that an output is selected; note that this doesn't ensure * the selected output is any useful (i.e. when switching types). */ if (!panel->current_output || !cc_display_monitor_is_active (panel->current_output)) set_current_output (panel, output, FALSE); n_active_outputs++; } } /* Sync the rebuild lists/buttons */ set_current_output (panel, panel->current_output, TRUE); n_outputs = g_list_length (outputs); type = config_get_current_type (panel); if (n_outputs == 2 && n_usable_outputs == 2 && n_active_outputs == 2) { /* We only show the top chooser with two monitors that are * both usable (i.e. two monitors incl. internal and lid not closed). * In this case, the arrangement widget is shown if we are in JOIN mode. */ if (type > CC_DISPLAY_CONFIG_LAST_VALID) type = CC_DISPLAY_CONFIG_JOIN; gtk_revealer_set_reveal_child (GTK_REVEALER (panel->config_type_revealer), TRUE); } else { /* We have 1 monitor, or 2+ including active and inactive. In this case there is no chooser, */ gtk_revealer_set_reveal_child (GTK_REVEALER (panel->config_type_revealer), FALSE); /* Mirror is also invalid as it cannot be configured using this UI. */ if (type == CC_DISPLAY_CONFIG_CLONE || type > CC_DISPLAY_CONFIG_LAST_VALID) type = CC_DISPLAY_CONFIG_JOIN; } cc_panel_set_selected_type (panel, type); gtk_widget_set_sensitive (GTK_WIDGET (panel->output_selection_combo), n_outputs > 1 && !cloned); panel->rebuilding_counter--; update_bottom_buttons (panel); } static void reset_current_config (CcDisplayPanel *panel) { CcDisplayConfig *current; CcDisplayConfig *old; GList *outputs, *l; g_debug ("Resetting current config!"); /* We need to hold on to the config until all display references are dropped. */ old = panel->current_config; panel->current_output = NULL; current = cc_display_config_manager_get_current (panel->manager); // Cinnamon could be restarting if (current == NULL) return; cc_display_config_set_minimum_size (current, MINIMUM_WIDTH, MINIMUM_HEIGHT); panel->current_config = current; gtk_list_store_clear (panel->output_selection_list); if (panel->current_config) { outputs = cc_display_config_get_ui_sorted_monitors (panel->current_config); for (l = outputs; l; l = l->next) { CcDisplayMonitor *output = l->data; /* Mark any builtin monitor as unusable if the lid is closed. */ if (cc_display_monitor_is_builtin (output) && panel->lid_is_closed) cc_display_monitor_set_usable (output, FALSE); } } cc_display_arrangement_set_config (panel->arrangement, panel->current_config); cc_display_settings_set_config (panel->settings, panel->current_config); set_current_output (panel, NULL, FALSE); g_clear_object (&old); update_bottom_buttons (panel); } static void on_screen_changed (CcDisplayPanel *panel) { if (!panel->manager) return; reset_current_config (panel); rebuild_ui (panel); if (!panel->current_config) return; } static void update_bottom_buttons (CcDisplayPanel *panel) { gboolean config_equal; g_autoptr(CcDisplayConfig) applied_config = NULL; if (!panel->current_config) { return; } applied_config = cc_display_config_manager_get_current (panel->manager); config_equal = cc_display_config_equal (panel->current_config, applied_config); if (config_equal) { gtk_widget_set_sensitive (panel->apply_button, FALSE); gtk_widget_set_sensitive (panel->cancel_button, FALSE); } else { gtk_widget_set_sensitive (panel->apply_button, cc_display_config_is_applicable (panel->current_config)); gtk_widget_set_sensitive (panel->cancel_button, TRUE); } } static void apply_current_configuration (CcDisplayPanel *self) { g_autoptr(GError) error = NULL; cc_display_config_apply (self->current_config, &error); /* re-read the configuration */ on_screen_changed (self); if (error) g_warning ("Error applying configuration: %s", error->message); } static void cc_display_panel_up_client_changed (UpClient *client, GParamSpec *pspec, CcDisplayPanel *self) { gboolean lid_is_closed; lid_is_closed = up_client_get_lid_is_closed (client); if (lid_is_closed != self->lid_is_closed) { self->lid_is_closed = lid_is_closed; on_screen_changed (self); } } static void update_has_accel (CcDisplayPanel *self) { g_autoptr(GVariant) v = NULL; if (self->iio_sensor_proxy == NULL) { g_debug ("Has no accelerometer"); self->has_accelerometer = FALSE; cc_display_settings_set_has_accelerometer (self->settings, self->has_accelerometer); return; } v = g_dbus_proxy_get_cached_property (self->iio_sensor_proxy, "HasAccelerometer"); if (v) { self->has_accelerometer = g_variant_get_boolean (v); } else { self->has_accelerometer = FALSE; } cc_display_settings_set_has_accelerometer (self->settings, self->has_accelerometer); g_debug ("Has %saccelerometer", self->has_accelerometer ? "" : "no "); } static void sensor_proxy_properties_changed_cb (GDBusProxy *proxy, GVariant *changed_properties, GStrv invalidated_properties, CcDisplayPanel *self) { GVariantDict dict; g_variant_dict_init (&dict, changed_properties); if (g_variant_dict_contains (&dict, "HasAccelerometer")) update_has_accel (self); } static void sensor_proxy_appeared_cb (GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data) { CcDisplayPanel *self = user_data; g_debug ("SensorProxy appeared"); self->iio_sensor_proxy = g_dbus_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE, NULL, "net.hadess.SensorProxy", "/net/hadess/SensorProxy", "net.hadess.SensorProxy", NULL, NULL); g_return_if_fail (self->iio_sensor_proxy); g_signal_connect (self->iio_sensor_proxy, "g-properties-changed", G_CALLBACK (sensor_proxy_properties_changed_cb), self); update_has_accel (self); } static void sensor_proxy_vanished_cb (GDBusConnection *connection, const gchar *name, gpointer user_data) { CcDisplayPanel *self = user_data; g_debug ("SensorProxy vanished"); g_clear_object (&self->iio_sensor_proxy); update_has_accel (self); } static void cinnamon_proxy_ready (GObject *source_object, GAsyncResult *res, gpointer user_data) { CcDisplayPanel *self = CC_DISPLAY_PANEL (user_data); GError *error = NULL; self->cinnamon_proxy = g_dbus_proxy_new_finish (res, &error); if (self->cinnamon_proxy == NULL) { g_critical ("Can't connect to Cinnamon, monitor labeler will be unavailable: %s", error->message); g_clear_error (&error); } } static void session_bus_ready (GObject *source, GAsyncResult *res, CcDisplayPanel *self) { GDBusConnection *bus; g_autoptr(GError) error = NULL; bus = g_bus_get_finish (res, &error); if (!bus) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { g_warning ("Failed to get session bus: %s", error->message); } return; } self->manager = cc_display_config_manager_dbus_new (); g_signal_connect_object (self->manager, "changed", G_CALLBACK (on_screen_changed), self, G_CONNECT_SWAPPED); if (WAYLAND_SESSION ()) { g_dbus_proxy_new (bus, G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START | G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, NULL, "org.Cinnamon", "/org/Cinnamon", "org.Cinnamon", NULL, (GAsyncReadyCallback) cinnamon_proxy_ready, self); } } static void experimental_features_changed (CcDisplayPanel *self) { on_monitor_settings_updated_cb (self, self->current_output, self->settings); } static void apply_button_clicked_cb (GtkWidget *widget, gpointer user_data) { apply_current_configuration (CC_DISPLAY_PANEL (user_data)); } static void cancel_button_clicked_cb (GtkWidget *widget, gpointer user_data) { on_screen_changed (CC_DISPLAY_PANEL (user_data)); } static void config_file_deleted (GObject *xml, GAsyncResult *res, gpointer user_data) { GError *error = NULL; if (!g_file_delete_finish (G_FILE (xml), res, &error)) { if (error != NULL) { g_warning ("Problem deleting ~/.config/cinnamon-monitors.xml: %s", error->message); g_clear_error (&error); } return; } g_spawn_command_line_async ("cinnamon-dbus-command RestartCinnamon 0", NULL); } static gboolean reset_to_defaults (gpointer data) { CcDisplayPanel *panel = CC_DISPLAY_PANEL (data); gchar *path = g_build_filename (g_get_user_config_dir (), "cinnamon-monitors.xml", NULL); GFile *xml = g_file_new_for_path (path); g_free (path); g_file_delete_async (xml, G_PRIORITY_DEFAULT, NULL, (GAsyncReadyCallback) (config_file_deleted), panel); g_object_unref (xml); return G_SOURCE_REMOVE; } static void defaults_button_clicked_cb (GtkWidget *widget, gpointer user_data) { GtkWidget *dialog_w, *w; GtkBox *box; GtkDialog *dialog; gint response; dialog_w = gtk_dialog_new (); dialog = GTK_DIALOG (dialog_w); gtk_window_set_transient_for (GTK_WINDOW (dialog_w), GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (user_data)))); gtk_window_set_default_size (GTK_WINDOW (dialog_w), 300, -1); gtk_window_set_title (GTK_WINDOW (dialog_w), _("Confirm reset to defaults")); gtk_dialog_add_buttons(dialog, _("Cancel"), GTK_RESPONSE_NO, _("Continue"), GTK_RESPONSE_YES, NULL); gtk_dialog_set_default_response(dialog, GTK_RESPONSE_NO); w = gtk_dialog_get_widget_for_response(dialog, GTK_RESPONSE_YES); gtk_style_context_add_class (gtk_widget_get_style_context (w), GTK_STYLE_CLASS_DESTRUCTIVE_ACTION); box = GTK_BOX (gtk_dialog_get_content_area (dialog)); gtk_container_set_border_width (GTK_CONTAINER (box), 15); gtk_box_set_spacing (box, 6); w = gtk_image_new_from_icon_name ("dialog-warning", GTK_ICON_SIZE_DIALOG); gtk_box_pack_start (box, w, FALSE, FALSE, 6); w = gtk_label_new (_("This will remove all existing display configurations and reset the current layout.")); gtk_box_pack_start (box, w, FALSE, FALSE, 0); gtk_widget_show_all (dialog_w); response = gtk_dialog_run (dialog); gtk_widget_destroy (dialog_w); if (response == GTK_RESPONSE_YES) { g_timeout_add (500, (GSourceFunc) reset_to_defaults, user_data); } } static void regenerate_palette (CcDisplayPanel *panel, gint n_outputs) { /* The idea is that we go around an hue color wheel. We want to start * at red, go around to green/etc. and stop at blue. * */ double start_hue; double end_hue; int i; g_clear_pointer (&panel->palette, g_free); panel->palette = g_new (GdkRGBA, n_outputs); start_hue = 0.0; /* red */ end_hue = 2.0/3; /* blue */ for (i = 0; i < n_outputs; i++) { double h, s, v; double r, g, b; h = start_hue + (end_hue - start_hue) / n_outputs * i; s = 0.6; v = 1.0; gtk_hsv_to_rgb (h, s, v, &r, &g, &b); panel->palette[i].red = r; panel->palette[i].green = g; panel->palette[i].blue = b; panel->palette[i].alpha = 1.0; } panel->n_outputs = n_outputs; } static gchar * get_color_string_for_output (CcDisplayPanel *panel, gint index) { if (index < 0 || index > panel->n_outputs - 1) { return g_strdup ("white"); } return gdk_rgba_to_string (&panel->palette[index]); } static gchar * get_output_color (GObject *source, gint index, CcDisplayPanel *self) { return get_color_string_for_output (self, index); } static void cc_display_panel_init (CcDisplayPanel *self) { g_autoptr(GtkCssProvider) provider = NULL; GtkCellRenderer *renderer; g_resources_register (cc_display_get_resource ()); self->builder = gtk_builder_new_from_resource ("/org/cinnamon/control-center/display/cc-display-panel.ui"); gtk_container_add (GTK_CONTAINER (self), WID ("toplevel")); self->arrangement_frame = WID ("arrangement_frame"); self->arrangement_bin = WID ("arrangement_bin"); self->config_type_revealer = WID ("config_type_revealer"); self->config_type_join = WID ("config_type_join"); self->config_type_mirror = WID ("config_type_mirror"); self->display_settings_frame = WID ("display_settings_frame"); self->output_enabled_switch = WID ("output_enabled_switch"); self->output_selection_combo = WID ("output_selection_combo"); self->primary_display_toggle = WID ("primary_display_toggle"); self->stack_switcher = WID ("stack_switcher"); self->apply_button = WID ("apply_button"); self->cancel_button = WID ("cancel_button"); self->defaults_button = WID ("defaults_button"); gtk_builder_add_callback_symbol (self->builder, "on_config_type_toggled_cb", G_CALLBACK (on_config_type_toggled_cb)); gtk_builder_add_callback_symbol (self->builder, "on_output_enabled_active_changed_cb", G_CALLBACK (on_output_enabled_active_changed_cb)); gtk_builder_add_callback_symbol (self->builder, "on_output_selection_combo_changed_cb", G_CALLBACK (on_output_selection_combo_changed_cb)); gtk_builder_add_callback_symbol (self->builder, "primary_display_toggle_toggled_cb", G_CALLBACK (primary_display_toggle_toggled_cb)); gtk_builder_add_callback_symbol (self->builder, "apply_button_clicked_cb", G_CALLBACK (apply_button_clicked_cb)); gtk_builder_add_callback_symbol (self->builder, "cancel_button_clicked_cb", G_CALLBACK (cancel_button_clicked_cb)); gtk_builder_add_callback_symbol (self->builder, "defaults_button_clicked_cb", G_CALLBACK (defaults_button_clicked_cb)); gtk_builder_connect_signals (self->builder, self); self->muffin_settings = g_settings_new ("org.cinnamon.muffin"); g_signal_connect_swapped (self->muffin_settings, "changed::experimental-features", G_CALLBACK (experimental_features_changed), self); self->arrangement = cc_display_arrangement_new (NULL); gtk_widget_show (GTK_WIDGET (self->arrangement)); gtk_widget_set_size_request (GTK_WIDGET (self->arrangement), 400, 175); gtk_container_add (GTK_CONTAINER (self->arrangement_bin), GTK_WIDGET (self->arrangement)); g_signal_connect_object (self->arrangement, "updated", G_CALLBACK (update_bottom_buttons), self, G_CONNECT_SWAPPED); g_signal_connect_object (self->arrangement, "notify::selected-output", G_CALLBACK (on_arrangement_selected_ouptut_changed_cb), self, G_CONNECT_SWAPPED); g_signal_connect_object (self->arrangement, "get-output-color", G_CALLBACK (get_output_color), self, 0); self->settings = cc_display_settings_new (); gtk_widget_show (GTK_WIDGET (self->settings)); gtk_container_add (GTK_CONTAINER (self->display_settings_frame), GTK_WIDGET (self->settings)); g_signal_connect_object (self->settings, "updated", G_CALLBACK (on_monitor_settings_updated_cb), self, G_CONNECT_SWAPPED); self->output_selection_list = gtk_list_store_new (3, G_TYPE_STRING, CC_TYPE_DISPLAY_MONITOR, GDK_TYPE_PIXBUF); gtk_combo_box_set_model (GTK_COMBO_BOX (self->output_selection_combo), GTK_TREE_MODEL (self->output_selection_list)); gtk_cell_layout_clear (GTK_CELL_LAYOUT (self->output_selection_combo)); renderer = gtk_cell_renderer_pixbuf_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self->output_selection_combo), renderer, FALSE); gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (self->output_selection_combo), renderer, "pixbuf", 2); gtk_cell_renderer_set_visible (renderer, TRUE); renderer = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self->output_selection_combo), renderer, TRUE); gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (self->output_selection_combo), renderer, "text", 0); gtk_cell_renderer_set_visible (renderer, TRUE); g_object_set (renderer, "xpad", 6, NULL); self->up_client = up_client_new (); if (up_client_get_lid_is_present (self->up_client)) { g_signal_connect (self->up_client, "notify::lid-is-closed", G_CALLBACK (cc_display_panel_up_client_changed), self); cc_display_panel_up_client_changed (self->up_client, NULL, self); } else g_clear_object (&self->up_client); self->cancellable = g_cancellable_new (); g_bus_get (G_BUS_TYPE_SESSION, self->cancellable, (GAsyncReadyCallback) session_bus_ready, self); self->sensor_watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM, "net.hadess.SensorProxy", G_BUS_NAME_WATCHER_FLAGS_NONE, sensor_proxy_appeared_cb, sensor_proxy_vanished_cb, self, NULL); provider = gtk_css_provider_new (); gtk_css_provider_load_from_resource (provider, "/org/cinnamon/control-center/display/display-arrangement.css"); gtk_style_context_add_provider_for_screen (gdk_screen_get_default (), GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); g_signal_connect (GTK_WIDGET (self), "show", G_CALLBACK (widget_visible_changed), NULL); g_signal_connect (GTK_WIDGET (self), "hide", G_CALLBACK (widget_visible_changed), NULL); } void cc_display_panel_register (GIOModule *module) { textdomain (GETTEXT_PACKAGE); bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); cc_display_panel_register_type (G_TYPE_MODULE (module)); g_io_extension_point_implement (CC_SHELL_PANEL_EXTENSION_POINT, CC_TYPE_DISPLAY_PANEL, "display", 0); } cinnamon-control-center-6.4.1/panels/display/cc-display-labeler.h0000664000175000017500000000272414724311620023745 0ustar fabiofabio/* gnome-rr-labeler.h - Utility to label monitors to identify them * while they are being configured. * * Copyright 2008, Novell, Inc. * * This file is part of the Gnome Library. * * The Gnome Library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * The Gnome 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with the Gnome Library; see the file COPYING.LIB. If not, * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * Author: Federico Mena-Quintero */ #pragma once // #define GNOME_DESKTOP_USE_UNSTABLE_API #include "cc-display-config.h" G_BEGIN_DECLS #define CC_TYPE_DISPLAY_LABELER (cc_display_labeler_get_type ()) G_DECLARE_FINAL_TYPE (CcDisplayLabeler, cc_display_labeler, CC, DISPLAY_LABELER, GObject) CcDisplayLabeler *cc_display_labeler_new (CcDisplayConfig *config); void cc_display_labeler_show (CcDisplayLabeler *labeler); void cc_display_labeler_hide (CcDisplayLabeler *labeler); G_END_DECLScinnamon-control-center-6.4.1/panels/display/cc-display-panel.ui0000664000175000017500000005060614724311620023626 0ustar fabiofabio True False 12 12 12 12 4 4 video-joined-displays-symbolic 2 True False 12 12 12 12 4 4 view-mirror-symbolic 2 550 True False vertical True False crossfade 500 True False never True False none True False True vertical 6 True False 0 none True False vertical True False 0 none True False False True 0 Display Arrangement False True 0 True False 20 20 0 none True False vertical 6 True False 6 True False True False True 0 Set as Primary True True True False True 1 True True end center False True 2 False True 0 True False 0 none False True 1 Display Configuration False True 1 True False 20 20 True False vertical 6 True False False True 0 True False center Join Displays True True False image-join-displays True True False True True 0 Mirror True True False image-mirror True False config_type_join True True 1 False True 1 False True 4 displays Displays False True 0 True False 6 10 start Reset to Defaults True True True True True 0 Cancel changes True True True True True end 1 True Apply True True True True True end 2 True False True end 1 True False stack cinnamon-control-center-6.4.1/panels/display/cc-display-labeler.c0000664000175000017500000003242314724311620023737 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * cc-rr-labeler.c - Utility to label monitors to identify them * while they are being configured. * * Copyright 2008, Novell, Inc. * * This file is part of the Gnome Library. * * The Gnome Library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * The Gnome 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with the Gnome Library; see the file COPYING.LIB. If not, * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * Author: Federico Mena-Quintero */ #include #include #include #include #include #include #include #include #include "cc-display-labeler.h" typedef struct { CcDisplayConfig *config; int num_outputs; GtkWidget **windows; GdkScreen *screen; Atom workarea_atom; } CcDisplayLabelerPrivate; struct _CcDisplayLabeler { GObject parent; CcDisplayLabelerPrivate *priv; }; G_DEFINE_TYPE_WITH_PRIVATE (CcDisplayLabeler, cc_display_labeler, G_TYPE_OBJECT) enum { PROP_0, PROP_CONFIG, PROP_LAST }; static void cc_display_labeler_finalize (GObject *object); static GdkFilterReturn screen_xevent_filter (GdkXEvent *xevent, GdkEvent *event, CcDisplayLabeler *labeler) { XEvent *xev; xev = (XEvent *) xevent; if (xev->type == PropertyNotify && xev->xproperty.atom == labeler->priv->workarea_atom) { /* update label positions */ if (labeler->priv->windows != NULL) { cc_display_labeler_hide (labeler); cc_display_labeler_show (labeler); } } return GDK_FILTER_CONTINUE; } static void cc_display_labeler_init (CcDisplayLabeler *labeler) { GdkWindow *gdkwindow; labeler->priv = cc_display_labeler_get_instance_private (labeler); labeler->priv->workarea_atom = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "_NET_WORKAREA", True); labeler->priv->screen = gdk_screen_get_default (); gdkwindow = gdk_screen_get_root_window (labeler->priv->screen); gdk_window_add_filter (gdkwindow, (GdkFilterFunc) screen_xevent_filter, labeler); gdk_window_set_events (gdkwindow, gdk_window_get_events (gdkwindow) | GDK_PROPERTY_CHANGE_MASK); } static void cc_display_labeler_set_property (GObject *gobject, guint property_id, const GValue *value, GParamSpec *param_spec) { CcDisplayLabeler *self = CC_DISPLAY_LABELER (gobject); switch (property_id) { case PROP_CONFIG: self->priv->config = CC_DISPLAY_CONFIG (g_value_dup_object (value)); return; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, param_spec); } } static void cc_display_labeler_class_init (CcDisplayLabelerClass *klass) { GObjectClass *object_class; object_class = (GObjectClass *) klass; object_class->set_property = cc_display_labeler_set_property; object_class->finalize = cc_display_labeler_finalize; g_object_class_install_property (object_class, PROP_CONFIG, g_param_spec_object ("config", "Configuration", "RandR configuration to label", CC_TYPE_DISPLAY_CONFIG, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); g_signal_new ("get-output-color", CC_TYPE_DISPLAY_LABELER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_STRING, 1, G_TYPE_INT); } static void cc_display_labeler_finalize (GObject *object) { CcDisplayLabeler *labeler; GdkWindow *gdkwindow; labeler = CC_DISPLAY_LABELER (object); gdkwindow = gdk_screen_get_root_window (labeler->priv->screen); gdk_window_remove_filter (gdkwindow, (GdkFilterFunc) screen_xevent_filter, labeler); if (labeler->priv->config != NULL) { g_object_unref (labeler->priv->config); } if (labeler->priv->windows != NULL) { cc_display_labeler_hide (labeler); g_free (labeler->priv->windows); } G_OBJECT_CLASS (cc_display_labeler_parent_class)->finalize (object); } static int count_outputs (CcDisplayConfig *config) { int i; GList *outputs = cc_display_config_get_ui_sorted_monitors (config); i = g_list_length (outputs); return i; } static void rounded_rectangle (cairo_t *cr, gint x, gint y, gint width, gint height, gint x_radius, gint y_radius) { gint x1, x2; gint y1, y2; gint xr1, xr2; gint yr1, yr2; x1 = x; x2 = x1 + width; y1 = y; y2 = y1 + height; x_radius = MIN (x_radius, width / 2.0); y_radius = MIN (y_radius, width / 2.0); xr1 = x_radius; xr2 = x_radius / 2.0; yr1 = y_radius; yr2 = y_radius / 2.0; cairo_move_to (cr, x1 + xr1, y1); cairo_line_to (cr, x2 - xr1, y1); cairo_curve_to (cr, x2 - xr2, y1, x2, y1 + yr2, x2, y1 + yr1); cairo_line_to (cr, x2, y2 - yr1); cairo_curve_to (cr, x2, y2 - yr2, x2 - xr2, y2, x2 - xr1, y2); cairo_line_to (cr, x1 + xr1, y2); cairo_curve_to (cr, x1 + xr2, y2, x1, y2 - yr2, x1, y2 - yr1); cairo_line_to (cr, x1, y1 + yr1); cairo_curve_to (cr, x1, y1 + yr2, x1 + xr2, y1, x1 + xr1, y1); cairo_close_path (cr); } #define LABEL_WINDOW_EDGE_THICKNESS 1 #define LABEL_WINDOW_PADDING 12 #define LABEL_CORNER_RADIUS 0 #define LABEL_WINDOW_MARGIN 5 static void label_draw_background_and_frame (GtkWidget *widget, cairo_t *cr) { GdkRGBA rgba; GtkAllocation allocation; gchar *rgba_str; rgba_str = g_object_get_data (G_OBJECT (widget), "rgba"); gtk_widget_get_allocation (widget, &allocation); cairo_save (cr); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); /* edge outline */ cairo_set_source_rgba (cr, 0, 0, 0, 1.0); rounded_rectangle (cr, LABEL_WINDOW_EDGE_THICKNESS / 2.0, LABEL_WINDOW_EDGE_THICKNESS / 2.0, allocation.width - LABEL_WINDOW_EDGE_THICKNESS, allocation.height - LABEL_WINDOW_EDGE_THICKNESS, LABEL_CORNER_RADIUS, LABEL_CORNER_RADIUS); cairo_set_line_width (cr, LABEL_WINDOW_EDGE_THICKNESS); cairo_stroke (cr); /* fill */ gdk_rgba_parse (&rgba, rgba_str); rgba.alpha = 0.90; gdk_cairo_set_source_rgba (cr, &rgba); rounded_rectangle (cr, LABEL_WINDOW_EDGE_THICKNESS, LABEL_WINDOW_EDGE_THICKNESS, allocation.width - LABEL_WINDOW_EDGE_THICKNESS * 2, allocation.height - LABEL_WINDOW_EDGE_THICKNESS * 2, LABEL_CORNER_RADIUS - LABEL_WINDOW_EDGE_THICKNESS / 2.0, LABEL_CORNER_RADIUS - LABEL_WINDOW_EDGE_THICKNESS / 2.0); cairo_fill (cr); cairo_restore (cr); } static gboolean label_window_draw_event_cb (GtkWidget *widget, cairo_t *cr, gpointer data) { /* clear any content */ cairo_save (cr); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_rgba (cr, 0, 0, 0, 0); cairo_paint (cr); cairo_restore (cr); gtk_widget_shape_combine_region (widget, NULL); label_draw_background_and_frame (widget, cr); return FALSE; } static void position_window (CcDisplayLabeler *labeler, CcDisplayMonitor *output, GtkWidget *window) { GdkDisplay *display; GdkRectangle workarea; int i; display = gdk_display_get_default (); for (i = 0; i < gdk_display_get_n_monitors (display); i++) { GdkMonitor *monitor = gdk_display_get_monitor (display, i); if (g_strcmp0 (gdk_monitor_get_model (monitor), cc_display_monitor_get_connector_name (output)) == 0) { gdk_monitor_get_workarea (monitor, &workarea); gtk_window_move (GTK_WINDOW (window), workarea.x + LABEL_WINDOW_MARGIN, workarea.y + LABEL_WINDOW_MARGIN); break; } } } static void label_window_realize_cb (GtkWidget *widget) { cairo_region_t *region; /* make the whole window ignore events */ region = cairo_region_create (); gtk_widget_input_shape_combine_region (widget, region); cairo_region_destroy (region); gtk_widget_shape_combine_region (widget, NULL); } static void label_window_composited_changed_cb (GtkWidget *widget, CcDisplayLabeler *labeler) { if (gtk_widget_get_realized (widget)) gtk_widget_shape_combine_region (widget, NULL); } static GtkWidget * create_label_window (CcDisplayLabeler *labeler, CcDisplayMonitor *output, gchar *rgba_str, gint num) { GtkWidget *window; GtkWidget *widget; char *str; const char *display_name, *output_name; GdkRGBA black = { 0, 0, 0, 1.0 }; int x, y; GdkScreen *screen; GdkVisual *visual; window = gtk_window_new (GTK_WINDOW_POPUP); gtk_window_set_resizable (GTK_WINDOW (window), FALSE); gtk_widget_set_app_paintable (window, TRUE); screen = gtk_widget_get_screen (window); visual = gdk_screen_get_rgba_visual (screen); if (visual != NULL) gtk_widget_set_visual (window, visual); gtk_container_set_border_width (GTK_CONTAINER (window), LABEL_WINDOW_PADDING + LABEL_WINDOW_EDGE_THICKNESS); /* This is semi-dangerous. The color is part of the labeler->palette * array. Note that in cc_display_labeler_finalize(), we are careful to * free the palette only after we free the windows. */ g_object_set_data_full (G_OBJECT (window), "rgba", rgba_str, (GDestroyNotify) g_free); g_signal_connect (window, "draw", G_CALLBACK (label_window_draw_event_cb), labeler); g_signal_connect (window, "realize", G_CALLBACK (label_window_realize_cb), labeler); g_signal_connect (window, "composited-changed", G_CALLBACK (label_window_composited_changed_cb), labeler); if (cc_display_config_is_cloning (labeler->priv->config)) { /* Translators: this is the feature where what you see on your * laptop's screen is the same as your external projector. * Here, "Mirrored" is being used as an adjective. For example, * the Spanish translation could be "Pantallas en Espejo". */ display_name = _("Mirrored Displays"); str = g_strdup_printf ("%s", display_name); } else { display_name = cc_display_monitor_get_display_name (output); output_name = cc_display_monitor_get_connector_name (output); str = g_strdup_printf ("%d %s\n%s", num, display_name, output_name); } widget = gtk_label_new (NULL); gtk_label_set_markup (GTK_LABEL (widget), str); gtk_label_set_justify (GTK_LABEL (widget), GTK_JUSTIFY_CENTER); g_free (str); gtk_widget_override_color (widget, gtk_widget_get_state_flags (widget), &black); gtk_container_add (GTK_CONTAINER (window), widget); cc_display_monitor_get_geometry (output, &x, &y, NULL, NULL); position_window (labeler, output, window); gtk_widget_show_all (window); return window; } /** * cc_display_labeler_new: * @config: Configuration of the screens to label * * Create a GUI element that will display colored labels on each connected monitor. * This is useful when users are required to identify which monitor is which, e.g. for * for configuring multiple monitors. * The labels will be shown by default, use cc_display_labeler_hide to hide them. * * Returns: A new #CcDisplayLabeler */ CcDisplayLabeler * cc_display_labeler_new (CcDisplayConfig *config) { g_return_val_if_fail (CC_IS_DISPLAY_CONFIG (config), NULL); return g_object_new (CC_TYPE_DISPLAY_LABELER, "config", config, NULL); } /** * cc_display_labeler_show: * @labeler: A #CcDisplayLabeler * * Show the labels. */ void cc_display_labeler_show (CcDisplayLabeler *labeler) { gint i; gboolean created_window_for_clone; GList *outputs, *l; g_return_if_fail (CC_IS_DISPLAY_LABELER (labeler)); if (labeler->priv->windows != NULL) return; labeler->priv->num_outputs = count_outputs (labeler->priv->config); labeler->priv->windows = g_new (GtkWidget *, labeler->priv->num_outputs); created_window_for_clone = FALSE; outputs = cc_display_config_get_ui_sorted_monitors (labeler->priv->config); for (l = outputs, i = 0; l != NULL; l = l->next, i++) { CcDisplayMonitor *output = CC_DISPLAY_MONITOR (l->data); if (!created_window_for_clone) { gchar *rgba_str; g_signal_emit_by_name (G_OBJECT (labeler), "get-output-color", i, &rgba_str); labeler->priv->windows[i] = create_label_window (labeler, output, rgba_str, i + 1); if (cc_display_config_is_cloning (labeler->priv->config)) created_window_for_clone = TRUE; } else labeler->priv->windows[i] = NULL; } } /** * cc_display_labeler_hide: * @labeler: A #CcDisplayLabeler * * Hide ouput labels. */ void cc_display_labeler_hide (CcDisplayLabeler *labeler) { int i; CcDisplayLabelerPrivate *priv; g_return_if_fail (CC_IS_DISPLAY_LABELER (labeler)); priv = labeler->priv; if (priv->windows == NULL) return; for (i = 0; i < priv->num_outputs; i++) if (priv->windows[i] != NULL) { gtk_widget_destroy (priv->windows[i]); priv->windows[i] = NULL; } g_free (priv->windows); priv->windows = NULL; } cinnamon-control-center-6.4.1/panels/display/cc-display-config-manager-dbus.c0000664000175000017500000001675314724311620026151 0ustar fabiofabio/* * Copyright (C) 2017 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include "cc-display-config-dbus.h" #include "cc-display-config-manager-dbus.h" #include struct _CcDisplayConfigManagerDBus { CcDisplayConfigManager parent_instance; GCancellable *cancellable; GDBusConnection *connection; guint monitors_changed_id; guint muffin_watch_id; GVariant *current_state; }; G_DEFINE_TYPE (CcDisplayConfigManagerDBus, cc_display_config_manager_dbus, CC_TYPE_DISPLAY_CONFIG_MANAGER) static CcDisplayConfig * cc_display_config_manager_dbus_get_current (CcDisplayConfigManager *pself) { CcDisplayConfigManagerDBus *self = CC_DISPLAY_CONFIG_MANAGER_DBUS (pself); if (!self->current_state) return NULL; return g_object_new (CC_TYPE_DISPLAY_CONFIG_DBUS, "state", self->current_state, "connection", self->connection, NULL); } static void got_current_state (GObject *object, GAsyncResult *result, gpointer data) { CcDisplayConfigManagerDBus *self; GVariant *variant; g_autoptr(GError) error = NULL; variant = g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error); if (!variant) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { self = CC_DISPLAY_CONFIG_MANAGER_DBUS (data); g_clear_pointer (&self->current_state, g_variant_unref); _cc_display_config_manager_emit_changed (CC_DISPLAY_CONFIG_MANAGER (data)); g_warning ("Error calling GetCurrentState: %s", error->message); } return; } self = CC_DISPLAY_CONFIG_MANAGER_DBUS (data); g_clear_pointer (&self->current_state, g_variant_unref); self->current_state = variant; _cc_display_config_manager_emit_changed (CC_DISPLAY_CONFIG_MANAGER (self)); } static void get_current_state (CcDisplayConfigManagerDBus *self) { g_dbus_connection_call (self->connection, "org.cinnamon.Muffin.DisplayConfig", "/org/cinnamon/Muffin/DisplayConfig", "org.cinnamon.Muffin.DisplayConfig", "GetCurrentState", NULL, NULL, G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, self->cancellable, got_current_state, self); } static void monitors_changed (GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer data) { CcDisplayConfigManagerDBus *self = CC_DISPLAY_CONFIG_MANAGER_DBUS (data); get_current_state (self); } static void muffin_vanished_cb (GDBusConnection *connection, const gchar *name, gpointer user_data) { CcDisplayConfigManagerDBus *self = user_data; g_debug ("Muffin vanished"); g_clear_pointer (&self->current_state, g_variant_unref); _cc_display_config_manager_emit_changed (CC_DISPLAY_CONFIG_MANAGER (user_data)); } static void muffin_appeared_cb (GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data) { CcDisplayConfigManagerDBus *self = user_data; g_debug ("Muffin appeared"); get_current_state (self); } static void bus_gotten (GObject *object, GAsyncResult *result, gpointer data) { CcDisplayConfigManagerDBus *self; GDBusConnection *connection; g_autoptr(GError) error = NULL; connection = g_bus_get_finish (result, &error); if (!connection) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { _cc_display_config_manager_emit_changed (CC_DISPLAY_CONFIG_MANAGER (data)); g_warning ("Error obtaining DBus connection: %s", error->message); } return; } self = CC_DISPLAY_CONFIG_MANAGER_DBUS (data); self->connection = connection; self->monitors_changed_id = g_dbus_connection_signal_subscribe (self->connection, "org.cinnamon.Muffin.DisplayConfig", "org.cinnamon.Muffin.DisplayConfig", "MonitorsChanged", "/org/cinnamon/Muffin/DisplayConfig", NULL, G_DBUS_SIGNAL_FLAGS_NONE, monitors_changed, self, NULL); self->muffin_watch_id = g_bus_watch_name_on_connection (self->connection, "org.cinnamon.Muffin.DisplayConfig", G_BUS_NAME_WATCHER_FLAGS_NONE, muffin_appeared_cb, muffin_vanished_cb, self, NULL); get_current_state (self); } static void cc_display_config_manager_dbus_init (CcDisplayConfigManagerDBus *self) { self->cancellable = g_cancellable_new (); g_bus_get (G_BUS_TYPE_SESSION, self->cancellable, bus_gotten, self); } static void cc_display_config_manager_dbus_finalize (GObject *object) { CcDisplayConfigManagerDBus *self = CC_DISPLAY_CONFIG_MANAGER_DBUS (object); g_cancellable_cancel (self->cancellable); g_clear_object (&self->cancellable); if (self->monitors_changed_id && self->connection) g_dbus_connection_signal_unsubscribe (self->connection, self->monitors_changed_id); if (self->muffin_watch_id && self->connection) g_bus_unwatch_name (self->muffin_watch_id); g_clear_object (&self->connection); g_clear_pointer (&self->current_state, g_variant_unref); G_OBJECT_CLASS (cc_display_config_manager_dbus_parent_class)->finalize (object); } static void cc_display_config_manager_dbus_class_init (CcDisplayConfigManagerDBusClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); CcDisplayConfigManagerClass *parent_class = CC_DISPLAY_CONFIG_MANAGER_CLASS (klass); gobject_class->finalize = cc_display_config_manager_dbus_finalize; parent_class->get_current = cc_display_config_manager_dbus_get_current; } CcDisplayConfigManager * cc_display_config_manager_dbus_new (void) { return g_object_new (CC_TYPE_DISPLAY_CONFIG_MANAGER_DBUS, NULL); } cinnamon-control-center-6.4.1/panels/display/cc-display-settings.c0000664000175000017500000006654614724311620024206 0ustar fabiofabio/* cc-display-settings.c * * Copyright (C) 2007, 2008, 2018, 2019 Red Hat, Inc. * Copyright (C) 2013 Intel, Inc. * * Written by: Benjamin Berg * * 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, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ #include #include #include "cc-display-settings.h" #include "cc-display-config.h" #define MAX_SCALE_BUTTONS 6 #define WID(s) GTK_WIDGET (gtk_builder_get_object (self->builder, s)) struct _CcDisplaySettings { GtkBin parent_instance; gboolean updating; guint idle_udpate_id; gboolean has_accelerometer; CcDisplayConfig *config; CcDisplayMonitor *selected_output; GtkListStore *orientation_list; GtkListStore *refresh_rate_list; GtkListStore *resolution_list; GtkBuilder *builder; GtkWidget *orientation_combo; GtkWidget *refresh_rate_combo; GtkWidget *resolution_combo; GtkWidget *scale_bbox; GtkWidget *scale_row; GtkWidget *scale_label; GtkWidget *underscanning_row; GtkWidget *underscanning_switch; GSettings *muffin_settings; }; typedef struct _CcDisplaySettings CcDisplaySettings; enum { PROP_0, PROP_HAS_ACCELEROMETER, PROP_CONFIG, PROP_SELECTED_OUTPUT, PROP_LAST }; G_DEFINE_TYPE (CcDisplaySettings, cc_display_settings, GTK_TYPE_BIN) static GParamSpec *props[PROP_LAST]; static void on_scale_btn_active_changed_cb (GtkWidget *widget, GParamSpec *pspec, CcDisplaySettings *self); static gboolean should_show_rotation (CcDisplaySettings *self) { gboolean supports_rotation; supports_rotation = cc_display_monitor_supports_rotation (self->selected_output, CC_DISPLAY_ROTATION_90 | CC_DISPLAY_ROTATION_180 | CC_DISPLAY_ROTATION_270); /* Doesn't support rotation at all */ if (!supports_rotation) return FALSE; /* We can always rotate displays that aren't builtin */ if (!cc_display_monitor_is_builtin (self->selected_output)) return TRUE; /* Only offer rotation if there's no accelerometer */ return !self->has_accelerometer; } static const gchar * string_for_rotation (CcDisplayRotation rotation) { switch (rotation) { case CC_DISPLAY_ROTATION_NONE: case CC_DISPLAY_ROTATION_180_FLIPPED: return C_("Display rotation", "Landscape"); case CC_DISPLAY_ROTATION_90: case CC_DISPLAY_ROTATION_270_FLIPPED: return C_("Display rotation", "Portrait Right"); case CC_DISPLAY_ROTATION_270: case CC_DISPLAY_ROTATION_90_FLIPPED: return C_("Display rotation", "Portrait Left"); case CC_DISPLAY_ROTATION_180: case CC_DISPLAY_ROTATION_FLIPPED: return C_("Display rotation", "Landscape (flipped)"); } return ""; } static const gchar * make_aspect_string (gint width, gint height) { int ratio; const gchar *aspect = NULL; /* We use a number of Unicode characters below: * ∶ is U+2236 RATIO *   is U+2009 THIN SPACE, * Ɨ is U+00D7 MULTIPLICATION SIGN */ if (width && height) { if (width > height) ratio = width * 10 / height; else ratio = height * 10 / width; switch (ratio) { case 13: aspect = "4∶3"; break; case 16: aspect = "16∶10"; break; case 17: aspect = "16∶9"; break; case 23: aspect = "21∶9"; break; case 12: aspect = "5∶4"; break; /* This catches 1.5625 as well (1600x1024) when maybe it shouldn't. */ case 15: aspect = "3∶2"; break; case 18: aspect = "9∶5"; break; case 10: aspect = "1∶1"; break; } } return aspect; } static char * make_resolution_string (CcDisplayMode *mode) { const char *interlaced = cc_display_mode_is_interlaced (mode) ? "i" : ""; const char *aspect; int width, height; cc_display_mode_get_resolution (mode, &width, &height); aspect = make_aspect_string (width, height); if (aspect != NULL) return g_strdup_printf ("%d × %d%s (%s)", width, height, interlaced, aspect); else return g_strdup_printf ("%d × %d%s", width, height, interlaced); } static gchar * get_frequency_string (CcDisplayMode *mode) { return g_strdup_printf (_("%.2lf Hz"), cc_display_mode_get_freq_f (mode)); } static double round_scale_for_ui (double scale) { /* Keep in sync with mutter */ return round (scale*4)/4; } static gchar * make_scale_string (gdouble scale) { return g_strdup_printf ("%d %%", (int) (round_scale_for_ui (scale)*100)); } static gint sort_modes_by_area_desc (CcDisplayMode *a, CcDisplayMode *b) { gint wa, ha, wb, hb; gint res; cc_display_mode_get_resolution (a, &wa, &ha); cc_display_mode_get_resolution (b, &wb, &hb); /* Prefer wide screen if the size is equal */ res = wb*hb - wa*ha; if (res == 0) return wb - wa; return res; } static gboolean cc_display_settings_rebuild_ui (CcDisplaySettings *self) { GList *modes; GList *item; gint width, height; CcDisplayMode *current_mode; GtkRadioButton *group = NULL; gint buttons = 0; const gdouble *scales, *scale; self->idle_udpate_id = 0; if (!self->config || !self->selected_output) { gtk_widget_set_sensitive (self->orientation_combo, FALSE); gtk_widget_set_sensitive (self->refresh_rate_combo, FALSE); gtk_widget_set_sensitive (self->resolution_combo, FALSE); gtk_widget_set_sensitive (self->scale_row, FALSE); gtk_widget_set_sensitive (self->underscanning_row, FALSE); return G_SOURCE_REMOVE; } g_object_freeze_notify ((GObject*) self->orientation_combo); g_object_freeze_notify ((GObject*) self->refresh_rate_combo); g_object_freeze_notify ((GObject*) self->resolution_combo); g_object_freeze_notify ((GObject*) self->underscanning_switch); cc_display_monitor_get_geometry (self->selected_output, NULL, NULL, &width, &height); /* Selecte the first mode we can find if the monitor is disabled. */ current_mode = cc_display_monitor_get_mode (self->selected_output); if (current_mode == NULL) current_mode = cc_display_monitor_get_preferred_mode (self->selected_output); if (current_mode == NULL) { modes = cc_display_monitor_get_modes (self->selected_output); /* Lets assume that a monitor always has at least one mode. */ g_assert (modes); current_mode = CC_DISPLAY_MODE (modes->data); } if (should_show_rotation (self)) { guint i; CcDisplayRotation rotations[] = { CC_DISPLAY_ROTATION_NONE, CC_DISPLAY_ROTATION_90, CC_DISPLAY_ROTATION_270, CC_DISPLAY_ROTATION_180 }; gtk_widget_set_sensitive (self->orientation_combo, TRUE); gtk_list_store_clear (self->orientation_list); for (i = 0; i < G_N_ELEMENTS (rotations); i++) { if (!cc_display_monitor_supports_rotation (self->selected_output, rotations[i])) continue; GtkTreeIter iter; gtk_list_store_append (self->orientation_list, &iter); gtk_list_store_set (self->orientation_list, &iter, 0, string_for_rotation (rotations[i]), 1, rotations[i], -1); if (cc_display_monitor_get_rotation (self->selected_output) == rotations[i]) gtk_combo_box_set_active_iter (GTK_COMBO_BOX (self->orientation_combo), &iter); } } else { gtk_widget_set_sensitive (self->orientation_combo, FALSE); } /* Only show refresh rate if we are not in cloning mode. */ if (!cc_display_config_is_cloning (self->config)) { GList *item; gdouble freq; freq = cc_display_mode_get_freq_f (current_mode); modes = g_list_copy (cc_display_monitor_get_modes (self->selected_output)); modes = g_list_reverse (modes); gtk_list_store_clear (self->refresh_rate_list); for (item = modes; item != NULL; item = item->next) { gint w, h; CcDisplayMode *mode = CC_DISPLAY_MODE (item->data); cc_display_mode_get_resolution (mode, &w, &h); if (w != width || h != height) continue; GtkTreeIter iter; gtk_list_store_append (self->refresh_rate_list, &iter); gchar *rate_string = get_frequency_string (mode); gtk_list_store_set (self->refresh_rate_list, &iter, 0, rate_string, 1, mode, -1); g_free (rate_string); /* At some point we used to filter very close resolutions, * but we don't anymore these days. */ if (freq == cc_display_mode_get_freq_f (mode)) gtk_combo_box_set_active_iter (GTK_COMBO_BOX (self->refresh_rate_combo), &iter); } g_list_free (modes); /* Show if we have more than one frequency to choose from. */ gtk_widget_set_sensitive (self->refresh_rate_combo, gtk_tree_model_iter_n_children (GTK_TREE_MODEL (self->refresh_rate_list), NULL) > 1); } else { gtk_widget_set_sensitive (self->refresh_rate_combo, FALSE); } if (cc_display_config_is_cloning (self->config)) modes = g_list_copy (cc_display_config_get_cloning_modes (self->config)); else modes = g_list_copy (cc_display_monitor_get_modes (self->selected_output)); gtk_list_store_clear (self->resolution_list); modes = g_list_reverse (modes); GList *unique_resolutions = g_list_prepend (NULL, current_mode); GList *l; for (item = modes; item != NULL; item = item->next) { gint w, h; CcDisplayMode *mode = CC_DISPLAY_MODE (item->data); /* Exclude unusable low resolutions */ if (!cc_display_config_is_scaled_mode_valid (self->config, mode, 1.0)) continue; cc_display_mode_get_resolution (mode, &w, &h); gint ins = 0; for (l = unique_resolutions; l != NULL; l = l->next, ins++) { CcDisplayMode *m = l->data; gint cmp; cmp = sort_modes_by_area_desc (mode, m); if (cmp < 0) break; /* Don't insert if it is already in the list */ if (cmp == 0) { ins = -1; break; } } if (ins >= 0) { unique_resolutions = g_list_insert (unique_resolutions, mode, ins); } } g_list_free (modes); for (l = unique_resolutions; l != NULL; l = l->next) { GtkTreeIter iter; gchar *resolution_string; gtk_list_store_append (self->resolution_list, &iter); resolution_string = make_resolution_string (l->data); gtk_list_store_set (self->resolution_list, &iter, 0, resolution_string, 1, l->data, -1); g_free (resolution_string); if (current_mode == l->data) { gtk_combo_box_set_active_iter (GTK_COMBO_BOX (self->resolution_combo), &iter); } } gtk_widget_set_sensitive (self->resolution_combo, gtk_tree_model_iter_n_children (GTK_TREE_MODEL (self->resolution_list), NULL) > 1); g_list_free (unique_resolutions); /* Scale row is usually shown. */ gtk_container_foreach (GTK_CONTAINER (self->scale_bbox), (GtkCallback) gtk_widget_destroy, NULL); scales = cc_display_mode_get_supported_scales (current_mode); for (scale = scales; *scale != 0.0; scale++) { g_autofree gchar *scale_str = NULL; GtkWidget *scale_btn; if (!cc_display_config_is_scaled_mode_valid (self->config, current_mode, *scale) && cc_display_monitor_get_scale (self->selected_output) != *scale) continue; scale_str = make_scale_string (*scale); scale_btn = gtk_radio_button_new_with_label_from_widget (group, scale_str); if (!group) group = GTK_RADIO_BUTTON (scale_btn); gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (scale_btn), FALSE); g_object_set_data_full (G_OBJECT (scale_btn), "scale", g_memdup (scale, sizeof (gdouble)), g_free); gtk_widget_show (scale_btn); gtk_container_add (GTK_CONTAINER (self->scale_bbox), scale_btn); g_signal_connect_object (scale_btn, "notify::active", G_CALLBACK (on_scale_btn_active_changed_cb), self, 0); if (cc_display_monitor_get_scale (self->selected_output) == *scale) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scale_btn), TRUE); buttons += 1; if (buttons >= MAX_SCALE_BUTTONS) break; } gtk_widget_set_sensitive (self->scale_row, buttons > 1); if (cc_display_config_get_fractional_scaling (self->config)) { gtk_label_set_text (GTK_LABEL (self->scale_label), _("Monitor scale")); } else { gtk_label_set_text (GTK_LABEL (self->scale_label), _("User interface scale")); } gtk_widget_set_visible (self->underscanning_row, cc_display_monitor_supports_underscanning (self->selected_output) && !cc_display_config_is_cloning (self->config)); gtk_switch_set_active (GTK_SWITCH (self->underscanning_switch), cc_display_monitor_get_underscanning (self->selected_output)); self->updating = TRUE; g_object_thaw_notify ((GObject*) self->orientation_combo); g_object_thaw_notify ((GObject*) self->refresh_rate_combo); g_object_thaw_notify ((GObject*) self->resolution_combo); g_object_thaw_notify ((GObject*) self->underscanning_switch); self->updating = FALSE; return G_SOURCE_REMOVE; } static void on_output_changed_cb (CcDisplaySettings *self, GParamSpec *pspec, CcDisplayMonitor *output) { /* Do this frmo an idle handler, because otherwise we may create an * infinite loop triggering the notify::selected-index from the * combo rows. */ if (self->idle_udpate_id) return; self->idle_udpate_id = g_idle_add ((GSourceFunc) cc_display_settings_rebuild_ui, self); } static void on_orientation_selection_changed_cb (GtkComboBox *box, GParamSpec *pspec, CcDisplaySettings *panel) { if (panel->updating) return; GtkTreeIter iter; if (gtk_combo_box_get_active_iter (box, &iter)) { CcDisplayRotation rotation; gtk_tree_model_get (GTK_TREE_MODEL (panel->orientation_list), &iter, 1, &rotation, -1); cc_display_monitor_set_rotation (panel->selected_output, rotation); g_signal_emit_by_name (G_OBJECT (panel), "updated", panel->selected_output); } } static void on_refresh_rate_selection_changed_cb (GtkComboBox *box, GParamSpec *pspec, CcDisplaySettings *panel) { GtkTreeIter iter; if (panel->updating) return; if (gtk_combo_box_get_active_iter (box, &iter)) { g_autoptr(CcDisplayMode) mode = NULL; gtk_tree_model_get (GTK_TREE_MODEL (panel->refresh_rate_list), &iter, 1, &mode, -1); cc_display_monitor_set_mode (panel->selected_output, mode); g_signal_emit_by_name (G_OBJECT (panel), "updated", panel->selected_output); } } static void on_resolution_selection_changed_cb (GtkComboBox *box, GParamSpec *pspec, CcDisplaySettings *panel) { GtkTreeIter iter; if (panel->updating) return; if (gtk_combo_box_get_active_iter (box, &iter)) { g_autoptr(CcDisplayMode) mode = NULL; gtk_tree_model_get (GTK_TREE_MODEL (panel->resolution_list), &iter, 1, &mode, -1); /* This is the only row that can be changed when in cloning mode. */ if (!cc_display_config_is_cloning (panel->config)) cc_display_monitor_set_mode (panel->selected_output, mode); else cc_display_config_set_mode_on_all_outputs (panel->config, mode); g_signal_emit_by_name (G_OBJECT (panel), "updated", panel->selected_output); } } static void on_scale_btn_active_changed_cb (GtkWidget *widget, GParamSpec *pspec, CcDisplaySettings *self) { gdouble scale; if (self->updating) return; if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) return; scale = *(gdouble*) g_object_get_data (G_OBJECT (widget), "scale"); cc_display_monitor_set_scale (self->selected_output, scale); g_signal_emit_by_name (G_OBJECT (self), "updated", self->selected_output); } static void on_underscanning_switch_active_changed_cb (GtkWidget *widget, GParamSpec *pspec, CcDisplaySettings *self) { if (self->updating) return; cc_display_monitor_set_underscanning (self->selected_output, gtk_switch_get_active (GTK_SWITCH (self->underscanning_switch))); g_signal_emit_by_name (G_OBJECT (self), "updated", self->selected_output); } static void cc_display_settings_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { CcDisplaySettings *self = CC_DISPLAY_SETTINGS (object); switch (prop_id) { case PROP_HAS_ACCELEROMETER: g_value_set_boolean (value, cc_display_settings_get_has_accelerometer (self)); break; case PROP_CONFIG: g_value_set_object (value, self->config); break; case PROP_SELECTED_OUTPUT: g_value_set_object (value, self->selected_output); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void cc_display_settings_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { CcDisplaySettings *self = CC_DISPLAY_SETTINGS (object); switch (prop_id) { case PROP_HAS_ACCELEROMETER: cc_display_settings_set_has_accelerometer (self, g_value_get_boolean (value)); break; case PROP_CONFIG: cc_display_settings_set_config (self, g_value_get_object (value)); break; case PROP_SELECTED_OUTPUT: cc_display_settings_set_selected_output (self, g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void cc_display_settings_finalize (GObject *object) { CcDisplaySettings *self = CC_DISPLAY_SETTINGS (object); g_clear_object (&self->config); g_clear_object (&self->orientation_list); g_clear_object (&self->refresh_rate_list); g_clear_object (&self->resolution_list); g_clear_object (&self->builder); if (self->idle_udpate_id) g_source_remove (self->idle_udpate_id); self->idle_udpate_id = 0; G_OBJECT_CLASS (cc_display_settings_parent_class)->finalize (object); } static void cc_display_settings_class_init (CcDisplaySettingsClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); gobject_class->finalize = cc_display_settings_finalize; gobject_class->get_property = cc_display_settings_get_property; gobject_class->set_property = cc_display_settings_set_property; props[PROP_HAS_ACCELEROMETER] = g_param_spec_boolean ("has-accelerometer", "Has Accelerometer", "If an accelerometre is available for the builtin display", FALSE, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); props[PROP_CONFIG] = g_param_spec_object ("config", "Display Config", "The display configuration to work with", CC_TYPE_DISPLAY_CONFIG, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); props[PROP_SELECTED_OUTPUT] = g_param_spec_object ("selected-output", "Selected Output", "The output that is currently selected on the configuration", CC_TYPE_DISPLAY_MONITOR, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (gobject_class, PROP_LAST, props); g_signal_new ("updated", CC_TYPE_DISPLAY_SETTINGS, G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, CC_TYPE_DISPLAY_MONITOR); } static void cc_display_settings_init (CcDisplaySettings *self) { self->builder = gtk_builder_new_from_resource ("/org/cinnamon/control-center/display/cc-display-settings.ui"); gtk_container_add (GTK_CONTAINER (self), WID ("display_settings_toplevel")); self->orientation_combo = WID ("orientation_combo"); self->refresh_rate_combo = WID ("refresh_rate_combo"); self->resolution_combo = WID ("resolution_combo"); self->scale_bbox = WID ("scale_bbox");; self->scale_row = WID ("scale_row"); self->scale_label = WID ("scale_label"); self->underscanning_row = WID ("underscanning_row"); self->underscanning_switch = WID ("underscanning_switch"); gtk_builder_add_callback_symbol (self->builder, "on_orientation_selection_changed_cb", G_CALLBACK (on_orientation_selection_changed_cb)); gtk_builder_add_callback_symbol (self->builder, "on_refresh_rate_selection_changed_cb", G_CALLBACK (on_refresh_rate_selection_changed_cb)); gtk_builder_add_callback_symbol (self->builder, "on_resolution_selection_changed_cb", G_CALLBACK (on_resolution_selection_changed_cb)); gtk_builder_add_callback_symbol (self->builder, "on_underscanning_switch_active_changed_cb", G_CALLBACK (on_underscanning_switch_active_changed_cb)); GtkCellRenderer *renderer; self->updating = TRUE; self->orientation_list = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT); gtk_combo_box_set_model (GTK_COMBO_BOX (self->orientation_combo), GTK_TREE_MODEL (self->orientation_list)); gtk_cell_layout_clear (GTK_CELL_LAYOUT (self->orientation_combo)); renderer = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self->orientation_combo), renderer, TRUE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (self->orientation_combo), renderer, "text", 0, NULL); gtk_cell_renderer_set_visible (renderer, TRUE); self->refresh_rate_list = gtk_list_store_new (2, G_TYPE_STRING, CC_TYPE_DISPLAY_MODE); gtk_combo_box_set_model (GTK_COMBO_BOX (self->refresh_rate_combo), GTK_TREE_MODEL (self->refresh_rate_list)); gtk_cell_layout_clear (GTK_CELL_LAYOUT (self->refresh_rate_combo)); renderer = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self->refresh_rate_combo), renderer, TRUE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (self->refresh_rate_combo), renderer, "text", 0, NULL); gtk_cell_renderer_set_visible (renderer, TRUE); self->resolution_list = gtk_list_store_new (2, G_TYPE_STRING, CC_TYPE_DISPLAY_MODE); gtk_combo_box_set_model (GTK_COMBO_BOX (self->resolution_combo), GTK_TREE_MODEL (self->resolution_list)); gtk_cell_layout_clear (GTK_CELL_LAYOUT (self->resolution_combo)); renderer = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self->resolution_combo), renderer, TRUE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (self->resolution_combo), renderer, "text", 0, NULL); gtk_cell_renderer_set_visible (renderer, TRUE); gtk_builder_connect_signals (self->builder, self); self->updating = FALSE; } CcDisplaySettings* cc_display_settings_new (void) { return g_object_new (CC_TYPE_DISPLAY_SETTINGS, NULL); } gboolean cc_display_settings_get_has_accelerometer (CcDisplaySettings *settings) { return settings->has_accelerometer; } void cc_display_settings_set_has_accelerometer (CcDisplaySettings *self, gboolean has_accelerometer) { self->has_accelerometer = has_accelerometer; cc_display_settings_rebuild_ui (self); g_object_notify_by_pspec (G_OBJECT (self), props[PROP_CONFIG]); } CcDisplayConfig* cc_display_settings_get_config (CcDisplaySettings *self) { return self->config; } void cc_display_settings_set_config (CcDisplaySettings *self, CcDisplayConfig *config) { const gchar *signals[] = { "rotation", "mode", "scale", "is-usable", "active" }; GList *outputs, *l; guint i; if (self->config) { outputs = cc_display_config_get_monitors (self->config); for (l = outputs; l; l = l->next) { CcDisplayMonitor *output = l->data; g_signal_handlers_disconnect_by_data (output, self); } } g_clear_object (&self->config); self->config = g_object_ref (config); /* Listen to all the signals */ if (self->config) { outputs = cc_display_config_get_monitors (self->config); for (l = outputs; l; l = l->next) { CcDisplayMonitor *output = l->data; for (i = 0; i < G_N_ELEMENTS (signals); ++i) g_signal_connect_object (output, signals[i], G_CALLBACK (on_output_changed_cb), self, G_CONNECT_SWAPPED); } } cc_display_settings_set_selected_output (self, NULL); g_object_notify_by_pspec (G_OBJECT (self), props[PROP_CONFIG]); } CcDisplayMonitor* cc_display_settings_get_selected_output (CcDisplaySettings *self) { return self->selected_output; } void cc_display_settings_set_selected_output (CcDisplaySettings *self, CcDisplayMonitor *output) { self->selected_output = output; cc_display_settings_rebuild_ui (self); g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SELECTED_OUTPUT]); } cinnamon-control-center-6.4.1/panels/display/cc-display-settings.h0000664000175000017500000000363714724311620024203 0ustar fabiofabio/* -*- mode: c; style: linux -*- * * Copyright (C) 2019 Red Hat, Inc. * * Written by: Benjamin Berg * * 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, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ #pragma once #include #include "cc-display-config.h" G_BEGIN_DECLS #define CC_TYPE_DISPLAY_SETTINGS cc_display_settings_get_type () G_DECLARE_FINAL_TYPE (CcDisplaySettings, cc_display_settings, CC, DISPLAY_SETTINGS, GtkBin); CcDisplaySettings* cc_display_settings_new (void); gboolean cc_display_settings_get_has_accelerometer (CcDisplaySettings *settings); void cc_display_settings_set_has_accelerometer (CcDisplaySettings *settings, gboolean has_accelerometer); CcDisplayConfig* cc_display_settings_get_config (CcDisplaySettings *settings); void cc_display_settings_set_config (CcDisplaySettings *settings, CcDisplayConfig *config); CcDisplayMonitor* cc_display_settings_get_selected_output (CcDisplaySettings *settings); void cc_display_settings_set_selected_output (CcDisplaySettings *settings, CcDisplayMonitor *output); G_END_DECLS cinnamon-control-center-6.4.1/panels/display/cc-display-settings.ui0000664000175000017500000001751014724311620024364 0ustar fabiofabio True True vertical 6 True False False True 0 True False 6 12 True False Resolution 1 0 0 100 True False True 1 0 2 True False Refresh Rate 1 0 1 True False Rotation 1 0 2 100 True False True 1 2 2 100 True False True 1 1 2 100 True False True False center True True expand False True end 0 1 3 2 True False User interface scale 1 0 3 False True 1 True False 6 12 True False Adjust for TV 1 0 0 True True end center True 1 0 2 False True 2 cinnamon-control-center-6.4.1/panels/display/display.gresource.xml0000664000175000017500000000047514724311620024325 0ustar fabiofabio cc-display-panel.ui cc-display-settings.ui display-arrangement.css cinnamon-control-center-6.4.1/panels/display/cc-display-config.c0000664000175000017500000006122614724311620023601 0ustar fabiofabio/* * Copyright (C) 2016 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #define MUFFIN_SCHEMA "org.cinnamon.muffin" #define MUFFIN_EXPERIMENTAL_FEATURES_KEY "experimental-features" #define MUFFIN_FEATURE_FRACTIONAL_SCALING_X11 "x11-randr-fractional-scaling" #define MUFFIN_FEATURE_FRACTIONAL_SCALING_WAYLAND "scale-monitor-framebuffer" #include #include #include #include "cc-display-config.h" #ifdef GDK_WINDOWING_WAYLAND #include #endif #ifdef GDK_WINDOWING_X11 #include #endif static const double known_diagonals[] = { 12.1, 13.3, 15.6 }; static char * diagonal_to_str (double d) { int i; for (i = 0; i < G_N_ELEMENTS (known_diagonals); i++) { double delta; delta = fabs(known_diagonals[i] - d); if (delta < 0.1) return g_strdup_printf ("%0.1lf\"", known_diagonals[i]); } return g_strdup_printf ("%d\"", (int) (d + 0.5)); } static char * make_display_size_string (int width_mm, int height_mm) { char *inches = NULL; if (width_mm > 0 && height_mm > 0) { double d = sqrt (width_mm * width_mm + height_mm * height_mm); inches = diagonal_to_str (d / 25.4); } return inches; } static char * make_output_ui_name (CcDisplayMonitor *output) { int width_mm, height_mm; g_autofree char *size = NULL; cc_display_monitor_get_physical_size (output, &width_mm, &height_mm); size = make_display_size_string (width_mm, height_mm); if (size) return g_strdup_printf ("%s (%s)", cc_display_monitor_get_display_name (output), size); else return g_strdup_printf ("%s", cc_display_monitor_get_display_name (output)); } G_DEFINE_TYPE (CcDisplayMode, cc_display_mode, G_TYPE_OBJECT) static void cc_display_mode_init (CcDisplayMode *self) { } static void cc_display_mode_class_init (CcDisplayModeClass *klass) { } void cc_display_mode_get_resolution (CcDisplayMode *self, int *w, int *h) { return CC_DISPLAY_MODE_GET_CLASS (self)->get_resolution (self, w, h); } const double * cc_display_mode_get_supported_scales (CcDisplayMode *self) { return CC_DISPLAY_MODE_GET_CLASS (self)->get_supported_scales (self); } double cc_display_mode_get_preferred_scale (CcDisplayMode *self) { return CC_DISPLAY_MODE_GET_CLASS (self)->get_preferred_scale (self); } gboolean cc_display_mode_is_interlaced (CcDisplayMode *self) { return CC_DISPLAY_MODE_GET_CLASS (self)->is_interlaced (self); } int cc_display_mode_get_freq (CcDisplayMode *self) { return CC_DISPLAY_MODE_GET_CLASS (self)->get_freq (self); } double cc_display_mode_get_freq_f (CcDisplayMode *self) { return CC_DISPLAY_MODE_GET_CLASS (self)->get_freq_f (self); } struct _CcDisplayMonitorPrivate { int ui_number; gchar *ui_name; gchar *ui_number_name; gboolean is_usable; GdkRectangle disabled_rect; }; typedef struct _CcDisplayMonitorPrivate CcDisplayMonitorPrivate; G_DEFINE_TYPE_WITH_PRIVATE (CcDisplayMonitor, cc_display_monitor, G_TYPE_OBJECT) static void cc_display_monitor_init (CcDisplayMonitor *self) { CcDisplayMonitorPrivate *priv = cc_display_monitor_get_instance_private (self); priv->ui_number = 0; priv->ui_name = NULL; priv->ui_number_name = NULL; priv->is_usable = TRUE; } static void cc_display_monitor_finalize (GObject *object) { CcDisplayMonitor *self = CC_DISPLAY_MONITOR (object); CcDisplayMonitorPrivate *priv = cc_display_monitor_get_instance_private (self); g_clear_pointer (&priv->ui_name, g_free); g_clear_pointer (&priv->ui_number_name, g_free); G_OBJECT_CLASS (cc_display_monitor_parent_class)->finalize (object); } static void cc_display_monitor_class_init (CcDisplayMonitorClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); gobject_class->finalize = cc_display_monitor_finalize; g_signal_new ("rotation", CC_TYPE_DISPLAY_MONITOR, G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); g_signal_new ("mode", CC_TYPE_DISPLAY_MONITOR, G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); g_signal_new ("primary", CC_TYPE_DISPLAY_MONITOR, G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); g_signal_new ("active", CC_TYPE_DISPLAY_MONITOR, G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); g_signal_new ("scale", CC_TYPE_DISPLAY_MONITOR, G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); g_signal_new ("position-changed", CC_TYPE_DISPLAY_MONITOR, G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); g_signal_new ("is-usable", CC_TYPE_DISPLAY_MONITOR, G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); } const char * cc_display_monitor_get_display_name (CcDisplayMonitor *self) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->get_display_name (self); } const char * cc_display_monitor_get_connector_name (CcDisplayMonitor *self) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->get_connector_name (self); } gboolean cc_display_monitor_is_builtin (CcDisplayMonitor *self) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->is_builtin (self); } gboolean cc_display_monitor_is_primary (CcDisplayMonitor *self) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->is_primary (self); } void cc_display_monitor_set_primary (CcDisplayMonitor *self, gboolean primary) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->set_primary (self, primary); } gboolean cc_display_monitor_is_active (CcDisplayMonitor *self) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->is_active (self); } void cc_display_monitor_set_active (CcDisplayMonitor *self, gboolean active) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->set_active (self, active); } CcDisplayRotation cc_display_monitor_get_rotation (CcDisplayMonitor *self) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->get_rotation (self); } void cc_display_monitor_set_rotation (CcDisplayMonitor *self, CcDisplayRotation rotation) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->set_rotation (self, rotation); } gboolean cc_display_monitor_supports_rotation (CcDisplayMonitor *self, CcDisplayRotation r) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->supports_rotation (self, r); } void cc_display_monitor_get_physical_size (CcDisplayMonitor *self, int *w, int *h) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->get_physical_size (self, w, h); } void cc_display_monitor_get_geometry (CcDisplayMonitor *self, int *x, int *y, int *w, int *h) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->get_geometry (self, x, y, w, h); } void cc_display_monitor_get_disabled_geometry (CcDisplayMonitor *self, int *x1, int *y1, int *x2, int *y2) { CcDisplayMonitorPrivate *priv = cc_display_monitor_get_instance_private (self); *x1 = priv->disabled_rect.x; *y1 = priv->disabled_rect.y; *x2 = priv->disabled_rect.x + priv->disabled_rect.width; *y2 = priv->disabled_rect.y + priv->disabled_rect.height; } void cc_display_monitor_set_disabled_geometry (CcDisplayMonitor *self, int x, int y, int w, int h) { CcDisplayMonitorPrivate *priv = cc_display_monitor_get_instance_private (self); priv->disabled_rect.x = x; priv->disabled_rect.y = y; priv->disabled_rect.width = w; priv->disabled_rect.height = h; } CcDisplayMode * cc_display_monitor_get_mode (CcDisplayMonitor *self) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->get_mode (self); } CcDisplayMode * cc_display_monitor_get_preferred_mode (CcDisplayMonitor *self) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->get_preferred_mode (self); } guint32 cc_display_monitor_get_id (CcDisplayMonitor *self) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->get_id (self); } GList * cc_display_monitor_get_modes (CcDisplayMonitor *self) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->get_modes (self); } gboolean cc_display_monitor_supports_underscanning (CcDisplayMonitor *self) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->supports_underscanning (self); } gboolean cc_display_monitor_get_underscanning (CcDisplayMonitor *self) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->get_underscanning (self); } void cc_display_monitor_set_underscanning (CcDisplayMonitor *self, gboolean underscanning) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->set_underscanning (self, underscanning); } void cc_display_monitor_set_mode (CcDisplayMonitor *self, CcDisplayMode *m) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->set_mode (self, m); } void cc_display_monitor_set_position (CcDisplayMonitor *self, int x, int y) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->set_position (self, x, y); } double cc_display_monitor_get_scale (CcDisplayMonitor *self) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->get_scale (self); } void cc_display_monitor_set_scale (CcDisplayMonitor *self, double s) { return CC_DISPLAY_MONITOR_GET_CLASS (self)->set_scale (self, s); } gboolean cc_display_monitor_is_useful (CcDisplayMonitor *self) { CcDisplayMonitorPrivate *priv = cc_display_monitor_get_instance_private (self); return priv->is_usable && cc_display_monitor_is_active (self); } gboolean cc_display_monitor_is_usable (CcDisplayMonitor *self) { CcDisplayMonitorPrivate *priv = cc_display_monitor_get_instance_private (self); return priv->is_usable; } void cc_display_monitor_set_usable (CcDisplayMonitor *self, gboolean is_usable) { CcDisplayMonitorPrivate *priv = cc_display_monitor_get_instance_private (self); priv->is_usable = is_usable; g_signal_emit_by_name (self, "is-usable"); } gint cc_display_monitor_get_ui_number (CcDisplayMonitor *self) { CcDisplayMonitorPrivate *priv = cc_display_monitor_get_instance_private (self); return priv->ui_number; } const char * cc_display_monitor_get_ui_name (CcDisplayMonitor *self) { CcDisplayMonitorPrivate *priv = cc_display_monitor_get_instance_private (self); return priv->ui_name; } const char * cc_display_monitor_get_ui_number_name (CcDisplayMonitor *self) { CcDisplayMonitorPrivate *priv = cc_display_monitor_get_instance_private (self); return priv->ui_number_name; } char * cc_display_monitor_dup_ui_number_name (CcDisplayMonitor *self) { CcDisplayMonitorPrivate *priv = cc_display_monitor_get_instance_private (self); return g_strdup (priv->ui_number_name); } static void cc_display_monitor_set_ui_info (CcDisplayMonitor *self, gint ui_number, gchar *ui_name) { CcDisplayMonitorPrivate *priv = cc_display_monitor_get_instance_private (self); priv->ui_number = ui_number; g_free (priv->ui_name); priv->ui_name = ui_name; priv->ui_number_name = g_strdup_printf ("%d\u2003%s", ui_number, ui_name); } struct _CcDisplayConfigPrivate { GList *ui_sorted_monitors; GSettings *muffin_settings; gboolean fractional_scaling; gboolean fractional_scaling_pending_disable; }; typedef struct _CcDisplayConfigPrivate CcDisplayConfigPrivate; G_DEFINE_TYPE_WITH_PRIVATE (CcDisplayConfig, cc_display_config, G_TYPE_OBJECT) static const char * get_fractional_scaling_key (void) { GdkDisplay *display; display = gdk_display_get_default (); #if defined(GDK_WINDOWING_X11) if (GDK_IS_X11_DISPLAY (display)) return MUFFIN_FEATURE_FRACTIONAL_SCALING_X11; #endif /* GDK_WINDOWING_X11 */ #if defined(GDK_WINDOWING_WAYLAND) if (GDK_IS_WAYLAND_DISPLAY (display)) return MUFFIN_FEATURE_FRACTIONAL_SCALING_WAYLAND; #endif /* GDK_WINDOWING_WAYLAND */ g_return_val_if_reached (NULL); } static gboolean get_fractional_scaling_active (CcDisplayConfig *self) { CcDisplayConfigPrivate *priv = cc_display_config_get_instance_private (self); g_auto(GStrv) features = NULL; const char *key = get_fractional_scaling_key (); g_return_val_if_fail (key, FALSE); features = g_settings_get_strv (priv->muffin_settings, MUFFIN_EXPERIMENTAL_FEATURES_KEY); return g_strv_contains ((const gchar **) features, key); } static void set_fractional_scaling_active (CcDisplayConfig *self, gboolean enable) { CcDisplayConfigPrivate *priv = cc_display_config_get_instance_private (self); g_auto(GStrv) existing_features = NULL; gboolean have_fractional_scaling = FALSE; g_autoptr(GVariantBuilder) builder = NULL; const char *key = get_fractional_scaling_key (); /* Add or remove the fractional scaling feature from muffin */ existing_features = g_settings_get_strv (priv->muffin_settings, MUFFIN_EXPERIMENTAL_FEATURES_KEY); builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); for (int i = 0; existing_features[i] != NULL; i++) { if (g_strcmp0 (existing_features[i], key) == 0) { if (enable) have_fractional_scaling = TRUE; else continue; } g_variant_builder_add (builder, "s", existing_features[i]); } if (enable && !have_fractional_scaling && key) g_variant_builder_add (builder, "s", key); g_settings_set_value (priv->muffin_settings, MUFFIN_EXPERIMENTAL_FEATURES_KEY, g_variant_builder_end (builder)); } static void cc_display_config_init (CcDisplayConfig *self) { CcDisplayConfigPrivate *priv = cc_display_config_get_instance_private (self); priv->ui_sorted_monitors = NULL; /* No need to connect to the setting, as we'll get notified by mutter */ priv->muffin_settings = g_settings_new (MUFFIN_SCHEMA); priv->fractional_scaling = get_fractional_scaling_active (self); } static void cc_display_config_constructed (GObject *object) { CcDisplayConfig *self = CC_DISPLAY_CONFIG (object); CcDisplayConfigPrivate *priv = cc_display_config_get_instance_private (self); GList *monitors = cc_display_config_get_monitors (self); GList *item; gint ui_number = 1; for (item = monitors; item != NULL; item = item->next) { CcDisplayMonitor *monitor = item->data; if (cc_display_monitor_is_builtin (monitor)) priv->ui_sorted_monitors = g_list_prepend (priv->ui_sorted_monitors, monitor); else priv->ui_sorted_monitors = g_list_append (priv->ui_sorted_monitors, monitor); } for (item = priv->ui_sorted_monitors; item != NULL; item = item->next) { CcDisplayMonitor *monitor = item->data; char *ui_name; ui_name = make_output_ui_name (monitor); cc_display_monitor_set_ui_info (monitor, ui_number, ui_name); ui_number += 1; } } static void cc_display_config_finalize (GObject *object) { CcDisplayConfig *self = CC_DISPLAY_CONFIG (object); CcDisplayConfigPrivate *priv = cc_display_config_get_instance_private (self); g_list_free (priv->ui_sorted_monitors); g_clear_object (&priv->muffin_settings); G_OBJECT_CLASS (cc_display_config_parent_class)->finalize (object); } static void cc_display_config_class_init (CcDisplayConfigClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); g_signal_new ("primary", CC_TYPE_DISPLAY_CONFIG, G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); gobject_class->constructed = cc_display_config_constructed; gobject_class->finalize = cc_display_config_finalize; } GList * cc_display_config_get_monitors (CcDisplayConfig *self) { g_return_val_if_fail (CC_IS_DISPLAY_CONFIG (self), NULL); return CC_DISPLAY_CONFIG_GET_CLASS (self)->get_monitors (self); } GList * cc_display_config_get_ui_sorted_monitors (CcDisplayConfig *self) { CcDisplayConfigPrivate *priv = cc_display_config_get_instance_private (self); g_return_val_if_fail (CC_IS_DISPLAY_CONFIG (self), NULL); return priv->ui_sorted_monitors; } int cc_display_config_count_useful_monitors (CcDisplayConfig *self) { CcDisplayConfigPrivate *priv = cc_display_config_get_instance_private (self); GList *outputs, *l; guint count = 0; g_return_val_if_fail (CC_IS_DISPLAY_CONFIG (self), 0); outputs = priv->ui_sorted_monitors; for (l = outputs; l != NULL; l = l->next) { CcDisplayMonitor *output = l->data; if (!cc_display_monitor_is_useful (output)) continue; else count++; } return count; } gboolean cc_display_config_is_applicable (CcDisplayConfig *self) { g_return_val_if_fail (CC_IS_DISPLAY_CONFIG (self), FALSE); return CC_DISPLAY_CONFIG_GET_CLASS (self)->is_applicable (self); } void cc_display_config_set_mode_on_all_outputs (CcDisplayConfig *config, CcDisplayMode *mode) { GList *outputs, *l; g_return_if_fail (CC_IS_DISPLAY_CONFIG (config)); outputs = cc_display_config_get_monitors (config); for (l = outputs; l; l = l->next) { CcDisplayMonitor *output = l->data; cc_display_monitor_set_mode (output, mode); cc_display_monitor_set_position (output, 0, 0); } } gboolean cc_display_config_equal (CcDisplayConfig *self, CcDisplayConfig *other) { CcDisplayConfigPrivate *spriv = cc_display_config_get_instance_private (self); CcDisplayConfigPrivate *opriv = cc_display_config_get_instance_private (other); g_return_val_if_fail (CC_IS_DISPLAY_CONFIG (self), FALSE); g_return_val_if_fail (CC_IS_DISPLAY_CONFIG (other), FALSE); if (spriv->fractional_scaling_pending_disable != opriv->fractional_scaling_pending_disable) return FALSE; return CC_DISPLAY_CONFIG_GET_CLASS (self)->equal (self, other); } gboolean cc_display_config_apply (CcDisplayConfig *self, GError **error) { CcDisplayConfigPrivate *priv = cc_display_config_get_instance_private (self); if (!CC_IS_DISPLAY_CONFIG (self)) { g_warning ("Cannot apply invalid configuration"); g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Cannot apply invalid configuration"); return FALSE; } if (priv->fractional_scaling_pending_disable) { set_fractional_scaling_active (self, FALSE); priv->fractional_scaling_pending_disable = FALSE; } return CC_DISPLAY_CONFIG_GET_CLASS (self)->apply (self, error); } gboolean cc_display_config_is_cloning (CcDisplayConfig *self) { g_return_val_if_fail (CC_IS_DISPLAY_CONFIG (self), FALSE); return CC_DISPLAY_CONFIG_GET_CLASS (self)->is_cloning (self); } void cc_display_config_set_cloning (CcDisplayConfig *self, gboolean clone) { g_return_if_fail (CC_IS_DISPLAY_CONFIG (self)); return CC_DISPLAY_CONFIG_GET_CLASS (self)->set_cloning (self, clone); } GList * cc_display_config_get_cloning_modes (CcDisplayConfig *self) { g_return_val_if_fail (CC_IS_DISPLAY_CONFIG (self), NULL); return CC_DISPLAY_CONFIG_GET_CLASS (self)->get_cloning_modes (self); } gboolean cc_display_config_is_layout_logical (CcDisplayConfig *self) { g_return_val_if_fail (CC_IS_DISPLAY_CONFIG (self), FALSE); return CC_DISPLAY_CONFIG_GET_CLASS (self)->is_layout_logical (self); } void cc_display_config_set_minimum_size (CcDisplayConfig *self, int width, int height) { g_return_if_fail (CC_IS_DISPLAY_CONFIG (self)); CC_DISPLAY_CONFIG_GET_CLASS (self)->set_minimum_size (self, width, height); } gint cc_display_config_get_legacy_ui_scale (CcDisplayConfig *self) { return CC_DISPLAY_CONFIG_GET_CLASS (self)->get_legacy_ui_scale (self); } static gboolean scale_value_is_fractional (double scale) { return (int) scale != scale; } gboolean cc_display_config_is_scaled_mode_valid (CcDisplayConfig *self, CcDisplayMode *mode, double scale) { CcDisplayConfigPrivate *priv = cc_display_config_get_instance_private (self); g_return_val_if_fail (CC_IS_DISPLAY_CONFIG (self), FALSE); g_return_val_if_fail (CC_IS_DISPLAY_MODE (mode), FALSE); if (priv->fractional_scaling_pending_disable && scale_value_is_fractional (scale)) return FALSE; return CC_DISPLAY_CONFIG_GET_CLASS (self)->is_scaled_mode_valid (self, mode, scale); } gboolean cc_display_config_layout_use_ui_scale (CcDisplayConfig *self) { return CC_DISPLAY_CONFIG_GET_CLASS (self)->layout_use_ui_scale (self); } double cc_display_config_get_maximum_scaling (CcDisplayConfig *self) { GList *outputs, *l; double max_scale = 1.0; outputs = cc_display_config_get_monitors (self); for (l = outputs; l; l = l->next) { CcDisplayMonitor *output = l->data; if (!cc_display_monitor_is_useful (output)) continue; max_scale = MAX (max_scale, cc_display_monitor_get_scale (output)); } return max_scale; } static gboolean set_monitors_scaling_to_preferred_integers (CcDisplayConfig *self) { GList *l; gboolean any_changed = FALSE; for (l = cc_display_config_get_monitors (self); l; l = l->next) { CcDisplayMonitor *monitor = l->data; gdouble monitor_scale = cc_display_monitor_get_scale (monitor); if (scale_value_is_fractional (monitor_scale)) { CcDisplayMode *preferred_mode; double preferred_scale; double *saved_scale; preferred_mode = cc_display_monitor_get_preferred_mode (monitor); preferred_scale = cc_display_mode_get_preferred_scale (preferred_mode); cc_display_monitor_set_scale (monitor, preferred_scale); any_changed = TRUE; saved_scale = g_new (double, 1); *saved_scale = monitor_scale; g_object_set_data_full (G_OBJECT (monitor), "previous-fractional-scale", saved_scale, g_free); } else { g_signal_emit_by_name (monitor, "scale"); } } return any_changed; } static void reset_monitors_scaling_to_selected_values (CcDisplayConfig *self) { GList *l; for (l = cc_display_config_get_monitors (self); l; l = l->next) { CcDisplayMonitor *monitor = l->data; gdouble *saved_scale; saved_scale = g_object_get_data (G_OBJECT (monitor), "previous-fractional-scale"); if (saved_scale) { cc_display_monitor_set_scale (monitor, *saved_scale); g_object_set_data (G_OBJECT (monitor), "previous-fractional-scale", NULL); } else { g_signal_emit_by_name (monitor, "scale"); } } } void cc_display_config_set_fractional_scaling (CcDisplayConfig *self, gboolean enabled) { CcDisplayConfigPrivate *priv = cc_display_config_get_instance_private (self); if (priv->fractional_scaling == enabled) return; priv->fractional_scaling = enabled; if (priv->fractional_scaling) { if (priv->fractional_scaling_pending_disable) { priv->fractional_scaling_pending_disable = FALSE; reset_monitors_scaling_to_selected_values (self); } if (!get_fractional_scaling_active (self)) set_fractional_scaling_active (self, enabled); } else { priv->fractional_scaling_pending_disable = TRUE; if (!set_monitors_scaling_to_preferred_integers (self)) { gboolean disable_now = FALSE; if (cc_display_config_layout_use_ui_scale (self)) { disable_now = G_APPROX_VALUE (cc_display_config_get_legacy_ui_scale (self), cc_display_config_get_maximum_scaling (self), DBL_EPSILON); } if (disable_now) { priv->fractional_scaling_pending_disable = FALSE; reset_monitors_scaling_to_selected_values (self); set_fractional_scaling_active (self, enabled); } } } } gboolean cc_display_config_get_fractional_scaling (CcDisplayConfig *self) { CcDisplayConfigPrivate *priv = cc_display_config_get_instance_private (self); return priv->fractional_scaling; } cinnamon-control-center-6.4.1/panels/display/cc-display-arrangement.h0000664000175000017500000000376114724311620024644 0ustar fabiofabio/* -*- mode: c; style: linux -*- * * Copyright (C) 2017 Red Hat, Inc. * * Written by: Benjamin Berg * * 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, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ #pragma once #include #include "cc-display-config.h" G_BEGIN_DECLS #define CC_TYPE_DISPLAY_ARRANGEMENT cc_display_arrangement_get_type () G_DECLARE_FINAL_TYPE (CcDisplayArrangement, cc_display_arrangement, CC, DISPLAY_ARRANGEMENT, GtkDrawingArea); CcDisplayArrangement* cc_display_arrangement_new (CcDisplayConfig *config); CcDisplayConfig* cc_display_arrangement_get_config (CcDisplayArrangement *self); void cc_display_arrangement_set_config (CcDisplayArrangement *self, CcDisplayConfig *config); CcDisplayMonitor* cc_display_arrangement_get_selected_output (CcDisplayArrangement *arr); void cc_display_arrangement_set_selected_output (CcDisplayArrangement *arr, CcDisplayMonitor *output); /* This is a bit of an odd-ball, but it currently makes sense to have it with * the arrangement widget where the snapping code lives. */ void cc_display_config_snap_output (CcDisplayConfig *config, CcDisplayMonitor *output); G_END_DECLS cinnamon-control-center-6.4.1/panels/display/cc-display-config-manager-dbus.h0000664000175000017500000000225314724311620026144 0ustar fabiofabio/* * Copyright (C) 2017 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #pragma once #include #include "cc-display-config-manager.h" G_BEGIN_DECLS #define CC_TYPE_DISPLAY_CONFIG_MANAGER_DBUS (cc_display_config_manager_dbus_get_type ()) G_DECLARE_FINAL_TYPE (CcDisplayConfigManagerDBus, cc_display_config_manager_dbus, CC, DISPLAY_CONFIG_MANAGER_DBUS, CcDisplayConfigManager) CcDisplayConfigManager * cc_display_config_manager_dbus_new (void); G_END_DECLS cinnamon-control-center-6.4.1/panels/display/display-module.c0000664000175000017500000000200514724311620023224 0ustar fabiofabio/* * Copyright (C) 2010 Intel, Inc * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * * Author: Thomas Wood * */ #include "cc-display-panel.h" #include void g_io_module_load (GIOModule *module) { /* register the panel */ cc_display_panel_register (module); } void g_io_module_unload (GIOModule *module) { } cinnamon-control-center-6.4.1/panels/display/cc-display-config.h0000664000175000017500000003606514724311620023611 0ustar fabiofabio/* * Copyright (C) 2016 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #pragma once #include G_BEGIN_DECLS /* * GNOME Control Center display configuration system: * * The display configuration system consists of multiple concepts: * * CcDisplayConfig: * * Configuration instance, read from mutter using the * org.cinnamon.Muffin.DisplayConfig D-Bus API. Contains information about the * current configuration. Can be copied, to create a representation of a * configuration at a given time, and applied, applying any changes that has * been made to the objects associated with the configuration. * * CcDisplayConfig provides a list of all known "monitors" known to the * compositor. It does not know about ports without any monitors connected, * nor low level details about monitors, such as tiling etc. * * CcDisplayMonitor: * * A high level representation of a connected monitor. A monitor have details * associated with it, some which can be altered. Each CcDisplayMonitor * instance is associated with a single CcDisplayConfig instance. All * alteration to a monitor is cached and not applied until * cc_display_config_apply() is called on the corresponding CcDisplayConfig * object. * * CcDisplayMode: * * A monitor mode, including resolution, refresh rate, and scale. Each monitor * will have a list of possible modes. * */ typedef enum _CcDisplayRotation { CC_DISPLAY_ROTATION_NONE, CC_DISPLAY_ROTATION_90, CC_DISPLAY_ROTATION_180, CC_DISPLAY_ROTATION_270, CC_DISPLAY_ROTATION_FLIPPED, CC_DISPLAY_ROTATION_90_FLIPPED, CC_DISPLAY_ROTATION_180_FLIPPED, CC_DISPLAY_ROTATION_270_FLIPPED, } CcDisplayRotation; #define CC_TYPE_DISPLAY_MODE (cc_display_mode_get_type ()) G_DECLARE_DERIVABLE_TYPE (CcDisplayMode, cc_display_mode, CC, DISPLAY_MODE, GObject) struct _CcDisplayModeClass { GObjectClass parent_class; void (*get_resolution) (CcDisplayMode *self, int *w, int *h); const double* (*get_supported_scales) (CcDisplayMode *self); double (*get_preferred_scale) (CcDisplayMode *self); gboolean (*is_interlaced) (CcDisplayMode *self); int (*get_freq) (CcDisplayMode *self); double (*get_freq_f) (CcDisplayMode *self); }; #define CC_TYPE_DISPLAY_MONITOR (cc_display_monitor_get_type ()) G_DECLARE_DERIVABLE_TYPE (CcDisplayMonitor, cc_display_monitor, CC, DISPLAY_MONITOR, GObject) struct _CcDisplayMonitorClass { GObjectClass parent_class; guint32 (*get_id) (CcDisplayMonitor *self); const char* (*get_display_name) (CcDisplayMonitor *self); const char* (*get_connector_name) (CcDisplayMonitor *self); gboolean (*is_builtin) (CcDisplayMonitor *self); gboolean (*is_primary) (CcDisplayMonitor *self); void (*set_primary) (CcDisplayMonitor *self, gboolean primary); gboolean (*is_active) (CcDisplayMonitor *self); void (*set_active) (CcDisplayMonitor *self, gboolean a); CcDisplayRotation (*get_rotation) (CcDisplayMonitor *self); void (*set_rotation) (CcDisplayMonitor *self, CcDisplayRotation r); gboolean (*supports_rotation) (CcDisplayMonitor *self, CcDisplayRotation r); void (*get_physical_size) (CcDisplayMonitor *self, int *w, int *h); void (*get_geometry) (CcDisplayMonitor *self, int *x, int *y, int *w, int *h); gboolean (*supports_underscanning) (CcDisplayMonitor *self); gboolean (*get_underscanning) (CcDisplayMonitor *self); void (*set_underscanning) (CcDisplayMonitor *self, gboolean u); CcDisplayMode* (*get_mode) (CcDisplayMonitor *self); CcDisplayMode* (*get_preferred_mode) (CcDisplayMonitor *self); GList* (*get_modes) (CcDisplayMonitor *self); void (*set_mode) (CcDisplayMonitor *self, CcDisplayMode *m); void (*set_position) (CcDisplayMonitor *self, int x, int y); double (*get_scale) (CcDisplayMonitor *self); void (*set_scale) (CcDisplayMonitor *self, double s); }; #define CC_TYPE_DISPLAY_CONFIG (cc_display_config_get_type ()) G_DECLARE_DERIVABLE_TYPE (CcDisplayConfig, cc_display_config, CC, DISPLAY_CONFIG, GObject) struct _CcDisplayConfigClass { GObjectClass parent_class; GList* (*get_monitors) (CcDisplayConfig *self); gboolean (*is_applicable) (CcDisplayConfig *self); gboolean (*equal) (CcDisplayConfig *self, CcDisplayConfig *other); gboolean (*apply) (CcDisplayConfig *self, GError **error); gboolean (*is_cloning) (CcDisplayConfig *self); void (*set_cloning) (CcDisplayConfig *self, gboolean clone); GList* (*get_cloning_modes) (CcDisplayConfig *self); gboolean (*is_layout_logical) (CcDisplayConfig *self); void (*set_minimum_size) (CcDisplayConfig *self, int width, int height); gboolean (*is_scaled_mode_valid) (CcDisplayConfig *self, CcDisplayMode *mode, double scale); gboolean (*layout_use_ui_scale) (CcDisplayConfig *self); gint (*get_legacy_ui_scale) (CcDisplayConfig *self); }; GList* cc_display_config_get_monitors (CcDisplayConfig *config); GList* cc_display_config_get_ui_sorted_monitors (CcDisplayConfig *config); int cc_display_config_count_useful_monitors (CcDisplayConfig *config); gboolean cc_display_config_is_applicable (CcDisplayConfig *config); gboolean cc_display_config_equal (CcDisplayConfig *config, CcDisplayConfig *other); gboolean cc_display_config_apply (CcDisplayConfig *config, GError **error); gboolean cc_display_config_is_cloning (CcDisplayConfig *config); void cc_display_config_set_cloning (CcDisplayConfig *config, gboolean clone); GList* cc_display_config_get_cloning_modes (CcDisplayConfig *config); void cc_display_config_set_mode_on_all_outputs (CcDisplayConfig *config, CcDisplayMode *mode); gboolean cc_display_config_is_layout_logical (CcDisplayConfig *self); void cc_display_config_set_minimum_size (CcDisplayConfig *self, int width, int height); gboolean cc_display_config_is_scaled_mode_valid (CcDisplayConfig *self, CcDisplayMode *mode, double scale); gboolean cc_display_config_layout_use_ui_scale (CcDisplayConfig *self); gint cc_display_config_get_legacy_ui_scale (CcDisplayConfig *self); double cc_display_config_get_maximum_scaling (CcDisplayConfig *self); void cc_display_config_set_fractional_scaling (CcDisplayConfig *self, gboolean enabled); gboolean cc_display_config_get_fractional_scaling (CcDisplayConfig *self); const char* cc_display_monitor_get_display_name (CcDisplayMonitor *monitor); gboolean cc_display_monitor_is_active (CcDisplayMonitor *monitor); void cc_display_monitor_set_active (CcDisplayMonitor *monitor, gboolean active); const char* cc_display_monitor_get_connector_name (CcDisplayMonitor *monitor); CcDisplayRotation cc_display_monitor_get_rotation (CcDisplayMonitor *monitor); void cc_display_monitor_set_rotation (CcDisplayMonitor *monitor, CcDisplayRotation r); gboolean cc_display_monitor_supports_rotation (CcDisplayMonitor *monitor, CcDisplayRotation rotation); void cc_display_monitor_get_physical_size (CcDisplayMonitor *monitor, int *w, int *h); gboolean cc_display_monitor_is_builtin (CcDisplayMonitor *monitor); gboolean cc_display_monitor_is_primary (CcDisplayMonitor *monitor); void cc_display_monitor_set_primary (CcDisplayMonitor *monitor, gboolean primary); guint32 cc_display_monitor_get_id (CcDisplayMonitor *monitor); gboolean cc_display_monitor_supports_underscanning (CcDisplayMonitor *monitor); gboolean cc_display_monitor_get_underscanning (CcDisplayMonitor *monitor); void cc_display_monitor_set_underscanning (CcDisplayMonitor *monitor, gboolean underscanning); CcDisplayMode* cc_display_monitor_get_mode (CcDisplayMonitor *monitor); void cc_display_monitor_get_geometry (CcDisplayMonitor *monitor, int *x, int *y, int *width, int *height); void cc_display_monitor_get_disabled_geometry (CcDisplayMonitor *monitor, int *x, int *y, int *width, int *height); void cc_display_monitor_set_disabled_geometry (CcDisplayMonitor *monitor, int x, int y, int width, int height); GList* cc_display_monitor_get_modes (CcDisplayMonitor *monitor); CcDisplayMode* cc_display_monitor_get_preferred_mode (CcDisplayMonitor *monitor); double cc_display_monitor_get_scale (CcDisplayMonitor *monitor); void cc_display_monitor_set_scale (CcDisplayMonitor *monitor, double s); void cc_display_monitor_set_mode (CcDisplayMonitor *monitor, CcDisplayMode *mode); void cc_display_monitor_set_position (CcDisplayMonitor *monitor, int x, int y); gboolean cc_display_monitor_is_useful (CcDisplayMonitor *monitor); gboolean cc_display_monitor_is_usable (CcDisplayMonitor *monitor); void cc_display_monitor_set_usable (CcDisplayMonitor *monitor, gboolean is_usable); int cc_display_monitor_get_ui_number (CcDisplayMonitor *monitor); const char* cc_display_monitor_get_ui_name (CcDisplayMonitor *monitor); const char* cc_display_monitor_get_ui_number_name (CcDisplayMonitor *monitor); char* cc_display_monitor_dup_ui_number_name (CcDisplayMonitor *monitor); void cc_display_mode_get_resolution (CcDisplayMode *mode, int *width, int *height); const double* cc_display_mode_get_supported_scales (CcDisplayMode *self); double cc_display_mode_get_preferred_scale (CcDisplayMode *self); gboolean cc_display_mode_is_interlaced (CcDisplayMode *mode); int cc_display_mode_get_freq (CcDisplayMode *mode); double cc_display_mode_get_freq_f (CcDisplayMode *mode); G_END_DECLS cinnamon-control-center-6.4.1/panels/display/cc-display-config-dbus.h0000664000175000017500000000270414724311620024535 0ustar fabiofabio/* * Copyright (C) 2017 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #pragma once #include #include "cc-display-config.h" G_BEGIN_DECLS #define CC_TYPE_DISPLAY_MODE_DBUS (cc_display_mode_dbus_get_type ()) G_DECLARE_FINAL_TYPE (CcDisplayModeDBus, cc_display_mode_dbus, CC, DISPLAY_MODE_DBUS, CcDisplayMode) #define CC_TYPE_DISPLAY_MONITOR_DBUS (cc_display_monitor_dbus_get_type ()) G_DECLARE_FINAL_TYPE (CcDisplayMonitorDBus, cc_display_monitor_dbus, CC, DISPLAY_MONITOR_DBUS, CcDisplayMonitor) #define CC_TYPE_DISPLAY_CONFIG_DBUS (cc_display_config_dbus_get_type ()) G_DECLARE_FINAL_TYPE (CcDisplayConfigDBus, cc_display_config_dbus, CC, DISPLAY_CONFIG_DBUS, CcDisplayConfig) G_END_DECLS cinnamon-control-center-6.4.1/panels/display/cinnamon-display-panel.desktop0000664000175000017500000002624314724311620026077 0ustar fabiofabio[Desktop Entry] Exec=cinnamon-settings display Icon=cs-display Terminal=false Type=Application StartupNotify=true Categories=GTK;Settings;HardwareSettings;X-Cinnamon-Settings-Panel; OnlyShowIn=X-Cinnamon; X-Cinnamon-Settings-Panel=display Name=Display Name[am]=įˆ›įˆ³į‹« Name[ar]=العرض Name[ast]=Pantalla Name[ay]=UƱjachawi Name[az]=Gƶstərmə Name[be]=Š”Ń‹ŃŠæŠ»ŃŠ¹ Name[be@latin]=Š”Ń‹ŃŠæŠ»ŃŠ¹ Name[bg]=Екран Name[br]=SkrammaƱ Name[ca]=Pantalla Name[ca@valencia]=Pantalla Name[cs]=Displej Name[cy]=Dangosydd Name[da]=SkƦrm Name[de]=Bildschirm Name[el]=Προβολή Name[eo]=Montri Name[es]=Visualización Name[et]=Kuva Name[eu]=Pantaila Name[fa]=ŲµŁŲ­Ł‡ā€ŒŁ†Ł…Ų§ŪŒŲ“ Name[fi]=NƤyttƶ Name[fr]=Affichage Name[fr_CA]=Ɖcran Name[gd]=Uidheam-taisbeanaidh Name[gl]=Pantalla Name[he]=צג Name[hi]=ą¤”ą¤æą¤øą„ą¤Ŗą„ą¤²ą„‡ Name[hr]=Zaslon Name[hu]=Kijelző Name[ia]=Schermo Name[id]=Tampilan Name[ie]=Monitor Name[is]=SkjĆ”r Name[it]=Monitor Name[ja]=ćƒ‡ć‚£ć‚¹ćƒ—ćƒ¬ć‚¤ Name[ka]=įƒ“įƒ įƒįƒ˜įƒ” įƒ©įƒ•įƒ”įƒœįƒ”įƒ‘įƒ Name[kab]=Sken Name[kk]=Дисплей Name[ko]=ė””ģŠ¤ķ”Œė ˆģ“ Name[ku]=Nîşandan Name[la]=Ostenditor Name[lt]=Ekranas Name[nb]=Skjerm Name[nds]=Bildschirm Name[nl]=Beeldscherm Name[oc]=Afichar Name[pl]=Ekran Name[pt]=EcrĆ£ Name[pt_BR]=Monitor Name[ro]=Afișare Name[ru]=ŠœŠ¾Š½ŠøŃ‚Š¾Ń€ Name[rue]=Дісплей Name[sc]=Ischermu Name[sk]=Obrazovka Name[sl]=Zaslon Name[sq]=Ekrani Name[sr]=ŠŸŃ€ŠøŠŗŠ°Š· Name[sr@latin]=Ekran Name[sv]=SkƤrm Name[ta]=ą®•ą®¾ą®£ąÆą®Ŗą®æ Name[th]=ąøˆąø­ą¹ąøŖąø”ąø‡ąøœąø„ Name[tr]=Ekran Name[uk]=Дисплей Name[ur]=ŚˆŲ³Ł¾Ł„Ū’ Name[uz]=Ekran Name[uz@cyrillic]=Ekran Name[vi]=Hiển thị Name[zh_CN]=显示 Name[zh_HK]=锯示器 Name[zh_TW]=锯示器 Comment=Change resolution and position of monitors and projectors Comment[am]=የ įˆžįŠ’į‰°įˆ­ įˆŖį‹žįˆŠįˆ½įŠ•: ቦታ įŠ„įŠ“ įˆ›įˆ³į‹« įˆ˜į‰€į‹ØįˆŖį‹« Comment[ar]=تغيير الدقة ووضع الؓاؓات ŁˆŲ£Ų¬Ł‡Ų²Ų© العرض Comment[ast]=Camuda la resolución y posición de los monitores y proyeutores Comment[ay]=Munituranaka ukhamaraki uƱtayirinaka (proyectores) ukan qawqha ch'aqanakanisa ukhamaraki kawkhans uskuta uk mayjachaƱa Comment[az]=Gƶstərənlərin, işgƶstərənlərin Ƨƶzünürlüyünü, yerini dəyiş Comment[be]=Š—Š¼ŃŠ½Ń–Ń†ŃŒ разрозненне і ŠæŠ°Š·Ń–Ń†Ń‹ŃŽ Š¼Š°Š½Ń–Ń‚Š¾Ń€Š°Ńž і ŠæŃ€Š°ŠµŠŗŃ‚Š°Ń€Š°Ńž Comment[be@latin]=Š—Š¼ŃŠ½Ń–Ń†ŃŒ разрозненне і ŠæŠ°Š·Ń–Ń†Ń‹ŃŽ Š¼Š°Š½Ń–Ń‚Š¾Ń€Š°Ńž і ŠæŃ€Š°ŠµŠŗŃ‚Š°Ń€Š°Ńž Comment[bg]=ŠŸŃ€Š¾Š¼ŃŠ½Š° на разГелителната способност Šø положението на екраните Šø проекторите Comment[bs]=Promijeni rezoluciju i poziciju monitora i projektora Comment[ca]=Canvieu la resolució i la posició dels monitors i projectors Comment[ca@valencia]=Canvieu la resolució i la posició dels monitors i projectors Comment[cs]=Změnit rozliÅ”enĆ­ a polohu monitorÅÆ a projektorÅÆ Comment[cy]=Newid cydraniad a safle dangosyddion a thaflynyddion Comment[da]=Ɔndr oplĆøsning og placering af skƦrme og projektorer Comment[de]=Auflƶsung und Anordnung der Bildschirme und Projektoren Ƥndern Comment[el]=Αλλαγή της Ī±Ī½Ī±Ī»ĻĻƒĪ·Ļ‚ και της ĪøĪ­ĻƒĪ·Ļ‚ των ĪæĪøĪæĪ½ĻŽĪ½ και του προτζέκτορα Comment[eo]=Ŝanĝi distingivon kaj posicion de ekranoj kaj projekciiloj Comment[es]=Cambie la resolución y la posición de monitores y proyectores Comment[et]=Kuvarite ja projektorite eraldusvƵime ja asukoha muutmine Comment[eu]=Aldatu pantaila eta proiektagailuen bereizmena eta posizioa Comment[fa]=تغییر وضوح و Ł…ŁˆŁ‚Ų¹ŪŒŲŖ Ł†Ł…Ų§ŪŒŲ“ŚÆŲ± و پروژکتور ها Comment[fi]=Vaihda nƤyttƶjen ja projektorien tarkkuutta sekƤ sijaintia Comment[fr]=Modifier la rĆ©solution et la position des Ć©crans et projecteurs Comment[fr_CA]=Modifier la rĆ©solution et la position des Ć©crans et projecteurs Comment[gd]=Atharraich dùmhlachd-bhreacaidh agus ionad nam monatairean agus nam proiseactaran Comment[gl]=Cambiar a resolución e a posición dos monitores e proxectores Comment[he]=שינוי הפרדה והמיקום של הצגים ×•×”×ž×§×Ø× ×™× Comment[hi]=ą¤®ą„‰ą¤Øą¤æą¤Ÿą¤° ą¤ą¤µą¤‚ ą¤Ŗą„ą¤°ą„‹ą¤œą„‡ą¤•ą„ą¤Ÿą¤° ą¤¹ą„‡ą¤¤ą„ ą¤°ą„‡ą¤œą„‹ą¤²ą„ą¤¶ą¤Ø व ą¤øą„ą¤„ą¤æą¤¤ą¤æ ą¤¬ą¤¦ą¤²ą„‡ą¤‚ Comment[hr]=Promijenite razlučivost i položaj zaslona i projektora Comment[hu]=Kijelzők Ć©s projektorok felbontĆ”sĆ”nak Ć©s elhelyezĆ©sĆ©nek módosĆ­tĆ”sa Comment[ia]=Cambiar le resolution e le position de monitores e projectores Comment[id]=Ubah resolusi dan posisi monitor dan projektor Comment[ie]=Cambiar un resolution e position de monitores e projectores Comment[is]=Breyttu upplausn og stƶưu skjĆ”a og myndvarpa Comment[it]=Cambia la risoluzione e la posizione dei monitor e dei proiettori Comment[ja]=ćƒ¢ćƒ‹ć‚æćƒ¼ć‚„ćƒ—ćƒ­ć‚øć‚§ć‚Æć‚æćƒ¼ć®č§£åƒåŗ¦ćØä½ē½®ć‚’å¤‰ę›“ć—ć¾ć™ Comment[kab]=Beddel tabadut d wadeg n iferdisen n yimagaren Comment[kk]=ŠœŠ¾Š½ŠøŃ‚Š¾Ń€Š¼ŠµŠ½ проекторГың ŃŠŗŃ€Š°Š½ рұқсатын және Š¾Ń€Š½Š°Š»Š°ŃŃƒŃ‹Š½ Ó©Š·Š³ŠµŃ€Ń‚Ńƒ Comment[ko]=ėŖØė‹ˆķ„° ė° ķ”„ė”œģ ķ„°ģ˜ ķ•“ģƒė„ģ™€ ģœ„ģ¹˜ė„¼ ė°”źæ‰ė‹ˆė‹¤ Comment[lt]=Pakeisti ekranų ar projektorių raiÅ”ką ir poziciją Comment[lv]=MainÄ«t monitoru un projektoru izŔķirtspēju un izvietojumu Comment[ms]=Ubah resolusi dan kedudukan monitor dan projektor Comment[nb]=Endre opplĆøsning og posisjon av skjermer og prosjektorer Comment[nds]=Ƅnderung der Auflƶsung und Position für Monitore und Projektoren Comment[nl]=Resolutie en positie van beeldschermen en projectoren wijzigen Comment[oc]=Modificar la resolucion e la posicion dels ecrans e projectors Comment[pl]=Zmiana rozdzielczości i położenia monitorów oraz projektorów Comment[pt]=Alterar resolução e posição dos monitores e projetores Comment[pt_BR]=Mudar a resolução e posição dos monitores e projetores Comment[ro]=Schimbați rezoluția și poziția monitoarelor și a proiectoarelor Comment[ru]=Š˜Š·Š¼ŠµŠ½ŠøŃ‚ŃŒ Ń€Š°Š·Ń€ŠµŃˆŠµŠ½ŠøŠµ Šø ŠæŠ¾Š·ŠøŃ†ŠøŃŽ мониторов, проекторов Comment[sk]=ZmeniÅ„ rozlĆ­Å”enie a pozĆ­ciu monitorov a projektorov Comment[sl]=Spremeni ločljivost in položaj zaslonov in projektorjev Comment[sq]=Ndrysho rezolucionin dhe pozicionin e monitorĆ«ve dhe projektorĆ«ve Comment[sr]=ŠŸŃ€Š¾Š¼ŠµŠ½ŠøŃ‚Šµ Ń€Š°Š·Š¼ŠµŃ€Ńƒ Šø места екрана Šø ŠæŃ€Š¾Ń˜ŠµŠŗŃ‚Š¾Ń€Š° Comment[sr@latin]=Promenite rezoluciju i mesta ekrana i projektora Comment[sv]=Ƅndra upplƶsning och position fƶr skƤrmar och projektorer Comment[tg]=Тағйир ГоГани возеҳӣ ва Š¼Š°Š²Ņ›ŠµŠøŃŃ‚Šø мониторҳо ва проекторҳо Comment[th]=ą¹€ąø›ąø„ąøµą¹ˆąø¢ąø™ąø„ąø§ąø²ąø”ąø„ąø°ą¹€ąø­ąøµąø¢ąø”ą¹ąø„ąø°ąø•ąø³ą¹ąø«ąø™ą¹ˆąø‡ąø‚ąø­ąø‡ąøˆąø­ąø ąø²ąøžą¹ąø„ąø°ą¹€ąø„ąø£ąø·ą¹ˆąø­ąø‡ąø‰ąø²ąø¢ Comment[tr]=Monitƶr ve projektƶr Ƨƶzünürlüğü ve konumunu değiştir Comment[uk]=Змінити Ń€Š¾Š·Š“Ń–Š»ŃŒŠ½Ń–ŃŃ‚ŃŒ і Ń€Š¾Š·Ń‚Š°ŃˆŃƒŠ²Š°Š½Š½Ń моніторів та проєкторів Comment[ur]=Ł…Ų§Ł†ŪŒŁ¹Ų±ŁˆŚŗ اور پراجیکٹروں کی Ų±ŪŒŲ²ŁˆŁ„ŁˆŲ“Ł† اور Ł¾ŁˆŲ²ŪŒŲ“Ł† ŲŖŲØŲÆŪŒŁ„ کریں Comment[uz]=Monitorlar va proektorlar uchun ruxsat berilgan parametrlar (resolution) va ularning joyini oā€˜zgartirish Comment[uz@cyrillic]=Monitorlar va proektorlar uchun ruxsat berilgan parametrlar (resolution) va ularning joyini oā€˜zgartirish Comment[vi]=Đổi độ phĆ¢n giįŗ£i vĆ  vị trĆ­ mĆ n hƬnh/mĆ”y chiįŗæu Comment[zh_CN]=ę›“ę”¹ę˜¾ē¤ŗå™Øå’ŒęŠ•å½±ä»Ŗēš„åˆ†č¾ØēŽ‡å’Œä½ē½® Comment[zh_HK]=č®Šę›“é”Æē¤ŗå™Øčˆ‡ęŠ•å½±ę©Ÿēš„č§£åƒåŗ¦å’Œä½ē½® Comment[zh_TW]=č®Šę›“é”Æē¤ŗå™Øčˆ‡ęŠ•å½±ę©Ÿēš„č§£ęžåŗ¦čˆ‡ä½ē½® Keywords=Panel;Projector;xrandr;Screen;Resolution;Refresh; Keywords[ast]=Panel;Proyeutor;xrandr;Pantalla;Resolución;Refrescar; Keywords[be]=ŠæŠ°Š½ŃŠ»ŃŒ;праектар;xrandr;ŃŠŗŃ€Š°Š½;памер;разрозненне;Ń€Š°Š·Š“Š·ŃŠ»ŃŠ»ŃŒŠ½Š°ŃŃ†ŃŒ;Š°Š±Š½Š°Š²Ń–Ń†ŃŒ; Keywords[be@latin]=ŠæŠ°Š½ŃŠ»ŃŒ;праектар;xrandr;ŃŠŗŃ€Š°Š½;памер;разрозненне;Ń€Š°Š·Š“Š·ŃŠ»ŃŠ»ŃŒŠ½Š°ŃŃ†ŃŒ;Š°Š±Š½Š°Š²Ń–Ń†ŃŒ; Keywords[ca]=Panell;Projector;Xrandr;Pantalla;Resolució;Actualitzar; Keywords[ca@valencia]=Panell;Projector;Xrandr;Pantalla;Resolució;Actualitzar; Keywords[cs]=Panel;projektor;xrandr;obrazovka;rozliÅ”enĆ­;obnovenĆ­; Keywords[cy]=Panel;Taflunydd;xrandr;Sgrin;Cydraniad;Adnewyddu; Keywords[da]=Panel;Projektor;xrandr;SkƦrm;OplĆøsning;Genopfrisk;GenindlƦs; Keywords[de]=Panel;Projector;xrandr;Screen;Resolution;Refresh;Paneel;Projektor;xrandr;Bildschirm;Auflƶsung;Aktualisieren;Auffrischen; Keywords[el]=Πίνακας;Προβολέας;xrandr;Οθόνη;Ī‘Ī½Ī¬Ī»Ļ…ĻƒĪ·;Ī‘Ī½Ī±Ī½Ī­Ļ‰ĻƒĪ·; Keywords[eo]=Panelo;Projekciilo;xrandr;Ekrano;Distingivo;Aktualigi; Keywords[es]=Panel;Proyector;xrandr;Pantalla;Resolución;Refresco; Keywords[et]=Paneel;projektor;xrandr;ekraan;eraldusvƵime;vƤrskendus; Keywords[eu]=Panela;Proiektagailua;xrandr;Pantaila;Bereizmena;Freskatu; Keywords[fa]=Ł¾Ł†Ł„ŲŒ پروژکتور، xrandr، ŲµŁŲ­Ł‡ŲŒ وضوح، ŲŖŲ§Ų²Ł‡ā€ŒŲ³Ų§Ų²ŪŒ; Keywords[fi]=Paneeli;Projektori;xrandr;NƤyttƶ;Resoluutio;Virkistys; Keywords[fr]=Paneau;Projecteur;xrandr;Ecran;RĆ©solution;Raffraichir; Keywords[fr_CA]=Paneau;Projecteur;xrandr;Ecran;RĆ©solution;Raffraichir; Keywords[he]=לוח;×ž×§×Ø×Ÿ;xrandr;×ž×Ø×§×¢;הפרדה;×Ø×¢× ×•×Ÿ; Keywords[hi]=ą¤Ŗą„ˆą¤Øą¤²;ą¤Ŗą„ą¤°ą„‹ą¤œą„‡ą¤•ą„ą¤Ÿą¤°;xrandr;ą¤øą„ą¤•ą„ą¤°ą„€ą¤Ø;ą¤°ą¤æą¤œą¤¼ą„‰ą¤²ą„ą¤Æą„‚ą¤¶ą¤Ø;ą¤°ą¤æą¤«ą„ą¤°ą„‡ą¤¶; Keywords[hr]=Panel;Projektor;xrandr;Zaslon;Razlučivost;Osvježavanje; Keywords[hu]=Panel;Projektor;xrandr;KĆ©pernyő;FelbontĆ”s;FrissĆ­tĆ©s;Monitor;Ɖjszakai;fĆ©ny;redshift;szĆ­n;napkelte;napnyugta;Panel;Projector;xrandr;Screen;Resolution;Refresh; Keywords[ia]=Panello;Projector;xrandr;Schermo;Resolution;Refrescar; Keywords[id]=Panel;Proyektor;xrandr;Layar;Resolusi;Segarkan; Keywords[is]=Panell;SkjĆ”varpi;xrandr;SkjĆ”r;Upplausn;UppfƦrslutƭưni; Keywords[it]=Pannello;Proiettore;xrandr;Schermo;Risoluzione;Refresh; Keywords[ja]=Panel;Projector;xrandr;Screen;Resolution;Refresh;ćƒ‘ćƒćƒ«;ćƒ—ćƒ­ć‚øć‚§ć‚Æć‚æćƒ¼;ć‚¹ć‚ÆćƒŖćƒ¼ćƒ³;ē”»é¢;č§£åƒåŗ¦;ćƒŖćƒ•ćƒ¬ćƒƒć‚·ćƒ„; Keywords[ko]=ķŒØė„;ķ”„ė”œģ ķ„°;xrandr;화멓;ķ•“ģƒė„;새딜 고침; Keywords[nb]=Panel;Prosjektor;xrandr;Skjerm;OpplĆøsning;Oppdater; Keywords[nl]=Paneel;Projector;xrandr;Scherm;Resolutie;Verversen; Keywords[oc]=PanĆØl;Projector;Xrandr;Ecran;Resolucion;Actualizar; Keywords[pl]=Panel;Projektor;xrandr;Ekran;Rozdzielczość;Odświeżanie; Keywords[pt]=Painel;Projetor;xrandr;EcrĆ£;Resolução;Atualizar; Keywords[pt_BR]=Painel;Projetor;xrandr;Tela;Resolução;Atualizar; Keywords[ro]=Panou;proiector;xrandr;ecran;rezoluție;reĆ®mprospătare; Keywords[ru]=Панель;ŠŸŃ€Š¾ŠµŠŗŃ‚Š¾Ń€;xrandr;Экран;Š Š°Š·Ń€ŠµŃˆŠµŠ½ŠøŠµ;ŠžŠ±Š½Š¾Š²ŠøŃ‚ŃŒ; Keywords[sk]=Panel;Projektor;xrandr;Obrazovka;RozlĆ­Å”enie;ObnoviÅ„; Keywords[sl]=PloŔča;projektor;xrandr;zaslon;ločljivost;osveževanje; Keywords[sv]=Panel;Projektor;xrandr;SkƤrm;Upplƶsning;Uppdatera; Keywords[tr]=Panel;Projektƶr;xrandr;Ekran;Ƈƶzünürlük;Tazeleme; Keywords[uk]=Панель;ŠŸŃ€Š¾ŠµŠŗŃ‚Š¾Ń€;xrandr;Екран;Š Š¾Š·Š“Ń–Š»ŃŒŠ½Š° Š·Š“Š°Ń‚Š½Ń–ŃŃ‚ŃŒ;ŠžŠ½Š¾Š²ŠøŃ‚Šø; Keywords[uz]=Panel;Proyektor;xrandr;Ekran;Ruxsat;Yangilash; Keywords[uz@cyrillic]=Panel;Proyektor;xrandr;Ekran;Ruxsat;Yangilash; Keywords[vi]=Bįŗ£ng panel;MĆ”y chiįŗæu;xrandr;MĆ n hƬnh;Độ phĆ¢n giįŗ£i;LĆ m mį»›i; Keywords[zh_TW]=č§øęŽ§ęæ;ęŠ•å½±ę©Ÿ;xrandr;čž¢å¹•;č§£ęžåŗ¦;ę›“ę–°ēŽ‡; cinnamon-control-center-6.4.1/panels/display/cc-display-config-manager.c0000664000175000017500000000344714724311620025212 0ustar fabiofabio/* * Copyright (C) 2016 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include "cc-display-config-manager.h" G_DEFINE_TYPE (CcDisplayConfigManager, cc_display_config_manager, G_TYPE_OBJECT) enum { CONFIG_MANAGER_CHANGED, N_CONFIG_MANAGER_SIGNALS, }; static guint config_manager_signals[N_CONFIG_MANAGER_SIGNALS] = { 0 }; static void cc_display_config_manager_init (CcDisplayConfigManager *self) { } static void cc_display_config_manager_class_init (CcDisplayConfigManagerClass *klass) { config_manager_signals[CONFIG_MANAGER_CHANGED] = g_signal_new ("changed", CC_TYPE_DISPLAY_CONFIG_MANAGER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } void _cc_display_config_manager_emit_changed (CcDisplayConfigManager *self) { g_signal_emit (self, config_manager_signals[CONFIG_MANAGER_CHANGED], 0); } CcDisplayConfig * cc_display_config_manager_get_current (CcDisplayConfigManager *self) { return CC_DISPLAY_CONFIG_MANAGER_GET_CLASS (self)->get_current (self); } cinnamon-control-center-6.4.1/ChangeLog0000664000175000017500003037646314724311620017004 0ustar fabiofabio# Generated by Makefile. Do not edit. commit d303d9f36064c5dcf523c5a545a6542e635bbf3d Author: Bastien Nocera Date: Wed Nov 14 12:52:56 2012 +0100 3.6.3 NEWS | 20 +++++++++++++++++--- configure.ac | 2 +- 2 files changed, 18 insertions(+), 4 deletions(-) commit 05f19e36a4b0c7516858126250a8d1a5af46b9a0 Author: Bastien Nocera Date: Wed Nov 14 13:07:23 2012 +0100 build: Fix distcheck Left-over files from update-icon-cache shouldn't be created in the first place when running distcheck. Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 001156637a858969eee45e868a03a294c559093b Author: Debarshi Ray Date: Sat Nov 10 18:48:25 2012 +0100 bluetooth: Align the device list with the all settings button Fixes: https://bugzilla.gnome.org/688055 panels/bluetooth/bluetooth.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 7a22f0605c5099079828d0cffbdf6698fa1fe8f0 Author: Debarshi Ray Date: Sat Nov 10 18:42:01 2012 +0100 online-accounts: Align the accounts list with the all settings button Fixes: https://bugzilla.gnome.org/668312 panels/online-accounts/online-accounts.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit b23aef0aef77c3844c6a665713c68f96b20fb628 Author: Debarshi Ray Date: Fri Nov 9 19:12:46 2012 +0100 online-accounts: Don't preselect the first item when adding an account Fixes: https://bugzilla.gnome.org/687875 panels/online-accounts/cc-online-accounts-add-account-dialog.c | 4 ++++ 1 file changed, 4 insertions(+) commit 725aecc9e38c8a817aa62d676ced466aeeeeb8f1 Author: Bastien Nocera Date: Fri Nov 9 11:32:52 2012 +0100 network: Avoid type clashes with the Bluetooth panel Done with: sed -i -e 's/RfkillGlib/CcRfkillGlib/g' \ -e 's/RFKILL_GLIB/CC_RFKILL_GLIB/g' \ -e 's/rfkill_glib/cc_rfkill_glib/g' \ -e 's/RFKILL_TYPE_GLIB/CC_RFKILL_TYPE_GLIB/g' \ rfkill-glib.[ch] cc-network-panel.c This would need to be done when we reset the copy/paste from gnome-bluetooth. panels/network/cc-network-panel.c | 10 ++++---- panels/network/rfkill-glib.c | 48 +++++++++++++++++++-------------------- panels/network/rfkill-glib.h | 44 +++++++++++++++++------------------ 3 files changed, 51 insertions(+), 51 deletions(-) commit 7aef2fb307a9ff9c32fbe9dc6bc36e1eef5e72ab Author: Bastien Nocera Date: Fri Nov 9 11:16:07 2012 +0100 network: Make sure Airplane mode switch everything off And not just wireless. We need to use /dev/rfkill directly to make sure that all the devices (3G, GPS, Bluetooth, etc.) get switched off correctly when airplane mode is on. https://bugzilla.gnome.org/show_bug.cgi?id=675778 panels/network/Makefile.am | 5 +- panels/network/cc-network-panel.c | 94 ++++++++++-- panels/network/rfkill-glib.c | 299 ++++++++++++++++++++++++++++++++++++++ panels/network/rfkill-glib.h | 65 +++++++++ panels/network/rfkill.h | 107 ++++++++++++++ 5 files changed, 560 insertions(+), 10 deletions(-) commit 627238003890e18069b90e8e2935f9548bf96f98 Author: Bastien Nocera Date: Fri Nov 9 10:20:29 2012 +0100 network: Make sure flight mode is always visible Because it's not just about disabling the network, it needs to disable a host of other wireless devices, and those need to be blocked even if you end up plugging them into your computer. panels/network/cc-network-panel.c | 54 +-------------------------------------- 1 file changed, 1 insertion(+), 53 deletions(-) commit c8837d2650c8558492e8f3aeb2362c7a7118c517 Author: Bastien Nocera Date: Thu Nov 8 18:52:28 2012 +0100 bluetooth: Use spinner when connecting Rather than having an unusable switch (which wouldn't represent the real state of the connection), show a spinner until the connection is finished doing. panels/bluetooth/bluetooth.ui | 2 +- panels/bluetooth/cc-bluetooth-panel.c | 30 ++++++++++++++++++++++++++---- 2 files changed, 27 insertions(+), 5 deletions(-) commit f299846ba76a8c2d712414b9380dc4adfc1a545a Author: Bastien Nocera Date: Thu Nov 8 18:36:33 2012 +0100 bluetooth: Simplify ->finalize panels/bluetooth/cc-bluetooth-panel.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) commit d309183dd352cef5e075070caaac8ac050b4d11d Author: Bastien Nocera Date: Thu Nov 8 18:31:07 2012 +0100 bluetooth: Fix main switch acting bizarrely The only time we were looking at the powered state of the adapter is when the killswitch state was changing. Except that we're fast enough that bluetoothd didn't have time to power up the adapter, so its state was unpowered, which we would set the switch to. The switch was off, the adapter was on. We fix that problem by tracking the powered state of the adapter separately. https://bugzilla.redhat.com/show_bug.cgi?id=841881 panels/bluetooth/cc-bluetooth-panel.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) commit 68917676a077ad36ae3c7570afe3789bdd6fea65 Author: Bastien Nocera Date: Thu Nov 8 18:11:47 2012 +0100 bluetooth: Add UI code for a spinner during the connection panels/bluetooth/bluetooth.ui | 45 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) commit 2dc30a08d5a4844c1f9028356c44440d2be62eaf Author: Bastien Nocera Date: Thu Nov 8 18:00:03 2012 +0100 bluetooth: Remove unused variable panels/bluetooth/cc-bluetooth-panel.c | 2 -- 1 file changed, 2 deletions(-) commit f9f6e7525e55059361ca15dbda7826105eb3fdbc Author: Bastien Nocera Date: Thu Nov 8 17:56:26 2012 +0100 bluetooth: Avoid possible loops when Connection fails If we switch "Connection" on via the switch, the disabling on failure will create a loop where it always tries to connect again. Break that loop. panels/bluetooth/cc-bluetooth-panel.c | 46 ++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 4 deletions(-) commit 80c1f5a79da01091f93eb48ed686192781852efe Author: Marek Kasik Date: Thu Oct 18 11:35:14 2012 +0200 printers: Resolve symlink when passing a PPD to CUPS root is not able to resolve symlinks in /tmp/ created by ordinary users because of a new policy and PPDs got from CUPS are symlinks to /etc/cups/ppd/* placed to /tmp/. Since we need to pass PPD file of original printer to CUPS when renaming a printer we resolve given symlink and pass original filename to the CUPS. panels/printers/pp-utils.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) commit 8f3733dfca5ceb1d9862dbe2aa6137a57277dee6 Author: Bastien Nocera Date: Thu Nov 8 09:02:38 2012 +0100 NEWS: Prepare for release Last updated item is: d2e70f2d45d5460296d027c44e0e3aa86078329c NEWS | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) commit d2e70f2d45d5460296d027c44e0e3aa86078329c Author: Bastien Nocera Date: Mon Nov 5 09:35:13 2012 +0100 region: Fix possible crasher on startup When the X11Variant localed property was empty, variants[i] was being checked even though only variants[0] was defined (an empty string). ==17035== Invalid read of size 8 ==17035== at 0x26B9529A: on_localed_properties_changed (gnome-region-panel-system.c:339) ==17035== by 0x26B95546: localed_proxy_ready (gnome-region-panel-system.c:381) ==17035== by 0x8CA2589: g_simple_async_result_complete (gsimpleasyncresult.c:775) ==17035== by 0x8CA25BB: complete_in_idle_cb (gsimpleasyncresult.c:787) ==17035== by 0x94B8ED4: g_idle_dispatch (gmain.c:4806) ==17035== by 0x94B6890: g_main_dispatch (gmain.c:2715) ==17035== by 0x94B7440: g_main_context_dispatch (gmain.c:3219) ==17035== by 0x94B7623: g_main_context_iterate (gmain.c:3290) ==17035== by 0x94B76E7: g_main_context_iteration (gmain.c:3351) ==17035== by 0x8CDB1A1: g_application_run (gapplication.c:1620) ==17035== by 0x4083C6: main (control-center.c:256) ==17035== Address 0x13b92e18 is 0 bytes after a block of size 8 alloc'd ==17035== at 0x4A0883C: malloc (vg_replace_malloc.c:270) ==17035== by 0x94BE97B: standard_malloc (gmem.c:85) ==17035== by 0x94BEA04: g_malloc (gmem.c:159) ==17035== by 0x94BED2F: g_malloc_n (gmem.c:400) ==17035== by 0x94DB26A: g_strsplit (gstrfuncs.c:2281) ==17035== by 0x26B95169: on_localed_properties_changed (gnome-region-panel-system.c:319) ==17035== by 0x26B95546: localed_proxy_ready (gnome-region-panel-system.c:381) ==17035== by 0x8CA2589: g_simple_async_result_complete (gsimpleasyncresult.c:775) ==17035== by 0x8CA25BB: complete_in_idle_cb (gsimpleasyncresult.c:787) ==17035== by 0x94B8ED4: g_idle_dispatch (gmain.c:4806) ==17035== by 0x94B6890: g_main_dispatch (gmain.c:2715) ==17035== by 0x94B7440: g_main_context_dispatch (gmain.c:3219) panels/region/gnome-region-panel-system.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) commit 28bcf96598ed63a50235f4908d67a10d5c22be85 Author: Bastien Nocera Date: Mon Nov 5 09:34:37 2012 +0100 common: Quiet valgrind when checking lang codeset panels/common/gdm-languages.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit a9718601b62ef411e384a0eb332c10dd7accf97f Author: Pavol Klačanský Date: Sun Nov 4 11:27:58 2012 +0100 Updated slovak translation po/sk.po | 7268 ++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 4190 insertions(+), 3078 deletions(-) commit 59cd59945102e783557e81d872cd95c17eba1b38 Author: Jeremy Bicha Date: Fri Nov 2 21:04:11 2012 -0400 keyboard: Point help to more specific page https://bugzilla.gnome.org/show_bug.cgi?id=687486 panels/keyboard/cc-keyboard-panel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit c251e5962b510ca3b2869f4835078271e0460144 Author: Jeremy Bicha Date: Fri Nov 2 20:50:42 2012 -0400 shell: Add F1 accelerator to show help https://bugzilla.gnome.org/show_bug.cgi?id=687485 shell/control-center.c | 3 +++ 1 file changed, 3 insertions(+) commit 07b76034f8cb26acf5d172cf5e40975b975c1f9b Author: Changwoo Ryu Date: Sat Nov 3 01:34:33 2012 +0900 Updated Korean translation po/ko.po | 151 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 74 insertions(+), 77 deletions(-) commit ad25b22e16bf2dacf0a157d0bfcb3c8d591d9055 Author: Jeremy Bicha Date: Wed Oct 31 06:46:28 2012 -0400 Show Printers & Region panels in Unity but hide Background Ubuntu plans to fork a separate Appearance panel this cycle so that Gnomebuntu can use the GNOME Background panel. I believe Ubuntu will try to use the Printers and Region & Language panels instead of system-config-printer & language-selector https://bugzilla.gnome.org/show_bug.cgi?id=687258 panels/background/gnome-background-panel.desktop.in.in | 2 +- panels/printers/gnome-printers-panel.desktop.in.in | 2 +- panels/region/gnome-region-panel.desktop.in.in | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) commit bf820b005f3ca9af74e26b7ef615ce37734885b0 Author: Sweta Kothari Date: Mon Oct 29 12:07:21 2012 +0530 Updated gujarati file po/gu.po | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) commit 1302e9c43cbbdd6ccd4384b71653b222229ec200 Author: SeĆ”n de BĆŗrca Date: Fri Oct 26 13:23:23 2012 -0600 Updated Irish translation. po/ga.po | 6440 ++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 3770 insertions(+), 2670 deletions(-) commit 32bfab1e526166f03f79132723cd98b2184fb0e8 Author: Bastien Nocera Date: Mon Oct 22 16:14:59 2012 +0200 3.6.2 NEWS | 21 +++++++++++++++++++++ configure.ac | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) commit e7722d9eea8f77334954c20b33e0234e16aaccb4 Author: Ondrej Holy Date: Fri Oct 19 10:12:58 2012 +0200 user-accounts: fix wrong sensitivity of the autologin combo https://bugzilla.gnome.org/show_bug.cgi?id=686383 panels/user-accounts/um-user-panel.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) commit 600ad0176bf4b20eaef8cbe78ecfee85c0ee0d19 Author: Olivier Fourdan Date: Fri Oct 19 15:41:43 2012 +0200 wacom: Update from gnome-settings-daemon panels/wacom/gsd-wacom-device.c | 61 +++++++++++++++++++++++++++++++++-------- panels/wacom/gsd-wacom-device.h | 2 ++ 2 files changed, 52 insertions(+), 11 deletions(-) commit b9b2f6a91fa45bcd387d468daf5d48c8343aa8b9 Author: Stef Walter Date: Thu Oct 18 18:37:24 2012 +0200 user-accounts: Don't have domains twice in the drop down If we discover domains again, don't add them twice to the drop down and confuse the user. This is especially important if we receive two realms from realmd for the same domain for use with different clients (ie: sssd/winbind). We only want to offer the first choice https://bugzilla.gnome.org/show_bug.cgi?id=686397 panels/user-accounts/um-account-dialog.c | 34 ++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) commit c16278d484d4d2f43da29b24dc4e20ddc3f8456c Author: Stef Walter Date: Thu Oct 18 18:40:00 2012 +0200 user-accounts: Set timeouts on all realmd interface proxies Without this, we can get timeout problems during joining a domain. This is a regression from when we refactored UmRealmManager to use GDBusObjectManagerClient. Make sure to call g_dbus_proxy_set_default_timeout() on all realmd interface proxies whenever they show up. https://bugzilla.gnome.org/show_bug.cgi?id=686390 panels/user-accounts/um-realm-manager.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) commit 24421985d74dac4f1531e66a2b8a86ae783efbb7 Author: Stef Walter Date: Fri Oct 19 10:55:02 2012 +0200 background: Fix compilation error Related to: https://bugzilla.redhat.com/show_bug.cgi?id=866973 panels/background/cc-background-panel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit d5af7612603a57983d06a277e9ac57709563c140 Author: Stef Walter Date: Sat Oct 6 12:17:21 2012 -0400 user-accounts: Remove the realmd version check The idea is that the realmd DBus API will remain stable from now on, so remove the version check. It was broken anyway. https://bugzilla.gnome.org/show_bug.cgi?id=685616 panels/user-accounts/um-realm-manager.c | 167 +++++++++++++++++--------------- 1 file changed, 91 insertions(+), 76 deletions(-) commit 32937d2b27fd4816cec88c20b4d5c88518c3af8a Author: Matthias Clasen Date: Tue Oct 16 14:36:16 2012 -0400 network: Fix 8021x connections We were always throwing away requests to connect to 8021x APs, due to missing braces. https://bugzilla.gnome.org/show_bug.cgi?id=686244 panels/network/cc-network-panel.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) commit e3a42c6ba87e4fe28479dd3bd65cdde22208f199 Author: Bastien Nocera Date: Wed Oct 17 09:38:05 2012 +0200 background: Fix crash when exiting panel too quickly The background capture would still be on-going, and we would crash poking at the now gone panel. https://bugzilla.redhat.com/show_bug.cgi?id=866973 panels/background/cc-background-panel.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) commit 38b7e045f1d439ea81429d5b414008960575c62b Author: Bastien Nocera Date: Wed Oct 17 09:37:10 2012 +0200 background: Handle copy cancellation correctly Make sure to avoid poking at the panel when the file copy is cancelled. panels/background/cc-background-panel.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) commit 8a27842d73ac265d56e22c8146d102967ded049e Author: Andreas Nesdal Date: Tue Oct 16 20:58:10 2012 +0200 Updated Norwegian Nynorsk translation (sync with Ubuntu) po/nn.po | 7646 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 4264 insertions(+), 3382 deletions(-) commit 78257521ed083529668f3bedf858441c5aaf17bf Author: Stef Walter Date: Sat Oct 6 13:01:03 2012 -0400 user-accounts: Recognize that some kerberos domains cannot be joined realmd supports discovering generic kerberos domains, which cannot be joined. https://bugzilla.gnome.org/show_bug.cgi?id=685618 panels/user-accounts/um-realm-manager.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) commit e581b12786e9424ea1dddc62787f5df823041b94 Author: Sweta Kothari Date: Mon Oct 15 17:19:09 2012 +0530 Updated gujarati file po/gu.po | 355 +++++++++++++++++++++++++-------------------------------------- 1 file changed, 140 insertions(+), 215 deletions(-) commit cf065fb8f420c2d6cda63838f60af7b577165dc7 Author: Ask H. Larsen Date: Mon Oct 15 06:35:16 2012 +0200 Updated Danish translation po/da.po | 328 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 164 insertions(+), 164 deletions(-) commit 242f2b268a43ee6c1db6a9aca4d7d1cf837ae627 Author: Kjartan Maraas Date: Sat Oct 13 12:33:43 2012 +0200 Updated Norwegian bokmĆ„l translation po/nb.po | 702 ++++++++++++++++++++++++++++++--------------------------------- 1 file changed, 330 insertions(+), 372 deletions(-) commit bb94a0166a6f764efd4b8ec0718f21254498d9ad Author: Arash Mousavi Date: Sat Oct 13 10:17:00 2012 +0330 L10N: Updated Persian translation po/fa.po | 729 +++++++++++++++++++++++++-------------------------------------- 1 file changed, 293 insertions(+), 436 deletions(-) commit 5fc63896eed325a297fef2a1daff4e6d755bfdd6 Author: Bastien Nocera Date: Thu Oct 11 13:13:32 2012 +0200 screen: Don't print a warning with no backlight device panels/screen/cc-screen-panel.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) commit fc7c41f4293a1d3e37c45eb6f2d95cd80dd52edc Author: Bastien Nocera Date: Tue Jun 12 18:22:28 2012 +0100 screen: Avoid accessing destroyed panel When we cancel the Brightness calls because the panel is getting destroyed, we shouldn't try to access panel widgets. https://bugzilla.gnome.org/show_bug.cgi?id=677963 panels/screen/cc-screen-panel.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) commit d4f24d6608a056da3addb51fbd0d80a373e66404 Author: Stef Walter Date: Sat Oct 6 12:27:34 2012 -0400 user-accounts: Complete discover on failure When realmd discovery doesn't return a domain, complete the discovery appropriately. Previously we would never complete. https://bugzilla.gnome.org/show_bug.cgi?id=685617 panels/user-accounts/um-realm-manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit e5b58ed51dbd19005d096aa48011d432d90f8dba Author: Gabor Kelemen Date: Mon Oct 8 23:33:54 2012 +0200 Remove excess colon from Hungarian translation po/hu.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit b8df7443f53e99249cb55d31b75fde755783ea08 Author: Gabor Kelemen Date: Mon Oct 8 22:57:14 2012 +0200 Use better wording in Hungarian translation po/hu.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 6d8ac68f7ee0fe69f70056841799a12dd70ac6eb Author: Bastien Nocera Date: Mon Oct 8 18:55:14 2012 +0200 3.6.1 NEWS | 44 ++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 2 +- 2 files changed, 45 insertions(+), 1 deletion(-) commit aef03317e81b358d0fc0c26e58bcad8334d11a17 Author: Bastien Nocera Date: Mon Oct 8 18:18:49 2012 +0200 background: Fix distcheck panels/background/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 8f0091c2c9c313ef360d022c2786bf512b3bcb7a Author: Rui Matos Date: Mon Oct 8 17:40:26 2012 +0200 region: Add the Marathi phonetic input source to the white list https://bugzilla.gnome.org/show_bug.cgi?id=685721 panels/region/gnome-region-panel-input.c | 1 + 1 file changed, 1 insertion(+) commit a9ba8f9bc4197ce53b58a29ccb74dac747d9598d Author: Wouter Bolsterlee Date: Sat Oct 6 15:07:52 2012 +0200 Updated Dutch translation po/nl.po | 3597 ++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 2305 insertions(+), 1292 deletions(-) commit 841ce5ace6b2699546b9ac37806ec09bbb093819 Author: Khoem Sokhem Date: Wed Oct 3 17:41:03 2012 +0200 [l10n] Added Khmer translation po/LINGUAS | 1 + po/km.po | 5784 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 5785 insertions(+) commit c35850649175044aa8d93e217d48884f49ac37fb Author: Bastien Nocera Date: Wed Oct 3 14:49:23 2012 +0200 network: Verify command-line arguments To avoid invalid bug reports ;) panels/network/cc-network-panel.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) commit ea0f359e4df4cdeb07c82e88469274002819852b Author: Matthias Clasen Date: Sun Sep 30 21:14:36 2012 -0400 network: Use a regular button for 'Connect to Hidden' The treeview is not really up to this level of custom UI. https://bugzilla.gnome.org/show_bug.cgi?id=684819 panels/network/net-device-wifi.c | 44 ++++++-------------------------------- panels/network/network-wifi.ui | 46 ++++++++++++++++++++++++++++++++-------- 2 files changed, 44 insertions(+), 46 deletions(-) commit 3e32d858a1880fb0abc428b10c125cfe180d7c77 Author: Rui Matos Date: Mon Oct 1 16:42:22 2012 +0200 region: Add inscript2 m17n keymaps to the whitelist https://bugzilla.gnome.org/show_bug.cgi?id=684854 panels/region/gnome-region-panel-input.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) commit c7677010a0d4f5e9fdfc82b216b866d5b51dca75 Author: Rui Matos Date: Sat Sep 29 19:47:38 2012 +0200 region: Repopulate input sources chooser when IBus becomes available Otherwise the IBus sources wouldn't be available in the chooser until it was closed and re-opened. https://bugzilla.gnome.org/show_bug.cgi?id=684874 panels/region/gnome-region-panel-input.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) commit fb6c89f45a3c73d34de4cf0c8d381bce301176f1 Author: Daiki Ueno Date: Thu Sep 27 17:46:40 2012 +0900 region: build IBus setup app filename only from the engine prefix There are 84 m17n engines in the whitelist and they all use ibus-setup-m17n. To reduce the number of .desktop files, this patch uses the prefix before the first ":" to construct the .desktop filename and set IBUS_ENGINE_NAME envvar to let the setup app know the actual engine ID. https://bugzilla.gnome.org/show_bug.cgi?id=684935 panels/region/gnome-region-panel-input.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) commit 42d835b3ce92188fc9f01d0461b53b6f44f67160 Author: Matthias Clasen Date: Tue Oct 2 15:11:59 2012 +0200 network: Further refinements to out-of-range avoidance panels/network/net-device-wifi.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) commit 75086eb149079ae9f1818774d8b3f73ecab62120 Author: Bastien Nocera Date: Tue Oct 2 14:55:59 2012 +0200 network: Fix WPA Enterprise connection not working https://bugzilla.gnome.org/show_bug.cgi?id=685207 panels/network/net-device-wifi.c | 52 +++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 6 deletions(-) commit 7e708ae52c48a1b1dcc240f0007c5066cec0a19b Author: Bastien Nocera Date: Tue Oct 2 12:33:15 2012 +0200 network: Scope correctly the connection variable panels/network/net-device-wifi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) commit e7e02390b6b4506a002f48b5d20b40d3270d0902 Author: Bastien Nocera Date: Tue Oct 2 12:28:58 2012 +0200 network: Add debug for connection activation failures panels/network/net-device-wifi.c | 6 ++++++ 1 file changed, 6 insertions(+) commit 6264fea2fe06d3ee06279b1aba14109d149fcdcf Author: Matthias Clasen Date: Sat Sep 29 19:35:23 2012 -0400 Don't try to activate out-of-range connections It is not going to work... https://bugzilla.gnome.org/show_bug.cgi?id=684824 panels/network/net-device-wifi.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) commit 446f7cf0272f5ba88790c012cde193c393246f07 Author: Bastien Nocera Date: Tue Oct 2 08:57:38 2012 +0200 network: Fix parenting of the broadband wizard By showing the wizard in an idle by default, or waiting until the shell is visible. panels/network/network-dialogs.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) commit aceaf347a93f3a8dd2a53a9a8457c6d53a1c5100 Author: Bastien Nocera Date: Mon Oct 1 23:05:41 2012 +0200 network: Show the network dialogues after showing the shell To avoid confusing the hell out of Mutter, we should show the parented dialogue _after_ showing the parent itself. https://bugzilla.gnome.org/show_bug.cgi?id=684927 panels/network/network-dialogs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) commit 3c973b587deec0570f743af83699c567ee15eea1 Author: Bastien Nocera Date: Mon Oct 1 23:05:29 2012 +0200 network: Add debug for argv handling panels/network/cc-network-panel.c | 4 ++++ 1 file changed, 4 insertions(+) commit d941ca15af9799efbba55bc62ee5a4f1a0668dae Author: Bastien Nocera Date: Mon Oct 1 23:03:54 2012 +0200 network: Fix possible incorrect exit of the loop A bug fix for the Proxy page handling panels/network/cc-network-panel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit 813843cf85bffd66af4421dcfec35487487edacf Author: Bastien Nocera Date: Mon Oct 1 21:16:05 2012 +0200 network: Fix possible crasher when handling argv prop When looking for a matching device, we might end up checking for the proxy page's nm-device, which it obviously doesn't have. panels/network/cc-network-panel.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) commit 9dcf8cbfef005d4a473504b687588f93eb88ebed Author: Bastien Nocera Date: Thu Sep 27 12:41:56 2012 +0200 region: Remove dead button The button hasn't ever been hooked to anything. Let's remove it. https://bugzilla.gnome.org/show_bug.cgi?id=684864 panels/region/gnome-region-panel.ui | 15 --------------- 1 file changed, 15 deletions(-) commit 2a24b5978e51bfcc5e9431a319ae481eac830a73 Author: Bastien Nocera Date: Mon Oct 1 09:32:18 2012 +0200 common: Fix list-languages build panels/common/list-languages.c | 1 + 1 file changed, 1 insertion(+) commit 5b6385067d89f6b2262ad7da3bd13b928ccc36e9 Author: Bastien Nocera Date: Sun Sep 30 05:40:56 2012 +0200 background: Fix clearing too much from the background panels/background/cc-background-panel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit fbddd14a454cebfff6c2203abb0715b31d8ad2d1 Author: Bastien Nocera Date: Sun Sep 30 05:39:08 2012 +0200 common: Add i18n support to language test app panels/common/list-languages.c | 6 ++++++ 1 file changed, 6 insertions(+) commit 1522b3909a3beb95628773472fab9498d383c9f8 Author: Tom Tryfonidis Date: Sat Sep 29 14:52:30 2012 +0300 Fixes for Greek translation po/el.po | 87 ++++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 43 insertions(+), 44 deletions(-) commit 4b30021a97f7385eaffea209e269134e7a8ad1ef Author: Bastien Nocera Date: Fri Sep 28 13:35:28 2012 +0200 network: Top-align the back button in wifi panels panels/network/network-wifi.ui | 61 ++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 23 deletions(-) commit ccc3f0bf3ce8927cd62d9ddf208e6b1b1f1ca16d Author: Bastien Nocera Date: Fri Sep 28 11:44:19 2012 +0200 network: Don't resize the panel or the wifi list panels/network/cc-network-panel.c | 6 ++++-- panels/network/net-device-wifi.c | 1 + panels/network/network-wifi.ui | 5 ++++- 3 files changed, 9 insertions(+), 3 deletions(-) commit 194d28ae5002444e5d2495f4681bb18dd171cde9 Author: Bastien Nocera Date: Fri Sep 28 11:24:11 2012 +0200 network: Simplify access to the device treeview panels/network/cc-network-panel.c | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) commit a11ad3bed1a2df01fb1a292eda4925927164fbda Author: Bastien Nocera Date: Thu Sep 27 21:07:53 2012 +0200 network: Handle argv property every time it changes Newer version of network-manager-applet required to avoid the run-time warnings though. https://bugzilla.gnome.org/show_bug.cgi?id=684983 panels/network/cc-network-panel.c | 123 +++++++++++++++++++++++++++----------- 1 file changed, 88 insertions(+), 35 deletions(-) commit f49261bb8d0728f77c45a287c4fc9c94aaa7a494 Author: Jakub Steiner Date: Fri Aug 24 16:25:53 2012 +0200 background: use a lighter texture for solid colors. https://bugzilla.gnome.org/show_bug.cgi?id=682612 panels/background/Makefile.am | 5 +++++ panels/background/bg-colors-source.c | 2 +- panels/background/noise-texture-light.png | Bin 0 -> 69136 bytes 3 files changed, 6 insertions(+), 1 deletion(-) commit 97af01b56f7fdbb979e4484c8c38a8d08935b9fb Author: Bastien Nocera Date: Fri Sep 28 01:31:02 2012 +0200 background: Fix preview when primary is not the leftmost https://bugzilla.gnome.org/show_bug.cgi?id=684985 panels/background/cc-background-panel.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) commit 4c237034747e34bcc5d18f98d6111470e5eea69d Author: Bastien Nocera Date: Thu Sep 27 22:39:12 2012 +0200 network: Remove g_print() debug panels/network/net-device-wifi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit 2ab1f2172338608f5b95858d46c05b71cf46b438 Author: Bastien Nocera Date: Thu Sep 27 22:12:52 2012 +0200 datetime: Update current time when tz changes https://bugzilla.gnome.org/show_bug.cgi?id=665137 panels/datetime/cc-datetime-panel.c | 4 ++++ 1 file changed, 4 insertions(+) commit f4a8e0a73c2dc01bcaa8545fa399b944239f4201 Author: Bastien Nocera Date: Thu Sep 27 20:37:01 2012 +0200 background: Add debug to get_screenshot_async() https://bugzilla.gnome.org/show_bug.cgi?id=684985 panels/background/cc-background-panel.c | 3 +++ 1 file changed, 3 insertions(+) commit 112edc7cf72f34b6fc0b43ce714b3228f0b86699 Author: Bastien Nocera Date: Thu Sep 27 20:36:35 2012 +0200 background: Capture the primary monitor Not monitor 0. https://bugzilla.gnome.org/show_bug.cgi?id=684985 panels/background/cc-background-panel.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) commit dc559e3a9953ccef8f01802031375a722164c458 Author: Bastien Nocera Date: Thu Sep 27 20:26:50 2012 +0200 network: Clean up all args when done handling them panels/network/cc-network-panel.c | 14 +++++++------- panels/network/network-dialogs.c | 2 ++ 2 files changed, 9 insertions(+), 7 deletions(-) commit 38cbe1fb1674bc4a152398683c2592b4be477004 Author: Bastien Nocera Date: Thu Sep 27 20:22:57 2012 +0200 network: Add function to clean up the argv property panels/network/cc-network-panel.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) commit 5ae3d6b01aeda595f6a02454141f2c3be9ed673a Author: Bastien Nocera Date: Thu Sep 27 16:11:55 2012 +0200 wacom: Bump the required version of g-s-d So that GSD_WACOM_ACTION_TYPE_SWITCH_MONITOR is available. https://bugzilla.gnome.org/show_bug.cgi?id=684952 configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 287b0b917ab1e8182a2f8da0d60c6210d5ce296b Author: Bastien Nocera Date: Thu Sep 27 12:43:39 2012 +0200 region: Fix possibly uninitialised variable panels/region/gnome-region-panel-system.c | 1 + 1 file changed, 1 insertion(+) commit 3d7e215024afd4b94c86a2328f6f07d71fbd9302 Author: Bastien Nocera Date: Wed Sep 26 18:34:49 2012 +0200 mouse: Reset test area to the bottom at every try This prevents window resizes from making the first visit to the mouse test area one that doesn't scroll all the way to the bottom. 1. Open System Settings 2. Open a panel that's smaller than the mouse one (eg. Background) 3. Back to overview 4. Open Mouse panel, click on test button https://bugzilla.gnome.org/show_bug.cgi?id=684817 panels/mouse/cc-mouse-panel.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) commit f48db43be9e3642040070c7f733580f15da41fa1 Author: Bastien Nocera Date: Wed Sep 26 17:25:28 2012 +0200 common: Add more debug for select_current_language() panels/common/cc-common-language.c | 10 ++++++++++ 1 file changed, 10 insertions(+) commit 7181ca7c95b4fa9c08a02afbd95e4e17d196f133 Author: Cosimo Cecchi Date: Tue Sep 25 17:47:04 2012 -0400 user-panel: make the autologin cell renderer follow state Since it renders a symbolic icon, let it follow the state, so it takes the selected text color when the row is selected https://bugzilla.gnome.org/show_bug.cgi?id=684828 panels/user-accounts/um-user-panel.c | 1 + 1 file changed, 1 insertion(+) commit 89bb6457a2d9382deb4d37bfafc8636e8d3f2ca8 Author: Timur Zhamakeev Date: Wed Sep 26 22:28:56 2012 +0600 Updated Kyrgyz translation po/ky.po | 245 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 125 insertions(+), 120 deletions(-) commit 420240840a4c5f271342e12af34bc4ea1e968dbd Author: Cosimo Cecchi Date: Tue Sep 25 17:38:31 2012 -0400 printers: don't override search entry's icon name GtkSearchEntry already gets it right; this icon should be symbolic and there's no need to override it. https://bugzilla.gnome.org/show_bug.cgi?id=684827 panels/printers/new-printer-dialog.ui | 1 - 1 file changed, 1 deletion(-) commit cc07f54956614b0e4e04957c248e20e5061276ce Author: Timur Zhamakeev Date: Wed Sep 26 12:52:35 2012 +0600 Updated Kyrgyz translation po/ky.po | 308 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 159 insertions(+), 149 deletions(-) commit 5115a8ba7a0b9446588e545aab58e80c3739c0a1 Author: Daniel Korostil Date: Wed Sep 26 08:49:32 2012 +0300 Added uk translation po/uk.po | 12394 +++++++++++++++++++++++++++++++------------------------------ 1 file changed, 6207 insertions(+), 6187 deletions(-) commit d1afdf4dd11c01b20704ebe304e6d07dc667a78c Author: Chao-Hsiung Liao Date: Wed Sep 26 11:51:49 2012 +0800 Updated Traditional Chinese translation(Hong Kong and Taiwan) po/zh_HK.po | 193 +++++++++++++++++++++++++++++++----------------------------- po/zh_TW.po | 193 +++++++++++++++++++++++++++++++----------------------------- 2 files changed, 198 insertions(+), 188 deletions(-) commit b3287e1b971db4955f2914be9f6ff69a89ad99dd Author: Bastien Nocera Date: Tue Sep 25 21:23:57 2012 +0200 shell: Fix entering the same panel twice Manually this time. https://bugzilla.gnome.org/show_bug.cgi?id=684812 shell/cinnamon-control-center.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) commit a6cb76eff8984a263cd6bbb18fe962cb5ae658b5 Author: Timur Zhamakeev Date: Tue Sep 25 23:27:38 2012 +0600 Added Kyrgyz translation po/ky.po | 734 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 381 insertions(+), 353 deletions(-) commit 4abdc131c9725d116157c85f515cfab2f6b14b4a Author: Rui Matos Date: Fri Sep 21 22:24:50 2012 +0200 Revert "region: Create a source from the X layout in use when setting is empty" This reverts commit 1e0192555b686f24d084903d4ce70b5534af6260. https://bugzilla.gnome.org/show_bug.cgi?id=684584 panels/region/gnome-region-panel-input.c | 48 ------------------------------- panels/region/gnome-region-panel-input.h | 2 -- panels/region/gnome-region-panel-system.c | 6 ---- 3 files changed, 56 deletions(-) commit 52387c58bea62059b4c99d1c7c176ba1d1281117 Author: Matthias Clasen Date: Sat Sep 22 13:32:24 2012 -0400 network: RTL flipping for details arrow https://bugzilla.gnome.org/show_bug.cgi?id=684604 panels/network/net-device-wifi.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) commit fb8b858cba020c850e09f65f9b4d83adecface3a Author: Matthias Clasen Date: Sat Sep 22 23:04:02 2012 -0400 sound: Flip the input level bar in RTL languages https://bugzilla.gnome.org/show_bug.cgi?id=684603 panels/sound/gvc-level-bar.c | 9 +++++++++ 1 file changed, 9 insertions(+) commit 2c8b16ed64e410482818e4a4bb245442fb51b1eb Author: Timur Zhamakeev Date: Tue Sep 25 16:19:56 2012 +0600 Added ky to LINGUAS po/LINGUAS | 1 + 1 file changed, 1 insertion(+) commit 70d405aaf602a440beb60e0133763fe29fa91f01 Author: Timur Zhamakeev Date: Tue Sep 25 16:19:36 2012 +0600 Added Kyrgyz translation po/ky.po | 5183 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 5183 insertions(+) commit 4a993e753a898899a6cc05dbbcc222ef6fe5cbae Author: Bastien Nocera Date: Mon Sep 24 11:37:56 2012 +0200 online-accounts: Remove unneeded signal disconnections Those signals will not be emitted anymore, as the objects that could emit them will be destroyed. Fixes a warning on exit, as panel->accounts_treeview is already destroyed when we get there. https://bugzilla.gnome.org/show_bug.cgi?id=684702 panels/online-accounts/cc-online-accounts-panel.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) commit 8f3c5793bba8c152549535b5d2716766aeb1b91f Author: Bastien Nocera Date: Tue Sep 25 10:47:48 2012 +0200 3.6.0 NEWS | 17 +++++++++++++++++ configure.ac | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) commit fdbcda8233ef7438e6bc0a28ab34e4cda9dbed0b Author: Petr Kovar Date: Mon Sep 24 22:03:45 2012 +0200 Update Czech translation po/cs.po | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) commit a80b3d75c501a08acbbd97406bd21d2926c72b42 Author: Matthias Clasen Date: Sat Sep 22 14:08:29 2012 -0400 users: Don't ask for the old password when none is set This prevents passwordless users (common on live cd setups) from setting a password. https://bugzilla.gnome.org/show_bug.cgi?id=684492 panels/user-accounts/um-password-dialog.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) commit 752bfc47aa776233c3aba1e38e04383719122926 Author: Petr Kovar Date: Mon Sep 24 16:01:31 2012 +0200 Update Czech translation by Adam Matousek Review by Lucas Lommer. po/cs.po | 3204 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 1896 insertions(+), 1308 deletions(-) commit f85347c5d05ea0500c8dbba88a8e024702b49601 Author: Alexandre Franke Date: Mon Sep 24 13:15:37 2012 +0200 Update French translation po/fr.po | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) commit 5198f7a5d05346b88bb17e3d3721f215e1508d5e Author: Mattias PƵldaru Date: Mon Sep 24 10:54:07 2012 +0300 [l10n] Updated Estonian translation po/et.po | 2174 ++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 1491 insertions(+), 683 deletions(-) commit cea712cc2191717d396c24b368eff3ff8369796e Author: Timo Jyrinki Date: Mon Sep 24 09:29:00 2012 +0300 Finnish translation update by Jiri Grƶnroos po/fi.po | 138 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 68 insertions(+), 70 deletions(-) commit 154349ba08f3a65c33865cf7855ed2705c654c58 Author: Anita Reitere Date: Mon Sep 24 01:18:00 2012 +0300 Updated Latvian translation po/lv.po | 4367 ++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 2659 insertions(+), 1708 deletions(-) commit d345f2e799560ceb31d9b987a1b389035ad488af Author: Mario BlƤttermann Date: Sun Sep 23 14:40:37 2012 +0200 [l10n] Updated German translation po/de.po | 436 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 218 insertions(+), 218 deletions(-) commit c4f6c714632932e3ee9e12370974410df63143b7 Author: Theppitak Karoonboonyanan Date: Sun Sep 23 16:25:39 2012 +0700 Updated Thai translation po/th.po | 132 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 68 insertions(+), 64 deletions(-) commit eaa0edee70cdda9310016e63042f8dfc6a14429e Author: Carles Ferrando Date: Sun Sep 23 01:26:38 2012 +0200 [l10n]Updated Catalan (Valencian) translation po/ca@valencia.po | 3685 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 2311 insertions(+), 1374 deletions(-) commit 62328d03d5cb1579a0fdbb957d8c58848c6a793d Author: Joan Duran Date: Sun Sep 23 01:26:26 2012 +0200 [l10n] Updated Catalan translation po/ca.po | 3710 +++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 2324 insertions(+), 1386 deletions(-) commit c2c69fb93e5abafe3a163d603c475f9d62a13878 Author: Cheng Lu Date: Sat Sep 22 21:22:44 2012 +0400 update Simplified Chinese (zh_CN) translation po/zh_CN.po | 1921 ++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 1040 insertions(+), 881 deletions(-) commit f00a1cb6450140d0adb02782c0d8c0cac407a7c1 Author: Yuri Myasoedov Date: Sat Sep 22 21:22:44 2012 +0400 Updated Russian translation po/ru.po | 268 ++++++++++++++++++--------------------------------------------- 1 file changed, 77 insertions(+), 191 deletions(-) commit c3d00a6c44f56292d3541bc489899d379a5132b4 Author: Matthias Clasen Date: Fri Sep 21 16:07:46 2012 -0400 Make connecting to Enterprise WPA work again gnome-shell relies on being able to call cinnamon-control-center network connect-8021x-wifi This was broken in the big refactoring of the wifi panel last cycle. Bring it back. panels/network/cc-network-panel.c | 20 ++++++++++---------- panels/network/net-device-wifi.c | 11 ----------- panels/network/network-dialogs.c | 13 ++++++++++++- panels/network/network-dialogs.h | 2 +- 4 files changed, 23 insertions(+), 23 deletions(-) commit 1218fff1cc1b0c2453d6d7dd668b54b3a412fd82 Author: Yaron Shahrabani Date: Sat Sep 22 14:58:10 2012 +0300 Updated Hebrew translation. po/he.po | 349 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 183 insertions(+), 166 deletions(-) commit f82d1246dac6746fad0ddc6fd8715485ef463925 Author: Bruce Cowan Date: Sat Sep 22 11:22:09 2012 +0100 Updated British English translation po/en_GB.po | 68 +++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 37 insertions(+), 31 deletions(-) commit 867125c816075b1a15094132ef4b25ca1443f0c6 Author: Seong-ho Cho Date: Sat Sep 22 18:21:38 2012 +0900 Updated Korean translation po/ko.po | 171 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 88 insertions(+), 83 deletions(-) commit c8b4efd10bd05697ce66987085fcca6097c04f18 Author: Bastien Nocera Date: Tue Sep 18 13:26:28 2012 +0200 region: Switch to the input sources section When clicking on the link. https://bugzilla.gnome.org/show_bug.cgi?id=684280 panels/region/gnome-region-panel-input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 35029d6b17bc12f8d7d7bcdd8e6dd7b8befc7bf4 Author: Aurimas Černius Date: Fri Sep 21 20:50:56 2012 +0300 Updated Lithuanian translation po/lt.po | 131 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 65 insertions(+), 66 deletions(-) commit 03ceb2dfea6e06e95e23e88bc97e1b98b4d1523b Author: Ihar Hrachyshka Date: Fri Sep 21 20:04:43 2012 +0300 Updated Belarusian translation. po/be.po | 129 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 66 insertions(+), 63 deletions(-) commit 8dd9ec4b2da2929908422ea5bad8c953185740cb Author: Daniel Mustieles Date: Fri Sep 21 17:52:01 2012 +0200 Updated Spanish translation po/es.po | 120 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 62 insertions(+), 58 deletions(-) commit ff96fb22c1f709b51f230f8d5b00f3371c0ceacd Author: ManojKumar Giri Date: Fri Sep 21 20:30:06 2012 +0530 Updated translation for Odia. po/or.po | 657 +++++++++++++++++++++++++++++---------------------------------- 1 file changed, 306 insertions(+), 351 deletions(-) commit 65ed1ca9ef922072add434454a4606637d59ed01 Author: Ani Peter Date: Fri Sep 21 19:42:11 2012 +0530 Updated Malayalam file po/ml.po | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) commit f7ae60f058bf170945a2b24045755f77a70b5f00 Author: Ani Peter Date: Fri Sep 21 19:39:09 2012 +0530 Updated Malayalam file po/ml.po | 259 +++++++++++++++++++++------------------------------------------ 1 file changed, 85 insertions(+), 174 deletions(-) commit 558a231fc6854ff72ee8560a90a488628a863fdd Author: Ani Peter Date: Fri Sep 21 19:36:24 2012 +0530 Updated Malayalam file po/ml.po | 6167 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 3415 insertions(+), 2752 deletions(-) commit 93af763f32afa66373e0fd82d0d2f8de27fa5401 Author: ManojKumar Giri Date: Fri Sep 21 17:41:04 2012 +0530 Updated translation for Odia. po/or.po | 64 ++++++++++------------------------------------------------------ 1 file changed, 10 insertions(+), 54 deletions(-) commit 024f2c49fb5c4d39f0c6a8c3d9b037fb23af1db2 Author: Sweta Kothari Date: Fri Sep 21 12:42:45 2012 +0530 Updated gujarati file po/gu.po | 72 ++++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 36 insertions(+), 36 deletions(-) commit cbab0b66ec90061ecf1e15726f4a272672ef6857 Author: Duarte Loreto Date: Thu Sep 20 22:15:52 2012 +0100 Updated Portuguese translation po/pt.po | 122 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 64 insertions(+), 58 deletions(-) commit 876d41b141ee102fc383369459827101af406e69 Author: Bastien Nocera Date: Thu Sep 20 20:58:28 2012 +0200 shell: Pass args to existing panels When re-activating the same panel, we could destroy and recreate the panel, or better reuse the panel, and set the new argv (usually to switch pages). Since we're changing the "argv" property of panels to not be construct- only anymore, we reviewed the panels for potential memory leaks as well. https://bugzilla.gnome.org/show_bug.cgi?id=684490 shell/cc-panel.c | 2 +- shell/cinnamon-control-center.c | 29 +++++++++++++++++++++++------ 2 files changed, 24 insertions(+), 7 deletions(-) commit ab435aa9e18f550e6926e06ab08e71282a9d442b Author: Bastien Nocera Date: Thu Sep 20 20:51:14 2012 +0200 shell: Rename current_panel to current_panel_box So that we can use current_panel for the current panel, not for the container parent of the panel. https://bugzilla.gnome.org/show_bug.cgi?id=684490 shell/cinnamon-control-center.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) commit ca8d78e6201ba07d7b8546f62b1becd16e97f3da Author: Shankar Prasad Date: Fri Sep 21 01:14:06 2012 +0530 Updated kn translation po/kn.po | 511 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 249 insertions(+), 262 deletions(-) commit 74751e874eae8778b0d382440edb73809af5d015 Author: ŠœŠøŃ€Š¾ŃŠ»Š°Š² ŠŠøŠŗŠ¾Š»ŠøŃ› Date: Thu Sep 20 20:58:04 2012 +0200 Updated Serbian translation po/sr.po | 134 +++++++++++++++++++++++++++++---------------------------- po/sr@latin.po | 134 +++++++++++++++++++++++++++++---------------------------- 2 files changed, 136 insertions(+), 132 deletions(-) commit 67d9f3a4b4655f41abfd538264a3dc0efc542bfc Author: Gabor Kelemen Date: Thu Sep 20 14:39:55 2012 +0200 Updated Hungarian translation po/hu.po | 66 ++++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 35 insertions(+), 31 deletions(-) commit 44bfa9d31fc5b138e859bbe30e6ffd38a6c2a86a Author: Sweta Kothari Date: Thu Sep 20 15:16:16 2012 +0530 Updated gujarati file po/gu.po | 955 +++++++++++++++++++++++++-------------------------------------- 1 file changed, 385 insertions(+), 570 deletions(-) commit 45b2689f6bde5018bd1d18a2ba350cbaa598f9b9 Author: Tom Tryfonidis Date: Thu Sep 20 11:09:42 2012 +0300 Updated Greek translation po/el.po | 134 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 68 insertions(+), 66 deletions(-) commit 0dfb1e2725c4b3adc2796a0de29d76068b5028d9 Author: Alexandre Franke Date: Thu Sep 20 09:11:52 2012 +0200 Update French translation po/fr.po | 127 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 65 insertions(+), 62 deletions(-) commit 7fc288302f07fe0ed6ccc821893cdc603e2b2989 Author: Sandeep Sheshrao Shedmake Date: Thu Sep 20 11:47:34 2012 +0530 Updated Marathi Translations po/mr.po | 122 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 62 insertions(+), 60 deletions(-) commit c9344e5f416adb5a116a1e67bdd67fdb7ed8098e Author: Khaled Hosny Date: Thu Sep 20 06:40:53 2012 +0200 Updated Arabic translation po/ar.po | 69 +++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 38 insertions(+), 31 deletions(-) commit 5b776981f38674d2bc0f5fd48cad687a76133f77 Author: Praveen Illa Date: Wed Sep 19 23:25:14 2012 +0530 Updated Telugu Translation po/te.po | 3809 ++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 2357 insertions(+), 1452 deletions(-) commit 6782f962a5299e8c67630123718146e6934a83f4 Author: Alexander Shopov Date: Wed Sep 19 20:45:31 2012 +0300 Updated Bulgarian translation po/bg.po | 125 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 66 insertions(+), 59 deletions(-) commit 9973d617496bae90e79f6c569a3f0cb82fddb59c Author: Noriko Mizumoto Date: Thu Sep 20 01:12:15 2012 +0900 [l10n] Update Japanese translation po/ja.po | 1273 +++++++++++++++++++++++++++++--------------------------------- 1 file changed, 595 insertions(+), 678 deletions(-) commit d02c7c0338ff3146737bb9023fd9761ade7ed10c Author: A S Alam Date: Wed Sep 19 21:40:57 2012 +0530 update Punjabi Translation po/pa.po | 134 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 68 insertions(+), 66 deletions(-) commit 27f7319073955d42e5fec01266121e1c34909621 Author: Rafael Ferreira Date: Wed Sep 19 10:04:01 2012 -0300 Updated Brazilian Portuguese Translation po/pt_BR.po | 101 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 50 insertions(+), 51 deletions(-) commit 2406c3a4e9b7e1443350e9b4d6d08e39193fb3ae Author: Dr.T.Vasudevan Date: Wed Sep 19 17:51:00 2012 +0530 updated Tamil translation po/ta.po | 343 ++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 183 insertions(+), 160 deletions(-) commit 4d3bf50f1f8bfbe0425d1aab7e6aa0124890ffd6 Author: Rajesh Ranjan Date: Wed Sep 19 16:55:22 2012 +0530 hindi update po/hi.po | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) commit 80b89a87ff75c915d9b0940af8589bc299cb9ab5 Author: Rajesh Ranjan Date: Wed Sep 19 14:17:15 2012 +0530 hindi update po/hi.po | 465 ++++++++++++++++++++++----------------------------------------- 1 file changed, 164 insertions(+), 301 deletions(-) commit e3defaa82e3b82a2303c81b659d0b586b57b8eed Author: Matej Urbančič Date: Wed Sep 19 09:03:44 2012 +0200 Updated Slovenian translation po/sl.po | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) commit 742a3cecd4d0bb4bb4b42a3b58e61ba8030e665d Author: Nilamdyuti Goswami Date: Wed Sep 19 12:06:41 2012 +0530 Assamese translation updated po/as.po | 137 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 69 insertions(+), 68 deletions(-) commit 9228ddc36e09a167ff4cab2707b14e5187dcf101 Author: Andika Triwidada Date: Wed Sep 19 10:37:38 2012 +0700 Updated Indonesian translation po/id.po | 134 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 68 insertions(+), 66 deletions(-) commit 50ae0268666a8fae2a175001427015bc7a0dc0fd Author: Fran DiĆ©guez Date: Wed Sep 19 02:52:04 2012 +0200 Updated Galician translations po/gl.po | 131 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 68 insertions(+), 63 deletions(-) commit 25973a1ea4d75a41921bc986b9e182ac87254233 Author: Piotr Drąg Date: Wed Sep 19 01:14:11 2012 +0200 Updated Polish translation po/pl.po | 137 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 71 insertions(+), 66 deletions(-) commit 5f27eb0cec5efd3da76fae8a8bfbb1bedf01656a Author: Bastien Nocera Date: Wed Sep 19 00:52:24 2012 +0200 power: Make Tip translatable https://bugzilla.gnome.org/show_bug.cgi?id=684309 panels/power/cc-power-panel.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) commit 491234c533adecf83abe03fa298e1e76639bdc4e Author: Bastien Nocera Date: Tue Sep 18 19:01:36 2012 +0200 keyboard: Handle arguments for the shortcuts tab So it's possible to switch directly to a section of the shortcuts tab, rather than have users look for particular sections when redirected there through a link. https://bugzilla.gnome.org/show_bug.cgi?id=684280 panels/keyboard/cc-keyboard-panel.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) commit 22e31eb3f7c946cdf987f6fc38ef616bd82dd46e Author: Bastien Nocera Date: Tue Sep 18 19:01:06 2012 +0200 keyboard: Add ability to switch to a shortcuts section With some new API. https://bugzilla.gnome.org/show_bug.cgi?id=684280 panels/keyboard/keyboard-shortcuts.c | 78 +++++++++++++++++++++++++++++++++--- panels/keyboard/keyboard-shortcuts.h | 1 + 2 files changed, 73 insertions(+), 6 deletions(-) commit 968618ef8b0206971addf6924abc63b6d37795ba Author: Bastien Nocera Date: Tue Sep 18 18:57:50 2012 +0200 keyboard: Add unique IDs for each shortcuts section Rather than relying on comparison of translated strings. https://bugzilla.gnome.org/show_bug.cgi?id=684280 panels/keyboard/keyboard-shortcuts.c | 37 ++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) commit d150446139a601276b3868260fa77fc31191ef69 Author: Matej Urbančič Date: Tue Sep 18 21:08:31 2012 +0200 Updated Slovenian translation po/sl.po | 96 +++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 50 insertions(+), 46 deletions(-) commit c3c0f2a3e54e00555666c05ad2d4a41ffbf3f7c4 Author: Piotr Drąg Date: Tue Sep 18 18:39:52 2012 +0200 Mark string as translatable panels/network/network-wifi.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 486d17039b0c8da44732b2e90ad717f585ffc841 Author: Daniel Mustieles Date: Tue Sep 18 16:35:36 2012 +0200 Updated Spanish translation po/es.po | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) commit 5b6c95500b74c88e83b3c3452d6055d12e65ceb6 Author: Rajesh Ranjan Date: Tue Sep 18 17:23:19 2012 +0530 hindi update po/hi.po | 4290 ++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 2624 insertions(+), 1666 deletions(-) commit a3cda9a3daa9d93a4c7044d820e15f1f00d97e1d Author: Gabor Kelemen Date: Tue Sep 18 10:04:28 2012 +0200 Updated Hungarian translation po/hu.po | 1041 +++++++++++--------------------------------------------------- 1 file changed, 183 insertions(+), 858 deletions(-) commit ff34f7e29b6e4e20ea7995a47b6ce0ea2a7b918d Author: Sandeep Sheshrao Shedmake Date: Tue Sep 18 13:33:00 2012 +0530 Updated Marathi Translations po/mr.po | 248 ++++++++++++++++++++++++++++----------------------------------- 1 file changed, 111 insertions(+), 137 deletions(-) commit c8bb4c8fbed5382e58dfbb0706d767d3c11433fe Author: Chris Leonard Date: Mon Sep 17 20:45:52 2012 +0100 Updated British English translation po/en_GB.po | 572 +++++++++++++++++++++++++++++------------------------------- 1 file changed, 281 insertions(+), 291 deletions(-) commit 9648fae3beb793b6e0aab1cd727e25ec3012cd53 Author: Chris Leonard Date: Mon Sep 17 20:42:58 2012 +0100 Updated British English translation po/en_GB.po | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) commit d2209c3542cc762f76461cf88ee3b01a9ee85754 Author: Khaled Hosny Date: Mon Sep 17 20:43:41 2012 +0200 Updated Arabic translation po/ar.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) commit e846becec0ba60170325a2e0db0d7fc091c9a070 Author: Khaled Hosny Date: Mon Sep 17 20:31:04 2012 +0200 Updated Arabic translation po/ar.po | 357 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 187 insertions(+), 170 deletions(-) commit 5a23d99ce95c707ce326ff6c9f75cc9e3175f058 Author: Bastien Nocera Date: Mon Sep 17 19:49:36 2012 +0200 3.5.92 NEWS | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 2 +- 2 files changed, 54 insertions(+), 1 deletion(-) commit 95fb453d879b00f98c2e7cc13eb988ca48b2ae13 Author: Bastien Nocera Date: Mon Sep 17 12:33:51 2012 +0100 user-accounts: Disable password changing for remote users Works-around: https://bugs.freedesktop.org/show_bug.cgi?id=55002 See also: https://bugzilla.gnome.org/show_bug.cgi?id=681866#c11 panels/user-accounts/um-user-panel.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) commit 0721469d566e1005415c974c8cfd29ad718497cd Author: Stef Walter Date: Mon Sep 17 14:19:53 2012 +0200 user-accounts: Default LocalAccount property to TRUE When loading properties from the AccountsService we may encounter an implementation that does not yet have the LocalAccount property, so set the LocalAccount property to TRUE by default to make things work correctly in the above case. https://bugzilla.gnome.org/show_bug.cgi?id=684207 panels/user-accounts/um-user.c | 3 +++ 1 file changed, 3 insertions(+) commit 0882d9131823dc34f2b8aa70d91961422e54c408 Author: Theppitak Karoonboonyanan Date: Mon Sep 17 22:31:57 2012 +0700 Updated Thai translation po/th.po | 5257 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 3128 insertions(+), 2129 deletions(-) commit 531c568645ba3ba21a8b600f8b7ab35925748d0b Author: Djavan Fagundes Date: Mon Sep 17 10:05:34 2012 -0300 Updated Brazilian Portuguese translation by Rafael Ferreira and myself po/pt_BR.po | 5061 +++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 3003 insertions(+), 2058 deletions(-) commit 31a293bc08d2ac5fe3b0a8c9e8cb06b1d3b9d432 Author: Stef Walter Date: Mon Sep 17 10:32:23 2012 +0200 user-accounts: Fix memory leak of realm list https://bugzilla.gnome.org/show_bug.cgi?id=684188 panels/user-accounts/um-realm-manager.c | 1 + 1 file changed, 1 insertion(+) commit 65aaaf9d0451ba076ee7d8f09e7a472dc9926024 Author: Stef Walter Date: Mon Sep 3 16:16:42 2012 +0200 user-accounts: Add debug messages to user creation and realm procedures https://bugzilla.gnome.org/show_bug.cgi?id=684185 panels/user-accounts/um-account-dialog.c | 27 +++++++++++++++++ panels/user-accounts/um-realm-manager.c | 52 +++++++++++++++++++++++++++----- 2 files changed, 72 insertions(+), 7 deletions(-) commit 09e62d679c9f16fe05d476773632c3761510c92d Author: Stef Walter Date: Mon Sep 17 10:42:31 2012 +0200 user-accounts: Relicense UmRealmManager to GPLv2+ And update the 'Written By' of UmRealmManager https://bugzilla.gnome.org/show_bug.cgi?id=683420 panels/user-accounts/um-realm-manager.c | 5 ++--- panels/user-accounts/um-realm-manager.h | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) commit b4251d847be7d25ffcdb28b85fbdef42a542222e Author: Daiki Ueno Date: Thu Sep 13 10:15:46 2012 +0900 region: move Amharic in IBus engine whitelist Move Amharic input method to non-trivial unconfirmed section. https://bugzilla.gnome.org/show_bug.cgi?id=683697 panels/region/gnome-region-panel-input.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) commit e09ca1074c1ed585d1379980f83a2ae191618080 Author: Daiki Ueno Date: Tue Sep 11 10:38:17 2012 +0900 region: add non-trivial IBus engines to whitelist Add non-trivial IBus engines such as transliteration based ones. Though these engines have not yet confirmed by local language users, it would be probably safe to leave them. https://bugzilla.gnome.org/show_bug.cgi?id=683697 panels/region/gnome-region-panel-input.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) commit bd5105d7f61d2e536d981991c6d94cc9f86fb7d1 Author: Daiki Ueno Date: Tue Sep 11 10:13:26 2012 +0900 region: whitelist IBus engines with no XKB equiv Some IBus engines don't have XKB equivalents, so need to be whitelisted to be usable. https://bugzilla.gnome.org/show_bug.cgi?id=683697 panels/region/gnome-region-panel-input.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) commit ab43e935a5c4fc1824acaf9d9357be22be438657 Author: Daiki Ueno Date: Tue Sep 11 09:56:35 2012 +0900 region: add wubi and erbi to IBus engine whitelist wubi and erbi (both from ibus-table) are popular stroke based input methods for inputing Simplified Chinese and Traditional Chinese. A local user said that wubi covers at least 20% of the Simplified Chinese users. erbi is similar to wubi and getting popular because of easiness to learn. https://bugzilla.gnome.org/show_bug.cgi?id=683697 panels/region/gnome-region-panel-input.c | 2 ++ 1 file changed, 2 insertions(+) commit 521bcadd512f81a4c103f03177ced7c59049aae7 Author: Daiki Ueno Date: Thu Sep 13 10:03:37 2012 +0900 region: remove Farsi item from IBus engine whitelist m17n:fa:isiri is removed from IBus engine whitelist, since it has XKB equivalent. https://bugzilla.gnome.org/show_bug.cgi?id=683697 panels/region/gnome-region-panel-input.c | 3 --- 1 file changed, 3 deletions(-) commit 89007c64ff3a7584bc0e79c80910c6e22a244c1f Author: Daiki Ueno Date: Tue Sep 11 09:51:50 2012 +0900 region: mark Vietnamese IBus engine whitelist as confirmed A local user confirmed that the Vietnamese whitelist items cover 90% of the language users, thus it is now marked as "confirmed". https://bugzilla.gnome.org/show_bug.cgi?id=683697 panels/region/gnome-region-panel-input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit a61f0654b98357283ef68bea6d827aabc0a2779e Author: Benjamin Berg Date: Sun Sep 16 17:09:45 2012 -0400 display: Fix coordinate calculations https://bugzilla.gnome.org/show_bug.cgi?id=681475 panels/display/scrollarea.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) commit bfca71076d654f91190b2349ad481aff9490c148 Author: Matthias Clasen Date: Sun Sep 16 16:15:22 2012 -0400 users: Fix a typo One translatable string contained the typo 'enterpise logins', where it should have said 'enterprise logins'. Pointed out in https://bugzilla.gnome.org/show_bug.cgi?id=684122 This commit updates the msgid in all .po files, so translations should not be negatively affected by this string change. panels/user-accounts/data/account-dialog.ui | 2 +- po/ar.po | 2 +- po/as.po | 2 +- po/be.po | 2 +- po/bg.po | 2 +- po/da.po | 2 +- po/de.po | 2 +- po/el.po | 2 +- po/en_GB.po | 4 ++-- po/es.po | 2 +- po/fa.po | 2 +- po/fi.po | 2 +- po/fr.po | 2 +- po/gl.po | 2 +- po/gu.po | 2 +- po/he.po | 2 +- po/hu.po | 2 +- po/id.po | 2 +- po/ja.po | 2 +- po/kn.po | 2 +- po/ko.po | 2 +- po/lt.po | 2 +- po/mr.po | 2 +- po/nb.po | 2 +- po/or.po | 2 +- po/pa.po | 2 +- po/pl.po | 2 +- po/pt.po | 2 +- po/ru.po | 2 +- po/sl.po | 2 +- po/sr.po | 2 +- po/sr@latin.po | 2 +- po/ta.po | 2 +- po/uk.po | 2 +- po/vi.po | 2 +- po/zh_CN.po | 2 +- po/zh_HK.po | 2 +- po/zh_TW.po | 2 +- 38 files changed, 39 insertions(+), 39 deletions(-) commit f251788f9ae4fb0a9dac84c4999d6bc11c3cc192 Author: Matthias Clasen Date: Sun Sep 16 15:46:25 2012 -0400 region: Fix a layout problem on the system tab The Format: row was being pushed to the bottom, and when the input sources value was longer on the one side than the other, the horizontal alignment was broken. panels/region/gnome-region-panel.ui | 13 +++++++++++++ 1 file changed, 13 insertions(+) commit 914e8b25629dbb1c8da83926098ecd7de9c2242f Author: Bastien Nocera Date: Thu Sep 13 01:23:38 2012 +0100 region: Handle input sources in the system tab Unfortunately we don't have a way yet to make gsettings system wide defaults so we are just using the localed API to export the XKB input sources and ignore the IBus ones. https://bugzilla.gnome.org/show_bug.cgi?id=683875 panels/region/gnome-region-panel-input.c | 2 +- panels/region/gnome-region-panel-input.h | 2 + panels/region/gnome-region-panel-system.c | 157 +++++++++++++++++++++++++++++- 3 files changed, 155 insertions(+), 6 deletions(-) commit 77700f82ffa623d9776ac5b3ab69a7f996b9c21b Author: Seong-ho Cho Date: Mon Sep 17 01:35:00 2012 +0900 Updated Korean translation po/ko.po | 3626 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 2037 insertions(+), 1589 deletions(-) commit 8083977272c04107ec6f3f4c5d306517f05f45dc Author: Daniel Mustieles Date: Sun Sep 16 13:19:38 2012 +0200 Updated Spanish translation po/es.po | 201 +++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 111 insertions(+), 90 deletions(-) commit f5c0dda9eb8add1618f8f6da58135229c363c47a Author: Chao-Hsiung Liao Date: Sun Sep 16 12:22:50 2012 +0800 Updated Traditional Chinese translation(Hong Kong and Taiwan) po/zh_HK.po | 294 ++++++++++++++++++++++++++++++++---------------------------- po/zh_TW.po | 294 ++++++++++++++++++++++++++++++++---------------------------- 2 files changed, 312 insertions(+), 276 deletions(-) commit c69d46cc4e098baaada0c40a6b61ec7cd24e889a Author: Ask H. Larsen Date: Sun Sep 16 02:04:10 2012 +0200 Updated Danish translation po/da.po | 5055 ++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 2983 insertions(+), 2072 deletions(-) commit e4907262773b42cb0a295c7f18f281e3d97f3479 Author: Matej Urbančič Date: Sat Sep 15 22:48:26 2012 +0200 Updated Slovenian translation po/sl.po | 156 +++++++++++++++++++++++---------------------------------------- 1 file changed, 56 insertions(+), 100 deletions(-) commit c063f854176e6ee2cf9a821972723dd7ff759fd6 Author: Matej Urbančič Date: Sat Sep 15 22:13:56 2012 +0200 Updated Slovenian translation po/sl.po | 409 +++++++++++++++++++++++++++++---------------------------------- 1 file changed, 186 insertions(+), 223 deletions(-) commit 08f57a1b6644e5c7a6249dae309f1c00d1bb5d71 Author: Timo Jyrinki Date: Sat Sep 15 22:51:27 2012 +0300 Finnish translation update by Jiri Grƶnroos po/fi.po | 459 ++++++++++++++++++++++----------------------------------------- 1 file changed, 160 insertions(+), 299 deletions(-) commit d4e00f6ced184577be50ce918956450e3e2b9201 Author: Duarte Loreto Date: Sat Sep 15 19:41:33 2012 +0100 Updated Portuguese translation po/pt.po | 204 ++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 110 insertions(+), 94 deletions(-) commit 8cdcc1eb433571c03841db9fdc949d69d971c92f Author: Yuri Myasoedov Date: Sat Sep 15 15:39:39 2012 +0400 Updated Russian translation po/ru.po | 154 ++++++++++++++++++++++++++------------------------------------- 1 file changed, 64 insertions(+), 90 deletions(-) commit 9b9dfc9ebd01791a211dfdaedb562e2d8fb3ba65 Author: Ivaylo Valkov Date: Sat Sep 15 09:37:14 2012 +0300 Updated Bulgarian translation po/bg.po | 3392 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 2007 insertions(+), 1385 deletions(-) commit f52d6c35137d46fa136cce1ebdb23342d93647eb Author: Andika Triwidada Date: Sat Sep 15 11:54:12 2012 +0700 Updated Indonesian translation po/id.po | 274 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 141 insertions(+), 133 deletions(-) commit 56744d801bd80b2cbb10885f6156dd527f9ae793 Author: Yuri Myasoedov Date: Fri Sep 14 20:38:53 2012 +0400 Updated Russian translation po/ru.po | 2912 +++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 1842 insertions(+), 1070 deletions(-) commit b68b6d84cd01eff2517aed27c57b6471a65294d5 Author: Debarshi Ray Date: Fri Sep 14 13:38:06 2012 +0200 online-accounts: Get rid of extra "Add Account" label Back in the day when titles were not shown for modal dialogs we added the big "Add Account" label. Now that modal dialogs have titles, we don't need it anymore. Fixes: https://bugzilla.gnome.org/684013 .../online-accounts/cc-online-accounts-add-account-dialog.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) commit 5f6391059273bdf7309763a26ab499d9da7a7b0d Author: Ihar Hrachyshka Date: Fri Sep 14 13:21:57 2012 +0300 Updated Belarusian translation. po/be.po | 258 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 135 insertions(+), 123 deletions(-) commit 932a23ba308b9c009d76bc0949dc9856f23714c4 Author: ŠœŠøŃ€Š¾ŃŠ»Š°Š² ŠŠøŠŗŠ¾Š»ŠøŃ› Date: Fri Sep 14 09:44:45 2012 +0200 Updated Serbian translation po/sr.po | 279 ++++++++++++++++++++++++++++++--------------------------- po/sr@latin.po | 279 ++++++++++++++++++++++++++++++--------------------------- 2 files changed, 298 insertions(+), 260 deletions(-) commit 24f21af498e78965708f757ea7eafdfd7944c972 Author: Alexandre Franke Date: Fri Sep 14 09:32:55 2012 +0200 Update French translation po/fr.po | 3120 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 1850 insertions(+), 1270 deletions(-) commit 8b036a133f5270c8a558463c63b13b86909d4919 Author: A S Alam Date: Fri Sep 14 07:24:20 2012 +0530 update Punjabi Translation po/pa.po | 190 ++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 102 insertions(+), 88 deletions(-) commit 1e0192555b686f24d084903d4ce70b5534af6260 Author: Rui Matos Date: Thu Sep 13 16:20:29 2012 +0200 region: Create a source from the X layout in use when setting is empty We don't want to show an empty input sources list so we create a source from the current X layout in case the setting is empty. https://bugzilla.gnome.org/show_bug.cgi?id=683879 panels/region/gnome-region-panel-input.c | 48 ++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) commit fb6881d53b6487c3503e352b0bf0356faf6b637a Author: Rui Matos Date: Sat Sep 8 18:25:50 2012 +0200 region: Handle the case of an empty input sources list We would end up in an endless loop on update. https://bugzilla.gnome.org/show_bug.cgi?id=683879 panels/region/gnome-region-panel-input.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) commit ff5767b9cb56ec30b89be6d7dde47bf623373a23 Author: Fran DiĆ©guez Date: Fri Sep 14 00:12:31 2012 +0200 Updated Galician translations po/gl.po | 185 ++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 100 insertions(+), 85 deletions(-) commit 100c87519aa9a99d721855b3aa35457212eb1040 Author: Aurimas Černius Date: Thu Sep 13 22:37:21 2012 +0300 Updated Lithuanian translation po/lt.po | 263 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 135 insertions(+), 128 deletions(-) commit 75f76aa453ffd3de23e0c4e506ca3151645614cc Author: Daniel Korostil Date: Thu Sep 13 20:11:53 2012 +0300 uk update po/uk.po | 9144 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 4572 insertions(+), 4572 deletions(-) commit d2e56f2bd6a14b2f497220061af4c238ebfcf293 Author: Daniel Korostil Date: Thu Sep 13 20:06:35 2012 +0300 uk update po/uk.po | 5069 ++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 2983 insertions(+), 2086 deletions(-) commit d2b5c1cbfa137193557c446d3a49774c13056a9b Author: Nilamdyuti Goswami Date: Thu Sep 13 21:04:26 2012 +0530 Assamese translation updated po/as.po | 205 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 104 insertions(+), 101 deletions(-) commit 941dd0ead5fb2df239d47866876caa3a08b95511 Author: Piotr Drąg Date: Thu Sep 13 17:02:36 2012 +0200 Updated Polish translation po/pl.po | 267 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 138 insertions(+), 129 deletions(-) commit 44fff9996a762299ac792d739eba43aefc2f6c55 Author: Tom Tryfonidis Date: Thu Sep 13 18:02:27 2012 +0300 Updated Greek translation po/el.po | 187 +++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 103 insertions(+), 84 deletions(-) commit 98040db22a6450d7d782b8f63d83f6d86a870683 Author: Matthias Clasen Date: Sat Sep 8 23:33:24 2012 -0400 network: No selection in the wifi list Set the selection mode to none, to avoid a meaningless and distracting blue selection in the wifi list. panels/network/network-wifi.ui | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) commit 794b89d561b20a7237509f581ac431a09b6265e6 Author: Matthias Clasen Date: Sat Sep 8 23:29:15 2012 -0400 network: Handle activation in the wifi list better Instead of manually handling button release events on the treeview, use activatable cell renderers for the ssid text and for the arrow, and connect to activate signals for them. We use cell area focus-sibling technology to make the keynav in the list just have focus locations for the ssid and the arrow. This makes the details pages reachable by keynav, which was not the case before. panels/network/net-device-wifi.c | 203 ++++++++++++++++++++------------------- 1 file changed, 106 insertions(+), 97 deletions(-) commit 24968aad71ddd32edd5213f7eef925a180bfaf25 Author: Matthias Clasen Date: Sat Sep 8 23:28:10 2012 -0400 network: Add cell renderers These are activatable variants of text and pixbuf cell renderers. They emit an 'activate' signal when clicked or activated by keyboard. panels/network/Makefile.am | 4 ++ panels/network/panel-cell-renderer-pixbuf.c | 82 +++++++++++++++++++++++++++++ panels/network/panel-cell-renderer-pixbuf.h | 61 +++++++++++++++++++++ panels/network/panel-cell-renderer-text.c | 82 +++++++++++++++++++++++++++++ panels/network/panel-cell-renderer-text.h | 61 +++++++++++++++++++++ 5 files changed, 290 insertions(+) commit 292c8b9fe68bad03186c9bc22acfdeecb2aa731b Author: Matthias Clasen Date: Sat Sep 8 23:32:21 2012 -0400 network: Don't override cell renderer properties The mode cell renderer had a property named 'mode', which clashed with the GtkCellRenderer property of that name, which confused the treeview keynav. Rename the new property to ap-mode. panels/network/net-device-wifi.c | 2 +- panels/network/panel-cell-renderer-mode.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) commit 701fb2846ff8c8705e7df3e284b57d34acc0aeff Author: Matthias Clasen Date: Sat Sep 8 21:37:47 2012 -0400 network: Avoid critical warnings Remove the reference to the new longer existing viewport_list widget, and be more careful about getting a NMRemoteSettings object when calculating the last used time. panels/network/net-device-wifi.c | 106 +++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 55 deletions(-) commit 36958cbf84325805ee16f74a04362239f607e9ff Author: Matthias Clasen Date: Sat Sep 8 21:17:47 2012 -0400 network: Improve the wifi list appearance Use non-symbolic icons for the arrow, and add padding around the arrow and the check mark. https://bugzilla.gnome.org/show_bug.cgi?id=682270 panels/network/net-device-wifi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) commit a04445ebd75d48ab25489647c096eca137ad538a Author: Matthias Clasen Date: Sat Sep 8 21:17:24 2012 -0400 network: Remove one more reference to the subnet widgets panels/network/panel-common.c | 5 ----- 1 file changed, 5 deletions(-) commit 7882874a14b62dfbaf93aa05a698e0007c79344f Author: Matthias Clasen Date: Sat Sep 8 21:13:19 2012 -0400 network: Remove a reference to a no-longer existing widget panels/network/network-wired.ui | 1 - 1 file changed, 1 deletion(-) commit 63fd710f8334b2c24d84a5722754c98c378e0594 Author: Matthias Clasen Date: Sat Sep 8 20:26:11 2012 -0400 network: Small tweak for vpn page Make selectable labels on the vpn page focusable as well. panels/network/network-vpn.ui | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) commit aec8cdd7f19374b265d0d5ccd2700a9ab8eaf9e1 Author: Matthias Clasen Date: Sat Sep 8 20:24:48 2012 -0400 network: Don't show subnet for wired either We don't show it for wifi details, and it is causing ugly warnings from the setting code. At the same time, make all selectable labels on the wired page focusable as well, to be consistent with wifi. panels/network/network-wired.ui | 51 ++++++++--------------------------------- panels/network/panel-common.c | 7 ------ 2 files changed, 9 insertions(+), 49 deletions(-) commit 17e3c23cd5d75cc89341a22cb54ee6f484d6261b Author: Matthias Clasen Date: Sat Sep 8 20:10:26 2012 -0400 network: Remove references to no-longer existing widgets And also make sure the initial focus on the details page is always on the back button. panels/network/net-device-wifi.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) commit 75d815ded3903734f0ae25bc0eecb401bd225beb Author: Matthias Clasen Date: Sat Sep 8 19:48:36 2012 -0400 network: Remove the saved-ap tab Saved connections without an access point are now shown in the same tab as all the others. panels/network/net-device-wifi.c | 22 +--- panels/network/network-wifi.ui | 249 --------------------------------------- 2 files changed, 2 insertions(+), 269 deletions(-) commit 18248493d51ab12081b81a43694869cdbc95c4a0 Author: Matthias Clasen Date: Sat Sep 8 19:41:31 2012 -0400 network: Remove an unused object from the ui file panels/network/network-wifi.ui | 5 ----- 1 file changed, 5 deletions(-) commit 32c29a3f253b13910912b3529d3ddfccc02c9f91 Author: Matthias Clasen Date: Sat Sep 8 19:35:15 2012 -0400 network: Only show 'Out of range' when appropriate Showing it whenever we have a saved connection goes wrong for all items where we have both an ap and a saved connection. Also, use the same details page for out-of-range saved connections. panels/network/net-device-wifi.c | 42 ++++++++++++++++++---------------------- panels/network/network-wifi.ui | 10 ++++++---- 2 files changed, 25 insertions(+), 27 deletions(-) commit 3871d52947120c4b08e3898ae6e0e5ab0294898b Author: Matthias Clasen Date: Sat Sep 8 19:06:28 2012 -0400 network: Make 'Connect to hidden' work again panels/network/net-device-wifi.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) commit f10a29b10f5ae2fbf681481d400ec44393092c59 Author: Matthias Clasen Date: Sat Sep 8 18:15:53 2012 -0400 network: Make all values selectable and focusable Also, sort them so that the focus chain makes sense. panels/network/network-wifi.ui | 287 ++++++++++++++++++++--------------------- 1 file changed, 143 insertions(+), 144 deletions(-) commit 78e9ed9ceacb0b09cbe4eda35261dc66b4d8222e Author: Matthias Clasen Date: Sat Sep 8 17:49:25 2012 -0400 network: Say 'never' when the connection hasn't been used Nicer to say 'Last used: never', then to show nothing. panels/network/net-device-wifi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) commit 16011384efe4ad5841be067b2856060c949f87b3 Author: Matthias Clasen Date: Sat Sep 8 17:47:01 2012 -0400 network: Say 'today' instead of '0 days ago' 'Last used: 0 days ago' is odd. Also, say 'yesterday' instead of '1 day ago'. panels/network/net-device-wifi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) commit f6aff65e6434a92dddcbc43dd3dfc815fdc253dc Author: Matthias Clasen Date: Sat Sep 8 17:44:05 2012 -0400 network: Add a 'Last used' item Copy the 'Last used' item for non-active, in-range access points. This is another step towards using the same details page for all aps and connections. panels/network/net-device-wifi.c | 10 ++ panels/network/network-wifi.ui | 279 ++++++++++++++++++++++----------------- 2 files changed, 166 insertions(+), 123 deletions(-) commit ab045fcc0b9a48267a4c61ed9918a51407b1171d Author: Matthias Clasen Date: Sat Sep 8 17:30:37 2012 -0400 network: Add a period to the disconnect warning panels/network/net-device-wifi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 1ba197468b76e935608b6b3af5a7c4ae2a7f6c8a Author: Matthias Clasen Date: Sat Sep 8 17:29:46 2012 -0400 network: Add a 'Connect' button When showing details of a non-active access point, replace the 'Disconnect' button with a 'Connect' button. panels/network/net-device-wifi.c | 60 +++++++++++++++++++++-- panels/network/network-wifi.ui | 102 +++++++++++++++++++++++++-------------- 2 files changed, 122 insertions(+), 40 deletions(-) commit 518efcda09cc492792732dca04b2124c43c3b154 Author: Matthias Clasen Date: Sat Sep 8 16:58:14 2012 -0400 network: Start handling disconnected APs correctly When showing the details for an in-range, but not active access point, we were just always showing details for the currently active connection. This commit starts to sort things apart. panels/network/net-device-wifi.c | 120 ++++++++++++++++++++++++--------------- panels/network/network-wifi.ui | 28 ++++----- panels/network/panel-common.c | 10 ++++ panels/network/panel-common.h | 1 + 4 files changed, 94 insertions(+), 65 deletions(-) commit bcbc6d1aafbb26f6379e0448da16539afcab8d53 Author: Matthias Clasen Date: Sat Sep 8 16:11:29 2012 -0400 network: Remove unused object from ui file The liststore for wifi connections is now defined in network-wifi.ui, the object in network.ui is a leftover. panels/network/network.ui | 18 ------------------ 1 file changed, 18 deletions(-) commit 69a823f9a9a2ea986de293b48c779391ac4ad0bd Author: Matthias Clasen Date: Sat Sep 8 15:41:18 2012 -0400 network: Rename a function 'Connect to hidden' is not really an access point. Update the function name to reflect that. Also, update the translator comment to be more to the point. panels/network/net-device-wifi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) commit ac67290cb7cf2f0830afd39350d5e501c7d1d0d9 Author: Matthias Clasen Date: Sat Sep 8 15:25:31 2012 -0400 network: Make the 'Settings...' buttons work properly The code was assuming that 'editing' always means editing the currently active connection. With the new design of the wifi details tabs, that is no longer the case, we want to be able to edit non-active connections. This commit makes it so. panels/network/net-device-wifi.c | 48 +++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 6 deletions(-) commit 56a0be042243d250c32c98c448b20049f56bc7c3 Author: Matthias Clasen Date: Sat Sep 8 15:24:39 2012 -0400 network: Add more buttons Make the details pages for in-range and out-of-range aps more similar, by adding 'Forget Network' and 'Settings...' buttons to both. This is a step towards using the same details page for all aps and connections. panels/network/network-wifi.ui | 127 +++++++++++++++++++++++++++-------------- 1 file changed, 84 insertions(+), 43 deletions(-) commit 31dade6279e9b23f77d37beb013921f009be0168 Author: Matthias Clasen Date: Sat Sep 8 14:23:36 2012 -0400 network: Mark all rows representing saved connections as such When we find a saved connection among the access points already in the list, we forget to mark it as saved, so the arrow to go to the details page is not shown. panels/network/net-device-wifi.c | 1 + 1 file changed, 1 insertion(+) commit ec629b73ad5e2b29eb49992861b0c46faf58b7b4 Author: Matthias Clasen Date: Sat Sep 8 14:22:17 2012 -0400 network: Add a separator before the arrow when needed The separator is giving a hint that there are two clickable areas in the row. https://bugzilla.gnome.org/show_bug.cgi?id=682270 panels/network/Makefile.am | 2 + panels/network/net-device-wifi.c | 57 ++++++++++- panels/network/panel-cell-renderer-separator.c | 130 +++++++++++++++++++++++++ panels/network/panel-cell-renderer-separator.h | 62 ++++++++++++ 4 files changed, 250 insertions(+), 1 deletion(-) commit 7ef84e87e9728587aea5fd3cf80031c5b1a894c1 Author: Matthias Clasen Date: Thu Sep 13 01:19:35 2012 -0400 mouse: Fix accessible labels for switches in mouse panel Setting mnemonic-widget on the labels makes orca read out meaningful text for the switches. https://bugzilla.gnome.org/show_bug.cgi?id=683703 panels/mouse/gnome-mouse-properties.ui | 1 + 1 file changed, 1 insertion(+) commit 828e896e12a31427e6e56f855365bfca2ff151dc Author: Matthias Clasen Date: Thu Sep 13 01:18:55 2012 -0400 bluetooth: Fix accessible labels for switches in bluetooth panel Setting mnemonic-widget on the labels makes orca read out meaningful text for the switches. https://bugzilla.gnome.org/show_bug.cgi?id=683703 panels/bluetooth/bluetooth.ui | 2 ++ 1 file changed, 2 insertions(+) commit 1db660c410769930eef6d043e36e3e13f4267a96 Author: Matthias Clasen Date: Thu Sep 13 00:40:32 2012 -0400 screen: Make notification checkbox focusable This was certainly just an oversight, but it makes the checkbox essentially nonaccessible. panels/screen/screen.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 539d78cb63e542b6d0e060c9d2e41ea817701458 Author: Matthias Clasen Date: Thu Sep 13 06:28:44 2012 -0400 universal access: Fix labels for switches in zoom options Setting mnemonic-widget on the labels makes orca read out meaningful text for the switches. https://bugzilla.gnome.org/show_bug.cgi?id=683703 panels/universal-access/zoom-options.ui | 10 ++++++++++ 1 file changed, 10 insertions(+) commit 4e24e944ebed97cf9ca7e813267b6ffbb1fa7090 Author: Matthias Clasen Date: Thu Sep 13 06:26:24 2012 -0400 Universal access: Fix up whitespace in zoom options dialog https://bugzilla.gnome.org/show_bug.cgi?id=683544 panels/universal-access/zoom-options.ui | 56 ++++++++++++++++----------------- 1 file changed, 27 insertions(+), 29 deletions(-) commit d5a186d26c3bf4f9af9eab6c786b44e45ca82f3a Author: Matthias Clasen Date: Thu Sep 13 00:38:46 2012 -0400 universal access: Fix accessible labels for switches Setting mnemonic-widget on the labels makes orca read out meaningful text for the switches. https://bugzilla.gnome.org/show_bug.cgi?id=683703 panels/universal-access/uap.ui | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) commit 4f59a4aee657b11aa11fe23f74cea8a570725083 Author: Tom Tryfonidis Date: Thu Sep 13 13:15:55 2012 +0300 Updated Greek translation po/el.po | 185 ++++++++++++++++++++++++++++++--------------------------------- 1 file changed, 87 insertions(+), 98 deletions(-) commit e0c68028be17a5a102c699620f08486616027f62 Author: Daniel Mustieles Date: Thu Sep 13 09:46:00 2012 +0200 Updated Spanish translation po/es.po | 99 ++++++++++++++++++++++++++++++---------------------------------- 1 file changed, 47 insertions(+), 52 deletions(-) commit 8679167492daf471e2bb81dbae82ecc565fe4177 Author: Ville-Pekka Vainio Date: Wed Sep 12 22:31:31 2012 +0300 Finnish translation update by Jiri Grƶnroos po/fi.po | 3883 ++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 2490 insertions(+), 1393 deletions(-) commit 5186ae767c343a349637a992eed578994eaac144 Author: ManojKumar Giri Date: Wed Sep 12 20:31:03 2012 +0530 Updated translation for Odia. po/or.po | 3976 ++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 2584 insertions(+), 1392 deletions(-) commit 885f44c1c8bd56de99477d6721e9440e901bb432 Author: Shankar Prasad Date: Wed Sep 12 18:43:01 2012 +0530 Updated kn translation po/kn.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit e9c6aefeb70db2238d8281415ed192c63885fb79 Author: Shankar Prasad Date: Wed Sep 12 18:39:18 2012 +0530 Updated kn translation po/kn.po | 78 ++++++++++++++++++++++++++++++---------------------------------- 1 file changed, 36 insertions(+), 42 deletions(-) commit c4544a8a470b3dd3cc396b77f5416f2fa8024845 Author: Shankar Prasad Date: Wed Sep 12 16:31:35 2012 +0530 Updated kn translation po/kn.po | 82 +++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 48 insertions(+), 34 deletions(-) commit d06250b1bab3f25de55c5d43e0344a6b36550f11 Author: Sandeep Sheshrao Shedmake Date: Wed Sep 12 15:44:41 2012 +0530 Updated Marathi Translations po/mr.po | 1906 ++++++++++++++++++++++++++++---------------------------------- 1 file changed, 866 insertions(+), 1040 deletions(-) commit 2a88736cf61395b731b3d3f8f9615ec11248d004 Author: Bastien Nocera Date: Wed Sep 12 10:24:19 2012 +0100 wacom: Add link to wacom docs And not the generic control-center docs. https://bugzilla.gnome.org/show_bug.cgi?id=675471#c40 panels/wacom/cc-wacom-panel.c | 9 +++++++++ 1 file changed, 9 insertions(+) commit 2ebf2ecad24df1567380d30b2d2929aa63e9fc90 Author: Bastien Nocera Date: Wed Sep 12 10:23:39 2012 +0100 wacom: Bump g-s-d requirement For the new action type. configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 083c19d5528f5c765a2990e9a8c13e45563c1fbb Author: Bastien Nocera Date: Wed Sep 12 09:44:00 2012 +0100 wacom: Bump minimum libwacom req to 0.6 configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 1384bb5ecea83fce78a1a7451e86ac09f6b76cd9 Author: A S Alam Date: Wed Sep 12 07:20:56 2012 +0530 update Punjabi Translation po/pa.po | 382 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 186 insertions(+), 196 deletions(-) commit eebb95d2f7a7697324518cab64d9cd1418ca6855 Author: Nilamdyuti Goswami Date: Tue Sep 11 20:46:30 2012 +0530 Assamese translation updated po/as.po | 782 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 408 insertions(+), 374 deletions(-) commit 3550944c489d3d73be2f409765f7895e2f828128 Author: Nguyį»…n ThĆ”i Ngį»c Duy Date: Tue Sep 11 21:04:02 2012 +0700 Updated Vietnamese translation po/vi.po | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) commit 34da50157175abbb569b408d745aa11168e82621 Author: Nguyį»…n ThĆ”i Ngį»c Duy Date: Tue Sep 11 21:01:25 2012 +0700 po/vi.po: import from Damned Lies po/vi.po | 438 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 232 insertions(+), 206 deletions(-) commit 1eb906515fe100bb3193ed29ceda616266f5ebd4 Author: Marek Kasik Date: Thu Sep 6 14:06:01 2012 +0200 printers: Use GPLv2+ for files created by Marek Kasik This commit is related to the bug #683420. panels/printers/pp-cups.c | 2 +- panels/printers/pp-cups.h | 2 +- panels/printers/pp-host.c | 2 +- panels/printers/pp-host.h | 2 +- panels/printers/pp-ipp-option-widget.c | 2 +- panels/printers/pp-ipp-option-widget.h | 2 +- panels/printers/pp-jobs-dialog.c | 2 +- panels/printers/pp-jobs-dialog.h | 2 +- panels/printers/pp-maintenance-command.c | 2 +- panels/printers/pp-maintenance-command.h | 2 +- panels/printers/pp-new-printer-dialog.c | 2 +- panels/printers/pp-new-printer-dialog.h | 2 +- panels/printers/pp-new-printer.c | 2 +- panels/printers/pp-new-printer.h | 2 +- panels/printers/pp-options-dialog.c | 2 +- panels/printers/pp-options-dialog.h | 2 +- panels/printers/pp-ppd-option-widget.c | 2 +- panels/printers/pp-ppd-option-widget.h | 2 +- panels/printers/pp-ppd-selection-dialog.c | 2 +- panels/printers/pp-ppd-selection-dialog.h | 2 +- panels/printers/pp-utils.c | 2 +- panels/printers/pp-utils.h | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) commit fde7b55ce3902d2772a0ecf046f6f544f78dd2ac Author: Shankar Prasad Date: Tue Sep 11 18:33:16 2012 +0530 Updated kn translation po/kn.po | 1685 ++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 857 insertions(+), 828 deletions(-) commit 52dca977990e4e5194378bcaac957b7a3843a501 Author: Sweta Kothari Date: Tue Sep 11 16:58:13 2012 +0530 Updated gujarati file po/gu.po | 4074 ++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 2518 insertions(+), 1556 deletions(-) commit e2d852c58390a8d2d9b730620b3a2ddd919402e4 Author: Nguyį»…n ThĆ”i Ngį»c Duy Date: Mon Sep 10 21:25:01 2012 +0700 Updated Vietnamese translation po/vi.po | 54 +++++++++++++++++++----------------------------------- 1 file changed, 19 insertions(+), 35 deletions(-) commit 0a0bc59afacc08fe0ec6378a7171eb3fdb549fe3 Author: Bastien Nocera Date: Mon Sep 10 14:55:04 2012 +0100 printers: Avoid redefinition of UserResponseCallback It was declared to be the same value in all three headers, which causes problems with old version of GCC. https://bugzilla.gnome.org/show_bug.cgi?id=683696 panels/printers/pp-jobs-dialog.h | 3 +-- panels/printers/pp-options-dialog.h | 3 +-- panels/printers/pp-ppd-selection-dialog.h | 2 -- panels/printers/pp-utils.h | 2 ++ 4 files changed, 4 insertions(+), 6 deletions(-) commit 312a5dfe874483ebfd59c960b804e70086ac4519 Author: William Jon McCann Date: Mon Sep 10 09:42:24 2012 -0400 Set pixbuf renderer stock size to 32 so emblems render at 16px https://bugzilla.gnome.org/show_bug.cgi?id=682123 panels/background/cc-background-chooser-dialog.c | 6 ++++++ 1 file changed, 6 insertions(+) commit 35219123286cfcf08452ef49e2c6a578fd1fd1f3 Author: Fran DiĆ©guez Date: Mon Sep 10 15:06:37 2012 +0200 Updated Galician translations po/gl.po | 108 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 56 insertions(+), 52 deletions(-) commit f2e54f77feb22cd021ba8676878594f81169ec8d Author: Duarte Loreto Date: Mon Sep 10 01:11:43 2012 +0100 Updated Portuguese translation po/pt.po | 3754 ++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 2312 insertions(+), 1442 deletions(-) commit 8af69625d3373809ffb5e603e69c6979e5e67247 Author: Daiki Ueno Date: Tue Aug 28 14:04:34 2012 +0900 region: Use ibus_get_language_name() to get a language from its code ibus_engine_desc_get_language() may return an empty string or language codes that gdm_get_language_from_name() doesn't understand. Use ibus_get_language_name() instead to handle such cases properly. This also allows us to use the same method in gnome-shell to get consistent display strings. https://bugzilla.gnome.org/show_bug.cgi?id=682851 panels/region/gnome-region-panel-input.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) commit 830c1aa5a2df1d4a5a37656b3ee5ec86117d9c97 Author: Arash Mousavi Date: Sat Sep 8 15:28:58 2012 +0430 l10n: Updated Persian translation po/fa.po | 5085 +++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 3413 insertions(+), 1672 deletions(-) commit 014f153dcfdc0ff62a4d8a3a5a0f336ead1f7fb8 Author: Gabor Kelemen Date: Sat Sep 8 00:03:33 2012 +0200 Updated Hungarian translation po/hu.po | 5194 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 3146 insertions(+), 2048 deletions(-) commit 5f353fa2b6d44a4be4e601b25f712e73736cd4c2 Author: Michael Terry Date: Fri Sep 7 15:37:42 2012 -0400 power: Use GCancellable better, to avoid a crash https://bugzilla.gnome.org/show_bug.cgi?id=683533 panels/power/cc-power-panel.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) commit 11d808953933143bb272730a417322c8161e7f3d Author: Aurimas Černius Date: Fri Sep 7 20:33:36 2012 +0300 Updated Lithuanian translation po/lt.po | 251 +++++++++++++++++++++++++++------------------------------------ 1 file changed, 106 insertions(+), 145 deletions(-) commit 3406a950b6bd5e023e9d348adb5e20ea7df46a60 Author: Ihar Hrachyshka Date: Fri Sep 7 19:29:17 2012 +0300 Updated Belarusian translation. po/be.po | 999 ++++++++++++++++++++++++++++++--------------------------------- 1 file changed, 476 insertions(+), 523 deletions(-) commit ec35ef91d6e5f863ac4e2c6ec2cb4f68d0b72c11 Author: Yaron Shahrabani Date: Fri Sep 7 16:19:00 2012 +0300 Updated Hebrew translation. po/he.po | 536 ++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 289 insertions(+), 247 deletions(-) commit 12a319875a96b01e8f717880371a6e462a51fcb9 Author: Bastien Nocera Date: Tue Aug 28 16:27:19 2012 +0100 bluetooth: Don't break the custom widgets on connect We used to destroy and recreate the custom widgets whenever any of the properties changed. Now we make sure that the custom widgets are only destroyed and recreated when the device selected is a different one. This fixes NetworkManager's Bluetooth plugins getting destroyed because the Connected property changed, as it was trying to connect to the device. https://bugzilla.gnome.org/show_bug.cgi?id=681456 panels/bluetooth/cc-bluetooth-panel.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) commit ba7171a57972cf7cd3189ac006aad492db302a9c Author: Matthias Clasen Date: Thu Sep 6 19:17:21 2012 -0400 Set a window title on the add printer dialog Otherwise, it shows up as cinnamon-control-center, which is ugly. panels/printers/new-printer-dialog.ui | 1 + 1 file changed, 1 insertion(+) commit 299530a7a6f9a3ebb028a4c1e9ae02e0b2c5b651 Author: Matthias Clasen Date: Thu Sep 6 19:12:19 2012 -0400 Set a window title on the add network dialog Otherwise, it shows up as cinnamon-control-center, which is ugly. panels/network/network.ui | 1 + 1 file changed, 1 insertion(+) commit cd0363d3f59d7d53d28188bef3479073f724d1ce Author: Matthias Clasen Date: Thu Sep 6 19:10:37 2012 -0400 Set a window title on the hotspot dialog Set a blank title on the hotspot dialog, otherwise it shows up as cinnamon-control-center, which is ugly. panels/network/network-wifi.ui | 1 + 1 file changed, 1 insertion(+) commit a955ec4152584f208c4e4e26bf58a1a4d285ce7a Author: Matthias Clasen Date: Thu Sep 6 07:43:05 2012 -0400 Switch files created by me to GPLv2+ This matches the rest of the control-center code base. https://bugzilla.gnome.org/show_bug.cgi?id=683420 panels/common/cc-common-language.c | 2 +- panels/common/cc-common-language.h | 2 +- panels/common/cc-language-chooser.c | 2 +- panels/common/cc-language-chooser.h | 2 +- panels/user-accounts/pw-utils.c | 2 +- panels/user-accounts/pw-utils.h | 2 +- panels/user-accounts/um-account-dialog.c | 2 +- panels/user-accounts/um-account-dialog.h | 2 +- panels/user-accounts/um-account-type.c | 2 +- panels/user-accounts/um-account-type.h | 2 +- panels/user-accounts/um-crop-area.c | 2 +- panels/user-accounts/um-editable-button.c | 2 +- panels/user-accounts/um-editable-button.h | 2 +- panels/user-accounts/um-editable-combo.c | 2 +- panels/user-accounts/um-editable-combo.h | 2 +- panels/user-accounts/um-password-dialog.c | 2 +- panels/user-accounts/um-password-dialog.h | 2 +- panels/user-accounts/um-photo-dialog.c | 2 +- panels/user-accounts/um-photo-dialog.h | 2 +- panels/user-accounts/um-user-manager.c | 2 +- panels/user-accounts/um-user-manager.h | 2 +- panels/user-accounts/um-user-module.c | 2 +- panels/user-accounts/um-user-panel.c | 2 +- panels/user-accounts/um-user-panel.h | 2 +- panels/user-accounts/um-utils.c | 2 +- panels/user-accounts/um-utils.h | 2 +- shell/cc-editable-entry.c | 2 +- shell/cc-editable-entry.h | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) commit 611cc74c14881fb019b43fe176ff004a3ab10b25 Author: Christian Kirbach Date: Fri Sep 7 00:07:21 2012 +0200 Updated German translation po/de.po | 2536 ++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 1206 insertions(+), 1330 deletions(-) commit 8d5a43a0878a6ecfdbb4224750b2faf565d4a9bb Author: ŠœŠøŃ€Š¾ŃŠ»Š°Š² ŠŠøŠŗŠ¾Š»ŠøŃ› Date: Thu Sep 6 22:54:31 2012 +0200 Updated Serbian translation po/sr.po | 51 +++++++++++++-------------------------------------- po/sr@latin.po | 51 +++++++++++++-------------------------------------- 2 files changed, 26 insertions(+), 76 deletions(-) commit 406b1f4b74570a4497683efa33d37db238a004bd Author: Piotr Drąg Date: Thu Sep 6 21:49:33 2012 +0200 Fix Slovenian translation po/sl.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) commit 19d04d6dff5c49f3076ccc98e6bf3e97b2c2c004 Author: Matej Urbančič Date: Thu Sep 6 21:09:39 2012 +0200 Updated Slovenian translation po/sl.po | 2605 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 1545 insertions(+), 1060 deletions(-) commit 226a0af02893d83faee0faeba40c8ebb6a443b5e Author: Daniel Mustieles Date: Thu Sep 6 18:26:14 2012 +0200 Updated Spanish translation po/es.po | 288 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 143 insertions(+), 145 deletions(-) commit c1857b0f9c80434890679ace83865db5d2565fa6 Author: Benjamin Berg Date: Wed Aug 8 21:49:00 2012 +0200 display: Fix mouse events not working in preview We need to save event areas with the correct transformation. The following things need to be take into account: * Current cairo matrix (translations) * Widget allocation because it is painting on the parents widgets window * Cairo device offset, which GTK+ sets (but not for a full window redraw) https://bugzilla.gnome.org/show_bug.cgi?id=681475 panels/display/scrollarea.c | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) commit 72cce6b89f7013a9004ddd3b240c823155cc49ce Author: Andika Triwidada Date: Thu Sep 6 16:00:01 2012 +0700 Updated Indonesian translation po/id.po | 65 ++++++++-------------------------------------------------------- 1 file changed, 8 insertions(+), 57 deletions(-) commit 4130be13b55fdf1f6d7d76c2f7b928a4f3fcf2c4 Author: Dirgita Date: Thu Sep 6 15:57:42 2012 +0700 Updated Indonesian translation po/id.po | 323 +++++++++++++++++++++++++++++---------------------------------- 1 file changed, 147 insertions(+), 176 deletions(-) commit 3e86bed190ae912778ff8b1b6dd3f3d552168a30 Author: Tom Tryfonidis Date: Thu Sep 6 02:37:48 2012 +0300 Updated Greek translation po/el.po | 282 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 144 insertions(+), 138 deletions(-) commit 954b530d37fe5070fc64d508d3498fc4218c66d4 Author: Piotr Drąg Date: Wed Sep 5 21:07:06 2012 +0200 Updated Polish translation \m/ I kinda miss the easter egg GEGL Invaders game. po/pl.po | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) commit eee381abddf230a2518ff49e745eab4903ed0d45 Author: Florian Müllner Date: Wed Aug 22 19:28:41 2012 +0200 mouse: Add penta-click test in addition to double-click Clicking anything five times should obviously bring up an image (by Jakub Steiner) of a five-legged goat :-) https://bugzilla.gnome.org/show_bug.cgi?id=682492 panels/mouse/Makefile.am | 1 + panels/mouse/double-click-gegl.png | Bin 0 -> 9568 bytes panels/mouse/gnome-mouse-test.c | 93 +- panels/mouse/scroll-test-gegl.svg | 1781 ++++++++++++++++++++++++++++++++++++ 4 files changed, 1861 insertions(+), 14 deletions(-) commit 49797e8ae2753bacc74b86cd28be250ff93a62cc Author: Stefano Facchini Date: Wed Sep 5 19:34:19 2012 +0200 printers: Add missing definition of HAVE_CUPS_1_6 Commit 1532d7ef forgot to actually define HAVE_CUPS_1_6 when building against CUPS 1.6 https://bugzilla.gnome.org/show_bug.cgi?id=683441 panels/printers/pp-maintenance-command.c | 4 ++++ 1 file changed, 4 insertions(+) commit dbff39026baac85e96ad1fa38bbd95ba68680a11 Author: Jakub Steiner Date: Sat Sep 1 00:31:34 2012 +0200 background: Use a varied color palette The original palette for color selection was a bit flat. The new selection includes 9 "fun" colors that are highly saturated and people would be initialy drawn to select, as well as 6 colors that are more appropriate wallpapers and are good to use for extended periods of time. https://bugzilla.gnome.org/show_bug.cgi?id=682556 panels/background/bg-colors-source.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) commit eaacb99d5feae22fb6b2794b318fc303962e0cf9 Author: Matthias Clasen Date: Tue Jul 24 12:27:19 2012 -0400 user-accounts: Use GStreamer 1.0 Just changing the versions in configure.ac seems to make cheese build fine against gstreamer 1.0. https://bugzilla.gnome.org/show_bug.cgi?id=680538 configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 1913cc212644b1464a595d2799e6300465c1fcc9 Author: Chao-Hsiung Liao Date: Wed Sep 5 19:58:30 2012 +0800 Updated Traditional Chinese translation(Hong Kong and Taiwan) po/zh_HK.po | 850 +++++++++++++++++++++++++++++++---------------------------- po/zh_TW.po | 852 ++++++++++++++++++++++++++++++++---------------------------- 2 files changed, 900 insertions(+), 802 deletions(-) commit 1cd19d0f472c48108d35222fd74ae316a37fdace Author: ŠœŠøŃ€Š¾ŃŠ»Š°Š² ŠŠøŠŗŠ¾Š»ŠøŃ› Date: Wed Sep 5 10:02:43 2012 +0200 Updated Serbian translation po/sr.po | 1261 ++++++++++++++++++++++++++++++-------------------------- po/sr@latin.po | 1261 ++++++++++++++++++++++++++++++-------------------------- 2 files changed, 1354 insertions(+), 1168 deletions(-) commit dd18ab17d44c5981b8f4e74c33ce58202bee9758 Author: Khaled Hosny Date: Wed Sep 5 07:18:57 2012 +0200 Updated Arabic translation po/ar.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit 753f9472dcf4ec53f68bb45bfa1e083f7f950755 Author: Khaled Hosny Date: Wed Sep 5 07:15:38 2012 +0200 Updated Arabic translation po/ar.po | 256 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 126 insertions(+), 130 deletions(-) commit 9e4566b1f5cac101eeaedba97bf29763a0c33bfe Author: Piotr Drąg Date: Wed Sep 5 00:24:11 2012 +0200 Updated Polish translation po/pl.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) commit 3bff79d8210453e31ec30a4d69df1a7e546da3ec Author: Bastien Nocera Date: Tue Sep 4 21:51:58 2012 +0100 3.5.91 NEWS | 44 ++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 2 +- 2 files changed, 45 insertions(+), 1 deletion(-) commit 503a9104ed10970cc492ecee1820b0b59cce56f0 Author: Bastien Nocera Date: Tue Sep 4 21:34:35 2012 +0100 build: Bump dependencies for keyboard panel changes We want the "show all the input sources" setting to work. configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit ef4d5c57431128c3746f9b1d614786be9ff80776 Author: Fran DiĆ©guez Date: Tue Sep 4 22:37:32 2012 +0200 Updated Galician translations po/gl.po | 267 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 132 insertions(+), 135 deletions(-) commit edba26d342b2cdc51049b657791bfe741e1dbfe5 Author: Dr.T.Vasudevan Date: Tue Sep 4 21:08:26 2012 +0530 updated Tamil translation po/ta.po | 255 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 124 insertions(+), 131 deletions(-) commit 13319e391ada514809762a442c2ffa8c462b4a7e Author: Dr.T.Vasudevan Date: Tue Sep 4 21:04:36 2012 +0530 updated Tamil translation po/ta.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 7bdfb4017edbd54a2be1dfbfbc726b009429b025 Author: Dr.T.Vasudevan Date: Tue Sep 4 20:58:29 2012 +0530 updated Tamil translation po/ta.po | 3620 ++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 2254 insertions(+), 1366 deletions(-) commit 9d46f8393c0074cbc65c1c4b62e3996fd5b6b255 Author: Rui Matos Date: Tue Sep 4 14:43:42 2012 +0200 region: Expand the supported IBus engines whitelist Thanks to Daiki Ueno for assembling the list. https://bugzilla.gnome.org/show_bug.cgi?id=682313 panels/region/gnome-region-panel-input.c | 130 ++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 1 deletion(-) commit 42e8783376c89f3a8ed04c30d763f6d52614703d Author: Piotr Drąg Date: Tue Sep 4 15:00:49 2012 +0200 Updated Polish translation po/pl.po | 174 +++++++++++++++++++++++---------------------------------------- 1 file changed, 62 insertions(+), 112 deletions(-) commit a0ad46365fa96b7159ab16dede4b5e39b1346750 Author: Marek Kasik Date: Mon Sep 3 21:35:21 2012 +0200 printers: Remove redundant functions Remove functions which are not used anymore. (#683229) panels/printers/pp-utils.c | 1216 -------------------------------------------- panels/printers/pp-utils.h | 11 - 2 files changed, 1227 deletions(-) commit 45ba8e89e86397df912e07df14d76373f1c7e7af Author: Marek Kasik Date: Mon Sep 3 21:25:59 2012 +0200 printers: Redesign of new printer dialog This commit implements design changes from https://live.gnome.org/Design/SystemSettings/Printers. The new printer dialog gets informations about connected devices from CUPS server asynchronously and separately for each backend now. Entering an address into the entry and pressing the icon inside the entry or enter starts to detect printers on the entered host. Entering a text which is a substring of a name of a device or its location filters the list to contain just devicess with the string in it (e.g. Canon will keep devices with "Canon" in their name). The PpNewPrinterDialog is regular object now. It emits signal "pre-response" when dialog is closed and a printer is being added and signal "response" when the new printer was added, addition of the new printer failed or the dialog was cancelled. This commit removes FirewallD support from new printer dialog. (#683229) panels/printers/cc-printers-panel.c | 390 ++++- panels/printers/new-printer-dialog.ui | 448 ++--- panels/printers/pp-new-printer-dialog.c | 2900 ++++++++++++------------------- panels/printers/pp-new-printer-dialog.h | 39 +- 4 files changed, 1641 insertions(+), 2136 deletions(-) commit 9428b7a641052f164a4d7f1b78958ecf931e01f5 Author: Marek Kasik Date: Mon Sep 3 21:18:58 2012 +0200 printers: Set longer timeouts Set longer timeouts for GetBestDrivers, PrinterAddOption and PrinterAddOptionDefault. These can take more time than already specified timeouts. (#683229) panels/printers/pp-utils.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) commit c34e282babfc6e7d90c9f9a832c186b2c8a3288f Author: Marek Kasik Date: Mon Sep 3 21:16:06 2012 +0200 printers: Return after callback Return from get_ppds_attribute_async() right after callback was called. Otherwise the callback could be called twice. (#683229) panels/printers/pp-utils.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) commit dea424dbeeaabb46cb0a5e9d950371c837babb6e Author: Marek Kasik Date: Mon Sep 3 20:44:32 2012 +0200 printers: Add PpNewPrinter object for installation of new printer PpNewPrinter contains asynchronous method for installation of new printer. The new printer is specified by given parameters (e.g. name, device-id, device-uri, ppd-name, info, location, ...). (#683229) panels/printers/Makefile.am | 2 + panels/printers/pp-new-printer.c | 1444 ++++++++++++++++++++++++++++++++++++++ panels/printers/pp-new-printer.h | 66 ++ 3 files changed, 1512 insertions(+) commit 6f8b9e88254cb01879ff4a9891b123eb8270b488 Author: Marek Kasik Date: Mon Sep 3 20:33:21 2012 +0200 printers: Allow printer_get_ppd_async() to get PPD from remote host Adds host_name and port parameters to printer_get_ppd_async(). If host_name is NULL then it gets the PPD from local CUPS server. (#683229) panels/printers/pp-options-dialog.c | 2 ++ panels/printers/pp-ppd-option-widget.c | 2 ++ panels/printers/pp-utils.c | 23 ++++++++++++++++++++++- panels/printers/pp-utils.h | 2 ++ 4 files changed, 28 insertions(+), 1 deletion(-) commit 869555455795d688ec0c520df0bba9ae6ba3c12b Author: Marek Kasik Date: Mon Sep 3 20:27:04 2012 +0200 printers: Make get_paper_size_from_locale() available to other source files Export get_paper_size_from_locale() in pp-utils.h. (#683229) panels/printers/pp-utils.c | 2 +- panels/printers/pp-utils.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) commit 1532d7ef1af7790c7eda92ae2fff1179230fd6d0 Author: Marek Kasik Date: Mon Sep 3 20:18:47 2012 +0200 printers: Add PpMaintenanceCommand object for execution of commands PpMaintenanceCommand object contains asynchronous method which executes given CUPS maintenance command (e.g. "AutoConfigure"). (#683229) panels/printers/Makefile.am | 2 + panels/printers/pp-maintenance-command.c | 325 +++++++++++++++++++++++++++++++ panels/printers/pp-maintenance-command.h | 69 +++++++ 3 files changed, 396 insertions(+) commit 142d2c65b4fa01100d7cc8d6f6ca856c94d07182 Author: Marek Kasik Date: Mon Sep 3 20:04:38 2012 +0200 printers: Add PpHost object for listing print devices This commit adds PpHost object which represents a remote host from which we want to get printers. It contains asynchronous method for enumerating printers list from the host using CUPS' SNMP backend and method for enumerating printers list directly from the remote CUPS server running on the host. (#683229) panels/printers/Makefile.am | 2 + panels/printers/pp-host.c | 459 ++++++++++++++++++++++++++++++++++++++++++++ panels/printers/pp-host.h | 82 ++++++++ panels/printers/pp-utils.h | 4 +- 4 files changed, 546 insertions(+), 1 deletion(-) commit 0cb0dab3778d75c3edec5b6de956ee70ddb026b5 Author: Marek Kasik Date: Mon Sep 3 19:50:31 2012 +0200 printers: Add async method for listing print devices This commit adds asynchronous function get_cups_devices_async() which sequentially executes CUPS' backends and returns found devices by a callback. (#683229) panels/printers/pp-utils.c | 286 +++++++++++++++++++++++++++++++++++++++++++++ panels/printers/pp-utils.h | 29 +++++ 2 files changed, 315 insertions(+) commit 5a2794a7fefaebe7c3467136a27ad8c9facda747 Author: Marek Kasik Date: Mon Sep 3 21:46:50 2012 +0200 printers: Add PpCups object for getting destinations PpCups object represents local CUPS server. It contains asynchronous method for getting printers installed on the server. It is an asynchronous version of cupsGetDests(). (#683229) panels/printers/Makefile.am | 2 + panels/printers/pp-cups.c | 125 ++++++++++++++++++++++++++++++++++++++++++++ panels/printers/pp-cups.h | 71 +++++++++++++++++++++++++ 3 files changed, 198 insertions(+) commit cc2e15a592b34be022bb649e18fe397c31214cb4 Author: Marek Kasik Date: Mon Sep 3 21:43:14 2012 +0200 printers: Move common constants to pp-utils.h Move constants which are used in more than one source file to pp-utils.h. (#683229) panels/printers/pp-new-printer-dialog.c | 8 -------- panels/printers/pp-utils.c | 6 ------ panels/printers/pp-utils.h | 8 ++++++++ 3 files changed, 8 insertions(+), 14 deletions(-) commit 1f76a739e3e0a79190b036fc890fdaac1a6b8c16 Author: Marek Kasik Date: Mon Sep 3 19:11:28 2012 +0200 printers: Include missing header has to be included in pp-utils.h because there are functions in pp-utils.h which accepts types defined in the cups.h as their parameters. (#683229) panels/printers/pp-utils.h | 1 + 1 file changed, 1 insertion(+) commit 2a87480f2654fa18cd683497fe2a569f732dab68 Author: Rui Matos Date: Mon Sep 3 01:36:20 2012 +0200 region: Honor the 'show-all-sources' gsettings key This setting overrides our supported IBus engines whitelist and makes us show every engine installed on the system when enabled. https://bugzilla.gnome.org/show_bug.cgi?id=682313 panels/region/gnome-region-panel-input.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) commit 72bf4895558173dcfbdeead2175fd619fc2264e8 Author: Bruce Cowan Date: Tue Sep 4 12:09:17 2012 +0100 Updated British English translation po/en_GB.po | 3710 ++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 2288 insertions(+), 1422 deletions(-) commit dd256f265b1a94d6466034e7933196e4668b81a1 Author: Piotr Drąg Date: Mon Sep 3 21:53:45 2012 +0200 Updated Polish translation po/pl.po | 55 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 24 deletions(-) commit f0be9146d418d7db8dce6826134e8e7ab15af911 Author: Federico Mena Quintero Date: Mon Sep 3 14:07:29 2012 -0500 displays: bgo#592412 - Make 'Mirrored Displays' string consistent with GnomeRRLabeler We had 'Mirror displays' as a command in the control center, but 'Mirror screens' as a description in GnomeRRLabeler. Now we have 'Mirrored Displays' as a description of the current state. Signed-off-by: Federico Mena Quintero panels/display/cc-display-panel.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) commit 7171520e72f633b905e9b6ea8afa48adada8d4ea Author: Rui Matos Date: Sat Aug 25 21:23:23 2012 +0200 region: Use the async IBus engines getter https://bugzilla.gnome.org/show_bug.cgi?id=683035 panels/region/gnome-region-panel-input.c | 63 +++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 9 deletions(-) commit 0703d545a5d82f0748d30d898659a340d78684bf Author: William Jon McCann Date: Tue Aug 21 23:16:33 2012 -0400 datetime: make the map insensitive when the panel is locked https://bugzilla.gnome.org/show_bug.cgi?id=672445 panels/datetime/Makefile.am | 43 ++++++++++++++++- panels/datetime/cc-timezone-map.c | 72 +++++++++++++++++++++++----- panels/datetime/data/bg_dim.png | Bin 0 -> 95862 bytes panels/datetime/data/timezone_-10_dim.png | Bin 0 -> 5139 bytes panels/datetime/data/timezone_-11_dim.png | Bin 0 -> 4815 bytes panels/datetime/data/timezone_-1_dim.png | Bin 0 -> 4953 bytes panels/datetime/data/timezone_-2_dim.png | Bin 0 -> 2670 bytes panels/datetime/data/timezone_-3.5_dim.png | Bin 0 -> 995 bytes panels/datetime/data/timezone_-3_dim.png | Bin 0 -> 8773 bytes panels/datetime/data/timezone_-4.5_dim.png | Bin 0 -> 1527 bytes panels/datetime/data/timezone_-4_dim.png | Bin 0 -> 9836 bytes panels/datetime/data/timezone_-5.5_dim.png | Bin 0 -> 859 bytes panels/datetime/data/timezone_-5_dim.png | Bin 0 -> 12224 bytes panels/datetime/data/timezone_-6_dim.png | Bin 0 -> 8833 bytes panels/datetime/data/timezone_-7_dim.png | Bin 0 -> 7868 bytes panels/datetime/data/timezone_-8_dim.png | Bin 0 -> 4261 bytes panels/datetime/data/timezone_-9.5_dim.png | Bin 0 -> 859 bytes panels/datetime/data/timezone_-9_dim.png | Bin 0 -> 4972 bytes panels/datetime/data/timezone_0_dim.png | Bin 0 -> 7074 bytes panels/datetime/data/timezone_10.5_dim.png | Bin 0 -> 844 bytes panels/datetime/data/timezone_10_dim.png | Bin 0 -> 8395 bytes panels/datetime/data/timezone_11.5_dim.png | Bin 0 -> 868 bytes panels/datetime/data/timezone_11_dim.png | Bin 0 -> 6744 bytes panels/datetime/data/timezone_12.75_dim.png | Bin 0 -> 846 bytes panels/datetime/data/timezone_12_dim.png | Bin 0 -> 3935 bytes panels/datetime/data/timezone_13_dim.png | Bin 0 -> 876 bytes panels/datetime/data/timezone_14_dim.png | Bin 0 -> 4150 bytes panels/datetime/data/timezone_1_dim.png | Bin 0 -> 10187 bytes panels/datetime/data/timezone_2_dim.png | Bin 0 -> 8709 bytes panels/datetime/data/timezone_3.5_dim.png | Bin 0 -> 1781 bytes panels/datetime/data/timezone_3_dim.png | Bin 0 -> 9877 bytes panels/datetime/data/timezone_4.5_dim.png | Bin 0 -> 1385 bytes panels/datetime/data/timezone_4_dim.png | Bin 0 -> 2754 bytes panels/datetime/data/timezone_5.5_dim.png | Bin 0 -> 3405 bytes panels/datetime/data/timezone_5.75_dim.png | Bin 0 -> 1596 bytes panels/datetime/data/timezone_5_dim.png | Bin 0 -> 8117 bytes panels/datetime/data/timezone_6.5_dim.png | Bin 0 -> 1675 bytes panels/datetime/data/timezone_6_dim.png | Bin 0 -> 4678 bytes panels/datetime/data/timezone_7_dim.png | Bin 0 -> 7972 bytes panels/datetime/data/timezone_8.75_dim.png | Bin 0 -> 7064 bytes panels/datetime/data/timezone_8_dim.png | Bin 0 -> 9378 bytes panels/datetime/data/timezone_9.5_dim.png | Bin 0 -> 1611 bytes panels/datetime/data/timezone_9_dim.png | Bin 0 -> 8383 bytes 43 files changed, 103 insertions(+), 12 deletions(-) commit ca987eefa277d0a2db0371cedc6aa96820eafffc Author: Daniel Mustieles Date: Mon Sep 3 15:58:32 2012 +0200 Updated Spanish translation po/es.po | 48 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) commit baa6139536bdf8eedf5cc49be87b0bb472904441 Author: Aurimas Černius Date: Sun Sep 2 15:54:24 2012 +0300 Updated Lithuanian translation po/lt.po | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) commit 2f62ee3ca32b266dc905a9baecc5c2b120f7fc89 Author: Kjartan Maraas Date: Sun Sep 2 11:12:52 2012 +0200 Updated Norwegian bokmĆ„l translation po/nb.po | 250 +++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 139 insertions(+), 111 deletions(-) commit 1043d7c741e9f122f2969dc1249793fb8952391f Author: A S Alam Date: Sun Sep 2 09:57:23 2012 +0530 update Punjabi Translation po/pa.po | 462 +++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 255 insertions(+), 207 deletions(-) commit bf6cff639f6618105ca32c94ccf8c629c5724b69 Author: Nguyį»…n ThĆ”i Ngį»c Duy Date: Sat Sep 1 21:07:54 2012 +0700 Updated Vietnamese translation po/vi.po | 52 ++++++++++++++++++++++------------------------------ 1 file changed, 22 insertions(+), 30 deletions(-) commit 62082e8bfdb3b75e0167677b1342c67b7f9d6ab7 Author: Nguyį»…n ThĆ”i Ngį»c Duy Date: Sat Sep 1 20:42:24 2012 +0700 po/vi: import from Damned Lies po/vi.po | 535 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 265 insertions(+), 270 deletions(-) commit 26638cdc7cd8dce50f48d90c64541534269c0951 Author: Fran DiĆ©guez Date: Sat Sep 1 12:38:18 2012 +0200 Updated Galician translations po/gl.po | 135 ++++++--------------------------------------------------------- 1 file changed, 11 insertions(+), 124 deletions(-) commit 041245eeff3646f1cc7027fbea37d95bcf062ea8 Author: Piotr Drąg Date: Fri Aug 31 21:52:39 2012 +0200 Updated Polish translation po/pl.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) commit 41a79d6a35d18e9293fb6326cfac803d92b61f81 Author: Matthias Clasen Date: Fri Aug 31 15:10:45 2012 -0400 Fix big editable labels The code we used to match the entry and label font size and weight broke down with the latest CSS improvements in GTK+. Use a new GtkEntry api for this instead. The GTK+ requirement has been bumped to 3.5.13. configure.ac | 2 +- shell/cc-editable-entry.c | 36 +----------------------------------- 2 files changed, 2 insertions(+), 36 deletions(-) commit cc6734e5c12f859330eb8a8f4b67cfb854cff8c4 Author: Fran DiĆ©guez Date: Fri Aug 31 20:58:20 2012 +0200 Updated Galician translations po/gl.po | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) commit 2231b3dacc23e91c44ff48c9127d13c7fdb62857 Author: Tom Tryfonidis Date: Fri Aug 31 17:56:06 2012 +0300 Updated Greek translation po/el.po | 2304 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 1316 insertions(+), 988 deletions(-) commit 08c06849aa669847003d391aac60bc4946f3b113 Author: Andika Triwidada Date: Fri Aug 31 10:33:14 2012 +0700 Updated Indonesian translation po/id.po | 1281 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 650 insertions(+), 631 deletions(-) commit 4c761c29750ccb2bbdb3a210436b0ac883d354bb Author: Khaled Hosny Date: Thu Aug 30 22:21:43 2012 +0200 Updated Arabic translation po/ar.po | 263 ++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 152 insertions(+), 111 deletions(-) commit 23ce2dbea7ea7341220eb63b4ace34afb64b988b Author: Piotr Drąg Date: Thu Aug 30 18:13:48 2012 +0200 Updated Polish translation po/pl.po | 50 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) commit a73aa77465351cad1da54d9cfb6278bdb1a970df Author: Piotr Drąg Date: Thu Aug 30 17:08:52 2012 +0200 Updated POTFILES.in po/POTFILES.in | 1 + 1 file changed, 1 insertion(+) commit 42b6a0138a730415a3eb6ee1b80ec9bc8c98946f Author: Fran DiĆ©guez Date: Thu Aug 30 14:20:19 2012 +0200 Updated Galician translations po/gl.po | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) commit 936c188bf04a4cddc49308435948e530523d7718 Author: Ondrej Holy Date: Wed Aug 29 12:44:55 2012 +0200 mouse: Widget allocated size fallback https://bugzilla.gnome.org/show_bug.cgi?id=579135 panels/mouse/gnome-mouse-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 1f68f46d74f29403d518be8793f240abcda0ecad Author: Ondrej Holy Date: Wed Aug 29 09:33:16 2012 +0200 mouse: Reset timeouts id to zero https://bugzilla.gnome.org/show_bug.cgi?id=579135 panels/mouse/gnome-mouse-test.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) commit 1cf9c9b078b1068276d4ec548b84b42ac3c6295c Author: Ondrej Holy Date: Thu Aug 23 15:10:19 2012 +0200 mouse: New testing area according to mockup https://bugzilla.gnome.org/show_bug.cgi?id=579135 panels/mouse/Makefile.am | 12 +- panels/mouse/double-click-maybe.png | Bin 4643 -> 0 bytes panels/mouse/double-click-off.png | Bin 4751 -> 0 bytes panels/mouse/double-click-on.png | Bin 6360 -> 0 bytes panels/mouse/gnome-mouse-test.c | 197 +++- panels/mouse/gnome-mouse-test.ui | 78 +- panels/mouse/scroll-test.svg | 1960 +++++++++++++++++++++++++++++++++++ 7 files changed, 2182 insertions(+), 65 deletions(-) commit 419a0481a33cf708c25e944b0d223ffe4fd0b096 Author: Aurimas Černius Date: Wed Aug 29 22:36:19 2012 +0300 Updated Lithuanian translation po/lt.po | 629 ++++++++++++++++++++++++++++++--------------------------------- 1 file changed, 300 insertions(+), 329 deletions(-) commit c4f19cdf22f688efe157a7d7b197142788a4a9f5 Author: Daniel Mustieles Date: Wed Aug 29 17:01:52 2012 +0200 Updated Spanish translation po/es.po | 396 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 206 insertions(+), 190 deletions(-) commit 8198d2602cae1acf5784ab7bae8f29c443f90ab3 Author: Fran DiĆ©guez Date: Wed Aug 29 00:41:28 2012 +0200 Updated Galician translations po/gl.po | 1172 ++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 610 insertions(+), 562 deletions(-) commit 3b87bfd1c0ee55b25e41a475a9d14cf0fe5e325d Author: Piotr Drąg Date: Tue Aug 28 18:54:04 2012 +0200 Updated Polish translation po/pl.po | 298 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 151 insertions(+), 147 deletions(-) commit 8b7fd5787f9bf9d9d9c29f01df9da50cacbcf91b Author: Bastien Nocera Date: Tue Aug 28 16:47:20 2012 +0100 universal-access: Remove unused object One less thing for translators to translate. panels/universal-access/uap.ui | 23 ----------------------- 1 file changed, 23 deletions(-) commit 8c921b2dd4071aa96f27a8d1ecb7edb95f928577 Author: Jiro Matsuzawa Date: Tue Aug 28 23:17:22 2012 +0900 network: add translation context for Wifi security https://bugzilla.gnome.org/show_bug.cgi?id=682876 panels/network/net-device-wifi.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) commit 41584b6e5bef9c175872f0247a7690682e3628d5 Author: Jiro Matsuzawa Date: Tue Aug 28 23:58:06 2012 +0900 universal-access: add translation context for Zoom https://bugzilla.gnome.org/show_bug.cgi?id=682876 panels/universal-access/zoom-options.ui | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) commit ce53dc7fd95528fa3069991e55d859e4a9145b21 Author: Jiro Matsuzawa Date: Tue Aug 28 21:43:02 2012 +0900 wacom: add translation context for Wacom action type https://bugzilla.gnome.org/show_bug.cgi?id=682876 panels/wacom/cc-wacom-page.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) commit 658083fffa95a8787baf734f5b87d1a7e0cff2dc Author: Rui Matos Date: Sun Aug 26 16:55:11 2012 +0200 region: Don't use IBus if running in fallback mode In fallback mode we don't want to touch IBus since the gnome-shell UI isn't there to provide the full integrated user experience. We expect users to continue using existing IBus UIs in fallback mode. https://bugzilla.gnome.org/show_bug.cgi?id=682864 panels/region/gnome-region-panel-input.c | 45 ++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 11 deletions(-) commit dee8e0917abdc2ec9b33baf571b944508ae42447 Author: Rui Matos Date: Sun Aug 26 15:33:24 2012 +0200 region: Use a filter model on input sources This allows us to hide some entries which for whatever reason we can't display without removing them from gsettings. This reverts commit 54835c8f4486309c1517a7f71735fbdd7e098c5f. This reverts commit 953cc81b0f07c0e5f4e1f34a139efafe6d61fea1. This reverts commit ab0594239c5e43b3a14a0cf40ab2cce039a17a53. This reverts commit 03f08fd36c059c17f3af723ca29e0ad931fc6a26. https://bugzilla.gnome.org/show_bug.cgi?id=682864 panels/region/gnome-region-panel-input.c | 125 ++++++++++++++++++++++++------- 1 file changed, 100 insertions(+), 25 deletions(-) commit 14dde72dfe2205629b0db17aa5ba239b31ced284 Author: Ondrej Holy Date: Thu Aug 23 16:50:33 2012 +0200 mouse: Fix of bad radio spacing in RTL. https://bugzilla.gnome.org/show_bug.cgi?id=669961 panels/mouse/gnome-mouse-properties.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 3e5cdb6fce45e1ce3cce4801ef36df3abcbc8fc8 Author: Ondrej Holy Date: Thu Aug 23 14:34:59 2012 +0200 mouse: Switch left/right radios according text direction. https://bugzilla.gnome.org/show_bug.cgi?id=669961 panels/mouse/gnome-mouse-properties.c | 2 ++ panels/mouse/gnome-mouse-properties.ui | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) commit b0dcb2985742292947e5f44422de50a7a1bc5de3 Author: Bastien Nocera Date: Thu Aug 23 15:37:11 2012 +0100 sound: The angry flower read the comments again panels/sound/gvc-mixer-control.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) commit 5b8509088cdd8e8d8bfe832f9b64aa8b1b27faf3 Author: Bastien Nocera Date: Thu Aug 23 15:30:35 2012 +0100 sound: Spell "Can't" properly in debug panels/sound/gvc-mixer-dialog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit f9f9f38a969990c10c0891542fea316ad985d928 Author: Kjartan Maraas Date: Tue Aug 28 07:35:05 2012 +0200 Updated Norwegian bokmĆ„l translation po/nb.po | 195 ++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 105 insertions(+), 90 deletions(-) commit 058edd5922378576484c6ea6a09d7cbd943d9a38 Author: Nilamdyuti Goswami Date: Mon Aug 27 23:48:44 2012 +0530 Implemented FUEL entries to Assamese translation po/as.po | 128 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 64 insertions(+), 64 deletions(-) commit 33a628be07d6032e8787d77e50056370a757c730 Author: Jiro Matsuzawa Date: Mon Aug 27 23:58:05 2012 +0900 [l10n] Update Japanese translation po/ja.po | 1598 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 893 insertions(+), 705 deletions(-) commit 39c1ecab054977edff77f89263b7be176516a505 Author: Nilamdyuti Goswami Date: Mon Aug 27 13:47:11 2012 +0530 Assamese translation updated po/as.po | 957 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 496 insertions(+), 461 deletions(-) commit 46b269eb8bd79e8f9e36f62fdef0e6e002c59477 Author: Yaron Shahrabani Date: Sun Aug 26 11:13:07 2012 +0300 Updated Hebrew translation. po/he.po | 2296 ++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 1345 insertions(+), 951 deletions(-) commit cec48ff08a2e6c6eb705db20fa5923d9e32f7a28 Author: Yaron Shahrabani Date: Thu Jul 12 19:11:11 2012 +0300 Updated Hebrew translation. po/he.po | 777 ++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 450 insertions(+), 327 deletions(-) commit 1a53ec676284175093e38202457a1a7eb956bff4 Author: Khaled Hosny Date: Sun Aug 26 05:15:08 2012 +0200 Updated Arabic translation po/ar.po | 443 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 223 insertions(+), 220 deletions(-) commit 4d80e477763742d0dc06ac57e308a0662773018c Author: Giovanni Campagna Date: Sat Apr 14 01:51:35 2012 +0200 system info: set related mime types when changing preferred apps Setting the preferred music or video app only changed the handler for ogg audio/video, leaving an inconsistent state where the previous (system default) app would be used for other images, audio and video formats. Instead make it so that when the user changes his preferences, the application becomes the default for all mime types in the same group that it supports. Nothing changes if configuration is modified externally (e.g. by hand or through nautilus): expose as preferred app the one that is configured to handle the primary content type. https://bugzilla.gnome.org/show_bug.cgi?id=674084 panels/info/cc-info-panel.c | 102 ++++++++++++++++++++++++++++---------------- 1 file changed, 66 insertions(+), 36 deletions(-) commit 98137cc4e63aa022ee4cb6dd96e1c3526b49a4e6 Author: Piotr Drąg Date: Fri Aug 24 04:32:21 2012 +0200 Updated Polish translation po/pl.po | 3275 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 1950 insertions(+), 1325 deletions(-) commit 74b09b6edad57d23dd0c608e8cb0827a8ceaaec6 Author: Daniel Mustieles Date: Thu Aug 23 17:40:29 2012 +0200 Updated Spanish translation po/es.po | 467 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 243 insertions(+), 224 deletions(-) commit f4c3d190bc5210418b65a6fe5c398cf99068eb91 Author: Bastien Nocera Date: Thu Aug 23 14:22:19 2012 +0100 display: Avoid possible warning on exit (cinnamon-control-center:8728): GLib-GObject-WARNING **: invalid (NULL) pointer instance (cinnamon-control-center:8728): GLib-GObject-CRITICAL **: g_signal_handler_disconnect: assertion `G_TYPE_CHECK_INSTANCE (instance)' failed panels/display/cc-display-panel.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) commit 570bafaf6b2ae0d24d921a9b34811cb3ef4fd005 Author: Zan Dobersek Date: Thu Apr 5 08:11:23 2012 +0200 user-accounts: Fix match icon not updating in some cases Check the new password matching after focusing out either entries. Validate the content of the verify password entry after focusing out either the new password entry or the verify entry. Previously the user could mistype his new password in the new password entry, but when it was corrected, the verify entry would still be indicating that the confirmation password did not match when it did. https://bugzilla.gnome.org/show_bug.cgi?id=668844 panels/user-accounts/um-password-dialog.c | 49 +++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 16 deletions(-) commit af8a6440756ce3845b94c685918f8959968e6dd0 Author: Bastien Nocera Date: Wed Aug 22 16:31:59 2012 +0100 user-accounts: Fix login keyring password not getting updated By passing the environment down to passwed rather than an empty one. This means that passwd's PAM modules will be able to access the session D-Bus, for the gnome-keyring PAM module to change the keyring password for example. https://bugzilla.gnome.org/show_bug.cgi?id=616703 panels/user-accounts/run-passwd.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) commit b682a3c6e936a889436e53c81250a826dd1f8504 Author: Javier Jardón Date: Tue Aug 14 20:34:51 2012 +0900 common: Add Arabic as a common language https://bugzilla.gnome.org/show_bug.cgi?id=671530 panels/common/cc-common-language.c | 3 +++ 1 file changed, 3 insertions(+) commit 0e2b4a9600cf9c82c021baa034beecf067f6fbc4 Author: Bastien Nocera Date: Thu Mar 8 13:54:30 2012 +0100 common: Add Russian as a common language https://bugzilla.gnome.org/show_bug.cgi?id=671530 panels/common/cc-common-language.c | 3 +++ 1 file changed, 3 insertions(+) commit d1cfd2b0f367c944854e9aa3156cd78fe27e7415 Author: Dominique Leuenberger Date: Mon Jul 23 16:45:59 2012 +0200 build: Update COPYING with new mailing address https://bugzilla.gnome.org/show_bug.cgi?id=680456 COPYING | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) commit 8f1b6d678755a0497c1abc34a626b77f95cfa099 Author: Dan Winship Date: Wed Aug 22 09:23:03 2012 -0400 network: don't try to activate slave connections https://bugzilla.gnome.org/show_bug.cgi?id=682469 panels/network/net-device.c | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) commit 8df1069f7dedc31886acc04ae744cd052926472d Author: Dan Winship Date: Wed Aug 22 09:22:03 2012 -0400 network: fix wired/mobile activation You have to pass the NMDevice to nm_client_activate_connection() for a device-specific connection. This got broken at some point in the rewrites since 3.4. https://bugzilla.gnome.org/show_bug.cgi?id=682469 panels/network/net-device-mobile.c | 5 +++-- panels/network/net-device-wired.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) commit ecdb1d847794b43dc0d1ae3b107d811fe52e5846 Author: Dan Winship Date: Wed Aug 22 09:00:35 2012 -0400 network: ignore unrecognized device types rather than showing a blank line in the device-type list that doesn't do anything. https://bugzilla.gnome.org/show_bug.cgi?id=678210 panels/network/cc-network-panel.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) commit 20a980d6ca8d4e40d62d9add1c3745ba403cf08a Author: Colin Walters Date: Wed Aug 22 09:42:18 2012 -0400 Fix missing = panels/common/cc-common-language.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 4d62e05fb088d64c3133912f0995a42157b8e968 Author: Matthias Clasen Date: Wed Aug 22 14:15:04 2012 +0100 common: Add Policykit rules for hostname setting Allow setting the computer's pretty hostname if the user is an admin. https://bugzilla.gnome.org/show_bug.cgi?id=679281 panels/common/Makefile.am | 5 +++++ panels/common/cinnamon-control-center.rules | 8 ++++++++ 2 files changed, 13 insertions(+) commit d2aa0ce5d8c93e777d201da779f13802e5249c95 Author: Jasper St. Pierre Date: Thu Jul 12 17:26:03 2012 -0400 common: Fix memory leaks in language sorting https://bugzilla.gnome.org/show_bug.cgi?id=679836 panels/common/cc-common-language.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) commit e730edb6cc4a5477be9608bf6798ac747558f0f0 Author: Kjartan Maraas Date: Wed Aug 22 14:10:21 2012 +0200 Updated Norwegian bokmĆ„l translation po/nb.po | 1384 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 761 insertions(+), 623 deletions(-) commit ddf8c56caf3ba9bb68884840c398e6485c107cfd Author: Rico Tzschichholz Date: Wed Aug 22 12:52:29 2012 +0200 background: Add missing include bg_pictures_source_get_*_path is defined in bg-pictures-source.h panels/background/cc-background-panel.c | 2 ++ 1 file changed, 2 insertions(+) commit 03a88bbba537e3360bfaed3b6f89f2f0d4420187 Author: Bastien Nocera Date: Wed Aug 22 10:38:34 2012 +0100 mouse: Remove unused variable panels/mouse/cc-mouse-panel.c | 1 - 1 file changed, 1 deletion(-) commit 905b7f999c52f7ca064a01fa5e5dee9ef7d71649 Author: Bastien Nocera Date: Wed Aug 22 10:37:34 2012 +0100 mouse: Remove italics from test page https://bugzilla.gnome.org/show_bug.cgi?id=682397 NEWS | 1 + panels/mouse/gnome-mouse-test.ui | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) commit 51c06e781d69e73ce866bacc010fb1bf21eaebd0 Author: Nguyį»…n ThĆ”i Ngį»c Duy Date: Wed Aug 22 15:01:14 2012 +0700 Updated Vietnamese translation po/vi.po | 263 +++++++++++++++++++++++++-------------------------------------- 1 file changed, 103 insertions(+), 160 deletions(-) commit 26f65ccd57345a8ff0abfdef047f008271389763 Author: Nguyį»…n ThĆ”i Ngį»c Duy Date: Wed Aug 22 14:42:52 2012 +0700 po/vi: imported from Damned Lies po/vi.po | 2494 ++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 1467 insertions(+), 1027 deletions(-) commit eaef6e5d50140fd7ff9803f79c71e6ccfca18838 Author: Jasper St. Pierre Date: Tue Aug 14 17:14:10 2012 -0300 um-user: Use GdkCairo operations to draw on the pixbuf Remove a bunch of bit twiddling code. https://bugzilla.gnome.org/show_bug.cgi?id=682391 panels/user-accounts/um-user.c | 139 ++--------------------------------------- 1 file changed, 4 insertions(+), 135 deletions(-) commit 36d09e19176c73183d1f47b546dbfa6b327ec92c Author: A S Alam Date: Wed Aug 22 07:14:22 2012 +0530 update Punjabi Translation po/pa.po | 717 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 363 insertions(+), 354 deletions(-) commit 9538df6ba1da6353396ff901f8cfdafe2351d978 Author: Aurimas Černius Date: Tue Aug 21 23:11:39 2012 +0300 Updated Lithuanian translation po/lt.po | 1722 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 857 insertions(+), 865 deletions(-) commit e87c564cdbf7810e0c15b40ed680d9c8bc6734b5 Author: FrĆ©dĆ©ric PĆ©ters Date: Tue Aug 21 22:05:35 2012 +0200 printers: remove blank class_finalize function panels/printers/cc-printers-panel.c | 5 ----- 1 file changed, 5 deletions(-) commit b0e7a5efa819525bf6709ac3a009b12bb145d601 Author: Ray Strode Date: Tue Aug 21 14:29:22 2012 -0400 panels: add register macro Bastien says he doesn't like the blank class_finalize functions in every panel and he would like a wrapper macro to hide them. This commit does that. panels/background/cc-background-panel.c | 7 +------ panels/bluetooth/cc-bluetooth-panel.c | 7 +------ panels/color/cc-color-panel.c | 7 +------ panels/datetime/cc-datetime-panel.c | 8 +------- panels/display/cc-display-panel.c | 7 +------ panels/info/cc-info-panel.c | 7 +------ panels/keyboard/cc-keyboard-panel.c | 7 +------ panels/mouse/cc-mouse-panel.c | 7 +------ panels/network/cc-network-panel.c | 7 +------ panels/online-accounts/cc-online-accounts-panel.c | 7 +------ panels/power/cc-power-panel.c | 7 +------ panels/printers/cc-printers-panel.c | 2 +- panels/region/cc-region-panel.c | 7 +------ panels/screen/cc-screen-panel.c | 7 +------ panels/sound/cc-sound-panel.c | 7 +------ panels/universal-access/cc-ua-panel.c | 7 +------ panels/user-accounts/um-user-panel.c | 7 +------ panels/wacom/cc-wacom-panel.c | 7 +------ shell/cc-panel.h | 14 ++++++++++++++ 19 files changed, 32 insertions(+), 104 deletions(-) commit 0c1a76df6ac1d12b23f911c07607b19e51f167f8 Author: Bastien Nocera Date: Tue Aug 21 18:41:25 2012 +0100 3.5.90 NEWS | 43 +++++++++++++++++++++++++++++++++++++++++++ configure.ac | 2 +- 2 files changed, 44 insertions(+), 1 deletion(-) commit 3bf8bcf3f8a357f0c33f1f790852c42eec954483 Author: Ray Strode Date: Tue Aug 21 13:29:46 2012 -0400 online-accounts: set up finalize handler at class init time It was being set up at class finalization time, which is too late. Fixes crash when switching from panel to shell and back (and then try to interact with the switches). https://bugzilla.gnome.org/show_bug.cgi?id=682379 panels/online-accounts/cc-online-accounts-panel.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) commit 06ede122abd90194eff4275ed1b97cd9bfa1902e Author: Debarshi Ray Date: Tue Aug 21 17:23:50 2012 +0200 online-accounts: Don't show spurious "No online accounts configured" Programmatically deleting or inserting a row into a GtkTreeModel implementation does not change the selection on the GtkTreeView even if it is in browse mode (see GTK+ documentation). So, we need to connect to the model's row-deleted and row-inserted signals and adjust the selection ourselves. Fixes: https://bugzilla.gnome.org/682175 panels/online-accounts/cc-online-accounts-panel.c | 69 ++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) commit 7b20a3d0f30601353c9ae510b4a884a89c6cd4d1 Author: Khaled Hosny Date: Tue Aug 21 18:56:26 2012 +0200 Updated Arabic translation po/ar.po | 701 ++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 382 insertions(+), 319 deletions(-) commit 44f742659e5d039327009364e6b53071bcbe8212 Author: Bastien Nocera Date: Tue Aug 21 15:23:43 2012 +0100 common: Add more debug to list-languages panels/common/list-languages.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) commit 8c7632e66e410c03579a9caa9abf695e36bf51fb Author: Bastien Nocera Date: Tue Aug 21 17:40:30 2012 +0100 sound: Avoid use-after-free of destroyed streams When switching between 2 outputs that share the same device with different connector types, the old stream is destroyed, and a new one with the new connector type created. We were generating warnings because the old stream was destroyed, and we were trying to access it. Instead we should remove the reference to that old stream from the GvcLevelBars used for output and input levels. panels/sound/gvc-mixer-dialog.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) commit e34dd3bb83dfbda6c130c5851453082bc8f2b16a Author: Bastien Nocera Date: Tue Aug 21 17:33:18 2012 +0100 sound: Fix incorrectly documented return type gvc_mixer_control_get_stream_from_device returns a GvcMixerStream, not a container that contains one of those. panels/sound/gvc-mixer-control.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 4513207bfb7801868f84ff3524f0d46f4f9b40a9 Author: David Henningsson Date: Fri Jul 13 14:47:44 2012 +0200 sound: Remove hardware tab Since the output and input tabs now offer the possibility to select profile, we can remove the hardware tab completely. https://bugzilla.gnome.org/show_bug.cgi?id=674831 panels/sound/gvc-mixer-dialog.c | 312 ---------------------------------------- 1 file changed, 312 deletions(-) commit ac2a8ced05324c2a97332fb0f61efd0a9c2c5365 Author: David Henningsson Date: Fri Jul 13 13:54:45 2012 +0200 sound: Move "Test speakers" to the output tab Test speakers will now test the speakers of the active output on the output tab. https://bugzilla.gnome.org/show_bug.cgi?id=674831 panels/sound/gvc-mixer-dialog.c | 80 ++++++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 17 deletions(-) commit db8ee1eabe4f719f494e16813609e9054cc44806 Author: David Henningsson Date: Fri Jun 22 11:36:35 2012 +0200 sound: Make speaker test work for sinks without card By speaker-test taking a stream/sink instead of card as parameter, it can be used for outputs that don't have cards (e g network sinks). https://bugzilla.gnome.org/show_bug.cgi?id=674831 panels/sound/gvc-speaker-test.c | 91 ++++++++++------------------------------- panels/sound/gvc-speaker-test.h | 2 +- 2 files changed, 23 insertions(+), 70 deletions(-) commit b3fe98e7c1eca17ef8e2e728e44a9a42edd0e149 Author: David Henningsson Date: Tue Jul 10 17:45:27 2012 +0200 sound: Make the dialog UI use GvcMixerUIDevice The input and output treeview now represent GvcMixerUIDevices, not sinks and sources. Also turn the connector combobox into a profile combobox. https://bugzilla.gnome.org/show_bug.cgi?id=674831 panels/sound/gvc-mixer-dialog.c | 1054 +++++++++++++++++++++------------------ 1 file changed, 579 insertions(+), 475 deletions(-) commit a2e515ea39e136ed19c52e3572da64f5dc6944a7 Author: Olivier Fourdan Date: Tue Jun 26 11:06:07 2012 +0200 wacom: add different action types to mapping dialog https://bugzilla.gnome.org/show_bug.cgi?id=679067 panels/wacom/cc-wacom-mapping-panel.c | 4 +- panels/wacom/cc-wacom-page.c | 181 +++++++++++++++++++++++++++++++--- 2 files changed, 172 insertions(+), 13 deletions(-) commit 8d8cf753528e991578d01203f440fd482fb41060 Author: Olivier Fourdan Date: Tue Aug 21 17:59:36 2012 +0200 wacom: Update from gnome-settings-daemon panels/wacom/gsd-input-helper.c | 13 +++++++++++++ panels/wacom/gsd-input-helper.h | 2 ++ panels/wacom/gsd-wacom-device.c | 14 +++++++------- panels/wacom/gsd-wacom-device.h | 3 +++ 4 files changed, 25 insertions(+), 7 deletions(-) commit 29c49c9a48cd258dc1361648a83f01ee74a5cd0c Author: Chao-Hsiung Liao Date: Tue Aug 21 19:27:54 2012 +0800 Updated Traditional Chinese translation(Hong Kong and Taiwan) po/zh_HK.po | 271 ++++++++++++++++++++++++++++++++---------------------------- po/zh_TW.po | 271 ++++++++++++++++++++++++++++++++---------------------------- 2 files changed, 286 insertions(+), 256 deletions(-) commit 349cdb533fde7180fe4609ab13ebe81104ab4c1c Author: Piotr Drąg Date: Mon Aug 20 21:50:51 2012 +0200 Updated POTFILES.in po/POTFILES.in | 3 +++ 1 file changed, 3 insertions(+) commit 3b1238a5568cfa3f623702c919153ca8aadf6133 Author: Daniel Mustieles Date: Mon Aug 20 20:46:47 2012 +0200 Updated Spanish translation po/es.po | 283 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 142 insertions(+), 141 deletions(-) commit 544a8ff8896da9361f22cf515ab3587404d828a1 Author: Ondrej Holy Date: Mon Aug 20 19:49:07 2012 +0200 mouse: Add mouse test toggle https://bugzilla.gnome.org/show_bug.cgi?id=677206 panels/mouse/Makefile.am | 8 +++- panels/mouse/cc-mouse-panel.c | 98 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 96 insertions(+), 10 deletions(-) commit 7981d4423a35ca6dcebabe8571abd92aa28b317d Author: Ondrej Holy Date: Mon Aug 20 19:24:03 2012 +0200 mouse: Add mouse test window https://bugzilla.gnome.org/show_bug.cgi?id=677206 panels/mouse/Makefile.am | 10 ++ panels/mouse/gnome-mouse-test.c | 171 +++++++++++++++++++++++++++++++++++ panels/mouse/gnome-mouse-test.h | 27 ++++++ panels/mouse/gnome-mouse-test.ui | 70 ++++++++++++++ panels/mouse/test-gnome-mouse-test.c | 44 +++++++++ 5 files changed, 322 insertions(+) commit 278c89fdce5e5351192652079386c29d806128f4 Author: Ondrej Holy Date: Mon Aug 20 14:50:44 2012 +0200 mouse: Show mouse section only if mouse is present https://bugzilla.gnome.org/show_bug.cgi?id=677206 panels/mouse/gnome-mouse-properties.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) commit 7929e550f1eacccf804403b748879377f68d29d5 Author: Ondrej Holy Date: Thu Aug 9 15:34:51 2012 +0200 mouse: Add natural scroll toggle https://bugzilla.gnome.org/show_bug.cgi?id=677206 panels/mouse/gnome-mouse-properties.c | 3 +++ panels/mouse/gnome-mouse-properties.ui | 24 +++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) commit 9f76e8966104b361ffc6474dfe5a04e64989a323 Author: Ondrej Holy Date: Thu Aug 9 15:16:05 2012 +0200 mouse: Sensitivity and acceleration sliders merge https://bugzilla.gnome.org/show_bug.cgi?id=677206 panels/mouse/gnome-mouse-properties.c | 54 +++++---- panels/mouse/gnome-mouse-properties.ui | 205 +++------------------------------ 2 files changed, 43 insertions(+), 216 deletions(-) commit a6262b0ad448c25e656ab08aaf1c423abfd01c12 Author: Ondrej Holy Date: Thu Aug 9 14:11:52 2012 +0200 mouse: Reorganize widgets according to mockup https://bugzilla.gnome.org/show_bug.cgi?id=677206 panels/mouse/gnome-mouse-properties.c | 181 +---- panels/mouse/gnome-mouse-properties.ui | 1233 +++++++++++--------------------- 2 files changed, 439 insertions(+), 975 deletions(-) commit a41624305039f7d3e0503e72ea63268da8b80242 Author: Ray Strode Date: Mon Aug 20 13:52:49 2012 -0400 user-accounts: fix crash for incompatible realmd version The version property may not be available if realmd is version 0.1 (which lacked the property) or if other properties changed signatures (causing gdbus to fail to load cache any property) This commit fixes a crash where property is NULL in those cases. panels/user-accounts/um-realm-manager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit daa8b098a434809baaf92441b43d09c750953e15 Author: Bastien Nocera Date: Mon Aug 20 15:53:55 2012 +0100 mouse: Update from gnome-settings-daemon panels/mouse/gsd-input-helper.c | 37 +++++++++++++++++++++++++++++++------ panels/mouse/gsd-input-helper.h | 2 ++ 2 files changed, 33 insertions(+), 6 deletions(-) commit 8947021b3eb76d6b8cbdc317552e6cd858baef7f Author: Bastien Nocera Date: Mon Aug 20 15:43:41 2012 +0100 build: Check news before release configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 978ab40f3eb6e4ec2a632941cd8f879919aa2e02 Author: Rui Matos Date: Tue Jul 31 18:27:17 2012 +0200 keyboard: Add common XKB options to the Typing shortcuts section Both the compose key and the 3rd level chooser are common and useful enough to expose in the control center. Since these shortcuts are a small pre-defined set of only modifier keys we present them in combo cell renderers. https://bugzilla.gnome.org/show_bug.cgi?id=682069 configure.ac | 8 +- panels/keyboard/Makefile.am | 2 + panels/keyboard/cc-keyboard-option.c | 449 +++++++++++++++++++++++++++++++++++ panels/keyboard/cc-keyboard-option.h | 48 ++++ panels/keyboard/keyboard-shortcuts.c | 291 ++++++++++++++++++----- 5 files changed, 736 insertions(+), 62 deletions(-) commit 4e0bc86e5b665519980aa562d3a3311a73c2066a Author: Rui Matos Date: Sat Aug 18 19:18:51 2012 +0200 keyboard: Rename the Input Sources shortcuts section to Typing This way we can add more typing related keybindings here. https://bugzilla.gnome.org/show_bug.cgi?id=682069 panels/keyboard/01-input-sources.xml.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit a24f221eeb69879aebaa90fb1dfaed6849a96d5e Author: Rui Matos Date: Thu Aug 16 19:30:08 2012 +0200 keyboard: Introduce a BINDING_GROUP_SEPARATOR type for the separator This way we can control the shortcut section separator position in case we introduce other types. https://bugzilla.gnome.org/show_bug.cgi?id=682069 panels/keyboard/cc-keyboard-item.h | 1 + panels/keyboard/keyboard-shortcuts.c | 40 +++++++++++------------------------- 2 files changed, 13 insertions(+), 28 deletions(-) commit 71978a802e10f076a577bbc66a9a6f89dc906caa Author: Chao-Hsiung Liao Date: Mon Aug 20 23:13:40 2012 +0800 Updated Traditional Chinese translation(Hong Kong and Taiwan) po/zh_HK.po | 421 ++++++++++++++++++++++++++++++++++-------------------------- po/zh_TW.po | 421 ++++++++++++++++++++++++++++++++++-------------------------- 2 files changed, 478 insertions(+), 364 deletions(-) commit 56b2d3221819952c67e6034ed9be327e748ac191 Author: Piotr Drąg Date: Mon Aug 20 15:46:36 2012 +0200 Updated Polish translation po/pl.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit b8a919fccbf7751e1b692979a398175d3c500d7d Author: Daniel Mustieles Date: Mon Aug 20 14:16:23 2012 +0200 Updated Spanish translation po/es.po | 304 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 153 insertions(+), 151 deletions(-) commit 3aab3eb358805c1b7a06c5a54b04ceaff2cc06b8 Author: Stef Walter Date: Fri Aug 17 16:58:10 2012 +0200 user-accounts: Update for realmd DBus interface changes * DBus interface was reviewed and there were several things added to make it more generic and useful for other realm types. * Use ObjectManager to track objects in realmd. This facilitates using realmd with the way it now uses multiple interfaces on objects. https://bugzilla.gnome.org/show_bug.cgi?id=682185 panels/user-accounts/Makefile.am | 4 +- .../user-accounts/data/org.freedesktop.realmd.xml | 645 ++++++++++++++++++--- ...org.gnome.controlcenter.user-accounts.policy.in | 2 +- panels/user-accounts/um-account-dialog.c | 68 ++- panels/user-accounts/um-realm-manager.c | 501 +++++++--------- panels/user-accounts/um-realm-manager.h | 13 +- 6 files changed, 837 insertions(+), 396 deletions(-) commit 6b2557f1b3380119d06848cc4c84f064780480cd Author: Sebastian Keller Date: Mon Aug 20 10:50:08 2012 +0100 network: Improve wifi layout - Increase size of the window - Remove killswitch and hotspot buttons from scrollview Signed-off-by: Richard Hughes panels/network/network-wifi.ui | 154 ++++++++++++++++++++--------------------- 1 file changed, 76 insertions(+), 78 deletions(-) commit 21c6fccc129c052899a4e8c4bd830041bcb6fce6 Author: Piotr Drąg Date: Sun Aug 19 18:35:37 2012 +0200 Updated Polish translation po/pl.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit 99a99b7f13b2df41aa883e30f60701e18ad36cc1 Author: A S Alam Date: Sun Aug 19 15:08:33 2012 +0530 Update Punjabi Translation po/pa.po | 437 ++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 249 insertions(+), 188 deletions(-) commit 7ffbf3bc5eb4d65510040465177c5525d1ca6a6c Author: Ihar Hrachyshka Date: Sun Aug 19 00:46:09 2012 +0300 Updated Belarusian translation. po/be.po | 1296 +++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 685 insertions(+), 611 deletions(-) commit 7dd80f829fe092e25d8e8c8bb64eb467c30db3be Author: Matthew Barnes Date: Wed Aug 8 17:04:39 2012 +0200 online-accounts: Open specific account through command-line Bump required GOA version to 3.5.90 for goa_client_lookup_by_id. Fixes: https://bugzilla.gnome.org/680458 configure.ac | 2 +- panels/online-accounts/cc-online-accounts-panel.c | 66 +++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) commit db2ff0fe5210f1fd752b1b035b99277fb0b56fc7 Author: Bastien Nocera Date: Wed Aug 15 16:56:21 2012 +0100 keyboard: Clarify screenshot actions And explain that it saves directly to the Pictures directory. https://bugzilla.gnome.org/show_bug.cgi?id=681849 panels/keyboard/01-screenshot.xml.in | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) commit f217fa286af37fbd040a3d9a98922d02929bc2de Author: Stef Walter Date: Tue Aug 14 18:34:22 2012 +0200 user-accounts: Change behavior/display of panel for remote accounts * Hide the automatic-login and fingerprint widgets * Insensitive account type and real name widgets https://bugzilla.gnome.org/show_bug.cgi?id=681770 panels/user-accounts/um-user-panel.c | 51 +++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 15 deletions(-) commit 251a189cfc47b38df14e4ca515f0643973d08668 Author: Stef Walter Date: Tue Aug 14 18:33:30 2012 +0200 user-accounts: Add um_user_is_local_account() method * Use new LocalAccount property in accountsservice to add the um_user_is_local_account() method. https://bugzilla.gnome.org/show_bug.cgi?id=681770 panels/user-accounts/um-user.c | 12 ++++++++++++ panels/user-accounts/um-user.h | 1 + 2 files changed, 13 insertions(+) commit a2149736cdb72cde857d568cff04f29d45478183 Author: Stef Walter Date: Tue Aug 14 17:23:28 2012 +0200 user-accounts: Display the username in list * By displaying the username we get the unix user name for local accounts, and the full login name for remote accounts. * Can now differentiate between accounts with the same display 'real' name. * Can see the full login identity of remote accounts. https://bugzilla.gnome.org/show_bug.cgi?id=681767 panels/user-accounts/um-user-panel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit f5502645ff683b3be9f661929591ed7f5aeef764 Author: Rui Matos Date: Mon Aug 13 23:20:48 2012 +0200 keyboard: Remove unused shortcut treeview sorting code Since the shortcut treeview doesn't have visible headers the sorting code isn't needed. https://bugzilla.gnome.org/show_bug.cgi?id=681794 panels/keyboard/keyboard-shortcuts.c | 71 +----------------------------------- 1 file changed, 2 insertions(+), 69 deletions(-) commit 7bce5758c8facf21be012c815f60fdb720515e97 Author: Rui Matos Date: Mon Aug 13 22:02:36 2012 +0200 keyboard: Fix adding the section separator after the first time The separator would only get added the first time the keyboard panel was opened. https://bugzilla.gnome.org/show_bug.cgi?id=681788 panels/keyboard/keyboard-shortcuts.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) commit 923f27950a960a4e94c95c2db78ab9e89647e382 Author: Bastien Nocera Date: Sat Aug 18 18:32:34 2012 +0100 user-accounts: Fix crash on startup Due to badly installed PolicyKit files. https://bugzilla.gnome.org/show_bug.cgi?id=681763 panels/user-accounts/um-user-panel.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) commit 0651abd7fb24278426222d9620591a3d70079693 Author: Rui Matos Date: Mon Aug 13 21:53:11 2012 +0200 keyboard: Plug a memory leak https://bugzilla.gnome.org/show_bug.cgi?id=681787 panels/keyboard/keyboard-shortcuts.c | 2 ++ 1 file changed, 2 insertions(+) commit 3f76a97915643522eeac207c17f2d62960271bad Author: Stef Walter Date: Tue Aug 14 17:04:41 2012 +0200 user-accounts: Create the add account dialog on demand * Creating the add account dialog as the panel gets created means that realmd is invoked, network discovery is done and so on. Not optimal. * We also don't really need to cache the account dialog, and can create a new one for each [+] click. https://bugzilla.gnome.org/show_bug.cgi?id=681852 panels/user-accounts/um-user-panel.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) commit 36fa8bf9b76efc6eba11dec503743aa09547451b Author: Stef Walter Date: Tue Aug 14 18:43:18 2012 +0200 user-accounts: Consistent capitalization of 'Account Type' https://bugzilla.gnome.org/show_bug.cgi?id=681771 panels/user-accounts/data/user-accounts-dialog.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 6baadbf8271c09a737ef4463c4e9bc1503425ae8 Author: Bastien Nocera Date: Sat Aug 18 18:10:44 2012 +0100 mouse: Remove dead code panels/mouse/gnome-mouse-properties.c | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) commit e7d6514a11605dd115ae35cec59a99526e310715 Author: Bastien Nocera Date: Sat Aug 18 16:09:24 2012 +0100 shell: Only link to clutter-gtk with cheese support configure.ac | 5 ++--- shell/Makefile.am | 6 ++++-- shell/cinnamon-control-center.c | 4 ++++ 3 files changed, 10 insertions(+), 5 deletions(-) commit 69b2a05b255a7b9e5623ee6007636671b596286c Author: Bastien Nocera Date: Sat Aug 18 16:09:01 2012 +0100 shell: Remove CcNotebook https://bugzilla.gnome.org/show_bug.cgi?id=682127 shell/Makefile.am | 7 - shell/cc-notebook.c | 566 ------------------------------------------- shell/cc-notebook.h | 70 ------ shell/cinnamon-control-center.c | 1 - shell/test-notebook.c | 92 ------- 5 files changed, 736 deletions(-) commit 10c00125f4ce4f8fad1c11556f85bfd46c222289 Author: Bastien Nocera Date: Sat Aug 18 16:03:19 2012 +0100 shell: Drop panel transitions They're not finished and don't match what the designers would want. https://bugzilla.gnome.org/show_bug.cgi?id=682127 shell/cinnamon-control-center.c | 30 +++++++++++++----------------- shell/shell.ui | 3 ++- 2 files changed, 15 insertions(+), 18 deletions(-) commit 72fd5636e5f769d887796caaf450efeaa139ec9b Author: Bastien Nocera Date: Sat Aug 18 16:02:39 2012 +0100 shell: Add GtkNotebook helper functions https://bugzilla.gnome.org/show_bug.cgi?id=682127 shell/cinnamon-control-center.c | 57 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) commit 2a01afe25d7ca42cdd8291df58111b385ba57fec Author: ŠœŠøŃ€Š¾ŃŠ»Š°Š² ŠŠøŠŗŠ¾Š»ŠøŃ› Date: Sat Aug 18 07:47:58 2012 +0200 Updated Serbian translation po/sr.po | 152 +++++++++++++++++++++++++++------------------------------ po/sr@latin.po | 152 +++++++++++++++++++++++++++------------------------------ 2 files changed, 146 insertions(+), 158 deletions(-) commit b7e549165bb2f0ba0c45862ce7353ed2cebee183 Author: Piotr Drąg Date: Sat Aug 18 00:25:50 2012 +0200 Updated POTFILES.in po/POTFILES.in | 1 + 1 file changed, 1 insertion(+) commit 4ee558bdc8374fd1093904096d05a417734daebc Author: William Jon McCann Date: Wed Aug 15 21:12:07 2012 -0400 background: Update the preview when the settings change They may be change from outside (eg. Nautilus). https://bugzilla.gnome.org/show_bug.cgi?id=676539 panels/background/cc-background-panel.c | 66 ++++++++++++++------------------- 1 file changed, 28 insertions(+), 38 deletions(-) commit 18b3486a064e45d77526f8f270231283087c17c3 Author: William Jon McCann Date: Fri Aug 10 18:52:12 2012 -0400 background: Remove sheen overlay The metaphor was valid when we used a monitor to display the preview but now it doesn't work. There is no glass to reflect light. It distracts from the preview and may look like a defect. https://bugzilla.gnome.org/show_bug.cgi?id=676539 panels/background/Makefile.am | 3 +-- panels/background/cc-background-panel.c | 19 ------------------- panels/background/display-overlay.png | Bin 6700 -> 0 bytes 3 files changed, 1 insertion(+), 21 deletions(-) commit 79ec684fa4912a1e5bff17ce11b036cef4a298aa Author: William Jon McCann Date: Tue May 22 11:34:20 2012 -0400 background: New background panel design Implement a new design for the wallpaper selection. https://bugzilla.gnome.org/show_bug.cgi?id=676539 panels/background/Makefile.am | 6 +- panels/background/background.ui | 352 ++----- panels/background/bg-colors-source.c | 61 +- panels/background/bg-flickr-source.c | 2 +- panels/background/bg-pictures-source.c | 2 +- panels/background/bg-source.h | 4 +- panels/background/bg-wallpapers-source.c | 2 +- panels/background/cc-background-chooser-dialog.c | 335 ++++++ panels/background/cc-background-chooser-dialog.h | 60 ++ panels/background/cc-background-panel.c | 1194 ++++++---------------- panels/background/display-base.png | Bin 22374 -> 0 bytes panels/background/display-overlay.png | Bin 9549 -> 6700 bytes 12 files changed, 824 insertions(+), 1194 deletions(-) commit c2987d8cdee89be5209b1bc4c8af108bcb0f7dcb Author: Bastien Nocera Date: Fri Aug 17 17:47:43 2012 +0100 printers: Check that cups-config exists Before using it. configure.ac | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) commit 7483b80b14aa48637c5f68c2298be1c93d905328 Author: ŠœŠøŃ€Š¾ŃŠ»Š°Š² ŠŠøŠŗŠ¾Š»ŠøŃ› Date: Fri Aug 17 12:11:22 2012 +0200 Updated Serbian translation po/sr.po | 309 +++++++++++++++++++++++++++++++++------------------------ po/sr@latin.po | 309 +++++++++++++++++++++++++++++++++------------------------ 2 files changed, 360 insertions(+), 258 deletions(-) commit d3571a0b597d0846a1203892becdc1115edc41b0 Author: Shankar Prasad Date: Fri Aug 17 12:08:55 2012 +0530 Updated kn translation po/kn.po | 3638 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 2036 insertions(+), 1602 deletions(-) commit b523cb386055b8d8c68f62922432841f5eb66170 Author: Shankar Prasad Date: Fri Aug 17 11:58:17 2012 +0530 Updated kn translation po/kn.po | 3634 +++++++++++++++++++++++++++----------------------------------- 1 file changed, 1600 insertions(+), 2034 deletions(-) commit bc76ba093d0d00cc29ae3ac3ded9c297bf7c7def Author: Shankar Prasad Date: Fri Aug 17 10:46:41 2012 +0530 Updated kn translation po/kn.po | 369 ++++++++++++++++++++++++++------------------------------------- 1 file changed, 149 insertions(+), 220 deletions(-) commit 11abc4ad1c7a09fa6ac433b57c6e2e9ce9d4647d Author: Shankar Prasad Date: Fri Aug 17 07:57:26 2012 +0530 Updated kn translation po/kn.po | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) commit 9a5d3c267b9017a7b17558c07eb6ea7e1770a5d2 Author: Reşat SABIQ Date: Thu Aug 16 19:25:18 2012 -0500 Minor update for Crimean Tatar/Turkish translation po/crh.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit d8d5cf447e330e9506cb8dd8f4563b0f52ad0cf2 Author: Reşat SABIQ Date: Thu Aug 16 19:03:25 2012 -0500 Updated Crimean Tatar (Crimean Turkish) translation po/crh.po | 2701 ++++++++++++++++++++++++++++++------------------------------- 1 file changed, 1349 insertions(+), 1352 deletions(-) commit 5e6bf1972ef94084609335a941c130c58ee3796a Author: Fran DiĆ©guez Date: Fri Aug 17 01:33:53 2012 +0200 Updated Galician translations po/gl.po | 2091 +++++--------------------------------------------------------- 1 file changed, 144 insertions(+), 1947 deletions(-) commit c6e7235d5ecc61450077b2ed9dd5bcc64ebedf04 Author: Daniel Mustieles Date: Thu Aug 16 16:10:03 2012 +0200 Updated Spanish translation po/es.po | 307 ++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 176 insertions(+), 131 deletions(-) commit 1585d18edfbeeee99b5b60ca8b65a8bfd1e61bde Author: Nilamdyuti Goswami Date: Thu Aug 16 18:39:26 2012 +0530 Assamese translation updated po/as.po | 312 ++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 179 insertions(+), 133 deletions(-) commit b106468e01e7ef6be5b7784808f152318a8ba925 Author: Bastien Nocera Date: Wed Aug 15 19:05:17 2012 +0100 universal-access: Fix deprecation warnings Related to GtkColorButton https://bugzilla.gnome.org/show_bug.cgi?id=676817 panels/universal-access/zoom-options.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) commit 131a5ce94764658a6d5733fb50c24f17299b0f29 Author: Alejandro PiƱeiro Date: Wed Aug 15 17:02:42 2012 +0200 universal-access: Split the zoom dialog options Split dialogue into 3 tabs: * Magnifier * Crosshair * Color Effects and add a global zoom switch for easy access. https://bugzilla.gnome.org/show_bug.cgi?id=676817 panels/universal-access/zoom-options.c | 12 +- panels/universal-access/zoom-options.ui | 1519 +++++++++++++++++-------------- 2 files changed, 837 insertions(+), 694 deletions(-) commit 2d6161d45b09518b76cabc0567690d13cf5a02a1 Author: Joseph Scheuhammer Date: Fri Jul 27 15:50:41 2012 -0400 universal-access: Add zoom shader options Add 'Color effects' section to zoom options dialogue: - a toggle for inversion (White on black) - a slider for brightness - a slider for contrast - a slider for grey scale https://bugzilla.gnome.org/show_bug.cgi?id=676817 panels/universal-access/zoom-options.c | 126 +++++++- panels/universal-access/zoom-options.ui | 492 ++++++++++++++++++++++++++++---- 2 files changed, 565 insertions(+), 53 deletions(-) commit cda48dbf6ba0a0105ffc445d57395a301fbfc1db Author: Shankar Prasad Date: Tue Aug 14 17:51:22 2012 +0530 Updated kn translation po/kn.po | 161 ++++++++++++++++++++++++--------------------------------------- 1 file changed, 62 insertions(+), 99 deletions(-) commit c4f4272f7c6ff23aa6b09dec6c862b08cda8fc01 Author: Stef Walter Date: Mon Aug 13 10:59:47 2012 +0200 bluetooth: Require gnome-bluetooth 3.5.5 * Due to API change in gnome-bluetooth commit 1c39fbaeaf782597857216430906a74865e7661b where there were changes like s/KILLSWITCH_STATE/BLUETOOTH_KILLSWITCH_STATE/ https://bugzilla.gnome.org/show_bug.cgi?id=681734 configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 65b09049d88447d89e7c323a667870e3fd538548 Author: Fran DiĆ©guez Date: Tue Aug 14 11:43:44 2012 +0200 Updated Galician translations po/gl.po | 564 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 296 insertions(+), 268 deletions(-) commit c6b24ba94ba55b04c6df9d761ea2f7cd60b7f9d9 Author: Shankar Prasad Date: Mon Aug 13 15:04:53 2012 +0530 Updated kn translation po/kn.po | 3545 ++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 2157 insertions(+), 1388 deletions(-) commit 5b9d311c2d36bd224a6b4f552650e5a1b2372c47 Author: A S Alam Date: Mon Aug 13 07:25:30 2012 +0530 Update Punjabi Translation po/pa.po | 692 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 352 insertions(+), 340 deletions(-) commit c693e4f33f0658d7a010b5199bfe3391f2656fa0 Author: Chao-Hsiung Liao Date: Sun Aug 12 23:01:55 2012 +0800 Updated Traditional Chinese translation(Hong Kong and Taiwan) po/zh_HK.po | 778 +++++++++++++++++++++++++++++--------------------------- po/zh_TW.po | 834 ++++++++++++++++++++++++++++++++---------------------------- 2 files changed, 837 insertions(+), 775 deletions(-) commit 9745f93922c5793b78c018eb27f5ed0b594207f8 Author: Khaled Hosny Date: Sun Aug 12 12:50:19 2012 +0200 Updated Arabic translation po/ar.po | 822 +++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 461 insertions(+), 361 deletions(-) commit e959be7e869d08ff041a3de4cebfbf8965e1ad9e Author: Sandeep Sheshrao Shedmake Date: Sat Aug 11 19:52:45 2012 +0530 Updated Marathi Translations po/mr.po | 9390 +++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 6589 insertions(+), 2801 deletions(-) commit 621d05e65acf397906cd124ebee7808a60b4fbf4 Author: Dirgita Date: Sat Aug 11 04:31:35 2012 +0700 Updated Indonesian translation po/id.po | 485 ++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 291 insertions(+), 194 deletions(-) commit 71db59d9a2b881b941df03e04eeb910f029822cf Author: Marek Kasik Date: Thu Aug 9 14:23:49 2012 +0200 printers: Remove obsoleted notebook page This commit removes the notebook page which consists old printer options. It was replaced by separate dialog. panels/printers/cc-printers-panel.c | 20 ---- panels/printers/printers.ui | 182 +----------------------------------- 2 files changed, 4 insertions(+), 198 deletions(-) commit 0f5eae643b186162c1397e1b05b5aa19e144f77e Author: Bastien Nocera Date: Wed Aug 8 17:20:52 2012 +0100 3.5.6 NEWS | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 2 +- 2 files changed, 49 insertions(+), 1 deletion(-) commit 54f5a8c7c6661ad6e7565f038a4e829d199b9d03 Author: Daniel Mustieles Date: Wed Aug 8 17:07:24 2012 +0200 Updated Spanish translation po/es.po | 370 +++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 215 insertions(+), 155 deletions(-) commit fa5e27d3209fa15eb6096ef975f305e6032ac037 Author: Jiri Popelka Date: Wed Aug 8 14:33:25 2012 +0200 Use CUPS-1.6 IPP API getter/setter functions. CUPS 1.6 makes various structures private and introduces these ippGet and ippSet functions for all of the fields in these structures. http://www.cups.org/str.php?L3928 We define our own accessors when building against CUPS < 1.6. (#679759) (modified by Marek Kasik) panels/printers/cc-printers-panel.c | 20 ++- panels/printers/pp-new-printer-dialog.c | 10 +- panels/printers/pp-utils.c | 277 ++++++++++++++++++-------------- 3 files changed, 183 insertions(+), 124 deletions(-) commit ec2fc6d8b6aeb9d1faf42911e675224a4d152ba9 Author: Stef Walter Date: Wed Aug 8 09:33:07 2012 +0200 user-accounts: Remove needless console output https://bugzilla.gnome.org/show_bug.cgi?id=680892 panels/user-accounts/um-realm-manager.c | 1 - 1 file changed, 1 deletion(-) commit 4e67ecc45651729e2bcff40fac420098cdf41449 Author: Stef Walter Date: Wed Aug 8 09:30:35 2012 +0200 user-accounts: Cleanup GVariant usage * Don't call g_variant_ref_sink() unnecessarily. * Don't call g_variant_new_variant() unnecessarily. https://bugzilla.gnome.org/show_bug.cgi?id=680892 panels/user-accounts/um-account-dialog.c | 4 +--- panels/user-accounts/um-realm-manager.c | 9 ++------- 2 files changed, 3 insertions(+), 10 deletions(-) commit f28736ce17d5430510fb08e722f96809f627e50e Author: Nilamdyuti Goswami Date: Wed Aug 8 12:51:32 2012 +0530 Assamese translation updated po/as.po | 525 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 259 insertions(+), 266 deletions(-) commit fe25e2302e96483b32d67787f41d2342c1776ec1 Author: ŠœŠøŃ€Š¾ŃŠ»Š°Š² ŠŠøŠŗŠ¾Š»ŠøŃ› Date: Wed Aug 8 07:20:46 2012 +0200 Updated Serbian translation po/sr.po | 363 +++++++++++++++++++++++++++++++++------------------------ po/sr@latin.po | 363 +++++++++++++++++++++++++++++++++------------------------ 2 files changed, 424 insertions(+), 302 deletions(-) commit 478c6af97d6b1f99134ec9d864aa19b430eb4ca0 Author: Matthias Clasen Date: Wed Aug 8 01:14:58 2012 -0400 network: Make only the list background white panels/network/net-device-wifi.c | 5 +++++ 1 file changed, 5 insertions(+) commit 96682e13684d7b0e3fd17a63635006b86bb9b53e Author: Matthias Clasen Date: Wed Aug 8 00:32:34 2012 -0400 network: Put the ssid in the detail page header panels/network/net-device-wifi.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) commit 901ad8c94105993b5522968ddffd2bf9cd42823f Author: Matthias Clasen Date: Wed Aug 8 00:20:04 2012 -0400 network: Cosmetic fixes Mark a few strings as translatable, and rename 'Options' to 'Settings' to match the mockups. panels/network/network-wifi.ui | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) commit 61a5c180ecc4acec1d74cb02c573660572cd32e0 Author: Matthias Clasen Date: Wed Aug 8 00:16:37 2012 -0400 network: Don't make the options button insensitive We always want to be able to go there. panels/network/net-device-wifi.c | 8 -------- 1 file changed, 8 deletions(-) commit 0e70a56f9e713b266f5f523cf03e5e44959f4423 Author: Matthias Clasen Date: Tue Aug 7 23:44:22 2012 -0400 Trivial: Add a missing space panels/network/net-device-wifi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) commit e76472c5483eec908f926a6fe9ec6012959978df Author: Matthias Clasen Date: Tue Aug 7 23:40:47 2012 -0400 network: Improve the hotspot dialog Change the hotspot dialog to match the mockups more closely. panels/network/net-device-wifi.c | 80 ++++++++++--------------- panels/network/network-wifi.ui | 122 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+), 50 deletions(-) commit 637bd5183bb91b0ad029ef59af7b9d578bb1e906 Author: Matthias Clasen Date: Wed Aug 1 20:37:13 2012 +0200 info: change 'other media action' mnemonic Use the A instead of the o. There are no conflicts, and using the first character as mnemonic is better. https://bugzilla.gnome.org/show_bug.cgi?id=681211 panels/info/info.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 5fc4b1809b41c5acc7622df02744aba8dff91639 Author: Matthias Clasen Date: Wed Aug 1 20:36:04 2012 +0200 info: Fix mnemonic activation for 'other media action' The mnemonic was pointing at a box, which is not activatable. https://bugzilla.gnome.org/show_bug.cgi?id=681211 panels/info/cc-info-panel.c | 6 ++++++ panels/info/info.ui | 3 +-- 2 files changed, 7 insertions(+), 2 deletions(-) commit 34caef89ef89d63548572621ed4a2166b49eee1a Author: Matthias Clasen Date: Wed Aug 1 20:25:28 2012 +0200 info: replace one GtkTable instance by GtkGrid https://bugzilla.gnome.org/show_bug.cgi?id=681211 panels/info/info.ui | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) commit a8662e4261fbd6edaf2ed42b503964e164d54ee9 Author: Matthias Clasen Date: Wed Aug 1 20:16:21 2012 +0200 info: Use GtkBox instead of GtkHBox/GtkVBox https://bugzilla.gnome.org/show_bug.cgi?id=681211 panels/info/info.ui | 48 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 16 deletions(-) commit d06f19b903935ccbbaf736efc2513fa0f376f9de Author: Piotr Drąg Date: Tue Aug 7 23:45:02 2012 +0200 Updated POTFILES.in po/POTFILES.in | 2 ++ 1 file changed, 2 insertions(+) commit b5e0cc29e91441b73ae86a8700c9c57b143863e8 Author: ŠœŠøŃ€Š¾ŃŠ»Š°Š² ŠŠøŠŗŠ¾Š»ŠøŃ› Date: Tue Aug 7 23:32:33 2012 +0200 Updated Serbian translation po/sr.po | 276 +++++++++++++++++++++++++-------------------------------- po/sr@latin.po | 276 +++++++++++++++++++++++++-------------------------------- 2 files changed, 240 insertions(+), 312 deletions(-) commit 96d58bf995d180f43fc8861f50880b7a41d36a26 Author: Andika Triwidada Date: Wed Aug 8 03:58:28 2012 +0700 Updated Indonesian translation po/id.po | 6526 ++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 3761 insertions(+), 2765 deletions(-) commit 6a068261a67fe0f4308056a0b3676ad325598ae4 Author: Daniel Mustieles Date: Tue Aug 7 21:02:46 2012 +0200 Updated Spanish translation po/es.po | 264 ++++++++++++++++++++++++++++----------------------------------- 1 file changed, 119 insertions(+), 145 deletions(-) commit 15bcc03b4063bad9c3f338ca5fd37e21c0ced779 Author: Cyrus Lien Date: Tue Aug 7 14:23:21 2012 +0800 display: Do not add preferred mode to drop down in clone mode. Use preferred resolution to switch to mirror mode will popup error messages if preferred resolution is not a common resolution. https://bugzilla.gnome.org/show_bug.cgi?id=680969 panels/display/cc-display-panel.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) commit c3e71b49277e1e12bccd65b8575aa847862e6868 Author: Matthias Clasen Date: Tue Aug 7 10:19:18 2012 -0400 network: Don't show shared connections in the wifi list A shared connection is the leftover of an inactive hotspot. We don't want to show these in the list. panels/network/net-device-wifi.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) commit 9db6b3c5f531578b06d80ae286609fa8468d5c34 Author: Matthias Clasen Date: Tue Aug 7 09:58:29 2012 -0400 Trivial: fix a typo panels/user-accounts/um-account-dialog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit c6d8b9c8252cbf4e439cad0a225b841b2189fec0 Author: Marek Kasik Date: Tue Aug 7 14:09:33 2012 +0200 printers: Place jobs to separate dialog This commit places list of jobs to separate dialog. The dialog is updated through calling of pp_jobs_dialog_update() from "Printers" panel because the panel is already subscribed to cups notifications. panels/printers/Makefile.am | 7 +- panels/printers/cc-printers-panel.c | 446 ++++------------------------- panels/printers/jobs-dialog.ui | 183 ++++++++++++ panels/printers/pp-jobs-dialog.c | 541 ++++++++++++++++++++++++++++++++++++ panels/printers/pp-jobs-dialog.h | 42 +++ panels/printers/pp-utils.c | 265 ++++++++++++++++++ panels/printers/pp-utils.h | 26 ++ panels/printers/printers.ui | 154 +--------- 8 files changed, 1122 insertions(+), 542 deletions(-) commit 439b75fcea59101c02b378388f14b502dc6baea9 Author: Marek Kasik Date: Tue Aug 7 12:28:05 2012 +0200 printers: Return accidentally removed code Return implementation of get_help_uri() which was accidentally removed. panels/printers/cc-printers-panel.c | 7 +++++++ 1 file changed, 7 insertions(+) commit ed1c9becf7bdd80b2d18a8635819240f9ab3579e Author: Richard Hughes Date: Tue Aug 7 09:19:23 2012 +0100 network: If a hotspot is already connected at startup then don't show the AP list panels/network/net-device-wifi.c | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) commit a6b2db1e178d1f82409966a8ffa772955eea3525 Author: Marek Kasik Date: Tue Aug 7 11:54:11 2012 +0200 printers: Cancel async operations properly Don't call callbacks of async functions called from Printers panel if they were cancelled. User data are not valid in that case (rhbz#845496). panels/printers/cc-printers-panel.c | 90 ++++++++++++++++++++++++++++++------- panels/printers/pp-utils.c | 31 ++++++++++--- panels/printers/pp-utils.h | 5 ++- 3 files changed, 103 insertions(+), 23 deletions(-) commit aa867311c2ef48ee13d6dc9acf6d446fbdc1e21b Author: Nilamdyuti Goswami Date: Tue Aug 7 14:54:47 2012 +0530 Assamese translation updated po/as.po | 1303 +++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 826 insertions(+), 477 deletions(-) commit 3fa35643fa5c3371a1d699d496b03a167f6732b3 Author: Chao-Hsiung Liao Date: Tue Aug 7 15:10:48 2012 +0800 Updated Traditional Chinese translation(Hong Kong and Taiwan) po/zh_HK.po | 765 +++++++++++++++++++++++++++++++------------------------- po/zh_TW.po | 819 ++++++++++++++++++++++++++++++++---------------------------- 2 files changed, 865 insertions(+), 719 deletions(-) commit fdad89f85205a37707649ea70514ae34774f33ce Author: Colin Walters Date: Mon Aug 6 18:19:24 2012 -0400 build: Add --disable-documentation option For embedded systems, it's pointless to build the docs if they're not going to be used/shown. Also, for gnome-ostree right now I don't have the Docbook infrastructure set up. Makefile.am | 5 ++++- configure.ac | 12 +++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) commit 576d6ba04dc89406bd0e62ca7be23f05a9e2d489 Author: Matthias Clasen Date: Mon Aug 6 14:34:51 2012 -0400 screen: Keep 'show notifications' sensitive Even when automatic screen locking is disabled, the user can still manually lock the screen, and may want to control whether notifications show up in that case or not. panels/screen/cc-screen-panel.c | 6 ------ 1 file changed, 6 deletions(-) commit 1f4aeb1d05c24af428294b5955d36456d0a3544e Author: Stef Walter Date: Tue Jul 31 09:17:34 2012 +0200 user-panel: Update to new DBus interface for realmd 0.6 * In particular support of different credential methods and better hints for different owners of those credentials, so we can prompt more cleanly. * Less abstraction in the realmd interfaces https://bugzilla.gnome.org/show_bug.cgi?id=680892 .../user-accounts/data/org.freedesktop.realmd.xml | 101 ++++++------ panels/user-accounts/um-account-dialog.c | 47 ++++-- panels/user-accounts/um-realm-manager.c | 169 ++++++++++++++++----- panels/user-accounts/um-realm-manager.h | 16 +- 4 files changed, 224 insertions(+), 109 deletions(-) commit 6ee1e694df965c92ed8f5e16bc5067f59a845ae2 Author: ŠœŠøŃ€Š¾ŃŠ»Š°Š² ŠŠøŠŗŠ¾Š»ŠøŃ› Date: Sun Aug 5 12:18:44 2012 +0200 Updated Serbian translation po/sr.po | 479 ++++++++++++++++++++++++++++++++++----------------------- po/sr@latin.po | 479 ++++++++++++++++++++++++++++++++++----------------------- 2 files changed, 568 insertions(+), 390 deletions(-) commit dfede0780038d6aae840ef059c6efff0060876d4 Author: Matthias Clasen Date: Sat Aug 4 12:50:05 2012 -0400 Add a man page The main purpose of this man page is to document which options can be given to individual panels. https://bugzilla.gnome.org/show_bug.cgi?id=680547 Makefile.am | 4 +- configure.ac | 3 + man/Makefile.am | 19 +++ man/cinnamon-control-center.xml | 308 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 332 insertions(+), 2 deletions(-) commit 45bd60108f8f4648b5b85efe556d419b29a32487 Author: Cheng Lu Date: Sat Aug 4 14:54:05 2012 +0800 Update Chinese simplified translation for ui po/zh_CN.po | 1508 ++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 876 insertions(+), 632 deletions(-) commit c272aa5eb572012b0aa5da4c63a76d4b310cbaa8 Author: Marek Kasik Date: Thu Aug 2 11:47:39 2012 +0200 printers: Don't restrict PPD list Don't restrict PPD list to PPDs with DeviceIDs only. Extend dictionary of manufacturers names. panels/printers/cc-printers-panel.c | 8 +- panels/printers/pp-utils.c | 158 ++++++++++++++++++++++++------------ 2 files changed, 112 insertions(+), 54 deletions(-) commit 1cffa8e206e7fb9f4a0dbab05c3a810b15ee2879 Author: Stef Walter Date: Tue Jul 31 09:14:52 2012 +0200 user-panel: Fix memory leak of UmRealmManager https://bugzilla.gnome.org/show_bug.cgi?id=680890 panels/user-accounts/um-realm-manager.c | 2 ++ 1 file changed, 2 insertions(+) commit fb6833e57ab92cea99cc1af13a7c6b8db77ba900 Author: Stef Walter Date: Tue Jul 31 09:08:04 2012 +0200 user-panel: Strip remote dbus error before showing error * GDBus transfers dbus error codes in the error->message so strip that out before display https://bugzilla.gnome.org/show_bug.cgi?id=680889 panels/user-accounts/um-account-dialog.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) commit e707b83dc5033f44bdfb2c37596e2b2bf6588be1 Author: Fran DiĆ©guez Date: Tue Jul 31 01:46:02 2012 +0200 Updated Galician translations po/gl.po | 131 ++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 76 insertions(+), 55 deletions(-) commit 4386dcadfa86fd3520cd18f4095a5b687aa50b3e Author: Daniel Mustieles Date: Mon Jul 30 16:53:22 2012 +0200 Updated Spanish translation po/es.po | 147 +++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 81 insertions(+), 66 deletions(-) commit 68405bcf376b2187ffa7c9b0c0db29fe6135a157 Author: Daniel Mustieles Date: Mon Jul 30 12:48:16 2012 +0200 Updated Spanish translation po/es.po | 295 ++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 177 insertions(+), 118 deletions(-) commit d282d37e92f3735b042e8ee7a4468e6e289b0064 Author: Richard Hughes Date: Mon Jul 30 10:05:41 2012 +0100 network: Fix a Gtk warning introduced recently due to a mnemonic widget name panels/network/network-wifi.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit c0d771c277bda0ba73ab308d4c3013601e04bd3a Author: Richard Hughes Date: Mon Jul 30 10:03:04 2012 +0100 network: Don't show a blank name server label in the IP overview panels/network/panel-common.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) commit 763788894c4383894d638b6764507da4b036705a Author: Richard Hughes Date: Mon Jul 30 09:59:13 2012 +0100 network: Don't show the NULL address in the IP overview panels/network/panel-common.c | 2 ++ 1 file changed, 2 insertions(+) commit ae5acbe421159fc559746713d56e6c18a84cca6d Author: Richard Hughes Date: Mon Jul 30 09:53:38 2012 +0100 network: Show hotspot details in a new sub-frame to match the mockup panels/network/net-device-wifi.c | 123 ++++++++-------- panels/network/network-wifi.ui | 304 ++++++++++++++++++++++++++++----------- 2 files changed, 285 insertions(+), 142 deletions(-) commit 14011dac11840c2894d2d3eb0e964317091b11af Author: Richard Hughes Date: Mon Jul 30 09:49:40 2012 +0100 network: Cleanup coding style to match the rest of the file panels/network/net-device-wifi.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) commit 240e3b0598926d0411bcf258a92e055b94e36966 Author: Richard Hughes Date: Mon Jul 30 09:45:44 2012 +0100 network: Do not show the start hotspot button if the user has no permissions panels/network/net-device-wifi.c | 9 +++++++++ 1 file changed, 9 insertions(+) commit 5b35fb719c0527ee96af7af01afdeecec08f37e9 Author: Richard Hughes Date: Mon Jul 30 08:57:55 2012 +0100 network: Re-enable the hidden network functionality panels/network/net-device-wifi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) commit f7af831ff62e7975cb2b5128d3e9536ca079b3d8 Author: Richard Hughes Date: Mon Jul 30 08:53:43 2012 +0100 network: Make the hidden network UI match the new mockups panels/network/net-device-wifi.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) commit 26432f180f33bd8163b410b069a64d709a989306 Author: Fran DiĆ©guez Date: Mon Jul 30 02:09:41 2012 +0200 Updated Galician translations po/gl.po | 1240 +++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 774 insertions(+), 466 deletions(-) commit 051766d4827655be0211ffd20fcbbfd0aa82f249 Author: Matthias Clasen Date: Fri Jul 27 22:37:46 2012 +0200 network: Remove nonexisting widget from size group This was causing warnings. panels/network/network.ui | 3 --- 1 file changed, 3 deletions(-) commit 5b1491ba0c253bfaf3300eeea29b19b9c026d53b Author: Cosimo Cecchi Date: Sun Jul 29 11:35:24 2012 +0200 network: don't set 'dim-label' in the section It should be set among the normal properties. https://bugzilla.gnome.org/show_bug.cgi?id=680773 panels/network/network-wifi.ui | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) commit 2ad1d5461a08d9c761b4c66b9d237680b71639b0 Author: Cosimo Cecchi Date: Sun Jul 29 11:34:57 2012 +0200 network: add a shadow to the wireless scrolled window https://bugzilla.gnome.org/show_bug.cgi?id=680773 panels/network/network-wifi.ui | 1 + 1 file changed, 1 insertion(+) commit 1c762ace213c95f7111aa047617de7abd1078ddf Author: A S Alam Date: Sat Jul 28 07:07:29 2012 +0530 update Punjabi Translation po/pa.po | 1331 +++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 836 insertions(+), 495 deletions(-) commit b05de99a0be85ae4abaf437a9a10b6397f535320 Merge: fbe6756 5c5c538 Author: Richard Hughes Date: Fri Jul 27 16:20:37 2012 +0100 Merge branch 'network-wifi-rework' commit 5c5c538ebed771db16d51159a1f065b2b0aa8821 Author: Richard Hughes Date: Fri Jul 27 16:19:18 2012 +0100 network: Don't show the speed and security when the wifi device is deactivated panels/network/net-device-wifi.c | 50 +++++++++++++--------------------------- 1 file changed, 16 insertions(+), 34 deletions(-) commit 7cca78437db4bbbea291d2b915c6926dc6f26e78 Author: Richard Hughes Date: Fri Jul 27 14:12:18 2012 +0100 network: Forget the last selected network when the button is clicked Before we were deleting the connection currently bound to the device... panels/network/net-device-wifi.c | 99 ++++++++++++++++++++++++++++------------ 1 file changed, 70 insertions(+), 29 deletions(-) commit 1aa2ed94919a9d2e4278dd2e0f2248e6b905d199 Author: Richard Hughes Date: Fri Jul 27 11:49:54 2012 +0100 network: Show detailed information about saved wireless connections panels/network/net-device-wifi.c | 109 +++++++++++++++--- panels/network/network-wifi.ui | 237 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 317 insertions(+), 29 deletions(-) commit fbe6756c6f2104d78854da927b96c3d88cd31a2e Author: Rico Tzschichholz Date: Fri Jul 27 09:06:47 2012 +0200 configure: fix build with --disable-ibus https://bugzilla.gnome.org/show_bug.cgi?id=680133 configure.ac | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) commit c1201537cdb0b8b9d304e072d6f20658126dcfef Author: ŠœŠøŃ€Š¾ŃŠ»Š°Š² ŠŠøŠŗŠ¾Š»ŠøŃ› Date: Thu Jul 26 23:16:22 2012 +0200 Updated Serbian translation po/sr.po | 7366 +++++++++++++++++++++++++++++++++++++------------------- po/sr@latin.po | 7366 +++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 9786 insertions(+), 4946 deletions(-) commit 8776700a73f68ac00bf23d846c9158f8e6c1ce35 Author: Bastien Nocera Date: Thu Jul 26 17:54:03 2012 +0200 bluetooth: Update for killswitch API change panels/bluetooth/cc-bluetooth-panel.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) commit 9a10722da21096501a45af13e6191971465bf799 Author: Richard Hughes Date: Thu Jul 26 15:41:25 2012 +0100 network: Show the wireless speed as a seporate line in the details ...to match the mockup. panels/network/net-device-wifi.c | 19 +++++++++---------- panels/network/network-wifi.ui | 34 +++++++++++++++++++++++++++++----- 2 files changed, 38 insertions(+), 15 deletions(-) commit a0f69c0809aff8c717b6d7548c280ec9c3e1af8c Author: Richard Hughes Date: Thu Jul 26 14:46:53 2012 +0100 network: Don't crash when showing active APs that are not valid UTF8 There doesn't appear to be any standard saying you have to have ASCII/UTF-8 access point names... panels/network/net-device-wifi.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) commit f14b5501444faec72809b84706cc490b081218e8 Author: Richard Hughes Date: Thu Jul 26 14:43:54 2012 +0100 network: Only show the disconnect button when a device is fully activated panels/network/net-device-wifi.c | 5 +++++ 1 file changed, 5 insertions(+) commit 9441a74e8a289f80a0542b1c665f766837328001 Author: Richard Hughes Date: Thu Jul 26 14:43:17 2012 +0100 network: Add another panel for future hotspot information panels/network/network-wifi.ui | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) commit 38ea1cdefd6fce444a409bde4706a09ebabcd373 Author: Richard Hughes Date: Thu Jul 26 14:29:57 2012 +0100 network: Add network strength to the details panel panels/network/net-device-wifi.c | 2 -- 1 file changed, 2 deletions(-) commit 6b526f121319b78e56423d41cbe1ae143077a8aa Author: Richard Hughes Date: Thu Jul 26 14:29:38 2012 +0100 network: Add network strength to the details panel panels/network/net-device-wifi.c | 22 ++++++++++++++++++++++ panels/network/network-wifi.ui | 34 +++++++++++++++++++++++++++++----- 2 files changed, 51 insertions(+), 5 deletions(-) commit e7319edc9b61bf9ca667a8d1f3b1ad7e04f43706 Author: Richard Hughes Date: Thu Jul 26 14:23:31 2012 +0100 network: Add saved connections to the wireless network list panels/network/net-device-wifi.c | 160 ++++++++++++++++++++++++-- panels/network/network-wifi.ui | 4 + panels/network/panel-cell-renderer-security.c | 4 +- panels/network/panel-cell-renderer-signal.c | 2 +- 4 files changed, 157 insertions(+), 13 deletions(-) commit 5c11b6f94bd9518f449419e089143d7467ff6e2c Author: Richard Hughes Date: Thu Jul 26 13:47:09 2012 +0100 network: Only show the details arrow for active connections panels/network/net-device-wifi.c | 46 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) commit 391815c2c19d833eeb61fc7e4e617c1e416ae17a Author: Richard Hughes Date: Thu Jul 26 13:38:55 2012 +0100 network: split the wireless panel into a network list and details panel panels/network/net-device-wifi.c | 322 +++++++++++++++++++++++++++------------ panels/network/network-wifi.ui | 223 ++++++++++++++++++--------- 2 files changed, 372 insertions(+), 173 deletions(-) commit 22323ad6c6974891ff6680811d8f316b88e42e1d Author: Richard Hughes Date: Thu Jul 26 09:58:53 2012 +0100 network: Start to split up the network panel into different views to match the new mockup panels/network/net-device-wifi.c | 8 +- panels/network/network-wifi.ui | 932 +++++++++++++++++++++------------------ 2 files changed, 502 insertions(+), 438 deletions(-) commit 2bbd94094251f5b5aa2a632866974dfbca0bbd2c Author: ŠœŠøŃ€Š¾ŃŠ»Š°Š² ŠŠøŠŗŠ¾Š»ŠøŃ› Date: Thu Jul 26 09:49:49 2012 +0200 Updated Serbian translation po/sr.po | 7015 ++++++++++++++++++++------------------------------------ po/sr@latin.po | 7015 ++++++++++++++++++++------------------------------------ 2 files changed, 4960 insertions(+), 9070 deletions(-) commit 3e827ce3342681d61fc272bf1949d8aaa7717ec6 Author: Jiro Matsuzawa Date: Wed Jul 25 22:38:15 2012 +0900 [l10n] Update Japanese translation po/ja.po | 1331 ++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 777 insertions(+), 554 deletions(-) commit 556e2cf4e3e41b625774a8deddf19f82a3fb274b Author: Tom Tryfonidis Date: Tue Jul 24 18:35:41 2012 +0300 Updated Greek translation po/el.po | 4839 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 2673 insertions(+), 2166 deletions(-) commit c4db04f8a53548738a4fe665f56ea59e91aa92b5 Author: Dominique Leuenberger Date: Mon Jul 23 15:56:53 2012 +0200 configure: We require ibus version 1.4.99 or newer (1.5 unstable) https://bugzilla.gnome.org/show_bug.cgi?id=680133 configure.ac | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) commit f9e052eea0703e0e5d7e33fada7d7d2920f2d3d7 Author: Dominique Leuenberger Date: Mon Jul 23 15:04:58 2012 +0200 configure: Bump GTK+ requirement to 3.5.8: first version to bring GtkLevelBar. https://bugzilla.gnome.org/show_bug.cgi?id=680133 configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 3c1d245cbc3061194c5db4d3442c3fb08bae221d Author: Piotr Drąg Date: Mon Jul 23 22:34:14 2012 +0200 Updated POTFILES.in po/POTFILES.in | 2 ++ 1 file changed, 2 insertions(+) commit 12799fdb19feea7cd53425ef9cfe877911c4b0f3 Author: Kjartan Maraas Date: Mon Jul 23 12:38:08 2012 +0200 Updated Norwegian bokmĆ„l translation po/nb.po | 1077 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 603 insertions(+), 474 deletions(-) commit 125da078891c703be1fd52e305599a848145a5bc Author: Richard Hughes Date: Mon Jul 23 10:43:02 2012 +0100 network: Remove some dead code from the conversion panels/network/cc-network-panel.c | 110 +++++++------------------------------- 1 file changed, 19 insertions(+), 91 deletions(-) commit 08532a3a86e2a8ee6621c857281cf9a06bc77545 Author: Richard Hughes Date: Mon Jul 23 10:14:31 2012 +0100 network: Prevent a crash when a device is removed and then re-added panels/network/net-device.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) commit b06bb9e5f36a26f99506c2ef0d284885b3ba6e08 Author: Richard Hughes Date: Fri Jul 20 12:05:10 2012 +0100 network: Split the wifi device from the .c and .ui file panels/network/Makefile.am | 3 + panels/network/cc-network-panel.c | 2483 ++++++------------------------------- panels/network/net-device-wifi.c | 1538 +++++++++++++++++++++++ panels/network/net-device-wifi.h | 58 + panels/network/network-wifi.ui | 525 ++++++++ panels/network/network.ui | 520 -------- 6 files changed, 2475 insertions(+), 2652 deletions(-) commit a70b3f2c8e3b9c88c72e67793a82f7de006890dd Author: Khaled Hosny Date: Sun Jul 22 23:45:39 2012 +0200 Updated Arabic translation po/ar.po | 300 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 157 insertions(+), 143 deletions(-) commit 5366d1188e212d472905ac325df9a4c03eb711a9 Author: Matthias Clasen Date: Sun Jul 22 13:00:18 2012 -0400 info: Check PackageKit version at runtime The previous patch made use use PackageKit 0.8 API. This patch adds a version check that keeps the info panel from crashing when it finds an older PackageKit at runtime. panels/info/cc-info-panel.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) commit 76add03e25d87da3c99b1ad1b29081b9195f8d69 Author: Matthias Clasen Date: Sun Jul 22 12:59:15 2012 -0400 info: Adapt to PackageKit API breakage PackageKit 0.8.x has broken several APIs that we are using here. panels/info/cc-info-panel.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) commit 2b3a82b5ce1908099253148fb5fdfa4d03ed9585 Author: Daniel Mustieles Date: Sat Jul 21 18:44:55 2012 +0200 Updated Spanish translation po/es.po | 332 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 163 insertions(+), 169 deletions(-) commit cb6f427798e48d7672e9d608fb614f31b2f43453 Author: Piotr Drąg Date: Sat Jul 21 01:05:18 2012 +0200 Updated POTFILES.in po/POTFILES.in | 4 ++++ 1 file changed, 4 insertions(+) commit aee6325cf22156d274cfb02e2b2c6766cc6b13ce Author: Richard Hughes Date: Fri Jul 20 11:43:05 2012 +0100 network: Add a missing file for the mobile broadband UI panels/network/network-mobile.ui | 378 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 378 insertions(+) commit de8993eddbbea7a67e5de590913ce4563363b256 Author: Richard Hughes Date: Fri Jul 20 09:28:26 2012 +0100 network: Allow NetObjects to get the main panel object so they can show modal dialogs panels/network/cc-network-panel.c | 2 ++ panels/network/net-device-mobile.c | 5 +++-- panels/network/net-object.c | 22 ++++++++++++++++++++++ panels/network/net-object.h | 3 +++ 4 files changed, 30 insertions(+), 2 deletions(-) commit 26b5169beeb7045b77b871cb8aa81d5637c1c025 Author: Richard Hughes Date: Fri Jul 20 09:21:57 2012 +0100 network: Split the mobile broadband device from the .c and .ui file panels/network/Makefile.am | 3 + panels/network/cc-network-panel.c | 343 +--------------------- panels/network/net-device-mobile.c | 570 +++++++++++++++++++++++++++++++++++++ panels/network/net-device-mobile.h | 59 ++++ panels/network/network.ui | 420 --------------------------- 5 files changed, 636 insertions(+), 759 deletions(-) commit 62b8a4c8bbca007eb6514771baa4e3eea94e93e7 Author: Richard Hughes Date: Fri Jul 20 09:08:53 2012 +0100 network: Add a NetObject->edit vfunc for the different devices to use panels/network/net-device-wired.c | 15 +-------------- panels/network/net-device.c | 23 +++++++++++++++++++++++ panels/network/net-object.c | 8 ++++++++ panels/network/net-object.h | 2 ++ panels/network/net-vpn.c | 8 ++++++++ 5 files changed, 42 insertions(+), 14 deletions(-) commit a808633484695fbe245f5797108123c749985e5a Author: Richard Hughes Date: Wed Jul 18 15:08:07 2012 +0100 network: Split the wired device from the .c and .ui file panels/network/Makefile.am | 3 + panels/network/cc-network-panel.c | 165 +++-------------- panels/network/net-device-wired.c | 271 ++++++++++++++++++++++++++++ panels/network/net-device-wired.h | 58 ++++++ panels/network/network-wired.ui | 366 ++++++++++++++++++++++++++++++++++++++ panels/network/network.ui | 360 ------------------------------------- 6 files changed, 726 insertions(+), 497 deletions(-) commit 5644bd6e6291278e3829cbb0c2a04e0a1d2fcd21 Author: Richard Hughes Date: Wed Jul 18 14:57:26 2012 +0100 network: Add panel_set_device_widgets() to the widget common code We can use this from the different NetDevice types, and once all the devices are converted to actual NetDeviceFoo-style objects we can remove the legacy code in cc-network-panel.c panels/network/panel-common.c | 172 +++++++++++++++++++++++++++++++++++++++++- panels/network/panel-common.h | 2 + 2 files changed, 172 insertions(+), 2 deletions(-) commit 1e4b0649f497e3969c73ac20e27a25df1886b435 Author: Matthias Clasen Date: Thu Jul 19 21:36:20 2012 -0400 region: Handle being opened twice gracefully When the going from the region panel to the overview and back, the input methods in the list loose their display names. What is happening is that we recreate the ibus object, but the second time around it is already connected since ibus uses a shared singleton connection internally. Thus, the ::connected signal is never emitted, and we don't fetch the engines. Work around this by checking if the newly created ibus object is already connected, and directly calling fetch_ibus_engines if it is. To make this work, we have to set up the treeview with its model earlier. panels/region/gnome-region-panel-input.c | 39 +++++++++++++++++--------------- 1 file changed, 21 insertions(+), 18 deletions(-) commit 0af48c80a95f9ca6ceca0b1b65e0a17b96fcb4f3 Author: Matthias Clasen Date: Thu Jul 19 21:34:18 2012 -0400 region: Make the code more robust update_ibus_active_sources may very well be called with an empty treeview. The code that iterates over the model was assuming that there is at least one item. Fix that by checking the return value of gtk_tree_model_get_iter_first(). panels/region/gnome-region-panel-input.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) commit b807656dbb8db5bb0e61d2de47004be9a616f07a Author: Ihar Hrachyshka Date: Thu Jul 19 22:58:20 2012 +0300 Updated Belarusian translation. po/be.po | 600 +++++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 428 insertions(+), 172 deletions(-) commit 06554439b7243aa3625d52ad8fe41ed621d3ac3c Author: Olivier Fourdan Date: Wed Jul 18 14:23:29 2012 +0200 wacom: Do calibration for the selected tool only As different tools may have different resolutions (e.g. touch vs. stylus on tablets which support both). https://bugzilla.gnome.org/show_bug.cgi?id=680114 panels/wacom/calibrator/gui_gtk.c | 13 +++++++++++++ panels/wacom/calibrator/gui_gtk.h | 1 + panels/wacom/calibrator/main.c | 3 ++- panels/wacom/cc-wacom-page.c | 14 +++++++++++++- 4 files changed, 29 insertions(+), 2 deletions(-) commit f004ecb17d826ef4389ebe0d2f8ca5c34eb6392d Author: Olivier Fourdan Date: Wed Jul 18 15:17:36 2012 +0200 wacom: Fix critical warning after calibration g_variant_new_array() creates a floating reference and g_settings_set_value() consumes it, so don't unref the GVariant ourselves. https://bugzilla.gnome.org/show_bug.cgi?id=680171 panels/wacom/cc-wacom-page.c | 1 - 1 file changed, 1 deletion(-) commit d37487ffa52d7294b186c75562e2753513426e6b Author: Tobias Endrigkeit Date: Wed Jul 18 21:48:29 2012 +0200 Updated German translation po/de.po | 2714 ++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 1740 insertions(+), 974 deletions(-) commit 20f85e38b742d7976cea10de5f910a91b05d5648 Author: Chao-Hsiung Liao Date: Wed Jul 18 09:34:45 2012 +0800 Updated Traditional Chinese translation(Hong Kong and Taiwan) po/zh_HK.po | 594 +++++++++++++++++++++++++++++++++++++++++++----------------- po/zh_TW.po | 594 +++++++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 848 insertions(+), 340 deletions(-) commit 21d93f184c192a73b6984d320a7b432c92bbc8eb Author: Aurimas Černius Date: Tue Jul 17 22:19:40 2012 +0300 Updated Lithuanian translation po/lt.po | 1592 +++++++++++++++++++++++++++++--------------------------------- 1 file changed, 754 insertions(+), 838 deletions(-) commit fad7dcba736a2b3a3e873d442475fdd3c17e4b23 Author: Bastien Nocera Date: Tue Jul 17 19:09:17 2012 +0100 3.5.5 NEWS | 36 ++++++++++++++++++++++++++++++++++++ configure.ac | 2 +- 2 files changed, 37 insertions(+), 1 deletion(-) commit 00c51443ae596b7e024b175e8c9f047c42fe5738 Author: Richard Hughes Date: Tue Jul 17 16:15:13 2012 +0100 network: Add some more widget setting common code panels/network/panel-common.c | 20 ++++++++++++++++++++ panels/network/panel-common.h | 3 +++ 2 files changed, 23 insertions(+) commit f4c13e835b72c8f3f274000663390932c0f74462 Author: Richard Hughes Date: Tue Jul 17 16:00:40 2012 +0100 network: Move setting the device header pairs to common panel code This is yet another step to splitting out the other devices types. panels/network/net-vpn.c | 84 +++++++++++-------------------------------- panels/network/network-vpn.ui | 52 +++++++++++++-------------- panels/network/panel-common.c | 34 ++++++++++++++++++ panels/network/panel-common.h | 4 +++ 4 files changed, 85 insertions(+), 89 deletions(-) commit 95d0a2e537e02fcd880bf70f7d607a74145f06b9 Author: Giovanni Campagna Date: Tue Jul 10 16:17:15 2012 +0200 screen: add "Show Notifications" setting Add a checkbox to control the visibility of notifications when the screen is locked. https://bugzilla.gnome.org/show_bug.cgi?id=658660 panels/screen/cc-screen-panel.c | 12 ++++++++++++ panels/screen/screen.ui | 30 +++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 3 deletions(-) commit 7e5654bf484c2e1d47eb3e29658a03320f44643f Author: Richard Hughes Date: Tue Jul 17 14:13:31 2012 +0100 network: Fix a trivial GTK warning at startup about a missing widget panels/network/network.ui | 1 - 1 file changed, 1 deletion(-) commit 6de161617a324b49332de624b037a3d8f6132ad7 Author: Richard Hughes Date: Tue Jul 17 14:13:08 2012 +0100 network: Fix the VPN information my setting the connection at object construction time panels/network/cc-network-panel.c | 1 + panels/network/net-vpn.c | 73 +++++++++++++++++++++++++++++++++++++-- panels/network/net-vpn.h | 2 -- 3 files changed, 71 insertions(+), 5 deletions(-) commit 04dc515aa51b0a105a9675dacd8fd0ad40ce6d7f Author: Khaled Hosny Date: Tue Jul 17 13:26:56 2012 +0200 Updated Arabic translation po/ar.po | 824 ++++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 528 insertions(+), 296 deletions(-) commit 89a815a6f95ff3d6846b8eec63c0095f1a5ef652 Author: Daniel Mustieles Date: Tue Jul 17 12:04:18 2012 +0200 Updated Spanish translation po/es.po | 364 +++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 285 insertions(+), 79 deletions(-) commit 96f7cbae9064592eb4717a9ae2bd913750ce6c9d Author: Richard Hughes Date: Mon Jul 16 17:37:18 2012 +0100 network: Return success from panel_set_notebook_page_for_object() This is so we can run the panel with both old-style and new-style NetDevices whilst we are migrating the device kinds. panels/network/cc-network-panel.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) commit e72194482e3eb718a42615fa9e6bd52025a15ad2 Author: Richard Hughes Date: Mon Jul 16 17:35:56 2012 +0100 network: Remove some unused code panels/network/cc-network-panel.c | 24 ------------------------ 1 file changed, 24 deletions(-) commit 3c2a09294cb6fc237f5f780b2f37adc8c113d12c Author: Richard Hughes Date: Mon Jul 16 17:34:24 2012 +0100 network: Set the device properties at construct time We need this for more complicated devices that need to contact other daemons, for instance ModemManager. panels/network/cc-network-panel.c | 31 ++++++++++++++++++------------- panels/network/net-device.c | 10 ---------- panels/network/net-device.h | 2 -- panels/network/net-object.c | 31 ++++--------------------------- panels/network/net-object.h | 3 --- panels/network/net-vpn.c | 11 ----------- panels/network/net-vpn.h | 1 - 7 files changed, 22 insertions(+), 67 deletions(-) commit cd765a1267b01c843fdf10ad122e4b8daab973c2 Author: Richard Hughes Date: Mon Jul 16 17:28:09 2012 +0100 network: Export net_device_get_find_connection() so it can be used by future network devices panels/network/cc-network-panel.c | 168 ++------------------------------------ panels/network/net-device.c | 167 +++++++++++++++++++++++++++++++++++++ panels/network/net-device.h | 1 + 3 files changed, 177 insertions(+), 159 deletions(-) commit 5d17320817bc26418d9e07745affba50ec680e11 Author: Richard Hughes Date: Mon Jul 16 17:22:56 2012 +0100 network: Add a GObject nm-device property for NetDevice panels/network/net-device.c | 65 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) commit f9e2828f77bb2a03b6bdc27e249f4fa7ed59c565 Author: Richard Hughes Date: Mon Jul 16 17:15:43 2012 +0100 network: Add a NMRemoteSettings property to NetObject for future use panels/network/net-object.c | 22 ++++++++++++++++++++++ panels/network/net-object.h | 2 ++ 2 files changed, 24 insertions(+) commit b48fc1b65c5781a4da1fe51941d02daa2c9abc9a Author: Richard Hughes Date: Mon Jul 16 17:14:01 2012 +0100 network: Add a GCancellable property to NetObject for future use panels/network/net-object.c | 23 ++++++++++++++++++++++- panels/network/net-object.h | 1 + 2 files changed, 23 insertions(+), 1 deletion(-) commit 7fcc4666ac8fce4cb0d8599b0b921f75097358e2 Author: Richard Hughes Date: Tue Jul 17 10:21:13 2012 +0100 network: Set the correct page when using mobile broadband devices panels/network/cc-network-panel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 64150f145890143316fa3aefbbd322f3698369de Author: Matthias Clasen Date: Tue Jul 17 00:00:16 2012 -0400 Avoid losing the selection When the active input sources list is changed in any way (add or remove or reorder a source), we write the list to the setting, and then we get a changed signal for the setting, and rebuild the list from the setting. Doing so loses the selection, unless we take extra precaution to keep it. https://bugzilla.gnome.org/show_bug.cgi?id=680027 panels/region/gnome-region-panel-input.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) commit 54835c8f4486309c1517a7f71735fbdd7e098c5f Author: Matthias Clasen Date: Mon Jul 16 23:59:03 2012 -0400 Remove one more leftover reference to a filter model The active input sources are no longer stored in a filter model. Also, use gtk_list_store_insert_with_values for atomic insertion. panels/region/gnome-region-panel-input.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) commit ee32c358f1f7da62f9876e38a010f72eb2323ab1 Author: Bastien Nocera Date: Mon Jul 16 18:05:04 2012 +0100 shell: Don't handle shortcuts with excess modifiers Ctrl+Alt+W shouldn't be handled the same way as Ctrl+W. https://bugzilla.gnome.org/show_bug.cgi?id=675475 shell/cinnamon-control-center.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) commit 1fdfa6bc32077ff246cc8531e01d690327467602 Author: Olivier Fourdan Date: Thu Jul 5 15:36:10 2012 +0200 wacom: show calibration success by drawing an "emblem-ok-symbolic" icon when calibration is successful https://bugzilla.gnome.org/show_bug.cgi?id=668610 panels/wacom/calibrator/gui_gtk.c | 108 +++++++++++++++++++++++++++++++++++--- 1 file changed, 101 insertions(+), 7 deletions(-) commit 953cc81b0f07c0e5f4e1f34a139efafe6d61fea1 Author: Matthias Clasen Date: Mon Jul 16 12:07:39 2012 -0400 Region: Remove references to a no-longer-existing filter model There was some code left around for dealing with a filter model, but we don't have the active input sources in a filtered list anymore. This was leading to crashes when removing or rearranging input sources. panels/region/gnome-region-panel-input.c | 36 ++++++-------------------------- 1 file changed, 6 insertions(+), 30 deletions(-) commit 3b4f577652bf0544a2070df5ea473ba08b926ab0 Author: Bastien Nocera Date: Mon Jul 16 17:03:36 2012 +0100 shell: Fix not being able to assign Ctrl+Q to a shortcut Because the shell window was capturing it before the key editing cell had a change to get to it. s/g_signal_connect/g_signal_connect_after/ https://bugzilla.gnome.org/show_bug.cgi?id=671448 shell/cinnamon-control-center.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit ab0594239c5e43b3a14a0cf40ab2cce039a17a53 Author: Bastien Nocera Date: Mon Jul 16 16:40:15 2012 +0100 region: Fix compilation failure A use of the removed tree_view_get_actual_model() crept in. panels/region/gnome-region-panel-input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit bf710914becf8f228ed38cf8d9b3c7c075df65b1 Author: Piotr Drąg Date: Mon Jul 16 17:49:55 2012 +0200 Updated POTFILES.in po/POTFILES.in | 6 ++++++ 1 file changed, 6 insertions(+) commit 5dd45a964d062dc2f7a066c00247bfe062f2a7f4 Author: Daniel Mustieles Date: Mon Jul 16 16:43:23 2012 +0200 Updated Spanish translation po/es.po | 608 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 321 insertions(+), 287 deletions(-) commit 661019dadcdfe08a7d184c37a881fafea254a10e Author: Bastien Nocera Date: Mon Jul 16 15:24:23 2012 +0100 region: Remove unneeded signal blockers The value isn't going to change from under us, as the settings object is in delayed mode. panels/region/gnome-region-panel-input.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) commit 3579d7bb970376a0a9d8616f334d23e7f71202af Author: Rui Matos Date: Mon Jul 2 03:30:12 2012 +0200 region: Try to keep the current input source when modifying the list When modifying the input sources list the currently active source's index might change. We must change the current setting accordingly to keep it active. https://bugzilla.gnome.org/show_bug.cgi?id=662489 panels/region/gnome-region-panel-input.c | 62 ++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 11 deletions(-) commit 49f7d379bc38aeeeb84cf98571d34a1a0ba28423 Author: Rui Matos Date: Mon Jul 2 04:05:09 2012 +0200 region: Fix a couple of memory leaks Unref the GSettings object and build the GnomeXkbInfo only once. There's no need to free and keep rebuilding the latter since it doesn't keep any state and is a bit expensive to build. https://bugzilla.gnome.org/show_bug.cgi?id=662489 panels/region/gnome-region-panel-input.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) commit 03f08fd36c059c17f3af723ca29e0ad931fc6a26 Author: Bastien Nocera Date: Mon Jul 16 15:15:28 2012 +0100 region: Never hide items from view If IBus is unavailable to get the input source's display name, just show the ID instead, and populate the display name when we get a change (eg. when fetching the input sources from IBus is done). panels/region/gnome-region-panel-input.c | 70 ++++++-------------------------- 1 file changed, 13 insertions(+), 57 deletions(-) commit 5e737900b0df98aa5c6aac9fc0b83fff9f454692 Author: Rui Matos Date: Mon Jul 2 03:39:10 2012 +0200 region: Wire up the input source settings button For XKB input sources the settings button remains unsensitive. For IBus sources we make it sensitive and launch the engine's setup tool on clicked if there is one. https://bugzilla.gnome.org/show_bug.cgi?id=662489 panels/region/gnome-region-panel-input.c | 115 ++++++++++++++++++++++++++++--- 1 file changed, 104 insertions(+), 11 deletions(-) commit 412e53079f051c7358f0200c38cd5957dc082e94 Author: Rui Matos Date: Tue May 22 19:14:40 2012 +0200 region: Add IBus input sources We query IBus for the available engines and present them alongside XKB layouts. https://bugzilla.gnome.org/show_bug.cgi?id=662489 configure.ac | 22 +- panels/region/gnome-region-panel-input.c | 356 ++++++++++++++++++++++++++++--- 2 files changed, 348 insertions(+), 30 deletions(-) commit 7ae3027b472422cdae47c09dd0420b297dacf089 Author: Marek Kasik Date: Mon Jul 16 15:25:10 2012 +0200 printer: Add "Options" dialog Add Options dialog which allows users to set more options than current dialog. The dialog reads printer's PPD file and add its options to the dialog together with some preselected IPP options (#678637). All operations in the dialog are asynchronous. During implementation of this, the option for setting allowed users was removed because this is not suitable for this panel (the option is intended for administrators). panels/printers/Makefile.am | 7 + panels/printers/cc-printers-panel.c | 343 ++---------- panels/printers/options-dialog.ui | 182 ++++++ panels/printers/pp-ipp-option-widget.c | 605 ++++++++++++++++++++ panels/printers/pp-ipp-option-widget.h | 70 +++ panels/printers/pp-options-dialog.c | 984 +++++++++++++++++++++++++++++++++ panels/printers/pp-options-dialog.h | 42 ++ panels/printers/pp-ppd-option-widget.c | 624 +++++++++++++++++++++ panels/printers/pp-ppd-option-widget.h | 63 +++ panels/printers/pp-utils.c | 285 ++++++++++ panels/printers/pp-utils.h | 25 + 11 files changed, 2937 insertions(+), 293 deletions(-) commit e61ec214b06fb1b9a82abb42e076f51ef6c2ee76 Author: Richard Hughes Date: Mon Jul 16 14:08:25 2012 +0100 network: Ensure to install the VPN .ui file panels/network/Makefile.am | 1 + 1 file changed, 1 insertion(+) commit dd7479caeace07e44d72cd310753a87a44e3e578 Author: Marek Kasik Date: Mon Jul 16 11:10:02 2012 +0200 printers: Allow users to change printer's PPD file This commit adds popup window which when activated allows user to select PPD from local database of installed PPDs, select directly PPD from filesystem or select one from 3 recommended PPDs (#678637). The popup is activated by clicking on model field (the panel has to be unlocked). It starts to search for the best PPDs available immediately after its popup. All operations are asynchronous. panels/printers/Makefile.am | 15 +- panels/printers/cc-printers-panel.c | 641 ++++++++++- panels/printers/pp-ppd-selection-dialog.c | 444 ++++++++ panels/printers/pp-ppd-selection-dialog.h | 46 + panels/printers/pp-utils.c | 1635 +++++++++++++++++++++++++++++ panels/printers/pp-utils.h | 90 ++ panels/printers/ppd-selection-dialog.ui | 206 ++++ panels/printers/printers.ui | 75 +- 8 files changed, 3119 insertions(+), 33 deletions(-) commit 1b3e877ef2e1e35ab4f33fea83ffb422286dbf88 Author: Cosimo Cecchi Date: Mon Jun 11 09:58:07 2012 -0400 shell: remove CcStrengthBar Panels are all ported to GtkLevelBar instead. https://bugzilla.gnome.org/show_bug.cgi?id=679984 shell/Makefile.am | 2 - shell/cc-strength-bar.c | 395 ------------------------------------------------ shell/cc-strength-bar.h | 69 --------- 3 files changed, 466 deletions(-) commit dfe03a1173f2c1d5cae8db948bfd57a0e193ecf4 Author: Cosimo Cecchi Date: Mon Jun 11 09:57:31 2012 -0400 user-accounts: port to GtkLevelBar This also adds another out parameter to pw_strength(), which is a discrete indication of the password strength (to be used with GtkLevelBar). The advantage of having such a parameter back from pw_strength() is that we can make sure the fill value and the hint string change at the same time, for better consistency. https://bugzilla.gnome.org/show_bug.cgi?id=679984 panels/user-accounts/data/password-dialog.ui | 8 +++++++- panels/user-accounts/pw-utils.c | 30 ++++++++++++++++++---------- panels/user-accounts/pw-utils.h | 3 ++- panels/user-accounts/um-password-dialog.c | 9 ++++----- panels/user-accounts/um-user-panel.c | 2 -- 5 files changed, 33 insertions(+), 19 deletions(-) commit b05591b1654c391f6d4aa113525b70ca736f68a0 Author: Cosimo Cecchi Date: Mon Jun 11 09:56:49 2012 -0400 power: port to GtkLevelBar https://bugzilla.gnome.org/show_bug.cgi?id=679984 panels/power/cc-power-panel.c | 32 ++++++++++---------------------- panels/power/power.ui | 4 ++-- 2 files changed, 12 insertions(+), 24 deletions(-) commit 38411a0d461540c9cd7a851ff13220786fef6dba Author: Ihar Hrachyshka Date: Sun Jul 15 12:10:30 2012 +0300 Updated Belarusian translation. po/be.po | 735 ++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 417 insertions(+), 318 deletions(-) commit 59c159da2b6e4174aafbf3e0d73ea744eb5b560c Author: Chao-Hsiung Liao Date: Sat Jul 14 13:54:46 2012 +0800 Updated Traditional Chinese translation(Hong Kong and Taiwan) po/zh_HK.po | 465 ++++++++++++++++++++++++++--------------------------------- po/zh_TW.po | 467 ++++++++++++++++++++++++++---------------------------------- 2 files changed, 402 insertions(+), 530 deletions(-) commit 118d5c276d1236b29d66f7fd3761aa7b317c381f Author: Piotr Drąg Date: Thu Jul 12 22:23:22 2012 +0200 Updated POTFILES.in po/POTFILES.in | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) commit 0a98c5a921225055af230dcf218e52c99035134d Author: Richard Hughes Date: Thu Jul 12 17:29:47 2012 +0100 network: Provide a vfunc for refreshing a NetObject panels/network/net-device.c | 1 + panels/network/net-object.c | 8 ++++++++ panels/network/net-object.h | 2 ++ panels/network/net-vpn.c | 8 ++++++++ 4 files changed, 19 insertions(+) commit 8384a0b741728c33c6a84003fc6efde4ec91161c Author: Richard Hughes Date: Thu Jul 12 16:58:11 2012 +0100 network: Split the VPN parts from the .c and .ui file panels/network/cc-network-panel.c | 189 ++------------------- panels/network/net-vpn.c | 273 ++++++++++++++++++++++++++++--- panels/network/net-vpn.h | 7 - panels/network/network-vpn.ui | 336 ++++++++++++++++++++++++++++++++++++++ panels/network/network.ui | 313 ----------------------------------- 5 files changed, 603 insertions(+), 515 deletions(-) commit ddabc6049f8aaf7e7123970ee289a1d8af309332 Author: Richard Hughes Date: Thu Jul 12 16:55:20 2012 +0100 network: Add a vfunc so a NetObject can be deleted We will only support this for VPN 'devices' but it seemed a cleaner abstraction this way. panels/network/net-object.c | 8 ++++++++ panels/network/net-object.h | 2 ++ 2 files changed, 10 insertions(+) commit eeecc61d0583023dd40fcc295432cab1e50a3ca0 Author: Richard Hughes Date: Thu Jul 12 16:35:06 2012 +0100 network: Share a NMClient instance between NetObjects Creating a NMClient is expensive and slow. This will be used in future code. panels/network/cc-network-panel.c | 1 + panels/network/net-object.c | 31 +++++++++++++++++++++++++++++++ panels/network/net-object.h | 4 ++++ 3 files changed, 36 insertions(+) commit c26e14518ea66491dba2c2dcf356bbab865f68ef Author: Richard Hughes Date: Thu Jul 12 14:07:54 2012 +0100 network: Split the proxy parts from the .c and .ui file A source file with 4k lines of code is not understandable, and the glade file was becoming quite a challenge for glade. To add more features we need to split things up just to keep them maintainable. This is the first patch that just splits out the proxy bits. Other device types will follow in the next few days. panels/network/Makefile.am | 6 +- panels/network/cc-network-panel.c | 353 +++++-------------------------- panels/network/net-device.c | 4 +- panels/network/net-object.c | 20 ++ panels/network/net-object.h | 17 +- panels/network/net-proxy.c | 388 ++++++++++++++++++++++++++++++++++ panels/network/net-proxy.h | 59 ++++++ panels/network/network-proxy.ui | 427 ++++++++++++++++++++++++++++++++++++++ panels/network/network.ui | 415 ------------------------------------ po/POTFILES.in | 2 + 10 files changed, 975 insertions(+), 716 deletions(-) commit 298489ee167486c0ca808805c699e73843b09356 Author: Richard Hughes Date: Thu Jul 12 14:00:40 2012 +0100 network: Add a boolean 'removable' property to NetObject for future use Also add GObject getters and setters for the other two properties. panels/network/net-object.c | 99 +++++++++++++++++++++++++++++++++++++++++++++ panels/network/net-object.h | 3 ++ 2 files changed, 102 insertions(+) commit a995cfac99e0642517268b5ba2552cadb15a962a Author: Bastien Nocera Date: Wed Jul 11 16:35:38 2012 +0100 build: Require PulseAudio 2.0 for the sound changes configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 89fbf2b35bfef9d56e9109745f040158a5594b60 Author: Bastien Nocera Date: Wed Jul 11 16:26:28 2012 +0100 sound: Use PulseAudio's implementation of pa_cvolume_set_position() panels/sound/gvc-balance-bar.c | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) commit 3cf252f4f0874276804f0c64c3c194ed42995d02 Author: Bastien Nocera Date: Wed Jul 11 16:24:53 2012 +0100 sound: Remove support code for older PulseAudio our define of PA_VOLUME_UI_MAX was only needed for PA 0.9.22 and older. panels/sound/gvc-mixer-control.c | 5 ----- 1 file changed, 5 deletions(-) commit 1dfd464a5907a1aa8b241790ffe5b7f8f31e505f Author: Conor Curran Date: Wed Jul 11 16:19:24 2012 +0100 sound: Add support for GvcMixerUIDevices in GvcMixerControl https://bugzilla.gnome.org/show_bug.cgi?id=674831 panels/sound/gvc-mixer-control.c | 1116 +++++++++++++++++++++++++++++++++++++- panels/sound/gvc-mixer-control.h | 60 +- 2 files changed, 1138 insertions(+), 38 deletions(-) commit 3201240eeecb935d7eab985230d6104e6a5188a9 Author: Bastien Nocera Date: Wed Jul 11 15:28:44 2012 +0100 sound: Add more debug panels/sound/gvc-mixer-control.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) commit 2a567809a24e6a55b2b88e47225971e61b7aaf71 Author: Conor Curran Date: Wed Jul 11 13:43:07 2012 +0100 sound: Add "available" member to GvcMixerStreamPort https://bugzilla.gnome.org/show_bug.cgi?id=674831 panels/sound/gvc-mixer-stream.h | 1 + 1 file changed, 1 insertion(+) commit 6135c964a7dba0792ef9be7365383667667ed657 Author: Bastien Nocera Date: Wed Jul 11 13:37:56 2012 +0100 sound: Add gvc_mixer_ui_device_get_active_profile() helper https://bugzilla.gnome.org/show_bug.cgi?id=674831 panels/sound/gvc-mixer-ui-device.c | 45 ++++++++++++++++++++++++-------------- panels/sound/gvc-mixer-ui-device.h | 1 + 2 files changed, 29 insertions(+), 17 deletions(-) commit 0489296c33edff1408f897eac768b5576e543650 Author: Bastien Nocera Date: Wed Jul 11 13:18:14 2012 +0100 sound: Fix indentation panels/sound/gvc-mixer-ui-device.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) commit e32a02e2dda8432572075e9134a9a04abdbecbae Author: Conor Curran Date: Wed Jul 11 12:49:20 2012 +0100 sound: Make sort_profiles public And rename it to gvc_mixer_card_profile_compare() https://bugzilla.gnome.org/show_bug.cgi?id=674831 panels/sound/gvc-mixer-card.c | 15 ++++++++++----- panels/sound/gvc-mixer-card.h | 3 +++ 2 files changed, 13 insertions(+), 5 deletions(-) commit e5e7080e4e8e4e8dc5662216d9e5daa9b04bef66 Author: Conor Curran Date: Wed Jul 4 15:26:52 2012 +0200 sound: Add get_gicon() function to GvcMixerCard https://bugzilla.gnome.org/show_bug.cgi?id=674831 panels/sound/gvc-mixer-card.c | 18 ++++++++++++++++++ panels/sound/gvc-mixer-card.h | 2 ++ 2 files changed, 20 insertions(+) commit 4da83052d2c3e237795d64af588ceec9fd0b3cbe Author: Bastien Nocera Date: Wed Jul 11 12:25:31 2012 +0100 sound: Indentation in gvc-mixer-card.h panels/sound/gvc-mixer-card.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) commit fd75ccd894e11951c7149b918759c2e3f87cb97c Author: Conor Curran Date: Fri Jun 8 13:03:58 2012 +0100 sound: Expose ports in GvcMixerCard https://bugzilla.gnome.org/show_bug.cgi?id=674831 panels/sound/gvc-mixer-card.c | 32 ++++++++++++++++++++++++++++++++ panels/sound/gvc-mixer-card.h | 15 ++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) commit db6afc826644f522c4d985083deb6a5b31910a2f Author: Conor Curran Date: Fri Jun 8 12:45:22 2012 +0100 sound: Add new UIDevice object GvcMixerUIDevice objects correspond to an item on either the input or output tab - typically "Headphones", "Speaker", "Internal Mic" etc. https://bugzilla.gnome.org/show_bug.cgi?id=674831 panels/sound/Makefile.am | 2 + panels/sound/gvc-mixer-ui-device.c | 645 +++++++++++++++++++++++++++++++++++++ panels/sound/gvc-mixer-ui-device.h | 81 +++++ 3 files changed, 728 insertions(+) commit e2a75e76c2c4380c1312157f6623efd464d89a28 Author: Bastien Nocera Date: Wed Jul 11 11:21:18 2012 +0100 sound: Remove unused eol parameter panels/sound/gvc-mixer-control.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) commit 4d4aab542af24f47393526b40926f8ba6ad6630a Author: Bastien Nocera Date: Wed Jul 11 11:06:34 2012 +0100 Revert "Brightness & Lock: add Show Notifications setting" This reverts commit 11ad5954c62d3ac083d0a2cde3fd7d3db07c059e. Committed in error panels/screen/cc-screen-panel.c | 12 ------------ panels/screen/screen.ui | 42 +++-------------------------------------- 2 files changed, 3 insertions(+), 51 deletions(-) commit ca29f85201dbd9de72a863e2d67fa198e452db35 Author: David Henningsson Date: Tue Jul 10 17:51:39 2012 +0200 sound: Fixup "set default source" patch The previous commit introduced a segfault due to referencing a NULL pointer. https://bugzilla.gnome.org/show_bug.cgi?id=674925 panels/sound/gvc-mixer-control.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) commit 0d4aa158d8a164aa6d6c688a79b5cc021539c53a Author: Bastien Nocera Date: Tue Jul 10 16:17:04 2012 +0100 build: Require newer gsettings-desktop-schemas configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 11ad5954c62d3ac083d0a2cde3fd7d3db07c059e Author: Giovanni Campagna Date: Tue Jul 10 16:17:15 2012 +0200 Brightness & Lock: add Show Notifications setting Add a switch to control the visibility of notifications when the screen is locked. https://bugzilla.gnome.org/show_bug.cgi?id=658660 panels/screen/cc-screen-panel.c | 12 ++++++++++++ panels/screen/screen.ui | 42 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 51 insertions(+), 3 deletions(-) commit 7d426ffda37c7ad205b96d3721f6dd27582ae78b Author: Colin Walters Date: Tue Jul 10 17:54:38 2012 -0400 build: Adjust previous patch to be what was intended configure.ac | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) commit e939825c6dc79accb8a00b66d519718a8b71487f Author: Colin Walters Date: Tue Jul 10 17:31:52 2012 -0400 build: Fix previous commit configure.ac | 1 + 1 file changed, 1 insertion(+) commit 1b26ec14e916296300126a82bf660913baf006a6 Author: Žygimantas Beručka Date: Tue Jul 10 18:50:47 2012 +0300 Updated Lithuanian translation po/lt.po | 2620 ++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 1623 insertions(+), 997 deletions(-) commit 484b35ec7721c62c313b4cc01eae153908ec4c60 Author: Giovanni Campagna Date: Thu Jun 14 22:55:58 2012 +0200 build: Don't check for gsettings-desktop-schemas in each panel It is already in the common modules, no need to repeat it. https://bugzilla.gnome.org/show_bug.cgi?id=658660 configure.ac | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) commit 80aac59a25f0deb59ae837ac29dd55abe9380745 Author: Kjartan Maraas Date: Mon Jul 9 14:55:01 2012 +0200 Updated Norwegian bokmĆ„l translation po/nb.po | 601 +++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 358 insertions(+), 243 deletions(-) commit 4eee8fab7c364565c7ebde7ab2a0da3cf237be3f Author: Nilamdyuti Goswami Date: Fri Jul 6 14:55:33 2012 +0530 Assamese translation reviewed po/as.po | 453 ++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 260 insertions(+), 193 deletions(-) commit 836755f593a3e31b6d22a0ef21e08937170970af Author: Olivier Fourdan Date: Thu Jul 5 18:27:56 2012 +0200 wacom: Update from gnome-settings-daemon panels/wacom/gsd-wacom-device.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) commit fcc40582482b37865c301065cbd73109b0dc9363 Author: Khaled Hosny Date: Thu Jul 5 16:52:24 2012 +0200 Updated Arabic translation po/ar.po | 202 +++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 111 insertions(+), 91 deletions(-) commit 3083fda606bce5ce09662a16911262b4f4958c81 Author: Olivier Fourdan Date: Tue Jul 3 13:59:08 2012 +0200 wacom: Destroy display mapping dialogue on unplug https://bugzilla.gnome.org/show_bug.cgi?id=679159 panels/wacom/cc-wacom-page.c | 7 +++++++ 1 file changed, 7 insertions(+) commit 13b64e04867a06468051c570467b22e57d237853 Author: Rui Matos Date: Tue Jul 3 15:25:46 2012 +0200 keyboard: Plug a GSettings object leak Also, rename the variable holding it since there are other 'settings' variables in the same file. https://bugzilla.gnome.org/show_bug.cgi?id=679328 panels/keyboard/keyboard-shortcuts.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) commit f2df6d7fbbb41cee78b94a7c2d3dc331168433b7 Author: Rico Tzschichholz Date: Tue Jul 3 13:54:38 2012 +0200 user-accounts: Fix build with -Werror=format-security panels/user-accounts/um-account-dialog.c | 2 +- panels/user-accounts/um-realm-manager.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) commit 1612735104832e90efd00b8ac4557679877dfe76 Author: Olivier Fourdan Date: Wed May 16 16:56:28 2012 +0200 wacom: apply display rotation to device When an output is mapped to a device, match the device rotation with the output (bug #676170) panels/wacom/cc-wacom-mapping-panel.c | 11 +++++++++++ panels/wacom/cc-wacom-page.c | 28 ++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) commit 62f34db3327dfeeaa7cc73bd1083169d6c0d78eb Author: Olivier Fourdan Date: Tue Jul 3 11:49:36 2012 +0200 wacom: Update from gnome-settings-daemon panels/wacom/gsd-wacom-device.c | 76 +++++++++++++++++++++++++++++++++++++++++ panels/wacom/gsd-wacom-device.h | 5 +++ 2 files changed, 81 insertions(+) commit b761b7d7c4f9cbdef9dea979d4892f6210675589 Author: Daniel Mustieles Date: Mon Jul 2 17:29:22 2012 +0200 Updated Spanish translation po/es.po | 151 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 77 insertions(+), 74 deletions(-) commit a46eff6f8ca2137330c3302caa2c6d8623e2e3dd Author: Nguyį»…n ThĆ”i Ngį»c Duy Date: Sun Jul 1 10:50:32 2012 +0700 Updated Vietnamese translation po/vi.po | 301 ++++++++++++++++++++++----------------------------------------- 1 file changed, 105 insertions(+), 196 deletions(-) commit 8444760f3a0e92d323a0024d7de7014595184bf0 Author: Nguyį»…n ThĆ”i Ngį»c Duy Date: Sun Jul 1 10:31:57 2012 +0700 po/vi: import from Damned Lies po/vi.po | 2344 +++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 1487 insertions(+), 857 deletions(-) commit a4d0923108412d602d9c32405b27b6edd2ef598d Author: Cheng-Chia Tseng Date: Sat Jun 30 23:04:53 2012 +0800 Updated Traditional Chinese translation(Hong Kong and Taiwan) po/zh_HK.po | 3899 ++++++++++++++++++++++++++++++++-------------------------- po/zh_TW.po | 3907 +++++++++++++++++++++++++++++++++-------------------------- 2 files changed, 4420 insertions(+), 3386 deletions(-) commit 75e74cc09b5965ff80f41c25458ff24b6e333891 Author: Matthias Clasen Date: Wed Jun 13 23:18:39 2012 -0400 network: Use g_clear_object where appropriate Signed-off-by: Richard Hughes panels/network/cc-network-panel.c | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) commit b154ebd1d639cb74ae98d2ba31a1eab3df9f1bc2 Author: Matthias Clasen Date: Wed Jun 13 23:20:53 2012 -0400 network: Remove redundant returns https://bugzilla.gnome.org/show_bug.cgi?id=678158 Signed-off-by: Richard Hughes panels/network/cc-network-panel.c | 2 -- 1 file changed, 2 deletions(-) commit 31cd509a7502a7df9c6236554a99e1b9abf6c4b2 Author: Matthias Clasen Date: Wed Jun 27 22:42:19 2012 -0400 network: Sort access points by strength Keep the active network at the top, and 'Other' at the bottom. the other access points are sorted by strength now. https://bugzilla.gnome.org/show_bug.cgi?id=678505 Signed-off-by: Richard Hughes panels/network/cc-network-panel.c | 54 +++++++++++++++++++++++++++++---------- panels/network/network.ui | 2 ++ 2 files changed, 42 insertions(+), 14 deletions(-) commit dcb34090cc5b258dcec19f88306d2119e4c57c29 Author: Matthias Clasen Date: Wed Jun 27 23:02:02 2012 -0400 network: avoid crashes due to leftover signal handlers The libnm objects can survive the disposal of the network panel. If we don't disconnect the signal handlers on them, bad things can happen. Use g_signal_connect_object to tie the life-cycle of the signal handlers to the panel. https://bugzilla.gnome.org/show_bug.cgi?id=677969 Signed-off-by: Richard Hughes panels/network/cc-network-panel.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) commit 6689012eb8881c548fbca52c2ac09c7511e7deae Author: Richard Hughes Date: Thu Jun 28 12:17:18 2012 +0100 network: Show multiple connections in the mobile broadband panel Resolves: https://bugzilla.gnome.org/show_bug.cgi?id=647170 panels/network/cc-network-panel.c | 137 ++++++++++++++++++++++++++++++++++++++ panels/network/network.ui | 40 +++++++++++ 2 files changed, 177 insertions(+) commit f0b88883d028f43deb09d21dcec95920d4f64b64 Author: Richard Hughes Date: Thu Jun 28 13:42:44 2012 +0100 network: Increase the amount of debugging for mobile-bb panels/network/cc-network-panel.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) commit 59b7500fb64e907fef101ef5607d721e04b0ebe2 Author: Richard Hughes Date: Thu Jun 28 13:41:29 2012 +0100 network: Don't try to show a wizard that failed to setup This fixes a critical warning when mobile-broadband-provider-info isn't installed into the correct prefix. panels/network/network-dialogs.c | 8 ++++++++ 1 file changed, 8 insertions(+) commit fd059a2d1447d6ec32f818dae7668933f2145848 Author: Richard Hughes Date: Thu Jun 28 13:40:08 2012 +0100 network: Don't try to set the mobile broadband speed widgets This fixes a critical warning when using mobile broadband adaptors. panels/network/cc-network-panel.c | 6 ------ 1 file changed, 6 deletions(-) commit fe69f4f1355ae7816d601bb11c155904d9dd86fe Author: David Henningsson Date: Fri Apr 27 11:15:52 2012 +0200 sound: Move running input streams when default source is changed When changing the default input source, active recording streams are not moved. This patch will fix that, which will make input and output behaviour consistent. As a bonus, it will not destroy pulseaudio's input database when changing default sink anymore. https://bugzilla.gnome.org/show_bug.cgi?id=674925 panels/sound/gvc-mixer-control.c | 58 +++++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 9 deletions(-) commit 49e3d8b4ce824e8c98bbf1d343055bac8df4ed87 Author: Bastien Nocera Date: Wed Jun 27 10:58:32 2012 +0100 wacom: Update from gnome-settings-daemon panels/wacom/gsd-wacom-device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 4cdaf4e022497334cfb28e828630f9c88534d4bd Author: Daniel Mustieles Date: Tue Jun 26 21:56:05 2012 +0200 Updated Spanish translation po/es.po | 73 +++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 42 insertions(+), 31 deletions(-) commit 953da26d6876ecf3da9fd1841df2bc5f08a0d774 Author: Bastien Nocera Date: Tue Jun 26 16:39:14 2012 +0100 3.5.4 NEWS | 7 +++++++ configure.ac | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) commit ba5aea5ef72d463eb92f434e68f2faa09bd86eb6 Author: Bastien Nocera Date: Tue Jun 26 16:33:45 2012 +0100 wacom: Update from gnome-settings-daemon panels/wacom/gsd-wacom-device.c | 66 +++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 32 deletions(-) commit 206e365eeac7165984f0dc8170cf6ed4ba44ab57 Author: Matej Urbančič Date: Tue Jun 26 09:13:13 2012 +0200 Updated Slovenian translation po/sl.po | 121 +++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 71 insertions(+), 50 deletions(-) commit cfa3aaed0fda99a8bfe3cb169e43992c2141560a Author: Bastien Nocera Date: Mon Jun 25 19:01:07 2012 +0100 3.5.3 NEWS | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) commit 0b029d61e3970e447718a0303455de40c5487068 Author: Noriko Mizumoto Date: Tue Jun 26 00:49:08 2012 +0900 [l10n] Update Japanese translation po/ja.po | 2403 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 1442 insertions(+), 961 deletions(-) commit 25708e9c8e395c465be8e9643127b3b43ef4ffb7 Author: Bastien Nocera Date: Mon Jun 25 16:35:41 2012 +0100 sound: Make sure the event sound stream stays unmuted Apply mute changes to the stream straight away so that we don't get a race with gvc_mixer_event_role_push_volume(). See https://bugs.freedesktop.org/show_bug.cgi?id=51413 for details. https://bugzilla.gnome.org/show_bug.cgi?id=677478 panels/sound/gvc-mixer-event-role.c | 4 ++++ 1 file changed, 4 insertions(+) commit 8138227ae3961cc6b39e17ddcb3465107970bbc3 Author: Debarshi Ray Date: Wed Jun 20 14:15:38 2012 +0200 online-accounts: Improve the layout when there is no configured account Use a GtkButton instead of a GtkLabel to incite the user to configure a new account, and insensitize the GtkBox on the left. Fixes: https://bugzilla.gnome.org/672421 panels/online-accounts/cc-online-accounts-panel.c | 49 ++++++++++++- panels/online-accounts/online-accounts.ui | 84 +++++++++++++++++++---- 2 files changed, 115 insertions(+), 18 deletions(-) commit bb531687ca957072470a5851c499993fe056ea85 Author: Matthias Clasen Date: Mon Mar 19 22:11:00 2012 +0000 sound: Fix mouse scrolls on sliders Use gdk_event_get_scroll_deltas() to get the scroll direction. https://bugzilla.gnome.org/show_bug.cgi?id=671724 panels/sound/gvc-balance-bar.c | 43 +++++++++++++++++++++++++---------- panels/sound/gvc-channel-bar.c | 42 ++++++++++++++++++++++++++-------- panels/sound/gvc-channel-bar.h | 4 ++-- panels/sound/gvc-stream-status-icon.c | 2 +- 4 files changed, 66 insertions(+), 25 deletions(-) commit 75cc274a3b62011958f749eb52be4b977ea152e7 Author: Bastien Nocera Date: Mon Jun 25 13:33:04 2012 +0100 sound: Fix use of deprecated gtk_vscale_new() panels/sound/gvc-channel-bar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 9859ffbc27aca0a4f1a58412233498cdf846da70 Author: Bastien Nocera Date: Mon Jun 25 13:32:36 2012 +0100 sound: Remove left-click behaviour work-around https://bugzilla.gnome.org/show_bug.cgi?id=678598 panels/sound/gvc-channel-bar.c | 12 ------------ 1 file changed, 12 deletions(-) commit dd2e8ed5676b2045497e25247049c57b2ddba4d9 Author: Fran DiĆ©guez Date: Sun Jun 24 22:44:38 2012 +0200 Updated Galician translations po/gl.po | 353 ++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 192 insertions(+), 161 deletions(-) commit a5aeae889963216dac91ca8867e9cea2f67c13b8 Author: Wylmer Wang Date: Sat Jun 23 17:09:05 2012 +0800 update Simplified Chinese (zh_CN) translation po/zh_CN.po | 2140 +++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 1345 insertions(+), 795 deletions(-) commit 973adfa43b953fd52063404224952b4c55ea98b6 Author: Stef Walter Date: Thu Jun 14 17:10:31 2012 +0200 user-accounts: Update the realmd dbus interface to latest The changes in the realmd dbus interface are futureproofing to support cancellation. In addition during this time of interface flux, check the daemon version number to make sure we can talk to it. https://bugzilla.gnome.org/show_bug.cgi?id=678105 .../user-accounts/data/org.freedesktop.realmd.xml | 23 +++++++++ panels/user-accounts/um-account-dialog.c | 2 +- panels/user-accounts/um-realm-manager.c | 55 ++++++++++++++++++++-- 3 files changed, 76 insertions(+), 4 deletions(-) commit 7ed7628ba6a6f6934b8e93a97e6f20e8ba876462 Author: Gabor Kelemen Date: Thu Jun 21 22:35:42 2012 +0200 Insert soft hyphen characters into long panel names po/hu.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) commit 0f4f7b797dfdcf9a88bbdcc0b1d5839487008f7e Author: Khaled Hosny Date: Thu Jun 21 21:32:11 2012 +0200 Updated Arabic translation po/ar.po | 118 ++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 64 insertions(+), 54 deletions(-) commit c920ba6d4f7ce56d2e240929278f46ddd791b54a Author: Debarshi Ray Date: Wed Jun 20 15:35:45 2012 +0200 online-accounts: The treeview should be in BROWSE mode and not SINGLE This ensures that if there are configured accounts, then atleast one of them will stay selected. Fixes: https://bugzilla.gnome.org/672421 panels/online-accounts/online-accounts.ui | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) commit 03ccd9d7806b350e36a5c9bc70edf5a3c8f5169c Author: Daniel Mustieles Date: Thu Jun 21 12:30:37 2012 +0200 Updated Spanish translation po/es.po | 118 +++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 66 insertions(+), 52 deletions(-) commit 4db702151377804043ca6b71184096d4441bf6e3 Author: Bastien Nocera Date: Thu Jun 21 10:36:08 2012 +0100 shell: Fix search results not appearing Introduced in commit d382c42e5ce9b834456b8cda80bddea65b0639c1 by some overeager code removal. https://bugzilla.gnome.org/show_bug.cgi?id=678514 shell/cinnamon-control-center.c | 1 + 1 file changed, 1 insertion(+) commit fd3afa8d4f64d942f2da42fde7504dbd519a2ce1 Author: Jasper St. Pierre Date: Tue Jun 12 17:53:08 2012 -0400 shell: Handle non-existant panels more gracefully If we're at the overview screen and try to launch a non-existant panel, we shouldn't remove the scroll view. https://bugzilla.gnome.org/show_bug.cgi?id=677980 shell/cinnamon-control-center.c | 40 +++++++++++++++------------------------- 1 file changed, 15 insertions(+), 25 deletions(-) commit 8c9a1eec336f9687aff079f6322b12bfc550f852 Author: Matthias Clasen Date: Tue Jun 12 15:22:33 2012 -0400 Be robust against extraneous signal emissions It seems that we are occasionally get duplicate ClutterTimeline::completed emissions. Make the code robust against that. https://bugzilla.gnome.org/show_bug.cgi?id=677946 shell/cc-notebook.c | 1 + 1 file changed, 1 insertion(+) commit 651431dd839702f36c46a8dfe0702471b9b3b145 Author: Debarshi Ray Date: Mon Apr 16 20:22:42 2012 +0200 online-accounts: We might have an object even when the error is set Fixes: https://bugzilla.gnome.org/674165 panels/online-accounts/cc-online-accounts-panel.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) commit 6339c1819a2ae81c831b5d22ba2a431b2af49657 Author: Bastien Nocera Date: Wed Jun 20 13:28:22 2012 +0100 wacom: Bump required gnome-desktop version As needed for gnome_rr_output_get_ids_from_edid() configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 4f935ad4bdc59692239fb023fb8723fd7a5bf629 Author: Luca Ferretti Date: Thu May 31 00:33:11 2012 +0200 backgrounds: add translation context for background sytles panels/background/background.ui | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) commit 9d002d98fdd338593dc08718f62932327d81e5a2 Author: Luca Ferretti Date: Thu May 31 00:32:02 2012 +0200 universal-access: add translator context for Zoom label panels/universal-access/uap.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 22ea414271a6037d4c14ca16602e73367b1a5be3 Author: Olivier Fourdan Date: Tue Jun 19 15:42:45 2012 +0200 wacom: Update from gnome-settings-daemon panels/wacom/gsd-wacom-device.c | 294 +++++++++++++++++++++++----------------- panels/wacom/gsd-wacom-device.h | 1 + 2 files changed, 172 insertions(+), 123 deletions(-) commit 4bbd27ad257a58fbcdb4bf011975350de6be2b22 Author: Sasi Bhushan Boddepalli Date: Tue Jun 19 18:00:03 2012 +0530 Updated Telugu Translation po/te.po | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) commit dd10dac5b3a9aa6c6d18ef5adf391aa47b1ee838 Author: A S Alam Date: Tue Jun 19 07:41:19 2012 +0530 Update Punjabi Translation po/pa.po | 553 +++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 328 insertions(+), 225 deletions(-) commit 9be10b2f6419deb8ccf8beff5da76125e2998690 Author: Matej Urbančič Date: Mon Jun 18 21:08:52 2012 +0200 Updated Slovenian translation po/sl.po | 843 ++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 487 insertions(+), 356 deletions(-) commit 9386e13aa8009b7beec1418de2791acd5e41c289 Author: Daniel Mustieles Date: Mon Jun 18 14:04:52 2012 +0200 Updated Spanish translation po/es.po | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) commit 806b3e0e13ec63edeb5f635e67dc5a2cd798bd62 Author: Thomas Bechtold Date: Tue Jun 12 00:56:37 2012 +0200 network: Find connections specific MAC address set Resolves: https://bugzilla.gnome.org/show_bug.cgi?id=677899 Signed-off-by: Richard Hughes panels/network/cc-network-panel.c | 180 ++++++++++++++++++++++++++++++++------ 1 file changed, 154 insertions(+), 26 deletions(-) commit e9288acf1c4954dd7cf2f8ac4865a145d426085f Author: Bastien Nocera Date: Mon Jun 18 11:04:19 2012 +0100 sound: Add audio keyword https://bugzilla.gnome.org/show_bug.cgi?id=678303 panels/sound/data/gnome-sound-panel.desktop.in.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit a94f98985130cd61c3ba0d7ef896ea8bb7bf4cb5 Author: Khaled Hosny Date: Sun Jun 17 13:24:33 2012 +0200 Updated Arabic translation po/ar.po | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) commit 43cf067cf2fedc4b0a29a5796bde915c3a708d5f Author: Stef Walter Date: Fri Jun 15 18:45:41 2012 +0200 user-accounts: Use the symbolic error icon in entries Use the symbolic error icon when entries as indication when entries don't validate. https://bugzilla.gnome.org/show_bug.cgi?id=678178 panels/user-accounts/um-utils.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) commit a9ebbaa4a89e155ea92ab4cd8a95b32bb0bf8b60 Author: Matthias Clasen Date: Fri Jun 15 07:40:56 2012 -0400 users: Set the right toolbar-style on the inline toolbar While running in a bare X server, I noticed the inline toolbar here showing its labels, while all the other inline toolbars in other panels stayed nice and icon-only. The reason is that they explicitly set the toolbar-style to 'icons'. Do the same here. https://bugzilla.gnome.org/show_bug.cgi?id=678157 panels/user-accounts/data/user-accounts-dialog.ui | 1 + 1 file changed, 1 insertion(+) commit 27e8c650af5b3e7a8eab73242939cf7be854ccdc Author: Piotr Drąg Date: Fri Jun 15 20:00:12 2012 +0200 Updated POTFILES.in po/POTFILES.in | 1 + 1 file changed, 1 insertion(+) commit dd9493821cea68e9607eb1220c0785e30ff071b4 Author: Matthias Clasen Date: Fri Jun 15 11:40:27 2012 -0400 screen: Fix the build Move the on_signal callback below the functions that it is using. panels/screen/cc-screen-panel.c | 54 ++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 27 deletions(-) commit a1abae0375cb24e27e6cee055ab55ae170b99ee1 Author: Cosimo Cecchi Date: Fri Jun 15 11:04:11 2012 -0400 online-accounts: make "Add Account" label bigger and centered So it's consistent with the User Accounts panel. https://bugzilla.gnome.org/show_bug.cgi?id=678174 panels/online-accounts/cc-online-accounts-add-account-dialog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit b40c1fb2cfcfe70f7c84d7c825d99f7cb4c23f00 Author: Cosimo Cecchi Date: Fri Jun 15 11:01:52 2012 -0400 online-accounts: fix alignment with closing button https://bugzilla.gnome.org/show_bug.cgi?id=678174 .../cc-online-accounts-add-account-dialog.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) commit 99047ec0f5db72e1d6fa3d8fc6844b555d23413b Author: Cosimo Cecchi Date: Fri Jun 15 10:37:10 2012 -0400 user-accounts: fix right alignment of controls with actions The controls are not perfectly right-aligned with the action buttons at the bottom; this is because the action area has a border of 6px and the control box of 10px. Fix it, and at the same time add another 6px of spacing at the bottom between the control box and the action box. https://bugzilla.gnome.org/show_bug.cgi?id=678173 panels/user-accounts/data/account-dialog.ui | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) commit 2e2ad76e59866ff616640ca7ab6b1b5f47646c9e Author: Cosimo Cecchi Date: Fri Jun 15 10:22:14 2012 -0400 region: Input Sources tab has a different spacing The first two tabs have 12px, make this 12px too. https://bugzilla.gnome.org/show_bug.cgi?id=678168 panels/region/gnome-region-panel.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 7ab09177e12b6041ca9a681c0739ffa40b6e1f57 Author: Giovanni Campagna Date: Fri Jun 8 23:01:10 2012 +0200 screen: Fix for gnome-settings-daemon changes g-s-d changed its DBus interface, and that made all external changes to brightness invisible to the panel. Update accordingly. https://bugzilla.gnome.org/show_bug.cgi?id=662117 panels/screen/cc-screen-panel.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) commit c8e9d70679f8a311fbf4a0a5da51006a89d2decb Author: Khaled Hosny Date: Fri Jun 15 12:56:46 2012 +0200 Updated Arabic translation po/ar.po | 325 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 164 insertions(+), 161 deletions(-) commit 59661162bd016bae52435028be66fb5f425f8091 Author: Daniel Mustieles Date: Fri Jun 15 12:10:40 2012 +0200 Updated Spanish translation po/es.po | 96 +++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 52 insertions(+), 44 deletions(-) commit a70e50f268cd70c3f504d0ec6cbc905a4af34931 Author: Stef Walter Date: Thu Jun 14 14:22:18 2012 +0200 user-accounts: Combine realmd permissions into panel unlock Create a new policy file for the admin actions of the user accounts panel, combining the relevant actions of accountsservice and realmd. https://bugzilla.gnome.org/show_bug.cgi?id=678098 panels/user-accounts/Makefile.am | 11 +++++++++++ .../org.gnome.controlcenter.user-accounts.policy.in | 21 +++++++++++++++++++++ panels/user-accounts/um-user-panel.c | 2 +- 3 files changed, 33 insertions(+), 1 deletion(-) commit ea048cce8a0d49e24ff97942acaba47dc89396bf Author: Cosimo Cecchi Date: Thu Jun 14 11:12:30 2012 -0400 user-accounts: avoid horizontal resizing when switching local/enterprise Pack labels and controls in horizontal size groups, so we don't resize the dialog horizontally when switching between the local and enterprise pages. https://bugzilla.gnome.org/show_bug.cgi?id=678104 panels/user-accounts/data/account-dialog.ui | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) commit 6e8ddbaeeadfb02c924eae58ab8965adb0eee2f1 Author: Sebastien Bacher Date: Mon Mar 5 13:47:46 2012 +0100 info: Add software media to "other media" dialogue https://bugzilla.gnome.org/show_bug.cgi?id=671358 panels/info/cc-info-panel.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) commit cb359701923296502bc38cc4102607485b3a42a5 Author: Sebastien Bacher Date: Mon Mar 5 16:16:56 2012 +0100 info: Add title for the "other media" dialog https://bugzilla.gnome.org/show_bug.cgi?id=671374 panels/info/cc-info-panel.c | 1 + 1 file changed, 1 insertion(+) commit 978aa81a2c2ab18f2f3cbc79ea4dd30e91e9c867 Author: Olivier Fourdan Date: Thu May 3 14:04:20 2012 +0200 wacom: Cancel calibration if window loses focus Make the calibrator window stay above other windows and cancel calibration if/when the calibrator loses input focus. https://bugzilla.gnome.org/show_bug.cgi?id=675354 panels/wacom/calibrator/gui_gtk.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) commit 46186a5f0227602ae0af1103ef1927926b794328 Author: Jon McCann Date: Wed Mar 28 15:10:32 2012 -0400 background: Escape wallpaper filename before display https://bugzilla.gnome.org/show_bug.cgi?id=673015 panels/background/cc-background-panel.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) commit 38d693b1c8c3a8245f339d14961432c6073f4191 Author: Daniel Mustieles Date: Thu Jun 14 13:48:46 2012 +0200 Updated Spanish translation po/es.po | 160 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 81 insertions(+), 79 deletions(-) commit 4a76728978cc36f131db09d71ab62121196eca25 Author: Stef Walter Date: Tue Jun 12 17:17:46 2012 +0200 user-accounts: Set high DBus timeouts for managing realms Enrolling the machine, or discovering realms can take a long time. We don't want DBus timeouts. https://bugzilla.gnome.org/show_bug.cgi?id=677953 panels/user-accounts/um-realm-manager.c | 2 ++ 1 file changed, 2 insertions(+) commit f6838df0c5a5702362b90ed781dbdf581b49b45d Author: Matthias Clasen Date: Wed Jun 13 22:28:46 2012 -0400 network: Make buttons stay put When switching between devices, the Options buttons were jumping up and down. This patch makes them stay put in the lower right corner. The patch also removes a bunch of glade placeholder gunk from the ui file. https://bugzilla.gnome.org/show_bug.cgi?id=677054 Signed-off-by: Richard Hughes panels/network/network.ui | 43 +++++++++++-------------------------------- 1 file changed, 11 insertions(+), 32 deletions(-) commit 9efba451dc8f3de47669251b12996b084b157cb8 Author: Matthias Clasen Date: Wed Jun 13 21:53:12 2012 -0400 network: Make ap list more similar to the shell menu Sort the strength and security indicators in the combo box popup to be in the same order as the shell menu. https://bugzilla.gnome.org/show_bug.cgi?id=677788 Signed-off-by: Richard Hughes panels/network/cc-network-panel.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) commit 398ca18a71e2f8e7c85c071bbc1d9c2e630b10f4 Author: Matthias Clasen Date: Wed Jun 13 22:01:04 2012 -0400 network: Sort Wireless first This is the most common case, and is the page we want to end up on when we're coming from the shell menu. https://bugzilla.gnome.org/show_bug.cgi?id=677791 Signed-off-by: Richard Hughes panels/network/panel-common.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) commit df77ca0883e965c25c1f5623bb4c9f8d9ef0508d Author: Matthias Clasen Date: Wed Jun 13 22:47:29 2012 -0400 network: Add mnemonic for Airplane mode This was lost when the airplane mode switch moved up to the top. https://bugzilla.gnome.org/show_bug.cgi?id=671879 Signed-off-by: Richard Hughes panels/network/cc-network-panel.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) commit 22fd0deddae9f997ef9660ed54ab4fb3cec060eb Author: Matthias Clasen Date: Wed Jun 13 22:46:59 2012 -0400 network: Add mnemonics The Create dialog was missing mnemonics for several controls. https://bugzilla.gnome.org/show_bug.cgi?id=671879 Signed-off-by: Richard Hughes panels/network/network.ui | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) commit fd8ca81f8b39b90a65f071c1bbbf6fae310270a3 Author: Matthias Clasen Date: Wed Jun 13 22:56:04 2012 -0400 network: Add a mnemonic for 'Forget Network' https://bugzilla.gnome.org/show_bug.cgi?id=671879 Signed-off-by: Richard Hughes panels/network/network.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit d66e2be977ae9f6cd373e1172c3e1f19a599ad8e Author: Fran DiĆ©guez Date: Thu Jun 14 01:00:35 2012 +0200 Updated Galician translations po/gl.po | 341 +++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 211 insertions(+), 130 deletions(-) commit a43eef3ebb33a637851a8b1a7f6afd670642ee1c Author: Nilamdyuti Goswami Date: Wed Jun 13 19:05:56 2012 +0530 Assamese translation reviewed po/as.po | 2750 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 1355 insertions(+), 1395 deletions(-) commit 2589fcfb19683c9d02da835deab9d4a1c45c2c4e Author: Stef Walter Date: Tue Jun 12 17:17:01 2012 +0200 user-accounts: Properly fill the join prompt dialog When prompting users for administrative domain credentials, correctly fill the dialog the first time the prompt is shown. https://bugzilla.gnome.org/show_bug.cgi?id=677954 panels/user-accounts/um-account-dialog.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) commit e6b49fa28dd2e9fd8699fc58fb5545194a1bc982 Author: Daniel Mustieles Date: Wed Jun 13 10:08:59 2012 +0200 Updated Spanish translation po/es.po | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) commit 4511182439fbb31ad47e6521ab071abbcb7be831 Author: Khaled Hosny Date: Tue Jun 12 23:35:38 2012 +0200 Updated Arabic translation po/ar.po | 1905 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 1155 insertions(+), 750 deletions(-) commit c619f0bb7949bea8c9e18a8089e0d2a6ff0b94f0 Author: Piotr Drąg Date: Tue Jun 12 21:33:24 2012 +0200 Updated POTFILES.in po/POTFILES.in | 1 + 1 file changed, 1 insertion(+) commit d382c42e5ce9b834456b8cda80bddea65b0639c1 Author: Jasper St. Pierre Date: Tue Jun 12 13:57:43 2012 -0400 shell: Remove reparenting hacks Now that CcNotebook is buildable, we don't need to do these ugly hacks. shell/cinnamon-control-center.c | 14 -------------- 1 file changed, 14 deletions(-) commit f8da96e4259ac331c69587aec26f8c777ed4111b Author: Jasper St. Pierre Date: Tue Jun 12 13:57:19 2012 -0400 shell: Make CcNotebook buildable shell/cc-notebook.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) commit 54d24f0574c1ada8eb3ec6d48cb2b9990cb12950 Author: Jasper St. Pierre Date: Tue Jun 12 13:43:45 2012 -0400 shell: Remove unnecessary tabs shell/shell.ui | 6 ------ 1 file changed, 6 deletions(-) commit 5d228b707a4ef559b9e739baf574955bb812a043 Author: Jasper St. Pierre Date: Tue Jun 12 18:27:02 2012 +0100 shell: Fix wrong function being used to get width get width better than get height... shell/cc-notebook.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 7d7fc2e12453f85f0a0f90a77b6f01d89fb4bf4c Author: Bastien Nocera Date: Tue Jun 12 18:16:36 2012 +0100 shell: Fix possible crashers when there are no pages Wouldn't happen in cinnamon-control-center. Spotted by Jasper St. Pierre shell/cc-notebook.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) commit 94033718af8d7458e50a10cf26c01c09b546deee Author: Daniel Mustieles Date: Tue Jun 12 18:31:29 2012 +0200 Updated Spanish translation po/es.po | 271 +++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 175 insertions(+), 96 deletions(-) commit b9e356412fad645fc55f4790f2022ef192bd1a8a Author: Bastien Nocera Date: Tue Jun 12 14:03:25 2012 +0100 power: Fix reference to "Screen" settings This also fixes the use of a split string, as mentioned in bug #675929. https://bugzilla.gnome.org/show_bug.cgi?id=670567 panels/power/cc-power-panel.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) commit 4bb0739670e1b44eb53ad1b1568c17e78cf6c3ce Author: Stef Walter Date: Thu Jun 7 00:58:27 2012 +0200 user-accounts: Implement enterprise logins in add dialog * Use realmd for domain joining and lookup, runtime dependency * Validate join domain correctly * Add UmRealmManager for handling some stuff above the autogenerated realmd dbus code * Show a dialog if the user's credentials cannot be used to join the domain. Prompt for admin creds. * Register the user's login with the AccountsService * This depends on the CacheUser() method of AccountsService https://bugzilla.gnome.org/show_bug.cgi?id=677548 configure.ac | 17 + panels/user-accounts/Makefile.am | 19 +- panels/user-accounts/data/Makefile.am | 1 + panels/user-accounts/data/account-dialog.ui | 359 +++++++++- .../user-accounts/data/org.freedesktop.realmd.xml | 145 ++++ panels/user-accounts/um-account-dialog.c | 591 +++++++++++++++- panels/user-accounts/um-realm-manager.c | 765 +++++++++++++++++++++ panels/user-accounts/um-realm-manager.h | 91 +++ 8 files changed, 1968 insertions(+), 20 deletions(-) commit 06233ebba84913a8f3ace64b0b52c659648a638c Author: Stef Walter Date: Thu May 31 17:06:42 2012 +0200 user-accounts: Add um_user_manager_cache_user() This calls the AccountsService.CacheUser() method to register a user that's not in /etc/passwd Depends on: https://bugs.freedesktop.org/show_bug.cgi?id=50770 https://bugzilla.gnome.org/show_bug.cgi?id=677548 panels/user-accounts/um-user-manager.c | 68 +++++++++++++++++++++++++++++++--- panels/user-accounts/um-user-manager.h | 10 +++++ 2 files changed, 73 insertions(+), 5 deletions(-) commit 228347e713103d052c79c09cc9f76ef83fe6e97d Author: Stef Walter Date: Thu Jun 7 00:20:29 2012 +0200 user-accounts: Add way to change modes Add the buttons to switch between the local account and enterprise modes. The enterprise area just has a place holder widget for now. https://bugzilla.gnome.org/show_bug.cgi?id=677548 panels/user-accounts/data/account-dialog.ui | 82 ++++++++++++++++ panels/user-accounts/um-account-dialog.c | 147 +++++++++++++++++++++++++++- 2 files changed, 227 insertions(+), 2 deletions(-) commit 3a7ee1bff932edc420640fd0e2cdd3297c820ce9 Author: Stef Walter Date: Wed Jun 6 23:40:32 2012 +0200 user-accounts: Cleaner validation and validate on open Clean up the validation so we can plug in the enterprise login stuff. https://bugzilla.gnome.org/show_bug.cgi?id=677548 panels/user-accounts/um-account-dialog.c | 81 ++++++++++++++++---------------- 1 file changed, 41 insertions(+), 40 deletions(-) commit 67066255bae8f49755b3cabc5b40c7018a53f3c7 Author: Stef Walter Date: Wed Jun 6 23:32:31 2012 +0200 user-accounts: Separate local account stuff in accounts dialog Separate the local account stuff a bit so when the enterprise stuff comes in it's still readable. https://bugzilla.gnome.org/show_bug.cgi?id=677548 panels/user-accounts/data/account-dialog.ui | 14 ++-- panels/user-accounts/um-account-dialog.c | 102 ++++++++++++++++------------ 2 files changed, 66 insertions(+), 50 deletions(-) commit fd4f3cc9ce845fc23dbf1200d8ec18102464149a Author: Stef Walter Date: Wed Jun 6 23:20:42 2012 +0200 user-accounts: Port account dialog to GtkGrid Some spacing issues will be sorted in a later commit. https://bugzilla.gnome.org/show_bug.cgi?id=677548 panels/user-accounts/data/account-dialog.ui | 121 +++++++++------------------- 1 file changed, 37 insertions(+), 84 deletions(-) commit 2e0623e7d560120d8084536dbe6d5c6f7d691990 Author: Stef Walter Date: Wed Jun 6 23:10:53 2012 +0200 user-accounts: Title of accounts dialog becomes "Add Account" This title makes sense for both remote and local users. In the case of remote users we're not creating accounts, we're just adding them to the system. https://bugzilla.gnome.org/show_bug.cgi?id=677548 panels/user-accounts/data/account-dialog.ui | 2 +- panels/user-accounts/um-account-dialog.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) commit b09cd23d85a5c0467436580bd7877568d365af20 Author: Stef Walter Date: Wed Jun 6 23:08:22 2012 +0200 user-accounts: Add test tool frob-account-dialog A simple tool to show the add account dialog for quick iterations testing of the 'enterprise login' functionality. https://bugzilla.gnome.org/show_bug.cgi?id=677548 panels/user-accounts/Makefile.am | 20 ++++++++++ panels/user-accounts/frob-account-dialog.c | 61 ++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) commit 2a545187dab163a40a9a5b6add1af72af34b371e Author: Stef Walter Date: Wed Jun 6 23:06:05 2012 +0200 user-accounts: Show a spinner during account dialog actions During actions which can run a long time show a spinner indicating that something is going on. https://bugzilla.gnome.org/show_bug.cgi?id=677548 panels/user-accounts/um-account-dialog.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) commit 2e228b99926a199489a664178e034714864770af Author: Stef Walter Date: Wed Jun 6 22:51:19 2012 +0200 user-accounts: Cleaner interaction with UmAccountDialog actions More clear scoping and interaction with running actions in UmAccountDialog. In later 'enterprise login' patches we have long running actions that's why this needs cleaning up. In particular: * Show errors as children of the dialog. * Errors don't make the account dialog go away, user can correct problems. * Use more standard GAsyncResult style callbacks: um_account_dialog_perform() um_account_dialog_finish() * Disable controls while the operation is happening. * Allow the user to cancel long actions in UmAccountDialog by pressing the cancel button. https://bugzilla.gnome.org/show_bug.cgi?id=677548 panels/user-accounts/um-account-dialog.c | 157 ++++++++++++++++++++++++------- panels/user-accounts/um-account-dialog.h | 8 +- panels/user-accounts/um-user-manager.c | 3 +- panels/user-accounts/um-user-manager.h | 1 + panels/user-accounts/um-user-panel.c | 14 ++- 5 files changed, 142 insertions(+), 41 deletions(-) commit 61eadc3fe372a27bd7d464d7ead55443fbff1d90 Author: Stef Walter Date: Tue Jun 12 10:56:09 2012 +0200 user-accounts: Fix memory leak in create_user_done() g_dbus_error_get_remote_error() returns an allocated string https://bugzilla.gnome.org/show_bug.cgi?id=677930 panels/user-accounts/um-user-manager.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) commit 5fbce5f8daddb72cf08341e6f729c0d51413d702 Author: Stef Walter Date: Tue Jun 12 10:35:45 2012 +0200 user-accounts: UmAccountDialog shouldn't be valid when shown The user needs to enter some data before the dialog's 'Create' button can be clicked. https://bugzilla.gnome.org/show_bug.cgi?id=677928 panels/user-accounts/um-account-dialog.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) commit 5b022773b35537c6ce5b2e8d7ab3ba00f33387e8 Author: Stef Walter Date: Wed Jun 6 23:28:05 2012 +0200 user-accounts: Fix memory leak of GtkBuilder in accounts dialog https://bugzilla.gnome.org/show_bug.cgi?id=677548 panels/user-accounts/um-account-dialog.c | 2 ++ 1 file changed, 2 insertions(+) commit 195e0137b2ac9b7d03dbe15396d60bd767d3d4ed Author: Stef Walter Date: Wed Jun 6 22:28:44 2012 +0200 user-accounts: Don't refer to UmAccountDialog as um It's confusing to read; it reads as 'user manager'. Since this is a GObject, just use self as customary. Most of these lines change in later commits anyway, so this won't really pollute the 'git blame' https://bugzilla.gnome.org/show_bug.cgi?id=677548 panels/user-accounts/um-account-dialog.c | 86 ++++++++++++++++---------------- panels/user-accounts/um-account-dialog.h | 2 +- 2 files changed, 44 insertions(+), 44 deletions(-) commit 6aff0f9a8600de1303a56484b774151ff6207fac Author: Stef Walter Date: Wed Jun 6 21:43:57 2012 +0200 user-accounts: Make UmAccountDialog a GtkDialog The dialog will get much more complex due to 'enterprise login' work and we want a proper object here. https://bugzilla.gnome.org/show_bug.cgi?id=677548 panels/user-accounts/data/account-dialog.ui | 69 +----------------- panels/user-accounts/um-account-dialog.c | 107 ++++++++++++++++++---------- panels/user-accounts/um-account-dialog.h | 7 +- panels/user-accounts/um-user-panel.c | 2 +- 4 files changed, 76 insertions(+), 109 deletions(-) commit a5dc2b80cc13c57a6a7eff181603c00e44d688ff Author: Stef Walter Date: Wed Jun 6 20:43:07 2012 +0200 user-accounts: Remove unused MAXNAMELEN definition https://bugzilla.gnome.org/show_bug.cgi?id=677548 panels/user-accounts/um-account-dialog.c | 2 -- 1 file changed, 2 deletions(-) commit 6004616bbc049bf4612a1342c3a0f10768c3ce44 Author: Kjartan Maraas Date: Mon Jun 11 22:08:55 2012 +0200 Updated Norwegian bokmĆ„l translation po/nb.po | 263 +++++++++++++++++++++++++++++---------------------------------- 1 file changed, 123 insertions(+), 140 deletions(-) commit 42c65b5c5fee5830b31fd30370c1b8209ba71eca Author: Bastien Nocera Date: Mon Jun 11 15:42:55 2012 +0100 shell: Use GtkSearchEntry And require GTK+ 3.3.5 for it. configure.ac | 2 +- shell/cinnamon-control-center.c | 19 ------------------- shell/shell.ui | 2 +- 3 files changed, 2 insertions(+), 21 deletions(-) commit 786a36db1f5ccc54b1675951a16e1d2b88400023 Author: Olivier Fourdan Date: Fri May 11 14:16:39 2012 +0200 wacom: Add keep aspect ratio option Adjust tablet area to match the aspect ratio of the output assigned to the tablet. https://bugzilla.gnome.org/show_bug.cgi?id=668907 panels/wacom/cc-wacom-mapping-panel.c | 53 ++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 7 deletions(-) commit cde88dca907311164c317e394edea54c2c13fee1 Author: Cosimo Cecchi Date: Wed May 30 09:34:37 2012 -0400 network: fix packing order of children in the service dialog The heading should be packed at the top, before the combobox. https://bugzilla.gnome.org/show_bug.cgi?id=674498 panels/network/network.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 94a46524b5078c2723e4394634d7bb39dfe6679c Author: Bastien Nocera Date: Mon Jun 11 14:26:57 2012 +0100 shell: Don't animate between overview and search pages shell/cinnamon-control-center.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) commit 0fdecb67c3709df7e9fb626c707946c4874c049e Author: Bastien Nocera Date: Mon Jun 11 14:26:45 2012 +0100 shell: Update test-notebook for API change shell/test-notebook.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 56bd29ebf3f49b8e53d37817ba6ca99b82fb7e66 Author: Bastien Nocera Date: Mon Jun 11 14:26:20 2012 +0100 shell: Make it possible to not animate transitions In CcNotebook. shell/cc-notebook.c | 20 +++++++++++++------- shell/cc-notebook.h | 3 ++- 2 files changed, 15 insertions(+), 8 deletions(-) commit 761f5f0b8bc9c6794f5df51041bfa404abec6b4c Author: Cosimo Cecchi Date: Mon Jun 11 08:59:09 2012 -0400 background: always pass a cancellable down to I/O operations So they will be properly cancelled when the panel is disposed. Also, check early if the operation was cancelled, since it's not safe to assume the data of the callback is valid anymore before that point. https://bugzilla.gnome.org/show_bug.cgi?id=672572 panels/background/bg-pictures-source.c | 50 +++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 19 deletions(-) commit 6c140396e6dafaa20fc33b0a79251495d86ebf5f Author: FrĆ©dĆ©ric PĆ©ters Date: Sun Jun 10 14:13:22 2012 +0200 configure: bump gnome-settings-daemon required version This is required to get the input-sources schema used by the Region panel https://bugzilla.gnome.org/show_bug.cgi?id=677807 configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 042b237f821d3447d69eaae6f5c7e8f4cd2bdd7b Author: Ihar Hrachyshka Date: Fri Jun 8 18:42:03 2012 +0300 Updated Belarusian translation. po/be.po | 1690 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 955 insertions(+), 735 deletions(-) commit 8631717b3d1cb85bf21b0e0d648b784e8e7c3f8f Author: Dan Williams Date: Fri Apr 20 11:48:17 2012 -0500 network: don't crash on hidden SSIDs APs that don't broadcast their SSID will return NULL from nm_access_point_get_ssid() (since that's easier to check in C using an if statement than returning a zero-length GByteArray). Thus the code shouldn't try to dereference the SSID byte array since it could be NULL. But in fact, the panel shouldn't be showing hidden APs anywhere in the UI, since the user needs to manually enter the SSID to connect to it anyway. So just ignore hidden APs like nm-applet does. Signed-off-by: Dan Williams Signed-off-by: Richard Hughes panels/network/cc-network-panel.c | 6 ++++++ 1 file changed, 6 insertions(+) commit c908531feb49f24e490d23c57955ed6473d7dbef Author: Daniel Mustieles Date: Thu Jun 7 12:27:48 2012 +0200 Updated Spanish translation po/es.po | 93 +++++++++++++++++++++++++++++----------------------------------- 1 file changed, 42 insertions(+), 51 deletions(-) commit f7245a39b795ddd1e6b819cdceb6ea9bdc5c1c9d Author: A S Alam Date: Thu Jun 7 07:29:30 2012 +0530 Update Punjabi Translation po/pa.po | 563 ++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 307 insertions(+), 256 deletions(-) commit 469c8b3be8de563ec09a99c8ce8f6c04f58dbd7f Author: Piotr Drąg Date: Wed Jun 6 21:22:00 2012 +0200 Updated POTFILES.in po/POTFILES.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 1261d73821529d5b789956fb2d1b69a8003f49ce Author: Bastien Nocera Date: Wed Jun 6 17:44:57 2012 +0100 mouse: Use '&' instead of 'and' Using "&" not only keeps the names shorter but would also keeps the user focused on the other words which compose the name. https://bugzilla.gnome.org/show_bug.cgi?id=676562 panels/mouse/gnome-mouse-panel.desktop.in.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit d07be14ba05b6110c5b4f1470bfda58504b84d5b Author: Bastien Nocera Date: Wed Jun 6 17:44:49 2012 +0100 region: Use '&' instead of 'and' Using "&" not only keeps the names shorter but would also keeps the user focused on the other words which compose the name. https://bugzilla.gnome.org/show_bug.cgi?id=676562 panels/region/gnome-region-panel.desktop.in.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 8aca1c2090c2e02a376458f3321af7845ef97895 Author: Bastien Nocera Date: Wed Jun 6 17:44:38 2012 +0100 screen: Use '&' instead of 'and' Using "&" not only keeps the names shorter but would also keeps the user focused on the other words which compose the name. https://bugzilla.gnome.org/show_bug.cgi?id=676562 panels/screen/gnome-screen-panel.desktop.in.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit a4475970eeca23e7d6af965106dcf4b847f7d6bb Author: Bastien Nocera Date: Wed Jun 6 17:43:47 2012 +0100 datetime: Use '&' instead of 'and' Using "&" not only keeps the names shorter but would also keeps the user focused on the other words which compose the name. https://bugzilla.gnome.org/show_bug.cgi?id=676562 panels/datetime/gnome-datetime-panel.desktop.in.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit d079041b14db5dc3fb10f6ac4e9c6700df2e956b Author: Stef Walter Date: Mon Jun 4 10:39:34 2012 +0200 build: Only enable _FORTIFY_SOURCE if optimization enabled Otherwise we get a spew of warnings when building non-optimized https://bugzilla.gnome.org/show_bug.cgi?id=677373 configure.ac | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) commit f2a9d3a4787e69f1c27fa8e2b328ec82fb707302 Author: Bastien Nocera Date: Wed Jun 6 16:11:26 2012 +0100 shell: Fix crash when using keynav in overview get_item_views() was expecting all the children of the overview to be of type "CcShellCategoryView". It's not the case since 620e70113c30b0ae868577153dda60139f3c20b4 added GtkSeparators as children. We now just skip them non-views in get_item_views(). https://bugzilla.gnome.org/show_bug.cgi?id=677314 shell/cinnamon-control-center.c | 2 ++ 1 file changed, 2 insertions(+) commit f94490a5b51003d6f1f45a53f57f0200ea2f62b4 Author: Debarshi Ray Date: Mon Jun 4 20:44:07 2012 +0200 build: require GOA >= 3.5.1 GOA got ported from GtkTable to GtkGrid. Fixes: https://bugzilla.gnome.org/669625 configure.ac | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) commit f86d8eb26cc922fabd6765f3ad2481b9f0218298 Author: Debarshi Ray Date: Wed Apr 4 17:28:54 2012 +0200 online-accounts: Remove horizontal scrolling from accounts list We have enough space. Therefore, instead of having horizontal scrollbars, widen the text renderer and then ellipsize, if required. Implemented design: https://live.gnome.org/Design/SystemSettings/OnlineAccounts Fixes: https://bugzilla.gnome.org/671980 panels/online-accounts/cc-online-accounts-panel.c | 5 +++++ panels/online-accounts/online-accounts.ui | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) commit 93051830a7fc70756334bab03e46011619755150 Author: Debarshi Ray Date: Mon Mar 12 14:35:24 2012 +0100 online-accounts: New "Add Account" dialog Implemented design: https://live.gnome.org/Design/SystemSettings/OnlineAccounts Fixes: https://bugzilla.gnome.org/671980 panels/online-accounts/Makefile.am | 2 + .../cc-online-accounts-add-account-dialog.c | 367 +++++++++++++++++++++ .../cc-online-accounts-add-account-dialog.h | 62 ++++ panels/online-accounts/cc-online-accounts-panel.c | 74 +---- po/POTFILES.in | 1 + 5 files changed, 440 insertions(+), 66 deletions(-) commit 3ab49ea66d3a7fd2a800359f1f5b6a7ce0da2790 Author: Matthias Clasen Date: Tue Jun 5 00:27:00 2012 -0400 Post-release version bump configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 29fc916be101ee7b259ab9a54949a2f2ed0010f5 Author: Matthias Clasen Date: Tue Jun 5 00:02:38 2012 -0400 3.5.2 NEWS | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 2 +- 2 files changed, 68 insertions(+), 1 deletion(-) commit 8ba96c7daffcd218b6822296f487896b5ac2725a Author: Debarshi Ray Date: Tue May 1 03:11:15 2012 +0200 online-accounts: Don't hardcode the text color With hard coded colors, when an account is selected in the tree view, the text shows up as black on blue, instead of white on blue. Fixes: https://bugzilla.gnome.org/671980 panels/online-accounts/cc-online-accounts-model.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) commit ca36f361d97ea96bebc40575aacaf1144cc3dd6e Author: Daniel Mustieles Date: Sun Jun 3 17:56:40 2012 +0200 Updated Spanish translation po/es.po | 282 ++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 163 insertions(+), 119 deletions(-) commit c6be102d1d3792567555670ca00e62d0abc84d95 Author: Fran DiĆ©guez Date: Sun Jun 3 02:35:33 2012 +0200 Updated Galician translations po/gl.po | 441 ++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 252 insertions(+), 189 deletions(-) commit cf3c9f33d986d9d6baaf20d4ef403dc43b631e51 Author: Yuri Kozlov Date: Sat Jun 2 18:10:48 2012 +0400 Updated Russian translation po/ru.po | 2039 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 1212 insertions(+), 827 deletions(-) commit fde8a37bcf750494d35d0b210350579e594f4eb6 Author: Yaron Shahrabani Date: Sat Jun 2 12:52:34 2012 +0300 Updated Hebrew translation. po/he.po | 255 ++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 145 insertions(+), 110 deletions(-) commit e307f303e70e9a42b098a909851ed0b9c9770dfa Author: Piotr Drąg Date: Fri Jun 1 20:08:48 2012 +0200 Updated POTFILES.in po/POTFILES.in | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) commit e880784fcb5ac584686d3d7b855bfbe2c0818309 Author: Bastien Nocera Date: Fri Jun 1 19:01:36 2012 +0100 region: Update the shortcuts labels on startup https://bugzilla.gnome.org/show_bug.cgi?id=662489 panels/region/gnome-region-panel-input.c | 61 ++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 15 deletions(-) commit 5e4376cfdeaf970543d761dfbb6ddfe232a19c43 Author: Rui Matos Date: Thu Apr 19 05:43:38 2012 +0200 keyboard: Add key bindings to switch input sources https://bugzilla.gnome.org/show_bug.cgi?id=662489 panels/keyboard/01-input-sources.xml.in | 12 ++++++++++++ panels/keyboard/Makefile.am | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-) commit 0a78c3504e34927c9864d489fafd3e8025e21d5c Author: Rui Matos Date: Tue May 22 19:14:19 2012 +0200 region: Add XKB input sources We allow the user to choose from all XKB layouts installed and keep a user picked list in gsettings. https://bugzilla.gnome.org/show_bug.cgi?id=662489 configure.ac | 3 +- panels/region/gnome-region-panel-input-chooser.ui | 5 + panels/region/gnome-region-panel-input.c | 250 ++++++++++++++++++++-- 3 files changed, 238 insertions(+), 20 deletions(-) commit 375bf2363fcfdf0916acb0e3550bb5909de5eb12 Author: Rui Matos Date: Thu May 17 00:13:54 2012 +0200 region: Improved keynav on the input chooser This makes the dialog return when the user presses Enter on the filter entry and prevents the GtkTreeView search popup from being used since we already handle searching on that tree view. https://bugzilla.gnome.org/show_bug.cgi?id=662489 panels/region/gnome-region-panel-input.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) commit e38f9acf39f6e7a5fa079efb081586ec215a5bcc Author: Rui Matos Date: Wed Apr 18 17:11:08 2012 +0200 region: Improved selection handling on the input chooser This makes the input chooser list always have a selected row and be centered on it when the filter is applied. https://bugzilla.gnome.org/show_bug.cgi?id=662489 panels/region/gnome-region-panel-input.c | 45 +++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 13 deletions(-) commit 0fb0d6139b373dfd6ef934d86b92aa99edf8b23e Author: Rui Matos Date: Wed May 16 23:22:02 2012 +0200 region: Removal of the Layouts tab https://bugzilla.gnome.org/show_bug.cgi?id=662489 configure.ac | 5 +- panels/region/Makefile.am | 10 +- panels/region/cc-region-panel.c | 2 - panels/region/gnome-region-panel-layout-chooser.ui | 180 ------- panels/region/gnome-region-panel-options-dialog.ui | 79 ---- panels/region/gnome-region-panel-system.c | 103 +---- panels/region/gnome-region-panel-xkb.c | 190 -------- panels/region/gnome-region-panel-xkb.h | 96 ---- panels/region/gnome-region-panel-xkblt.c | 470 ------------------- panels/region/gnome-region-panel-xkbltadd.c | 495 -------------------- panels/region/gnome-region-panel-xkbot.c | 515 --------------------- panels/region/gnome-region-panel-xkbpv.c | 120 ----- panels/region/use_cases.txt | 42 -- 13 files changed, 7 insertions(+), 2300 deletions(-) commit bfaeb6a41ddd5ad0c65744397e026346a0acf89f Author: Rui Matos Date: Wed May 16 23:05:00 2012 +0200 region: Add an initial input sources tab This is just the scaffolding according to https://live.gnome.org/Design/SystemSettings/RegionAndLanguage No code behind it yet. Original code from Matthias Clasen. https://bugzilla.gnome.org/show_bug.cgi?id=662489 panels/region/Makefile.am | 3 + panels/region/cc-region-panel.c | 2 + panels/region/gnome-region-panel-input-chooser.ui | 152 +++++ panels/region/gnome-region-panel-input.c | 536 +++++++++++++++++ panels/region/gnome-region-panel-input.h | 36 ++ panels/region/gnome-region-panel.ui | 676 ++++++++++++---------- 6 files changed, 1091 insertions(+), 314 deletions(-) commit e59dc8dec45a3092cf6ef7d5f531617bccc3b0a1 Author: Matthias Clasen Date: Tue Nov 15 21:10:31 2011 -0500 keyboard: Make it possible to jump to shortcuts tab To make this work, we need to move the setting up of priv->builder to the instance init, so that it is available when construct properties are set; the other setup needs to remain in the constructor, since it relies on construct properties. https://bugzilla.gnome.org/show_bug.cgi?id=662489 panels/keyboard/cc-keyboard-panel.c | 112 +++++++++++++++++++++++++----------- 1 file changed, 80 insertions(+), 32 deletions(-) commit 6bc14ced7f1aca3c46b675787db0ffbad7facd2a Author: Marek Černocký Date: Fri Jun 1 17:47:46 2012 +0200 Updated Czech translation po/cs.po | 1729 ++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 994 insertions(+), 735 deletions(-) commit ec27900578642435ccffc2f59b7f1efe9263c1ee Author: Richard Hughes Date: Wed May 30 14:23:45 2012 +0100 network: Allow configuring wired network devices when not connected This prevents the chicken-and-egg problem as described in #653296 by launching nm-connection-editor for the inactive connection for the device. This only works when there is one possible connection for the device, which is helpfully typical for wired ethernet devices. Resolves: https://bugzilla.gnome.org/show_bug.cgi?id=653296 panels/network/cc-network-panel.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) commit 04fdb2b456c4752a5b28883bb90873417c21989d Author: Richard Hughes Date: Wed May 30 12:46:55 2012 +0100 network: Don't resize the panel when switching network types Resolves: https://bugzilla.gnome.org/show_bug.cgi?id=671482 panels/network/network.ui | 1 - 1 file changed, 1 deletion(-) commit 0c4bbebf4e1e67760e69ea039e8bfdab420a079a Author: Kjartan Maraas Date: Wed May 30 14:01:25 2012 +0200 Updated Norwegian bokmĆ„l translation po/nb.po | 1070 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 641 insertions(+), 429 deletions(-) commit 160697df6ca870efc153c77d32f42ffb05359c1d Author: Richard Hughes Date: Wed May 30 12:39:48 2012 +0100 network: Do not print a critical warning when NetworkManager is restarted Resolves: https://bugzilla.gnome.org/show_bug.cgi?id=676369 panels/network/cc-network-panel.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) commit 033a7acb122b89551c141f200a6d4c489cd7b1ad Author: Matej Urbančič Date: Tue May 29 09:07:29 2012 +0200 Updated Slovenian translation po/sl.po | 1341 ++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 827 insertions(+), 514 deletions(-) commit 44c88a37a1fcd1a81107ad7c1e216c0e04e81cdb Author: Baurzhan Muftakhidinov Date: Mon May 28 08:44:06 2012 +0600 Updated Kazakh translation po/kk.po | 442 +++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 286 insertions(+), 156 deletions(-) commit fbc4d703bdfca934cedbe22c9439327f45db3a7d Author: Yaron Shahrabani Date: Sat May 26 07:32:25 2012 +0300 Updated Hebrew Translation. po/he.po | 76 ++++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 38 insertions(+), 38 deletions(-) commit f4db8bb8b27d9560c73dac4a12cdc19eae7db2cb Author: Yaron Shahrabani Date: Fri May 25 19:00:24 2012 +0300 Updated Hebrew translation. po/he.po | 1149 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 696 insertions(+), 453 deletions(-) commit c11a6398bc3935ab04d00288a24b5c75cd674542 Author: Daniel Mustieles Date: Fri May 25 16:19:41 2012 +0200 Updated Spanish translation po/es.po | 181 ++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 103 insertions(+), 78 deletions(-) commit 487c11c0d952ee9c70a43477d02be63b0af067dc Author: Bastien Nocera Date: Fri May 25 14:04:53 2012 +0100 wacom: Update from gnome-settings-daemon panels/wacom/gsd-input-helper.c | 15 ++++++++++----- panels/wacom/gsd-wacom-device.c | 30 ++++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 11 deletions(-) commit 5c78387b592bd5f3eae1f8fb667bbd3db03ac6e4 Author: Bastien Nocera Date: Fri May 25 12:48:34 2012 +0100 wacom: Update from gnome-settings-daemon panels/wacom/gsd-wacom-device.c | 3 +++ 1 file changed, 3 insertions(+) commit 5a2b4112553f2b910c559a7624c16adfaa9d6d3d Author: Bastien Nocera Date: Fri May 25 12:14:27 2012 +0100 wacom: Fix crasher using link to display panel ->panel was never set within the page object. panels/wacom/cc-wacom-page.c | 2 ++ panels/wacom/cc-wacom-panel.c | 2 ++ 2 files changed, 4 insertions(+) commit aa161bacc9c11b9dfee2551ef03f294dd2d78aad Author: Bastien Nocera Date: Fri May 25 11:19:37 2012 +0100 wacom: Destroy button mapping dialogue on unplug https://bugzilla.gnome.org/show_bug.cgi?id=676790 panels/wacom/cc-wacom-page.c | 9 +++++++++ 1 file changed, 9 insertions(+) commit 0b782b5633249a1f8c15a24399a833ac2e41c6d5 Author: Antoine Jacoutot Date: Thu May 24 09:50:52 2012 +0200 disable wacom on s390/s390x and non Linux platforms Follow gnome-settings-daemon behavior and disable the wacom panel on s390/s390x (because this architecture does not provide development files from the wacom xorg driver) and on non Linux platforms (where udev is missing). https://bugzilla.gnome.org/show_bug.cgi?id=676714 configure.ac | 28 ++++++++++++++++++++++++---- panels/Makefile.am | 7 +++++-- 2 files changed, 29 insertions(+), 6 deletions(-) commit 8f289ff79921a5bbfab72944368d0b4790333687 Author: Bastien Nocera Date: Thu May 24 15:25:59 2012 +0100 user-accounts: Require libpwquality configure.ac | 1 + 1 file changed, 1 insertion(+) commit bd3405d9e19ffc9c52bd789b645d3859a726aea4 Author: Bastien Nocera Date: Tue Mar 13 17:38:34 2012 +0100 universal-access: Add context for haircross length https://bugzilla.gnome.org/show_bug.cgi?id=671989 panels/universal-access/zoom-options.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) commit c11e4a9c5398cd729786a216387edc4b1a3309eb Author: Piotr Drąg Date: Wed May 23 19:33:13 2012 +0200 Updated POTFILES.in po/POTFILES.in | 1 + 1 file changed, 1 insertion(+) commit 93bc61e0b46d5209f579ae85d00e4f8930c42356 Author: Bastien Nocera Date: Wed May 23 18:06:22 2012 +0100 shell: Fix --verbose not working anymore shell/cc-shell-log.c | 2 ++ 1 file changed, 2 insertions(+) commit a2d338b2d8ffbc39da26de192bdc1bbc01d86b84 Author: Bastien Nocera Date: Wed May 23 18:06:06 2012 +0100 shell: Add debug to CcNotebook scrolling shell/cc-notebook.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) commit 2c4d1b7b59c085988cfb9d314fdbdf09bd88cf2a Author: Daniel Mustieles Date: Wed May 23 18:09:44 2012 +0200 Updated Spanish translation po/es.po | 69 +++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 36 insertions(+), 33 deletions(-) commit 95d5e61100aa7667f7789a28eee1b04e6614f470 Author: Bastien Nocera Date: Wed May 23 17:07:29 2012 +0100 shell: Fix first selection not working We weren't saving the last_width early enough. shell/cc-notebook.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit f62d8016562c96dc701a6e6ad8cb2ce1aaba7b78 Author: Matthias Clasen Date: Sat May 19 17:45:04 2012 -0400 users: Pass more information to password checker Passing the username and the old password allows the password quality check find more bad passwords. Also, add a way to provide more information about why a password is not good enough. https://bugzilla.gnome.org/show_bug.cgi?id=676396 panels/user-accounts/pw-utils.c | 11 +++++++++-- panels/user-accounts/pw-utils.h | 5 ++++- panels/user-accounts/um-password-dialog.c | 10 +++++++++- 3 files changed, 22 insertions(+), 4 deletions(-) commit 810f29b6cee271cf784aef6478a1952a5ee60b8e Author: Matthias Clasen Date: Wed May 23 10:43:17 2012 -0400 users: Use libpwquality for password handling Using a library for password generation and quality checking has the obvious benefit that we can have centralized policy for password quality, and our homegrown code for this was not a beauty in the first place. This commit drops the use of /usr/bin/agp for generating random passwords. https://bugzilla.gnome.org/show_bug.cgi?id=676396 panels/user-accounts/Makefile.am | 2 + panels/user-accounts/pw-utils.c | 132 +++++++++++++-------------------------- 2 files changed, 44 insertions(+), 90 deletions(-) commit 8947cf84688d59d710716616866c68e699ab9972 Author: Matthias Clasen Date: Wed May 23 08:40:56 2012 -0400 users: Separate out password generation and strength calculation This is in preparation of using a library for this purpose, and is just generally cleaner. panels/user-accounts/Makefile.am | 2 + panels/user-accounts/pw-utils.c | 158 ++++++++++++++++++++++++++++++ panels/user-accounts/pw-utils.h | 27 +++++ panels/user-accounts/um-password-dialog.c | 124 ++--------------------- 4 files changed, 195 insertions(+), 116 deletions(-) commit 142070e8ea94cc693ca43ea3ea0d08abb1bc8295 Author: Debarshi Ray Date: Fri Apr 20 16:21:20 2012 +0200 user-accounts: Use instead of to indicate user role Fixes: https://bugzilla.gnome.org/674423 panels/user-accounts/um-user-panel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 86bd905920104af14fdd1e047bbe1ad1ccdad37a Author: Matthias Clasen Date: Sat May 19 17:09:39 2012 -0400 users: Make generated password visible A generated password is useless if you can't read it. https://bugzilla.gnome.org/show_bug.cgi?id=633601 panels/user-accounts/um-password-dialog.c | 2 ++ 1 file changed, 2 insertions(+) commit a7beb087db07f2d7d13e52794be7f15f90e3e156 Author: Matthias Clasen Date: Tue May 8 21:50:10 2012 -0400 user-accounts: Simplify generated password handling Move the 'generate password' icon into the entry to make the focus chain more straightforward. Also switch from generating a choice of 6 passwords in a menu, just put put the next choice directly into the entry. To keep the password generation keyboard accessible, add a 'Generate password' context menu item. https://bugzilla.gnome.org/show_bug.cgi?id=633601 https://bugzilla.gnome.org/show_bug.cgi?id=658522 panels/user-accounts/data/password-dialog.ui | 21 +--- panels/user-accounts/um-password-dialog.c | 164 +++++++++------------------ 2 files changed, 56 insertions(+), 129 deletions(-) commit 359f029419d0c7962ae2afc04c7fd1d569897c5f Author: Bastien Nocera Date: Tue May 22 18:19:39 2012 +0100 shell: Fix keyboard focus in animated notebook But just for panels, the main overview is still sub-par. shell/cc-notebook.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) commit b82141038e3a55d01cda805badd562130a9bd887 Author: Bastien Nocera Date: Tue May 22 17:48:11 2012 +0100 shell: CcNotebook can focus indeed shell/cc-notebook.c | 2 ++ 1 file changed, 2 insertions(+) commit e18742c90ea1738907b7e514c0b5eead9514907f Author: William Jon McCann Date: Mon May 21 23:01:50 2012 -0400 Implement a new search results design Search results aren't laid out evenly and they are packed together too tightly. Also, panel descriptions are truncated. There is plenty of space available, we might as well use it. https://bugzilla.gnome.org/show_bug.cgi?id=654977 shell/Makefile.am | 2 - shell/cc-shell-search-renderer.c | 366 --------------------------------------- shell/cc-shell-search-renderer.h | 74 -------- shell/cinnamon-control-center.c | 96 ++++++---- 4 files changed, 60 insertions(+), 478 deletions(-) commit d3841bb2c89b5ddf99bad61afbf2731864204496 Author: Cosimo Cecchi Date: Mon May 21 15:17:53 2012 -0400 build: require Clutter >= 1.11.3 We require clutter master for ClutterScrollActor now. https://bugzilla.gnome.org/show_bug.cgi?id=676517 configure.ac | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) commit fc7bc983b08d6ed224ba0e19d21d741ff88065a5 Author: A S Alam Date: Mon May 21 07:04:53 2012 +0530 Update Punjabi Translation po/pa.po | 1495 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 889 insertions(+), 606 deletions(-) commit 0b93e7c80f47b1ef2e6358917e073aa116e00a3e Author: Bastien Nocera Date: Mon May 21 19:16:55 2012 +0100 shell: Make all-settings button always square By wrapping it in an aspect frame. https://bugzilla.gnome.org/show_bug.cgi?id=670551 shell/shell.ui | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) commit 9e6ed56939b30591ecd93ea1720fb134fc90bbec Author: Bastien Nocera Date: Mon May 21 18:51:18 2012 +0100 shell: Fix possible warning on startup When started with a specific panel listed. shell/cc-shell.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) commit 85dbb1d8c55d505f4759a6239fa1348e5975b987 Author: Bastien Nocera Date: Mon May 21 16:08:52 2012 +0100 shell: Update scrolled window height on smallness change When the small mode changes, make sure to update the scrolled window's natural height. https://bugzilla.gnome.org/show_bug.cgi?id=673869#c47 shell/cinnamon-control-center.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) commit 8efba88f4c2a01e2fb13be01bde839f638c35de3 Author: Bastien Nocera Date: Mon May 21 16:01:28 2012 +0100 shell: Use enum for small screen Instead of 2 variables to track the unset status. shell/cinnamon-control-center.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) commit a112361267f6b13216937fce56c23303054b990e Author: Bastien Nocera Date: Mon May 21 14:23:00 2012 +0100 shell: Don't use workarea height Instead of monitor height to check for the available height, as the workarea height won't have been updated fast enough after a monitors-changed signal. https://bugzilla.gnome.org/show_bug.cgi?id=673869#c47 shell/cinnamon-control-center.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) commit a6f8a9a6134bd1d6c603d8516cb585baed186b0f Author: Daniel Mustieles Date: Mon May 21 13:57:27 2012 +0200 Updated Spanish translation po/es.po | 385 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 194 insertions(+), 191 deletions(-) commit 57f0bc4f0b03aa4d4f20a6919c76a04da2027256 Author: Fran DiĆ©guez Date: Sat May 19 15:46:16 2012 +0200 Updated Galician translations po/gl.po | 684 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 347 insertions(+), 337 deletions(-) commit 7e77b7b7da946ed90e68ecc21408c5b2db19c0da Author: Florian Müllner Date: Fri May 18 18:46:41 2012 +0200 shell: Fix ctrl-w keybinding shell/cinnamon-control-center.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit c626ba5cdfa037fc68c6db517084fe8a3a0de6c8 Author: Florian Müllner Date: Sun May 6 02:57:51 2012 +0200 shell: Add application menu Add a simple application menu containing just "Help" and "Quit". https://bugzilla.gnome.org/show_bug.cgi?id=675471 shell/control-center.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) commit ad4da161269a991153408227ae9c665956fec9e6 Author: Florian Müllner Date: Fri May 18 16:40:31 2012 +0200 shell: Make the main window a GtkApplicationWindow This is a prerequisite of using the new GMenu API. Also move the check for small screen sizes introduced in commit 22ed5a9fd5, as GtkApplicationWindows cannot be realized unless their application property has been set. https://bugzilla.gnome.org/show_bug.cgi?id=675471 shell/cinnamon-control-center.c | 20 ++++++++++++++++---- shell/shell.ui | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) commit a901cc1c18886c25a829111fd91f7b3c196e36e1 Author: Florian Müllner Date: Fri May 18 17:08:52 2012 +0200 user-accounts: Add get_help_uri() implementation https://bugzilla.gnome.org/show_bug.cgi?id=675471 panels/user-accounts/um-user-panel.c | 7 +++++++ 1 file changed, 7 insertions(+) commit fa4a95752980a9be494ad3dd042b37fd8068d590 Author: Florian Müllner Date: Fri May 18 17:08:15 2012 +0200 universal-access: Add get_help_uri() implementation https://bugzilla.gnome.org/show_bug.cgi?id=675471 panels/universal-access/cc-ua-panel.c | 9 +++++++++ 1 file changed, 9 insertions(+) commit 45b793848fb9fcfa9b659b355a8cb0567a27e75e Author: Florian Müllner Date: Fri May 18 17:07:48 2012 +0200 sound: Add get_help_uri() implementation https://bugzilla.gnome.org/show_bug.cgi?id=675471 panels/sound/cc-sound-panel.c | 9 +++++++++ 1 file changed, 9 insertions(+) commit dc381014c06322c724385feb108584a7b0a2d9ea Author: Florian Müllner Date: Fri May 18 17:07:24 2012 +0200 screen: Add get_help_uri() implementation https://bugzilla.gnome.org/show_bug.cgi?id=675471 panels/screen/cc-screen-panel.c | 9 +++++++++ 1 file changed, 9 insertions(+) commit 79b11894dd38bc14b0ed478ff0da326d87e0aad0 Author: Florian Müllner Date: Fri May 18 17:06:51 2012 +0200 region: Add get_help_uri() implementation https://bugzilla.gnome.org/show_bug.cgi?id=675471 panels/region/cc-region-panel.c | 9 +++++++++ 1 file changed, 9 insertions(+) commit 0c353fb4a89085c05263f12f1d41668bfd5811e7 Author: Florian Müllner Date: Fri May 18 17:06:07 2012 +0200 printers: Add get_help_uri() implementation https://bugzilla.gnome.org/show_bug.cgi?id=675471 panels/printers/cc-printers-panel.c | 7 +++++++ 1 file changed, 7 insertions(+) commit e38491ed0dc917c98f398b43a16cc017422263b2 Author: Florian Müllner Date: Fri May 18 17:05:46 2012 +0200 power: Add get_help_uri() implementation https://bugzilla.gnome.org/show_bug.cgi?id=675471 panels/power/cc-power-panel.c | 9 +++++++++ 1 file changed, 9 insertions(+) commit 4b72311259b474f481aac1af526f7c99caac0405 Author: Florian Müllner Date: Fri May 18 17:05:25 2012 +0200 online-accounts: Add get_help_uri() implementation https://bugzilla.gnome.org/show_bug.cgi?id=675471 panels/online-accounts/cc-online-accounts-panel.c | 9 +++++++++ 1 file changed, 9 insertions(+) commit 1bbe93cd0c0e81ad8b2044479c288de9f5f4f71c Author: Florian Müllner Date: Fri May 18 17:04:58 2012 +0200 network: Add get_help_uri() implementation https://bugzilla.gnome.org/show_bug.cgi?id=675471 panels/network/cc-network-panel.c | 9 +++++++++ 1 file changed, 9 insertions(+) commit 164d8b54a076ac4bca4928b2100e9da411a5c0a1 Author: Florian Müllner Date: Fri May 18 17:04:32 2012 +0200 mouse: Add get_help_uri() implementation https://bugzilla.gnome.org/show_bug.cgi?id=675471 panels/mouse/cc-mouse-panel.c | 9 +++++++++ 1 file changed, 9 insertions(+) commit 7adcd012616f7b1f2a71e9bbc452cb06e1c36cca Author: Florian Müllner Date: Fri May 18 17:04:03 2012 +0200 keyboard: Add get_help_uri() implementation https://bugzilla.gnome.org/show_bug.cgi?id=675471 panels/keyboard/cc-keyboard-panel.c | 9 +++++++++ 1 file changed, 9 insertions(+) commit 4e374a27f06ac19e618197d13ac3551566176774 Author: Florian Müllner Date: Fri May 18 17:03:34 2012 +0200 display: Add get_help_uri() implementation https://bugzilla.gnome.org/show_bug.cgi?id=675471 panels/display/cc-display-panel.c | 9 +++++++++ 1 file changed, 9 insertions(+) commit afe99e36fda6980c62015ac0981663abdc133d3b Author: Florian Müllner Date: Fri May 18 17:03:05 2012 +0200 datetime: Add get_help_uri() implementation https://bugzilla.gnome.org/show_bug.cgi?id=675471 panels/datetime/cc-datetime-panel.c | 7 +++++++ 1 file changed, 7 insertions(+) commit 186d615dee5b82eaf14d242f3872e01ba770024a Author: Florian Müllner Date: Fri May 18 17:00:13 2012 +0200 color: Add get_help_uri() implementation https://bugzilla.gnome.org/show_bug.cgi?id=675471 panels/color/cc-color-panel.c | 9 +++++++++ 1 file changed, 9 insertions(+) commit bc18595051b7561e7ccce77837dae70d0282b5eb Author: Florian Müllner Date: Fri May 18 16:59:27 2012 +0200 bluetooth: Add get_help_uri() implementation https://bugzilla.gnome.org/show_bug.cgi?id=675471 panels/bluetooth/cc-bluetooth-panel.c | 9 +++++++++ 1 file changed, 9 insertions(+) commit f8637475ba867a01369475c6b662de54de93b706 Author: Florian Müllner Date: Tue May 8 19:40:13 2012 +0200 background: Add get_help_uri() implementation https://bugzilla.gnome.org/show_bug.cgi?id=675471 panels/background/cc-background-panel.c | 9 +++++++++ 1 file changed, 9 insertions(+) commit 6827068ade00ec04e1895c772513667b6d6a1bdb Author: Florian Müllner Date: Tue May 8 18:47:13 2012 +0200 cc-panel: Add get_help_uri() vfunc We want to allow panels to point to a specific help page, so add a vfunc for that. https://bugzilla.gnome.org/show_bug.cgi?id=675471 shell/cc-panel.c | 11 +++++++++++ shell/cc-panel.h | 3 +++ 2 files changed, 14 insertions(+) commit 78717031db90c42221a7dce1f20762b9d8b8103c Author: Florian Müllner Date: Tue May 8 18:45:25 2012 +0200 shell: Make sure the "active-panel" property is updated The (currently unused) cc_shell_get_active_panel() method is useless unless "active-panel" is actually updated correctly. https://bugzilla.gnome.org/show_bug.cgi?id=675471 shell/cc-shell.c | 1 - shell/cinnamon-control-center.c | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) commit ce8e1208bc87f91785c6ab91deb7c5e50a2d2dc6 Author: Florian Müllner Date: Fri May 18 16:53:41 2012 +0200 shell: Pass the object to show_overview_page(), not its private We will need it to update the "active-panel" property properly. https://bugzilla.gnome.org/show_bug.cgi?id=675471 shell/cinnamon-control-center.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) commit 4a4f3c20a4ad5e2ea57ae9f4d241d27f0a13358a Author: Piotr Drąg Date: Fri May 18 18:44:58 2012 +0200 universal-access: remove tabulation from a translatable string panels/universal-access/uap.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 948867b6d39d644733acc7b82ca71ecf22fc4ca5 Author: Bastien Nocera Date: Fri May 18 17:33:08 2012 +0100 shell: Fix resetting page selection When the page selection happens when another page selection hasn't started yet, we need to cancel the previous animation, or only one of them might be effectively acted upon. This fixes the page from being selected if the search term is changed quickly (you'd end up at the overview page instead of staying on the search results page). Requires the clutter patch from: https://bugzilla.gnome.org/show_bug.cgi?id=676334 https://bugzilla.gnome.org/show_bug.cgi?id=676328 shell/cc-notebook.c | 3 +++ 1 file changed, 3 insertions(+) commit 5f124d600810b1a56484bb1957f441eb5f715b16 Author: Piotr Drąg Date: Fri May 18 18:39:31 2012 +0200 all: fix up tooltips Idea from commit d5088b2eb1bd5f1501e36ec878e60aa3f6e7241b. panels/bluetooth/bluetooth.ui | 6 +++--- panels/color/color.ui | 9 +++------ panels/region/gnome-region-panel.ui | 5 +---- panels/screen/screen.ui | 2 +- panels/universal-access/uap.ui | 4 ++-- panels/wacom/gnome-wacom-properties.ui | 4 ++-- 6 files changed, 12 insertions(+), 18 deletions(-) commit d5088b2eb1bd5f1501e36ec878e60aa3f6e7241b Author: Richard Hughes Date: Fri May 18 16:02:13 2012 +0100 color: Fix up a tooltip for the 'Set for all users' button panels/color/color.ui | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) commit 93184f16b924478be6c5f6e6719e46463cdf458e Author: Richard Hughes Date: Fri May 18 15:59:01 2012 +0100 color: Make the 'Set for all users' insensitive if the profile is already set Resolves: https://bugzilla.gnome.org/show_bug.cgi?id=676271 panels/color/cc-color-panel.c | 2 ++ 1 file changed, 2 insertions(+) commit 19f27721073955626171ebb42adf02ce73517016 Author: Bastien Nocera Date: Fri May 18 11:48:29 2012 +0100 shell: Rename search renderer And cc- prefix it, like the rest of our widgets. shell/Makefile.am | 4 +- shell/cc-shell-search-renderer.c | 366 +++++++++++++++++++++++++++++++++++++++ shell/cc-shell-search-renderer.h | 74 ++++++++ shell/cinnamon-control-center.c | 4 +- shell/shell-search-renderer.c | 365 -------------------------------------- shell/shell-search-renderer.h | 74 -------- 6 files changed, 444 insertions(+), 443 deletions(-) commit 17c2e2c2576cc7fd116c930210a1baeb539df1b6 Author: Peter Hutterer Date: Thu Apr 12 15:36:08 2012 +0200 wacom: Make "Calibrate" button insensitive if there is no screen match If no match is found for the screen tablet, calibration will fail anyway. https://bugzilla.gnome.org/show_bug.cgi?id=673892 panels/wacom/cc-wacom-page.c | 4 ++++ 1 file changed, 4 insertions(+) commit 928e921d8d95887fe7ff29f9ad36e0413164020c Author: Bastien Nocera Date: Fri May 18 10:34:20 2012 +0100 wacom: Update from gnome-settings-daemon panels/wacom/gsd-wacom-device.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) commit c6c239c94f9667451be0e251f702286e22235498 Author: Daniel Mustieles Date: Fri May 18 10:58:01 2012 +0200 Updated Spanish translation po/es.po | 362 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 177 insertions(+), 185 deletions(-) commit c0aa0b2d433b066b2bbcfcb0f4abb3a60ef988b8 Author: Bastien Nocera Date: Thu May 17 18:30:32 2012 +0100 wacom: Bump libwacom requirements For API change in 0.5. See https://bugzilla.gnome.org/show_bug.cgi?id=675872 configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit fb6051401c95d7bc9f8e67679f992d91b0c7eeb9 Author: Bastien Nocera Date: Thu May 17 18:30:14 2012 +0100 wacom: Update from gnome-settings-daemon panels/wacom/gsd-input-helper.c | 9 ++++++++- panels/wacom/gsd-wacom-device.c | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) commit 229390f1f5898c46119c51b8d5a4d31a0d733a12 Author: William Jon McCann Date: Tue May 8 20:08:33 2012 -0400 universal-access: Redesign for consistency and smallness https://bugzilla.gnome.org/show_bug.cgi?id=665588 panels/universal-access/cc-ua-panel.c | 328 +-- panels/universal-access/uap.ui | 3977 +++++++++++++++------------------ 2 files changed, 1945 insertions(+), 2360 deletions(-) commit 3d79e1174e7287f29ad630a4aea55cfa0a6d2b2a Author: Bastien Nocera Date: Thu May 17 18:12:13 2012 +0100 background: Only show the image types we support And add image/bmp to those types. https://bugzilla.gnome.org/show_bug.cgi?id=669960 panels/background/bg-pictures-source.c | 69 ++++++++++++++++++++------------- panels/background/bg-pictures-source.h | 2 + panels/background/cc-background-panel.c | 6 ++- 3 files changed, 50 insertions(+), 27 deletions(-) commit 0ed1bef14fa8c7d43c989c7d1c093d8dd37f942e Author: Fran DiĆ©guez Date: Thu May 17 12:19:09 2012 +0200 Updated Galician translations po/gl.po | 355 ++++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 282 insertions(+), 73 deletions(-) commit 835a09e1f84315ffc49552462f88282ebadd645a Author: Bastien Nocera Date: Wed May 16 13:13:43 2012 +0100 shell: Destroy the page instead of removing it Because we don't actually need the child simply removed. Works-around run-time warnings with clutter-gtk. shell/cc-notebook.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) commit 75323fffb280eda7bd625436dbcf143f9c22de1d Author: Daniel Mustieles Date: Wed May 16 12:32:06 2012 +0200 Updated Spanish translation po/es.po | 380 +++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 299 insertions(+), 81 deletions(-) commit 1f24b178ac7fdcbe442f5634c0bb04fcb9b979b6 Author: Thomas Bechtold Date: Mon May 14 08:07:06 2012 +0200 network: show device state reasons (Closes:bgo#676117) Signed-off-by: Richard Hughes panels/network/cc-network-panel.c | 1 + panels/network/panel-common.c | 193 ++++++++++++++++++++++++++++++++++++++ panels/network/panel-common.h | 13 +-- 3 files changed, 201 insertions(+), 6 deletions(-) commit dbfd9ecb5983e7101dbddf389a480f78e6febe21 Author: Bastien Nocera Date: Fri May 11 12:21:37 2012 +0100 shell: Fix another memleak in CcNotebook shell/cc-notebook.c | 3 +++ 1 file changed, 3 insertions(+) commit 2ea396cee3b4ccb11290985fa4f18db5796206cd Author: Bastien Nocera Date: Fri May 11 12:18:34 2012 +0100 shell: Chain up CcNotebook's finalize function shell/cc-notebook.c | 2 ++ 1 file changed, 2 insertions(+) commit b96c440da95450de78022cad8fdd525ca26e60b1 Author: Bastien Nocera Date: Fri May 11 11:57:01 2012 +0100 shell: Remove left-over FIXME shell/cc-notebook.c | 2 -- 1 file changed, 2 deletions(-) commit bec2efb36abf5b232a1b54a00f15fa91ee5dc7d4 Author: Bastien Nocera Date: Thu May 10 19:20:58 2012 +0100 shell: Try to always use delayed removal shell/cc-notebook.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) commit 62d2bcf0b8e9187b77c7b79becb1b40f9793fd1e Author: Bastien Nocera Date: Thu May 10 18:21:39 2012 +0100 shell: Fix xrefs not working We were scrolling to parts of the stage where we wouldn't have a page anymore. Don't do that, and only remove pages when we're done with animations. shell/cc-notebook.c | 67 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 12 deletions(-) commit b389c604b6c9d82b3505e3935d7730d87856f7c7 Author: Bruno Brouard Date: Thu May 10 15:16:23 2012 +0200 Updated French translation po/fr.po | 544 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 287 insertions(+), 257 deletions(-) commit 9225b11112b04f621163ce11602d8f141a8d4277 Author: Bastien Nocera Date: Thu May 10 11:13:52 2012 +0100 shell: Update animated notebook TODO shell/TODO | 3 +++ 1 file changed, 3 insertions(+) commit c573a07b06989034751abe2df54315f37d260345 Author: Colin Walters Date: Wed May 9 13:14:32 2012 -0400 git.mk: Update from upstream git.mk | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) commit f8c0eceb80780a1e2d391a97e5f9ceca0c89b3ac Author: Bastien Nocera Date: Mon Apr 30 19:24:45 2012 +0100 shell: Use CcNotebook instead of GtkNotebook shell/cinnamon-control-center.c | 97 +++++++++++++++++++++----------------------- shell/shell.ui | 7 +--- 2 files changed, 48 insertions(+), 56 deletions(-) commit 74aa98b7c81b5a59577f2180352efdbce7235bcd Author: Bastien Nocera Date: Mon Apr 30 19:24:14 2012 +0100 shell: Add animated notebook Powered by gtk-clutter. configure.ac | 2 +- shell/Makefile.am | 7 + shell/TODO | 4 + shell/cc-notebook.c | 466 ++++++++++++++++++++++++++++++++++++++++++++++++++ shell/cc-notebook.h | 69 ++++++++ shell/test-notebook.c | 92 ++++++++++ 6 files changed, 639 insertions(+), 1 deletion(-) commit 8a01c7caf1a93ae7b973b2063fbdc5ce3dd57280 Author: Bastien Nocera Date: Mon Apr 30 18:04:33 2012 +0100 shell: Remove another use of page numbers shell/cinnamon-control-center.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) commit 43b53020cac5ca0c9ef2e1dfcf30ba9c6b49cdea Author: Bastien Nocera Date: Mon Apr 30 18:03:50 2012 +0100 shell: Move helper functions shell/cinnamon-control-center.c | 60 ++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 30 deletions(-) commit e01e33e76e777142db01fa220c789779fd569256 Author: Bastien Nocera Date: Mon Apr 30 17:07:36 2012 +0100 shell: Remove prior panel at the last minute Once we've already switch to a new panel. shell/cinnamon-control-center.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) commit cdbd37fa47a7244e9aaba1cd03936677a7541bc7 Author: Bastien Nocera Date: Mon Apr 30 17:05:15 2012 +0100 shell: Add return value to activate_panel() shell/cinnamon-control-center.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) commit d25563f5c475fcc86740539013640178faea8e3e Author: Bastien Nocera Date: Mon Apr 30 17:00:33 2012 +0100 shell: Flatten activate_panel() And exit as soon as we fail. shell/cinnamon-control-center.c | 88 ++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 48 deletions(-) commit ec7f8c9b51d6fd490af1cafb101890e745ad0373 Author: Bastien Nocera Date: Mon Apr 30 16:29:07 2012 +0100 shell: Use widgets rather than page numbers To differentiate children of a GtkNotebook. shell/cinnamon-control-center.c | 69 ++++++++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 19 deletions(-) commit cd867b1158f5fca433e7920aa84eb4e6f7080d7b Author: William Jon McCann Date: Tue May 8 16:14:57 2012 -0400 Adapt to gnome-desktop API change for display labels GdkColor -> GdkRGBA configure.ac | 2 +- panels/display/cc-display-panel.c | 21 ++++++++------------- 2 files changed, 9 insertions(+), 14 deletions(-) commit 22ed5a9fd565872eb3acd404b798739ac45455a8 Author: Bastien Nocera Date: Tue May 8 19:15:19 2012 +0100 shell: Check for small screen before showing window Map the window before displaying it, so we can maximise it straight away and avoid visible resizing. shell/cinnamon-control-center.c | 4 ++++ 1 file changed, 4 insertions(+) commit ecda0ad5c0d94236b6bf188fa31512309522e101 Author: Bastien Nocera Date: Tue May 8 19:12:46 2012 +0100 shell: Lower the small screen fixed height As this is the minimum size of the content view, not the whole window. shell/cinnamon-control-center.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 3bd227a9055746238d24ce777ded471a569f0376 Author: Bastien Nocera Date: Tue May 8 18:54:28 2012 +0100 shell: Maximise window on monitor size change When the monitor changes size, and we have a small screen, reset small_screen_set so that we maximise the window. shell/cinnamon-control-center.c | 3 +++ 1 file changed, 3 insertions(+) commit c3fa222461df600a863fa5411566a98a7db6cb3b Author: Bastien Nocera Date: Tue May 8 18:53:04 2012 +0100 Revert "shell: Reset "small_screen_set" when we use a big screen" This reverts commit 3e5f488160ff2ba72d6871a8b9848fb1206da3c8. shell/cinnamon-control-center.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) commit 3bc75764c654d62a421fcb7c3f5734a01f077901 Author: William Jon McCann Date: Tue May 1 13:30:18 2012 -0400 Use menubar style class for toolbar https://bugzilla.gnome.org/show_bug.cgi?id=673869 shell/shell.ui | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) commit f264ebea0bea905113de1d1e35a3db8f11a49357 Author: Bastien Nocera Date: Tue May 8 18:48:06 2012 +0100 shell: Set the minimum content height Instead of using gtk_widget_size_request() on the parent scrolled window, to make sure that border are taken into account when sizing the icon views. shell/cinnamon-control-center.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) commit 3e5f488160ff2ba72d6871a8b9848fb1206da3c8 Author: Bastien Nocera Date: Tue May 8 18:46:22 2012 +0100 shell: Reset "small_screen_set" when we use a big screen Otherwise we wouldn't maximise the screen again. shell/cinnamon-control-center.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) commit 9c2e8c28f53025e3aa5d9596b36f1581897d0301 Author: Jon McCann Date: Thu Apr 12 16:02:36 2012 -0400 Hide window titlebar when maximized https://bugzilla.gnome.org/show_bug.cgi?id=673869 shell/cinnamon-control-center.c | 1 + 1 file changed, 1 insertion(+) commit 796d4ebafad432e9d9723781e831f3cf3f25c838 Author: Jon McCann Date: Tue Apr 10 18:04:38 2012 -0400 Fit three columns of search results And center labels vertically that have no search matching text. https://bugzilla.gnome.org/show_bug.cgi?id=673869 shell/cinnamon-control-center.c | 8 ++++++-- shell/shell-search-renderer.c | 15 +++++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) commit 620e70113c30b0ae868577153dda60139f3c20b4 Author: Jon McCann Date: Tue Apr 10 16:55:26 2012 -0400 Add horizontal separators between sections Based on patch from Ubuntu https://bugzilla.gnome.org/show_bug.cgi?id=673869 shell/cinnamon-control-center.c | 10 ++++++++++ 1 file changed, 10 insertions(+) commit 599f19a595331db6a79d964f71168a3249cb9493 Author: Jon McCann Date: Tue Apr 10 16:42:09 2012 -0400 Increase icon size to 48px https://bugzilla.gnome.org/show_bug.cgi?id=673869 shell/cc-shell-model.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit ad0e02f100966c244aef9f4b1710c561bf9cb899 Author: Jon McCann Date: Tue May 8 16:56:20 2012 +0100 shell: Be smarter about smaller screen sizes Make the minimum window size smaller, and the window resizable when using small screens. Based on patch from Ubuntu https://bugzilla.gnome.org/show_bug.cgi?id=673869 shell/cinnamon-control-center.c | 106 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 102 insertions(+), 4 deletions(-) commit d955d484da02871e146f7bd1d4d9ef32f0000c14 Author: Jon McCann Date: Tue May 8 16:43:57 2012 +0100 shell: Increase default window size https://bugzilla.gnome.org/show_bug.cgi?id=673869 shell/cinnamon-control-center.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit b393ca6d022a1c4b71d1d6ed316cbcc4f4998a35 Author: Bastien Nocera Date: Tue May 8 16:37:51 2012 +0100 shell: Move all sizing hacks in one location And make sure that the overview has no scrollbars to start with. Add a FIXME to handle smaller sized screens later on. shell/cinnamon-control-center.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) commit 241e6186e0315ebbe02e2cf4bf8d89895314b21a Author: Reinout van Schouwen Date: Thu May 3 01:15:52 2012 +0200 Updated Dutch translation by Hannie Dumoleyn. Reviewed by Reinout van Schouwen po/nl.po | 6165 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 3426 insertions(+), 2739 deletions(-) commit d009a3fc352287306035230fa58d3e56a65ab80a Author: William Jon McCann Date: Tue May 1 14:55:43 2012 -0400 Revert "Increase icon size to 48px" This reverts commit c8c8720d726b78a66ff2f2c6a8061c377ccd76e3. shell/cc-shell-model.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 9d55273c147c2a2782168bcc8e0925cc4e9e27aa Author: William Jon McCann Date: Tue May 1 14:55:42 2012 -0400 Revert "Increase default window size" This reverts commit f36d42b9d109dc2636be7d4c8d104f608b3706fa. shell/cinnamon-control-center.c | 122 ++----------------------------------------- shell/shell.ui | 2 +- 2 files changed, 6 insertions(+), 118 deletions(-) commit 523a85f70474d93b44e7a1ec7578547400dcc024 Author: William Jon McCann Date: Tue May 1 14:55:41 2012 -0400 Revert "Add horizontal separators between sections" This reverts commit e924ea03fa6c3621bdcf17e629d6b1383156c3dd. shell/cinnamon-control-center.c | 10 ---------- 1 file changed, 10 deletions(-) commit 29792b41e5e06a8267586daa75a790383a195cc9 Author: William Jon McCann Date: Tue May 1 14:55:40 2012 -0400 Revert "Fit three columns of search results" This reverts commit 2d145a6fa4b21a5b558597ab9b6dde460a41a4f6. shell/shell-search-renderer.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) commit b796b4c3767e7dfb6f36a957b2a7c38fd7b8bd9a Author: William Jon McCann Date: Tue May 1 14:55:38 2012 -0400 Revert "Hide window titlebar when maximized" This reverts commit 700ea6a1aa23c1738b0cb444a032a607df66ae82. shell/cinnamon-control-center.c | 1 - 1 file changed, 1 deletion(-) commit d8e10a566cd950cf96a0010381ce8cab351ee61b Author: William Jon McCann Date: Tue May 1 14:55:28 2012 -0400 Revert "Use menubar style class for toolbar" This reverts commit b1431c00e04692d4be38fde769591c987516b2fc. shell/shell.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit b1431c00e04692d4be38fde769591c987516b2fc Author: William Jon McCann Date: Tue May 1 13:30:18 2012 -0400 Use menubar style class for toolbar shell/shell.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 700ea6a1aa23c1738b0cb444a032a607df66ae82 Author: Jon McCann Date: Thu Apr 12 16:02:36 2012 -0400 Hide window titlebar when maximized https://bugzilla.gnome.org/show_bug.cgi?id=673869 shell/cinnamon-control-center.c | 1 + 1 file changed, 1 insertion(+) commit 2d145a6fa4b21a5b558597ab9b6dde460a41a4f6 Author: Jon McCann Date: Tue Apr 10 18:04:38 2012 -0400 Fit three columns of search results And center labels vertically that have no search matching text. https://bugzilla.gnome.org/show_bug.cgi?id=673869 shell/shell-search-renderer.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) commit e924ea03fa6c3621bdcf17e629d6b1383156c3dd Author: Jon McCann Date: Tue Apr 10 16:55:26 2012 -0400 Add horizontal separators between sections Based on patch from Ubuntu https://bugzilla.gnome.org/show_bug.cgi?id=673869 shell/cinnamon-control-center.c | 10 ++++++++++ 1 file changed, 10 insertions(+) commit f36d42b9d109dc2636be7d4c8d104f608b3706fa Author: Jon McCann Date: Tue Apr 10 16:52:15 2012 -0400 Increase default window size And be smarter about small screen sizes. Based on patch from Ubuntu https://bugzilla.gnome.org/show_bug.cgi?id=673869 shell/cinnamon-control-center.c | 122 +++++++++++++++++++++++++++++++++++++++++-- shell/shell.ui | 2 +- 2 files changed, 118 insertions(+), 6 deletions(-) commit c8c8720d726b78a66ff2f2c6a8061c377ccd76e3 Author: Jon McCann Date: Tue Apr 10 16:42:09 2012 -0400 Increase icon size to 48px https://bugzilla.gnome.org/show_bug.cgi?id=673869 shell/cc-shell-model.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 8cc0b7207b811c6c7de879ff9592a38ec5473023 Author: Bastien Nocera Date: Mon Apr 30 16:28:09 2012 +0100 shell: Fix GtkBuilder file for complaining glade shell/shell.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit f620c524259a63e25179273b3794e3d7718aa929 Author: Luca Ferretti Date: Mon Apr 30 15:05:23 2012 +0200 l10n: Updated Italian translation po/it.po | 2592 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 1295 insertions(+), 1297 deletions(-) commit f232788c6ccab0524f38a196f279dabbb3e35076 Author: Bastien Nocera Date: Mon Apr 30 13:43:33 2012 +0100 shell: Fix missing sedding shell/cc-strength-bar.c | 4 ++-- shell/cc-strength-bar.h | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) commit 656862e697523f40f712f9bcf887f39b4e72b0a7 Author: Cosimo Cecchi Date: Tue Mar 27 17:42:40 2012 -0400 bluetooth: don't set a shadow type on the viewport https://bugzilla.gnome.org/show_bug.cgi?id=672956 panels/bluetooth/bluetooth.ui | 2 ++ 1 file changed, 2 insertions(+) commit 5edec8138b127d0e783918c6860aca35345e7d8e Author: Cosimo Cecchi Date: Tue Mar 27 17:42:25 2012 -0400 shell: don't set a shadow type on the GtkViewport https://bugzilla.gnome.org/show_bug.cgi?id=672956 shell/shell.ui | 1 + 1 file changed, 1 insertion(+) commit 84084b28d4d34355fb141644c26333853d5b0be1 Author: Kjartan Maraas Date: Mon Apr 30 11:10:11 2012 +0200 Updated Norwegian bokmĆ„l translation po/nb.po | 207 +++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 115 insertions(+), 92 deletions(-) commit 0bb2e2142a801178c44c23ccebb975e3987221bd Author: Jon McCann Date: Wed Mar 28 15:01:53 2012 -0400 background: Sort Pictures folder by name https://bugzilla.gnome.org/show_bug.cgi?id=672925 panels/background/bg-pictures-source.c | 42 ++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) commit a3055b3202ca4446f15fa7941c25811a7b4e2f7c Author: Bastien Nocera Date: Thu Apr 26 11:07:08 2012 +0100 background: Ignore screenshots Don't list screenshots coming from gnome-screenshot in our Pictures source. https://bugzilla.gnome.org/show_bug.cgi?id=672925 panels/background/bg-pictures-source.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) commit f102ca7363651cb2b815198018b3d389257e7610 Author: Bastien Nocera Date: Wed Apr 25 20:01:14 2012 +0100 mouse: Update from gnome-settings-daemon panels/mouse/gsd-input-helper.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) commit a760238a67d26b3e4ae8fab4662ac9f49fdd1bcf Author: Bastien Nocera Date: Wed Apr 25 20:00:44 2012 +0100 wacom: Update from gnome-settings-daemon panels/wacom/gsd-input-helper.c | 16 +++++++++------- panels/wacom/gsd-wacom-device.c | 16 ++++++++++++++-- 2 files changed, 23 insertions(+), 9 deletions(-) commit bbdcabcaafc0b27ff8d06e77cf0e0307eb051a2d Author: Daniel Mustieles Date: Mon Apr 23 11:41:15 2012 +0200 Updated Spanish translation po/es.po | 191 ++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 110 insertions(+), 81 deletions(-) commit 87beb8b31aea8b399a8c94f4740476a8c13d37e9 Author: Yaron Shahrabani Date: Sun Apr 22 17:23:34 2012 +0300 Updated Hebrew translation. po/he.po | 86 +++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 53 insertions(+), 33 deletions(-) commit 9eeeeba8f8c99f6e95cc75888ccd4ff2f0100181 Author: Fran DiĆ©guez Date: Sun Apr 22 15:52:13 2012 +0200 Updated Galician translations po/gl.po | 87 ++++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 55 insertions(+), 32 deletions(-) commit 42aa44c68eab4d9e91c4dc1e61132efab9077e91 Author: Bastien Nocera Date: Mon Mar 26 17:01:33 2012 +0200 power: Add context for the battery levels https://bugzilla.gnome.org/show_bug.cgi?id=672738 panels/power/cc-power-panel.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) commit 0e49b5b88d3903f0caa90cc771aef211f68248c6 Author: Bastien Nocera Date: Mon Mar 26 17:00:35 2012 +0200 mouse: Add context for Low/High https://bugzilla.gnome.org/show_bug.cgi?id=672738 panels/mouse/gnome-mouse-properties.ui | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) commit 816b3f4dd0ea7c15fef02857ce917c340bc8006d Author: Yaron Shahrabani Date: Sun Apr 22 11:09:52 2012 +0300 Updated Hebrew translation. po/he.po | 2615 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 1312 insertions(+), 1303 deletions(-) commit 648ef0f5dab517d9b1da80a168d4285dcac3b0db Author: YunQiang Su Date: Fri Apr 20 20:28:54 2012 +0800 Fix zh_CN translation problem po/zh_CN.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit 214146426e01a1a58421eecfa7a0a8f0c5f31c14 Author: Fran DiĆ©guez Date: Thu Apr 19 19:46:59 2012 +0200 Updated Galician translations po/gl.po | 611 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 310 insertions(+), 301 deletions(-) commit 57078e0de914c17aef4fd5c3b689bf16cf08e918 Author: Fran DiĆ©guez Date: Fri Mar 16 23:17:59 2012 +0100 Little fix in Galician translations Signed-off-by: Fran DiĆ©guez po/gl.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit 3ae795ea6ec09c8a1d49533510904dec9425f617 Author: Debarshi Ray Date: Sat Apr 14 23:10:37 2012 +0200 online-accounts: goa_provider_show_account now expects GtkGrids, not GtkTable Fixes: https://bugzilla.gnome.org/669625 panels/online-accounts/cc-online-accounts-panel.c | 30 ++++++++++++++++------- 1 file changed, 21 insertions(+), 9 deletions(-) commit d6092763436100b22dcba7dbd9d90b8f4680b405 Author: Debarshi Ray Date: Mon Mar 12 20:28:11 2012 +0100 online-accounts: Fix spacing and alignment when showing accounts Implemented design: http://ur1.ca/8m05c https://live.gnome.org/Design/SystemSettings/OnlineAccounts Fixes: https://bugzilla.gnome.org/671980 panels/online-accounts/cc-online-accounts-panel.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) commit 07866aa933408219016195ae4fda50b94b638dd8 Author: Bastien Nocera Date: Thu Apr 19 14:26:11 2012 +0100 info: Ignore removable mounts That used to be in /media and are now in /run/media/$USERNAME/ panels/info/cc-info-panel.c | 1 + 1 file changed, 1 insertion(+) commit 3d063ebaf7c8b8c5123191425a03585a100a05cd Author: Bastien Nocera Date: Thu Apr 19 14:25:55 2012 +0100 info: Update from gnome-settings-daemon panels/info/gsd-disk-space-helper.c | 19 +++++++++++++++++++ panels/info/gsd-disk-space-helper.h | 1 + 2 files changed, 20 insertions(+) commit 9c56a95358fd2fa2d7692a040ce6bca2db81007c Author: Bastien Nocera Date: Thu Apr 19 12:00:04 2012 +0100 info: Ignore NFS mounts when calculating disk size https://bugzilla.gnome.org/show_bug.cgi?id=674356 panels/info/Makefile.am | 4 +++- panels/info/cc-info-panel.c | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) commit 18524ddb9db17a97b4a1c05b8ff2aef8fb7670b1 Author: Bastien Nocera Date: Thu Apr 19 11:59:41 2012 +0100 info: Add code to update disk space helper panels/info/Makefile.am | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) commit 27d917458d7b54580fd7417915ff23a9f5831dbf Author: Bastien Nocera Date: Thu Apr 19 11:58:29 2012 +0100 info: Update from gnome-settings-daemon panels/info/gsd-disk-space-helper.c | 105 ++++++++++++++++++++++++++++++++++++ panels/info/gsd-disk-space-helper.h | 38 +++++++++++++ 2 files changed, 143 insertions(+) commit 5a472dc515e784e645ae9bd4e82396d87c6817c3 Author: Bastien Nocera Date: Thu Apr 19 11:56:56 2012 +0100 mouse: Use update-from-gsd.sh to update input helper panels/mouse/Makefile.am | 6 ++++++ 1 file changed, 6 insertions(+) commit be45283bb43e3734de6cc6773bc589b51d120c0f Author: Bastien Nocera Date: Thu Apr 19 11:56:21 2012 +0100 mouse: Update from gnome-settings-daemon panels/mouse/gsd-input-helper.c | 343 ++++++++++++++++++++++++++++++++++++++-- panels/mouse/gsd-input-helper.h | 48 +++++- 2 files changed, 374 insertions(+), 17 deletions(-) commit 69b5afd9fed2c8f6b24e9c9706307df836d7a009 Author: Bastien Nocera Date: Thu Apr 19 11:50:58 2012 +0100 wacom: Move update-from-gsd.sh to root panels/wacom/Makefile.am | 4 ++-- panels/wacom/update-from-gsd.sh | 26 -------------------------- update-from-gsd.sh | 26 ++++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 28 deletions(-) commit eeed45ff81e6ae9be0f4b0a51136da200afc3156 Author: Kjartan Maraas Date: Wed Apr 18 20:29:42 2012 +0200 Updated Norwegian bokmĆ„l translation po/nb.po | 388 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 197 insertions(+), 191 deletions(-) commit 6b49166b70846d501287653c2349bb7123884b32 Author: Matej Urbančič Date: Mon Apr 16 22:31:06 2012 +0200 Updated Slovenian translation po/sl.po | 509 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 259 insertions(+), 250 deletions(-) commit 1798742050b3df00c7d68a10c66029f301172339 Author: Daniel Mustieles Date: Mon Apr 16 16:31:55 2012 +0200 Updated Spanish translation po/es.po | 577 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 293 insertions(+), 284 deletions(-) commit c642ca41d011ac3ac9b3ddeb7bfa84f97ccf69cc Author: Reşat SABIQ Date: Mon Apr 16 04:45:20 2012 -0500 Updated Crimean Tatar (Crimean Turkish) translation po/crh.po | 10251 ++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 7294 insertions(+), 2957 deletions(-) commit 8fe181c7ae6cdc25872d74284fcbaca40953d787 Author: Piotr Drąg Date: Mon Apr 16 01:19:29 2012 +0200 Updated POTFILES.in po/POTFILES.in | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) commit 8c123db9cab2042870a45575ed16ef9576c7aebe Author: Khaled Hosny Date: Sat Apr 14 23:26:11 2012 +0200 Updated Arabic translation po/ar.po | 174 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 87 insertions(+), 87 deletions(-) commit 6000ef1d63a80172cf778701d77cdd948294fe1a Author: Piotr Drąg Date: Sat Apr 14 18:49:22 2012 +0200 Updated Polish translation po/pl.po | 2665 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 1332 insertions(+), 1333 deletions(-) commit dc6dd8f9ecb7578233e0bcceea56c9b5d8f0e0f1 Author: Jiro Matsuzawa Date: Sat Apr 14 12:17:35 2012 +0900 [l10n] Update Japanese translation po/ja.po | 124 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 62 insertions(+), 62 deletions(-) commit 82aa5d01306e8435aff4ccc2ab7832d9ca422915 Author: Bastien Nocera Date: Fri Mar 30 11:34:47 2012 +0200 printers: Fix small memory leak https://bugzilla.gnome.org/show_bug.cgi?id=673151 panels/printers/pp-new-printer-dialog.c | 2 ++ 1 file changed, 2 insertions(+) commit f87e38441d080969dd3bd5b3e44efff8b2112488 Author: Marek Kasik Date: Fri Apr 13 13:16:08 2012 +0200 printers: A little correction of previous commit Correcting a little typo. panels/printers/pp-utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 5272bcc06d892c4066751afba8e17bc1df233220 Author: Marek Kasik Date: Fri Apr 13 13:09:38 2012 +0200 printers: Use PrinterAddOption method to set media size Use new cups-pk-helper's method PrinterAddOption for setting default media size for new printers. This fixes problem with setting default media size (#672694). panels/printers/pp-new-printer-dialog.c | 130 ++++++-------------------------- panels/printers/pp-utils.c | 67 ++++++++++++++++ panels/printers/pp-utils.h | 2 + 3 files changed, 90 insertions(+), 109 deletions(-) commit fa3c8585028ad61352a908f18b744a9991486de4 Author: Cosimo Cecchi Date: Mon Mar 26 15:40:52 2012 -0400 wacom: fix "Map to Monitor..." button alignment It should use the same align of the button next to it, i.e. 'center', or it will look bigger. https://bugzilla.gnome.org/show_bug.cgi?id=672873 panels/wacom/gnome-wacom-properties.ui | 1 + 1 file changed, 1 insertion(+) commit 89a5e737b092aa3c093b2ecb5866857b72660dd8 Author: Yaron Shahrabani Date: Thu Apr 12 18:02:53 2012 +0300 Updated Hebrew translation. po/he.po | 146 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 73 insertions(+), 73 deletions(-) commit ff31b771bbff300de4da4b4860d4ebdcd09acb6b Author: Peter Hutterer Date: Thu Apr 12 15:29:36 2012 +0200 wacom: update the UI if a new tool comes in The device_added_cb is called once for each tool added. The wacom driver hotplugs tools in the order stylus, eraser, cursor, pad. update_current_page will add a new page once a tablet has stylus and eraser, before cursor and pad exist. priv->pad is thus always NULL, causing, cc_wacom_page's update_tablet_ui to remove the "Map Buttons..." button for any device. Change the code to update the tool list for every new tool we get, merely triggering the visibility of the button instead of destroying it completely. https://bugzilla.gnome.org/show_bug.cgi?id=672691 panels/wacom/cc-wacom-page.c | 83 +++++++++++++++++++++++++++++++------------ panels/wacom/cc-wacom-page.h | 5 +++ panels/wacom/cc-wacom-panel.c | 11 +++--- 3 files changed, 71 insertions(+), 28 deletions(-) commit 0463ba862220ceb14433dbf1ab90043357bfeac7 Author: Bastien Nocera Date: Thu Apr 12 11:05:26 2012 +0100 wacom: Rename to "Wacom Tablet" The name of the panel is currently Wacom Graphics Tablet. This is really long and redundant. The name is also currently wrapped onto three lines. https://bugzilla.gnome.org/show_bug.cgi?id=673864 panels/wacom/gnome-wacom-panel.desktop.in.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 5a2daec0a364cee4addab3a93228c9a8469060f7 Author: Sebastien Bacher Date: Tue Apr 10 19:31:44 2012 +0200 wacom: Mark extra strings as translatable https://bugzilla.gnome.org/show_bug.cgi?id=673854 panels/wacom/cc-wacom-mapping-panel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit 8f7b92e89972c1fb80917384e26d05ffb3e7fc27 Author: Carles Ferrando Date: Wed Apr 11 00:11:02 2012 +0200 [l10n]Updated Catalan (Valencian) translation po/ca@valencia.po | 139 +++++++++++++++++++++++++++--------------------------- 1 file changed, 70 insertions(+), 69 deletions(-) commit 867787678d3c12af333a0e9c76f168ba76794b6c Author: Jordi Serratosa Date: Wed Apr 11 00:10:30 2012 +0200 [l10n] Fixes on Catalan translation po/ca.po | 103 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 52 insertions(+), 51 deletions(-) commit 04eca6d9515ea1eb6827f334d6c57c26b0e58718 Author: Michael Terry Date: Tue Apr 10 09:19:03 2012 -0400 user-accounts: Make controls insensitive when a user is not selected https://bugzilla.gnome.org/show_bug.cgi?id=671484l panels/user-accounts/data/user-accounts-dialog.ui | 1 + panels/user-accounts/um-user-panel.c | 3 +++ 2 files changed, 4 insertions(+) commit 80fdb0bee20af5c3f718bd09dccb2b34dad0aeba Author: Gabor Kelemen Date: Mon Apr 9 09:20:31 2012 +0300 display: Translate the rotation drop-down again The rotation combo box items on the Displays panel do not appear translated. This is because the items got translation context support in 5a5a037d09787da48f3c8b60ca5ce6dcb5ebcbf3, but to get the localized strings, one needs to use g_dpgettext2()[1], not gettext(). https://bugzilla.gnome.org/show_bug.cgi?id=673766 panels/display/cc-display-panel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit a47bdcfdb478554598faf416790ed2ca708e25d2 Author: Milo Casagrande Date: Sat Apr 7 17:51:58 2012 +0200 [l10n] Updated Italian translation po/it.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) commit 5605ba8336d19a0b30b8dd856811ff1d4c6ab275 Author: Milo Casagrande Date: Fri Apr 6 17:15:27 2012 +0200 [l10n] Updated Italian translation po/it.po | 2884 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 1448 insertions(+), 1436 deletions(-) commit 463090e67c69f2464c8a9dedc875113dd0249b7b Author: Neliton Pereira Jr Date: Wed Apr 4 16:03:04 2012 -0300 Fixed some strings in Brazilian Portuguese translation po/pt_BR.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit 9eb047baff69f78273e0be20c42c06cde7a2e27f Author: Richard Hughes Date: Mon Mar 26 17:48:23 2012 +0100 Always round up the CcStrengthBar rather than down It's a measure of completeness, not of progress. shell/cc-strength-bar.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) commit 13b534adb86ad601e7f637d6543e636b3b76092b Author: ManojKumar Giri Date: Tue Apr 3 20:40:37 2012 +0530 Updated Odia Translation po/or.po | 1550 ++++++++++++++++++++------------------------------------------ 1 file changed, 504 insertions(+), 1046 deletions(-) commit 4f090a1accca2a31b0f475ddc60eb9fcb9bb248b Author: ManojKumar Giri Date: Mon Apr 2 21:47:26 2012 +0530 Updated Odia Translation po/or.po | 747 ++++++++++++++++++++++++++------------------------------------- 1 file changed, 313 insertions(+), 434 deletions(-) commit 4ea22e9921de151614384a61159e20f6fd85049e Author: Bruno Brouard Date: Sun Apr 1 13:14:45 2012 +0200 Updated French translation po/fr.po | 162 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 81 insertions(+), 81 deletions(-) commit 3da4a4a5bf916fb134e4f59e2ccd9ce59cc32cd2 Author: Arash Mousavi Date: Sun Apr 1 01:02:00 2012 +0430 Updated Persian Translations po/fa.po | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) commit 064d02216dcd36c67a5e83e5c47c51a3e2bf8633 Author: Andrej ŽnidarÅ”ič Date: Fri Mar 30 15:40:34 2012 +0200 Updated Slovenian translation po/sl.po | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) commit f518abebe8e553ad1a44b67397fc2a4f73de7253 Author: Andrej ŽnidarÅ”ič Date: Thu Mar 29 20:21:07 2012 +0200 Updated Slovenian translation po/sl.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) commit ce7afa847139d5057599db5e82196501bc6d2b5b Author: Andrej ŽnidarÅ”ič Date: Wed Mar 28 15:16:46 2012 +0200 Updated Slovenian translation po/sl.po | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) commit f1dfd2968df725a0b506cc6061f9b2110e3631b8 Author: Shankar Prasad Date: Wed Mar 28 14:10:55 2012 +0530 Updated Kannada Translation po/kn.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit dac1f38f0f19e56744ca0acb40f8c81ae1320729 Author: Daniel Nylander Date: Wed Mar 28 08:06:05 2012 +0200 Updated Swedish translation po/sv.po | 297 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 150 insertions(+), 147 deletions(-) commit 0008d8fd8dd45e2d50cb8fdd252e5b1b896672e0 Author: Shankar Prasad Date: Tue Mar 27 19:15:02 2012 +0530 Updated Kannada Translation po/kn.po | 1147 +++++++++++++++++++++++++------------------------------------- 1 file changed, 466 insertions(+), 681 deletions(-) commit 2d0203bfad3d77d77a078c72f064cb07b582a2e5 Author: Matthias Clasen Date: Mon Mar 19 07:21:40 2012 -0400 common: Make insertion of new languages quicker See https://bugzilla.gnome.org/show_bug.cgi?id=672293#c6 panels/common/cc-common-language.c | 46 +++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 18 deletions(-) commit ee3f0720f2a22c9e829ba114713bfaf5b97cc8e2 Author: Bastien Nocera Date: Tue Mar 27 13:44:44 2012 +0200 common: Fix crash when filtering language list And it's still being populated. If the list gets filtered while it's being populated, we would end up with a row with NULL data, causing us to crash. Make sure to hold the GDK threads lock when reading from the list, to avoid racing with the insert code. http://bugzilla.gnome.org/show_bug.cgi?id=672293 panels/common/cc-language-chooser.c | 6 ++++++ 1 file changed, 6 insertions(+) commit 49ec6af014326efd0001dd1531d5b09cf22d2121 Author: Shankar Prasad Date: Tue Mar 27 10:51:20 2012 +0530 Updated Kannada Translation po/kn.po | 7188 ++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 4388 insertions(+), 2800 deletions(-) commit a7aa5f0c77277b9317cd77fbb832152920a9403e Author: Richard Hughes Date: Mon Mar 26 18:47:55 2012 +0100 trivial: Post branch version bump configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit bff2c80f0e3aa462f98d66df7be2da3d5738001e Author: Richard Hughes Date: Mon Mar 26 18:03:29 2012 +0100 3.4.0 NEWS | 27 +++++++++++++++++++++++++++ configure.ac | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) commit 2806e68657fe453a1db4e3232bc75a83fd318c61 Author: Richard Hughes Date: Mon Mar 26 11:16:01 2012 +0100 Fix a crash in the network panel by disconnecting idle sources If you open and close the network panel again and again at speed, you can trigger a crash. panels/network/cc-network-panel.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) commit cf01ab57dc812157aff83a5c91218c636a4dda16 Author: ManojKumar Giri Date: Mon Mar 26 13:21:29 2012 +0530 Updated Odia Translation po/or.po | 235 ++++++++++++++++++++++++++++----------------------------------- 1 file changed, 104 insertions(+), 131 deletions(-) commit 344a1c909bc64658ec9de990bf8e3055f36d4bff Author: Marek Černocký Date: Sun Mar 25 11:20:51 2012 +0200 Updated Czech translation po/cs.po | 3805 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 1911 insertions(+), 1894 deletions(-) commit 9ae5305a303980d56f23f916451458799a8c1b1a Author: Sasi Bhushan Date: Sun Mar 25 13:30:13 2012 +0530 Updated Telugu translation po/te.po | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) commit 34f0b87d5af317e492698192467d5276a5bcce8b Author: Christian Kirbach Date: Sat Mar 24 20:14:45 2012 +0100 [l10n] Updated German translation po/de.po | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) commit 2021bbc433e3b50488e01f1e0ed1b86ca7c633c3 Author: Takayuki KUSANO Date: Sun Mar 25 02:48:03 2012 +0900 Updated Japanese translation. po/ja.po | 403 ++++++++++++++++++++++++++------------------------------------- 1 file changed, 167 insertions(+), 236 deletions(-) commit 6298fe50dc2534cbef0e62bf99c5cab4bd7cdabd Author: Yaron Shahrabani Date: Sat Mar 24 19:13:57 2012 +0200 Updated Hebrew translation. po/he.po | 231 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 117 insertions(+), 114 deletions(-) commit 16c0d49a3b3a07467f42b9e2766eb6e5aa68b972 Author: Sasi Bhushan Boddepalli Date: Sat Mar 24 17:02:42 2012 +0530 Updated Telugu Translation po/te.po | 143 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 72 insertions(+), 71 deletions(-) commit 30a9c7c7a719650f5ee95966f4cdca8b5ec18c90 Author: Marek Kasik Date: Fri Mar 23 14:30:24 2012 +0100 printers: Fix crash in actualize_printers_list() This fixes a typo in handling of printers options in actualize_printers_list() which caused a crash when number of printers exceeded number of options (#672689). panels/printers/cc-printers-panel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit 4cb845983d112be99448d390c56a4b3660a5b285 Author: Kjartan Maraas Date: Fri Mar 23 13:24:59 2012 +0100 Updated Norwegian bokmĆ„l translation po/nb.po | 72 ++++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 36 insertions(+), 36 deletions(-) commit 79c8f3f3bbaa41ed018cb06399f55b719df0d1b4 Author: Praveen Illa Date: Fri Mar 23 15:05:48 2012 +0530 Updated Telugu Translation po/te.po | 374 ++++++++++++++++++++++++++------------------------------------- 1 file changed, 152 insertions(+), 222 deletions(-) commit afbf8eef408b60a62fbffb75821546d6e689d55c Author: Nguyį»…n ThĆ”i Ngį»c Duy Date: Thu Mar 22 10:25:05 2012 +0700 Updated Vietnamese translation po/vi.po | 51 +++++++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 26 deletions(-) commit 8b2c01c75b5826cbb63e2a0d717548e77d557011 Author: Nguyį»…n ThĆ”i Ngį»c Duy Date: Thu Mar 22 10:03:39 2012 +0700 po/vi: import from Damned Lies po/vi.po | 302 ++++++++++++++++++--------------------------------------------- 1 file changed, 83 insertions(+), 219 deletions(-) commit bb5e8cafaeee9f4de25ab65de97497513ae67ccb Author: Duarte Loreto Date: Wed Mar 21 23:55:49 2012 +0000 Updated Portuguese translation po/pt.po | 6033 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 3340 insertions(+), 2693 deletions(-) commit 473cec42ebc87d9e28204c8b8458c8105e773956 Author: Aurimas Černius Date: Thu Mar 22 00:01:07 2012 +0200 Updated Lithuanian translation po/lt.po | 3359 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 1864 insertions(+), 1495 deletions(-) commit e6061221713a885f0096603d5cc0977d0be163a0 Author: Timo Jyrinki Date: Wed Mar 21 18:14:12 2012 +0200 Updated Finnish translation by Jiri Grƶnroos. po/fi.po | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) commit fb84f3dcd3ff7e5bedc6ba76844d33afed259e25 Author: Khaled Hosny Date: Wed Mar 21 17:12:30 2012 +0200 Updated Arabic translation po/ar.po | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) commit de0f8fd5e7531ecded0d9976d5e84aa24524a3e3 Author: Khaled Hosny Date: Wed Mar 21 17:08:38 2012 +0200 Typo po/ar.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit cddee53cf292052c2ab2e502f9e807a008bf824d Author: Automatic Mirroring Date: Wed Mar 21 13:15:05 2012 +0000 Update Simplified Chinese translation. po/zh_CN.po | 466 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 244 insertions(+), 222 deletions(-) commit a581b35e7f12a3ef45481f762a60350020ef779d Author: Nilamdyuti Goswami Date: Wed Mar 21 17:49:07 2012 +0530 Assamese translation updated po/as.po | 1135 +++++++++++++++++++++++++++++--------------------------------- 1 file changed, 522 insertions(+), 613 deletions(-) commit 5c999a17f14c0311eb766f4515fbf0a560b94365 Author: Nilamdyuti Goswami Date: Wed Mar 21 13:23:29 2012 +0530 Assamese translation updated po/as.po | 359 +++++++++++++++++++++++++-------------------------------------- 1 file changed, 143 insertions(+), 216 deletions(-) commit 9a11f006924d2d91bd7fa86e15769e04c35abdf8 Author: Timo Jyrinki Date: Tue Mar 20 18:55:22 2012 +0200 Updated Finnish translation po/fi.po | 482 ++++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 309 insertions(+), 173 deletions(-) commit c5d8731fb4cff70d6df938227957abad99217fb8 Author: Nilamdyuti Goswami Date: Tue Mar 20 20:59:02 2012 +0530 Assamese translation updated po/as.po | 601 ++++++++++++++++++++++++++------------------------------------- 1 file changed, 250 insertions(+), 351 deletions(-) commit b5ced40020b1298666eb6c1cddd5c4060612ac18 Author: ManojKumar Giri Date: Tue Mar 20 13:56:02 2012 +0530 Updated Odia Translation po/or.po | 9060 ++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 6159 insertions(+), 2901 deletions(-) commit 14aba24c26e7c87dc8c910e542e96ab4170b81de Author: Rajesh Ranjan Date: Tue Mar 20 13:23:00 2012 +0530 hindi translation by Chandan Kumar po/hi.po | 6239 +++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 3949 insertions(+), 2290 deletions(-) commit 38bc6a745337a6b3604b1cfe7e261078b418122b Author: Nilamdyuti Goswami Date: Mon Mar 19 20:58:50 2012 +0530 Assamese translation updated po/as.po | 489 ++++++++++++++++++++++++++------------------------------------- 1 file changed, 205 insertions(+), 284 deletions(-) commit d1cdbd2fd3bb8d10dffda270493b5edb19d11dfe Author: Nilamdyuti Goswami Date: Mon Mar 19 18:23:14 2012 +0530 Assamese translation updated po/as.po | 9309 ++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 6340 insertions(+), 2969 deletions(-) commit 5f614d6361147916365e75cd8c44a2fdb7cb7c1b Author: Richard Hughes Date: Mon Mar 19 09:49:32 2012 +0000 3.3.92 NEWS | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 2 +- 2 files changed, 62 insertions(+), 1 deletion(-) commit ed4f55db3c6b3af191bc65cc7a4bbcfd5d3a3dae Author: Kenneth Nielsen Date: Mon Mar 19 10:04:33 2012 +0100 Updated Danish translation po/da.po | 321 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 166 insertions(+), 155 deletions(-) commit ea3993c40ed906b832d02876e1f719d4b58d16b4 Author: Carles Ferrando Date: Mon Mar 19 01:16:58 2012 +0100 [l10n]Updated Catalan (Valencian) translation po/ca@valencia.po | 6057 +++++++++++++++++++++++++++++------------------------ 1 file changed, 3303 insertions(+), 2754 deletions(-) commit 536faec936c04b1368e1afdbedb438ca183ab70e Author: Joan Duran Date: Mon Mar 19 01:16:48 2012 +0100 [l10n] Updated Catalan translation po/ca.po | 6209 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 3450 insertions(+), 2759 deletions(-) commit 967d9ae1b80d5f212461eb32dd65778127fbc81f Author: Daniel Korostil Date: Sun Mar 18 17:26:18 2012 +0200 Uploaded Ukranian po/uk.po | 126 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 63 insertions(+), 63 deletions(-) commit 3359d0e5abc782cdbd629fd74552f797687a9dce Author: Mario BlƤttermann Date: Sun Mar 18 02:14:30 2012 +0100 [l10n] Updated German translation po/de.po | 3442 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 1889 insertions(+), 1553 deletions(-) commit 1cd12c0f3bb68a9f4957817ec16681092a9f819f Author: Abderrahim Kitouni Date: Sat Mar 17 17:54:51 2012 +0100 Fix a small error in Arabic translation po/ar.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 83c3cf20b70923d4c9dbd2fb43713cc860d8aa70 Author: Pin-hsien Li Date: Sat Mar 17 14:16:34 2012 +0800 Updated Traditional Chinese translation(Hong Kong and Taiwan) po/zh_HK.po | 357 +++++++++++++++++++++++++++++++----------------------------- po/zh_TW.po | 357 +++++++++++++++++++++++++++++++----------------------------- 2 files changed, 368 insertions(+), 346 deletions(-) commit c31f2eed794ed2be4c17ca7c1c85eb41eebe930d Author: Richard Hughes Date: Fri Mar 16 12:45:13 2012 +0000 color: Prevent a crash when hotplugging monitors when the color panel is open panels/color/cc-color-panel.c | 8 ++++++++ 1 file changed, 8 insertions(+) commit 2b1fa69453859c36b9352aa49dd873f3742d535a Author: Praveen Arimbrathodiyil Date: Fri Mar 16 18:06:29 2012 +0530 Malayalam translation updated by Sadiq and me po/ml.po | 8636 ++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 5848 insertions(+), 2788 deletions(-) commit ac8ca99e6515b272a964109db210164c4a8d0f47 Author: Arash Mousavi Date: Thu Mar 15 20:23:57 2012 +0330 Updated Persian Translations po/fa.po | 6139 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 3448 insertions(+), 2691 deletions(-) commit 0727c1e9301e151c2ce368952c1e32757f4186a2 Author: Khaled Hosny Date: Thu Mar 15 18:10:27 2012 +0200 Updated Arabic translation po/ar.po | 2483 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 1235 insertions(+), 1248 deletions(-) commit df164193bbdad03ab99839097b208b20f315bf7f Author: Richard Hughes Date: Thu Mar 15 11:59:04 2012 +0000 color: Don't allow the user to add existing profiles to devices The existing code prevents the user from adding the existing default device profile to the device again, but to prevent a warning message we need to prevent the user from selecting *any* of the profiles already assigned to the device. panels/color/cc-color-panel.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) commit eb42930f97271cb611fde7a73b47cf71ddfc9684 Author: Yuri Myasoedov Date: Thu Mar 15 14:27:34 2012 +0400 Fixed Russian translation po/ru.po | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) commit 5d4510504331f1a22311c6979fd98f60f7d14891 Author: Sweta Kothari Date: Thu Mar 15 13:05:10 2012 +0530 Updated Gujarati Translations po/gu.po | 6384 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 3553 insertions(+), 2831 deletions(-) commit e07394eee15b645c1140b9694a02e6fed7aebd3f Author: A S Alam Date: Thu Mar 15 06:48:20 2012 +0530 update Punjabi Translation po/pa.po | 414 +++++++++++++++++++++------------------------------------------ 1 file changed, 139 insertions(+), 275 deletions(-) commit b1741edc0876fbada7a1a961f476ed80f58856d2 Author: Enrico Nicoletto Date: Wed Mar 14 17:45:31 2012 -0300 Updated Brazilian Portuguese translation po/pt_BR.po | 6336 ++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 3457 insertions(+), 2879 deletions(-) commit 4db95ec07f3f43e72c40358de04d0b5a8abe8eef Author: Gabor Kelemen Date: Wed Mar 14 02:22:27 2012 +0100 Updated Hungarian translation po/hu.po | 5827 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 3268 insertions(+), 2559 deletions(-) commit f7d409964dcee95171c93c36dec5b2223cf06966 Author: Rudolfs Mazurs Date: Tue Mar 13 23:20:31 2012 +0200 Updated Latvian translation. po/lv.po | 6681 ++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 3860 insertions(+), 2821 deletions(-) commit 3964582635d229662a88ebf7c2aa6e31d6dc7534 Author: Peter Hutterer Date: Tue Mar 13 19:08:38 2012 +0100 mouse: Don't enable two-finger scrolling based on width Reverts part of 109b36919921d757b93b91e8082620078608967e Good idea in principle, albeit the hardware gets in our way. In synaptics 1.4 two-finger emulation was enabled by default on devices that reported finger width but had to since revert this. The hardware doesn't really separate width and pressure, so a hard tap off a finger gives a high width, a wide finger gives a high pressure on light touches. We got spurious right-click presses when two-finger emulation was enabled. Now we have the control-center providing a checkbox for two-finger emulation but it doesn't enable emulation, which to the users appears as if two-finger scrolling is broken (https://bugzilla.redhat.com/show_bug.cgi?id=738123). We now disable the checkbox again for hardware that doesn't do two-fingers. it's not reliable and we're likely to see further bugs when the spurious right clicks take effect https://bugzilla.gnome.org/show_bug.cgi?id=661963 panels/mouse/gnome-mouse-properties.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit 75ea35d9393bef35575b56aa70785d5cc54310f3 Author: Kjartan Maraas Date: Mon Mar 12 18:50:00 2012 +0100 Updated Norwegian bokmĆ„l translation po/nb.po | 265 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 137 insertions(+), 128 deletions(-) commit bd41bd788be0f999e95ddb9a7b1ea8f507733646 Author: Bastien Nocera Date: Mon Mar 12 16:37:53 2012 +0100 datetime: Fix broken time setting on 32-bit machines time_t might be a 32-bit integer, which wouldn't be big enough to contain the number of microseconds since Epoch (since it can only fit the number of seconds from Epoch until 2038). https://bugzilla.redhat.com/show_bug.cgi?id=795792 panels/datetime/cc-datetime-panel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit a0d0da46b2e218848c154f3af99d9376c734ed80 Author: Timo Jyrinki Date: Mon Mar 12 11:03:00 2012 +0200 Finnish translation update from http://l10n.laxstrom.name/wiki/Gnome_3.4 translation sprint po/fi.po | 3745 ++++++++++++++------------------------------------------------ 1 file changed, 824 insertions(+), 2921 deletions(-) commit b0071c9a63eb5e066461ef10459d32a7e2a89a25 Author: ŠœŠøŃ€Š¾ŃŠ»Š°Š² ŠŠøŠŗŠ¾Š»ŠøŃ› Date: Sat Mar 10 23:05:07 2012 +0100 Updated Serbian translation po/sr.po | 231 +++++++++++++++++++++++++++++---------------------------- po/sr@latin.po | 231 +++++++++++++++++++++++++++++---------------------------- 2 files changed, 234 insertions(+), 228 deletions(-) commit 769aef9a5d0f2c953eda5bc2733350d487e38764 Author: Ibrahim Saed Date: Sat Mar 10 19:56:15 2012 +0100 Updated Arabic translation po/ar.po | 5740 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 3129 insertions(+), 2611 deletions(-) commit 7c3943a093523151707200044ef6fd37e778ce03 Author: Seong-ho, Cho Date: Sat Mar 10 22:17:54 2012 +0900 Updated Korean translation po/ko.po | 6554 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 3619 insertions(+), 2935 deletions(-) commit 5e78f3185c6bc701970ea7d5a951ec969ce27601 Author: Richard Hughes Date: Sat Mar 10 09:03:26 2012 +0000 color: Do not select the device in the treeview if it changes This prevents the treeview 'flickering' when going from selected device1->profile1 to device2->profile1. panels/color/cc-color-panel.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) commit 57fa4dcc186d6fcd718f9c1bb08e657133378646 Author: Bruno Brouard Date: Fri Mar 9 22:49:20 2012 +0100 Updated French translation po/fr.po | 5912 ++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 3063 insertions(+), 2849 deletions(-) commit c8d4af99b72fb8537f2da50357ab58d7844c76d1 Author: Daniel Korostil Date: Fri Mar 9 15:43:21 2012 +0200 Uploaded Ukranian po/uk.po | 5972 ++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 3448 insertions(+), 2524 deletions(-) commit 2b19f30b42fb3f33a069f8fc1ba59a2d736d3a59 Author: Nguyį»…n ThĆ”i Ngį»c Duy Date: Fri Mar 9 11:33:17 2012 +0700 Updated Vietnamese translation po/vi.po | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) commit cbdcc60a8531c0a03e8ca19927b3a264cd48cd64 Author: Praveen Illa Date: Fri Mar 9 01:51:07 2012 +0530 Updated Telugu Translation po/te.po | 6200 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 3372 insertions(+), 2828 deletions(-) commit 96b404c53772a00f9a2efc5a5c074a448599a513 Author: Bastien Nocera Date: Thu Mar 8 17:13:50 2012 +0100 user-accounts: Minimum of 200 width for the users list https://bugzilla.gnome.org/show_bug.cgi?id=671480 panels/user-accounts/um-user-panel.c | 3 +++ 1 file changed, 3 insertions(+) commit 48389f283a61f0890f1f89f7f265417bb9bc89eb Author: Colin Walters Date: Thu Mar 8 10:26:21 2012 -0500 build: Add missing git.mk to panels/color/icons panels/color/icons/16x16/Makefile.am | 2 ++ panels/color/icons/22x22/Makefile.am | 2 ++ panels/color/icons/24x24/Makefile.am | 2 ++ panels/color/icons/256x256/Makefile.am | 2 ++ panels/color/icons/32x32/Makefile.am | 2 ++ panels/color/icons/48x48/Makefile.am | 2 ++ panels/color/icons/64x64/Makefile.am | 2 ++ panels/color/icons/Makefile.am | 2 ++ panels/color/icons/scalable/Makefile.am | 1 + 9 files changed, 17 insertions(+) commit c48536c10262c39f9a3cb710a64b09f793cd523d Author: Bastien Nocera Date: Thu Mar 8 16:16:54 2012 +0100 universal-access: Hide zoom options when not in shell https://bugzilla.gnome.org/show_bug.cgi?id=671386 panels/universal-access/cc-ua-panel.c | 35 +++++++++++++++++++++++++++++++++++ panels/universal-access/uap.ui | 2 +- 2 files changed, 36 insertions(+), 1 deletion(-) commit d378dbae4880cc9cc9f47fa94a6b4fcb90036d44 Author: Colin Walters Date: Thu Mar 8 10:07:56 2012 -0500 build: Add missing include of git.mk in user-accounts/data/icons panels/user-accounts/data/icons/Makefile.am | 1 + 1 file changed, 1 insertion(+) commit 94555eadc83c0dc75aa2af6f3b2ad1055b8a71b7 Author: Bastien Nocera Date: Thu Mar 8 13:53:20 2012 +0100 common: Look harder for some languages It's fairly common to have de rather than de_DE translations, ditto for French and Spanish that share most of the vocabulary. panels/common/cc-common-language.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) commit 048a9bc85e594eeeac85dd6dc21815eae0c1be99 Author: Bastien Nocera Date: Wed Mar 7 17:13:55 2012 +0100 display: Sort resolutions by width first https://bugzilla.gnome.org/show_bug.cgi?id=671465 panels/display/cc-display-panel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit 57bba2631110359b8eb5c7eb558da6f18599a84e Author: Bastien Nocera Date: Wed Mar 7 18:27:25 2012 +0100 region: Fix possible crasher with empty layout panels/region/gnome-region-panel-system.c | 3 +++ 1 file changed, 3 insertions(+) commit 22ac9fa06bc6c4e797e80030dff4a93ff242d473 Author: Bastien Nocera Date: Wed Mar 7 18:12:12 2012 +0100 region: Don't make the dialogue overly wide https://bugzilla.gnome.org/show_bug.cgi?id=670667 panels/region/gnome-region-panel.ui | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) commit f75c06b9794daec6716ae7a83b5b91f52d098570 Author: Bastien Nocera Date: Wed Mar 7 17:07:31 2012 +0100 display: Use symbolic name panels/display/cc-display-panel.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) commit 6b6e17788ea96604ae22ccb59eb9f2b5f02fe63f Author: Bastien Nocera Date: Tue Mar 6 14:59:46 2012 +0100 display: Simplify add_key() calls and function panels/display/cc-display-panel.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) commit dd7c5fe67ac3bd0343674d8fe55821aeaa3995a1 Author: Bruce Cowan Date: Wed Mar 7 16:01:20 2012 +0000 Updated British English translation po/en_GB.po | 5951 +++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 3294 insertions(+), 2657 deletions(-) commit 08cf361129d46f3cf881ee7c1594c781178a2a49 Author: Yuri Myasoedov Date: Wed Mar 7 13:58:10 2012 +0400 Updated Russian translation po/ru.po | 349 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 169 insertions(+), 180 deletions(-) commit fb25a7857baa292f7610fe6c874a181d2b515dfa Author: Alexander Shopov Date: Wed Mar 7 06:47:21 2012 +0200 Updated Bulgarian translation po/bg.po | 230 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 115 insertions(+), 115 deletions(-) commit 09472ead247a691838621cc696a9a766f33bc47d Author: Nguyį»…n ThĆ”i Ngį»c Duy Date: Wed Mar 7 11:32:18 2012 +0700 po/vi.po: fix Bluetooth "visibility" translations po/vi.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) commit ecabd158711b2cac43a489855a0c471a7f7bd12c Author: Jiro Matsuzawa Date: Wed Mar 7 10:47:22 2012 +0900 [l10n] Update Japanese translation po/ja.po | 3245 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 1763 insertions(+), 1482 deletions(-) commit 97451c84e9516489102fd55d2736fd78b8e19644 Author: Matej Urbančič Date: Tue Mar 6 15:39:31 2012 +0100 Updated Slovenian translation po/sl.po | 3066 +++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 1644 insertions(+), 1422 deletions(-) commit daa86f15bce4277def58eb653b91496785b2d474 Author: Bastien Nocera Date: Mon Mar 5 19:30:35 2012 +0000 3.3.91 NEWS | 41 +++++++++++++++++++++++++++++++++++++++++ configure.ac | 2 +- 2 files changed, 42 insertions(+), 1 deletion(-) commit b328274e0eb56e2e5a056a5d8a7de81281178ce6 Author: Bastien Nocera Date: Mon Mar 5 19:05:08 2012 +0000 build: Require newest gnome-settings-daemon configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) commit 460d2574831a1fff186cc677c0417b794fb232e2 Author: Richard Hughes Date: Mon Mar 5 18:59:48 2012 +0000 info: Fix the updates state machine Resolves: https://bugzilla.gnome.org/show_bug.cgi?id=671393 panels/info/cc-info-panel.c | 7 +++++++ 1 file changed, 7 insertions(+) commit 13717dce8dd2ba4f546acd8d23348cbce2eeabc6 Author: Bastien Nocera Date: Mon Mar 5 18:32:52 2012 +0000 wacom: Update from gnome-settings-daemon panels/wacom/gsd-wacom-device.c | 38 ++++++++++++++++++++++---------------- panels/wacom/gsd-wacom-device.h | 1 + 2 files changed, 23 insertions(+), 16 deletions(-) commit bdb09755c8de06ed98050d57ee3ffc0aeca04d98 Author: Bastien Nocera Date: Mon Mar 5 18:27:18 2012 +0000 info: Remove unused icons In GNOME 3.2, the icons were hidden. Some changes in GTK+ mean that the icons are now visible. As we don't use them, remove them altogether. https://bugzilla.gnome.org/show_bug.cgi?id=671376 panels/info/cc-info-panel.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) commit 0c464812bbc7f379ebd40af13b12c0701fadce7e Author: Mattias PƵldaru Date: Mon Mar 5 18:20:17 2012 +0200 [l10n] Updated Estonian translation po/et.po | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) commit 7e5c60a81822a448087cf3d61f50ae4ca2b63a80 Author: Bastien Nocera Date: Mon Mar 5 14:15:16 2012 +0000 info: Avoid empty entries in "Other types" dialogue https://bugzilla.gnome.org/show_bug.cgi?id=671358 panels/info/cc-info-panel.c | 5 +++++ 1 file changed, 5 insertions(+) commit c5157bb545eb9e650b28bc3c1353c94970c6ffec Author: Matthias Clasen Date: Mon Mar 5 14:01:44 2012 +0000 info: handle dialog closing consistently The 'Other media' dialog is just hidden when the close button is clicked (so that it can be shown again), but when closing it with the Escape key, it gets destroyed and an attempt to bring it up again just shows a sad empty little square. https://bugzilla.gnome.org/show_bug.cgi?id=659948 panels/info/cc-info-panel.c | 4 ++++ 1 file changed, 4 insertions(+) commit d5afe63f898c54e13a5802038db62029d700c482 Author: Bastien Nocera Date: Thu Mar 1 18:02:00 2012 +0000 common: Add more debug to list-languages So we can print the name of the locales listed on the command-line. panels/common/list-languages.c | 11 +++++++++++ 1 file changed, 11 insertions(+) commit e3c3380feaf11e84b4a7f4629afbfec120ca1aa2 Author: Bastien Nocera Date: Thu Mar 1 17:54:13 2012 +0000 common: Fix crashes for incomplete locales By ignoring locales without language codes, or territory. https://bugzilla.gnome.org/show_bug.cgi?id=658551 panels/common/gdm-languages.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) commit 242bb936103b567210d7f67117e3f5003746e861 Author: Piotr Drąg Date: Sun Mar 4 22:42:14 2012 +0100 Updated Polish translation po/pl.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) commit ccf5376ec0ed668b4daab394cfc2f5c523c07875 Author: Fran DiĆ©guez Date: Sun Mar 4 20:15:58 2012 +0100 Updated Galician translations po/gl.po | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) commit 4a5cac0bfcfbd779e2d6503fff728b61cfa68083 Author: Fran DiĆ©guez Date: Sun Mar 4 19:58:48 2012 +0100 Updated Galician translations po/gl.po | 267 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 140 insertions(+), 127 deletions(-) commit 9a830b30964c0b3fe06a2c12210b1f1ac2ab10d5 Author: Daniel Mustieles Date: Sun Mar 4 19:28:32 2012 +0100 Updated Spanish translation po/es.po | 164 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 84 insertions(+), 80 deletions(-) commit 6c3a11207af22f884f9ddbd608dc6d5ff7b43035 Author: Inaki Larranaga Murgoitio Date: Sun Mar 4 17:08:10 2012 +0100 Updated Basque language po/eu.po | 6005 ++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 3735 insertions(+), 2270 deletions(-) commit ce9bdda6510ca7ae995b11b9d7af7b234b11fb50 Author: Ihar Hrachyshka Date: Sun Mar 4 14:33:36 2012 +0300 Updated Belarusian translation. po/be.po | 152 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 76 insertions(+), 76 deletions(-) commit 1091c88e8a4442f29de41e02728a8df3043f2a7f Author: Javier Jardón Date: Thu Mar 1 14:34:10 2012 +0000 power: reference to "Brightness and Lock" panel, not "Screen" The "Screen" panel has been renamed to "Brightness and Lock" Fixes https://bugzilla.gnome.org/show_bug.cgi?id=670567 Signed-off-by: Richard Hughes panels/power/cc-power-panel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit cd9bae5967f4ff3e1e479e13440a91e8e7c1b73a Author: Piotr Drąg Date: Sat Mar 3 22:35:46 2012 +0100 Updated Polish translation po/pl.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) commit f451ef818cb0860d14c11941116c46b259a7cc68 Author: Piotr Drąg Date: Sat Mar 3 22:25:44 2012 +0100 Updated Polish translation po/pl.po | 6063 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 3291 insertions(+), 2772 deletions(-) commit af6c80ec15c52f1b01279c0e24365b86a2904c5c Author: Nguyį»…n ThĆ”i Ngį»c Duy Date: Sat Mar 3 21:04:38 2012 +0700 Updated Vietnamese translation po/vi.po | 530 +++++++++++++++++++++++++-------------------------------------- 1 file changed, 208 insertions(+), 322 deletions(-) commit 8c6a1f974d95514957133bf50ec8c19d80ced8f9 Author: Nguyį»…n ThĆ”i Ngį»c Duy Date: Sat Mar 3 11:19:07 2012 +0700 po/vi.po: import from Damned Lies po/vi.po | 6393 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 3637 insertions(+), 2756 deletions(-) commit 74730321f936f0d05f814746008dd6ab5a9f9603 Author: Yaron Shahrabani Date: Fri Mar 2 14:08:37 2012 +0200 Updated Hebrew translation. po/he.po | 254 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 134 insertions(+), 120 deletions(-) commit 74450e3acdf65d728ecbba9f82085e406040f2d0 Author: Bastien Nocera Date: Thu Mar 1 17:11:14 2012 +0000 user-accounts: Fix sizing problems in user list About half-way through the user list, vertically, the user's name would get cut off. Showing the treeview headers showed that the "automatic login" pixbuf was added in a separate column. To make sizing easier, and avoid the user's name being cut off half-way through, add the "automatic-login" icon in the first column. https://bugzilla.gnome.org/show_bug.cgi?id=659998 panels/user-accounts/um-user-panel.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) commit 72e1e7aa49fb927b21a8f82c23d8f6f88d46593f Author: Mattias PƵldaru Date: Thu Mar 1 18:04:38 2012 +0200 [l10n] Updated Estonian translation po/et.po | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) commit 49f9de6182ff19dbfc13187dcca2fa5252c81a9f Author: Michael Terry Date: Thu Mar 1 16:00:09 2012 +0000 display: Fix crash when the screen setup changes after the Display panel has been closed. https://bugzilla.gnome.org/show_bug.cgi?id=670570 panels/display/cc-display-panel.c | 2 ++ 1 file changed, 2 insertions(+) commit 3844923a4bf42fe66bc5fed623152a5c4e4d3519 Author: Bastien Nocera Date: Thu Mar 1 10:25:34 2012 +0000 wacom: Fix crasher when XRandR isn't available Spotted by Olivier Fourdan panels/wacom/cc-wacom-mapping-panel.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) commit b97782616ee418b220c61ef41b9b62c4eb39b9ce Author: Cosimo Cecchi Date: Wed Feb 29 18:31:01 2012 -0500 network: fix huge inline toolbar icons Apparently GtkBuilder doesn't like too much True True 5 5 10 5 True True 1 0 True horizontal False True 0 True True False 0 True True False True True never automatic in True queue none True vertical True True automatic automatic in 1 True False view-grid-symbolic True 16 cinnamon-control-center-6.4.1/shell/cc-shell-category-view.h0000664000175000017500000000446614724311620022753 0ustar fabiofabio/* * Copyright (c) 2010 Intel, Inc. * * The Control Center 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. * * The Control Center 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 the Control Center; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Author: Thomas Wood */ #ifndef _CC_SHELL_CATEGORY_VIEW_H #define _CC_SHELL_CATEGORY_VIEW_H #include #include "cc-shell-item-view.h" G_BEGIN_DECLS #define CC_TYPE_SHELL_CATEGORY_VIEW cc_shell_category_view_get_type() #define CC_SHELL_CATEGORY_VIEW(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ CC_TYPE_SHELL_CATEGORY_VIEW, CcShellCategoryView)) #define CC_SHELL_CATEGORY_VIEW_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), \ CC_TYPE_SHELL_CATEGORY_VIEW, CcShellCategoryViewClass)) #define CC_IS_SHELL_CATEGORY_VIEW(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ CC_TYPE_SHELL_CATEGORY_VIEW)) #define CC_IS_SHELL_CATEGORY_VIEW_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), \ CC_TYPE_SHELL_CATEGORY_VIEW)) #define CC_SHELL_CATEGORY_VIEW_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), \ CC_TYPE_SHELL_CATEGORY_VIEW, CcShellCategoryViewClass)) typedef struct _CcShellCategoryView CcShellCategoryView; typedef struct _CcShellCategoryViewClass CcShellCategoryViewClass; typedef struct _CcShellCategoryViewPrivate CcShellCategoryViewPrivate; struct _CcShellCategoryView { GtkFrame parent; CcShellCategoryViewPrivate *priv; }; struct _CcShellCategoryViewClass { GtkFrameClass parent_class; }; GType cc_shell_category_view_get_type (void) G_GNUC_CONST; GtkWidget *cc_shell_category_view_new (const gchar *name, GtkTreeModel *model); CcShellItemView* cc_shell_category_view_get_item_view (CcShellCategoryView *self); G_END_DECLS #endif /* _CC_SHELL_CATEGORY_VIEW_H */ cinnamon-control-center-6.4.1/shell/cc-shell-category-view.c0000664000175000017500000001503214724311620022735 0ustar fabiofabio/* * Copyright (c) 2010 Intel, Inc. * * The Control Center 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. * * The Control Center 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 the Control Center; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Author: Thomas Wood */ #include "cc-shell-category-view.h" #include "cc-shell-item-view.h" #include "cc-shell.h" #include "cc-shell-model.h" G_DEFINE_TYPE (CcShellCategoryView, cc_shell_category_view, GTK_TYPE_FRAME) #define SHELL_CATEGORY_VIEW_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_SHELL_CATEGORY_VIEW, CcShellCategoryViewPrivate)) enum { PROP_NAME = 1, PROP_MODEL }; struct _CcShellCategoryViewPrivate { gchar *name; GtkTreeModel *model; GtkWidget *iconview; }; static void cc_shell_category_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { CcShellCategoryViewPrivate *priv = CC_SHELL_CATEGORY_VIEW (object)->priv; switch (property_id) { case PROP_NAME: g_value_set_string (value, priv->name); break; case PROP_MODEL: g_value_set_object (value, priv->model); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void cc_shell_category_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { CcShellCategoryViewPrivate *priv = CC_SHELL_CATEGORY_VIEW (object)->priv; switch (property_id) { case PROP_NAME: priv->name = g_value_dup_string (value); break; case PROP_MODEL: priv->model = g_value_dup_object (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void cc_shell_category_view_dispose (GObject *object) { CcShellCategoryViewPrivate *priv = CC_SHELL_CATEGORY_VIEW (object)->priv; if (priv->model) { g_object_unref (priv->model); priv->model = NULL; } G_OBJECT_CLASS (cc_shell_category_view_parent_class)->dispose (object); } static void cc_shell_category_view_finalize (GObject *object) { CcShellCategoryViewPrivate *priv = CC_SHELL_CATEGORY_VIEW (object)->priv; if (priv->name) { g_free (priv->name); priv->name = NULL; } G_OBJECT_CLASS (cc_shell_category_view_parent_class)->finalize (object); } static void cc_shell_category_view_constructed (GObject *object) { CcShellCategoryViewPrivate *priv = CC_SHELL_CATEGORY_VIEW (object)->priv; GtkWidget *iconview, *vbox; GtkCellRenderer *renderer; iconview = cc_shell_item_view_new (); gtk_icon_view_set_model (GTK_ICON_VIEW (iconview), priv->model); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); renderer = gtk_cell_renderer_pixbuf_new (); g_object_set (renderer, "follow-state", TRUE, NULL); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (iconview), renderer, FALSE); gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (iconview), renderer, "pixbuf", COL_PIXBUF); gtk_icon_view_set_text_column (GTK_ICON_VIEW (iconview), COL_NAME); gtk_icon_view_set_item_width (GTK_ICON_VIEW (iconview), 100); cc_shell_item_view_update_cells (CC_SHELL_ITEM_VIEW (iconview)); /* create the header if required */ if (priv->name) { GtkWidget *label; PangoAttrList *attrs; label = gtk_label_new (priv->name); attrs = pango_attr_list_new (); pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD)); gtk_label_set_attributes (GTK_LABEL (label), attrs); pango_attr_list_unref (attrs); gtk_frame_set_label_widget (GTK_FRAME (object), label); gtk_widget_show (label); } /* add the iconview to the vbox */ gtk_box_pack_start (GTK_BOX (vbox), iconview, FALSE, TRUE, 0); /* add the main vbox to the view */ gtk_container_add (GTK_CONTAINER (object), vbox); gtk_widget_show_all (vbox); priv->iconview = iconview; } static void cc_shell_category_view_class_init (CcShellCategoryViewClass *klass) { GParamSpec *pspec; GObjectClass *object_class = G_OBJECT_CLASS (klass); g_type_class_add_private (klass, sizeof (CcShellCategoryViewPrivate)); object_class->get_property = cc_shell_category_view_get_property; object_class->set_property = cc_shell_category_view_set_property; object_class->dispose = cc_shell_category_view_dispose; object_class->finalize = cc_shell_category_view_finalize; object_class->constructed = cc_shell_category_view_constructed; pspec = g_param_spec_string ("name", "Name", "Name of the category", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_NAME, pspec); pspec = g_param_spec_object ("model", "Model", "Model of the category", GTK_TYPE_TREE_MODEL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_MODEL, pspec); } static void cc_shell_category_view_init (CcShellCategoryView *self) { self->priv = SHELL_CATEGORY_VIEW_PRIVATE (self); gtk_frame_set_shadow_type (GTK_FRAME (self), GTK_SHADOW_NONE); } GtkWidget * cc_shell_category_view_new (const gchar *name, GtkTreeModel *model) { return g_object_new (CC_TYPE_SHELL_CATEGORY_VIEW, "name", name, "model", model, NULL); } CcShellItemView* cc_shell_category_view_get_item_view (CcShellCategoryView *self) { return (CcShellItemView*) self->priv->iconview; } cinnamon-control-center-6.4.1/shell/cc-shell-nav-bar.h0000664000175000017500000000415114724311620021503 0ustar fabiofabio/* * Copyright 2012 Canonical * * The Control Center 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. * * The Control Center 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 the Control Center; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Author: AurĆ©lien GĆ¢teau */ #ifndef _CC_SHELL_NAV_BAR_H #define _CC_SHELL_NAV_BAR_H #include G_BEGIN_DECLS #define CC_TYPE_SHELL_NAV_BAR cc_shell_nav_bar_get_type() #define CC_SHELL_NAV_BAR(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ CC_TYPE_SHELL_NAV_BAR, CcShellNavBar)) #define CC_SHELL_NAV_BAR_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), \ CC_TYPE_SHELL_NAV_BAR, CcShellNavBarClass)) #define CC_IS_SHELL_NAV_BAR(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ CC_TYPE_SHELL_NAV_BAR)) #define CC_IS_SHELL_NAV_BAR_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), \ CC_TYPE_SHELL_NAV_BAR)) #define CC_SHELL_NAV_BAR_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), \ CC_TYPE_SHELL_NAV_BAR, CcShellNavBarClass)) typedef struct _CcShellNavBar CcShellNavBar; typedef struct _CcShellNavBarClass CcShellNavBarClass; typedef struct _CcShellNavBarPrivate CcShellNavBarPrivate; struct _CcShellNavBar { GtkBox parent; CcShellNavBarPrivate *priv; }; struct _CcShellNavBarClass { GtkBoxClass parent_class; }; GType cc_shell_nav_bar_get_type (void) G_GNUC_CONST; GtkWidget *cc_shell_nav_bar_new (void); void cc_shell_nav_bar_show_detail_button (CcShellNavBar *bar, const gchar *label); void cc_shell_nav_bar_hide_detail_button (CcShellNavBar *bar); G_END_DECLS #endif /* _CC_SHELL_NAV_BAR_H */ cinnamon-control-center-6.4.1/shell/libcinnamon-control-center.pc.in0000664000175000017500000000060414724311620024471 0ustar fabiofabioprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ extensiondir=@libdir@/cinnamon-control-center-1/panels Name: libcinnamon-control-center Description: A library to create Cinnamon Control Center extensions Version: @VERSION@ Requires: glib-2.0 gio-2.0 gtk+-3.0 Libs: -L${libdir} -lcinnamon-control-center Cflags: -I${includedir}/cinnamon-control-center-1 cinnamon-control-center-6.4.1/shell/cc-shell.h0000664000175000017500000000665714724311620020174 0ustar fabiofabio/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- * * Copyright (c) 2010 Intel, Inc. * * The Control Center 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. * * The Control Center 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 the Control Center; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Author: Thomas Wood */ #ifndef _CC_SHELL_H #define _CC_SHELL_H #include G_BEGIN_DECLS #define CC_TYPE_SHELL cc_shell_get_type() #define CC_SHELL(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ CC_TYPE_SHELL, CcShell)) #define CC_SHELL_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), \ CC_TYPE_SHELL, CcShellClass)) #define CC_IS_SHELL(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ CC_TYPE_SHELL)) #define CC_IS_SHELL_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), \ CC_TYPE_SHELL)) #define CC_SHELL_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), \ CC_TYPE_SHELL, CcShellClass)) #define CC_SHELL_PANEL_EXTENSION_POINT "cinnamon-control-center-1" typedef struct _CcShell CcShell; typedef struct _CcShellClass CcShellClass; typedef struct _CcShellPrivate CcShellPrivate; /* cc-panel.h requires CcShell, so make sure they are defined first */ #include "cc-panel.h" /** * CcShell: * * The contents of this struct are private should not be accessed directly. */ struct _CcShell { /*< private >*/ GObject parent; CcShellPrivate *priv; }; /** * CcShellClass: * @set_active_panel_from_id: virtual function to set the active panel from an * id string * */ struct _CcShellClass { /*< private >*/ GObjectClass parent_class; /*< public >*/ /* vfuncs */ gboolean (*set_active_panel_from_id) (CcShell *shell, const gchar *id, GVariant *parameters, GError **error); GtkWidget * (*get_toplevel) (CcShell *shell); void (*embed_widget_in_header) (CcShell *shell, GtkWidget *widget); }; GType cc_shell_get_type (void) G_GNUC_CONST; CcPanel* cc_shell_get_active_panel (CcShell *shell); void cc_shell_set_active_panel (CcShell *shell, CcPanel *panel); gboolean cc_shell_set_active_panel_from_id (CcShell *shell, const gchar *id, GVariant *parameters, GError **error); GtkWidget * cc_shell_get_toplevel (CcShell *shell); void cc_shell_embed_widget_in_header (CcShell *shell, GtkWidget *widget); G_END_DECLS #endif /* _CC_SHELL_H */ cinnamon-control-center-6.4.1/shell/list-box-helper.h0000664000175000017500000000202714724311620021503 0ustar fabiofabio/* * Copyright (C) 2014 Red Hat, Inc * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include void cc_list_box_update_header_func (GtkListBoxRow *row, GtkListBoxRow *before, gpointer user_data); void cc_list_box_adjust_scrolling (GtkListBox *listbox); void cc_list_box_setup_scrolling (GtkListBox *listbox, guint num_rows); cinnamon-control-center-6.4.1/shell/cinnamon-control-center.c0000664000175000017500000011733314724311620023225 0ustar fabiofabio/* * Copyright (c) 2009, 2010 Intel, Inc. * Copyright (c) 2010 Red Hat, Inc. * * The Control Center 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. * * The Control Center 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 the Control Center; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Author: Thomas Wood */ #include "config.h" #include "cinnamon-control-center.h" #include #include #include #include #include #include #define GMENU_I_KNOW_THIS_IS_UNSTABLE #include #include "cc-panel.h" #include "cc-shell.h" #include "cc-shell-category-view.h" #include "cc-shell-model.h" #include "cc-shell-nav-bar.h" G_DEFINE_TYPE (CinnamonControlCenter, cinnamon_control_center, CC_TYPE_SHELL) #define CONTROL_CENTER_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), CINNAMON_TYPE_CONTROL_CENTER, CinnamonControlCenterPrivate)) #define W(b,x) GTK_WIDGET (gtk_builder_get_object (b, x)) /* Use a fixed width for the shell, since resizing horizontally is more awkward * for the user than resizing vertically * Both sizes are defined in https://live.gnome.org/Design/SystemSettings/ */ #define FIXED_WIDTH 740 #define UNITY_FIXED_WIDTH 850 #define FIXED_HEIGHT 650 #define SMALL_SCREEN_FIXED_HEIGHT 400 #define MIN_ICON_VIEW_HEIGHT 300 typedef enum { SMALL_SCREEN_UNSET, SMALL_SCREEN_TRUE, SMALL_SCREEN_FALSE } CcSmallScreen; struct _CinnamonControlCenterPrivate { GtkBuilder *builder; GtkWidget *notebook; GtkWidget *main_vbox; GtkWidget *scrolled_window; GtkWidget *search_scrolled; GtkWidget *current_panel_box; GtkWidget *current_panel; char *current_panel_id; GtkWidget *window; GtkWidget *search_entry; GtkWidget *lock_button; GPtrArray *custom_widgets; GtkWidget *nav_bar; GMenuTree *menu_tree; GtkListStore *store; GHashTable *category_views; GtkTreeModel *search_filter; GtkWidget *search_view; gchar *filter_string; guint32 last_time; GIOExtensionPoint *extension_point; gchar *default_window_title; gchar *default_window_icon; int monitor_num; CcSmallScreen small_screen; }; /* Notebook helpers */ static GtkWidget * notebook_get_selected_page (GtkWidget *notebook) { int curr; curr = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook)); if (curr == -1) return NULL; return gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), curr); } static void notebook_select_page (GtkWidget *notebook, GtkWidget *page) { int i, num; num = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)); for (i = 0; i < num; i++) { if (gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), i) == page) { gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), i); return; } } g_warning ("Couldn't select GtkNotebook page %p", page); } static void notebook_remove_page (GtkWidget *notebook, GtkWidget *page) { int i, num; num = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)); for (i = 0; i < num; i++) { if (gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), i) == page) { gtk_notebook_remove_page (GTK_NOTEBOOK (notebook), i); return; } } g_warning ("Couldn't find GtkNotebook page to remove %p", page); } static void notebook_add_page (GtkWidget *notebook, GtkWidget *page) { gtk_notebook_append_page (GTK_NOTEBOOK (notebook), page, NULL); } static const gchar * get_icon_name_from_g_icon (GIcon *gicon) { const gchar * const *names; GtkIconTheme *icon_theme; int i; if (!G_IS_THEMED_ICON (gicon)) return NULL; names = g_themed_icon_get_names (G_THEMED_ICON (gicon)); icon_theme = gtk_icon_theme_get_default (); for (i = 0; names[i] != NULL; i++) { if (gtk_icon_theme_has_icon (icon_theme, names[i])) return names[i]; } return NULL; } static gboolean activate_panel (CinnamonControlCenter *shell, const gchar *id, GVariant *parameters, const gchar *desktop_file, const gchar *name, GIcon *gicon) { CinnamonControlCenterPrivate *priv = shell->priv; GType panel_type = G_TYPE_INVALID; GList *panels, *l; GtkWidget *box; const gchar *icon_name; /* check if there is an plugin that implements this panel */ panels = g_io_extension_point_get_extensions (priv->extension_point); if (!desktop_file) return FALSE; if (!id) return FALSE; for (l = panels; l != NULL; l = l->next) { GIOExtension *extension; const gchar *name; extension = l->data; name = g_io_extension_get_name (extension); if (!g_strcmp0 (name, id)) { panel_type = g_io_extension_get_type (extension); break; } } if (panel_type == G_TYPE_INVALID) { GKeyFile *key_file; /* It might be an external panel */ key_file = g_key_file_new (); if (g_key_file_load_from_file (key_file, desktop_file, G_KEY_FILE_NONE, NULL)) { gchar *command; command = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_EXEC, NULL); if (command && command[0]) { g_spawn_command_line_async (command, NULL); g_free (command); } } g_key_file_free (key_file); return FALSE; } /* create the panel plugin */ priv->current_panel = g_object_new (panel_type, "shell", shell, "parameters", parameters, NULL); cc_shell_set_active_panel (CC_SHELL (shell), CC_PANEL (priv->current_panel)); gtk_widget_show (priv->current_panel); gtk_lock_button_set_permission (GTK_LOCK_BUTTON (priv->lock_button), cc_panel_get_permission (CC_PANEL (priv->current_panel))); box = gtk_alignment_new (0, 0, 1, 1); gtk_alignment_set_padding (GTK_ALIGNMENT (box), 6, 6, 6, 6); gtk_container_add (GTK_CONTAINER (box), priv->current_panel); gtk_widget_set_name (box, id); notebook_add_page (priv->notebook, box); /* switch to the new panel */ gtk_widget_show (box); notebook_select_page (priv->notebook, box); cc_shell_nav_bar_show_detail_button (CC_SHELL_NAV_BAR(shell->priv->nav_bar), name); /* set the title of the window */ icon_name = get_icon_name_from_g_icon (gicon); gtk_window_set_role (GTK_WINDOW (priv->window), id); gtk_window_set_title (GTK_WINDOW (priv->window), name); gtk_window_set_default_icon_name (icon_name); gtk_window_set_icon_name (GTK_WINDOW (priv->window), icon_name); priv->current_panel_box = box; return TRUE; } static void _shell_remove_all_custom_widgets (CinnamonControlCenterPrivate *priv) { GtkBox *box; GtkWidget *widget; guint i; /* remove from the header */ box = GTK_BOX (W (priv->builder, "topright")); for (i = 0; i < priv->custom_widgets->len; i++) { widget = g_ptr_array_index (priv->custom_widgets, i); gtk_container_remove (GTK_CONTAINER (box), widget); } g_ptr_array_set_size (priv->custom_widgets, 0); } static void shell_show_overview_page (CinnamonControlCenter *center) { CinnamonControlCenterPrivate *priv = center->priv; notebook_select_page (priv->notebook, priv->scrolled_window); if (priv->current_panel_box) notebook_remove_page (priv->notebook, priv->current_panel_box); priv->current_panel = NULL; priv->current_panel_box = NULL; if (priv->current_panel_id) { g_free (priv->current_panel_id); priv->current_panel_id = NULL; } /* clear the search text */ g_free (priv->filter_string); priv->filter_string = g_strdup (""); gtk_lock_button_set_permission (GTK_LOCK_BUTTON (priv->lock_button), NULL); /* reset window title and icon */ gtk_window_set_role (GTK_WINDOW (priv->window), NULL); gtk_window_set_title (GTK_WINDOW (priv->window), priv->default_window_title); gtk_window_set_default_icon_name (priv->default_window_icon); gtk_window_set_icon_name (GTK_WINDOW (priv->window), priv->default_window_icon); cc_shell_set_active_panel (CC_SHELL (center), NULL); /* clear any custom widgets */ _shell_remove_all_custom_widgets (priv); cc_shell_nav_bar_hide_detail_button (CC_SHELL_NAV_BAR (priv->nav_bar)); } void cinnamon_control_center_set_overview_page (CinnamonControlCenter *center) { shell_show_overview_page (center); } static void item_activated_cb (CcShellCategoryView *view, gchar *name, gchar *id, gchar *desktop_file, CinnamonControlCenter *shell) { GError *err = NULL; if (!cc_shell_set_active_panel_from_id (CC_SHELL (shell), id, NULL, &err)) { /* TODO: show message to user */ if (err) { g_warning ("Could not active panel \"%s\": %s", id, err->message); g_error_free (err); } } } static gboolean category_focus_out (GtkWidget *view, GdkEventFocus *event, CinnamonControlCenter *shell) { gtk_icon_view_unselect_all (GTK_ICON_VIEW (view)); return FALSE; } static gboolean category_focus_in (GtkWidget *view, GdkEventFocus *event, CinnamonControlCenter *shell) { GtkTreePath *path; if (!gtk_icon_view_get_cursor (GTK_ICON_VIEW (view), &path, NULL)) { path = gtk_tree_path_new_from_indices (0, -1); gtk_icon_view_set_cursor (GTK_ICON_VIEW (view), path, NULL, FALSE); } gtk_icon_view_select_path (GTK_ICON_VIEW (view), path); gtk_tree_path_free (path); return FALSE; } static GList * get_item_views (CinnamonControlCenter *shell) { GList *list, *l; GList *res; list = gtk_container_get_children (GTK_CONTAINER (shell->priv->main_vbox)); res = NULL; for (l = list; l; l = l->next) { if (!CC_IS_SHELL_CATEGORY_VIEW (l->data)) continue; res = g_list_append (res, cc_shell_category_view_get_item_view (CC_SHELL_CATEGORY_VIEW (l->data))); } g_list_free (list); return res; } static gboolean keynav_failed (GtkIconView *current_view, GtkDirectionType direction, CinnamonControlCenter *shell) { GList *views, *v; GtkIconView *new_view; GtkTreePath *path; GtkTreeModel *model; GtkTreeIter iter; gint col, c, dist, d; GtkTreePath *sel; gboolean res; res = FALSE; views = get_item_views (shell); for (v = views; v; v = v->next) { if (v->data == current_view) break; } if (direction == GTK_DIR_DOWN && v != NULL && v->next != NULL) { new_view = v->next->data; if (gtk_icon_view_get_cursor (current_view, &path, NULL)) { col = gtk_icon_view_get_item_column (current_view, path); gtk_tree_path_free (path); sel = NULL; dist = 1000; model = gtk_icon_view_get_model (new_view); gtk_tree_model_get_iter_first (model, &iter); do { path = gtk_tree_model_get_path (model, &iter); c = gtk_icon_view_get_item_column (new_view, path); d = ABS (c - col); if (d < dist) { if (sel) gtk_tree_path_free (sel); sel = path; dist = d; } else gtk_tree_path_free (path); } while (gtk_tree_model_iter_next (model, &iter)); gtk_icon_view_set_cursor (new_view, sel, NULL, FALSE); gtk_tree_path_free (sel); } gtk_widget_grab_focus (GTK_WIDGET (new_view)); res = TRUE; } if (direction == GTK_DIR_UP && v != NULL && v->prev != NULL) { new_view = v->prev->data; if (gtk_icon_view_get_cursor (current_view, &path, NULL)) { col = gtk_icon_view_get_item_column (current_view, path); gtk_tree_path_free (path); sel = NULL; dist = 1000; model = gtk_icon_view_get_model (new_view); gtk_tree_model_get_iter_first (model, &iter); do { path = gtk_tree_model_get_path (model, &iter); c = gtk_icon_view_get_item_column (new_view, path); d = ABS (c - col); if (d <= dist) { if (sel) gtk_tree_path_free (sel); sel = path; dist = d; } else gtk_tree_path_free (path); } while (gtk_tree_model_iter_next (model, &iter)); gtk_icon_view_set_cursor (new_view, sel, NULL, FALSE); gtk_tree_path_free (sel); } gtk_widget_grab_focus (GTK_WIDGET (new_view)); res = TRUE; } g_list_free (views); return res; } static gboolean model_filter_func (GtkTreeModel *model, GtkTreeIter *iter, CinnamonControlCenterPrivate *priv) { gchar *name, *description; gchar *needle, *haystack; gboolean result; gchar **keywords; gtk_tree_model_get (model, iter, COL_NAME, &name, COL_DESCRIPTION, &description, COL_KEYWORDS, &keywords, -1); if (!priv->filter_string || !name) { g_free (name); g_free (description); g_strfreev (keywords); return FALSE; } needle = g_utf8_casefold (priv->filter_string, -1); haystack = g_utf8_casefold (name, -1); result = (strstr (haystack, needle) != NULL); if (!result && description) { gchar *folded; folded = g_utf8_casefold (description, -1); result = (strstr (folded, needle) != NULL); g_free (folded); } if (!result && keywords) { gint i; gchar *keyword; for (i = 0; !result && keywords[i]; i++) { keyword = g_utf8_casefold (keywords[i], -1); result = strstr (keyword, needle) == keyword; g_free (keyword); } } g_free (name); g_free (haystack); g_free (needle); g_strfreev (keywords); return result; } static gboolean category_filter_func (GtkTreeModel *model, GtkTreeIter *iter, gchar *filter) { gchar *category; gboolean result; gtk_tree_model_get (model, iter, COL_CATEGORY, &category, -1); result = (g_strcmp0 (category, filter) == 0); g_free (category); return result; } static void search_entry_changed_cb (GtkEntry *entry, CinnamonControlCenter *center) { CinnamonControlCenterPrivate *priv = center->priv; char *str; /* if the entry text was set manually (not by the user) */ if (!g_strcmp0 (priv->filter_string, gtk_entry_get_text (entry))) return; /* Don't re-filter for added trailing or leading spaces */ str = g_strdup (gtk_entry_get_text (entry)); g_strstrip (str); if (!g_strcmp0 (str, priv->filter_string)) { g_free (str); return; } g_free (priv->filter_string); priv->filter_string = str; if (!g_strcmp0 (priv->filter_string, "")) { shell_show_overview_page (center); } else { gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->search_filter)); notebook_select_page (priv->notebook, priv->search_scrolled); } } static gboolean search_entry_key_press_event_cb (GtkEntry *entry, GdkEventKey *event, CinnamonControlCenterPrivate *priv) { if (event->keyval == GDK_KEY_Return) { GtkTreePath *path; path = gtk_tree_path_new_first (); priv->last_time = event->time; gtk_icon_view_item_activated (GTK_ICON_VIEW (priv->search_view), path); gtk_tree_path_free (path); return TRUE; } if (event->keyval == GDK_KEY_Escape) { gtk_entry_set_text (entry, ""); return TRUE; } return FALSE; } static void on_search_selection_changed (GtkTreeSelection *selection, CinnamonControlCenter *shell) { GtkTreeModel *model; GtkTreeIter iter; char *id = NULL; if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return; gtk_tree_model_get (model, &iter, COL_ID, &id, -1); if (id) cc_shell_set_active_panel_from_id (CC_SHELL (shell), id, NULL, NULL); gtk_tree_selection_unselect_all (selection); g_free (id); } static void setup_search (CinnamonControlCenter *shell) { GtkWidget *search_view, *widget; GtkCellRenderer *renderer; GtkTreeViewColumn *column; CinnamonControlCenterPrivate *priv = shell->priv; g_return_if_fail (priv->store != NULL); /* create the search filter */ priv->search_filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (priv->store), NULL); gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (priv->search_filter), (GtkTreeModelFilterVisibleFunc) model_filter_func, priv, NULL); /* set up the search view */ priv->search_view = search_view = gtk_tree_view_new (); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (search_view), FALSE); gtk_tree_view_set_model (GTK_TREE_VIEW (search_view), GTK_TREE_MODEL (priv->search_filter)); renderer = gtk_cell_renderer_pixbuf_new (); g_object_set (renderer, "follow-state", TRUE, "xpad", 15, "ypad", 10, "stock-size", GTK_ICON_SIZE_DIALOG, NULL); column = gtk_tree_view_column_new_with_attributes ("Icon", renderer, "gicon", COL_GICON, NULL); gtk_tree_view_column_set_expand (column, FALSE); gtk_tree_view_append_column (GTK_TREE_VIEW (priv->search_view), column); renderer = gtk_cell_renderer_text_new (); g_object_set (renderer, "xpad", 0, NULL); column = gtk_tree_view_column_new_with_attributes ("Name", renderer, "text", COL_NAME, NULL); gtk_tree_view_column_set_expand (column, FALSE); gtk_tree_view_append_column (GTK_TREE_VIEW (priv->search_view), column); renderer = gtk_cell_renderer_text_new (); g_object_set (renderer, "xpad", 15, NULL); column = gtk_tree_view_column_new_with_attributes ("Description", renderer, "text", COL_DESCRIPTION, NULL); gtk_tree_view_column_set_expand (column, TRUE); gtk_tree_view_append_column (GTK_TREE_VIEW (priv->search_view), column); priv->search_scrolled = W (priv->builder, "search-scrolled-window"); gtk_container_add (GTK_CONTAINER (priv->search_scrolled), search_view); g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->search_view)), "changed", G_CALLBACK (on_search_selection_changed), shell); } static void setup_lock (CinnamonControlCenter *shell) { CinnamonControlCenterPrivate *priv = shell->priv; priv->lock_button = W (priv->builder, "lock-button"); } static void maybe_add_category_view (CinnamonControlCenter *shell, const char *name) { GtkTreeModel *filter; GtkWidget *categoryview; if (g_hash_table_lookup (shell->priv->category_views, name) != NULL) return; if (g_hash_table_size (shell->priv->category_views) > 0) { GtkWidget *separator; separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL); gtk_widget_set_margin_top (separator, 11); gtk_widget_set_margin_bottom (separator, 10); gtk_box_pack_start (GTK_BOX (shell->priv->main_vbox), separator, FALSE, FALSE, 0); gtk_widget_show (separator); } /* create new category view for this category */ filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (shell->priv->store), NULL); gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter), (GtkTreeModelFilterVisibleFunc) category_filter_func, g_strdup (name), g_free); categoryview = cc_shell_category_view_new (name, filter); gtk_box_pack_start (GTK_BOX (shell->priv->main_vbox), categoryview, FALSE, TRUE, 0); g_signal_connect (cc_shell_category_view_get_item_view (CC_SHELL_CATEGORY_VIEW (categoryview)), "desktop-item-activated", G_CALLBACK (item_activated_cb), shell); gtk_widget_show (categoryview); g_signal_connect (cc_shell_category_view_get_item_view (CC_SHELL_CATEGORY_VIEW (categoryview)), "focus-in-event", G_CALLBACK (category_focus_in), shell); g_signal_connect (cc_shell_category_view_get_item_view (CC_SHELL_CATEGORY_VIEW (categoryview)), "focus-out-event", G_CALLBACK (category_focus_out), shell); g_signal_connect (cc_shell_category_view_get_item_view (CC_SHELL_CATEGORY_VIEW (categoryview)), "keynav-failed", G_CALLBACK (keynav_failed), shell); g_hash_table_insert (shell->priv->category_views, g_strdup (name), categoryview); } static void reload_menu (CinnamonControlCenter *shell) { GError *error; GDir *dir; const gchar *name; error = NULL; maybe_add_category_view (shell, "C Modules"); dir = g_dir_open (PANEL_DEF_DIR, 0, &error); if (error != NULL) { g_critical ("Could not read PANEL_DEF_DIR: %s", PANEL_DEF_DIR); g_error_free (error); return; } do { gchar *full_path; name = g_dir_read_name (dir); if (name == NULL) { break; } full_path = g_build_filename (PANEL_DEF_DIR, name, NULL); cc_shell_model_add_item (CC_SHELL_MODEL (shell->priv->store), full_path); g_free (full_path); } while (name != NULL); g_dir_close (dir); } static void on_menu_changed (GMenuTree *monitor, CinnamonControlCenter *shell) { gtk_list_store_clear (shell->priv->store); reload_menu (shell); } static void setup_model (CinnamonControlCenter *shell) { CinnamonControlCenterPrivate *priv = shell->priv; gtk_widget_set_margin_top (shell->priv->main_vbox, 8); gtk_widget_set_margin_bottom (shell->priv->main_vbox, 8); gtk_widget_set_margin_left (shell->priv->main_vbox, 12); gtk_widget_set_margin_right (shell->priv->main_vbox, 12); gtk_container_set_focus_vadjustment (GTK_CONTAINER (shell->priv->main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (shell->priv->scrolled_window))); priv->store = (GtkListStore *) cc_shell_model_new (); priv->category_views = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); priv->menu_tree = gmenu_tree_new_for_path (MENUDIR "/cinnamoncc.menu", 0); reload_menu (shell); g_signal_connect (priv->menu_tree, "changed", G_CALLBACK (on_menu_changed), shell); } static void load_panel_plugins (CinnamonControlCenter *shell) { GList *modules; /* only allow this function to be run once to prevent modules being loaded * twice */ if (shell->priv->extension_point) return; /* make sure the base type is registered */ g_type_from_name ("CcPanel"); shell->priv->extension_point = g_io_extension_point_register (CC_SHELL_PANEL_EXTENSION_POINT); /* load all the plugins in the panels directory */ modules = g_io_modules_load_all_in_directory (PANELS_DIR); g_list_free (modules); } static void home_button_clicked_cb (GtkButton *button, CinnamonControlCenter *shell) { shell_show_overview_page (shell); } static void notebook_page_notify_cb (GtkNotebook *notebook, GParamSpec *spec, CinnamonControlCenterPrivate *priv) { int nat_height; GtkWidget *child; child = notebook_get_selected_page (GTK_WIDGET (notebook)); if (child == priv->scrolled_window || child == priv->search_scrolled) { gtk_widget_hide (W (priv->builder, "lock-button")); if (!g_strcmp0(g_getenv("XDG_CURRENT_DESKTOP"), "Unity")) gtk_widget_get_preferred_height_for_width (GTK_WIDGET (priv->main_vbox), UNITY_FIXED_WIDTH, NULL, &nat_height); else gtk_widget_get_preferred_height_for_width (GTK_WIDGET (priv->main_vbox), FIXED_WIDTH, NULL, &nat_height); gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (priv->scrolled_window), priv->small_screen == SMALL_SCREEN_TRUE ? SMALL_SCREEN_FIXED_HEIGHT : nat_height); } else { /* set the scrolled window small so that it doesn't force the window to be larger than this panel */ if (!g_strcmp0(g_getenv("XDG_CURRENT_DESKTOP"), "Unity")) { gtk_widget_get_preferred_height_for_width (GTK_WIDGET (priv->window), UNITY_FIXED_WIDTH, NULL, &nat_height); gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (priv->scrolled_window), MIN_ICON_VIEW_HEIGHT); gtk_window_resize (GTK_WINDOW (priv->window), UNITY_FIXED_WIDTH, nat_height); } else { gtk_widget_get_preferred_height_for_width (GTK_WIDGET (priv->window), FIXED_WIDTH, NULL, &nat_height); gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (priv->scrolled_window), MIN_ICON_VIEW_HEIGHT); gtk_window_resize (GTK_WINDOW (priv->window), FIXED_WIDTH, nat_height); } } } /* CcShell implementation */ static void _shell_embed_widget_in_header (CcShell *shell, GtkWidget *widget) { CinnamonControlCenterPrivate *priv = CINNAMON_CONTROL_CENTER (shell)->priv; GtkBox *box; /* add to header */ box = GTK_BOX (W (priv->builder, "topright")); gtk_box_pack_end (box, widget, FALSE, FALSE, 0); g_ptr_array_add (priv->custom_widgets, g_object_ref (widget)); } /* CcShell implementation */ static gboolean _shell_set_active_panel_from_id (CcShell *shell, const gchar *start_id, GVariant *parameters, GError **err) { GtkTreeIter iter; gboolean iter_valid; gchar *name = NULL; gchar *desktop = NULL; GIcon *gicon = NULL; CinnamonControlCenterPrivate *priv = CINNAMON_CONTROL_CENTER (shell)->priv; GtkWidget *old_panel; /* When loading the same panel again, just set its parameters */ if (g_strcmp0 (priv->current_panel_id, start_id) == 0) { g_object_set (G_OBJECT (priv->current_panel), "parameters", parameters, NULL); return TRUE; } if (priv->current_panel_id) { g_free (priv->current_panel_id); priv->current_panel_id = NULL; } /* clear any custom widgets */ _shell_remove_all_custom_widgets (priv); iter_valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->store), &iter); /* find the details for this item */ while (iter_valid) { gchar *id; gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter, COL_NAME, &name, COL_DESKTOP_FILE, &desktop, COL_GICON, &gicon, COL_ID, &id, -1); if (id && !strcmp (id, start_id)) { g_free (id); break; } else { g_free (id); g_free (name); g_free (desktop); if (gicon) g_object_unref (gicon); name = NULL; id = NULL; desktop = NULL; gicon = NULL; } iter_valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->store), &iter); } if (!name) { g_warning ("Could not find settings panel \"%s\"", start_id); } else if (activate_panel (CINNAMON_CONTROL_CENTER (shell), start_id, parameters, desktop, name, gicon) == FALSE) { /* Failed to activate the panel for some reason */ old_panel = priv->current_panel_box; priv->current_panel_box = NULL; notebook_select_page (priv->notebook, priv->scrolled_window); if (old_panel) notebook_remove_page (priv->notebook, old_panel); } else { priv->current_panel_id = g_strdup (start_id); } g_free (name); g_free (desktop); if (gicon) g_object_unref (gicon); return TRUE; } static GtkWidget * _shell_get_toplevel (CcShell *shell) { return CINNAMON_CONTROL_CENTER (shell)->priv->window; } /* GObject Implementation */ static void cinnamon_control_center_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { switch (property_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void cinnamon_control_center_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { switch (property_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void cinnamon_control_center_dispose (GObject *object) { CinnamonControlCenterPrivate *priv = CINNAMON_CONTROL_CENTER (object)->priv; g_free (priv->current_panel_id); if (priv->custom_widgets) { g_ptr_array_unref (priv->custom_widgets); priv->custom_widgets = NULL; } if (priv->window) { gtk_widget_destroy (priv->window); priv->window = NULL; /* destroying the window will destroy its children */ priv->notebook = NULL; priv->search_entry = NULL; priv->search_view = NULL; } if (priv->builder) { g_object_unref (priv->builder); priv->builder = NULL; } if (priv->store) { g_object_unref (priv->store); priv->store = NULL; } if (priv->search_filter) { g_object_unref (priv->search_filter); priv->search_filter = NULL; } G_OBJECT_CLASS (cinnamon_control_center_parent_class)->dispose (object); } static void cinnamon_control_center_finalize (GObject *object) { CinnamonControlCenterPrivate *priv = CINNAMON_CONTROL_CENTER (object)->priv; if (priv->filter_string) { g_free (priv->filter_string); priv->filter_string = NULL; } if (priv->default_window_title) { g_free (priv->default_window_title); priv->default_window_title = NULL; } if (priv->default_window_icon) { g_free (priv->default_window_icon); priv->default_window_icon = NULL; } if (priv->menu_tree) { g_signal_handlers_disconnect_by_func (priv->menu_tree, G_CALLBACK (on_menu_changed), object); g_object_unref (priv->menu_tree); } if (priv->category_views) { g_hash_table_destroy (priv->category_views); } G_OBJECT_CLASS (cinnamon_control_center_parent_class)->finalize (object); } static void cinnamon_control_center_class_init (CinnamonControlCenterClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); CcShellClass *shell_class = CC_SHELL_CLASS (klass); g_type_class_add_private (klass, sizeof (CinnamonControlCenterPrivate)); object_class->get_property = cinnamon_control_center_get_property; object_class->set_property = cinnamon_control_center_set_property; object_class->dispose = cinnamon_control_center_dispose; object_class->finalize = cinnamon_control_center_finalize; shell_class->set_active_panel_from_id = _shell_set_active_panel_from_id; shell_class->embed_widget_in_header = _shell_embed_widget_in_header; shell_class->get_toplevel = _shell_get_toplevel; } static gboolean window_key_press_event (GtkWidget *win, GdkEventKey *event, CinnamonControlCenter *self) { GdkKeymap *keymap; gboolean retval; GdkModifierType state; if (event->state == 0) return FALSE; retval = FALSE; state = event->state; keymap = gdk_keymap_get_default (); gdk_keymap_add_virtual_modifiers (keymap, &state); state = state & gtk_accelerator_get_default_mod_mask (); if (state == GDK_CONTROL_MASK) { switch (event->keyval) { case GDK_KEY_s: case GDK_KEY_S: case GDK_KEY_f: case GDK_KEY_F: retval = TRUE; break; case GDK_KEY_Q: case GDK_KEY_q: g_object_unref (self); retval = TRUE; break; case GDK_KEY_W: case GDK_KEY_w: if (notebook_get_selected_page (self->priv->notebook) != self->priv->scrolled_window) shell_show_overview_page (self); retval = TRUE; break; } } return retval; } static gint get_monitor_height (CinnamonControlCenter *self) { GdkScreen *screen; GdkRectangle rect; /* We cannot use workarea here, as this wouldn't * be updated when we read it after a monitors-changed signal */ screen = gtk_widget_get_screen (self->priv->window); gdk_screen_get_monitor_geometry (screen, self->priv->monitor_num, &rect); return rect.height; } static gboolean update_monitor_number (CinnamonControlCenter *self) { gboolean changed = FALSE; GtkWidget *widget; GdkScreen *screen; GdkWindow *window; int monitor; widget = self->priv->window; window = gtk_widget_get_window (widget); screen = gtk_widget_get_screen (widget); monitor = gdk_screen_get_monitor_at_window (screen, window); if (self->priv->monitor_num != monitor) { self->priv->monitor_num = monitor; changed = TRUE; } return changed; } static CcSmallScreen is_small (CinnamonControlCenter *self) { if (get_monitor_height (self) <= FIXED_HEIGHT) return SMALL_SCREEN_TRUE; return SMALL_SCREEN_FALSE; } static void update_small_screen_settings (CinnamonControlCenter *self) { CcSmallScreen small; update_monitor_number (self); small = is_small (self); if (small == SMALL_SCREEN_TRUE) { gtk_window_set_resizable (GTK_WINDOW (self->priv->window), TRUE); if (self->priv->small_screen != small) gtk_window_maximize (GTK_WINDOW (self->priv->window)); } else { if (self->priv->small_screen != small) gtk_window_unmaximize (GTK_WINDOW (self->priv->window)); gtk_window_set_resizable (GTK_WINDOW (self->priv->window), FALSE); } self->priv->small_screen = small; /* And update the minimum sizes */ notebook_page_notify_cb (GTK_NOTEBOOK (self->priv->notebook), NULL, self->priv); } static gboolean main_window_configure_cb (GtkWidget *widget, GdkEvent *event, CinnamonControlCenter *self) { update_small_screen_settings (self); return FALSE; } static void application_set_cb (GObject *object, GParamSpec *pspec, CinnamonControlCenter *self) { /* update small screen settings now - to avoid visible resizing, we want * to do it before showing the window, and GtkApplicationWindow cannot be * realized unless its application property has been set */ if (gtk_window_get_application (GTK_WINDOW (self->priv->window))) { gtk_widget_realize (self->priv->window); update_small_screen_settings (self); } } static void monitors_changed_cb (GdkScreen *screen, CinnamonControlCenter *self) { /* We reset small_screen_set to make sure that the * window gets maximised if need be, in update_small_screen_settings() */ self->priv->small_screen = SMALL_SCREEN_UNSET; update_small_screen_settings (self); } static void cinnamon_control_center_init (CinnamonControlCenter *self) { GError *err = NULL; CinnamonControlCenterPrivate *priv; GdkScreen *screen; GtkWidget *widget; priv = self->priv = CONTROL_CENTER_PRIVATE (self); priv->monitor_num = -1; self->priv->small_screen = SMALL_SCREEN_UNSET; /* load the user interface */ priv->builder = gtk_builder_new (); if (!gtk_builder_add_from_file (priv->builder, UIDIR "/shell.ui", &err)) { g_critical ("Could not build interface: %s", err->message); g_error_free (err); return; } /* connect various signals */ priv->window = W (priv->builder, "main-window"); gtk_window_set_hide_titlebar_when_maximized (GTK_WINDOW (priv->window), TRUE); screen = gtk_widget_get_screen (priv->window); g_signal_connect (screen, "monitors-changed", G_CALLBACK (monitors_changed_cb), self); g_signal_connect (priv->window, "configure-event", G_CALLBACK (main_window_configure_cb), self); g_signal_connect (priv->window, "notify::application", G_CALLBACK (application_set_cb), self); g_signal_connect_swapped (priv->window, "delete-event", G_CALLBACK (g_object_unref), self); g_signal_connect_after (priv->window, "key_press_event", G_CALLBACK (window_key_press_event), self); priv->notebook = W (priv->builder, "notebook"); /* Main scrolled window */ priv->scrolled_window = W (priv->builder, "scrolledwindow1"); if (!g_strcmp0(g_getenv("XDG_CURRENT_DESKTOP"), "Unity")) gtk_widget_set_size_request (priv->scrolled_window, UNITY_FIXED_WIDTH, -1); else gtk_widget_set_size_request (priv->scrolled_window, FIXED_WIDTH, -1); priv->main_vbox = W (priv->builder, "main-vbox"); g_signal_connect (priv->notebook, "notify::page", G_CALLBACK (notebook_page_notify_cb), priv); priv->nav_bar = cc_shell_nav_bar_new (); widget = W (priv->builder, "hbox1"); gtk_box_pack_start (GTK_BOX (widget), priv->nav_bar, FALSE, FALSE, 0); gtk_box_reorder_child (GTK_BOX (widget), priv->nav_bar, 0); gtk_widget_show (priv->nav_bar); g_signal_connect (priv->nav_bar, "home-clicked", G_CALLBACK (home_button_clicked_cb), self); /* keep a list of custom widgets to unload on panel change */ priv->custom_widgets = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); /* load the available settings panels */ setup_model (self); /* load the panels that are implemented as plugins */ load_panel_plugins (self); /* setup search functionality */ setup_search (self); setup_lock (self); /* store default window title and name */ priv->default_window_title = g_strdup (gtk_window_get_title (GTK_WINDOW (priv->window))); priv->default_window_icon = g_strdup (gtk_window_get_icon_name (GTK_WINDOW (priv->window))); notebook_page_notify_cb (GTK_NOTEBOOK (priv->notebook), NULL, priv); } CinnamonControlCenter * cinnamon_control_center_new (void) { return g_object_new (CINNAMON_TYPE_CONTROL_CENTER, NULL); } void cinnamon_control_center_present (CinnamonControlCenter *center) { gtk_window_present (GTK_WINDOW (center->priv->window)); } void cinnamon_control_center_show (CinnamonControlCenter *center, GtkApplication *app) { gtk_window_set_application (GTK_WINDOW (center->priv->window), app); gtk_widget_show (gtk_bin_get_child (GTK_BIN (center->priv->window))); } cinnamon-control-center-6.4.1/shell/cc-shell-item-view.h0000664000175000017500000000411114724311620022057 0ustar fabiofabio/* * Copyright (c) 2010 Intel, Inc. * * The Control Center 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. * * The Control Center 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 the Control Center; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Author: Thomas Wood */ #ifndef _CC_SHELL_ITEM_VIEW_H #define _CC_SHELL_ITEM_VIEW_H #include G_BEGIN_DECLS #define CC_TYPE_SHELL_ITEM_VIEW cc_shell_item_view_get_type() #define CC_SHELL_ITEM_VIEW(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ CC_TYPE_SHELL_ITEM_VIEW, CcShellItemView)) #define CC_SHELL_ITEM_VIEW_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), \ CC_TYPE_SHELL_ITEM_VIEW, CcShellItemViewClass)) #define CC_IS_SHELL_ITEM_VIEW(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ CC_TYPE_SHELL_ITEM_VIEW)) #define CC_IS_SHELL_ITEM_VIEW_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), \ CC_TYPE_SHELL_ITEM_VIEW)) #define CC_SHELL_ITEM_VIEW_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), \ CC_TYPE_SHELL_ITEM_VIEW, CcShellItemViewClass)) typedef struct _CcShellItemView CcShellItemView; typedef struct _CcShellItemViewClass CcShellItemViewClass; typedef struct _CcShellItemViewPrivate CcShellItemViewPrivate; struct _CcShellItemView { GtkIconView parent; CcShellItemViewPrivate *priv; }; struct _CcShellItemViewClass { GtkIconViewClass parent_class; }; GType cc_shell_item_view_get_type (void) G_GNUC_CONST; GtkWidget *cc_shell_item_view_new (void); void cc_shell_item_view_update_cells (CcShellItemView *view); G_END_DECLS #endif /* _CC_SHELL_ITEM_VIEW_H */ cinnamon-control-center-6.4.1/shell/list-box-helper.c0000664000175000017500000000663514724311620021507 0ustar fabiofabio/* * Copyright (C) 2014 Red Hat, Inc * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * */ #include "list-box-helper.h" #define MAX_ROWS_VISIBLE 5 void cc_list_box_update_header_func (GtkListBoxRow *row, GtkListBoxRow *before, gpointer user_data) { GtkWidget *current; if (before == NULL) { gtk_list_box_row_set_header (row, NULL); return; } current = gtk_list_box_row_get_header (row); if (current == NULL) { current = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL); gtk_widget_show (current); gtk_list_box_row_set_header (row, current); } } void cc_list_box_adjust_scrolling (GtkListBox *listbox) { GtkWidget *scrolled_window; GList *children; guint n_rows, num_max_rows; scrolled_window = g_object_get_data (G_OBJECT (listbox), "cc-scrolling-scrolled-window"); if (!scrolled_window) return; children = gtk_container_get_children (GTK_CONTAINER (listbox)); n_rows = g_list_length (children); num_max_rows = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (listbox), "cc-max-rows-visible")); if (n_rows >= num_max_rows) { gint total_row_height = 0; GList *l; guint i; for (l = children, i = 0; l != NULL && i < num_max_rows; l = l->next, i++) { gint row_height; gtk_widget_get_preferred_height (GTK_WIDGET (l->data), &row_height, NULL); total_row_height += row_height; } gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (scrolled_window), total_row_height); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); } else { gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (scrolled_window), -1); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_NEVER); } g_list_free (children); } void cc_list_box_setup_scrolling (GtkListBox *listbox, guint num_max_rows) { GtkWidget *parent; GtkWidget *scrolled_window; parent = gtk_widget_get_parent (GTK_WIDGET (listbox)); scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_widget_show (scrolled_window); g_object_ref (listbox); gtk_container_remove (GTK_CONTAINER (parent), GTK_WIDGET (listbox)); gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET (listbox)); g_object_unref (listbox); gtk_container_add (GTK_CONTAINER (parent), scrolled_window); if (num_max_rows == 0) num_max_rows = MAX_ROWS_VISIBLE; g_object_set_data (G_OBJECT (listbox), "cc-scrolling-scrolled-window", scrolled_window); g_object_set_data (G_OBJECT (listbox), "cc-max-rows-visible", GUINT_TO_POINTER (num_max_rows)); } cinnamon-control-center-6.4.1/shell/cc-shell-log.h0000664000175000017500000000203514724311620020735 0ustar fabiofabio/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2009 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. * */ #ifndef __CC_SHELL_LOG_H #define __CC_SHELL_LOG_H #include G_BEGIN_DECLS void cc_shell_log_init (void); void cc_shell_log_set_debug (gboolean debug); G_END_DECLS #endif /* __CC_SHELL_LOG_H */ cinnamon-control-center-6.4.1/shell/control-center.c0000664000175000017500000002054414724311620021422 0ustar fabiofabio/* * Copyright (c) 2009, 2010 Intel, Inc. * Copyright (c) 2010 Red Hat, Inc. * * The Control Center 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. * * The Control Center 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 the Control Center; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Author: Thomas Wood */ #include "config.h" #include #include #include "cinnamon-control-center.h" #include #include #include #ifdef GDK_WINDOWING_X11 #include #endif #include "cc-shell-log.h" G_GNUC_NORETURN static gboolean option_version_cb (const gchar *option_name, const gchar *value, gpointer data, GError **error) { g_print ("%s %s\n", PACKAGE, VERSION); exit (0); } static char **start_panels = NULL; static gboolean show_overview = FALSE; static gboolean verbose = FALSE; static gboolean show_help = FALSE; static gboolean show_help_gtk = FALSE; static gboolean show_help_all = FALSE; const GOptionEntry all_options[] = { { "version", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, option_version_cb, NULL, NULL }, { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, N_("Enable verbose mode"), NULL }, { "overview", 'o', 0, G_OPTION_ARG_NONE, &show_overview, N_("Show the overview"), NULL }, { "help", 'h', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &show_help, N_("Show help options"), NULL }, { "help-all", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &show_help_all, N_("Show help options"), NULL }, { "help-gtk", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &show_help_gtk, N_("Show help options"), NULL }, { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &start_panels, N_("Panel to display"), NULL }, { NULL, 0, 0, 0, NULL, NULL, NULL } /* end the list */ }; static int application_command_line_cb (GApplication *application, GApplicationCommandLine *command_line, CinnamonControlCenter *shell) { int argc; char **argv; int retval = 0; GOptionContext *context; GError *error = NULL; verbose = FALSE; show_overview = FALSE; show_help = FALSE; start_panels = NULL; argv = g_application_command_line_get_arguments (command_line, &argc); context = g_option_context_new (N_("- System Settings")); g_option_context_add_main_entries (context, all_options, GETTEXT_PACKAGE); g_option_context_set_translation_domain(context, GETTEXT_PACKAGE); g_option_context_add_group (context, gtk_get_option_group (TRUE)); g_option_context_set_help_enabled (context, FALSE); if (g_option_context_parse (context, &argc, &argv, &error) == FALSE) { g_print (_("%s\nRun '%s --help' to see a full list of available command line options.\n"), error->message, argv[0]); g_error_free (error); g_option_context_free (context); return 1; } if (show_help || show_help_all || show_help_gtk) { gchar *help; GOptionGroup *group; if (show_help || show_help_all) group = NULL; else group = gtk_get_option_group (FALSE); help = g_option_context_get_help (context, FALSE, group); g_print ("%s", help); g_free (help); g_option_context_free (context); return 0; } g_option_context_free (context); cc_shell_log_set_debug (verbose); cinnamon_control_center_show (shell, GTK_APPLICATION (application)); if (show_overview) { cinnamon_control_center_set_overview_page (shell); } else if (start_panels != NULL && start_panels[0] != NULL) { const char *start_id; GError *err = NULL; GVariant *parameters; GVariantBuilder *builder; int i; start_id = start_panels[0]; if (start_panels[1]) g_debug ("Extra argument: %s", start_panels[1]); else g_debug ("No extra argument"); builder = g_variant_builder_new (G_VARIANT_TYPE ("av")); for (i = 1; start_panels[i] != NULL; i++) g_variant_builder_add (builder, "v", g_variant_new_string (start_panels[i])); parameters = g_variant_builder_end (builder); if (!cc_shell_set_active_panel_from_id (CC_SHELL (shell), start_id, parameters, &err)) { g_warning ("Could not load setting panel \"%s\": %s", start_id, (err) ? err->message : "Unknown error"); retval = 1; if (err) { g_error_free (err); err = NULL; } } } cinnamon_control_center_present (shell); gdk_notify_startup_complete (); g_strfreev (argv); if (start_panels != NULL) { g_strfreev (start_panels); start_panels = NULL; } show_overview = FALSE; return retval; } static void help_activated (GSimpleAction *action, GVariant *parameter, gpointer user_data) { CinnamonControlCenter *shell = user_data; CcPanel *panel = cc_shell_get_active_panel (CC_SHELL (shell)); GtkWidget *window = cc_shell_get_toplevel (CC_SHELL (shell)); const char *uri = NULL; if (panel) uri = cc_panel_get_help_uri (panel); if (!g_strcmp0(g_getenv("XDG_CURRENT_DESKTOP"), "Unity")) gtk_show_uri (gtk_widget_get_screen (window), uri ? uri : "help:ubuntu-help/prefs", GDK_CURRENT_TIME, NULL); else gtk_show_uri (gtk_widget_get_screen (window), uri ? uri : "help:gnome-help/prefs", GDK_CURRENT_TIME, NULL); } static void quit_activated (GSimpleAction *action, GVariant *parameter, gpointer user_data) { CinnamonControlCenter *shell = user_data; g_object_unref (shell); } static void application_startup_cb (GApplication *application, CinnamonControlCenter *shell) { GMenu *menu, *section; GAction *action; action = G_ACTION (g_simple_action_new ("help", NULL)); g_action_map_add_action (G_ACTION_MAP (application), action); g_signal_connect (action, "activate", G_CALLBACK (help_activated), shell); action = G_ACTION (g_simple_action_new ("quit", NULL)); g_action_map_add_action (G_ACTION_MAP (application), action); g_signal_connect (action, "activate", G_CALLBACK (quit_activated), shell); menu = g_menu_new (); section = g_menu_new (); g_menu_append (section, _("Help"), "app.help"); g_menu_append (section, _("Quit"), "app.quit"); g_menu_append_section (menu, NULL, G_MENU_MODEL (section)); gtk_application_set_app_menu (GTK_APPLICATION (application), G_MENU_MODEL (menu)); gtk_application_add_accelerator (GTK_APPLICATION (application), "F1", "app.help", NULL); /* nothing else to do here, we don't want to show a window before * we've looked at the commandline */ } int main (int argc, char **argv) { CinnamonControlCenter *shell; GtkApplication *application; int status; bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); #ifdef GDK_WINDOWING_X11 XInitThreads (); #endif gtk_init (&argc, &argv); cc_shell_log_init (); /* register a symbolic icon size for use in sidebar lists */ gtk_icon_size_register ("cc-sidebar-list", 24, 24); notify_init ("cinnamon-control-center"); shell = cinnamon_control_center_new (); /* enforce single instance of this application */ application = gtk_application_new ("org.cinnamon.ControlCenter", G_APPLICATION_HANDLES_COMMAND_LINE); g_signal_connect (application, "startup", G_CALLBACK (application_startup_cb), shell); g_signal_connect (application, "command-line", G_CALLBACK (application_command_line_cb), shell); status = g_application_run (G_APPLICATION (application), argc, argv); g_object_unref (application); return status; }