summaryrefslogtreecommitdiff
path: root/src/x.c
blob: 828445f3ca4e47aba9b1216e89edd20cf32ef0ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/keysym.h>
#include <xcb/xcb_keysyms.h>

#include "x.h"
#include "types.h"

Server_context_t *init_XCB_server();
xcb_window_t create_win(Server_context_t *info);

Server_context_t *init_XCB_server()
{
	Server_context_t *info;

	if (!(info = malloc(sizeof(Server_context_t)))) {
		fprintf(stderr, "memory allocation failed.\n");
		return NULL;
	}

	info->con = xcb_connect(NULL, &info->scr_nbr);
	if (xcb_connection_has_error(info->con) > 0) {
		fprintf(stderr, "Error opening display.\n");
		free(info);
		return NULL;
	}

	info->iter = xcb_setup_roots_iterator(xcb_get_setup(info->con));
	for (; info->iter.rem; --info->scr_nbr, xcb_screen_next(&info->iter))
		if (info->scr_nbr == 0) {
			info->scr = info->iter.data;
			break;
		}

	return info;
}

xcb_window_t create_win(Server_context_t *info)
{
	xcb_gcontext_t gc;
	xcb_window_t win;
	u32 vmask, vlist[2];

	// create gc
	win = info->scr->root;
	gc = xcb_generate_id(info->con);
	vmask = XCB_GC_FOREGROUND         |
		    /*
		    XCB_GC_LINE_WIDTH         |
		    XCB_GC_LINE_STYLE         |
		    XCB_GC_FILL_STYLE         |
			XCB_GC_ARC_MODE           |
			*/
		    XCB_GC_GRAPHICS_EXPOSURES;
	vlist[0] = info->scr->black_pixel;
	vlist[1] = 0;
	xcb_create_gc (info->con, gc, win, vmask, vlist);

	// create window
	win = xcb_generate_id(info->con);
	vmask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
	vlist[0] = /* 0 */ info->scr->white_pixel;
	vlist[1] = XCB_EVENT_MASK_EXPOSURE        | // window is exposed, needs to be redrawn
		       XCB_EVENT_MASK_BUTTON_PRESS    |
		       XCB_EVENT_MASK_BUTTON_RELEASE  |
		   	   XCB_EVENT_MASK_BUTTON_1_MOTION | // mouse is dragging
		   	   XCB_EVENT_MASK_POINTER_MOTION  | // mouse is moving without clicking
			   XCB_MOTION_NOTIFY              |
			   XCB_EVENT_MASK_BUTTON_MOTION   |
			   /*
			   XCB_MOTION_NOTIFY              |
			   XCB_EVENT_MASK_EXPOSURE        |
			   XCB_EVENT_MASK_BUTTON_PRESS    |
			   XCB_EVENT_MASK_BUTTON_RELEASE; // keyboard
			   XCB_KEY_PRESS                  |
			   XCB_EVENT_MASK_KEY_PRESS       |
			   */
			   XCB_KEY_PRESS                  |
			   XCB_KEY_RELEASE;

	xcb_create_window(info->con,
					  XCB_COPY_FROM_PARENT,
					  win,
					  info->scr->root,
					  0, 0,
					  info->scr->width_in_pixels,
					  info->scr->height_in_pixels,
					  10, // boarder width
					  XCB_WINDOW_CLASS_INPUT_OUTPUT,
					  info->scr->root_visual,
					  vmask, vlist
			   		 );

	xcb_map_window(info->con, win);
	xcb_flush(info->con);

	return win;
}

xcb_cursor_t cursor_set(xcb_connection_t *c, xcb_screen_t *scr, xcb_window_t win, u32 cid)
{
	xcb_font_t font;
	xcb_cursor_t ptr;
	u32 mask;
	u32 value_list;

	font = xcb_generate_id(c);
	xcb_open_font(c, font, strlen("cursor"), "cursor");
	ptr = xcb_generate_id(c);
	xcb_create_glyph_cursor(c,
			                ptr,
			                font, font,
			                cid, cid,
			                0, 0, 0,
			                0, 0, 0);


	mask = XCB_CW_CURSOR;
	value_list = ptr;
	xcb_change_window_attributes(c, win, mask, &value_list);
	xcb_flush(c);

	return ptr;
}

void cursor_die(xcb_connection_t *c, xcb_window_t win, u32 value_list)
{
	value_list = 0;
	xcb_change_window_attributes(c, win, XCB_CW_CURSOR, &value_list);
	// xcb_free_cursor(c, value_list);
	xcb_flush(c);
}

const char *ksym_to_str(const xcb_keysym_t *ksym)
{
	switch (*ksym) {
		case XK_Escape: return "Escape";
		case XK_q:      return "q";
		case XK_Q:      return "Q";
		case XK_l:      return "l";
		case XK_w:      return "w";
		case XK_c:      return "c";
		case XK_r:      return "r";
		default:        return NULL;
	}

	return NULL;
}

void die(xcb_key_symbols_t *sym, Server_context_t *s_info, xcb_drawable_t win)
{
	xcb_key_symbols_free(sym);
	xcb_free_gc(s_info->con, win);
	xcb_disconnect(s_info->con);
	free(s_info);
	exit(0);
}