Codebase list virt-viewer / 875aeef
Merge commit 'upstream/0.4.1' Laurent LĂ©onard 12 years ago
34 changed file(s) with 3350 addition(s) and 2760 deletion(s). Raw diff Collapse all Expand all
120120 AUTOHEADER = @AUTOHEADER@
121121 AUTOMAKE = @AUTOMAKE@
122122 AWK = @AWK@
123 CATALOGS = @CATALOGS@
124 CATOBJEXT = @CATOBJEXT@
125123 CC = @CC@
126124 CCDEPMODE = @CCDEPMODE@
127125 CFLAGS = @CFLAGS@
145143 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
146144 GLIB2_CFLAGS = @GLIB2_CFLAGS@
147145 GLIB2_LIBS = @GLIB2_LIBS@
148 GMOFILES = @GMOFILES@
149146 GMSGFMT = @GMSGFMT@
150147 GREP = @GREP@
151148 GTK_API_VERSION = @GTK_API_VERSION@
160157 INSTALL_PROGRAM = @INSTALL_PROGRAM@
161158 INSTALL_SCRIPT = @INSTALL_SCRIPT@
162159 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
163 INSTOBJEXT = @INSTOBJEXT@
164 INTLLIBS = @INTLLIBS@
165160 INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
166161 INTLTOOL_MERGE = @INTLTOOL_MERGE@
167162 INTLTOOL_PERL = @INTLTOOL_PERL@
181176 MAKEINFO = @MAKEINFO@
182177 MANIFEST_TOOL = @MANIFEST_TOOL@
183178 MKDIR_P = @MKDIR_P@
184 MKINSTALLDIRS = @MKINSTALLDIRS@
185179 MOZILLA_PLUGIN_CFLAGS = @MOZILLA_PLUGIN_CFLAGS@
186180 MOZILLA_PLUGIN_LIBS = @MOZILLA_PLUGIN_LIBS@
187181 MSGFMT = @MSGFMT@
188 MSGFMT_OPTS = @MSGFMT_OPTS@
189182 MSGMERGE = @MSGMERGE@
190183 NM = @NM@
191184 NMEDIT = @NMEDIT@
206199 PKG_CONFIG = @PKG_CONFIG@
207200 PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
208201 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@
213202 RANLIB = @RANLIB@
214203 SED = @SED@
215204 SET_MAKE = @SET_MAKE@
00 Virt Viewer News
11 ================
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
210
311 0.4.0: Jul 12, 2011
412 -------------------
1717 You have another version of autoconf. It may work, but is not guaranteed to.
1818 If you have problems, you may need to regenerate the build system entirely.
1919 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
45320
45421
45522 dnl IT_PROG_INTLTOOL([MINIMUM-VERSION], [no-xml])
00 /* config.h.in. Generated from configure.ac by autoheader. */
1
2 /* always defined to indicate that i18n is enabled */
3 #undef ENABLE_NLS
41
52 /* GETTEXT package name */
63 #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
134
145 /* Define to 1 if you have the <dlfcn.h> header file. */
156 #undef HAVE_DLFCN_H
178 /* Define to 1 if you have the `fork' function. */
189 #undef HAVE_FORK
1910
20 /* Define if the GNU gettext() function is already present or preinstalled. */
21 #undef HAVE_GETTEXT
22
2311 /* Define to 1 if you have the <inttypes.h> header file. */
2412 #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
3113
3214 /* Define to 1 if you have the <memory.h> header file. */
3315 #undef HAVE_MEMORY_H
00 #! /bin/sh
11 # 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.
33 #
44 #
55 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
566566 # Identity of this package.
567567 PACKAGE_NAME='virt-viewer'
568568 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'
571571 PACKAGE_BUGREPORT=''
572572 PACKAGE_URL=''
573573
645645 PKG_CONFIG_LIBDIR
646646 PKG_CONFIG_PATH
647647 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
659648 DATADIRNAME
660649 ALL_LINGUAS
661650 INTLTOOL_PERL
13881377 # Omit some internal or obsolete options to make the list less imposing.
13891378 # This message is too long to be a string in the A/UX 3.1 sh.
13901379 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.
13921381
13931382 Usage: $0 [OPTION]... [VAR=VALUE]...
13941383
14581447
14591448 if test -n "$ac_init_help"; then
14601449 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:";;
14621451 esac
14631452 cat <<\_ACEOF
14641453
16041593 test -n "$ac_init_help" && exit $ac_status
16051594 if $ac_init_version; then
16061595 cat <<\_ACEOF
1607 virt-viewer configure 0.4.0
1596 virt-viewer configure 0.4.1
16081597 generated by GNU Autoconf 2.68
16091598
16101599 Copyright (C) 2010 Free Software Foundation, Inc.
19691958 This file contains any messages produced by compilers while
19701959 running configure, to aid debugging if configure makes a mistake.
19711960
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
19731962 generated by GNU Autoconf 2.68. Invocation command line was
19741963
19751964 $ $0 $@
27872776
27882777 # Define the identity of the package.
27892778 PACKAGE='virt-viewer'
2790 VERSION='0.4.0'
2779 VERSION='0.4.1'
27912780
27922781
27932782 cat >>confdefs.h <<_ACEOF
1216412153
1216512154
1216612155
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
1287112156
1287212157
1287312158
1454913834 # report actual input values of CONFIG_FILES etc. instead of their
1455013835 # values after options handling.
1455113836 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
1455313838 generated by GNU Autoconf 2.68. Invocation command line was
1455413839
1455513840 CONFIG_FILES = $CONFIG_FILES
1461513900 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
1461613901 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
1461713902 ac_cs_version="\\
14618 virt-viewer config.status 0.4.0
13903 virt-viewer config.status 0.4.1
1461913904 configured by $0, generated by GNU Autoconf 2.68,
1462013905 with options \\"\$ac_cs_config\\"
1462113906
1501314298
1501414299
1501514300
15016
1501714301 _ACEOF
1501814302
1501914303 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
1502514309 "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
1502614310 "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
1502714311 "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
15028 "default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;;
1502914312 "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
1503014313 "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
1503114314 "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;;
1635515638 chmod +x "$ofile"
1635615639
1635715640 ;;
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 ;;
1636115641 "po/stamp-it":C)
1636215642 if ! grep "^# INTLTOOL_MAKEFILE$" "po/Makefile.in" > /dev/null ; then
1636315643 as_fn_error $? "po/Makefile.in.in was not created by intltoolize." "$LINENO" 5
00
1 AC_INIT(virt-viewer, 0.4.0)
1 AC_INIT(virt-viewer, 0.4.1)
22 AC_CONFIG_SRCDIR(src/virt-viewer-main.c)
33 AM_CONFIG_HEADER(config.h)
44 dnl Make automake keep quiet about wildcards & other GNUmake-isms
3232 AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [GETTEXT package name])
3333
3434 IT_PROG_INTLTOOL([0.35.0])
35 AM_GLIB_GNU_GETTEXT
3635
3736
3837 PKG_CHECK_MODULES(GLIB2, gmodule-export-2.0 >= $GLIB2_REQUIRED)
8888 AUTOHEADER = @AUTOHEADER@
8989 AUTOMAKE = @AUTOMAKE@
9090 AWK = @AWK@
91 CATALOGS = @CATALOGS@
92 CATOBJEXT = @CATOBJEXT@
9391 CC = @CC@
9492 CCDEPMODE = @CCDEPMODE@
9593 CFLAGS = @CFLAGS@
113111 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
114112 GLIB2_CFLAGS = @GLIB2_CFLAGS@
115113 GLIB2_LIBS = @GLIB2_LIBS@
116 GMOFILES = @GMOFILES@
117114 GMSGFMT = @GMSGFMT@
118115 GREP = @GREP@
119116 GTK_API_VERSION = @GTK_API_VERSION@
128125 INSTALL_PROGRAM = @INSTALL_PROGRAM@
129126 INSTALL_SCRIPT = @INSTALL_SCRIPT@
130127 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
131 INSTOBJEXT = @INSTOBJEXT@
132 INTLLIBS = @INTLLIBS@
133128 INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
134129 INTLTOOL_MERGE = @INTLTOOL_MERGE@
135130 INTLTOOL_PERL = @INTLTOOL_PERL@
149144 MAKEINFO = @MAKEINFO@
150145 MANIFEST_TOOL = @MANIFEST_TOOL@
151146 MKDIR_P = @MKDIR_P@
152 MKINSTALLDIRS = @MKINSTALLDIRS@
153147 MOZILLA_PLUGIN_CFLAGS = @MOZILLA_PLUGIN_CFLAGS@
154148 MOZILLA_PLUGIN_LIBS = @MOZILLA_PLUGIN_LIBS@
155149 MSGFMT = @MSGFMT@
156 MSGFMT_OPTS = @MSGFMT_OPTS@
157150 MSGMERGE = @MSGMERGE@
158151 NM = @NM@
159152 NMEDIT = @NMEDIT@
174167 PKG_CONFIG = @PKG_CONFIG@
175168 PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
176169 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@
181170 RANLIB = @RANLIB@
182171 SED = @SED@
183172 SET_MAKE = @SET_MAKE@
134134 AUTOHEADER = @AUTOHEADER@
135135 AUTOMAKE = @AUTOMAKE@
136136 AWK = @AWK@
137 CATALOGS = @CATALOGS@
138 CATOBJEXT = @CATOBJEXT@
139137 CC = @CC@
140138 CCDEPMODE = @CCDEPMODE@
141139 CFLAGS = @CFLAGS@
159157 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
160158 GLIB2_CFLAGS = @GLIB2_CFLAGS@
161159 GLIB2_LIBS = @GLIB2_LIBS@
162 GMOFILES = @GMOFILES@
163160 GMSGFMT = @GMSGFMT@
164161 GREP = @GREP@
165162 GTK_API_VERSION = @GTK_API_VERSION@
174171 INSTALL_PROGRAM = @INSTALL_PROGRAM@
175172 INSTALL_SCRIPT = @INSTALL_SCRIPT@
176173 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
177 INSTOBJEXT = @INSTOBJEXT@
178 INTLLIBS = @INTLLIBS@
179174 INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
180175 INTLTOOL_MERGE = @INTLTOOL_MERGE@
181176 INTLTOOL_PERL = @INTLTOOL_PERL@
195190 MAKEINFO = @MAKEINFO@
196191 MANIFEST_TOOL = @MANIFEST_TOOL@
197192 MKDIR_P = @MKDIR_P@
198 MKINSTALLDIRS = @MKINSTALLDIRS@
199193 MOZILLA_PLUGIN_CFLAGS = @MOZILLA_PLUGIN_CFLAGS@
200194 MOZILLA_PLUGIN_LIBS = @MOZILLA_PLUGIN_LIBS@
201195 MSGFMT = @MSGFMT@
202 MSGFMT_OPTS = @MSGFMT_OPTS@
203196 MSGMERGE = @MSGMERGE@
204197 NM = @NM@
205198 NMEDIT = @NMEDIT@
220213 PKG_CONFIG = @PKG_CONFIG@
221214 PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
222215 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@
227216 RANLIB = @RANLIB@
228217 SED = @SED@
229218 SET_MAKE = @SET_MAKE@
1010
1111 virt_viewer_SOURCES = \
1212 virt-viewer-main.c \
13 virt-viewer.h virt-viewer.c \
1314 virt-viewer-util.h virt-viewer-util.c \
1415 virt-viewer-auth.h virt-viewer-auth.c \
1516 virt-viewer-events.h virt-viewer-events.c \
16 virt-viewer.h virt-viewer.c \
17 virt-viewer-app.h virt-viewer-app.c \
1718 virt-viewer-session.h virt-viewer-session.c \
1819 virt-viewer-session-vnc.h virt-viewer-session-vnc.c \
1920 virt-viewer-display.h virt-viewer-display.c \
2021 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 \
2124 view/autoDrawer.c \
2225 view/autoDrawer.h \
2326 view/drawer.c \
5454 CONFIG_CLEAN_VPATH_FILES =
5555 am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(builderxmldir)"
5656 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 \
6162 virt-viewer-session-vnc.h virt-viewer-session-vnc.c \
6263 virt-viewer-display.h virt-viewer-display.c \
6364 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
6871 @HAVE_SPICE_GTK_TRUE@am__objects_1 = virt_viewer-virt-viewer-session-spice.$(OBJEXT) \
6972 @HAVE_SPICE_GTK_TRUE@ virt_viewer-virt-viewer-display-spice.$(OBJEXT)
7073 am_virt_viewer_OBJECTS = virt_viewer-virt-viewer-main.$(OBJEXT) \
74 virt_viewer-virt-viewer.$(OBJEXT) \
7175 virt_viewer-virt-viewer-util.$(OBJEXT) \
7276 virt_viewer-virt-viewer-auth.$(OBJEXT) \
7377 virt_viewer-virt-viewer-events.$(OBJEXT) \
74 virt_viewer-virt-viewer.$(OBJEXT) \
78 virt_viewer-virt-viewer-app.$(OBJEXT) \
7579 virt_viewer-virt-viewer-session.$(OBJEXT) \
7680 virt_viewer-virt-viewer-session-vnc.$(OBJEXT) \
7781 virt_viewer-virt-viewer-display.$(OBJEXT) \
7882 virt_viewer-virt-viewer-display-vnc.$(OBJEXT) \
83 virt_viewer-virt-viewer-notebook.$(OBJEXT) \
84 virt_viewer-virt-viewer-window.$(OBJEXT) \
7985 virt_viewer-autoDrawer.$(OBJEXT) virt_viewer-drawer.$(OBJEXT) \
8086 virt_viewer-ovBox.$(OBJEXT) $(am__objects_1)
8187 virt_viewer_OBJECTS = $(am_virt_viewer_OBJECTS)
148154 AUTOHEADER = @AUTOHEADER@
149155 AUTOMAKE = @AUTOMAKE@
150156 AWK = @AWK@
151 CATALOGS = @CATALOGS@
152 CATOBJEXT = @CATOBJEXT@
153157 CC = @CC@
154158 CCDEPMODE = @CCDEPMODE@
155159 CFLAGS = @CFLAGS@
173177 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
174178 GLIB2_CFLAGS = @GLIB2_CFLAGS@
175179 GLIB2_LIBS = @GLIB2_LIBS@
176 GMOFILES = @GMOFILES@
177180 GMSGFMT = @GMSGFMT@
178181 GREP = @GREP@
179182 GTK_API_VERSION = @GTK_API_VERSION@
188191 INSTALL_PROGRAM = @INSTALL_PROGRAM@
189192 INSTALL_SCRIPT = @INSTALL_SCRIPT@
190193 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
191 INSTOBJEXT = @INSTOBJEXT@
192 INTLLIBS = @INTLLIBS@
193194 INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
194195 INTLTOOL_MERGE = @INTLTOOL_MERGE@
195196 INTLTOOL_PERL = @INTLTOOL_PERL@
209210 MAKEINFO = @MAKEINFO@
210211 MANIFEST_TOOL = @MANIFEST_TOOL@
211212 MKDIR_P = @MKDIR_P@
212 MKINSTALLDIRS = @MKINSTALLDIRS@
213213 MOZILLA_PLUGIN_CFLAGS = @MOZILLA_PLUGIN_CFLAGS@
214214 MOZILLA_PLUGIN_LIBS = @MOZILLA_PLUGIN_LIBS@
215215 MSGFMT = @MSGFMT@
216 MSGFMT_OPTS = @MSGFMT_OPTS@
217216 MSGMERGE = @MSGMERGE@
218217 NM = @NM@
219218 NMEDIT = @NMEDIT@
234233 PKG_CONFIG = @PKG_CONFIG@
235234 PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
236235 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@
241236 RANLIB = @RANLIB@
242237 SED = @SED@
243238 SET_MAKE = @SET_MAKE@
308303 virt-viewer-auth.xml
309304
310305 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)
320318 virt_viewer_LDADD = \
321319 @GTK_VNC_LIBS@ \
322320 @SPICE_GTK_LIBS@ \
426424 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-autoDrawer.Po@am__quote@
427425 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-drawer.Po@am__quote@
428426 @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@
429428 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer-auth.Po@am__quote@
430429 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer-display-spice.Po@am__quote@
431430 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer-display-vnc.Po@am__quote@
432431 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer-display.Po@am__quote@
433432 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer-events.Po@am__quote@
434433 @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@
435435 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer-session-spice.Po@am__quote@
436436 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer-session-vnc.Po@am__quote@
437437 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer-session.Po@am__quote@
438438 @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@
439440 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-virt-viewer.Po@am__quote@
440441
441442 .c.o:
478479 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
479480 @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`
480481
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
481498 virt_viewer-virt-viewer-util.o: virt-viewer-util.c
482499 @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
483500 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/virt_viewer-virt-viewer-util.Tpo $(DEPDIR)/virt_viewer-virt-viewer-util.Po
526543 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
527544 @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`
528545
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`
544561
545562 virt_viewer-virt-viewer-session.o: virt-viewer-session.c
546563 @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
605622 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='virt-viewer-display-vnc.c' object='virt_viewer-virt-viewer-display-vnc.obj' libtool=no @AMDEPBACKSLASH@
606623 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
607624 @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`
608657
609658 virt_viewer-autoDrawer.o: view/autoDrawer.c
610659 @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
88 <property name="window_position">center-on-parent</property>
99 <property name="type_hint">dialog</property>
1010 <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>
1414 <property name="website">http://virt-manager.org/</property>
1515 <property name="website_label" translatable="yes">virt-manager.org</property>
1616 <property name="license" translatable="yes">This program is free software; you can redistribute it and/or modify
2727 along with this program; if not, write to the Free Software
2828 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2929 </property>
30 <property name="authors">Daniel P. Berrange</property>
30 <property name="authors">Daniel P. Berrange
31 Marc-André Lureau
32 </property>
3133 <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"/>
3436 <child internal-child="vbox">
3537 <object class="GtkVBox" id="dialog-vbox1">
3638 <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 */
6262 message = g_strdup_printf("Authentication is required for the %s connection to:\n\n"
6363 "<b>%s</b>\n\n",
6464 type,
65 address ? address : "[unknown]");
65 address);
6666 } else {
6767 message = g_strdup_printf("Authentication is required for the %s connection:\n",
6868 type);
9999 }
100100
101101 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)
110105 {
111 DEBUG_LOG("desktop resize %dx%d", width, height);
106 DEBUG_LOG("display mark %d", mark);
112107
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");
115125 }
116126
117127
120130 SpiceDisplay *display)
121131 {
122132 VirtViewerDisplaySpice *self;
133 gint channelid;
123134
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);
125137
126 self->priv->channel = channel;
127 self->priv->display = display;
138 g_object_get(channel, "channel-id", &channelid, NULL);
128139
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);
131145
132146 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);
134150
135151 gtk_container_add(GTK_CONTAINER(self), GTK_WIDGET(self->priv->display));
136152 gtk_widget_show(GTK_WIDGET(self->priv->display));
3939 #define VIRT_VIEWER_DISPLAY_SPICE_CLASS(klass) \
4040 (G_TYPE_CHECK_CLASS_CAST ((klass), VIRT_VIEWER_TYPE_DISPLAY_SPICE, VirtViewerDisplaySpiceClass))
4141
42 #define VIRT_IS_VIEWER_DISPLAY_SPICE(obj) \
42 #define VIRT_VIEWER_IS_DISPLAY_SPICE(obj) \
4343 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIRT_VIEWER_TYPE_DISPLAY_SPICE))
4444
45 #define VIRT_IS_VIEWER_DISPLAY_SPICE_CLASS(klass) \
45 #define VIRT_VIEWER_IS_DISPLAY_SPICE_CLASS(klass) \
4646 (G_TYPE_CHECK_CLASS_TYPE ((klass), VIRT_VIEWER_TYPE_DISPLAY_SPICE))
4747
4848 #define VIRT_VIEWER_DISPLAY_SPICE_GET_CLASS(obj) \
3838 #define VIRT_VIEWER_DISPLAY_VNC_CLASS(klass) \
3939 (G_TYPE_CHECK_CLASS_CAST ((klass), VIRT_VIEWER_TYPE_DISPLAY_VNC, VirtViewerDisplayVncClass))
4040
41 #define VIRT_IS_VIEWER_DISPLAY_VNC(obj) \
41 #define VIRT_VIEWER_IS_DISPLAY_VNC(obj) \
4242 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIRT_VIEWER_TYPE_DISPLAY_VNC))
4343
44 #define VIRT_IS_VIEWER_DISPLAY_VNC_CLASS(klass) \
44 #define VIRT_VIEWER_IS_DISPLAY_VNC_CLASS(klass) \
4545 (G_TYPE_CHECK_CLASS_TYPE ((klass), VIRT_VIEWER_TYPE_DISPLAY_VNC))
4646
4747 #define VIRT_VIEWER_DISPLAY_VNC_GET_CLASS(obj) \
3737 guint desktopHeight;
3838 guint zoom_level;
3939 gboolean zoom;
40 gint nth_display;
41 gint show_hint;
4042 };
4143
4244 static void virt_viewer_display_size_request(GtkWidget *widget,
6769
6870 PROP_DESKTOP_WIDTH,
6971 PROP_DESKTOP_HEIGHT,
72 PROP_NTH_DISPLAY,
7073 PROP_ZOOM,
7174 PROP_ZOOM_LEVEL,
75 PROP_SHOW_HINT,
7276 };
7377
7478 static void
97101 G_MAXINT32,
98102 100,
99103 G_PARAM_READWRITE));
104
100105 g_object_class_install_property(object_class,
101106 PROP_DESKTOP_HEIGHT,
102107 g_param_spec_int("desktop-height",
106111 G_MAXINT32,
107112 100,
108113 G_PARAM_READWRITE));
114
109115 g_object_class_install_property(object_class,
110116 PROP_ZOOM,
111117 g_param_spec_boolean("zoom",
113119 "Zoom",
114120 TRUE,
115121 G_PARAM_READWRITE));
122
116123 g_object_class_install_property(object_class,
117124 PROP_ZOOM_LEVEL,
118125 g_param_spec_int("zoom-level",
123130 100,
124131 G_PARAM_READWRITE));
125132
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
126154
127155 g_signal_new("display-pointer-grab",
128156 G_OBJECT_CLASS_TYPE(object_class),
205233 {
206234 VirtViewerDisplay *display = VIRT_VIEWER_DISPLAY(object);
207235 VirtViewerDisplayPrivate *priv = display->priv;
208
236
209237 switch (prop_id) {
210238 case PROP_DESKTOP_WIDTH:
211239 virt_viewer_display_set_desktop_size(display,
217245 priv->desktopWidth,
218246 g_value_get_int(value));
219247 break;
220
248 case PROP_NTH_DISPLAY:
249 priv->nth_display = g_value_get_int(value);
250 break;
221251 default:
222252 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
223253 break;
232262 {
233263 VirtViewerDisplay *display = VIRT_VIEWER_DISPLAY(object);
234264 VirtViewerDisplayPrivate *priv = display->priv;
235
265
236266 switch (prop_id) {
237267 case PROP_DESKTOP_WIDTH:
238268 g_value_set_int(value, priv->desktopWidth);
240270 case PROP_DESKTOP_HEIGHT:
241271 g_value_set_int(value, priv->desktopHeight);
242272 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
244280 default:
245281 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
246282 break;
443479 return VIRT_VIEWER_DISPLAY_GET_CLASS(display)->get_pixbuf(display);
444480 }
445481
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
446495 /*
447496 * Local variables:
448497 * c-indent-level: 8
5050
5151 typedef struct _VirtViewerDisplayChannel VirtViewerDisplayChannel;
5252
53 enum {
54 VIRT_VIEWER_DISPLAY_SHOW_HINT_HIDE = 0,
55 VIRT_VIEWER_DISPLAY_SHOW_HINT_READY,
56 };
5357
5458 /* perhaps this become an interface, and be pushed in gtkvnc and spice? */
5559 struct _VirtViewerDisplay {
9296 void virt_viewer_display_set_zoom(VirtViewerDisplay *display,
9397 gboolean zoom);
9498
95 void virt_viewer_display_send_keys(VirtViewerDisplay* display,
99 void virt_viewer_display_send_keys(VirtViewerDisplay *display,
96100 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);
98103
99104 G_END_DECLS
100105
5050 gboolean waitvm = FALSE;
5151 gboolean reconnect = FALSE;
5252 gboolean fullscreen = FALSE;
53 VirtViewer *viewer = NULL;
5354 const char *help_msg = N_("Run '" PACKAGE " --help' to see a full list of available command line options");
5455 const GOptionEntry options [] = {
5556 { "version", 'V', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
106107 goto cleanup;
107108 }
108109
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;
112119
113120 gtk_main();
114121
115 cleanup:
122 ret = 0;
123
124 cleanup:
125 if (viewer)
126 g_object_unref(viewer);
116127 g_free(uri);
117128 g_strfreev(args);
118129
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 */
232232
233233 if (SPICE_IS_DISPLAY_CHANNEL(channel)) {
234234 GtkWidget *display;
235 if (id != 0)
236 return;
237235
238236 g_signal_emit_by_name(session, "session-connected");
239237
3939 #define VIRT_VIEWER_SESSION_SPICE_CLASS(klass) \
4040 (G_TYPE_CHECK_CLASS_CAST ((klass), VIRT_VIEWER_TYPE_SESSION_SPICE, VirtViewerSessionSpiceClass))
4141
42 #define VIRT_IS_VIEWER_SESSION_SPICE(obj) \
42 #define VIRT_VIEWER_IS_SESSION_SPICE(obj) \
4343 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIRT_VIEWER_TYPE_SESSION_SPICE))
4444
45 #define VIRT_IS_VIEWER_SESSION_SPICE_CLASS(klass) \
45 #define VIRT_VIEWER_IS_SESSION_SPICE_CLASS(klass) \
4646 (G_TYPE_CHECK_CLASS_TYPE ((klass), VIRT_VIEWER_TYPE_SESSION_SPICE))
4747
4848 #define VIRT_VIEWER_SESSION_SPICE_GET_CLASS(obj) \
8585 {
8686 GtkWidget *display = virt_viewer_display_vnc_new(session->priv->vnc);
8787 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);
8890 virt_viewer_session_add_display(VIRT_VIEWER_SESSION(session),
8991 VIRT_VIEWER_DISPLAY(display));
9092 }
9496 VirtViewerSessionVnc *session)
9597 {
9698 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); */
97102 }
98103
99104 static void
3838 #define VIRT_VIEWER_SESSION_VNC_CLASS(klass) \
3939 (G_TYPE_CHECK_CLASS_CAST ((klass), VIRT_VIEWER_TYPE_SESSION_VNC, VirtViewerSessionVncClass))
4040
41 #define VIRT_IS_VIEWER_SESSION_VNC(obj) \
41 #define VIRT_VIEWER_IS_SESSION_VNC(obj) \
4242 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIRT_VIEWER_TYPE_SESSION_VNC))
4343
44 #define VIRT_IS_VIEWER_SESSION_VNC_CLASS(klass) \
44 #define VIRT_VIEWER_IS_SESSION_VNC_CLASS(klass) \
4545 (G_TYPE_CHECK_CLASS_TYPE ((klass), VIRT_VIEWER_TYPE_SESSION_VNC))
4646
4747 #define VIRT_VIEWER_SESSION_VNC_GET_CLASS(obj) \
2525 #include <sys/types.h>
2626 #include <sys/stat.h>
2727 #include <unistd.h>
28 #include <string.h>
29 #include <libxml/xpath.h>
30 #include <libxml/uri.h>
2831
2932 #include "virt-viewer-util.h"
3033
5053 return builder;
5154 }
5255
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 }
53108
54109 /*
55110 * Local variables:
3232
3333
3434 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);
3541
3642 #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 */
3939 #include <libxml/xpath.h>
4040 #include <libxml/uri.h>
4141
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
5542 #include "virt-viewer.h"
43 #include "virt-viewer-app.h"
5644 #include "virt-viewer-events.h"
5745 #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 {
14748 char *uri;
14849 virConnectPtr conn;
14950 char *domkey;
15051 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;
16652 gboolean withEvents;
167
168 gboolean active;
169
170 gboolean accelEnabled;
171 GValue accelSetting;
172 GSList *accelList;
173 int accelMenuSig[LAST_MENU];
174
17553 gboolean waitvm;
17654 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;
19655 };
19756
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);
312124 }
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);
313128 } 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 }
676132
677133 static int
678134 virt_viewer_parse_uuid(const char *name,
718174
719175
720176 static virDomainPtr
721 virt_viewer_lookup_domain(VirtViewer *viewer)
177 virt_viewer_lookup_domain(VirtViewer *self)
722178 {
723179 char *end;
724 int id = strtol(viewer->domkey, &end, 10);
180 VirtViewerPrivate *priv = self->priv;
181 int id = strtol(priv->domkey, &end, 10);
725182 virDomainPtr dom = NULL;
726183 unsigned char uuid[16];
727184
728185 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);
733190 }
734191 if (!dom) {
735 dom = virDomainLookupByName(viewer->conn, viewer->domkey);
192 dom = virDomainLookupByName(priv->conn, priv->domkey);
736193 }
737194 return dom;
738195 }
739196
740197 static int
741 virt_viewer_matches_domain(VirtViewer *viewer,
198 virt_viewer_matches_domain(VirtViewer *self,
742199 virDomainPtr dom)
743200 {
744201 char *end;
745202 const char *name;
746 int id = strtol(viewer->domkey, &end, 10);
203 VirtViewerPrivate *priv = self->priv;
204 int id = strtol(priv->domkey, &end, 10);
747205 unsigned char wantuuid[16];
748206 unsigned char domuuid[16];
749207
751209 if (virDomainGetID(dom) == id)
752210 return 1;
753211 }
754 if (virt_viewer_parse_uuid(viewer->domkey, wantuuid) == 0) {
212 if (virt_viewer_parse_uuid(priv->domkey, wantuuid) == 0) {
755213 virDomainGetUUID(dom, domuuid);
756214 if (memcmp(wantuuid, domuuid, VIR_UUID_BUFLEN) == 0)
757215 return 1;
758216 }
759217
760218 name = virDomainGetName(dom);
761 if (strcmp(name, viewer->domkey) == 0)
219 if (strcmp(name, priv->domkey) == 0)
762220 return 1;
763221
764222 return 0;
810268 return port;
811269 }
812270
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
1076271 static gboolean
1077 virt_viewer_extract_connect_info(VirtViewer *viewer,
272 virt_viewer_extract_connect_info(VirtViewer *self,
1078273 virDomainPtr dom)
1079274 {
1080275 char *type = NULL;
1081276 char *xpath = NULL;
1082277 gboolean retval = FALSE;
1083278 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);
1086290
1087291 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);
1090294 goto cleanup;
1091295 }
1092296
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)
1108298 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);
1132299
1133300 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) {
1135302 free(xpath);
1136303 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);
1140307 goto cleanup;
1141308 }
1142309 } else {
1143310 free(xpath);
1144311 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);
1152319 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);
1158325 goto cleanup;
1159326 }
1160327
328 virt_viewer_app_set_connect_info(app, host, ghost, gport, transport, unixsock, user, port);
329
1161330 retval = TRUE;
1162331
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);
1164339 g_free(type);
1165340 g_free(xpath);
1166341 g_free(xmldesc);
1167342 return retval;
1168343 }
1169344
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
1202345 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))
1241356 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 }
1432361
1433362 static int
1434363 virt_viewer_domain_event(virConnectPtr conn G_GNUC_UNUSED,
1437366 int detail G_GNUC_UNUSED,
1438367 void *opaque)
1439368 {
1440 VirtViewer *viewer = opaque;
369 VirtViewer *self = opaque;
370 VirtViewerApp *app = VIRT_VIEWER_APP(self);
1441371
1442372 DEBUG_LOG("Got domain event %d %d", event, detail);
1443373
1444 if (!virt_viewer_matches_domain(viewer, dom))
374 if (!virt_viewer_matches_domain(self, dom))
1445375 return 0;
1446
376
1447377 switch (event) {
1448378 case VIR_DOMAIN_EVENT_STOPPED:
1449 //virt_viewer_deactivate(viewer);
379 //virt_viewer_deactivate(self);
1450380 break;
1451381
1452382 case VIR_DOMAIN_EVENT_STARTED:
1453 virt_viewer_activate(viewer, dom);
383 virt_viewer_update_display(self, dom);
384 virt_viewer_app_activate(app);
1454385 break;
1455386 }
1456387
1457388 return 0;
1458389 }
1459390
1460
1461391 static int
1462 virt_viewer_initial_connect(VirtViewer *viewer)
392 virt_viewer_initial_connect(VirtViewerApp *app)
1463393 {
1464394 virDomainPtr dom = NULL;
1465395 virDomainInfo info;
1466396 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);
1470402 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);
1475407 goto done;
1476408 } 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);
1480412 goto cleanup;
1481413 }
1482414 }
1483415
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"));
1488420 if (virDomainGetInfo(dom, &info) < 0) {
1489421 DEBUG_LOG("Cannot get guest state");
1490422 goto cleanup;
1491423 }
1492424
1493425 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"));
1495427 } 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);
1497431 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);
1502436 } else {
1503437 DEBUG_LOG("Failed to activate viewer");
1504438 goto cleanup;
1518452 return ret;
1519453 }
1520454
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
1576455 static void
1577456 virt_viewer_error_func (void *data G_GNUC_UNUSED,
1578457 virErrorPtr error G_GNUC_UNUSED)
1580459 /* nada */
1581460 }
1582461
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;
1597467 int cred_types[] =
1598468 { VIR_CRED_AUTHNAME, VIR_CRED_PASSPHRASE };
1599469 virConnectAuth auth_libvirt = {
1600470 .credtype = cred_types,
1601471 .ncredtype = ARRAY_CARDINALITY(cred_types),
1602472 .cb = virt_viewer_auth_libvirt_credentials,
1603 .cbdata = (void *)uri,
473 .cbdata = (void *)priv->uri,
1604474 };
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);
1620475
1621476 virt_viewer_events_register();
1622477
1623478 virSetErrorFunc(NULL, virt_viewer_error_func);
1624479
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,
1696496 virt_viewer_domain_event,
1697 viewer,
497 self,
1698498 NULL) < 0)
1699 viewer->withEvents = FALSE;
499 priv->withEvents = FALSE;
1700500 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)) {
1705505 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 }
1714544
1715545 /*
1716546 * Local variables:
2222 #ifndef VIRT_VIEWER_H
2323 #define VIRT_VIEWER_H
2424
25 #include "virt-viewer-util.h"
25 #include <glib-object.h>
26 #include "virt-viewer-app.h"
2627
27 typedef struct _VirtViewer VirtViewer;
28 G_BEGIN_DECLS
2829
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
3961
4062 #endif /* VIRT_VIEWER_H */
0 <?xml version="1.0"?>
0 <?xml version="1.0" encoding="UTF-8"?>
11 <interface>
22 <!-- interface-requires gtk+ 2.6 -->
3 <!-- interface-naming-policy toplevel-contextual -->
43 <object class="GtkWindow" id="viewer">
4 <property name="can_focus">False</property>
55 <property name="default_width">400</property>
66 <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"/>
88 <child>
99 <object class="GtkVBox" id="viewer-box">
1010 <property name="visible">True</property>
11 <property name="orientation">vertical</property>
11 <property name="can_focus">False</property>
1212 <child>
1313 <object class="GtkMenuBar" id="top-menu">
1414 <property name="visible">True</property>
15 <property name="can_focus">False</property>
1516 <child>
1617 <object class="GtkMenuItem" id="menu-file">
1718 <property name="visible">True</property>
19 <property name="can_focus">False</property>
20 <property name="use_action_appearance">False</property>
1821 <property name="label" translatable="yes">_File</property>
1922 <property name="use_underline">True</property>
2023 <child type="submenu">
2124 <object class="GtkMenu" id="menu1">
2225 <property name="visible">True</property>
26 <property name="can_focus">False</property>
2327 <child>
2428 <object class="GtkMenuItem" id="menu-file-screenshot">
2529 <property name="visible">True</property>
30 <property name="can_focus">False</property>
31 <property name="use_action_appearance">False</property>
2632 <property name="label" translatable="yes">Screenshot</property>
2733 <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"/>
2935 </object>
3036 </child>
3137 <child>
3238 <object class="GtkSeparatorMenuItem" id="separatormenuitem1">
3339 <property name="visible">True</property>
40 <property name="can_focus">False</property>
3441 </object>
3542 </child>
3643 <child>
3744 <object class="GtkImageMenuItem" id="imagemenuitem5">
3845 <property name="label">gtk-quit</property>
3946 <property name="visible">True</property>
47 <property name="can_focus">False</property>
48 <property name="use_action_appearance">False</property>
4049 <property name="use_underline">True</property>
4150 <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"/>
4453 </object>
4554 </child>
4655 </object>
5059 <child>
5160 <object class="GtkMenuItem" id="menu-view">
5261 <property name="visible">True</property>
62 <property name="can_focus">False</property>
63 <property name="use_action_appearance">False</property>
5364 <property name="label" translatable="yes">_View</property>
5465 <property name="use_underline">True</property>
5566 <child type="submenu">
5667 <object class="GtkMenu" id="menu2">
5768 <property name="visible">True</property>
69 <property name="can_focus">False</property>
5870 <child>
5971 <object class="GtkCheckMenuItem" id="menu-view-fullscreen">
6072 <property name="visible">True</property>
73 <property name="can_focus">False</property>
74 <property name="use_action_appearance">False</property>
6175 <property name="label" translatable="yes">Full screen</property>
6276 <property name="use_underline">True</property>
6377 <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"/>
6579 </object>
6680 </child>
6781 <child>
6882 <object class="GtkMenuItem" id="menu-view-zoom">
6983 <property name="visible">True</property>
84 <property name="can_focus">False</property>
85 <property name="use_action_appearance">False</property>
7086 <property name="label" translatable="yes">_Zoom</property>
7187 <property name="use_underline">True</property>
7288 <child type="submenu">
7389 <object class="GtkMenu" id="menu4">
7490 <property name="visible">True</property>
91 <property name="can_focus">False</property>
7592 <child>
7693 <object class="GtkImageMenuItem" id="menu-view-zoom-in">
94 <property name="label">gtk-zoom-in</property>
7795 <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>
7998 <property name="use_underline">True</property>
8099 <property name="use_stock">True</property>
81100 <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"/>
83102 </object>
84103 </child>
85104 <child>
86105 <object class="GtkImageMenuItem" id="menu-view-zoom-out">
106 <property name="label">gtk-zoom-out</property>
87107 <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>
89110 <property name="use_underline">True</property>
90111 <property name="use_stock">True</property>
91112 <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"/>
93114 </object>
94115 </child>
95116 <child>
96117 <object class="GtkSeparatorMenuItem" id="separatormenuitem4">
97118 <property name="visible">True</property>
119 <property name="can_focus">False</property>
98120 </object>
99121 </child>
100122 <child>
101123 <object class="GtkImageMenuItem" id="menu-view-zoom-reset">
124 <property name="label">gtk-zoom-100</property>
102125 <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>
104128 <property name="use_underline">True</property>
105129 <property name="use_stock">True</property>
106130 <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"/>
108132 </object>
109133 </child>
110134 </object>
114138 <child>
115139 <object class="GtkCheckMenuItem" id="menu-view-resize">
116140 <property name="visible">True</property>
141 <property name="can_focus">False</property>
142 <property name="use_action_appearance">False</property>
117143 <property name="label" translatable="yes">Automatically resize</property>
118144 <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>
120155 </object>
121156 </child>
122157 </object>
126161 <child>
127162 <object class="GtkMenuItem" id="menu-send">
128163 <property name="visible">True</property>
164 <property name="can_focus">False</property>
165 <property name="use_action_appearance">False</property>
129166 <property name="label" translatable="yes">_Send key</property>
130167 <property name="use_underline">True</property>
131168 <child type="submenu">
132169 <object class="GtkMenu" id="menu5">
133170 <property name="visible">True</property>
171 <property name="can_focus">False</property>
134172 <child>
135173 <object class="GtkMenuItem" id="menu-send-cad">
136174 <property name="visible">True</property>
175 <property name="can_focus">False</property>
176 <property name="use_action_appearance">False</property>
137177 <property name="label" translatable="yes">Ctrl+Alt+_Del</property>
138178 <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"/>
140180 </object>
141181 </child>
142182 <child>
143183 <object class="GtkMenuItem" id="menu-send-cab">
144184 <property name="visible">True</property>
185 <property name="can_focus">False</property>
186 <property name="use_action_appearance">False</property>
145187 <property name="label" translatable="yes">Ctrl+Alt+_Backspace</property>
146188 <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"/>
148190 </object>
149191 </child>
150192 <child>
151193 <object class="GtkSeparatorMenuItem" id="separatormenuitem2">
152194 <property name="visible">True</property>
195 <property name="can_focus">False</property>
153196 </object>
154197 </child>
155198 <child>
156199 <object class="GtkMenuItem" id="menu-send-caf1">
157200 <property name="visible">True</property>
201 <property name="can_focus">False</property>
202 <property name="use_action_appearance">False</property>
158203 <property name="label" translatable="yes">Ctrl+Alt+F_1</property>
159204 <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"/>
161206 </object>
162207 </child>
163208 <child>
164209 <object class="GtkMenuItem" id="menu-send-caf2">
165210 <property name="visible">True</property>
211 <property name="can_focus">False</property>
212 <property name="use_action_appearance">False</property>
166213 <property name="label" translatable="yes">Ctrl+Alt+F_2</property>
167214 <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"/>
169216 </object>
170217 </child>
171218 <child>
172219 <object class="GtkMenuItem" id="menu-send-caf3">
173220 <property name="visible">True</property>
221 <property name="can_focus">False</property>
222 <property name="use_action_appearance">False</property>
174223 <property name="label" translatable="yes">Ctrl+Alt+F_3</property>
175224 <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"/>
177226 </object>
178227 </child>
179228 <child>
180229 <object class="GtkMenuItem" id="menu-send-caf4">
181230 <property name="visible">True</property>
231 <property name="can_focus">False</property>
232 <property name="use_action_appearance">False</property>
182233 <property name="label" translatable="yes">Ctrl+Alt+F_4</property>
183234 <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"/>
185236 </object>
186237 </child>
187238 <child>
188239 <object class="GtkMenuItem" id="menu-send-caf5">
189240 <property name="visible">True</property>
241 <property name="can_focus">False</property>
242 <property name="use_action_appearance">False</property>
190243 <property name="label" translatable="yes">Ctrl+Alt+F_5</property>
191244 <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"/>
193246 </object>
194247 </child>
195248 <child>
196249 <object class="GtkMenuItem" id="menu-send-caf6">
197250 <property name="visible">True</property>
251 <property name="can_focus">False</property>
252 <property name="use_action_appearance">False</property>
198253 <property name="label" translatable="yes">Ctrl+Alt+F_6</property>
199254 <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"/>
201256 </object>
202257 </child>
203258 <child>
204259 <object class="GtkMenuItem" id="menu-send-caf7">
205260 <property name="visible">True</property>
261 <property name="can_focus">False</property>
262 <property name="use_action_appearance">False</property>
206263 <property name="label" translatable="yes">Ctrl+Alt+F_7</property>
207264 <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"/>
209266 </object>
210267 </child>
211268 <child>
212269 <object class="GtkMenuItem" id="menu-send-caf8">
213270 <property name="visible">True</property>
271 <property name="can_focus">False</property>
272 <property name="use_action_appearance">False</property>
214273 <property name="label" translatable="yes">Ctrl+Alt+F_8</property>
215274 <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"/>
217276 </object>
218277 </child>
219278 <child>
220279 <object class="GtkMenuItem" id="menu-send-caf9">
221280 <property name="visible">True</property>
281 <property name="can_focus">False</property>
282 <property name="use_action_appearance">False</property>
222283 <property name="label" translatable="yes">Ctrl+Alt+F_9</property>
223284 <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"/>
225286 </object>
226287 </child>
227288 <child>
228289 <object class="GtkMenuItem" id="menu-send-caf10">
229290 <property name="visible">True</property>
291 <property name="can_focus">False</property>
292 <property name="use_action_appearance">False</property>
230293 <property name="label" translatable="yes">Ctrl+Alt+F1_0</property>
231294 <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"/>
233296 </object>
234297 </child>
235298 <child>
236299 <object class="GtkMenuItem" id="menu-send-caf11">
237300 <property name="visible">True</property>
301 <property name="can_focus">False</property>
302 <property name="use_action_appearance">False</property>
238303 <property name="label" translatable="yes">Ctrl+Alt+F11</property>
239304 <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"/>
241306 </object>
242307 </child>
243308 <child>
244309 <object class="GtkMenuItem" id="menu-send-caf12">
245310 <property name="visible">True</property>
311 <property name="can_focus">False</property>
312 <property name="use_action_appearance">False</property>
246313 <property name="label" translatable="yes">Ctrl+Alt+F12</property>
247314 <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"/>
249316 </object>
250317 </child>
251318 <child>
252319 <object class="GtkSeparatorMenuItem" id="separatormenuitem3">
253320 <property name="visible">True</property>
321 <property name="can_focus">False</property>
254322 </object>
255323 </child>
256324 <child>
257325 <object class="GtkMenuItem" id="menu-send-print">
258326 <property name="visible">True</property>
327 <property name="can_focus">False</property>
328 <property name="use_action_appearance">False</property>
259329 <property name="label" translatable="yes">_PrintScreen</property>
260330 <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"/>
262332 </object>
263333 </child>
264334 </object>
268338 <child>
269339 <object class="GtkMenuItem" id="menu-help">
270340 <property name="visible">True</property>
341 <property name="can_focus">False</property>
342 <property name="use_action_appearance">False</property>
271343 <property name="label" translatable="yes">_Help</property>
272344 <property name="use_underline">True</property>
273345 <child type="submenu">
274346 <object class="GtkMenu" id="menu3">
275347 <property name="visible">True</property>
348 <property name="can_focus">False</property>
276349 <child>
277350 <object class="GtkImageMenuItem" id="imagemenuitem10">
278351 <property name="label">gtk-about</property>
279352 <property name="visible">True</property>
353 <property name="can_focus">False</property>
354 <property name="use_action_appearance">False</property>
280355 <property name="use_underline">True</property>
281356 <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"/>
283358 </object>
284359 </child>
285360 </object>
289364 </object>
290365 <packing>
291366 <property name="expand">False</property>
367 <property name="fill">True</property>
292368 <property name="position">0</property>
293369 </packing>
294370 </child>
1919 %endif
2020
2121 Name: virt-viewer
22 Version: 0.4.0
22 Version: 0.4.1
2323 Release: 1%{?dist}%{?extra_release}
2424 Summary: Virtual Machine Viewer
2525 Group: Applications/System