我正在用 libX11 编写一个简单的文本用户界面,并且我有一组用于基本库抽象的代码。
问题是当我尝试绘制文本时,标题栏挡住了第一行。所以现在我必须将垂直打印偏移大约 20 个像素。有没有办法确定标题栏的确切大小,以便我可以正确偏移每一行文本?
这是我到目前为止的代码,并且tui_puts
是我需要执行此操作的功能:
#include "tui.h"
#include <X11/Xlib.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
struct tui_data {
Display * display;
Window id_window;
GC context_graphics;
XIM method_input;
XIC context_input;
XWindowAttributes spec_window;
XFontStruct * spec_font;
size_t offset_y;
size_t offset_x;
};
int tui_init (struct tui_session * ptr_tui){
memset (ptr_tui, 0, sizeof (struct tui_session));
ptr_tui->ptr_data = calloc (sizeof (struct tui_data), 1);
if (!ptr_tui->ptr_data) return -1;
ptr_tui->ptr_data->display = XOpenDisplay (0);
if (!ptr_tui->ptr_data->display) return -1;
int color_black = BlackPixel(ptr_tui->ptr_data->display, DefaultScreen(ptr_tui->ptr_data->display));
int color_white = WhitePixel(ptr_tui->ptr_data->display, DefaultScreen(ptr_tui->ptr_data->display));
ptr_tui->ptr_data->id_window = XCreateSimpleWindow(ptr_tui->ptr_data->display,
DefaultRootWindow(ptr_tui->ptr_data->display),
0, 0, 640, 480, 0, color_black, color_black);
XSelectInput (ptr_tui->ptr_data->display,
ptr_tui->ptr_data->id_window,
StructureNotifyMask);
XMapWindow (ptr_tui->ptr_data->display,
ptr_tui->ptr_data->id_window);
ptr_tui->ptr_data->context_graphics = XCreateGC(ptr_tui->ptr_data->display,
ptr_tui->ptr_data->id_window, 0, 0);
for (;;){
XEvent e;
XNextEvent (ptr_tui->ptr_data->display, &e);
if (e.type == MapNotify) break;
}
XSetForeground (ptr_tui->ptr_data->display,
ptr_tui->ptr_data->context_graphics,
color_white);
XGetWindowAttributes (ptr_tui->ptr_data->display,
ptr_tui->ptr_data->id_window,
&ptr_tui->ptr_data->spec_window);
XSelectInput (ptr_tui->ptr_data->display,
ptr_tui->ptr_data->id_window,
ExposureMask | KeyPressMask | ResizeRedirectMask);
ptr_tui->ptr_data->method_input = XOpenIM (ptr_tui->ptr_data->display, 0, 0, 0);
if (!ptr_tui->ptr_data->method_input){
return -1;
}
ptr_tui->ptr_data->context_input = XCreateIC (ptr_tui->ptr_data->method_input,
XNInputStyle, XIMPreeditNothing
| XIMStatusNothing, XNClientWindow,
ptr_tui->ptr_data->id_window, NULL);
if (!ptr_tui->ptr_data->context_input){
return -1;
}
XSetICFocus (ptr_tui->ptr_data->context_input);
ptr_tui->ptr_data->spec_font = XLoadQueryFont (ptr_tui->ptr_data->display,
"-misc-fixed-medium-"
"r-normal-*-*-120-*-*");
if (!ptr_tui->ptr_data->spec_font){
return -1;
}
XSetFont (ptr_tui->ptr_data->display,
ptr_tui->ptr_data->context_graphics,
ptr_tui->ptr_data->spec_font->fid);
ptr_tui->max_x = ptr_tui->ptr_data->spec_window.width
/ ptr_tui->ptr_data->spec_font->max_bounds.width;
ptr_tui->max_y = ptr_tui->ptr_data->spec_window.height
/ (ptr_tui->ptr_data->spec_font->max_bounds.ascent
+ ptr_tui->ptr_data->spec_font->max_bounds.descent);
return 0;
}
int tui_free (struct tui_session * ptr_tui){
if (ptr_tui->ptr_data){
XFreeFont (ptr_tui->ptr_data->display, ptr_tui->ptr_data->spec_font);
XFreeGC (ptr_tui->ptr_data->display, ptr_tui->ptr_data->context_graphics);
XSetCloseDownMode(ptr_tui->ptr_data->display, DestroyAll);
XCloseDisplay (ptr_tui->ptr_data->display);
free (ptr_tui->ptr_data);
}
memset (ptr_tui, 0, sizeof (struct tui_session));
return 0;
}
int tui_refresh (struct tui_session * ptr_tui){
XFlush (ptr_tui->ptr_data->display);
return 0;
}
int tui_clear (struct tui_session * ptr_tui){
XClearWindow (ptr_tui->ptr_data->display,
ptr_tui->ptr_data->id_window);
return 0;
}
int tui_puts (struct tui_session * ptr_tui,
const void * ptr_data, size_t len_data,
size_t index_x, size_t index_y, uint32_t flags){
if (((index_x + len_data) >= ptr_tui->max_x)
|| (index_y >= ptr_tui->max_y)) return -1;
XDrawImageString (ptr_tui->ptr_data->display,
ptr_tui->ptr_data->id_window,
ptr_tui->ptr_data->context_graphics,
ptr_tui->ptr_data->spec_window.border_width
+ ptr_tui->ptr_data->spec_font->max_bounds.width * index_x,
(ptr_tui->ptr_data->spec_font->max_bounds.ascent
+ ptr_tui->ptr_data->spec_font->max_bounds.descent)
* index_y + 20, ptr_data, len_data);
return 0;
}
int tui_message (struct tui_session * ptr_tui, const char * format, ...){
return -1;
}
int tui_prompt (struct tui_session * ptr_tui, const char * format, ...){
return -1;
}
int tui_input (struct tui_session * ptr_tui, tui_event * ptr_event){
XEvent event;
Status status = 0;
KeySym keysym = 0;
char buffer[4];
int count = 0;
XNextEvent(ptr_tui->ptr_data->display, &event);
switch (event.type){
case KeyPress:
count = Xutf8LookupString (ptr_tui->ptr_data->context_input,
(XKeyPressedEvent*) &event, buffer,
sizeof (buffer), &keysym, &status);
if (count){
ptr_event->type = TUI_EVENT_KEYPRESS;
ptr_event->value = buffer[0];
}
break;
case Expose:
ptr_event->type = TUI_EVENT_REPRINT;
ptr_event->value = 0;
break;
case ResizeRequest:
XGetWindowAttributes (ptr_tui->ptr_data->display,
ptr_tui->ptr_data->id_window,
&ptr_tui->ptr_data->spec_window);
ptr_event->type = TUI_EVENT_REPRINT;
ptr_event->value = 0;
break;
default:
ptr_event->type = 0;
ptr_event->value = 0;
}
return 0;
}
int tui_scroll (struct tui_session * ptr_tui, int offset){
return -1;
}
另外,这是一个重要的结构:
typedef struct {
int x, y; /* location of window */
int width, height; /* width and height of window */
int border_width; /* border width of window */
int depth; /* depth of window */
Visual *visual; /* the associated visual structure */
Window root; /* root of screen containing window */
int class; /* InputOutput, InputOnly*/
int bit_gravity; /* one of the bit gravity values */
int win_gravity; /* one of the window gravity values */
int backing_store; /* NotUseful, WhenMapped, Always */
unsigned long backing_planes; /* planes to be preserved if possible */
unsigned long backing_pixel; /* value to be used when restoring planes */
Bool save_under; /* boolean, should bits under be saved? */
Colormap colormap; /* color map to be associated with window */
Bool map_installed; /* boolean, is color map currently installed*/
int map_state; /* IsUnmapped, IsUnviewable, IsViewable */
long all_event_masks; /* set of events all people have interest in*/
long your_event_mask; /* my event mask */
long do_not_propagate_mask; /* set of events that should not propagate */
Bool override_redirect; /* boolean value for override-redirect */
Screen *screen; /* back pointer to correct screen */
} XWindowAttributes;
这有助于获得客户区域的水平偏移,但我没有看到任何可以帮助我获得垂直偏移的东西。