/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ /* commands.c --- menus and toolbar. Created: Jamie Zawinski , 27-Jun-94. */ #include "mozilla.h" #include "xfe.h" #include "felocale.h" #include "xlate.h" #include "menu.h" #include "net.h" #include "e_kit.h" #include "prefapi.h" #include "intl_csi.h" #include #ifdef FORTEZZA #include "ssl.h" #endif #include "selection.h" #include "outline.h" #include "layers.h" #ifdef EDITOR #include "xeditor.h" #include "edt.h" /* just for EDT_MailDocument() */ #endif /*EDITOR*/ #ifdef MOZ_MAIL_NEWS #include "msgcom.h" #include "msg_srch.h" #include "mailnews.h" #endif /* MOZ_MAIL_NEWS */ #include "il_icons.h" /* Image icon enumeration. */ #include "mozjava.h" #ifdef X_PLUGINS #include "np.h" #endif /* X_PLUGINS */ #ifndef NO_WEB_FONTS #include "nf.h" #endif /* NO_WEB_FONTS */ #include #include /* for XP_GetString() */ #include extern int XFE_COMMANDS_UPLOAD_FILE; extern int XFE_CANNOT_SEE_FILE; extern int XFE_CANNOT_READ_FILE; extern int XFE_IS_A_DIRECTORY; extern int XFE_UNKNOWN_ESCAPE_CODE; extern int XFE_LOG_IN_AS; extern int XFE_COULDNT_FORK; extern int XFE_EXECVP_FAILED; extern int XFE_OUT_OF_MEMORY_URL; extern int XFE_COMMANDS_OPEN_URL_USAGE; extern int XFE_COMMANDS_HTML_HELP_USAGE; extern int XFE_COMMANDS_UNPARSABLE_ENCODING_FILTER_SPEC; extern int XFE_NETSCAPE_MAIL; extern int XFE_NETSCAPE_NEWS; extern int XFE_BOOKMARKS; extern int XFE_ADDRESS_BOOK; extern int XFE_DOWNLOAD_FILE; extern int XFE_COMPOSE_NO_SUBJECT; extern int XFE_COMPOSE; extern int XFE_NETSCAPE_UNTITLED; extern int XFE_NETSCAPE; extern int XFE_COMMANDS_MAIL_TO_USAGE; extern char* help_menu_names[]; extern char* directory_menu_names[]; extern MWContext * fe_reuseBrowser(MWContext *context,URL_Struct *url); /* Local forward declarations */ extern void fe_InsertMessageCompositionText(MWContext *context, const char *text, XP_Bool leaveCursorAtBeginning); extern void fe_mailfilter_cb(Widget, XtPointer, XtPointer); /* Externs from dialog.c: */ extern int fe_await_synchronous_url (MWContext *context); /* Externs from mozilla.c */ extern char * fe_MakeSashGeometry(char *old_geom_str, int pane_config, unsigned int w, unsigned int h); static void fe_page_forward_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; Widget sb = CONTEXT_DATA (context)->vscroll; XmScrollBarCallbackStruct cb; int pi = 0, v = 0, max = 1, min = 0; XP_ASSERT(sb); if (!sb) return; XtVaGetValues (sb, XmNpageIncrement, &pi, XmNvalue, &v, XmNmaximum, &max, XmNminimum, &min, 0); cb.reason = XmCR_PAGE_INCREMENT; cb.event = 0; cb.pixel = 0; cb.value = v + pi; if (cb.value > max - pi) cb.value = max - pi; if (cb.value < min) cb.value = min; XtCallCallbacks (sb, XmNvalueChangedCallback, &cb); } static void fe_page_backward_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; Widget sb = CONTEXT_DATA (context)->vscroll; XmScrollBarCallbackStruct cb; int pi = 0, v = 0, min = 0; XP_ASSERT(sb); if (!sb) return; fe_UserActivity (context); XtVaGetValues (sb, XmNpageIncrement, &pi, XmNvalue, &v, XmNminimum, &min, 0); cb.reason = XmCR_PAGE_INCREMENT; cb.event = 0; cb.pixel = 0; cb.value = v - pi; if (cb.value < min) cb.value = min; XtCallCallbacks (sb, XmNvalueChangedCallback, &cb); } static void fe_line_forward_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; Widget sb = CONTEXT_DATA (context)->vscroll; XmScrollBarCallbackStruct cb; int li = 0, v = 0, max = 1, min = 0; #ifdef EDITOR if (context->is_editor) return; #endif /* EDITOR */ XP_ASSERT(sb); if (!sb) return; fe_UserActivity (context); XtVaGetValues (sb, XmNincrement, &li, XmNvalue, &v, XmNmaximum, &max, XmNminimum, &min, 0); cb.reason = XmCR_INCREMENT; cb.event = 0; cb.pixel = 0; cb.value = v + li; if (cb.value > max - li) cb.value = max - li; if (cb.value < min) cb.value = min; XtCallCallbacks (sb, XmNvalueChangedCallback, &cb); } static void fe_line_backward_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; Widget sb = CONTEXT_DATA (context)->vscroll; XmScrollBarCallbackStruct cb; int li = 0, v = 0, min = 0; #ifdef EDITOR if (context->is_editor) return; #endif /* EDITOR */ XP_ASSERT(sb); if (!sb) return; fe_UserActivity (context); XtVaGetValues (sb, XmNincrement, &li, XmNvalue, &v, XmNminimum, &min, 0); cb.reason = XmCR_INCREMENT; cb.event = 0; cb.pixel = 0; cb.value = v - li; if (cb.value < min) cb.value = min; XtCallCallbacks (sb, XmNvalueChangedCallback, &cb); } static void fe_column_forward_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; Widget sb = CONTEXT_DATA (context)->hscroll; XmScrollBarCallbackStruct cb; int li = 0, v = 0, min = 0; XP_ASSERT(sb); if (!sb) return; fe_UserActivity (context); XtVaGetValues (sb, XmNincrement, &li, XmNvalue, &v, XmNminimum, &min, 0); cb.reason = XmCR_INCREMENT; cb.event = 0; cb.pixel = 0; cb.value = v - li; if (cb.value < min) cb.value = min; XtCallCallbacks (sb, XmNvalueChangedCallback, &cb); } static void fe_column_backward_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; Widget sb = CONTEXT_DATA (context)->hscroll; XmScrollBarCallbackStruct cb; int li = 0, v = 0, max = 1, min = 0; XP_ASSERT(sb); if (!sb) return; fe_UserActivity (context); XtVaGetValues (sb, XmNincrement, &li, XmNvalue, &v, XmNmaximum, &max, XmNminimum, &min, 0); cb.reason = XmCR_INCREMENT; cb.event = 0; cb.pixel = 0; cb.value = v + li; if (cb.value > max - li) cb.value = max - li; if (cb.value < min) cb.value = min; XtCallCallbacks (sb, XmNvalueChangedCallback, &cb); } /* File menu */ static void fe_open_url_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; fe_UserActivity (context); fe_OpenURLDialog(context); } void fe_upload_file_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; XmString xm_title; char *title = XP_GetString(XFE_COMMANDS_UPLOAD_FILE); char *file, *msg; fe_UserActivity (context); file = fe_ReadFileName (context, title, 0, True, 0); /* validate filename */ if (file) { if (!fe_isFileExist(file)) { msg = PR_smprintf( XP_GetString( XFE_CANNOT_SEE_FILE ), file); if (msg) { XFE_Alert(context, msg); XP_FREE(msg); } XP_FREE (file); file = NULL; } else if (!fe_isFileReadable(file)) { msg = PR_smprintf( XP_GetString( XFE_CANNOT_READ_FILE ) , file); if (msg) { XFE_Alert(context, msg); XP_FREE(msg); } XP_FREE (file); file = NULL; } else if (fe_isDir(file)) { msg = PR_smprintf( XP_GetString( XFE_IS_A_DIRECTORY ), file); if (msg) { XFE_Alert(context, msg); if (msg) XP_FREE(msg); } XP_FREE (file); file = NULL; } } if (file) { History_entry *he = SHIST_GetCurrent (&context->hist); URL_Struct *url; if (he && he->address && (XP_STRNCMP (he->address, "ftp://", 6) == 0) && he->address [strlen (he->address)-1] == '/') { url = NET_CreateURLStruct (he->address, NET_SUPER_RELOAD); if (!url) { XP_FREE (file); return; } url->method = URL_POST_METHOD; url->files_to_post = XP_ALLOC (2); if (!url->files_to_post) { XP_FREE (file); return; } url->files_to_post [0] = XP_STRDUP ((const char *) file); url->files_to_post [1] = 0; fe_GetURL (context, url, FALSE); } XP_FREE (file); } } void fe_reload_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; XmPushButtonCallbackStruct *cd = (XmPushButtonCallbackStruct *) call_data; fe_UserActivity (context); if (cd && cd->event->xkey.state & ShiftMask) fe_ReLayout (context, NET_SUPER_RELOAD); else fe_ReLayout (context, NET_NORMAL_RELOAD); } /* not static -- it's needed by src/HTMLView.cpp */ void fe_abort_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; fe_UserActivity (context); fe_AbortCallback (widget, closure, call_data); } void fe_refresh_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; Widget wid; Display *dpy; Window win; Dimension w = 0, h = 0; XGCValues gcv; GC gc; if (fe_IsGridParent (context)) context = fe_GetFocusGridOfContext (context); XP_ASSERT (context); if (!context) return; wid = CONTEXT_DATA (context)->drawing_area; if (wid == NULL) return; dpy = XtDisplay (wid); win = XtWindow (wid); fe_UserActivity (context); XtVaGetValues (wid, XmNbackground, &gcv.foreground, XmNwidth, &w, XmNheight, &h, 0); gc = XCreateGC (dpy, win, GCForeground, &gcv); XFillRectangle (dpy, win, gc, 0, 0, w, h); XFreeGC (dpy, gc); if (context->compositor) { XP_Rect rect; rect.left = CONTEXT_DATA(context)->document_x; rect.top = CONTEXT_DATA(context)->document_y; rect.right = rect.left + w; rect.bottom = rect.top + h; CL_UpdateDocumentRect(context->compositor, &rect, (PRBool)FALSE); } } char **fe_encoding_extensions = 0; /* gag. used by mkcache.c. */ #ifdef EDITOR /* * Hack, hack, hack. These are in editor.c, please move the menu * definition there. */ extern void fe_editor_view_source_cb(Widget, XtPointer, XtPointer); extern void fe_editor_edit_source_cb(Widget, XtPointer, XtPointer); extern void fe_editor_browse_doc_cb(Widget, XtPointer, XtPointer); extern void fe_editor_about_cb(Widget, XtPointer, XtPointer); extern void fe_editor_open_file_cb(Widget, XtPointer, XtPointer); extern void fe_editor_edit_cb(Widget, XtPointer, XtPointer); extern void fe_editor_paragraph_style_menu_cb(Widget, XtPointer, XtPointer); extern void fe_editor_paragraph_style_cb(Widget, XtPointer, XtPointer); extern void fe_editor_new_cb(Widget, XtPointer, XtPointer); extern void fe_editor_new_from_wizard_cb(Widget, XtPointer, XtPointer); extern void fe_editor_new_from_template_cb(Widget, XtPointer, XtPointer); extern void fe_editor_open_file_cb(Widget, XtPointer, XtPointer); extern void fe_editor_save_cb(Widget, XtPointer, XtPointer); extern void fe_editor_save_as_cb(Widget, XtPointer, XtPointer); extern void fe_editor_edit_menu_cb(Widget, XtPointer, XtPointer); extern void fe_editor_undo_cb(Widget, XtPointer, XtPointer); extern void fe_editor_redo_cb(Widget, XtPointer, XtPointer); extern void fe_editor_view_menu_cb(Widget, XtPointer, XtPointer); extern void fe_editor_properties_menu_cb(Widget, XtPointer, XtPointer); extern void fe_editor_hrule_properties_cb(Widget, XtPointer, XtPointer); extern void fe_editor_display_tables_cb(Widget, XtPointer, XtPointer); extern void fe_editor_paragraph_marks_cb(Widget, XtPointer, XtPointer); extern void fe_editor_insert_menu_cb(Widget, XtPointer, XtPointer); extern void fe_editor_insert_link_cb(Widget, XtPointer, XtPointer); extern void fe_editor_insert_target_cb(Widget, XtPointer, XtPointer); extern void fe_editor_insert_image_cb(Widget, XtPointer, XtPointer); extern void fe_editor_insert_hrule_dialog_cb(Widget, XtPointer, XtPointer); extern void fe_editor_insert_html_cb(Widget, XtPointer, XtPointer); extern void fe_editor_insert_line_break_cb(Widget, XtPointer, XtPointer); extern void fe_editor_insert_non_breaking_space_cb(Widget,XtPointer,XtPointer); extern void fe_editor_char_props_menu_cb(Widget, XtPointer, XtPointer); extern void fe_editor_toggle_char_props_cb(Widget, XtPointer, XtPointer); extern void fe_editor_char_props_cb(Widget, XtPointer, XtPointer); extern void fe_editor_clear_char_props_cb(Widget, XtPointer, XtPointer); extern void fe_editor_font_size_menu_cb(Widget, XtPointer, XtPointer); extern void fe_editor_font_size_cb(Widget, XtPointer, XtPointer); extern void fe_editor_paragraph_props_menu_cb(Widget, XtPointer, XtPointer); extern void fe_editor_paragraph_props_cb(Widget, XtPointer, XtPointer); extern void fe_editor_indent_cb(Widget, XtPointer, XtPointer); extern void fe_editor_properties_dialog_cb(Widget, XtPointer, XtPointer); extern void fe_editor_delete_cb(Widget, XtPointer, XtPointer); extern void fe_editor_refresh_cb(Widget, XtPointer, XtPointer); extern void fe_editor_insert_hrule_cb(Widget, XtPointer, XtPointer); extern void fe_editor_cut_cb(Widget, XtPointer, XtPointer); extern void fe_editor_copy_cb(Widget, XtPointer, XtPointer); extern void fe_editor_paste_cb(Widget, XtPointer, XtPointer); extern void fe_editor_table_menu_cb(Widget, XtPointer, XtPointer); extern void fe_editor_table_insert_cb(Widget, XtPointer, XtPointer); extern void fe_editor_table_row_insert_cb(Widget, XtPointer, XtPointer); extern void fe_editor_table_column_insert_cb(Widget, XtPointer, XtPointer); extern void fe_editor_table_cell_insert_cb(Widget, XtPointer, XtPointer); extern void fe_editor_table_delete_cb(Widget, XtPointer, XtPointer); extern void fe_editor_table_row_delete_cb(Widget, XtPointer, XtPointer); extern void fe_editor_table_column_delete_cb(Widget, XtPointer, XtPointer); extern void fe_editor_table_cell_delete_cb(Widget, XtPointer, XtPointer); extern void fe_editor_file_menu_cb(Widget, XtPointer, XtPointer); extern void fe_editor_document_properties_dialog_cb(Widget, XtPointer, XtPointer); extern void fe_editor_preferences_dialog_cb(Widget, XtPointer, XtPointer); extern void fe_editor_target_properties_dialog_cb(Widget, XtPointer, XtPointer); extern void fe_editor_html_properties_dialog_cb(Widget, XtPointer, XtPointer); extern void fe_editor_table_properties_dialog_cb(Widget, XtPointer, XtPointer); extern void fe_editor_publish_cb(Widget, XtPointer, XtPointer); extern void fe_editor_find_cb(Widget, XtPointer, XtPointer); extern void fe_editor_find_again_cb(Widget, XtPointer, XtPointer); extern void fe_editor_windows_menu_cb(Widget, XtPointer, XtPointer); extern void fe_editor_select_all_cb(Widget, XtPointer, XtPointer); extern void fe_editor_delete_item_cb(Widget, XtPointer, XtPointer); extern void fe_editor_select_table_cb(Widget, XtPointer, XtPointer); extern void fe_editor_reload_cb(Widget, XtPointer, XtPointer); extern void fe_editor_set_colors_dialog_cb(Widget, XtPointer, XtPointer); extern void fe_editor_default_color_cb(Widget, XtPointer, XtPointer); extern void fe_editor_remove_links_cb(Widget, XtPointer, XtPointer); extern void fe_editor_open_url_cb(Widget, XtPointer, XtPointer); extern void fe_editor_options_menu_cb(Widget, XtPointer, XtPointer); extern void fe_editor_browse_publish_location_cb(Widget, XtPointer, XtPointer); #endif /* EDITOR */ /* not static -- it's needed by src/HTMLView.cpp */ void fe_save_as_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; URL_Struct *url; fe_UserActivity (context); { MWContext *ctx = fe_GetFocusGridOfContext (context); if (ctx) context = ctx; } url = SHIST_CreateWysiwygURLStruct (context, SHIST_GetCurrent (&context->hist)); if (url) fe_SaveURL (context, url); else FE_Alert (context, fe_globalData.no_url_loaded_message); } /* not static -- it's needed by src/HTMLView.cpp */ void fe_save_top_frame_as_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; URL_Struct *url; fe_UserActivity (context); url = SHIST_CreateWysiwygURLStruct (context, SHIST_GetCurrent (&context->hist)); if (url) fe_SaveURL (context, url); else FE_Alert (context, fe_globalData.no_url_loaded_message); } static unsigned int fe_save_as_stream_write_ready_method (NET_StreamClass *stream) { return(MAX_WRITE_READY); } struct view_source_data { MWContext *context; Widget widget; }; void fe_view_source_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; History_entry *h; URL_Struct *url; char *new_url_add=0; h = SHIST_GetCurrent (&context->hist); url = SHIST_CreateURLStructFromHistoryEntry(context, h); if (! url) { FE_Alert (context, fe_globalData.no_url_loaded_message); return; } /* check to make sure it doesn't already have a view-source * prefix. If it does then this window is already viewing * the source of another window. In this case just * show the same thing by reloading the url... */ if(strncmp(VIEW_SOURCE_URL_PREFIX, url->address, sizeof(VIEW_SOURCE_URL_PREFIX)-1)) { /* prepend VIEW_SOURCE_URL_PREFIX to the url to * get the netlib to display the source view */ StrAllocCopy(new_url_add, VIEW_SOURCE_URL_PREFIX); StrAllocCat(new_url_add, url->address); free(url->address); url->address = new_url_add; } /* make damn sure the form_data slot is zero'd or else all * hell will break loose */ XP_MEMSET (&url->savedData, 0, sizeof (SHIST_SavedData)); #ifdef EDITOR if (EDT_IS_EDITOR(context) && !FE_CheckAndSaveDocument(context)) return; #endif /* fe_GetSecondaryURL (context, url, FO_PRESENT, NULL, FALSE); */ fe_GetURL (context, url, FALSE); } static int fe_view_source_stream_write_method (NET_StreamClass *stream, const char *str, int32 len) { struct view_source_data *vsd = (struct view_source_data *) stream->data_object; char buf [1024]; XmTextPosition pos, cpos; if (!vsd || !vsd->widget) return -1; pos = XmTextGetLastPosition (vsd->widget); cpos = 0; XtVaGetValues (vsd->widget, XmNcursorPosition, &cpos, 0); /* We copy the data first because XmTextInsert() needs a null-terminated string, and there isn't necessarily room on the end of `str' for us to plop down a null. */ while (len > 0) { int i; int L = (len > (sizeof(buf)-1) ? (sizeof(buf)-1) : len); memcpy (buf, str, L); buf [L] = 0; str += L; len -= L; /* Crockishly translate CR to LF for the Motif text widget... */ for (i = 0; i < L; i++) if (buf[i] == '\r' && buf[i+1] != '\n') buf[i] = '\n'; XmTextInsert (vsd->widget, pos, buf); pos += L; } XtVaSetValues (vsd->widget, XmNcursorPosition, cpos, 0); return 1; } static void fe_view_source_stream_complete_method (NET_StreamClass *stream) { struct view_source_data *vsd = (struct view_source_data *) stream->data_object; free (vsd); } static void fe_view_source_stream_abort_method (NET_StreamClass *stream, int status) { struct view_source_data *vsd = (struct view_source_data *) stream->data_object; free (vsd); } /* Creates and returns a stream object which writes the data read into a text widget. */ NET_StreamClass * fe_MakeViewSourceStream (int format_out, void *data_obj, URL_Struct *url_struct, MWContext *context) { struct view_source_data *vsd; NET_StreamClass* stream; if (url_struct->is_binary) { FE_Alert (context, fe_globalData.binary_document_message); return 0; } vsd = url_struct->fe_data; if (! vsd) abort (); url_struct->fe_data = 0; stream = (NET_StreamClass *) calloc (sizeof (NET_StreamClass), 1); if (!stream) return 0; stream->name = "ViewSource"; stream->complete = fe_view_source_stream_complete_method; stream->abort = fe_view_source_stream_abort_method; stream->put_block = fe_view_source_stream_write_method; stream->is_write_ready = fe_save_as_stream_write_ready_method; stream->data_object = vsd; stream->window_id = context; return stream; } #if defined(MOZ_MAIL_NEWS) || defined(MOZ_MAIL_COMPOSE) /* Mailing documents */ void fe_mailNew_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; fe_UserActivity (context); MSG_Mail (context); } void fe_mailto_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; fe_UserActivity (context); /* * You cannot mail a frameset, you must mail the frame child * with focus */ if (fe_IsGridParent (context)) { MWContext *ctx = fe_GetFocusGridOfContext (context); if (ctx) context = ctx; } #ifdef EDITOR if (EDT_IS_EDITOR(context)) EDT_MailDocument (context); else #endif MSG_MailDocument (context); } #endif /* MOZ_MAIL_NEWS || MOZ_MAIL_COMPOSE */ void fe_print_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; URL_Struct *url; fe_UserActivity (context); #ifdef EDITOR if (EDT_IS_EDITOR(context) && !FE_CheckAndSaveDocument(context)) return; #endif { MWContext *ctx = fe_GetFocusGridOfContext (context); if (ctx) context = ctx; } url = SHIST_CreateURLStructFromHistoryEntry (context, SHIST_GetCurrent(&context->hist)); if (url) { /* Free the url struct we created */ NET_FreeURLStruct(url); #ifdef X_PLUGINS if (CONTEXT_DATA(context)->is_fullpage_plugin) { /* Full page plugins need a step here. We need to ask the plugin if * it wants to handle the printing. */ NPPrint npprint; npprint.mode = NP_FULL; npprint.print.fullPrint.pluginPrinted = FALSE; npprint.print.fullPrint.printOne = TRUE; npprint.print.fullPrint.platformPrint = NULL; NPL_Print(context->pluginList, &npprint); if (npprint.print.fullPrint.pluginPrinted == TRUE) return; } #endif /* X_PLUGINS */ fe_PrintDialog (context); } else FE_Alert(context, fe_globalData.no_url_loaded_message); } #define fe_quit_cb fe_QuitCallback void fe_QuitCallback (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; fe_UserActivity (context); #ifdef MOZ_MAIL_NEWS if (!fe_CheckUnsentMail ()) return; if (!fe_CheckDeferredMail ()) return; #endif #ifdef EDITOR if (!fe_EditorCheckUnsaved(context)) return; #endif /*EDITOR*/ if (!CONTEXT_DATA (context)->confirm_exit_p || FE_Confirm (context, fe_globalData.really_quit_message)) { fe_AbortCallback (widget, closure, call_data); fe_Exit (0); } } /* FIND */ void fe_find_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; MWContext *top_context; fe_unset_findcommand_context(); top_context = XP_GetNonGridContext(context); if (!top_context) top_context = context; fe_UserActivity (top_context); fe_FindDialog (top_context, False); } void fe_find_again_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; MWContext *top_context; fe_FindData *find_data; fe_unset_findcommand_context(); top_context = XP_GetNonGridContext(context); if (!top_context) top_context = context; fe_UserActivity (top_context); find_data = CONTEXT_DATA(top_context)->find_data; if ((top_context->type == MWContextBrowser #ifdef MOZ_MAIL_NEWS || top_context->type == MWContextMail || top_context->type == MWContextNews || top_context->type == MWContextMailMsg #endif ) && find_data && find_data->string && find_data->string[0] != '\0') fe_FindDialog (top_context, True); else XBell (XtDisplay (widget), 0); } #ifdef FORTEZZA static void fe_fortezza_card_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; fe_UserActivity (context); SSL_FortezzaMenu(context,SSL_FORTEZZA_CARD_SELECT); } static void fe_fortezza_change_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; fe_UserActivity (context); SSL_FortezzaMenu(context,SSL_FORTEZZA_CHANGE_PERSONALITY); } static void fe_fortezza_view_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; fe_UserActivity (context); SSL_FortezzaMenu(context,SSL_FORTEZZA_VIEW_PERSONALITY); } static void fe_fortezza_info_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; fe_UserActivity (context); SSL_FortezzaMenu(context,SSL_FORTEZZA_CARD_INFO); } static void fe_fortezza_logout_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; fe_UserActivity (context); SSL_FortezzaMenu(context,SSL_FORTEZZA_LOGOUT); } #endif #define HTTP_OFF 42 /* "about:document" */ #define DOCINFO "about:document" /* ".netscape.com/" */ #define DOT_NETSCAPE_DOT_COM_SLASH \ "\130\230\217\236\235\215\213\232\217\130\215"\ "\231\227\131" /* "http://home.netscape.com/" */ #define HTTP_NETSCAPE "\222\236\236\232\144\131\131\222\231\227\217"\ "\130\230\217\236\235\215\213\232\217\130\215"\ "\231\227\131" /* "http://cgi.netscape.com/cgi-bin/" */ #define HTTP_CGI "\222\236\236\232\144\131\131\215\221\223\130"\ "\230\217\236\235\215\213\232\217\130\215\231"\ "\227\131\215\221\223\127\214\223\230\131" /* "http://home.netscape.com/home/" */ #define HTTP_HOME "\222\236\236\232\144\131\131\222\231\227\217"\ "\130\230\217\236\235\215\213\232\217\130\215"\ "\231\227\131\222\231\227\217\131" /* "http://home.netscape.com/eng/mozilla/4.0/" */ #define HTTP_ENG "\222\236\236\232\144\131\131\222\231\227\217"\ "\130\230\217\236\235\215\213\232\217\130\215"\ "\231\227\131\217\230\221\131\227\231\244\223"\ "\226\226\213\131\136\130\132\131" /* "http://home.netscape.com/eng/mozilla/2.0/" */ #define HTTP_ENG_2_0 "\222\236\236\232\144\131\131\222\231\227\217"\ "\130\230\217\236\235\215\213\232\217\130\215"\ "\231\227\131\217\230\221\131\227\231\244\223"\ "\226\226\213\131\134\130\132\131" /* "http://guide.netscape.com/" */ #define HTTP_GUIDE "\222\236\236\232\144\131\131\221\237\223"\ "\216\217\130\230\217\236\235\215\213\232"\ "\217\130\215\231\227\131" /* "http://help.netscape.com/" */ #define HTTP_HELP "\222\236\236\232\144\131\131\222\217\226\232"\ "\130\230\217\236\235\215\213\232\217\130\215"\ "\231\227\131" /* "http://home.netscape.com/info/" */ #define HTTP_INFO "\222\236\236\232\144\131\131\222\231\227\217"\ "\130\230\217\236\235\215\213\232\217\130\215"\ "\231\227\131\223\230\220\231\131" /* "fishcam/" */ #define HTTP_FC HTTP_NETSCAPE \ "\220\223\235\222\215\213\227\131" #ifdef MOZ_MAIL_NEWS /* "newsrc:" */ #define HTTP_NEWSRC "\230\217\241\235\234\215\144" #endif /* "whats_new/" */ #define HTTP_WHATS_NEW HTTP_GUIDE \ "\241\222\213\236\235\211\230\217\241\131" /* "whats_cool/" */ #define HTTP_WHATS_COOL HTTP_GUIDE \ "\241\222\213\236\235\211\215\231\231\226"\ "\131" /* "" */ #define HTTP_INET_DIRECTORY HTTP_GUIDE /* "internet-search.html" */ #define HTTP_INET_SEARCH HTTP_HOME "\223\230\236\217\234\230\217\236"\ "\127\235\217\213\234\215\222\130\222\236\227"\ "\226" /* "people/" */ #define HTTP_INET_WHITE HTTP_GUIDE \ "\232\217\231\232\226\217\131" /* "yellow_pages/" */ #define HTTP_INET_YELLOW HTTP_GUIDE \ "\243\217\226\226\231\241\211\232\213\221"\ "\217\235\131" /* "about-the-internet.html" */ #define HTTP_INET_ABOUT HTTP_HOME "\213\214\231\237\236\127\236\222"\ "\217\127\223\230\236\217\234\230\217\236\130"\ "\222\236\227\226" /* "update.html" */ #define HTTP_SOFTWARE HTTP_HOME "\237\232\216\213\236\217\130\222\236\227\226" /* "how-to-create-web-services.html" */ #define HTTP_HOWTO HTTP_HOME "\222\231\241\127\236\231\127\215"\ "\234\217\213\236\217\127\241\217\214\127\235"\ "\217\234\240\223\215\217\235\130\222\236\227"\ "\226" /* "netscape-galleria.html" */ #define HTTP_GALLERIA HTTP_HOME "\230\217\236\235\215\213\232\217"\ "\127\221\213\226\226\217\234\223\213\130\222"\ "\236\227\226" /* "relnotes/unix-" */ # define HTTP_REL_VERSION_PREFIX HTTP_ENG "\234\217\226\230\231\236\217\235"\ "\131\237\230\223\242\127" # define HTTP_BETA_VERSION_PREFIX H_REL_VERSION_PREFIX /* "reginfo-x.cgi" */ #define HTTP_REG HTTP_HOME "\234\217\221\223\235\236\217\234\130\222\236\227\226" /* "handbook/" */ #define HTTP_MANUAL HTTP_ENG "\222\213\230\216\214\231\231\225\131" /* "starter.html" */ #define HTTP_STARTER HTTP_HOME "\235\236\213\234\236\217\234\130"\ "\222\236\227\226" #ifdef NON_BETA /* "http://help.netscape.com/faqs.html" */ #define HTTP_FAQ "\222\236\236\232\144\131\131\222\217\226\232"\ "\130\230\217\236\235\215\213\232\217\130\215"\ "\231\227\131\220\213\233\235\130\222\236\227"\ "\226" #else /* "eng/beta_central/faq/index.html" */ #define HTTP_FAQ HTTP_NETSCAPE "\217\230\221\131\214\217\236"\ "\213\211\215\217\230\236\234\213\226\131\220\213\233"\ "\131\223\230\216\217\242\130\222\236\227\226" #endif /* "security-doc.html" */ #define HTTP_SECURITY HTTP_INFO "\235\217\215\237\234\223\236\243"\ "\127\216\231\215\130\222\236\227\226" #ifdef NON_BETA /* "auto_bug.cgi" */ #define HTTP_FEEDBACK HTTP_CGI "\213\237\236\231\211\214\237\221"\ "\130\215\221\223" #else /* "eng/beta_central" */ #define HTTP_FEEDBACK HTTP_NETSCAPE "\217\230\221\131\214\217\236"\ "\213\211\215\217\230\236\234\213\226" #endif #ifdef NON_BETA /* "http://help.netscape.com/" */ #define HTTP_SUPPORT "\222\236\236\232\144\131\131\222\217\226\232"\ "\130\230\217\236\235\215\213\232\217\130\215"\ "\231\227\131" #else /* "eng/beta_central" */ #define HTTP_SUPPORT HTTP_NETSCAPE "\217\230\221\131\214\217\236"\ "\213\211\215\217\230\236\234\213\226" #endif #ifdef MOZ_MAIL_NEWS /* "news/news.html" */ #define HTTP_USENET HTTP_ENG_2_0 "\230\217\241\235\131\230\217\241"\ "\235\130\222\236\227\226" #endif /* "about:plugins" */ #define HTTP_PLUGINS "\213\214\231\237\236\144\232\226\237\221\223\230\235" /* "about:fonts" */ #define HTTP_FONTS "\213\214\231\237\236\144\220\231\230\236\235" #ifdef __sgi /* "http://www.sgi.com/surfer/silicon_sites.html" */ # define HTTP_SGI_MENU "\222\236\236\232\144\131\131\241\241\241\130\235\221"\ "\223\130\215\231\227\131\235\237\234\220\217\234\131\235"\ "\223\226\223\215\231\230\211\235\223\236\217\235\130\222"\ "\236\227\226" /* "http://www.sgi.com" */ # define HTTP_SGI_BUTTON "\222\236\236\232\144\131\131\241\241\241\130\235"\ "\221\223\130\215\231\227" /* "file:/usr/local/lib/netscape/docs/Welcome.html" */ # define HTTP_SGI_WELCOME "\220\223\226\217\144\131\237\235\234\131\226\231"\ "\215\213\226\131\226\223\214\131\230\217\236\235"\ "\215\213\232\217\131\216\231\215\235\131\201\217"\ "\226\215\231\227\217\130\222\236\227\226" /* "http://www.adobe.com" */ # define HTTP_ADOBE_MENU "\222\236\236\232\144\131\131\241\241\241\130\213"\ "\216\231\214\217\130\215\231\227" /* "http://www.sgi.com/surfer/cool_sites.html" */ # define SGI_WHATS_COOL "\222\236\236\232\144\131\131\241\241\241\130\235"\ "\221\223\130\215\231\227\131\235\237\234\220\217"\ "\234\131\215\231\231\226\211\235\223\236\217\235"\ "\130\222\236\227\226" /* "http://www.sgi.com/surfer/netscape/relnotes-" */ # define SGI_VERSION_PREFIX "\222\236\236\232\144\131\131\241\241\241\130"\ "\235\221\223\130\215\231\227\131\235\237\234"\ "\220\217\234\131\230\217\236\235\215\213\232"\ "\217\131\234\217\226\230\231\236\217\235\127" #endif /* __sgi */ /* "products/client/communicator/" */ #define HTTP_PRODUCT_INFO HTTP_HELP "\232\234\231\216\237\215\236"\ "\235\131\215\226\223\217\230\236\131\215\231\227"\ "\227\237\230\223\215\213\236\231\234\131" /* "http://home.netscape.com/eng/intl/" */ #define HTTP_INTL "\222\236\236\232\144\131\131\222\231\227\217\130"\ "\230\217\236\235\215\213\232\217\130\215\231\227"\ "\131\217\230\221\131\223\230\236\226\131" /* "services.html" */ #define HTTP_SERVICES HTTP_HOME "\235\217\234\240\223\215\217\235"\ "\130\222\236\227\226" static char * go_get_url(char *which) { char clas[128]; char name[128]; char *p; char *ret; char *type; XrmValue value; PR_snprintf(clas, sizeof (clas), "%s.Url.Which", fe_progclass); PR_snprintf(name, sizeof (name), "%s.url.%s", fe_progclass, which); if (XrmGetResource(XtDatabase(fe_display), name, clas, &type, &value)) { ret = strdup(value.addr); if (!ret) { return NULL; } p = ret; while (*p) { *p += HTTP_OFF; p++; } if (!strstr(ret, DOT_NETSCAPE_DOT_COM_SLASH)) { free(ret); return NULL; } return ret; } return NULL; } #define GO_GET_URL(func, res) \ static char * \ func(char *builtin) \ { \ static char *ret = NULL; \ \ if (ret) \ { \ return ret; \ } \ \ ret = go_get_url(res); \ if (ret) \ { \ return ret; \ } \ \ return builtin; \ } GO_GET_URL(go_get_url_plugins, "aboutplugins") GO_GET_URL(go_get_url_fonts, "aboutfonts") GO_GET_URL(go_get_url_whats_new, "whats_new") GO_GET_URL(go_get_url_whats_cool, "whats_cool") GO_GET_URL(go_get_url_inet_directory, "directory") GO_GET_URL(go_get_url_inet_search, "search") GO_GET_URL(go_get_url_inet_white, "white") GO_GET_URL(go_get_url_inet_yellow, "yellow") GO_GET_URL(go_get_url_inet_about, "about") GO_GET_URL(go_get_url_software, "software") GO_GET_URL(go_get_url_howto, "howto") GO_GET_URL(go_get_url_netscape, "netscape") GO_GET_URL(go_get_url_galleria, "galleria") GO_GET_URL(go_get_url_starter, "starter") GO_GET_URL(go_get_url_rel_version_prefix, "rel_notes") GO_GET_URL(go_get_url_reg, "reg") GO_GET_URL(go_get_url_manual, "manual") GO_GET_URL(go_get_url_faq, "faq") GO_GET_URL(go_get_url_usenet, "usenet") GO_GET_URL(go_get_url_security, "security") GO_GET_URL(go_get_url_feedback, "feedback") GO_GET_URL(go_get_url_support, "support") GO_GET_URL(go_get_url_product_info, "productInfo") GO_GET_URL(go_get_url_intl, "intl") GO_GET_URL(go_get_url_services, "services") #define H_WHATS_NEW go_get_url_whats_new(HTTP_WHATS_NEW) #define H_WHATS_COOL go_get_url_whats_cool(HTTP_WHATS_COOL) #define H_INET_DIRECTORY go_get_url_inet_directory(HTTP_INET_DIRECTORY) #define H_INET_SEARCH go_get_url_inet_search(HTTP_INET_SEARCH) #define H_INET_WHITE go_get_url_inet_white(HTTP_INET_WHITE) #define H_INET_YELLOW go_get_url_inet_yellow(HTTP_INET_YELLOW) #define H_INET_ABOUT go_get_url_inet_about(HTTP_INET_ABOUT) #define H_SOFTWARE go_get_url_software(HTTP_SOFTWARE) #define H_HOWTO go_get_url_howto(HTTP_HOWTO) #define H_NETSCAPE go_get_url_netscape(HTTP_NETSCAPE) #define H_GALLERIA go_get_url_galleria(HTTP_GALLERIA) #define H_REL_VERSION_PREFIX go_get_url_rel_version_prefix(HTTP_REL_VERSION_PREFIX) #define H_REG go_get_url_reg(HTTP_REG) #define H_MANUAL go_get_url_manual(HTTP_MANUAL) #define H_STARTER go_get_url_starter(HTTP_STARTER) #define H_FAQ go_get_url_faq(HTTP_FAQ) #define H_USENET go_get_url_usenet(HTTP_USENET) #define H_SECURITY go_get_url_security(HTTP_SECURITY) #define H_FEEDBACK go_get_url_feedback(HTTP_FEEDBACK) #define H_SUPPORT go_get_url_support(HTTP_SUPPORT) #define H_PRODUCT_INFO go_get_url_product_info(HTTP_PRODUCT_INFO) #define H_INTL go_get_url_intl(HTTP_INTL) #define H_SERVICES go_get_url_services(HTTP_SERVICES) /* * EXPORT_URL creates a function that returns a localized URL. * It is needed by the e-kit in order to allow localized URL's. */ #define EXPORT_URL(func, builtin) char* xfe_##func(void) {return func(builtin);} EXPORT_URL(go_get_url_plugins, HTTP_PLUGINS) EXPORT_URL(go_get_url_fonts, HTTP_FONTS) EXPORT_URL(go_get_url_whats_new, HTTP_WHATS_NEW) EXPORT_URL(go_get_url_whats_cool, HTTP_WHATS_COOL) EXPORT_URL(go_get_url_inet_directory, HTTP_INET_DIRECTORY) EXPORT_URL(go_get_url_inet_search, HTTP_INET_SEARCH) EXPORT_URL(go_get_url_inet_white, HTTP_INET_WHITE) EXPORT_URL(go_get_url_inet_yellow, HTTP_INET_YELLOW) EXPORT_URL(go_get_url_inet_about, HTTP_INET_ABOUT) EXPORT_URL(go_get_url_software, HTTP_SOFTWARE) EXPORT_URL(go_get_url_howto, HTTP_HOWTO) EXPORT_URL(go_get_url_netscape, HTTP_NETSCAPE) EXPORT_URL(go_get_url_galleria, HTTP_GALLERIA) EXPORT_URL(go_get_url_reg, HTTP_REG) EXPORT_URL(go_get_url_manual, HTTP_MANUAL) EXPORT_URL(go_get_url_starter, HTTP_STARTER) EXPORT_URL(go_get_url_faq, HTTP_FAQ) #ifdef MOZ_MAIL_NEWS EXPORT_URL(go_get_url_usenet, HTTP_USENET) #endif EXPORT_URL(go_get_url_security, HTTP_SECURITY) EXPORT_URL(go_get_url_feedback, HTTP_FEEDBACK) EXPORT_URL(go_get_url_support, HTTP_SUPPORT) EXPORT_URL(go_get_url_product_info, HTTP_PRODUCT_INFO) EXPORT_URL(go_get_url_intl, HTTP_INTL) EXPORT_URL(go_get_url_services, HTTP_SERVICES) /* * xfe_go_get_url_relnotes */ char* xfe_go_get_url_relnotes(void) { static char* url = NULL; if ( url == NULL ) { char buf[1024]; char* ptr; char* prefix = (strchr(fe_version, 'a') || strchr(fe_version, 'b')) ? HTTP_BETA_VERSION_PREFIX : H_REL_VERSION_PREFIX; sprintf(buf, "%s.html", fe_version); for ( ptr = buf; *ptr; ptr++ ) { *ptr+= HTTP_OFF; } url = (char*) malloc(strlen(prefix)+strlen(buf)+1); strcpy(url, prefix); strcat(url, buf); } return url; } void fe_docinfo_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; char buf [1024], *in, *out; fe_UserActivity (context); for (in = DOCINFO, out = buf; *in; in++, out++) *out = *in - HTTP_OFF; *out = 0; #ifdef EDITOR if (EDT_IS_EDITOR(context) && !FE_CheckAndSaveDocument(context)) return; #endif /* @@@@ this is the proper way to do it but I dont' * know the encoding scheme * fe_GetURL (context,NET_CreateURLStruct(buf, FALSE), FALSE); */ fe_GetURL (context,NET_CreateURLStruct(DOCINFO, FALSE), FALSE); #ifdef EDITOR fe_EditorRefresh(context); #endif } char * xfe_get_netscape_home_page_url() { static char buf [128]; char *in, *out; for (in = H_NETSCAPE, out = buf; *in; in++, out++) *out = *in - HTTP_OFF; *out = 0; return buf; } static void fe_net_showstatus_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; char *rv; fe_UserActivity (context); rv = NET_PrintNetlibStatus(); NET_ToggleTrace(); /* toggle trace mode on and off */ XFE_Alert (context, rv); free(rv); } static void fe_fishcam_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; char buf [1024], *in, *out; fe_UserActivity (context); for (in = HTTP_FC, out = buf; *in; in++, out++) *out = *in - HTTP_OFF; *out = 0; fe_GetURL (context,NET_CreateURLStruct(buf, FALSE), FALSE); } void fe_SearchCallback (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; char* url; fe_UserActivity (context); if ( PREF_GetUrl("internal_url.net_search", &url) ) { fe_GetURL (context,NET_CreateURLStruct(url, FALSE), FALSE); } } void fe_GuideCallback (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; char* url = NULL; int ok; fe_UserActivity (context); ok = PREF_CopyConfigString("toolbar.places.default_url",&url); if (ok == PREF_NOERROR) { FE_GetURL(context,NET_CreateURLStruct(url,NET_DONT_RELOAD)); } if (url) { XP_FREE(url); } } void fe_NetscapeCallback (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; char* url; fe_UserActivity (context); if ( PREF_GetUrl("toolbar.logo", &url) ) { /* * Call this guy, it will sort out if the current context * is suitable, etc... */ FE_GetURL(context, NET_CreateURLStruct(url, NET_DONT_RELOAD)); } } #ifdef __sgi static void fe_sgi_menu_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; char buf [1024], *in, *out; fe_UserActivity (context); for (in = HTTP_SGI_MENU, out = buf; *in; in++, out++) *out = *in - HTTP_OFF; *out = 0; fe_GetURL (context, NET_CreateURLStruct (buf, FALSE), FALSE); } static void fe_adobe_menu_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; char buf [1024], *in, *out; fe_UserActivity (context); for (in = HTTP_ADOBE_MENU, out = buf; *in; in++, out++) *out = *in - HTTP_OFF; *out = 0; fe_GetURL (context, NET_CreateURLStruct (buf, FALSE), FALSE); } void fe_SGICallback (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; char buf [1024], *in, *out; fe_UserActivity (context); for (in = HTTP_SGI_BUTTON, out = buf; *in; in++, out++) *out = *in - HTTP_OFF; *out = 0; fe_GetURL (context, NET_CreateURLStruct (buf, FALSE), FALSE); } void fe_sgi_welcome_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; char buf [1024], *in, *out; fe_UserActivity (context); for (in = HTTP_SGI_WELCOME, out = buf; *in; in++, out++) *out = *in - HTTP_OFF; *out = 0; fe_GetURL (context, NET_CreateURLStruct (buf, FALSE), FALSE); } #endif /* __sgi */ #ifdef JAVA void fe_new_show_java_console_cb (Widget widget, XtPointer closure, XtPointer call_data) { LJ_HideConsole(); LJ_ShowConsole(); } #endif void fe_load_images_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; fe_UserActivity (context); fe_LoadDelayedImages (context); } /* Navigate menu */ /* not static -- it's needed by src/HTMLView.cpp */ void fe_back_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; MWContext *top_context = XP_GetNonGridContext(context); URL_Struct *url; if (fe_IsGridParent(top_context)) { if (LO_BackInGrid(top_context)) { return; } } fe_UserActivity (top_context); url = SHIST_CreateURLStructFromHistoryEntry (top_context, SHIST_GetPrevious (top_context)); if (url) { fe_GetURL (top_context, url, FALSE); } else { FE_Alert (top_context, fe_globalData.no_previous_url_message); } } /* not static -- it's needed by src/HTMLView.cpp */ void fe_forward_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; MWContext *top_context = XP_GetNonGridContext(context); URL_Struct *url; if (fe_IsGridParent(top_context)) { if (LO_ForwardInGrid(top_context)) { return; } } fe_UserActivity (top_context); url = SHIST_CreateURLStructFromHistoryEntry (top_context, SHIST_GetNext (top_context)); if (url) { fe_GetURL (top_context, url, FALSE); } else { FE_Alert (top_context, fe_globalData.no_next_url_message); } } /* not static -- it's needed by src/HTMLView.cpp ; BrowserFrame.cpp */ void fe_home_cb (Widget widget, XtPointer closure, XtPointer call_data) { URL_Struct *url; MWContext *context = (MWContext *) closure; fe_UserActivity (context); if (!fe_globalPrefs.home_document || !*fe_globalPrefs.home_document) { XClearArea (XtDisplay (CONTEXT_WIDGET (context)), XtWindow (CONTEXT_DATA (context)->drawing_area), 0, 0, CONTEXT_DATA (context)->scrolled_width, CONTEXT_DATA (context)->scrolled_height, False); FE_Alert (context, fe_globalData.no_home_url_message); return; } url = NET_CreateURLStruct (fe_globalPrefs.home_document, FALSE); fe_GetURL ((MWContext *) closure, url, FALSE); } /* Help menu */ void fe_about_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; fe_UserActivity (context); fe_reuseBrowser(context, NET_CreateURLStruct ("about:", FALSE)); } void fe_manual_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; char* url; char buf[1024], *in, *out; fe_UserActivity (context); url = HTTP_MANUAL; if ( url ) { for (in = url, out = buf; *in; in++, out++) *out = *in - HTTP_OFF; *out = 0; fe_reuseBrowser(context, NET_CreateURLStruct (buf, FALSE)); } } #ifdef X_PLUGINS void fe_aboutPlugins_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; fe_UserActivity (context); fe_GetURL (context, NET_CreateURLStruct ("about:plugins", FALSE), FALSE); } #endif /* X_PLUGINS */ void fe_aboutFonts_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; fe_UserActivity (context); fe_GetURL (context, NET_CreateURLStruct ("about:fonts", FALSE), FALSE); } /* Message composition stuff. */ void fe_mailcompose_obeycb(MWContext *context, fe_MailComposeCallback cbid, void *call_data) { switch (cbid) { case ComposeClearAllText_cb: { Widget text = CONTEXT_DATA (context)->mcBodyText; fe_SetTextFieldAndCallBack(text, ""); break; } case ComposeSelectAllText_cb: { Widget text = CONTEXT_DATA (context)->mcBodyText; XmPushButtonCallbackStruct *cb = (XmPushButtonCallbackStruct *) call_data; if (cb) XmTextSetSelection(text, 0, XmTextGetLastPosition(text), cb->event->xkey.time); break; } default: XP_ASSERT (0); break; } } #if defined(MOZ_MAIL_NEWS) || defined(MOZ_MAIL_COMPOSE) void FE_InsertMessageCompositionText(MSG_Pane* comppane, const char* text, XP_Bool leaveCursorAtBeginning) { MWContext* context = MSG_GetContext(comppane); /* call - function defined in src/ComposeView.cpp */ fe_InsertMessageCompositionText(context, text, leaveCursorAtBeginning); return; } #endif /* MOZ_MAIL_NEWS || MOZ_MAIL_COMPOSE */ /* rlogin */ void FE_ConnectToRemoteHost (MWContext *context, int url_type, char *hostname, char *port, char *username) { char *name; const char *command; const char *user_command; char *buf; const char *in; char *out; char **av, **ac, **ae; int na; Boolean cop_out_p = False; pid_t forked; switch (url_type) { case FE_TELNET_URL_TYPE: name = "telnet"; command = fe_globalPrefs.telnet_command; user_command = 0 /* fe_globalPrefs.telnet_user_command */; break; case FE_TN3270_URL_TYPE: name = "tn3270"; command = fe_globalPrefs.tn3270_command; user_command = 0 /* fe_globalPrefs.tn3270_user_command */; break; case FE_RLOGIN_URL_TYPE: name = "rlogin"; command = fe_globalPrefs.rlogin_command; user_command = fe_globalPrefs.rlogin_user_command; break; default: abort (); } if (username && user_command && *user_command) command = user_command; else if (username) cop_out_p = True; buf = (char*) malloc( strlen(command) + 1 + (hostname && *hostname ? strlen(hostname) : strlen("localhost")) + (username && *username ? strlen(username) : 0) + (port && *port ? strlen(port) : 0) ); ac = av = (char**) malloc(10 * sizeof (char*)); if (buf == NULL || av == NULL) goto malloc_lossage; ae = av + 10; in = command; *ac = out = buf; na = 0; while (*in) { if (*in == '%') { in++; if (*in == 'h') { char *s; char *h = (hostname && *hostname ? hostname : "localhost"); /* Only allow the hostname to contain alphanumerics or _ - and . to prevent people from embedding shell command security holes in the host name. */ for (s = h; *s; s++) if (*s == '_' || (*s == '-' && s != h) || *s == '.' || isalpha(*s) || isdigit(*s)) *out++ = *s; } else if (*in == 'p') { if (port && *port) { int port_num = atoi(port); if (port_num > 0) { char buf1[6]; PR_snprintf (buf1, sizeof (buf1), "%.5u", port_num); strcpy(out, buf1); out += strlen(buf1); } } } else if (*in == 'u') { char *s; /* Only allow the user name to contain alphanumerics or _ - and . to prevent people from embedding shell command security holes in the host name. */ if (username && *username) { for (s = username; *s; s++) if (*s == '_' || (*s == '-' && s != username) || *s == '.' || isalpha(*s) || isdigit(*s)) *out++ = *s; } } else if (*in == '%') { *out++ = '%'; } else { char buf2 [255]; PR_snprintf (buf2, sizeof (buf2), XP_GetString( XFE_UNKNOWN_ESCAPE_CODE ), name, *in); FE_Alert (context, buf2); } if (*in) in++; } else if (*in == ' ') { if (out != *ac) { *out++ = '\0'; na++; if (++ac == ae) { av = (char**) realloc(av, (na + 10) * sizeof (char*)); if (av == NULL) goto malloc_lossage; ac = av + na; ae = ac + 10; } *ac = out; } in++; } else { *out = *in; out++; in++; } } if (out != *ac) { *out = '\0'; na++; ac++; } if (ac == ae) { av = (char**) realloc(av, (na + 1) * sizeof (char*)); if (av == NULL) goto malloc_lossage; ac = av + na; } *ac = 0; if (cop_out_p) { char buf2 [1024]; PR_snprintf (buf2, sizeof (buf2), XP_GetString(XFE_LOG_IN_AS), username); fe_Message (context, buf2); } switch (forked = fork ()) { case -1: fe_perror (context, XP_GetString( XFE_COULDNT_FORK ) ); break; case 0: { Display *dpy = XtDisplay (CONTEXT_WIDGET (context)); close (ConnectionNumber (dpy)); execvp (av [0], av); PR_snprintf (buf, sizeof (buf), XP_GetString( XFE_EXECVP_FAILED ), fe_progname, av[0]); perror (buf); exit (1); /* Note that this only exits a child fork. */ break; } default: /* This is the "old" process (subproc pid is in `forked'.) */ break; } free(av); free(buf); return; malloc_lossage: if (av) free(av); if (buf) free(buf); fe_Message (context, XP_GetString(XFE_OUT_OF_MEMORY_URL)); } /* The popup menu */ URL_Struct *fe_url_under_mouse = 0; URL_Struct *fe_image_under_mouse = 0; static void fe_save_image_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; XmString xm_title = 0; char *title = 0; URL_Struct *url; fe_UserActivity (context); XtVaGetValues (widget, XmNlabelString, &xm_title, 0); XmStringGetLtoR (xm_title, XmFONTLIST_DEFAULT_TAG, &title); XmStringFree(xm_title); url = fe_image_under_mouse; if (! url) FE_Alert (context, fe_globalData.not_over_image_message); if (title) free (title); if (url) fe_SaveURL (context, url); fe_image_under_mouse = 0; /* it will be freed in the exit routine. */ } static void fe_save_link_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; XmString xm_title = 0; char *title = 0; URL_Struct *url; fe_UserActivity (context); XtVaGetValues (widget, XmNlabelString, &xm_title, 0); XmStringGetLtoR (xm_title, XmFONTLIST_DEFAULT_TAG, &title); XmStringFree(xm_title); url = fe_url_under_mouse; if (! url) FE_Alert (context, fe_globalData.not_over_link_message); if (title) free (title); if (url) fe_SaveURL (context, url); fe_url_under_mouse = 0; /* it will be freed in the exit routine. */ } static void fe_open_image_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; URL_Struct *url; fe_UserActivity (context); url = fe_image_under_mouse; if (! url) FE_Alert (context, fe_globalData.not_over_image_message); else { fe_GetURL (XP_GetNonGridContext(context), url, FALSE); fe_image_under_mouse = 0; /* it will be freed in the exit routine. */ } } static void fe_clipboard_url_1 (Widget widget, XtPointer closure, XtPointer call_data, URL_Struct *url, char* html) { MWContext *context = (MWContext *) closure; XmPushButtonCallbackStruct *cb = (XmPushButtonCallbackStruct *) call_data; XEvent *event = (cb ? cb->event : 0); Time time = (event && (event->type == KeyPress || event->type == KeyRelease) ? event->xkey.time : event && (event->type == ButtonPress || event->type == ButtonRelease) ? event->xbutton.time : XtLastTimestampProcessed (XtDisplay(CONTEXT_WIDGET (context)))); fe_UserActivity (context); if (! url) FE_Alert (context, fe_globalData.not_over_link_message); else { fe_OwnClipboard(widget, time, strdup (url->address), html, NULL, 0, False); #ifdef NOT_rhess /* * NOTE: it's not really valid to make a primary selection if you * can't show the selection on the display... * [ this is a hidden selection ] * */ fe_OwnPrimarySelection(widget, time, strdup (url->address), html, NULL, 0, context); #endif NET_FreeURLStruct (url); } } static char fe_link_html_head[] = ""; static char fe_link_html_tail[] = ""; static char fe_image_html_head[] = "\"Image\""; #define XFE_LINK_HTML_HEAD (fe_link_html_head) #define XFE_LINK_HTML_MIDDLE (fe_link_html_middle) #define XFE_LINK_HTML_TAIL (fe_link_html_tail) #define XFE_IMAGE_HTML_HEAD (fe_image_html_head) #define XFE_IMAGE_HTML_TAIL (fe_image_html_tail) void fe_clipboard_link_cb (Widget widget, XtPointer closure, XtPointer call_data, URL_Struct *url) { char *html = NULL; char *link = url->address; int32 len = strlen(link); char *head = XFE_LINK_HTML_HEAD; char *midd = XFE_LINK_HTML_MIDDLE; char *tail = XFE_LINK_HTML_TAIL; html = XP_ALLOC(len + len + 2 + strlen(head) + strlen(midd) + strlen(tail) ); sprintf(html, "%s%s%s%s%s\0", head, link, midd, link, tail); fe_clipboard_url_1 (widget, closure, call_data, url, html); XP_FREE(html); } void fe_clipboard_image_link_cb (Widget widget, XtPointer closure, XtPointer call_data, URL_Struct *url, URL_Struct *img) { char *html = NULL; char *link = url->address; int32 len = strlen(link); char *head = XFE_LINK_HTML_HEAD; char *midd = XFE_LINK_HTML_MIDDLE; char *tail = XFE_LINK_HTML_TAIL; if (!img) { html = XP_ALLOC(len + len + 2 + strlen(head) + strlen(midd) + strlen(tail) ); sprintf(html, "%s%s%s%s%s\0", head, link, midd, link, tail); fe_clipboard_url_1 (widget, closure, call_data, url, html); XP_FREE(html); } else { char *image = img->address; char *ihead = XFE_IMAGE_HTML_HEAD; char *itail = XFE_IMAGE_HTML_TAIL; html = XP_ALLOC(len + 2 + strlen(image) + strlen(head) + strlen(midd) + strlen(tail) + strlen(ihead) + strlen(itail) ); sprintf(html, "%s%s%s%s%s%s%s\0", head, link, midd, ihead, image, itail, tail); fe_clipboard_url_1 (widget, closure, call_data, url, html); NET_FreeURLStruct (img); } XP_FREE(html); } void fe_clipboard_image_cb (Widget widget, XtPointer closure, XtPointer call_data, URL_Struct *url) { char *html = NULL; char *link = url->address; int32 len = strlen(link); char *head = XFE_IMAGE_HTML_HEAD; char *tail = XFE_IMAGE_HTML_TAIL; html = XP_ALLOC(len + 2 + strlen(head) + strlen(tail)); sprintf(html, "%s%s%s\0", head, link, tail); fe_clipboard_url_1 (widget, closure, call_data, url, html); XP_FREE(html); } /* * For scrolling the window with the arrow keys, we need to * insert a lookahead key eater into each action routine, * else it is possible to queue up too many key events, and * screw up our careful scroll/expose event timing. */ static void fe_eat_window_key_events(Display *display, Window window) { XEvent event; XSync(display, FALSE); while (XCheckTypedWindowEvent(display, window, KeyPress, &event) == TRUE); } static void fe_column_forward_action (Widget widget, XEvent *event, String *av, Cardinal *ac) { XKeyEvent *kev = (XKeyEvent *)event; MWContext *context = fe_WidgetToMWContext (widget); XP_ASSERT (context); if (!context) return; fe_column_forward_cb (widget, (XtPointer)context, (XtPointer)0); fe_eat_window_key_events(XtDisplay(widget), kev->window); } static void fe_column_backward_action (Widget widget, XEvent *event, String *av, Cardinal *ac) { XKeyEvent *kev = (XKeyEvent *)event; MWContext *context = fe_WidgetToMWContext (widget); XP_ASSERT (context); if (!context) return; fe_column_backward_cb (widget, (XtPointer)context, (XtPointer)0); fe_eat_window_key_events(XtDisplay(widget), kev->window); } static void fe_line_forward_action (Widget widget, XEvent *event, String *av, Cardinal *ac) { XKeyEvent *kev = (XKeyEvent *)event; MWContext *context = fe_WidgetToMWContext (widget); XP_ASSERT (context); if (!context) return; fe_line_forward_cb (widget, (XtPointer)context, (XtPointer)0); fe_eat_window_key_events(XtDisplay(widget), kev->window); } static void fe_line_backward_action (Widget widget, XEvent *event, String *av, Cardinal *ac) { XKeyEvent *kev = (XKeyEvent *)event; MWContext *context = fe_WidgetToMWContext (widget); XP_ASSERT (context); if (!context) return; fe_line_backward_cb (widget, (XtPointer)context, (XtPointer)0); fe_eat_window_key_events(XtDisplay(widget), kev->window); } /* Actions for use in translations tables. */ #define DEFACTION(NAME) \ static void \ fe_##NAME##_action (Widget widget, XEvent *event, String *av, Cardinal *ac) \ { \ MWContext *context = fe_WidgetToMWContext (widget); \ XP_ASSERT (context); \ if (!context) return; \ fe_##NAME##_cb (widget, (XtPointer)context, (XtPointer)0); \ } /* DEFACTION (new) */ /*DEFACTION (open_url)*/ /*DEFACTION (open_file)*/ #ifdef EDITOR /*DEFACTION (edit)*/ #endif /* EDITOR */ /*DEFACTION (save_as)*/ /*DEFACTION (mailto)*/ /*DEFACTION (print)*/ /* DEFACTION (docinfo) */ /*DEFACTION (delete)*/ /* DEFACTION (quit) */ /* DEFACTION (cut) */ /* DEFACTION (copy) */ /* DEFACTION (paste) */ /* DEFACTION (paste_quoted) */ /*DEFACTION (find)*/ /* DEFACTION (find_again) */ /* DEFACTION (reload) */ /* DEFACTION (load_images) */ /* DEFACTION (refresh) */ /* DEFACTION (view_source) */ /* DEFACTION (back) */ /* DEFACTION (forward) */ /* DEFACTION (history) */ /* DEFACTION (home) */ /*DEFACTION (save_options)*/ /* DEFACTION (view_bookmark) */ DEFACTION (fishcam) DEFACTION (net_showstatus) /* DEFACTION (abort) */ DEFACTION (page_forward) DEFACTION (page_backward) /*DEFACTION (line_forward)*/ /*DEFACTION (line_backward)*/ /*DEFACTION (column_forward)*/ /*DEFACTION (column_backward)*/ DEFACTION (save_image) DEFACTION (open_image) DEFACTION (save_link) /*DEFACTION (follow_link)*/ /*DEFACTION (follow_link_new)*/ #undef DEFACTION static void fe_open_url_action (Widget widget, XEvent *event, String *av, Cardinal *ac) { /* openURL() pops up a file requestor. openURL(http:xxx) opens that URL. Really only one arg is meaningful, but we also accept the form openURL(http:xxx, remote) for the sake of remote.c, and treat openURL(remote) the same as openURL(). */ MWContext *context = fe_WidgetToMWContext (widget); MWContext *old_context = NULL; Boolean other_p = False; char *windowName = 0; XP_ASSERT (context); if (!context) return; context = XP_GetNonGridContext (context); fe_UserActivity (context); if (*ac && av[*ac-1] && !strcmp (av[*ac-1], "")) (*ac)--; if (*ac > 1 && av[*ac-1] ) { if ( (!strcasecomp (av[*ac-1], "new-window") || !strcasecomp (av[*ac-1], "new_window") || !strcasecomp (av[*ac-1], "newWindow") || !strcasecomp (av[*ac-1], "new"))) { other_p = True; (*ac)--; } else if ( (old_context = XP_FindNamedContextInList(context, av[*ac-1]))) { context = old_context; other_p = False; (*ac)--; } else { StrAllocCopy(windowName, av[*ac-1]); other_p = True; (*ac)--; } } if (*ac == 1 && av[0]) { URL_Struct *url_struct = NET_CreateURLStruct (av[0], FALSE); #if defined(MOZ_MAIL_NEWS) || defined(MOZ_MAIL_COMPOSE) /* Dont create new windows for Compose. fe_GetURL will take care of it */ if (MSG_RequiresComposeWindow(url_struct->address)) other_p = False; #endif if (other_p) { context = fe_MakeWindow (XtParent (CONTEXT_WIDGET (context)), context, url_struct, windowName, MWContextBrowser, FALSE); XP_FREE(windowName); } else fe_GetURL (context, url_struct, FALSE); } else if (*ac > 1) { fprintf (stderr, XP_GetString(XFE_COMMANDS_OPEN_URL_USAGE), fe_progname); } else { fe_open_url_cb (widget, (XtPointer)context, (XtPointer)0); } } static void fe_print_remote_action (Widget widget, XEvent *event, String *av, Cardinal *ac) { /* Silent print for remote. Valid invocations are print(filename, remote) : print URL of context to filename print(remote) : print URL of context to printer print(remote) : print URL of context to printer */ MWContext *context = fe_WidgetToMWContext (widget); URL_Struct *url_struct = NULL; Boolean toFile = False; char *filename = NULL; XP_ASSERT (context); if (!context) return; fe_UserActivity (context); if (*ac && av[*ac-1] && !strcmp (av[*ac-1], "")) (*ac)--; else return; /* this is valid only for remote */ if (*ac && av[*ac-1]) { filename = av[*ac-1]; if (*filename) toFile = True; (*ac)--; } if (*ac > 0) fprintf (stderr, "%s: usage: print([filename])\n", fe_progname); url_struct = SHIST_CreateWysiwygURLStruct (context, SHIST_GetCurrent (&context->hist)); if (url_struct) { if (!toFile || filename) fe_Print(context, url_struct, toFile, filename); else NET_FreeURLStruct (url_struct); } } #if defined(MOZ_MAIL_NEWS) || defined(MOZ_MAIL_COMPOSE) static void fe_mailto_action (Widget widget, XEvent *event, String *av, Cardinal *ac) { /* see also fe_open_url_action() #### This really ought to be implemented by opening a "mailto:" URL, instead of by calling MSG_ComposeMessage -- that'd be more abstract and stuff. -jwz */ MWContext *context = fe_WidgetToMWContext (widget); XP_ASSERT (context); if (!context) return; fe_UserActivity (context); if (*ac && av[*ac-1] && !strcmp (av[*ac-1], "")) (*ac)--; if (*ac >= 1) { char *to; int size = 0; int i; for (i = 0; i < *ac; i++) size += (strlen (av[i]) + 2); to = (char *) malloc (size + 1); *to = 0; for (i = 0; i < *ac; i++) { strcat (to, av[i]); if (i < (*ac)-1) strcat (to, ", "); } MSG_ComposeMessage (context, 0, /* from */ 0, /* reply_to */ to, 0, /* cc */ 0, /* bcc */ 0, /* fcc */ 0, /* newsgroups */ 0, /* followup_to */ 0, /* organization */ 0, /* subject */ 0, /* references */ 0, /* other_random_headers */ 0, /* priority */ 0, /* attachment */ 0, /* newspost_url */ 0, /* body */ FALSE, /* force_plain_text */ 0 /* html_part */ ); } else if (*ac > 1) { fprintf (stderr, XP_GetString(XFE_COMMANDS_MAIL_TO_USAGE), fe_progname); } else { fe_mailto_cb (widget, (XtPointer)context, (XtPointer)0); } } #endif /* MOZ_MAIL_NEWS || MOZ_MAIL_COMPOSE */ static void fe_html_help_action (Widget widget, XEvent *event, String *av, Cardinal *ac) { MWContext *context = fe_WidgetToMWContext (widget); XP_Bool remote_p = False; char *map_file_url; char *id; char *search_text; XP_ASSERT (context); if (!context) return; fe_UserActivity (context); if (*ac && av[*ac-1] && !strcmp (av[*ac-1], "")) { remote_p = True; (*ac)--; } if (*ac == 3) { map_file_url = av[0]; id = av[1]; search_text = av[2]; NET_GetHTMLHelpFileFromMapFile(context, map_file_url, id, search_text); } else { fprintf (stderr, XP_GetString(XFE_COMMANDS_HTML_HELP_USAGE), fe_progname); } } static void fe_deleteKey_action (Widget widget, XEvent *event, String *av, Cardinal *ac) { MWContext *context = fe_WidgetToMWContext (widget); XP_ASSERT(context); if (!context) return; #ifdef MOZ_MAIL_NEWS if (context->type == MWContextMail || context->type == MWContextNews) XP_ASSERT(0); else #endif /* MOZ_MAIL_NEWS */ fe_page_backward_action(widget, event, av, ac); } static void fe_undefined_key_action (Widget widget, XEvent *event, String *av, Cardinal *ac) { XBell (XtDisplay (widget), 0); } /* for the rest, look in src/Command.cpp -- for 'cmd_mapping mapping[]' */ XtActionsRec fe_CommandActions [] = { #if defined(MOZ_MAIL_NEWS) || defined(MOZ_MAIL_COMPOSE) { "mailto", fe_mailto_action }, #endif { "print", fe_print_remote_action }, { "fishcam", fe_fishcam_action }, { "net_showstatus", fe_net_showstatus_action }, { "PageDown", fe_page_forward_action }, { "PageUp", fe_page_backward_action }, { "LineDown", fe_line_forward_action }, { "LineUp", fe_line_backward_action }, { "ColumnLeft", fe_column_forward_action }, { "ColumnRight", fe_column_backward_action }, { "Delete", fe_deleteKey_action }, { "Backspace", fe_deleteKey_action }, { "SaveImage", fe_save_image_action }, { "OpenImage", fe_open_image_action }, { "SaveURL", fe_save_link_action }, { "OpenURL", fe_open_url_action }, { "OpenURLNewWindow", fe_open_url_action }, /* For Html Help */ { "htmlHelp", fe_html_help_action }, { "undefined-key", fe_undefined_key_action } }; int fe_CommandActionsSize = countof (fe_CommandActions); /**************************/ /* MessageCompose actions */ /* (Mail/News actions are */ /* defined in mailnews.c) */ /**************************/ void fe_InitCommandActions () { XtAppAddActions(fe_XtAppContext, fe_CommandActions, fe_CommandActionsSize); } /* This installs all the usual translations on widgets which are a part of the main Netscape window -- it recursively decends the tree, installing the appropriate translations everywhere. This should not be called on popups/transients, but only on widgets which are children of the main Shell. */ void fe_HackTranslations (MWContext *context, Widget widget) { XtTranslations global_translations = 0; XtTranslations secondary_translations = 0; XP_Bool has_display_area = FALSE; if (XmIsGadget (widget)) return; /* To prevent focus problems, dont enable translations on the menubar and its children. The problem was that when we had the translations in the menubar too, we could do a translation and popup a modal dialog when one of the menu's from the menubar was pulleddown. Now motif gets too confused about who holds pointer and keyboard focus. */ if (XmIsRowColumn(widget)) { unsigned char type; XtVaGetValues(widget, XmNrowColumnType, &type, 0); if (type == XmMENU_BAR) return; } switch (context->type) { #ifdef EDITOR case MWContextEditor: has_display_area = FALSE; global_translations = fe_globalData.global_translations; secondary_translations = fe_globalData.editor_global_translations; break; #endif /*EDITOR*/ case MWContextBrowser: has_display_area = TRUE; global_translations = fe_globalData.global_translations; secondary_translations = fe_globalData.browser_global_translations; break; case MWContextMail: case MWContextNews: has_display_area = TRUE; global_translations = fe_globalData.global_translations; secondary_translations = fe_globalData.mailnews_global_translations; break; case MWContextMailMsg: has_display_area = TRUE; global_translations = fe_globalData.global_translations; secondary_translations = fe_globalData.messagewin_global_translations; break; case MWContextMessageComposition: has_display_area = FALSE; global_translations = fe_globalData.global_translations; secondary_translations = fe_globalData.mailcompose_global_translations; break; case MWContextAddressBook: has_display_area = FALSE; global_translations = fe_globalData.global_translations; secondary_translations = fe_globalData.ab_global_translations; break; case MWContextDialog: has_display_area = TRUE; /*global_translations = 0;*/ /*secondary_translations = fe_globalData.dialog_global_translations;*/ global_translations = fe_globalData.global_translations; secondary_translations = fe_globalData.browser_global_translations; break; case MWContextPane: /*context used by navcenter right now */ global_translations = fe_globalData.global_translations; secondary_translations = fe_globalData.navcenter_global_translations; default: break; } if (!XP_STRCMP( XtName(widget), "editorDrawingArea" )) { XtOverrideTranslations (widget, fe_globalData.global_translations); XtOverrideTranslations (widget, fe_globalData.editor_global_translations); } else { if (global_translations) XtOverrideTranslations (widget, global_translations); if (secondary_translations) XtOverrideTranslations (widget, secondary_translations); } if (XmIsTextField (widget) || XmIsText (widget) || XmIsList(widget)) { /* Set up the editing translations (all text fields, everywhere.) */ if (XmIsTextField (widget) || XmIsText (widget)) fe_HackTextTranslations (widget); /* Install globalTextFieldTranslations on single-line text fields in windows which have an HTML display area (browser, mail, news) but not in windows which don't have one (compose, download, bookmarks, address book...) */ if (has_display_area && XmIsTextField (widget) && fe_globalData.global_text_field_translations) XtOverrideTranslations (widget, fe_globalData.global_text_field_translations); } else { Widget *kids = 0; Cardinal nkids = 0; /* Not a Text or TextField. */ /* Install globalNonTextTranslations on non-text widgets in windows which have an HTML display area (browser, mail, news, view source) but not in windows which don't have one (compose, download, bookmarks, address book...) */ if (has_display_area && fe_globalData.global_nontext_translations) XtOverrideTranslations (widget, fe_globalData.global_nontext_translations); /* Now recurse on the children. */ XtVaGetValues (widget, XmNchildren, &kids, XmNnumChildren, &nkids, 0); while (nkids--) fe_HackTranslations (context, kids [nkids]); } } /* This installs all the usual translations on Text and TextField widgets. */ void fe_HackTextTranslations (Widget widget) { Widget parent = widget; for (parent=widget; parent && !XtIsWMShell (parent); parent=XtParent(parent)) if (XmLIsGrid(parent)) /* We shouldn't be messing with Grid widget and its children */ return; if (XmIsTextField(widget)) { if (fe_globalData.editing_translations) XtOverrideTranslations (widget, fe_globalData.editing_translations); if (fe_globalData.single_line_editing_translations) XtOverrideTranslations (widget, fe_globalData.single_line_editing_translations); } else if (XmIsText(widget)) { if (fe_globalData.editing_translations) XtOverrideTranslations (widget, fe_globalData.editing_translations); if (fe_globalData.multi_line_editing_translations) XtOverrideTranslations (widget, fe_globalData.multi_line_editing_translations); } else { XP_ASSERT(0); } } void fe_HackFormTextTranslations(Widget widget) { Widget parent = widget; for (parent=widget; parent && !XtIsWMShell (parent); parent=XtParent(parent)) if (XmLIsGrid(parent)) /* We shouldn't be messing with Grid widget and its children */ return; if ((XmIsTextField(widget)) || (XmIsText(widget)) ) { if (fe_globalData.form_elem_editing_translations) XtOverrideTranslations (widget, fe_globalData.form_elem_editing_translations); } else { XP_ASSERT(0); } } /* This installs all the usual translations for popups/transients. All it does is recurse the tree and call fe_HackTextTranslations on any Text or TextField widgets it finds. */ void fe_HackDialogTranslations (Widget widget) { if (XmIsGadget (widget)) return; else if (XmIsText (widget) || XmIsTextField (widget)) fe_HackTextTranslations (widget); else { Widget *kids = 0; Cardinal nkids = 0; XtVaGetValues (widget, XmNchildren, &kids, XmNnumChildren, &nkids, 0); while (nkids--) fe_HackDialogTranslations (kids [nkids]); } } /* these two are now in src/DownloadFrame.cpp */ extern NET_StreamClass *fe_MakeSaveAsStream (int format_out, void *data_obj, URL_Struct *url_struct, MWContext *context); extern NET_StreamClass *fe_MakeSaveAsStreamNoPrompt (int format_out, void *data_obj, URL_Struct *url_struct, MWContext *context); /* * parse_extensions * Give a comma separated string of extensions, fills in the array of * character strings in NET_cdataStruct. * eg, "cpp,cc" becomes: * mimetype_entry->exts[0] = "cpp"; * mimetype_entry->exts[1] = "cc"; * mimetype_entry->exts[2] = NULL; */ static void parse_extensions(NET_cdataStruct* mimetype_entry, char* exts) { int i; char* p; XP_ASSERT(mimetype_entry && exts); mimetype_entry->num_exts = 0; for ( p = exts; p && *p; p = strchr(p, ',') ) { if ( *p == ',' ) p++; mimetype_entry->num_exts++; } mimetype_entry->exts = (char**) malloc(sizeof(char*) * (mimetype_entry->num_exts+1)); if ( mimetype_entry->exts == NULL ) return; for ( i = 0, p = exts; p && *p; p = strchr(p, ','), i++ ) { if ( *p == ',' ) p++; mimetype_entry->exts[i] = strdup(p); if ( strchr(mimetype_entry->exts[i], ',') ) *strchr(mimetype_entry->exts[i], ',') = '\0'; } mimetype_entry->exts[i] = NULL; } /* * add_pref_mime_type * Given the beginning of a mimetype preference, registers that * mimetype handler with netlib. */ static void add_pref_mime_type(char* name) { char buf[1024]; int32 load_action; char* extension = NULL; char* contenttype = NULL; char* command = NULL; char* description = NULL; NET_cdataStruct* mimetype_entry = NULL; NET_mdataStruct* mailcap_entry = NULL; strcpy(buf, name); strcat(buf, ".mimetype"); if ( PREF_CopyCharPref(buf, &contenttype) != PREF_OK ) goto failed; strcpy(buf, name); strcat(buf, ".extension"); if ( PREF_CopyCharPref(buf, &extension) != PREF_OK ) goto failed; strcpy(buf, name); strcat(buf, ".load_action"); if ( PREF_GetIntPref(buf, &load_action) != PREF_OK ) goto failed; strcpy(buf, name); strcat(buf, ".unix_appname"); if ( PREF_CopyCharPref(buf, &command) != PREF_OK ) goto failed; strcpy(buf, name); strcat(buf, ".description"); if ( PREF_CopyCharPref(buf, &description) != PREF_OK ) goto failed; mailcap_entry = NET_mdataCreate(); mimetype_entry = NET_cdataCreate(); mailcap_entry->contenttype = strdup(contenttype); mailcap_entry->command = command ? strdup(command) : NULL; mailcap_entry->xmode = (load_action == 1) ? strdup(NET_COMMAND_SAVE_TO_DISK) : (load_action == 3) ? strdup(NET_COMMAND_UNKNOWN) : (load_action == 4) ? strdup(NET_COMMAND_PLUGIN) : NULL; mimetype_entry->ci.type = contenttype ? strdup(contenttype) : NULL; mimetype_entry->ci.desc = description ? strdup(description) : NULL; mimetype_entry->pref_name = strdup(name); parse_extensions(mimetype_entry, extension); if ( mailcap_entry->xmode == NULL && mailcap_entry->command && *(mailcap_entry->command) && strcasecmp(mailcap_entry->contenttype, TEXT_HTML) && strcasecmp(mailcap_entry->contenttype, MESSAGE_RFC822) && strcasecmp(mailcap_entry->contenttype, MESSAGE_NEWS) ) { NET_RegisterExternalViewerCommand(mailcap_entry->contenttype, mailcap_entry->command, mailcap_entry->stream_buffer_size); } NET_cdataAdd(mimetype_entry); NET_mdataAdd(mailcap_entry); if ( extension ) XP_FREE(extension); if ( contenttype ) XP_FREE(contenttype); if ( description ) XP_FREE(description); if ( command ) XP_FREE(command); return; failed: if ( extension ) XP_FREE(extension); if ( contenttype ) XP_FREE(contenttype); if ( description ) XP_FREE(description); if ( command ) XP_FREE(command); if ( mimetype_entry ) NET_cdataFree(mimetype_entry); if ( mailcap_entry ) NET_mdataFree(mailcap_entry); } /* * fe_RegisterPrefConverters * Registers the mimetype converters that are specified by the * preferences. */ void fe_RegisterPrefConverters(void) { extern FILE* real_stderr; char* children = NULL; char* child = NULL; int index = 0; if ( PREF_CreateChildList("mime", &children) != PREF_OK ) { return; } while ( (child = PREF_NextChild(children, &index)) != NULL ) { add_pref_mime_type(child); } XP_FREE(children); } void fe_RegisterConverters (void) { #ifdef NEW_DECODERS NET_ClearAllConverters (); #endif /* NEW_DECODERS */ if (fe_encoding_extensions) { int i = 0; while (fe_encoding_extensions [i]) free (fe_encoding_extensions [i++]); free (fe_encoding_extensions); fe_encoding_extensions = 0; } /* register X specific decoders */ if (fe_globalData.encoding_filters) { char *copy = strdup (fe_globalData.encoding_filters); char *rest = copy; char *end = rest + strlen (rest); int exts_count = 0; int exts_size = 10; char **all_exts = (char **) malloc (sizeof (char *) * exts_size); while (rest < end) { char *start; char *eol, *colon; char *input, *output, *extensions, *command; eol = strchr (rest, '\n'); if (eol) *eol = 0; rest = fe_StringTrim (rest); if (! *rest) /* blank lines are ok */ continue; start = rest; colon = strchr (rest, ':'); if (! colon) goto LOSER; *colon = 0; input = fe_StringTrim (rest); rest = colon + 1; colon = strchr (rest, ':'); if (! colon) goto LOSER; *colon = 0; output = fe_StringTrim (rest); rest = colon + 1; colon = strchr (rest, ':'); if (! colon) goto LOSER; *colon = 0; extensions = fe_StringTrim (rest); rest = colon + 1; command = fe_StringTrim (rest); rest = colon + 1; if (*command) { /* First save away the extensions. */ char *rest = extensions; while (*rest) { char *start; char *comma, *end; while (isspace (*rest)) rest++; start = rest; comma = XP_STRCHR (start, ','); end = (comma ? comma - 1 : start + strlen (start)); while (end >= start && isspace (*end)) end--; if (comma) end++; if (start < end) { all_exts [exts_count] = (char *) malloc (end - start + 1); strncpy (all_exts [exts_count], start, end - start); all_exts [exts_count][end - start] = 0; if (++exts_count == exts_size) all_exts = (char **) realloc (all_exts, sizeof (char *) * (exts_size += 10)); } rest = (comma ? comma + 1 : end); } all_exts [exts_count] = 0; fe_encoding_extensions = all_exts; /* Now register the converter. */ NET_RegisterExternalDecoderCommand (input, output, command); } else { LOSER: fprintf (stderr, XP_GetString(XFE_COMMANDS_UNPARSABLE_ENCODING_FILTER_SPEC), fe_progname, start); } rest = (eol ? eol + 1 : end); } free (copy); } /* Register standard decoders This must come AFTER all calls to NET_RegisterExternalDecoderCommand(), (at least in the `NEW_DECODERS' world.) */ NET_RegisterMIMEDecoders (); /* How to save to disk. */ NET_RegisterContentTypeConverter ("*", FO_SAVE_AS, NULL, fe_MakeSaveAsStream); /* Saving any binary format as type `text' should save as `source' instead. */ NET_RegisterContentTypeConverter ("*", FO_SAVE_AS_TEXT, NULL, fe_MakeSaveAsStreamNoPrompt); NET_RegisterContentTypeConverter ("*", FO_QUOTE_MESSAGE, NULL, fe_MakeSaveAsStreamNoPrompt); /* default presentation converter - offer to save unknown types. */ NET_RegisterContentTypeConverter ("*", FO_PRESENT, NULL, fe_MakeSaveAsStream); #if 0 NET_RegisterContentTypeConverter ("*", FO_VIEW_SOURCE, NULL, fe_MakeViewSourceStream); #endif #ifndef NO_MOCHA_CONVERTER_HACK /* libmocha:LM_InitMocha() installs this convert. We blow away all * converters that were installed and hence these mocha default converters * dont get recreated. And mocha has no call to re-register them. * So this hack. - dp/brendan */ NET_RegisterContentTypeConverter(APPLICATION_JAVASCRIPT, FO_PRESENT, 0, NET_CreateMochaConverter); #endif /* NO_MOCHA_CONVERTER_HACK */ /* Parse stuff out of the .mime.types and .mailcap files. * We dont have to check dates of files for modified because all that * would have been done by the caller. The only place time checking * happens is * (1) Helperapp page is created * (2) Helpers are being saved (OK button pressed on the General Prefs). */ NET_InitFileFormatTypes (fe_globalPrefs.private_mime_types_file, fe_globalPrefs.global_mime_types_file); fe_isFileChanged(fe_globalPrefs.private_mime_types_file, 0, &fe_globalData.privateMimetypeFileModifiedTime); NET_RegisterConverters (fe_globalPrefs.private_mailcap_file, fe_globalPrefs.global_mailcap_file); fe_isFileChanged(fe_globalPrefs.private_mailcap_file, 0, &fe_globalData.privateMailcapFileModifiedTime); fe_RegisterPrefConverters(); #ifndef NO_WEB_FONTS /* Register webfont converters */ NF_RegisterConverters(); #endif /* NO_WEB_FONTS */ /* Plugins go on top of all this */ fe_RegisterPluginConverters(); } /* The Windows menu in the toolbar */ static void fe_switch_context_cb (Widget widget, XtPointer closure, XtPointer call_data) { MWContext *context = (MWContext *) closure; struct fe_MWContext_cons *cntx = fe_all_MWContexts; /* We need to watchout here. If we were holding down the menu and * before we select, a context gets destroyed (ftp is done say), then * selecting on that item would give an invalid context here. Guard * against that case by validating the context. */ while (cntx && (cntx->context != context)) cntx = cntx->next; if (!cntx) /* Ah ha! invalid context. I told you! */ return; XMapRaised(XtDisplay(CONTEXT_WIDGET(context)), XtWindow(CONTEXT_WIDGET(context))); return; } void fe_SetString(Widget widget, const char* propname, char* str) { XmString xmstr; xmstr = XmStringCreate(str, XmFONTLIST_DEFAULT_TAG); XtVaSetValues(widget, propname, xmstr, 0); XmStringFree(xmstr); }