1 /*
2  *  This program is free software; you can redistribute it and/or modify
3  *  it under the terms of the GNU General Public License as published by
4  *  the Free Software Foundation; either version 2 of the License, or
5  *  (at your option) any later version.
6  *
7  *  This program is distributed in the hope that it will be useful,
8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *  GNU General Public License for more details.
11  *
12  *  You should have received a copy of the GNU General Public License
13  *  along with this program; if not, write to the Free Software
14  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
15  *
16  *  Copyright (C) 2006-2016 XNeur Team
17  *
18  */
19 
20 #include <stdlib.h>
21 #include <strings.h>
22 
23 #include "utils.h"
24 #include "defines.h"
25 #include "keymap.h"
26 
27 #include "types.h"
28 #include "log.h"
29 
30 #include "window.h"
31 
32 #define MWM_HINTS_DECORATIONS   (1L << 1)
33 #define PROP_MWM_HINTS_ELEMENTS 5
34 
35 typedef struct {
36 	int flags;
37 	int functions;
38 	int decorations;
39 	int input_mode;
40 	int status;
41 } MWMHints;
42 
error_handler(Display * d,XErrorEvent * e)43 static int error_handler(Display *d, XErrorEvent *e)
44 {
45 	if (d || e) {}
46         return FALSE;
47 }
48 
window_create(struct _window * p)49 static int window_create(struct _window *p)
50 {
51 	XSetErrorHandler(error_handler);
52 
53 	Display *display = XOpenDisplay(NULL);
54 	if (!display)
55 	{
56 		log_message(ERROR, _("Can't connect to XServer"));
57 		return FALSE;
58 	}
59 
60 	// Create Main Window
61 	Window window = XCreateSimpleWindow(display, DefaultRootWindow(display), 0, 0, 100, 100, 0, 0, 0);
62 	if (!window)
63 	{
64 		log_message(ERROR, _("Can't create program window"));
65 		XCloseDisplay(display);
66 		return FALSE;
67 	}
68 
69 	// Create flag window
70 	XSetWindowAttributes attrs;
71 	attrs.override_redirect = True;
72 
73 	Window flag_window = XCreateWindow(display, DefaultRootWindow(display), 0, 0, 1, 1,0, CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attrs);
74 	if (!flag_window)
75 	{
76 		log_message(ERROR, _("Can't create flag window"));
77 		XCloseDisplay(display);
78 		return FALSE;
79 	}
80 
81 	// Set no border mode to flag window
82 	MWMHints mwmhints;
83 	bzero(&mwmhints, sizeof(mwmhints));
84 	mwmhints.flags		= MWM_HINTS_DECORATIONS;
85 	mwmhints.decorations	= 0;
86 
87 	Atom motif_prop = XInternAtom(display, "_MOTIF_WM_HINTS", False);
88 
89 	XChangeProperty(display, flag_window, motif_prop, motif_prop, 32, PropModeReplace, (unsigned char *) &mwmhints, PROP_MWM_HINTS_ELEMENTS);
90 
91 	XWMHints wmhints;
92 	bzero(&wmhints, sizeof(wmhints));
93 	wmhints.flags = InputHint;
94 	wmhints.input = 0;
95 
96 	Atom win_prop = XInternAtom(display, "_WIN_HINTS", False);
97 
98 	XChangeProperty(display, flag_window, win_prop, win_prop, 32, PropModeReplace, (unsigned char *) &mwmhints, sizeof (XWMHints) / 4);
99 
100 	p->display 	= display;
101 	p->window  	= window;
102 
103 	p->internal_atom = XInternAtom(p->display, "XNEUR_INTERNAL_MSG", 0);
104 
105 	// Check "_NET_SUPPORTED" atom support
106 	Atom type = 0;
107 	long nitems = 0L;
108 	int size = 0;
109 	Atom *results = NULL;
110 	long i = 0;
111 
112 	Window root;
113 	Atom request;
114 	Atom feature_atom;
115 
116 	request = XInternAtom(p->display, "_NET_SUPPORTED", False);
117 	feature_atom = XInternAtom(p->display, "_NET_ACTIVE_WINDOW", False);
118 	root = XDefaultRootWindow(p->display);
119 
120 	p->_NET_SUPPORTED = FALSE;
121 	results = (Atom *) get_win_prop(root, request, &nitems, &type, &size);
122 	for (i = 0L; i < nitems; i++)
123 	{
124 		if (results[i] == feature_atom)
125 			p->_NET_SUPPORTED = TRUE;
126 	}
127 	//if (results != NULL)
128 		//free(results);
129 
130 	log_message(LOG, _("Main window with id %d created"), window);
131 
132 	XSynchronize(display, TRUE);
133 	XFlush(display);
134 
135 	return TRUE;
136 }
137 
window_destroy(struct _window * p)138 static void window_destroy(struct _window *p)
139 {
140 	if (p->window == None)
141 		return;
142 
143 	p->window	= None;
144 }
145 
window_init_keymap(struct _window * p)146 static int window_init_keymap(struct _window *p)
147 {
148 	p->keymap = keymap_init(p->handle, p->display);
149 	if (p->keymap == NULL)
150 		return FALSE;
151 	return TRUE;
152 }
153 
window_uninit_keymap(struct _window * p)154 static void window_uninit_keymap(struct _window *p)
155 {
156 	if (p->keymap != NULL)
157 		p->keymap->uninit(p->keymap),
158 		p->keymap = NULL;
159 }
160 
window_uninit(struct _window * p)161 static void window_uninit(struct _window *p)
162 {
163 	if (p->keymap != NULL)
164 		p->keymap->uninit(p->keymap);
165 
166 	p->destroy(p);
167 	free(p);
168 
169 	log_message(DEBUG, _("Window is freed"));
170 }
171 
window_init(struct _xneur_handle * handle)172 struct _window* window_init(struct _xneur_handle *handle)
173 {
174 	struct _window *p = (struct _window *) malloc(sizeof(struct _window));
175 	bzero(p, sizeof(struct _window));
176 
177 	p->handle = handle;
178 
179 	// Function mapping
180 	p->create		= window_create;
181 	p->destroy		= window_destroy;
182 	p->init_keymap		= window_init_keymap;
183 	p->uninit_keymap	= window_uninit_keymap;
184 	p->uninit		= window_uninit;
185 
186 	return p;
187 }
188