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

📄 matchbox-keyboard-ui.c

📁 Linux系统上的一款屏幕软键盘
💻 C
📖 第 1 页 / 共 2 页
字号:
      if (streq(wm_name, "matchbox"))	have_matchbox_wm = True;    }  win_attr.override_redirect = False; /* Set to true for extreme case */  win_attr.event_mask     = ButtonPressMask|ButtonReleaseMask|Button1MotionMask|StructureNotifyMask;  ui->xwin = XCreateWindow(ui->xdpy,			   ui->xwin_root,			   0, 0,			   ui->xwin_width, ui->xwin_height,			   0,			   CopyFromParent, CopyFromParent, CopyFromParent,			   CWOverrideRedirect|CWEventMask,			   &win_attr);  wm_hints = XAllocWMHints();  if (wm_hints)    {      DBG("setting no focus hint");      wm_hints->input = False;      wm_hints->flags = InputHint;      XSetWMHints(ui->xdpy, ui->xwin, wm_hints );      XFree(wm_hints);    }  size_hints.flags = PPosition | PSize | PMinSize;  size_hints.x = 0;  size_hints.y = 0;  size_hints.width      =  ui->xwin_width;   size_hints.height     =  ui->xwin_height;  size_hints.min_width  =  ui->xwin_width;  size_hints.min_height =  ui->xwin_height;      XSetStandardProperties(ui->xdpy, ui->xwin, "Keyboard", 			 NULL, 0, NULL, 0, &size_hints);  if (!ui->want_embedding)    {      mwm_hints = util_malloc0(sizeof(PropMotifWmHints));        if (mwm_hints)	{	  mwm_hints->flags = MWM_HINTS_DECORATIONS;	  mwm_hints->decorations = 0;	  	  XChangeProperty(ui->xdpy, ui->xwin, atom_MOTIF_WM_HINTS, 			  XA_ATOM, 32, PropModeReplace, 			  (unsigned char *)mwm_hints, 			  PROP_MOTIF_WM_HINTS_ELEMENTS);	  	  free(mwm_hints);	}            if (have_ewmh_wm)	{	  /* XXX Fix this for display size */	  int wm_struct_vals[] = { 0, /* left */							   0, /* right */ 				   0, /* top */				   0, /* bottom */				   0, /* left_start_y */				   0, /* left_end_y */				   0, /* right_start_y */				   0, /* right_end_y */				   0, /* top_start_x */				   0, /* top_end_x */				   0, /* bottom_start_x */				   1399 }; /* bottom_end_x */	  	  Atom states[] = { atom_NET_WM_STATE_SKIP_TASKBAR, atom_NET_WM_STATE_SKIP_PAGER };	  int  desk_width = 0, desk_height = 0, desk_y = 0;	  	  XChangeProperty(ui->xdpy, ui->xwin, 			  atom_NET_WM_STATE, XA_ATOM, 32, 			  PropModeReplace, 			  (unsigned char *)states, 2);	  	  if (get_desktop_area(ui, NULL, &desk_y, &desk_width, &desk_height))	    {	      /* Assuming we take up all available display width 	       * ( at least true with matchbox wm ). we resize	       * the base ui width to this ( and height as a factor ) 	       * to avoid the case of mapping and then the wm resizing	       * us, causing an ugly repaint. 	       */	      if (desk_width > ui->xwin_width)		{		  mb_kbd_ui_resize(ui, 				   desk_width, 				   ( desk_width * ui->xwin_height ) / ui->xwin_width);		}	      	      wm_struct_vals[2]  = desk_y + desk_height - ui->xwin_height;	      wm_struct_vals[11] = desk_width;	      	      XChangeProperty(ui->xdpy, ui->xwin, 			      atom_NET_WM_STRUT_PARTIAL, XA_CARDINAL, 32, 			      PropModeReplace, 			      (unsigned char *)wm_struct_vals , 12);	      	      DBG("desk width: %i, desk height: %i xwin_height :%i",		  desk_width, desk_height, ui->xwin_height);	      	    }	  	  if (have_matchbox_wm)	    {	      XChangeProperty(ui->xdpy, ui->xwin, 			      atom_NET_WM_WINDOW_TYPE, XA_ATOM, 32, 			      PropModeReplace, 			      (unsigned char *) &atom_NET_WM_WINDOW_TYPE_TOOLBAR, 1);	    }	  else	    {	      /*		XChangeProperty(ui->xdpy, ui->xwin, 		atom_NET_WM_WINDOW_TYPE, XA_ATOM, 32, 		PropModeReplace, 		(unsigned char *) &atom_NET_WM_WINDOW_TYPE_DOCK, 1);	      */	      	    }	}    }  ui->backbuffer = XCreatePixmap(ui->xdpy,				 ui->xwin,				 ui->xwin_width, 				 ui->xwin_height,				 DefaultDepth(ui->xdpy, ui->xscreen));  XSetWindowBackgroundPixmap(ui->xdpy,			     ui->xwin, 			     ui->backbuffer);  ui->backend->resources_create(ui);  /* Get root size change events for rotation */  /* XSelectInput(ui->xdpy, ui->xwin_root, StructureNotifyMask); */  return 1;}static voidmb_kbd_ui_resize(MBKeyboardUI *ui, int width, int height) {  MBKeyboard       *kbd = ui->kbd;  MBKeyboardLayout *layout;  List              *row_item, *key_item;  int               width_diff, height_diff;  int               height_font_pt_size, width_font_pt_size;  int               next_row_y,  n_rows, extra_key_height;  MARK();  width_diff  = width  - ui->base_alloc_width;   height_diff = height - ui->base_alloc_height;   if (width_diff < 0 || height_diff < 0)    return;  /* dont go smaller than our int request - get clipped */  layout   = mb_kbd_get_selected_layout(ui->kbd);  row_item = mb_kbd_layout_rows(layout);  /* load a bigger font ?    * Only load if height and width have changed   */  width_font_pt_size = ( (ui->base_font_pt_size * width) 		               / ui->base_alloc_width );    if (util_abs(width_font_pt_size - kbd->font_pt_size) > 2)    {      height_font_pt_size = ( (ui->base_font_pt_size * height) 			         / ui->base_alloc_height );      if (util_abs(height_font_pt_size - kbd->font_pt_size) > 2)	{	  ui->kbd->font_pt_size = (height_font_pt_size > width_font_pt_size)                  	       ? width_font_pt_size : height_font_pt_size;	  mb_kbd_ui_load_font(ui);	}    }  n_rows = util_list_length(row_item);  extra_key_height = (height_diff / n_rows);  DBG("****** extra height is %i ******", extra_key_height);  next_row_y = mb_kbd_row_spacing(ui->kbd);  /* allocate the extra width we have as padding to keys */  while (row_item != NULL)    {      int row_base_width, new_row_base_width, row_width_diff;      int  next_key_x = 0,  n_fillers  = 0, free_space = 0, new_w = 0;      row_base_width = mb_kbd_row_base_width(row_item->data);      new_row_base_width = ( row_base_width * width ) / ui->base_alloc_width;      row_width_diff = new_row_base_width - row_base_width;      DBG("row_width_diff = %i", row_width_diff);      next_key_x = mb_kbd_col_spacing(ui->kbd);      /*        * row_base_width              * --------------  X  new_width  = new_base_width       *   base_width             *       * key_extra_pad  = key_base_width X base_width_diff        *                  --------------------------------       *                          row_base_width      */      mb_kbd_row_for_each_key(row_item->data, key_item)	{	  MBKeyboardKey *key = key_item->data;	  int            key_base_width, key_new_pad;	  if (!mb_kbd_is_extended(kbd) && mb_kbd_key_get_extended(key))	    continue;	  key_base_width =( mb_kbd_key_width(key) 			    - mb_kbd_key_get_extra_width_pad(key));	  key_new_pad= ( (key_base_width + mb_kbd_col_spacing(kbd)) * row_width_diff) / row_base_width;                              	  mb_kbd_key_set_extra_width_pad (key, key_new_pad );	  /* Height */	  mb_kbd_key_set_extra_height_pad (key, extra_key_height);	  mb_kbd_key_set_geometry(key, next_key_x, -1, -1, -1);	  next_key_x += (mb_kbd_key_width(key) + mb_kbd_col_spacing(ui->kbd)); 	  if (mb_kbd_key_get_fill(key))	      n_fillers++;	}      /* The above ( likely due to rounding ) leaves a few pixels free.        * This can be critical on a small handheld display. Therefore        * we do a second parse deviding up any left over space between       * keys marked as fill.       */      if (n_fillers)	{	  free_space = width - mb_kbd_row_width(row_item->data);	  mb_kbd_row_for_each_key(row_item->data, key_item)	    {	      if (!mb_kbd_is_extended(kbd) 		  && mb_kbd_key_get_extended(key_item->data))		continue;	      if (mb_kbd_key_get_fill(key_item->data))		{		  int   old_w;		  List *nudge_key_item = util_list_next(key_item);		  		  old_w = mb_kbd_key_width(key_item->data);		  new_w = old_w + (free_space/n_fillers);		  		  mb_kbd_key_set_geometry(key_item->data, -1, -1, new_w, -1);		  		  /* nudge next keys forward */		  for (; 		       nudge_key_item != NULL; 		       nudge_key_item = util_list_next(nudge_key_item)) 		    {		      if (!mb_kbd_is_extended(ui->kbd) 			  && mb_kbd_key_get_extended(nudge_key_item->data))			continue;		      mb_kbd_key_set_geometry(nudge_key_item->data,					      mb_kbd_key_x(nudge_key_item->data) + (new_w - old_w ), -1, -1, -1);		    }		}	    }	}      /* re-center row */      mb_kbd_row_set_x(row_item->data, 		       (width - mb_kbd_row_width(row_item->data))/2);      /* and position down */      mb_kbd_row_set_y(row_item->data, next_row_y);      next_row_y  += (mb_kbd_row_height(row_item->data) 		      + mb_kbd_row_spacing(ui->kbd));      row_item = util_list_next(row_item);    }  /* center entire layout vertically if space left */  if (next_row_y < height)    {      int vspace = ( height - next_row_y ) / 2;      row_item = mb_kbd_layout_rows(layout);      while (row_item != NULL)	{	  mb_kbd_row_set_y(row_item->data, 			   mb_kbd_row_y(row_item->data) + vspace + 1);	  row_item = util_list_next(row_item);	}    }  XResizeWindow(ui->xdpy, ui->xwin, width, height);  ui->xwin_width  = width;  ui->xwin_height = height;  if (ui->backbuffer) /* may get called before initialised */    {      XFreePixmap(ui->xdpy, ui->backbuffer);      ui->backbuffer = XCreatePixmap(ui->xdpy,				     ui->xwin,				     ui->xwin_width, 				     ui->xwin_height,				     DefaultDepth(ui->xdpy, ui->xscreen));      ui->backend->resize(ui, width, height);      XSetWindowBackgroundPixmap(ui->xdpy, ui->xwin, ui->backbuffer);      mb_kbd_ui_redraw(ui);    }}voidmb_kbd_ui_handle_configure(MBKeyboardUI *ui,			   int           width,			   int           height){  boolean old_state, new_state;  MARK();  /* Figure out if screen size has changed - does a round trip - bad */  update_display_size(ui);  old_state = mb_kbd_is_extended(ui->kbd);  new_state = want_extended(ui);     if (new_state == old_state) 	/* Not a rotation */    {      mb_kbd_ui_resize(ui, width, height);       return;    }  mb_kbd_set_extended(ui->kbd, new_state);  /* realocate the layout */  mb_kbd_ui_allocate_ui_layout(ui, 			       &ui->base_alloc_width, &ui->base_alloc_height);  mb_kbd_ui_resize(ui, width, height); }voidmb_kbd_ui_event_loop(MBKeyboardUI *ui){  MBKeyboardKey *key = NULL;  struct timeval tvt;  /* Key repeat - values for standard xorg install ( xset q) */  int repeat_delay = 100 * 10000;  int repeat_rate  = 30  * 1000;  tvt.tv_sec  = 0;  tvt.tv_usec = repeat_delay;  while (True)      {	XEvent xev;	if (get_xevent_timed(ui->xdpy, &xev, &tvt))	  {	    switch (xev.type) 	      {	      case ButtonPress:		DBG("got button bress at %i,%i", xev.xbutton.x, xev.xbutton.y);		key = mb_kbd_locate_key(ui->kbd, xev.xbutton.x, xev.xbutton.y);		if (key)		  {		    /* Hack if we never get a release event */		    if (key != mb_kbd_get_held_key(ui->kbd))		      {			mb_kbd_key_release(ui->kbd);			tvt.tv_usec = repeat_delay;   		      }		    else		      tvt.tv_usec = repeat_rate;		    DBG("found key for press");		    mb_kbd_key_press(key);		  }		break;	      case ButtonRelease:		if (mb_kbd_get_held_key(ui->kbd) != NULL)		  {		    mb_kbd_key_release(ui->kbd);	 		    tvt.tv_usec = repeat_delay;		  }		break;	      case ConfigureNotify:		if (xev.xconfigure.width != ui->xwin_width		    || xev.xconfigure.height != ui->xwin_height)		  mb_kbd_ui_handle_configure(ui,					     xev.xconfigure.width,					     xev.xconfigure.height);		break;	      case MappingNotify: 		fakekey_reload_keysyms(ui->fakekey);		XRefreshKeyboardMapping(&xev.xmapping);		break;	      default:		break;	      }	    if (ui->want_embedding)	      mb_kbd_xembed_process_xevents (ui, &xev);	  }	else	  {	    /* Keyrepeat */	    if (mb_kbd_get_held_key(ui->kbd) != NULL)	      {		fakekey_repeat(ui->fakekey);		tvt.tv_usec = repeat_rate;	      }	  }      }}static intmb_kbd_ui_load_font(MBKeyboardUI *ui){  return ui->backend->font_load(ui);}intmb_kbd_ui_display_width(MBKeyboardUI *ui){  return ui->dpy_width;}intmb_kbd_ui_display_height(MBKeyboardUI *ui){  return ui->dpy_height;}MBKeyboardUIBackend*mb_kbd_ui_backend(MBKeyboardUI *ui){  return ui->backend;}Display*mb_kbd_ui_x_display(MBKeyboardUI *ui){  return ui->xdpy;}intmb_kbd_ui_x_screen(MBKeyboardUI *ui){  return ui->xscreen;}Windowmb_kbd_ui_x_win(MBKeyboardUI *ui){  return ui->xwin;}Windowmb_kbd_ui_x_win_root(MBKeyboardUI *ui){  return ui->xwin_root;}intmb_kbd_ui_x_win_height(MBKeyboardUI *ui){  return ui->xwin_height;}intmb_kbd_ui_x_win_width(MBKeyboardUI *ui){  return ui->xwin_width;}Pixmapmb_kbd_ui_backbuffer(MBKeyboardUI *ui){  return ui->backbuffer;}MBKeyboard*mb_kbd_ui_kbd(MBKeyboardUI *ui){  return ui->kbd;}intmb_kbd_ui_realize(MBKeyboardUI *ui){  ui->base_font_pt_size = ui->kbd->font_pt_size;  if (!mb_kbd_ui_load_font(ui))    return 0;  /* potrait or landscape */  if (want_extended(ui))    mb_kbd_set_extended(ui->kbd, True);  /*    * figure out how small this keyboard can be..  */  mb_kbd_ui_allocate_ui_layout(ui, 			       &ui->base_alloc_width, &ui->base_alloc_height);  ui->xwin_width  = ui->base_alloc_width;  ui->xwin_height = ui->base_alloc_height;  mb_kbd_ui_resources_create(ui);  unless (mb_kbd_ui_embeded(ui))    {      mb_kbd_ui_show(ui);      mb_kbd_ui_redraw(ui);    }  else    mb_kbd_xembed_init (ui);  return 1;}intmb_kbd_ui_init(MBKeyboard *kbd){  MBKeyboardUI     *ui = NULL;    ui = kbd->ui = util_malloc0(sizeof(MBKeyboardUI));    ui->kbd = kbd;  if ((ui->xdpy = XOpenDisplay(getenv("DISPLAY"))) == NULL)    return 0;  if ((ui->fakekey = fakekey_init(ui->xdpy)) == NULL)    return 0;  ui->xscreen   = DefaultScreen(ui->xdpy);  ui->xwin_root = RootWindow(ui->xdpy, ui->xscreen);     ui->backend = MB_KBD_UI_BACKEND_INIT_FUNC(ui);  update_display_size(ui);  return 1;}/* Embedding */voidmb_kbd_ui_set_embeded (MBKeyboardUI *ui, int embed){  ui->want_embedding = embed;} intmb_kbd_ui_embeded (MBKeyboardUI *ui){  return ui->want_embedding;}voidmb_kbd_ui_print_window (MBKeyboardUI *ui){  fprintf(stdout, "%li\n", mb_kbd_ui_x_win(ui));  fflush(stdout);}

⌨️ 快捷键说明

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