📄 gdkmain-fb.c
字号:
}static gbooleangdk_fb_manager_callback (GIOChannel *gioc, GIOCondition cond, gpointer data){ struct FBManagerMessage msg; GdkFBDisplay *display; int res; display = data; res = recv (display->manager_fd, &msg, sizeof (msg), 0); if (res==0) { g_source_remove (gdk_display->manager_tag); /*g_io_channel_unref (kb->io);*/ close (gdk_display->manager_fd); } if (res != sizeof (msg)) { g_warning ("Got wrong size message"); return TRUE; } switch (msg.msg_type) { case FB_MANAGER_SWITCH_FROM: g_print ("Got switch from message\n"); display->manager_blocked = TRUE; gdk_fb_switch_from (); msg.msg_type = FB_MANAGER_ACK; send (display->manager_fd, &msg, sizeof (msg), 0); break; case FB_MANAGER_SWITCH_TO: g_print ("Got switch to message\n"); display->manager_blocked = FALSE; gdk_fb_switch_to (); break; default: g_warning ("Got unknown message"); } return TRUE;}#endif /* ENABLE_FB_MANAGER */static voidgdk_fb_manager_connect (GdkFBDisplay *display){#ifdef ENABLE_FB_MANAGER int fd; struct sockaddr_un addr; struct msghdr msg = {0}; struct cmsghdr *cmsg; struct ucred credentials; struct FBManagerMessage init_msg; struct iovec iov; char buf[CMSG_SPACE (sizeof (credentials))]; /* ancillary data buffer */ int *fdptr; int res; display->manager_blocked = FALSE; display->manager_fd = -1; fd = socket (PF_UNIX, SOCK_STREAM, 0); g_print ("socket: %d\n", fd); if (fd < 0) return; addr.sun_family = AF_UNIX; strcpy (addr.sun_path, "/tmp/.fb.manager"); if (connect(fd, (struct sockaddr *)&addr, sizeof (addr)) < 0) { g_print ("connect failed\n"); close (fd); return; } credentials.pid = getpid (); credentials.uid = geteuid (); credentials.gid = getegid (); init_msg.msg_type = FB_MANAGER_NEW_CLIENT; iov.iov_base = &init_msg; iov.iov_len = sizeof (init_msg); msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = buf; msg.msg_controllen = sizeof buf; cmsg = CMSG_FIRSTHDR(&msg); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_CREDENTIALS; cmsg->cmsg_len = CMSG_LEN (sizeof (credentials)); /* Initialize the payload: */ fdptr = (int *)CMSG_DATA (cmsg); memcpy (fdptr, &credentials, sizeof (credentials)); /* Sum of the length of all control messages in the buffer: */ msg.msg_controllen = cmsg->cmsg_len; res = sendmsg (fd, &msg, 0); display->manager_fd = fd; display->manager_blocked = TRUE; display->manager_tag = g_io_add_watch (g_io_channel_unix_new (fd), G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, gdk_fb_manager_callback, display); init_msg.msg_type = FB_MANAGER_REQUEST_SWITCH_TO_PID; init_msg.data = getpid (); /* Request a switch-to */ send (fd, &init_msg, sizeof (init_msg), 0);#endif}static voidgdk_fb_switch (int sig){ if (sig == SIGUSR1) { ioctl (gdk_display->tty_fd, VT_RELDISP, 1); _gdk_fb_is_active_vt = FALSE; gdk_shadow_fb_stop_updates (); gdk_fb_mouse_close (); gdk_fb_keyboard_close (); } else { GdkColormap *cmap; ioctl (gdk_display->tty_fd, VT_RELDISP, VT_ACKACQ); _gdk_fb_is_active_vt = TRUE; /* XXX: is it dangerous to put all this stuff in a signal handler? */ cmap = gdk_screen_get_default_colormap (_gdk_screen); gdk_colormap_change (cmap, cmap->size); gdk_shadow_fb_update (0, 0, gdk_display->fb_width, gdk_display->fb_height); if (!gdk_fb_keyboard_open ()) g_warning ("Failed to re-initialize keyboard"); if (!gdk_fb_mouse_open ()) g_warning ("Failed to re-initialize mouse"); gdk_fb_redraw_all (); }}static GdkFBDisplay *gdk_fb_display_new (void){ GdkFBDisplay *display; gchar *fb_filename; struct vt_stat vs; struct vt_mode vtm; int vt, n; gchar *s, *send; char buf[32]; display = g_new0 (GdkFBDisplay, 1); display->console_fd = open ("/dev/console", O_RDWR); if (display->console_fd < 0) { g_warning ("Can't open /dev/console: %s", strerror (errno)); g_free (display); return NULL; } ioctl (display->console_fd, VT_GETSTATE, &vs); display->start_vt = vs.v_active; vt = display->start_vt; s = getenv("GDK_VT"); if (s) { if (g_ascii_strcasecmp ("new", s)==0) { n = ioctl (display->console_fd, VT_OPENQRY, &vt); if (n < 0 || vt == -1) g_error("Cannot allocate new VT"); } else { vt = strtol (s, &send, 10); if (s==send) { g_warning ("Cannot parse GDK_VT"); vt = display->start_vt; } } } display->vt = vt; /* Switch to the new VT */ if (vt != display->start_vt) { ioctl (display->console_fd, VT_ACTIVATE, vt); ioctl (display->console_fd, VT_WAITACTIVE, vt); } /* Open the tty */ g_snprintf (buf, sizeof(buf), "/dev/tty%d", vt); display->tty_fd = open (buf, O_RDWR|O_NONBLOCK); if (display->tty_fd < 0) { g_warning ("Can't open %s: %s", buf, strerror (errno)); close (display->console_fd); g_free (display); return NULL; } /* set up switch signals */ if (ioctl (display->tty_fd, VT_GETMODE, &vtm) >= 0) { signal (SIGUSR1, gdk_fb_switch); signal (SIGUSR2, gdk_fb_switch); vtm.mode = VT_PROCESS; vtm.waitv = 0; vtm.relsig = SIGUSR1; vtm.acqsig = SIGUSR2; ioctl (display->tty_fd, VT_SETMODE, &vtm); } _gdk_fb_is_active_vt = TRUE; fb_filename = gdk_get_display (); display->fb_fd = open (fb_filename, O_RDWR); if (display->fb_fd < 0) { g_warning ("Can't open %s: %s", fb_filename, strerror (errno)); g_free (fb_filename); close (display->tty_fd); close (display->console_fd); g_free (display); return NULL; } g_free (fb_filename); if (gdk_fb_set_mode (display) < 0) { close (display->fb_fd); close (display->tty_fd); close (display->console_fd); g_free (display); return NULL; } /* Disable normal text on the console */ ioctl (display->fb_fd, KDSETMODE, KD_GRAPHICS); ioctl (display->fb_fd, FBIOBLANK, 0); /* We used to use sinfo.smem_len, but that seemed to be broken in many cases */ display->fb_mmap = mmap (NULL, display->modeinfo.yres * display->sinfo.line_length, PROT_READ|PROT_WRITE, MAP_SHARED, display->fb_fd, 0); g_assert (display->fb_mmap != MAP_FAILED); if (display->sinfo.visual == FB_VISUAL_TRUECOLOR) { display->red_byte = display->modeinfo.red.offset >> 3; display->green_byte = display->modeinfo.green.offset >> 3; display->blue_byte = display->modeinfo.blue.offset >> 3; }#ifdef ENABLE_SHADOW_FB if (_gdk_fb_screen_angle % 2 == 0) { display->fb_width = display->modeinfo.xres; display->fb_height = display->modeinfo.yres; } else { display->fb_width = display->modeinfo.yres; display->fb_height = display->modeinfo.xres; } display->fb_stride = display->fb_width * (display->modeinfo.bits_per_pixel / 8); display->fb_mem = g_malloc(display->fb_height * display->fb_stride);#else display->fb_mem = display->fb_mmap; display->fb_width = display->modeinfo.xres; display->fb_height = display->modeinfo.yres; display->fb_stride = display->sinfo.line_length;#endif return display;}static voidgdk_fb_display_destroy (GdkFBDisplay *display){ /* Restore old framebuffer mode */ ioctl (display->fb_fd, FBIOPUT_VSCREENINFO, &display->orig_modeinfo); /* Enable normal text on the console */ ioctl (display->fb_fd, KDSETMODE, KD_TEXT); munmap (display->fb_mmap, display->modeinfo.yres * display->sinfo.line_length); close (display->fb_fd); ioctl (display->console_fd, VT_ACTIVATE, display->start_vt); ioctl (display->console_fd, VT_WAITACTIVE, display->start_vt); if (display->vt != display->start_vt) ioctl (display->console_fd, VT_DISALLOCATE, display->vt); close (display->tty_fd); close (display->console_fd); g_free (display);}void_gdk_windowing_init (void){ if (gdk_initialized) return; /* Create new session and become session leader */ setsid(); gdk_display = gdk_fb_display_new (); if (!gdk_display) return; gdk_shadow_fb_init (); gdk_fb_manager_connect (gdk_display); if (!gdk_fb_keyboard_init (!gdk_display->manager_blocked)) { g_warning ("Failed to initialize keyboard"); gdk_fb_display_destroy (gdk_display); gdk_display = NULL; return; } if (!gdk_fb_mouse_init (!gdk_display->manager_blocked)) { g_warning ("Failed to initialize mouse"); gdk_fb_keyboard_close (); gdk_fb_display_destroy (gdk_display); gdk_display = NULL; return; } /* Although atexit is evil, we need it here because otherwise the * keyboard is left in a bad state. you can still run 'reset' but * that gets annoying after running testgtk for the 20th time. */ g_atexit(_gdk_windowing_exit); gdk_initialized = TRUE; _gdk_selection_property = gdk_atom_intern ("GDK_SELECTION", FALSE);}void_gdk_windowing_set_default_display (GdkDisplay *display){}/* *-------------------------------------------------------------- * gdk_pointer_grab * * Grabs the pointer to a specific window * * Arguments: * "window" is the window which will receive the grab * "owner_events" specifies whether events will be reported as is, * or relative to "window" * "event_mask" masks only interesting events * "confine_to" limits the cursor movement to the specified window * "cursor" changes the cursor for the duration of the grab * "time" specifies the time * * Results: * * Side effects: * requires a corresponding call to gdk_pointer_ungrab * *-------------------------------------------------------------- */GdkGrabStatusgdk_pointer_grab (GdkWindow * window, gint owner_events, GdkEventMask event_mask, GdkWindow * confine_to, GdkCursor * cursor, guint32 time){ return gdk_fb_pointer_grab (window, owner_events, event_mask, confine_to, cursor, time, FALSE);}static gboolean _gdk_fb_pointer_implicit_grab = FALSE;GdkGrabStatusgdk_fb_pointer_grab (GdkWindow * window, gint owner_events, GdkEventMask event_mask, GdkWindow * confine_to, GdkCursor * cursor, guint32 time, gboolean implicit_grab){ g_return_val_if_fail (window != NULL, 0); g_return_val_if_fail (GDK_IS_WINDOW (window), 0); g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0); if (_gdk_fb_pointer_grab_window) { if (implicit_grab && !_gdk_fb_pointer_implicit_grab) return GDK_GRAB_ALREADY_GRABBED; gdk_pointer_ungrab (time); } gdk_fb_window_send_crossing_events (NULL, window, GDK_CROSSING_GRAB); if (event_mask & GDK_BUTTON_MOTION_MASK) event_mask |= GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK; _gdk_fb_pointer_implicit_grab = implicit_grab; _gdk_fb_pointer_grab_window = gdk_window_ref (window); _gdk_fb_pointer_grab_owner_events = owner_events; _gdk_fb_pointer_grab_confine = confine_to ? gdk_window_ref (confine_to) : NULL; _gdk_fb_pointer_grab_events = event_mask; _gdk_fb_pointer_grab_cursor = cursor ? gdk_cursor_ref (cursor) : NULL; if (cursor) gdk_fb_cursor_reset (); return GDK_GRAB_SUCCESS;}/* *-------------------------------------------------------------- * gdk_display_pointer_ungrab * * Releases any pointer grab * * Arguments: * * Results: * * Side effects: * *-------------------------------------------------------------- */voidgdk_display_pointer_ungrab (GdkDisplay *display, guint32 time){ gdk_fb_pointer_ungrab (time, FALSE);}voidgdk_fb_pointer_ungrab (guint32 time, gboolean implicit_grab){ gboolean have_grab_cursor = _gdk_fb_pointer_grab_cursor && 1; GdkWindow *mousewin; GdkWindow *old_grab_window; if (!_gdk_fb_pointer_grab_window) return; if (implicit_grab && !_gdk_fb_pointer_implicit_grab) return; if (_gdk_fb_pointer_grab_confine) gdk_window_unref (_gdk_fb_pointer_grab_confine); _gdk_fb_pointer_grab_confine = NULL; if (_gdk_fb_pointer_grab_cursor) gdk_cursor_unref (_gdk_fb_pointer_grab_cursor); _gdk_fb_pointer_grab_cursor = NULL; if (have_grab_cursor) gdk_fb_cursor_reset (); old_grab_window = _gdk_fb_pointer_grab_window; _gdk_fb_pointer_grab_window = NULL; _gdk_fb_pointer_implicit_grab = FALSE; mousewin = gdk_window_at_pointer (NULL, NULL); gdk_fb_window_send_crossing_events (old_grab_window, mousewin, GDK_CROSSING_UNGRAB); if (old_grab_window) gdk_window_unref (old_grab_window);}/* *-------------------------------------------------------------- * gdk_display_pointer_is_grabbed * * Tell wether there is an active x pointer grab in effect * * Arguments: * * Results: * * Side effects: * *-------------------------------------------------------------- */gint
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -