⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 onspot.c

📁 《Linux程序设计权威指南》源代码
💻 C
字号:
	/* File: overspot.c */	#include <X11/Xlib.h>	#include <X11/Xutil.h>	#include <X11/keysym.h>	#include <stdio.h>	#include <locale.h>	#define F_SIZE		16	#define COL 		30	#define ROW		10	#define W_WIDTH         (F_SIZE * COL)	#define W_HEIGHT        (F_SIZE * ROW)	//回调函数	int     P_StartCB(XIC, XPointer, XPointer);	int     P_DoneCB(XIC, XPointer, XPointer);	int     P_DrawCB(XIC, XPointer, XIMPreeditDrawCallbackStruct*);	int     P_CaretCB(XIC, XPointer, XIMPreeditCaretCallbackStruct*);		int     S_StartCB(XIC, XPointer, XPointer);	int     S_DoneCB(XIC, XPointer, XPointer);	int     S_DrawCB(XIC, XPointer, XIMStatusDrawCallbackStruct*);	Display *display;	int screen_num;	Window win;			//窗口ID	GC gc, rgc;	XFontSet        fontset;	int             dec;	int             row = 0, col = 0;	char            status_tab[30];	char            preedit_tab[128];	char            Feedback[128];	void            DrawPreeditString(char *, char *);	int main(int argc, char **argv)	{		unsigned int width, height;	//窗口尺寸		unsigned int border_width = 4;	//边界空白		unsigned int display_width, display_height;//屏幕尺寸		XEvent report;		unsigned long valuemask = 0;		XGCValues values;		char *display_name = NULL;		Atom          protocols;		//edit		int           len = 127;		unsigned char string[128], s_tab[ROW][127];		KeySym        keysym;		int           i, count = 0;		Status        status;		//字体集		char **missing_charsets;		int num_missing_charsets;		char *default_string;		XFontSetExtents *fs_ext;		//XIM		XIM im;		XIC ic;		XVaNestedList preedit_attr, status_attr;		//回调函数		XIMCallback   P_StartCB_Str;		XIMCallback   P_DoneCB_Str;		XIMCallback   P_DrawCB_Str;		XIMCallback   P_CaretCB_Str;		XIMCallback   S_StartCB_Str;		XIMCallback   S_DoneCB_Str;		XIMCallback   S_DrawCB_Str;		//设置locale			if((setlocale(LC_ALL, "")) == NULL){			printf("cannot set locale\n");			exit(1);		}		//判断X是否支持locale		if(!XSupportsLocale()){			printf("X does not support current locale\n");			exit(1);		}		//设置locale修饰		if(XSetLocaleModifiers(NULL)){			printf("Cannot set locale modifiers\n");			exit(1);		}			// 和X 服务器连接		if ( (display=XOpenDisplay(display_name)) == NULL )		{			printf("Cannot connect to X server %s\n", 					XDisplayName(display_name));			exit(-1);		}		//获得缺省的 screen_num		screen_num = DefaultScreen(display);		//获得屏幕的宽度和高度		display_width = DisplayWidth(display, screen_num);		display_height = DisplayHeight(display, screen_num);			//建立字体集		fontset = XCreateFontSet(display, 			"8x16,-*-song-medium-r-normal--16-*-*-*-*-*-gb2312.1980-0",			&missing_charsets, &num_missing_charsets,			&default_string);		if(num_missing_charsets > 0){			int i;			printf("Following charsets are missing:\n");			for(i=0; i<num_missing_charsets; i++){				printf("Missing %d: %s\n", 					i, missing_charsets[i]);			}			printf("\nDefault string:%s\n", default_string);			XFreeStringList(missing_charsets);		}		//字体的Extents		fs_ext = XExtentsOfFontSet(fontset);		dec = fs_ext->max_logical_extent.height 			+ fs_ext->max_logical_extent.y;		width  = W_WIDTH;		height = W_HEIGHT + dec;			//建立窗口		win = XCreateSimpleWindow(display, 	//display			RootWindow(display,screen_num), //父窗口			0, 0, width, height, 		//位置和大小			border_width, 			//边界宽度			BlackPixel(display,screen_num), //前景色			WhitePixel(display,screen_num));//背景色			//选择窗口感兴趣的事件掩码		XSelectInput(display, win, 			ExposureMask | KeyPressMask | 			ButtonPressMask | StructureNotifyMask);		//建立GC和翻转色GC		gc = DefaultGC(display, screen_num);		values.foreground = WhitePixel(display, screen_num);		values.background = BlackPixel(display, screen_num);		rgc = XCreateGC(display, win,			(GCForeground | GCBackground), &values);		protocols = XInternAtom(display, "WM_DELETE_WINDOW", True);		XSetWMProtocols(display, win, &protocols, 1);		//显示窗口		XMapWindow(display, win);		//联接输入服务器		if((im = XOpenIM(display, NULL, NULL, NULL)) == NULL){			printf("Error : XOpenIM !\n");			exit(1);		}		//设置输入服务器的回调		P_StartCB_Str.client_data = NULL;		P_StartCB_Str.callback = (XIMProc)P_StartCB;		P_DoneCB_Str.client_data = NULL;		P_DoneCB_Str.callback = (XIMProc)P_DoneCB;		P_DrawCB_Str.client_data = NULL;		P_DrawCB_Str.callback = (XIMProc)P_DrawCB;		P_CaretCB_Str.client_data = NULL;		P_CaretCB_Str.callback = (XIMProc)P_StartCB;		preedit_attr = XVaCreateNestedList(0,			XNPreeditStartCallback, &P_StartCB_Str,			XNPreeditDoneCallback, &P_DoneCB_Str,			XNPreeditDrawCallback, &P_DrawCB_Str,			XNPreeditCaretCallback, &P_CaretCB_Str,			NULL);		S_StartCB_Str.client_data = NULL;		S_StartCB_Str.callback = (XIMProc)S_StartCB;		S_DoneCB_Str.client_data = NULL;		S_DoneCB_Str.callback = (XIMProc)S_DoneCB;		S_DrawCB_Str.client_data = NULL;		S_DrawCB_Str.callback = (XIMProc)S_DrawCB;		status_attr = XVaCreateNestedList(0,			XNStatusStartCallback, &S_StartCB_Str,			XNStatusDoneCallback, &S_DoneCB_Str,			XNStatusDrawCallback, &S_DrawCB_Str,			NULL);		//建立IC		if((ic = XCreateIC(im, 			XNInputStyle, XIMPreeditCallbacks | XIMStatusCallbacks,			XNClientWindow, win, 			XNPreeditAttributes, preedit_attr,			XNStatusAttributes, status_attr, NULL)) == NULL){			printf("Error : XCreateIC() ! \n");			XCloseIM(im);			exit(0);		}		//释放内存		XFree(preedit_attr);		XFree(status_attr);		//写屏缓冲区初始化		for(i = 0; i < ROW; i++)s_tab[i][0] = 0;		//进入事件循环		while (1)  {			//取得队列中的事件			XNextEvent(display, &report);			//过滤事件			if(XFilterEvent(&report, None) == True) continue;			switch  (report.type) {			//聚焦发声变化			case FocusIn:				XSetICFocus(ic); 				break;			case FocusOut:				XUnsetICFocus(ic);				break;			//曝光事件, 窗口应重绘			case Expose:				//取得最后一个曝光事件/*				if (report.xexpose.count != 0) break;				for ( i=0; i < ROW; i++)					XmbDrawString(display, win, fontset,gc, 					0, F_SIZE * (i +1), 					s_tab[i], strlen(s_tab[i]));				DrawPreeditString(preedit_tab, Feedback);				XmbDrawString(display, win, fontset, gc, 					20, W_HEIGHT, status_tab, 					strlen(status_tab));*/				break;			//窗口尺寸改变, 重新取得窗口的宽度和高度			case ConfigureNotify:				width = report.xconfigure.width;				height = report.xconfigure.height;				break;			//鼠标点击或有按键, 释放资源则退出			case KeyPress:				count = XmbLookupString(ic, 					(XKeyPressedEvent *) &report,					string, len, &keysym, &status);				string[count] = 0;				if (status == XLookupBoth&&keysym == XK_Return){					row = (++row) % ROW;					col = 0;					s_tab[row][0] = 0;					preedit_tab[0] = 0;					Feedback[0] = 0;					XClearArea(display, win, 						0, F_SIZE * row + dec,						W_WIDTH, F_SIZE, False);				} else if (status = XLookupChars 					|| status == XLookupBoth){					XmbDrawString(display, win, fontset, gc,						F_SIZE / 2 * col, F_SIZE * (row + 1),						string, count);					for (i = 0; i < count; i++, col++)						s_tab[row][col] = 0;					s_tab[row][col] = 0;					preedit_tab[0] = 0;					Feedback[0] = 0;				}				break;			case ClientMessage:				if (report.xclient.data.l[0] == protocols) {					XDestroyIC(ic);					XCloseIM(im);					XDestroyWindow(display, win);					XCloseDisplay(display);					exit(0);				}				break;			default:				break;			}		}	}	int P_StartCB(XIC ic, XPointer client_data, XPointer P_S)	{		printf(" PreeditStartCallback\n");		return(127);	}	int P_DoneCB(XIC ic, XPointer client_data, XPointer P_DN)	{		printf(" PreeditDoneCallback\n");		preedit_tab[0] = 0;		Feedback[0] = 0;	}	int P_DrawCB(XIC ic, XPointer client_data,	      XIMPreeditDrawCallbackStruct *P_DR)	{		int i, j, lcol;		char preedit_string[128], emp_string[1]; 		lcol = col;		emp_string[0] = ' ' ;  		for (i = 0; i <(P_DR->chg_length*2); i++, lcol++)			XmbDrawImageString(display, win, fontset, gc,				F_SIZE / 2 * (lcol + 2 * P_DR->chg_first),				F_SIZE * (row + 1), emp_string, 1);		if (P_DR->text) {			if (P_DR->text->encoding_is_wchar)				wctomb(preedit_string, 					P_DR->text->string.wide_char);			else				strcpy(preedit_string, 					P_DR->text->string.multi_byte);			for (i = P_DR->chg_first * 2, j = 0; 				preedit_string[j] != 0; i++, j++)				preedit_tab[j] = preedit_string[j];			preedit_tab[i] = 0;			for (i = P_DR->chg_first, j = 0;				(unsigned int)i < P_DR->chg_first + 				P_DR->text->length; i++, j++)				Feedback[i] = P_DR->text->feedback[j];			DrawPreeditString(preedit_tab, Feedback);		}}	int P_CaretCB(XIC ic, XPointer client_data,	      XIMPreeditCaretCallbackStruct *P_C)	{		printf(" PreeditCaretCalback\n");	}	int S_StartCB(XIC ic, XPointer client_data, XPointer S_S)	{		printf(" StatusStartCallback\n");	}	int S_DoneCB(XIC ic, XPointer client_data, XPointer S_S)	{		printf(" StartusDoneCallback\n");	}	int S_DrawCB(XIC ic, XPointer client_data,	      XIMStatusDrawCallbackStruct *S_DR)	{		if (S_DR->type != XIMBitmapType) {			if (S_DR->data.text->encoding_is_wchar)				wctomb(status_tab, 					S_DR->data.text->string.wide_char);			else				strcpy(status_tab, 					S_DR->data.text->string.multi_byte);			XClearArea(display, win, 0, 				W_HEIGHT - F_SIZE + dec,W_WIDTH, F_SIZE, False);			XmbDrawImageString(display, win, fontset, gc,				20, W_HEIGHT, status_tab, strlen(status_tab));		}	}	void DrawPreeditString(char *p, char *fp)	{		int i;		int lcol = col;		dec = 2;		for (i = 0; i < strlen(fp); i++) {			if (fp[i] == XIMReverse)				XmbDrawImageString(display, win, fontset, rgc,					F_SIZE / 2 * lcol, F_SIZE * (row + 1),					p, mblen(p, 3));			else {				XmbDrawImageString(display, win, fontset, rgc,					F_SIZE / 2 * lcol, F_SIZE * (row + 1),					p, mblen(p, 3));				XDrawLine(display, win, gc,					F_SIZE / 2 * lcol, F_SIZE * (row + 1),					F_SIZE / 2 * (lcol + mblen(p, 3)) 					- (dec - 1), F_SIZE * (row + 1) + 1);			}			lcol += mblen(p, 3);			p += mblen(p, 3);		}	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -