Imported Upstream version 0.4.1
Laurent LĂ©onard
12 years ago
120 | 120 | AUTOHEADER = @AUTOHEADER@ |
121 | 121 | AUTOMAKE = @AUTOMAKE@ |
122 | 122 | AWK = @AWK@ |
123 | CATALOGS = @CATALOGS@ | |
124 | CATOBJEXT = @CATOBJEXT@ | |
125 | 123 | CC = @CC@ |
126 | 124 | CCDEPMODE = @CCDEPMODE@ |
127 | 125 | CFLAGS = @CFLAGS@ |
145 | 143 | GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ |
146 | 144 | GLIB2_CFLAGS = @GLIB2_CFLAGS@ |
147 | 145 | GLIB2_LIBS = @GLIB2_LIBS@ |
148 | GMOFILES = @GMOFILES@ | |
149 | 146 | GMSGFMT = @GMSGFMT@ |
150 | 147 | GREP = @GREP@ |
151 | 148 | GTK_API_VERSION = @GTK_API_VERSION@ |
160 | 157 | INSTALL_PROGRAM = @INSTALL_PROGRAM@ |
161 | 158 | INSTALL_SCRIPT = @INSTALL_SCRIPT@ |
162 | 159 | INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ |
163 | INSTOBJEXT = @INSTOBJEXT@ | |
164 | INTLLIBS = @INTLLIBS@ | |
165 | 160 | INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ |
166 | 161 | INTLTOOL_MERGE = @INTLTOOL_MERGE@ |
167 | 162 | INTLTOOL_PERL = @INTLTOOL_PERL@ |
181 | 176 | MAKEINFO = @MAKEINFO@ |
182 | 177 | MANIFEST_TOOL = @MANIFEST_TOOL@ |
183 | 178 | MKDIR_P = @MKDIR_P@ |
184 | MKINSTALLDIRS = @MKINSTALLDIRS@ | |
185 | 179 | MOZILLA_PLUGIN_CFLAGS = @MOZILLA_PLUGIN_CFLAGS@ |
186 | 180 | MOZILLA_PLUGIN_LIBS = @MOZILLA_PLUGIN_LIBS@ |
187 | 181 | MSGFMT = @MSGFMT@ |
188 | MSGFMT_OPTS = @MSGFMT_OPTS@ | |
189 | 182 | MSGMERGE = @MSGMERGE@ |
190 | 183 | NM = @NM@ |
191 | 184 | NMEDIT = @NMEDIT@ |
206 | 199 | PKG_CONFIG = @PKG_CONFIG@ |
207 | 200 | PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ |
208 | 201 | PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ |
209 | POFILES = @POFILES@ | |
210 | POSUB = @POSUB@ | |
211 | PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ | |
212 | PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ | |
213 | 202 | RANLIB = @RANLIB@ |
214 | 203 | SED = @SED@ |
215 | 204 | SET_MAKE = @SET_MAKE@ |
0 | 0 | Virt Viewer News |
1 | 1 | ================ |
2 | ||
3 | 0.4.1: Aug 4, 2011 | |
4 | ------------------- | |
5 | ||
6 | - Remove bogus use of AM_GLIB_GNU_GETTEXT macro to try to | |
7 | facilitate BSD builds | |
8 | - Support multiple monitors with SPICE and QXL drivers | |
9 | - Don't hardcode SSH port to 22 when tunnelling | |
2 | 10 | |
3 | 11 | 0.4.0: Jul 12, 2011 |
4 | 12 | ------------------- |
17 | 17 | You have another version of autoconf. It may work, but is not guaranteed to. |
18 | 18 | If you have problems, you may need to regenerate the build system entirely. |
19 | 19 | To do so, use the procedure documented by the package, typically `autoreconf'.])]) |
20 | ||
21 | # Copyright (C) 1995-2002 Free Software Foundation, Inc. | |
22 | # Copyright (C) 2001-2003,2004 Red Hat, Inc. | |
23 | # | |
24 | # This file is free software, distributed under the terms of the GNU | |
25 | # General Public License. As a special exception to the GNU General | |
26 | # Public License, this file may be distributed as part of a program | |
27 | # that contains a configuration script generated by Autoconf, under | |
28 | # the same distribution terms as the rest of that program. | |
29 | # | |
30 | # This file can be copied and used freely without restrictions. It can | |
31 | # be used in projects which are not available under the GNU Public License | |
32 | # but which still want to provide support for the GNU gettext functionality. | |
33 | # | |
34 | # Macro to add for using GNU gettext. | |
35 | # Ulrich Drepper <drepper@cygnus.com>, 1995, 1996 | |
36 | # | |
37 | # Modified to never use included libintl. | |
38 | # Owen Taylor <otaylor@redhat.com>, 12/15/1998 | |
39 | # | |
40 | # Major rework to remove unused code | |
41 | # Owen Taylor <otaylor@redhat.com>, 12/11/2002 | |
42 | # | |
43 | # Added better handling of ALL_LINGUAS from GNU gettext version | |
44 | # written by Bruno Haible, Owen Taylor <otaylor.redhat.com> 5/30/3002 | |
45 | # | |
46 | # Modified to require ngettext | |
47 | # Matthias Clasen <mclasen@redhat.com> 08/06/2004 | |
48 | # | |
49 | # We need this here as well, since someone might use autoconf-2.5x | |
50 | # to configure GLib then an older version to configure a package | |
51 | # using AM_GLIB_GNU_GETTEXT | |
52 | AC_PREREQ(2.53) | |
53 | ||
54 | dnl | |
55 | dnl We go to great lengths to make sure that aclocal won't | |
56 | dnl try to pull in the installed version of these macros | |
57 | dnl when running aclocal in the glib directory. | |
58 | dnl | |
59 | m4_copy([AC_DEFUN],[glib_DEFUN]) | |
60 | m4_copy([AC_REQUIRE],[glib_REQUIRE]) | |
61 | dnl | |
62 | dnl At the end, if we're not within glib, we'll define the public | |
63 | dnl definitions in terms of our private definitions. | |
64 | dnl | |
65 | ||
66 | # GLIB_LC_MESSAGES | |
67 | #-------------------- | |
68 | glib_DEFUN([GLIB_LC_MESSAGES], | |
69 | [AC_CHECK_HEADERS([locale.h]) | |
70 | if test $ac_cv_header_locale_h = yes; then | |
71 | AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, | |
72 | [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES], | |
73 | am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) | |
74 | if test $am_cv_val_LC_MESSAGES = yes; then | |
75 | AC_DEFINE(HAVE_LC_MESSAGES, 1, | |
76 | [Define if your <locale.h> file defines LC_MESSAGES.]) | |
77 | fi | |
78 | fi]) | |
79 | ||
80 | # GLIB_PATH_PROG_WITH_TEST | |
81 | #---------------------------- | |
82 | dnl GLIB_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, | |
83 | dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) | |
84 | glib_DEFUN([GLIB_PATH_PROG_WITH_TEST], | |
85 | [# Extract the first word of "$2", so it can be a program name with args. | |
86 | set dummy $2; ac_word=[$]2 | |
87 | AC_MSG_CHECKING([for $ac_word]) | |
88 | AC_CACHE_VAL(ac_cv_path_$1, | |
89 | [case "[$]$1" in | |
90 | /*) | |
91 | ac_cv_path_$1="[$]$1" # Let the user override the test with a path. | |
92 | ;; | |
93 | *) | |
94 | IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" | |
95 | for ac_dir in ifelse([$5], , $PATH, [$5]); do | |
96 | test -z "$ac_dir" && ac_dir=. | |
97 | if test -f $ac_dir/$ac_word; then | |
98 | if [$3]; then | |
99 | ac_cv_path_$1="$ac_dir/$ac_word" | |
100 | break | |
101 | fi | |
102 | fi | |
103 | done | |
104 | IFS="$ac_save_ifs" | |
105 | dnl If no 4th arg is given, leave the cache variable unset, | |
106 | dnl so AC_PATH_PROGS will keep looking. | |
107 | ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" | |
108 | ])dnl | |
109 | ;; | |
110 | esac])dnl | |
111 | $1="$ac_cv_path_$1" | |
112 | if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then | |
113 | AC_MSG_RESULT([$]$1) | |
114 | else | |
115 | AC_MSG_RESULT(no) | |
116 | fi | |
117 | AC_SUBST($1)dnl | |
118 | ]) | |
119 | ||
120 | # GLIB_WITH_NLS | |
121 | #----------------- | |
122 | glib_DEFUN([GLIB_WITH_NLS], | |
123 | dnl NLS is obligatory | |
124 | [USE_NLS=yes | |
125 | AC_SUBST(USE_NLS) | |
126 | ||
127 | gt_cv_have_gettext=no | |
128 | ||
129 | CATOBJEXT=NONE | |
130 | XGETTEXT=: | |
131 | INTLLIBS= | |
132 | ||
133 | AC_CHECK_HEADER(libintl.h, | |
134 | [gt_cv_func_dgettext_libintl="no" | |
135 | libintl_extra_libs="" | |
136 | ||
137 | # | |
138 | # First check in libc | |
139 | # | |
140 | AC_CACHE_CHECK([for ngettext in libc], gt_cv_func_ngettext_libc, | |
141 | [AC_TRY_LINK([ | |
142 | #include <libintl.h> | |
143 | ], | |
144 | [return !ngettext ("","", 1)], | |
145 | gt_cv_func_ngettext_libc=yes, | |
146 | gt_cv_func_ngettext_libc=no) | |
147 | ]) | |
148 | ||
149 | if test "$gt_cv_func_ngettext_libc" = "yes" ; then | |
150 | AC_CACHE_CHECK([for dgettext in libc], gt_cv_func_dgettext_libc, | |
151 | [AC_TRY_LINK([ | |
152 | #include <libintl.h> | |
153 | ], | |
154 | [return !dgettext ("","")], | |
155 | gt_cv_func_dgettext_libc=yes, | |
156 | gt_cv_func_dgettext_libc=no) | |
157 | ]) | |
158 | fi | |
159 | ||
160 | if test "$gt_cv_func_ngettext_libc" = "yes" ; then | |
161 | AC_CHECK_FUNCS(bind_textdomain_codeset) | |
162 | fi | |
163 | ||
164 | # | |
165 | # If we don't have everything we want, check in libintl | |
166 | # | |
167 | if test "$gt_cv_func_dgettext_libc" != "yes" \ | |
168 | || test "$gt_cv_func_ngettext_libc" != "yes" \ | |
169 | || test "$ac_cv_func_bind_textdomain_codeset" != "yes" ; then | |
170 | ||
171 | AC_CHECK_LIB(intl, bindtextdomain, | |
172 | [AC_CHECK_LIB(intl, ngettext, | |
173 | [AC_CHECK_LIB(intl, dgettext, | |
174 | gt_cv_func_dgettext_libintl=yes)])]) | |
175 | ||
176 | if test "$gt_cv_func_dgettext_libintl" != "yes" ; then | |
177 | AC_MSG_CHECKING([if -liconv is needed to use gettext]) | |
178 | AC_MSG_RESULT([]) | |
179 | AC_CHECK_LIB(intl, ngettext, | |
180 | [AC_CHECK_LIB(intl, dcgettext, | |
181 | [gt_cv_func_dgettext_libintl=yes | |
182 | libintl_extra_libs=-liconv], | |
183 | :,-liconv)], | |
184 | :,-liconv) | |
185 | fi | |
186 | ||
187 | # | |
188 | # If we found libintl, then check in it for bind_textdomain_codeset(); | |
189 | # we'll prefer libc if neither have bind_textdomain_codeset(), | |
190 | # and both have dgettext and ngettext | |
191 | # | |
192 | if test "$gt_cv_func_dgettext_libintl" = "yes" ; then | |
193 | glib_save_LIBS="$LIBS" | |
194 | LIBS="$LIBS -lintl $libintl_extra_libs" | |
195 | unset ac_cv_func_bind_textdomain_codeset | |
196 | AC_CHECK_FUNCS(bind_textdomain_codeset) | |
197 | LIBS="$glib_save_LIBS" | |
198 | ||
199 | if test "$ac_cv_func_bind_textdomain_codeset" = "yes" ; then | |
200 | gt_cv_func_dgettext_libc=no | |
201 | else | |
202 | if test "$gt_cv_func_dgettext_libc" = "yes" \ | |
203 | && test "$gt_cv_func_ngettext_libc" = "yes"; then | |
204 | gt_cv_func_dgettext_libintl=no | |
205 | fi | |
206 | fi | |
207 | fi | |
208 | fi | |
209 | ||
210 | if test "$gt_cv_func_dgettext_libc" = "yes" \ | |
211 | || test "$gt_cv_func_dgettext_libintl" = "yes"; then | |
212 | gt_cv_have_gettext=yes | |
213 | fi | |
214 | ||
215 | if test "$gt_cv_func_dgettext_libintl" = "yes"; then | |
216 | INTLLIBS="-lintl $libintl_extra_libs" | |
217 | fi | |
218 | ||
219 | if test "$gt_cv_have_gettext" = "yes"; then | |
220 | AC_DEFINE(HAVE_GETTEXT,1, | |
221 | [Define if the GNU gettext() function is already present or preinstalled.]) | |
222 | GLIB_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, | |
223 | [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl | |
224 | if test "$MSGFMT" != "no"; then | |
225 | glib_save_LIBS="$LIBS" | |
226 | LIBS="$LIBS $INTLLIBS" | |
227 | AC_CHECK_FUNCS(dcgettext) | |
228 | MSGFMT_OPTS= | |
229 | AC_MSG_CHECKING([if msgfmt accepts -c]) | |
230 | GLIB_RUN_PROG([$MSGFMT -c -o /dev/null],[ | |
231 | msgid "" | |
232 | msgstr "" | |
233 | "Content-Type: text/plain; charset=UTF-8\n" | |
234 | "Project-Id-Version: test 1.0\n" | |
235 | "PO-Revision-Date: 2007-02-15 12:01+0100\n" | |
236 | "Last-Translator: test <foo@bar.xx>\n" | |
237 | "Language-Team: C <LL@li.org>\n" | |
238 | "MIME-Version: 1.0\n" | |
239 | "Content-Transfer-Encoding: 8bit\n" | |
240 | ], [MSGFMT_OPTS=-c; AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])]) | |
241 | AC_SUBST(MSGFMT_OPTS) | |
242 | AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) | |
243 | GLIB_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, | |
244 | [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) | |
245 | AC_TRY_LINK(, [extern int _nl_msg_cat_cntr; | |
246 | return _nl_msg_cat_cntr], | |
247 | [CATOBJEXT=.gmo | |
248 | DATADIRNAME=share], | |
249 | [case $host in | |
250 | *-*-solaris*) | |
251 | dnl On Solaris, if bind_textdomain_codeset is in libc, | |
252 | dnl GNU format message catalog is always supported, | |
253 | dnl since both are added to the libc all together. | |
254 | dnl Hence, we'd like to go with DATADIRNAME=share and | |
255 | dnl and CATOBJEXT=.gmo in this case. | |
256 | AC_CHECK_FUNC(bind_textdomain_codeset, | |
257 | [CATOBJEXT=.gmo | |
258 | DATADIRNAME=share], | |
259 | [CATOBJEXT=.mo | |
260 | DATADIRNAME=lib]) | |
261 | ;; | |
262 | *) | |
263 | CATOBJEXT=.mo | |
264 | DATADIRNAME=lib | |
265 | ;; | |
266 | esac]) | |
267 | LIBS="$glib_save_LIBS" | |
268 | INSTOBJEXT=.mo | |
269 | else | |
270 | gt_cv_have_gettext=no | |
271 | fi | |
272 | fi | |
273 | ]) | |
274 | ||
275 | if test "$gt_cv_have_gettext" = "yes" ; then | |
276 | AC_DEFINE(ENABLE_NLS, 1, | |
277 | [always defined to indicate that i18n is enabled]) | |
278 | fi | |
279 | ||
280 | dnl Test whether we really found GNU xgettext. | |
281 | if test "$XGETTEXT" != ":"; then | |
282 | dnl If it is not GNU xgettext we define it as : so that the | |
283 | dnl Makefiles still can work. | |
284 | if $XGETTEXT --omit-header /dev/null 2> /dev/null; then | |
285 | : ; | |
286 | else | |
287 | AC_MSG_RESULT( | |
288 | [found xgettext program is not GNU xgettext; ignore it]) | |
289 | XGETTEXT=":" | |
290 | fi | |
291 | fi | |
292 | ||
293 | # We need to process the po/ directory. | |
294 | POSUB=po | |
295 | ||
296 | AC_OUTPUT_COMMANDS( | |
297 | [case "$CONFIG_FILES" in *po/Makefile.in*) | |
298 | sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile | |
299 | esac]) | |
300 | ||
301 | dnl These rules are solely for the distribution goal. While doing this | |
302 | dnl we only have to keep exactly one list of the available catalogs | |
303 | dnl in configure.ac. | |
304 | for lang in $ALL_LINGUAS; do | |
305 | GMOFILES="$GMOFILES $lang.gmo" | |
306 | POFILES="$POFILES $lang.po" | |
307 | done | |
308 | ||
309 | dnl Make all variables we use known to autoconf. | |
310 | AC_SUBST(CATALOGS) | |
311 | AC_SUBST(CATOBJEXT) | |
312 | AC_SUBST(DATADIRNAME) | |
313 | AC_SUBST(GMOFILES) | |
314 | AC_SUBST(INSTOBJEXT) | |
315 | AC_SUBST(INTLLIBS) | |
316 | AC_SUBST(PO_IN_DATADIR_TRUE) | |
317 | AC_SUBST(PO_IN_DATADIR_FALSE) | |
318 | AC_SUBST(POFILES) | |
319 | AC_SUBST(POSUB) | |
320 | ]) | |
321 | ||
322 | # AM_GLIB_GNU_GETTEXT | |
323 | # ------------------- | |
324 | # Do checks necessary for use of gettext. If a suitable implementation | |
325 | # of gettext is found in either in libintl or in the C library, | |
326 | # it will set INTLLIBS to the libraries needed for use of gettext | |
327 | # and AC_DEFINE() HAVE_GETTEXT and ENABLE_NLS. (The shell variable | |
328 | # gt_cv_have_gettext will be set to "yes".) It will also call AC_SUBST() | |
329 | # on various variables needed by the Makefile.in.in installed by | |
330 | # glib-gettextize. | |
331 | dnl | |
332 | glib_DEFUN([GLIB_GNU_GETTEXT], | |
333 | [AC_REQUIRE([AC_PROG_CC])dnl | |
334 | AC_REQUIRE([AC_HEADER_STDC])dnl | |
335 | ||
336 | GLIB_LC_MESSAGES | |
337 | GLIB_WITH_NLS | |
338 | ||
339 | if test "$gt_cv_have_gettext" = "yes"; then | |
340 | if test "x$ALL_LINGUAS" = "x"; then | |
341 | LINGUAS= | |
342 | else | |
343 | AC_MSG_CHECKING(for catalogs to be installed) | |
344 | NEW_LINGUAS= | |
345 | for presentlang in $ALL_LINGUAS; do | |
346 | useit=no | |
347 | if test "%UNSET%" != "${LINGUAS-%UNSET%}"; then | |
348 | desiredlanguages="$LINGUAS" | |
349 | else | |
350 | desiredlanguages="$ALL_LINGUAS" | |
351 | fi | |
352 | for desiredlang in $desiredlanguages; do | |
353 | # Use the presentlang catalog if desiredlang is | |
354 | # a. equal to presentlang, or | |
355 | # b. a variant of presentlang (because in this case, | |
356 | # presentlang can be used as a fallback for messages | |
357 | # which are not translated in the desiredlang catalog). | |
358 | case "$desiredlang" in | |
359 | "$presentlang"*) useit=yes;; | |
360 | esac | |
361 | done | |
362 | if test $useit = yes; then | |
363 | NEW_LINGUAS="$NEW_LINGUAS $presentlang" | |
364 | fi | |
365 | done | |
366 | LINGUAS=$NEW_LINGUAS | |
367 | AC_MSG_RESULT($LINGUAS) | |
368 | fi | |
369 | ||
370 | dnl Construct list of names of catalog files to be constructed. | |
371 | if test -n "$LINGUAS"; then | |
372 | for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done | |
373 | fi | |
374 | fi | |
375 | ||
376 | dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly | |
377 | dnl find the mkinstalldirs script in another subdir but ($top_srcdir). | |
378 | dnl Try to locate is. | |
379 | MKINSTALLDIRS= | |
380 | if test -n "$ac_aux_dir"; then | |
381 | MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" | |
382 | fi | |
383 | if test -z "$MKINSTALLDIRS"; then | |
384 | MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" | |
385 | fi | |
386 | AC_SUBST(MKINSTALLDIRS) | |
387 | ||
388 | dnl Generate list of files to be processed by xgettext which will | |
389 | dnl be included in po/Makefile. | |
390 | test -d po || mkdir po | |
391 | if test "x$srcdir" != "x."; then | |
392 | if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then | |
393 | posrcprefix="$srcdir/" | |
394 | else | |
395 | posrcprefix="../$srcdir/" | |
396 | fi | |
397 | else | |
398 | posrcprefix="../" | |
399 | fi | |
400 | rm -f po/POTFILES | |
401 | sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ | |
402 | < $srcdir/po/POTFILES.in > po/POTFILES | |
403 | ]) | |
404 | ||
405 | # AM_GLIB_DEFINE_LOCALEDIR(VARIABLE) | |
406 | # ------------------------------- | |
407 | # Define VARIABLE to the location where catalog files will | |
408 | # be installed by po/Makefile. | |
409 | glib_DEFUN([GLIB_DEFINE_LOCALEDIR], | |
410 | [glib_REQUIRE([GLIB_GNU_GETTEXT])dnl | |
411 | glib_save_prefix="$prefix" | |
412 | glib_save_exec_prefix="$exec_prefix" | |
413 | glib_save_datarootdir="$datarootdir" | |
414 | test "x$prefix" = xNONE && prefix=$ac_default_prefix | |
415 | test "x$exec_prefix" = xNONE && exec_prefix=$prefix | |
416 | datarootdir=`eval echo "${datarootdir}"` | |
417 | if test "x$CATOBJEXT" = "x.mo" ; then | |
418 | localedir=`eval echo "${libdir}/locale"` | |
419 | else | |
420 | localedir=`eval echo "${datadir}/locale"` | |
421 | fi | |
422 | prefix="$glib_save_prefix" | |
423 | exec_prefix="$glib_save_exec_prefix" | |
424 | datarootdir="$glib_save_datarootdir" | |
425 | AC_DEFINE_UNQUOTED($1, "$localedir", | |
426 | [Define the location where the catalogs will be installed]) | |
427 | ]) | |
428 | ||
429 | dnl | |
430 | dnl Now the definitions that aclocal will find | |
431 | dnl | |
432 | ifdef(glib_configure_ac,[],[ | |
433 | AC_DEFUN([AM_GLIB_GNU_GETTEXT],[GLIB_GNU_GETTEXT($@)]) | |
434 | AC_DEFUN([AM_GLIB_DEFINE_LOCALEDIR],[GLIB_DEFINE_LOCALEDIR($@)]) | |
435 | ])dnl | |
436 | ||
437 | # GLIB_RUN_PROG(PROGRAM, TEST-FILE, [ACTION-IF-PASS], [ACTION-IF-FAIL]) | |
438 | # | |
439 | # Create a temporary file with TEST-FILE as its contents and pass the | |
440 | # file name to PROGRAM. Perform ACTION-IF-PASS if PROGRAM exits with | |
441 | # 0 and perform ACTION-IF-FAIL for any other exit status. | |
442 | AC_DEFUN([GLIB_RUN_PROG], | |
443 | [cat >conftest.foo <<_ACEOF | |
444 | $2 | |
445 | _ACEOF | |
446 | if AC_RUN_LOG([$1 conftest.foo]); then | |
447 | m4_ifval([$3], [$3], [:]) | |
448 | m4_ifvaln([$4], [else $4])dnl | |
449 | echo "$as_me: failed input was:" >&AS_MESSAGE_LOG_FD | |
450 | sed 's/^/| /' conftest.foo >&AS_MESSAGE_LOG_FD | |
451 | fi]) | |
452 | ||
453 | 20 | |
454 | 21 | |
455 | 22 | dnl IT_PROG_INTLTOOL([MINIMUM-VERSION], [no-xml]) |
0 | 0 | /* config.h.in. Generated from configure.ac by autoheader. */ |
1 | ||
2 | /* always defined to indicate that i18n is enabled */ | |
3 | #undef ENABLE_NLS | |
4 | 1 | |
5 | 2 | /* GETTEXT package name */ |
6 | 3 | #undef GETTEXT_PACKAGE |
7 | ||
8 | /* Define to 1 if you have the `bind_textdomain_codeset' function. */ | |
9 | #undef HAVE_BIND_TEXTDOMAIN_CODESET | |
10 | ||
11 | /* Define to 1 if you have the `dcgettext' function. */ | |
12 | #undef HAVE_DCGETTEXT | |
13 | 4 | |
14 | 5 | /* Define to 1 if you have the <dlfcn.h> header file. */ |
15 | 6 | #undef HAVE_DLFCN_H |
17 | 8 | /* Define to 1 if you have the `fork' function. */ |
18 | 9 | #undef HAVE_FORK |
19 | 10 | |
20 | /* Define if the GNU gettext() function is already present or preinstalled. */ | |
21 | #undef HAVE_GETTEXT | |
22 | ||
23 | 11 | /* Define to 1 if you have the <inttypes.h> header file. */ |
24 | 12 | #undef HAVE_INTTYPES_H |
25 | ||
26 | /* Define if your <locale.h> file defines LC_MESSAGES. */ | |
27 | #undef HAVE_LC_MESSAGES | |
28 | ||
29 | /* Define to 1 if you have the <locale.h> header file. */ | |
30 | #undef HAVE_LOCALE_H | |
31 | 13 | |
32 | 14 | /* Define to 1 if you have the <memory.h> header file. */ |
33 | 15 | #undef HAVE_MEMORY_H |
0 | 0 | #! /bin/sh |
1 | 1 | # Guess values for system-dependent variables and create Makefiles. |
2 | # Generated by GNU Autoconf 2.68 for virt-viewer 0.4.0. | |
2 | # Generated by GNU Autoconf 2.68 for virt-viewer 0.4.1. | |
3 | 3 | # |
4 | 4 | # |
5 | 5 | # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, |
566 | 566 | # Identity of this package. |
567 | 567 | PACKAGE_NAME='virt-viewer' |
568 | 568 | PACKAGE_TARNAME='virt-viewer' |
569 | PACKAGE_VERSION='0.4.0' | |
570 | PACKAGE_STRING='virt-viewer 0.4.0' | |
569 | PACKAGE_VERSION='0.4.1' | |
570 | PACKAGE_STRING='virt-viewer 0.4.1' | |
571 | 571 | PACKAGE_BUGREPORT='' |
572 | 572 | PACKAGE_URL='' |
573 | 573 | |
645 | 645 | PKG_CONFIG_LIBDIR |
646 | 646 | PKG_CONFIG_PATH |
647 | 647 | PKG_CONFIG |
648 | MKINSTALLDIRS | |
649 | POSUB | |
650 | POFILES | |
651 | PO_IN_DATADIR_FALSE | |
652 | PO_IN_DATADIR_TRUE | |
653 | INTLLIBS | |
654 | INSTOBJEXT | |
655 | GMOFILES | |
656 | CATOBJEXT | |
657 | CATALOGS | |
658 | MSGFMT_OPTS | |
659 | 648 | DATADIRNAME |
660 | 649 | ALL_LINGUAS |
661 | 650 | INTLTOOL_PERL |
1388 | 1377 | # Omit some internal or obsolete options to make the list less imposing. |
1389 | 1378 | # This message is too long to be a string in the A/UX 3.1 sh. |
1390 | 1379 | cat <<_ACEOF |
1391 | \`configure' configures virt-viewer 0.4.0 to adapt to many kinds of systems. | |
1380 | \`configure' configures virt-viewer 0.4.1 to adapt to many kinds of systems. | |
1392 | 1381 | |
1393 | 1382 | Usage: $0 [OPTION]... [VAR=VALUE]... |
1394 | 1383 | |
1458 | 1447 | |
1459 | 1448 | if test -n "$ac_init_help"; then |
1460 | 1449 | case $ac_init_help in |
1461 | short | recursive ) echo "Configuration of virt-viewer 0.4.0:";; | |
1450 | short | recursive ) echo "Configuration of virt-viewer 0.4.1:";; | |
1462 | 1451 | esac |
1463 | 1452 | cat <<\_ACEOF |
1464 | 1453 | |
1604 | 1593 | test -n "$ac_init_help" && exit $ac_status |
1605 | 1594 | if $ac_init_version; then |
1606 | 1595 | cat <<\_ACEOF |
1607 | virt-viewer configure 0.4.0 | |
1596 | virt-viewer configure 0.4.1 | |
1608 | 1597 | generated by GNU Autoconf 2.68 |
1609 | 1598 | |
1610 | 1599 | Copyright (C) 2010 Free Software Foundation, Inc. |
1969 | 1958 | This file contains any messages produced by compilers while |
1970 | 1959 | running configure, to aid debugging if configure makes a mistake. |
1971 | 1960 | |
1972 | It was created by virt-viewer $as_me 0.4.0, which was | |
1961 | It was created by virt-viewer $as_me 0.4.1, which was | |
1973 | 1962 | generated by GNU Autoconf 2.68. Invocation command line was |
1974 | 1963 | |
1975 | 1964 | $ $0 $@ |
2787 | 2776 | |
2788 | 2777 | # Define the identity of the package. |
2789 | 2778 | PACKAGE='virt-viewer' |
2790 | VERSION='0.4.0' | |
2779 | VERSION='0.4.1' | |
2791 | 2780 | |
2792 | 2781 | |
2793 | 2782 | cat >>confdefs.h <<_ACEOF |
12164 | 12153 | |
12165 | 12154 | |
12166 | 12155 | |
12167 | for ac_header in locale.h | |
12168 | do : | |
12169 | ac_fn_c_check_header_mongrel "$LINENO" "locale.h" "ac_cv_header_locale_h" "$ac_includes_default" | |
12170 | if test "x$ac_cv_header_locale_h" = xyes; then : | |
12171 | cat >>confdefs.h <<_ACEOF | |
12172 | #define HAVE_LOCALE_H 1 | |
12173 | _ACEOF | |
12174 | ||
12175 | fi | |
12176 | ||
12177 | done | |
12178 | ||
12179 | if test $ac_cv_header_locale_h = yes; then | |
12180 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LC_MESSAGES" >&5 | |
12181 | $as_echo_n "checking for LC_MESSAGES... " >&6; } | |
12182 | if ${am_cv_val_LC_MESSAGES+:} false; then : | |
12183 | $as_echo_n "(cached) " >&6 | |
12184 | else | |
12185 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |
12186 | /* end confdefs.h. */ | |
12187 | #include <locale.h> | |
12188 | int | |
12189 | main () | |
12190 | { | |
12191 | return LC_MESSAGES | |
12192 | ; | |
12193 | return 0; | |
12194 | } | |
12195 | _ACEOF | |
12196 | if ac_fn_c_try_link "$LINENO"; then : | |
12197 | am_cv_val_LC_MESSAGES=yes | |
12198 | else | |
12199 | am_cv_val_LC_MESSAGES=no | |
12200 | fi | |
12201 | rm -f core conftest.err conftest.$ac_objext \ | |
12202 | conftest$ac_exeext conftest.$ac_ext | |
12203 | fi | |
12204 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_val_LC_MESSAGES" >&5 | |
12205 | $as_echo "$am_cv_val_LC_MESSAGES" >&6; } | |
12206 | if test $am_cv_val_LC_MESSAGES = yes; then | |
12207 | ||
12208 | $as_echo "#define HAVE_LC_MESSAGES 1" >>confdefs.h | |
12209 | ||
12210 | fi | |
12211 | fi | |
12212 | USE_NLS=yes | |
12213 | ||
12214 | ||
12215 | gt_cv_have_gettext=no | |
12216 | ||
12217 | CATOBJEXT=NONE | |
12218 | XGETTEXT=: | |
12219 | INTLLIBS= | |
12220 | ||
12221 | ac_fn_c_check_header_mongrel "$LINENO" "libintl.h" "ac_cv_header_libintl_h" "$ac_includes_default" | |
12222 | if test "x$ac_cv_header_libintl_h" = xyes; then : | |
12223 | gt_cv_func_dgettext_libintl="no" | |
12224 | libintl_extra_libs="" | |
12225 | ||
12226 | # | |
12227 | # First check in libc | |
12228 | # | |
12229 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ngettext in libc" >&5 | |
12230 | $as_echo_n "checking for ngettext in libc... " >&6; } | |
12231 | if ${gt_cv_func_ngettext_libc+:} false; then : | |
12232 | $as_echo_n "(cached) " >&6 | |
12233 | else | |
12234 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |
12235 | /* end confdefs.h. */ | |
12236 | ||
12237 | #include <libintl.h> | |
12238 | ||
12239 | int | |
12240 | main () | |
12241 | { | |
12242 | return !ngettext ("","", 1) | |
12243 | ; | |
12244 | return 0; | |
12245 | } | |
12246 | _ACEOF | |
12247 | if ac_fn_c_try_link "$LINENO"; then : | |
12248 | gt_cv_func_ngettext_libc=yes | |
12249 | else | |
12250 | gt_cv_func_ngettext_libc=no | |
12251 | fi | |
12252 | rm -f core conftest.err conftest.$ac_objext \ | |
12253 | conftest$ac_exeext conftest.$ac_ext | |
12254 | ||
12255 | fi | |
12256 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_ngettext_libc" >&5 | |
12257 | $as_echo "$gt_cv_func_ngettext_libc" >&6; } | |
12258 | ||
12259 | if test "$gt_cv_func_ngettext_libc" = "yes" ; then | |
12260 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dgettext in libc" >&5 | |
12261 | $as_echo_n "checking for dgettext in libc... " >&6; } | |
12262 | if ${gt_cv_func_dgettext_libc+:} false; then : | |
12263 | $as_echo_n "(cached) " >&6 | |
12264 | else | |
12265 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |
12266 | /* end confdefs.h. */ | |
12267 | ||
12268 | #include <libintl.h> | |
12269 | ||
12270 | int | |
12271 | main () | |
12272 | { | |
12273 | return !dgettext ("","") | |
12274 | ; | |
12275 | return 0; | |
12276 | } | |
12277 | _ACEOF | |
12278 | if ac_fn_c_try_link "$LINENO"; then : | |
12279 | gt_cv_func_dgettext_libc=yes | |
12280 | else | |
12281 | gt_cv_func_dgettext_libc=no | |
12282 | fi | |
12283 | rm -f core conftest.err conftest.$ac_objext \ | |
12284 | conftest$ac_exeext conftest.$ac_ext | |
12285 | ||
12286 | fi | |
12287 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_dgettext_libc" >&5 | |
12288 | $as_echo "$gt_cv_func_dgettext_libc" >&6; } | |
12289 | fi | |
12290 | ||
12291 | if test "$gt_cv_func_ngettext_libc" = "yes" ; then | |
12292 | for ac_func in bind_textdomain_codeset | |
12293 | do : | |
12294 | ac_fn_c_check_func "$LINENO" "bind_textdomain_codeset" "ac_cv_func_bind_textdomain_codeset" | |
12295 | if test "x$ac_cv_func_bind_textdomain_codeset" = xyes; then : | |
12296 | cat >>confdefs.h <<_ACEOF | |
12297 | #define HAVE_BIND_TEXTDOMAIN_CODESET 1 | |
12298 | _ACEOF | |
12299 | ||
12300 | fi | |
12301 | done | |
12302 | ||
12303 | fi | |
12304 | ||
12305 | # | |
12306 | # If we don't have everything we want, check in libintl | |
12307 | # | |
12308 | if test "$gt_cv_func_dgettext_libc" != "yes" \ | |
12309 | || test "$gt_cv_func_ngettext_libc" != "yes" \ | |
12310 | || test "$ac_cv_func_bind_textdomain_codeset" != "yes" ; then | |
12311 | ||
12312 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bindtextdomain in -lintl" >&5 | |
12313 | $as_echo_n "checking for bindtextdomain in -lintl... " >&6; } | |
12314 | if ${ac_cv_lib_intl_bindtextdomain+:} false; then : | |
12315 | $as_echo_n "(cached) " >&6 | |
12316 | else | |
12317 | ac_check_lib_save_LIBS=$LIBS | |
12318 | LIBS="-lintl $LIBS" | |
12319 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |
12320 | /* end confdefs.h. */ | |
12321 | ||
12322 | /* Override any GCC internal prototype to avoid an error. | |
12323 | Use char because int might match the return type of a GCC | |
12324 | builtin and then its argument prototype would still apply. */ | |
12325 | #ifdef __cplusplus | |
12326 | extern "C" | |
12327 | #endif | |
12328 | char bindtextdomain (); | |
12329 | int | |
12330 | main () | |
12331 | { | |
12332 | return bindtextdomain (); | |
12333 | ; | |
12334 | return 0; | |
12335 | } | |
12336 | _ACEOF | |
12337 | if ac_fn_c_try_link "$LINENO"; then : | |
12338 | ac_cv_lib_intl_bindtextdomain=yes | |
12339 | else | |
12340 | ac_cv_lib_intl_bindtextdomain=no | |
12341 | fi | |
12342 | rm -f core conftest.err conftest.$ac_objext \ | |
12343 | conftest$ac_exeext conftest.$ac_ext | |
12344 | LIBS=$ac_check_lib_save_LIBS | |
12345 | fi | |
12346 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_bindtextdomain" >&5 | |
12347 | $as_echo "$ac_cv_lib_intl_bindtextdomain" >&6; } | |
12348 | if test "x$ac_cv_lib_intl_bindtextdomain" = xyes; then : | |
12349 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ngettext in -lintl" >&5 | |
12350 | $as_echo_n "checking for ngettext in -lintl... " >&6; } | |
12351 | if ${ac_cv_lib_intl_ngettext+:} false; then : | |
12352 | $as_echo_n "(cached) " >&6 | |
12353 | else | |
12354 | ac_check_lib_save_LIBS=$LIBS | |
12355 | LIBS="-lintl $LIBS" | |
12356 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |
12357 | /* end confdefs.h. */ | |
12358 | ||
12359 | /* Override any GCC internal prototype to avoid an error. | |
12360 | Use char because int might match the return type of a GCC | |
12361 | builtin and then its argument prototype would still apply. */ | |
12362 | #ifdef __cplusplus | |
12363 | extern "C" | |
12364 | #endif | |
12365 | char ngettext (); | |
12366 | int | |
12367 | main () | |
12368 | { | |
12369 | return ngettext (); | |
12370 | ; | |
12371 | return 0; | |
12372 | } | |
12373 | _ACEOF | |
12374 | if ac_fn_c_try_link "$LINENO"; then : | |
12375 | ac_cv_lib_intl_ngettext=yes | |
12376 | else | |
12377 | ac_cv_lib_intl_ngettext=no | |
12378 | fi | |
12379 | rm -f core conftest.err conftest.$ac_objext \ | |
12380 | conftest$ac_exeext conftest.$ac_ext | |
12381 | LIBS=$ac_check_lib_save_LIBS | |
12382 | fi | |
12383 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_ngettext" >&5 | |
12384 | $as_echo "$ac_cv_lib_intl_ngettext" >&6; } | |
12385 | if test "x$ac_cv_lib_intl_ngettext" = xyes; then : | |
12386 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dgettext in -lintl" >&5 | |
12387 | $as_echo_n "checking for dgettext in -lintl... " >&6; } | |
12388 | if ${ac_cv_lib_intl_dgettext+:} false; then : | |
12389 | $as_echo_n "(cached) " >&6 | |
12390 | else | |
12391 | ac_check_lib_save_LIBS=$LIBS | |
12392 | LIBS="-lintl $LIBS" | |
12393 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |
12394 | /* end confdefs.h. */ | |
12395 | ||
12396 | /* Override any GCC internal prototype to avoid an error. | |
12397 | Use char because int might match the return type of a GCC | |
12398 | builtin and then its argument prototype would still apply. */ | |
12399 | #ifdef __cplusplus | |
12400 | extern "C" | |
12401 | #endif | |
12402 | char dgettext (); | |
12403 | int | |
12404 | main () | |
12405 | { | |
12406 | return dgettext (); | |
12407 | ; | |
12408 | return 0; | |
12409 | } | |
12410 | _ACEOF | |
12411 | if ac_fn_c_try_link "$LINENO"; then : | |
12412 | ac_cv_lib_intl_dgettext=yes | |
12413 | else | |
12414 | ac_cv_lib_intl_dgettext=no | |
12415 | fi | |
12416 | rm -f core conftest.err conftest.$ac_objext \ | |
12417 | conftest$ac_exeext conftest.$ac_ext | |
12418 | LIBS=$ac_check_lib_save_LIBS | |
12419 | fi | |
12420 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_dgettext" >&5 | |
12421 | $as_echo "$ac_cv_lib_intl_dgettext" >&6; } | |
12422 | if test "x$ac_cv_lib_intl_dgettext" = xyes; then : | |
12423 | gt_cv_func_dgettext_libintl=yes | |
12424 | fi | |
12425 | ||
12426 | fi | |
12427 | ||
12428 | fi | |
12429 | ||
12430 | ||
12431 | if test "$gt_cv_func_dgettext_libintl" != "yes" ; then | |
12432 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking if -liconv is needed to use gettext" >&5 | |
12433 | $as_echo_n "checking if -liconv is needed to use gettext... " >&6; } | |
12434 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5 | |
12435 | $as_echo "" >&6; } | |
12436 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ngettext in -lintl" >&5 | |
12437 | $as_echo_n "checking for ngettext in -lintl... " >&6; } | |
12438 | if ${ac_cv_lib_intl_ngettext+:} false; then : | |
12439 | $as_echo_n "(cached) " >&6 | |
12440 | else | |
12441 | ac_check_lib_save_LIBS=$LIBS | |
12442 | LIBS="-lintl -liconv $LIBS" | |
12443 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |
12444 | /* end confdefs.h. */ | |
12445 | ||
12446 | /* Override any GCC internal prototype to avoid an error. | |
12447 | Use char because int might match the return type of a GCC | |
12448 | builtin and then its argument prototype would still apply. */ | |
12449 | #ifdef __cplusplus | |
12450 | extern "C" | |
12451 | #endif | |
12452 | char ngettext (); | |
12453 | int | |
12454 | main () | |
12455 | { | |
12456 | return ngettext (); | |
12457 | ; | |
12458 | return 0; | |
12459 | } | |
12460 | _ACEOF | |
12461 | if ac_fn_c_try_link "$LINENO"; then : | |
12462 | ac_cv_lib_intl_ngettext=yes | |
12463 | else | |
12464 | ac_cv_lib_intl_ngettext=no | |
12465 | fi | |
12466 | rm -f core conftest.err conftest.$ac_objext \ | |
12467 | conftest$ac_exeext conftest.$ac_ext | |
12468 | LIBS=$ac_check_lib_save_LIBS | |
12469 | fi | |
12470 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_ngettext" >&5 | |
12471 | $as_echo "$ac_cv_lib_intl_ngettext" >&6; } | |
12472 | if test "x$ac_cv_lib_intl_ngettext" = xyes; then : | |
12473 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dcgettext in -lintl" >&5 | |
12474 | $as_echo_n "checking for dcgettext in -lintl... " >&6; } | |
12475 | if ${ac_cv_lib_intl_dcgettext+:} false; then : | |
12476 | $as_echo_n "(cached) " >&6 | |
12477 | else | |
12478 | ac_check_lib_save_LIBS=$LIBS | |
12479 | LIBS="-lintl -liconv $LIBS" | |
12480 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |
12481 | /* end confdefs.h. */ | |
12482 | ||
12483 | /* Override any GCC internal prototype to avoid an error. | |
12484 | Use char because int might match the return type of a GCC | |
12485 | builtin and then its argument prototype would still apply. */ | |
12486 | #ifdef __cplusplus | |
12487 | extern "C" | |
12488 | #endif | |
12489 | char dcgettext (); | |
12490 | int | |
12491 | main () | |
12492 | { | |
12493 | return dcgettext (); | |
12494 | ; | |
12495 | return 0; | |
12496 | } | |
12497 | _ACEOF | |
12498 | if ac_fn_c_try_link "$LINENO"; then : | |
12499 | ac_cv_lib_intl_dcgettext=yes | |
12500 | else | |
12501 | ac_cv_lib_intl_dcgettext=no | |
12502 | fi | |
12503 | rm -f core conftest.err conftest.$ac_objext \ | |
12504 | conftest$ac_exeext conftest.$ac_ext | |
12505 | LIBS=$ac_check_lib_save_LIBS | |
12506 | fi | |
12507 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_dcgettext" >&5 | |
12508 | $as_echo "$ac_cv_lib_intl_dcgettext" >&6; } | |
12509 | if test "x$ac_cv_lib_intl_dcgettext" = xyes; then : | |
12510 | gt_cv_func_dgettext_libintl=yes | |
12511 | libintl_extra_libs=-liconv | |
12512 | else | |
12513 | : | |
12514 | fi | |
12515 | ||
12516 | else | |
12517 | : | |
12518 | fi | |
12519 | ||
12520 | fi | |
12521 | ||
12522 | # | |
12523 | # If we found libintl, then check in it for bind_textdomain_codeset(); | |
12524 | # we'll prefer libc if neither have bind_textdomain_codeset(), | |
12525 | # and both have dgettext and ngettext | |
12526 | # | |
12527 | if test "$gt_cv_func_dgettext_libintl" = "yes" ; then | |
12528 | glib_save_LIBS="$LIBS" | |
12529 | LIBS="$LIBS -lintl $libintl_extra_libs" | |
12530 | unset ac_cv_func_bind_textdomain_codeset | |
12531 | for ac_func in bind_textdomain_codeset | |
12532 | do : | |
12533 | ac_fn_c_check_func "$LINENO" "bind_textdomain_codeset" "ac_cv_func_bind_textdomain_codeset" | |
12534 | if test "x$ac_cv_func_bind_textdomain_codeset" = xyes; then : | |
12535 | cat >>confdefs.h <<_ACEOF | |
12536 | #define HAVE_BIND_TEXTDOMAIN_CODESET 1 | |
12537 | _ACEOF | |
12538 | ||
12539 | fi | |
12540 | done | |
12541 | ||
12542 | LIBS="$glib_save_LIBS" | |
12543 | ||
12544 | if test "$ac_cv_func_bind_textdomain_codeset" = "yes" ; then | |
12545 | gt_cv_func_dgettext_libc=no | |
12546 | else | |
12547 | if test "$gt_cv_func_dgettext_libc" = "yes" \ | |
12548 | && test "$gt_cv_func_ngettext_libc" = "yes"; then | |
12549 | gt_cv_func_dgettext_libintl=no | |
12550 | fi | |
12551 | fi | |
12552 | fi | |
12553 | fi | |
12554 | ||
12555 | if test "$gt_cv_func_dgettext_libc" = "yes" \ | |
12556 | || test "$gt_cv_func_dgettext_libintl" = "yes"; then | |
12557 | gt_cv_have_gettext=yes | |
12558 | fi | |
12559 | ||
12560 | if test "$gt_cv_func_dgettext_libintl" = "yes"; then | |
12561 | INTLLIBS="-lintl $libintl_extra_libs" | |
12562 | fi | |
12563 | ||
12564 | if test "$gt_cv_have_gettext" = "yes"; then | |
12565 | ||
12566 | $as_echo "#define HAVE_GETTEXT 1" >>confdefs.h | |
12567 | ||
12568 | # Extract the first word of "msgfmt", so it can be a program name with args. | |
12569 | set dummy msgfmt; ac_word=$2 | |
12570 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 | |
12571 | $as_echo_n "checking for $ac_word... " >&6; } | |
12572 | if ${ac_cv_path_MSGFMT+:} false; then : | |
12573 | $as_echo_n "(cached) " >&6 | |
12574 | else | |
12575 | case "$MSGFMT" in | |
12576 | /*) | |
12577 | ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. | |
12578 | ;; | |
12579 | *) | |
12580 | IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" | |
12581 | for ac_dir in $PATH; do | |
12582 | test -z "$ac_dir" && ac_dir=. | |
12583 | if test -f $ac_dir/$ac_word; then | |
12584 | if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then | |
12585 | ac_cv_path_MSGFMT="$ac_dir/$ac_word" | |
12586 | break | |
12587 | fi | |
12588 | fi | |
12589 | done | |
12590 | IFS="$ac_save_ifs" | |
12591 | test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no" | |
12592 | ;; | |
12593 | esac | |
12594 | fi | |
12595 | MSGFMT="$ac_cv_path_MSGFMT" | |
12596 | if test "$MSGFMT" != "no"; then | |
12597 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5 | |
12598 | $as_echo "$MSGFMT" >&6; } | |
12599 | else | |
12600 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 | |
12601 | $as_echo "no" >&6; } | |
12602 | fi | |
12603 | if test "$MSGFMT" != "no"; then | |
12604 | glib_save_LIBS="$LIBS" | |
12605 | LIBS="$LIBS $INTLLIBS" | |
12606 | for ac_func in dcgettext | |
12607 | do : | |
12608 | ac_fn_c_check_func "$LINENO" "dcgettext" "ac_cv_func_dcgettext" | |
12609 | if test "x$ac_cv_func_dcgettext" = xyes; then : | |
12610 | cat >>confdefs.h <<_ACEOF | |
12611 | #define HAVE_DCGETTEXT 1 | |
12612 | _ACEOF | |
12613 | ||
12614 | fi | |
12615 | done | |
12616 | ||
12617 | MSGFMT_OPTS= | |
12618 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking if msgfmt accepts -c" >&5 | |
12619 | $as_echo_n "checking if msgfmt accepts -c... " >&6; } | |
12620 | cat >conftest.foo <<_ACEOF | |
12621 | ||
12622 | msgid "" | |
12623 | msgstr "" | |
12624 | "Content-Type: text/plain; charset=UTF-8\n" | |
12625 | "Project-Id-Version: test 1.0\n" | |
12626 | "PO-Revision-Date: 2007-02-15 12:01+0100\n" | |
12627 | "Last-Translator: test <foo@bar.xx>\n" | |
12628 | "Language-Team: C <LL@li.org>\n" | |
12629 | "MIME-Version: 1.0\n" | |
12630 | "Content-Transfer-Encoding: 8bit\n" | |
12631 | ||
12632 | _ACEOF | |
12633 | if { { $as_echo "$as_me:${as_lineno-$LINENO}: \$MSGFMT -c -o /dev/null conftest.foo"; } >&5 | |
12634 | ($MSGFMT -c -o /dev/null conftest.foo) 2>&5 | |
12635 | ac_status=$? | |
12636 | $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 | |
12637 | test $ac_status = 0; }; then | |
12638 | MSGFMT_OPTS=-c; { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 | |
12639 | $as_echo "yes" >&6; } | |
12640 | else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 | |
12641 | $as_echo "no" >&6; } | |
12642 | echo "$as_me: failed input was:" >&5 | |
12643 | sed 's/^/| /' conftest.foo >&5 | |
12644 | fi | |
12645 | ||
12646 | # Extract the first word of "gmsgfmt", so it can be a program name with args. | |
12647 | set dummy gmsgfmt; ac_word=$2 | |
12648 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 | |
12649 | $as_echo_n "checking for $ac_word... " >&6; } | |
12650 | if ${ac_cv_path_GMSGFMT+:} false; then : | |
12651 | $as_echo_n "(cached) " >&6 | |
12652 | else | |
12653 | case $GMSGFMT in | |
12654 | [\\/]* | ?:[\\/]*) | |
12655 | ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. | |
12656 | ;; | |
12657 | *) | |
12658 | as_save_IFS=$IFS; IFS=$PATH_SEPARATOR | |
12659 | for as_dir in $PATH | |
12660 | do | |
12661 | IFS=$as_save_IFS | |
12662 | test -z "$as_dir" && as_dir=. | |
12663 | for ac_exec_ext in '' $ac_executable_extensions; do | |
12664 | if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then | |
12665 | ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext" | |
12666 | $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 | |
12667 | break 2 | |
12668 | fi | |
12669 | done | |
12670 | done | |
12671 | IFS=$as_save_IFS | |
12672 | ||
12673 | test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" | |
12674 | ;; | |
12675 | esac | |
12676 | fi | |
12677 | GMSGFMT=$ac_cv_path_GMSGFMT | |
12678 | if test -n "$GMSGFMT"; then | |
12679 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5 | |
12680 | $as_echo "$GMSGFMT" >&6; } | |
12681 | else | |
12682 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 | |
12683 | $as_echo "no" >&6; } | |
12684 | fi | |
12685 | ||
12686 | ||
12687 | # Extract the first word of "xgettext", so it can be a program name with args. | |
12688 | set dummy xgettext; ac_word=$2 | |
12689 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 | |
12690 | $as_echo_n "checking for $ac_word... " >&6; } | |
12691 | if ${ac_cv_path_XGETTEXT+:} false; then : | |
12692 | $as_echo_n "(cached) " >&6 | |
12693 | else | |
12694 | case "$XGETTEXT" in | |
12695 | /*) | |
12696 | ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. | |
12697 | ;; | |
12698 | *) | |
12699 | IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" | |
12700 | for ac_dir in $PATH; do | |
12701 | test -z "$ac_dir" && ac_dir=. | |
12702 | if test -f $ac_dir/$ac_word; then | |
12703 | if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then | |
12704 | ac_cv_path_XGETTEXT="$ac_dir/$ac_word" | |
12705 | break | |
12706 | fi | |
12707 | fi | |
12708 | done | |
12709 | IFS="$ac_save_ifs" | |
12710 | test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" | |
12711 | ;; | |
12712 | esac | |
12713 | fi | |
12714 | XGETTEXT="$ac_cv_path_XGETTEXT" | |
12715 | if test "$XGETTEXT" != ":"; then | |
12716 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5 | |
12717 | $as_echo "$XGETTEXT" >&6; } | |
12718 | else | |
12719 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 | |
12720 | $as_echo "no" >&6; } | |
12721 | fi | |
12722 | ||
12723 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |
12724 | /* end confdefs.h. */ | |
12725 | ||
12726 | int | |
12727 | main () | |
12728 | { | |
12729 | extern int _nl_msg_cat_cntr; | |
12730 | return _nl_msg_cat_cntr | |
12731 | ; | |
12732 | return 0; | |
12733 | } | |
12734 | _ACEOF | |
12735 | if ac_fn_c_try_link "$LINENO"; then : | |
12736 | CATOBJEXT=.gmo | |
12737 | DATADIRNAME=share | |
12738 | else | |
12739 | case $host in | |
12740 | *-*-solaris*) | |
12741 | ac_fn_c_check_func "$LINENO" "bind_textdomain_codeset" "ac_cv_func_bind_textdomain_codeset" | |
12742 | if test "x$ac_cv_func_bind_textdomain_codeset" = xyes; then : | |
12743 | CATOBJEXT=.gmo | |
12744 | DATADIRNAME=share | |
12745 | else | |
12746 | CATOBJEXT=.mo | |
12747 | DATADIRNAME=lib | |
12748 | fi | |
12749 | ||
12750 | ;; | |
12751 | *) | |
12752 | CATOBJEXT=.mo | |
12753 | DATADIRNAME=lib | |
12754 | ;; | |
12755 | esac | |
12756 | fi | |
12757 | rm -f core conftest.err conftest.$ac_objext \ | |
12758 | conftest$ac_exeext conftest.$ac_ext | |
12759 | LIBS="$glib_save_LIBS" | |
12760 | INSTOBJEXT=.mo | |
12761 | else | |
12762 | gt_cv_have_gettext=no | |
12763 | fi | |
12764 | fi | |
12765 | ||
12766 | fi | |
12767 | ||
12768 | ||
12769 | ||
12770 | if test "$gt_cv_have_gettext" = "yes" ; then | |
12771 | ||
12772 | $as_echo "#define ENABLE_NLS 1" >>confdefs.h | |
12773 | ||
12774 | fi | |
12775 | ||
12776 | if test "$XGETTEXT" != ":"; then | |
12777 | if $XGETTEXT --omit-header /dev/null 2> /dev/null; then | |
12778 | : ; | |
12779 | else | |
12780 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: found xgettext program is not GNU xgettext; ignore it" >&5 | |
12781 | $as_echo "found xgettext program is not GNU xgettext; ignore it" >&6; } | |
12782 | XGETTEXT=":" | |
12783 | fi | |
12784 | fi | |
12785 | ||
12786 | # We need to process the po/ directory. | |
12787 | POSUB=po | |
12788 | ||
12789 | ac_config_commands="$ac_config_commands default-1" | |
12790 | ||
12791 | ||
12792 | for lang in $ALL_LINGUAS; do | |
12793 | GMOFILES="$GMOFILES $lang.gmo" | |
12794 | POFILES="$POFILES $lang.po" | |
12795 | done | |
12796 | ||
12797 | ||
12798 | ||
12799 | ||
12800 | ||
12801 | ||
12802 | ||
12803 | ||
12804 | ||
12805 | ||
12806 | ||
12807 | ||
12808 | ||
12809 | if test "$gt_cv_have_gettext" = "yes"; then | |
12810 | if test "x$ALL_LINGUAS" = "x"; then | |
12811 | LINGUAS= | |
12812 | else | |
12813 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for catalogs to be installed" >&5 | |
12814 | $as_echo_n "checking for catalogs to be installed... " >&6; } | |
12815 | NEW_LINGUAS= | |
12816 | for presentlang in $ALL_LINGUAS; do | |
12817 | useit=no | |
12818 | if test "%UNSET%" != "${LINGUAS-%UNSET%}"; then | |
12819 | desiredlanguages="$LINGUAS" | |
12820 | else | |
12821 | desiredlanguages="$ALL_LINGUAS" | |
12822 | fi | |
12823 | for desiredlang in $desiredlanguages; do | |
12824 | # Use the presentlang catalog if desiredlang is | |
12825 | # a. equal to presentlang, or | |
12826 | # b. a variant of presentlang (because in this case, | |
12827 | # presentlang can be used as a fallback for messages | |
12828 | # which are not translated in the desiredlang catalog). | |
12829 | case "$desiredlang" in | |
12830 | "$presentlang"*) useit=yes;; | |
12831 | esac | |
12832 | done | |
12833 | if test $useit = yes; then | |
12834 | NEW_LINGUAS="$NEW_LINGUAS $presentlang" | |
12835 | fi | |
12836 | done | |
12837 | LINGUAS=$NEW_LINGUAS | |
12838 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LINGUAS" >&5 | |
12839 | $as_echo "$LINGUAS" >&6; } | |
12840 | fi | |
12841 | ||
12842 | if test -n "$LINGUAS"; then | |
12843 | for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done | |
12844 | fi | |
12845 | fi | |
12846 | ||
12847 | MKINSTALLDIRS= | |
12848 | if test -n "$ac_aux_dir"; then | |
12849 | MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" | |
12850 | fi | |
12851 | if test -z "$MKINSTALLDIRS"; then | |
12852 | MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" | |
12853 | fi | |
12854 | ||
12855 | ||
12856 | test -d po || mkdir po | |
12857 | if test "x$srcdir" != "x."; then | |
12858 | if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then | |
12859 | posrcprefix="$srcdir/" | |
12860 | else | |
12861 | posrcprefix="../$srcdir/" | |
12862 | fi | |
12863 | else | |
12864 | posrcprefix="../" | |
12865 | fi | |
12866 | rm -f po/POTFILES | |
12867 | sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ | |
12868 | < $srcdir/po/POTFILES.in > po/POTFILES | |
12869 | ||
12870 | ||
12871 | 12156 | |
12872 | 12157 | |
12873 | 12158 | |
14549 | 13834 | # report actual input values of CONFIG_FILES etc. instead of their |
14550 | 13835 | # values after options handling. |
14551 | 13836 | ac_log=" |
14552 | This file was extended by virt-viewer $as_me 0.4.0, which was | |
13837 | This file was extended by virt-viewer $as_me 0.4.1, which was | |
14553 | 13838 | generated by GNU Autoconf 2.68. Invocation command line was |
14554 | 13839 | |
14555 | 13840 | CONFIG_FILES = $CONFIG_FILES |
14615 | 13900 | cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 |
14616 | 13901 | ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" |
14617 | 13902 | ac_cs_version="\\ |
14618 | virt-viewer config.status 0.4.0 | |
13903 | virt-viewer config.status 0.4.1 | |
14619 | 13904 | configured by $0, generated by GNU Autoconf 2.68, |
14620 | 13905 | with options \\"\$ac_cs_config\\" |
14621 | 13906 | |
15013 | 14298 | |
15014 | 14299 | |
15015 | 14300 | |
15016 | ||
15017 | 14301 | _ACEOF |
15018 | 14302 | |
15019 | 14303 | cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 |
15025 | 14309 | "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; |
15026 | 14310 | "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; |
15027 | 14311 | "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; |
15028 | "default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;; | |
15029 | 14312 | "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; |
15030 | 14313 | "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; |
15031 | 14314 | "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;; |
16355 | 15638 | chmod +x "$ofile" |
16356 | 15639 | |
16357 | 15640 | ;; |
16358 | "default-1":C) case "$CONFIG_FILES" in *po/Makefile.in*) | |
16359 | sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile | |
16360 | esac ;; | |
16361 | 15641 | "po/stamp-it":C) |
16362 | 15642 | if ! grep "^# INTLTOOL_MAKEFILE$" "po/Makefile.in" > /dev/null ; then |
16363 | 15643 | as_fn_error $? "po/Makefile.in.in was not created by intltoolize." "$LINENO" 5 |
0 | 0 | |
1 | AC_INIT(virt-viewer, 0.4.0) | |
1 | AC_INIT(virt-viewer, 0.4.1) | |
2 | 2 | AC_CONFIG_SRCDIR(src/virt-viewer-main.c) |
3 | 3 | AM_CONFIG_HEADER(config.h) |
4 | 4 | dnl Make automake keep quiet about wildcards & other GNUmake-isms |
32 | 32 | AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [GETTEXT package name]) |
33 | 33 | |
34 | 34 | IT_PROG_INTLTOOL([0.35.0]) |
35 | AM_GLIB_GNU_GETTEXT | |
36 | 35 | |
37 | 36 | |
38 | 37 | PKG_CHECK_MODULES(GLIB2, gmodule-export-2.0 >= $GLIB2_REQUIRED) |
88 | 88 | AUTOHEADER = @AUTOHEADER@ |
89 | 89 | AUTOMAKE = @AUTOMAKE@ |
90 | 90 | AWK = @AWK@ |
91 | CATALOGS = @CATALOGS@ | |
92 | CATOBJEXT = @CATOBJEXT@ | |
93 | 91 | CC = @CC@ |
94 | 92 | CCDEPMODE = @CCDEPMODE@ |
95 | 93 | CFLAGS = @CFLAGS@ |
113 | 111 | GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ |
114 | 112 | GLIB2_CFLAGS = @GLIB2_CFLAGS@ |
115 | 113 | GLIB2_LIBS = @GLIB2_LIBS@ |
116 | GMOFILES = @GMOFILES@ | |
117 | 114 | GMSGFMT = @GMSGFMT@ |
118 | 115 | GREP = @GREP@ |
119 | 116 | GTK_API_VERSION = @GTK_API_VERSION@ |
128 | 125 | INSTALL_PROGRAM = @INSTALL_PROGRAM@ |
129 | 126 | INSTALL_SCRIPT = @INSTALL_SCRIPT@ |
130 | 127 | INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ |
131 | INSTOBJEXT = @INSTOBJEXT@ | |
132 | INTLLIBS = @INTLLIBS@ | |
133 | 128 | INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ |
134 | 129 | INTLTOOL_MERGE = @INTLTOOL_MERGE@ |
135 | 130 | INTLTOOL_PERL = @INTLTOOL_PERL@ |
149 | 144 | MAKEINFO = @MAKEINFO@ |
150 | 145 | MANIFEST_TOOL = @MANIFEST_TOOL@ |
151 | 146 | MKDIR_P = @MKDIR_P@ |
152 | MKINSTALLDIRS = @MKINSTALLDIRS@ | |
153 | 147 | MOZILLA_PLUGIN_CFLAGS = @MOZILLA_PLUGIN_CFLAGS@ |
154 | 148 | MOZILLA_PLUGIN_LIBS = @MOZILLA_PLUGIN_LIBS@ |
155 | 149 | MSGFMT = @MSGFMT@ |
156 | MSGFMT_OPTS = @MSGFMT_OPTS@ | |
157 | 150 | MSGMERGE = @MSGMERGE@ |
158 | 151 | NM = @NM@ |
159 | 152 | NMEDIT = @NMEDIT@ |
174 | 167 | PKG_CONFIG = @PKG_CONFIG@ |
175 | 168 | PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ |
176 | 169 | PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ |
177 | POFILES = @POFILES@ | |
178 | POSUB = @POSUB@ | |
179 | PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ | |
180 | PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ | |
181 | 170 | RANLIB = @RANLIB@ |
182 | 171 | SED = @SED@ |
183 | 172 | SET_MAKE = @SET_MAKE@ |
134 | 134 | AUTOHEADER = @AUTOHEADER@ |
135 | 135 | AUTOMAKE = @AUTOMAKE@ |
136 | 136 | AWK = @AWK@ |
137 | CATALOGS = @CATALOGS@ | |
138 | CATOBJEXT = @CATOBJEXT@ | |
139 | 137 | CC = @CC@ |
140 | 138 | CCDEPMODE = @CCDEPMODE@ |
141 | 139 | CFLAGS = @CFLAGS@ |
159 | 157 | GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ |
160 | 158 | GLIB2_CFLAGS = @GLIB2_CFLAGS@ |
161 | 159 | GLIB2_LIBS = @GLIB2_LIBS@ |
162 | GMOFILES = @GMOFILES@ | |
163 | 160 | GMSGFMT = @GMSGFMT@ |
164 | 161 | GREP = @GREP@ |
165 | 162 | GTK_API_VERSION = @GTK_API_VERSION@ |
174 | 171 | INSTALL_PROGRAM = @INSTALL_PROGRAM@ |
175 | 172 | INSTALL_SCRIPT = @INSTALL_SCRIPT@ |
176 | 173 | INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ |
177 | INSTOBJEXT = @INSTOBJEXT@ | |
178 | INTLLIBS = @INTLLIBS@ | |
179 | 174 | INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ |
180 | 175 | INTLTOOL_MERGE = @INTLTOOL_MERGE@ |
181 | 176 | INTLTOOL_PERL = @INTLTOOL_PERL@ |
195 | 190 | MAKEINFO = @MAKEINFO@ |
196 | 191 | MANIFEST_TOOL = @MANIFEST_TOOL@ |
197 | 192 | MKDIR_P = @MKDIR_P@ |
198 | MKINSTALLDIRS = @MKINSTALLDIRS@ | |
199 | 193 | MOZILLA_PLUGIN_CFLAGS = @MOZILLA_PLUGIN_CFLAGS@ |
200 | 194 | MOZILLA_PLUGIN_LIBS = @MOZILLA_PLUGIN_LIBS@ |
201 | 195 | MSGFMT = @MSGFMT@ |
202 | MSGFMT_OPTS = @MSGFMT_OPTS@ | |
203 | 196 | MSGMERGE = @MSGMERGE@ |
204 | 197 | NM = @NM@ |
205 | 198 | NMEDIT = @NMEDIT@ |
220 | 213 | PKG_CONFIG = @PKG_CONFIG@ |
221 | 214 | PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ |
222 | 215 | PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ |
223 | POFILES = @POFILES@ | |
224 | POSUB = @POSUB@ | |
225 | PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ | |
226 | PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ | |
227 | 216 | RANLIB = @RANLIB@ |
228 | 217 | SED = @SED@ |
229 | 218 | SET_MAKE = @SET_MAKE@ |
10 | 10 | |
11 | 11 | virt_viewer_SOURCES = \ |
12 | 12 | virt-viewer-main.c \ |
13 | virt-viewer.h virt-viewer.c \ | |
13 | 14 | virt-viewer-util.h virt-viewer-util.c \ |
14 | 15 | virt-viewer-auth.h virt-viewer-auth.c \ |
15 | 16 | virt-viewer-events.h virt-viewer-events.c \ |
16 | virt-viewer.h virt-viewer.c \ | |
17 | virt-viewer-app.h virt-viewer-app.c \ | |
17 | 18 | virt-viewer-session.h virt-viewer-session.c \ |
18 | 19 | virt-viewer-session-vnc.h virt-viewer-session-vnc.c \ |
19 | 20 | virt-viewer-display.h virt-viewer-display.c \ |
20 | 21 | virt-viewer-display-vnc.h virt-viewer-display-vnc.c \ |
22 | virt-viewer-notebook.h virt-viewer-notebook.c \ | |
23 | virt-viewer-window.h virt-viewer-window.c \ | |
21 | 24 | view/autoDrawer.c \ |
22 | 25 | view/autoDrawer.h \ |
23 | 26 | view/drawer.c \ |
54 | 54 | CONFIG_CLEAN_VPATH_FILES = |
55 | 55 | am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(builderxmldir)" |
56 | 56 | PROGRAMS = $(bin_PROGRAMS) |
57 | am__virt_viewer_SOURCES_DIST = virt-viewer-main.c virt-viewer-util.h \ | |
58 | virt-viewer-util.c virt-viewer-auth.h virt-viewer-auth.c \ | |
59 | virt-viewer-events.h virt-viewer-events.c virt-viewer.h \ | |
60 | virt-viewer.c virt-viewer-session.h virt-viewer-session.c \ | |
57 | am__virt_viewer_SOURCES_DIST = virt-viewer-main.c virt-viewer.h \ | |
58 | virt-viewer.c virt-viewer-util.h virt-viewer-util.c \ | |
59 | virt-viewer-auth.h virt-viewer-auth.c virt-viewer-events.h \ | |
60 | virt-viewer-events.c virt-viewer-app.h virt-viewer-app.c \ | |
61 | virt-viewer-session.h virt-viewer-session.c \ | |
61 | 62 | virt-viewer-session-vnc.h virt-viewer-session-vnc.c \ |
62 | 63 | virt-viewer-display.h virt-viewer-display.c \ |
63 | 64 | virt-viewer-display-vnc.h virt-viewer-display-vnc.c \ |
64 | view/autoDrawer.c view/autoDrawer.h view/drawer.c \ | |
65 | view/drawer.h view/ovBox.c view/ovBox.h \ | |
66 | virt-viewer-session-spice.h virt-viewer-session-spice.c \ | |
67 | virt-viewer-display-spice.h virt-viewer-display-spice.c | |
65 | virt-viewer-notebook.h virt-viewer-notebook.c \ | |
66 | virt-viewer-window.h virt-viewer-window.c view/autoDrawer.c \ | |
67 | view/autoDrawer.h view/drawer.c view/drawer.h view/ovBox.c \ | |
68 | view/ovBox.h virt-viewer-session-spice.h \ | |
69 | virt-viewer-session-spice.c virt-viewer-display-spice.h \ | |
70 | virt-viewer-display-spice.c | |
68 | 71 | @HAVE_SPICE_GTK_TRUE@am__objects_1 = virt_viewer-virt-viewer-session-spice.$(OBJEXT) \ |
69 | 72 | @HAVE_SPICE_GTK_TRUE@ virt_viewer-virt-viewer-display-spice.$(OBJEXT) |
70 | 73 | am_virt_viewer_OBJECTS = virt_viewer-virt-viewer-main.$(OBJEXT) \ |
74 | virt_viewer-virt-viewer.$(OBJEXT) \ | |
71 | 75 | virt_viewer-virt-viewer-util.$(OBJEXT) \ |
72 | 76 | virt_viewer-virt-viewer-auth.$(OBJEXT) \ |
73 | 77 | virt_viewer-virt-viewer-events.$(OBJEXT) \ |
74 | virt_viewer-virt-viewer.$(OBJEXT) \ | |
78 | virt_viewer-virt-viewer-app.$(OBJEXT) \ | |
75 | 79 | virt_viewer-virt-viewer-session.$(OBJEXT) \ |
76 | 80 | virt_viewer-virt-viewer-session-vnc.$(OBJEXT) \ |
77 | 81 | virt_viewer-virt-viewer-display.$(OBJEXT) \ |
78 | 82 | virt_viewer-virt-viewer-display-vnc.$(OBJEXT) \ |
83 | virt_viewer-virt-viewer-notebook.$(OBJEXT) \ | |
84 | virt_viewer-virt-viewer-window.$(OBJEXT) \ | |
79 | 85 | virt_viewer-autoDrawer.$(OBJEXT) virt_viewer-drawer.$(OBJEXT) \ |
80 | 86 | virt_viewer-ovBox.$(OBJEXT) $(am__objects_1) |
81 | 87 | virt_viewer_OBJECTS = $(am_virt_viewer_OBJECTS) |
148 | 154 | AUTOHEADER = @AUTOHEADER@ |
149 | 155 | AUTOMAKE = @AUTOMAKE@ |
150 | 156 | AWK = @AWK@ |
151 | CATALOGS = @CATALOGS@ | |
152 | CATOBJEXT = @CATOBJEXT@ | |
153 | 157 | CC = @CC@ |
154 | 158 | CCDEPMODE = @CCDEPMODE@ |
155 | 159 | CFLAGS = @CFLAGS@ |
173 | 177 | GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ |
174 | 178 | GLIB2_CFLAGS = @GLIB2_CFLAGS@ |
175 | 179 | GLIB2_LIBS = @GLIB2_LIBS@ |
176 | GMOFILES = @GMOFILES@ | |
177 | 180 | GMSGFMT = @GMSGFMT@ |
178 | 181 | GREP = @GREP@ |
179 | 182 | GTK_API_VERSION = @GTK_API_VERSION@ |
188 | 191 | INSTALL_PROGRAM = @INSTALL_PROGRAM@ |
189 | 192 | INSTALL_SCRIPT = @INSTALL_SCRIPT@ |
190 | 193 | INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ |
191 | INSTOBJEXT = @INSTOBJEXT@ | |
192 | INTLLIBS = @INTLLIBS@ | |
193 | 194 | INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ |
194 | 195 | INTLTOOL_MERGE = @INTLTOOL_MERGE@ |
195 | 196 | INTLTOOL_PERL = @INTLTOOL_PERL@ |
209 | 210 | MAKEINFO = @MAKEINFO@ |
210 | 211 | MANIFEST_TOOL = @MANIFEST_TOOL@ |
211 | 212 | MKDIR_P = @MKDIR_P@ |
212 | MKINSTALLDIRS = @MKINSTALLDIRS@ | |
213 | 213 | MOZILLA_PLUGIN_CFLAGS = @MOZILLA_PLUGIN_CFLAGS@ |
214 | 214 | MOZILLA_PLUGIN_LIBS = @MOZILLA_PLUGIN_LIBS@ |
215 | 215 | MSGFMT = @MSGFMT@ |
216 | MSGFMT_OPTS = @MSGFMT_OPTS@ | |
217 | 216 | MSGMERGE = @MSGMERGE@ |
218 | 217 | NM = @NM@ |
219 | 218 | NMEDIT = @NMEDIT@ |
234 | 233 | PKG_CONFIG = @PKG_CONFIG@ |
235 | 234 | PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ |
236 | 235 | PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ |
237 | POFILES = @POFILES@ | |
238 | POSUB = @POSUB@ | |
239 | PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ | |
240 | PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ | |
241 | 236 | RANLIB = @RANLIB@ |
242 | 237 | SED = @SED@ |
243 | 238 | SET_MAKE = @SET_MAKE@ |
308 | 303 | virt-viewer-auth.xml |
309 | 304 | |
310 | 305 | EXTRA_DIST = $(builderxml_DATA) |
311 | virt_viewer_SOURCES = virt-viewer-main.c virt-viewer-util.h \ | |
312 | virt-viewer-util.c virt-viewer-auth.h virt-viewer-auth.c \ | |
313 | virt-viewer-events.h virt-viewer-events.c virt-viewer.h \ | |
314 | virt-viewer.c virt-viewer-session.h virt-viewer-session.c \ | |
315 | virt-viewer-session-vnc.h virt-viewer-session-vnc.c \ | |
316 | virt-viewer-display.h virt-viewer-display.c \ | |
317 | virt-viewer-display-vnc.h virt-viewer-display-vnc.c \ | |
318 | view/autoDrawer.c view/autoDrawer.h view/drawer.c \ | |
319 | view/drawer.h view/ovBox.c view/ovBox.h $(am__append_1) | |
306 | virt_viewer_SOURCES = virt-viewer-main.c virt-viewer.h virt-viewer.c \ | |
307 | virt-viewer-util.h virt-viewer-util.c virt-viewer-auth.h \ | |
308 | virt-viewer-auth.c virt-viewer-events.h virt-viewer-events.c \ | |
309 | virt-viewer-app.h virt-viewer-app.c virt-viewer-session.h \ | |
310 | virt-viewer-session.c virt-viewer-session-vnc.h \ | |
311 | virt-viewer-session-vnc.c virt-viewer-display.h \ | |
312 | virt-viewer-display.c virt-viewer-display-vnc.h \ | |
313 | virt-viewer-display-vnc.c virt-viewer-notebook.h \ | |
314 | virt-viewer-notebook.c virt-viewer-window.h \ | |
315 | virt-viewer-window.c view/autoDrawer.c view/autoDrawer.h \ | |
316 | view/drawer.c view/drawer.h view/ovBox.c view/ovBox.h \ | |
317 | $(am__append_1) | |
320 | 318 | virt_viewer_LDADD = \ |
321 | 319 | @GTK_VNC_LIBS@ \ |
322 | 320 | @SPICE_GTK_LIBS@ \ |
426 | 424 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-autoDrawer.Po@am__quote@ |
427 | 425 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-drawer.Po@am__quote@ |
428 | 426 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-ovBox.Po@am__quote@ |
427 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer-app.Po@am__quote@ | |
429 | 428 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer-auth.Po@am__quote@ |
430 | 429 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer-display-spice.Po@am__quote@ |
431 | 430 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer-display-vnc.Po@am__quote@ |
432 | 431 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer-display.Po@am__quote@ |
433 | 432 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer-events.Po@am__quote@ |
434 | 433 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer-main.Po@am__quote@ |
434 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer-notebook.Po@am__quote@ | |
435 | 435 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer-session-spice.Po@am__quote@ |
436 | 436 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer-session-vnc.Po@am__quote@ |
437 | 437 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer-session.Po@am__quote@ |
438 | 438 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer-util.Po@am__quote@ |
439 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer-window.Po@am__quote@ | |
439 | 440 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer.Po@am__quote@ |
440 | 441 | |
441 | 442 | .c.o: |
478 | 479 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
479 | 480 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -c -o virt_viewer-virt-viewer-main.obj `if test -f 'virt-viewer-main.c'; then $(CYGPATH_W) 'virt-viewer-main.c'; else $(CYGPATH_W) '$(srcdir)/virt-viewer-main.c'; fi` |
480 | 481 | |
482 | virt_viewer-virt-viewer.o: virt-viewer.c | |
483 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -MT virt_viewer-virt-viewer.o -MD -MP -MF $(DEPDIR)/virt_viewer-virt-viewer.Tpo -c -o virt_viewer-virt-viewer.o `test -f 'virt-viewer.c' || echo '$(srcdir)/'`virt-viewer.c | |
484 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/virt_viewer-virt-viewer.Tpo $(DEPDIR)/virt_viewer-virt-viewer.Po | |
485 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | |
486 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='virt-viewer.c' object='virt_viewer-virt-viewer.o' libtool=no @AMDEPBACKSLASH@ | |
487 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | |
488 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -c -o virt_viewer-virt-viewer.o `test -f 'virt-viewer.c' || echo '$(srcdir)/'`virt-viewer.c | |
489 | ||
490 | virt_viewer-virt-viewer.obj: virt-viewer.c | |
491 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -MT virt_viewer-virt-viewer.obj -MD -MP -MF $(DEPDIR)/virt_viewer-virt-viewer.Tpo -c -o virt_viewer-virt-viewer.obj `if test -f 'virt-viewer.c'; then $(CYGPATH_W) 'virt-viewer.c'; else $(CYGPATH_W) '$(srcdir)/virt-viewer.c'; fi` | |
492 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/virt_viewer-virt-viewer.Tpo $(DEPDIR)/virt_viewer-virt-viewer.Po | |
493 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | |
494 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='virt-viewer.c' object='virt_viewer-virt-viewer.obj' libtool=no @AMDEPBACKSLASH@ | |
495 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | |
496 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -c -o virt_viewer-virt-viewer.obj `if test -f 'virt-viewer.c'; then $(CYGPATH_W) 'virt-viewer.c'; else $(CYGPATH_W) '$(srcdir)/virt-viewer.c'; fi` | |
497 | ||
481 | 498 | virt_viewer-virt-viewer-util.o: virt-viewer-util.c |
482 | 499 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -MT virt_viewer-virt-viewer-util.o -MD -MP -MF $(DEPDIR)/virt_viewer-virt-viewer-util.Tpo -c -o virt_viewer-virt-viewer-util.o `test -f 'virt-viewer-util.c' || echo '$(srcdir)/'`virt-viewer-util.c |
483 | 500 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/virt_viewer-virt-viewer-util.Tpo $(DEPDIR)/virt_viewer-virt-viewer-util.Po |
526 | 543 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
527 | 544 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -c -o virt_viewer-virt-viewer-events.obj `if test -f 'virt-viewer-events.c'; then $(CYGPATH_W) 'virt-viewer-events.c'; else $(CYGPATH_W) '$(srcdir)/virt-viewer-events.c'; fi` |
528 | 545 | |
529 | virt_viewer-virt-viewer.o: virt-viewer.c | |
530 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -MT virt_viewer-virt-viewer.o -MD -MP -MF $(DEPDIR)/virt_viewer-virt-viewer.Tpo -c -o virt_viewer-virt-viewer.o `test -f 'virt-viewer.c' || echo '$(srcdir)/'`virt-viewer.c | |
531 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/virt_viewer-virt-viewer.Tpo $(DEPDIR)/virt_viewer-virt-viewer.Po | |
532 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | |
533 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='virt-viewer.c' object='virt_viewer-virt-viewer.o' libtool=no @AMDEPBACKSLASH@ | |
534 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | |
535 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -c -o virt_viewer-virt-viewer.o `test -f 'virt-viewer.c' || echo '$(srcdir)/'`virt-viewer.c | |
536 | ||
537 | virt_viewer-virt-viewer.obj: virt-viewer.c | |
538 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -MT virt_viewer-virt-viewer.obj -MD -MP -MF $(DEPDIR)/virt_viewer-virt-viewer.Tpo -c -o virt_viewer-virt-viewer.obj `if test -f 'virt-viewer.c'; then $(CYGPATH_W) 'virt-viewer.c'; else $(CYGPATH_W) '$(srcdir)/virt-viewer.c'; fi` | |
539 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/virt_viewer-virt-viewer.Tpo $(DEPDIR)/virt_viewer-virt-viewer.Po | |
540 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | |
541 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='virt-viewer.c' object='virt_viewer-virt-viewer.obj' libtool=no @AMDEPBACKSLASH@ | |
542 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | |
543 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -c -o virt_viewer-virt-viewer.obj `if test -f 'virt-viewer.c'; then $(CYGPATH_W) 'virt-viewer.c'; else $(CYGPATH_W) '$(srcdir)/virt-viewer.c'; fi` | |
546 | virt_viewer-virt-viewer-app.o: virt-viewer-app.c | |
547 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -MT virt_viewer-virt-viewer-app.o -MD -MP -MF $(DEPDIR)/virt_viewer-virt-viewer-app.Tpo -c -o virt_viewer-virt-viewer-app.o `test -f 'virt-viewer-app.c' || echo '$(srcdir)/'`virt-viewer-app.c | |
548 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/virt_viewer-virt-viewer-app.Tpo $(DEPDIR)/virt_viewer-virt-viewer-app.Po | |
549 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | |
550 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='virt-viewer-app.c' object='virt_viewer-virt-viewer-app.o' libtool=no @AMDEPBACKSLASH@ | |
551 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | |
552 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -c -o virt_viewer-virt-viewer-app.o `test -f 'virt-viewer-app.c' || echo '$(srcdir)/'`virt-viewer-app.c | |
553 | ||
554 | virt_viewer-virt-viewer-app.obj: virt-viewer-app.c | |
555 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -MT virt_viewer-virt-viewer-app.obj -MD -MP -MF $(DEPDIR)/virt_viewer-virt-viewer-app.Tpo -c -o virt_viewer-virt-viewer-app.obj `if test -f 'virt-viewer-app.c'; then $(CYGPATH_W) 'virt-viewer-app.c'; else $(CYGPATH_W) '$(srcdir)/virt-viewer-app.c'; fi` | |
556 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/virt_viewer-virt-viewer-app.Tpo $(DEPDIR)/virt_viewer-virt-viewer-app.Po | |
557 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | |
558 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='virt-viewer-app.c' object='virt_viewer-virt-viewer-app.obj' libtool=no @AMDEPBACKSLASH@ | |
559 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | |
560 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -c -o virt_viewer-virt-viewer-app.obj `if test -f 'virt-viewer-app.c'; then $(CYGPATH_W) 'virt-viewer-app.c'; else $(CYGPATH_W) '$(srcdir)/virt-viewer-app.c'; fi` | |
544 | 561 | |
545 | 562 | virt_viewer-virt-viewer-session.o: virt-viewer-session.c |
546 | 563 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -MT virt_viewer-virt-viewer-session.o -MD -MP -MF $(DEPDIR)/virt_viewer-virt-viewer-session.Tpo -c -o virt_viewer-virt-viewer-session.o `test -f 'virt-viewer-session.c' || echo '$(srcdir)/'`virt-viewer-session.c |
605 | 622 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='virt-viewer-display-vnc.c' object='virt_viewer-virt-viewer-display-vnc.obj' libtool=no @AMDEPBACKSLASH@ |
606 | 623 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
607 | 624 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -c -o virt_viewer-virt-viewer-display-vnc.obj `if test -f 'virt-viewer-display-vnc.c'; then $(CYGPATH_W) 'virt-viewer-display-vnc.c'; else $(CYGPATH_W) '$(srcdir)/virt-viewer-display-vnc.c'; fi` |
625 | ||
626 | virt_viewer-virt-viewer-notebook.o: virt-viewer-notebook.c | |
627 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -MT virt_viewer-virt-viewer-notebook.o -MD -MP -MF $(DEPDIR)/virt_viewer-virt-viewer-notebook.Tpo -c -o virt_viewer-virt-viewer-notebook.o `test -f 'virt-viewer-notebook.c' || echo '$(srcdir)/'`virt-viewer-notebook.c | |
628 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/virt_viewer-virt-viewer-notebook.Tpo $(DEPDIR)/virt_viewer-virt-viewer-notebook.Po | |
629 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | |
630 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='virt-viewer-notebook.c' object='virt_viewer-virt-viewer-notebook.o' libtool=no @AMDEPBACKSLASH@ | |
631 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | |
632 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -c -o virt_viewer-virt-viewer-notebook.o `test -f 'virt-viewer-notebook.c' || echo '$(srcdir)/'`virt-viewer-notebook.c | |
633 | ||
634 | virt_viewer-virt-viewer-notebook.obj: virt-viewer-notebook.c | |
635 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -MT virt_viewer-virt-viewer-notebook.obj -MD -MP -MF $(DEPDIR)/virt_viewer-virt-viewer-notebook.Tpo -c -o virt_viewer-virt-viewer-notebook.obj `if test -f 'virt-viewer-notebook.c'; then $(CYGPATH_W) 'virt-viewer-notebook.c'; else $(CYGPATH_W) '$(srcdir)/virt-viewer-notebook.c'; fi` | |
636 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/virt_viewer-virt-viewer-notebook.Tpo $(DEPDIR)/virt_viewer-virt-viewer-notebook.Po | |
637 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | |
638 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='virt-viewer-notebook.c' object='virt_viewer-virt-viewer-notebook.obj' libtool=no @AMDEPBACKSLASH@ | |
639 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | |
640 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -c -o virt_viewer-virt-viewer-notebook.obj `if test -f 'virt-viewer-notebook.c'; then $(CYGPATH_W) 'virt-viewer-notebook.c'; else $(CYGPATH_W) '$(srcdir)/virt-viewer-notebook.c'; fi` | |
641 | ||
642 | virt_viewer-virt-viewer-window.o: virt-viewer-window.c | |
643 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -MT virt_viewer-virt-viewer-window.o -MD -MP -MF $(DEPDIR)/virt_viewer-virt-viewer-window.Tpo -c -o virt_viewer-virt-viewer-window.o `test -f 'virt-viewer-window.c' || echo '$(srcdir)/'`virt-viewer-window.c | |
644 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/virt_viewer-virt-viewer-window.Tpo $(DEPDIR)/virt_viewer-virt-viewer-window.Po | |
645 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | |
646 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='virt-viewer-window.c' object='virt_viewer-virt-viewer-window.o' libtool=no @AMDEPBACKSLASH@ | |
647 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | |
648 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -c -o virt_viewer-virt-viewer-window.o `test -f 'virt-viewer-window.c' || echo '$(srcdir)/'`virt-viewer-window.c | |
649 | ||
650 | virt_viewer-virt-viewer-window.obj: virt-viewer-window.c | |
651 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -MT virt_viewer-virt-viewer-window.obj -MD -MP -MF $(DEPDIR)/virt_viewer-virt-viewer-window.Tpo -c -o virt_viewer-virt-viewer-window.obj `if test -f 'virt-viewer-window.c'; then $(CYGPATH_W) 'virt-viewer-window.c'; else $(CYGPATH_W) '$(srcdir)/virt-viewer-window.c'; fi` | |
652 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/virt_viewer-virt-viewer-window.Tpo $(DEPDIR)/virt_viewer-virt-viewer-window.Po | |
653 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | |
654 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='virt-viewer-window.c' object='virt_viewer-virt-viewer-window.obj' libtool=no @AMDEPBACKSLASH@ | |
655 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | |
656 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -c -o virt_viewer-virt-viewer-window.obj `if test -f 'virt-viewer-window.c'; then $(CYGPATH_W) 'virt-viewer-window.c'; else $(CYGPATH_W) '$(srcdir)/virt-viewer-window.c'; fi` | |
608 | 657 | |
609 | 658 | virt_viewer-autoDrawer.o: view/autoDrawer.c |
610 | 659 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -MT virt_viewer-autoDrawer.o -MD -MP -MF $(DEPDIR)/virt_viewer-autoDrawer.Tpo -c -o virt_viewer-autoDrawer.o `test -f 'view/autoDrawer.c' || echo '$(srcdir)/'`view/autoDrawer.c |
8 | 8 | <property name="window_position">center-on-parent</property> |
9 | 9 | <property name="type_hint">dialog</property> |
10 | 10 | <property name="program_name">Virtual Machine Viewer</property> |
11 | <property name="copyright" translatable="yes">Copyright 2007-2008 Daniel P. Berrange | |
12 | Copyright 2007-2008 Red Hat, Inc.</property> | |
13 | <property name="comments" translatable="yes">A remote desktop client built with GTK-VNC and libvirt</property> | |
11 | <property name="copyright" translatable="yes">Copyright 2007-2011 Daniel P. Berrange | |
12 | Copyright 2007-2011 Red Hat, Inc.</property> | |
13 | <property name="comments" translatable="yes">A remote desktop client built with GTK-VNC, SPICE-GTK and libvirt</property> | |
14 | 14 | <property name="website">http://virt-manager.org/</property> |
15 | 15 | <property name="website_label" translatable="yes">virt-manager.org</property> |
16 | 16 | <property name="license" translatable="yes">This program is free software; you can redistribute it and/or modify |
27 | 27 | along with this program; if not, write to the Free Software |
28 | 28 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
29 | 29 | </property> |
30 | <property name="authors">Daniel P. Berrange</property> | |
30 | <property name="authors">Daniel P. Berrange | |
31 | Marc-André Lureau | |
32 | </property> | |
31 | 33 | <property name="translator_credits" translatable="yes">The Fedora Translation Team</property> |
32 | <signal name="response" handler="virt_viewer_about_close"/> | |
33 | <signal name="delete_event" handler="virt_viewer_about_delete"/> | |
34 | <signal name="response" handler="virt_viewer_app_about_close"/> | |
35 | <signal name="delete_event" handler="virt_viewer_app_about_delete"/> | |
34 | 36 | <child internal-child="vbox"> |
35 | 37 | <object class="GtkVBox" id="dialog-vbox1"> |
36 | 38 | <property name="visible">True</property> |
0 | /* | |
1 | * Virt Viewer: A virtual machine console viewer | |
2 | * | |
3 | * Copyright (C) 2007-2009 Red Hat, | |
4 | * Copyright (C) 2009 Daniel P. Berrange | |
5 | * Copyright (C) 2010 Marc-André Lureau | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with this program; if not, write to the Free Software | |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 | * | |
21 | * Author: Daniel P. Berrange <berrange@redhat.com> | |
22 | */ | |
23 | ||
24 | #include <config.h> | |
25 | ||
26 | #include <gdk/gdkkeysyms.h> | |
27 | #include <gtk/gtk.h> | |
28 | #include <sys/types.h> | |
29 | #include <sys/stat.h> | |
30 | #include <stdlib.h> | |
31 | #include <string.h> | |
32 | #include <unistd.h> | |
33 | #include <locale.h> | |
34 | #include <glib/gprintf.h> | |
35 | #include <glib/gi18n.h> | |
36 | ||
37 | #include <libxml/xpath.h> | |
38 | #include <libxml/uri.h> | |
39 | ||
40 | #ifdef HAVE_SYS_SOCKET_H | |
41 | #include <sys/socket.h> | |
42 | #endif | |
43 | ||
44 | #ifdef HAVE_SYS_UN_H | |
45 | #include <sys/un.h> | |
46 | #endif | |
47 | ||
48 | #ifdef HAVE_WINDOWS_H | |
49 | #include <windows.h> | |
50 | #endif | |
51 | ||
52 | #include "virt-viewer-app.h" | |
53 | #include "virt-viewer-auth.h" | |
54 | #include "virt-viewer-window.h" | |
55 | #include "virt-viewer-session.h" | |
56 | #include "virt-viewer-session-vnc.h" | |
57 | #ifdef HAVE_SPICE_GTK | |
58 | #include "virt-viewer-session-spice.h" | |
59 | #endif | |
60 | ||
61 | gboolean doDebug = FALSE; | |
62 | ||
63 | /* Signal handlers for about dialog */ | |
64 | void virt_viewer_app_about_close(GtkWidget *dialog, VirtViewerApp *self); | |
65 | void virt_viewer_app_about_delete(GtkWidget *dialog, void *dummy, VirtViewerApp *self); | |
66 | ||
67 | ||
68 | /* Internal methods */ | |
69 | static void virt_viewer_app_connected(VirtViewerSession *session, | |
70 | VirtViewerApp *self); | |
71 | static void virt_viewer_app_initialized(VirtViewerSession *session, | |
72 | VirtViewerApp *self); | |
73 | static void virt_viewer_app_disconnected(VirtViewerSession *session, | |
74 | VirtViewerApp *self); | |
75 | static void virt_viewer_app_auth_refused(VirtViewerSession *session, | |
76 | const char *msg, | |
77 | VirtViewerApp *self); | |
78 | static void virt_viewer_app_auth_failed(VirtViewerSession *session, | |
79 | const char *msg, | |
80 | VirtViewerApp *self); | |
81 | ||
82 | static void virt_viewer_app_server_cut_text(VirtViewerSession *session, | |
83 | const gchar *text, | |
84 | VirtViewerApp *self); | |
85 | static void virt_viewer_app_bell(VirtViewerSession *session, | |
86 | VirtViewerApp *self); | |
87 | ||
88 | static void virt_viewer_app_channel_open(VirtViewerSession *session, | |
89 | VirtViewerSessionChannel *channel, | |
90 | VirtViewerApp *self); | |
91 | static void virt_viewer_app_update_pretty_address(VirtViewerApp *self); | |
92 | static void virt_viewer_app_set_fullscreen(VirtViewerApp *self, gboolean fullscreen); | |
93 | static void virt_viewer_app_update_menu_displays(VirtViewerApp *self); | |
94 | ||
95 | ||
96 | struct _VirtViewerAppPrivate { | |
97 | VirtViewerWindow *main_window; | |
98 | GtkWidget *main_notebook; | |
99 | GtkWidget *container; | |
100 | GHashTable *windows; | |
101 | gchar *clipboard; | |
102 | ||
103 | gboolean direct; | |
104 | gboolean verbose; | |
105 | gboolean authretry; | |
106 | gboolean started; | |
107 | gboolean fullscreen; | |
108 | ||
109 | VirtViewerSession *session; | |
110 | gboolean active; | |
111 | gboolean connected; | |
112 | guint reconnect_poll; /* source id */ | |
113 | char *unixsock; | |
114 | char *ghost; | |
115 | char *gport; | |
116 | char *host; /* ssh */ | |
117 | int port;/* ssh */ | |
118 | char *user; /* ssh */ | |
119 | char *transport; | |
120 | char *pretty_address; | |
121 | gchar *guest_name; | |
122 | gboolean grabbed; | |
123 | }; | |
124 | ||
125 | ||
126 | G_DEFINE_ABSTRACT_TYPE(VirtViewerApp, virt_viewer_app, G_TYPE_OBJECT) | |
127 | #define GET_PRIVATE(o) \ | |
128 | (G_TYPE_INSTANCE_GET_PRIVATE ((o), VIRT_VIEWER_TYPE_APP, VirtViewerAppPrivate)) | |
129 | ||
130 | enum { | |
131 | PROP_0, | |
132 | PROP_VERBOSE, | |
133 | PROP_CONTAINER, | |
134 | PROP_SESSION, | |
135 | PROP_GUEST_NAME, | |
136 | PROP_FULLSCREEN, | |
137 | }; | |
138 | ||
139 | void | |
140 | virt_viewer_app_set_debug(gboolean debug) | |
141 | { | |
142 | doDebug = debug; | |
143 | } | |
144 | ||
145 | void | |
146 | virt_viewer_app_simple_message_dialog(VirtViewerApp *self, | |
147 | const char *fmt, ...) | |
148 | { | |
149 | g_return_if_fail(VIRT_VIEWER_IS_APP(self)); | |
150 | GtkWindow *window = GTK_WINDOW(virt_viewer_window_get_window(self->priv->main_window)); | |
151 | GtkWidget *dialog; | |
152 | char *msg; | |
153 | va_list vargs; | |
154 | ||
155 | va_start(vargs, fmt); | |
156 | ||
157 | msg = g_strdup_vprintf(fmt, vargs); | |
158 | ||
159 | va_end(vargs); | |
160 | ||
161 | dialog = gtk_message_dialog_new(window, | |
162 | GTK_DIALOG_MODAL | | |
163 | GTK_DIALOG_DESTROY_WITH_PARENT, | |
164 | GTK_MESSAGE_ERROR, | |
165 | GTK_BUTTONS_OK, | |
166 | "%s", | |
167 | msg); | |
168 | ||
169 | gtk_dialog_run(GTK_DIALOG(dialog)); | |
170 | ||
171 | gtk_widget_destroy(dialog); | |
172 | ||
173 | g_free(msg); | |
174 | } | |
175 | ||
176 | void | |
177 | virt_viewer_app_quit(VirtViewerApp *self) | |
178 | { | |
179 | g_return_if_fail(VIRT_VIEWER_IS_APP(self)); | |
180 | VirtViewerAppPrivate *priv = self->priv; | |
181 | ||
182 | if (priv->session) | |
183 | virt_viewer_session_close(VIRT_VIEWER_SESSION(priv->session)); | |
184 | gtk_main_quit(); | |
185 | } | |
186 | ||
187 | static void count_window_visible(gpointer key G_GNUC_UNUSED, | |
188 | gpointer value, | |
189 | gpointer user_data) | |
190 | { | |
191 | GtkWindow *win = virt_viewer_window_get_window(VIRT_VIEWER_WINDOW(value)); | |
192 | guint *n = (guint*)user_data; | |
193 | ||
194 | if (gtk_widget_get_visible(GTK_WIDGET(win))) | |
195 | *n += 1; | |
196 | } | |
197 | ||
198 | static guint | |
199 | virt_viewer_app_get_n_windows_visible(VirtViewerApp *self) | |
200 | { | |
201 | guint n = 0; | |
202 | g_hash_table_foreach(self->priv->windows, count_window_visible, &n); | |
203 | return n; | |
204 | } | |
205 | ||
206 | static guint | |
207 | virt_viewer_app_get_n_windows(VirtViewerApp *self) | |
208 | { | |
209 | return g_hash_table_size(self->priv->windows); | |
210 | } | |
211 | ||
212 | gboolean | |
213 | virt_viewer_app_window_set_visible(VirtViewerApp *self, | |
214 | VirtViewerWindow *vwin, | |
215 | gboolean visible) | |
216 | { | |
217 | GtkWidget *window; | |
218 | g_return_val_if_fail(VIRT_VIEWER_IS_APP(self), FALSE); | |
219 | g_return_val_if_fail(VIRT_VIEWER_IS_WINDOW(vwin), FALSE); | |
220 | ||
221 | window = GTK_WIDGET(virt_viewer_window_get_window(vwin)); | |
222 | if (visible) { | |
223 | gtk_widget_show(window); | |
224 | return TRUE; | |
225 | } else { | |
226 | if (virt_viewer_app_get_n_windows_visible(self) > 1) { | |
227 | gtk_widget_hide(window); | |
228 | return FALSE; | |
229 | } else if (virt_viewer_app_get_n_windows(self) > 1) { | |
230 | GtkWidget *dialog = | |
231 | gtk_message_dialog_new (GTK_WINDOW(window), | |
232 | GTK_DIALOG_DESTROY_WITH_PARENT, | |
233 | GTK_MESSAGE_QUESTION, | |
234 | GTK_BUTTONS_OK_CANCEL, | |
235 | _("This is the last visible display. Do you want to quit?")); | |
236 | gint result = gtk_dialog_run (GTK_DIALOG (dialog)); | |
237 | switch (result) { | |
238 | case GTK_RESPONSE_OK: | |
239 | virt_viewer_app_quit(self); | |
240 | break; | |
241 | default: | |
242 | break; | |
243 | } | |
244 | gtk_widget_destroy(dialog); | |
245 | return FALSE; | |
246 | } else { | |
247 | virt_viewer_app_quit(self); | |
248 | return FALSE; | |
249 | } | |
250 | } | |
251 | ||
252 | g_warn_if_reached(); | |
253 | return FALSE; | |
254 | } | |
255 | ||
256 | void | |
257 | virt_viewer_app_about_close(GtkWidget *dialog, | |
258 | VirtViewerApp *self G_GNUC_UNUSED) | |
259 | { | |
260 | gtk_widget_hide(dialog); | |
261 | gtk_widget_destroy(dialog); | |
262 | } | |
263 | ||
264 | void | |
265 | virt_viewer_app_about_delete(GtkWidget *dialog, | |
266 | void *dummy G_GNUC_UNUSED, | |
267 | VirtViewerApp *self G_GNUC_UNUSED) | |
268 | { | |
269 | gtk_widget_hide(dialog); | |
270 | gtk_widget_destroy(dialog); | |
271 | } | |
272 | ||
273 | #if defined(HAVE_SOCKETPAIR) && defined(HAVE_FORK) | |
274 | ||
275 | static int | |
276 | virt_viewer_app_open_tunnel(const char **cmd) | |
277 | { | |
278 | int fd[2]; | |
279 | pid_t pid; | |
280 | ||
281 | if (socketpair(PF_UNIX, SOCK_STREAM, 0, fd) < 0) | |
282 | return -1; | |
283 | ||
284 | pid = fork(); | |
285 | if (pid == -1) { | |
286 | close(fd[0]); | |
287 | close(fd[1]); | |
288 | return -1; | |
289 | } | |
290 | ||
291 | if (pid == 0) { /* child */ | |
292 | close(fd[0]); | |
293 | close(0); | |
294 | close(1); | |
295 | if (dup(fd[1]) < 0) | |
296 | _exit(1); | |
297 | if (dup(fd[1]) < 0) | |
298 | _exit(1); | |
299 | close(fd[1]); | |
300 | execvp("ssh", (char *const*)cmd); | |
301 | _exit(1); | |
302 | } | |
303 | close(fd[1]); | |
304 | return fd[0]; | |
305 | } | |
306 | ||
307 | ||
308 | static int | |
309 | virt_viewer_app_open_tunnel_ssh(const char *sshhost, | |
310 | int sshport, | |
311 | const char *sshuser, | |
312 | const char *host, | |
313 | const char *port, | |
314 | const char *unixsock) | |
315 | { | |
316 | const char *cmd[10]; | |
317 | char portstr[50]; | |
318 | int n = 0; | |
319 | ||
320 | cmd[n++] = "ssh"; | |
321 | if (!sshport) { | |
322 | cmd[n++] = "-p"; | |
323 | sprintf(portstr, "%d", sshport); | |
324 | cmd[n++] = portstr; | |
325 | } | |
326 | if (sshuser) { | |
327 | cmd[n++] = "-l"; | |
328 | cmd[n++] = sshuser; | |
329 | } | |
330 | cmd[n++] = sshhost; | |
331 | cmd[n++] = "nc"; | |
332 | if (port) { | |
333 | cmd[n++] = host; | |
334 | cmd[n++] = port; | |
335 | } else { | |
336 | cmd[n++] = "-U"; | |
337 | cmd[n++] = unixsock; | |
338 | } | |
339 | cmd[n++] = NULL; | |
340 | ||
341 | return virt_viewer_app_open_tunnel(cmd); | |
342 | } | |
343 | ||
344 | static int | |
345 | virt_viewer_app_open_unix_sock(const char *unixsock) | |
346 | { | |
347 | struct sockaddr_un addr; | |
348 | int fd; | |
349 | ||
350 | memset(&addr, 0, sizeof addr); | |
351 | addr.sun_family = AF_UNIX; | |
352 | strcpy(addr.sun_path, unixsock); | |
353 | ||
354 | if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) | |
355 | return -1; | |
356 | ||
357 | if (connect(fd, (struct sockaddr *)&addr, sizeof addr) < 0) { | |
358 | close(fd); | |
359 | return -1; | |
360 | } | |
361 | ||
362 | return fd; | |
363 | } | |
364 | ||
365 | #endif /* defined(HAVE_SOCKETPAIR) && defined(HAVE_FORK) */ | |
366 | ||
367 | void | |
368 | virt_viewer_app_trace(VirtViewerApp *self, | |
369 | const char *fmt, ...) | |
370 | { | |
371 | g_return_if_fail(VIRT_VIEWER_IS_APP(self)); | |
372 | va_list ap; | |
373 | VirtViewerAppPrivate *priv = self->priv; | |
374 | ||
375 | if (doDebug) { | |
376 | va_start(ap, fmt); | |
377 | g_logv(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, fmt, ap); | |
378 | va_end(ap); | |
379 | } | |
380 | ||
381 | if (priv->verbose) { | |
382 | va_start(ap, fmt); | |
383 | g_vprintf(fmt, ap); | |
384 | va_end(ap); | |
385 | } | |
386 | } | |
387 | ||
388 | static void update_title(gpointer key G_GNUC_UNUSED, | |
389 | gpointer value, | |
390 | gpointer user_data G_GNUC_UNUSED) | |
391 | { | |
392 | virt_viewer_window_update_title(VIRT_VIEWER_WINDOW(value)); | |
393 | } | |
394 | ||
395 | static void | |
396 | virt_viewer_app_update_title(VirtViewerApp *self) | |
397 | { | |
398 | g_hash_table_foreach(self->priv->windows, update_title, NULL); | |
399 | } | |
400 | ||
401 | static VirtViewerWindow * | |
402 | virt_viewer_app_get_nth_window(VirtViewerApp *self, gint nth) | |
403 | { | |
404 | return g_hash_table_lookup(self->priv->windows, &nth); | |
405 | } | |
406 | ||
407 | static gboolean | |
408 | virt_viewer_app_remove_nth_window(VirtViewerApp *self, gint nth) | |
409 | { | |
410 | gboolean removed; | |
411 | ||
412 | g_return_val_if_fail(nth != 0, FALSE); | |
413 | removed = g_hash_table_remove(self->priv->windows, &nth); | |
414 | g_warn_if_fail(removed); | |
415 | ||
416 | return removed; | |
417 | } | |
418 | ||
419 | static void | |
420 | virt_viewer_app_set_nth_window(VirtViewerApp *self, gint nth, VirtViewerWindow *win) | |
421 | { | |
422 | gint *key; | |
423 | ||
424 | g_return_if_fail(virt_viewer_app_get_nth_window(self, nth) == NULL); | |
425 | key = g_malloc(sizeof(gint)); | |
426 | *key = nth; | |
427 | g_hash_table_insert(self->priv->windows, key, win); | |
428 | } | |
429 | ||
430 | static void | |
431 | viewer_window_visible_cb(GtkWidget *widget G_GNUC_UNUSED, | |
432 | gpointer user_data) | |
433 | { | |
434 | virt_viewer_app_update_menu_displays(VIRT_VIEWER_APP(user_data)); | |
435 | } | |
436 | ||
437 | ||
438 | static VirtViewerWindow* | |
439 | virt_viewer_app_window_new(VirtViewerApp *self, GtkWidget *container, gint nth) | |
440 | { | |
441 | VirtViewerWindow* window; | |
442 | GtkWindow *w; | |
443 | ||
444 | window = g_object_new(VIRT_VIEWER_TYPE_WINDOW, | |
445 | "app", self, | |
446 | "container", container, | |
447 | NULL); | |
448 | virt_viewer_app_set_nth_window(self, nth, window); | |
449 | w = virt_viewer_window_get_window(window); | |
450 | ||
451 | /* this will set new window to fullscreen if necessary */ | |
452 | virt_viewer_app_set_fullscreen(self, self->priv->fullscreen); | |
453 | g_signal_connect(w, "hide", G_CALLBACK(viewer_window_visible_cb), self); | |
454 | g_signal_connect(w, "show", G_CALLBACK(viewer_window_visible_cb), self); | |
455 | return window; | |
456 | } | |
457 | ||
458 | static void | |
459 | display_show_hint(VirtViewerDisplay *display, | |
460 | GParamSpec *pspec G_GNUC_UNUSED, | |
461 | VirtViewerWindow *win) | |
462 | { | |
463 | VirtViewerApp *self; | |
464 | VirtViewerNotebook *nb = virt_viewer_window_get_notebook(win); | |
465 | GtkWindow *w = virt_viewer_window_get_window(win); | |
466 | gint nth, hint; | |
467 | ||
468 | g_object_get(win, | |
469 | "app", &self, | |
470 | NULL); | |
471 | g_object_get(display, | |
472 | "nth-display", &nth, | |
473 | "show-hint", &hint, | |
474 | NULL); | |
475 | ||
476 | if (hint == VIRT_VIEWER_DISPLAY_SHOW_HINT_HIDE) { | |
477 | if (win != self->priv->main_window && | |
478 | g_getenv("VIRT_VIEWER_HIDE")) | |
479 | gtk_widget_hide(GTK_WIDGET(w)); | |
480 | virt_viewer_notebook_show_status(nb, _("Waiting for display %d..."), nth + 1); | |
481 | } else { | |
482 | virt_viewer_notebook_show_display(nb); | |
483 | gtk_widget_show(GTK_WIDGET(w)); | |
484 | gtk_window_present(w); | |
485 | } | |
486 | ||
487 | g_object_unref(self); | |
488 | } | |
489 | ||
490 | static void | |
491 | virt_viewer_app_display_added(VirtViewerSession *session G_GNUC_UNUSED, | |
492 | VirtViewerDisplay *display, | |
493 | VirtViewerApp *self) | |
494 | { | |
495 | VirtViewerAppPrivate *priv = self->priv; | |
496 | VirtViewerWindow *window; | |
497 | gint nth; | |
498 | ||
499 | g_object_get(display, "nth-display", &nth, NULL); | |
500 | if (nth == 0) { | |
501 | window = priv->main_window; | |
502 | } else { | |
503 | if (priv->container) { | |
504 | g_warning("multi-head not yet supported within container"); | |
505 | return; | |
506 | } | |
507 | ||
508 | g_return_if_fail(virt_viewer_app_get_nth_window(self, nth) == NULL); | |
509 | window = virt_viewer_app_window_new(self, NULL, nth); | |
510 | } | |
511 | ||
512 | virt_viewer_window_set_display(window, display); | |
513 | g_signal_connect(display, "notify::show-hint", | |
514 | G_CALLBACK(display_show_hint), window); | |
515 | g_object_notify(G_OBJECT(display), "show-hint"); /* call display_show_hint */ | |
516 | } | |
517 | ||
518 | ||
519 | static void | |
520 | virt_viewer_app_display_removed(VirtViewerSession *session G_GNUC_UNUSED, | |
521 | VirtViewerDisplay *display, | |
522 | VirtViewerApp *self) | |
523 | { | |
524 | VirtViewerWindow *win = NULL; | |
525 | gint nth; | |
526 | ||
527 | gtk_widget_hide(GTK_WIDGET(display)); | |
528 | g_object_get(display, "nth-display", &nth, NULL); | |
529 | win = virt_viewer_app_get_nth_window(self, nth); | |
530 | virt_viewer_window_set_display(win, NULL); | |
531 | ||
532 | if (nth != 0) | |
533 | virt_viewer_app_remove_nth_window(self, nth); | |
534 | } | |
535 | ||
536 | int | |
537 | virt_viewer_app_create_session(VirtViewerApp *self, const gchar *type) | |
538 | { | |
539 | g_return_val_if_fail(VIRT_VIEWER_IS_APP(self), -1); | |
540 | VirtViewerAppPrivate *priv = self->priv; | |
541 | g_return_val_if_fail(priv->session == NULL, -1); | |
542 | ||
543 | if (g_strcasecmp(type, "vnc") == 0) { | |
544 | virt_viewer_app_trace(self, "Guest %s has a %s display\n", | |
545 | priv->guest_name, type); | |
546 | priv->session = virt_viewer_session_vnc_new(); | |
547 | } else | |
548 | #ifdef HAVE_SPICE_GTK | |
549 | if (g_strcasecmp(type, "spice") == 0) { | |
550 | virt_viewer_app_trace(self, "Guest %s has a %s display\n", | |
551 | priv->guest_name, type); | |
552 | priv->session = virt_viewer_session_spice_new(); | |
553 | } else | |
554 | #endif | |
555 | { | |
556 | virt_viewer_app_trace(self, "Guest %s has unsupported %s display type\n", | |
557 | priv->guest_name, type); | |
558 | virt_viewer_app_simple_message_dialog(self, _("Unknown graphic type for the guest %s"), | |
559 | priv->guest_name); | |
560 | return -1; | |
561 | } | |
562 | ||
563 | g_signal_connect(priv->session, "session-initialized", | |
564 | G_CALLBACK(virt_viewer_app_initialized), self); | |
565 | g_signal_connect(priv->session, "session-connected", | |
566 | G_CALLBACK(virt_viewer_app_connected), self); | |
567 | g_signal_connect(priv->session, "session-disconnected", | |
568 | G_CALLBACK(virt_viewer_app_disconnected), self); | |
569 | g_signal_connect(priv->session, "session-channel-open", | |
570 | G_CALLBACK(virt_viewer_app_channel_open), self); | |
571 | g_signal_connect(priv->session, "session-auth-refused", | |
572 | G_CALLBACK(virt_viewer_app_auth_refused), self); | |
573 | g_signal_connect(priv->session, "session-auth-failed", | |
574 | G_CALLBACK(virt_viewer_app_auth_failed), self); | |
575 | g_signal_connect(priv->session, "session-display-added", | |
576 | G_CALLBACK(virt_viewer_app_display_added), self); | |
577 | g_signal_connect(priv->session, "session-display-removed", | |
578 | G_CALLBACK(virt_viewer_app_display_removed), self); | |
579 | ||
580 | g_signal_connect(priv->session, "session-cut-text", | |
581 | G_CALLBACK(virt_viewer_app_server_cut_text), self); | |
582 | g_signal_connect(priv->session, "session-bell", | |
583 | G_CALLBACK(virt_viewer_app_bell), self); | |
584 | ||
585 | return 0; | |
586 | } | |
587 | ||
588 | #if defined(HAVE_SOCKETPAIR) && defined(HAVE_FORK) | |
589 | static void | |
590 | virt_viewer_app_channel_open(VirtViewerSession *session, | |
591 | VirtViewerSessionChannel *channel, | |
592 | VirtViewerApp *self) | |
593 | { | |
594 | VirtViewerAppPrivate *priv; | |
595 | int fd = -1; | |
596 | ||
597 | g_return_if_fail(self != NULL); | |
598 | ||
599 | priv = self->priv; | |
600 | if (priv->transport && g_strcasecmp(priv->transport, "ssh") == 0 && | |
601 | !priv->direct) { | |
602 | if ((fd = virt_viewer_app_open_tunnel_ssh(priv->host, priv->port, priv->user, | |
603 | priv->ghost, priv->gport, NULL)) < 0) | |
604 | virt_viewer_app_simple_message_dialog(self, _("Connect to ssh failed.")); | |
605 | } else { | |
606 | virt_viewer_app_simple_message_dialog(self, _("Can't connect to channel, SSH only supported.")); | |
607 | } | |
608 | ||
609 | if (fd >= 0) | |
610 | virt_viewer_session_channel_open_fd(session, channel, fd); | |
611 | } | |
612 | #else | |
613 | static void | |
614 | virt_viewer_app_channel_open(VirtViewerSession *session G_GNUC_UNUSED, | |
615 | VirtViewerSessionChannel *channel G_GNUC_UNUSED, | |
616 | VirtViewerApp *self) | |
617 | { | |
618 | virt_viewer_app_simple_message_dialog(self, _("Connect to channel unsupported.")); | |
619 | } | |
620 | #endif | |
621 | ||
622 | int | |
623 | virt_viewer_app_activate(VirtViewerApp *self) | |
624 | { | |
625 | g_return_val_if_fail(VIRT_VIEWER_IS_APP(self), -1); | |
626 | VirtViewerAppPrivate *priv = self->priv; | |
627 | int fd = -1; | |
628 | int ret = -1; | |
629 | ||
630 | if (priv->active) | |
631 | goto cleanup; | |
632 | ||
633 | #if defined(HAVE_SOCKETPAIR) && defined(HAVE_FORK) | |
634 | if (priv->transport && | |
635 | g_strcasecmp(priv->transport, "ssh") == 0 && | |
636 | !priv->direct) { | |
637 | if (priv->gport) { | |
638 | virt_viewer_app_trace(self, "Opening indirect TCP connection to display at %s:%s\n", | |
639 | priv->ghost, priv->gport); | |
640 | } else { | |
641 | virt_viewer_app_trace(self, "Opening indirect UNIX connection to display at %s\n", | |
642 | priv->unixsock); | |
643 | } | |
644 | virt_viewer_app_trace(self, "Setting up SSH tunnel via %s@%s:%d\n", | |
645 | priv->user, priv->host, priv->port ? priv->port : 22); | |
646 | ||
647 | if ((fd = virt_viewer_app_open_tunnel_ssh(priv->host, priv->port, | |
648 | priv->user, priv->ghost, | |
649 | priv->gport, priv->unixsock)) < 0) | |
650 | return -1; | |
651 | } else if (priv->unixsock) { | |
652 | virt_viewer_app_trace(self, "Opening direct UNIX connection to display at %s", | |
653 | priv->unixsock); | |
654 | if ((fd = virt_viewer_app_open_unix_sock(priv->unixsock)) < 0) | |
655 | return -1; | |
656 | } | |
657 | #endif | |
658 | ||
659 | if (fd >= 0) { | |
660 | ret = virt_viewer_session_open_fd(VIRT_VIEWER_SESSION(priv->session), fd); | |
661 | } else { | |
662 | virt_viewer_app_trace(self, "Opening direct TCP connection to display at %s:%s\n", | |
663 | priv->ghost, priv->gport); | |
664 | ret = virt_viewer_session_open_host(VIRT_VIEWER_SESSION(priv->session), | |
665 | priv->ghost, priv->gport); | |
666 | } | |
667 | ||
668 | virt_viewer_app_show_status(self, _("Connecting to graphic server")); | |
669 | ||
670 | priv->connected = FALSE; | |
671 | priv->active = TRUE; | |
672 | priv->grabbed = FALSE; | |
673 | virt_viewer_app_update_title(self); | |
674 | ||
675 | cleanup: | |
676 | return ret; | |
677 | } | |
678 | ||
679 | /* text was actually requested */ | |
680 | static void | |
681 | virt_viewer_app_clipboard_copy(GtkClipboard *clipboard G_GNUC_UNUSED, | |
682 | GtkSelectionData *data, | |
683 | guint info G_GNUC_UNUSED, | |
684 | VirtViewerApp *self) | |
685 | { | |
686 | VirtViewerAppPrivate *priv = self->priv; | |
687 | ||
688 | gtk_selection_data_set_text(data, priv->clipboard, -1); | |
689 | } | |
690 | ||
691 | static void | |
692 | virt_viewer_app_server_cut_text(VirtViewerSession *session G_GNUC_UNUSED, | |
693 | const gchar *text, | |
694 | VirtViewerApp *self) | |
695 | { | |
696 | GtkClipboard *cb; | |
697 | gsize a, b; | |
698 | VirtViewerAppPrivate *priv = self->priv; | |
699 | GtkTargetEntry targets[] = { | |
700 | {g_strdup("UTF8_STRING"), 0, 0}, | |
701 | {g_strdup("COMPOUND_TEXT"), 0, 0}, | |
702 | {g_strdup("TEXT"), 0, 0}, | |
703 | {g_strdup("STRING"), 0, 0}, | |
704 | }; | |
705 | ||
706 | if (!text) | |
707 | return; | |
708 | ||
709 | g_free (priv->clipboard); | |
710 | priv->clipboard = g_convert (text, -1, "utf-8", "iso8859-1", &a, &b, NULL); | |
711 | ||
712 | if (priv->clipboard) { | |
713 | cb = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); | |
714 | ||
715 | gtk_clipboard_set_with_owner (cb, | |
716 | targets, | |
717 | G_N_ELEMENTS(targets), | |
718 | (GtkClipboardGetFunc)virt_viewer_app_clipboard_copy, | |
719 | NULL, | |
720 | G_OBJECT (self)); | |
721 | } | |
722 | } | |
723 | ||
724 | ||
725 | static void virt_viewer_app_bell(VirtViewerSession *session G_GNUC_UNUSED, | |
726 | VirtViewerApp *self) | |
727 | { | |
728 | VirtViewerAppPrivate *priv = self->priv; | |
729 | ||
730 | gdk_window_beep(gtk_widget_get_window(GTK_WIDGET(virt_viewer_window_get_window(priv->main_window)))); | |
731 | } | |
732 | ||
733 | ||
734 | static int | |
735 | virt_viewer_app_default_initial_connect(VirtViewerApp *self) | |
736 | { | |
737 | return virt_viewer_app_activate(self); | |
738 | } | |
739 | ||
740 | int | |
741 | virt_viewer_app_initial_connect(VirtViewerApp *self) | |
742 | { | |
743 | VirtViewerAppClass *klass; | |
744 | ||
745 | g_return_val_if_fail(VIRT_VIEWER_IS_APP(self), -1); | |
746 | klass = VIRT_VIEWER_APP_GET_CLASS(self); | |
747 | ||
748 | return klass->initial_connect(self); | |
749 | } | |
750 | ||
751 | static gboolean | |
752 | virt_viewer_app_retryauth(gpointer opaque) | |
753 | { | |
754 | VirtViewerApp *self = opaque; | |
755 | ||
756 | virt_viewer_app_initial_connect(self); | |
757 | ||
758 | return FALSE; | |
759 | } | |
760 | ||
761 | static gboolean | |
762 | virt_viewer_app_connect_timer(void *opaque) | |
763 | { | |
764 | VirtViewerApp *self = opaque; | |
765 | VirtViewerAppPrivate *priv = self->priv; | |
766 | ||
767 | DEBUG_LOG("Connect timer fired"); | |
768 | ||
769 | if (!priv->active && | |
770 | virt_viewer_app_initial_connect(self) < 0) | |
771 | gtk_main_quit(); | |
772 | ||
773 | if (priv->active) { | |
774 | priv->reconnect_poll = 0; | |
775 | return FALSE; | |
776 | } | |
777 | ||
778 | return TRUE; | |
779 | } | |
780 | ||
781 | void | |
782 | virt_viewer_app_start_reconnect_poll(VirtViewerApp *self) | |
783 | { | |
784 | g_return_if_fail(VIRT_VIEWER_IS_APP(self)); | |
785 | VirtViewerAppPrivate *priv = self->priv; | |
786 | ||
787 | if (priv->reconnect_poll != 0) | |
788 | return; | |
789 | ||
790 | priv->reconnect_poll = g_timeout_add(500, virt_viewer_app_connect_timer, self); | |
791 | } | |
792 | ||
793 | static void | |
794 | virt_viewer_app_default_deactivated(VirtViewerApp *self) | |
795 | { | |
796 | VirtViewerAppPrivate *priv = self->priv; | |
797 | ||
798 | virt_viewer_app_show_status(self, _("Guest domain has shutdown")); | |
799 | virt_viewer_app_trace(self, "Guest %s display has disconnected, shutting down", | |
800 | priv->guest_name); | |
801 | gtk_main_quit(); | |
802 | } | |
803 | ||
804 | static void | |
805 | virt_viewer_app_deactivated(VirtViewerApp *self) | |
806 | { | |
807 | VirtViewerAppClass *klass; | |
808 | klass = VIRT_VIEWER_APP_GET_CLASS(self); | |
809 | ||
810 | klass->deactivated(self); | |
811 | } | |
812 | ||
813 | static void | |
814 | virt_viewer_app_deactivate(VirtViewerApp *self) | |
815 | { | |
816 | VirtViewerAppPrivate *priv = self->priv; | |
817 | ||
818 | if (!priv->active) | |
819 | return; | |
820 | ||
821 | if (priv->session) | |
822 | virt_viewer_session_close(VIRT_VIEWER_SESSION(priv->session)); | |
823 | ||
824 | priv->connected = FALSE; | |
825 | priv->active = FALSE; | |
826 | #if 0 | |
827 | g_free(priv->pretty_address); | |
828 | priv->pretty_address = NULL; | |
829 | #endif | |
830 | priv->grabbed = FALSE; | |
831 | virt_viewer_app_update_title(self); | |
832 | ||
833 | if (priv->authretry) { | |
834 | priv->authretry = FALSE; | |
835 | g_idle_add(virt_viewer_app_retryauth, self); | |
836 | } else | |
837 | virt_viewer_app_deactivated(self); | |
838 | ||
839 | } | |
840 | ||
841 | static void | |
842 | virt_viewer_app_connected(VirtViewerSession *session G_GNUC_UNUSED, | |
843 | VirtViewerApp *self) | |
844 | { | |
845 | VirtViewerAppPrivate *priv = self->priv; | |
846 | ||
847 | priv->connected = TRUE; | |
848 | virt_viewer_app_show_status(self, _("Connected to graphic server")); | |
849 | } | |
850 | ||
851 | ||
852 | ||
853 | static void | |
854 | virt_viewer_app_initialized(VirtViewerSession *session G_GNUC_UNUSED, | |
855 | VirtViewerApp *self) | |
856 | { | |
857 | virt_viewer_app_update_title(self); | |
858 | } | |
859 | ||
860 | static void | |
861 | virt_viewer_app_disconnected(VirtViewerSession *session G_GNUC_UNUSED, | |
862 | VirtViewerApp *self) | |
863 | { | |
864 | VirtViewerAppPrivate *priv = self->priv; | |
865 | ||
866 | if (!priv->connected) { | |
867 | virt_viewer_app_simple_message_dialog(self, | |
868 | _("Unable to connect to the graphic server %s"), | |
869 | priv->pretty_address); | |
870 | } | |
871 | virt_viewer_app_deactivate(self); | |
872 | } | |
873 | ||
874 | ||
875 | static void virt_viewer_app_auth_refused(VirtViewerSession *session G_GNUC_UNUSED, | |
876 | const char *msg, | |
877 | VirtViewerApp *self) | |
878 | { | |
879 | GtkWidget *dialog; | |
880 | int ret; | |
881 | VirtViewerAppPrivate *priv = self->priv; | |
882 | ||
883 | dialog = gtk_message_dialog_new(virt_viewer_window_get_window(priv->main_window), | |
884 | GTK_DIALOG_MODAL | | |
885 | GTK_DIALOG_DESTROY_WITH_PARENT, | |
886 | GTK_MESSAGE_ERROR, | |
887 | GTK_BUTTONS_YES_NO, | |
888 | _("Unable to authenticate with remote desktop server at %s: %s\n" | |
889 | "Retry connection again?"), | |
890 | priv->pretty_address, msg); | |
891 | ||
892 | ret = gtk_dialog_run(GTK_DIALOG(dialog)); | |
893 | ||
894 | gtk_widget_destroy(dialog); | |
895 | ||
896 | if (ret == GTK_RESPONSE_YES) | |
897 | priv->authretry = TRUE; | |
898 | else | |
899 | priv->authretry = FALSE; | |
900 | } | |
901 | ||
902 | ||
903 | static void virt_viewer_app_auth_failed(VirtViewerSession *session G_GNUC_UNUSED, | |
904 | const char *msg, | |
905 | VirtViewerApp *self) | |
906 | { | |
907 | VirtViewerAppPrivate *priv = self->priv; | |
908 | ||
909 | virt_viewer_app_simple_message_dialog(self, | |
910 | _("Unable to authenticate with remote desktop server at %s"), | |
911 | priv->pretty_address, msg); | |
912 | } | |
913 | ||
914 | static void | |
915 | virt_viewer_app_get_property (GObject *object, guint property_id, | |
916 | GValue *value G_GNUC_UNUSED, GParamSpec *pspec) | |
917 | { | |
918 | g_return_if_fail(VIRT_VIEWER_IS_APP(object)); | |
919 | VirtViewerApp *self = VIRT_VIEWER_APP(object); | |
920 | VirtViewerAppPrivate *priv = self->priv; | |
921 | ||
922 | switch (property_id) { | |
923 | case PROP_VERBOSE: | |
924 | g_value_set_boolean(value, priv->verbose); | |
925 | break; | |
926 | ||
927 | case PROP_CONTAINER: | |
928 | g_value_set_object(value, priv->container); | |
929 | break; | |
930 | ||
931 | case PROP_SESSION: | |
932 | g_value_set_object(value, priv->session); | |
933 | break; | |
934 | ||
935 | case PROP_GUEST_NAME: | |
936 | g_value_set_string(value, priv->guest_name); | |
937 | break; | |
938 | ||
939 | case PROP_FULLSCREEN: | |
940 | g_value_set_boolean(value, priv->fullscreen); | |
941 | break; | |
942 | ||
943 | default: | |
944 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); | |
945 | } | |
946 | } | |
947 | ||
948 | static void | |
949 | virt_viewer_app_set_property (GObject *object, guint property_id, | |
950 | const GValue *value G_GNUC_UNUSED, GParamSpec *pspec) | |
951 | { | |
952 | g_return_if_fail(VIRT_VIEWER_IS_APP(object)); | |
953 | VirtViewerApp *self = VIRT_VIEWER_APP(object); | |
954 | VirtViewerAppPrivate *priv = self->priv; | |
955 | ||
956 | switch (property_id) { | |
957 | case PROP_VERBOSE: | |
958 | priv->verbose = g_value_get_boolean(value); | |
959 | break; | |
960 | ||
961 | case PROP_CONTAINER: | |
962 | g_return_if_fail(priv->container == NULL); | |
963 | priv->container = g_value_dup_object(value); | |
964 | break; | |
965 | ||
966 | case PROP_GUEST_NAME: | |
967 | g_free(priv->guest_name); | |
968 | priv->guest_name = g_value_dup_string(value); | |
969 | break; | |
970 | ||
971 | case PROP_FULLSCREEN: | |
972 | virt_viewer_app_set_fullscreen(self, g_value_get_boolean(value)); | |
973 | break; | |
974 | ||
975 | default: | |
976 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); | |
977 | } | |
978 | } | |
979 | ||
980 | static void | |
981 | virt_viewer_app_dispose (GObject *object) | |
982 | { | |
983 | VirtViewerApp *self = VIRT_VIEWER_APP(object); | |
984 | VirtViewerAppPrivate *priv = self->priv; | |
985 | ||
986 | if (priv->windows) { | |
987 | g_hash_table_unref(priv->windows); | |
988 | priv->windows = NULL; | |
989 | } | |
990 | ||
991 | if (priv->main_window) { | |
992 | g_object_unref(priv->main_window); | |
993 | priv->main_window = NULL; | |
994 | } | |
995 | ||
996 | if (priv->container) { | |
997 | g_object_unref(priv->container); | |
998 | priv->container = NULL; | |
999 | } | |
1000 | ||
1001 | virt_viewer_app_free_connect_info(self); | |
1002 | ||
1003 | G_OBJECT_CLASS (virt_viewer_app_parent_class)->dispose (object); | |
1004 | } | |
1005 | ||
1006 | static gboolean | |
1007 | virt_viewer_app_default_start(VirtViewerApp *self) | |
1008 | { | |
1009 | VirtViewerAppPrivate *priv; | |
1010 | GtkWindow *win; | |
1011 | priv = self->priv; | |
1012 | ||
1013 | win = virt_viewer_window_get_window(priv->main_window); | |
1014 | if (win) | |
1015 | gtk_widget_show(GTK_WIDGET(win)); | |
1016 | else { | |
1017 | gtk_box_pack_end(GTK_BOX(priv->container), priv->main_notebook, TRUE, TRUE, 0); | |
1018 | gtk_widget_show(GTK_WIDGET(priv->main_notebook)); | |
1019 | } | |
1020 | ||
1021 | return TRUE; | |
1022 | } | |
1023 | ||
1024 | gboolean virt_viewer_app_start(VirtViewerApp *self) | |
1025 | { | |
1026 | VirtViewerAppClass *klass; | |
1027 | ||
1028 | g_return_val_if_fail(VIRT_VIEWER_IS_APP(self), FALSE); | |
1029 | klass = VIRT_VIEWER_APP_GET_CLASS(self); | |
1030 | ||
1031 | g_return_val_if_fail(!self->priv->started, TRUE); | |
1032 | ||
1033 | self->priv->started = klass->start(self); | |
1034 | return self->priv->started; | |
1035 | } | |
1036 | ||
1037 | static void | |
1038 | virt_viewer_app_init (VirtViewerApp *self) | |
1039 | { | |
1040 | self->priv = GET_PRIVATE(self); | |
1041 | self->priv->windows = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_object_unref); | |
1042 | } | |
1043 | ||
1044 | static GObject * | |
1045 | virt_viewer_app_constructor (GType gtype, | |
1046 | guint n_properties, | |
1047 | GObjectConstructParam *properties) | |
1048 | { | |
1049 | GObject *obj; | |
1050 | VirtViewerApp *self; | |
1051 | VirtViewerAppPrivate *priv; | |
1052 | ||
1053 | obj = G_OBJECT_CLASS (virt_viewer_app_parent_class)->constructor (gtype, n_properties, properties); | |
1054 | self = VIRT_VIEWER_APP(obj); | |
1055 | priv = self->priv; | |
1056 | ||
1057 | priv->main_window = virt_viewer_app_window_new(self, priv->container, 0); | |
1058 | priv->main_notebook = GTK_WIDGET(virt_viewer_window_get_notebook(priv->main_window)); | |
1059 | ||
1060 | return obj; | |
1061 | } | |
1062 | ||
1063 | static void | |
1064 | virt_viewer_app_class_init (VirtViewerAppClass *klass) | |
1065 | { | |
1066 | GObjectClass *object_class = G_OBJECT_CLASS (klass); | |
1067 | ||
1068 | g_type_class_add_private (klass, sizeof (VirtViewerAppPrivate)); | |
1069 | ||
1070 | object_class->constructor = virt_viewer_app_constructor; | |
1071 | object_class->get_property = virt_viewer_app_get_property; | |
1072 | object_class->set_property = virt_viewer_app_set_property; | |
1073 | object_class->dispose = virt_viewer_app_dispose; | |
1074 | ||
1075 | klass->start = virt_viewer_app_default_start; | |
1076 | klass->initial_connect = virt_viewer_app_default_initial_connect; | |
1077 | klass->deactivated = virt_viewer_app_default_deactivated; | |
1078 | ||
1079 | g_object_class_install_property(object_class, | |
1080 | PROP_VERBOSE, | |
1081 | g_param_spec_boolean("verbose", | |
1082 | "Verbose", | |
1083 | "Verbose trace", | |
1084 | FALSE, | |
1085 | G_PARAM_READABLE | | |
1086 | G_PARAM_WRITABLE | | |
1087 | G_PARAM_STATIC_STRINGS)); | |
1088 | ||
1089 | g_object_class_install_property(object_class, | |
1090 | PROP_CONTAINER, | |
1091 | g_param_spec_object("container", | |
1092 | "Container", | |
1093 | "Widget container", | |
1094 | GTK_TYPE_WIDGET, | |
1095 | G_PARAM_READABLE | | |
1096 | G_PARAM_WRITABLE | | |
1097 | G_PARAM_CONSTRUCT_ONLY | | |
1098 | G_PARAM_STATIC_STRINGS)); | |
1099 | ||
1100 | g_object_class_install_property(object_class, | |
1101 | PROP_SESSION, | |
1102 | g_param_spec_object("session", | |
1103 | "Session", | |
1104 | "ViewerSession", | |
1105 | VIRT_VIEWER_TYPE_SESSION, | |
1106 | G_PARAM_READABLE | | |
1107 | G_PARAM_STATIC_STRINGS)); | |
1108 | ||
1109 | g_object_class_install_property(object_class, | |
1110 | PROP_GUEST_NAME, | |
1111 | g_param_spec_string("guest-name", | |
1112 | "Guest name", | |
1113 | "Guest name", | |
1114 | "", | |
1115 | G_PARAM_READABLE | | |
1116 | G_PARAM_WRITABLE | | |
1117 | G_PARAM_STATIC_STRINGS)); | |
1118 | ||
1119 | g_object_class_install_property(object_class, | |
1120 | PROP_FULLSCREEN, | |
1121 | g_param_spec_boolean("fullscreen", | |
1122 | "Fullscreen", | |
1123 | "Fullscreen", | |
1124 | FALSE, | |
1125 | G_PARAM_READABLE | | |
1126 | G_PARAM_WRITABLE | | |
1127 | G_PARAM_STATIC_STRINGS)); | |
1128 | } | |
1129 | ||
1130 | void | |
1131 | virt_viewer_app_set_direct(VirtViewerApp *self, gboolean direct) | |
1132 | { | |
1133 | g_return_if_fail(VIRT_VIEWER_IS_APP(self)); | |
1134 | ||
1135 | self->priv->direct = direct; | |
1136 | } | |
1137 | ||
1138 | gboolean | |
1139 | virt_viewer_app_is_active(VirtViewerApp *self) | |
1140 | { | |
1141 | g_return_val_if_fail(VIRT_VIEWER_IS_APP(self), FALSE); | |
1142 | ||
1143 | return self->priv->active; | |
1144 | } | |
1145 | ||
1146 | gboolean | |
1147 | virt_viewer_app_has_session(VirtViewerApp *self) | |
1148 | { | |
1149 | g_return_val_if_fail(VIRT_VIEWER_IS_APP(self), FALSE); | |
1150 | ||
1151 | return self->priv->session != NULL; | |
1152 | } | |
1153 | ||
1154 | static void | |
1155 | virt_viewer_app_update_pretty_address(VirtViewerApp *self) | |
1156 | { | |
1157 | VirtViewerAppPrivate *priv; | |
1158 | ||
1159 | priv = self->priv; | |
1160 | g_free(priv->pretty_address); | |
1161 | if (priv->gport) | |
1162 | priv->pretty_address = g_strdup_printf("%s:%s", priv->ghost, priv->gport); | |
1163 | else | |
1164 | priv->pretty_address = g_strdup_printf("%s:%s", priv->host, priv->unixsock); | |
1165 | } | |
1166 | ||
1167 | typedef struct { | |
1168 | gboolean fullscreen; | |
1169 | gboolean move; | |
1170 | } FullscreenOptions; | |
1171 | ||
1172 | static void fullscreen_cb(gpointer key, | |
1173 | gpointer value, | |
1174 | gpointer user_data) | |
1175 | { | |
1176 | gint nth = *(gint*)key; | |
1177 | FullscreenOptions *options = (FullscreenOptions *)user_data; | |
1178 | VirtViewerWindow *vwin = VIRT_VIEWER_WINDOW(value); | |
1179 | ||
1180 | DEBUG_LOG("fullscreen display %d: %d", nth, options->fullscreen); | |
1181 | if (options->fullscreen) { | |
1182 | GdkScreen *screen = gdk_screen_get_default (); | |
1183 | GdkRectangle mon; | |
1184 | ||
1185 | if (nth >= gdk_screen_get_n_monitors(screen)) { | |
1186 | DEBUG_LOG("skipping display %d", nth); | |
1187 | return; | |
1188 | } | |
1189 | gdk_screen_get_monitor_geometry(screen, nth, &mon); | |
1190 | virt_viewer_window_enter_fullscreen(vwin, options->move, mon.x, mon.y); | |
1191 | } else | |
1192 | virt_viewer_window_leave_fullscreen(vwin); | |
1193 | } | |
1194 | ||
1195 | static void | |
1196 | virt_viewer_app_set_fullscreen(VirtViewerApp *self, gboolean fullscreen) | |
1197 | { | |
1198 | VirtViewerAppPrivate *priv = self->priv; | |
1199 | FullscreenOptions options = { | |
1200 | .fullscreen = fullscreen, | |
1201 | .move = virt_viewer_app_get_n_windows_visible(self) > 1, | |
1202 | }; | |
1203 | ||
1204 | /* we iterate unconditionnaly, even if it was set before to update new windows */ | |
1205 | priv->fullscreen = fullscreen; | |
1206 | g_hash_table_foreach(priv->windows, fullscreen_cb, &options); | |
1207 | } | |
1208 | ||
1209 | static void | |
1210 | menu_display_visible_toggled_cb(GtkCheckMenuItem *checkmenuitem, | |
1211 | VirtViewerWindow *vwin) | |
1212 | { | |
1213 | VirtViewerApp *self; | |
1214 | gboolean visible; | |
1215 | static gboolean reentering = FALSE; | |
1216 | ||
1217 | if (reentering) /* do not reenter if I switch you back */ | |
1218 | return; | |
1219 | ||
1220 | reentering = TRUE; | |
1221 | g_object_get(vwin, "app", &self, NULL); | |
1222 | visible = virt_viewer_app_window_set_visible(self, vwin, | |
1223 | gtk_check_menu_item_get_active(checkmenuitem)); | |
1224 | gtk_check_menu_item_set_active(checkmenuitem, /* will be toggled again */ !visible); | |
1225 | g_object_unref(self); | |
1226 | reentering = FALSE; | |
1227 | } | |
1228 | ||
1229 | static gint | |
1230 | update_menu_displays_sort(gconstpointer a, gconstpointer b) | |
1231 | { | |
1232 | const int *ai = a; | |
1233 | const int *bi = b; | |
1234 | ||
1235 | if (*ai > *bi) | |
1236 | return 1; | |
1237 | else if (*ai < *bi) | |
1238 | return -1; | |
1239 | else | |
1240 | return 0; | |
1241 | } | |
1242 | ||
1243 | static void | |
1244 | window_update_menu_displays_cb(gpointer key G_GNUC_UNUSED, | |
1245 | gpointer value, | |
1246 | gpointer user_data) | |
1247 | { | |
1248 | VirtViewerApp *self = VIRT_VIEWER_APP(user_data); | |
1249 | VirtViewerWindow *window = VIRT_VIEWER_WINDOW(value); | |
1250 | GtkMenuShell *submenu = GTK_MENU_SHELL(gtk_menu_new()); | |
1251 | GtkMenuItem *menu = virt_viewer_window_get_menu_displays(window); | |
1252 | GList *keys = g_hash_table_get_keys(self->priv->windows); | |
1253 | GList *tmp; | |
1254 | ||
1255 | keys = g_list_sort(keys, update_menu_displays_sort); | |
1256 | ||
1257 | tmp = keys; | |
1258 | while (tmp) { | |
1259 | int *nth = tmp->data; | |
1260 | VirtViewerWindow *vwin = VIRT_VIEWER_WINDOW(g_hash_table_lookup(self->priv->windows, nth)); | |
1261 | GtkWidget *item; | |
1262 | gboolean visible; | |
1263 | ||
1264 | item = gtk_check_menu_item_new_with_label(g_strdup_printf("Display %d", *nth)); | |
1265 | visible = gtk_widget_get_visible(GTK_WIDGET(virt_viewer_window_get_window(vwin))); | |
1266 | gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), visible); | |
1267 | g_signal_connect(G_OBJECT(item), | |
1268 | "toggled", G_CALLBACK(menu_display_visible_toggled_cb), vwin); | |
1269 | gtk_menu_shell_append(submenu, item); | |
1270 | tmp = tmp->next; | |
1271 | } | |
1272 | ||
1273 | gtk_widget_show_all(GTK_WIDGET(submenu)); | |
1274 | gtk_menu_item_set_submenu(menu, GTK_WIDGET(submenu)); | |
1275 | g_list_free(keys); | |
1276 | } | |
1277 | ||
1278 | static void | |
1279 | virt_viewer_app_update_menu_displays(VirtViewerApp *self) | |
1280 | { | |
1281 | g_hash_table_foreach(self->priv->windows, window_update_menu_displays_cb, self); | |
1282 | } | |
1283 | ||
1284 | void | |
1285 | virt_viewer_app_set_connect_info(VirtViewerApp *self, | |
1286 | const gchar *host, | |
1287 | const gchar *ghost, | |
1288 | const gchar *gport, | |
1289 | const gchar *transport, | |
1290 | const gchar *unixsock, | |
1291 | const gchar *user, | |
1292 | gint port) | |
1293 | { | |
1294 | g_return_if_fail(VIRT_VIEWER_IS_APP(self)); | |
1295 | VirtViewerAppPrivate *priv = self->priv; | |
1296 | ||
1297 | DEBUG_LOG("Set connect info: %s,%s,%s,%s,%s,%s,%d", | |
1298 | host, ghost, gport, transport, unixsock, user, port); | |
1299 | ||
1300 | g_free(priv->host); | |
1301 | g_free(priv->ghost); | |
1302 | g_free(priv->gport); | |
1303 | g_free(priv->transport); | |
1304 | g_free(priv->unixsock); | |
1305 | g_free(priv->user); | |
1306 | ||
1307 | priv->host = g_strdup(host); | |
1308 | priv->ghost = g_strdup(ghost); | |
1309 | priv->gport = g_strdup(gport); | |
1310 | priv->transport = g_strdup(transport); | |
1311 | priv->unixsock = g_strdup(unixsock); | |
1312 | priv->user = g_strdup(user); | |
1313 | priv->port = 0; | |
1314 | ||
1315 | virt_viewer_app_update_pretty_address(self); | |
1316 | } | |
1317 | ||
1318 | void | |
1319 | virt_viewer_app_free_connect_info(VirtViewerApp *self) | |
1320 | { | |
1321 | g_return_if_fail(VIRT_VIEWER_IS_APP(self)); | |
1322 | ||
1323 | virt_viewer_app_set_connect_info(self, NULL, NULL, NULL, NULL, NULL, NULL, 0); | |
1324 | } | |
1325 | ||
1326 | VirtViewerWindow* | |
1327 | virt_viewer_app_get_main_window(VirtViewerApp *self) | |
1328 | { | |
1329 | g_return_val_if_fail(VIRT_VIEWER_IS_APP(self), NULL); | |
1330 | ||
1331 | return self->priv->main_window; | |
1332 | } | |
1333 | ||
1334 | static void | |
1335 | show_status_cb(gpointer key G_GNUC_UNUSED, | |
1336 | gpointer value, | |
1337 | gpointer user_data) | |
1338 | { | |
1339 | VirtViewerNotebook *nb = virt_viewer_window_get_notebook(VIRT_VIEWER_WINDOW(value)); | |
1340 | gchar *text = (gchar*)user_data; | |
1341 | ||
1342 | virt_viewer_notebook_show_status(nb, text); | |
1343 | } | |
1344 | ||
1345 | void | |
1346 | virt_viewer_app_show_status(VirtViewerApp *self, const gchar *fmt, ...) | |
1347 | { | |
1348 | va_list args; | |
1349 | gchar *text; | |
1350 | ||
1351 | g_return_if_fail(VIRT_VIEWER_IS_APP(self)); | |
1352 | ||
1353 | va_start(args, fmt); | |
1354 | text = g_strdup_vprintf(fmt, args); | |
1355 | va_end(args); | |
1356 | ||
1357 | g_hash_table_foreach(self->priv->windows, show_status_cb, text); | |
1358 | g_free(text); | |
1359 | } | |
1360 | ||
1361 | /* | |
1362 | * Local variables: | |
1363 | * c-indent-level: 8 | |
1364 | * c-basic-offset: 8 | |
1365 | * tab-width: 8 | |
1366 | * indent-tabs-mode: t | |
1367 | * End: | |
1368 | */ |
0 | /* | |
1 | * Virt Viewer: A virtual machine console viewer | |
2 | * | |
3 | * Copyright (C) 2007 Red Hat, | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms of the GNU General Public License as published by | |
7 | * the Free Software Foundation; either version 2 of the License, or | |
8 | * (at your option) any later version. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License | |
16 | * along with this program; if not, write to the Free Software | |
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | * | |
19 | * Author: Daniel P. Berrange <berrange@redhat.com> | |
20 | */ | |
21 | ||
22 | #ifndef VIRT_VIEWER_APP_H | |
23 | #define VIRT_VIEWER_APP_H | |
24 | ||
25 | #include <glib-object.h> | |
26 | #include "virt-viewer-util.h" | |
27 | #include "virt-viewer-window.h" | |
28 | ||
29 | G_BEGIN_DECLS | |
30 | ||
31 | #define VIRT_VIEWER_TYPE_APP virt_viewer_app_get_type() | |
32 | #define VIRT_VIEWER_APP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIRT_VIEWER_TYPE_APP, VirtViewerApp)) | |
33 | #define VIRT_VIEWER_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VIRT_VIEWER_TYPE_APP, VirtViewerAppClass)) | |
34 | #define VIRT_VIEWER_IS_APP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIRT_VIEWER_TYPE_APP)) | |
35 | #define VIRT_VIEWER_IS_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VIRT_VIEWER_TYPE_APP)) | |
36 | #define VIRT_VIEWER_APP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VIRT_VIEWER_TYPE_APP, VirtViewerAppClass)) | |
37 | ||
38 | typedef struct _VirtViewerAppPrivate VirtViewerAppPrivate; | |
39 | ||
40 | typedef struct { | |
41 | GObject parent; | |
42 | VirtViewerAppPrivate *priv; | |
43 | } VirtViewerApp; | |
44 | ||
45 | typedef struct { | |
46 | GObjectClass parent_class; | |
47 | ||
48 | gboolean (*start) (VirtViewerApp *self); | |
49 | int (*initial_connect) (VirtViewerApp *self); | |
50 | void (*deactivated) (VirtViewerApp *self); | |
51 | } VirtViewerAppClass; | |
52 | ||
53 | GType virt_viewer_app_get_type (void); | |
54 | ||
55 | void virt_viewer_app_set_debug(gboolean debug); | |
56 | gboolean virt_viewer_app_start(VirtViewerApp *app); | |
57 | void virt_viewer_app_quit(VirtViewerApp *self); | |
58 | VirtViewerWindow* virt_viewer_app_get_main_window(VirtViewerApp *self); | |
59 | void virt_viewer_app_trace(VirtViewerApp *self, const char *fmt, ...); | |
60 | void virt_viewer_app_simple_message_dialog(VirtViewerApp *self, const char *fmt, ...); | |
61 | gboolean virt_viewer_app_is_active(VirtViewerApp *app); | |
62 | void virt_viewer_app_free_connect_info(VirtViewerApp *self); | |
63 | int virt_viewer_app_create_session(VirtViewerApp *self, const gchar *type); | |
64 | int virt_viewer_app_activate(VirtViewerApp *self); | |
65 | int virt_viewer_app_initial_connect(VirtViewerApp *self); | |
66 | void virt_viewer_app_start_reconnect_poll(VirtViewerApp *self); | |
67 | void virt_viewer_app_set_zoom_level(VirtViewerApp *self, gint zoom_level); | |
68 | void virt_viewer_app_set_direct(VirtViewerApp *self, gboolean direct); | |
69 | gboolean virt_viewer_app_has_session(VirtViewerApp *self); | |
70 | void virt_viewer_app_set_connect_info(VirtViewerApp *self, | |
71 | const gchar *host, | |
72 | const gchar *ghost, | |
73 | const gchar *gport, | |
74 | const gchar *transport, | |
75 | const gchar *unixsock, | |
76 | const gchar *user, | |
77 | gint port); | |
78 | gboolean virt_viewer_app_window_set_visible(VirtViewerApp *self, VirtViewerWindow *window, gboolean visible); | |
79 | void virt_viewer_app_show_status(VirtViewerApp *self, const gchar *fmt, ...); | |
80 | ||
81 | G_END_DECLS | |
82 | ||
83 | #endif /* VIRT_VIEWER_APP_H */ |
62 | 62 | message = g_strdup_printf("Authentication is required for the %s connection to:\n\n" |
63 | 63 | "<b>%s</b>\n\n", |
64 | 64 | type, |
65 | address ? address : "[unknown]"); | |
65 | address); | |
66 | 66 | } else { |
67 | 67 | message = g_strdup_printf("Authentication is required for the %s connection:\n", |
68 | 68 | type); |
99 | 99 | } |
100 | 100 | |
101 | 101 | static void |
102 | virt_viewer_display_spice_primary_create(SpiceChannel *channel G_GNUC_UNUSED, | |
103 | gint format G_GNUC_UNUSED, | |
104 | gint width, | |
105 | gint height, | |
106 | gint stride G_GNUC_UNUSED, | |
107 | gint shmid G_GNUC_UNUSED, | |
108 | gpointer imgdata G_GNUC_UNUSED, | |
109 | VirtViewerDisplay *display) | |
102 | display_mark(SpiceChannel *channel G_GNUC_UNUSED, | |
103 | gint mark, | |
104 | VirtViewerDisplay *display) | |
110 | 105 | { |
111 | DEBUG_LOG("desktop resize %dx%d", width, height); | |
106 | DEBUG_LOG("display mark %d", mark); | |
112 | 107 | |
113 | virt_viewer_display_set_desktop_size(display, width, height); | |
114 | g_signal_emit_by_name(display, "display-desktop-resize"); | |
108 | virt_viewer_display_set_show_hint(display, mark); | |
109 | } | |
110 | ||
111 | static void | |
112 | primary_create(SpiceChannel *channel G_GNUC_UNUSED, | |
113 | gint format G_GNUC_UNUSED, | |
114 | gint width, | |
115 | gint height, | |
116 | gint stride G_GNUC_UNUSED, | |
117 | gint shmid G_GNUC_UNUSED, | |
118 | gpointer imgdata G_GNUC_UNUSED, | |
119 | VirtViewerDisplay *display) | |
120 | { | |
121 | DEBUG_LOG("spice desktop resize %dx%d", width, height); | |
122 | ||
123 | virt_viewer_display_set_desktop_size(display, width, height); | |
124 | g_signal_emit_by_name(display, "display-desktop-resize"); | |
115 | 125 | } |
116 | 126 | |
117 | 127 | |
120 | 130 | SpiceDisplay *display) |
121 | 131 | { |
122 | 132 | VirtViewerDisplaySpice *self; |
133 | gint channelid; | |
123 | 134 | |
124 | self = g_object_new(VIRT_VIEWER_TYPE_DISPLAY_SPICE, NULL); | |
135 | g_return_val_if_fail(SPICE_IS_DISPLAY_CHANNEL(channel), NULL); | |
136 | g_return_val_if_fail(SPICE_IS_DISPLAY(display), NULL); | |
125 | 137 | |
126 | self->priv->channel = channel; | |
127 | self->priv->display = display; | |
138 | g_object_get(channel, "channel-id", &channelid, NULL); | |
128 | 139 | |
129 | g_object_ref(channel); | |
130 | g_object_ref(display); | |
140 | self = g_object_new(VIRT_VIEWER_TYPE_DISPLAY_SPICE, | |
141 | "nth-display", channelid, | |
142 | NULL); | |
143 | self->priv->channel = g_object_ref(channel); | |
144 | self->priv->display = g_object_ref(display); | |
131 | 145 | |
132 | 146 | g_signal_connect(channel, "display-primary-create", |
133 | G_CALLBACK(virt_viewer_display_spice_primary_create), self); | |
147 | G_CALLBACK(primary_create), self); | |
148 | g_signal_connect(channel, "display-mark", | |
149 | G_CALLBACK(display_mark), self); | |
134 | 150 | |
135 | 151 | gtk_container_add(GTK_CONTAINER(self), GTK_WIDGET(self->priv->display)); |
136 | 152 | gtk_widget_show(GTK_WIDGET(self->priv->display)); |
39 | 39 | #define VIRT_VIEWER_DISPLAY_SPICE_CLASS(klass) \ |
40 | 40 | (G_TYPE_CHECK_CLASS_CAST ((klass), VIRT_VIEWER_TYPE_DISPLAY_SPICE, VirtViewerDisplaySpiceClass)) |
41 | 41 | |
42 | #define VIRT_IS_VIEWER_DISPLAY_SPICE(obj) \ | |
42 | #define VIRT_VIEWER_IS_DISPLAY_SPICE(obj) \ | |
43 | 43 | (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIRT_VIEWER_TYPE_DISPLAY_SPICE)) |
44 | 44 | |
45 | #define VIRT_IS_VIEWER_DISPLAY_SPICE_CLASS(klass) \ | |
45 | #define VIRT_VIEWER_IS_DISPLAY_SPICE_CLASS(klass) \ | |
46 | 46 | (G_TYPE_CHECK_CLASS_TYPE ((klass), VIRT_VIEWER_TYPE_DISPLAY_SPICE)) |
47 | 47 | |
48 | 48 | #define VIRT_VIEWER_DISPLAY_SPICE_GET_CLASS(obj) \ |
38 | 38 | #define VIRT_VIEWER_DISPLAY_VNC_CLASS(klass) \ |
39 | 39 | (G_TYPE_CHECK_CLASS_CAST ((klass), VIRT_VIEWER_TYPE_DISPLAY_VNC, VirtViewerDisplayVncClass)) |
40 | 40 | |
41 | #define VIRT_IS_VIEWER_DISPLAY_VNC(obj) \ | |
41 | #define VIRT_VIEWER_IS_DISPLAY_VNC(obj) \ | |
42 | 42 | (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIRT_VIEWER_TYPE_DISPLAY_VNC)) |
43 | 43 | |
44 | #define VIRT_IS_VIEWER_DISPLAY_VNC_CLASS(klass) \ | |
44 | #define VIRT_VIEWER_IS_DISPLAY_VNC_CLASS(klass) \ | |
45 | 45 | (G_TYPE_CHECK_CLASS_TYPE ((klass), VIRT_VIEWER_TYPE_DISPLAY_VNC)) |
46 | 46 | |
47 | 47 | #define VIRT_VIEWER_DISPLAY_VNC_GET_CLASS(obj) \ |
37 | 37 | guint desktopHeight; |
38 | 38 | guint zoom_level; |
39 | 39 | gboolean zoom; |
40 | gint nth_display; | |
41 | gint show_hint; | |
40 | 42 | }; |
41 | 43 | |
42 | 44 | static void virt_viewer_display_size_request(GtkWidget *widget, |
67 | 69 | |
68 | 70 | PROP_DESKTOP_WIDTH, |
69 | 71 | PROP_DESKTOP_HEIGHT, |
72 | PROP_NTH_DISPLAY, | |
70 | 73 | PROP_ZOOM, |
71 | 74 | PROP_ZOOM_LEVEL, |
75 | PROP_SHOW_HINT, | |
72 | 76 | }; |
73 | 77 | |
74 | 78 | static void |
97 | 101 | G_MAXINT32, |
98 | 102 | 100, |
99 | 103 | G_PARAM_READWRITE)); |
104 | ||
100 | 105 | g_object_class_install_property(object_class, |
101 | 106 | PROP_DESKTOP_HEIGHT, |
102 | 107 | g_param_spec_int("desktop-height", |
106 | 111 | G_MAXINT32, |
107 | 112 | 100, |
108 | 113 | G_PARAM_READWRITE)); |
114 | ||
109 | 115 | g_object_class_install_property(object_class, |
110 | 116 | PROP_ZOOM, |
111 | 117 | g_param_spec_boolean("zoom", |
113 | 119 | "Zoom", |
114 | 120 | TRUE, |
115 | 121 | G_PARAM_READWRITE)); |
122 | ||
116 | 123 | g_object_class_install_property(object_class, |
117 | 124 | PROP_ZOOM_LEVEL, |
118 | 125 | g_param_spec_int("zoom-level", |
123 | 130 | 100, |
124 | 131 | G_PARAM_READWRITE)); |
125 | 132 | |
133 | g_object_class_install_property(object_class, | |
134 | PROP_NTH_DISPLAY, | |
135 | g_param_spec_int("nth-display", | |
136 | "Nth display", | |
137 | "Nth display", | |
138 | 0, | |
139 | G_MAXINT32, | |
140 | 0, | |
141 | G_PARAM_READWRITE | | |
142 | G_PARAM_CONSTRUCT_ONLY)); | |
143 | ||
144 | g_object_class_install_property(object_class, | |
145 | PROP_SHOW_HINT, | |
146 | g_param_spec_int("show-hint", | |
147 | "Show hint", | |
148 | "Show state hint", | |
149 | 0, | |
150 | G_MAXINT32, | |
151 | 0, | |
152 | G_PARAM_READABLE)); | |
153 | ||
126 | 154 | |
127 | 155 | g_signal_new("display-pointer-grab", |
128 | 156 | G_OBJECT_CLASS_TYPE(object_class), |
205 | 233 | { |
206 | 234 | VirtViewerDisplay *display = VIRT_VIEWER_DISPLAY(object); |
207 | 235 | VirtViewerDisplayPrivate *priv = display->priv; |
208 | ||
236 | ||
209 | 237 | switch (prop_id) { |
210 | 238 | case PROP_DESKTOP_WIDTH: |
211 | 239 | virt_viewer_display_set_desktop_size(display, |
217 | 245 | priv->desktopWidth, |
218 | 246 | g_value_get_int(value)); |
219 | 247 | break; |
220 | ||
248 | case PROP_NTH_DISPLAY: | |
249 | priv->nth_display = g_value_get_int(value); | |
250 | break; | |
221 | 251 | default: |
222 | 252 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
223 | 253 | break; |
232 | 262 | { |
233 | 263 | VirtViewerDisplay *display = VIRT_VIEWER_DISPLAY(object); |
234 | 264 | VirtViewerDisplayPrivate *priv = display->priv; |
235 | ||
265 | ||
236 | 266 | switch (prop_id) { |
237 | 267 | case PROP_DESKTOP_WIDTH: |
238 | 268 | g_value_set_int(value, priv->desktopWidth); |
240 | 270 | case PROP_DESKTOP_HEIGHT: |
241 | 271 | g_value_set_int(value, priv->desktopHeight); |
242 | 272 | break; |
243 | ||
273 | case PROP_NTH_DISPLAY: | |
274 | g_value_set_int(value, priv->nth_display); | |
275 | break; | |
276 | case PROP_SHOW_HINT: | |
277 | g_value_set_int(value, priv->show_hint); | |
278 | break; | |
279 | ||
244 | 280 | default: |
245 | 281 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
246 | 282 | break; |
443 | 479 | return VIRT_VIEWER_DISPLAY_GET_CLASS(display)->get_pixbuf(display); |
444 | 480 | } |
445 | 481 | |
482 | void virt_viewer_display_set_show_hint(VirtViewerDisplay *self, gint hint) | |
483 | { | |
484 | VirtViewerDisplayPrivate *priv; | |
485 | g_return_if_fail(VIRT_VIEWER_IS_DISPLAY(self)); | |
486 | ||
487 | priv = self->priv; | |
488 | if (priv->show_hint == hint) | |
489 | return; | |
490 | ||
491 | priv->show_hint = hint; | |
492 | g_object_notify(G_OBJECT(self), "show-hint"); | |
493 | } | |
494 | ||
446 | 495 | /* |
447 | 496 | * Local variables: |
448 | 497 | * c-indent-level: 8 |
50 | 50 | |
51 | 51 | typedef struct _VirtViewerDisplayChannel VirtViewerDisplayChannel; |
52 | 52 | |
53 | enum { | |
54 | VIRT_VIEWER_DISPLAY_SHOW_HINT_HIDE = 0, | |
55 | VIRT_VIEWER_DISPLAY_SHOW_HINT_READY, | |
56 | }; | |
53 | 57 | |
54 | 58 | /* perhaps this become an interface, and be pushed in gtkvnc and spice? */ |
55 | 59 | struct _VirtViewerDisplay { |
92 | 96 | void virt_viewer_display_set_zoom(VirtViewerDisplay *display, |
93 | 97 | gboolean zoom); |
94 | 98 | |
95 | void virt_viewer_display_send_keys(VirtViewerDisplay* display, | |
99 | void virt_viewer_display_send_keys(VirtViewerDisplay *display, | |
96 | 100 | const guint *keyvals, int nkeyvals); |
97 | GdkPixbuf* virt_viewer_display_get_pixbuf(VirtViewerDisplay* display); | |
101 | GdkPixbuf* virt_viewer_display_get_pixbuf(VirtViewerDisplay *display); | |
102 | void virt_viewer_display_set_show_hint(VirtViewerDisplay *display, gint hint); | |
98 | 103 | |
99 | 104 | G_END_DECLS |
100 | 105 |
50 | 50 | gboolean waitvm = FALSE; |
51 | 51 | gboolean reconnect = FALSE; |
52 | 52 | gboolean fullscreen = FALSE; |
53 | VirtViewer *viewer = NULL; | |
53 | 54 | const char *help_msg = N_("Run '" PACKAGE " --help' to see a full list of available command line options"); |
54 | 55 | const GOptionEntry options [] = { |
55 | 56 | { "version", 'V', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, |
106 | 107 | goto cleanup; |
107 | 108 | } |
108 | 109 | |
109 | ret = virt_viewer_start(uri, args[0], zoom, direct, waitvm, reconnect, verbose, debug, fullscreen, NULL); | |
110 | if (ret != 0) | |
111 | return ret; | |
110 | virt_viewer_app_set_debug(debug); | |
111 | ||
112 | viewer = virt_viewer_new(uri, args[0], zoom, direct, waitvm, reconnect, verbose, NULL); | |
113 | if (viewer == NULL) | |
114 | goto cleanup; | |
115 | ||
116 | g_object_set(viewer, "fullscreen", fullscreen, NULL); | |
117 | if (!virt_viewer_app_start(VIRT_VIEWER_APP(viewer))) | |
118 | goto cleanup; | |
112 | 119 | |
113 | 120 | gtk_main(); |
114 | 121 | |
115 | cleanup: | |
122 | ret = 0; | |
123 | ||
124 | cleanup: | |
125 | if (viewer) | |
126 | g_object_unref(viewer); | |
116 | 127 | g_free(uri); |
117 | 128 | g_strfreev(args); |
118 | 129 |
0 | /* | |
1 | * Virt Viewer: A virtual machine console viewer | |
2 | * | |
3 | * Copyright (C) 2007-2009 Red Hat, | |
4 | * Copyright (C) 2009 Daniel P. Berrange | |
5 | * Copyright (C) 2010 Marc-André Lureau | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with this program; if not, write to the Free Software | |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 | * | |
21 | * Author: Daniel P. Berrange <berrange@redhat.com> | |
22 | */ | |
23 | #include "virt-viewer-notebook.h" | |
24 | #include "virt-viewer-util.h" | |
25 | ||
26 | G_DEFINE_TYPE (VirtViewerNotebook, virt_viewer_notebook, GTK_TYPE_NOTEBOOK) | |
27 | ||
28 | #define GET_PRIVATE(o) \ | |
29 | (G_TYPE_INSTANCE_GET_PRIVATE ((o), VIRT_VIEWER_TYPE_NOTEBOOK, VirtViewerNotebookPrivate)) | |
30 | ||
31 | struct _VirtViewerNotebookPrivate { | |
32 | GtkWidget *status; | |
33 | }; | |
34 | ||
35 | static void | |
36 | virt_viewer_notebook_get_property (GObject *object, guint property_id, | |
37 | GValue *value G_GNUC_UNUSED, GParamSpec *pspec) | |
38 | { | |
39 | switch (property_id) { | |
40 | default: | |
41 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); | |
42 | } | |
43 | } | |
44 | ||
45 | static void | |
46 | virt_viewer_notebook_set_property (GObject *object, guint property_id, | |
47 | const GValue *value G_GNUC_UNUSED, GParamSpec *pspec) | |
48 | { | |
49 | switch (property_id) { | |
50 | default: | |
51 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); | |
52 | } | |
53 | } | |
54 | ||
55 | static void | |
56 | virt_viewer_notebook_dispose (GObject *object) | |
57 | { | |
58 | G_OBJECT_CLASS (virt_viewer_notebook_parent_class)->dispose (object); | |
59 | } | |
60 | ||
61 | static void | |
62 | virt_viewer_notebook_class_init (VirtViewerNotebookClass *klass) | |
63 | { | |
64 | GObjectClass *object_class = G_OBJECT_CLASS (klass); | |
65 | ||
66 | g_type_class_add_private (klass, sizeof (VirtViewerNotebookPrivate)); | |
67 | ||
68 | object_class->get_property = virt_viewer_notebook_get_property; | |
69 | object_class->set_property = virt_viewer_notebook_set_property; | |
70 | object_class->dispose = virt_viewer_notebook_dispose; | |
71 | } | |
72 | ||
73 | static void | |
74 | virt_viewer_notebook_init (VirtViewerNotebook *self) | |
75 | { | |
76 | VirtViewerNotebookPrivate *priv; | |
77 | GdkColor color; | |
78 | ||
79 | self->priv = GET_PRIVATE(self); | |
80 | priv = self->priv; | |
81 | ||
82 | priv->status = gtk_label_new(""); | |
83 | gtk_notebook_set_show_tabs(GTK_NOTEBOOK(self), FALSE); | |
84 | gtk_notebook_set_show_border(GTK_NOTEBOOK(self), FALSE); | |
85 | gtk_notebook_append_page(GTK_NOTEBOOK(self), priv->status, NULL); | |
86 | gdk_color_parse("white", &color); | |
87 | gtk_widget_modify_fg(priv->status, GTK_STATE_NORMAL, &color); | |
88 | } | |
89 | ||
90 | void | |
91 | virt_viewer_notebook_show_status_va(VirtViewerNotebook *self, const gchar *fmt, va_list args) | |
92 | { | |
93 | VirtViewerNotebookPrivate *priv; | |
94 | gchar *text; | |
95 | ||
96 | DEBUG_LOG("notebook show status %p", self); | |
97 | g_return_if_fail(VIRT_VIEWER_IS_NOTEBOOK(self)); | |
98 | ||
99 | text = g_strdup_vprintf(fmt, args); | |
100 | priv = self->priv; | |
101 | gtk_label_set_text(GTK_LABEL(priv->status), text); | |
102 | gtk_notebook_set_current_page(GTK_NOTEBOOK(self), 0); | |
103 | gtk_widget_show_all(GTK_WIDGET(self)); | |
104 | g_free(text); | |
105 | } | |
106 | ||
107 | void | |
108 | virt_viewer_notebook_show_status(VirtViewerNotebook *self, const gchar *fmt, ...) | |
109 | { | |
110 | va_list args; | |
111 | ||
112 | g_return_if_fail(VIRT_VIEWER_IS_NOTEBOOK(self)); | |
113 | ||
114 | va_start(args, fmt); | |
115 | virt_viewer_notebook_show_status_va(self, fmt, args); | |
116 | va_end(args); | |
117 | } | |
118 | ||
119 | void | |
120 | virt_viewer_notebook_show_display(VirtViewerNotebook *self) | |
121 | { | |
122 | GtkWidget *display; | |
123 | ||
124 | DEBUG_LOG("notebook show display %p", self); | |
125 | g_return_if_fail(VIRT_VIEWER_IS_NOTEBOOK(self)); | |
126 | ||
127 | display = gtk_notebook_get_nth_page(GTK_NOTEBOOK(self), 1); | |
128 | g_warn_if_fail(display != NULL); | |
129 | ||
130 | gtk_notebook_set_current_page(GTK_NOTEBOOK(self), 1); | |
131 | gtk_widget_show_all(GTK_WIDGET(self)); | |
132 | } | |
133 | ||
134 | VirtViewerNotebook* | |
135 | virt_viewer_notebook_new (void) | |
136 | { | |
137 | return g_object_new (VIRT_VIEWER_TYPE_NOTEBOOK, NULL); | |
138 | } | |
139 | ||
140 | /* | |
141 | * Local variables: | |
142 | * c-indent-level: 8 | |
143 | * c-basic-offset: 8 | |
144 | * tab-width: 8 | |
145 | * indent-tabs-mode: t | |
146 | * End: | |
147 | */ |
0 | /* | |
1 | * Virt Viewer: A virtual machine console viewer | |
2 | * | |
3 | * Copyright (C) 2007-2009 Red Hat, | |
4 | * Copyright (C) 2009 Daniel P. Berrange | |
5 | * Copyright (C) 2010 Marc-André Lureau | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with this program; if not, write to the Free Software | |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 | * | |
21 | * Author: Daniel P. Berrange <berrange@redhat.com> | |
22 | */ | |
23 | #ifndef _VIRT_VIEWER_NOTEBOOK | |
24 | #define _VIRT_VIEWER_NOTEBOOK | |
25 | ||
26 | #include <glib-object.h> | |
27 | #include <gtk/gtk.h> | |
28 | ||
29 | G_BEGIN_DECLS | |
30 | ||
31 | #define VIRT_VIEWER_TYPE_NOTEBOOK virt_viewer_notebook_get_type() | |
32 | ||
33 | #define VIRT_VIEWER_NOTEBOOK(obj) \ | |
34 | (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIRT_VIEWER_TYPE_NOTEBOOK, VirtViewerNotebook)) | |
35 | ||
36 | #define VIRT_VIEWER_NOTEBOOK_CLASS(klass) \ | |
37 | (G_TYPE_CHECK_CLASS_CAST ((klass), VIRT_VIEWER_TYPE_NOTEBOOK, VirtViewerNotebookClass)) | |
38 | ||
39 | #define VIRT_VIEWER_IS_NOTEBOOK(obj) \ | |
40 | (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIRT_VIEWER_TYPE_NOTEBOOK)) | |
41 | ||
42 | #define VIRT_VIEWER_IS_NOTEBOOK_CLASS(klass) \ | |
43 | (G_TYPE_CHECK_CLASS_TYPE ((klass), VIRT_VIEWER_TYPE_NOTEBOOK)) | |
44 | ||
45 | #define VIRT_VIEWER_NOTEBOOK_GET_CLASS(obj) \ | |
46 | (G_TYPE_INSTANCE_GET_CLASS ((obj), VIRT_VIEWER_TYPE_NOTEBOOK, VirtViewerNotebookClass)) | |
47 | ||
48 | typedef struct _VirtViewerNotebookPrivate VirtViewerNotebookPrivate; | |
49 | ||
50 | typedef struct { | |
51 | GtkNotebook parent; | |
52 | VirtViewerNotebookPrivate *priv; | |
53 | } VirtViewerNotebook; | |
54 | ||
55 | typedef struct { | |
56 | GtkNotebookClass parent_class; | |
57 | } VirtViewerNotebookClass; | |
58 | ||
59 | GType virt_viewer_notebook_get_type (void); | |
60 | ||
61 | VirtViewerNotebook* virt_viewer_notebook_new (void); | |
62 | void virt_viewer_notebook_show_status_va(VirtViewerNotebook *self, const gchar *fmt, va_list args); | |
63 | void virt_viewer_notebook_show_status(VirtViewerNotebook *nb, const gchar *fmt, ...); | |
64 | void virt_viewer_notebook_show_display(VirtViewerNotebook *nb); | |
65 | ||
66 | G_END_DECLS | |
67 | ||
68 | #endif /* _VIRT_VIEWER_NOTEBOOK */ | |
69 | ||
70 | /* | |
71 | * Local variables: | |
72 | * c-indent-level: 8 | |
73 | * c-basic-offset: 8 | |
74 | * tab-width: 8 | |
75 | * indent-tabs-mode: t | |
76 | * End: | |
77 | */ |
232 | 232 | |
233 | 233 | if (SPICE_IS_DISPLAY_CHANNEL(channel)) { |
234 | 234 | GtkWidget *display; |
235 | if (id != 0) | |
236 | return; | |
237 | 235 | |
238 | 236 | g_signal_emit_by_name(session, "session-connected"); |
239 | 237 |
39 | 39 | #define VIRT_VIEWER_SESSION_SPICE_CLASS(klass) \ |
40 | 40 | (G_TYPE_CHECK_CLASS_CAST ((klass), VIRT_VIEWER_TYPE_SESSION_SPICE, VirtViewerSessionSpiceClass)) |
41 | 41 | |
42 | #define VIRT_IS_VIEWER_SESSION_SPICE(obj) \ | |
42 | #define VIRT_VIEWER_IS_SESSION_SPICE(obj) \ | |
43 | 43 | (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIRT_VIEWER_TYPE_SESSION_SPICE)) |
44 | 44 | |
45 | #define VIRT_IS_VIEWER_SESSION_SPICE_CLASS(klass) \ | |
45 | #define VIRT_VIEWER_IS_SESSION_SPICE_CLASS(klass) \ | |
46 | 46 | (G_TYPE_CHECK_CLASS_TYPE ((klass), VIRT_VIEWER_TYPE_SESSION_SPICE)) |
47 | 47 | |
48 | 48 | #define VIRT_VIEWER_SESSION_SPICE_GET_CLASS(obj) \ |
85 | 85 | { |
86 | 86 | GtkWidget *display = virt_viewer_display_vnc_new(session->priv->vnc); |
87 | 87 | g_signal_emit_by_name(session, "session-connected"); |
88 | virt_viewer_display_set_show_hint(VIRT_VIEWER_DISPLAY(display), | |
89 | VIRT_VIEWER_DISPLAY_SHOW_HINT_READY); | |
88 | 90 | virt_viewer_session_add_display(VIRT_VIEWER_SESSION(session), |
89 | 91 | VIRT_VIEWER_DISPLAY(display)); |
90 | 92 | } |
94 | 96 | VirtViewerSessionVnc *session) |
95 | 97 | { |
96 | 98 | g_signal_emit_by_name(session, "session-disconnected"); |
99 | /* TODO perhaps? */ | |
100 | /* virt_viewer_display_set_show_hint(VIRT_VIEWER_DISPLAY(session->priv->vnc), */ | |
101 | /* VIRT_VIEWER_DISPLAY_SHOW_HINT_HIDE); */ | |
97 | 102 | } |
98 | 103 | |
99 | 104 | static void |
38 | 38 | #define VIRT_VIEWER_SESSION_VNC_CLASS(klass) \ |
39 | 39 | (G_TYPE_CHECK_CLASS_CAST ((klass), VIRT_VIEWER_TYPE_SESSION_VNC, VirtViewerSessionVncClass)) |
40 | 40 | |
41 | #define VIRT_IS_VIEWER_SESSION_VNC(obj) \ | |
41 | #define VIRT_VIEWER_IS_SESSION_VNC(obj) \ | |
42 | 42 | (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIRT_VIEWER_TYPE_SESSION_VNC)) |
43 | 43 | |
44 | #define VIRT_IS_VIEWER_SESSION_VNC_CLASS(klass) \ | |
44 | #define VIRT_VIEWER_IS_SESSION_VNC_CLASS(klass) \ | |
45 | 45 | (G_TYPE_CHECK_CLASS_TYPE ((klass), VIRT_VIEWER_TYPE_SESSION_VNC)) |
46 | 46 | |
47 | 47 | #define VIRT_VIEWER_SESSION_VNC_GET_CLASS(obj) \ |
25 | 25 | #include <sys/types.h> |
26 | 26 | #include <sys/stat.h> |
27 | 27 | #include <unistd.h> |
28 | #include <string.h> | |
29 | #include <libxml/xpath.h> | |
30 | #include <libxml/uri.h> | |
28 | 31 | |
29 | 32 | #include "virt-viewer-util.h" |
30 | 33 | |
50 | 53 | return builder; |
51 | 54 | } |
52 | 55 | |
56 | int | |
57 | virt_viewer_util_extract_host(const char *uristr, | |
58 | char **scheme, | |
59 | char **host, | |
60 | char **transport, | |
61 | char **user, | |
62 | int *port) | |
63 | { | |
64 | xmlURIPtr uri; | |
65 | char *offset; | |
66 | ||
67 | if (uristr == NULL || | |
68 | !g_strcasecmp(uristr, "xen")) | |
69 | uristr = "xen:///"; | |
70 | ||
71 | uri = xmlParseURI(uristr); | |
72 | if (host) { | |
73 | if (!uri || !uri->server) | |
74 | *host = g_strdup("localhost"); | |
75 | else | |
76 | *host = g_strdup(uri->server); | |
77 | } | |
78 | ||
79 | if (user) { | |
80 | if (uri->user) | |
81 | *user = g_strdup(uri->user); | |
82 | else | |
83 | *user = NULL; | |
84 | } | |
85 | ||
86 | if (port) | |
87 | *port = uri->port; | |
88 | ||
89 | offset = strchr(uri->scheme, '+'); | |
90 | ||
91 | if (transport) { | |
92 | if (offset) | |
93 | *transport = g_strdup(offset+1); | |
94 | else | |
95 | *transport = NULL; | |
96 | } | |
97 | ||
98 | if (scheme) { | |
99 | if (offset) | |
100 | *scheme = g_strndup(uri->scheme, offset - uri->scheme); | |
101 | else | |
102 | *scheme = g_strdup(uri->scheme); | |
103 | } | |
104 | ||
105 | xmlFreeURI(uri); | |
106 | return 0; | |
107 | } | |
53 | 108 | |
54 | 109 | /* |
55 | 110 | * Local variables: |
32 | 32 | |
33 | 33 | |
34 | 34 | GtkBuilder *virt_viewer_util_load_ui(const char *name); |
35 | int virt_viewer_util_extract_host(const char *uristr, | |
36 | char **scheme, | |
37 | char **host, | |
38 | char **transport, | |
39 | char **user, | |
40 | int *port); | |
35 | 41 | |
36 | 42 | #endif |
0 | /* | |
1 | * Virt Viewer: A virtual machine console viewer | |
2 | * | |
3 | * Copyright (C) 2007-2009 Red Hat, | |
4 | * Copyright (C) 2009 Daniel P. Berrange | |
5 | * Copyright (C) 2010 Marc-André Lureau | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with this program; if not, write to the Free Software | |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 | * | |
21 | * Author: Daniel P. Berrange <berrange@redhat.com> | |
22 | */ | |
23 | ||
24 | #include <config.h> | |
25 | ||
26 | #include <gdk/gdkkeysyms.h> | |
27 | #include <gtk/gtk.h> | |
28 | #include <sys/types.h> | |
29 | #include <sys/stat.h> | |
30 | #include <stdlib.h> | |
31 | #include <string.h> | |
32 | #include <unistd.h> | |
33 | #include <locale.h> | |
34 | #include <glib/gprintf.h> | |
35 | #include <glib/gi18n.h> | |
36 | ||
37 | #include "virt-viewer-window.h" | |
38 | #include "virt-viewer-app.h" | |
39 | #include "virt-viewer-util.h" | |
40 | #include "view/autoDrawer.h" | |
41 | ||
42 | /* Signal handlers for main window (move in a VirtViewerMainWindow?) */ | |
43 | void virt_viewer_window_menu_view_zoom_out(GtkWidget *menu, VirtViewerWindow *self); | |
44 | void virt_viewer_window_menu_view_zoom_in(GtkWidget *menu, VirtViewerWindow *self); | |
45 | void virt_viewer_window_menu_view_zoom_reset(GtkWidget *menu, VirtViewerWindow *self); | |
46 | gboolean virt_viewer_window_delete(GtkWidget *src, void *dummy, VirtViewerWindow *self); | |
47 | void virt_viewer_window_menu_file_quit(GtkWidget *src, VirtViewerWindow *self); | |
48 | void virt_viewer_window_menu_help_about(GtkWidget *menu, VirtViewerWindow *self); | |
49 | void virt_viewer_window_menu_view_fullscreen(GtkWidget *menu, VirtViewerWindow *self); | |
50 | void virt_viewer_window_menu_view_resize(GtkWidget *menu, VirtViewerWindow *self); | |
51 | void virt_viewer_window_menu_send(GtkWidget *menu, VirtViewerWindow *self); | |
52 | void virt_viewer_window_menu_file_screenshot(GtkWidget *menu, VirtViewerWindow *self); | |
53 | ||
54 | /* Internal methods */ | |
55 | static void virt_viewer_window_enable_modifiers(VirtViewerWindow *self); | |
56 | static void virt_viewer_window_disable_modifiers(VirtViewerWindow *self); | |
57 | static void virt_viewer_window_resize(VirtViewerWindow *self); | |
58 | static void virt_viewer_window_toolbar_setup(VirtViewerWindow *self); | |
59 | ||
60 | G_DEFINE_TYPE (VirtViewerWindow, virt_viewer_window, G_TYPE_OBJECT) | |
61 | ||
62 | #define GET_PRIVATE(o) \ | |
63 | (G_TYPE_INSTANCE_GET_PRIVATE ((o), VIRT_VIEWER_TYPE_WINDOW, VirtViewerWindowPrivate)) | |
64 | ||
65 | enum { | |
66 | PROP_0, | |
67 | PROP_WINDOW, | |
68 | PROP_DISPLAY, | |
69 | PROP_SUBTITLE, | |
70 | PROP_CONTAINER, | |
71 | PROP_APP, | |
72 | }; | |
73 | ||
74 | enum menuNums { | |
75 | FILE_MENU, | |
76 | VIEW_MENU, | |
77 | SEND_KEY_MENU, | |
78 | HELP_MENU, | |
79 | LAST_MENU // sentinel | |
80 | }; | |
81 | ||
82 | struct _VirtViewerWindowPrivate { | |
83 | VirtViewerApp *app; | |
84 | GtkContainer *container; /* if any, then there is no window */ | |
85 | ||
86 | GtkBuilder *builder; | |
87 | GtkWidget *window; | |
88 | GtkWidget *layout; | |
89 | GtkWidget *toolbar; | |
90 | VirtViewerNotebook *notebook; | |
91 | VirtViewerDisplay *display; | |
92 | ||
93 | gboolean accel_enabled; | |
94 | GValue accel_setting; | |
95 | GSList *accel_list; | |
96 | int accel_menu_sig[LAST_MENU]; | |
97 | gboolean grabbed; | |
98 | gboolean before_saved; | |
99 | GdkRectangle before_fullscreen; | |
100 | ||
101 | gint zoomlevel; | |
102 | gboolean auto_resize; | |
103 | gboolean fullscreen; | |
104 | gchar *subtitle; | |
105 | }; | |
106 | ||
107 | #if GTK_CHECK_VERSION(3, 0, 0) | |
108 | #define GDK_Control_L GDK_KEY_Control_L | |
109 | #define GDK_Alt_L GDK_KEY_Alt_L | |
110 | #define GDK_Delete GDK_KEY_Delete | |
111 | #define GDK_BackSpace GDK_KEY_BackSpace | |
112 | #define GDK_Print GDK_KEY_Print | |
113 | #define GDK_F1 GDK_KEY_F1 | |
114 | #define GDK_F2 GDK_KEY_F2 | |
115 | #define GDK_F3 GDK_KEY_F3 | |
116 | #define GDK_F4 GDK_KEY_F4 | |
117 | #define GDK_F5 GDK_KEY_F5 | |
118 | #define GDK_F6 GDK_KEY_F6 | |
119 | #define GDK_F7 GDK_KEY_F7 | |
120 | #define GDK_F8 GDK_KEY_F8 | |
121 | #define GDK_F9 GDK_KEY_F9 | |
122 | #define GDK_F10 GDK_KEY_F10 | |
123 | #define GDK_F11 GDK_KEY_F11 | |
124 | #define GDK_F12 GDK_KEY_F12 | |
125 | #endif | |
126 | ||
127 | static void | |
128 | virt_viewer_window_get_property (GObject *object, guint property_id, | |
129 | GValue *value, GParamSpec *pspec) | |
130 | { | |
131 | VirtViewerWindowPrivate *priv = VIRT_VIEWER_WINDOW(object)->priv; | |
132 | ||
133 | switch (property_id) { | |
134 | case PROP_SUBTITLE: | |
135 | g_value_set_string(value, priv->subtitle); | |
136 | break; | |
137 | ||
138 | case PROP_WINDOW: | |
139 | g_value_set_object(value, priv->window); | |
140 | break; | |
141 | ||
142 | case PROP_DISPLAY: | |
143 | g_value_set_object(value, priv->display); | |
144 | break; | |
145 | ||
146 | case PROP_CONTAINER: | |
147 | g_value_set_object(value, priv->container); | |
148 | break; | |
149 | ||
150 | case PROP_APP: | |
151 | g_value_set_object(value, priv->app); | |
152 | break; | |
153 | ||
154 | default: | |
155 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); | |
156 | } | |
157 | } | |
158 | ||
159 | static void | |
160 | virt_viewer_window_set_property (GObject *object, guint property_id, | |
161 | const GValue *value, GParamSpec *pspec) | |
162 | { | |
163 | VirtViewerWindowPrivate *priv = VIRT_VIEWER_WINDOW(object)->priv; | |
164 | ||
165 | switch (property_id) { | |
166 | case PROP_SUBTITLE: | |
167 | g_free(priv->subtitle); | |
168 | priv->subtitle = g_value_dup_string(value); | |
169 | break; | |
170 | ||
171 | case PROP_CONTAINER: | |
172 | g_return_if_fail(priv->container == NULL); | |
173 | priv->container = g_value_dup_object(value); | |
174 | break; | |
175 | ||
176 | case PROP_APP: | |
177 | g_return_if_fail(priv->app == NULL); | |
178 | priv->app = g_value_dup_object(value); | |
179 | break; | |
180 | ||
181 | default: | |
182 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); | |
183 | } | |
184 | } | |
185 | ||
186 | static void | |
187 | virt_viewer_window_dispose (GObject *object) | |
188 | { | |
189 | VirtViewerWindowPrivate *priv = VIRT_VIEWER_WINDOW(object)->priv; | |
190 | G_OBJECT_CLASS (virt_viewer_window_parent_class)->dispose (object); | |
191 | ||
192 | if (priv->display) { | |
193 | g_object_unref(priv->display); | |
194 | priv->display = NULL; | |
195 | } | |
196 | ||
197 | if (priv->app) { | |
198 | g_object_unref(priv->app); | |
199 | priv->app = NULL; | |
200 | } | |
201 | ||
202 | g_free(priv->subtitle); | |
203 | priv->subtitle = NULL; | |
204 | } | |
205 | ||
206 | static void | |
207 | virt_viewer_window_class_init (VirtViewerWindowClass *klass) | |
208 | { | |
209 | GObjectClass *object_class = G_OBJECT_CLASS (klass); | |
210 | ||
211 | g_type_class_add_private (klass, sizeof (VirtViewerWindowPrivate)); | |
212 | ||
213 | object_class->get_property = virt_viewer_window_get_property; | |
214 | object_class->set_property = virt_viewer_window_set_property; | |
215 | object_class->dispose = virt_viewer_window_dispose; | |
216 | ||
217 | g_object_class_install_property(object_class, | |
218 | PROP_SUBTITLE, | |
219 | g_param_spec_string("subtitle", | |
220 | "Subtitle", | |
221 | "Window subtitle", | |
222 | "", | |
223 | G_PARAM_READABLE | | |
224 | G_PARAM_WRITABLE | | |
225 | G_PARAM_STATIC_STRINGS)); | |
226 | ||
227 | g_object_class_install_property(object_class, | |
228 | PROP_WINDOW, | |
229 | g_param_spec_object("window", | |
230 | "Window", | |
231 | "GtkWindow", | |
232 | GTK_TYPE_WIDGET, | |
233 | G_PARAM_READABLE | | |
234 | G_PARAM_STATIC_STRINGS)); | |
235 | ||
236 | g_object_class_install_property(object_class, | |
237 | PROP_DISPLAY, | |
238 | g_param_spec_object("display", | |
239 | "Display", | |
240 | "VirtDisplay", | |
241 | VIRT_VIEWER_TYPE_DISPLAY, | |
242 | G_PARAM_READABLE | | |
243 | G_PARAM_STATIC_STRINGS)); | |
244 | ||
245 | g_object_class_install_property(object_class, | |
246 | PROP_CONTAINER, | |
247 | g_param_spec_object("container", | |
248 | "Container", | |
249 | "Container widget", | |
250 | VIRT_VIEWER_TYPE_DISPLAY, | |
251 | G_PARAM_READABLE | | |
252 | G_PARAM_WRITABLE | | |
253 | G_PARAM_CONSTRUCT_ONLY | | |
254 | G_PARAM_STATIC_STRINGS)); | |
255 | ||
256 | g_object_class_install_property(object_class, | |
257 | PROP_APP, | |
258 | g_param_spec_object("app", | |
259 | "App", | |
260 | "VirtViewerApp", | |
261 | VIRT_VIEWER_TYPE_APP, | |
262 | G_PARAM_READABLE | | |
263 | G_PARAM_WRITABLE | | |
264 | G_PARAM_CONSTRUCT_ONLY | | |
265 | G_PARAM_STATIC_STRINGS)); | |
266 | } | |
267 | ||
268 | static void | |
269 | virt_viewer_window_init (VirtViewerWindow *self) | |
270 | { | |
271 | VirtViewerWindowPrivate *priv; | |
272 | GtkWidget *vbox; | |
273 | GtkWidget *menu; | |
274 | GdkColor color; | |
275 | GSList *accels; | |
276 | ||
277 | self->priv = GET_PRIVATE(self); | |
278 | priv = self->priv; | |
279 | ||
280 | priv->auto_resize = TRUE; | |
281 | g_value_init(&priv->accel_setting, G_TYPE_STRING); | |
282 | ||
283 | priv->notebook = virt_viewer_notebook_new(); | |
284 | priv->builder = virt_viewer_util_load_ui("virt-viewer.xml"); | |
285 | ||
286 | menu = GTK_WIDGET(gtk_builder_get_object(priv->builder, "menu-view-resize")); | |
287 | gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE); | |
288 | ||
289 | gtk_builder_connect_signals(priv->builder, self); | |
290 | ||
291 | vbox = GTK_WIDGET(gtk_builder_get_object(priv->builder, "viewer-box")); | |
292 | virt_viewer_window_toolbar_setup(self); | |
293 | ||
294 | gtk_box_pack_end(GTK_BOX(vbox), priv->layout, TRUE, TRUE, 0); | |
295 | gdk_color_parse("black", &color); | |
296 | gtk_widget_modify_bg(priv->layout, GTK_STATE_NORMAL, &color); | |
297 | ||
298 | priv->window = GTK_WIDGET(gtk_builder_get_object(priv->builder, "viewer")); | |
299 | ||
300 | virt_viewer_window_update_title(self); | |
301 | gtk_window_set_resizable(GTK_WINDOW(priv->window), TRUE); | |
302 | #if GTK_CHECK_VERSION(3, 0, 0) | |
303 | gtk_window_set_has_resize_grip(GTK_WINDOW(priv->window), FALSE); | |
304 | #endif | |
305 | priv->accel_enabled = TRUE; | |
306 | ||
307 | accels = gtk_accel_groups_from_object(G_OBJECT(priv->window)); | |
308 | for ( ; accels ; accels = accels->next) { | |
309 | priv->accel_list = g_slist_append(priv->accel_list, accels->data); | |
310 | g_object_ref(G_OBJECT(accels->data)); | |
311 | } | |
312 | } | |
313 | ||
314 | static void | |
315 | virt_viewer_window_desktop_resize(VirtViewerDisplay *display G_GNUC_UNUSED, | |
316 | VirtViewerWindow *self) | |
317 | { | |
318 | VirtViewerWindowPrivate *priv = self->priv; | |
319 | if (priv->auto_resize && priv->window && !priv->fullscreen) | |
320 | virt_viewer_window_resize(self); | |
321 | } | |
322 | ||
323 | ||
324 | void | |
325 | virt_viewer_window_menu_view_zoom_out(GtkWidget *menu G_GNUC_UNUSED, | |
326 | VirtViewerWindow *self) | |
327 | { | |
328 | VirtViewerWindowPrivate *priv = self->priv; | |
329 | ||
330 | if (priv->zoomlevel > 10) | |
331 | priv->zoomlevel -= 10; | |
332 | ||
333 | if (!priv->display) | |
334 | return; | |
335 | ||
336 | gtk_window_resize(GTK_WINDOW(priv->window), 1, 1); | |
337 | if (priv->display) | |
338 | virt_viewer_display_set_zoom_level(VIRT_VIEWER_DISPLAY(priv->display), priv->zoomlevel); | |
339 | } | |
340 | ||
341 | void | |
342 | virt_viewer_window_menu_view_zoom_in(GtkWidget *menu G_GNUC_UNUSED, | |
343 | VirtViewerWindow *self) | |
344 | { | |
345 | VirtViewerWindowPrivate *priv = self->priv; | |
346 | ||
347 | if (priv->zoomlevel < 400) | |
348 | priv->zoomlevel += 10; | |
349 | ||
350 | if (!priv->display) | |
351 | return; | |
352 | ||
353 | gtk_window_resize(GTK_WINDOW(priv->window), 1, 1); | |
354 | if (priv->display) | |
355 | virt_viewer_display_set_zoom_level(VIRT_VIEWER_DISPLAY(priv->display), priv->zoomlevel); | |
356 | } | |
357 | ||
358 | void | |
359 | virt_viewer_window_menu_view_zoom_reset(GtkWidget *menu G_GNUC_UNUSED, | |
360 | VirtViewerWindow *self) | |
361 | { | |
362 | VirtViewerWindowPrivate *priv = self->priv; | |
363 | gtk_window_resize(GTK_WINDOW(priv->window), 1, 1); | |
364 | priv->zoomlevel = 100; | |
365 | ||
366 | if (priv->display) | |
367 | virt_viewer_display_set_zoom_level(VIRT_VIEWER_DISPLAY(priv->display), priv->zoomlevel); | |
368 | } | |
369 | ||
370 | /* | |
371 | * This code attempts to resize the top level window to be large enough | |
372 | * to contain the entire display desktop at 1:1 ratio. If the local desktop | |
373 | * isn't large enough that it goes as large as possible and lets the display | |
374 | * scale down to fit, maintaining aspect ratio | |
375 | */ | |
376 | static void | |
377 | virt_viewer_window_resize(VirtViewerWindow *self) | |
378 | { | |
379 | GdkRectangle fullscreen; | |
380 | GdkScreen *screen; | |
381 | int width, height; | |
382 | double desktopAspect; | |
383 | double screenAspect; | |
384 | guint desktopWidth; | |
385 | guint desktopHeight; | |
386 | VirtViewerWindowPrivate *priv = self->priv; | |
387 | ||
388 | DEBUG_LOG("Preparing main window resize"); | |
389 | if (!priv->display) { | |
390 | DEBUG_LOG("Skipping inactive resize"); | |
391 | return; | |
392 | } | |
393 | ||
394 | gtk_window_resize(GTK_WINDOW(priv->window), 1, 1); | |
395 | ||
396 | virt_viewer_display_get_desktop_size(VIRT_VIEWER_DISPLAY(priv->display), | |
397 | &desktopWidth, &desktopHeight); | |
398 | ||
399 | screen = gtk_widget_get_screen(priv->window); | |
400 | gdk_screen_get_monitor_geometry(screen, | |
401 | gdk_screen_get_monitor_at_window | |
402 | (screen, gtk_widget_get_window(priv->window)), | |
403 | &fullscreen); | |
404 | ||
405 | desktopAspect = (double)desktopWidth / (double)desktopHeight; | |
406 | screenAspect = (double)(fullscreen.width - 128) / (double)(fullscreen.height - 128); | |
407 | ||
408 | if ((desktopWidth > (fullscreen.width - 128)) || | |
409 | (desktopHeight > (fullscreen.height - 128))) { | |
410 | /* Doesn't fit native res, so go as large as possible | |
411 | maintaining aspect ratio */ | |
412 | if (screenAspect > desktopAspect) { | |
413 | width = desktopHeight * desktopAspect; | |
414 | height = desktopHeight; | |
415 | } else { | |
416 | width = desktopWidth; | |
417 | height = desktopWidth / desktopAspect; | |
418 | } | |
419 | } else { | |
420 | width = desktopWidth; | |
421 | height = desktopHeight; | |
422 | } | |
423 | ||
424 | DEBUG_LOG("Decided todo %dx%d (desktop is %dx%d, fullscreen is %dx%d", | |
425 | width, height, desktopWidth, desktopHeight, | |
426 | fullscreen.width, fullscreen.height); | |
427 | ||
428 | virt_viewer_display_set_desktop_size(VIRT_VIEWER_DISPLAY(priv->display), | |
429 | width, height); | |
430 | } | |
431 | ||
432 | void | |
433 | virt_viewer_window_leave_fullscreen(VirtViewerWindow *self) | |
434 | { | |
435 | VirtViewerWindowPrivate *priv = self->priv; | |
436 | GtkWidget *menu = GTK_WIDGET(gtk_builder_get_object(priv->builder, "top-menu")); | |
437 | GtkCheckMenuItem *check = GTK_CHECK_MENU_ITEM(gtk_builder_get_object(priv->builder, "menu-view-fullscreen")); | |
438 | ||
439 | if (!priv->fullscreen) | |
440 | return; | |
441 | ||
442 | gtk_check_menu_item_set_active(check, FALSE); | |
443 | priv->fullscreen = FALSE; | |
444 | ViewAutoDrawer_SetActive(VIEW_AUTODRAWER(priv->layout), FALSE); | |
445 | gtk_widget_show(menu); | |
446 | gtk_widget_hide(priv->toolbar); | |
447 | gtk_window_unfullscreen(GTK_WINDOW(priv->window)); | |
448 | ||
449 | if (priv->before_saved) { | |
450 | gtk_window_move(GTK_WINDOW(priv->window), | |
451 | priv->before_fullscreen.x, | |
452 | priv->before_fullscreen.y); | |
453 | gtk_window_resize(GTK_WINDOW(priv->window), | |
454 | priv->before_fullscreen.width, | |
455 | priv->before_fullscreen.height); | |
456 | priv->before_saved = FALSE; | |
457 | } | |
458 | } | |
459 | ||
460 | void | |
461 | virt_viewer_window_enter_fullscreen(VirtViewerWindow *self, gboolean move, gint x, gint y) | |
462 | { | |
463 | VirtViewerWindowPrivate *priv = self->priv; | |
464 | GtkWidget *menu = GTK_WIDGET(gtk_builder_get_object(priv->builder, "top-menu")); | |
465 | GtkCheckMenuItem *check = GTK_CHECK_MENU_ITEM(gtk_builder_get_object(priv->builder, "menu-view-fullscreen")); | |
466 | ||
467 | if (!priv->before_saved) { | |
468 | gtk_window_get_position(GTK_WINDOW(priv->window), | |
469 | &priv->before_fullscreen.x, | |
470 | &priv->before_fullscreen.y); | |
471 | gtk_window_get_size(GTK_WINDOW(priv->window), | |
472 | &priv->before_fullscreen.width, | |
473 | &priv->before_fullscreen.height); | |
474 | priv->before_saved = TRUE; | |
475 | } | |
476 | ||
477 | if (!priv->fullscreen) { | |
478 | gtk_check_menu_item_set_active(check, TRUE); | |
479 | priv->fullscreen = TRUE; | |
480 | gtk_widget_hide(menu); | |
481 | gtk_widget_show(priv->toolbar); | |
482 | ViewAutoDrawer_SetActive(VIEW_AUTODRAWER(priv->layout), TRUE); | |
483 | ViewAutoDrawer_Close(VIEW_AUTODRAWER(priv->layout)); | |
484 | } | |
485 | ||
486 | if (move) | |
487 | gtk_window_move(GTK_WINDOW(priv->window), x, y); | |
488 | ||
489 | gtk_window_fullscreen(GTK_WINDOW(priv->window)); | |
490 | } | |
491 | ||
492 | #define MAX_KEY_COMBO 3 | |
493 | struct keyComboDef { | |
494 | guint keys[MAX_KEY_COMBO]; | |
495 | guint nkeys; | |
496 | const char *label; | |
497 | }; | |
498 | ||
499 | static const struct keyComboDef keyCombos[] = { | |
500 | { { GDK_Control_L, GDK_Alt_L, GDK_Delete }, 3, "Ctrl+Alt+_Del"}, | |
501 | { { GDK_Control_L, GDK_Alt_L, GDK_BackSpace }, 3, "Ctrl+Alt+_Backspace"}, | |
502 | { {}, 0, "" }, | |
503 | { { GDK_Control_L, GDK_Alt_L, GDK_F1 }, 3, "Ctrl+Alt+F_1"}, | |
504 | { { GDK_Control_L, GDK_Alt_L, GDK_F2 }, 3, "Ctrl+Alt+F_2"}, | |
505 | { { GDK_Control_L, GDK_Alt_L, GDK_F3 }, 3, "Ctrl+Alt+F_3"}, | |
506 | { { GDK_Control_L, GDK_Alt_L, GDK_F4 }, 3, "Ctrl+Alt+F_4"}, | |
507 | { { GDK_Control_L, GDK_Alt_L, GDK_F5 }, 3, "Ctrl+Alt+F_5"}, | |
508 | { { GDK_Control_L, GDK_Alt_L, GDK_F6 }, 3, "Ctrl+Alt+F_6"}, | |
509 | { { GDK_Control_L, GDK_Alt_L, GDK_F7 }, 3, "Ctrl+Alt+F_7"}, | |
510 | { { GDK_Control_L, GDK_Alt_L, GDK_F8 }, 3, "Ctrl+Alt+F_8"}, | |
511 | { { GDK_Control_L, GDK_Alt_L, GDK_F5 }, 3, "Ctrl+Alt+F_9"}, | |
512 | { { GDK_Control_L, GDK_Alt_L, GDK_F6 }, 3, "Ctrl+Alt+F1_0"}, | |
513 | { { GDK_Control_L, GDK_Alt_L, GDK_F7 }, 3, "Ctrl+Alt+F11"}, | |
514 | { { GDK_Control_L, GDK_Alt_L, GDK_F8 }, 3, "Ctrl+Alt+F12"}, | |
515 | { {}, 0, "" }, | |
516 | { { GDK_Print }, 1, "_PrintScreen"}, | |
517 | }; | |
518 | ||
519 | void | |
520 | virt_viewer_window_menu_send(GtkWidget *menu G_GNUC_UNUSED, | |
521 | VirtViewerWindow *self) | |
522 | { | |
523 | int i; | |
524 | GtkWidget *label = gtk_bin_get_child(GTK_BIN(menu)); | |
525 | const char *text = gtk_label_get_label(GTK_LABEL(label)); | |
526 | VirtViewerWindowPrivate *priv = self->priv; | |
527 | ||
528 | for (i = 0 ; i < G_N_ELEMENTS(keyCombos) ; i++) { | |
529 | if (!strcmp(text, keyCombos[i].label)) { | |
530 | DEBUG_LOG("Sending key combo %s", gtk_label_get_text(GTK_LABEL(label))); | |
531 | virt_viewer_display_send_keys(VIRT_VIEWER_DISPLAY(priv->display), | |
532 | keyCombos[i].keys, | |
533 | keyCombos[i].nkeys); | |
534 | return; | |
535 | } | |
536 | } | |
537 | DEBUG_LOG("Failed to find key combo %s", gtk_label_get_text(GTK_LABEL(label))); | |
538 | } | |
539 | ||
540 | static gboolean | |
541 | virt_viewer_window_ignore_accel(GtkWidget *menu G_GNUC_UNUSED, | |
542 | VirtViewerWindow *self G_GNUC_UNUSED) | |
543 | { | |
544 | /* ignore accelerator */ | |
545 | return TRUE; | |
546 | } | |
547 | ||
548 | static const char * const menuNames[LAST_MENU] = { | |
549 | "menu-file", "menu-view", "menu-send", "menu-help" | |
550 | }; | |
551 | ||
552 | void | |
553 | virt_viewer_window_disable_modifiers(VirtViewerWindow *self) | |
554 | { | |
555 | GtkSettings *settings = gtk_settings_get_default(); | |
556 | VirtViewerWindowPrivate *priv = self->priv; | |
557 | GValue empty; | |
558 | GSList *accels; | |
559 | int i; | |
560 | ||
561 | if (!priv->window) | |
562 | return; | |
563 | ||
564 | if (!priv->accel_enabled) | |
565 | return; | |
566 | ||
567 | /* This stops F10 activating menu bar */ | |
568 | memset(&empty, 0, sizeof empty); | |
569 | g_value_init(&empty, G_TYPE_STRING); | |
570 | g_object_get_property(G_OBJECT(settings), "gtk-menu-bar-accel", &priv->accel_setting); | |
571 | g_object_set_property(G_OBJECT(settings), "gtk-menu-bar-accel", &empty); | |
572 | ||
573 | /* This stops global accelerators like Ctrl+Q == Quit */ | |
574 | for (accels = priv->accel_list ; accels ; accels = accels->next) { | |
575 | gtk_window_remove_accel_group(GTK_WINDOW(priv->window), accels->data); | |
576 | } | |
577 | ||
578 | /* This stops menu bar shortcuts like Alt+F == File */ | |
579 | for (i = 0 ; i < LAST_MENU ; i++) { | |
580 | GtkWidget *menu = GTK_WIDGET(gtk_builder_get_object(priv->builder, menuNames[i])); | |
581 | priv->accel_menu_sig[i] = | |
582 | g_signal_connect(menu, "mnemonic-activate", | |
583 | G_CALLBACK(virt_viewer_window_ignore_accel), self); | |
584 | } | |
585 | ||
586 | priv->accel_enabled = FALSE; | |
587 | } | |
588 | ||
589 | void | |
590 | virt_viewer_window_enable_modifiers(VirtViewerWindow *self) | |
591 | { | |
592 | GtkSettings *settings = gtk_settings_get_default(); | |
593 | VirtViewerWindowPrivate *priv = self->priv; | |
594 | GSList *accels; | |
595 | int i; | |
596 | ||
597 | if (!priv->window) | |
598 | return; | |
599 | ||
600 | if (priv->accel_enabled) | |
601 | return; | |
602 | ||
603 | /* This allows F10 activating menu bar */ | |
604 | g_object_set_property(G_OBJECT(settings), "gtk-menu-bar-accel", &priv->accel_setting); | |
605 | ||
606 | /* This allows global accelerators like Ctrl+Q == Quit */ | |
607 | for (accels = priv->accel_list ; accels ; accels = accels->next) { | |
608 | gtk_window_add_accel_group(GTK_WINDOW(priv->window), accels->data); | |
609 | } | |
610 | ||
611 | /* This allows menu bar shortcuts like Alt+F == File */ | |
612 | for (i = 0 ; i < LAST_MENU ; i++) { | |
613 | GtkWidget *menu = GTK_WIDGET(gtk_builder_get_object(priv->builder, menuNames[i])); | |
614 | g_signal_handler_disconnect(menu, priv->accel_menu_sig[i]); | |
615 | } | |
616 | ||
617 | priv->accel_enabled = TRUE; | |
618 | } | |
619 | ||
620 | ||
621 | gboolean | |
622 | virt_viewer_window_delete(GtkWidget *src G_GNUC_UNUSED, | |
623 | void *dummy G_GNUC_UNUSED, | |
624 | VirtViewerWindow *self) | |
625 | { | |
626 | virt_viewer_app_window_set_visible(self->priv->app, self, FALSE); | |
627 | return TRUE; | |
628 | } | |
629 | ||
630 | ||
631 | void | |
632 | virt_viewer_window_menu_file_quit(GtkWidget *src G_GNUC_UNUSED, | |
633 | VirtViewerWindow *self) | |
634 | { | |
635 | virt_viewer_app_quit(self->priv->app); | |
636 | } | |
637 | ||
638 | ||
639 | static void | |
640 | virt_viewer_window_toolbar_leave_fullscreen(GtkWidget *button G_GNUC_UNUSED, | |
641 | VirtViewerWindow *self) | |
642 | { | |
643 | g_object_set(self->priv->app, "fullscreen", FALSE, NULL); | |
644 | } | |
645 | ||
646 | ||
647 | void | |
648 | virt_viewer_window_menu_view_fullscreen(GtkWidget *menu, | |
649 | VirtViewerWindow *self) | |
650 | { | |
651 | gboolean fullscreen = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu)); | |
652 | ||
653 | g_object_set(self->priv->app, "fullscreen", fullscreen, NULL); | |
654 | } | |
655 | ||
656 | void | |
657 | virt_viewer_window_menu_view_resize(GtkWidget *menu, | |
658 | VirtViewerWindow *self) | |
659 | { | |
660 | VirtViewerWindowPrivate *priv = self->priv; | |
661 | ||
662 | if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu))) { | |
663 | priv->auto_resize = TRUE; | |
664 | if (!priv->fullscreen) | |
665 | virt_viewer_window_resize(self); | |
666 | } else { | |
667 | priv->auto_resize = FALSE; | |
668 | } | |
669 | } | |
670 | ||
671 | static void | |
672 | virt_viewer_window_save_screenshot(VirtViewerWindow *self, | |
673 | const char *file) | |
674 | { | |
675 | VirtViewerWindowPrivate *priv = self->priv; | |
676 | GdkPixbuf *pix = virt_viewer_display_get_pixbuf(VIRT_VIEWER_DISPLAY(priv->display)); | |
677 | ||
678 | gdk_pixbuf_save(pix, file, "png", NULL, | |
679 | "tEXt::Generator App", PACKAGE, NULL); | |
680 | gdk_pixbuf_unref(pix); | |
681 | } | |
682 | ||
683 | void | |
684 | virt_viewer_window_menu_file_screenshot(GtkWidget *menu G_GNUC_UNUSED, | |
685 | VirtViewerWindow *self) | |
686 | { | |
687 | GtkWidget *dialog; | |
688 | VirtViewerWindowPrivate *priv = self->priv; | |
689 | ||
690 | g_return_if_fail(priv->display != NULL); | |
691 | ||
692 | dialog = gtk_file_chooser_dialog_new ("Save screenshot", | |
693 | NULL, | |
694 | GTK_FILE_CHOOSER_ACTION_SAVE, | |
695 | GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, | |
696 | GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, | |
697 | NULL); | |
698 | gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE); | |
699 | ||
700 | //gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), default_folder_for_saving); | |
701 | //gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), "Screenshot"); | |
702 | ||
703 | if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { | |
704 | char *filename; | |
705 | ||
706 | filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); | |
707 | virt_viewer_window_save_screenshot(self, filename); | |
708 | g_free (filename); | |
709 | } | |
710 | ||
711 | gtk_widget_destroy (dialog); | |
712 | } | |
713 | ||
714 | void | |
715 | virt_viewer_window_menu_help_about(GtkWidget *menu G_GNUC_UNUSED, | |
716 | VirtViewerWindow *self) | |
717 | { | |
718 | GtkBuilder *about = virt_viewer_util_load_ui("virt-viewer-about.xml"); | |
719 | ||
720 | GtkWidget *dialog = GTK_WIDGET(gtk_builder_get_object(about, "about")); | |
721 | gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), VERSION); | |
722 | ||
723 | gtk_builder_connect_signals(about, self); | |
724 | ||
725 | gtk_widget_show_all(dialog); | |
726 | ||
727 | g_object_unref(G_OBJECT(about)); | |
728 | } | |
729 | ||
730 | ||
731 | static void | |
732 | virt_viewer_window_toolbar_setup(VirtViewerWindow *self) | |
733 | { | |
734 | GtkWidget *button; | |
735 | VirtViewerWindowPrivate *priv = self->priv; | |
736 | ||
737 | priv->toolbar = gtk_toolbar_new(); | |
738 | gtk_toolbar_set_show_arrow(GTK_TOOLBAR(priv->toolbar), FALSE); | |
739 | gtk_widget_set_no_show_all(priv->toolbar, TRUE); | |
740 | gtk_toolbar_set_style(GTK_TOOLBAR(priv->toolbar), GTK_TOOLBAR_BOTH_HORIZ); | |
741 | ||
742 | /* Close connection */ | |
743 | button = GTK_WIDGET(gtk_tool_button_new_from_stock(GTK_STOCK_CLOSE)); | |
744 | gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(button), _("Disconnect")); | |
745 | gtk_widget_show(GTK_WIDGET(button)); | |
746 | gtk_toolbar_insert(GTK_TOOLBAR(priv->toolbar), GTK_TOOL_ITEM (button), 0); | |
747 | g_signal_connect(button, "clicked", G_CALLBACK(gtk_main_quit), NULL); | |
748 | ||
749 | /* Leave fullscreen */ | |
750 | button = GTK_WIDGET(gtk_tool_button_new_from_stock(GTK_STOCK_LEAVE_FULLSCREEN)); | |
751 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(button), _("Leave fullscreen")); | |
752 | gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(button), _("Leave fullscreen")); | |
753 | gtk_tool_item_set_is_important(GTK_TOOL_ITEM(button), TRUE); | |
754 | gtk_widget_show(GTK_WIDGET(button)); | |
755 | gtk_toolbar_insert(GTK_TOOLBAR(priv->toolbar), GTK_TOOL_ITEM(button), 0); | |
756 | g_signal_connect(button, "clicked", G_CALLBACK(virt_viewer_window_toolbar_leave_fullscreen), self); | |
757 | ||
758 | priv->layout = ViewAutoDrawer_New(); | |
759 | ||
760 | ViewAutoDrawer_SetActive(VIEW_AUTODRAWER(priv->layout), FALSE); | |
761 | ViewOvBox_SetOver(VIEW_OV_BOX(priv->layout), priv->toolbar); | |
762 | ViewOvBox_SetUnder(VIEW_OV_BOX(priv->layout), GTK_WIDGET(priv->notebook)); | |
763 | ViewAutoDrawer_SetOffset(VIEW_AUTODRAWER(priv->layout), -1); | |
764 | ViewAutoDrawer_SetFill(VIEW_AUTODRAWER(priv->layout), FALSE); | |
765 | ViewAutoDrawer_SetOverlapPixels(VIEW_AUTODRAWER(priv->layout), 1); | |
766 | ViewAutoDrawer_SetNoOverlapPixels(VIEW_AUTODRAWER(priv->layout), 0); | |
767 | gtk_widget_show(priv->layout); | |
768 | } | |
769 | ||
770 | VirtViewerNotebook* | |
771 | virt_viewer_window_get_notebook (VirtViewerWindow *self) | |
772 | { | |
773 | return VIRT_VIEWER_NOTEBOOK(self->priv->notebook); | |
774 | } | |
775 | ||
776 | GtkWindow* | |
777 | virt_viewer_window_get_window (VirtViewerWindow *self) | |
778 | { | |
779 | return GTK_WINDOW(self->priv->window); | |
780 | } | |
781 | ||
782 | static void | |
783 | virt_viewer_window_pointer_grab(VirtViewerDisplay *display G_GNUC_UNUSED, | |
784 | VirtViewerWindow *self) | |
785 | { | |
786 | VirtViewerWindowPrivate *priv = self->priv; | |
787 | ||
788 | priv->grabbed = TRUE; | |
789 | virt_viewer_window_update_title(self); | |
790 | } | |
791 | ||
792 | static void | |
793 | virt_viewer_window_pointer_ungrab(VirtViewerDisplay *display G_GNUC_UNUSED, | |
794 | VirtViewerWindow *self) | |
795 | { | |
796 | VirtViewerWindowPrivate *priv = self->priv; | |
797 | ||
798 | priv->grabbed = FALSE; | |
799 | virt_viewer_window_update_title(self); | |
800 | } | |
801 | ||
802 | static void | |
803 | virt_viewer_window_keyboard_grab(VirtViewerDisplay *display G_GNUC_UNUSED, | |
804 | VirtViewerWindow *self) | |
805 | { | |
806 | virt_viewer_window_disable_modifiers(self); | |
807 | } | |
808 | ||
809 | static void | |
810 | virt_viewer_window_keyboard_ungrab(VirtViewerDisplay *display G_GNUC_UNUSED, | |
811 | VirtViewerWindow *self) | |
812 | { | |
813 | virt_viewer_window_enable_modifiers(self); | |
814 | } | |
815 | ||
816 | void | |
817 | virt_viewer_window_update_title(VirtViewerWindow *self) | |
818 | { | |
819 | VirtViewerWindowPrivate *priv = self->priv; | |
820 | char *title; | |
821 | const char *subtitle; | |
822 | ||
823 | if (priv->grabbed) | |
824 | subtitle = "(Press Ctrl+Alt to release pointer) "; | |
825 | else | |
826 | subtitle = ""; | |
827 | ||
828 | if (priv->subtitle) | |
829 | title = g_strdup_printf("%s%s - Virt Viewer", | |
830 | subtitle, priv->subtitle); | |
831 | else | |
832 | title = g_strdup("Virt Viewer"); | |
833 | ||
834 | gtk_window_set_title(GTK_WINDOW(priv->window), title); | |
835 | ||
836 | g_free(title); | |
837 | } | |
838 | ||
839 | void | |
840 | virt_viewer_window_set_display(VirtViewerWindow *self, VirtViewerDisplay *display) | |
841 | { | |
842 | VirtViewerWindowPrivate *priv; | |
843 | ||
844 | g_return_if_fail(VIRT_VIEWER_IS_WINDOW(self)); | |
845 | g_return_if_fail(display == NULL || VIRT_VIEWER_IS_DISPLAY(display)); | |
846 | ||
847 | priv = self->priv; | |
848 | if (priv->display) { | |
849 | gtk_notebook_remove_page(GTK_NOTEBOOK(priv->notebook), 1); | |
850 | g_object_unref(priv->display); | |
851 | priv->display = NULL; | |
852 | } | |
853 | ||
854 | if (display != NULL) { | |
855 | priv->display = g_object_ref(display); | |
856 | ||
857 | gtk_notebook_append_page(GTK_NOTEBOOK(priv->notebook), GTK_WIDGET(display), NULL); | |
858 | if (gtk_bin_get_child(GTK_BIN(display))) | |
859 | gtk_widget_realize(GTK_WIDGET(gtk_bin_get_child(GTK_BIN(display)))); | |
860 | gtk_widget_show_all(GTK_WIDGET(display)); | |
861 | ||
862 | g_signal_connect(display, "display-pointer-grab", | |
863 | G_CALLBACK(virt_viewer_window_pointer_grab), self); | |
864 | g_signal_connect(display, "display-pointer-ungrab", | |
865 | G_CALLBACK(virt_viewer_window_pointer_ungrab), self); | |
866 | g_signal_connect(display, "display-keyboard-grab", | |
867 | G_CALLBACK(virt_viewer_window_keyboard_grab), self); | |
868 | g_signal_connect(display, "display-keyboard-ungrab", | |
869 | G_CALLBACK(virt_viewer_window_keyboard_ungrab), self); | |
870 | g_signal_connect(display, "display-desktop-resize", | |
871 | G_CALLBACK(virt_viewer_window_desktop_resize), self); | |
872 | } | |
873 | } | |
874 | ||
875 | void | |
876 | virt_viewer_window_set_zoom_level(VirtViewerWindow *self, gint zoom_level) | |
877 | { | |
878 | g_return_if_fail(VIRT_VIEWER_IS_WINDOW(self)); | |
879 | ||
880 | /* FIXME: turn into a dynamic property */ | |
881 | self->priv->zoomlevel = zoom_level; | |
882 | } | |
883 | ||
884 | GtkMenuItem* | |
885 | virt_viewer_window_get_menu_displays(VirtViewerWindow *self) | |
886 | { | |
887 | g_return_val_if_fail(VIRT_VIEWER_IS_WINDOW(self), NULL); | |
888 | return GTK_MENU_ITEM(gtk_builder_get_object(self->priv->builder, "menu-displays")); | |
889 | } | |
890 | ||
891 | /* | |
892 | * Local variables: | |
893 | * c-indent-level: 8 | |
894 | * c-basic-offset: 8 | |
895 | * tab-width: 8 | |
896 | * indent-tabs-mode: t | |
897 | * End: | |
898 | */ |
0 | /* | |
1 | * Virt Viewer: A virtual machine console viewer | |
2 | * | |
3 | * Copyright (C) 2007-2009 Red Hat, | |
4 | * Copyright (C) 2009 Daniel P. Berrange | |
5 | * Copyright (C) 2010 Marc-André Lureau | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with this program; if not, write to the Free Software | |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 | * | |
21 | * Author: Daniel P. Berrange <berrange@redhat.com> | |
22 | */ | |
23 | #ifndef _VIRT_VIEWER_WINDOW | |
24 | #define _VIRT_VIEWER_WINDOW | |
25 | ||
26 | #include <glib-object.h> | |
27 | #include "virt-viewer-notebook.h" | |
28 | #include "virt-viewer-display.h" | |
29 | ||
30 | G_BEGIN_DECLS | |
31 | ||
32 | #define VIRT_VIEWER_TYPE_WINDOW virt_viewer_window_get_type() | |
33 | ||
34 | #define VIRT_VIEWER_WINDOW(obj) \ | |
35 | (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIRT_VIEWER_TYPE_WINDOW, VirtViewerWindow)) | |
36 | ||
37 | #define VIRT_VIEWER_WINDOW_CLASS(klass) \ | |
38 | (G_TYPE_CHECK_CLASS_CAST ((klass), VIRT_VIEWER_TYPE_WINDOW, VirtViewerWindowClass)) | |
39 | ||
40 | #define VIRT_VIEWER_IS_WINDOW(obj) \ | |
41 | (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIRT_VIEWER_TYPE_WINDOW)) | |
42 | ||
43 | #define VIRT_VIEWER_IS_WINDOW_CLASS(klass) \ | |
44 | (G_TYPE_CHECK_CLASS_TYPE ((klass), VIRT_VIEWER_TYPE_WINDOW)) | |
45 | ||
46 | #define VIRT_VIEWER_WINDOW_GET_CLASS(obj) \ | |
47 | (G_TYPE_INSTANCE_GET_CLASS ((obj), VIRT_VIEWER_TYPE_WINDOW, VirtViewerWindowClass)) | |
48 | ||
49 | typedef struct _VirtViewerWindowPrivate VirtViewerWindowPrivate; | |
50 | ||
51 | typedef struct { | |
52 | GObject parent; | |
53 | VirtViewerWindowPrivate *priv; | |
54 | } VirtViewerWindow; | |
55 | ||
56 | typedef struct { | |
57 | GObjectClass parent_class; | |
58 | } VirtViewerWindowClass; | |
59 | ||
60 | GType virt_viewer_window_get_type (void); | |
61 | ||
62 | GtkWindow* virt_viewer_window_get_window (VirtViewerWindow* window); | |
63 | VirtViewerNotebook* virt_viewer_window_get_notebook (VirtViewerWindow* window); | |
64 | void virt_viewer_window_set_display(VirtViewerWindow *self, VirtViewerDisplay *display); | |
65 | void virt_viewer_window_update_title(VirtViewerWindow *self); | |
66 | void virt_viewer_window_set_zoom_level(VirtViewerWindow *self, gint zoom_level); | |
67 | void virt_viewer_window_leave_fullscreen(VirtViewerWindow *self); | |
68 | void virt_viewer_window_enter_fullscreen(VirtViewerWindow *self, gboolean move, gint x, gint y); | |
69 | GtkMenuItem *virt_viewer_window_get_menu_displays(VirtViewerWindow *self); | |
70 | ||
71 | G_END_DECLS | |
72 | ||
73 | #endif /* _VIRT_VIEWER_WINDOW */ | |
74 | /* | |
75 | * Local variables: | |
76 | * c-indent-level: 8 | |
77 | * c-basic-offset: 8 | |
78 | * tab-width: 8 | |
79 | * indent-tabs-mode: t | |
80 | * End: | |
81 | */ |
39 | 39 | #include <libxml/xpath.h> |
40 | 40 | #include <libxml/uri.h> |
41 | 41 | |
42 | ||
43 | #ifdef HAVE_SYS_SOCKET_H | |
44 | #include <sys/socket.h> | |
45 | #endif | |
46 | ||
47 | #ifdef HAVE_SYS_UN_H | |
48 | #include <sys/un.h> | |
49 | #endif | |
50 | ||
51 | #ifdef HAVE_WINDOWS_H | |
52 | #include <windows.h> | |
53 | #endif | |
54 | ||
55 | 42 | #include "virt-viewer.h" |
43 | #include "virt-viewer-app.h" | |
56 | 44 | #include "virt-viewer-events.h" |
57 | 45 | #include "virt-viewer-auth.h" |
58 | #include "virt-viewer-session-vnc.h" | |
59 | ||
60 | #ifdef HAVE_SPICE_GTK | |
61 | #include "virt-viewer-session-spice.h" | |
62 | #endif | |
63 | ||
64 | #include "view/autoDrawer.h" | |
65 | ||
66 | gboolean doDebug = FALSE; | |
67 | ||
68 | /* Signal handlers for main window */ | |
69 | void virt_viewer_menu_view_zoom_out(GtkWidget *menu, VirtViewer *viewer); | |
70 | void virt_viewer_menu_view_zoom_in(GtkWidget *menu, VirtViewer *viewer); | |
71 | void virt_viewer_menu_view_zoom_reset(GtkWidget *menu, VirtViewer *viewer); | |
72 | void virt_viewer_delete(GtkWidget *src, void *dummy, VirtViewer *viewer); | |
73 | void virt_viewer_menu_file_quit(GtkWidget *src, VirtViewer *viewer); | |
74 | void virt_viewer_menu_help_about(GtkWidget *menu, VirtViewer *viewer); | |
75 | void virt_viewer_menu_view_fullscreen(GtkWidget *menu, VirtViewer *viewer); | |
76 | void virt_viewer_menu_view_resize(GtkWidget *menu, VirtViewer *viewer); | |
77 | void virt_viewer_menu_send(GtkWidget *menu, VirtViewer *viewer); | |
78 | void virt_viewer_menu_file_screenshot(GtkWidget *menu, VirtViewer *viewer); | |
79 | ||
80 | /* Signal handlers for about dialog */ | |
81 | void virt_viewer_about_close(GtkWidget *dialog, VirtViewer *viewer); | |
82 | void virt_viewer_about_delete(GtkWidget *dialog, void *dummy, VirtViewer *viewer); | |
83 | ||
84 | ||
85 | /* Internal methods */ | |
86 | static void virt_viewer_connected(VirtViewerSession *session, | |
87 | VirtViewer *viewer); | |
88 | static void virt_viewer_initialized(VirtViewerSession *session, | |
89 | VirtViewer *viewer); | |
90 | static void virt_viewer_disconnected(VirtViewerSession *session, | |
91 | VirtViewer *viewer); | |
92 | static void virt_viewer_auth_refused(VirtViewerSession *session, | |
93 | const char *msg, | |
94 | VirtViewer *viewer); | |
95 | static void virt_viewer_auth_failed(VirtViewerSession *session, | |
96 | const char *msg, | |
97 | VirtViewer *viewer); | |
98 | ||
99 | static void virt_viewer_server_cut_text(VirtViewerSession *session, | |
100 | const gchar *text, | |
101 | VirtViewer *viewer); | |
102 | static void virt_viewer_bell(VirtViewerSession *session, | |
103 | VirtViewer *viewer); | |
104 | static void virt_viewer_enable_modifiers(VirtViewer *viewer); | |
105 | static void virt_viewer_disable_modifiers(VirtViewer *viewer); | |
106 | static void virt_viewer_resize_main_window(VirtViewer *viewer); | |
107 | ||
108 | static void virt_viewer_set_status(VirtViewer *viewer, const char *text); | |
109 | static void virt_viewer_set_title(VirtViewer *viewer, gboolean grabbed); | |
110 | static void virt_viewer_channel_open(VirtViewerSession *session, | |
111 | VirtViewerSessionChannel *channel, | |
112 | VirtViewer *viewer); | |
113 | static void virt_viewer_quit(VirtViewer *viewer); | |
114 | ||
115 | static void virt_viewer_simple_message_dialog(GtkWidget *window, const char *fmt, ...); | |
116 | ||
117 | ||
118 | #if GTK_CHECK_VERSION(3, 0, 0) | |
119 | #define GDK_Control_L GDK_KEY_Control_L | |
120 | #define GDK_Alt_L GDK_KEY_Alt_L | |
121 | #define GDK_Delete GDK_KEY_Delete | |
122 | #define GDK_BackSpace GDK_KEY_BackSpace | |
123 | #define GDK_Print GDK_KEY_Print | |
124 | #define GDK_F1 GDK_KEY_F1 | |
125 | #define GDK_F2 GDK_KEY_F2 | |
126 | #define GDK_F3 GDK_KEY_F3 | |
127 | #define GDK_F4 GDK_KEY_F4 | |
128 | #define GDK_F5 GDK_KEY_F5 | |
129 | #define GDK_F6 GDK_KEY_F6 | |
130 | #define GDK_F7 GDK_KEY_F7 | |
131 | #define GDK_F8 GDK_KEY_F8 | |
132 | #define GDK_F9 GDK_KEY_F9 | |
133 | #define GDK_F10 GDK_KEY_F10 | |
134 | #define GDK_F11 GDK_KEY_F11 | |
135 | #define GDK_F12 GDK_KEY_F12 | |
136 | #endif | |
137 | ||
138 | enum menuNums { | |
139 | FILE_MENU, | |
140 | VIEW_MENU, | |
141 | SEND_KEY_MENU, | |
142 | HELP_MENU, | |
143 | LAST_MENU // sentinel | |
144 | }; | |
145 | ||
146 | struct _VirtViewer { | |
46 | ||
47 | struct _VirtViewerPrivate { | |
147 | 48 | char *uri; |
148 | 49 | virConnectPtr conn; |
149 | 50 | char *domkey; |
150 | 51 | char *domtitle; |
151 | ||
152 | GtkBuilder *builder; | |
153 | GtkWidget *window; | |
154 | GtkWidget *container; | |
155 | ||
156 | GtkWidget *notebook; | |
157 | GtkWidget *status; | |
158 | ||
159 | GtkWidget *toolbar; | |
160 | GtkWidget *layout; | |
161 | ||
162 | char *pretty_address; | |
163 | ||
164 | gboolean autoResize; | |
165 | gboolean fullscreen; | |
166 | 52 | gboolean withEvents; |
167 | ||
168 | gboolean active; | |
169 | ||
170 | gboolean accelEnabled; | |
171 | GValue accelSetting; | |
172 | GSList *accelList; | |
173 | int accelMenuSig[LAST_MENU]; | |
174 | ||
175 | 53 | gboolean waitvm; |
176 | 54 | gboolean reconnect; |
177 | gboolean direct; | |
178 | gboolean verbose; | |
179 | gboolean authretry; | |
180 | gboolean connected; | |
181 | ||
182 | gchar *clipboard; | |
183 | ||
184 | GtkWidget *display; | |
185 | VirtViewerSession *session; | |
186 | ||
187 | gint zoomlevel; | |
188 | ||
189 | char *unixsock; | |
190 | char *ghost; | |
191 | char *gport; | |
192 | char *host; | |
193 | char *transport; | |
194 | char *user; | |
195 | int port; | |
196 | 55 | }; |
197 | 56 | |
198 | static const char * const menuNames[LAST_MENU] = { | |
199 | "menu-file", "menu-view", "menu-send", "menu-help" | |
200 | }; | |
201 | ||
202 | ||
203 | #define MAX_KEY_COMBO 3 | |
204 | struct keyComboDef { | |
205 | guint keys[MAX_KEY_COMBO]; | |
206 | guint nkeys; | |
207 | const char *label; | |
208 | }; | |
209 | ||
210 | static const struct keyComboDef keyCombos[] = { | |
211 | { { GDK_Control_L, GDK_Alt_L, GDK_Delete }, 3, "Ctrl+Alt+_Del"}, | |
212 | { { GDK_Control_L, GDK_Alt_L, GDK_BackSpace }, 3, "Ctrl+Alt+_Backspace"}, | |
213 | { {}, 0, "" }, | |
214 | { { GDK_Control_L, GDK_Alt_L, GDK_F1 }, 3, "Ctrl+Alt+F_1"}, | |
215 | { { GDK_Control_L, GDK_Alt_L, GDK_F2 }, 3, "Ctrl+Alt+F_2"}, | |
216 | { { GDK_Control_L, GDK_Alt_L, GDK_F3 }, 3, "Ctrl+Alt+F_3"}, | |
217 | { { GDK_Control_L, GDK_Alt_L, GDK_F4 }, 3, "Ctrl+Alt+F_4"}, | |
218 | { { GDK_Control_L, GDK_Alt_L, GDK_F5 }, 3, "Ctrl+Alt+F_5"}, | |
219 | { { GDK_Control_L, GDK_Alt_L, GDK_F6 }, 3, "Ctrl+Alt+F_6"}, | |
220 | { { GDK_Control_L, GDK_Alt_L, GDK_F7 }, 3, "Ctrl+Alt+F_7"}, | |
221 | { { GDK_Control_L, GDK_Alt_L, GDK_F8 }, 3, "Ctrl+Alt+F_8"}, | |
222 | { { GDK_Control_L, GDK_Alt_L, GDK_F5 }, 3, "Ctrl+Alt+F_9"}, | |
223 | { { GDK_Control_L, GDK_Alt_L, GDK_F6 }, 3, "Ctrl+Alt+F1_0"}, | |
224 | { { GDK_Control_L, GDK_Alt_L, GDK_F7 }, 3, "Ctrl+Alt+F11"}, | |
225 | { { GDK_Control_L, GDK_Alt_L, GDK_F8 }, 3, "Ctrl+Alt+F12"}, | |
226 | { {}, 0, "" }, | |
227 | { { GDK_Print }, 1, "_PrintScreen"}, | |
228 | }; | |
229 | ||
230 | ||
231 | static gboolean virt_viewer_connect_timer(void *opaque); | |
232 | static int virt_viewer_initial_connect(VirtViewer *viewer); | |
233 | ||
234 | ||
235 | void | |
236 | virt_viewer_simple_message_dialog(GtkWidget *window, | |
237 | const char *fmt, ...) | |
238 | { | |
239 | GtkWidget *dialog; | |
240 | char *msg; | |
241 | va_list vargs; | |
242 | ||
243 | va_start(vargs, fmt); | |
244 | ||
245 | msg = g_strdup_vprintf(fmt, vargs); | |
246 | ||
247 | va_end(vargs); | |
248 | ||
249 | dialog = gtk_message_dialog_new(GTK_WINDOW(window), | |
250 | GTK_DIALOG_MODAL | | |
251 | GTK_DIALOG_DESTROY_WITH_PARENT, | |
252 | GTK_MESSAGE_ERROR, | |
253 | GTK_BUTTONS_OK, | |
254 | "%s", | |
255 | msg); | |
256 | ||
257 | gtk_dialog_run(GTK_DIALOG(dialog)); | |
258 | ||
259 | gtk_widget_destroy(dialog); | |
260 | ||
261 | g_free(msg); | |
262 | } | |
263 | ||
264 | ||
265 | /* | |
266 | * This code attempts to resize the top level window to be large enough | |
267 | * to contain the entire display desktop at 1:1 ratio. If the local desktop | |
268 | * isn't large enough that it goes as large as possible and lets the display | |
269 | * scale down to fit, maintaining aspect ratio | |
270 | */ | |
271 | static void | |
272 | virt_viewer_resize_main_window(VirtViewer *viewer) | |
273 | { | |
274 | GdkRectangle fullscreen; | |
275 | GdkScreen *screen; | |
276 | int width, height; | |
277 | double desktopAspect; | |
278 | double screenAspect; | |
279 | guint desktopWidth; | |
280 | guint desktopHeight; | |
281 | ||
282 | DEBUG_LOG("Preparing main window resize"); | |
283 | if (!viewer->active) { | |
284 | DEBUG_LOG("Skipping inactive resize"); | |
285 | return; | |
286 | } | |
287 | ||
288 | gtk_window_resize(GTK_WINDOW(viewer->window), 1, 1); | |
289 | ||
290 | virt_viewer_display_get_desktop_size(VIRT_VIEWER_DISPLAY(viewer->display), | |
291 | &desktopWidth, &desktopHeight); | |
292 | ||
293 | screen = gtk_widget_get_screen(viewer->window); | |
294 | gdk_screen_get_monitor_geometry(screen, | |
295 | gdk_screen_get_monitor_at_window | |
296 | (screen, gtk_widget_get_window(viewer->window)), | |
297 | &fullscreen); | |
298 | ||
299 | desktopAspect = (double)desktopWidth / (double)desktopHeight; | |
300 | screenAspect = (double)(fullscreen.width - 128) / (double)(fullscreen.height - 128); | |
301 | ||
302 | if ((desktopWidth > (fullscreen.width - 128)) || | |
303 | (desktopHeight > (fullscreen.height - 128))) { | |
304 | /* Doesn't fit native res, so go as large as possible | |
305 | maintaining aspect ratio */ | |
306 | if (screenAspect > desktopAspect) { | |
307 | width = desktopHeight * desktopAspect; | |
308 | height = desktopHeight; | |
309 | } else { | |
310 | width = desktopWidth; | |
311 | height = desktopWidth / desktopAspect; | |
57 | G_DEFINE_TYPE (VirtViewer, virt_viewer, VIRT_VIEWER_TYPE_APP) | |
58 | #define GET_PRIVATE(o) \ | |
59 | (G_TYPE_INSTANCE_GET_PRIVATE ((o), VIRT_VIEWER_TYPE, VirtViewerPrivate)) | |
60 | ||
61 | static int virt_viewer_initial_connect(VirtViewerApp *self); | |
62 | static void virt_viewer_deactivated(VirtViewerApp *self); | |
63 | static gboolean virt_viewer_start(VirtViewerApp *self); | |
64 | ||
65 | static void | |
66 | virt_viewer_get_property (GObject *object, guint property_id, | |
67 | GValue *value G_GNUC_UNUSED, GParamSpec *pspec) | |
68 | { | |
69 | switch (property_id) { | |
70 | default: | |
71 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); | |
72 | } | |
73 | } | |
74 | ||
75 | static void | |
76 | virt_viewer_set_property (GObject *object, guint property_id, | |
77 | const GValue *value G_GNUC_UNUSED, GParamSpec *pspec) | |
78 | { | |
79 | switch (property_id) { | |
80 | default: | |
81 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); | |
82 | } | |
83 | } | |
84 | ||
85 | static void | |
86 | virt_viewer_dispose (GObject *object) | |
87 | { | |
88 | G_OBJECT_CLASS(virt_viewer_parent_class)->dispose (object); | |
89 | } | |
90 | ||
91 | static void | |
92 | virt_viewer_class_init (VirtViewerClass *klass) | |
93 | { | |
94 | GObjectClass *object_class = G_OBJECT_CLASS (klass); | |
95 | VirtViewerAppClass *app_class = VIRT_VIEWER_APP_CLASS (klass); | |
96 | ||
97 | g_type_class_add_private (klass, sizeof (VirtViewerPrivate)); | |
98 | ||
99 | object_class->get_property = virt_viewer_get_property; | |
100 | object_class->set_property = virt_viewer_set_property; | |
101 | object_class->dispose = virt_viewer_dispose; | |
102 | ||
103 | app_class->initial_connect = virt_viewer_initial_connect; | |
104 | app_class->deactivated = virt_viewer_deactivated; | |
105 | app_class->start = virt_viewer_start; | |
106 | } | |
107 | ||
108 | static void | |
109 | virt_viewer_init(VirtViewer *self) | |
110 | { | |
111 | self->priv = GET_PRIVATE(self); | |
112 | } | |
113 | ||
114 | static void | |
115 | virt_viewer_deactivated(VirtViewerApp *app) | |
116 | { | |
117 | VirtViewer *self = VIRT_VIEWER(app); | |
118 | VirtViewerPrivate *priv = self->priv; | |
119 | ||
120 | if (priv->reconnect) { | |
121 | if (!priv->withEvents) { | |
122 | DEBUG_LOG("No domain events, falling back to polling"); | |
123 | virt_viewer_app_start_reconnect_poll(app); | |
312 | 124 | } |
125 | ||
126 | virt_viewer_app_show_status(app, _("Waiting for guest domain to re-start")); | |
127 | virt_viewer_app_trace(app, "Guest %s display has disconnected, waiting to reconnect", priv->domkey); | |
313 | 128 | } else { |
314 | width = desktopWidth; | |
315 | height = desktopHeight; | |
316 | } | |
317 | ||
318 | DEBUG_LOG("Decided todo %dx%d (desktop is %dx%d, fullscreen is %dx%d", | |
319 | width, height, desktopWidth, desktopHeight, | |
320 | fullscreen.width, fullscreen.height); | |
321 | ||
322 | virt_viewer_display_set_desktop_size(VIRT_VIEWER_DISPLAY(viewer->display), | |
323 | width, height); | |
324 | } | |
325 | ||
326 | static void | |
327 | virt_viewer_desktop_resize(VirtViewerDisplay *display G_GNUC_UNUSED, | |
328 | VirtViewer *viewer) | |
329 | { | |
330 | if (viewer->autoResize && viewer->window && !viewer->fullscreen) | |
331 | virt_viewer_resize_main_window(viewer); | |
332 | } | |
333 | ||
334 | ||
335 | void | |
336 | virt_viewer_menu_view_zoom_out(GtkWidget *menu G_GNUC_UNUSED, | |
337 | VirtViewer *viewer) | |
338 | { | |
339 | gtk_window_resize(GTK_WINDOW(viewer->window), 1, 1); | |
340 | if (viewer->zoomlevel > 10) | |
341 | viewer->zoomlevel -= 10; | |
342 | ||
343 | if (viewer->display) | |
344 | virt_viewer_display_set_zoom_level(VIRT_VIEWER_DISPLAY(viewer->display), viewer->zoomlevel); | |
345 | } | |
346 | ||
347 | void | |
348 | virt_viewer_menu_view_zoom_in(GtkWidget *menu G_GNUC_UNUSED, | |
349 | VirtViewer *viewer) | |
350 | { | |
351 | gtk_window_resize(GTK_WINDOW(viewer->window), 1, 1); | |
352 | if (viewer->zoomlevel < 400) | |
353 | viewer->zoomlevel += 10; | |
354 | ||
355 | if (viewer->display) | |
356 | virt_viewer_display_set_zoom_level(VIRT_VIEWER_DISPLAY(viewer->display), viewer->zoomlevel); | |
357 | } | |
358 | ||
359 | void | |
360 | virt_viewer_menu_view_zoom_reset(GtkWidget *menu G_GNUC_UNUSED, | |
361 | VirtViewer *viewer) | |
362 | { | |
363 | gtk_window_resize(GTK_WINDOW(viewer->window), 1, 1); | |
364 | viewer->zoomlevel = 100; | |
365 | ||
366 | if (viewer->display) | |
367 | virt_viewer_display_set_zoom_level(VIRT_VIEWER_DISPLAY(viewer->display), viewer->zoomlevel); | |
368 | } | |
369 | ||
370 | void | |
371 | virt_viewer_set_title(VirtViewer *viewer, | |
372 | gboolean grabbed) | |
373 | { | |
374 | char *title; | |
375 | const char *subtitle; | |
376 | ||
377 | if (!viewer->window) | |
378 | return; | |
379 | ||
380 | if (grabbed) | |
381 | subtitle = "(Press Ctrl+Alt to release pointer) "; | |
382 | else | |
383 | subtitle = ""; | |
384 | ||
385 | if (viewer->domtitle) | |
386 | title = g_strdup_printf("%s%s - Virt Viewer", | |
387 | subtitle, viewer->domtitle); | |
388 | else | |
389 | title = g_strdup("Virt Viewer"); | |
390 | ||
391 | gtk_window_set_title(GTK_WINDOW(viewer->window), title); | |
392 | ||
393 | g_free(title); | |
394 | } | |
395 | ||
396 | static gboolean | |
397 | virt_viewer_ignore_accel(GtkWidget *menu G_GNUC_UNUSED, | |
398 | VirtViewer *viewer G_GNUC_UNUSED) | |
399 | { | |
400 | /* ignore accelerator */ | |
401 | return TRUE; | |
402 | } | |
403 | ||
404 | ||
405 | void | |
406 | virt_viewer_disable_modifiers(VirtViewer *viewer) | |
407 | { | |
408 | GtkSettings *settings = gtk_settings_get_default(); | |
409 | GValue empty; | |
410 | GSList *accels; | |
411 | int i; | |
412 | ||
413 | if (!viewer->window) | |
414 | return; | |
415 | ||
416 | if (!viewer->accelEnabled) | |
417 | return; | |
418 | ||
419 | /* This stops F10 activating menu bar */ | |
420 | memset(&empty, 0, sizeof empty); | |
421 | g_value_init(&empty, G_TYPE_STRING); | |
422 | g_object_get_property(G_OBJECT(settings), "gtk-menu-bar-accel", &viewer->accelSetting); | |
423 | g_object_set_property(G_OBJECT(settings), "gtk-menu-bar-accel", &empty); | |
424 | ||
425 | /* This stops global accelerators like Ctrl+Q == Quit */ | |
426 | for (accels = viewer->accelList ; accels ; accels = accels->next) { | |
427 | gtk_window_remove_accel_group(GTK_WINDOW(viewer->window), accels->data); | |
428 | } | |
429 | ||
430 | /* This stops menu bar shortcuts like Alt+F == File */ | |
431 | for (i = 0 ; i < LAST_MENU ; i++) { | |
432 | GtkWidget *menu = GTK_WIDGET(gtk_builder_get_object(viewer->builder, menuNames[i])); | |
433 | viewer->accelMenuSig[i] = | |
434 | g_signal_connect(menu, "mnemonic-activate", | |
435 | G_CALLBACK(virt_viewer_ignore_accel), viewer); | |
436 | } | |
437 | ||
438 | viewer->accelEnabled = FALSE; | |
439 | } | |
440 | ||
441 | ||
442 | void | |
443 | virt_viewer_enable_modifiers(VirtViewer *viewer) | |
444 | { | |
445 | GtkSettings *settings = gtk_settings_get_default(); | |
446 | GSList *accels; | |
447 | int i; | |
448 | ||
449 | if (!viewer->window) | |
450 | return; | |
451 | ||
452 | if (viewer->accelEnabled) | |
453 | return; | |
454 | ||
455 | /* This allows F10 activating menu bar */ | |
456 | g_object_set_property(G_OBJECT(settings), "gtk-menu-bar-accel", &viewer->accelSetting); | |
457 | ||
458 | /* This allows global accelerators like Ctrl+Q == Quit */ | |
459 | for (accels = viewer->accelList ; accels ; accels = accels->next) { | |
460 | gtk_window_add_accel_group(GTK_WINDOW(viewer->window), accels->data); | |
461 | } | |
462 | ||
463 | /* This allows menu bar shortcuts like Alt+F == File */ | |
464 | for (i = 0 ; i < LAST_MENU ; i++) { | |
465 | GtkWidget *menu = GTK_WIDGET(gtk_builder_get_object(viewer->builder, menuNames[i])); | |
466 | g_signal_handler_disconnect(menu, viewer->accelMenuSig[i]); | |
467 | } | |
468 | ||
469 | viewer->accelEnabled = TRUE; | |
470 | } | |
471 | ||
472 | void | |
473 | virt_viewer_quit(VirtViewer *viewer) | |
474 | { | |
475 | g_return_if_fail(viewer != NULL); | |
476 | ||
477 | if (viewer->session) | |
478 | virt_viewer_session_close(VIRT_VIEWER_SESSION(viewer->session)); | |
479 | gtk_main_quit(); | |
480 | } | |
481 | ||
482 | void | |
483 | virt_viewer_delete(GtkWidget *src G_GNUC_UNUSED, | |
484 | void *dummy G_GNUC_UNUSED, | |
485 | VirtViewer *viewer) | |
486 | { | |
487 | virt_viewer_quit(viewer); | |
488 | } | |
489 | ||
490 | void | |
491 | virt_viewer_menu_file_quit(GtkWidget *src G_GNUC_UNUSED, | |
492 | VirtViewer *viewer) | |
493 | { | |
494 | virt_viewer_quit(viewer); | |
495 | } | |
496 | ||
497 | ||
498 | static void | |
499 | virt_viewer_leave_fullscreen(VirtViewer *viewer) | |
500 | { | |
501 | GtkWidget *menu = GTK_WIDGET(gtk_builder_get_object(viewer->builder, "top-menu")); | |
502 | if (!viewer->fullscreen) | |
503 | return; | |
504 | viewer->fullscreen = FALSE; | |
505 | ViewAutoDrawer_SetActive(VIEW_AUTODRAWER(viewer->layout), FALSE); | |
506 | gtk_widget_show(menu); | |
507 | gtk_widget_hide(viewer->toolbar); | |
508 | gtk_window_unfullscreen(GTK_WINDOW(viewer->window)); | |
509 | if (viewer->autoResize) | |
510 | virt_viewer_resize_main_window(viewer); | |
511 | } | |
512 | ||
513 | static void | |
514 | virt_viewer_enter_fullscreen(VirtViewer *viewer) | |
515 | { | |
516 | GtkWidget *menu = GTK_WIDGET(gtk_builder_get_object(viewer->builder, "top-menu")); | |
517 | if (viewer->fullscreen) | |
518 | return; | |
519 | viewer->fullscreen = TRUE; | |
520 | gtk_widget_hide(menu); | |
521 | gtk_window_fullscreen(GTK_WINDOW(viewer->window)); | |
522 | gtk_widget_show(viewer->toolbar); | |
523 | ViewAutoDrawer_SetActive(VIEW_AUTODRAWER(viewer->layout), TRUE); | |
524 | } | |
525 | ||
526 | static gboolean | |
527 | window_state_cb(GtkWidget *widget G_GNUC_UNUSED, GdkEventWindowState *event, | |
528 | gpointer data) | |
529 | { | |
530 | VirtViewer *viewer = data; | |
531 | ||
532 | if (!(event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN)) | |
533 | return TRUE; | |
534 | ||
535 | if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) | |
536 | virt_viewer_enter_fullscreen(viewer); | |
537 | else | |
538 | virt_viewer_leave_fullscreen(viewer); | |
539 | ||
540 | return TRUE; | |
541 | } | |
542 | ||
543 | static void | |
544 | virt_viewer_toolbar_leave_fullscreen(GtkWidget *button G_GNUC_UNUSED, | |
545 | VirtViewer *viewer) | |
546 | { | |
547 | GtkWidget *menu = GTK_WIDGET(gtk_builder_get_object(viewer->builder, "menu-view-fullscreen")); | |
548 | ||
549 | gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), FALSE); | |
550 | virt_viewer_leave_fullscreen(viewer); | |
551 | } | |
552 | ||
553 | ||
554 | void | |
555 | virt_viewer_menu_view_fullscreen(GtkWidget *menu, | |
556 | VirtViewer *viewer) | |
557 | { | |
558 | if (!viewer->window) | |
559 | return; | |
560 | ||
561 | if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu))) { | |
562 | virt_viewer_enter_fullscreen(viewer); | |
563 | } else { | |
564 | virt_viewer_leave_fullscreen(viewer); | |
565 | } | |
566 | } | |
567 | ||
568 | void | |
569 | virt_viewer_menu_view_resize(GtkWidget *menu, | |
570 | VirtViewer *viewer) | |
571 | { | |
572 | if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu))) { | |
573 | viewer->autoResize = TRUE; | |
574 | if (!viewer->fullscreen) | |
575 | virt_viewer_resize_main_window(viewer); | |
576 | } else { | |
577 | viewer->autoResize = FALSE; | |
578 | } | |
579 | } | |
580 | ||
581 | void | |
582 | virt_viewer_menu_send(GtkWidget *menu G_GNUC_UNUSED, | |
583 | VirtViewer *viewer) | |
584 | { | |
585 | int i; | |
586 | GtkWidget *label = gtk_bin_get_child(GTK_BIN(menu)); | |
587 | const char *text = gtk_label_get_label(GTK_LABEL(label)); | |
588 | ||
589 | for (i = 0 ; i < G_N_ELEMENTS(keyCombos) ; i++) { | |
590 | if (!strcmp(text, keyCombos[i].label)) { | |
591 | DEBUG_LOG("Sending key combo %s", gtk_label_get_text(GTK_LABEL(label))); | |
592 | virt_viewer_display_send_keys(VIRT_VIEWER_DISPLAY(viewer->display), | |
593 | keyCombos[i].keys, | |
594 | keyCombos[i].nkeys); | |
595 | return; | |
596 | } | |
597 | } | |
598 | DEBUG_LOG("Failed to find key combo %s", gtk_label_get_text(GTK_LABEL(label))); | |
599 | } | |
600 | ||
601 | ||
602 | static void | |
603 | virt_viewer_save_screenshot(VirtViewer *viewer, | |
604 | const char *file) | |
605 | { | |
606 | GdkPixbuf *pix = virt_viewer_display_get_pixbuf(VIRT_VIEWER_DISPLAY(viewer->display)); | |
607 | gdk_pixbuf_save(pix, file, "png", NULL, | |
608 | "tEXt::Generator App", PACKAGE, NULL); | |
609 | gdk_pixbuf_unref(pix); | |
610 | } | |
611 | ||
612 | ||
613 | void | |
614 | virt_viewer_menu_file_screenshot(GtkWidget *menu G_GNUC_UNUSED, | |
615 | VirtViewer *viewer) | |
616 | { | |
617 | GtkWidget *dialog; | |
618 | ||
619 | g_return_if_fail(viewer->display != NULL); | |
620 | ||
621 | dialog = gtk_file_chooser_dialog_new ("Save screenshot", | |
622 | NULL, | |
623 | GTK_FILE_CHOOSER_ACTION_SAVE, | |
624 | GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, | |
625 | GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, | |
626 | NULL); | |
627 | gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE); | |
628 | ||
629 | //gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), default_folder_for_saving); | |
630 | //gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), "Screenshot"); | |
631 | ||
632 | if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { | |
633 | char *filename; | |
634 | ||
635 | filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); | |
636 | virt_viewer_save_screenshot(viewer, filename); | |
637 | g_free (filename); | |
638 | } | |
639 | ||
640 | gtk_widget_destroy (dialog); | |
641 | } | |
642 | ||
643 | void | |
644 | virt_viewer_about_close(GtkWidget *dialog, | |
645 | VirtViewer *viewer G_GNUC_UNUSED) | |
646 | { | |
647 | gtk_widget_hide(dialog); | |
648 | gtk_widget_destroy(dialog); | |
649 | } | |
650 | ||
651 | void | |
652 | virt_viewer_about_delete(GtkWidget *dialog, | |
653 | void *dummy G_GNUC_UNUSED, | |
654 | VirtViewer *viewer G_GNUC_UNUSED) | |
655 | { | |
656 | gtk_widget_hide(dialog); | |
657 | gtk_widget_destroy(dialog); | |
658 | } | |
659 | ||
660 | void | |
661 | virt_viewer_menu_help_about(GtkWidget *menu G_GNUC_UNUSED, | |
662 | VirtViewer *viewer) | |
663 | { | |
664 | GtkBuilder *about = virt_viewer_util_load_ui("virt-viewer-about.xml"); | |
665 | ||
666 | GtkWidget *dialog = GTK_WIDGET(gtk_builder_get_object(about, "about")); | |
667 | gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), VERSION); | |
668 | ||
669 | gtk_builder_connect_signals(about, viewer); | |
670 | ||
671 | gtk_widget_show_all(dialog); | |
672 | ||
673 | g_object_unref(G_OBJECT(about)); | |
674 | } | |
675 | ||
129 | VIRT_VIEWER_APP_CLASS(virt_viewer_parent_class)->deactivated(app); | |
130 | } | |
131 | } | |
676 | 132 | |
677 | 133 | static int |
678 | 134 | virt_viewer_parse_uuid(const char *name, |
718 | 174 | |
719 | 175 | |
720 | 176 | static virDomainPtr |
721 | virt_viewer_lookup_domain(VirtViewer *viewer) | |
177 | virt_viewer_lookup_domain(VirtViewer *self) | |
722 | 178 | { |
723 | 179 | char *end; |
724 | int id = strtol(viewer->domkey, &end, 10); | |
180 | VirtViewerPrivate *priv = self->priv; | |
181 | int id = strtol(priv->domkey, &end, 10); | |
725 | 182 | virDomainPtr dom = NULL; |
726 | 183 | unsigned char uuid[16]; |
727 | 184 | |
728 | 185 | if (id >= 0 && end && !*end) { |
729 | dom = virDomainLookupByID(viewer->conn, id); | |
730 | } | |
731 | if (!dom && virt_viewer_parse_uuid(viewer->domkey, uuid) == 0) { | |
732 | dom = virDomainLookupByUUID(viewer->conn, uuid); | |
186 | dom = virDomainLookupByID(priv->conn, id); | |
187 | } | |
188 | if (!dom && virt_viewer_parse_uuid(priv->domkey, uuid) == 0) { | |
189 | dom = virDomainLookupByUUID(priv->conn, uuid); | |
733 | 190 | } |
734 | 191 | if (!dom) { |
735 | dom = virDomainLookupByName(viewer->conn, viewer->domkey); | |
192 | dom = virDomainLookupByName(priv->conn, priv->domkey); | |
736 | 193 | } |
737 | 194 | return dom; |
738 | 195 | } |
739 | 196 | |
740 | 197 | static int |
741 | virt_viewer_matches_domain(VirtViewer *viewer, | |
198 | virt_viewer_matches_domain(VirtViewer *self, | |
742 | 199 | virDomainPtr dom) |
743 | 200 | { |
744 | 201 | char *end; |
745 | 202 | const char *name; |
746 | int id = strtol(viewer->domkey, &end, 10); | |
203 | VirtViewerPrivate *priv = self->priv; | |
204 | int id = strtol(priv->domkey, &end, 10); | |
747 | 205 | unsigned char wantuuid[16]; |
748 | 206 | unsigned char domuuid[16]; |
749 | 207 | |
751 | 209 | if (virDomainGetID(dom) == id) |
752 | 210 | return 1; |
753 | 211 | } |
754 | if (virt_viewer_parse_uuid(viewer->domkey, wantuuid) == 0) { | |
212 | if (virt_viewer_parse_uuid(priv->domkey, wantuuid) == 0) { | |
755 | 213 | virDomainGetUUID(dom, domuuid); |
756 | 214 | if (memcmp(wantuuid, domuuid, VIR_UUID_BUFLEN) == 0) |
757 | 215 | return 1; |
758 | 216 | } |
759 | 217 | |
760 | 218 | name = virDomainGetName(dom); |
761 | if (strcmp(name, viewer->domkey) == 0) | |
219 | if (strcmp(name, priv->domkey) == 0) | |
762 | 220 | return 1; |
763 | 221 | |
764 | 222 | return 0; |
810 | 268 | return port; |
811 | 269 | } |
812 | 270 | |
813 | ||
814 | static int | |
815 | virt_viewer_extract_host(const char *uristr, | |
816 | char **host, | |
817 | char **transport, | |
818 | char **user, | |
819 | int *port) | |
820 | { | |
821 | xmlURIPtr uri; | |
822 | char *offset; | |
823 | ||
824 | *host = NULL; | |
825 | *transport = NULL; | |
826 | *user = NULL; | |
827 | ||
828 | if (uristr == NULL || | |
829 | !g_strcasecmp(uristr, "xen")) | |
830 | uristr = "xen:///"; | |
831 | ||
832 | uri = xmlParseURI(uristr); | |
833 | if (!uri || !uri->server) { | |
834 | *host = g_strdup("localhost"); | |
835 | } else { | |
836 | *host = g_strdup(uri->server); | |
837 | } | |
838 | ||
839 | if (uri->user) | |
840 | *user = g_strdup(uri->user); | |
841 | *port = uri->port; | |
842 | ||
843 | offset = strchr(uri->scheme, '+'); | |
844 | if (offset) | |
845 | *transport = g_strdup(offset+1); | |
846 | ||
847 | xmlFreeURI(uri); | |
848 | return 0; | |
849 | } | |
850 | ||
851 | #if defined(HAVE_SOCKETPAIR) && defined(HAVE_FORK) | |
852 | ||
853 | static int | |
854 | virt_viewer_open_tunnel(const char **cmd) | |
855 | { | |
856 | int fd[2]; | |
857 | pid_t pid; | |
858 | ||
859 | if (socketpair(PF_UNIX, SOCK_STREAM, 0, fd) < 0) | |
860 | return -1; | |
861 | ||
862 | pid = fork(); | |
863 | if (pid == -1) { | |
864 | close(fd[0]); | |
865 | close(fd[1]); | |
866 | return -1; | |
867 | } | |
868 | ||
869 | if (pid == 0) { /* child */ | |
870 | close(fd[0]); | |
871 | close(0); | |
872 | close(1); | |
873 | if (dup(fd[1]) < 0) | |
874 | _exit(1); | |
875 | if (dup(fd[1]) < 0) | |
876 | _exit(1); | |
877 | close(fd[1]); | |
878 | execvp("ssh", (char *const*)cmd); | |
879 | _exit(1); | |
880 | } | |
881 | close(fd[1]); | |
882 | return fd[0]; | |
883 | } | |
884 | ||
885 | ||
886 | static int | |
887 | virt_viewer_open_tunnel_ssh(const char *sshhost, | |
888 | int sshport, | |
889 | const char *sshuser, | |
890 | const char *host, | |
891 | const char *port, | |
892 | const char *unixsock) | |
893 | { | |
894 | const char *cmd[10]; | |
895 | char portstr[50]; | |
896 | int n = 0; | |
897 | ||
898 | if (!sshport) | |
899 | sshport = 22; | |
900 | ||
901 | sprintf(portstr, "%d", sshport); | |
902 | ||
903 | cmd[n++] = "ssh"; | |
904 | cmd[n++] = "-p"; | |
905 | cmd[n++] = portstr; | |
906 | if (sshuser) { | |
907 | cmd[n++] = "-l"; | |
908 | cmd[n++] = sshuser; | |
909 | } | |
910 | cmd[n++] = sshhost; | |
911 | cmd[n++] = "nc"; | |
912 | if (port) { | |
913 | cmd[n++] = host; | |
914 | cmd[n++] = port; | |
915 | } else { | |
916 | cmd[n++] = "-U"; | |
917 | cmd[n++] = unixsock; | |
918 | } | |
919 | cmd[n++] = NULL; | |
920 | ||
921 | return virt_viewer_open_tunnel(cmd); | |
922 | } | |
923 | ||
924 | static int | |
925 | virt_viewer_open_unix_sock(const char *unixsock) | |
926 | { | |
927 | struct sockaddr_un addr; | |
928 | int fd; | |
929 | ||
930 | memset(&addr, 0, sizeof addr); | |
931 | addr.sun_family = AF_UNIX; | |
932 | strcpy(addr.sun_path, unixsock); | |
933 | ||
934 | if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) | |
935 | return -1; | |
936 | ||
937 | if (connect(fd, (struct sockaddr *)&addr, sizeof addr) < 0) { | |
938 | close(fd); | |
939 | return -1; | |
940 | } | |
941 | ||
942 | return fd; | |
943 | } | |
944 | ||
945 | #endif /* defined(HAVE_SOCKETPAIR) && defined(HAVE_FORK) */ | |
946 | ||
947 | static void | |
948 | virt_viewer_trace(VirtViewer *viewer, | |
949 | const char *fmt, ...) | |
950 | { | |
951 | va_list ap; | |
952 | ||
953 | if (doDebug) { | |
954 | va_start(ap, fmt); | |
955 | g_logv(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, fmt, ap); | |
956 | va_end(ap); | |
957 | } | |
958 | ||
959 | if (viewer->verbose) { | |
960 | va_start(ap, fmt); | |
961 | g_vprintf(fmt, ap); | |
962 | va_end(ap); | |
963 | } | |
964 | } | |
965 | ||
966 | ||
967 | void | |
968 | virt_viewer_set_status(VirtViewer *viewer, | |
969 | const char *text) | |
970 | { | |
971 | gtk_notebook_set_current_page(GTK_NOTEBOOK(viewer->notebook), 0); | |
972 | gtk_label_set_text(GTK_LABEL(viewer->status), text); | |
973 | } | |
974 | ||
975 | ||
976 | static void | |
977 | virt_viewer_show_display(VirtViewer *viewer) | |
978 | { | |
979 | g_return_if_fail(viewer != NULL); | |
980 | g_return_if_fail(viewer->display != NULL); | |
981 | ||
982 | gtk_widget_grab_focus(gtk_bin_get_child(GTK_BIN(viewer->display))); | |
983 | gtk_notebook_set_current_page(GTK_NOTEBOOK(viewer->notebook), 1); | |
984 | } | |
985 | ||
986 | static void | |
987 | virt_viewer_pointer_grab(VirtViewerDisplay *display G_GNUC_UNUSED, | |
988 | VirtViewer *viewer) | |
989 | { | |
990 | virt_viewer_set_title(viewer, TRUE); | |
991 | } | |
992 | ||
993 | static void | |
994 | virt_viewer_pointer_ungrab(VirtViewerDisplay *display G_GNUC_UNUSED, | |
995 | VirtViewer *viewer) | |
996 | { | |
997 | virt_viewer_set_title(viewer, FALSE); | |
998 | } | |
999 | ||
1000 | static void | |
1001 | virt_viewer_keyboard_grab(VirtViewerDisplay *display G_GNUC_UNUSED, | |
1002 | VirtViewer *viewer) | |
1003 | { | |
1004 | virt_viewer_disable_modifiers(viewer); | |
1005 | } | |
1006 | ||
1007 | static void | |
1008 | virt_viewer_keyboard_ungrab(VirtViewerDisplay *display G_GNUC_UNUSED, | |
1009 | VirtViewer *viewer) | |
1010 | { | |
1011 | virt_viewer_enable_modifiers(viewer); | |
1012 | } | |
1013 | ||
1014 | ||
1015 | static void | |
1016 | virt_viewer_display_added(VirtViewerSession *session G_GNUC_UNUSED, | |
1017 | VirtViewerDisplay *display, | |
1018 | VirtViewer *viewer) | |
1019 | { | |
1020 | /* XXX multihead */ | |
1021 | if (viewer->display) | |
1022 | return; | |
1023 | viewer->display = GTK_WIDGET(display); | |
1024 | ||
1025 | g_signal_connect(viewer->display, "display-pointer-grab", | |
1026 | G_CALLBACK(virt_viewer_pointer_grab), viewer); | |
1027 | g_signal_connect(viewer->display, "display-pointer-ungrab", | |
1028 | G_CALLBACK(virt_viewer_pointer_ungrab), viewer); | |
1029 | g_signal_connect(viewer->display, "display-keyboard-grab", | |
1030 | G_CALLBACK(virt_viewer_keyboard_grab), viewer); | |
1031 | g_signal_connect(viewer->display, "display-keyboard-ungrab", | |
1032 | G_CALLBACK(virt_viewer_keyboard_ungrab), viewer); | |
1033 | ||
1034 | g_signal_connect(viewer->display, "display-desktop-resize", | |
1035 | G_CALLBACK(virt_viewer_desktop_resize), viewer); | |
1036 | ||
1037 | gtk_notebook_append_page(GTK_NOTEBOOK(viewer->notebook), viewer->display, NULL); | |
1038 | if (gtk_bin_get_child(GTK_BIN(viewer->display))) | |
1039 | gtk_widget_realize(GTK_WIDGET(gtk_bin_get_child(GTK_BIN(viewer->display)))); | |
1040 | gtk_widget_show_all(viewer->display); | |
1041 | } | |
1042 | ||
1043 | static void | |
1044 | virt_viewer_display_removed(VirtViewerSession *session G_GNUC_UNUSED, | |
1045 | VirtViewerDisplay *display, | |
1046 | VirtViewer *viewer) | |
1047 | { | |
1048 | /* XXX multihead */ | |
1049 | if (viewer->display != GTK_WIDGET(display)) | |
1050 | return; | |
1051 | ||
1052 | gtk_widget_hide(GTK_WIDGET(display)); | |
1053 | gtk_notebook_remove_page(GTK_NOTEBOOK(viewer->notebook), 1); | |
1054 | viewer->display = NULL; | |
1055 | } | |
1056 | ||
1057 | static void | |
1058 | virt_viewer_connect_info_free(VirtViewer *viewer) | |
1059 | { | |
1060 | free(viewer->host); | |
1061 | free(viewer->ghost); | |
1062 | free(viewer->gport); | |
1063 | free(viewer->transport); | |
1064 | free(viewer->user); | |
1065 | free(viewer->unixsock); | |
1066 | ||
1067 | viewer->host = NULL; | |
1068 | viewer->ghost = NULL; | |
1069 | viewer->gport = NULL; | |
1070 | viewer->transport = NULL; | |
1071 | viewer->user = NULL; | |
1072 | viewer->unixsock = NULL; | |
1073 | viewer->port = 0; | |
1074 | } | |
1075 | ||
1076 | 271 | static gboolean |
1077 | virt_viewer_extract_connect_info(VirtViewer *viewer, | |
272 | virt_viewer_extract_connect_info(VirtViewer *self, | |
1078 | 273 | virDomainPtr dom) |
1079 | 274 | { |
1080 | 275 | char *type = NULL; |
1081 | 276 | char *xpath = NULL; |
1082 | 277 | gboolean retval = FALSE; |
1083 | 278 | char *xmldesc = virDomainGetXMLDesc(dom, 0); |
1084 | ||
1085 | virt_viewer_connect_info_free(viewer); | |
279 | VirtViewerPrivate *priv = self->priv; | |
280 | VirtViewerApp *app = VIRT_VIEWER_APP(self); | |
281 | gchar *gport = NULL; | |
282 | gchar *ghost = NULL; | |
283 | gchar *unixsock = NULL; | |
284 | gchar *host = NULL; | |
285 | gchar *transport = NULL; | |
286 | gchar *user = NULL; | |
287 | gint port = 0; | |
288 | ||
289 | virt_viewer_app_free_connect_info(app); | |
1086 | 290 | |
1087 | 291 | if ((type = virt_viewer_extract_xpath_string(xmldesc, "string(/domain/devices/graphics/@type)")) == NULL) { |
1088 | virt_viewer_simple_message_dialog(viewer->window, _("Cannot determine the graphic type for the guest %s"), | |
1089 | viewer->domkey); | |
292 | virt_viewer_app_simple_message_dialog(app, _("Cannot determine the graphic type for the guest %s"), | |
293 | priv->domkey); | |
1090 | 294 | goto cleanup; |
1091 | 295 | } |
1092 | 296 | |
1093 | if (g_strcasecmp(type, "vnc") == 0) { | |
1094 | virt_viewer_trace(viewer, "Guest %s has a %s display\n", | |
1095 | viewer->domkey, type); | |
1096 | viewer->session = virt_viewer_session_vnc_new(); | |
1097 | #ifdef HAVE_SPICE_GTK | |
1098 | } else if (g_strcasecmp(type, "spice") == 0) { | |
1099 | virt_viewer_trace(viewer, "Guest %s has a %s display\n", | |
1100 | viewer->domkey, type); | |
1101 | viewer->session = virt_viewer_session_spice_new(); | |
1102 | #endif | |
1103 | } else { | |
1104 | virt_viewer_trace(viewer, "Guest %s has unsupported %s display type\n", | |
1105 | viewer->domkey, type); | |
1106 | virt_viewer_simple_message_dialog(viewer->window, _("Unknown graphic type for the guest %s"), | |
1107 | viewer->domkey); | |
297 | if (virt_viewer_app_create_session(app, type) < 0) | |
1108 | 298 | goto cleanup; |
1109 | } | |
1110 | ||
1111 | g_signal_connect(viewer->session, "session-initialized", | |
1112 | G_CALLBACK(virt_viewer_initialized), viewer); | |
1113 | g_signal_connect(viewer->session, "session-connected", | |
1114 | G_CALLBACK(virt_viewer_connected), viewer); | |
1115 | g_signal_connect(viewer->session, "session-disconnected", | |
1116 | G_CALLBACK(virt_viewer_disconnected), viewer); | |
1117 | g_signal_connect(viewer->session, "session-channel-open", | |
1118 | G_CALLBACK(virt_viewer_channel_open), viewer); | |
1119 | g_signal_connect(viewer->session, "session-auth-refused", | |
1120 | G_CALLBACK(virt_viewer_auth_refused), viewer); | |
1121 | g_signal_connect(viewer->session, "session-auth-failed", | |
1122 | G_CALLBACK(virt_viewer_auth_failed), viewer); | |
1123 | g_signal_connect(viewer->session, "session-display-added", | |
1124 | G_CALLBACK(virt_viewer_display_added), viewer); | |
1125 | g_signal_connect(viewer->session, "session-display-removed", | |
1126 | G_CALLBACK(virt_viewer_display_removed), viewer); | |
1127 | ||
1128 | g_signal_connect(viewer->session, "session-cut-text", | |
1129 | G_CALLBACK(virt_viewer_server_cut_text), viewer); | |
1130 | g_signal_connect(viewer->session, "session-bell", | |
1131 | G_CALLBACK(virt_viewer_bell), viewer); | |
1132 | 299 | |
1133 | 300 | xpath = g_strdup_printf("string(/domain/devices/graphics[@type='%s']/@port)", type); |
1134 | if ((viewer->gport = virt_viewer_extract_xpath_string(xmldesc, xpath)) == NULL) { | |
301 | if ((gport = virt_viewer_extract_xpath_string(xmldesc, xpath)) == NULL) { | |
1135 | 302 | free(xpath); |
1136 | 303 | xpath = g_strdup_printf("string(/domain/devices/graphics[@type='%s']/@socket)", type); |
1137 | if ((viewer->unixsock = virt_viewer_extract_xpath_string(xmldesc, xpath)) == NULL) { | |
1138 | virt_viewer_simple_message_dialog(viewer->window, _("Cannot determine the graphic address for the guest %s"), | |
1139 | viewer->domkey); | |
304 | if ((unixsock = virt_viewer_extract_xpath_string(xmldesc, xpath)) == NULL) { | |
305 | virt_viewer_app_simple_message_dialog(app, _("Cannot determine the graphic address for the guest %s"), | |
306 | priv->domkey); | |
1140 | 307 | goto cleanup; |
1141 | 308 | } |
1142 | 309 | } else { |
1143 | 310 | free(xpath); |
1144 | 311 | xpath = g_strdup_printf("string(/domain/devices/graphics[@type='%s']/@listen)", type); |
1145 | viewer->ghost = virt_viewer_extract_xpath_string(xmldesc, xpath); | |
1146 | if (viewer->ghost == NULL) | |
1147 | viewer->ghost = g_strdup("localhost"); | |
1148 | } | |
1149 | ||
1150 | if (viewer->gport) | |
1151 | DEBUG_LOG("Guest graphics address is %s:%s", viewer->ghost, viewer->gport); | |
312 | ghost = virt_viewer_extract_xpath_string(xmldesc, xpath); | |
313 | if (ghost == NULL) | |
314 | ghost = g_strdup("localhost"); | |
315 | } | |
316 | ||
317 | if (gport) | |
318 | DEBUG_LOG("Guest graphics address is %s:%s", ghost, gport); | |
1152 | 319 | else |
1153 | DEBUG_LOG("Guest graphics address is %s", viewer->unixsock); | |
1154 | ||
1155 | if (virt_viewer_extract_host(viewer->uri, &viewer->host, &viewer->transport, &viewer->user, &viewer->port) < 0) { | |
1156 | virt_viewer_simple_message_dialog(viewer->window, _("Cannot determine the host for the guest %s"), | |
1157 | viewer->domkey); | |
320 | DEBUG_LOG("Guest graphics address is %s", unixsock); | |
321 | ||
322 | if (virt_viewer_util_extract_host(priv->uri, NULL, &host, &transport, &user, &port) < 0) { | |
323 | virt_viewer_app_simple_message_dialog(app, _("Cannot determine the host for the guest %s"), | |
324 | priv->domkey); | |
1158 | 325 | goto cleanup; |
1159 | 326 | } |
1160 | 327 | |
328 | virt_viewer_app_set_connect_info(app, host, ghost, gport, transport, unixsock, user, port); | |
329 | ||
1161 | 330 | retval = TRUE; |
1162 | 331 | |
1163 | cleanup: | |
332 | cleanup: | |
333 | g_free(gport); | |
334 | g_free(ghost); | |
335 | g_free(unixsock); | |
336 | g_free(host); | |
337 | g_free(transport); | |
338 | g_free(user); | |
1164 | 339 | g_free(type); |
1165 | 340 | g_free(xpath); |
1166 | 341 | g_free(xmldesc); |
1167 | 342 | return retval; |
1168 | 343 | } |
1169 | 344 | |
1170 | #if defined(HAVE_SOCKETPAIR) && defined(HAVE_FORK) | |
1171 | static void | |
1172 | virt_viewer_channel_open(VirtViewerSession *session, | |
1173 | VirtViewerSessionChannel *channel, | |
1174 | VirtViewer *viewer) | |
1175 | { | |
1176 | int fd = -1; | |
1177 | ||
1178 | g_return_if_fail(viewer != NULL); | |
1179 | ||
1180 | if (viewer->transport && g_strcasecmp(viewer->transport, "ssh") == 0 && | |
1181 | !viewer->direct) { | |
1182 | if ((fd = virt_viewer_open_tunnel_ssh(viewer->host, viewer->port, viewer->user, | |
1183 | viewer->ghost, viewer->gport, NULL)) < 0) | |
1184 | virt_viewer_simple_message_dialog(viewer->window, _("Connect to ssh failed.")); | |
1185 | } else { | |
1186 | virt_viewer_simple_message_dialog(viewer->window, _("Can't connect to channel, SSH only supported.")); | |
1187 | } | |
1188 | ||
1189 | if (fd >= 0) | |
1190 | virt_viewer_session_channel_open_fd(session, channel, fd); | |
1191 | } | |
1192 | #else | |
1193 | static void | |
1194 | virt_viewer_channel_open(VirtViewerSession *session G_GNUC_UNUSED, | |
1195 | VirtViewerSessionChannel *channel G_GNUC_UNUSED, | |
1196 | VirtViewer *viewer) | |
1197 | { | |
1198 | virt_viewer_simple_message_dialog(viewer->window, _("Connect to channel unsupported.")); | |
1199 | } | |
1200 | #endif | |
1201 | ||
1202 | 345 | static int |
1203 | virt_viewer_activate(VirtViewer *viewer, | |
1204 | virDomainPtr dom) | |
1205 | { | |
1206 | int fd = -1; | |
1207 | int ret = -1; | |
1208 | ||
1209 | if (viewer->active) | |
1210 | goto cleanup; | |
1211 | ||
1212 | virt_viewer_trace(viewer, "Guest %s is running, determining display\n", | |
1213 | viewer->domkey); | |
1214 | if (viewer->session == NULL) { | |
1215 | if (!virt_viewer_extract_connect_info(viewer, dom)) | |
1216 | goto cleanup; | |
1217 | ||
1218 | if (viewer->gport) | |
1219 | viewer->pretty_address = g_strdup_printf("%s:%s", viewer->ghost, viewer->gport); | |
1220 | else | |
1221 | viewer->pretty_address = g_strdup_printf("%s:%s", viewer->host, viewer->unixsock); | |
1222 | } | |
1223 | ||
1224 | #if defined(HAVE_SOCKETPAIR) && defined(HAVE_FORK) | |
1225 | if (viewer->transport && | |
1226 | g_strcasecmp(viewer->transport, "ssh") == 0 && | |
1227 | !viewer->direct) { | |
1228 | if (viewer->gport) { | |
1229 | virt_viewer_trace(viewer, "Opening indirect TCP connection to display at %s:%s\n", | |
1230 | viewer->ghost, viewer->gport); | |
1231 | } else { | |
1232 | virt_viewer_trace(viewer, "Opening indirect UNIX connection to display at %s\n", | |
1233 | viewer->unixsock); | |
1234 | } | |
1235 | virt_viewer_trace(viewer, "Setting up SSH tunnel via %s@%s:%d\n", | |
1236 | viewer->user, viewer->host, viewer->port ? viewer->port : 22); | |
1237 | ||
1238 | if ((fd = virt_viewer_open_tunnel_ssh(viewer->host, viewer->port, | |
1239 | viewer->user, viewer->ghost, | |
1240 | viewer->gport, viewer->unixsock)) < 0) | |
346 | virt_viewer_update_display(VirtViewer *self, virDomainPtr dom) | |
347 | { | |
348 | VirtViewerPrivate *priv = self->priv; | |
349 | VirtViewerApp *app = VIRT_VIEWER_APP(self); | |
350 | ||
351 | virt_viewer_app_trace(app, "Guest %s is running, determining display\n", | |
352 | priv->domkey); | |
353 | ||
354 | if (!virt_viewer_app_has_session(app)) { | |
355 | if (!virt_viewer_extract_connect_info(self, dom)) | |
1241 | 356 | return -1; |
1242 | } else if (viewer->unixsock) { | |
1243 | virt_viewer_trace(viewer, "Opening direct UNIX connection to display at %s", | |
1244 | viewer->unixsock); | |
1245 | if ((fd = virt_viewer_open_unix_sock(viewer->unixsock)) < 0) | |
1246 | return -1; | |
1247 | } | |
1248 | #endif | |
1249 | ||
1250 | if (fd >= 0) { | |
1251 | ret = virt_viewer_session_open_fd(VIRT_VIEWER_SESSION(viewer->session), fd); | |
1252 | } else { | |
1253 | virt_viewer_trace(viewer, "Opening direct TCP connection to display at %s:%s\n", | |
1254 | viewer->ghost, viewer->gport); | |
1255 | ret = virt_viewer_session_open_host(VIRT_VIEWER_SESSION(viewer->session), | |
1256 | viewer->ghost, viewer->gport); | |
1257 | } | |
1258 | ||
1259 | virt_viewer_set_status(viewer, "Connecting to graphic server"); | |
1260 | ||
1261 | viewer->connected = FALSE; | |
1262 | viewer->active = TRUE; | |
1263 | virt_viewer_set_title(viewer, FALSE); | |
1264 | ||
1265 | cleanup: | |
1266 | return ret; | |
1267 | } | |
1268 | ||
1269 | /* text was actually requested */ | |
1270 | static void | |
1271 | virt_viewer_clipboard_copy(GtkClipboard *clipboard G_GNUC_UNUSED, | |
1272 | GtkSelectionData *data, | |
1273 | guint info G_GNUC_UNUSED, | |
1274 | VirtViewer *viewer) | |
1275 | { | |
1276 | gtk_selection_data_set_text(data, viewer->clipboard, -1); | |
1277 | } | |
1278 | ||
1279 | static void | |
1280 | virt_viewer_server_cut_text(VirtViewerSession *session G_GNUC_UNUSED, | |
1281 | const gchar *text, | |
1282 | VirtViewer *viewer) | |
1283 | { | |
1284 | GtkClipboard *cb; | |
1285 | gsize a, b; | |
1286 | GtkTargetEntry targets[] = { | |
1287 | {g_strdup("UTF8_STRING"), 0, 0}, | |
1288 | {g_strdup("COMPOUND_TEXT"), 0, 0}, | |
1289 | {g_strdup("TEXT"), 0, 0}, | |
1290 | {g_strdup("STRING"), 0, 0}, | |
1291 | }; | |
1292 | ||
1293 | if (!text) | |
1294 | return; | |
1295 | ||
1296 | g_free (viewer->clipboard); | |
1297 | viewer->clipboard = g_convert (text, -1, "utf-8", "iso8859-1", &a, &b, NULL); | |
1298 | ||
1299 | if (viewer->clipboard) { | |
1300 | cb = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); | |
1301 | ||
1302 | gtk_clipboard_set_with_owner (cb, | |
1303 | targets, | |
1304 | G_N_ELEMENTS(targets), | |
1305 | (GtkClipboardGetFunc)virt_viewer_clipboard_copy, | |
1306 | NULL, | |
1307 | G_OBJECT (viewer)); | |
1308 | } | |
1309 | } | |
1310 | ||
1311 | ||
1312 | static void virt_viewer_bell(VirtViewerSession *session G_GNUC_UNUSED, | |
1313 | VirtViewer *viewer) | |
1314 | { | |
1315 | gdk_window_beep(gtk_widget_get_window(GTK_WIDGET(viewer->window))); | |
1316 | } | |
1317 | ||
1318 | ||
1319 | static gboolean | |
1320 | virt_viewer_retryauth(gpointer opaque) | |
1321 | { | |
1322 | VirtViewer *viewer = opaque; | |
1323 | virt_viewer_initial_connect(viewer); | |
1324 | ||
1325 | return FALSE; | |
1326 | } | |
1327 | ||
1328 | static void | |
1329 | virt_viewer_deactivate(VirtViewer *viewer) | |
1330 | { | |
1331 | if (!viewer->active) | |
1332 | return; | |
1333 | ||
1334 | if (viewer->session) | |
1335 | virt_viewer_session_close(VIRT_VIEWER_SESSION(viewer->session)); | |
1336 | ||
1337 | viewer->connected = FALSE; | |
1338 | viewer->active = FALSE; | |
1339 | #if 0 | |
1340 | g_free(viewer->pretty_address); | |
1341 | viewer->pretty_address = NULL; | |
1342 | #endif | |
1343 | virt_viewer_set_title(viewer, FALSE); | |
1344 | ||
1345 | if (viewer->authretry) { | |
1346 | viewer->authretry = FALSE; | |
1347 | g_idle_add(virt_viewer_retryauth, viewer); | |
1348 | } else if (viewer->reconnect) { | |
1349 | if (!viewer->withEvents) { | |
1350 | DEBUG_LOG("No domain events, falling back to polling"); | |
1351 | g_timeout_add(500, | |
1352 | virt_viewer_connect_timer, | |
1353 | viewer); | |
1354 | } | |
1355 | ||
1356 | virt_viewer_set_status(viewer, "Waiting for guest domain to re-start"); | |
1357 | virt_viewer_trace(viewer, "Guest %s display has disconnected, waiting to reconnect", | |
1358 | viewer->domkey); | |
1359 | } else { | |
1360 | virt_viewer_set_status(viewer, "Guest domain has shutdown"); | |
1361 | virt_viewer_trace(viewer, "Guest %s display has disconnected, shutting down", | |
1362 | viewer->domkey); | |
1363 | gtk_main_quit(); | |
1364 | } | |
1365 | } | |
1366 | ||
1367 | static void | |
1368 | virt_viewer_connected(VirtViewerSession *session G_GNUC_UNUSED, | |
1369 | VirtViewer *viewer) | |
1370 | { | |
1371 | viewer->connected = TRUE; | |
1372 | virt_viewer_set_status(viewer, "Connected to graphic server"); | |
1373 | } | |
1374 | ||
1375 | static void | |
1376 | virt_viewer_initialized(VirtViewerSession *session G_GNUC_UNUSED, | |
1377 | VirtViewer *viewer) | |
1378 | { | |
1379 | virt_viewer_show_display(viewer); | |
1380 | virt_viewer_set_title(viewer, FALSE); | |
1381 | } | |
1382 | ||
1383 | static void | |
1384 | virt_viewer_disconnected(VirtViewerSession *session G_GNUC_UNUSED, | |
1385 | VirtViewer *viewer) | |
1386 | { | |
1387 | if (!viewer->connected) { | |
1388 | virt_viewer_simple_message_dialog(viewer->window, | |
1389 | _("Unable to connect to the graphic server %s"), | |
1390 | viewer->pretty_address); | |
1391 | } | |
1392 | virt_viewer_deactivate(viewer); | |
1393 | } | |
1394 | ||
1395 | ||
1396 | static void virt_viewer_auth_refused(VirtViewerSession *session G_GNUC_UNUSED, | |
1397 | const char *msg, | |
1398 | VirtViewer *viewer) | |
1399 | { | |
1400 | GtkWidget *dialog; | |
1401 | int ret; | |
1402 | ||
1403 | dialog = gtk_message_dialog_new(GTK_WINDOW(viewer->window), | |
1404 | GTK_DIALOG_MODAL | | |
1405 | GTK_DIALOG_DESTROY_WITH_PARENT, | |
1406 | GTK_MESSAGE_ERROR, | |
1407 | GTK_BUTTONS_YES_NO, | |
1408 | _("Unable to authenticate with remote desktop server at %s: %s\n" | |
1409 | "Retry connection again?"), | |
1410 | viewer->pretty_address, msg); | |
1411 | ||
1412 | ret = gtk_dialog_run(GTK_DIALOG(dialog)); | |
1413 | ||
1414 | gtk_widget_destroy(dialog); | |
1415 | ||
1416 | if (ret == GTK_RESPONSE_YES) | |
1417 | viewer->authretry = TRUE; | |
1418 | else | |
1419 | viewer->authretry = FALSE; | |
1420 | } | |
1421 | ||
1422 | ||
1423 | static void virt_viewer_auth_failed(VirtViewerSession *session G_GNUC_UNUSED, | |
1424 | const char *msg, | |
1425 | VirtViewer *viewer) | |
1426 | { | |
1427 | virt_viewer_simple_message_dialog(viewer->window, | |
1428 | _("Unable to authenticate with remote desktop server at %s"), | |
1429 | viewer->pretty_address, msg); | |
1430 | } | |
1431 | ||
357 | } | |
358 | ||
359 | return 0; | |
360 | } | |
1432 | 361 | |
1433 | 362 | static int |
1434 | 363 | virt_viewer_domain_event(virConnectPtr conn G_GNUC_UNUSED, |
1437 | 366 | int detail G_GNUC_UNUSED, |
1438 | 367 | void *opaque) |
1439 | 368 | { |
1440 | VirtViewer *viewer = opaque; | |
369 | VirtViewer *self = opaque; | |
370 | VirtViewerApp *app = VIRT_VIEWER_APP(self); | |
1441 | 371 | |
1442 | 372 | DEBUG_LOG("Got domain event %d %d", event, detail); |
1443 | 373 | |
1444 | if (!virt_viewer_matches_domain(viewer, dom)) | |
374 | if (!virt_viewer_matches_domain(self, dom)) | |
1445 | 375 | return 0; |
1446 | ||
376 | ||
1447 | 377 | switch (event) { |
1448 | 378 | case VIR_DOMAIN_EVENT_STOPPED: |
1449 | //virt_viewer_deactivate(viewer); | |
379 | //virt_viewer_deactivate(self); | |
1450 | 380 | break; |
1451 | 381 | |
1452 | 382 | case VIR_DOMAIN_EVENT_STARTED: |
1453 | virt_viewer_activate(viewer, dom); | |
383 | virt_viewer_update_display(self, dom); | |
384 | virt_viewer_app_activate(app); | |
1454 | 385 | break; |
1455 | 386 | } |
1456 | 387 | |
1457 | 388 | return 0; |
1458 | 389 | } |
1459 | 390 | |
1460 | ||
1461 | 391 | static int |
1462 | virt_viewer_initial_connect(VirtViewer *viewer) | |
392 | virt_viewer_initial_connect(VirtViewerApp *app) | |
1463 | 393 | { |
1464 | 394 | virDomainPtr dom = NULL; |
1465 | 395 | virDomainInfo info; |
1466 | 396 | int ret = -1; |
1467 | ||
1468 | virt_viewer_set_status(viewer, "Finding guest domain"); | |
1469 | dom = virt_viewer_lookup_domain(viewer); | |
397 | VirtViewer *self = VIRT_VIEWER(app); | |
398 | VirtViewerPrivate *priv = self->priv; | |
399 | ||
400 | virt_viewer_app_show_status(app, _("Finding guest domain")); | |
401 | dom = virt_viewer_lookup_domain(self); | |
1470 | 402 | if (!dom) { |
1471 | if (viewer->waitvm) { | |
1472 | virt_viewer_set_status(viewer, "Waiting for guest domain to be created"); | |
1473 | virt_viewer_trace(viewer, "Guest %s does not yet exist, waiting for it to be created\n", | |
1474 | viewer->domkey); | |
403 | if (priv->waitvm) { | |
404 | virt_viewer_app_show_status(app, _("Waiting for guest domain to be created")); | |
405 | virt_viewer_app_trace(app, "Guest %s does not yet exist, waiting for it to be created\n", | |
406 | priv->domkey); | |
1475 | 407 | goto done; |
1476 | 408 | } else { |
1477 | virt_viewer_simple_message_dialog(viewer->window, _("Cannot find guest domain %s"), | |
1478 | viewer->domkey); | |
1479 | DEBUG_LOG("Cannot find guest %s", viewer->domkey); | |
409 | virt_viewer_app_simple_message_dialog(app, _("Cannot find guest domain %s"), | |
410 | priv->domkey); | |
411 | DEBUG_LOG("Cannot find guest %s", priv->domkey); | |
1480 | 412 | goto cleanup; |
1481 | 413 | } |
1482 | 414 | } |
1483 | 415 | |
1484 | free(viewer->domtitle); | |
1485 | viewer->domtitle = g_strdup(virDomainGetName(dom)); | |
1486 | ||
1487 | virt_viewer_set_status(viewer, "Checking guest domain status"); | |
416 | free(priv->domtitle); | |
417 | priv->domtitle = g_strdup(virDomainGetName(dom)); | |
418 | ||
419 | virt_viewer_app_show_status(app, _("Checking guest domain status")); | |
1488 | 420 | if (virDomainGetInfo(dom, &info) < 0) { |
1489 | 421 | DEBUG_LOG("Cannot get guest state"); |
1490 | 422 | goto cleanup; |
1491 | 423 | } |
1492 | 424 | |
1493 | 425 | if (info.state == VIR_DOMAIN_SHUTOFF) { |
1494 | virt_viewer_set_status(viewer, "Waiting for guest domain to start"); | |
426 | virt_viewer_app_show_status(app, _("Waiting for guest domain to start")); | |
1495 | 427 | } else { |
1496 | ret = virt_viewer_activate(viewer, dom); | |
428 | ret = virt_viewer_update_display(self, dom); | |
429 | if (ret >= 0) | |
430 | ret = VIRT_VIEWER_APP_CLASS(virt_viewer_parent_class)->initial_connect(app); | |
1497 | 431 | if (ret < 0) { |
1498 | if (viewer->waitvm) { | |
1499 | virt_viewer_set_status(viewer, "Waiting for guest domain to start server"); | |
1500 | virt_viewer_trace(viewer, "Guest %s has not activated its display yet, waiting for it to start\n", | |
1501 | viewer->domkey); | |
432 | if (priv->waitvm) { | |
433 | virt_viewer_app_show_status(app, _("Waiting for guest domain to start server")); | |
434 | virt_viewer_app_trace(app, "Guest %s has not activated its display yet, waiting for it to start\n", | |
435 | priv->domkey); | |
1502 | 436 | } else { |
1503 | 437 | DEBUG_LOG("Failed to activate viewer"); |
1504 | 438 | goto cleanup; |
1518 | 452 | return ret; |
1519 | 453 | } |
1520 | 454 | |
1521 | static gboolean | |
1522 | virt_viewer_connect_timer(void *opaque) | |
1523 | { | |
1524 | VirtViewer *viewer = opaque; | |
1525 | ||
1526 | DEBUG_LOG("Connect timer fired"); | |
1527 | ||
1528 | if (!viewer->active && | |
1529 | virt_viewer_initial_connect(viewer) < 0) | |
1530 | gtk_main_quit(); | |
1531 | ||
1532 | if (viewer->active) | |
1533 | return FALSE; | |
1534 | ||
1535 | return TRUE; | |
1536 | } | |
1537 | ||
1538 | static void | |
1539 | virt_viewer_toolbar_setup(VirtViewer *viewer) | |
1540 | { | |
1541 | GtkWidget *button; | |
1542 | ||
1543 | viewer->toolbar = gtk_toolbar_new(); | |
1544 | gtk_toolbar_set_show_arrow(GTK_TOOLBAR(viewer->toolbar), FALSE); | |
1545 | gtk_widget_set_no_show_all(viewer->toolbar, TRUE); | |
1546 | gtk_toolbar_set_style(GTK_TOOLBAR(viewer->toolbar), GTK_TOOLBAR_BOTH_HORIZ); | |
1547 | ||
1548 | /* Close connection */ | |
1549 | button = GTK_WIDGET(gtk_tool_button_new_from_stock(GTK_STOCK_CLOSE)); | |
1550 | gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(button), _("Disconnect")); | |
1551 | gtk_widget_show(GTK_WIDGET(button)); | |
1552 | gtk_toolbar_insert(GTK_TOOLBAR(viewer->toolbar), GTK_TOOL_ITEM (button), 0); | |
1553 | g_signal_connect(button, "clicked", G_CALLBACK(gtk_main_quit), NULL); | |
1554 | ||
1555 | /* Leave fullscreen */ | |
1556 | button = GTK_WIDGET(gtk_tool_button_new_from_stock(GTK_STOCK_LEAVE_FULLSCREEN)); | |
1557 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(button), _("Leave fullscreen")); | |
1558 | gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(button), _("Leave fullscreen")); | |
1559 | gtk_tool_item_set_is_important(GTK_TOOL_ITEM(button), TRUE); | |
1560 | gtk_widget_show(GTK_WIDGET(button)); | |
1561 | gtk_toolbar_insert(GTK_TOOLBAR(viewer->toolbar), GTK_TOOL_ITEM(button), 0); | |
1562 | g_signal_connect(button, "clicked", G_CALLBACK(virt_viewer_toolbar_leave_fullscreen), viewer); | |
1563 | ||
1564 | viewer->layout = ViewAutoDrawer_New(); | |
1565 | ||
1566 | ViewAutoDrawer_SetActive(VIEW_AUTODRAWER(viewer->layout), FALSE); | |
1567 | ViewOvBox_SetOver(VIEW_OV_BOX(viewer->layout), viewer->toolbar); | |
1568 | ViewOvBox_SetUnder(VIEW_OV_BOX(viewer->layout), viewer->notebook); | |
1569 | ViewAutoDrawer_SetOffset(VIEW_AUTODRAWER(viewer->layout), -1); | |
1570 | ViewAutoDrawer_SetFill(VIEW_AUTODRAWER(viewer->layout), FALSE); | |
1571 | ViewAutoDrawer_SetOverlapPixels(VIEW_AUTODRAWER(viewer->layout), 1); | |
1572 | ViewAutoDrawer_SetNoOverlapPixels(VIEW_AUTODRAWER(viewer->layout), 0); | |
1573 | } | |
1574 | ||
1575 | ||
1576 | 455 | static void |
1577 | 456 | virt_viewer_error_func (void *data G_GNUC_UNUSED, |
1578 | 457 | virErrorPtr error G_GNUC_UNUSED) |
1580 | 459 | /* nada */ |
1581 | 460 | } |
1582 | 461 | |
1583 | int | |
1584 | virt_viewer_start(const char *uri, | |
1585 | const char *name, | |
1586 | gint zoom, | |
1587 | gboolean direct, | |
1588 | gboolean waitvm, | |
1589 | gboolean reconnect, | |
1590 | gboolean verbose, | |
1591 | gboolean debug, | |
1592 | gboolean fullscreen, | |
1593 | GtkWidget *container) | |
1594 | { | |
1595 | VirtViewer *viewer; | |
1596 | GtkWidget *menu; | |
462 | static gboolean | |
463 | virt_viewer_start(VirtViewerApp *app) | |
464 | { | |
465 | VirtViewer *self = VIRT_VIEWER(app); | |
466 | VirtViewerPrivate *priv = self->priv; | |
1597 | 467 | int cred_types[] = |
1598 | 468 | { VIR_CRED_AUTHNAME, VIR_CRED_PASSPHRASE }; |
1599 | 469 | virConnectAuth auth_libvirt = { |
1600 | 470 | .credtype = cred_types, |
1601 | 471 | .ncredtype = ARRAY_CARDINALITY(cred_types), |
1602 | 472 | .cb = virt_viewer_auth_libvirt_credentials, |
1603 | .cbdata = (void *)uri, | |
473 | .cbdata = (void *)priv->uri, | |
1604 | 474 | }; |
1605 | GdkColor color; | |
1606 | doDebug = debug; | |
1607 | ||
1608 | viewer = g_new0(VirtViewer, 1); | |
1609 | ||
1610 | viewer->active = FALSE; | |
1611 | viewer->autoResize = TRUE; | |
1612 | viewer->direct = direct; | |
1613 | viewer->waitvm = waitvm; | |
1614 | viewer->reconnect = reconnect; | |
1615 | viewer->verbose = verbose; | |
1616 | viewer->domkey = g_strdup(name); | |
1617 | viewer->uri = g_strdup(uri); | |
1618 | ||
1619 | g_value_init(&viewer->accelSetting, G_TYPE_STRING); | |
1620 | 475 | |
1621 | 476 | virt_viewer_events_register(); |
1622 | 477 | |
1623 | 478 | virSetErrorFunc(NULL, virt_viewer_error_func); |
1624 | 479 | |
1625 | virt_viewer_trace(viewer, "Opening connection to libvirt with URI %s\n", | |
1626 | uri ? uri : "<null>"); | |
1627 | viewer->conn = virConnectOpenAuth(uri, | |
1628 | //virConnectAuthPtrDefault, | |
1629 | &auth_libvirt, | |
1630 | VIR_CONNECT_RO); | |
1631 | if (!viewer->conn) { | |
1632 | virt_viewer_simple_message_dialog(NULL, _("Unable to connect to libvirt with URI %s"), | |
1633 | uri ? uri : _("[none]")); | |
1634 | return -1; | |
1635 | } | |
1636 | ||
1637 | if (!container) { | |
1638 | viewer->builder = virt_viewer_util_load_ui("virt-viewer.xml"); | |
1639 | ||
1640 | menu = GTK_WIDGET(gtk_builder_get_object(viewer->builder, "menu-view-resize")); | |
1641 | gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE); | |
1642 | ||
1643 | gtk_builder_connect_signals(viewer->builder, viewer); | |
1644 | } | |
1645 | ||
1646 | viewer->status = gtk_label_new(""); | |
1647 | ||
1648 | viewer->zoomlevel = zoom; | |
1649 | ||
1650 | viewer->notebook = gtk_notebook_new(); | |
1651 | gtk_notebook_set_show_tabs(GTK_NOTEBOOK(viewer->notebook), FALSE); | |
1652 | gtk_notebook_set_show_border(GTK_NOTEBOOK(viewer->notebook), FALSE); | |
1653 | ||
1654 | gtk_notebook_append_page(GTK_NOTEBOOK(viewer->notebook), viewer->status, NULL); | |
1655 | ||
1656 | if (container) { | |
1657 | viewer->container = container; | |
1658 | ||
1659 | gtk_box_pack_end(GTK_BOX(container), viewer->notebook, TRUE, TRUE, 0); | |
1660 | gtk_widget_show_all(GTK_WIDGET(container)); | |
1661 | } else { | |
1662 | GtkWidget *vbox = GTK_WIDGET(gtk_builder_get_object(viewer->builder, "viewer-box")); | |
1663 | virt_viewer_toolbar_setup(viewer); | |
1664 | ||
1665 | gtk_box_pack_end(GTK_BOX(vbox), viewer->layout, TRUE, TRUE, 0); | |
1666 | gdk_color_parse("black", &color); | |
1667 | gtk_widget_modify_bg(viewer->layout, GTK_STATE_NORMAL, &color); | |
1668 | gdk_color_parse("white", &color); | |
1669 | gtk_widget_modify_fg(viewer->status, GTK_STATE_NORMAL, &color); | |
1670 | ||
1671 | GtkWidget *window = GTK_WIDGET(gtk_builder_get_object(viewer->builder, "viewer")); | |
1672 | GSList *accels; | |
1673 | viewer->container = window; | |
1674 | viewer->window = window; | |
1675 | virt_viewer_set_title(viewer, FALSE); | |
1676 | gtk_window_set_resizable(GTK_WINDOW(window), TRUE); | |
1677 | #if GTK_CHECK_VERSION(3, 0, 0) | |
1678 | gtk_window_set_has_resize_grip(GTK_WINDOW(window), FALSE); | |
1679 | #endif | |
1680 | viewer->accelEnabled = TRUE; | |
1681 | accels = gtk_accel_groups_from_object(G_OBJECT(window)); | |
1682 | for ( ; accels ; accels = accels->next) { | |
1683 | viewer->accelList = g_slist_append(viewer->accelList, accels->data); | |
1684 | g_object_ref(G_OBJECT(accels->data)); | |
1685 | } | |
1686 | g_signal_connect(G_OBJECT(window), "window-state-event", G_CALLBACK(window_state_cb), viewer); | |
1687 | if (fullscreen) | |
1688 | gtk_window_fullscreen(GTK_WINDOW(window)); | |
1689 | gtk_widget_show_all(viewer->window); | |
1690 | } | |
1691 | ||
1692 | if (virt_viewer_initial_connect(viewer) < 0) | |
1693 | return -1; | |
1694 | ||
1695 | if (virConnectDomainEventRegister(viewer->conn, | |
480 | virt_viewer_app_trace(app, "Opening connection to libvirt with URI %s\n", | |
481 | priv->uri ? priv->uri : "<null>"); | |
482 | priv->conn = virConnectOpenAuth(priv->uri, | |
483 | //virConnectAuthPtrDefault, | |
484 | &auth_libvirt, | |
485 | VIR_CONNECT_RO); | |
486 | if (!priv->conn) { | |
487 | virt_viewer_app_simple_message_dialog(app, _("Unable to connect to libvirt with URI %s"), | |
488 | priv->uri ? priv->uri : _("[none]")); | |
489 | return FALSE; | |
490 | } | |
491 | ||
492 | if (virt_viewer_app_initial_connect(app) < 0) | |
493 | return FALSE; | |
494 | ||
495 | if (virConnectDomainEventRegister(priv->conn, | |
1696 | 496 | virt_viewer_domain_event, |
1697 | viewer, | |
497 | self, | |
1698 | 498 | NULL) < 0) |
1699 | viewer->withEvents = FALSE; | |
499 | priv->withEvents = FALSE; | |
1700 | 500 | else |
1701 | viewer->withEvents = TRUE; | |
1702 | ||
1703 | if (!viewer->withEvents && | |
1704 | !viewer->active) { | |
501 | priv->withEvents = TRUE; | |
502 | ||
503 | if (!priv->withEvents && | |
504 | !virt_viewer_app_is_active(app)) { | |
1705 | 505 | DEBUG_LOG("No domain events, falling back to polling"); |
1706 | g_timeout_add(500, | |
1707 | virt_viewer_connect_timer, | |
1708 | viewer); | |
1709 | } | |
1710 | ||
1711 | return 0; | |
1712 | } | |
1713 | ||
506 | virt_viewer_app_start_reconnect_poll(app); | |
507 | } | |
508 | ||
509 | return VIRT_VIEWER_APP_CLASS(virt_viewer_parent_class)->start(app); | |
510 | } | |
511 | ||
512 | VirtViewer * | |
513 | virt_viewer_new(const char *uri, | |
514 | const char *name, | |
515 | gint zoom, | |
516 | gboolean direct, | |
517 | gboolean waitvm, | |
518 | gboolean reconnect, | |
519 | gboolean verbose, | |
520 | GtkWidget *container) | |
521 | { | |
522 | VirtViewer *self; | |
523 | VirtViewerApp *app; | |
524 | VirtViewerPrivate *priv; | |
525 | ||
526 | self = g_object_new(VIRT_VIEWER_TYPE, | |
527 | "container", container, | |
528 | "verbose", verbose, | |
529 | NULL); | |
530 | app = VIRT_VIEWER_APP(self); | |
531 | priv = self->priv; | |
532 | ||
533 | virt_viewer_window_set_zoom_level(virt_viewer_app_get_main_window(app), zoom); | |
534 | virt_viewer_app_set_direct(app, direct); | |
535 | ||
536 | /* should probably be properties instead */ | |
537 | priv->uri = g_strdup(uri); | |
538 | priv->domkey = g_strdup(name); | |
539 | priv->waitvm = waitvm; | |
540 | priv->reconnect = reconnect; | |
541 | ||
542 | return self; | |
543 | } | |
1714 | 544 | |
1715 | 545 | /* |
1716 | 546 | * Local variables: |
22 | 22 | #ifndef VIRT_VIEWER_H |
23 | 23 | #define VIRT_VIEWER_H |
24 | 24 | |
25 | #include "virt-viewer-util.h" | |
25 | #include <glib-object.h> | |
26 | #include "virt-viewer-app.h" | |
26 | 27 | |
27 | typedef struct _VirtViewer VirtViewer; | |
28 | G_BEGIN_DECLS | |
28 | 29 | |
29 | extern int virt_viewer_start(const char *uri, | |
30 | const char *name, | |
31 | gint zoom, | |
32 | gboolean direct, | |
33 | gboolean waitvm, | |
34 | gboolean reconnect, | |
35 | gboolean verbose, | |
36 | gboolean debug, | |
37 | gboolean fullscreen, | |
38 | GtkWidget *container); | |
30 | #define VIRT_VIEWER_TYPE virt_viewer_get_type() | |
31 | #define VIRT_VIEWER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIRT_VIEWER_TYPE, VirtViewer)) | |
32 | #define VIRT_VIEWER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VIRT_VIEWER_TYPE, VirtViewerClass)) | |
33 | #define VIRT_VIEWER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIRT_VIEWER_TYPE)) | |
34 | #define VIRT_VIEWER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VIRT_VIEWER_TYPE)) | |
35 | #define VIRT_VIEWER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VIRT_VIEWER_TYPE, VirtViewerClass)) | |
36 | ||
37 | typedef struct _VirtViewerPrivate VirtViewerPrivate; | |
38 | ||
39 | typedef struct { | |
40 | VirtViewerApp parent; | |
41 | VirtViewerPrivate *priv; | |
42 | } VirtViewer; | |
43 | ||
44 | typedef struct { | |
45 | VirtViewerAppClass parent_class; | |
46 | } VirtViewerClass; | |
47 | ||
48 | GType virt_viewer_get_type (void); | |
49 | ||
50 | VirtViewer * | |
51 | virt_viewer_new(const char *uri, | |
52 | const char *name, | |
53 | gint zoom, | |
54 | gboolean direct, | |
55 | gboolean waitvm, | |
56 | gboolean reconnect, | |
57 | gboolean verbose, | |
58 | GtkWidget *container); | |
59 | ||
60 | G_END_DECLS | |
39 | 61 | |
40 | 62 | #endif /* VIRT_VIEWER_H */ |
0 | <?xml version="1.0"?> | |
0 | <?xml version="1.0" encoding="UTF-8"?> | |
1 | 1 | <interface> |
2 | 2 | <!-- interface-requires gtk+ 2.6 --> |
3 | <!-- interface-naming-policy toplevel-contextual --> | |
4 | 3 | <object class="GtkWindow" id="viewer"> |
4 | <property name="can_focus">False</property> | |
5 | 5 | <property name="default_width">400</property> |
6 | 6 | <property name="default_height">400</property> |
7 | <signal name="delete_event" handler="virt_viewer_delete"/> | |
7 | <signal name="delete-event" handler="virt_viewer_window_delete" swapped="no"/> | |
8 | 8 | <child> |
9 | 9 | <object class="GtkVBox" id="viewer-box"> |
10 | 10 | <property name="visible">True</property> |
11 | <property name="orientation">vertical</property> | |
11 | <property name="can_focus">False</property> | |
12 | 12 | <child> |
13 | 13 | <object class="GtkMenuBar" id="top-menu"> |
14 | 14 | <property name="visible">True</property> |
15 | <property name="can_focus">False</property> | |
15 | 16 | <child> |
16 | 17 | <object class="GtkMenuItem" id="menu-file"> |
17 | 18 | <property name="visible">True</property> |
19 | <property name="can_focus">False</property> | |
20 | <property name="use_action_appearance">False</property> | |
18 | 21 | <property name="label" translatable="yes">_File</property> |
19 | 22 | <property name="use_underline">True</property> |
20 | 23 | <child type="submenu"> |
21 | 24 | <object class="GtkMenu" id="menu1"> |
22 | 25 | <property name="visible">True</property> |
26 | <property name="can_focus">False</property> | |
23 | 27 | <child> |
24 | 28 | <object class="GtkMenuItem" id="menu-file-screenshot"> |
25 | 29 | <property name="visible">True</property> |
30 | <property name="can_focus">False</property> | |
31 | <property name="use_action_appearance">False</property> | |
26 | 32 | <property name="label" translatable="yes">Screenshot</property> |
27 | 33 | <property name="use_underline">True</property> |
28 | <signal name="activate" handler="virt_viewer_menu_file_screenshot"/> | |
34 | <signal name="activate" handler="virt_viewer_window_menu_file_screenshot" swapped="no"/> | |
29 | 35 | </object> |
30 | 36 | </child> |
31 | 37 | <child> |
32 | 38 | <object class="GtkSeparatorMenuItem" id="separatormenuitem1"> |
33 | 39 | <property name="visible">True</property> |
40 | <property name="can_focus">False</property> | |
34 | 41 | </object> |
35 | 42 | </child> |
36 | 43 | <child> |
37 | 44 | <object class="GtkImageMenuItem" id="imagemenuitem5"> |
38 | 45 | <property name="label">gtk-quit</property> |
39 | 46 | <property name="visible">True</property> |
47 | <property name="can_focus">False</property> | |
48 | <property name="use_action_appearance">False</property> | |
40 | 49 | <property name="use_underline">True</property> |
41 | 50 | <property name="use_stock">True</property> |
42 | <signal name="activate" handler="virt_viewer_menu_file_quit"/> | |
43 | <accelerator key="q" signal="activate" modifiers="GDK_CONTROL_MASK|GDK_SHIFT_MASK"/> | |
51 | <accelerator key="q" signal="activate" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/> | |
52 | <signal name="activate" handler="virt_viewer_window_menu_file_quit" swapped="no"/> | |
44 | 53 | </object> |
45 | 54 | </child> |
46 | 55 | </object> |
50 | 59 | <child> |
51 | 60 | <object class="GtkMenuItem" id="menu-view"> |
52 | 61 | <property name="visible">True</property> |
62 | <property name="can_focus">False</property> | |
63 | <property name="use_action_appearance">False</property> | |
53 | 64 | <property name="label" translatable="yes">_View</property> |
54 | 65 | <property name="use_underline">True</property> |
55 | 66 | <child type="submenu"> |
56 | 67 | <object class="GtkMenu" id="menu2"> |
57 | 68 | <property name="visible">True</property> |
69 | <property name="can_focus">False</property> | |
58 | 70 | <child> |
59 | 71 | <object class="GtkCheckMenuItem" id="menu-view-fullscreen"> |
60 | 72 | <property name="visible">True</property> |
73 | <property name="can_focus">False</property> | |
74 | <property name="use_action_appearance">False</property> | |
61 | 75 | <property name="label" translatable="yes">Full screen</property> |
62 | 76 | <property name="use_underline">True</property> |
63 | 77 | <accelerator key="F11" signal="activate"/> |
64 | <signal name="toggled" handler="virt_viewer_menu_view_fullscreen"/> | |
78 | <signal name="toggled" handler="virt_viewer_window_menu_view_fullscreen" swapped="no"/> | |
65 | 79 | </object> |
66 | 80 | </child> |
67 | 81 | <child> |
68 | 82 | <object class="GtkMenuItem" id="menu-view-zoom"> |
69 | 83 | <property name="visible">True</property> |
84 | <property name="can_focus">False</property> | |
85 | <property name="use_action_appearance">False</property> | |
70 | 86 | <property name="label" translatable="yes">_Zoom</property> |
71 | 87 | <property name="use_underline">True</property> |
72 | 88 | <child type="submenu"> |
73 | 89 | <object class="GtkMenu" id="menu4"> |
74 | 90 | <property name="visible">True</property> |
91 | <property name="can_focus">False</property> | |
75 | 92 | <child> |
76 | 93 | <object class="GtkImageMenuItem" id="menu-view-zoom-in"> |
94 | <property name="label">gtk-zoom-in</property> | |
77 | 95 | <property name="visible">True</property> |
78 | <property name="label">gtk-zoom-in</property> | |
96 | <property name="can_focus">False</property> | |
97 | <property name="use_action_appearance">False</property> | |
79 | 98 | <property name="use_underline">True</property> |
80 | 99 | <property name="use_stock">True</property> |
81 | 100 | <accelerator key="plus" signal="activate" modifiers="GDK_CONTROL_MASK"/> |
82 | <signal name="activate" handler="virt_viewer_menu_view_zoom_in"/> | |
101 | <signal name="activate" handler="virt_viewer_window_menu_view_zoom_in" swapped="no"/> | |
83 | 102 | </object> |
84 | 103 | </child> |
85 | 104 | <child> |
86 | 105 | <object class="GtkImageMenuItem" id="menu-view-zoom-out"> |
106 | <property name="label">gtk-zoom-out</property> | |
87 | 107 | <property name="visible">True</property> |
88 | <property name="label">gtk-zoom-out</property> | |
108 | <property name="can_focus">False</property> | |
109 | <property name="use_action_appearance">False</property> | |
89 | 110 | <property name="use_underline">True</property> |
90 | 111 | <property name="use_stock">True</property> |
91 | 112 | <accelerator key="minus" signal="activate" modifiers="GDK_CONTROL_MASK"/> |
92 | <signal name="activate" handler="virt_viewer_menu_view_zoom_out"/> | |
113 | <signal name="activate" handler="virt_viewer_window_menu_view_zoom_out" swapped="no"/> | |
93 | 114 | </object> |
94 | 115 | </child> |
95 | 116 | <child> |
96 | 117 | <object class="GtkSeparatorMenuItem" id="separatormenuitem4"> |
97 | 118 | <property name="visible">True</property> |
119 | <property name="can_focus">False</property> | |
98 | 120 | </object> |
99 | 121 | </child> |
100 | 122 | <child> |
101 | 123 | <object class="GtkImageMenuItem" id="menu-view-zoom-reset"> |
124 | <property name="label">gtk-zoom-100</property> | |
102 | 125 | <property name="visible">True</property> |
103 | <property name="label">gtk-zoom-100</property> | |
126 | <property name="can_focus">False</property> | |
127 | <property name="use_action_appearance">False</property> | |
104 | 128 | <property name="use_underline">True</property> |
105 | 129 | <property name="use_stock">True</property> |
106 | 130 | <accelerator key="0" signal="activate" modifiers="GDK_CONTROL_MASK"/> |
107 | <signal name="activate" handler="virt_viewer_menu_view_zoom_reset"/> | |
131 | <signal name="activate" handler="virt_viewer_window_menu_view_zoom_reset" swapped="no"/> | |
108 | 132 | </object> |
109 | 133 | </child> |
110 | 134 | </object> |
114 | 138 | <child> |
115 | 139 | <object class="GtkCheckMenuItem" id="menu-view-resize"> |
116 | 140 | <property name="visible">True</property> |
141 | <property name="can_focus">False</property> | |
142 | <property name="use_action_appearance">False</property> | |
117 | 143 | <property name="label" translatable="yes">Automatically resize</property> |
118 | 144 | <property name="use_underline">True</property> |
119 | <signal name="toggled" handler="virt_viewer_menu_view_resize"/> | |
145 | <signal name="toggled" handler="virt_viewer_window_menu_view_resize" swapped="no"/> | |
146 | </object> | |
147 | </child> | |
148 | <child> | |
149 | <object class="GtkMenuItem" id="menu-displays"> | |
150 | <property name="visible">True</property> | |
151 | <property name="can_focus">False</property> | |
152 | <property name="use_action_appearance">False</property> | |
153 | <property name="label" translatable="yes">Displays</property> | |
154 | <property name="use_underline">True</property> | |
120 | 155 | </object> |
121 | 156 | </child> |
122 | 157 | </object> |
126 | 161 | <child> |
127 | 162 | <object class="GtkMenuItem" id="menu-send"> |
128 | 163 | <property name="visible">True</property> |
164 | <property name="can_focus">False</property> | |
165 | <property name="use_action_appearance">False</property> | |
129 | 166 | <property name="label" translatable="yes">_Send key</property> |
130 | 167 | <property name="use_underline">True</property> |
131 | 168 | <child type="submenu"> |
132 | 169 | <object class="GtkMenu" id="menu5"> |
133 | 170 | <property name="visible">True</property> |
171 | <property name="can_focus">False</property> | |
134 | 172 | <child> |
135 | 173 | <object class="GtkMenuItem" id="menu-send-cad"> |
136 | 174 | <property name="visible">True</property> |
175 | <property name="can_focus">False</property> | |
176 | <property name="use_action_appearance">False</property> | |
137 | 177 | <property name="label" translatable="yes">Ctrl+Alt+_Del</property> |
138 | 178 | <property name="use_underline">True</property> |
139 | <signal name="activate" handler="virt_viewer_menu_send"/> | |
179 | <signal name="activate" handler="virt_viewer_window_menu_send" swapped="no"/> | |
140 | 180 | </object> |
141 | 181 | </child> |
142 | 182 | <child> |
143 | 183 | <object class="GtkMenuItem" id="menu-send-cab"> |
144 | 184 | <property name="visible">True</property> |
185 | <property name="can_focus">False</property> | |
186 | <property name="use_action_appearance">False</property> | |
145 | 187 | <property name="label" translatable="yes">Ctrl+Alt+_Backspace</property> |
146 | 188 | <property name="use_underline">True</property> |
147 | <signal name="activate" handler="virt_viewer_menu_send"/> | |
189 | <signal name="activate" handler="virt_viewer_window_menu_send" swapped="no"/> | |
148 | 190 | </object> |
149 | 191 | </child> |
150 | 192 | <child> |
151 | 193 | <object class="GtkSeparatorMenuItem" id="separatormenuitem2"> |
152 | 194 | <property name="visible">True</property> |
195 | <property name="can_focus">False</property> | |
153 | 196 | </object> |
154 | 197 | </child> |
155 | 198 | <child> |
156 | 199 | <object class="GtkMenuItem" id="menu-send-caf1"> |
157 | 200 | <property name="visible">True</property> |
201 | <property name="can_focus">False</property> | |
202 | <property name="use_action_appearance">False</property> | |
158 | 203 | <property name="label" translatable="yes">Ctrl+Alt+F_1</property> |
159 | 204 | <property name="use_underline">True</property> |
160 | <signal name="activate" handler="virt_viewer_menu_send"/> | |
205 | <signal name="activate" handler="virt_viewer_window_menu_send" swapped="no"/> | |
161 | 206 | </object> |
162 | 207 | </child> |
163 | 208 | <child> |
164 | 209 | <object class="GtkMenuItem" id="menu-send-caf2"> |
165 | 210 | <property name="visible">True</property> |
211 | <property name="can_focus">False</property> | |
212 | <property name="use_action_appearance">False</property> | |
166 | 213 | <property name="label" translatable="yes">Ctrl+Alt+F_2</property> |
167 | 214 | <property name="use_underline">True</property> |
168 | <signal name="activate" handler="virt_viewer_menu_send"/> | |
215 | <signal name="activate" handler="virt_viewer_window_menu_send" swapped="no"/> | |
169 | 216 | </object> |
170 | 217 | </child> |
171 | 218 | <child> |
172 | 219 | <object class="GtkMenuItem" id="menu-send-caf3"> |
173 | 220 | <property name="visible">True</property> |
221 | <property name="can_focus">False</property> | |
222 | <property name="use_action_appearance">False</property> | |
174 | 223 | <property name="label" translatable="yes">Ctrl+Alt+F_3</property> |
175 | 224 | <property name="use_underline">True</property> |
176 | <signal name="activate" handler="virt_viewer_menu_send"/> | |
225 | <signal name="activate" handler="virt_viewer_window_menu_send" swapped="no"/> | |
177 | 226 | </object> |
178 | 227 | </child> |
179 | 228 | <child> |
180 | 229 | <object class="GtkMenuItem" id="menu-send-caf4"> |
181 | 230 | <property name="visible">True</property> |
231 | <property name="can_focus">False</property> | |
232 | <property name="use_action_appearance">False</property> | |
182 | 233 | <property name="label" translatable="yes">Ctrl+Alt+F_4</property> |
183 | 234 | <property name="use_underline">True</property> |
184 | <signal name="activate" handler="virt_viewer_menu_send"/> | |
235 | <signal name="activate" handler="virt_viewer_window_menu_send" swapped="no"/> | |
185 | 236 | </object> |
186 | 237 | </child> |
187 | 238 | <child> |
188 | 239 | <object class="GtkMenuItem" id="menu-send-caf5"> |
189 | 240 | <property name="visible">True</property> |
241 | <property name="can_focus">False</property> | |
242 | <property name="use_action_appearance">False</property> | |
190 | 243 | <property name="label" translatable="yes">Ctrl+Alt+F_5</property> |
191 | 244 | <property name="use_underline">True</property> |
192 | <signal name="activate" handler="virt_viewer_menu_send"/> | |
245 | <signal name="activate" handler="virt_viewer_window_menu_send" swapped="no"/> | |
193 | 246 | </object> |
194 | 247 | </child> |
195 | 248 | <child> |
196 | 249 | <object class="GtkMenuItem" id="menu-send-caf6"> |
197 | 250 | <property name="visible">True</property> |
251 | <property name="can_focus">False</property> | |
252 | <property name="use_action_appearance">False</property> | |
198 | 253 | <property name="label" translatable="yes">Ctrl+Alt+F_6</property> |
199 | 254 | <property name="use_underline">True</property> |
200 | <signal name="activate" handler="virt_viewer_menu_send"/> | |
255 | <signal name="activate" handler="virt_viewer_window_menu_send" swapped="no"/> | |
201 | 256 | </object> |
202 | 257 | </child> |
203 | 258 | <child> |
204 | 259 | <object class="GtkMenuItem" id="menu-send-caf7"> |
205 | 260 | <property name="visible">True</property> |
261 | <property name="can_focus">False</property> | |
262 | <property name="use_action_appearance">False</property> | |
206 | 263 | <property name="label" translatable="yes">Ctrl+Alt+F_7</property> |
207 | 264 | <property name="use_underline">True</property> |
208 | <signal name="activate" handler="virt_viewer_menu_send"/> | |
265 | <signal name="activate" handler="virt_viewer_window_menu_send" swapped="no"/> | |
209 | 266 | </object> |
210 | 267 | </child> |
211 | 268 | <child> |
212 | 269 | <object class="GtkMenuItem" id="menu-send-caf8"> |
213 | 270 | <property name="visible">True</property> |
271 | <property name="can_focus">False</property> | |
272 | <property name="use_action_appearance">False</property> | |
214 | 273 | <property name="label" translatable="yes">Ctrl+Alt+F_8</property> |
215 | 274 | <property name="use_underline">True</property> |
216 | <signal name="activate" handler="virt_viewer_menu_send"/> | |
275 | <signal name="activate" handler="virt_viewer_window_menu_send" swapped="no"/> | |
217 | 276 | </object> |
218 | 277 | </child> |
219 | 278 | <child> |
220 | 279 | <object class="GtkMenuItem" id="menu-send-caf9"> |
221 | 280 | <property name="visible">True</property> |
281 | <property name="can_focus">False</property> | |
282 | <property name="use_action_appearance">False</property> | |
222 | 283 | <property name="label" translatable="yes">Ctrl+Alt+F_9</property> |
223 | 284 | <property name="use_underline">True</property> |
224 | <signal name="activate" handler="virt_viewer_menu_send"/> | |
285 | <signal name="activate" handler="virt_viewer_window_menu_send" swapped="no"/> | |
225 | 286 | </object> |
226 | 287 | </child> |
227 | 288 | <child> |
228 | 289 | <object class="GtkMenuItem" id="menu-send-caf10"> |
229 | 290 | <property name="visible">True</property> |
291 | <property name="can_focus">False</property> | |
292 | <property name="use_action_appearance">False</property> | |
230 | 293 | <property name="label" translatable="yes">Ctrl+Alt+F1_0</property> |
231 | 294 | <property name="use_underline">True</property> |
232 | <signal name="activate" handler="virt_viewer_menu_send"/> | |
295 | <signal name="activate" handler="virt_viewer_window_menu_send" swapped="no"/> | |
233 | 296 | </object> |
234 | 297 | </child> |
235 | 298 | <child> |
236 | 299 | <object class="GtkMenuItem" id="menu-send-caf11"> |
237 | 300 | <property name="visible">True</property> |
301 | <property name="can_focus">False</property> | |
302 | <property name="use_action_appearance">False</property> | |
238 | 303 | <property name="label" translatable="yes">Ctrl+Alt+F11</property> |
239 | 304 | <property name="use_underline">True</property> |
240 | <signal name="activate" handler="virt_viewer_menu_send"/> | |
305 | <signal name="activate" handler="virt_viewer_window_menu_send" swapped="no"/> | |
241 | 306 | </object> |
242 | 307 | </child> |
243 | 308 | <child> |
244 | 309 | <object class="GtkMenuItem" id="menu-send-caf12"> |
245 | 310 | <property name="visible">True</property> |
311 | <property name="can_focus">False</property> | |
312 | <property name="use_action_appearance">False</property> | |
246 | 313 | <property name="label" translatable="yes">Ctrl+Alt+F12</property> |
247 | 314 | <property name="use_underline">True</property> |
248 | <signal name="activate" handler="virt_viewer_menu_send"/> | |
315 | <signal name="activate" handler="virt_viewer_window_menu_send" swapped="no"/> | |
249 | 316 | </object> |
250 | 317 | </child> |
251 | 318 | <child> |
252 | 319 | <object class="GtkSeparatorMenuItem" id="separatormenuitem3"> |
253 | 320 | <property name="visible">True</property> |
321 | <property name="can_focus">False</property> | |
254 | 322 | </object> |
255 | 323 | </child> |
256 | 324 | <child> |
257 | 325 | <object class="GtkMenuItem" id="menu-send-print"> |
258 | 326 | <property name="visible">True</property> |
327 | <property name="can_focus">False</property> | |
328 | <property name="use_action_appearance">False</property> | |
259 | 329 | <property name="label" translatable="yes">_PrintScreen</property> |
260 | 330 | <property name="use_underline">True</property> |
261 | <signal name="activate" handler="virt_viewer_menu_send"/> | |
331 | <signal name="activate" handler="virt_viewer_window_menu_send" swapped="no"/> | |
262 | 332 | </object> |
263 | 333 | </child> |
264 | 334 | </object> |
268 | 338 | <child> |
269 | 339 | <object class="GtkMenuItem" id="menu-help"> |
270 | 340 | <property name="visible">True</property> |
341 | <property name="can_focus">False</property> | |
342 | <property name="use_action_appearance">False</property> | |
271 | 343 | <property name="label" translatable="yes">_Help</property> |
272 | 344 | <property name="use_underline">True</property> |
273 | 345 | <child type="submenu"> |
274 | 346 | <object class="GtkMenu" id="menu3"> |
275 | 347 | <property name="visible">True</property> |
348 | <property name="can_focus">False</property> | |
276 | 349 | <child> |
277 | 350 | <object class="GtkImageMenuItem" id="imagemenuitem10"> |
278 | 351 | <property name="label">gtk-about</property> |
279 | 352 | <property name="visible">True</property> |
353 | <property name="can_focus">False</property> | |
354 | <property name="use_action_appearance">False</property> | |
280 | 355 | <property name="use_underline">True</property> |
281 | 356 | <property name="use_stock">True</property> |
282 | <signal name="activate" handler="virt_viewer_menu_help_about"/> | |
357 | <signal name="activate" handler="virt_viewer_window_menu_help_about" swapped="no"/> | |
283 | 358 | </object> |
284 | 359 | </child> |
285 | 360 | </object> |
289 | 364 | </object> |
290 | 365 | <packing> |
291 | 366 | <property name="expand">False</property> |
367 | <property name="fill">True</property> | |
292 | 368 | <property name="position">0</property> |
293 | 369 | </packing> |
294 | 370 | </child> |