1 /* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */
2 
3 /* AbiSource Application Framework
4  * Copyright (C) 1998-2000 AbiSource, Inc.
5  * Copyright (C) 2002 William Lachance
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  * 02110-1301 USA.
21  */
22 
23   /*
24   * Port to Maemo Development Platform
25   * Author: INdT - Renato Araujo <renato.filho@indt.org.br>
26   */
27 
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31 
32 #include <gtk/gtk.h>
33 #include <gdk/gdkkeysyms.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <unistd.h>
37 #include <sys/stat.h>
38 #include <string.h>
39 #include <vector>
40 
41 #include "ap_Features.h"
42 #include "ut_string.h"
43 #include "ut_types.h"
44 #include "ut_assert.h"
45 #include "ut_files.h"
46 #include "ut_misc.h"
47 #include "ut_sleep.h"
48 #include "xap_Gtk2Compat.h"
49 #include "xap_ViewListener.h"
50 #include "xap_UnixApp.h"
51 #include "xap_UnixFrameImpl.h"
52 #include "xap_Frame.h"
53 #include "ev_UnixKeyboard.h"
54 #include "ev_UnixMouse.h"
55 #include "ev_UnixMenuBar.h"
56 #include "ev_UnixMenuPopup.h"
57 #include "ev_UnixToolbar.h"
58 #include "ev_EditMethod.h"
59 #include "xav_View.h"
60 #include "fv_View.h"
61 #include "fv_FrameEdit.h"
62 #include "fl_DocLayout.h"
63 #include "xad_Document.h"
64 #include "gr_CairoGraphics.h"
65 #include "xap_UnixDialogHelper.h"
66 #include "xap_UnixClipboard.h"
67 #include "xap_Strings.h"
68 #include "xap_Prefs.h"
69 #include "ap_FrameData.h"
70 #include "ap_UnixFrame.h"
71 #include "ev_Mouse.h"
72 
73 #include "ie_types.h"
74 #include "ie_imp.h"
75 #include "ie_impGraphic.h"
76 #include "fg_Graphic.h"
77 
78 #ifdef HAVE_GCONF
79 #include "ev_GnomeToolbar.h"
80 #endif
81 
82 #if defined(EMBEDDED_TARGET) && EMBEDDED_TARGET == EMBEDDED_TARGET_HILDON
83 #include "hildon/xap_UnixHildonApp.h"
84 #endif
85 
86 
87 enum {
88 	TARGET_DOCUMENT, // 0, to sync with gtk_drag_dest_add_text_target's default info value
89  	TARGET_IMAGE,
90 	TARGET_URI_LIST,
91 	TARGET_URL,
92 	TARGET_UNKNOWN
93 };
94 
95 static const GtkTargetEntry XAP_UnixFrameImpl__knownDragTypes[] = {
96 	{(gchar *)"text/uri-list", 	0, TARGET_URI_LIST},
97 	{(gchar *)"_NETSCAPE_URL", 	0, TARGET_URL},
98 	{(gchar *)"image/gif", 	0, TARGET_IMAGE},
99 	{(gchar *)"image/jpeg", 	0, TARGET_IMAGE},
100 	{(gchar *)"image/png", 	0, TARGET_IMAGE},
101 	{(gchar *)"image/tiff", 	0, TARGET_IMAGE},
102 	{(gchar *)"image/vnd", 	0, TARGET_IMAGE},
103 	{(gchar *)"image/bmp", 	0, TARGET_IMAGE},
104 	{(gchar *)"image/x-xpixmap", 	0, TARGET_IMAGE},
105 
106     // RDF types
107     {(gchar *)"text/x-vcard", 0, TARGET_DOCUMENT}
108 };
109 
110 struct DragInfo {
111 	GtkTargetEntry * entries;
112 	guint			 count;
113 
DragInfoDragInfo114 	DragInfo()
115 		: entries(NULL), count(0)
116 	{
117 	}
118 
~DragInfoDragInfo119 	~DragInfo()
120 	{
121 		for(guint i = 0; i < count; i++)
122 			g_free(entries[i].target);
123 
124 		g_free(entries);
125 	}
126 
addEntryDragInfo127 	void addEntry(const char * target, guint flags, guint info)
128 	{
129 		count++;
130 		entries = (GtkTargetEntry *)g_realloc(entries, count * sizeof(GtkTargetEntry));
131 		entries[count - 1].target = g_strdup(target);
132 		entries[count - 1].flags = flags;
133 		entries[count - 1].info = info;
134 	}
135 
136 private:
137 	DragInfo& operator=(const DragInfo & rhs);
138 	DragInfo(const DragInfo & rhs);
139 };
140 
141 /*!
142  * Build targets table from supported mime types.
143  */
s_getDragInfo()144 static DragInfo * s_getDragInfo ()
145 {
146 	static DragInfo dragInfo;
147 	bool			isInitialized = FALSE;
148 
149 	if (isInitialized) {
150 		return &dragInfo;
151 	}
152 
153 	std::vector<std::string>::const_iterator iter;
154 	std::vector<std::string>::const_iterator end;
155 
156 	// static types
157 	for (gsize idx = 0; idx < G_N_ELEMENTS(XAP_UnixFrameImpl__knownDragTypes); idx++) {
158 		dragInfo.addEntry(XAP_UnixFrameImpl__knownDragTypes[idx].target,
159 						   XAP_UnixFrameImpl__knownDragTypes[idx].flags,
160 						   XAP_UnixFrameImpl__knownDragTypes[idx].info);
161 	}
162 
163 	// document types
164 	std::vector<std::string> &mimeTypes = IE_Imp::getSupportedMimeTypes();
165 	iter = mimeTypes.begin();
166 	end = mimeTypes.end();
167 	while (iter != end) {
168 		dragInfo.addEntry((*iter).c_str(), 0, TARGET_DOCUMENT);
169 		iter++;
170 	}
171 
172 	// image types
173 	mimeTypes = IE_ImpGraphic::getSupportedMimeTypes();
174 	iter = mimeTypes.begin();
175 	end = mimeTypes.end();
176 	while (iter != end) {
177 		dragInfo.addEntry((*iter).c_str(), 0, TARGET_IMAGE);
178 		iter++;
179 	}
180 
181 	isInitialized = TRUE;
182 
183 	return &dragInfo;
184 }
185 
s_mapMimeToUriType(const char * uri)186 static int s_mapMimeToUriType (const char * uri)
187 {
188 	if (!uri || !strlen(uri))
189 		return TARGET_UNKNOWN;
190 
191 	int target = TARGET_UNKNOWN;
192 
193 	gchar *mimeType;
194 
195 	mimeType = UT_go_get_mime_type (uri);
196 
197 	if (g_ascii_strcasecmp (mimeType, "application/octet-stream") == 0) {
198 		FREEP (mimeType);
199 		std::string suffix = UT_pathSuffix(uri);
200 		if (!suffix.empty()) {
201 			const gchar *mt = IE_Imp::getMimeTypeForSuffix(suffix.c_str());
202 			if (!mt) {
203 				mt = IE_ImpGraphic::getMimeTypeForSuffix(suffix.c_str());
204 			}
205 			if (mt) {
206 				/* we to g_free that later */
207 				mimeType = g_strdup(mt);
208 			}
209 			else {
210 				return target;
211 			}
212 		}
213 		else {
214 			return target;
215 		}
216 	}
217 
218 	UT_DEBUGMSG(("DOM: mimeType %s dropped into AbiWord(%s)\n", mimeType, uri));
219 
220 	DragInfo * dragInfo = s_getDragInfo();
221 	for (size_t i = 0; i < dragInfo->count; i++)
222 		if (!g_ascii_strcasecmp (mimeType, dragInfo->entries[i].target)) {
223 			target = dragInfo->entries[i].info;
224 			break;
225 		}
226 
227 	g_free (mimeType);
228 	return target;
229 }
230 
231 static void
s_loadImage(const UT_UTF8String & file,FV_View * pView,XAP_Frame * pF,gint x,gint y)232 s_loadImage (const UT_UTF8String & file, FV_View * pView, XAP_Frame * pF, gint x, gint y)
233 {
234 	FG_Graphic    * pFG  = 0;
235 	UT_Error error = IE_ImpGraphic::loadGraphic (file.utf8_str(), 0, &pFG);
236 	if (error != UT_OK || !pFG)
237 		{
238 			UT_DEBUGMSG(("Dom: could not import graphic (%s)\n", file.utf8_str()));
239 			return;
240 		}
241 	UT_sint32 xoff = static_cast<AP_UnixFrame*>(pF)->getDocumentAreaXoff();
242 	UT_sint32 yoff = static_cast<AP_UnixFrame*>(pF)->getDocumentAreaYoff();
243 	UT_sint32 mouseX = x - xoff;
244 	UT_sint32 mouseY = y - yoff;
245 	UT_DEBUGMSG(("x %d xoff %d y %d yoff %d ",y,xoff,y,yoff));
246 	if(pView && pView->getGraphics())
247 		mouseX = pView->getGraphics()->tlu(mouseX);
248 	if(pView && pView->getGraphics())
249 		mouseY = pView->getGraphics()->tlu(mouseY);
250 #ifdef DEBUG
251 	double xInch = (double) mouseX/1440.;
252 	double yInch = (double) mouseY/1440.;
253 #endif
254 
255 	UT_DEBUGMSG(("Insert Image at logical (x,y) %d %d \n",mouseX,mouseY));
256 
257 	UT_DEBUGMSG(("Insert Image at x %f in y %f in \n",xInch,yInch));
258 	pView->cmdInsertPositionedGraphic(pFG,mouseX,mouseY);
259 	DELETEP(pFG);
260 }
261 
262 static void
s_loadImage(const UT_ByteBuf & bytes,FV_View * pView,XAP_Frame * pF,gint x,gint y)263 s_loadImage (const UT_ByteBuf & bytes, FV_View * pView, XAP_Frame * pF, gint x, gint y)
264 {
265 	FG_Graphic    * pFG  = 0;
266 	UT_Error error = IE_ImpGraphic::loadGraphic(bytes, 0, &pFG);
267 	if (error != UT_OK || !pFG)
268 		{
269 			UT_DEBUGMSG(("JK: could not import graphic from data buffer\n"));
270 			return;
271 		}
272 	UT_sint32 xoff = static_cast<AP_UnixFrame*>(pF)->getDocumentAreaXoff();
273 	UT_sint32 yoff = static_cast<AP_UnixFrame*>(pF)->getDocumentAreaYoff();
274 	UT_sint32 mouseX = x - xoff;
275 	UT_sint32 mouseY = y - yoff;
276 	UT_DEBUGMSG(("x %d newX %d y %d newY %d ",y,xoff,y,yoff));
277 	if(pView && pView->getGraphics())
278 		mouseX = pView->getGraphics()->tlu(mouseX);
279 	if(pView && pView->getGraphics())
280 		mouseY = pView->getGraphics()->tlu(mouseY);
281 
282 	pView->cmdInsertPositionedGraphic(pFG,mouseX,mouseY);
283 	DELETEP(pFG);
284 }
285 
286 static void
s_loadDocument(const UT_UTF8String & file,XAP_Frame * pFrame)287 s_loadDocument (const UT_UTF8String & file, XAP_Frame * pFrame)
288 {
289 	XAP_Frame * pNewFrame = 0;
290 	if (pFrame->isDirty() || pFrame->getFilename() ||
291 		(pFrame->getViewNumber() > 0))
292 		pNewFrame = XAP_App::getApp()->newFrame ();
293 	else
294 		pNewFrame = pFrame;
295 
296 
297 	UT_Error error = pNewFrame->loadDocument(file.utf8_str(), 0 /* IEFT_Unknown */);
298 	if (error)
299 		{
300 			// TODO: warn user that we couldn't open that file
301 			// TODO: we crash if we just delete this without putting something
302 			// TODO: in it, so let's go ahead and open an untitled document
303 			// TODO: for now.
304 			UT_DEBUGMSG(("DOM: couldn't load document %s\n", file.utf8_str()));
305 			pNewFrame->loadDocument((const char *)NULL, 0 /* IEFT_Unknown */);
306 		}
307 }
308 
s_pasteFile(const UT_UTF8String & file,XAP_Frame * pFrame)309 static void s_pasteFile(const UT_UTF8String & file, XAP_Frame * pFrame)
310 {
311 	    if(!pFrame)
312 			return;
313 	    XAP_App * pApp = XAP_App::getApp();
314 	    PD_Document * newDoc = new PD_Document();
315 	    UT_Error err = newDoc->readFromFile(file.utf8_str(), IEFT_Unknown);
316 	    if ( err != UT_OK )
317 		{
318 			UNREFP(newDoc);
319 			return;
320 		}
321 		FV_View * pView = static_cast<FV_View *>(pFrame->getCurrentView());
322 		// we'll share the same graphics context, which won't matter because
323 		// we only use it to get font metrics and stuff and not actually draw
324 		GR_Graphics *pGraphics = pView->getGraphics();
325 	    // create a new layout and view object for the doc
326 	    FL_DocLayout *pDocLayout = new FL_DocLayout(newDoc,pGraphics);
327 	    FV_View copyView(pApp,0,pDocLayout);
328 
329 	    pDocLayout->setView (&copyView);
330 	    pDocLayout->fillLayouts();
331 
332 	    copyView.cmdSelect(0, 0, FV_DOCPOS_BOD, FV_DOCPOS_EOD); // select all the contents of the new doc
333 	    copyView.cmdCopy(); // copy the contents of the new document
334 	    pView->cmdPaste ( true ); // paste the contents into the existing document honoring the formatting
335 
336 	    DELETEP(pDocLayout);
337 	    UNREFP(newDoc);
338 	    return ;
339 }
340 
341 static void
s_loadUri(XAP_Frame * pFrame,const char * uri,gint x,gint y)342 s_loadUri (XAP_Frame * pFrame, const char * uri,gint x, gint y)
343 {
344 	FV_View * pView  = static_cast<FV_View*>(pFrame->getCurrentView ());
345 
346 	int type = s_mapMimeToUriType (uri);
347 	if (type == TARGET_UNKNOWN)
348 		{
349 			UT_DEBUGMSG(("DOM: unknown uri type: %s\n", uri));
350 			return;
351 		}
352 
353 	if (type == TARGET_IMAGE)
354 		{
355 			s_loadImage (uri, pView,pFrame,x,y);
356 			return;
357 		}
358 	else
359 		{
360 			if(pFrame)
361 			{
362 				AP_FrameData *pFrameData = static_cast<AP_FrameData *>(pFrame->getFrameData());
363 				if(pFrameData && pFrameData->m_bIsWidget)
364 				{
365 					s_pasteFile(uri,pFrame);
366 				}
367 				else if(pFrame->isDirty() || pFrame->getFilename())
368 				{
369 					s_pasteFile(uri,pFrame);
370 				}
371 				else
372 				{
373 					s_loadDocument (uri, pFrame);
374 				}
375 			}
376 		}
377 }
378 
379 static void
s_loadUriList(XAP_Frame * pFrame,const char * uriList,gint x,gint y)380 s_loadUriList (XAP_Frame * pFrame,  const char * uriList,gint x, gint y)
381 {
382 	gchar ** uris = g_uri_list_extract_uris(uriList);
383 	gchar ** uriIter = uris;
384 
385 	while (uriIter && *uriIter) {
386 		s_loadUri(pFrame,*uriIter,x,y);
387 		uriIter++;
388 	}
389 	g_strfreev(uris);
390 }
391 
392 static void
s_pasteText(XAP_Frame * pFrame,const char * target_name,const unsigned char * data,UT_uint32 data_length)393 s_pasteText (XAP_Frame * pFrame, const char * target_name,
394 			 const unsigned char * data, UT_uint32 data_length)
395 {
396 	FV_View   * pView  = static_cast<FV_View*>(pFrame->getCurrentView ());
397 	PD_Document * pDoc = pView->getDocument ();
398 
399 	IEFileType file_type = IEFT_Unknown;
400 
401 	file_type = IE_Imp::fileTypeForMimetype (target_name);
402 	if (file_type == IEFT_Unknown)
403 		file_type = IE_Imp::fileTypeForContents (reinterpret_cast<const char *>(data), data_length);
404 
405 	if (file_type != IEFT_Unknown)
406 		{
407 			IE_Imp * importer = NULL;
408 
409 			if (UT_OK == IE_Imp::constructImporter (pDoc, file_type, &importer) && importer)
410 				{
411 					PD_DocumentRange dr(pDoc, pView->getPoint(), pView->getPoint());
412 					importer->pasteFromBuffer(&dr, data, data_length);
413 
414 					delete importer;
415 				}
416 		}
417 }
418 
419 static void
s_drag_data_get_cb(GtkWidget *,GdkDragContext *,GtkSelectionData * selection,guint,guint,gpointer)420 s_drag_data_get_cb (GtkWidget        * /*widget*/,
421 					GdkDragContext   * /*context*/,
422 					GtkSelectionData *selection,
423 					guint             /*_info*/,
424 					guint             /*_time*/,
425 					gpointer          /*user_data*/)
426 {
427 	void * data = NULL;
428 	UT_uint32 dataLen = 0;
429 	const char * formatFound = NULL;
430 
431 	GdkAtom target = gtk_selection_data_get_target(selection);
432 	char *targetName = gdk_atom_name(target);
433 	char *formatList[2];
434 
435 	formatList[0] = targetName;
436 	formatList[1] = 0;
437 
438 	XAP_UnixApp * pApp = static_cast<XAP_UnixApp *>(XAP_App::getApp ());
439 	XAP_Frame * pFrame = pApp->getLastFocussedFrame();
440 	if(!pFrame)
441 		return;
442 	FV_View * pView = static_cast<FV_View *>(pFrame->getCurrentView());
443 	if(!pView)
444 		return;
445 	UT_DEBUGMSG(("UnixFrameImpl: s_drag_data_get_cb(%s)\n", targetName));
446 	if(strcmp(targetName,"text/uri-list") == 0)
447 	{
448 		char * szName = *pApp->getTmpFile();
449 		if(!szName)
450 			return;
451 		UT_sint32 iLen = strlen(szName);
452 		UT_DEBUGMSG(("Gave name %s to Nautilus \n",szName));
453 		gtk_selection_data_set (selection,
454 								target,
455 								8,
456 								(guchar *) szName,
457 								iLen);
458 
459 		g_free(targetName);
460 		return;
461 	}
462 	EV_EditMouseContext emc = pView->getLastMouseContext();
463 	if(emc == EV_EMC_VISUALTEXTDRAG )
464 	{
465 		const UT_ByteBuf * pBuf = pView->getLocalBuf();
466 		UT_DEBUGMSG(("pBuf %p \n",pBuf));
467 		if(pBuf)
468 			{
469 				UT_DEBUGMSG((" data length %p \n", pBuf->getPointer(0)));
470 			}
471 		gtk_selection_data_set (selection,
472 								target,
473 								8,
474 								(guchar *) pBuf->getPointer(0),
475 								pBuf->getLength());
476 	}
477 	if(emc == EV_EMC_IMAGE)
478 	{
479 		return;
480 	}
481 	if(emc == EV_EMC_POSOBJECT)
482 	{
483 		UT_DEBUGMSG(("Dragging positioned object \n"));
484 		FV_FrameEdit * fvFrame  = pView->getFrameEdit();
485 		const UT_ByteBuf * pBuf = NULL;
486 		fvFrame->getPNGImage(&pBuf);
487 		if(pBuf)
488 		{
489 			UT_DEBUGMSG(("Got data of length %d \n",pBuf->getLength()));
490 				gtk_selection_data_set (selection,
491 										target,
492 										8,
493 										(guchar *) pBuf->getPointer(0),
494 										pBuf->getLength());
495 
496 		}
497 		return;
498 	}
499 	if (pApp->getCurrentSelection((const char **)formatList, &data, &dataLen, &formatFound))
500 		{
501 			UT_DEBUGMSG(("DOM: s_drag_data_get_cb SUCCESS!\n"));
502 			gtk_selection_data_set (selection,
503 									target,
504 									8,
505 									(guchar *)data,
506 									dataLen);
507 		}
508 
509 	g_free (targetName);
510 }
511 
512 static void
s_dndDropEvent(GtkWidget * widget,GdkDragContext *,gint x,gint y,GtkSelectionData * selection_data,guint info,guint,XAP_UnixFrameImpl * pFrameImpl)513 s_dndDropEvent(GtkWidget        *widget,
514 			   GdkDragContext   * /*context*/,
515 				 gint              x,
516 				 gint              y,
517 				 GtkSelectionData *selection_data,
518 				 guint             info,
519 				 guint             /*time*/,
520 				 XAP_UnixFrameImpl * pFrameImpl)
521 {
522 	UT_DEBUGMSG(("DOM: dnd_drop_event being handled\n"));
523 
524 	UT_return_if_fail(widget != NULL);
525 
526 	XAP_Frame * pFrame = pFrameImpl->getFrame ();
527 	FV_View   * pView  = static_cast<FV_View*>(pFrame->getCurrentView ());
528 
529 	char *targetName = gdk_atom_name(gtk_selection_data_get_target(selection_data));
530 	UT_DEBUGMSG(("JK: target in selection = %s \n", targetName));
531 
532 	if (info == TARGET_URI_LIST)
533 	{
534 		const char * rawChar = reinterpret_cast<const char *>(gtk_selection_data_get_data(selection_data));
535 		UT_DEBUGMSG(("DOM: text in selection = %s \n", rawChar));
536 		s_loadUriList (pFrame,rawChar,x,y);
537 	}
538 	else if (info == TARGET_DOCUMENT)
539 	{
540         if( !strcmp( targetName, "text/x-vcard" ))
541         {
542             UT_DEBUGMSG(("MIQ: Document target is a vcard/contact\n"));
543 
544 //            pView->cmdCharInsert( "fred" );
545             s_pasteText (pFrame, targetName, gtk_selection_data_get_data(selection_data),
546                          gtk_selection_data_get_length(selection_data));
547         }
548         else
549         {
550             UT_DEBUGMSG(("JK: Document target as data buffer\n"));
551             s_pasteText (pFrame, targetName, gtk_selection_data_get_data(selection_data),
552                          gtk_selection_data_get_length(selection_data));
553         }
554 	}
555 	else if (info == TARGET_IMAGE)
556 	{
557 		UT_ByteBuf bytes(gtk_selection_data_get_length(selection_data));
558 
559 		UT_DEBUGMSG(("JK: Image target\n"));
560 		bytes.append (gtk_selection_data_get_data(selection_data),
561 		              gtk_selection_data_get_length(selection_data));
562 		s_loadImage (bytes, pView,pFrame,x,y);
563 	}
564 	else if (info == TARGET_URL)
565 	{
566 		const char * uri = reinterpret_cast<const char *>(gtk_selection_data_get_data(selection_data));
567 		UT_DEBUGMSG(("DOM: hyperlink: %s\n", uri));
568 		//
569 		// Look to see if this is actually an image.
570 		//
571 		std::string suffix = UT_pathSuffix(uri);
572 		if (!suffix.empty())
573 		{
574 			UT_DEBUGMSG(("Suffix of uri is %s \n",suffix.c_str()));
575 			if ((suffix.substr(1,3) == "jpg") ||
576 				  (suffix.substr(1,4) == "jpeg") ||
577 				  (suffix.substr(1,3) == "png") ||
578 				  (suffix.substr(1,3) == "svg") ||
579 				  (suffix.substr(1,3) == "gif"))
580 			{
581 
582 				UT_UTF8String sUri = uri;
583 				UT_uint32 i = 0;
584 				if(sUri.length())
585 				{
586 					for(i=0;i<sUri.length()-1;i++)
587 					{
588 						if((sUri.substr(i,1) == "\n") ||
589 						   (sUri.substr(i,1) == " ")  )
590 						{
591 							sUri = sUri.substr(0,i);
592 							break;
593 						}
594 					}
595 				}
596 				UT_DEBUGMSG(("trimmed Uri is (%s) \n",sUri.utf8_str()));
597 				s_loadImage(sUri,pView,pFrame,x,y);
598 				g_free (targetName);
599 				return;
600 			}
601 		}
602 		pView->cmdInsertHyperlink(uri);
603 	}
604 
605 	g_free (targetName);
606 }
607 
608 static void
s_dndRealDropEvent(GtkWidget * widget,GdkDragContext * context,gint,gint,guint time,gpointer)609 s_dndRealDropEvent (GtkWidget *widget, GdkDragContext * context,
610 					gint /*x*/, gint /*y*/, guint time, gpointer /*ppFrame*/)
611 {
612 	UT_DEBUGMSG(("DOM: dnd drop event\n"));
613 	GdkAtom selection = gdk_drag_get_selection(context);
614 
615 	UT_DEBUGMSG(("RealDrag and drop event: target in selection = %s \n", gdk_atom_name(selection)));
616 	gtk_drag_get_data (widget,context,selection,time);
617 }
618 
619 static void
s_dndDragEnd(GtkWidget *,GdkDragContext *,gpointer)620 s_dndDragEnd (GtkWidget  *, GdkDragContext *, gpointer /*ppFrame*/)
621 {
622 	UT_DEBUGMSG(("DOM: dnd end event\n"));
623 
624 //	XAP_UnixApp * pApp = static_cast<XAP_UnixApp *>(XAP_App::getApp ());
625 }
626 
627 static void
s_dndDragBegin(GtkWidget *,GdkDragContext *,gpointer)628 s_dndDragBegin (GtkWidget  *, GdkDragContext *, gpointer /*ppFrame*/)
629 {
630 	UT_DEBUGMSG(("DOM: dnd begin event\n"));
631 }
632 
dragText()633 void XAP_UnixFrameImpl::dragText()
634 {
635 #if 0
636 	UT_DEBUGMSG(("DOM: XAP_UnixFrameImpl::dragText()\n"));
637 
638 	// todo: this requires an extra click in the target application. find a way to make that not suck
639 
640 	XAP_UnixClipboard *clipboard = static_cast<XAP_UnixApp *>(XAP_App::getApp())->getClipboard();
641 
642 	GtkTargetList *target_list = gtk_target_list_new (clipboard->getTargets(), clipboard->getNumTargets());
643 
644 	GdkDragContext *context = gtk_drag_begin (m_wTopLevelWindow,
645 											  target_list,
646 											  GDK_ACTION_COPY,
647 											  1,
648 											  NULL);
649 
650 	gtk_target_list_unref (target_list);
651 #endif
652 }
653 
XAP_UnixFrameImpl(XAP_Frame * pFrame)654 XAP_UnixFrameImpl::XAP_UnixFrameImpl(XAP_Frame *pFrame) :
655 	XAP_FrameImpl(pFrame),
656 	m_imContext(NULL),
657 	m_wTopLevelWindow(NULL),
658 	m_pUnixMenu(NULL),
659 	need_im_reset (false),
660 	m_bDoZoomUpdate(false),
661 	m_iNewX(0),
662 	m_iNewY(0),
663 	m_iNewWidth(0),
664 	m_iNewHeight(0),
665 	m_iZoomUpdateID(0),
666 	m_iAbiRepaintID(0),
667 	m_pUnixPopup(NULL),
668 	m_dialogFactory(XAP_App::getApp(), pFrame),
669 	m_iPreeditLen (0),
670 	m_iPreeditStart (0)
671 {
672 }
673 
~XAP_UnixFrameImpl()674 XAP_UnixFrameImpl::~XAP_UnixFrameImpl()
675 {
676 	if(m_bDoZoomUpdate) {
677 		g_source_remove(m_iZoomUpdateID);
678 	}
679 
680 	// only delete the things we created...
681 	if(m_iAbiRepaintID)
682 	{
683 		g_source_remove(m_iAbiRepaintID);
684 	}
685 
686 	DELETEP(m_pUnixMenu);
687 	DELETEP(m_pUnixPopup);
688 
689 	// unref the input method context
690 	g_object_unref (G_OBJECT (m_imContext));
691 }
692 
693 
realize(GtkWidget *,GdkEvent *,gpointer)694 void XAP_UnixFrameImpl::_fe::realize(GtkWidget *, GdkEvent * /*e*/,gpointer /*data*/)
695 {
696 }
697 
unrealize(GtkWidget *,GdkEvent *,gpointer)698 void XAP_UnixFrameImpl::_fe::unrealize(GtkWidget *, GdkEvent * /*e*/,gpointer /*data*/)
699 {
700 }
701 
sizeAllocate(GtkWidget *,GdkEvent *,gpointer)702 void XAP_UnixFrameImpl::_fe::sizeAllocate(GtkWidget *, GdkEvent * /*e*/,gpointer /*data*/)
703 {
704 }
705 
focusIn(GtkWidget *,GdkEvent *,gpointer)706 gint XAP_UnixFrameImpl::_fe::focusIn(GtkWidget *, GdkEvent * /*e*/,gpointer /*data*/)
707 {
708 	return FALSE;
709 }
710 
focusOut(GtkWidget *,GdkEvent *,gpointer)711 gint XAP_UnixFrameImpl::_fe::focusOut(GtkWidget * /* w*/, GdkEvent * /*e*/,gpointer /*data*/)
712 {
713   return FALSE;
714 }
715 
focusIMIn()716 void XAP_UnixFrameImpl::focusIMIn ()
717 {
718 	need_im_reset = true;
719 	gtk_im_context_focus_in(getIMContext());
720 	gtk_im_context_reset (getIMContext());
721 }
722 
focusIMOut()723 void XAP_UnixFrameImpl::focusIMOut ()
724 {
725 	need_im_reset = true;
726 	gtk_im_context_focus_out(getIMContext());
727 }
728 
resetIMContext()729 void XAP_UnixFrameImpl::resetIMContext()
730 {
731   if (need_im_reset)
732     {
733       need_im_reset = false;
734       gtk_im_context_reset (getIMContext());
735     }
736 }
737 
focus_in_event(GtkWidget * w,GdkEvent *,gpointer)738 gboolean XAP_UnixFrameImpl::_fe::focus_in_event(GtkWidget *w,GdkEvent */*event*/,gpointer /*user_data*/)
739 {
740 	XAP_UnixFrameImpl * pFrameImpl = static_cast<XAP_UnixFrameImpl *>(g_object_get_data(G_OBJECT(w), "user_data"));
741 	UT_return_val_if_fail(pFrameImpl,FALSE);
742 
743 	XAP_Frame* pFrame = pFrameImpl->getFrame();
744 	g_object_set_data(G_OBJECT(w), "toplevelWindowFocus",
745 						GINT_TO_POINTER(TRUE));
746 	if (pFrame->getCurrentView())
747 	{
748 		pFrame->getCurrentView()->focusChange(gtk_grab_get_current() == NULL || gtk_grab_get_current() == w ? AV_FOCUS_HERE : AV_FOCUS_NEARBY);
749 	}
750 	pFrameImpl->focusIMIn ();
751 	//
752 	// Note: GTK2's focus handler will send a superfluous expose event
753 	// which could cause the screen to be completely redrawn and flicker.
754 	// This function used to return TRUE to work around this, but that
755 	// causes gail not to see the focus event, either, which is not what
756 	// we want.  So we depend on code elsewhere to disable the class
757 	// focus handler.
758 	//
759 	return FALSE;
760 }
761 
focus_out_event(GtkWidget * w,GdkEvent *,gpointer)762 gboolean XAP_UnixFrameImpl::_fe::focus_out_event(GtkWidget *w,GdkEvent */*event*/,gpointer /*user_data*/)
763 {
764 	XAP_UnixFrameImpl * pFrameImpl = static_cast<XAP_UnixFrameImpl *>(g_object_get_data(G_OBJECT(w), "user_data"));
765 	UT_return_val_if_fail(pFrameImpl,FALSE);
766 
767 	XAP_Frame* pFrame = pFrameImpl->getFrame();
768 	g_object_set_data(G_OBJECT(w), "toplevelWindowFocus",
769 						GINT_TO_POINTER(FALSE));
770 	if (pFrame->getCurrentView())
771 		pFrame->getCurrentView()->focusChange(AV_FOCUS_NONE);
772 	pFrameImpl->focusIMOut();
773 	//
774 	// Note: GTK2's focus handler will send a superfluous expose event
775 	// which could cause the screen to be completely redrawn and flicker.
776 	// This function used to return TRUE to work around this, but that
777 	// causes gail not to see the focus event, either, which is not what
778 	// we want.  So we depend on code elsewhere to disable the class
779 	// focus handler.
780 	//
781 	return FALSE;
782 }
783 
button_press_event(GtkWidget * w,GdkEventButton * e)784 gint XAP_UnixFrameImpl::_fe::button_press_event(GtkWidget * w, GdkEventButton * e)
785 {
786 	XAP_UnixFrameImpl * pUnixFrameImpl = static_cast<XAP_UnixFrameImpl *>(g_object_get_data(G_OBJECT(w), "user_data"));
787 	XAP_Frame* pFrame = pUnixFrameImpl->getFrame();
788 	pUnixFrameImpl->setTimeOfLastEvent(e->time);
789 	AV_View * pView = pFrame->getCurrentView();
790 	EV_UnixMouse * pUnixMouse = static_cast<EV_UnixMouse *>(pFrame->getMouse());
791 
792 	gtk_grab_add(w);
793 
794 	pUnixFrameImpl->resetIMContext ();
795 
796 #if defined(EMBEDDED_TARGET) && EMBEDDED_TARGET == EMBEDDED_TARGET_HILDON
797 	/* UGLY HACK -- for some reason in the OS2006 release of maemo the VKB
798 	 * does not pop up automatically as it used to and we have to bring it up
799 	 * ourselves; since this function is static we cannot make it virtual, and
800 	 * adding an additional handler for the button_press_event does not work
801 	 * for some reason (even after changing the return value from there to 0)
802 	 */
803 	if (e->button == 1)
804 	{
805 		UT_DEBUGMSG(("Hildon button_press_event: pFrameImpl 0x%p\n",
806                      pUnixFrameImpl));
807 
808 		hildon_gtk_im_context_show(pUnixFrameImpl->getIMContext());
809 	}
810 #endif
811 
812 	if (pView)
813 		pUnixMouse->mouseClick(pView,e);
814 	return 1;
815 }
816 
button_release_event(GtkWidget * w,GdkEventButton * e)817 gint XAP_UnixFrameImpl::_fe::button_release_event(GtkWidget * w, GdkEventButton * e)
818 {
819 	XAP_UnixFrameImpl * pUnixFrameImpl = static_cast<XAP_UnixFrameImpl *>(g_object_get_data(G_OBJECT(w), "user_data"));
820 	XAP_Frame* pFrame = pUnixFrameImpl->getFrame();
821 	pUnixFrameImpl->setTimeOfLastEvent(e->time);
822 	AV_View * pView = pFrame->getCurrentView();
823 
824 	EV_UnixMouse * pUnixMouse = static_cast<EV_UnixMouse *>(pFrame->getMouse());
825 
826 	gtk_grab_remove(w);
827 
828 	if (pView)
829 		pUnixMouse->mouseUp(pView,e);
830 
831 	return 1;
832 }
833 
834 /*!
835  * Background zoom updater. It updates the view zoom level after all configure
836  * events have been processed. This is
837  */
do_ZoomUpdate(gpointer p)838 gint XAP_UnixFrameImpl::_fe::do_ZoomUpdate(gpointer /* XAP_UnixFrameImpl * */ p)
839 {
840 	XAP_UnixFrameImpl * pUnixFrameImpl = static_cast<XAP_UnixFrameImpl *>(p);
841 	XAP_Frame* pFrame = pUnixFrameImpl->getFrame();
842 	FV_View * pView = static_cast<FV_View *>(pFrame->getCurrentView());
843 	UT_sint32 prevWidth = 0;
844 	UT_sint32 prevHeight = 0;
845 	UT_sint32 iNewWidth = 0;
846 	UT_sint32 iNewHeight = 0;
847 	if(pView)
848 	{
849 		prevWidth = pView->getGraphics()->tdu(pView->getWindowWidth());
850 		prevHeight = pView->getGraphics()->tdu(pView->getWindowHeight());
851 		iNewWidth = pUnixFrameImpl->m_iNewWidth;
852 		iNewHeight = pUnixFrameImpl->m_iNewHeight;
853 		xxx_UT_DEBUGMSG(("OldWidth %d NewWidth %d \n",prevWidth,iNewWidth));
854 	}
855 	if(!pView || pFrame->isFrameLocked() ||
856 	   ((pUnixFrameImpl->m_bDoZoomUpdate) && (prevWidth == iNewWidth) && (prevHeight == iNewHeight)))
857 	{
858 		pUnixFrameImpl->m_iZoomUpdateID = 0;
859 		pUnixFrameImpl->m_bDoZoomUpdate = false;
860 		if(pView && !pFrame->isFrameLocked())
861 		{
862 				GR_Graphics * pGr = pView->getGraphics ();
863 				UT_Rect rClip;
864 				rClip.left = pGr->tlu(0);
865 				UT_sint32 iHeight = abs(iNewHeight - prevHeight);
866 				rClip.top = pGr->tlu(iNewHeight - iHeight);
867 				rClip.width = pGr->tlu(iNewWidth)+1;
868 				rClip.height = pGr->tlu(iHeight)+1;
869 				xxx_UT_DEBUGMSG(("Drawing in zoom at x %d y %d height %d width %d \n",rClip.left,rClip.top,rClip.height,rClip.width));
870 				pView->setWindowSize(iNewWidth, iNewHeight);
871 				if(!pView->isConfigureChanged())
872 				{
873 						pView->draw(&rClip);
874 				}
875 				else
876 				{
877 						pView->draw();
878 						pView->setConfigure(false);
879 				}
880 		}
881 		if(pView)
882 		{
883 			pView->setWindowSize(iNewWidth, iNewHeight);
884 		}
885 		//
886 		// Come back later when we have a view
887 		//
888    		if(!pView)
889 			return TRUE;
890 		return FALSE;
891 	}
892 	if(!pView || pFrame->isFrameLocked() ||
893 	   ((prevWidth == iNewWidth) && (pFrame->getZoomType() != XAP_Frame::z_WHOLEPAGE)))
894 	{
895 		xxx_UT_DEBUGMSG(("Abandoning zoom widths are equal \n"));
896 		pUnixFrameImpl->m_iZoomUpdateID = 0;
897 		pUnixFrameImpl->m_bDoZoomUpdate = false;
898 		if(pView && !pFrame->isFrameLocked())
899 		{
900 				GR_Graphics * pGr = pView->getGraphics ();
901 				UT_Rect rClip;
902 				rClip.left = pGr->tlu(0);
903 				UT_sint32 iHeight = abs(iNewHeight - prevHeight);
904 				rClip.top = pGr->tlu(iNewHeight - iHeight);
905 				rClip.width = pGr->tlu(iNewWidth)+1;
906 				rClip.height = pGr->tlu(iHeight)+1;
907 				xxx_UT_DEBUGMSG(("Drawing in zoom at x %d y %d height %d width %d \n",rClip.left,rClip.top,rClip.height,rClip.width));
908 				pView->setWindowSize(iNewWidth, iNewHeight);
909 				if(!pView->isConfigureChanged())
910 				{
911 						pView->draw(&rClip);
912 				}
913 				else
914 				{
915 						pView->draw();
916 						pView->setConfigure(false);
917 				}
918 		}
919 		if(pView)
920 			pView->setWindowSize(iNewWidth, iNewHeight);
921 		//
922 		// Come back later when we have a view
923 		//
924    		if(!pView)
925 			return TRUE;
926 		return FALSE;
927 	}
928 
929 	pUnixFrameImpl->m_bDoZoomUpdate = true;
930 	UT_sint32 iLoop = 0;
931 	do
932 	{
933 		// currently, we blow away the old view.  This will change, rendering
934 		// the loop superfluous.
935 		pView = static_cast<FV_View *>(pFrame->getCurrentView());
936 
937 		if(!pView)
938 		{
939 			pUnixFrameImpl->m_iZoomUpdateID = 0;
940 			pUnixFrameImpl->m_bDoZoomUpdate = false;
941 			return FALSE;
942 		}
943 
944 		// oops, we're not ready yet.
945 		if (pView->isLayoutFilling())
946 			return FALSE;
947 
948 		iNewWidth = pUnixFrameImpl->m_iNewWidth;
949 		iNewHeight = pUnixFrameImpl->m_iNewHeight;
950 		//
951 		// In web mode we reflow the text to changed page set at the
952 		// current zoom.
953 		//
954 		if((pView->getViewMode() == VIEW_WEB) && (abs(iNewWidth -prevWidth) > 2) && (prevWidth > 10) && (iNewWidth > 10))
955 		{
956 			pView->setWindowSize(iNewWidth, iNewHeight);
957 			UT_sint32 iAdjustZoom = pView->calculateZoomPercentForPageWidth();
958 			FL_DocLayout * pLayout = pView->getLayout();
959 			PD_Document * pDoc = pLayout->getDocument();
960 			UT_Dimension orig_ut = DIM_IN;
961 			orig_ut = pLayout->m_docViewPageSize.getDims();
962 			double orig_width = pDoc->m_docPageSize.Width(orig_ut);
963 			double orig_height = pDoc->m_docPageSize.Height(orig_ut);
964 			double rat = static_cast<double>(iAdjustZoom)/static_cast<double>(pView->getGraphics()->getZoomPercentage()) ;
965 			double new_width = orig_width*rat;
966 			UT_DEBUGMSG(("VIEW_WEB old width %f new width %f old height %f \n",orig_width,new_width,orig_height));
967 			bool isPortrait = pLayout->m_docViewPageSize.isPortrait();
968 			pLayout->m_docViewPageSize.Set(new_width,orig_height,orig_ut);
969 			pLayout->m_docViewPageSize.Set(fp_PageSize::psCustom,orig_ut);
970 			if(isPortrait)
971 			{
972 				pLayout->m_docViewPageSize.setPortrait();
973 			}
974 			else
975 			{
976 				pLayout->m_docViewPageSize.setLandscape();
977 			}
978 			pView->rebuildLayout();
979 			pView->updateScreen(false);
980 			//
981 			// We're done. No more calls needed
982 			//
983 			return TRUE;
984 		}
985 		//
986 		// If we are here in view_web we just return
987 		//
988 		pView->setWindowSize(iNewWidth, iNewHeight);
989 		if(pView->getViewMode() == VIEW_WEB)
990 		{
991 			return TRUE;
992 		}
993 		pFrame->quickZoom(); // was update zoom
994 		iLoop++;
995 	}
996 	while(((iNewWidth != pUnixFrameImpl->m_iNewWidth) || (iNewHeight != pUnixFrameImpl->m_iNewHeight))
997 		&& (iLoop < 10));
998 
999 	pUnixFrameImpl->m_iZoomUpdateID = 0;
1000 	pUnixFrameImpl->m_bDoZoomUpdate = false;
1001 	return FALSE;
1002 }
1003 
configure_event(GtkWidget * w,GdkEventConfigure * e)1004 gint XAP_UnixFrameImpl::_fe::configure_event(GtkWidget* w, GdkEventConfigure *e)
1005 {
1006 	// This is basically a resize event.
1007 
1008 	XAP_UnixFrameImpl * pUnixFrameImpl = static_cast<XAP_UnixFrameImpl *>(g_object_get_data(G_OBJECT(w), "user_data"));
1009 	XAP_Frame* pFrame = pUnixFrameImpl->getFrame();
1010 	AV_View * pView = pFrame->getCurrentView();
1011 	if (pView)
1012 	{
1013 		if (pUnixFrameImpl->m_iNewWidth == e->width &&
1014 		    pUnixFrameImpl->m_iNewHeight == e->height &&
1015 		    pUnixFrameImpl->m_iNewY == e->y &&
1016 		    pUnixFrameImpl->m_iNewX == e->x)
1017 			return 1;
1018 		pUnixFrameImpl->m_iNewWidth = e->width;
1019 		pUnixFrameImpl->m_iNewHeight = e->height;
1020 		pUnixFrameImpl->m_iNewY = e->y;
1021 		pUnixFrameImpl->m_iNewX = e->x;
1022 		xxx_UT_DEBUGMSG(("Drawing in zoom at x %d y %d height %d width %d \n",e->x,e->y,e->height,e->width));
1023 		XAP_App * pApp = XAP_App::getApp();
1024 		UT_sint32 x,y;
1025 		UT_uint32 width,height,flags;
1026 		pApp->getGeometry(&x,&y,&width,&height,&flags);
1027 //
1028 // Who ever wants to change this code in the future. The height and widths you
1029 // get from the event struct are the height and widths of the drawable area of
1030 // the screen. We want the height and width of the entire widget which we get
1031 // from the m_wTopLevelWindow widget.
1032 // -- MES
1033 //
1034 
1035 #if defined(EMBEDDED_TARGET) && EMBEDDED_TARGET == EMBEDDED_TARGET_HILDON
1036 #else
1037         GtkWindow * pWin = NULL;
1038 		if(pFrame->getFrameMode() == XAP_NormalFrame) {
1039 			pWin = GTK_WINDOW(pUnixFrameImpl->m_wTopLevelWindow);
1040 			// worth remembering size?
1041 			GdkWindowState state = gdk_window_get_state (gtk_widget_get_window(GTK_WIDGET(pWin)));
1042 			if (!(state & GDK_WINDOW_STATE_ICONIFIED ||
1043 				  state & GDK_WINDOW_STATE_MAXIMIZED ||
1044 				  state & GDK_WINDOW_STATE_FULLSCREEN)) {
1045 
1046 				gint gwidth,gheight;
1047 				gtk_window_get_size(pWin,&gwidth,&gheight);
1048 				pApp->setGeometry(e->x,e->y,gwidth,gheight,flags);
1049 			}
1050 		}
1051 #endif
1052 
1053 		// Dynamic Zoom Implementation
1054 
1055 		if(!pUnixFrameImpl->m_bDoZoomUpdate && (pUnixFrameImpl->m_iZoomUpdateID == 0))
1056 		{
1057 			pUnixFrameImpl->m_iZoomUpdateID = g_idle_add(reinterpret_cast<GSourceFunc>(do_ZoomUpdate), static_cast<gpointer>(pUnixFrameImpl));
1058 		}
1059 
1060 	}
1061 	gtk_widget_grab_focus(w);
1062 	return 1;
1063 }
1064 
motion_notify_event(GtkWidget * w,GdkEventMotion * e)1065 gint XAP_UnixFrameImpl::_fe::motion_notify_event(GtkWidget* w, GdkEventMotion* e)
1066 {
1067 	XAP_UnixFrameImpl * pUnixFrameImpl = static_cast<XAP_UnixFrameImpl *>(g_object_get_data(G_OBJECT(w), "user_data"));
1068 	if(e->type == GDK_MOTION_NOTIFY)
1069 	{
1070 		//
1071 		// swallow queued drag events and just get the last one.
1072 		//
1073 		GdkEvent  * eNext = gdk_event_peek();
1074 		if(eNext && eNext->type == GDK_MOTION_NOTIFY)
1075 		{
1076 			g_object_unref(G_OBJECT(e));
1077 			e = reinterpret_cast<GdkEventMotion *>(eNext);
1078 			while(eNext && eNext->type == GDK_MOTION_NOTIFY)
1079 			{
1080 				xxx_UT_DEBUGMSG(("Swallowing drag event \n"));
1081 				gdk_event_free(eNext);
1082 				eNext = gdk_event_get();
1083 				gdk_event_free(reinterpret_cast<GdkEvent *>(e));
1084 				e = reinterpret_cast<GdkEventMotion *>(eNext);
1085 				eNext = gdk_event_peek();
1086 			}
1087 			if(eNext != NULL)
1088 			{
1089 				gdk_event_free(eNext);
1090 			}
1091 		}
1092 	}
1093 
1094 	XAP_Frame* pFrame = pUnixFrameImpl->getFrame();
1095 	pUnixFrameImpl->setTimeOfLastEvent(e->time);
1096 	AV_View * pView = pFrame->getCurrentView();
1097 	EV_UnixMouse * pUnixMouse = static_cast<EV_UnixMouse *>(pFrame->getMouse());
1098 
1099 	if (pView)
1100 		pUnixMouse->mouseMotion(pView, e);
1101 
1102 	return 1;
1103 }
1104 
scroll_notify_event(GtkWidget * w,GdkEventScroll * e)1105 gint XAP_UnixFrameImpl::_fe::scroll_notify_event(GtkWidget* w, GdkEventScroll* e)
1106 {
1107 	xxx_UT_DEBUGMSG(("Scroll event \n"));
1108 	XAP_UnixFrameImpl * pUnixFrameImpl = static_cast<XAP_UnixFrameImpl *>(g_object_get_data(G_OBJECT(w), "user_data"));
1109 	XAP_Frame* pFrame = pUnixFrameImpl->getFrame();
1110 	pUnixFrameImpl->setTimeOfLastEvent(e->time);
1111 	AV_View * pView = pFrame->getCurrentView();
1112 	EV_UnixMouse * pUnixMouse = static_cast<EV_UnixMouse *>(pFrame->getMouse());
1113 
1114 	if (pView)
1115 		pUnixMouse->mouseScroll(pView, e);
1116 
1117 	return 1;
1118 }
1119 
key_release_event(GtkWidget * w,GdkEventKey * e)1120 gint XAP_UnixFrameImpl::_fe::key_release_event(GtkWidget* w, GdkEventKey* e)
1121 {
1122 	XAP_UnixFrameImpl * pUnixFrameImpl = static_cast<XAP_UnixFrameImpl *>(g_object_get_data(G_OBJECT(w), "user_data"));
1123 
1124 	// Let IM handle the event first.
1125 	if (gtk_im_context_filter_keypress(pUnixFrameImpl->getIMContext(), e)) {
1126 	    UT_DEBUGMSG(("IMCONTEXT keyevent swallow: %u\n", e->keyval));
1127 		pUnixFrameImpl->queueIMReset ();
1128 	    return 0;
1129 	}
1130 	return TRUE;
1131 }
1132 
key_press_event(GtkWidget * w,GdkEventKey * e)1133 gint XAP_UnixFrameImpl::_fe::key_press_event(GtkWidget* w, GdkEventKey* e)
1134 {
1135 	XAP_UnixFrameImpl * pUnixFrameImpl = static_cast<XAP_UnixFrameImpl *>(g_object_get_data(G_OBJECT(w), "user_data"));
1136 
1137 	// Let IM handle the event first.
1138 	if (gtk_im_context_filter_keypress(pUnixFrameImpl->getIMContext(), e)) {
1139 		pUnixFrameImpl->queueIMReset ();
1140 
1141 		if ((e->state & GDK_MOD1_MASK) ||
1142 			(e->state & GDK_MOD3_MASK) ||
1143 			(e->state & GDK_MOD4_MASK))
1144 			return 0;
1145 
1146 		// ... else, stop this signal
1147 		g_signal_stop_emission (G_OBJECT(w),
1148 								g_signal_lookup ("key_press_event",
1149 												 G_OBJECT_TYPE (w)), 0);
1150 		return 1;
1151 	}
1152 
1153 	XAP_Frame* pFrame = pUnixFrameImpl->getFrame();
1154 	pUnixFrameImpl->setTimeOfLastEvent(e->time);
1155 	AV_View * pView = pFrame->getCurrentView();
1156 	ev_UnixKeyboard * pUnixKeyboard = static_cast<ev_UnixKeyboard *>(pFrame->getKeyboard());
1157 
1158 	if (pView)
1159 		pUnixKeyboard->keyPressEvent(pView, e);
1160 
1161 	// stop emission for keys that would take the focus away from the document widget
1162 	switch (e->keyval) {
1163 	case GDK_KEY_Tab:
1164 	case GDK_KEY_ISO_Left_Tab:
1165 	case GDK_KEY_Left:
1166 	case GDK_KEY_Up:
1167 	case GDK_KEY_Right:
1168 	case GDK_KEY_Down:
1169 		return TRUE;
1170 		break;
1171 	}
1172 
1173 	return FALSE;
1174 }
1175 
delete_event(GtkWidget * w,GdkEvent *,gpointer)1176 gint XAP_UnixFrameImpl::_fe::delete_event(GtkWidget * w, GdkEvent * /*event*/, gpointer /*data*/)
1177 {
1178 	XAP_UnixFrameImpl * pUnixFrameImpl = static_cast<XAP_UnixFrameImpl *>(g_object_get_data(G_OBJECT(w), "user_data"));
1179 	XAP_Frame* pFrame = pUnixFrameImpl->getFrame();
1180 	XAP_App * pApp = XAP_App::getApp();
1181 	UT_return_val_if_fail(pApp,FALSE);
1182 	if(pApp->isBonoboRunning())
1183 		return FALSE;
1184 
1185 	UT_ASSERT(pApp->getMenuActionSet());
1186 
1187 	const EV_EditMethodContainer * pEMC = pApp->getEditMethodContainer();
1188 	UT_return_val_if_fail(pEMC,FALSE);
1189 
1190 	// was "closeWindow", TRUE, FALSE
1191 	const EV_EditMethod * pEM = pEMC->findEditMethodByName("closeWindowX");
1192 	UT_ASSERT_HARMLESS(pEM);
1193 
1194 	if (pEM)
1195 	{
1196 		if (pEM->Fn(pFrame->getCurrentView(),NULL))
1197 		{
1198 			// returning FALSE means destroy the window, continue along the
1199 			// chain of Gtk destroy events
1200 
1201 			return FALSE;
1202 		}
1203 	}
1204 
1205 	// returning TRUE means do NOT destroy the window; halt the message
1206 	// chain so it doesn't see destroy
1207 	return TRUE;
1208 }
1209 
1210 #if GTK_CHECK_VERSION(3,0,0)
draw(GtkWidget * w,cairo_t * cr)1211 gboolean XAP_UnixFrameImpl::_fe::draw(GtkWidget * w, cairo_t * cr)
1212 #else
1213 gboolean XAP_UnixFrameImpl::_fe::expose(GtkWidget * w, GdkEventExpose* pExposeEvent)
1214 #endif
1215 {
1216 	XAP_UnixFrameImpl * pUnixFrameImpl = static_cast<XAP_UnixFrameImpl *>(g_object_get_data(G_OBJECT(w), "user_data"));
1217 	FV_View * pView = static_cast<FV_View *>(pUnixFrameImpl->getFrame()->getCurrentView());
1218 	double x, y, width, height;
1219 #if GTK_CHECK_VERSION(3,0,0)
1220 	cairo_clip_extents (cr, &x, &y, &width, &height);
1221 	width -= x;
1222 	height -= y;
1223 #else
1224 	x = pExposeEvent->area.x;
1225 	y = pExposeEvent->area.y;
1226 	width = pExposeEvent->area.width;
1227 	height = pExposeEvent->area.height;
1228 #endif
1229 /* Jean: commenting out next lines since the zoom update code does draw only
1230  * part of what needs to be updated. */
1231 //	if((pUnixFrameImpl->m_bDoZoomUpdate) || (pUnixFrameImpl->m_iZoomUpdateID != 0))
1232 //	{
1233 //		return TRUE;
1234 //	}
1235 	if(pView)
1236 	{
1237 		GR_Graphics * pGr = pView->getGraphics ();
1238 		UT_Rect rClip;
1239 		if (pGr->getPaintCount () > 0)
1240 			return TRUE;
1241 		xxx_UT_DEBUGMSG(("Expose area: x %d y %d width %d  height %d \n",pExposeEvent->area.x,pExposeEvent->area.y,pExposeEvent->area.width,pExposeEvent->area.height));
1242 		rClip.left = pGr->tlu(x);
1243 		rClip.top = pGr->tlu(y);
1244 #if GTK_CHECK_VERSION(3,0,0)
1245 		rClip.width = pGr->tlu(width);
1246 		rClip.height = pGr->tlu(height);
1247 		static_cast<GR_CairoGraphics *>(pGr)->setCairo(cr);
1248 		pView->draw(&rClip);
1249 		static_cast<GR_CairoGraphics *>(pGr)->setCairo(NULL);
1250 #else
1251 		rClip.width = pGr->tlu(width)+1;
1252 		rClip.height = pGr->tlu(height)+1;
1253 		pView->draw(&rClip);
1254 #endif
1255 	}
1256 	return TRUE;
1257 }
1258 
1259 static bool bScrollWait = false;
1260 
1261 class _ViewScroll
1262 {
1263 public:
_ViewScroll(AV_View * pView,UT_sint32 amount)1264 	_ViewScroll(AV_View * pView, UT_sint32 amount):
1265 		m_pView(pView),m_amount(amount)
1266 	{
1267 	}
1268 	AV_View * m_pView;
1269 	UT_sint32 m_amount;
1270 };
1271 
_actualScroll(gpointer data)1272 static gboolean _actualScroll(gpointer data)
1273 {
1274 	_ViewScroll * pVS = reinterpret_cast<_ViewScroll *>(data);
1275 	AV_View * pView = pVS->m_pView;
1276 	xxx_UT_DEBUGMSG(("vScrollSchanged callback\n"));
1277 	if (pView)
1278 		pView->sendVerticalScrollEvent(pVS->m_amount);
1279 	bScrollWait = false;
1280 	delete pVS;
1281 	return FALSE;
1282 }
1283 
vScrollChanged(GtkAdjustment * w,gpointer)1284 void XAP_UnixFrameImpl::_fe::vScrollChanged(GtkAdjustment * w, gpointer /*data*/)
1285 {
1286 	XAP_UnixFrameImpl * pUnixFrameImpl = static_cast<XAP_UnixFrameImpl *>(g_object_get_data(G_OBJECT(w), "user_data"));
1287 	if(bScrollWait)
1288 	{
1289 		xxx_UT_DEBUGMSG(("VScroll dropped!!! \n"));
1290 		return;
1291 	}
1292 	XAP_Frame* pFrame = pUnixFrameImpl->getFrame();
1293 	AV_View * pView = pFrame->getCurrentView();
1294 	_ViewScroll * pVS = new  _ViewScroll(pView,static_cast<UT_sint32>(gtk_adjustment_get_value(w)));
1295 	bScrollWait = true;
1296 	g_idle_add(_actualScroll, (gpointer) pVS);
1297 }
1298 
hScrollChanged(GtkAdjustment * w,gpointer)1299 void XAP_UnixFrameImpl::_fe::hScrollChanged(GtkAdjustment * w, gpointer /*data*/)
1300 {
1301 	XAP_UnixFrameImpl * pUnixFrameImpl = static_cast<XAP_UnixFrameImpl *>(g_object_get_data(G_OBJECT(w), "user_data"));
1302 	XAP_Frame* pFrame = pUnixFrameImpl->getFrame();
1303 	AV_View * pView = pFrame->getCurrentView();
1304 
1305 	if (pView)
1306 		pView->sendHorizontalScrollEvent(static_cast<UT_sint32>(gtk_adjustment_get_value(w)));
1307 }
1308 
destroy(GtkWidget *,gpointer)1309 void XAP_UnixFrameImpl::_fe::destroy(GtkWidget * /*widget*/, gpointer /*data*/)
1310 {
1311 }
1312 
1313 /*****************************************************************/
1314 
_nullUpdate() const1315 void XAP_UnixFrameImpl::_nullUpdate() const
1316 {
1317    	for (UT_uint32 i = 0; (i < 5) && gtk_events_pending(); i++)
1318 		gtk_main_iteration ();
1319 }
1320 
_initialize()1321 void XAP_UnixFrameImpl::_initialize()
1322 {
1323 	UT_DEBUGMSG (("XAP_UnixFrameImpl::_initialize()\n"));
1324 
1325     	// get a handle to our keyboard binding mechanism
1326  	// and to our mouse binding mechanism.
1327  	EV_EditEventMapper * pEEM = XAP_App::getApp()->getEditEventMapper();
1328  	UT_ASSERT(pEEM);
1329 
1330 	m_pKeyboard = new ev_UnixKeyboard(pEEM);
1331 	UT_ASSERT(m_pKeyboard);
1332 
1333 	m_pMouse = new EV_UnixMouse(pEEM);
1334 	UT_ASSERT(m_pMouse);
1335 }
1336 
_setCursor(GR_Graphics::Cursor c)1337 void XAP_UnixFrameImpl::_setCursor(GR_Graphics::Cursor c)
1338 {
1339 //	if (m_cursor == c)
1340 //		return;
1341 //	m_cursor = c;
1342 	FV_View * pView = static_cast<FV_View *>(getFrame()->getCurrentView());
1343 	if(pView)
1344 	{
1345 		GR_Graphics * pG = pView->getGraphics();
1346 		if(pG && pG->queryProperties( GR_Graphics::DGP_PAPER))
1347 			return;
1348 	}
1349 	if(getTopLevelWindow() == NULL || (m_iFrameMode != XAP_NormalFrame))
1350 		return;
1351 
1352 	GdkCursorType cursor_number;
1353 
1354 	switch (c)
1355 	{
1356 	default:
1357 		UT_ASSERT_HARMLESS(UT_NOT_IMPLEMENTED);
1358 		/*FALLTHRU*/
1359 	case GR_Graphics::GR_CURSOR_DEFAULT:
1360 		cursor_number = GDK_LEFT_PTR;
1361 		break;
1362 
1363 	case GR_Graphics::GR_CURSOR_IBEAM:
1364 		cursor_number = GDK_XTERM;
1365 		break;
1366 
1367 	//I have changed the shape of the arrow so get a consistent
1368 	//behaviour in the bidi build; I think the new arrow is better
1369 	//for the purpose anyway
1370 
1371 	case GR_Graphics::GR_CURSOR_RIGHTARROW:
1372 		cursor_number = GDK_SB_RIGHT_ARROW; //GDK_ARROW;
1373 		break;
1374 
1375 	case GR_Graphics::GR_CURSOR_LEFTARROW:
1376 		cursor_number = GDK_SB_LEFT_ARROW; //GDK_LEFT_PTR;
1377 		break;
1378 
1379 	case GR_Graphics::GR_CURSOR_IMAGE:
1380 		cursor_number = GDK_FLEUR;
1381 		break;
1382 
1383 	case GR_Graphics::GR_CURSOR_IMAGESIZE_NW:
1384 		cursor_number = GDK_TOP_LEFT_CORNER;
1385 		break;
1386 
1387 	case GR_Graphics::GR_CURSOR_IMAGESIZE_N:
1388 		cursor_number = GDK_TOP_SIDE;
1389 		break;
1390 
1391 	case GR_Graphics::GR_CURSOR_IMAGESIZE_NE:
1392 		cursor_number = GDK_TOP_RIGHT_CORNER;
1393 		break;
1394 
1395 	case GR_Graphics::GR_CURSOR_IMAGESIZE_E:
1396 		cursor_number = GDK_RIGHT_SIDE;
1397 		break;
1398 
1399 	case GR_Graphics::GR_CURSOR_IMAGESIZE_SE:
1400 		cursor_number = GDK_BOTTOM_RIGHT_CORNER;
1401 		break;
1402 
1403 	case GR_Graphics::GR_CURSOR_IMAGESIZE_S:
1404 		cursor_number = GDK_BOTTOM_SIDE;
1405 		break;
1406 
1407 	case GR_Graphics::GR_CURSOR_IMAGESIZE_SW:
1408 		cursor_number = GDK_BOTTOM_LEFT_CORNER;
1409 		break;
1410 
1411 	case GR_Graphics::GR_CURSOR_IMAGESIZE_W:
1412 		cursor_number = GDK_LEFT_SIDE;
1413 		break;
1414 
1415 	case GR_Graphics::GR_CURSOR_LEFTRIGHT:
1416 		cursor_number = GDK_SB_H_DOUBLE_ARROW;
1417 		break;
1418 
1419 	case GR_Graphics::GR_CURSOR_UPDOWN:
1420 		cursor_number = GDK_SB_V_DOUBLE_ARROW;
1421 		break;
1422 
1423 	case GR_Graphics::GR_CURSOR_EXCHANGE:
1424 		cursor_number = GDK_EXCHANGE;
1425 		break;
1426 
1427 	case GR_Graphics::GR_CURSOR_GRAB:
1428 		cursor_number = GDK_HAND1;
1429 		break;
1430 
1431 	case GR_Graphics::GR_CURSOR_LINK:
1432 		cursor_number = GDK_HAND2;
1433 		break;
1434 
1435 	case GR_Graphics::GR_CURSOR_WAIT:
1436 		cursor_number = GDK_WATCH;
1437 		break;
1438 
1439 	case GR_Graphics::GR_CURSOR_HLINE_DRAG:
1440 		cursor_number = GDK_SB_V_DOUBLE_ARROW;
1441 		break;
1442 
1443 	case GR_Graphics::GR_CURSOR_VLINE_DRAG:
1444 		cursor_number = GDK_SB_H_DOUBLE_ARROW;
1445 		break;
1446 
1447 	case GR_Graphics::GR_CURSOR_CROSSHAIR:
1448 		cursor_number = GDK_CROSSHAIR;
1449 		break;
1450 
1451 	case GR_Graphics::GR_CURSOR_DOWNARROW:
1452 		cursor_number = GDK_SB_DOWN_ARROW;
1453 		break;
1454 
1455 	case GR_Graphics::GR_CURSOR_DRAGTEXT:
1456 		cursor_number = GDK_TARGET;
1457 		break;
1458 
1459 	case GR_Graphics::GR_CURSOR_COPYTEXT:
1460 		cursor_number = GDK_DRAPED_BOX;
1461 		break;
1462 	}
1463 	xxx_UT_DEBUGMSG(("Set cursor number in Frame %d to %d \n",c,cursor_number));
1464 	GdkCursor * cursor = gdk_cursor_new(cursor_number);
1465 	gdk_window_set_cursor(gtk_widget_get_window(getTopLevelWindow()), cursor);
1466 	gdk_window_set_cursor(gtk_widget_get_window(getVBoxWidget()), cursor);
1467 
1468 	gdk_window_set_cursor(gtk_widget_get_window(m_wSunkenBox), cursor);
1469 
1470 	if (m_wStatusBar)
1471 		gdk_window_set_cursor(gtk_widget_get_window(m_wStatusBar), cursor);
1472 
1473 #if GTK_CHECK_VERSION(3,0,0)
1474 	g_object_unref(cursor);
1475 #else
1476 	gdk_cursor_unref(cursor);
1477 #endif
1478 }
1479 
_setInputMode(const char * szName)1480 UT_sint32 XAP_UnixFrameImpl::_setInputMode(const char * szName)
1481 {
1482 	UT_sint32 result = XAP_App::getApp()->setInputMode(szName);
1483 	if (result == 1)
1484 	{
1485 		// if it actually changed we need to update keyboard and mouse
1486 
1487 		EV_EditEventMapper * pEEM = XAP_App::getApp()->getEditEventMapper();
1488 		UT_ASSERT(pEEM);
1489 
1490 		m_pKeyboard->setEditEventMap(pEEM);
1491 		m_pMouse->setEditEventMap(pEEM);
1492 	}
1493 
1494 	return result;
1495 }
1496 
getTopLevelWindow(void) const1497 GtkWidget * XAP_UnixFrameImpl::getTopLevelWindow(void) const
1498 {
1499 	return m_wTopLevelWindow;
1500 }
1501 
getVBoxWidget(void) const1502 GtkWidget * XAP_UnixFrameImpl::getVBoxWidget(void) const
1503 {
1504 	return m_wVBox;
1505 }
1506 
_getDialogFactory(void)1507 XAP_DialogFactory * XAP_UnixFrameImpl::_getDialogFactory(void)
1508 {
1509 	return &m_dialogFactory;
1510 }
1511 
_createInternalWindow(void)1512 GtkWidget *  XAP_UnixFrameImpl::_createInternalWindow (void)
1513 {
1514 	return gtk_window_new(GTK_WINDOW_TOPLEVEL);
1515 }
1516 
1517 // TODO: split me up into smaller pieces/subfunctions
_createTopLevelWindow(void)1518 void XAP_UnixFrameImpl::_createTopLevelWindow(void)
1519 {
1520 	// create a top-level window for us.
1521 
1522 	if(m_iFrameMode == XAP_NormalFrame)
1523 	{
1524 		m_wTopLevelWindow = _createInternalWindow ();
1525 		gtk_window_set_title(GTK_WINDOW(m_wTopLevelWindow),
1526 				     XAP_App::getApp()->getApplicationTitleForTitleBar());
1527 		gtk_window_set_resizable(GTK_WINDOW(m_wTopLevelWindow), TRUE);
1528 		gtk_window_set_role(GTK_WINDOW(m_wTopLevelWindow), "topLevelWindow");
1529 
1530 		gtk_window_set_resizable(GTK_WINDOW(m_wTopLevelWindow), TRUE);
1531 		gtk_window_set_role(GTK_WINDOW(m_wTopLevelWindow), "topLevelWindow");
1532 
1533 		g_object_set_data(G_OBJECT(m_wTopLevelWindow), "ic_attr", NULL);
1534 		g_object_set_data(G_OBJECT(m_wTopLevelWindow), "ic", NULL);
1535 
1536 	}
1537 	g_object_set_data(G_OBJECT(m_wTopLevelWindow), "toplevelWindow",
1538 						m_wTopLevelWindow);
1539 	g_object_set_data(G_OBJECT(m_wTopLevelWindow), "toplevelWindowFocus",
1540 						GINT_TO_POINTER(FALSE));
1541 	g_object_set_data(G_OBJECT(m_wTopLevelWindow), "user_data", this);
1542 
1543 	_setGeometry ();
1544 
1545 	g_signal_connect(G_OBJECT(m_wTopLevelWindow), "realize",
1546 					   G_CALLBACK(_fe::realize), NULL);
1547 	g_signal_connect(G_OBJECT(m_wTopLevelWindow), "unrealize",
1548 					   G_CALLBACK(_fe::unrealize), NULL);
1549 	g_signal_connect(G_OBJECT(m_wTopLevelWindow), "size_allocate",
1550 					   G_CALLBACK(_fe::sizeAllocate), NULL);
1551 
1552 	g_signal_connect(G_OBJECT(m_wTopLevelWindow), "focus_in_event",
1553 					   G_CALLBACK(_fe::focusIn), NULL);
1554 	g_signal_connect(G_OBJECT(m_wTopLevelWindow), "focus_out_event",
1555 					   G_CALLBACK(_fe::focusOut), NULL);
1556 
1557 	DragInfo * dragInfo = s_getDragInfo();
1558 
1559 	gtk_drag_dest_set (m_wTopLevelWindow,
1560 					   GTK_DEST_DEFAULT_ALL,
1561 					   dragInfo->entries,
1562 					   dragInfo->count,
1563 					   GDK_ACTION_COPY);
1564 
1565 	gtk_drag_dest_add_text_targets (m_wTopLevelWindow);
1566 
1567 	g_signal_connect (G_OBJECT (m_wTopLevelWindow),
1568 					  "drag_data_received",
1569 					  G_CALLBACK (s_dndDropEvent),
1570 					  static_cast<gpointer>(this));
1571   	g_signal_connect (G_OBJECT (m_wTopLevelWindow),
1572 					  "drag_drop",
1573 					  G_CALLBACK (s_dndRealDropEvent),
1574 					  static_cast<gpointer>(this));
1575 
1576   	g_signal_connect (G_OBJECT (m_wTopLevelWindow),
1577 					  "drag_end",
1578 					  G_CALLBACK (s_dndDragEnd),
1579 					  static_cast<gpointer>(this));
1580 
1581 	g_signal_connect (G_OBJECT (m_wTopLevelWindow),
1582 					  "drag_begin",
1583 					  G_CALLBACK (s_dndDragBegin),
1584 					  static_cast<gpointer>(this));
1585 	g_signal_connect (G_OBJECT (m_wTopLevelWindow), "drag_data_get",
1586 					  G_CALLBACK (s_drag_data_get_cb), this);
1587 
1588 	g_signal_connect(G_OBJECT(m_wTopLevelWindow), "delete_event",
1589 					   G_CALLBACK(_fe::delete_event), NULL);
1590 	// here we connect the "destroy" event to a signal handler.
1591 	// This event occurs when we call gtk_widget_destroy() on the window,
1592 	// or if we return 'FALSE' in the "delete_event" callback.
1593 	g_signal_connect(G_OBJECT(m_wTopLevelWindow), "destroy",
1594 					   G_CALLBACK(_fe::destroy), NULL);
1595 
1596 	g_signal_connect(G_OBJECT(m_wTopLevelWindow), "focus_in_event",
1597 					   G_CALLBACK(_fe::focus_in_event), NULL);
1598 	g_signal_connect(G_OBJECT(m_wTopLevelWindow), "focus_out_event",
1599 					   G_CALLBACK(_fe::focus_out_event), NULL);
1600 
1601 	// create a VBox inside it.
1602 
1603 	m_wVBox = gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
1604 	g_object_set_data(G_OBJECT(m_wTopLevelWindow), "vbox", m_wVBox);
1605 	g_object_set_data(G_OBJECT(m_wVBox),"user_data", this);
1606 	gtk_container_add(GTK_CONTAINER(m_wTopLevelWindow), m_wVBox);
1607 
1608 	if (m_iFrameMode != XAP_NoMenusWindowLess) {
1609 		// synthesize a menu from the info in our base class.
1610 		m_pUnixMenu = new EV_UnixMenuBar(static_cast<XAP_UnixApp*>(XAP_App::getApp()), getFrame(), m_szMenuLayoutName,
1611 										 m_szMenuLabelSetName);
1612 		UT_return_if_fail(m_pUnixMenu);
1613 		UT_DebugOnly<bool> bResult;
1614 		bResult = m_pUnixMenu->synthesizeMenuBar();
1615 		UT_ASSERT(bResult);
1616 	}
1617 
1618 	// create a toolbar instance for each toolbar listed in our base class.
1619 	// TODO for some reason, the toolbar functions require the TLW to be
1620 	// TODO realized (they reference m_wTopLevelWindow->window) before we call them.
1621 
1622 	if(m_iFrameMode == XAP_NormalFrame)
1623 		gtk_widget_realize(m_wTopLevelWindow);
1624 
1625 	_createIMContext(gtk_widget_get_window(m_wTopLevelWindow));
1626 
1627 	/* If refactoring the toolbars code, please make sure that toolbars
1628 	 * are created AFTER the main menu bar has been synthesized, otherwise
1629 	 * the embedded build will stop working
1630 	 */
1631 	if(m_iFrameMode == XAP_NormalFrame)
1632 		_createToolbars();
1633 
1634 	// Let the app-specific frame code create the contents of
1635 	// the child area of the window (between the toolbars and
1636 	// the status bar).
1637 	m_wSunkenBox = _createDocumentWindow();
1638 	gtk_container_add(GTK_CONTAINER(m_wVBox), m_wSunkenBox);
1639 	gtk_widget_show(m_wSunkenBox);
1640 
1641 	// Create statusLet the app-specific frame code create the status bar
1642 	// if it wants to.  we will put it below the document
1643 	// window (a peer with toolbars and the overall sunkenbox)
1644 	// so that it will appear outside of the scrollbars.
1645 	m_wStatusBar = NULL;
1646 
1647 #ifdef ENABLE_STATUSBAR
1648 	if(m_iFrameMode == XAP_NormalFrame)
1649 		m_wStatusBar = _createStatusBarWindow();
1650 #endif
1651 
1652 	if (m_wStatusBar)
1653 	{
1654 		gtk_widget_show(m_wStatusBar);
1655 		gtk_box_pack_end(GTK_BOX(m_wVBox), m_wStatusBar, FALSE, FALSE, 0);
1656 	}
1657 
1658 	gtk_widget_show(m_wVBox);
1659 
1660 	// set the icon
1661 	if(m_iFrameMode == XAP_NormalFrame)
1662 		_setWindowIcon();
1663 }
1664 
_createIMContext(GdkWindow * w)1665 void XAP_UnixFrameImpl::_createIMContext(GdkWindow *w)
1666 {
1667 	m_imContext = gtk_im_multicontext_new();
1668 
1669 	gtk_im_context_set_use_preedit (m_imContext, FALSE);
1670 
1671 	gtk_im_context_set_client_window(m_imContext, w);
1672 
1673 	g_signal_connect(G_OBJECT(m_imContext), "commit",
1674 					 G_CALLBACK(_imCommit_cb), this);
1675 	g_signal_connect (m_imContext, "preedit_start",
1676 					  G_CALLBACK (_imPreeditStart_cb), this);
1677 	g_signal_connect (m_imContext, "preedit_changed",
1678 					  G_CALLBACK (_imPreeditChanged_cb), this);
1679 	g_signal_connect (m_imContext, "preedit_end",
1680 					  G_CALLBACK (_imPreeditEnd_cb), this);
1681 	g_signal_connect (m_imContext, "retrieve_surrounding",
1682 					  G_CALLBACK (_imRetrieveSurrounding_cb), this);
1683 	g_signal_connect (m_imContext, "delete_surrounding",
1684 					  G_CALLBACK (_imDeleteSurrounding_cb), this);
1685 }
1686 
_imPreeditStart_cb(GtkIMContext *,gpointer data)1687 void XAP_UnixFrameImpl::_imPreeditStart_cb (GtkIMContext * /*context*/,
1688 											gpointer data)
1689 {
1690 	XAP_UnixFrameImpl * pImpl = static_cast<XAP_UnixFrameImpl*>(data);
1691 	FV_View * pView =
1692 		static_cast<FV_View*>(pImpl->getFrame()->getCurrentView ());
1693 
1694 	pImpl->m_iPreeditStart = pView->getInsPoint ();
1695 	pImpl->m_iPreeditLen = 0;
1696 
1697 	UT_DEBUGMSG(("@@@@ Preedit Started, pos %d\n", pView->getInsPoint ()));
1698 }
1699 
_imPreeditEnd_cb(GtkIMContext *,gpointer data)1700 void XAP_UnixFrameImpl::_imPreeditEnd_cb (GtkIMContext * /*context*/,
1701 										  gpointer data)
1702 {
1703 	XAP_UnixFrameImpl * pImpl = static_cast<XAP_UnixFrameImpl*>(data);
1704 	FV_View * pView =
1705 		static_cast<FV_View*>(pImpl->getFrame()->getCurrentView ());
1706 
1707 	UT_DEBUGMSG(("@@@@ Preedit Ended\n"));
1708 
1709 	if (pImpl->m_iPreeditLen)
1710 		{
1711 			// Anything that might have been entered as part of pre-edit
1712 			// needs to be nuked.
1713 			UT_DEBUGMSG(("@@@@@ deleting preedit from %d, len %d\n",
1714 						 pImpl->m_iPreeditStart,
1715 						 pImpl->m_iPreeditLen));
1716 			pView->moveInsPtTo (pImpl->m_iPreeditStart);
1717 			pView->cmdCharDelete (true, pImpl->m_iPreeditLen);
1718 
1719 			pImpl->m_iPreeditLen = 0;
1720 		}
1721 
1722 	pImpl->m_iPreeditStart = 0;
1723 }
1724 
_imPreeditChanged_cb(GtkIMContext * context,gpointer data)1725 void XAP_UnixFrameImpl::_imPreeditChanged_cb (GtkIMContext *context,
1726 											  gpointer data)
1727 {
1728 	gchar *text;
1729 	gint   len = 0;
1730 	gint   pos;
1731 
1732 	XAP_UnixFrameImpl * pImpl = static_cast<XAP_UnixFrameImpl*>(data);
1733 	XAP_Frame* pFrame = pImpl->getFrame();
1734 	FV_View * pView = static_cast<FV_View*>(pFrame->getCurrentView ());
1735 	ev_UnixKeyboard * pUnixKeyboard =
1736 		static_cast<ev_UnixKeyboard *>(pFrame->getKeyboard());
1737 
1738 	// delete previous pre-edit, if there is one
1739 	if (pImpl->m_iPreeditLen)
1740 		{
1741 			UT_DEBUGMSG(("deleting preedit from %d, len %d\n",
1742 						 pImpl->m_iPreeditStart,
1743 						 pImpl->m_iPreeditLen));
1744 			pView->moveInsPtTo (pImpl->m_iPreeditStart);
1745 			pView->cmdCharDelete (true, pImpl->m_iPreeditLen);
1746 
1747 			pImpl->m_iPreeditLen = 0;
1748 			pImpl->m_iPreeditStart = 0;
1749 		}
1750 
1751 	// fetch the updated pre-edit string.
1752 	gtk_im_context_get_preedit_string (context, &text, NULL, &pos);
1753 
1754 	if (!text || !(len = strlen (text)))
1755 		return;
1756 
1757 	pImpl->m_iPreeditStart = pView->getInsPoint ();
1758 	pImpl->m_iPreeditLen   = g_utf8_strlen (text, -1);
1759 
1760 	pUnixKeyboard->charDataEvent(pView, static_cast<EV_EditBits>(0),
1761 								 text, strlen(text));
1762 
1763 	UT_DEBUGMSG(("@@@@ Preedit Changed, text %s, len %d (utf8 chars %d)\n",
1764 				 text, len, pImpl->m_iPreeditLen));
1765 }
1766 
_imRetrieveSurrounding_cb(GtkIMContext * context,gpointer data)1767 gboolean XAP_UnixFrameImpl::_imRetrieveSurrounding_cb (GtkIMContext *context,
1768 												   gpointer data)
1769 {
1770 	XAP_UnixFrameImpl * pImpl = static_cast<XAP_UnixFrameImpl*>(data);
1771 	FV_View * pView =
1772 		static_cast<FV_View*>(pImpl->getFrame()->getCurrentView ());
1773 
1774 	if (pView == nullptr) {
1775         UT_DEBUGMSG(("XAP_UnixFrameImpl::_imRetrieveSurrounding_cb(): No current view.\n"));
1776 		return TRUE;
1777 	}
1778 
1779 	PT_DocPosition begin_p, end_p, here;
1780 
1781 	begin_p = pView->mapDocPosSimple (FV_DOCPOS_BOB);
1782 	end_p = pView->mapDocPosSimple (FV_DOCPOS_EOB);
1783 	here = pView->getInsPoint ();
1784 
1785 	UT_UCSChar * text = NULL;
1786 	if (end_p > begin_p)
1787 		text = pView->getTextBetweenPos (begin_p, end_p);
1788 
1789 	if (!text)
1790 		return TRUE;
1791 
1792 	UT_UTF8String utf (text);
1793 	DELETEPV(text);
1794 
1795 	gtk_im_context_set_surrounding (context,
1796 									utf.utf8_str(),
1797 									utf.byteLength (),
1798 									g_utf8_offset_to_pointer(utf.utf8_str(), here - begin_p) - utf.utf8_str());
1799 
1800 	return TRUE;
1801 }
1802 
_imDeleteSurrounding_cb(GtkIMContext *,gint offset,gint n_chars,gpointer data)1803 gint XAP_UnixFrameImpl::_imDeleteSurrounding_cb (GtkIMContext * /*slave*/,
1804 												 gint offset, gint n_chars,
1805 												 gpointer data)
1806 {
1807 	xxx_UT_DEBUGMSG(("Delete Surrounding\n"));
1808 	XAP_UnixFrameImpl * pImpl = static_cast<XAP_UnixFrameImpl*>(data);
1809 	FV_View * pView =
1810 		static_cast<FV_View*>(pImpl->getFrame()->getCurrentView ());
1811 
1812 	PT_DocPosition insPt = pView->getInsPoint ();
1813 	if ((gint) insPt + offset < 0)
1814 		return TRUE;
1815 
1816 	pView->moveInsPtTo (insPt + offset);
1817 	pView->cmdCharDelete (true, n_chars);
1818 
1819 	return TRUE;
1820 }
1821 
1822 // Actual keyboard commit should be done here.
_imCommit_cb(GtkIMContext * imc,const gchar * text,gpointer data)1823 void XAP_UnixFrameImpl::_imCommit_cb(GtkIMContext *imc,
1824 									 const gchar *text, gpointer data)
1825 {
1826 	XAP_UnixFrameImpl * impl = static_cast<XAP_UnixFrameImpl*>(data);
1827 	impl->_imCommit (imc, text);
1828 }
1829 
1830 // Actual keyboard commit should be done here.
_imCommit(GtkIMContext *,const gchar * text)1831 void XAP_UnixFrameImpl::_imCommit(GtkIMContext * /*imc*/, const gchar * text)
1832 {
1833 	XAP_Frame* pFrame = getFrame();
1834 	FV_View * pView = static_cast<FV_View*>(getFrame()->getCurrentView ());
1835 	ev_UnixKeyboard * pUnixKeyboard =
1836 		static_cast<ev_UnixKeyboard *>(pFrame->getKeyboard());
1837 
1838 	if (m_iPreeditLen)
1839 		{
1840 			/* delete previous pre-edit */
1841 			UT_DEBUGMSG(("deleting preedit from %d, len %d\n",
1842 						 m_iPreeditStart,
1843 						 m_iPreeditLen));
1844 			pView->moveInsPtTo (m_iPreeditStart);
1845 			pView->cmdCharDelete (true, m_iPreeditLen);
1846 
1847 			m_iPreeditLen = 0;
1848 			m_iPreeditStart = 0;
1849 		}
1850 
1851 	pUnixKeyboard->charDataEvent(pView, static_cast<EV_EditBits>(0),
1852 								 text, strlen(text));
1853 
1854 	xxx_UT_DEBUGMSG(("<<<<<<<<_imCommit: text %s, len %d\n", text, strlen(text)));
1855 }
1856 
getIMContext()1857 GtkIMContext * XAP_UnixFrameImpl::getIMContext()
1858 {
1859 	return m_imContext;
1860 }
1861 
_setGeometry()1862 void XAP_UnixFrameImpl::_setGeometry ()
1863 {
1864 	UT_sint32 app_x = 0;
1865 	UT_sint32 app_y = 0;
1866 	UT_uint32 app_w = 0;
1867 	UT_uint32 app_h = 0;
1868 	UT_uint32 app_f = 0;
1869 
1870 	XAP_UnixApp * pApp = static_cast<XAP_UnixApp*>(XAP_App::getApp ());
1871 	pApp->getGeometry (&app_x, &app_y, &app_w, &app_h, &app_f);
1872 	// (ignore app_x, app_y & app_f since the WM will set them for us just fine)
1873 
1874 	// This is now done with --geometry parsing.
1875 	if (app_w == 0 || app_w > USHRT_MAX) app_w = 760;
1876         if (app_h == 0 || app_h > USHRT_MAX) app_h = 520;
1877 
1878 	UT_DEBUGMSG(("xap_UnixFrameImpl: app-width=%lu, app-height=%lu\n",
1879 				 static_cast<unsigned long>(app_w),static_cast<unsigned long>(app_h)));
1880 
1881 	// set geometry hints as the user requested
1882 	gint user_x = 0;
1883 	gint user_y = 0;
1884 	UT_uint32 uuser_w = static_cast<UT_uint32>(app_w);
1885 	UT_uint32 uuser_h = static_cast<UT_uint32>(app_h);
1886 	UT_uint32 user_f = 0;
1887 
1888 	pApp->getWinGeometry (&user_x, &user_y, &uuser_w, &uuser_h, &user_f);
1889 	// to avoid bad signedess warnings
1890 	gint user_w = static_cast<gint>(uuser_w);
1891 	gint user_h = static_cast<gint>(uuser_h);
1892 
1893 	UT_DEBUGMSG(("xap_UnixFrameImpl: user-width=%u, user-height=%u\n",
1894 				 static_cast<unsigned>(user_w),static_cast<unsigned>(user_h)));
1895 
1896 	// Get fall-back defaults from preferences
1897 	UT_sint32 pref_x = 0;
1898 	UT_sint32 pref_y = 0;
1899 	UT_uint32 pref_w = static_cast<UT_uint32>(app_w);
1900 	UT_uint32 pref_h = static_cast<UT_uint32>(app_h);
1901 	UT_uint32 pref_f = 0;
1902 
1903 	pApp->getPrefs()->getGeometry (&pref_x, &pref_y, &pref_w, &pref_h, &pref_f);
1904 
1905 	UT_DEBUGMSG(("xap_UnixFrameImpl: pref-width=%lu, pref-height=%lu\n",
1906 				 static_cast<unsigned long>(pref_w),static_cast<unsigned long>(pref_h)));
1907 
1908 	if (!(user_f & XAP_UnixApp::GEOMETRY_FLAG_SIZE))
1909 		if (pref_f & PREF_FLAG_GEOMETRY_SIZE)
1910 			{
1911 				user_w = static_cast<guint>(pref_w);
1912 				user_h = static_cast<guint>(pref_h);
1913 				user_f |= XAP_UnixApp::GEOMETRY_FLAG_SIZE;
1914 			}
1915 	if (!(user_f & XAP_UnixApp::GEOMETRY_FLAG_POS))
1916 		if (pref_f & PREF_FLAG_GEOMETRY_POS)
1917 			{
1918 				user_x = static_cast<gint>(pref_x);
1919 				user_y = static_cast<gint>(pref_y);
1920 				user_f |= XAP_UnixApp::GEOMETRY_FLAG_POS;
1921 			}
1922 
1923 	UT_DEBUGMSG(("xap_UnixFrameImpl: user-x=%d, user-y=%d\n",
1924 				 static_cast<int>(user_x),static_cast<int>(user_y)));
1925 
1926 	if (!(user_f & XAP_UnixApp::GEOMETRY_FLAG_SIZE))
1927 		{
1928 			user_w = static_cast<guint>(app_w);
1929 			user_h = static_cast<guint>(app_h);
1930 		}
1931 
1932 	if (user_w > USHRT_MAX)
1933 		user_w = app_w;
1934         if (user_h > USHRT_MAX)
1935 		user_h = app_h;
1936 
1937 	if(getFrame()->getFrameMode() == XAP_NormalFrame)
1938 	{
1939 		GdkGeometry geom;
1940 		geom.min_width   = 100;
1941 		geom.min_height  = 100;
1942 		gtk_window_set_geometry_hints (GTK_WINDOW(m_wTopLevelWindow), m_wTopLevelWindow, &geom,
1943 									   static_cast<GdkWindowHints>(GDK_HINT_MIN_SIZE));
1944 
1945 		GdkScreen *screen = gdk_screen_get_default ();
1946 		user_w = (user_w < gdk_screen_get_width (screen) ? user_w : gdk_screen_get_width (screen));
1947 		user_h = (user_h < gdk_screen_get_height (screen) ? user_h : gdk_screen_get_height (screen));
1948 		gtk_window_set_default_size (GTK_WINDOW(m_wTopLevelWindow), user_w, user_h);
1949 	}
1950 
1951 	// Because we're clever, we only honor this flag when we
1952 	// are the first (well, only) top level frame available.
1953 	// This is so the user's window manager can find better
1954 	// places for new windows, instead of having our windows
1955 	// pile upon each other.
1956 
1957 	if (pApp->getFrameCount () <= 1)
1958 		if (user_f & XAP_UnixApp::GEOMETRY_FLAG_POS)
1959 			{
1960 				gtk_window_move (GTK_WINDOW(m_wTopLevelWindow), user_x, user_y);
1961 			}
1962 
1963 	// Remember geometry settings for next time
1964 	pApp->getPrefs()->setGeometry (user_x, user_y, user_w, user_h, user_f);
1965 
1966 }
1967 
1968 /*!
1969  * This code is used by the dynamic menu API to rebuild the menus after a
1970  * a change in the menu structure.
1971  */
_rebuildMenus(void)1972 void XAP_UnixFrameImpl::_rebuildMenus(void)
1973 {
1974 	// no menu? then nothing to rebuild!
1975 	if (!m_pUnixMenu) return;
1976 
1977 	// destroy old menu
1978 	m_pUnixMenu->destroy();
1979 	DELETEP(m_pUnixMenu);
1980 
1981 	// build new one.
1982 	m_pUnixMenu = new EV_UnixMenuBar(static_cast<XAP_UnixApp*>(XAP_App::getApp()), getFrame(),
1983 					 m_szMenuLayoutName,
1984 					 m_szMenuLabelSetName);
1985 	UT_return_if_fail(m_pUnixMenu);
1986 	UT_DebugOnly<bool> bResult = m_pUnixMenu->rebuildMenuBar();
1987 	UT_ASSERT_HARMLESS(bResult);
1988 }
1989 
1990 /*!
1991  * This code is used by the dynamic toolbar API to rebuild a toolbar after a
1992  * a change in the toolbar structure.
1993  */
_rebuildToolbar(UT_uint32 ibar)1994 void XAP_UnixFrameImpl::_rebuildToolbar(UT_uint32 ibar)
1995 {
1996 	XAP_Frame*	pFrame = getFrame();
1997 	// Destroy the old toolbar
1998 	EV_Toolbar * pToolbar = static_cast<EV_Toolbar *>(m_vecToolbars.getNthItem(ibar));
1999 	const char * szTBName = reinterpret_cast<const char *>(m_vecToolbarLayoutNames.getNthItem(ibar));
2000 	EV_UnixToolbar * pUTB = static_cast<EV_UnixToolbar *>(pToolbar);
2001 	UT_sint32 oldpos = pUTB->destroy();
2002 
2003 	// Delete the old class
2004 	delete pToolbar;
2005 	if(oldpos < 0) {
2006 		return;
2007 	}
2008 
2009 	// Build a new one.
2010 	pToolbar = _newToolbar(pFrame, szTBName,
2011 			       static_cast<const char *>(m_szToolbarLabelSetName));
2012 	static_cast<EV_UnixToolbar *>(pToolbar)->rebuildToolbar(oldpos);
2013 	m_vecToolbars.setNthItem(ibar, pToolbar, NULL);
2014 	// Refill the framedata pointers
2015 
2016 	pFrame->refillToolbarsInFrameData();
2017 	pFrame->repopulateCombos();
2018 }
2019 
_close()2020 bool XAP_UnixFrameImpl::_close()
2021 {
2022 	gtk_widget_destroy(m_wTopLevelWindow);
2023     m_wTopLevelWindow = NULL;
2024 	return true;
2025 }
2026 
_raise()2027 bool XAP_UnixFrameImpl::_raise()
2028 {
2029 	UT_ASSERT(m_wTopLevelWindow);
2030 	if (GTK_IS_WINDOW (m_wTopLevelWindow))
2031 		gtk_window_present(GTK_WINDOW (m_wTopLevelWindow));
2032 	return true;
2033 }
2034 
_show()2035 bool XAP_UnixFrameImpl::_show()
2036 {
2037 	if(m_wTopLevelWindow) {
2038 		gtk_widget_show(m_wTopLevelWindow);
2039 	}
2040 
2041 	return true;
2042 }
2043 
_updateTitle()2044 bool XAP_UnixFrameImpl::_updateTitle()
2045 {
2046 	if (!XAP_FrameImpl::_updateTitle() || (m_wTopLevelWindow== NULL) || (m_iFrameMode != XAP_NormalFrame))
2047 	{
2048 		// no relevant change, so skip it
2049 		return false;
2050 	}
2051 
2052 	if(getFrame()->getFrameMode() == XAP_NormalFrame)
2053 	{
2054 		if (GTK_IS_WINDOW (m_wTopLevelWindow))
2055 			{
2056 				gtk_window_set_title(GTK_WINDOW(m_wTopLevelWindow), getFrame()->getTitle().utf8_str());
2057 			}
2058 	}
2059 	return true;
2060 }
2061 
_runModalContextMenu(AV_View *,const char * szMenuName,UT_sint32,UT_sint32)2062 bool XAP_UnixFrameImpl::_runModalContextMenu(AV_View * /* pView */, const char * szMenuName,
2063 											 UT_sint32 /*x*/, UT_sint32 /*y*/)
2064 {
2065 	XAP_Frame*	pFrame = getFrame();
2066 	bool bResult = true;
2067 
2068 	UT_ASSERT_HARMLESS(!m_pUnixPopup);
2069 
2070 	// WL_REFACTOR: we DON'T want to do this
2071 	m_pUnixPopup = new EV_UnixMenuPopup(static_cast<XAP_UnixApp*>(XAP_App::getApp()),
2072 										pFrame, szMenuName, m_szMenuLabelSetName);
2073 
2074 	if (m_pUnixPopup && m_pUnixPopup->synthesizeMenuPopup())
2075 	{
2076 		// Add our InputMethod selection item to the popup menu, UNLESS WE'RE DOING A PRESENTATION Borrowed
2077 		// from gtkentry.c
2078 		if(!pFrame->isMenuScrollHidden())
2079 		{
2080 				GtkWidget * menuitem;
2081 				GtkWidget * submenu;
2082 				GtkWidget * menu = m_pUnixPopup->getMenuHandle();
2083 				menuitem = gtk_separator_menu_item_new ();
2084 				gtk_widget_show (menuitem);
2085 				gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2086 
2087 				const XAP_StringSet * pSS = XAP_App::getApp()->getStringSet();
2088 
2089 				menuitem = gtk_menu_item_new_with_label (pSS->getValue(XAP_STRING_ID_XIM_Methods));
2090 
2091 				gtk_widget_show (menuitem);
2092 				submenu = gtk_menu_new ();
2093 				gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
2094 
2095 				gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2096 
2097 				gtk_im_multicontext_append_menuitems(GTK_IM_MULTICONTEXT(m_imContext),
2098 													 GTK_MENU_SHELL(submenu));
2099 		}
2100 		// the popup will steal the mouse and so we won't get the
2101 		// button_release_event and we won't know to release our
2102 		// grab.  so let's do it here.  (when raised from a keyboard
2103 		// context menu, we may not have a grab, but that should be ok.
2104 		GtkWidget * w = gtk_grab_get_current();
2105 		if (w)
2106 			gtk_grab_remove(w);
2107 
2108 		//
2109 		// OK lets not immediately drop the menu if the user releases the mouse button.
2110 		// From the gtk FAQ.
2111 		//
2112 		GdkEvent * event = gtk_get_current_event();
2113 		GdkEventButton *bevent = reinterpret_cast<GdkEventButton *>(event);
2114 		if(!bevent)
2115 		{
2116 			DELETEP(m_pUnixPopup);
2117 			return false;
2118 		}
2119 
2120 		gtk_menu_popup(GTK_MENU(m_pUnixPopup->getMenuHandle()), NULL, NULL,
2121 			       NULL, NULL, bevent->button, bevent->time);
2122 
2123 		// We run this menu synchronously, since GTK doesn't.
2124 		// Popup menus have a special "unmap" function to call
2125 		// gtk_main_quit() when they're done.
2126 		gdk_event_free(event);
2127 		gtk_main();
2128 	}
2129 
2130 	if (pFrame && pFrame->getCurrentView())
2131 		pFrame->getCurrentView()->focusChange( AV_FOCUS_HERE);
2132 
2133 	DELETEP(m_pUnixPopup);
2134 	return bResult;
2135 }
2136 
setTimeOfLastEvent(guint32 eventTime)2137 void XAP_UnixFrameImpl::setTimeOfLastEvent(guint32 eventTime)
2138 {
2139 	static_cast<XAP_UnixApp*>(XAP_App::getApp())->setTimeOfLastEvent(eventTime);
2140 }
2141 
_queue_resize()2142 void XAP_UnixFrameImpl::_queue_resize()
2143 {
2144 	gtk_widget_queue_resize(m_wTopLevelWindow);
2145 }
2146 
_getMainMenu()2147 EV_Menu* XAP_UnixFrameImpl::_getMainMenu()
2148 {
2149 	return m_pUnixMenu;
2150 }
2151 
_setFullScreen(bool changeToFullScreen)2152 void XAP_UnixFrameImpl::_setFullScreen(bool changeToFullScreen)
2153 {
2154 	if (!GTK_IS_WINDOW(m_wTopLevelWindow)) return;
2155 
2156 	if (changeToFullScreen)
2157 		gtk_window_fullscreen (GTK_WINDOW(m_wTopLevelWindow));
2158 	else
2159 		gtk_window_unfullscreen (GTK_WINDOW(m_wTopLevelWindow));
2160 }
2161 
_newToolbar(XAP_Frame * pFrame,const char * szLayout,const char * szLanguage)2162 EV_Toolbar * XAP_UnixFrameImpl::_newToolbar(XAP_Frame *pFrame,
2163 											const char *szLayout,
2164 											const char *szLanguage)
2165 {
2166 	EV_UnixToolbar *pToolbar = NULL;
2167 #ifdef HAVE_GCONF
2168 	pToolbar = new EV_GnomeToolbar(static_cast<XAP_UnixApp *>(XAP_App::getApp()), pFrame, szLayout, szLanguage);
2169 #else
2170 	pToolbar = new EV_UnixToolbar(static_cast<XAP_UnixApp *>(XAP_App::getApp()), pFrame, szLayout, szLanguage);
2171 #endif
2172 	return pToolbar;
2173 }
2174