Keyboard settings Blank screen issue fixed
[framework/uifw/ise-default.git] / mcf / gwes / gtk / mcfwindows-gtk.cpp
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.tizenopensource.org/license
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 #include "mcfwindows-gtk.h"
19 #include "mcfdebug.h"
20 #include "mcfcontroller.h"
21 #include "mcfcontext.h"
22 #include "mcfresourcecache.h"
23
24 using namespace mcf;
25
26 /**
27  * Constructor
28  */
29 CMCFWindowsImplGtk::CMCFWindowsImplGtk()
30 {
31     MCF_DEBUG();
32     /* Initializes all window resources */
33 }
34
35 /**
36  * De-constructor
37  */
38 CMCFWindowsImplGtk::~CMCFWindowsImplGtk()
39 {
40     MCF_DEBUG();
41 }
42
43 /**
44  * Make a transparent window
45  */
46 static void
47 make_transparent_window (GtkWidget *window)
48 {
49     MCF_DEBUG();
50     GdkScreen *screen;
51     GdkColormap *colormap;
52
53     screen = gtk_widget_get_screen (window);
54     if (!screen) {
55         g_warning ("failed to get window's screen");
56         return;
57     }
58
59     colormap = gdk_screen_get_rgba_colormap (screen);
60     if (!colormap) {
61         g_warning ("failed to get RGBA colormap");
62         return;
63     }
64
65     gtk_widget_set_colormap (window, colormap);
66     gtk_widget_set_app_paintable (window, TRUE);
67     gtk_widget_realize (window);
68
69 }
70
71
72 /**
73  * Create a content window and binds it into given parent window as a child
74  */
75 mcfwindow
76 CMCFWindowsImplGtk::create_base_window(const mcfwindow parentWnd, McfWindowContext *winCtx,
77                                                const mcf16 width, const mcf16 height)
78 {
79     MCF_DEBUG();
80
81     GtkWidget* pWindow = NULL;
82
83     /* pre-condition */
84     mcf_assert(parentWnd != NULL);
85     mcf_assert(winCtx != NULL);
86     mcf_assert(winCtx->etcInfoPtr == NULL);
87
88     if (winCtx->window == NULL) {
89         pWindow = (GtkWidget*)parentWnd;
90
91         if (GTK_WIDGET_TOPLEVEL(pWindow)) {
92             pWindow = (GtkWidget*)parentWnd;
93             winCtx->etcInfoPtr = NULL;
94             winCtx->window = pWindow;
95             make_transparent_window(pWindow);
96         } else {
97             GtkWidget *drawarea = NULL;
98             drawarea = gtk_drawing_area_new();
99             gtk_widget_set_size_request(pWindow, width, height);
100             gtk_widget_set_size_request(drawarea, width, height);
101             gtk_box_pack_start(GTK_BOX(pWindow), drawarea, TRUE, TRUE, 0);
102             gtk_widget_show (drawarea);
103             gtk_widget_show (pWindow);
104             winCtx->etcInfoPtr = static_cast<void*>(drawarea);
105             winCtx->window = drawarea;
106             make_transparent_window(drawarea);
107         }
108     }
109     /* post-condition */
110     return winCtx->window;
111 }
112
113 /**
114  * Creates a window
115  */
116 mcfwindow
117 CMCFWindowsImplGtk::create_window(const mcfwindow parentWnd, McfWindowContext *winCtx,
118                                           const mcf16 width, const mcf16 height)
119 {
120     MCF_DEBUG();
121     /* pre-condition */
122     mcf_assert(parentWnd);
123     mcf_assert(winCtx);
124     mcf_assert(winCtx->etcInfoPtr == NULL);
125
126     GtkWidget* window = NULL;
127
128     if (winCtx->window == NULL) {
129         window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
130         gtk_window_set_type_hint(GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_UTILITY);
131         gtk_window_set_accept_focus(GTK_WINDOW(window), FALSE);
132 #ifdef NO_SOCKETPLUG
133         GtkWidget* toplevel = gtk_widget_get_toplevel((GtkWidget*)parentWnd);
134         gtk_window_set_transient_for(GTK_WINDOW(window), GTK_WINDOW(toplevel));
135 #endif
136         /* Sets a window relation between parent and popup */
137         make_transparent_window(window);
138         gtk_window_set_default_size(GTK_WINDOW(window), width, height);
139 #ifndef NO_SOCKETPLUG
140         gtk_widget_set_app_paintable(window, TRUE);
141 #endif
142         winCtx->etcInfoPtr = NULL;
143         winCtx->window = window;
144
145         /* Window rotation*/
146         CMCFContext* context = CMCFContext::get_instance();
147
148         if (context->get_display() == DISPLAY_LANDSCAPE) {
149             set_window_rotation(window, 90);
150         }
151     }
152
153     return window;
154 }
155
156 /**
157  * Creates the dim window
158  */
159 mcfwindow
160 CMCFWindowsImplGtk::create_dim_window(const mcfwindow parentWnd, McfWindowContext *winCtx,
161                                               const mcf16 width, const mcf16 height)
162 {
163     MCF_DEBUG();
164     /* pre-condition */
165     mcf_assert(parentWnd);
166     mcf_assert(winCtx);
167     mcf_assert(winCtx->etcInfoPtr == NULL);
168     GtkWidget* window = NULL;
169
170     if (winCtx->window == NULL) {
171         window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
172         gtk_window_set_type_hint(GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_UTILITY);
173
174         gtk_widget_set_name(window, "dialog_dim_window");
175 #ifdef NO_SOCKETPLUG
176         gtk_window_set_transient_for(GTK_WINDOW(window), GTK_WINDOW(gtk_widget_get_toplevel((GtkWidget*)parentWnd)));
177 #else
178         gtk_window_set_type_hint(GTK_WINDOW(window), GDK_WINDOW_TYPE_HINT_POPUP_MENU);
179 #endif
180         gtk_window_set_accept_focus(GTK_WINDOW(window), FALSE);
181         gtk_widget_set_size_request(window, width, height);
182         gtk_window_set_opacity(GTK_WINDOW(window), 0.5);
183         gtk_widget_realize(window);
184         winCtx->etcInfoPtr = NULL;
185         winCtx->window = window;
186     }
187
188     return window;
189 }
190
191 /**
192  * Make a window relation between parent and child
193  * Caution: Currently, If we use transient_for them the ISE will occure some crash. It needs to check X11
194  */
195 void
196 CMCFWindowsImplGtk::set_parent(const mcfwindow parentWindow, const mcfwindow window)
197 {
198     MCF_DEBUG();
199     mcf_assert_return(window);
200     mcf_assert_return(parentWindow);
201 #ifdef NO_SOCKETPLUG
202     GtkWidget* widget = static_cast<GtkWidget*>(parentWindow);
203     GtkWidget* toplevel = gtk_widget_get_toplevel(widget);
204 #else
205     GtkWindow* gtkParentWindow = static_cast<GtkWindow*>(parentWindow);
206 #endif
207     GtkWindow* gtkWindow = static_cast<GtkWindow*>(window);
208 #ifdef NO_SOCKETPLUG
209     gtk_window_set_transient_for(gtkWindow, GTK_WINDOW(toplevel));
210 #endif
211 }
212
213 /**
214  * Destroys the given window
215  */
216 bool
217 CMCFWindowsImplGtk::destroy_window(mcfwindow window)
218 {
219     MCF_DEBUG();
220     mcf_assert_return_false(window);
221     /* add codes for destroying window */
222     GtkWidget* widget = static_cast<GtkWidget*>(window);
223     gtk_widget_destroy(widget);
224     return TRUE;
225 }
226
227 /**
228  * Shows the given window
229  */
230 void
231 CMCFWindowsImplGtk::show_window(const mcfwindow window, mcfboolean queue)
232 {
233     MCF_DEBUG();
234     mcf_assert_return(window);
235     GtkWidget* widget = static_cast<GtkWidget*>(window);
236     gtk_widget_show(widget);
237
238     /*Forcing expose on the magnifier window*/
239     if (queue) {
240         gtk_widget_queue_draw(widget);
241     } else {
242         gdk_window_invalidate_rect(widget->window, NULL, TRUE);
243         gdk_window_process_updates(widget->window, TRUE);
244     }
245
246     /*we will use always on top style when the window is created */
247     /*we cannot use keep_above, becase the other toplevel window cannot appear if we use it*/
248     /* X team will fix it */
249     CMCFWindows *windows = CMCFWindows::get_instance();
250     if (windows->get_base_window() != window && windows->get_dim_window() != window) {
251 #ifndef NO_SOCKETPLUG
252         gdk_window_raise(widget->window);
253 #endif
254     } else if (windows->get_dim_window() == window) {
255 #ifndef NO_SOCKETPLUG
256         gdk_window_raise(widget->window);
257 #endif
258     } else if (windows->get_base_window() == window) {
259 #ifndef NO_SOCKETPLUG
260         gdk_window_raise(gtk_widget_get_toplevel(widget)->window);
261 #endif
262     }
263 }
264
265 /**
266  * Hides the given window
267  */
268 void
269 CMCFWindowsImplGtk::hide_window(const mcfwindow window,  const mcfboolean fForce)
270 {
271     MCF_DEBUG();
272     mcf_assert_return(window);
273     GtkWidget* widget = static_cast<GtkWidget*>(window);
274     CMCFWindows *windows = CMCFWindows::get_instance();
275     if (windows->get_magnifier_window() == window && fForce == FALSE) {
276         /* Fix me : The below is a temporary code for magnifier speed enhancement */
277 #ifdef NO_SOCKETPLUG
278         gint root_x, root_y;
279         gtk_window_get_position (GTK_WINDOW(widget), &root_x, &root_y);
280         if (GTK_WIDGET_MAPPED(widget)) {
281
282             /* Window rotation*/
283             CMCFContext* context = CMCFContext::get_instance();
284             if (context->get_display() == DISPLAY_LANDSCAPE) {
285                 gtk_window_move(GTK_WINDOW(widget), gdk_screen_get_height(gdk_screen_get_default()) - 1,
286                                         gdk_screen_get_width(gdk_screen_get_default())-1);
287             } else {
288                 gtk_window_move(GTK_WINDOW(widget), gdk_screen_get_width(gdk_screen_get_default()) - 1,
289                                         gdk_screen_get_height(gdk_screen_get_default())-1);
290             }
291 #else
292         if (GTK_WIDGET_VISIBLE(widget)) {
293             gtk_window_move(GTK_WINDOW(widget), 0, gdk_screen_get_height(gdk_screen_get_default())+1);
294 #endif
295         }
296     } else {
297         if (GTK_WIDGET_VISIBLE(widget)) {
298             gtk_widget_hide(widget);
299         }
300     }
301
302 }
303
304 /**
305  * Moves the window to the given position
306  */
307 void
308 CMCFWindowsImplGtk::move_window(const mcfwindow window, const mcf16 x, const mcf16 y)
309 {
310     MCF_DEBUG();
311     mcf_assert_return(window);
312     GtkWidget* widget = static_cast<GtkWidget*>(window);
313     gtk_window_move(GTK_WINDOW(widget), x, y);
314 }
315
316 /**
317 * Resizes the window to the given metric
318 */
319 void
320 CMCFWindowsImplGtk::resize_window(const mcfwindow window, const mcf16 width, const mcf16 height)
321 {
322     MCF_DEBUG();
323     mcf_assert_return(window);
324     GtkWidget* widget = static_cast<GtkWidget*>(window);
325     if (GTK_IS_WINDOW(widget)) {
326         gtk_widget_set_size_request(GTK_WIDGET(widget), width, height);
327     }
328 }
329
330 /**
331 * Resizes the window to the given metric
332 */
333 void
334 CMCFWindowsImplGtk::move_resize_window(const mcfwindow window, const mcf16 x, const mcf16 y,
335                                                const mcf16 width, const mcf16 height)
336 {
337     MCF_DEBUG();
338     mcf_assert_return(window);
339     GtkWidget* widget = static_cast<GtkWidget*>(window);
340     gdk_window_move_resize(GDK_WINDOW(widget->window), x, y, width, height);
341 }
342
343
344 /**
345 * Update the window to redraw given area
346 */
347 void
348 CMCFWindowsImplGtk::update_window(const mcfwindow window, const mcf16 x, const mcf16 y,
349                                           const mcf16 width, const mcf16 height)
350 {
351     MCF_DEBUG();
352     mcf_assert_return(window);
353     GtkWidget* widget = static_cast<GtkWidget*>(window);
354
355     if (!GTK_WIDGET_VISIBLE(widget)) gtk_widget_show(widget);
356
357     if (x + y + width + height == 0) {
358         gdk_window_invalidate_rect(widget->window, NULL, TRUE);
359     } else {
360         GdkRectangle rect = { x, y, width, height} ;
361         gdk_window_invalidate_rect(widget->window, &rect, TRUE);
362     }
363
364     gdk_window_process_updates(widget->window, TRUE);
365 }
366
367 /**
368  * Returns the position of x,y,width,height of the given window
369  */
370 mcfboolean
371 CMCFWindowsImplGtk::get_window_rect(const mcfwindow window, McfRectangle *rect)
372 {
373     MCF_DEBUG();
374     mcfboolean ret = FALSE;
375     GtkWidget* widget = static_cast<GtkWidget*>(window);
376     if (rect && GTK_WIDGET_REALIZED(widget)) {
377         CMCFContext *context = CMCFContext::get_instance();
378         CMCFWindows *windows = CMCFWindows::get_instance();
379         if (context->get_display() == DISPLAY_LANDSCAPE) {
380             gdk_window_get_root_origin (GDK_WINDOW(gtk_widget_get_toplevel(widget)->window),  &(rect->x), &(rect->y));
381             if (window == windows->get_base_window()) {
382                 CMCFUtils *utils = CMCFUtils::get_instance();
383                 CMCFResourceCache *cache = CMCFResourceCache::get_instance();
384
385                 mcfint scnWidth, scnHeight;
386                 utils->get_screen_resolution(&scnWidth, &scnHeight);
387                 rect->y = scnWidth - cache->get_cur_layout(window)->height;
388             }
389         } else {
390             gdk_window_get_root_origin (GDK_WINDOW(gtk_widget_get_toplevel(widget)->window),  &(rect->x), &(rect->y));
391             if (window == windows->get_base_window()) {
392                 CMCFUtils *utils = CMCFUtils::get_instance();
393                 CMCFResourceCache *cache = CMCFResourceCache::get_instance();
394
395                 mcfint scnWidth, scnHeight;
396                 utils->get_screen_resolution(&scnWidth, &scnHeight);
397                 rect->y = scnHeight - cache->get_cur_layout(window)->height;
398             }
399         }
400         gtk_window_get_size (GTK_WINDOW(gtk_widget_get_toplevel(widget)), &(rect->width), &(rect->height));
401
402         ret = TRUE;
403     }
404     return ret;
405 }
406
407 /**
408  * Sets rotation
409  */
410 void
411 CMCFWindowsImplGtk::set_window_rotation(const mcfwindow window, const mcfint degree)
412 {
413     MCF_DEBUG();
414     GtkWidget* widget = gtk_widget_get_toplevel(static_cast<GtkWidget*>(window));
415 }
416
417
418 /**
419  * Shows a message box
420  */
421 void
422 CMCFWindowsImplGtk::show_message_box(const mcfwindow parentWnd, const mcf8 msgType, mcfchar* title, mcfchar* msg)
423 {
424     MCF_DEBUG();
425     mcf_assert_return(strlen(msg) > 0);
426
427     GtkWidget *dialog = NULL;
428
429     switch (msgType) {
430     case MCF_MSG_BOX_TYPE_INFO:
431         dialog = gtk_message_dialog_new((GtkWindow*)parentWnd,
432                                         GTK_DIALOG_DESTROY_WITH_PARENT,
433                                         GTK_MESSAGE_INFO,
434                                         GTK_BUTTONS_OK,
435                                         msg, "");
436         break;
437     case MCF_MSG_BOX_TYPE_ERROR:
438         dialog = gtk_message_dialog_new((GtkWindow*)parentWnd,
439                                         GTK_DIALOG_DESTROY_WITH_PARENT,
440                                         GTK_MESSAGE_ERROR,
441                                         GTK_BUTTONS_OK,
442                                         msg);
443         break;
444     case MCF_MSG_BOX_TYPE_WARNING:
445         dialog = gtk_message_dialog_new((GtkWindow*)parentWnd,
446                                         GTK_DIALOG_DESTROY_WITH_PARENT,
447                                         GTK_MESSAGE_WARNING,
448                                         GTK_BUTTONS_OK,
449                                         msg);
450         break;
451     default:
452         break;
453     }
454
455     if (dialog) {
456         gtk_window_set_title(GTK_WINDOW(dialog), title);
457         gtk_dialog_run(GTK_DIALOG(dialog));
458         gtk_widget_destroy(dialog);
459     }
460 }
461
462
463 void
464 CMCFWindowsImplGtk::set_keep_above(const mcfwindow window, const mcfboolean keepabove)
465 {
466     MCF_DEBUG();
467
468     gtk_window_set_keep_above(GTK_WINDOW(window), keepabove);
469 }