gnome-shell/src/run-js-test.c
Owen W. Taylor c98103ffc8 Add run-js-test executable to run tests
ST makes use of GTK+ for input methods and for icon themes; therefore
we have need to initialize GTK+ in order to test these parts of Clutter.

Instead of LD_PRELOADING our module, use a separately compiled executable
that links to the UI components in GNOME Shell, initializes Clutter and
GTK+ and hooks them together.

Getting all the symbols from St and the GUI components exported for
use via GJS requires a bit of contortion: we need to actually link the
St convenience library into a shared library and link the executable
to that since there is no way with libtool to take a convenience library
and put all its symbols into an executable --whole-archive style.

https://bugzilla.gnome.org/show_bug.cgi?id=633657
2010-11-12 17:36:20 -05:00

145 lines
4.3 KiB
C

/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Based on gjs/console.c from GJS
*
* Copyright (c) 2008 litl, LLC
* Copyright (c) 2010 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include <config.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <clutter/x11/clutter-x11.h>
#include <string.h>
#include <stdlib.h>
#include <locale.h>
#include <gjs/gjs.h>
static char **include_path = NULL;
static char *command = NULL;
static GOptionEntry entries[] = {
{ "command", 'c', 0, G_OPTION_ARG_STRING, &command, "Program passed in as a string", "COMMAND" },
{ "include-path", 'I', 0, G_OPTION_ARG_STRING_ARRAY, &include_path, "Add the directory DIR to the list of directories to search for js files.", "DIR" },
{ NULL }
};
static GdkFilterReturn
event_filter (GdkXEvent *xevent,
GdkEvent *event,
gpointer data)
{
XEvent *xev = (XEvent *)xevent;
if (clutter_x11_handle_event (xev) == CLUTTER_X11_FILTER_CONTINUE)
return GDK_FILTER_CONTINUE;
else
return GDK_FILTER_REMOVE;
}
int
main(int argc, char **argv)
{
char *command_line;
GOptionContext *context;
ClutterActor *stage;
GError *error = NULL;
GjsContext *js_context;
char *script;
const char *filename;
char *title;
gsize len;
int code;
g_thread_init (NULL);
gtk_init (&argc, &argv);
clutter_x11_set_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
clutter_x11_disable_event_retrieval ();
clutter_init (&argc, &argv);
gdk_window_add_filter (NULL, event_filter, NULL);
context = g_option_context_new (NULL);
/* pass unknown through to the JS script */
g_option_context_set_ignore_unknown_options (context, TRUE);
g_option_context_add_main_entries (context, entries, NULL);
if (!g_option_context_parse (context, &argc, &argv, &error))
g_error ("option parsing failed: %s", error->message);
setlocale (LC_ALL, "");
g_type_init ();
command_line = g_strjoinv (" ", argv);
g_debug ("Command line: %s", command_line);
g_free (command_line);
g_debug ("Creating new context to eval console script");
js_context = gjs_context_new_with_search_path (include_path);
/* prepare command line arguments */
if (!gjs_context_define_string_array (js_context, "ARGV",
argc - 2, (const char**)argv + 2,
&error)) {
g_printerr ("Failed to defined ARGV: %s", error->message);
exit (1);
}
if (command != NULL) {
script = command;
len = strlen (script);
filename = "<command line>";
} else if (argc <= 1) {
script = g_strdup ("const Console = imports.console; Console.interact();");
len = strlen (script);
filename = "<stdin>";
} else /*if (argc >= 2)*/ {
error = NULL;
if (!g_file_get_contents (argv[1], &script, &len, &error)) {
g_printerr ("%s\n", error->message);
exit (1);
}
filename = argv[1];
}
stage = clutter_stage_get_default ();
title = g_filename_display_basename (filename);
clutter_stage_set_title (CLUTTER_STAGE (stage), title);
g_free (title);
/* evaluate the script */
error = NULL;
if (!gjs_context_eval (js_context, script, len,
filename, &code, &error)) {
g_free (script);
g_printerr ("%s\n", error->message);
exit (1);
}
g_free (script);
exit (code);
}