2022/06/04(土) [n年前の日記]
#1 [xlib] Xlibについて勉強中その3
_昨日、
Pixmapを拡大縮小する関数を書いて実験していたけれど、本当に毎フレーム拡大縮小処理ができているのかが気になってきたので、見た目で分かるように処理を書き換えてみた。
環境は、Ubuntu Linux 20.04 LTS。Windows10 x64 21H2 + VMware Player 上で動かしている。
結果はこんな感じに。それなりの速度で拡大縮小できていることが視覚的にも分かった。
環境は、Ubuntu Linux 20.04 LTS。Windows10 x64 21H2 + VMware Player 上で動かしている。
結果はこんな感じに。それなりの速度で拡大縮小できていることが視覚的にも分かった。
◎ ソース。 :
ソースは以下。
_06scale3.c
使用画像は以下。
_bg01.xpm
_bg02.xpm
Makefileの例。
_Makefile
コンパイルは以下。実行バイナリ 06scale3 が生成される。
実行は以下。
_06scale3.c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <X11/Xlib.h> #include <X11/xpm.h> #include <math.h> #include <time.h> /* include xpm binary */ #include "bg01.xpm" #define XPM_W 640 #define XPM_H 360 #define XPM_NAME bg01_xpm /* #include "bg02.xpm" #define XPM_W 320 #define XPM_H 180 #define XPM_NAME bg02_xpm */ /* kind. 0: slow, 1: fast */ #define SCALING_KIND 1 #define WIN_X 0 #define WIN_Y 64 #define BORDER 0 #ifndef M_PI #define M_PI 3.14159265358979 #endif #define deg2rad(x) (x * M_PI / 180.0) /* get a color value from a color name */ static unsigned long get_color(Display *dpy, char *colorname) { Colormap cmap; XColor near_color, true_color; cmap = DefaultColormap(dpy, DefaultScreen(dpy)); XAllocNamedColor(dpy, cmap, colorname, &near_color, &true_color); return near_color.pixel; } /* scale Pixmap */ static void scale_pixmap(Display *dpy, Drawable win, Pixmap *src, Pixmap *dst, int src_w, int src_h, int dst_w, int dst_h) { GC gc; float xscale, yscale; int x, y; struct timespec start, end; double diff; xscale = (float)src_w / dst_w; yscale = (float)src_h / dst_h; gc = XCreateGC(dpy, win, 0, 0); XSetGraphicsExposures(dpy, gc, False); timespec_get(&start, TIME_UTC); switch (SCALING_KIND) { case 0: /* slow */ for (y = 0; y < dst_h; y++) { int sy = (int)(y * yscale); for (x = 0; x < dst_w; x++) XCopyArea(dpy, *src, *dst, gc, (int)(x * xscale), sy, 1, 1, x, y); } break; case 1: /* fast */ for (x = dst_w - 1; x >= 0; x--) XCopyArea(dpy, *src, *dst, gc, (int)(x * xscale), 0, 1, src_h, x, 0); if (src_h <= dst_h) { for (y = dst_h - 1; y >= 0; y--) XCopyArea(dpy, *dst, *dst, gc, 0, (int)(y * yscale), dst_w, 1, 0, y); } else { for (y = 0; y < dst_h; y++) XCopyArea(dpy, *dst, *dst, gc, 0, (int)(y * yscale), dst_w, 1, 0, y); } break; default: break; } XFreeGC(dpy, gc); timespec_get(&end, TIME_UTC); diff = (end.tv_sec + (double)end.tv_nsec / 1000000000) - (start.tv_sec + (double)start.tv_nsec / 1000000000); printf("%lf sec\n", diff); } /* update and draw */ static void update(Display *dpy, Drawable win, GC gc, Pixmap pix, Pixmap buf, int new_w, int new_h) { XWindowAttributes xgwa; int r, x, y; int scrw, scrh; /* get window attributes */ XGetWindowAttributes(dpy, win, &xgwa); scrw = xgwa.width; /* window width */ scrh = xgwa.height; /* window height */ scale_pixmap(dpy, win, &pix, &buf, XPM_W, XPM_H, new_w, new_h); /* centering */ x = scrw - ((scrw + new_w) / 2); y = scrh - ((scrh + new_h) / 2); /* clear window */ XClearWindow(dpy, win); /* draw image (Pixmap) */ XSetGraphicsExposures(dpy, gc, False); XCopyArea(dpy, buf, win, gc, 0, 0, new_w, new_h, x, y); } int main(void) { Display *dpy; Window root; Window win; int screen; int display_w, display_h; XEvent evt; unsigned long black, white; XWindowAttributes xgwa; GC gc; Pixmap pix; Pixmap buf; int busy_loop; double new_w, new_h; double dx; /* open display */ dpy = XOpenDisplay(NULL); root = DefaultRootWindow(dpy); screen = DefaultScreen(dpy); /* get display size */ display_w = DisplayWidth(dpy, screen); display_h = DisplayHeight(dpy, screen); printf("Screen: %d x %d\n", display_w, display_h); /* get color black and white */ white = WhitePixel(dpy, screen); black = BlackPixel(dpy, screen); /* create window */ win = XCreateSimpleWindow(dpy, root, WIN_X, WIN_Y, display_w, display_h, BORDER, white, black); XSelectInput(dpy, win, KeyPressMask | ExposureMask); XMapWindow(dpy, win); /* wait display window */ do { XNextEvent(dpy, &evt); } while (evt.type != Expose); XMoveWindow(dpy, win, WIN_X, WIN_Y); /* create graphics context */ gc = XCreateGC(dpy, win, 0, 0); XSetGraphicsExposures(dpy, gc, False); /* load image */ if (XpmCreatePixmapFromData(dpy, win, XPM_NAME, &pix, NULL, NULL)) { fprintf(stderr, "Error not load xpm."); return 1; } XSetForeground(dpy, gc, get_color(dpy, "green")); XGetWindowAttributes(dpy, win, &xgwa); buf = XCreatePixmap(dpy, win, display_w, display_h, xgwa.depth); XFillRectangle(dpy, buf, gc, 0, 0, display_w, display_h); new_w = display_w; new_h = display_h; dx = -6; busy_loop = 1; while (busy_loop) { /* event */ while (XPending(dpy)) { XNextEvent(dpy, &evt); switch (evt.type) { /* case Expose: if (evt.xexpose.count == 0) { } break; */ case KeyPress: busy_loop = 0; break; default: break; } } update(dpy, win, gc, pix, buf, new_w, new_h); new_w += dx; if (new_w <= 32) { new_w = 32; dx *= -1; } if (new_w >= display_w) { new_w = display_w; dx *= -1; } new_h = display_h * new_w / display_w; XFlush(dpy); usleep(16 * 1000); /* wait */ } XFreePixmap(dpy, pix); XFreePixmap(dpy, buf); XFreeGC(dpy, gc); XDestroyWindow(dpy, win); XCloseDisplay(dpy); return 0; }
使用画像は以下。
_bg01.xpm
_bg02.xpm
Makefileの例。
_Makefile
コンパイルは以下。実行バイナリ 06scale3 が生成される。
gcc 06scale3.c -o 06scale3 -I /usr/include/X11 -lX11 -lXext -lm -lXpm
実行は以下。
./06scale3
◎ バグを見つけた。 :
_昨日、
書いた処理は、少しバグがあった。元画像より小さい縦サイズに縮小しようとすると、見た目がおかしなことになってしまう。
以下の処理では、(縦方向の)拡大はともかく、縮小はおかしなことになる。参照される部分を上書きコピーで破壊してしまう。
_05scale2.c
以下のように修正。拡大時と縮小時で処理を分けて、拡大時は下から上に向かってスキャン、縮小時は上から下に向かってスキャンしていけばおかしなことにはならない。
以下の処理では、(縦方向の)拡大はともかく、縮小はおかしなことになる。参照される部分を上書きコピーで破壊してしまう。
_05scale2.c
/* fast */ for (x = dst_w - 1; x >= 0; x--) XCopyArea(dpy, *src, *dst, gc, (int)(x * xscale), 0, 1, src_h, x, 0); for (y = dst_h - 1; y >= 0; y--) XCopyArea(dpy, *dst, *dst, gc, 0, (int)(y * yscale), dst_w, 1, 0, y);
以下のように修正。拡大時と縮小時で処理を分けて、拡大時は下から上に向かってスキャン、縮小時は上から下に向かってスキャンしていけばおかしなことにはならない。
/* fast */ for (x = dst_w - 1; x >= 0; x--) XCopyArea(dpy, *src, *dst, gc, (int)(x * xscale), 0, 1, src_h, x, 0); if (src_h <= dst_h) { for (y = dst_h - 1; y >= 0; y--) XCopyArea(dpy, *dst, *dst, gc, 0, (int)(y * yscale), dst_w, 1, 0, y); } else { for (y = 0; y < dst_h; y++) XCopyArea(dpy, *dst, *dst, gc, 0, (int)(y * yscale), dst_w, 1, 0, y); }
[ ツッコむ ]
#2 [nitijyou] 自転車でパソコン工房まで行ってきた
天気予報では、今日は雨が降らないとのことだったので、電動自転車に乗ってパソコン工房郡山店まで行ってきた。
新しい電動自転車を購入する際、郡山まで行ける程度のバッテリー容量が欲しいと要望を出したのだけど、その願いは叶ったのかどうかを一度確認してみたかった。ちなみに以前の電動自転車は、帰り道でバッテリーが切れて、しかも前輪駆動だったから、バッテリーが切れると鬼のようにペダルが重くなって地獄だった…。
一応、時間や、走った道をメモ。
09:46-10:42 (55分) : 家からパソコン工房まで、旧・旧国道沿い(須賀川-二本松線、県道355号)を移動。バッテリー残り90%の状態で出発。行きは、Autoモードで ―― アシストが弱いけれどバッテリーの持ちはそこそこらしいモードを利用。パソコン工房郡山店に着いた時点で残り80%。たった10%のバッテリー容量で移動できてしまって驚いた。以前の電動自転車とは違うな…。
ヨドバシカメラ郡山店に寄って、そこから帰ろうとした時点で、残り70%になった。
12:32-13:20 (47分) : ヨドバシカメラから安積永盛のHARD-OFFまで、旧・国道4号線(県道17号線、郡山の街中を通っている道路)を移動。店についてからタイマーを止めるのを忘れてたので、実際はもっと短いはず。
13:27-14:04 (36分) : HARD-OFFから家まで、現・国道4号線(バイパス)を移動。ここからはパワーモードで移動。家に到着した時点で残り60%。
つまり、行きは55分、帰りは83分かかった。ただ、帰りは、他の店に寄った上に、車向けの道を ―― 登ったり下りたりが頻繁にある道を選んで走ってきたので、単純に比較できない。
何にせよ、新しい電動自転車の、今現在のバッテリーの状態なら、バッテリーの1/3程度の容量で、郡山まで行って帰ってくることができると分かった。
ただ、体のほうが全然持たない。右膝が痛い…。行きの時点で、安積永盛のあたりで膝に違和感が…。バッテリーはともかく、自分の体の状態からして、気軽に行けるわけではないなと…。
新しい電動自転車を購入する際、郡山まで行ける程度のバッテリー容量が欲しいと要望を出したのだけど、その願いは叶ったのかどうかを一度確認してみたかった。ちなみに以前の電動自転車は、帰り道でバッテリーが切れて、しかも前輪駆動だったから、バッテリーが切れると鬼のようにペダルが重くなって地獄だった…。
一応、時間や、走った道をメモ。
09:46-10:42 (55分) : 家からパソコン工房まで、旧・旧国道沿い(須賀川-二本松線、県道355号)を移動。バッテリー残り90%の状態で出発。行きは、Autoモードで ―― アシストが弱いけれどバッテリーの持ちはそこそこらしいモードを利用。パソコン工房郡山店に着いた時点で残り80%。たった10%のバッテリー容量で移動できてしまって驚いた。以前の電動自転車とは違うな…。
ヨドバシカメラ郡山店に寄って、そこから帰ろうとした時点で、残り70%になった。
12:32-13:20 (47分) : ヨドバシカメラから安積永盛のHARD-OFFまで、旧・国道4号線(県道17号線、郡山の街中を通っている道路)を移動。店についてからタイマーを止めるのを忘れてたので、実際はもっと短いはず。
13:27-14:04 (36分) : HARD-OFFから家まで、現・国道4号線(バイパス)を移動。ここからはパワーモードで移動。家に到着した時点で残り60%。
つまり、行きは55分、帰りは83分かかった。ただ、帰りは、他の店に寄った上に、車向けの道を ―― 登ったり下りたりが頻繁にある道を選んで走ってきたので、単純に比較できない。
何にせよ、新しい電動自転車の、今現在のバッテリーの状態なら、バッテリーの1/3程度の容量で、郡山まで行って帰ってくることができると分かった。
ただ、体のほうが全然持たない。右膝が痛い…。行きの時点で、安積永盛のあたりで膝に違和感が…。バッテリーはともかく、自分の体の状態からして、気軽に行けるわけではないなと…。
◎ 余談。 :
帰りにHARD-OFFに寄ったけれど、相変わらずヨサゲなPCケースが見当たらなくて残念。通販なら新品でも、一番安いミニタワーPCケースなら3,000円ぐらいで買えるけど。見た目が傷だらけで、今となっては巨大に感じるミドルタワーATXケースで、フロントベイカバーがポツポツ無くなっている中古のケースが3,300円とか5,500円では…。なかなか厳しい。
[ ツッコむ ]
#3 [pc] パソコン工房の買取サービスを利用してみた
パソコン工房郡山店の店頭で、買取サービスを初めて利用してみた。一応、流れをメモ。
今回持ち込んだ品は以下の3点。
レジの前で「こちらの店舗で買取サービスはしてますか?」と尋ねたところ、店員さんが買取用カウンターに誘導してくれた。担当者が不在だったけれど、用紙を渡されて記入。名前、生年月日、住所、電話番号、職業、を書いた気がする。
10:47頃に受け付け。「査定に1時間ほどかかる」と言われた。「11:47〜」とメモされた、申し込み用紙の控えを渡された。
店内をウロウロしたり、隣のダイソーで買い物を済ませたりして時間を潰した。
11:47頃、買取サービス用カウンターの前に行った。今度は担当者が居たようで、査定内容が印刷された用紙を見せられつつ、査定額を伝えられた。それでいいですと答えたら、担当の方がそこから5分ほどPCに何かを入力。その後、譲渡証明書の控えと、現金を受け取った。
買取金額は以下。
今回持ち込んだ品は以下の3点。
- CPU AMD Ryzen 7 1700 BOX
- CPU AMD Ryzen 3 2200G BOX
- DDR4-2400メモリ 8GB x 2枚。パッケージ付き
レジの前で「こちらの店舗で買取サービスはしてますか?」と尋ねたところ、店員さんが買取用カウンターに誘導してくれた。担当者が不在だったけれど、用紙を渡されて記入。名前、生年月日、住所、電話番号、職業、を書いた気がする。
10:47頃に受け付け。「査定に1時間ほどかかる」と言われた。「11:47〜」とメモされた、申し込み用紙の控えを渡された。
店内をウロウロしたり、隣のダイソーで買い物を済ませたりして時間を潰した。
11:47頃、買取サービス用カウンターの前に行った。今度は担当者が居たようで、査定内容が印刷された用紙を見せられつつ、査定額を伝えられた。それでいいですと答えたら、担当の方がそこから5分ほどPCに何かを入力。その後、譲渡証明書の控えと、現金を受け取った。
買取金額は以下。
- Ryzen 7 1700 BOX : 7,700円
- Ryzen 3 2200G BOX : 6,600円
- DDR4-2400 8GBx2メモリ : 1,870円
- 合計 16,170円
◎ 余談。 :
相場より高いのか、それとも安いのか、そのあたりはよく分からない…。譲渡証明書の控えに査定内容が書いてあるのだけど、読み方が分からなくて…。Ryzen 3 2200G が特に分からない。買取基準金額と買取査定額が1,000円と書かれてるけど、最後の品目名で6,600円になってる。最初に1,000円の記述が目に入って、「え。そんなに低いの」と驚いてしまったけど、そういうわけではなかったらしい。
質問したかったけれど、後ろに他の買取客が並んでたので、迷惑になったらいかんよなと、質問しないまま店を出た。ただ、ちょっともやもやする…。自分はちゃんと奇麗な状態で持ち込めたのか、そうでもなかったのか等々、一言二言でいいから聞いておきたかったなと…。
譲渡証明書には「Sofmap U-FRONT」と書かれてた。パソコン工房の実店舗で買取してるけど、パソコン工房が買取してるわけではないということだろうか。パソコン工房の買取なら、土日祝日は買取価格上乗せ云々とサイトに書いてあったけど、郡山店ではSofmapの買取サービスを提供してるからそういうオマケは無し、ということかもしれない。
持ち込む前は、やれここが汚れてるだのなんだの言われて、下手すると全部合わせても3千円にすらならないのではと結構不安だったけど。パソコン工房やドスパラのサイトで確認した際の額と大体似たような結果になってホッとした。わざわざIPAやキムワイプを新規購入して掃除した甲斐はあった…のかどうかそのあたり結局何も分からないままだけど、まあ、結果には満足。
もっとも、この額では現行CPUの最低ランク品すら購入できないわけで、以前、弟が、「PCパーツを買取サービスに持ち込むぐらいなら欲しい人にタダでプレゼントしたほうがマシ」と言った感覚も、なんだかちょっと分かったような気もする。
とは言え今回、M/Bさえあれば手元に残してサブPC用として使っただろうけど、空いてる Socket AM4対応M/Bは無く、このままだとCPUもメモリも使われないまま埃を被ってしまうので、だったら別の誰かの手に渡ったほうが、と思った次第。
質問したかったけれど、後ろに他の買取客が並んでたので、迷惑になったらいかんよなと、質問しないまま店を出た。ただ、ちょっともやもやする…。自分はちゃんと奇麗な状態で持ち込めたのか、そうでもなかったのか等々、一言二言でいいから聞いておきたかったなと…。
譲渡証明書には「Sofmap U-FRONT」と書かれてた。パソコン工房の実店舗で買取してるけど、パソコン工房が買取してるわけではないということだろうか。パソコン工房の買取なら、土日祝日は買取価格上乗せ云々とサイトに書いてあったけど、郡山店ではSofmapの買取サービスを提供してるからそういうオマケは無し、ということかもしれない。
持ち込む前は、やれここが汚れてるだのなんだの言われて、下手すると全部合わせても3千円にすらならないのではと結構不安だったけど。パソコン工房やドスパラのサイトで確認した際の額と大体似たような結果になってホッとした。わざわざIPAやキムワイプを新規購入して掃除した甲斐はあった…のかどうかそのあたり結局何も分からないままだけど、まあ、結果には満足。
もっとも、この額では現行CPUの最低ランク品すら購入できないわけで、以前、弟が、「PCパーツを買取サービスに持ち込むぐらいなら欲しい人にタダでプレゼントしたほうがマシ」と言った感覚も、なんだかちょっと分かったような気もする。
とは言え今回、M/Bさえあれば手元に残してサブPC用として使っただろうけど、空いてる Socket AM4対応M/Bは無く、このままだとCPUもメモリも使われないまま埃を被ってしまうので、だったら別の誰かの手に渡ったほうが、と思った次第。
[ ツッコむ ]
#4 [pc] USB2.0ハブを購入
ヨドバシカメラ郡山店でUSB2.0ハブを購入。
_4ポートUSB2.0ハブ ホワイト | ナカバヤシ株式会社
値札は\485-だったのだけど、レジに持っていったら580円と言われて困惑。さては税抜き価格の値札だったかと、その場では思いながらそのまま帰ってきてしまったけれど、帰宅後、ヨドバシのサイトで確認したら580円だった。この値段で正しいらしい。もしかすると値札が古いままだったのかもしれない。店頭で購入するとこういうことがあるのだな。今後は極力、店頭では買わないようにしようか…。もっとも、初期不良品に当たった時のことを考えたら、件の店舗は距離的に遠いので、そもそもそこで買うのはマズかった気もする。今回ちょっと考え無しだったかも。
メインPCの背面に差して、キーボードとプリンタを接続して動作確認したが、どちらも問題無く動いてくれた。これで、現在使用しているM/B、GIGABYTE B450M S2H rev.1.0 の、USB2.0ポートが不足している問題は解決できそう。
ただ、USB2.0ハブごと抜けて動作がおかしくなる可能性はあるなと。キーボードやプリンタの動作がおかしくなったらUSBハブの差し込み具合を確認のこと>未来の自分。まあ、そのうち絶対忘れてドタバタしそうだな…。
- ナカバヤシ株式会社 Digio2 UH-2354W (USB2.0対応、4port、バスパワー、ケーブル長10cm、W15 x D93 x H13mm, 20g)。580円。
_4ポートUSB2.0ハブ ホワイト | ナカバヤシ株式会社
値札は\485-だったのだけど、レジに持っていったら580円と言われて困惑。さては税抜き価格の値札だったかと、その場では思いながらそのまま帰ってきてしまったけれど、帰宅後、ヨドバシのサイトで確認したら580円だった。この値段で正しいらしい。もしかすると値札が古いままだったのかもしれない。店頭で購入するとこういうことがあるのだな。今後は極力、店頭では買わないようにしようか…。もっとも、初期不良品に当たった時のことを考えたら、件の店舗は距離的に遠いので、そもそもそこで買うのはマズかった気もする。今回ちょっと考え無しだったかも。
メインPCの背面に差して、キーボードとプリンタを接続して動作確認したが、どちらも問題無く動いてくれた。これで、現在使用しているM/B、GIGABYTE B450M S2H rev.1.0 の、USB2.0ポートが不足している問題は解決できそう。
ただ、USB2.0ハブごと抜けて動作がおかしくなる可能性はあるなと。キーボードやプリンタの動作がおかしくなったらUSBハブの差し込み具合を確認のこと>未来の自分。まあ、そのうち絶対忘れてドタバタしそうだな…。
[ ツッコむ ]
以上、1 日分です。