1 /* Monolith window class.
2 * - by Richard W.M. Jones <rich@annexia.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 * $Id: ml_window.c,v 1.8 2003/04/30 13:15:34 rich Exp $
31 #include <pthr_http.h>
34 #include "ml_window.h"
38 pool pool; /* Pool for allocations. */
39 const char *windowid; /* Window ID. */
41 /* For ordinary windows: */
42 ml_widget w; /* Packed widget. */
43 int headers_flag; /* If set, emit start, end of page. */
44 const char *title; /* Title of the window. */
45 const char *stylesheet; /* Stylesheet for the window. */
46 const char *charset; /* Character encoding. */
47 int refresh; /* Refresh period (0 = no refresh). */
48 int scroll_to_x, scroll_to_y; /* Scroll to (x, y). */
51 const char *rows, *cols; /* Layout. */
52 vector frames; /* Frames (vector of struct
53 * ml_frame_description). */
54 vector actions; /* Action IDs (one per frame). */
57 const char *uri; /* URI to redirect to. */
59 /* Javascript cookies to set (see _ml_window_set_cookie_with_javascript). */
63 static int next_window_id = 0;
66 new_ml_window (ml_session session, pool pool)
68 ml_window w = pmalloc (pool, sizeof *w);
74 /* XXX Eventually take this from the default theme for the application? */
75 w->stylesheet = "/ml-styles/default.css";
78 w->scroll_to_x = w->scroll_to_y = 0;
80 w->rows = w->cols = 0;
85 w->js_cookies = new_vector (pool, const char *);
87 /* Register and set current window. */
88 w->windowid = pitoa (pool, ++next_window_id);
89 _ml_session_set_current_window (session, w, w->windowid);
95 ml_window_pack (ml_window w, ml_widget _w)
101 ml_window_set_headers_flag (ml_window w, int headers_flag)
103 w->headers_flag = headers_flag;
107 ml_window_get_headers_flag (ml_window w)
109 return w->headers_flag;
113 ml_window_set_title (ml_window w, const char *title)
119 ml_window_get_title (ml_window w)
125 ml_window_set_stylesheet (ml_window w, const char *stylesheet)
127 w->stylesheet = stylesheet;
131 ml_window_get_stylesheet (ml_window w)
133 return w->stylesheet;
137 ml_window_set_charset (ml_window w, const char *_charset)
139 w->charset = _charset;
143 ml_window_get_charset (ml_window w)
149 ml_window_set_refresh (ml_window w, int refresh)
151 w->refresh = refresh;
155 ml_window_get_refresh (ml_window w)
161 ml_window_scroll_to (ml_window w, int x, int y)
167 static void update_actions (ml_window w, ml_session session);
170 new_ml_frameset (ml_session session, pool pool,
171 const char *rows, const char *cols, vector frames)
173 ml_window w = new_ml_window (session, pool);
178 update_actions (w, session);
184 ml_frameset_set_description (ml_window w, ml_session session,
185 const char *rows, const char *cols, vector frames)
190 update_actions (w, session);
194 ml_frameset_set_title (ml_window w, const char *title)
200 ml_frameset_get_title (ml_window w)
206 update_actions (ml_window w, ml_session session)
209 const char *actionid;
210 struct ml_frame_description frame;
214 /* Unregister the old actions. */
215 for (i = 0; i < vector_size (w->actions); ++i)
217 vector_get (w->actions, i, actionid);
218 ml_unregister_action (session, actionid);
220 vector_clear (w->actions);
223 w->actions = new_vector (w->pool, const char *);
225 if (w->frames && vector_size (w->frames) > 0)
227 /* Register new actions. */
228 for (i = 0; i < vector_size (w->frames); ++i)
230 vector_get (w->frames, i, frame);
231 actionid = ml_register_action (session, frame.fn, frame.data);
232 vector_push_back (w->actions, actionid);
238 new_ml_redirect (ml_session session, pool pool,
241 ml_window w = new_ml_window (session, pool);
249 ml_redirect_set_uri (ml_window w, const char *uri)
255 ml_redirect_get_uri (ml_window w)
261 _ml_window_notify_begin_response (ml_window w)
263 vector_clear (w->js_cookies);
267 _ml_window_get_response_code (ml_window w)
269 if (! w->uri) return 200;
274 _ml_window_get_response_name (ml_window w)
276 if (! w->uri) return "OK";
277 else return "Moved Permanently";
280 /* To allow shared object scripts to be embedded in pages using
281 * mod_include we must set the session cookie using Javascript. This
282 * is because mod_include doesn't propagate the Set-Cookie header from
283 * a #include to the outer set of headers.
285 * NB. 'cookie' is allocated on the thread pool.
288 _ml_window_set_cookie_with_javascript (ml_window w,
291 vector_push_back (w->js_cookies, cookie);
295 set_cookies_with_javascript (ml_window w, io_handle io)
297 while (vector_size (w->js_cookies) > 0)
301 vector_pop_front (w->js_cookies, cookie);
303 "<script language=\"javascript\"><!--\n"
304 "document.cookie = '%s';\n"
311 _ml_window_send_headers (ml_window w, pool thread_pool,
312 http_response http_response)
316 /* Send the Content-Type: header. */
317 http_response_send_header
319 "Content-Type", psprintf (thread_pool,
320 "text/html; charset=%s",
323 /* Refresh period? */
325 http_response_send_header
327 "Refresh", pitoa (thread_pool, w->refresh));
331 /* Send the Location: header. */
332 http_response_send_header (http_response, "Location", w->uri);
334 /* Send the Content-Length: header. */
335 http_response_send_header (http_response, "Content-Length", "0");
340 _ml_window_get_windowid (ml_window w)
346 _ml_window_repaint (ml_window w, ml_session session, io_handle io)
348 if (!w->frames && !w->uri) /* Ordinary window. */
355 "PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" "
356 "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
357 "<html xmlns=\"http://www.w3.org/1999/xhtml\" "
358 "xml:lang=\"en\" lang=\"en\">\n"
362 io_fprintf (io, "<title>%s</title>\n", w->title);
366 "<link rel=\"stylesheet\" "
367 "href=\"%s\" type=\"text/css\">\n",
370 io_fprintf (io, "</head><body>\n");
373 set_cookies_with_javascript (w, io);
376 ml_widget_repaint (w->w, session, w->windowid, io);
378 if (w->scroll_to_x > 0 || w->scroll_to_y > 0)
382 "<script language=\"javascript\"><!--\n"
383 "window.scrollTo (%d, %d);\n"
385 w->scroll_to_x, w->scroll_to_y);
389 io_fprintf (io, "</body></html>\n");
391 else if (w->frames) /* Frameset. */
398 "PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" "
399 "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">\n"
400 "<html xmlns=\"http://www.w3.org/1999/xhtml\" "
401 "xml:lang=\"en\" lang=\"en\">\n"
405 io_fprintf (io, "<title>%s</title>\n", w->title);
407 io_fprintf (io, "</head><frameset");
410 io_fprintf (io, " rows=\"%s\"", w->rows);
412 io_fprintf (io, " cols=\"%s\"", w->cols);
414 io_fprintf (io, ">");
416 for (i = 0; i < vector_size (w->frames); ++i)
418 /* struct ml_frame_description frame; */
419 const char *actionid;
421 /* vector_get (w->frames, i, frame); */
422 vector_get (w->actions, i, actionid);
424 io_fprintf (io, "<frame src=\"%s?ml_action=%s\" />",
425 ml_session_script_name (session), actionid);
428 io_fprintf (io, "</frameset></html>\n");