1 
2 /*
3  * Copyright (C) 2002-2012 Edscott Wilson Garcia
4  * EMail: edscott@users.sf.net
5  *
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (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;
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
24 
25 
26 #include "rodent.h"
27 #include "rfm_modules.h"
28 #include "rodent_tip.i"
29 
30 // Thread pool queued functions.
31 
32 void
rodent_queue_f(void * data,void * pool_data)33 rodent_queue_f(void *data, void *pool_data){
34     // This is a stop light for initial setup:
35     rfm_global_t *rfm_global_p = rfm_global();
36     rfm_rw_lock_reader_lock (&(rfm_global_p->setup_lock));
37     rfm_rw_lock_reader_unlock (&(rfm_global_p->setup_lock));
38     void **arg = data;
39     enum signal_enum_e signal_enum = GPOINTER_TO_INT(arg[0]);
40     view_t *view_p = arg[1];
41     void *function_data = arg[2];
42     g_free(arg);
43 
44     g_mutex_lock(rfm_global_p->status_mutex);
45     gint status = rfm_global_p->status;
46     g_mutex_unlock(rfm_global_p->status_mutex);
47     if (status == STATUS_EXIT) return;
48 
49     const gchar *dbg_text = "signal_pool_f";
50 #ifdef DEBUG_TRACE
51     switch (signal_enum) {
52 	case ADD_TO_VIEW_LIST:
53 	    dbg_text = "signal_pool_f: ADD_TO_VIEW_LIST";
54 	    break;
55 	case BOOKMARK_MONITOR:
56 	    dbg_text = "signal_pool_f: BOOKMARK_MONITOR";
57 	    break;
58     }
59 #endif
60 
61     TRACE("rodent_queue_f(%s)...\n", dbg_text);
62     // FIXME: queued functions may not unlock view list...
63 //    if (!rfm_view_list_lock(view_p, "rodent_queue_f")) return;
64     if (view_p->flags.status == STATUS_EXIT) {
65  //       rfm_view_list_unlock("rodent_queue_f");
66         return;
67     }
68 
69     rfm_thread_reference(view_p, g_thread_self(), dbg_text);
70 
71     switch (signal_enum) {
72 	case ADD_TO_VIEW_LIST:;
73 	    //rfm_add_view(view_p);
74 	    break;
75 	case BOOKMARK_MONITOR:
76 	    rodent_bookmark_monitor(view_p, function_data);
77 	    break;
78     }
79 #ifdef DEBUG_TRACE
80     if (dbg_text==NULL) rfm_thread_unreference_quiet(view_p, g_thread_self());
81     else
82 #endif
83     rfm_thread_unreference(view_p, g_thread_self());
84   //  rfm_view_list_unlock("rodent_queue_f");
85 }
86 
87 
88 gboolean
rodent_on_leave_paper(view_t * view_p)89 rodent_on_leave_paper (view_t *view_p) {
90     NOOP (stderr,"on_leave_paper\n");
91     // this does not always work since there are ways to get
92     // around this signal. like exiting the window by cruising
93     // on top of a tooltip preview beyond the parent window's
94     // border...
95     rodent_hide_tip();
96     view_p->mouse_event.current_mouseX = -1;
97     view_p->mouse_event.current_mouseY = -1;
98     rodent_unsaturate_icon (view_p);
99     rodent_unsaturate_label(view_p);
100     return TRUE;
101 }
102 
103 void *
rodent_on_leave(void * data)104 rodent_on_leave (void *data){
105     rfm_global_t *rfm_global_p = rfm_global();
106     view_t *view_p = data;
107     TRACE("rodent_on_leave()...\n");
108     if (!rfm_view_list_lock(view_p, "rodent_on_leave")) return NULL;
109     widgets_t *widgets_p=&(view_p->widgets);
110     rodent_on_leave_paper (view_p);
111     if (widgets_p->rename) {
112        // get pointer position
113        GdkRectangle pointer;
114 #if GTK_MAJOR_VERSION<3
115        gdk_window_get_pointer(
116           gtk_widget_get_window(rfm_global_p->window),
117 	  &pointer.x, &pointer.y, NULL);
118 #else
119 	gdk_window_get_device_position(
120           gtk_widget_get_window(rfm_global_p->window),
121           rfm_global_p->pointer,
122 	  &pointer.x, &pointer.y, NULL);
123 #endif
124         NOOP("rodent_mouse: pointer: x=%d, y=%d\n", pointer.x, pointer.y);
125       // get window position
126        gint windowX, windowY;
127        gdk_window_get_position (
128 	       gtk_widget_get_window(rfm_global_p->window),
129     	        &windowX, &windowY);
130         pointer.x += windowX;
131         pointer.y += windowY;
132         NOOP("rodent_mouse: window: x=%d, y=%d\n", windowX, windowY);
133         GdkRectangle entry_extent;
134         gdk_window_get_position (
135 		gtk_widget_get_window(widgets_p->rename),
136     	        &entry_extent.x, &entry_extent.y);
137 	Drawable drawable =
138 	    GDK_WINDOW_XID(gtk_widget_get_window(widgets_p->rename));
139         rfm_get_drawable_geometry(
140 		drawable,
141                 NULL, NULL, &entry_extent.width, &entry_extent.height, NULL);
142         entry_extent.width += entry_extent.x;
143         entry_extent.height += entry_extent.y;
144         NOOP("rodent_mouse: rename: x,y= (%d, %d), w,h=( %d, %d) \n",
145                 entry_extent.x, entry_extent.y,
146 		entry_extent.x+entry_extent.width,
147                 entry_extent.y+entry_extent.height);
148         gboolean x_condition=pointer.x >= entry_extent.x && pointer.x < entry_extent.width;
149         gboolean y_condition=pointer.y >= entry_extent.y && pointer.y < entry_extent.height;
150 	NOOP ("rodent_mouse: pointerY=%d < ? entry_extent.height=%d\n",
151 		pointer.y, entry_extent.height);
152 
153         if (x_condition && y_condition) {
154                 NOOP("OK\n");
155         } else if (view_p->widgets.rename) {
156 	    rfm_natural(RFM_MODULE_DIR, "callbacks", GINT_TO_POINTER(DONE_WITH_RENAME), "callback");
157         }
158     }
159     rfm_view_list_unlock("rodent_on_leave");
160     return NULL;
161 }
162 
163 
164 
165 
166 
167