1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 // mopen1.cpp: Moonlight Open Application
8 // Rolf Bjarne Kvinge (RKvinge@novell.com)
11 // See LICENSE file in the Moonlight distribution for licensing details
14 // Implement everything mopen implements
27 #include "downloader.h"
31 #include "window-gtk.h"
32 #include "frameworkelement.h"
37 get_video_size (const char *filename
, int *width
, int *height
)
40 FileSource
*src
= NULL
;
41 ASFParser
*parser
= NULL
;
43 const asf_stream_properties
* stream_properties
;
44 const asf_video_stream_data
* video_data
;
45 const BITMAPINFOHEADER
* bmp
;
47 src
= new FileSource (NULL
, filename
);
48 if (!MEDIA_SUCCEEDED (tmp
= src
->Initialize ())) {
49 fprintf (stderr
, "mopen1: Error while opening the file %s\n", filename
);
53 parser
= new ASFParser (src
, NULL
);
54 if (!MEDIA_SUCCEEDED (tmp
= parser
->ReadHeader ())) {
55 fprintf (stderr
, "mopen1: Error while reading asf header in file %s\n", filename
);
59 for (int i
= 0; i
<= 127; i
++) {
60 if (!parser
->IsValidStream (i
))
63 stream_properties
= parser
->GetStream (i
);
65 if (!stream_properties
->is_video ())
68 video_data
= stream_properties
->get_video_data ();
73 bmp
= video_data
->get_bitmap_info_header ();
78 *width
= bmp
->image_width
;
79 *height
= bmp
->image_height
;
95 printf ("Usage is: mopen1 [args] [file.xaml]\n\n"
97 " --media <filename> Automatically creates some xaml with a MediaElement whose source is set to the filename\n"
98 " This is also automatically assumed if 1 filename is passed and the extension is either\n"
99 " wmv, wma, vc1, asf or mp3.\n"
100 " --timeout T Time, in seconds, before closing the window\n"
104 " --desklet Remove window decoration for desklets use\n" +
105 " --fixed Disable window resizing\n" +
106 " --geometry WxH Overrides the geometry to be W x H pixels\n" +
107 " --host NAME Specifies that this file should be loaded in host NAME\n" +
108 " --parseonly Only parse (don't display) the XAML input\n" +
109 " --story N1[,Nx] Plays the storyboard name N1, N2, .. Nx when the clicked\n" +
110 " -s,--stories Automatically prepare to play all stories on click\n" +
111 " --sync Make the gdk connection synchronous\n" +
112 " --transparent Transparent toplevel\n" +
117 class FileDownloadState
{
119 FileDownloadState (Downloader
*dl
) : uri(NULL
), downloader(dl
) { }
121 virtual ~FileDownloadState () { Close (); }
125 void Abort () { Close (); }
126 char* GetResponseText (char *fname
, char* PartName
) { return NULL
; } // XXX
127 void Open (const char *verb
, const char *uri
)
129 int fd
= open (uri
, O_RDONLY
);
131 const char *msg
= g_strerror (errno
);
132 printf ("downloader failed to open %s: %s\n", uri
, msg
);
133 downloader
->NotifyFailed (msg
);
140 this->uri
= g_strdup (uri
);
142 downloader
->NotifySize (size
);
147 downloader
->NotifyFinished (uri
);
156 Downloader
*downloader
;
160 downloader_create_state (Downloader
*dl
)
162 return new FileDownloadState (dl
);
166 downloader_destroy_state (gpointer data
)
168 delete ((FileDownloadState
*)data
);
172 downloader_open (gpointer state
, const char *verb
, const char *uri
, bool streaming
, bool disable_cache
)
174 ((FileDownloadState
*)state
)->Open (verb
, uri
);
178 downloader_send (gpointer state
)
180 ((FileDownloadState
*)state
)->Send ();
184 downloader_abort (gpointer state
)
186 ((FileDownloadState
*)state
)->Abort ();
190 downloader_header (gpointer state
, const char *header
, const char *value
)
192 g_assert_not_reached ();
196 downloader_body (gpointer state
, void *body
, guint32 length
)
198 g_assert_not_reached ();
202 *downloader_request (const char *method
, const char *uri
, gpointer context
)
204 g_assert_not_reached ();
208 delete_event (GtkWidget
*widget
, GdkEvent
*e
, gpointer data
)
215 static int LoadXaml (const char* file
)
219 runtime_init_desktop();
221 char* dir
= g_path_get_dirname (file
);
224 // printf ("nopen: %s\n", strerror (errno));
226 file
= g_basename (file
);
228 Downloader::SetFunctions (downloader_create_state
,
229 downloader_destroy_state
,
241 MoonWindowGtk
*moon_window
= new MoonWindowGtk (false, 300, 300);
242 Surface
* surface
= new Surface (moon_window
);
243 XamlLoader
* loader
= new XamlLoader (file
, NULL
, surface
);
244 DependencyObject
* dob
= loader
->CreateDependencyObjectFromFile (file
, FALSE
, &et
);
249 printf ("nopen::LoadXaml ('%s'): Could not create xaml from the file.\n", file
);
251 } else if (dob
->Is (Type::CANVAS
)) {
253 Canvas
* ui
= (Canvas
*) dob
;
254 surface
->Attach ((Canvas
*) ui
);
257 int width
= ui
->GetWidth ();
258 int height
= ui
->GetHeight ();
265 surface
->Resize (width
, height
);
269 window
= gtk_window_new (GTK_WINDOW_TOPLEVEL
);
270 gtk_widget_set_app_paintable (window
, TRUE
);
272 gtk_signal_connect (GTK_OBJECT (window
), "delete-event", G_CALLBACK (delete_event
), surface
);
273 gtk_container_add (GTK_CONTAINER(window
), moon_window
->GetWidget ());
275 gtk_widget_set_usize (window
, width
, height
);
277 gtk_widget_show_all (window
);
282 printf ("nopen::LoadXaml ('%s'): didn't get an uielement from the xaml.\n", file
);
291 printf ("Shutting down...\n");
297 QuitTimeout (gpointer data
)
305 main (int argc
, char *argv
[])
308 const char *media_extensions
[] = { ".wmv", ".wma", ".vc1", ".asf", ".mp3", NULL
};
309 const char *media_filename
= NULL
;
310 const char *filename
= NULL
;
311 const char *tmpfile
= NULL
;
313 int media_height
= 0;
316 // quick out if no arguments are provided
322 gtk_init (&argc
, &argv
);
323 g_thread_init (NULL
);
327 for (int i
= 1; i
< argc
; i
++) {
328 if (!strcmp (argv
[i
], "--media")) {
333 media_filename
= argv
[++i
];
334 } else if (!strcmp (argv
[i
], "--timeout")) {
339 timeout
= atoi (argv
[++i
]);
341 if (filename
!= NULL
) {
346 for (int j
= 0; media_extensions
[j
] != NULL
&& media_filename
== NULL
; j
++) {
347 if (g_str_has_suffix (filename
, media_extensions
[j
]))
348 media_filename
= filename
;
353 if (media_filename
) {
356 tmpfile
= "mopen1.default.xaml";
358 if (!get_video_size (media_filename
, &media_width
, &media_height
)) {
359 fprintf (stdout
, "mopen1: Could not get video size, using 400x300.\n");
364 xaml
= g_strdup_printf (
365 "<Canvas xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' Width='%i' Height='%i'>\n"
366 " <MediaElement x:Name='TestVideo' Width='%i' Height='%i' Source='%s'/>\n"
367 "</Canvas>\n", media_width
, media_height
, media_width
, media_height
, media_filename
);
369 if (!g_file_set_contents (tmpfile
, xaml
, -1, NULL
)) {
370 fprintf (stderr
, "mopen1: Error while writing temporary file.\n");
380 g_timeout_add (timeout
* 1000, QuitTimeout
, NULL
);
384 result
= LoadXaml (filename
);