till's patch! pants!

SVN revision: 7476
This commit is contained in:
Carsten Haitzler 2003-09-23 22:33:10 +00:00
parent a5c2425084
commit b6bcdee7db
6 changed files with 257 additions and 27 deletions

View File

@ -435,7 +435,7 @@ setup_ecore_x_test(void)
win = ecore_x_window_new(0, 0, 0, 120, 60);
ecore_x_window_prop_title_set(win, "Ecore Test Program");
ecore_x_window_prop_name_class_set(win, "ecore_test", "main");
ecore_x_window_prop_delete_request_set(win, 1);
ecore_x_window_prop_protocol_set(win, ECORE_X_WM_PROTOCOL_DELETE_REQUEST, 1);
ecore_x_window_show(win);
ecore_x_flush();

View File

@ -574,8 +574,8 @@ _ecore_evas_x_free(Ecore_Evas *ee)
static void
_ecore_evas_callback_delete_request_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
{
if (func) ecore_x_window_prop_delete_request_set(ee->engine.x.win_container, 1);
else ecore_x_window_prop_delete_request_set(ee->engine.x.win_container, 0);
if (func) ecore_x_window_prop_protocol_set(ee->engine.x.win_container, ECORE_X_WM_PROTOCOL_DELETE_REQUEST,1);
else ecore_x_window_prop_protocol_set(ee->engine.x.win_container, ECORE_X_WM_PROTOCOL_DELETE_REQUEST, 0);
ee->func.fn_delete_request = func;
}
@ -887,7 +887,7 @@ _ecore_evas_override_set(Ecore_Evas *ee, int on)
ecore_x_window_prop_title_set(ee->engine.x.win_container, ee->prop.title);
ecore_x_window_prop_name_class_set(ee->engine.x.win_container, ee->prop.name, ee->prop.clas);
if (ee->func.fn_delete_request)
ecore_x_window_prop_delete_request_set(ee->engine.x.win_container, 1);
ecore_x_window_prop_protocol_set(ee->engine.x.win_container, ECORE_X_WM_PROTOCOL_DELETE_REQUEST, 1);
ecore_x_window_prop_min_size_set(ee->engine.x.win_container, ee->prop.min.w, ee->prop.min.h);
ecore_x_window_prop_max_size_set(ee->engine.x.win_container, ee->prop.max.w, ee->prop.max.h);
ecore_x_window_prop_base_size_set(ee->engine.x.win_container, ee->prop.base.w, ee->prop.base.h);

View File

@ -424,6 +424,40 @@ extern int ECORE_X_LOCK_SCROLL;
extern int ECORE_X_LOCK_NUM;
extern int ECORE_X_LOCK_CAPS;
#ifndef _ECORE_X_PRIVATE_H
typedef enum _Ecore_X_WM_Protocol {
/**
* If enabled the window manager will be asked to send a
* delete message instead of just closing (destroying) the window.
*/
ECORE_X_WM_PROTOCOL_DELETE_REQUEST,
/**
* If enabled the window manager will be told that the window
* explicitly sets input focus.
*/
ECORE_X_WM_PROTOCOL_TAKE_FOCUS
} Ecore_X_WM_Protocol;
#endif
typedef enum _Ecore_X_Window_Input_Mode {
/** The window can never be focused */
ECORE_X_WINDOW_INPUT_MODE_NONE,
/** The window can be focused by the WM but doesn't focus itself */
ECORE_X_WINDOW_INPUT_MODE_PASSIVE,
/** The window sets the focus itself if one of its sub-windows
* already is focused
*/
ECORE_X_WINDOW_INPUT_MODE_ACTIVE_LOCAL,
/** The window sets the focus itself even if another window
* is currently focused
*/
ECORE_X_WINDOW_INPUT_MODE_ACTIVE_GLOBAL
} Ecore_X_Window_Input_Mode;
int ecore_x_init(const char *name);
int ecore_x_shutdown(void);
Ecore_X_Display *ecore_x_display_get(void);
@ -458,14 +492,16 @@ void ecore_x_window_prop_title_set(Ecore_X_Window win, const char *t
char *ecore_x_window_prop_title_get(Ecore_X_Window win);
void ecore_x_window_prop_name_class_set(Ecore_X_Window win, const char *n, const char *c);
void ecore_x_window_prop_name_class_get(Ecore_X_Window win, char **n, char **c);
void ecore_x_window_prop_delete_request_set(Ecore_X_Window win, int on);
void ecore_x_window_prop_protocol_set(Ecore_X_Window win, Ecore_X_WM_Protocol protocol, int on);
void ecore_x_window_prop_sticky_set(Ecore_X_Window win, int on);
int ecore_x_window_prop_input_mode_set(Ecore_X_Window win, Ecore_X_Window_Input_Mode mode);
void ecore_x_window_prop_min_size_set(Ecore_X_Window win, int w, int h);
void ecore_x_window_prop_max_size_set(Ecore_X_Window win, int w, int h);
void ecore_x_window_prop_base_size_set(Ecore_X_Window win, int w, int h);
void ecore_x_window_prop_step_size_set(Ecore_X_Window win, int x, int y);
void ecore_x_window_prop_xy_set(Ecore_X_Window win, int x, int y);
void ecore_x_window_prop_borderless_set(Ecore_X_Window win, int borderless);
void ecore_x_window_prop_layer_set(Ecore_X_Window win, int layer);
int ecore_x_window_prop_layer_set(Ecore_X_Window win, int layer);
void ecore_x_window_prop_withdrawn_set(Ecore_X_Window win, int withdrawn);
void ecore_x_window_shape_mask_set(Ecore_X_Window win, Ecore_X_Pixmap mask);

View File

@ -25,11 +25,19 @@ int _ecore_x_event_last_root_x = 0;
int _ecore_x_event_last_root_y = 0;
Atom _ecore_x_atom_wm_delete_window = 0;
Atom _ecore_x_atom_wm_take_focus = 0;
Atom _ecore_x_atom_wm_protocols = 0;
Atom _ecore_x_atom_wm_class = 0;
Atom _ecore_x_atom_wm_name = 0;
Atom _ecore_x_atom_motif_wm_hints = 0;
Atom _ecore_x_atom_win_layer = 0;
Atom _ecore_x_atom_net_wm_desktop = 0;
Atom _ecore_x_atom_net_current_desktop = 0;
Atom _ecore_x_atom_net_wm_state = 0;
Atom _ecore_x_atom_net_wm_state_above = 0;
Atom _ecore_x_atom_net_wm_state_below = 0;
Atom _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_NUM] = {0};
int ECORE_X_EVENT_KEY_DOWN = 0;
int ECORE_X_EVENT_KEY_UP = 0;
@ -214,12 +222,22 @@ ecore_x_init(const char *name)
return 0;
}
_ecore_x_filter_handler = ecore_event_filter_add(_ecore_x_event_filter_start, _ecore_x_event_filter_filter, _ecore_x_event_filter_end, NULL);
_ecore_x_atom_wm_delete_window = XInternAtom(_ecore_x_disp, "WM_DELETE_WINDOW", False);
_ecore_x_atom_wm_protocols = XInternAtom(_ecore_x_disp, "WM_PROTOCOLS", False);
_ecore_x_atom_wm_class = XInternAtom(_ecore_x_disp, "WM_CLASS", False);
_ecore_x_atom_wm_name = XInternAtom(_ecore_x_disp, "WM_NAME", False);
_ecore_x_atom_motif_wm_hints = XInternAtom(_ecore_x_disp, "_MOTIF_WM_HINTS", False);
_ecore_x_atom_win_layer = XInternAtom(_ecore_x_disp, "_WIN_LAYER", False);
_ecore_x_atom_wm_delete_window = XInternAtom(_ecore_x_disp, "WM_DELETE_WINDOW", False);
_ecore_x_atom_wm_take_focus = XInternAtom(_ecore_x_disp, "WM_TAKE_FOCUS", False);
_ecore_x_atom_wm_protocols = XInternAtom(_ecore_x_disp, "WM_PROTOCOLS", False);
_ecore_x_atom_wm_class = XInternAtom(_ecore_x_disp, "WM_CLASS", False);
_ecore_x_atom_wm_name = XInternAtom(_ecore_x_disp, "WM_NAME", False);
_ecore_x_atom_motif_wm_hints = XInternAtom(_ecore_x_disp, "_MOTIF_WM_HINTS", False);
_ecore_x_atom_win_layer = XInternAtom(_ecore_x_disp, "_WIN_LAYER", False);
_ecore_x_atom_net_wm_desktop = XInternAtom(_ecore_x_disp, "_NET_WM_DESKTOP", False);
_ecore_x_atom_net_current_desktop = XInternAtom(_ecore_x_disp, "_NET_CURRENT_DESKTOP", False);
_ecore_x_atom_net_wm_state = XInternAtom(_ecore_x_disp, "_NET_WM_STATE", False);
_ecore_x_atom_net_wm_state_above = XInternAtom(_ecore_x_disp, "_NET_WM_STATE_ABOVE", False);
_ecore_x_atom_net_wm_state_below = XInternAtom(_ecore_x_disp, "_NET_WM_STATE_BELOW", False);
_ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_DELETE_REQUEST] = _ecore_x_atom_wm_delete_window;
_ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_TAKE_FOCUS] = _ecore_x_atom_wm_take_focus;
_ecore_x_init_count++;
return _ecore_x_init_count;
}

View File

@ -29,6 +29,21 @@ struct _Ecore_X_Reply
void *data;
};
typedef enum _Ecore_X_WM_Protocol {
/**
* If enabled the window manager will be asked to send a
* delete message instead of just closing (destroying) the window.
*/
ECORE_X_WM_PROTOCOL_DELETE_REQUEST,
/**
* If enabled the window manager will be told that the window
* explicitly sets input focus.
*/
ECORE_X_WM_PROTOCOL_TAKE_FOCUS,
ECORE_X_WM_PROTOCOL_NUM
} Ecore_X_WM_Protocol;
extern Display *_ecore_x_disp;
extern double _ecore_x_double_click_time;
extern Time _ecore_x_event_last_time;
@ -37,11 +52,19 @@ extern int _ecore_x_event_last_root_x;
extern int _ecore_x_event_last_root_y;
extern Atom _ecore_x_atom_wm_delete_window;
extern Atom _ecore_x_atom_wm_take_focus;
extern Atom _ecore_x_atom_wm_protocols;
extern Atom _ecore_x_atom_wm_class;
extern Atom _ecore_x_atom_wm_name;
extern Atom _ecore_x_atom_motif_wm_hints;
extern Atom _ecore_x_atom_win_layer;
extern Atom _ecore_x_atom_net_wm_desktop;
extern Atom _ecore_x_atom_net_current_desktop;
extern Atom _ecore_x_atom_net_wm_state;
extern Atom _ecore_x_atom_net_wm_state_above;
extern Atom _ecore_x_atom_net_wm_state_below;
extern Atom _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_NUM];
void _ecore_x_error_handler_init(void);
void _ecore_x_event_handle_key_press(XEvent *xevent);

View File

@ -1,6 +1,8 @@
#include "Ecore.h"
#include "ecore_x_private.h"
#include "Ecore_X.h"
#include <inttypes.h>
#include <limits.h>
/**
* To be documented.
@ -31,6 +33,57 @@ ecore_x_window_prop_property_set(Ecore_X_Window win, Ecore_X_Atom type, Ecore_X_
}
}
/**
* To be documented.
*
* FIXME: To be fixed.
* <hr><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
*/
int
ecore_x_window_prop_property_get(Ecore_X_Window win, Ecore_X_Atom type, Ecore_X_Atom format, int size, unsigned char **data, int *num)
{
Atom type_ret = 0;
int ret, size_ret = 0;
unsigned long num_ret = 0, bytes = 0, i;
unsigned char *prop_ret = NULL;
if (!win)
win = DefaultRootWindow(_ecore_x_disp);
ret = XGetWindowProperty(_ecore_x_disp, win, type, 0, LONG_MAX, False, format, &type_ret, &size_ret, &num_ret, &bytes, &prop_ret);
if (ret != Success) {
*data = NULL;
return 0;
}
if (size != size_ret || !num_ret) {
XFree(prop_ret);
*data = NULL;
return 0;
}
if (!(*data = malloc(num_ret * size / 8))) {
XFree(prop_ret);
return 0;
}
for (i = 0; i < num_ret; i++)
switch (size) {
case 8:
*data[i] = prop_ret[i];
break;
case 16:
((uint16_t *) *data)[i] = ((uint16_t *) prop_ret)[i];
break;
case 32:
((uint32_t *) *data)[i] = ((uint32_t *) prop_ret)[i];
break;
}
*num = num_ret;
return 1;
}
/**
* Set a window title.
* @param win The window
@ -139,21 +192,24 @@ ecore_x_window_prop_name_class_get(Ecore_X_Window win, char **n, char **c)
}
/**
* Set a window property to get message for close.
* @param win The window
* Set or unset a wm protocol property.
* @param win The Window
* @param protocol The protocol to enable/disable
* @param on On/Off
*
* Set a window porperty to let a window manager send a delete message instead
* of just closing (destroying) the window.
* <hr><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
*/
void
ecore_x_window_prop_delete_request_set(Ecore_X_Window win, int on)
ecore_x_window_prop_protocol_set(Ecore_X_Window win,
Ecore_X_WM_Protocol protocol, int on)
{
Atom *protos = NULL;
Atom proto;
int protos_count = 0;
int already_set = 0;
int i;
proto = _ecore_x_atoms_wm_protocols[protocol];
if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count))
{
@ -162,7 +218,7 @@ ecore_x_window_prop_delete_request_set(Ecore_X_Window win, int on)
}
for (i = 0; i < protos_count; i++)
{
if (protos[i] == _ecore_x_atom_wm_delete_window)
if (protos[i] == proto)
{
already_set = 1;
break;
@ -177,7 +233,7 @@ ecore_x_window_prop_delete_request_set(Ecore_X_Window win, int on)
if (!new_protos) goto leave;
for (i = 0; i < protos_count; i++)
new_protos[i] = protos[i];
new_protos[protos_count] = _ecore_x_atom_wm_delete_window;
new_protos[protos_count] = proto;
XSetWMProtocols(_ecore_x_disp, win, new_protos, protos_count + 1);
free(new_protos);
}
@ -186,7 +242,7 @@ ecore_x_window_prop_delete_request_set(Ecore_X_Window win, int on)
if (!already_set) goto leave;
for (i = 0; i < protos_count; i++)
{
if (protos[i] == _ecore_x_atom_wm_delete_window)
if (protos[i] == proto)
{
int j;
@ -306,6 +362,63 @@ ecore_x_window_prop_xy_set(Ecore_X_Window win, int x, int y)
XSetWMNormalHints(_ecore_x_disp, win, &hints);
}
/**
* Sets the sticky state for @win
* @param win The window
* @param on Boolean representing the sticky state
*/
void
ecore_x_window_prop_sticky_set(Ecore_X_Window win, int on)
{
unsigned long val = 0xffffffff;
int ret, num = 0;
unsigned char *data = NULL;
if (on) {
ecore_x_window_prop_property_set(win, _ecore_x_atom_net_wm_desktop,
XA_CARDINAL, 32, &val, 1);
return;
}
ret = ecore_x_window_prop_property_get(0, _ecore_x_atom_net_current_desktop,
XA_CARDINAL, 32, &data, &num);
if (!ret || !num)
return;
ecore_x_window_prop_property_set(win, _ecore_x_atom_net_wm_desktop,
XA_CARDINAL, 32, data, 1);
free(data);
}
/**
* Sets the input mode for @win
* @param win The Window
* @param mode The input mode. See the description of
* @Ecore_X_Window_Input_Mode for details
* @return 1 if the input mode could be set, else 0
*/
int
ecore_x_window_prop_input_mode_set(Ecore_X_Window win, Ecore_X_Window_Input_Mode mode)
{
XWMHints *hints;
if (!(hints = XGetWMHints(_ecore_x_disp, win)))
if (!(hints = XAllocWMHints()))
return 0;
hints->flags |= InputHint;
hints->input = (mode == ECORE_X_WINDOW_INPUT_MODE_PASSIVE
|| mode == ECORE_X_WINDOW_INPUT_MODE_ACTIVE_LOCAL);
XSetWMHints(_ecore_x_disp, win, hints);
XFree(hints);
ecore_x_window_prop_protocol_set(win, ECORE_X_WM_PROTOCOL_TAKE_FOCUS,
(mode == ECORE_X_WINDOW_INPUT_MODE_ACTIVE_LOCAL
|| mode == ECORE_X_WINDOW_INPUT_MODE_ACTIVE_GLOBAL));
return 1;
}
/**
* To be documented.
*
@ -330,16 +443,56 @@ ecore_x_window_prop_borderless_set(Ecore_X_Window win, int borderless)
}
/**
* To be documented.
*
* FIXME: To be fixed.
* Puts @win in the desired layer. This currently works with
* windowmanagers that are Gnome-compliant or support NetWM.
*
* @param win
* @param layer If < 0, @win will be put below all other windows.
* If > 0, @win will be "always-on-top"
* If = 0, @win will be put in the default layer.
* @return 1 if the state could be set else 0
*
* <hr><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
*/
void
int
ecore_x_window_prop_layer_set(Ecore_X_Window win, int layer)
{
Ecore_X_Atom atom = 0;
unsigned char *data = NULL;
int i, val = 4, num = 0; /* normal layer */
if (layer < 0) { /* below */
atom = _ecore_x_atom_net_wm_state_below;
val = 2;
} else if (layer > 0) { /* above */
atom = _ecore_x_atom_net_wm_state_above;
val = 6;
}
/* set the NetWM atoms
* get the atoms that are already set
*/
if (ecore_x_window_prop_property_get(win, _ecore_x_atom_net_wm_state,
XA_ATOM, 32, &data, &num)) {
/* and set the ones we're interested in */
for (i = 0; i < num; i++)
if (data[i] == _ecore_x_atom_net_wm_state_below)
data[i] = (layer < 0);
else if (data[i] == _ecore_x_atom_net_wm_state_above)
data[i] = (layer > 0);
ecore_x_window_prop_property_set(win, _ecore_x_atom_net_wm_state,
XA_ATOM, 32, data, num);
free(data);
} else
ecore_x_window_prop_property_set(win, _ecore_x_atom_net_wm_state,
XA_ATOM, 32, &atom, 1);
/* set the gnome atom */
ecore_x_window_prop_property_set(win, _ecore_x_atom_win_layer,
XA_CARDINAL, 32, &layer, 1);
XA_CARDINAL, 32, &val, 1);
return 1;
}
/**
@ -356,7 +509,7 @@ ecore_x_window_prop_withdrawn_set(Ecore_X_Window win, int withdrawn)
long ret;
memset(&hints, 0, sizeof(XWMHints));
XGetWMNormalHints(_ecore_x_disp, win, &hints, &ret);
XGetWMNormalHints(_ecore_x_disp, win, (XSizeHints *) &hints, &ret);
if (!withdrawn)
hints.initial_state &= ~WithdrawnState;
@ -365,6 +518,6 @@ ecore_x_window_prop_withdrawn_set(Ecore_X_Window win, int withdrawn)
hints.flags = WindowGroupHint | StateHint;
XSetWMHints(_ecore_x_disp, win, &hints);
XSetWMNormalHints(_ecore_x_disp, win, &hints);
XSetWMNormalHints(_ecore_x_disp, win, (XSizeHints *) &hints);
}