XDisplay.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. #include <stdio.h>
  2. /*****************************************************************************/
  3. /* ここから */
  4. /*****************************************************************************/
  5. #include "XDisplayP.h"
  6. /*****************************************************************************/
  7. /* メンバ関数の定義 */
  8. /*****************************************************************************/
  9. unsigned int XDisplay_GetKeyPress(XDisplay x_display)
  10. { return (x_display->key_press); }
  11. int XDisplay_GetLCDDraw(XDisplay x_display)
  12. { return (x_display->lcd_draw); }
  13. /*****************************************************************************/
  14. /* 内部で使用する関数などの定義 */
  15. /*****************************************************************************/
  16. static XrmOptionDescRec options[] = {};
  17. static Atom wm_delete_window;
  18. static void die(Widget w)
  19. {
  20. kill(getpid(), SIGINT);
  21. }
  22. static void quit(Widget w, XEvent * event, String * params, Cardinal * num)
  23. {
  24. die(w);
  25. }
  26. static void wm_protocols_proc(Widget w, XEvent * event, String * params,
  27. Cardinal * num)
  28. {
  29. if ((event->type == ClientMessage) &&
  30. (event->xclient.data.l[0] != wm_delete_window)) {
  31. XBell(XtDisplay(w), 0);
  32. } else {
  33. die(w);
  34. }
  35. }
  36. static void iconify(Widget w, XEvent * event, String * params, Cardinal * num)
  37. {
  38. XIconifyWindow(XtDisplay(w), XtWindow(w), DefaultScreen(XtDisplay(w)));
  39. }
  40. static void pause(Widget w, XEvent * event, String * params, Cardinal * num)
  41. {
  42. sleep(3);
  43. }
  44. static XtActionsRec actions[] = {
  45. {"quit", quit},
  46. {"wm_protocols_proc", wm_protocols_proc},
  47. {"iconify", iconify},
  48. {"pause", pause}
  49. };
  50. static char * translations =
  51. "<Message>WM_PROTOCOLS: wm_protocols_proc()\n"
  52. "None<Key>p: pause()\n"
  53. "Ctrl<Key>i: iconify()\n"
  54. "Ctrl<Key>c: quit()\n"
  55. "None<Key>q: quit()";
  56. /*===========================================================================*/
  57. /* 色名からピクセル値を取得する */
  58. /*===========================================================================*/
  59. static unsigned long XDisplay_GetPixelFromColorName(XDisplay x_display,
  60. char * color_name)
  61. {
  62. XColor c0, c1;
  63. XAllocNamedColor(x_display->display, x_display->colormap, color_name,
  64. &c0, &c1);
  65. return (c0.pixel);
  66. }
  67. /*===========================================================================*/
  68. /* イベントハンドラ */
  69. /*===========================================================================*/
  70. /*---------------------------------------------------------------------------*/
  71. /* キーの押下 */
  72. /*---------------------------------------------------------------------------*/
  73. static void KeyHandler(Widget w, XtPointer p, XEvent * event,
  74. Boolean * dispatch)
  75. {
  76. XDisplay x_display = (XDisplay)p;
  77. KeySym key_sym;
  78. int press = 0;
  79. if ((event->type == KeyPress) || (event->type == KeyRelease)) {
  80. key_sym = XKeycodeToKeysym(x_display->display, event->xkey.keycode, 0);
  81. switch (key_sym) {
  82. /* WonderSwan用 */
  83. case XK_Up : press = KEY_UP1; break;
  84. case XK_Right : press = KEY_RIGHT1; break;
  85. case XK_Down : press = KEY_DOWN1; break;
  86. case XK_Left : press = KEY_LEFT1; break;
  87. case XK_i : press = KEY_UP2; break;
  88. case XK_l : press = KEY_RIGHT2; break;
  89. case XK_k : press = KEY_DOWN2; break;
  90. case XK_j : press = KEY_LEFT2; break;
  91. case XK_s : press = KEY_START; break;
  92. case XK_space : press = KEY_A; break;
  93. case XK_Shift_L : press = KEY_B; break;
  94. /* Wonx 操作用 */
  95. /* 表示モード変更 */
  96. case XK_p :
  97. press = 0;
  98. if (event->type == KeyPress)
  99. x_display->lcd_draw = !(x_display->lcd_draw);
  100. break;
  101. default : press = 0; break;
  102. }
  103. if (press) {
  104. if (event->type == KeyPress) x_display->key_press |= press;
  105. else x_display->key_press &= ~press;
  106. }
  107. }
  108. return;
  109. }
  110. /*---------------------------------------------------------------------------*/
  111. /* イクスポーズ */
  112. /*---------------------------------------------------------------------------*/
  113. static void ExposeHandler(Widget w, XtPointer p, XEvent * event,
  114. Boolean * dispatch)
  115. {
  116. XDisplay x_display = (XDisplay)p;
  117. XCopyArea(x_display->display, x_display->lcd_pixmap,
  118. x_display->lcd_window, x_display->copy_gc,
  119. 0, 0, x_display->width, x_display->height, 0, 0);
  120. return;
  121. }
  122. /*---------------------------------------------------------------------------*/
  123. /* マウスがウインドウを離れたら,キーを初期化する */
  124. /*---------------------------------------------------------------------------*/
  125. static void LeaveWindowHandler(Widget w, XtPointer p, XEvent * event,
  126. Boolean * dispatch)
  127. {
  128. XDisplay x_display = (XDisplay)p;
  129. x_display->key_press = 0;
  130. return;
  131. }
  132. /*===========================================================================*/
  133. /* オブジェクトの生成と消去 */
  134. /*===========================================================================*/
  135. /*---------------------------------------------------------------------------*/
  136. /* オブジェクトの生成 */
  137. /*---------------------------------------------------------------------------*/
  138. XDisplay XDisplay_Create(int width, int height)
  139. {
  140. XDisplay x_display;
  141. int argc = 0;
  142. char ** argv = NULL;
  143. XColor color;
  144. char * color_name[] = {"white", "gray84", "gray78", "gray72",
  145. "gray66", "gray60", "gray54", "gray48",
  146. "gray42", "gray36", "gray30", "gray24",
  147. "gray18", "gray12", "gray6", "black"};
  148. int i;
  149. x_display = (XDisplay)malloc(sizeof(_XDisplay));
  150. if (x_display == NULL) Error("XDisplay_Create", "Cannot allocate memory.");
  151. x_display->width = width;
  152. x_display->height = height;
  153. x_display->toplevel = XtAppInitialize(&(x_display->app_context),
  154. "Wonx",
  155. NULL, 0, &argc, argv, NULL, NULL, 0);
  156. XtVaSetValues(x_display->toplevel, XtNinput, True, NULL);
  157. XtVaSetValues(x_display->toplevel, XtNtitle, "Wonx", NULL);
  158. XtVaSetValues(x_display->toplevel, XtNwidth , x_display->width , NULL);
  159. XtVaSetValues(x_display->toplevel, XtNminWidth , x_display->width , NULL);
  160. XtVaSetValues(x_display->toplevel, XtNmaxWidth , x_display->width , NULL);
  161. XtVaSetValues(x_display->toplevel, XtNheight , x_display->height, NULL);
  162. XtVaSetValues(x_display->toplevel, XtNminHeight, x_display->height, NULL);
  163. XtVaSetValues(x_display->toplevel, XtNmaxHeight, x_display->height, NULL);
  164. x_display->key_press = 0;
  165. x_display->lcd_draw = 1;
  166. XtRealizeWidget(x_display->toplevel);
  167. while (!XtIsRealized(x_display->toplevel)) { /* None */ }
  168. x_display->display = XtDisplay(x_display->toplevel);
  169. x_display->root_window = DefaultRootWindow(x_display->display);
  170. x_display->lcd_window = XtWindow(x_display->toplevel);
  171. x_display->colormap = DefaultColormap(x_display->display,
  172. DefaultScreen(x_display->display));
  173. x_display->depth = DefaultDepth(x_display->display,
  174. DefaultScreen(x_display->display));
  175. x_display->lcd_pixmap = XCreatePixmap(x_display->display,
  176. x_display->lcd_window,
  177. x_display->width,
  178. x_display->height,
  179. x_display->depth);
  180. x_display->copy_gc = XCreateGC(x_display->display, x_display->lcd_window,
  181. 0, 0);
  182. XSetFunction(x_display->display, x_display->copy_gc, GXcopy);
  183. for (i = 0; i < 16; i++) {
  184. XParseColor(x_display->display, x_display->colormap,
  185. color_name[i], &color); /* 色の名前 → RGB値*/
  186. XAllocColor(x_display->display, x_display->colormap,
  187. &color); /* 色を確保し,ピクセル値を得る */
  188. x_display->color_gc[i] = XCreateGC(x_display->display,
  189. x_display->lcd_window, 0, 0);
  190. XSetForeground(x_display->display, x_display->color_gc[i], color.pixel);
  191. XSetFunction(x_display->display, x_display->color_gc[i], GXcopy);
  192. }
  193. /* フォントの確保 */
  194. x_display->font = XLoadFont(x_display->display, "8x16");
  195. x_display->font_gc = XCreateGC(x_display->display,
  196. x_display->lcd_window, 0, 0);
  197. XSetFont(x_display->display, x_display->font_gc, x_display->font);
  198. XSetFunction(x_display->display, x_display->font_gc, GXcopy);
  199. XSetForeground(x_display->display, x_display->font_gc,
  200. XDisplay_GetPixelFromColorName(x_display, "white"));
  201. XSetBackground(x_display->display, x_display->font_gc,
  202. XDisplay_GetPixelFromColorName(x_display, "black"));
  203. XFillRectangle(x_display->display, x_display->lcd_window,
  204. x_display->color_gc[0],
  205. 0, 0, x_display->width, x_display->height);
  206. /* イベントハンドラの登録 */
  207. XtAddEventHandler(x_display->toplevel, KeyPressMask | KeyReleaseMask,
  208. False, KeyHandler, x_display);
  209. XtAddEventHandler(x_display->toplevel, ExposureMask,
  210. False, ExposeHandler, x_display);
  211. XtAddEventHandler(x_display->toplevel, LeaveWindowMask | FocusChangeMask,
  212. False, LeaveWindowHandler, x_display);
  213. /* アイコンの設定 */
  214. #if 0
  215. XtVaSetValues(x_display->toplevel, XtNiconPixmap,
  216. x_display->icon_pixmap, NULL);
  217. XtVaSetValues(x_display->toplevel, XtNiconMask ,
  218. x_display->icon_mask , NULL);
  219. #endif
  220. /* アクションの設定 */
  221. XtAppAddActions(x_display->app_context, actions, XtNumber(actions));
  222. /* トランスレーションの設定 */
  223. XtOverrideTranslations(x_display->toplevel,
  224. XtParseTranslationTable(translations));
  225. /* ウィンドウマネージャからの f.delete への対応 */
  226. wm_delete_window = XInternAtom(x_display->display,
  227. "WM_DELETE_WINDOW", False);
  228. XSetWMProtocols(x_display->display, x_display->lcd_window,
  229. &wm_delete_window, 1);
  230. /* Xサーバと同期をとる */
  231. /* True だと,イベントキュー内のイベントを廃棄する */
  232. XSync(x_display->display, True);
  233. return (x_display);
  234. }
  235. /*---------------------------------------------------------------------------*/
  236. /* オブジェクトの消去 */
  237. /*---------------------------------------------------------------------------*/
  238. XDisplay XDisplay_Destroy(XDisplay x_display)
  239. {
  240. int i;
  241. if (x_display == NULL) return (NULL);
  242. /* あとでリソースの解放を追加すること */
  243. if (x_display->color_gc != NULL) {
  244. for (i = 0; i < 16; i++) {
  245. if (x_display->color_gc[i])
  246. XFreeGC(x_display->display, x_display->color_gc[i]);
  247. x_display->color_gc[i] = 0;
  248. }
  249. }
  250. free(x_display);
  251. return (NULL);
  252. }
  253. /*---------------------------------------------------------------------------*/
  254. /* Xサーバとの同期 */
  255. /*---------------------------------------------------------------------------*/
  256. int XDisplay_Sync(XDisplay x_display)
  257. {
  258. XEvent event;
  259. XFlush(x_display->display);
  260. /* Xサーバと同期をとる */
  261. /* False だと,イベントキュー内のイベントを廃棄しない */
  262. XSync(x_display->display, False);
  263. /* イベントの処理 */
  264. while (XtAppPending(x_display->app_context)) {
  265. XtAppNextEvent(x_display->app_context, &event);
  266. XtDispatchEvent(&event);
  267. }
  268. return (0);
  269. }
  270. /*---------------------------------------------------------------------------*/
  271. /* 描画 */
  272. /*---------------------------------------------------------------------------*/
  273. int XDisplay_DrawLCDWindow(XDisplay x_display, WWLCDPanel ww_lcd_panel)
  274. {
  275. int x, y, n;
  276. int px, py;
  277. int num;
  278. XRectangle * rectangles;
  279. int pixel;
  280. int ww_lcd_width, ww_lcd_height;
  281. num =
  282. WWLCDPanel_GetHeight(ww_lcd_panel) * WWLCDPanel_GetWidth(ww_lcd_panel);
  283. rectangles = (XRectangle *)malloc(sizeof(XRectangle) * num);
  284. if (rectangles == NULL)
  285. Error("XDisplay_DrawLCDWindow", "Cannot allocate memory.");
  286. ww_lcd_width = WWLCDPanel_GetWidth( ww_lcd_panel);
  287. ww_lcd_height = WWLCDPanel_GetHeight(ww_lcd_panel);
  288. /* ここの処理はホットスポットになるので,のちのちにチューニングすること */
  289. for (pixel = 0; pixel < 16; pixel++) {
  290. n = 0;
  291. for (y = 0; y < ww_lcd_height; y++) {
  292. for (x = 0; x < ww_lcd_width; x++) {
  293. if (pixel == WWLCDPanel_GetPixel(ww_lcd_panel, x, y)) {
  294. px = (x * x_display->width ) / ww_lcd_width;
  295. py = (y * x_display->height) / ww_lcd_height;
  296. rectangles[n].x = px;
  297. rectangles[n].y = py;
  298. rectangles[n].width = (x+1) * x_display->width / ww_lcd_width - px;
  299. rectangles[n].height = (y+1) * x_display->height / ww_lcd_height- py;
  300. n++;
  301. }
  302. }
  303. }
  304. if (n > 0) {
  305. XFillRectangles(x_display->display,
  306. x_display->lcd_pixmap,
  307. x_display->color_gc[pixel],
  308. rectangles, n);
  309. }
  310. }
  311. XCopyArea(x_display->display, x_display->lcd_pixmap,
  312. x_display->lcd_window, x_display->copy_gc,
  313. 0, 0, x_display->width, x_display->height, 0, 0);
  314. XDisplay_Sync(x_display);
  315. free(rectangles);
  316. return (0);
  317. }
  318. /*****************************************************************************/
  319. /* ここまで */
  320. /*****************************************************************************/
  321. /*****************************************************************************/
  322. /* End of File. */
  323. /*****************************************************************************/