ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

nsevents.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2007-2008 Jacek Caban for CodeWeavers
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00017  */
00018 
00019 #include "config.h"
00020 
00021 #include <stdarg.h>
00022 
00023 #define COBJMACROS
00024 
00025 #include "windef.h"
00026 #include "winbase.h"
00027 #include "winuser.h"
00028 #include "ole2.h"
00029 #include "mshtmcid.h"
00030 #include "shlguid.h"
00031 
00032 #include "wine/debug.h"
00033 #include "wine/unicode.h"
00034 
00035 #include "mshtml_private.h"
00036 #include "htmlevent.h"
00037 
00038 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
00039 
00040 typedef struct {
00041     const nsIDOMEventListenerVtbl      *lpDOMEventListenerVtbl;
00042     nsDocumentEventListener *This;
00043 } nsEventListener;
00044 
00045 struct nsDocumentEventListener {
00046     nsEventListener blur_listener;
00047     nsEventListener focus_listener;
00048     nsEventListener keypress_listener;
00049     nsEventListener load_listener;
00050     nsEventListener htmlevent_listener;
00051 
00052     LONG ref;
00053 
00054     HTMLDocumentNode *doc;
00055 };
00056 
00057 static LONG release_listener(nsDocumentEventListener *This)
00058 {
00059     LONG ref = InterlockedDecrement(&This->ref);
00060 
00061     TRACE("(%p) ref=%d\n", This, ref);
00062 
00063     if(!ref)
00064         heap_free(This);
00065 
00066     return ref;
00067 }
00068 
00069 #define NSEVENTLIST_THIS(iface) DEFINE_THIS(nsEventListener, DOMEventListener, iface)
00070 
00071 static nsresult NSAPI nsDOMEventListener_QueryInterface(nsIDOMEventListener *iface,
00072                                                         nsIIDRef riid, nsQIResult result)
00073 {
00074     nsEventListener *This = NSEVENTLIST_THIS(iface);
00075 
00076     *result = NULL;
00077 
00078     if(IsEqualGUID(&IID_nsISupports, riid)) {
00079         TRACE("(%p)->(IID_nsISupports, %p)\n", This, result);
00080         *result = NSEVENTLIST(This);
00081     }else if(IsEqualGUID(&IID_nsIDOMEventListener, riid)) {
00082         TRACE("(%p)->(IID_nsIDOMEventListener %p)\n", This, result);
00083         *result = NSEVENTLIST(This);
00084     }
00085 
00086     if(*result) {
00087         nsIWebBrowserChrome_AddRef(NSEVENTLIST(This));
00088         return NS_OK;
00089     }
00090 
00091     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
00092     return NS_NOINTERFACE;
00093 }
00094 
00095 static nsrefcnt NSAPI nsDOMEventListener_AddRef(nsIDOMEventListener *iface)
00096 {
00097     nsDocumentEventListener *This = NSEVENTLIST_THIS(iface)->This;
00098     LONG ref = InterlockedIncrement(&This->ref);
00099 
00100     TRACE("(%p) ref=%d\n", This, ref);
00101 
00102     return ref;
00103 }
00104 
00105 static nsrefcnt NSAPI nsDOMEventListener_Release(nsIDOMEventListener *iface)
00106 {
00107     nsDocumentEventListener *This = NSEVENTLIST_THIS(iface)->This;
00108 
00109     return release_listener(This);
00110 }
00111 
00112 static BOOL is_doc_child_focus(NSContainer *nscontainer)
00113 {
00114     HWND hwnd;
00115 
00116     for(hwnd = GetFocus(); hwnd && hwnd != nscontainer->hwnd; hwnd = GetParent(hwnd));
00117 
00118     return hwnd != NULL;
00119 }
00120 
00121 static nsresult NSAPI handle_blur(nsIDOMEventListener *iface, nsIDOMEvent *event)
00122 {
00123     HTMLDocumentNode *doc = NSEVENTLIST_THIS(iface)->This->doc;
00124     HTMLDocumentObj *doc_obj;
00125 
00126     TRACE("(%p)\n", doc);
00127 
00128     if(!doc || !doc->basedoc.doc_obj)
00129         return NS_ERROR_FAILURE;
00130     doc_obj = doc->basedoc.doc_obj;
00131 
00132     if(doc_obj->focus && !is_doc_child_focus(doc_obj->nscontainer)) {
00133         doc_obj->focus = FALSE;
00134         notif_focus(doc_obj);
00135     }
00136 
00137     return NS_OK;
00138 }
00139 
00140 static nsresult NSAPI handle_focus(nsIDOMEventListener *iface, nsIDOMEvent *event)
00141 {
00142     HTMLDocumentNode *doc = NSEVENTLIST_THIS(iface)->This->doc;
00143     HTMLDocumentObj *doc_obj;
00144 
00145     TRACE("(%p)\n", doc);
00146 
00147     if(!doc)
00148         return NS_ERROR_FAILURE;
00149     doc_obj = doc->basedoc.doc_obj;
00150 
00151     if(!doc_obj->focus) {
00152         doc_obj->focus = TRUE;
00153         notif_focus(doc_obj);
00154     }
00155 
00156     return NS_OK;
00157 }
00158 
00159 static nsresult NSAPI handle_keypress(nsIDOMEventListener *iface,
00160         nsIDOMEvent *event)
00161 {
00162     HTMLDocumentNode *doc = NSEVENTLIST_THIS(iface)->This->doc;
00163     HTMLDocumentObj *doc_obj;
00164 
00165     if(!doc)
00166         return NS_ERROR_FAILURE;
00167     doc_obj = doc->basedoc.doc_obj;
00168 
00169     TRACE("(%p)->(%p)\n", doc, event);
00170 
00171     update_doc(&doc_obj->basedoc, UPDATE_UI);
00172     if(doc_obj->usermode == EDITMODE)
00173         handle_edit_event(&doc_obj->basedoc, event);
00174 
00175     return NS_OK;
00176 }
00177 
00178 static void handle_docobj_load(HTMLDocumentObj *doc)
00179 {
00180     IOleCommandTarget *olecmd = NULL;
00181     HRESULT hres;
00182 
00183     if(!doc->client)
00184         return;
00185 
00186     hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd);
00187     if(SUCCEEDED(hres)) {
00188         if(doc->download_state) {
00189             VARIANT state, progress;
00190 
00191             V_VT(&progress) = VT_I4;
00192             V_I4(&progress) = 0;
00193             IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETPROGRESSPOS,
00194                     OLECMDEXECOPT_DONTPROMPTUSER, &progress, NULL);
00195 
00196             V_VT(&state) = VT_I4;
00197             V_I4(&state) = 0;
00198             IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETDOWNLOADSTATE,
00199                     OLECMDEXECOPT_DONTPROMPTUSER, &state, NULL);
00200         }
00201 
00202         IOleCommandTarget_Exec(olecmd, &CGID_ShellDocView, 103, 0, NULL, NULL);
00203         IOleCommandTarget_Exec(olecmd, &CGID_MSHTML, IDM_PARSECOMPLETE, 0, NULL, NULL);
00204         IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_HTTPEQUIV_DONE, 0, NULL, NULL);
00205 
00206         IOleCommandTarget_Release(olecmd);
00207     }
00208     doc->download_state = 0;
00209 }
00210 
00211 static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event)
00212 {
00213     HTMLDocumentNode *doc = NSEVENTLIST_THIS(iface)->This->doc;
00214     HTMLDocumentObj *doc_obj;
00215     nsIDOMHTMLElement *nsbody = NULL;
00216 
00217     TRACE("(%p)\n", doc);
00218 
00219     if(!doc || !doc->basedoc.window)
00220         return NS_ERROR_FAILURE;
00221     doc_obj = doc->basedoc.doc_obj;
00222 
00223     connect_scripts(doc->basedoc.window);
00224 
00225     if(doc_obj->nscontainer->editor_controller) {
00226         nsIController_Release(doc_obj->nscontainer->editor_controller);
00227         doc_obj->nscontainer->editor_controller = NULL;
00228     }
00229 
00230     if(doc_obj->usermode == EDITMODE)
00231         handle_edit_load(&doc_obj->basedoc);
00232 
00233     if(doc == doc_obj->basedoc.doc_node)
00234         handle_docobj_load(doc_obj);
00235 
00236     set_ready_state(doc->basedoc.window, READYSTATE_COMPLETE);
00237 
00238     if(doc == doc_obj->basedoc.doc_node) {
00239         if(doc_obj->view_sink)
00240             IAdviseSink_OnViewChange(doc_obj->view_sink, DVASPECT_CONTENT, -1);
00241 
00242         if(doc_obj->frame) {
00243             static const WCHAR wszDone[] = {'D','o','n','e',0};
00244             IOleInPlaceFrame_SetStatusText(doc_obj->frame, wszDone);
00245         }
00246 
00247         update_title(doc_obj);
00248     }
00249 
00250     if(!doc->nsdoc) {
00251         ERR("NULL nsdoc\n");
00252         return NS_ERROR_FAILURE;
00253     }
00254 
00255     nsIDOMHTMLDocument_GetBody(doc->nsdoc, &nsbody);
00256     if(nsbody) {
00257         fire_event(doc, EVENTID_LOAD, TRUE, (nsIDOMNode*)nsbody, event);
00258         nsIDOMHTMLElement_Release(nsbody);
00259     }
00260 
00261     return NS_OK;
00262 }
00263 
00264 static nsresult NSAPI handle_htmlevent(nsIDOMEventListener *iface, nsIDOMEvent *event)
00265 {
00266     HTMLDocumentNode *doc = NSEVENTLIST_THIS(iface)->This->doc;
00267     const PRUnichar *type;
00268     nsIDOMEventTarget *event_target;
00269     nsIDOMNode *nsnode;
00270     nsAString type_str;
00271     eventid_t eid;
00272     nsresult nsres;
00273 
00274     TRACE("\n");
00275 
00276     nsAString_Init(&type_str, NULL);
00277     nsIDOMEvent_GetType(event, &type_str);
00278     nsAString_GetData(&type_str, &type);
00279     eid = str_to_eid(type);
00280     nsAString_Finish(&type_str);
00281 
00282     nsres = nsIDOMEvent_GetTarget(event, &event_target);
00283     if(NS_FAILED(nsres) || !event_target) {
00284         ERR("GetEventTarget failed: %08x\n", nsres);
00285         return NS_OK;
00286     }
00287 
00288     nsres = nsIDOMEventTarget_QueryInterface(event_target, &IID_nsIDOMNode, (void**)&nsnode);
00289     nsIDOMEventTarget_Release(event_target);
00290     if(NS_FAILED(nsres)) {
00291         ERR("Could not get nsIDOMNode: %08x\n", nsres);
00292         return NS_OK;
00293     }
00294 
00295     fire_event(doc, eid, TRUE, nsnode, event);
00296 
00297     nsIDOMNode_Release(nsnode);
00298 
00299     return NS_OK;
00300 }
00301 
00302 #undef NSEVENTLIST_THIS
00303 
00304 #define EVENTLISTENER_VTBL(handler) \
00305     { \
00306         nsDOMEventListener_QueryInterface, \
00307         nsDOMEventListener_AddRef, \
00308         nsDOMEventListener_Release, \
00309         handler, \
00310     }
00311 
00312 static const nsIDOMEventListenerVtbl blur_vtbl =      EVENTLISTENER_VTBL(handle_blur);
00313 static const nsIDOMEventListenerVtbl focus_vtbl =     EVENTLISTENER_VTBL(handle_focus);
00314 static const nsIDOMEventListenerVtbl keypress_vtbl =  EVENTLISTENER_VTBL(handle_keypress);
00315 static const nsIDOMEventListenerVtbl load_vtbl =      EVENTLISTENER_VTBL(handle_load);
00316 static const nsIDOMEventListenerVtbl htmlevent_vtbl = EVENTLISTENER_VTBL(handle_htmlevent);
00317 
00318 static void init_event(nsIDOMEventTarget *target, const PRUnichar *type,
00319         nsIDOMEventListener *listener, BOOL capture)
00320 {
00321     nsAString type_str;
00322     nsresult nsres;
00323 
00324     nsAString_InitDepend(&type_str, type);
00325     nsres = nsIDOMEventTarget_AddEventListener(target, &type_str, listener, capture);
00326     nsAString_Finish(&type_str);
00327     if(NS_FAILED(nsres))
00328         ERR("AddEventTarget failed: %08x\n", nsres);
00329 
00330 }
00331 
00332 static void init_listener(nsEventListener *This, nsDocumentEventListener *listener,
00333         const nsIDOMEventListenerVtbl *vtbl)
00334 {
00335     This->lpDOMEventListenerVtbl = vtbl;
00336     This->This = listener;
00337 }
00338 
00339 void add_nsevent_listener(HTMLDocumentNode *doc, nsIDOMNode *nsnode, LPCWSTR type)
00340 {
00341     nsIDOMEventTarget *target;
00342     nsresult nsres;
00343 
00344     if(nsnode)
00345         nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMEventTarget, (void**)&target);
00346     else
00347         nsres = nsIDOMWindow_QueryInterface(doc->basedoc.window->nswindow, &IID_nsIDOMEventTarget, (void**)&target);
00348     if(NS_FAILED(nsres)) {
00349         ERR("Could not get nsIDOMEventTarget interface: %08x\n", nsres);
00350         return;
00351     }
00352 
00353     init_event(target, type, NSEVENTLIST(&doc->nsevent_listener->htmlevent_listener), TRUE);
00354     nsIDOMEventTarget_Release(target);
00355 }
00356 
00357 void release_nsevents(HTMLDocumentNode *doc)
00358 {
00359     if(doc->nsevent_listener) {
00360         doc->nsevent_listener->doc = NULL;
00361         release_listener(doc->nsevent_listener);
00362         doc->nsevent_listener = NULL;
00363     }
00364 }
00365 
00366 void init_nsevents(HTMLDocumentNode *doc)
00367 {
00368     nsDocumentEventListener *listener;
00369     nsIDOMEventTarget *target;
00370     nsresult nsres;
00371 
00372     static const PRUnichar wsz_blur[]      = {'b','l','u','r',0};
00373     static const PRUnichar wsz_focus[]     = {'f','o','c','u','s',0};
00374     static const PRUnichar wsz_keypress[]  = {'k','e','y','p','r','e','s','s',0};
00375     static const PRUnichar wsz_load[]      = {'l','o','a','d',0};
00376 
00377     listener = heap_alloc(sizeof(nsDocumentEventListener));
00378     if(!listener)
00379         return;
00380 
00381     listener->ref = 1;
00382     listener->doc = doc;
00383 
00384     init_listener(&listener->blur_listener,        listener, &blur_vtbl);
00385     init_listener(&listener->focus_listener,       listener, &focus_vtbl);
00386     init_listener(&listener->keypress_listener,    listener, &keypress_vtbl);
00387     init_listener(&listener->load_listener,        listener, &load_vtbl);
00388     init_listener(&listener->htmlevent_listener,   listener, &htmlevent_vtbl);
00389 
00390     doc->nsevent_listener = listener;
00391 
00392     nsres = nsIDOMWindow_QueryInterface(doc->basedoc.window->nswindow, &IID_nsIDOMEventTarget, (void**)&target);
00393     if(NS_FAILED(nsres)) {
00394         ERR("Could not get nsIDOMEventTarget interface: %08x\n", nsres);
00395         return;
00396     }
00397 
00398     init_event(target, wsz_blur,       NSEVENTLIST(&listener->blur_listener),        TRUE);
00399     init_event(target, wsz_focus,      NSEVENTLIST(&listener->focus_listener),       TRUE);
00400     init_event(target, wsz_keypress,   NSEVENTLIST(&listener->keypress_listener),    FALSE);
00401     init_event(target, wsz_load,       NSEVENTLIST(&listener->load_listener),        TRUE);
00402 
00403     nsIDOMEventTarget_Release(target);
00404 }

Generated on Sun May 27 2012 04:25:03 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.