static void weston_xserver_cleanup(struct weston_process *process, int status) { struct weston_xserver *mxs = container_of(process, struct weston_xserver, process); mxs->process.pid = 0; mxs->client = NULL; mxs->resource = NULL; mxs->abstract_source = wl_event_loop_add_fd(mxs->loop, mxs->abstract_fd, WL_EVENT_READABLE, weston_xserver_handle_event, mxs); mxs->unix_source = wl_event_loop_add_fd(mxs->loop, mxs->unix_fd, WL_EVENT_READABLE, weston_xserver_handle_event, mxs); if (mxs->wm) { weston_log("xserver exited, code %d\n", status); weston_wm_destroy(mxs->wm); mxs->wm = NULL; } else { /* If the X server crashes before it binds to the * xserver interface, shut down and don't try * again. */ weston_log("xserver crashing too fast: %d\n", status); weston_xserver_shutdown(mxs); } }
static int evdev_configure_device(struct evdev_device *device) { if ((device->caps & (EVDEV_MOTION_ABS | EVDEV_MOTION_REL | EVDEV_BUTTON))) { weston_seat_init_pointer(device->seat); weston_log("input device %s, %s is a pointer caps =%s%s%s\n", device->devname, device->devnode, device->caps & EVDEV_MOTION_ABS ? " absolute-motion" : "", device->caps & EVDEV_MOTION_REL ? " relative-motion": "", device->caps & EVDEV_BUTTON ? " button" : ""); } if ((device->caps & EVDEV_KEYBOARD)) { if (weston_seat_init_keyboard(device->seat, NULL) < 0) return -1; weston_log("input device %s, %s is a keyboard\n", device->devname, device->devnode); } if ((device->caps & EVDEV_TOUCH)) { weston_seat_init_touch(device->seat); weston_log("input device %s, %s is a touch device\n", device->devname, device->devnode); } return 0; }
static void weston_wm_send_incr_chunk(struct weston_wm *wm) { int length; weston_log("property deleted\n"); wm->selection_property_set = 0; if (wm->flush_property_on_delete) { weston_log("setting new property, %zu bytes\n", wm->source_data.size); wm->flush_property_on_delete = 0; length = weston_wm_flush_source_data(wm); if (wm->data_source_fd >= 0) { wm->property_source = wl_event_loop_add_fd(wm->server->loop, wm->data_source_fd, WL_EVENT_READABLE, weston_wm_read_data_source, wm); } else if (length > 0) { /* Transfer is all done, but queue a flush for * the delete of the last chunk so we can set * the 0 sized propert to signal the end of * the transfer. */ wm->flush_property_on_delete = 1; wl_array_release(&wm->source_data); } else { wm->selection_request.requestor = XCB_NONE; } } }
static void cms_output_created(struct cms_static *cms, struct weston_output *o) { struct weston_color_profile *p; struct weston_config_section *s; char *profile; weston_log("cms-static: output %i [%s] created\n", o->id, o->name); if (o->name == NULL) return; s = weston_config_get_section(cms->ec->config, "output", "name", o->name); if (s == NULL) return; if (weston_config_section_get_string(s, "icc_profile", &profile, NULL) < 0) return; p = weston_cms_load_profile(profile); if (p == NULL) { weston_log("cms-static: failed to load %s\n", profile); } else { weston_log("cms-static: loading %s for %s\n", profile, o->name); weston_cms_set_color_profile(o, p); } }
static void runner_run_handler(struct wl_client *client, struct wl_resource *resource, const char *test_name) { struct test_launcher *launcher; const struct runner_test *t; assert(static_context.runner_resource == NULL || static_context.runner_resource == resource); launcher = wl_resource_get_user_data(resource); static_context.layout_interface = launcher->layout_interface; static_context.runner_resource = resource; t = find_runner_test(test_name); if (!t) { weston_log("Error: runner test \"%s\" not found.\n", test_name); wl_resource_post_error(resource, WESTON_TEST_RUNNER_ERROR_UNKNOWN_TEST, "weston_test_runner: unknown: '%s'", test_name); return; } weston_log("weston_test_runner.run(\"%s\")\n", test_name); t->run(&static_context); weston_test_runner_send_finished(resource); }
static int weston_timeline_do_open(void) { const char *prefix = "weston-timeline-"; const char *suffix = ".log"; char fname[1000]; timeline_.file = file_create_dated(prefix, suffix, fname, sizeof(fname)); if (!timeline_.file) { const char *msg; switch (errno) { case ETIME: msg = "failure in datetime formatting"; break; default: msg = strerror(errno); } weston_log("Cannot open '%s*%s' for writing: %s\n", prefix, suffix, msg); return -1; } weston_log("Opened timeline file '%s'\n", fname); return 0; }
static int try_open_vt(struct tty *tty) { int tty0, fd; char filename[16]; tty0 = open("/dev/tty0", O_WRONLY | O_CLOEXEC); if (tty0 < 0) { weston_log("could not open tty0: %m\n"); return -1; } if (ioctl(tty0, VT_OPENQRY, &tty->vt) < 0 || tty->vt == -1) { weston_log("could not open tty0: %m\n"); close(tty0); return -1; } close(tty0); snprintf(filename, sizeof filename, "/dev/tty%d", tty->vt); weston_log("compositor: using new vt %s\n", filename); fd = open(filename, O_RDWR | O_NOCTTY | O_CLOEXEC); if (fd < 0) return fd; return fd; }
static void idle_launch_client(void *data) { struct test_launcher *launcher = data; pid_t pid; sigset_t allsigs; pid = fork(); if (pid == -1) { weston_log("fatal: failed to fork '%s': %m\n", launcher->exe); weston_compositor_exit_with_code(launcher->compositor, EXIT_FAILURE); return; } if (pid == 0) { sigfillset(&allsigs); sigprocmask(SIG_UNBLOCK, &allsigs, NULL); execl(launcher->exe, launcher->exe, NULL); weston_log("compositor: executing '%s' failed: %m\n", launcher->exe); _exit(EXIT_FAILURE); } launcher->process.pid = pid; launcher->process.cleanup = test_client_sigchld; weston_watch_process(&launcher->process); }
/*virtual*/ InputEmulatorUInput::~InputEmulatorUInput() { weston_log("weston-wfits: %s\n", BOOST_CURRENT_FUNCTION); if (ioctl(fd_, UI_DEV_DESTROY) < 0) { weston_log("weston-wfits: failed to destroy uinput device\n"); } }
static int weston_xserver_handle_event(int listen_fd, uint32_t mask, void *data) { struct weston_xserver *mxs = data; char display[8], s[8]; int sv[2], client_fd; if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) < 0) { weston_log("socketpair failed\n"); return 1; } mxs->process.pid = fork(); switch (mxs->process.pid) { case 0: /* SOCK_CLOEXEC closes both ends, so we need to unset * the flag on the client fd. */ client_fd = dup(sv[1]); if (client_fd < 0) return 1; snprintf(s, sizeof s, "%d", client_fd); setenv("WAYLAND_SOCKET", s, 1); snprintf(display, sizeof display, ":%d", mxs->display); if (execl(XSERVER_PATH, XSERVER_PATH, display, "-wayland", "-rootless", "-retro", "-nolisten", "all", "-terminate", NULL) < 0) weston_log("exec failed: %m\n"); exit(-1); default: weston_log("forked X server, pid %d\n", mxs->process.pid); close(sv[1]); mxs->client = wl_client_create(mxs->wl_display, sv[0]); weston_watch_process(&mxs->process); wl_event_source_remove(mxs->abstract_source); wl_event_source_remove(mxs->unix_source); break; case -1: weston_log( "failed to fork\n"); break; } return 1; }
static void ss_seat_handle_keymap(void *data, struct wl_keyboard *wl_keyboard, uint32_t format, int fd, uint32_t size) { struct ss_seat *seat = data; struct xkb_keymap *keymap; char *map_str; if (!data) goto error; if (format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); if (map_str == MAP_FAILED) { weston_log("mmap failed: %m\n"); goto error; } keymap = xkb_keymap_new_from_string(seat->base.compositor->xkb_context, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, 0); munmap(map_str, size); if (!keymap) { weston_log("failed to compile keymap\n"); goto error; } seat->keyboard_state_update = STATE_UPDATE_NONE; } else if (format == WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP) { weston_log("No keymap provided; falling back to default\n"); keymap = NULL; seat->keyboard_state_update = STATE_UPDATE_AUTOMATIC; } else { weston_log("Invalid keymap\n"); goto error; } close(fd); if (seat->base.keyboard_device_count) weston_seat_update_keymap(&seat->base, keymap); else weston_seat_init_keyboard(&seat->base, keymap); xkb_keymap_unref(keymap); return; error: wl_keyboard_release(seat->parent.keyboard); close(fd); }
static int weston_wm_handle_xfixes_selection_notify(struct weston_wm *wm, xcb_generic_event_t *event) { xcb_xfixes_selection_notify_event_t *xfixes_selection_notify = (xcb_xfixes_selection_notify_event_t *) event; struct weston_compositor *compositor; struct weston_seat *seat = weston_wm_pick_seat(wm); uint32_t serial; if (xfixes_selection_notify->selection != wm->atom.clipboard) return 0; weston_log("xfixes selection notify event: owner %d\n", xfixes_selection_notify->owner); if (xfixes_selection_notify->owner == XCB_WINDOW_NONE) { if (wm->selection_owner != wm->selection_window) { /* A real X client selection went away, not our * proxy selection. Clear the wayland selection. */ compositor = wm->server->compositor; serial = wl_display_next_serial(compositor->wl_display); weston_seat_set_selection(seat, NULL, serial); } wm->selection_owner = XCB_WINDOW_NONE; return 1; } wm->selection_owner = xfixes_selection_notify->owner; /* We have to use XCB_TIME_CURRENT_TIME when we claim the * selection, so grab the actual timestamp here so we can * answer TIMESTAMP conversion requests correctly. */ if (xfixes_selection_notify->owner == wm->selection_window) { wm->selection_timestamp = xfixes_selection_notify->timestamp; weston_log("our window, skipping\n"); return 1; } wm->incr = 0; xcb_convert_selection(wm->conn, wm->selection_window, wm->atom.clipboard, wm->atom.targets, wm->atom.wl_selection, xfixes_selection_notify->timestamp); xcb_flush(wm->conn); return 1; }
static void pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer) { struct pixman_surface_state *ps = get_surface_state(es); struct wl_shm_buffer *shm_buffer; pixman_format_code_t pixman_format; weston_buffer_reference(&ps->buffer_ref, buffer); if (ps->image) { pixman_image_unref(ps->image); ps->image = NULL; } if (!buffer) return; shm_buffer = wl_shm_buffer_get(buffer->resource); if (! shm_buffer) { weston_log("Pixman renderer supports only SHM buffers\n"); weston_buffer_reference(&ps->buffer_ref, NULL); return; } switch (wl_shm_buffer_get_format(shm_buffer)) { case WL_SHM_FORMAT_XRGB8888: pixman_format = PIXMAN_x8r8g8b8; break; case WL_SHM_FORMAT_ARGB8888: pixman_format = PIXMAN_a8r8g8b8; break; case WL_SHM_FORMAT_RGB565: pixman_format = PIXMAN_r5g6b5; break; default: weston_log("Unsupported SHM buffer format\n"); weston_buffer_reference(&ps->buffer_ref, NULL); return; break; } buffer->shm_buffer = shm_buffer; buffer->width = wl_shm_buffer_get_width(shm_buffer); buffer->height = wl_shm_buffer_get_height(shm_buffer); ps->image = pixman_image_create_bits(pixman_format, buffer->width, buffer->height, wl_shm_buffer_get_data(shm_buffer), wl_shm_buffer_get_stride(shm_buffer)); }
static pid_t spawn_xserver(struct weston_xserver *wxs) { int sv[2], wm[2]; if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) < 0) { weston_log("wl connection socketpair failed\n"); return 1; } if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, wm) < 0) { weston_log("X wm connection socketpair failed\n"); return 1; } QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); env.insert(QStringLiteral("WAYLAND_SOCKET"), QString::number(dup(sv[1]))); QString display = QStringLiteral(":%1").arg(wxs->display); QString abstract_fd = QString::number(dup(wxs->abstract_fd)); QString unix_fd = QString::number(dup(wxs->unix_fd)); QString wm_fd = QString::number(dup(wm[1])); s_process = new Process; s_process->setProcessChannelMode(QProcess::ForwardedChannels); s_process->setProcessEnvironment(env); s_process->connect(s_process, (void (QProcess::*)(int))&QProcess::finished, [wxs](int exitCode) { weston_xserver_exited(wxs, exitCode); if (s_process) { delete s_process; s_process = nullptr; } }); s_process->start(QStringLiteral("Xwayland"), { display, QStringLiteral("-rootless"), QStringLiteral("-listen"), abstract_fd, QStringLiteral("-listen"), unix_fd, QStringLiteral("-wm"), wm_fd, QStringLiteral("-terminate") }); close(sv[1]); wxs->client = wl_client_create(wxs->wl_display, sv[0]); close(wm[1]); wxs->wm_fd = wm[0]; return s_process->processId(); }
WL_EXPORT void weston_timeline_point(const char *name, ...) { va_list argp; struct timespec ts; enum timeline_type otype; void *obj; char buf[512]; struct timeline_emit_context ctx; clock_gettime(timeline_.clk_id, &ts); ctx.out = timeline_.file; ctx.cur = fmemopen(buf, sizeof(buf), "w"); ctx.series = timeline_.series; if (!ctx.cur) { weston_log("Timeline error in fmemopen, closing.\n"); weston_timeline_close(); return; } fprintf(ctx.cur, "{ \"T\":[%" PRId64 ", %ld], \"N\":\"%s\"", (int64_t)ts.tv_sec, ts.tv_nsec, name); va_start(argp, name); while (1) { otype = va_arg(argp, enum timeline_type); if (otype == TLT_END) break; obj = va_arg(argp, void *); if (type_dispatch[otype]) { fprintf(ctx.cur, ", "); type_dispatch[otype](&ctx, obj); } } va_end(argp); fprintf(ctx.cur, " }\n"); fflush(ctx.cur); if (ferror(ctx.cur)) { weston_log("Timeline error in constructing entry, closing.\n"); weston_timeline_close(); } else { fprintf(ctx.out, "%s", buf); } fclose(ctx.cur); }
static int launcher_logind_take_control(struct launcher_logind *wl) { DBusError err; DBusMessage *m, *reply; dbus_bool_t force; bool b; int r; dbus_error_init(&err); m = dbus_message_new_method_call("org.freedesktop.login1", wl->spath, "org.freedesktop.login1.Session", "TakeControl"); if (!m) return -ENOMEM; force = false; b = dbus_message_append_args(m, DBUS_TYPE_BOOLEAN, &force, DBUS_TYPE_INVALID); if (!b) { r = -ENOMEM; goto err_unref; } reply = dbus_connection_send_with_reply_and_block(wl->dbus, m, -1, &err); if (!reply) { if (dbus_error_has_name(&err, DBUS_ERROR_UNKNOWN_METHOD)) weston_log("logind: old systemd version detected\n"); else weston_log("logind: cannot take control over session %s\n", wl->sid); dbus_error_free(&err); r = -EIO; goto err_unref; } dbus_message_unref(reply); dbus_message_unref(m); return 0; err_unref: dbus_message_unref(m); return r; }
static void device_resumed(struct launcher_logind *wl, DBusMessage *m) { bool r; uint32_t major; r = dbus_message_get_args(m, NULL, DBUS_TYPE_UINT32, &major, /*DBUS_TYPE_UINT32, &minor, DBUS_TYPE_UNIX_FD, &fd,*/ DBUS_TYPE_INVALID); if (!r) { weston_log("logind: cannot parse ResumeDevice dbus signal\n"); return; } /* DeviceResumed messages provide us a new file-descriptor for * resumed devices. For DRM devices it's the same as before, for evdev * devices it's a new open-file. As we reopen evdev devices, anyway, * there is no need for us to handle this event for evdev. For DRM, we * notify the compositor to wake up. */ if (wl->sync_drm && major == DRM_MAJOR) launcher_logind_set_active(wl, true); }
WL_EXPORT int backend_init(struct weston_compositor *compositor, int *argc, char *argv[], struct weston_config *wc, struct weston_backend_config *config_base) { struct headless_backend *b; struct weston_headless_backend_config config = {{ 0, }}; if (config_base == NULL || config_base->struct_version != WESTON_HEADLESS_BACKEND_CONFIG_VERSION || config_base->struct_size > sizeof(struct weston_headless_backend_config)) { weston_log("headless backend config structure is invalid\n"); return -1; } config_init_to_defaults(&config); memcpy(&config, config_base, config_base->struct_size); b = headless_backend_create(compositor, &config); if (b == NULL) return -1; return 0; }
static void weston_wm_get_incr_chunk(struct weston_wm *wm) { xcb_get_property_cookie_t cookie; xcb_get_property_reply_t *reply; cookie = xcb_get_property(wm->conn, 0, /* delete */ wm->selection_window, wm->atom.wl_selection, XCB_GET_PROPERTY_TYPE_ANY, 0, /* offset */ 0x1fffffff /* length */); reply = xcb_get_property_reply(wm->conn, cookie, NULL); dump_property(wm, wm->atom.wl_selection, reply); if (xcb_get_property_value_length(reply) > 0) { weston_wm_write_property(wm, reply); } else { weston_log("transfer complete\n"); close(wm->data_source_fd); free(reply); } }
static void weston_wm_send_data(struct weston_wm *wm, xcb_atom_t target, const char *mime_type) { struct weston_data_source *source; struct weston_seat *seat = weston_wm_pick_seat(wm); int p[2]; if (pipe2(p, O_CLOEXEC | O_NONBLOCK) == -1) { weston_log("pipe2 failed: %m\n"); weston_wm_send_selection_notify(wm, XCB_ATOM_NONE); return; } wl_array_init(&wm->source_data); wm->selection_target = target; wm->data_source_fd = p[0]; wm->property_source = wl_event_loop_add_fd(wm->server->loop, wm->data_source_fd, WL_EVENT_READABLE, weston_wm_read_data_source, wm); source = seat->selection_data_source; source->send(source, mime_type, p[1]); close(p[1]); }
static GLuint CreateShader(GLenum type, const char *shader_src) { GLuint shader = glCreateShader(type); if(!shader) return 0; glShaderSource(shader, 1, &shader_src, NULL); glCompileShader(shader); GLint compiled = 0; glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); if(!compiled) { GLint info_len = 0; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_len); if(info_len > 1) { char *info_log = (char *)malloc(sizeof(char) * info_len); glGetShaderInfoLog(shader, info_len, NULL, info_log); weston_log("\tError compiling shader:\n\t%s\n", info_log); free(info_log); } glDeleteShader(shader); return 0; } return shader; }
void show_error_(const char *file, int line) { GLenum error = GL_NO_ERROR; error = glGetError(); if(error != GL_NO_ERROR) { switch(error) { case GL_INVALID_OPERATION: weston_log("\tGL Error: GL_INVALID_OPERATION - %s : %i\n", file, line); break; case GL_INVALID_ENUM: weston_log("\tGL Error: GL_INVALID_ENUM - %s : %i\n", file, line); break; case GL_INVALID_VALUE: weston_log("\tGL Error: GL_INVALID_VALUE - %s : %i\n", file, line); break; case GL_OUT_OF_MEMORY: weston_log("\tGL Error: GL_OUT_OF_MEMORY - %s : %i\n", file, line); break; case GL_INVALID_FRAMEBUFFER_OPERATION: weston_log("\tGL Error: GL_INVALID_FRAMEBUFFER_OPERATION - %s : %i\n", file, line); break; } } }
static int bind_to_abstract_socket(int display) { struct sockaddr_un addr; socklen_t size, name_size; int fd; fd = socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0); if (fd < 0) return -1; addr.sun_family = AF_LOCAL; name_size = snprintf(addr.sun_path, sizeof addr.sun_path, "%c/tmp/.X11-unix/X%d", 0, display); size = offsetof(struct sockaddr_un, sun_path) + name_size; if (bind(fd, (struct sockaddr *) &addr, size) < 0) { weston_log("failed to bind to @%s: %m\n", addr.sun_path + 1); close(fd); return -1; } if (listen(fd, 1) < 0) { close(fd); return -1; } return fd; }
WL_EXPORT int backend_init(struct weston_compositor *compositor, int *argc, char *argv[], struct weston_config *config, struct weston_backend_config *config_base) { int width = 1024, height = 640; char *display_name = NULL; struct headless_parameters param = { 0, }; const char *transform = "normal"; struct headless_backend *b; const struct weston_option headless_options[] = { { WESTON_OPTION_INTEGER, "width", 0, &width }, { WESTON_OPTION_INTEGER, "height", 0, &height }, { WESTON_OPTION_BOOLEAN, "use-pixman", 0, ¶m.use_pixman }, { WESTON_OPTION_STRING, "transform", 0, &transform }, }; parse_options(headless_options, ARRAY_LENGTH(headless_options), argc, argv); param.width = width; param.height = height; if (weston_parse_transform(transform, ¶m.transform) < 0) weston_log("Invalid transform \"%s\"\n", transform); b = headless_backend_create(compositor, ¶m, display_name); if (b == NULL) return -1; return 0; }
static int bind_to_unix_socket(int display) { struct sockaddr_un addr; socklen_t size, name_size; int fd; fd = socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0); if (fd < 0) return -1; addr.sun_family = AF_LOCAL; name_size = snprintf(addr.sun_path, sizeof addr.sun_path, "/tmp/.X11-unix/X%d", display) + 1; size = offsetof(struct sockaddr_un, sun_path) + name_size; unlink(addr.sun_path); if (bind(fd, (struct sockaddr *) &addr, size) < 0) { weston_log("failed to bind to %s (%s)\n", addr.sun_path, strerror(errno)); close(fd); return -1; } if (listen(fd, 1) < 0) { unlink(addr.sun_path); close(fd); return -1; } return fd; }
static void bind_runner(struct wl_client *client, void *data, uint32_t version, uint32_t id) { struct test_launcher *launcher = data; struct wl_resource *resource; resource = wl_resource_create(client, &weston_test_runner_interface, 1, id); if (!resource) { wl_client_post_no_memory(client); return; } wl_resource_set_implementation(resource, &runner_implementation, launcher, destroy_runner); if (static_context.runner_resource != NULL) { weston_log("test FATAL: " "attempting to run several tests in parallel.\n"); wl_resource_post_error(resource, WESTON_TEST_RUNNER_ERROR_TEST_FAILED, "attempt to run parallel tests"); } }
void evdev_notify_keyboard_focus(struct weston_seat *seat, struct wl_list *evdev_devices) { struct evdev_device *device; struct wl_array keys; unsigned int i, set; char evdev_keys[(KEY_CNT + 7) / 8]; char all_keys[(KEY_CNT + 7) / 8]; uint32_t *k; int ret; if (!seat->keyboard) return; memset(all_keys, 0, sizeof all_keys); wl_list_for_each(device, evdev_devices, link) { memset(evdev_keys, 0, sizeof evdev_keys); ret = ioctl(device->fd, EVIOCGKEY(sizeof evdev_keys), evdev_keys); if (ret < 0) { weston_log("failed to get keys for device %s\n", device->devnode); continue; } for (i = 0; i < ARRAY_LENGTH(evdev_keys); i++) all_keys[i] |= evdev_keys[i]; }
static void data_source_accept(struct weston_data_source *base, uint32_t time, const char *mime_type) { struct dnd_data_source *source = (struct dnd_data_source *) base; xcb_client_message_event_t client_message; struct weston_wm *wm = source->wm; weston_log("got accept, mime-type %s\n", mime_type); /* FIXME: If we rewrote UTF8_STRING to * text/plain;charset=utf-8 and the source doesn't support the * mime-type, we'll have to rewrite the mime-type back to * UTF8_STRING here. */ client_message.response_type = XCB_CLIENT_MESSAGE; client_message.format = 32; client_message.window = wm->dnd_window; client_message.type = wm->atom.xdnd_status; client_message.data.data32[0] = wm->dnd_window; client_message.data.data32[1] = 2; if (mime_type) client_message.data.data32[1] |= 1; client_message.data.data32[2] = 0; client_message.data.data32[3] = 0; client_message.data.data32[4] = wm->atom.xdnd_action_copy; xcb_send_event(wm->conn, 0, wm->dnd_owner, XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (char *) &client_message); }
WL_EXPORT int module_init(struct weston_compositor *ec, int *argc, char *argv[]) { struct cms_static *cms; struct weston_output *output; weston_log("cms-static: initialized\n"); /* create local state object */ cms = malloc(sizeof *cms); if (cms == NULL) return -1; memset(cms, 0, sizeof *cms); cms->ec = ec; cms->destroy_listener.notify = cms_notifier_destroy; wl_signal_add(&ec->destroy_signal, &cms->destroy_listener); cms->output_created_listener.notify = cms_notifier_output_created; wl_signal_add(&ec->output_created_signal, &cms->output_created_listener); /* discover outputs */ wl_list_for_each(output, &ec->output_list, link) cms_output_created(cms, output); return 0; }
WL_EXPORT void weston_spring_update(struct weston_spring *spring, uint32_t msec) { double force, v, current, step; /* Limit the number of executions of the loop below by ensuring that * the timestamp for last update of the spring is no more than 1s ago. * This handles the case where time moves backwards or forwards in * large jumps. */ if (msec - spring->timestamp > 1000) { weston_log("unexpectedly large timestamp jump (from %u to %u)\n", spring->timestamp, msec); spring->timestamp = msec - 1000; } step = 0.01; while (4 < msec - spring->timestamp) { current = spring->current; v = current - spring->previous; force = spring->k * (spring->target - current) / 10.0 + (spring->previous - current) - v * spring->friction; spring->current = current + (current - spring->previous) + force * step * step; spring->previous = current; switch (spring->clip) { case WESTON_SPRING_OVERSHOOT: break; case WESTON_SPRING_CLAMP: if (spring->current > spring->max) { spring->current = spring->max; spring->previous = spring->max; } else if (spring->current < 0.0) { spring->current = spring->min; spring->previous = spring->min; } break; case WESTON_SPRING_BOUNCE: if (spring->current > spring->max) { spring->current = 2 * spring->max - spring->current; spring->previous = 2 * spring->max - spring->previous; } else if (spring->current < spring->min) { spring->current = 2 * spring->min - spring->current; spring->previous = 2 * spring->min - spring->previous; } break; } spring->timestamp += 4; } }