* DEALINGS IN THE SOFTWARE.
*/
+#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
+#include <stdlib.h>
+#include <sys/inotify.h>
-#include <pepper.h>
#include <wayland-server.h>
#include <wayland-util.h>
-#include <pepper-inotify.h>
-#include <pepper-keyrouter.h>
-#include <pepper-xkb.h>
#include <headless_server.h>
#define MAX_CMDS 256
#define KEYMAP "keymap"
#define HELP_MSG "help"
-typedef struct
+struct headless_debug
{
- pepper_compositor_t *compositor;
- pepper_inotify_t *inotify;
+ headless_server_t *server;
- pepper_view_t *top_mapped;
- pepper_view_t *focus;
-} headless_debug_t;
+ struct {
+ struct wl_event_source *event_source;
+ int fd;
+ int wd;
+ } inotify;
+};
typedef void (*headless_debug_action_cb_t)(headless_debug_t *hd, void *data);
headless_debug_action_cb_t disable_cb;
} headless_debug_action_t;
-const static int KEY_DEBUG = 0xdeaddeb0;
extern void wl_debug_server_enable(int enable);
+static bool _headless_debug_inotify_init(headless_debug_t *hdebug);
+static void _headless_debug_inotify_deinit(headless_debug_t *hdebug);
+
static void
_headless_debug_usage()
{
{
int *n_resources = (int *)data;
- PEPPER_TRACE("\t\t [resource][%d] class=%s, id=%u\n", ++(*n_resources), wl_resource_get_class(resource), wl_resource_get_id(resource));
+ ds_inf("\t\t [resource][%d] class=%s, id=%u\n", ++(*n_resources), wl_resource_get_class(resource), wl_resource_get_id(resource));
return WL_ITERATOR_CONTINUE;
}
struct wl_list *clist = NULL;
struct wl_client *client_itr = NULL;
- pepper_bool_t need_reslist = PEPPER_FALSE;
+ bool need_reslist = false;
const char *cmds = (const char *)data;
/* check if reslist feature is required */
if (cmds && !strncmp(cmds, CLIENT_RESOURCES, MAX_CMDS)) {
- need_reslist = PEPPER_TRUE;
+ need_reslist = true;
}
/* get client list which bound wl_compositor global */
- clist = wl_display_get_client_list(pepper_compositor_get_display(hdebug->compositor));
- PEPPER_CHECK(clist, return, "Failed to get client list from compositor->display.\n");
+ clist = wl_display_get_client_list(hdebug->server->display);
+ HEADLESS_CHECK(clist, return, "Failed to get client list from compositor->display.\n");
- PEPPER_TRACE("========= [Connected clients information] =========\n");
+ ds_inf("========= [Connected clients information] =========\n");
wl_client_for_each(client_itr, clist) {
n_clients++;
client_fd = wl_client_get_fd(client_itr);
wl_client_get_credentials(client_itr, &pid, &uid, &gid);
- PEPPER_TRACE("\t client[%d]: pid=%d, user=%d, group=%d, socket_fd=%d", n_clients, pid, uid, gid, client_fd);
+ ds_inf("\t client[%d]: pid=%d, user=%d, group=%d, socket_fd=%d", n_clients, pid, uid, gid, client_fd);
- if (PEPPER_FALSE == need_reslist) {
- PEPPER_TRACE("\n");
+ if (false == need_reslist) {
+ ds_inf("\n");
continue;
}
- PEPPER_TRACE("\n");
+ ds_inf("\n");
wl_client_for_each_resource(client_itr, _client_get_resource_itr, &n_resources);
- PEPPER_TRACE("\t\t number of resources = %d\n", n_resources);
+ ds_inf("\t\t number of resources = %d\n", n_resources);
n_resources = 0;
}
if (!n_clients)
- PEPPER_TRACE("============ [No connected clients] ===========\n\n");
+ ds_inf("============ [No connected clients] ===========\n\n");
}
static void
int fd = -1;
int ret = 0;
- fd = open("/run/pepper/stdout.txt", O_CREAT | O_WRONLY | O_APPEND, S_IWUSR | S_IWGRP);
+ fd = open("/run/headless_server/stdout.txt", O_CREAT | O_WRONLY | O_APPEND, S_IWUSR | S_IWGRP);
if (fd < 0) {
- PEPPER_TRACE("Failed to open stdout.txt (errno=%m)\n");
+ HEADLESS_TRACE("Failed to open stdout.txt (errno=%m)\n");
return;
}
ret = dup2(fd, 1);
close(fd);
- PEPPER_CHECK(ret >= 0, return, "Failed to redirect STDOUT.\n");
+ HEADLESS_CHECK(ret >= 0, return, "Failed to redirect STDOUT.\n");
- PEPPER_TRACE("STDOUT has been redirected to stdout.txt.\n");
+ HEADLESS_TRACE("STDOUT has been redirected to stdout.txt.\n");
}
static void
int fd = -1;
int ret = 0;
- fd = open("/run/pepper/stderr.txt", O_CREAT | O_WRONLY | O_APPEND, S_IWUSR | S_IWGRP);
+ fd = open("/run/headless_server/stderr.txt", O_CREAT | O_WRONLY | O_APPEND, S_IWUSR | S_IWGRP);
if (fd < 0) {
- PEPPER_TRACE("Failed to open stderr.txt (errno=%m)\n");
+ HEADLESS_TRACE("Failed to open stderr.txt (errno=%m)\n");
return;
}
ret = dup2(fd, 2);
close(fd);
- PEPPER_CHECK(ret >= 0, return, "Failed to redirect STDERR.\n");
+ HEADLESS_CHECK(ret >= 0, return, "Failed to redirect STDERR.\n");
- PEPPER_TRACE("STDERR has been redirected to stderr.txt.\n");
+ HEADLESS_TRACE("STDERR has been redirected to stderr.txt.\n");
}
(void) data;
int cnt = 0;
- int w, h;
- double x, y;
pid_t pid;
- pepper_list_t *l;
- const pepper_list_t *list;
- pepper_view_t *view;
- pepper_surface_t *surface;
- pepper_view_t *top_visible = NULL;
+ struct wl_resource *resource;
+ headless_view_t *view;
- PEPPER_CHECK(hdebug, return, "[%s] Invalid headless debug !\n", __FUNCTION__);
+ ds_dbg("No. View RscID PID w h x y Mapped Visible Focus\n");
+ ds_dbg("==========================================================================================\n");
- PEPPER_TRACE("No. WinID RscID PID w h x y Mapped Visible Top Top_Visible Focus\n");
- PEPPER_TRACE("==========================================================================================\n");
-
- list = pepper_compositor_get_view_list(hdebug->compositor);
-
- pepper_list_for_each_list(l, list) {
- view = (pepper_view_t *)l->item;
- PEPPER_CHECK(view, continue, "[%s] Invalid object view:%p\n", __FUNCTION__, view);
+ wl_list_for_each(view, &hdebug->server->views, link) {
+ cnt++;
- surface = pepper_view_get_surface(view);
- PEPPER_CHECK(surface, continue, "[%s] Invalid object surface:%p\n", __FUNCTION__, surface);
+ resource = headless_shell_surface_get_resource(view->shell_surface);
+ wl_client_get_credentials(wl_resource_get_client(resource), &pid,
+ NULL, NULL);
- cnt++;
- pepper_view_get_position(view, &x, &y);
- pepper_view_get_size(view, &w, &h);
- wl_client_get_credentials(wl_resource_get_client(pepper_surface_get_resource(surface)), &pid, NULL, NULL);
- if (!top_visible && pepper_surface_get_buffer(surface))
- top_visible = view;
-
- pepper_log("DEBUG", PEPPER_LOG_LEVEL_DEBUG, "%3d 0x%08x 0x%08x %5d %4d %4d %4.0f %4.0f %s %s %s %s %s\n",
- cnt, surface, pepper_surface_get_resource(surface), pid, w, h, x, y,
- pepper_view_is_mapped(view) ? "O" : "X",
- pepper_view_is_visible(view) ? "O" : "X",
- (hdebug->top_mapped == view) ? "O" : "X",
- (top_visible == view) ? "O" : "X",
- (hdebug->focus == view) ? "O" : "X");
+ ds_dbg("%3d 0x%08x %4d %10d %6d %4d %4.0f %4.0f %s %s %s\n",
+ cnt, view, wl_resource_get_id(resource), pid,
+ view->width, view->height, view->x, view->y,
+ view->mapped ? "O" : "X",
+ (view->mapped && hdebug->server->top_view == view) ? "O" : "X",
+ (hdebug->server->focus_view == view) ? "O" : "X");
}
- PEPPER_TRACE("==========================================================================================\n");
+ ds_dbg("==========================================================================================\n");
}
static void
_headless_debug_keygrab_status(headless_debug_t *hdebug, void *data)
{
+ /* TODO */
+#if 0
pepper_keyrouter_t *keyrouter;
keyrouter = headless_input_get_keyrouter(hdebug->compositor);
pepper_keyrouter_debug_keygrab_status_print(keyrouter);
+#endif
}
static void
_headless_debug_keymap(headless_debug_t *hdebug, void *data)
{
+ /* TODO */
+#if 0
pepper_xkb_t *xkb;
int i;
char keyname[256] = {0, };
xkb = headless_input_get_xkb(hdebug->compositor);
- PEPPER_CHECK(xkb, return, "xkb is not set\n");
+ HEADLESS_CHECK(xkb, return, "xkb is not set\n");
context = pepper_xkb_get_context(xkb);
- PEPPER_CHECK(context, return, "Current pepper_xkb has no context.\n");
+ HEADLESS_CHECK(context, return, "Current pepper_xkb has no context.\n");
keymap = pepper_xkb_get_keymap(xkb);
- PEPPER_CHECK(keymap, return, "Current pepper_xkb has no keymap.\n");
+ HEADLESS_CHECK(keymap, return, "Current pepper_xkb has no keymap.\n");
state = pepper_xkb_get_state(xkb);
- PEPPER_CHECK(state, return, "Current pepper_xkb has no state.\n");
+ HEADLESS_CHECK(state, return, "Current pepper_xkb has no state.\n");
min_keycode = xkb_keymap_min_keycode(keymap);
max_keycode = xkb_keymap_max_keycode(keymap);
printf("\t%4d%-5s%-25s%-20x%-5d\n", i, "", keyname, sym, xkb_keymap_key_repeats(keymap, i));
}
+#endif
}
static const headless_debug_action_t debug_actions[] =
for(int n=0 ; n < n_actions ; n++) {
if (!strncmp(cmds, debug_actions[n].cmds, MAX_CMDS)) {
- PEPPER_TRACE("[%s : %s]\n", __FUNCTION__, debug_actions[n].cmds);
+ HEADLESS_TRACE("[%s : %s]\n", __FUNCTION__, debug_actions[n].cmds);
debug_actions[n].cb(hdebug, (void *)debug_actions[n].cmds);
break;
for(int n=0 ; n < n_actions ; n++) {
if (!strncmp(cmds, debug_actions[n].cmds, MAX_CMDS)) {
if (debug_actions[n].disable_cb) {
- PEPPER_TRACE("[%s : %s]\n", __FUNCTION__, debug_actions[n].cmds);
+ HEADLESS_TRACE("[%s : %s]\n", __FUNCTION__, debug_actions[n].cmds);
debug_actions[n].disable_cb(hdebug, (void *)debug_actions[n].cmds);
}
}
}
-static void
-_trace_cb_handle_inotify_event(uint32_t type, pepper_inotify_event_t *ev, void *data)
+void
+headless_debug_destroy(headless_debug_t *hdebug)
{
- headless_debug_t *hdebug = data;
- char *file_name = pepper_inotify_event_name_get(ev);
-
- PEPPER_CHECK(hdebug, return, "Invalid headless debug instance\n");
-
- switch (type)
- {
- case PEPPER_INOTIFY_EVENT_TYPE_CREATE:
- _headless_debug_enable_action(hdebug, file_name);
- break;
- case PEPPER_INOTIFY_EVENT_TYPE_REMOVE:
- _headless_debug_disable_action(hdebug, file_name);
- break;
- case PEPPER_INOTIFY_EVENT_TYPE_MODIFY:
- break;
- default:
- PEPPER_TRACE("[%s] Unhandled event type (%d)\n", __FUNCTION__, type);
- break;
- }
+ _headless_debug_inotify_deinit(hdebug);
+ free(hdebug);
}
-PEPPER_API void
-headless_debug_set_focus_view(pepper_compositor_t *compositor, pepper_view_t *focus_view)
+headless_debug_t *
+headless_debug_create(headless_server_t *server)
{
+ int n_actions;
headless_debug_t *hdebug = NULL;
+ bool res = false;
- hdebug = (headless_debug_t *)pepper_object_get_user_data((pepper_object_t *) compositor, &KEY_DEBUG);
- PEPPER_CHECK(hdebug, return, "Invalid headless debug.\n");
+ hdebug = (headless_debug_t*)calloc(1, sizeof(headless_debug_t));
+ HEADLESS_CHECK(hdebug, return NULL, "Failed to alloc for headless debug\n");
+ hdebug->server = server;
- if (hdebug->focus != focus_view) {
- PEPPER_TRACE("[DEBUG] Focus view has been changed to 0x%x (from 0x%x)\n", focus_view, hdebug->focus);
- hdebug->focus = focus_view;
- }
+ res = _headless_debug_inotify_init(hdebug);
+ HEADLESS_CHECK(res, goto err_inotify, "Failed to initialize inotify");
+
+ n_actions = sizeof(debug_actions)/sizeof(debug_actions[0]);
+
+ HEADLESS_TRACE("[%s] Done (%d actions have been defined.)\n", __FUNCTION__, n_actions);
+
+ return hdebug;
+
+err_inotify:
+ free(hdebug);
+
+ return NULL;
}
-PEPPER_API void
-headless_debug_set_top_view(pepper_compositor_t *compositor, pepper_view_t *top_view)
+static void
+_headless_debug_inotify_event_process(headless_debug_t *hdebug,
+ struct inotify_event *ev)
{
- headless_debug_t *hdebug = NULL;
-
- hdebug = (headless_debug_t *)pepper_object_get_user_data((pepper_object_t *) compositor, &KEY_DEBUG);
- PEPPER_CHECK(hdebug, return, "Invalid headless debug.\n");
+ if (!ev->len)
+ return;
- if (hdebug->top_mapped != top_view) {
- PEPPER_TRACE("[DEBUG] Top view has been changed to 0x%x (from 0x%x)\n", top_view, hdebug->top_mapped);
- hdebug->top_mapped = top_view;
+ if (ev->mask & IN_CREATE) {
+ _headless_debug_enable_action(hdebug, ev->name);
+ }
+ else if (ev->mask & IN_DELETE) {
+ _headless_debug_disable_action(hdebug, ev->name);
}
}
-PEPPER_API void
-headless_debug_deinit(pepper_compositor_t * compositor)
+static int
+_headless_debug_handle_inotify_fd(int fd, uint32_t mask, void *data)
{
- headless_debug_t *hdebug = NULL;
+ headless_debug_t *hdebug = data;
+ struct inotify_event ev[32];
+ uint32_t i;
+ int nread;
+
+ if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) {
+ HEADLESS_ERROR("With the given fd(%d, mask:0x%x), there is an error "
+ "or it's been hung-up. (error: %m)", fd, mask);
+ HEADLESS_ERROR("The event source will be disabled and the fd will be "
+ "closed.");
+
+ if (hdebug->inotify.event_source) {
+ wl_event_source_fd_update(hdebug->inotify.event_source,
+ (uint32_t)0);
+ wl_event_source_remove(hdebug->inotify.event_source);
+ }
- hdebug = (headless_debug_t *)pepper_object_get_user_data((pepper_object_t *) compositor, &KEY_DEBUG);
- PEPPER_CHECK(hdebug, return, "Failed to get headless debug instance\n");
+ return 0;
+ }
- /* remove the directory watching already */
- if (hdebug->inotify)
- pepper_inotify_del(hdebug->inotify, "/run/pepper");
+ if (!(mask & WL_EVENT_READABLE))
+ return 0;
- /* remove inotify */
- pepper_inotify_destroy(hdebug->inotify);
- hdebug->inotify = NULL;
+ nread = read(fd, &ev, sizeof(ev));
+ HEADLESS_CHECK(nread >= 0, return 0,
+ "Failed on reading given fd. (error msg : %m, fd: %d)", fd);
- pepper_object_set_user_data((pepper_object_t *)hdebug->compositor, &KEY_DEBUG, NULL, NULL);
- free(hdebug);
+ for (i = 0; i < (nread / sizeof(ev[0])); i++) {
+ if (ev[i].wd == hdebug->inotify.wd)
+ _headless_debug_inotify_event_process(hdebug, &ev[i]);
+ }
+
+ return 0;
}
-pepper_bool_t
-headless_debug_init(pepper_compositor_t *compositor)
+static bool
+_headless_debug_inotify_init(headless_debug_t *hdebug)
{
- int n_actions;
- headless_debug_t *hdebug = NULL;
- pepper_inotify_t *inotify = NULL;
- pepper_bool_t res = PEPPER_FALSE;
+ const char *path = "/run/headless_server";
+ int fd, wd;
- hdebug = (headless_debug_t*)calloc(1, sizeof(headless_debug_t));
- PEPPER_CHECK(hdebug, goto error, "Failed to alloc for headless debug\n");
- hdebug->compositor = compositor;
+ fd = inotify_init();
+ HEADLESS_CHECK(fd >= 0, return false, "Failed to init inotify");
- /* create inotify to watch file(s) for event trace */
- inotify = pepper_inotify_create(hdebug->compositor, _trace_cb_handle_inotify_event, hdebug);
- PEPPER_CHECK(inotify, goto error, "Failed to create inotify\n");
+ wd = inotify_add_watch(fd, path,
+ IN_MODIFY | IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO |
+ IN_MOVE_SELF);
+ HEADLESS_CHECK(wd >= 0, goto err_wd,
+ "Failed to add watch for %s (error msg:%m)", path);
- /* add a directory for watching */
- res = pepper_inotify_add(inotify, "/run/pepper");
- PEPPER_CHECK(res, goto error, "Failed on pepper_inotify_add()\n");
+ hdebug->inotify.event_source = wl_event_loop_add_fd(
+ wl_display_get_event_loop(hdebug->server->display),
+ fd, WL_EVENT_READABLE, _headless_debug_handle_inotify_fd,
+ hdebug);
+ HEADLESS_CHECK(hdebug->inotify.event_source, goto err_ev,
+ "Failed to add fd as an event source.");
- hdebug->inotify = inotify;
- n_actions = sizeof(debug_actions)/sizeof(debug_actions[0]);
+ hdebug->inotify.fd = fd;
+ hdebug->inotify.wd = wd;
- PEPPER_TRACE("[%s] Done (%d actions have been defined.)\n", __FUNCTION__, n_actions);
+ return true;
- pepper_object_set_user_data((pepper_object_t *)compositor, &KEY_DEBUG, hdebug, NULL);
- return PEPPER_TRUE;
+err_ev:
+ inotify_rm_watch(fd, wd);
+err_wd:
+ close(fd);
-error:
- headless_debug_deinit(compositor);
+ return false;
+}
- return PEPPER_FALSE;
+static void
+_headless_debug_inotify_deinit(headless_debug_t *hdebug)
+{
+ wl_event_source_remove(hdebug->inotify.event_source);
+ inotify_rm_watch(hdebug->inotify.fd, hdebug->inotify.wd);
+ close(hdebug->inotify.fd);
}