From adcec20bb8e26b7b77352d8448f4dc2d08416a0f Mon Sep 17 00:00:00 2001 From: Morgan Aldridge Date: Sat, 4 Apr 2015 19:54:38 -0400 Subject: [PATCH] Imported mlvwm 0.8.9 release --- CHANGELOG | 77 ++ CHANGELOG.jp | 376 +++++++ CONFIGURATION | 320 ++++++ CONFIGURATION.jp | 234 +++++ FAQ.jp | 20 + Imakefile | 9 + README | 57 ++ README.jp | 56 ++ bitmap/label1 | 6 + bitmap/label2 | 6 + bitmap/label3 | 8 + configure.h | 80 ++ man/mlvwm.1 | 316 ++++++ mlvwm/.depend | 113 +++ mlvwm/Imakefile | 31 + mlvwm/Makefile.make | 17 + mlvwm/add_window.c | 666 ++++++++++++ mlvwm/add_window.h | 20 + mlvwm/balloon.c | 365 +++++++ mlvwm/balloon.h | 12 + mlvwm/borders.c | 1057 +++++++++++++++++++ mlvwm/borders.h | 32 + mlvwm/config.c | 795 +++++++++++++++ mlvwm/config.h | 50 + mlvwm/event.c | 1949 ++++++++++++++++++++++++++++++++++++ mlvwm/event.h | 37 + mlvwm/functions.c | 879 ++++++++++++++++ mlvwm/functions.h | 29 + mlvwm/menus.c | 1593 +++++++++++++++++++++++++++++ mlvwm/menus.h | 129 +++ mlvwm/misc.c | 298 ++++++ mlvwm/misc.h | 33 + mlvwm/mlvwm.c | 699 +++++++++++++ mlvwm/mlvwm.h | 186 ++++ mlvwm/screen.h | 160 +++ mlvwm/sun_headers.h | 42 + mlvwm/wild.c | 75 ++ pixmap/MailEmpty.xpm | 33 + pixmap/MailFull.xpm | 34 + pixmap/disk.xpm | 47 + pixmap/label1.xpm | 25 + pixmap/label2.xpm | 26 + pixmap/label3.xpm | 26 + pixmap/pix_test.c | 63 ++ sample_rc/Imakefile | 18 + sample_rc/Mlvwmrc | 209 ++++ sample_rc/Mlvwmrc-Kterm-j | 15 + sample_rc/Mlvwmrc-Netscape | 110 ++ sample_rc/Mlvwmrc-Xterm | 16 + sample_rc/Mlvwmrc-j | 204 ++++ 50 files changed, 11658 insertions(+) create mode 100644 CHANGELOG create mode 100644 CHANGELOG.jp create mode 100644 CONFIGURATION create mode 100644 CONFIGURATION.jp create mode 100644 FAQ.jp create mode 100644 Imakefile create mode 100644 README create mode 100644 README.jp create mode 100644 bitmap/label1 create mode 100644 bitmap/label2 create mode 100644 bitmap/label3 create mode 100644 configure.h create mode 100644 man/mlvwm.1 create mode 100644 mlvwm/.depend create mode 100644 mlvwm/Imakefile create mode 100644 mlvwm/Makefile.make create mode 100644 mlvwm/add_window.c create mode 100644 mlvwm/add_window.h create mode 100644 mlvwm/balloon.c create mode 100644 mlvwm/balloon.h create mode 100644 mlvwm/borders.c create mode 100644 mlvwm/borders.h create mode 100644 mlvwm/config.c create mode 100644 mlvwm/config.h create mode 100644 mlvwm/event.c create mode 100644 mlvwm/event.h create mode 100644 mlvwm/functions.c create mode 100644 mlvwm/functions.h create mode 100644 mlvwm/menus.c create mode 100644 mlvwm/menus.h create mode 100644 mlvwm/misc.c create mode 100644 mlvwm/misc.h create mode 100644 mlvwm/mlvwm.c create mode 100644 mlvwm/mlvwm.h create mode 100644 mlvwm/screen.h create mode 100644 mlvwm/sun_headers.h create mode 100644 mlvwm/wild.c create mode 100644 pixmap/MailEmpty.xpm create mode 100644 pixmap/MailFull.xpm create mode 100644 pixmap/disk.xpm create mode 100644 pixmap/label1.xpm create mode 100644 pixmap/label2.xpm create mode 100644 pixmap/label3.xpm create mode 100644 pixmap/pix_test.c create mode 100644 sample_rc/Imakefile create mode 100644 sample_rc/Mlvwmrc create mode 100644 sample_rc/Mlvwmrc-Kterm-j create mode 100644 sample_rc/Mlvwmrc-Netscape create mode 100644 sample_rc/Mlvwmrc-Xterm create mode 100644 sample_rc/Mlvwmrc-j diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..a1361b7 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,77 @@ +0.8.8 -> 0.8.9 +Change scroll bar expose function and befavior +Add one click menu(OneClickMenu) + +0.8.7p1 -> 0.8.8 +Add OpaqueMove +Add OpaqueResize +Change configuration code +Add ZoomWait configuration +Change FlushMenu interval unit us to ms. +Change color of scrollbar anker and function. +Change transient window mappting position. + +0.8.7 -> 0.8.7 +Fix memory leak + +0.8.6 -> 0.8.7 +Some changes to use 64bit CPU. +Fix bugs to display window. +Some modification. +Add UseRootWin configuration. + +0.8.5 -> 0.8.6 +Add function MaxmizeScale to set WidethxHeight. +Fix calcurate font height at HasLocale NO. +Add RotateDesk. +The bug is fixed that the help balloon don't display at SunOS. + +0.8.4 -> 0.8.5 +The bug is fixed that sort window list name. +The bug is fixed that when the active window is changed form stickey +window. +The bug is fixed that when the desktop is changed, active window is not +selected with FollowToMouse and SloppyFocus. +Stop the animation at Show Window. +Fix HandleClientMessage bug. +The cursors have been reassigned to better match the current state or +functionality. +Change BalloonHelp Window to transparent(shape) window. +Change the menu display method. +Add function MaxmizeScale to set WidethxHeight. +Fix calcurate font height at HasLocale NO. + +0.8.3 -> 0.8.4 +The bug is fixed that when the active window is changed form stickey +window, the active window is mapped under other window. +The cursors have been reassigned to better match the current state or +functionality. +Add built-in function `ShowBalloon'. +When a window is hidden or unhidden, its outline is zoomed from the +icon menu to the window position or vice versa. +The black flash has been removed from RefreshScreen. It now looks much +smoother. +Left and right corners have been added to provided a rounded screen +bottom as well. +The entries in the icon menu get sorted alphabetically. +Change cursor shape at starting. +Add configuration `RestartPreviousState'. + +0.8.2 -> 0.8.3 +The bug is fixed that the window list problem with display desktop +number. + +0.8.1 -> 0.8.2 +The bug is fixed that the replacement of window on non current desktop +is valid at restart time. +The bug is fixed that the replacement of windows at restart time. +Fix display outline at resize with System8 configuration. +Add `DisplayDeskNumber' that means display desktop number on window +list. +Modify sample configuration file. + +0.8.0 -> 0.8.1 +The bug is fixed that the display of menu bar is incorrect at start +time with `System8' configuration. +The bug is fixed that Select{Prev,Next}Window select the window that +is not mapped on the desktop. diff --git a/CHANGELOG.jp b/CHANGELOG.jp new file mode 100644 index 0000000..5a4ee4d --- /dev/null +++ b/CHANGELOG.jp @@ -0,0 +1,376 @@ +0.8.8 -> 0.8.9 +スクロールバーの書換えと移動関数を変更 +OneClickMenu を追加 + +0.8.7p1 -> 0.8.8 +OpaqueMove を追加 +OpaqueResize を追加 +ZoomWait 設定を追加 +設定ファイルの読み込みを変更 +FlushMenu の点滅間隔設定単位を変更 +スクロールバーの動作とアンカーの色を変更 +トランシエントウインドウのマップ方法を変更 + +0.8.7 -> 0.8.7p1 +メモリリークを修正 + +0.8.6 -> 0.8.7 +64bit CPUに対応。 +ウインドウの表示のずれを修正。 +いくつかの修正。 +UseRootWinを追加。 + +0.8.5 -> 0.8.6 +MaxmizeScale を (Width)x(Height) での指定も可能に変更。 +HasLocale NO の時のフォントの高さの計算を修正。 +RotateDesk を追加。 +SunOSでバルーンヘルプが表示できないバグを修正。 + +0.8.4 -> 0.8.5 +ウインドウリストのソートのバグを修正。 +Sticky なウインドウからアクティブウインドウを切替えた時のバグを修正。 +FollowToMouse, SloppyFocusの時、デスクトップの切替で、アクティブウイン +ドウが選択されないバグを修正。 +Show Window のアニメーションを中止。 +HandleClientMessage の修正。 +カーソルフォントの変更。 +バルーンヘルプのウインドウを ShapeWindow に変更。 +メニューの表示を一部変更。 + +0.8.3 -> 0.8.4 +Stickey なウインドウからアクティブなウインドウを切替えると、アクティブ +なのに一番上に表示されないバグを修正。 +カーソルフォントの変更。 +内部関数 ShowBalloon を追加。 +Hide Window, Show Window で、アニメーションを追加。 +リフレッシュスクリーンを変更。 +ルートウインドウの下に丸みを持たせた。 +ウインドウリストをソートして表示。 +スタート時のカーソルを変更。 +設定にRestartPreviousStateを追加。 + +0.8.2 -> 0.8.3 +ウインドウリストにデスク番号を表示させている時の不具合を修正。 + +0.8.1 -> 0.8.2 +カレントじゃないデスクトップの配置がリスタートで壊れるバグを修正。 +System8 でリサイズの時に表示される線が異なるのを修正。 +DisplayDeskNumber 設定でウインドウリストのウインドウ名にデスク番号を表示。 +サンプル設定ファイルの修正 + +0.8.0 -> 0.8.1 +System8 を指定した時、起動時にメニューバーの表示がおかしいバグを修正 +存在しないウインドウが存在するバグを修正 + +0.7.2-Beta2 -> 0.8.0 +トランシエントウインドウに対する Hide の扱いを変更。 +モノクロディスプレイでリサイズの線がでなことがあるのを修正。 +ビットマップアイコンで、アイコンがグレイにならないのを修正。 +メニューのちらつきを減少。 +いくつかのバグフィックス。 +System8 に似たデコレーションを作成。 +Icon を読む順番を一部変更(Icon が見つからない時にエラーがでないことがある)。 + +0.7.2-Beta -> 0.7.2-Beta2 +バルーンヘルプのバグを修正。 +モノクロディスプレイで、アクティブでないウインドウのタイトルがでないバ +グを修正。 +モノクロディスプレイで PIXMAP のマスクに失敗するバグを修正。 +InitFunction, RestartFunction を追加。 +アクティブウインドウが下になるバグを修正。 +-xrm を用いて任意のデスクトップにアプリケーションを開ける。指定したデ +スクトップがカレントデスクトップと異なる場合フォーカスは移動しません。 +(Request from Shin HASEGAWA) +ウインドウの配置法を変更。 +スクロールバーの幅を負に指定すると表示がおかしくなるバグを修正。 +内部関数 Wait を追加。 +StayOnTop のバグを修正。 + +0.7.1 -> 0.7.2-Beta +アクティブウインドウがない時に HideActive を行なうと落ちるバグを修正。 +ResizeWindow の内部関数のバグを修正。 +ビットマップを使えるように修正。 +モノクロディスプレイに対応。 + +0.7.0 -> 0.7.1 +設定ファイルがない時に作られるメニューが選択できないバグを修正。 +MkLinux で Make に失敗するバグを修正。 +デスクトップの移動をした時、に最後にアクティブだったウインドウがアンマッ +プされていると落ちるバグを修正。 +SickShade の設定をしていない時に ChangeDesk がおかしいバグを修正。 +ShadeMap されていない時に ChangeDesk で Shade したウインドウが Unshade +してしまうバグを修正。 +一時ウインドウのデコレーションを変更。 +いくつかのバグフィックス。 +コンパチブルモードの切り換えを rc ファイルでできるように変更。 +スクロールバーが細い時にタイトルバーの表示がおかしいバグを修正。 +ShowAll ファンクションの修正。 +バルーンヘルプによるウインドウ情報の表示機能を追加。 +メニューバーの右端が欠けているのを修正。 + +0.6.3 -> 0.7.0 +背景が透明でないアイコンをメニューバーに使うとリスタートに失敗する +バグを修正。 +ウインドウのプロパティがとれなくなるものがあるバグを修正。 +ウインドウの上下関係のつみ方のバグを修正。 +マウスクリック関係のバグを修正? +サブメニューを指定できるようにした。 +SendMessage の送信文字列の指定方法の拡張。 +ButtonPress関連のバグフィックス。 +IconifyShade, IconifyHide 機能の追加。 + +0.6.2 -> 0.6.3 +NetBSD/sparc でコンパイルがうまくいかないのを修正。 +SGI Irix でコンパイルの Warning がでないように修正。 +SGI Irix でリスタートで Seg.Fault のバグを修正。 +チェックマークの表示方法を変更。 +メニューバー、メニュー、タイトルバーのフォントを設定可能にした。 +設定ファイルの中から別の設定ファイルを読めるように変更。 +アプリケーションに KeyPress のイベントを送る機能を追加。 +設定ファイルのエラーが多い時の処理を変更。 +アクティブなウインドウがない時に、KeyPress のイベント処理がおかしいバ +グを修正。 +xmascot が正常に動作しないバグを修正。 +netscape で remote が動かないバグを修正。 +Transient なウインドウのスタックの方法を変更。 +Shade したウインドウが終了できないバグを再度修正。 +タイトルデコレーションの修正。 +Shift etc. を押したままクリックするとダブルクリックになるバグを修正。 +メニューまわりの修正。 +アプリケーション毎にメニューを変更できるように修正。 +ウインドウがない時に NextWindow, PreviousWindow を行なうと落ちるのを修正。 +内部関数に NextSameDeskWindow, PreviousSameDeskWindow を追加。 +メニューの表示処理のバグ取り。 +自動翻訳の README を添付 +メニューでのボタンリリースがとれないことがあるバグを修正。 +スクロールバーの幅を可変に変更。 +SloppyFocus を追加。 +Shade しているウインドウをリサイズできないように変更。 +関数 getcontext がシステムコールとして存在する機種があるので名前を変更。 +スクロールバーがない時にもリサイズリュージョンを表示できるように変更。 + +0.6.1 -> 0.6.2 +Style に MaxmizeScale を追加。 +Style に MiniIcon を追加。 +アクティブなアプリケーションに連動してミニアイコンを表示。 +ウインドウリストにアイコンを表示。 +PATH の最後にあるコマンドが実行できないバグを修正。 +FreeBSD で make できないバグを修正。 +StayOnTop が認識されていないのを修正。 +ドキュメント(README.jp)の加筆修正。 +IconMenuIcon で指定するアイコンを "" でくくらないように変更。 +メニューの設定方法の変更。 +Shade したウインドウを Hide して、Map した時に陰が出なくなるのを修正。 +Shade したウインドウを Hide された状態から Map するときに、 Shade した +ままと、 Shade が解除されるのを ConfigFile で指定できるようにした。 +メニューを選択中にウインドウがマップ・アンマップすると落ちるバグを修正。 +Style が反映されないことがあるバグを修正。 +EnableScroll のオプションが処理されないバグを修正。 +FreeBSD で misc.c がうまくコンパイルできないバグを修正。 +FreeBSD 2.2 の Locale にあわせてライブラリを指定。 + +0.6.0 -> 0.6.1 +HideActive での動きを修正。 +ウインドウ名が出ないウインドウがあったのを修正。 +ウインドウ名が長い場合の表示を修正。 +シェイドしているウインドウの中身終了した時にタイトルバーが消えないのを +修正。 +アイコンメニューの内容が壊れることがあるバグを修正。 +リスタートに失敗した時の処理を修正? +Exec の書式を変更。 +メニューに埋め込むアプリケーションがなくてもハングアップをしないように修正。 +Style に * と ? が使用可能。 +Style を複数の行に分けて記述可能。 +Style に NormalDecoration を追加。 +スクロールバーの表示位置の修正。 +設定ファイルを .desktop から .mlvwm に変更(configure.h で変更可能)。 +XFetchName を XGetWMName に変更。 +ウインドウの影の付け方を変更。 +System Configfile をインストールして、それを設定として読み込めるように変更。 +スクロールバーのアンカーの位置の計算の修正。 +その他のバグ修正。 + +0.5.7 -> 0.6.0 +メニューのアイコンが変色しなくなった。 +デコレーションのないウインドウでもフォーカスが自動で入るように変更。 +Style に NoFocus を追加。 +ポップアップウインドウが呼び元のウインドウの上に常に表示する修正がうま +く動かないバグを修正。 +IconPath の指定の追加。 +IconMenuIcon の追加。 +メニューのアイコンを .desktop ファイルで指定するように変更。 +立ち上げ時のピックスマップの表示を中止。 +ディレクトリ構成の一部変更。 +サウンド機能の中止。 +イベントのとりかたを修正。 +アクティブでもウインドウが他のウインドウの下に来るバグを修正。 +スクロールバーが Enable の状態でのリサイズに関するバグを修正。 +Shade したウインドウのクローズができないバグを修正。 +Locale 対応ソースを configure.h で選択可能。 +Imakefile の修正 +細かいバグフィックス。 + +0.5.6 -> 0.5.7 +影を表示する関数を作成。 +ShapeIcon のマスクがずれるバグを修正。 +各種イベント処理の変更。 +Style に Scroll を追加。 +内部関数に ToggleScroll を追加。 +メニューの点滅間隔と点滅回数を指定する変数を追加。 +クローズボックスまわりのソースを変更。 +いくつかの細かいfix。 +Shape のマスクがずれていたのを修正。 +ポップアップウインドウが呼び元のウインドウの上に常に表示するように修正。 +ポップアップウインドウをウインドウリストに追加しないように変更。 + +0.5.5 -> 0.5.6 +アクティブでないウインドウで左ボタン以外を押すとマウスイベントが受け取れな +くなるバグを修正。 +真ん中、右ボタンでもウインドウをアクティブにできるように仕様変更。 +画面の縁に表示するウインドウの位置を修正。 +一時的なポップアップウインドウのデコレーションをアラートデコレーションに変 +更。 +デコレーションのないウインドウをアラートウインドウのデコレーションに変更。 +メニューの非表示と、コマンド実行の順番を変更。 +内部関数に MovwWindow, ResizeWindow, KillWindow を追加。 +FollowToMouse でないとき、立ち上げ時に適当なウインドウをアクティブにしてい +たのを中止。 +デスクトップの変更でアクティブだったウインドウを保存。 +アクティブウインドウのない時の、NextWindow, PreviousWindow の動きを変更。 +立ち上げ時にメニューに表示されるアプリケーション名のフォントがおかしくなる +バグを修正。 +イベント処理の一部変更。 +FollowToMouse でないとき、メニューや内部コマンドでウインドウを選択した時、 +マウスカーソルが移動するのを修正。 +FollowToMouse のとき、メニューや内部コマンドでウインドウを選択した時、マウ +スカーソルの移動する位置を修正。 +一部の長い関数を修正。 + +0.5.4 -> 0.5.5 +内部コマンドに NextWindow, PreviousWindow を追加。 +FollowToMouse でないときに、アクティブでないウインドウを選択すると、マウス +の位置によっては、ウインドウがクローズされるバグを修正。 +下のウインドウのサブウインドウとメインウインドウの上下関係がおかしくなるバ +グを修正。 +設定に StickShade, StickHide を追加。 +Style 設定に Sticky, SkipSelect を追加。 +一部のウインドウで大きさが 1 になるバグを修正。 +ShadeWindow のソースを一部変更。 +内部コマンドに ShadeUnShadeActive を追加。 +リサイズの計算の修正。 +README の修正。 + +0.5.3 -> 0.5.4 +キーボードショートカットの設定で、複数のモディファイアが設定できないバグを +修正。 +0 以外のデスクトップにアプリケーションを開けないバグを修正。 + +0.5.2 -> 0.5.3 +りんごアイコンの変更。 +メニューバーに biff を使うためのピックスマップを付属。 +Swallow 周辺のソースを変更。 +立ち上げのピックスマップの表示回りのソースを変更。 +メモリリークしている部分の修正。 +ディレクトリ構成を変更。 +立ち上げ画面の修正。 +Solaris 2 で & をつけるとアップルメニューからアプリケーションが起動できな +いバグを修正。 +Solaris 2 でリスタートできないことがあるバグを修正。 +Solaris 2 でアップルメニューからスターとしたアプリケーションの終了ができな +いバグを修正。 +Desktop Num が 1 の時、エラーになるバグを修正。 +xview で作成されたウインドウがマップされる時の位置がおかしいバグを修正。 + +0.5.1 -> 0.5.2 +アイコンの形を一部変更。 +0.5.0 -> 0.5.1 で使えなくなった Hide Active を使えるように修正。 +下のウインドウのサブウインドウとメインウインドウの上下関係がおかしくなるバ +グを修正。 +-debug オプションの内容を充実。 +Imakefile の修正 +メニューバーに埋め込むアプリケーションの高さを 25 ポイントから 23 ポイント +に変更。 +メニューバーに埋め込まれたアプリケーションの左右に適当なスペースを空けるよ +う変更。 +メニューバーにアプリケーションを埋め込む方法を変更。 + +0.5.0 -> 0.5.1 +立ち上げの時にちょっとした洒落を追加。 +メモリリークしている部分を修正。 + +0.4.1 -> 0.5.0 +FollowToMouse でないときに、アプリケーションウインドウの左クリックで、画面 +がアクティブになるように修正。 +内蔵コマンド Desk の修正。 +右寄メニューの指定方法の追加。 +イベント関係のソースの修正。 +キーボードショートカットの追加。 +メニューバーにアプリケーションを埋め込む機能を追加。 +ウインドウの配置方法に修正。 +オプションの追加。 +ウインドウの移動、リサイズの高速化。 +ダブルクリックタイムを .desktop ファイルで設定可能に変更。 +ウインドウの名前がアクティブに変わるのに、タイトルバーとウインドウリストを +対応。 +ReapChildren を SYSV に対応。 +FollowToMouse でないときにルートウインドウのクリックでアクティブウインドウ +がアクティブでなくなるように変更。 +バーチャルスクリーンからバーチャルデスクトップに変更。 +Hide Active, Hide Others, Show All をアイコンメニューに追加。 +FollowToMouse でないときにアクティブウインドウのクローズで別のウインドウが +アクティブになるように変更。 + +0.4.0 -> 0.4.1 +ウインドウスタイルに StayOnTop を追加。 +エラーハンドラの強化。 +ネットスケープで起きるエラーに対処。 +ウインドウの移動・リサイズのスピードアップ ? +メニュー表示ルーチンの修正。 +クローズボックスまわりのソースを変更。 + +0.3.1 -> 0.4.0 +ウインドウのマップの方法の変更。 +xarchie の終了と共にウインドウマネージャが終了するバグを修正。 +内蔵WindowShadeの搭載 +Netscape のブックマークウインドウを開くとウインドウマネージャが +終了するバグを修正。 +簡単なImakefileを作成してみた。 +ウインドウマネージャの終了時に各クライアントのウインドウ位置の戻し方を変更。 +config file のコメントが一部有効でないバグを修正。 +ウインドウデコレーションを一部変更。 +ファインダもどきのアイコンを表示するアプリケーションを付属。 +ソースコードに著作権表示を入力。 + +0.3.0 -> 0.3.1 +メニューバーのフォントを14ポイントに変更。 +kterm 等のリサイズをフォントサイズになるように変更。 +ウインドウのマップのバグを修正。 +Netscape とともに死ぬバグを修正。 +-geometry -0-0 とすると、スクロールバーが画面の外に出るバグを修正。 +カラーマップのインストールをウインドウ毎におこうなうよう修正。 +ウインドウの移動がタイトルバーより上にいかないよう修正。 +アップルメニューから起動したアプリケーションに対してゾンビができるバグを修 +正。 +ウインドウのリサイズで、マイナスのサイズにリサイズできるバグを修正。 + +0.2.1 -> 0.3.0 +xv の表示のずれを修正。 +サブウインドウがアンマップされないバグを修正。 +ClickToMouseの状態で、アイコンメニューでウインドウを選択した時、選択したウ +インドウがアクティブになるようにした。 +デスクトップを移動した時、メニューがウインドウの下になるバグを修正。 +スクロールバーを少し細くした。 +メニューのラベルウインドウを少し大きくした。 +Shape Window でリサイズできるようにした。 +アイコンメニューで項目が選択されないことがあるバグを修正。 +メニューの選択方法がマックとそっくりになった。 + +0.2.0 -> 0.2.1 +クローズボックスでウインドウを閉じるとウインドウマネージャが死ぬバグを +修正。 +~/.desktop ファイルが読めないバグを修正。 +Shape Window のタイトルバーにゴミがでるバグを修正。 +アイコンを選択してもメニューが反転するようにした。 +メニュウの表示の高速化。 +event.c の XConfigureWindow でのパラメータを変更。 +メニューのリスタートの扱いを変更。 diff --git a/CONFIGURATION b/CONFIGURATION new file mode 100644 index 0000000..01f056b --- /dev/null +++ b/CONFIGURATION @@ -0,0 +1,320 @@ +A configuration file goes to usually see a $HOME/.mlvwmrc file. It is +possible that this file is changed by the -f option in the start. Copy +this file on $B!A(B/.mlvwmrc if necessary, and change it because a sample +file is in sample_rc/Mlvwmrc, Mlvwmrc-j. sample_rc/Mlvwmrc-j is the +sample of Japanese edition. That goes to see system configuration file +when InstallSampleRC is YES, too. + +Note) configuration file became a change in .mlvwmrc from +.desktop. Set up OldRCFile with configure.h in YES when the +actualities of .desktop are wished to it. + +BuiltinCommand + +Builtin command which can be used in the menu, the keyboard short cut, +and so on is as the following. + + Exec + The practice of the outside command is performed. The outside + command carried out as an argument is taken. Set the name of + the application carried out. + Nop + Anything isn't done. + Refresh + It is made that the screen is fresh. + Restart + Window manager specified as an argument is carried out, and + restart of the window environment is performed. + Exit + Window manager is finished. + Desk + Desk-top movement is done. An argument takes a number or +, + -. It is moved to the shown desk-top of the number at the time + of the number. + (-) case current desktop number is + added(pulled) 1. + NextWindow + The window mapped after the present active window is + chosen. The window that the window that Hide was done and + SkipSelect are specified isn't chosen. + PreviousWindow + The window mapped before the present active window is + chosen. The window that the window that Hide was done and + SkipSelect are specified isn't chosen. + NextSameDeskWindow + A window about the same desk-top number which mapped in the + next of present active window is chosen. The window that the + window that Hide was done and SkipSelect are specified isn't + chosen. + PreviousSameDeskWindow + A window about the same desk-top number that is mapped + previous of present active window is chosen. The window that + the window that Hide was done and SkipSelect are specified + isn't chosen. + ShadedUnShadeActive + Shade or UnShade does present active window. + HideActive + Present active window is hidden. + HideOthers + The present one except for active window is hidden. + ShowAll + All hiding windows are indicated. + MoveWindow + It is moved through the window after the choice. + ResizeWindow + It resize a window after the choice. + KillWindow + A window is finished after the choice. + SendMessage + The event of KeyPress is sent to present active window. The way + of setting it moves space to the stop, and describes a key + name. If the length of key name is 1, all charactor inside + double quotation marks are changed to key name. + KeyModifier performs designation with the capital letter, and + it can be specified by the same character as the keyboard short + cut mentioned later. KeyModifier can be described by combining + it with the key name and +. + example ) control +x, -> C+x + Wait Application name or Application class + Wait to start application. + ShowBalloon + This function can be bound to a key in order to show balloon. + +Description + +The item which can be set by the initialization file is as the next. + + Desktopnum + Virtual screen number of sheets. Default is 1. + StickyShade + The shaded windows are indicated instead of the desk-top + movement. It isn't set up with the default. + StickyHide + It is indicated in the desk-top number of current when the + window which did Hide is chosen from the window list. When + ShowAll is performed, it is indicated in the original + desk-top. It isn't set up with the default. + ShadeMap + Shade isn't canceled when Map is done after Hide does the + window that Shade was done. Shade is canceled with the default. + DoubleClickTime + The establishment of the click time to perform double + click. Default is 300. + Compatible + Change to the dotted line that is displayed at move and resize + window. + FollowToMouse + When it is set up, active window is changed in accordance with + the movement of the mouse. It isn't set up with the default. + SloppyFocus + It turns on FollowToMouse with the modification of not loosing + focus when in the root window. + System8 + Change to window decoration to System 8(Only Color Monitor). + OpaqueMove + Enable Opaque move. + OpaqueResize + Enable Opaque resize. + OneClickMenu + Click pull down menu and more one click execute selection. + ZoomWait + Setting Hide animation speed. Default is 10ms. The unit is ms. + RotateDesk + Rotate desktop number at Desk + and Desk -. + DisplayDeskNumber + Display window name with desktop number on window list. + IconifyShade + WindowShade is regarded as Inocify. + IconifyHide + HideWindow is regarded as Iconify. + ScrollBarWidth + The variable scroll window is set and defaults to 19 if + unspecified. + FlushMenu + The flashing interval of the menu and number of times are set. An + argument can't be omitted in the flashing interval and the number + of times. The flashing interval is 100, flashing number of + times are 2 as for the default. Flashing interval is set at ms. + IconPath + An icon path is specified. When it is set in the plural, + `Divide it with : ', and set it. Icon specified with Icon and + MiniIcon can stop reading it when designation isn't performed + before Style, IconMenuIcon and Menu. + IconMenuIcon + The icon of the window list menu of the right end is + specified. When there is no designation, the character line of + ICON is indicated. It stopped binding it with. + UseRootWin + ignore button event on Root Window. + UseBalloon "str1" "str2", Icon iconname + Use balloon help. str1 is displayed as menu item when Balloon + help is not displayed. + InitFunction + RestartFunction + Define the function when start and restart the mlvwm. + MenuBarFont + The font of the menu bar is set up. + MenuFont + The font of menu item is set up. + TitleBarFont + The font of the title bar of the window is set up. + BalloonFont + The font of Balloon Help is set up. + Read + The establishment file of the set file name is read. + RestartPreviousState + It allows to regenerate the screen as it was before the + previous window manager was shutdown or the current window + manager was restarted. + Menu + A menu is set up. It is a menu item to END. A menu name is + continued, and it describes it. A menu name can't include + space. It is divided , and an option is inputted. There is the + next thing in the option. + + Right + It shows a menu label in the right. + Left + It shows a menu label in the left. The default of the menu is + Left and it is omitted. + Icon icon name + An icon to the icon name menu bar can be specified. Pixmap + and Bitmap files are used as icon. + Label + The label of the menu bar is set up. + Stick + The menu label is indicated any time in spite of the + designation of MenuBar mentioned later. + NonStick + The menu label is indicated only MenuBar indication (default). + + How to describe menu item + It is "label" options. + When a label is the dotted line. See a sample for detail. + There is the next thing in the option. Options are divided by ,. + + Gray + The character of the menu item is made gray. + Black + The character of the menu item is made black. + Check + A check mark is put. + NonCheck + A check mark isn't put. + Select + It is made possible a menu item is chosen. + NonSelect + A menu item is prevented from being chosen. + Icon icon name + An icon name icon is specified. Pixmap and Bitmap files are + used as icon. + SubMenu + A submenu is specified. + Action builtin command + Command when menu is chosen is specified. + + Swallow + It is filled up in the menu bar, and the application that it + gets crowded is established. It is divided , and an option is + inputted. There is the next thing in the option. + Right + It shows application in the right. + Left + It shows application in the left. + The default of the application is Right and it is omitted. + Action + The application that it is filled up and crowded is + set. Description is to continue the description of Exec of + inside command backward. + Stick + Indication is always in spite of MenuBar definitions. + NonStick + Indication is performed only with specified MenuBar. + + And, the application of the menu bar describes a name to the + application of the menu bar in succession. + + MenuBar + The menu of the name described in the space to END becomes the + item of this menu bar. + Style + A window decoration can be set. The ways of setting it are "a + window name or a class" a decoration switch, ... It becomes + designated completion with END. In the window name, *? can be + used for wild card. There is the next thing in the decoration + switch. + + NormalDecoration + Performs a standard decoration. + NoSbarH + Horizontal scroll bar isn't indicated. + NoSbarV + Vertical scroll bar isn't indicated. + NoResizeR + Resize region isn't indicated. + NoTitle + A title bar isn't indicated. + NoMinMaxR + Maximum, minimum region isn't indicated.(When NoTitle is + specified, it is set automatically.) + NoCloseR + Close region isn't indicated.(When NoTitle is + specified, it is set automatically.) + NoShadeR + Shade region isn't indicated(Only to set System8). + NoWinList + It isn't indicated in the window list. + NoFocus + The window doesn't have a focus when it mapped. + StayOnTop + It is indicated on all the windows. The window indicated + later becomes the top at the time of which a set window is + the same as. + Sticky + The window is indicated without the desk-top movement. + SkipSelect + It isn't chosen with NextWindow of inside command, + PreviousWindow. + EnableScroll + A window under the scroll condition of Enable. + MaxmizeScale + The percentage when it turns most is set or widthxheight. + MiniIcon + It has the small icon with the designated application. Pixmap + and Bitmap files are used as icon. + MenuBar + It has the menu bar with the designated application. The menu + is specified by continuing the name of the menu and + describing it. + NoTransientDecorate + No decorations for transient window. + + All decorations are indicated, and the window of the default is + indicated in the window list. StayOnTop isn't designation. + + ShortCut + The establishment of the keyboard short cut is performed. It + becomes designated completion with END. The way of setting it + is as the next. + + KeyName KeyboardModifier Command + + The thing to can spend with Menu is possible (it is set completely). + KeyboardModifier performs designation with the capital letter, + and it is as the next. + + S Shift key + C Control key + M Mod1 key + 1 Mod1 key + 2 Mod2 key + 3 Mod3 key + 4 Mod4 key + 5 Mod5 key + A AnyModifier + N No + + And it is to refer to the Mlvwmrc file of the attachment that + it is stuck though there may be a thing of the explanation + which is not. The description of the pole power all will be + performed here. + diff --git a/CONFIGURATION.jp b/CONFIGURATION.jp new file mode 100644 index 0000000..8d811c2 --- /dev/null +++ b/CONFIGURATION.jp @@ -0,0 +1,234 @@ +$B@_Dj%U%!%$%k$ODL>o(B $HOME/.mlvwmrc $B%U%!%$%k$r8+$K$$$-$^$9!#5/F0;~$N(B -f +$B%*%W%7%g%s$K$h$C$F!"$3$N%U%!%$%k$rJQ99$9$k$3$H$,2DG=$G$9!#(B +$B%5%s%W%k%U%!%$%k$,(B sample_rc/Mlvwmrc, Mlvwmrc-j $B$K$"$j$^$9$N$G!"I,MW$K(B +$B1~$8$F$3$N%U%!%$%k$r(B ~/.mlvwmrc $B$K%3%T!<$7$FJQ99$7$F2<$5$$!#(B +sample_rc/Mlvwmrc-j $B$OF|K\8lHG$N%5%s%W%k$G$9!#(B +InstallSampleRC $B$,(B YES $B$N>l9g!"$=$A$i$b8+$K9T$-$^$9!#(B + +$BCm(B) $B@_Dj%U%!%$%k$NL>A0$,(B .desktop $B$+$i(B .mlvwmrc $B$KJQ99$K$J$j$^$7$?!#(B + .desktop $B$N$^$^$r4uK>$9$k>l9g$O!"(B configure.h $B$G(B OldRCFile $B$r(B YES + $B$K@_Dj$7$F2<$5$$!#(B + +Builtin Command + +$B%a%K%e!A0$r;XDj$7$F2<$5$$!#(B + Nop $B2?$b$7$^$;$s!#(B + Refresh $B2hLL$N%j%U%l%C%7%e$r$7$^$9!#(B + Restart $B0z?t$H$7$F;XDj$5$l$?%&%$%s%I%&%^%M!<%8%c$rl9g$O$=$N?t;z$N<($9%G%9%/%H%C%W$K0\(B + $BF0$7$^$9!#(B+(-) $B$N>l9g$O%+%l%s%H%G%9%/%H%C%W$K(B1$BB-$7$?(B + ($B0z$$$?(B)$BHV9f$N%G%9%/%H%C%W$K0\F0$7$^$9!#(B + NextWindow $B8=:_$N%"%/%F%#%V%&%$%s%I%&$N$D$.$K%^%C%W$5$l$?%&%$%s(B + $B%I%&$rA*Br$7$^$9!#(BHide $B$5$l$?%&%$%s%I%&$H(B SkipSelect + $B;XDj$5$l$?%&%$%s%I%&$OA*Br$5$l$^$;$s!#(B + PreviousWindow + $B8=:_$N%"%/%F%#%V%&%$%s%I%&$N$^$($K%^%C%W$5$l$?%&%$%s(B + $B%I%&$rA*Br$7$^$9!#(BHide $B$5$l$?%&%$%s%I%&$H(B SkipSelect + $B;XDj$5$l$?%&%$%s%I%&$OA*Br$5$l$^$;$s!#(B + NextSameDeskWindow + $B8=:_$N%"%/%F%#%V%&%$%s%I%&$Ne$N%&%$%s%I%&$rA*Br$7$^$9!#(BHide $B$5$l$?%&%$%s(B + $B%I%&$H(B SkipSelect $B;XDj$5$l$?%&%$%s%I%&$OA*Br$5$l$^$;(B + $B$s!#(B + PreviousSameDeskWindow + $B8=:_$N%"%/%F%#%V%&%$%s%I%&$N$^$($K%^%C%W$5$l$?F1$8%G(B + $B%9%/%H%C%W>e$N%&%$%s%I%&$rA*Br$7$^$9!#(BHide $B$5$l$?%&%$(B + $B%s%I%&$H(B SkipSelect $B;XDj$5$l$?%&%$%s%I%&$OA*Br$5$l$^(B + $B$;$s!#(B + ShadeUnShadeActive + $B8=:_$N%"%/%F%#%V%&%$%s%I%&$r(B Shade $B$^$?$O(B UnShade $B$7(B + $B$^$9!#(B + HideActive $B8=:_$N%"%/%F%#%V%&%$%s%I%&$r1#$7$^$9!#(B + HideOthers $B8=:_$N%"%/%F%#%V%&%$%s%I%&0J30$r1#$7$^$9!#(B + ShowAll $B1#$l$F$$$k%&%$%s%I%&$r$9$Y$FI=<($7$^$9!#(B + MoveWindow $B%&%$%s%I%&$rA*Br$N8e!"0\F0$7$^$9!#(B + ResizeWindow + $B%&%$%s%I%&$rA*Br$N8e!"%j%5%$%:$7$^$9!#(B + KillWindow $B%&%$%s%I%&$rA*Br$N8e!"=*N;$7$^$9!#(B + SendMessage $B8=:_$N%"%/%F%#%V%&%$%s%I%&$K(B KeyPress $B$N%$%Y%s%H$rAw(B + $B$j$^$9!#;XDjJ}K!$O!"%9%Z!<%9$r6g@Z$j$K$7$F%-!<%M!<%`(B + $B$r5-=R$7$F$$$-$^$9!#%-!<%M!<%`$,0lJ8;z$N>l9g(B " $B$G3g$C(B + $B$F!"O"B3$7$F;XDj$9$k$3$H$,$G$-$^$9!#(B + $B%-!<%\!<%I%b%G%#%U%!%$%"$OBgJ8;z$G;XDj$r9T$J$$!"8e=R(B + $B$9$k%-!<%\!<%I%7%g!<%H%+%C%H$HF1$8%-%c%i%/%?$K$h$j;X(B + $BDj$G$-$^$9!#%-!<%\!<%I%b%G%#%U%!%$%"$O%-!<%M!<%`$H(B + + $B$G7k9g$9$k$3$H$K$h$j5-=R$G$-$^$9!#(B + $BNc(B) $B%3%s%H%m!<%k(B + x $B$N>l9g"*(B C+x + Wait $B%"%W%j%1!<%7%g%sL>(B $B$^$?$O(B $B%"%W%j%1!<%7%g%s%/%i%9(B + $B%"%W%j%1!<%7%g%s$,N)$A>e$,$k$N$rBT$D!#(B + ShowBalloon $B%-!<%\!<%I%7%g!<%H%+%C%H$GMxMQ$9$k!#%P%k!<%s%X%k%W$r(B + $BI=<($9$k!#(B + +Description + +$B=i4|@_Dj%U%!%$%k$G;XDj$G$-$k9`L\$OA[2hLLKg?t!#%G%U%)%k%H$O(B1$B!#(B + StickyShade $B%7%'!<%I$5$l$?%&%$%s%I%&$O%G%9%/%H%C%W$N0\F0$K4X78$J(B + $B$/I=<($5$l$k!#%G%U%)%k%H$O$J$7!#(B + StickyHide Hide $B$7$?%&%$%s%I%&$r%&%$%s%I%&%j%9%H$+$iA*Br$9$k$H!"(B + $B%+%l%s%H$N%G%9%/%H%C%W$KI=<(!#(BShowAll $B$r9T$J$C$?;~$O(B + $B%*%j%8%J%k$N%G%9%/%H%C%W$KI=<($5$l$k!#%G%U%)%k%H$O$J(B + $B$7!#(B + ShadeMap Shade $B$5$l$?%&%$%s%I%&$r(B Hide $B$7$?$"$H!"(B Map $B$9$k;~$K(B + Shade $B$r2r=|$7$J$$!#%G%U%)%k%H$G$O(B Shade $B$,2r=|$5$l$k!#(B + DoubleClickTime $B%@%V%k%/%j%C%/$r9T$J$&$?$a$N%/%j%C%/4V3V$N@_Dj!#%G%U%)(B + $B%k%H$O(B 300$B!#(B + Compatible $B%&%$%s%I%&$N0\F0!"%j%5%$%:$N;~$KI=<($5$l$kOH$,E@@~$K$J(B + $B$j$^$9!#(B + FollowToMouse $B@_Dj$9$k$H%^%&%9$NF0$-$K$"$o$;$F%"%/%F%#%V%&%$%s%I%&$,(B + $BJQ99$5$l$^$9!#%G%U%)%k%H$O$J$7!#(B + SloppyFocus FollowToMouse $BF1MM$K%^%&%9$NF0$-$K$"$o$;$F%"%/%F%#%V%&(B + $B%$%s%I%&$,JQ99$5$l$k!#%^%&%9$,%k!<%H%&%$%s%I%&$K=P$?(B + $B>l9g$O%"%/%F%#%V%&%$%s%I%&$,JQ99$5$l$J$$!#(B + System8 $B%G%3%l!<%7%g%s$r(B System8 $BIw$K$9$k!#%+%i!<%b%K%?$N$_!#(B + OpaqueMove $B0\F0;~$KCf?H$rI=<($7$?$^$^0\F0(B + OpaqueResize $B%j%5%$%:;~$KCf?H$rI=<($7$?$^$^0\F0(B + OneClickMenu $B%/%j%C%/$G%a%K%e!<$,%W%k%@%&%s$7$F!"$b$&0l2s$N%/%j%C%/(B + $B$G$K%G%9%/%H%C%WHV9f$r0l=o$K(B + $BI=<($9$k!#(B + IconifyShade WindowShade $B$5$l$?$b$N$r(B Inocify $B$H$_$J$9!#(B + IconifyHide HideWindow $B$5$l$?$b$N$r(B Iconify $B$H$_$J$9!#(B + ScrollBarWidth $B%9%/%m!<%k%P!<$NI=<($NI}$rJQ99$9$k!#%G%U%)%k%H$O(B19$B!#(B + FlushMenu $B%a%K%e!<$NE@LG4V3V$H2s?t$r;XDj!#0z?t$O!"E@LG4V3V$H2s(B + $B?t$G!">JN,$OIT2DG=!#%G%U%)%k%H$O!"E@LG4V3V$,(B 100, + $BE@LG2s?t$,(B 2$B!#E@LG4V3V$O(B ms $B$G;XDj!#(B + IconPath $B%"%$%3%s%Q%9$r;XDj$7$^$9!#J#?t;XDj$9$k;~$O(B `:' $B$G6h@Z$C(B + $B$F;XDj$7$F2<$5$$!#(BStyle $B$d(B IconMenuIcon $B$d(B Menu $B$NA0$K(B + $B;XDj$r9T$J$o$J$$>l9g!"(BIcon $B$d(B MiniIcon $B$G;XDj$5$l$?(B + Icon $B$,FI$_9~$a$J$/$J$j$^$9!#(B + IconMenuIcon $B1&C<$N%&%$%s%I%&%j%9%H%a%K%e!<$N%"%$%3%s$r;XDj$7$^$9!#(B + $B;XDj$N$J$$>l9g$O(B ICON $B$NJ8;zNs$,I=<($5$l$^$9!#(B"" $B$G3g$i(B + $B$J$/$J$j$^$7$?!#(B + UseRootWin Root$B%&%$%s%I%&$N%^%&%9%$%Y%s%H$r$H$i$J$/$J$j$^$9!#(B + UseBalloon "str1" "str2", Icon iconname + $B%P%k!<%s%X%k%W$rI=<($7$^$9!#(Bstr1 $B$O%P%k!<%s$,I=<($5$l$F(B + $B$$$J$$;~$N%a%K%e!<9`L\L>$G$9!#(B + InitFunction + RestartFunction $BN)$A$"$2!"%j%9%?!<%H;~$K$N@_Dj%U%!%$%k$rFI$_$^$9!#(B + RestartPreviousState + It allows to regenerate the screen as it was before + the previous window manager was shutdown or the + current window manager was restarted. + Menu $B%a%K%e!<$r@_Dj$7$^$9!#(B END $B$^$G$,%a%K%e!<9`L\$G$9!#%a(B + $B%K%e!$rB3$1$F5-=R$7$^$9!#%a%K%e!$K%9%Z!<%9$r4^(B + $B$a$k$3$H$O$G$-$^$;$s!#(B + $B%*%W%7%g%s$O!"(B, $B$G6h@Z$C$FF~NO$7$^$9!#%*%W%7%g%s$OJN,2DG=$G$9!#(B + Icon $B%"%$%3%sL>(B + $B%a%K%e!<%P!<$X$N%"%$%3%s$,;XDj$G$-$^$9!#%T%C%/%9%^%C(B + $B%W!"%S%C%H%^%C%W$I$A$i$G$b;XDj$,$G$-$^$9!#(B + Label "$B%i%Y%k(B" + $B%a%K%e!<%P!<$N%i%Y%k$r@_Dj$7$^$9!#(B + Stick $B8e=R$9$k(B MenuBar $B$N;XDj$K$+$+$o$i$:I=<($7$^$9!#(B + NonStick $B;XDj$5$l$?(B MenuBar $B$N$_$GI=<($r9T$J$$$^$9(B($B%G%U%)%k(B + $B%H(B)$B!#(B + $B%a%K%e!<%"%$%F%`$N5-=RJ}K!(B + "$B%i%Y%k(B" options + $B$G$9!#(B + $B$G$9!#%i%Y%k$,(B "" $B$N>l9g$O!"E@@~$,0z$+$l$^$9!#>\$7$/$O%5%s%W%k$r(B + $B8+$F2<$5$$!#(B + $B%*%W%7%g%s$K$O(B $B%"%$%3%s$r;XDj$7$^$9!#%T%C%/%9%^%C%W!"%S%C%H%^%C(B + $B%W$H$b$K;HMQ2DG=$G$9!#(B + SubMenu $B%a%K%e!(B $B%5%V%a%K%e!<$r;XDj$7$^$9!#(B + Action $BFbIt%3%^%s%I(B $B%a%K%e!<$,A*$P$l$?;~$N%3%^%s%I$r;XDj$7$^$9!#(B + Swallow $B%a%K%e!<%P!<$KKd$a9~$`%"%W%j%1!<%7%g%s$r@_Dj$7$^$9!#(B + $B%*%W%7%g%s$O!"(B, $B$G6h@Z$C$FF~NO$7$^$9!#%*%W%7%g%s$OJ(B + $BN,2DG=$G$9!#(B + Action $BKd$a9~$`%"%W%j%1!<%7%g%s$r;XDj$7$^$9!#5-=R$OFbIt%3%^%s%I$N(B + Exec $B$N5-=R$r8e$m$KB3$1$F2<$5$$!#(B + Stick $B8e=R$9$k(B MenuBar $B$N;XDj$K$+$+$o$i$:I=<($7$^$9(B($B%G%U%)%k%H(B)$B!#(B + NonStick $B;XDj$5$l$?(B MenuBar $B$N$_$GI=<($r9T$J$$$^$9!#(B + $B$^$?!"%a%K%e!<%P!<$N%"%W%j%1!<%7%g%s$O6/@)E*$K9b$5$,%a%K%e!<%P!<$N9b(B + $B$5$K%j%5%$%:$5$l$^$9!"(B + + MenuBar $BB3$1$FL>A0$r5-=R$7$^$9!#(BEND $B$^$G$N4V$K5-=R$5$l$?L>A0(B + $B$N%a%K%e!<$,$3$N%a%K%e!<%P!<$N9`L\$H$J$j$^$9!#(B + Style $B%&%$%s%I%&%G%3%l!<%7%g%s$r;XDj$G$-$^$9!#;XDjJ}K!$O!"(B + "$B%&%$%s%I%&%M!<%`$^$?$O%/%i%9(B" $B%G%3%l!<%7%g%s%9%$%C%A(B, [...] + $B$G$9!#(BEND$B$G;XDj$N=*N;$H$J$j$^$9!#(B + $B%&%$%s%I%&%M!<%`$K$O(B * $B$H(B ? $B$,;HMQ$G$-$^$9!#(B + $B%G%3%l!<%7%g%s%9%$%C%A$O%9%/%m!<%k%P!<$rI=<($7$J$$!#(B + NoResizeR $B%j%5%$%:%j%e!<%8%g%s$rI=<($7$J$$!#(B + NoTitle $B%?%$%H%k%P!<$rI=<($7$J$$!#(B + NoMinMaxR $B:GBg!&:G>.2=%j%e!<%8%g%s$rI=<($7$J$$(B(NoTitle $B$,;XDj$5$l$F(B + $B$$$k>l9g$O<+F0E*$K;XDj$5$l$^$9(B)$B!#(B + NoCloseR $B%/%m!<%:%j%e!<%8%g%s$rI=<($7$J$$(B(NoTitle $B$,;XDj$5$l$F$$$k(B + $B>l9g$O<+F0E*$K;XDj$5$l$^$9(B)$B!#(B + NoShadeR $B%&%$%s%I%&%7%'%$%I%j%e!<%8%g%s$rI=<($7$J$$!#(BSystem8 + $B$,;XDj$5$l$F$$$k;~$N$_!#(B + NoWinList $B%&%$%s%I%&%j%9%H$KI=<($7$J$$!#(B + NoFocus $B%^%C%W$5$l$?;~$K%U%)!<%+%9$,F~$i$J$$!#(B + StayOnTop $BA4$F$N%&%$%s%I%&$N>e$KI=<($9$k!#(B + $B;XDj$7$F$"$k%&%$%s%I%&F1;N$N>l9g$O8e$+$iI=<($7$?%&%$%s%I%&(B + $B$,>e$K$J$k!#(B + Sticky $B%G%9%/%H%C%W$N0\F0$K4X78$J$/I=<($5$l$k!#(B + SkipSelect $BFbIt%3%^%s%I$N(B NextWindow, PreviousWindow $B$GA*Br$5$l(B + $B$J$$!#(B + EnableScroll $B%9%/%m!<%k$,(B Enable $B$N>uBV$G!"%&%$%s%I%&$r%^%C%W$7(B + $B$^$9!#(B + MaxmizeScale $B:GBg2=$9$k;~$N%Q!<%;%s%F!<%8$^$?$O(B $BI}(Bx$B9b$5(B $B$r;XDj!#(B + MiniIcon $B%9%b!<%k%5%$%:$N%"%$%3%s$r;XDj!#%T%C%/%9%^%C%W!"%S%C(B + $B%H%^%C%W$H$b$K;XDj$G$-$^$9!#(B + MenuBar $B%"%W%j%1!<%7%g%s$G$b$A$$$k%a%K%e!<%P!<$r!"%a%K%e!<$N(B + $BL>A0$rB3$1$F5-=R$9$k$3$H$K$h$j;XDj$7$^$9!#(B + NoTransientDecorate + $B0l;~%&%$%s%I%&$K%G%3%l!<%7%g%s$7$J$$!#(B + $B%G%U%)%k%H$N%&%$%s%I%&$OA4$F$N%G%3%l!<%7%g%s$rI=<($7!"%&%$%s%I%&%j%9(B + $B%H$KI=<($7$^$9!#(BStayOnTop$B$OL$;XDj!#(B + + ShortCut $B%-!<%\!<%I%7%g!<%H%+%C%H$N@_Dj$r9T$J$$$^$9!#(BEND$B$G;XDj(B + $B$N=*N;$H$J$j$^$9!#;XDjJ}K!$OH$7$F2<$5$$!#$3$A$i$K$O!"6KNO$9$Y$F$N5-=R$r9T$J$&M=Dj$G$9!#(B + diff --git a/FAQ.jp b/FAQ.jp new file mode 100644 index 0000000..a5d5af5 --- /dev/null +++ b/FAQ.jp @@ -0,0 +1,20 @@ +Q1 ファインダーは作る予定はないのですか? +A1 当面ありません。どうしても欲しい方は sxplorer というものが、作られ + ているので、そちらを試してみて下さい。 + +Q2 アプリケーションがメニューバーに入らないのですが。 +A2 いくつかの原因が考えられますが、mlvwm に環境変数の PATH は正しくわ + たっているでしょうか。または、Exec の後ろに "" で囲まれたコマンド名 + は正しいものになっているでしょうか。確認してみて下さい。 + +Q3 設定ファイルにエラーがあるらしく、正常に読み込んでもらえません。 +A2 バージョンアップによって設定ファイルの記述方法が変更になることがよく + ありますので、サンプルファイルを参考に修正して下さい。 + +Q4 kterm にメッセージが送れないのですが。 +A4 resource の allowSendEvents を on にしないと、kterm はアプリケーショ + ンからのイベントを受け取らないようですので、確認して下さい。 + +Q5 設定ファイルの最後の行に書いてある設定が正しく動きません。 +A5 最後の行で改行してみて下さい。一部手抜きがあるので、改行コードの入っ + ていない設定行は正しく解釈できないことがあります。 \ No newline at end of file diff --git a/Imakefile b/Imakefile new file mode 100644 index 0000000..cda4cf0 --- /dev/null +++ b/Imakefile @@ -0,0 +1,9 @@ +XCOMM Imakefile for MLVWM + +#define IHaveSubdirs +SUBDIRS = mlvwm sample_rc +#define PassCDebugFlags + +MakeSubdirs($(SUBDIRS)) +DependSubdirs($(SUBDIRS)) + diff --git a/README b/README new file mode 100644 index 0000000..22a6703 --- /dev/null +++ b/README @@ -0,0 +1,57 @@ +This document is transformed README.jp into English by automatic. + +We don't assume all responsibility toward any situation which +responded by the use of this window manager, either. +Send e-mail to the author if there are a Bug report, a request, and so +on. + +How To Install + +If it has xmkmf, it can be compiled with +xmkmf -a; +make. +But, it must be compiled with gcc for SunOS4.x. + +The designation of the installation directory can be done by the +change of configure.h. Sauce complying with Locale came in. Make +HasLocale YES in configure.h. Cope additionally and suitably though +the modification of configure.h was performed very much, too. Make +HasLocale NO, and perform compilation when it doesn't go well. It +didn't move well with setlocale of SunOS4. It thinks that it moves if +X_LOCALE is compiled under the condition that it has define done in +X. + +The person who has imake is to make makefile by using imake, and +compile it. + +Be careful because there were various changes when this version is +used from the thing of the Version0.6.0 before. + +Execute + +mlvwm [-f config_file] [-d display_name] [-c] [-debug] + +-f The change of the establishment file. +-d The change of the start display. +-debug Debug output is performed. + +Others + +Some applications that understand standard Xt command line arguments +and X resources, like xterm and xfontsel, allow the user to specify +the start-up desk on the command line: + + xterm -xrm "*Desk:1" + +will start an xterm on desk number 1. Not all applications understand +this option, however. + +Pixmap was prepared for in pixmap/ for the person who used biff by the +menu bar. Use it because they are Thanks for shingo. MailFull.xpm, +MailEmpty.xpm. It copes when it can cope. + +Add manual page(Thanks for Daniel Henninger). + +See Also +http://www.bioele.nuee.nagoya-u.ac.jp/member/tak/mlvwm.html + diff --git a/README.jp b/README.jp new file mode 100644 index 0000000..5c98076 --- /dev/null +++ b/README.jp @@ -0,0 +1,56 @@ +本ウインドウマネージャの使用により応じた、いかなる事態に対しても当方 +は一切の責任も負いません。 +Bug report, 要望などございましたら、作者までメールを送付して下さい。 + +How To Install + +xmkmf を持っているならば、 +xmkmf -a +make +でコンパイルできます。ただし SunOS 4.x の場合 gcc でコンパイルする必要 +があります。 + +インストールディレクトリの指定は configure.h の変更で行なえます。 +Locale 対応のソースが入りました。configure.h の中で、 HasLocale を YES +にして下さい。その他にも、 configure.h の修正はかなり行ないましたが、 +適当に対処して下さい。うまくいかない場合は、HasLocale を NO にしてコン +パイルを行なって下さい。SunOS 4 の setlocale ではうまく動きませんでし +た。X に X_LOCALE が define された状態でコンパイルされていれば、動くと +思います。 + +imake を持っている人は imake を使って makefile を作成してコンパイルし +て下さい。 + +Version 0.6.0 以前のものからこのバージョンを使う場合、いろいろな変更があっ +たので、注意して下さい。 + +Execute + +mlvwm [-f config_file] [-d display_name] [-c] [-debug] + +-f 設定ファイルの変更 +-d 起動ディスプレイの変更 +-debug デバグ出力を行なう + +Others +アプリケーションによっては Xt のコマンドラインからの X リソース指定が +行なえるものがあります。例えば xterm や xfontsel においては、コマンド +ラインにおいて、 + + xterm -xrm "*Desk:1" + +と指定することにより、xterm をデスクトップ 1 に開くことができます。す +べてのアプリケーションでこのオプションを指定できるわけではありません。 + +メニューバーで biff を使う人用に pixmap を pixmap/ に用意しました。 +Thanks for shingo. MailFull.xpm, MailEmpty.xpm ですので、使って下さい。 + +マニュアルページができました(Thanks for Daniel Henninger)。 + +凍りついた時 HUP のシグナルを送ることによりデバグ情報を出すので、凍り +ついた時は再現の仕方または、どこで凍りついたかのデバグ情報を付けてメー +ルを下さい。対処可能な場合は、対処します。 + +See Also +http://www.bioele.nuee.nagoya-u.ac.jp/member/tak/mlvwm.html + diff --git a/bitmap/label1 b/bitmap/label1 new file mode 100644 index 0000000..2ff09a2 --- /dev/null +++ b/bitmap/label1 @@ -0,0 +1,6 @@ +#define label1_width 13 +#define label1_height 18 +static unsigned char label1_bits[] = { + 0x00, 0x00, 0xe0, 0x00, 0xf0, 0x01, 0xf8, 0x03, 0xcc, 0x07, 0xc6, 0x0f, + 0xe2, 0x0f, 0xf3, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, + 0xfe, 0x0f, 0xfe, 0x0f, 0xf8, 0x03, 0xf0, 0x01, 0xe0, 0x00, 0x00, 0x00}; diff --git a/bitmap/label2 b/bitmap/label2 new file mode 100644 index 0000000..570ef57 --- /dev/null +++ b/bitmap/label2 @@ -0,0 +1,6 @@ +#define label2_width 14 +#define label2_height 18 +static unsigned char label2_bits[] = { + 0xff, 0x3f, 0x93, 0x21, 0xc9, 0x30, 0x65, 0x38, 0x33, 0x3c, 0x19, 0x3e, + 0x0d, 0x3f, 0x87, 0x3f, 0xc3, 0x3f, 0xe1, 0x3f, 0xf1, 0x3f, 0xf9, 0x3f, + 0xfd, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x2f, 0xff, 0x3f}; diff --git a/bitmap/label3 b/bitmap/label3 new file mode 100644 index 0000000..65f247a --- /dev/null +++ b/bitmap/label3 @@ -0,0 +1,8 @@ +#define label3_width 18 +#define label3_height 18 +static unsigned char label3_bits[] = { + 0xe0, 0x1f, 0x00, 0x50, 0x35, 0x00, 0xa8, 0x6a, 0x00, 0x54, 0xd5, 0x00, + 0xaa, 0xaa, 0x01, 0x55, 0x55, 0x03, 0xff, 0xff, 0x03, 0xff, 0xff, 0x03, + 0xa9, 0x2a, 0x02, 0xff, 0xff, 0x03, 0xff, 0xff, 0x03, 0xff, 0xff, 0x03, + 0xab, 0xaa, 0x02, 0x56, 0x55, 0x01, 0xac, 0xaa, 0x00, 0x58, 0x55, 0x00, + 0xb0, 0x2a, 0x00, 0xe0, 0x1f, 0x00}; diff --git a/configure.h b/configure.h new file mode 100644 index 0000000..e686f11 --- /dev/null +++ b/configure.h @@ -0,0 +1,80 @@ +XCOMM Imakefile for MLVWM + +XCOMM Do you want to use Locale? +XCOMM If you use Solaris 1 and your X11 didn't compile with X_LOCALE, +XCOMM sometime, you can't find multi-byte character. + +#define HasLocale YES + +XCOMM After version 6.0-current, the name of default rc file is changed. +XCOMM Do you want to use .desktop to rc file? + +#define OldRCFile NO + +XCOMM Do you want to install sample rc file to MlvwmLibDir? + +#define InstallSampleRC NO + +XCOMM The directory name of bindir and libdir. + +XCOMM #define MlvwmBinDir /home/hase/bin +XCOMM #define MlvwmLibDir /home2/hase/bin/mlvwm-lib + +XCOMM +XCOMM Cannot modify as follows: +XCOMM + +#ifdef MlvwmBinDir + MLVWMBINDIR = MlvwmBinDir +#else + MLVWMBINDIR = $(BINDIR) +#endif + +#ifdef MlvwmLibDir + MLVWMLIBDIR = MlvwmLibDir +#else + MLVWMLIBDIR = $(USRLIBDIR)/mlvwm +#endif + +#ifndef HasLocale +#define HasLocale NO +#endif + +#ifndef OldRCFile +#define OldRCFile NO +#endif + +#if HasLocale + Locale_DEFINES = -DUSE_LOCALE + Loacle_INCLUDES = +#if defined(FreeBSDArchitecture) && OSMajorVersion>1 && OSMinorVersion>1 + Locale_LIBRARIES = -lxpg4 +#endif /* End FreeBSD */ +#endif /* End HasLocale */ + +#if defined(SunArchitecture) + CC = gcc +#endif + +#if OldRCFile + MLVWMRC = .desktop +#else + MLVWMRC = .mlvwmrc +#endif + +#if Compatible + COMPATIBLE = -DCOMPATIBLE +#else + COMPATIBLE = +#endif + +XCOMM +XCOMM CDEBUGFLAGS = -g -Wall -Wshadow +XCOMM CDEBUGFLAGS = -O2 -Wall +XCOMM CDEBUGFLAGS = -g -Wall +XCOMM CDEBUGFLAGS = -g + +ICONPATH = /usr/X11R6/include/pixmaps + +MLVWMDEFINES = $(Locale_DEFINES) $(COMPATIBLE) +MLVWMLIBRARIES = $(Locale_LIBRARIES) diff --git a/man/mlvwm.1 b/man/mlvwm.1 new file mode 100644 index 0000000..7bba591 --- /dev/null +++ b/man/mlvwm.1 @@ -0,0 +1,316 @@ +.\" t +.\" @(#)mlvwm.1 +'\"macro stdmacro +.de EX \"Begin example +.ne 5 +.if n .sp 1 +.if t .sp .5 +.nf +.in +.5i +.. +.de EE +.fi +.in -.5i +.if n .sp 1 +.if t .sp .5 +.. +.ta .3i .6i .9i 1.2i 1.5i 1.8i +.nr X +.TH mlvwm 1 "11 Feb 1997" +.SH NAME +mlvwm \- Macintosh Like Virtual Window Manager +.SH SYNOPSIS +\f4mlvwm [ \fIoptions\fP ] + +.SH DESCRIPTION +.I mlvwm +is a window manager for X11 designed to look and feel like +the Macintosh environment. It provides multiple desktops, separate +menu bars for different applications, and the ability to interact with +applications from that menu bar. It does this by sending key sequences +to the application, such as ctrl-X or alt-Y. + +.SH OPTIONS +These are the command line options that are recognized by \fImlvwm\fP: +.IP "\fB-f\fP \fIconfig_file\fP" +Causes \fImlvwm\fP to use \fIconfig_fule\fP as it's configuration file. +.IP "\fB-d\fP \fIdisplay_name\fP" +Brings \fImlvwm\fP on display \fIdisplay_name\fP instead of the name +taken from the DISPLAY environment variable. +.IP "\fB-c\fP\t" +Compatible mode. When windows are moved or resized, the border displayed +is a dotted line instead of solid. This causes a slight speed decline. +.IP "\fB-debug\fP" +Debug mode. Displays debugging information. + +.SH CONFIGURATION FILES +The configuration file is used to describe shortcut key bindings, menus, +fonts, and various other settings. It is typically ".mlvwmrc" in your +home directory, and if that does not exist it falls back to the system +default. A different config file can be defined using the -f option +shown above. + +Lines beginning with '#' are ignored by \fImlvwm\fP. + +.SH BUILT IN FUNCTIONS +There are a number of built in functions in \fImlvwm\fP that may be +used in the configuration file. If there is an error in the config file, +\fImlvwm\fP will try it's best to go on. If it can't find a particular +icon, it will complain on startup and leave the space blank where the +icon was meant to go. Likewise, if you have a command misspelled or something +to that effect, it will simply put up an error message and continue on +through the rest of the config file. + +The following commands can be used in menus, keyboard short cuts, +and anything else along those lines: + +.IP "Exec \fBapp_name\fP \fBcommand\fP" +Executes an external command as stated by \fBcommand\fP. \fBapp_name\fP +should be set to whatever the name of the application is that will be +executed. +.IP "Nop\t" +Does nothing. +.IP "Refresh" +Refreshes the screen. +.IP "Restart [\fBwindow_manager\fP]" +Restarts \fImlvwm\fP or, if \fBwindow_mananger\fP is defined, restart into +that window manager. +.IP "Exit\t" +Quits \fImlvwm\fP. +.IP "Desk [\fB+\fP|\fB-\fP|\fBnumber\fP]" +Changes desktops to \fBnumber\fP or, if + or - is the argument, goes up +one or down one desktop, respectively. +.IP "NextWindow" +Switches to the next active window. Windows that are hidden or defined +in SkipSelect are not chosen. This includes windows in other desktops +in it's list of windows to choose from. +.IP "PreviousWindow" +Swtiches to the previous active window. Windows that are hidden or defined +in SkipSelect are not chosen. This includes windows in other desktops +in it's list of windows to choose from. +.IP "NextSameDeskWindow" +Switches to the next active window. Windows that are hidden or defined +in SkipSelect are not chosen. Windows in other desktops are not chosen. +.IP "PreviousSameDeskWindow" +Switches to the previous active window. Windows that are hidden or defined +in SkipSelect are not chosen. Windows in other desktops are not chosen. +.IP "ShadedUnShadeActive" +Shades or UnShades active window. +.IP "HideActive" +Hides active window. +.IP "HideOthers" +Hides all other windows except the active one. +.IP "ShowAll" +All hidden windows are unhidden. +.IP "MoveWindow" +Move a window, chosen after this command is selected. +.IP "ResizeWindow" +Resize a window, chosen after this command is selected. +.IP "KillWindow" +Kills a chosen window. +.IP "SendMessage \fBsequence\fP" +A keypress is sent to the active window. The keys pressed are defined +in a similar fashion to those in the ShortCut command. You specify a +special key with it's corresponding capital letter identifier and a + +symbol. For instance, if you wanted to set the sequence: Ctrl-x, you +would use C+x. + +The following commands are used to change or describe \fImlvwm\fP's +functionality: + +.IP "Desktopnum \fBnum\fP" +The number of desktops available. Defaults to 1. +.IP "StickShade" +Shaded windows are present no matter what desktop you are on, instead +of staying on a particular desktop. This is not the default behavior. +.IP "StickHide" +Hidden windows are present no matter what desktop you are on, instead +of staying on a particular desktop. This is not the default behavior. +This means that if you hide a window in one desktop, and move to another, +then unhide it, it will appear in that desktop, instead of the desktop +it was originally in. +.IP "ShadeMap" +When a window is unhidden, shading remains. The default is for shading +to be canceled when a window is unhidden. +.IP "DoubleClickTime \fBtime\fP" +The number of milliseconds in which you must click the mouse button twice +in order to register a double click. +.IP "FollowToMouse" +The active window is the window the mouse is currently over. If you move +the mouse away from the current window and/or over another, you lose +focus in the current one. This is not set up by default. +.IP "FlushMenu \fBspeed\fP \fBflashes\fP" +Determines how fast the flashes are when you choose an option from a menu, +as well as how many times it does so. +.IP "IconPath \fBpath\fP" +Specify the path \fImlvwm\fP is to search in order to find it's icons. +Separate directories should be separated with a : and listed in the order +you wish them to be searched. This needs to be defined before any +references to icons are made. +.IP "IconMenuIcon \fBicon\fP" +This is the icon to be used with the windowlist menu on right side of the +menu bar. +.IP "MenuBarFont \fBfont\fP" +The font the menu bar is to use. +.IP "MenuFont \fBfont\fP" +The font the menus are to use. +.IP "TitleBarFont \fBfont\fP" +The font on the title bars of windows. +.IP "Read \fBfilename\fP" +Reads in a separate configuration file. +.IP "Menu \fBname\fP[, \fBoptions\fP] ... END" +Starts a menu block for the specified \fBname\fP menu. After the name of +the menu, some options may be defined as listed below to change the behavior +of that menu. All lines following the Menu command are read in as menu +items until an END statement is reached. Description of menu items will +be discussed after the options. + +Menu options are as follows: + +Right - places the menu on the right side of the menu bar. + +Left - places the menu on the left side of the menu bar. This is default. + +Icon \fBicon\fP - assigns an icon to be displayed on the menu bar instead +of a label. + +Label \fBlabel\fP - assigns a label to be displayed on the menu bar instead +of an icon. + +Stick - menu label is shown any time, in spite of the designation of which +application it is associated with via the MenuBar command. + +NonStick - opposite of Stick. This is default. + + +Menu items are described as follows: + +"label" options + +Multiple options are separated by commas. Options you can choose are as +follows: + +Gray - grays out a menu item. + +Black - makes a menu item black. + +Check - places a check mark next to item. + +NonCheck - doesn't place a check mark next to item. + +Select - makes a menu item selectable. + +NonSelect - prevents a menu item from being selectable. + +Icon \fBicon\fP - specifies an icon to place next to the menu item's label. + +Action \fBcommand\fP - performs any built in \fBcommand\fP. + +.IP "Swallow \fBappname\fP \fBoptions\fP" +Swallows an application into the menu bar. \fBoptions\fP are separated +by commas. \fBappname\fP should match the name of the application that +will be swallowed. The following options are allowed: + +Right - places the menu on the right side of the menu bar. This is default. + +Left - places the menu on the left side of the menu bar. + +Action \fBcommand\fP - performs any built in \fBcommand\fP. This is where +an Exec should be performed of the application to be swallowed. + +Stick - menu label is shown any time, in spite of the designation of which +application it is associated with via the MenuBar command. This is default. + +NonStick - opposite of Stick. + +.IP "MenuBar \fBappname\fP ... END" +This describes the names of the menus to be displayed, given a particular +\fBappname\fP is active. The keyword \fBdefault\fP can be placed for +\fBappname\fP to set up a menu bar for any application that does not +have it's own specific menu bar. Menus are listed one per line after +the MenuBar line, and closed off with an END statement. + +.IP "Style ... END" +This is used to describe certain attributes of particular windows, such +as decorations, MenuBars, mini-icons, and various other attributes. +The wildcards, * and ?, can be used. Lines are set up as follows: + +"appname" \fBoptions\fP + +Multiple \fBoptions\fP are separated by commas, and can be chosen from +the following: + +NormalDecoration - Places standard decorations (ie all the defaults) +around a particular window. + +NoSbarH - Horizontal scroll bar is removed. + +NoSbarV - Vertical scroll bar is removed. + +NoResizeR - no resize 'button'. This is automatic if both NoSbarH and NoSbarV +are defined. + +NoTitle - Removed title bar. + +NoMinMaxR - Min/Max 'button' is removed. Automatic when NoTitle defined. + +NoCloseR - Close 'button' is removed. Automatic when NoTitle defined. + +NoWinList - Prevents window from being show on the window list. + +NoFocus - Does not allow window to get focus. + +StayOnTop - Window stays above all other windows on the screen. + +Sticky - Window stays on screen even if you change desktops. + +SkipSelect - Prevents window from getting chosen by NextWindow, PreviousWindow, +PreviousSameDeskWindow, and NextSameDeskWindow. + +EnableScroll - Activates scroll bars. + +MaxmizeScale - The percentage the window will increase in size when it +maximized. + +MiniIcon \fBicon\fP - \fBicon\fP is used to represent that particular window. + +MenuBar \fBmenubar\fP - Switches the menu bar to \fBmenubar\fP when that +application is active. + +.IP "ShortCut ... END" +Binds key combinations to functions. Short cuts are listed one per line +in the following format: + +KeyName KeyboardModifier Command + +After all Short cuts are listed, an END statement should be placed. +KeyboardModifier's are as follows: + +.EX +S - Shift key +C - Control key +M - Mod1 key +1 - Mod1 key +2 - Mod2 key +3 - Mod3 key +4 - Mod4 key +5 - Mod5 key +A - Any Modifier +N - No Modifier +.EE + +.SH FILES +.nf +$HOME/.mlvwmrc +$MLVWMLIBDIR/system.mlvwmrc +.fi + +.SH COPYRIGHT NOTICES +This program is distributed as freeware. The copyright remains with +the author. + +Macintosh is a registered trademark of Apple Computer, Inc. + +.SH AUTHOR +Takashi HASEGAWA +.I tak@bioele.nuee.nagoya-u.ac.jp diff --git a/mlvwm/.depend b/mlvwm/.depend new file mode 100644 index 0000000..8f39a87 --- /dev/null +++ b/mlvwm/.depend @@ -0,0 +1,113 @@ +add_window.o: add_window.c /usr/include/stdio.h \ + /usr/include/sys/types.h /usr/include/machine/ansi.h \ + /usr/include/machine/types.h /usr/include/sys/cdefs.h \ + /usr/include/machine/endian.h /usr/include/stdlib.h mlvwm.h \ + /usr/X11R6/include/X11/Xlib.h /usr/X11R6/include/X11/X.h \ + /usr/X11R6/include/X11/Xfuncproto.h /usr/X11R6/include/X11/Xosdefs.h \ + /usr/include/stddef.h /usr/X11R6/include/X11/Xutil.h \ + /usr/X11R6/include/X11/cursorfont.h /usr/X11R6/include/X11/xpm.h \ + sun_headers.h /usr/include/sys/wait.h screen.h menus.h config.h \ + borders.h misc.h /usr/include/unistd.h /usr/include/sys/unistd.h \ + /usr/X11R6/include/X11/Xatom.h /usr/X11R6/include/X11/Xresource.h \ + /usr/X11R6/include/X11/extensions/shape.h +balloon.o: balloon.c /usr/include/stdio.h /usr/include/sys/types.h \ + /usr/include/machine/ansi.h /usr/include/machine/types.h \ + /usr/include/sys/cdefs.h /usr/include/machine/endian.h \ + /usr/include/stdlib.h mlvwm.h /usr/X11R6/include/X11/Xlib.h \ + /usr/X11R6/include/X11/X.h /usr/X11R6/include/X11/Xfuncproto.h \ + /usr/X11R6/include/X11/Xosdefs.h /usr/include/stddef.h \ + /usr/X11R6/include/X11/Xutil.h /usr/X11R6/include/X11/cursorfont.h \ + /usr/X11R6/include/X11/xpm.h sun_headers.h /usr/include/sys/wait.h \ + screen.h menus.h config.h misc.h /usr/include/unistd.h \ + /usr/include/sys/unistd.h event.h \ + /usr/X11R6/include/X11/extensions/shape.h +borders.o: borders.c /usr/include/stdio.h /usr/include/sys/types.h \ + /usr/include/machine/ansi.h /usr/include/machine/types.h \ + /usr/include/sys/cdefs.h /usr/include/machine/endian.h \ + /usr/include/stdlib.h /usr/include/string.h mlvwm.h \ + /usr/X11R6/include/X11/Xlib.h /usr/X11R6/include/X11/X.h \ + /usr/X11R6/include/X11/Xfuncproto.h /usr/X11R6/include/X11/Xosdefs.h \ + /usr/include/stddef.h /usr/X11R6/include/X11/Xutil.h \ + /usr/X11R6/include/X11/cursorfont.h /usr/X11R6/include/X11/xpm.h \ + sun_headers.h /usr/include/sys/wait.h screen.h menus.h config.h \ + misc.h /usr/include/unistd.h /usr/include/sys/unistd.h borders.h \ + /usr/X11R6/include/X11/extensions/shape.h +config.o: config.c /usr/include/stdio.h /usr/include/sys/types.h \ + /usr/include/machine/ansi.h /usr/include/machine/types.h \ + /usr/include/sys/cdefs.h /usr/include/machine/endian.h \ + /usr/include/stdlib.h /usr/include/string.h /usr/include/ctype.h \ + /usr/include/runetype.h mlvwm.h /usr/X11R6/include/X11/Xlib.h \ + /usr/X11R6/include/X11/X.h /usr/X11R6/include/X11/Xfuncproto.h \ + /usr/X11R6/include/X11/Xosdefs.h /usr/include/stddef.h \ + /usr/X11R6/include/X11/Xutil.h /usr/X11R6/include/X11/cursorfont.h \ + /usr/X11R6/include/X11/xpm.h sun_headers.h /usr/include/sys/wait.h \ + screen.h menus.h config.h misc.h /usr/include/unistd.h \ + /usr/include/sys/unistd.h +event.o: event.c /usr/include/stdio.h /usr/include/sys/types.h \ + /usr/include/machine/ansi.h /usr/include/machine/types.h \ + /usr/include/sys/cdefs.h /usr/include/machine/endian.h \ + /usr/include/stdlib.h /usr/include/unistd.h /usr/include/sys/unistd.h \ + /usr/include/string.h /usr/include/sys/time.h /usr/include/time.h \ + /usr/X11R6/include/X11/Xatom.h mlvwm.h /usr/X11R6/include/X11/Xlib.h \ + /usr/X11R6/include/X11/X.h /usr/X11R6/include/X11/Xfuncproto.h \ + /usr/X11R6/include/X11/Xosdefs.h /usr/include/stddef.h \ + /usr/X11R6/include/X11/Xutil.h /usr/X11R6/include/X11/cursorfont.h \ + /usr/X11R6/include/X11/xpm.h sun_headers.h /usr/include/sys/wait.h \ + screen.h menus.h config.h borders.h add_window.h functions.h misc.h \ + balloon.h /usr/X11R6/include/X11/extensions/shape.h +functions.o: functions.c /usr/include/stdio.h /usr/include/sys/types.h \ + /usr/include/machine/ansi.h /usr/include/machine/types.h \ + /usr/include/sys/cdefs.h /usr/include/machine/endian.h \ + /usr/include/stdlib.h /usr/include/string.h /usr/include/unistd.h \ + /usr/include/sys/unistd.h mlvwm.h /usr/X11R6/include/X11/Xlib.h \ + /usr/X11R6/include/X11/X.h /usr/X11R6/include/X11/Xfuncproto.h \ + /usr/X11R6/include/X11/Xosdefs.h /usr/include/stddef.h \ + /usr/X11R6/include/X11/Xutil.h /usr/X11R6/include/X11/cursorfont.h \ + /usr/X11R6/include/X11/xpm.h sun_headers.h /usr/include/sys/wait.h \ + screen.h menus.h config.h functions.h borders.h event.h misc.h \ + balloon.h +menus.o: menus.c /usr/include/stdio.h /usr/include/sys/types.h \ + /usr/include/machine/ansi.h /usr/include/machine/types.h \ + /usr/include/sys/cdefs.h /usr/include/machine/endian.h \ + /usr/include/stdlib.h /usr/include/string.h /usr/include/ctype.h \ + /usr/include/runetype.h mlvwm.h /usr/X11R6/include/X11/Xlib.h \ + /usr/X11R6/include/X11/X.h /usr/X11R6/include/X11/Xfuncproto.h \ + /usr/X11R6/include/X11/Xosdefs.h /usr/include/stddef.h \ + /usr/X11R6/include/X11/Xutil.h /usr/X11R6/include/X11/cursorfont.h \ + /usr/X11R6/include/X11/xpm.h sun_headers.h /usr/include/sys/wait.h \ + screen.h menus.h config.h event.h functions.h misc.h \ + /usr/include/unistd.h /usr/include/sys/unistd.h add_window.h \ + borders.h /usr/X11R6/include/X11/Xatom.h \ + /usr/X11R6/include/X11/Xresource.h \ + /usr/X11R6/include/X11/extensions/shape.h +misc.o: misc.c /usr/include/stdio.h /usr/include/sys/types.h \ + /usr/include/machine/ansi.h /usr/include/machine/types.h \ + /usr/include/sys/cdefs.h /usr/include/machine/endian.h \ + /usr/include/stdlib.h /usr/include/string.h /usr/include/ctype.h \ + /usr/include/runetype.h /usr/include/unistd.h \ + /usr/include/sys/unistd.h /usr/include/sys/time.h /usr/include/time.h \ + mlvwm.h /usr/X11R6/include/X11/Xlib.h /usr/X11R6/include/X11/X.h \ + /usr/X11R6/include/X11/Xfuncproto.h /usr/X11R6/include/X11/Xosdefs.h \ + /usr/include/stddef.h /usr/X11R6/include/X11/Xutil.h \ + /usr/X11R6/include/X11/cursorfont.h /usr/X11R6/include/X11/xpm.h \ + sun_headers.h /usr/include/sys/wait.h menus.h screen.h config.h +mlvwm.o: mlvwm.c /usr/include/stdio.h /usr/include/sys/types.h \ + /usr/include/machine/ansi.h /usr/include/machine/types.h \ + /usr/include/sys/cdefs.h /usr/include/machine/endian.h \ + /usr/include/stdlib.h /usr/include/signal.h /usr/include/sys/signal.h \ + /usr/include/machine/signal.h /usr/include/machine/trap.h \ + /usr/include/string.h /usr/include/unistd.h /usr/include/sys/unistd.h \ + /usr/include/fcntl.h mlvwm.h /usr/X11R6/include/X11/Xlib.h \ + /usr/X11R6/include/X11/X.h /usr/X11R6/include/X11/Xfuncproto.h \ + /usr/X11R6/include/X11/Xosdefs.h /usr/include/stddef.h \ + /usr/X11R6/include/X11/Xutil.h /usr/X11R6/include/X11/cursorfont.h \ + /usr/X11R6/include/X11/xpm.h sun_headers.h /usr/include/sys/wait.h \ + screen.h menus.h config.h event.h add_window.h functions.h misc.h \ + /usr/X11R6/include/X11/Xproto.h /usr/X11R6/include/X11/Xmd.h \ + /usr/X11R6/include/X11/Xprotostr.h /usr/X11R6/include/X11/Xatom.h \ + /usr/X11R6/include/X11/Xresource.h \ + /usr/X11R6/include/X11/extensions/shape.h \ + /usr/X11R6/include/X11/Xlocale.h /usr/include/locale.h +wild.o: wild.c /usr/include/stdio.h /usr/include/sys/types.h \ + /usr/include/machine/ansi.h /usr/include/machine/types.h \ + /usr/include/sys/cdefs.h /usr/include/machine/endian.h diff --git a/mlvwm/Imakefile b/mlvwm/Imakefile new file mode 100644 index 0000000..c89ccd0 --- /dev/null +++ b/mlvwm/Imakefile @@ -0,0 +1,31 @@ +XCOMM Imakefile for MLVWM + +#include "../configure.h" + + VERSION = 0.8.9 + COMPILE_OPTIONS = -DVERSION=\"$(VERSION)\" \ + -DCONFIGNAME=\"$(MLVWMRC)\" \ + -DMLVWMLIBDIR=\"$(MLVWMLIBDIR)\" + + TARGET = mlvwm + +XCOMM Do not change from here ! + + DEFINES = $(MLVWMDEFINES) $(COMPILE_OPTIONS) + LOCAL_LIBRARIES = -lXpm $(XLIB) $(MLVWMLIBRARIES) + SRCS = add_window.c\ + balloon.c\ + borders.c\ + config.c\ + event.c\ + functions.c\ + menus.c\ + misc.c\ + mlvwm.c\ + wild.c +OBJS = $(SRCS:.c=.o) + +all::$(TARGET) +InstallProgram($(TARGET),$(MLVWMBINDIR)) +DependTarget() +SingleProgramTarget($(TARGET),$(OBJS),NullParameter,$(LOCAL_LIBRARIES)) diff --git a/mlvwm/Makefile.make b/mlvwm/Makefile.make new file mode 100644 index 0000000..289ad55 --- /dev/null +++ b/mlvwm/Makefile.make @@ -0,0 +1,17 @@ +VERSION=\"0.6.2\" +CFLAGS = -g -Wall -DVERSION=$(VERSION) -fpcc-struct-return -DCONFIGNAME=\".mlvwmrc\" +CC = gcc +LDFLAGS = -lXpm -lXext -lX11 +CPPFLAGS = -I/usr/X11R6/include +SRC = add_window.c borders.c config.c event.c menus.c mlvwm.c functions.c\ + sound.c +OBJS = $(SRC:.c=.o) +TARGET = mlvwm + +all:$(TARGET) +$(TARGET):$$@.c $(OBJS) + ${CC} -o $@ $(OBJS) $(CFLAGS) $(LDFLAGS) $(LDLIBS) +clean: + rm -f $(TARGET) *.o core *% *~ #*# +clean.bak: + rm -f core *% *~ #*# diff --git a/mlvwm/add_window.c b/mlvwm/add_window.c new file mode 100644 index 0000000..fca2ac9 --- /dev/null +++ b/mlvwm/add_window.c @@ -0,0 +1,666 @@ +/****************************************************************************/ +/* This module is based on fvwm, but has been siginificantly modified */ +/* by TakaC Hasegawa (tak@bioele.nuee.nagoya-u.ac.jp) */ +/****************************************************************************/ +/**************************************************************************** + * This module is based on Twm, but has been siginificantly modified + * by Rob Nation (nation@rocket.sanders.lockheed.com) + ****************************************************************************/ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + +#include +#include + +#include "mlvwm.h" +#include "screen.h" +#include "menus.h" +#include "borders.h" +#include "misc.h" + +#include +#include +#include + +char NoName[] = "Untitled"; + +extern int matchWildcards( char *, char * ); + +/* Used to parse command line of clients for specific desk requests. */ +/* Todo: check for multiple desks. */ +static XrmDatabase db; +static XrmOptionDescRec table [] = { + /* Want to accept "-workspace N" or -xrm "afterstep*desk:N" as options + * to specify the desktop. I have to include dummy options that + * are meaningless since Xrm seems to allow -w to match -workspace + * if there would be no ambiguity. */ + {"-workspace", "*desk", XrmoptionSepArg, (caddr_t) NULL}, + {"-xrm", NULL, XrmoptionResArg, (caddr_t) NULL}, +}; + +styles *lookupstyles( char *name, XClassHint *class ) +{ + styles *nptr, *style=NULL; + + /* look for the name first */ + for( nptr = Scr.style_list; nptr != NULL; nptr = nptr->next){ + if( matchWildcards( nptr->name, name ) ) + style = nptr; + if( class ){ + if( matchWildcards( nptr->name, class->res_name ) ) + style = nptr; + if( matchWildcards( nptr->name, class->res_class ) ) + style = nptr; + } + } + if( style->iconname && !(style->miniicon) ) + style->miniicon = ReadIcon( style->iconname, NULL, False ); + return style; +} + +void create_resizebox( MlvwmWindow *tmp_win ) +{ + unsigned long valuemask; + XSetWindowAttributes attributes; + + valuemask = CWCursor | CWEventMask | CWBackPixel; + attributes.event_mask = ButtonPressMask | ButtonReleaseMask | ExposureMask; + attributes.background_pixel = WhitePixel( dpy, Scr.screen ); + attributes.cursor = Scr.MlvwmCursors[RESIZE]; + + tmp_win->resize_b = XCreateWindow( dpy, tmp_win->frame, + tmp_win->frame_w-2-SBAR_WH, + tmp_win->frame_h-2-SBAR_WH, + SBAR_WH+(Scr.flags&SYSTEM8?1:0), + SBAR_WH+(Scr.flags&SYSTEM8?1:0), + Scr.flags&SYSTEM8?0:1, + CopyFromParent, InputOutput, + CopyFromParent, + valuemask, &attributes ); + XSaveContext( dpy, tmp_win->resize_b, MlvwmContext, (caddr_t)tmp_win ); +} + +void create_scrollbar( MlvwmWindow *tmp_win ) +{ + unsigned long valuemask; + XSetWindowAttributes attributes; + int title_height; + int lp; + + title_height = tmp_win->flags & TITLE ? TITLE_HEIGHT : -1; + valuemask = CWCursor | CWEventMask | CWBackPixel; + attributes.event_mask = ButtonPressMask | ButtonReleaseMask | ExposureMask + | EnterWindowMask | LeaveWindowMask; + attributes.background_pixel = WhitePixel( dpy, Scr.screen ); + if( tmp_win->flags&SBARV ){ + attributes.cursor = Scr.MlvwmCursors[SBARV_CURSOR]; + tmp_win->scroll_v[0] = XCreateWindow( dpy, tmp_win->frame, + tmp_win->frame_w-2-SBAR_WH, + title_height, + SBAR_WH, tmp_win->attr.height, 1, + CopyFromParent, InputOutput, + CopyFromParent, + valuemask, &attributes ); + tmp_win->scroll_v[1] = XCreateWindow( dpy, tmp_win->scroll_v[0], + 0, 0, + SBAR_WH, SBAR_WH, 0, + CopyFromParent, InputOutput, + CopyFromParent, + valuemask, &attributes ); + tmp_win->scroll_v[2] = XCreateWindow( dpy, tmp_win->scroll_v[0], + 0, 0, + SBAR_WH, SBAR_WH, 0, + CopyFromParent, InputOutput, + CopyFromParent, + valuemask, &attributes ); + tmp_win->scroll_v[3] = XCreateWindow( dpy, tmp_win->scroll_v[0], + 0, 0, + SBAR_WH, SBAR_WH, 0, + CopyFromParent, InputOutput, + CopyFromParent, + valuemask, &attributes ); + XMapSubwindows( dpy, tmp_win->scroll_v[0] ); + if( !(tmp_win->flags&SCROLL) ) XUnmapWindow( dpy, tmp_win->scroll_v[3] ); + for( lp=0; lp<4; lp++ ) + XSaveContext( dpy, tmp_win->scroll_v[lp], MlvwmContext, (caddr_t)tmp_win ); + } + if( tmp_win->flags&SBARH ){ + attributes.cursor = Scr.MlvwmCursors[SBARH_CURSOR]; + tmp_win->scroll_h[0] = XCreateWindow( dpy, tmp_win->frame, + -1, tmp_win->frame_h-2-SBAR_WH, + tmp_win->attr.width, SBAR_WH, 1, + CopyFromParent, InputOutput, + CopyFromParent, + valuemask, &attributes ); + tmp_win->scroll_h[1] = XCreateWindow( dpy, tmp_win->scroll_h[0], + 0, 0, + SBAR_WH, SBAR_WH, 0, + CopyFromParent, InputOutput, + CopyFromParent, + valuemask, &attributes ); + tmp_win->scroll_h[2] = XCreateWindow( dpy, tmp_win->scroll_h[0], + 0, 0, + SBAR_WH, SBAR_WH, 0, + CopyFromParent, InputOutput, + CopyFromParent, + valuemask, &attributes ); + tmp_win->scroll_h[3] = XCreateWindow( dpy, tmp_win->scroll_h[0], + 0, 0, + SBAR_WH, SBAR_WH, 0, + CopyFromParent, InputOutput, + CopyFromParent, + valuemask, &attributes ); + XMapSubwindows( dpy, tmp_win->scroll_h[0] ); + if( !(tmp_win->flags&SCROLL) ) XUnmapWindow( dpy, tmp_win->scroll_h[3] ); + for( lp=0; lp<4; lp++ ) + XSaveContext(dpy,tmp_win->scroll_h[lp],MlvwmContext,(caddr_t)tmp_win); + } +} + +void create_titlebar( MlvwmWindow *tmp_win ) +{ + unsigned long valuemask; + XSetWindowAttributes attributes; + + valuemask = CWCursor | CWEventMask | CWBackPixel; + attributes.event_mask = ButtonPressMask | ButtonReleaseMask | ExposureMask; + attributes.background_pixel = WhitePixel( dpy, Scr.screen ); + attributes.cursor = Scr.MlvwmCursors[TITLE_CURSOR]; + tmp_win->title_w = XCreateWindow( dpy, tmp_win->frame, + Scr.flags&SYSTEM8?2:0, 0, + tmp_win->attr.width+SBAR_WH+1, + TITLE_HEIGHT, 0, + CopyFromParent, InputOutput, + CopyFromParent, + valuemask, &attributes ); + attributes.event_mask = ( ButtonPressMask|ButtonReleaseMask|ExposureMask + | EnterWindowMask | LeaveWindowMask ); + + if( tmp_win->flags&CLOSER ){ + attributes.cursor = Scr.MlvwmCursors[DESTROY]; + tmp_win->close_b = XCreateWindow( dpy, tmp_win->title_w, + Scr.flags&SYSTEM8?4:BOXSIZE+1, + (TITLE_HEIGHT-BOXSIZE)/2, + BOXSIZE, BOXSIZE, 0, + CopyFromParent, InputOutput, + CopyFromParent, + valuemask, &attributes ); + XSaveContext( dpy, tmp_win->close_b, MlvwmContext, (caddr_t)tmp_win ); + } + if( tmp_win->flags&MINMAXR ){ + attributes.cursor = Scr.MlvwmCursors[SELECT]; + tmp_win->minmax_b = XCreateWindow( dpy, tmp_win->title_w, + tmp_win->frame_w-BOXSIZE*2-1, + (TITLE_HEIGHT-BOXSIZE)/2, + BOXSIZE, BOXSIZE, 0, + CopyFromParent, InputOutput, + CopyFromParent, + valuemask, &attributes ); + XSaveContext( dpy, tmp_win->minmax_b, MlvwmContext, (caddr_t)tmp_win ); + } + if( tmp_win->flags&SHADER ){ + attributes.cursor = Scr.MlvwmCursors[SELECT]; + tmp_win->shade_b = XCreateWindow( dpy, tmp_win->title_w, + tmp_win->frame_w-BOXSIZE*2-1, + (TITLE_HEIGHT-BOXSIZE)/2, + BOXSIZE, BOXSIZE, 0, + CopyFromParent, InputOutput, + CopyFromParent, + valuemask, &attributes ); + XSaveContext( dpy, tmp_win->shade_b, MlvwmContext, (caddr_t)tmp_win ); + } + XMapSubwindows( dpy, tmp_win->title_w ); + XSaveContext( dpy, tmp_win->title_w, MlvwmContext, (caddr_t)tmp_win ); +} + +void FetchWmProtocols (MlvwmWindow *tmp) +{ + unsigned long flags = 0L; + Atom *protocols = NULL, *ap; + int i, n; + Atom atype; + int aformat; + unsigned long bytes_remain,nitems; + + if(tmp == NULL) return; + /* First, try the Xlib function to read the protocols. + * This is what Twm uses. */ + if (XGetWMProtocols (dpy, tmp->w, &protocols, &n)){ + for (i = 0, ap = protocols; i < n; i++, ap++){ + if (*ap == (Atom)_XA_WM_TAKE_FOCUS) flags |= DoesWmTakeFocus; + if (*ap == (Atom)_XA_WM_DELETE_WINDOW) flags |= DoesWmDeleteWindow; + } + if (protocols) XFree ((char *) protocols); + } + else{ + /* Next, read it the hard way. mosaic from Coreldraw needs to + * be read in this way. */ + if ((XGetWindowProperty(dpy, tmp->w, _XA_WM_PROTOCOLS, 0L, 10L, False, + _XA_WM_PROTOCOLS, &atype, &aformat, &nitems, + &bytes_remain, + (unsigned char **)&protocols))==Success){ + for (i = 0, ap = protocols; i < nitems; i++, ap++){ + if (*ap == (Atom)_XA_WM_TAKE_FOCUS) flags |= DoesWmTakeFocus; + if (*ap == (Atom)_XA_WM_DELETE_WINDOW) + flags |= DoesWmDeleteWindow; + } + if (protocols) XFree ((char *) protocols); + } + } + if( XGetWindowProperty(dpy, tmp->w, _XA_WM_STATE, 0L, 3L, False, + _XA_WM_STATE, &atype, &aformat, &nitems, + &bytes_remain, + (unsigned char **)&protocols)==Success && + protocols != NULL && *protocols==IconicState) + tmp->flags |= STARTICONIC; + + tmp->flags |= flags; + return; +} + +void GrabKeys( MlvwmWindow *tmp_win ) +{ + ShortCut *tmp; + + for (tmp = Scr.ShortCutRoot; tmp != NULL; tmp = tmp->next){ + XGrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->frame, True, + GrabModeAsync, GrabModeAsync); + } + return; +} + +void GetWindowSizeHints( MlvwmWindow *mw ) +{ + long supplied=0; + + if( !XGetWMNormalHints( dpy, mw->w,&(mw->hints), &supplied ) ) + mw->hints.flags = 0; + if (mw->hints.flags & PResizeInc){ + if (mw->hints.width_inc == 0) + mw->hints.width_inc = 1; + if (mw->hints.height_inc == 0) + mw->hints.height_inc = 1; + } + else{ + mw->hints.width_inc = 1; + mw->hints.height_inc = 1; + } + + if(!(mw->hints.flags & PBaseSize)){ + mw->hints.base_width = 0; + mw->hints.base_height = 0; + } + if(!(mw->hints.flags & PMinSize)){ + mw->hints.min_width = mw->hints.base_width; + mw->hints.min_height = mw->hints.base_height; + } + if(!(mw->hints.flags & PMaxSize)){ + mw->hints.max_width = MAX_WINDOW_WIDTH; + mw->hints.max_height = MAX_WINDOW_HEIGHT; + } + if(mw->hints.max_width < mw->hints.min_width) + mw->hints.max_width = MAX_WINDOW_WIDTH; + if(mw->hints.max_height < mw->hints.min_height) + mw->hints.max_height = MAX_WINDOW_HEIGHT; + + if(mw->hints.min_height <= 0) + mw->hints.min_height = 1; + if(mw->hints.min_width <= 0) + mw->hints.min_width = 1; +} + +void SmartPlacement( MlvwmWindow *t, int width, int height, int *x, int *y ) +{ + int temp_h,temp_w; + int test_x = 0,test_y = 0; + int loc_ok = False, tw,tx,ty,th; + MlvwmWindow *test_window; + + temp_h = height; + temp_w = width; + + while( test_y+temp_hDesk==Scr.currentdesk && + !(Scr.flags&STARTING))|| + test_window->Desk==t->Desk) && + !(test_window->flags&HIDED) && + !(test_window->flags&TRANSIENT) ){ + if( test_window!=t ){ + tw=test_window->frame_w+2; + th=test_window->frame_h+2; + tx = test_window->frame_x; + ty = test_window->frame_y; + if( tx<=test_x+width && tx+tw>=test_x && + ty<=test_y+height && ty+th>=test_y ){ + loc_ok = False; + test_x = tx + tw; + } + } + } + test_window = test_window->next; + } + test_x +=1; + } + test_y +=1; + } + if( loc_ok==False ){ + if( Scr.ActiveWin ){ + *x = Scr.ActiveWin->frame_x+TITLE_HEIGHT; + *y = Scr.ActiveWin->frame_y+TITLE_HEIGHT; + } + } + else{ + *x = test_x; + *y = test_y; + } + return; +} + + +MlvwmWindow *AddWindow( Window win ) +{ + MlvwmWindow *tmp_win, *last; + unsigned long valuemask; + XSetWindowAttributes attributes; + int title_height; + XTextProperty text_prop; + Atom atype; + int aformat; + int diff_x=0, diff_y=0; + styles *tmp_style; +#ifdef USE_LOCALE + int num; + char **list; +#endif + unsigned long nitems, bytes_remain; + unsigned char *prop; + + XrmValue rm_value; + int client_argc; + char **client_argv = NULL, *str_type; + Bool status; + + tmp_win = calloc( 1, sizeof( MlvwmWindow ) ); + + tmp_win->flags = NORMALWIN; + if( Scr.flags&SYSTEM8 ) tmp_win->flags |= SHADER; + tmp_win->size_w = Scr.MyDisplayWidth*90./100.; + tmp_win->size_h = Scr.MyDisplayHeight*90./100.; + + tmp_win->miniicon = NULL; + + if( Scr.ActiveWin ) + last = Scr.ActiveWin; + else + for ( last = (MlvwmWindow *)&Scr.MlvwmRoot; + last->next != NULL; + last = last->next); + if( last->next ){ + tmp_win->next = last->next; + last->next->prev = tmp_win; + } + last->next = (struct MlvwmWindow *)tmp_win; + tmp_win->prev = last; + if( tmp_win==(MlvwmWindow *)0 ) return NULL; + tmp_win->flags = 0; + tmp_win->w = win; + + XGetWindowAttributes( dpy, tmp_win->w, &tmp_win->attr ); + if( XGetWMName( dpy, tmp_win->w, &text_prop) != 0 ){ +#ifdef USE_LOCALE + if(text_prop.value) + text_prop.nitems = strlen(text_prop.value); + if(XmbTextPropertyToTextList(dpy, &text_prop, &list, &num) >= Success + && num > 0 && *list) + tmp_win->name = *list; + else + tmp_win->name = NoName; +#else + tmp_win->name = (char *)text_prop.value; +#endif + } + else + tmp_win->name = NoName; + tmp_win->class = NoClass; + XGetClassHint(dpy, tmp_win->w, &tmp_win->class); + if (tmp_win->class.res_name == NULL) + tmp_win->class.res_name = NoName; + if (tmp_win->class.res_class == NULL) + tmp_win->class.res_class = NoName; + + tmp_win->wmhints = XGetWMHints( dpy, tmp_win->w ); + tmp_win->old_bw = tmp_win->attr.border_width; + + { + int xws, yws, xbs, ybs; + unsigned wws, hws, wbs, hbs; + int boundingShaped, clipShaped; + + XShapeSelectInput (dpy, tmp_win->w, ShapeNotifyMask); + XShapeQueryExtents (dpy, tmp_win->w, + &boundingShaped, &xws, &yws, &wws, &hws, + &clipShaped, &xbs, &ybs, &wbs, &hbs); + tmp_win->wShaped = boundingShaped; + } + + GetWindowSizeHints( tmp_win ); + if( (tmp_style = lookupstyles( tmp_win->name, &tmp_win->class ))!=NULL ){ + tmp_win->flags = tmp_style->flags; + if( tmp_style->maxmizescale ){ + tmp_win->size_w = + Scr.MyDisplayWidth*(double)tmp_style->maxmizescale/100.; + tmp_win->size_h = (Scr.MyDisplayHeight-MENUB_H)* + (double)tmp_style->maxmizescale/100.; + } + else{ + tmp_win->size_w = + tmp_style->maxmizesize_w*tmp_win->hints.width_inc+ + tmp_win->hints.base_width; + tmp_win->size_h = + tmp_style->maxmizesize_h*tmp_win->hints.height_inc+ + tmp_win->hints.base_height; + tmp_win->size_w += SBAR_WH+1+2; + if( !(tmp_win->flags&SBARV) ) tmp_win->size_w-=(SBAR_WH+1); + tmp_win->size_h += SBAR_WH+TITLE_HEIGHT+2+2; + if( !(tmp_win->flags&SBARH) ) tmp_win->size_h-=(SBAR_WH+1); + if( Scr.flags&SYSTEM8 ){ + tmp_win->size_w += 12; + tmp_win->size_h += 6; + } + } + tmp_win->miniicon = tmp_style->miniicon; + if( !tmp_win->miniicon ) + if( (tmp_style = lookupstyles( "*", NULL ))!=NULL && + tmp_style->miniicon ) + tmp_win->miniicon = tmp_style->miniicon; + } + if(XGetTransientForHint(dpy, tmp_win->w, &tmp_win->transientfor)){ + tmp_win->flags &= ~NORMALWIN; + if( Scr.flags&SYSTEM8 ) tmp_win->flags &= ~SHADER; + tmp_win->flags |= TRANSIENT; + if( !(tmp_win->flags&NONTRANSIENTDECORATE) ) + tmp_win->flags |= TITLE; + } + + title_height = tmp_win->flags & TITLE ? TITLE_HEIGHT : -1; + + tmp_win->Desk = Scr.currentdesk; + /* Find out if the client requested a specific desk on the command line. */ + if ( XGetCommand( dpy, tmp_win->w, &client_argv, &client_argc ) ) { + XrmParseCommand( &db, table, 2, "mlvwm", &client_argc, client_argv ); + status = XrmGetResource( db, "mlvwm.desk", "Mlvwm.Desk", + &str_type, &rm_value ); + if ((status == True) && (rm_value.size != 0)) + tmp_win->Desk = atoi(rm_value.addr); + XrmDestroyDatabase (db); + db = NULL; + } + if ((XGetWindowProperty(dpy, tmp_win->w, _XA_WM_DESKTOP, 0L, 1L, True, + _XA_WM_DESKTOP, &atype, &aformat, &nitems, + &bytes_remain, &prop))==Success){ + if(prop != NULL){ + tmp_win->Desk = *(unsigned long *)prop; + XFree(prop); + } + } + if( tmp_win->Desk<0 || tmp_win->Desk>=Scr.n_desktop ) + tmp_win->Desk = 0; + + if( tmp_win->flags&(TITLE|SBARV|SBARH|RESIZER) ){ + tmp_win->frame_w = tmp_win->attr.width+SBAR_WH+1+2; + diff_x = 1; + diff_y = title_height+1; + if( !(tmp_win->flags&SBARV) ) tmp_win->frame_w-=(SBAR_WH+1); + tmp_win->frame_h = tmp_win->attr.height+SBAR_WH+title_height+2+2; + if( !(tmp_win->flags&SBARH) ) tmp_win->frame_h-=(SBAR_WH+1); + if( Scr.flags&SYSTEM8 ){ + diff_x += 6; + tmp_win->frame_w += 12; + tmp_win->frame_h += 6; + } + } + else{ + diff_x = (5+tmp_win->old_bw); + diff_y = (5+tmp_win->old_bw); + tmp_win->frame_w = tmp_win->attr.width+2+5*2; + tmp_win->frame_h = tmp_win->attr.height+2+5*2; + } + + if( !(tmp_win->flags & TRANSIENT) && + !(tmp_win->hints.flags & USPosition) && + !(tmp_win->hints.flags & PPosition) ) + SmartPlacement( tmp_win, tmp_win->frame_w+2, tmp_win->frame_h+2, + &(tmp_win->attr.x), &(tmp_win->attr.y) ); + + tmp_win->diff_x = tmp_win->attr.x; + tmp_win->diff_y = tmp_win->attr.y; + + tmp_win->frame_x = tmp_win->attr.x + tmp_win->old_bw-1; + tmp_win->frame_y = tmp_win->attr.y + tmp_win->old_bw-1; + + if( !(tmp_win->flags&TRANSIENT) ){ + tmp_win->frame_x = + tmp_win->frame_x+tmp_win->frame_w < Scr.MyDisplayWidth ? + tmp_win->frame_x : Scr.MyDisplayWidth-tmp_win->frame_w-2; + tmp_win->frame_x = tmp_win->frame_x<0 ? 0 : tmp_win->frame_x; + + tmp_win->frame_y = + tmp_win->attr.y+tmp_win->frame_h < Scr.MyDisplayHeight ? + tmp_win->frame_y : Scr.MyDisplayHeight-tmp_win->frame_h-2; + if( tmp_win->frame_yframe_y = MENUB_H; + } + else{ + tmp_win->frame_x -= diff_x; + tmp_win->frame_y -= diff_y; + } + + valuemask = CWCursor | CWEventMask | CWBackPixel; + + attributes.cursor = Scr.MlvwmCursors[TITLE_CURSOR]; + attributes.background_pixel = WhitePixel( dpy, Scr.screen ); + attributes.event_mask = (SubstructureRedirectMask | ButtonPressMask | + ButtonReleaseMask |EnterWindowMask | + ExposureMask | LeaveWindowMask ); + tmp_win->frame = XCreateWindow( dpy, Scr.Root, + tmp_win->frame_x, tmp_win->frame_y, + tmp_win->frame_w, tmp_win->frame_h, 1, + CopyFromParent, InputOutput, CopyFromParent, + valuemask, &attributes ); + attributes.cursor = Scr.MlvwmCursors[DEFAULT]; + attributes.background_pixel = WhitePixel( dpy, Scr.screen ); + tmp_win->Parent = XCreateWindow( dpy, tmp_win->frame, + -1, title_height, + tmp_win->attr.width, tmp_win->attr.height, + 1, CopyFromParent, + InputOutput,CopyFromParent, + valuemask,&attributes); + if( tmp_win->flags&TITLE ) create_titlebar( tmp_win ); + if( tmp_win->flags&RESIZER ) create_resizebox( tmp_win ); + if( tmp_win->flags&SBARH || tmp_win->flags&SBARV ) + create_scrollbar( tmp_win ); + if( !(tmp_win->flags&( TITLE | SBARV | SBARH | RESIZER )) ) + XMoveWindow( dpy, tmp_win->Parent, 5, 5 ); + XSetWindowBorderWidth( dpy, tmp_win->w, 0 ); + + XSaveContext( dpy, tmp_win->frame, MlvwmContext, (caddr_t)tmp_win ); + XSaveContext( dpy, tmp_win->Parent, MlvwmContext, (caddr_t)tmp_win ); + XSaveContext( dpy, tmp_win->w, MlvwmContext, (caddr_t)tmp_win ); + XAddToSaveSet( dpy, win ); + + XUnmapWindow( dpy, tmp_win->w ); + XRaiseWindow( dpy, tmp_win->Parent ); + if( tmp_win->flags&RESIZER ) + XRaiseWindow( dpy, tmp_win->resize_b ); + XReparentWindow( dpy, tmp_win->w, tmp_win->Parent, 0, 0 ); + + valuemask = (CWEventMask | CWDontPropagate ); + attributes.event_mask = (StructureNotifyMask | PropertyChangeMask | + VisibilityChangeMask | EnterWindowMask | + LeaveWindowMask | + ColormapChangeMask | FocusChangeMask); + attributes.do_not_propagate_mask = ( ButtonPressMask | ButtonReleaseMask ); + XChangeWindowAttributes( dpy, tmp_win->w, valuemask, &attributes ); + SetUpFrame( tmp_win, tmp_win->frame_x, tmp_win->frame_y, + tmp_win->frame_w, tmp_win->frame_h, True ); + XMapSubwindows( dpy, tmp_win->Parent ); + XMapWindow( dpy, tmp_win->Parent ); + + { + Window JunkRoot, JunkChild; + int JunkX, JunkY; + unsigned int JunkWidth, JunkHeight, JunkBW, JunkDepth; + int a, b; + + XGetGeometry(dpy, tmp_win->w, &JunkRoot, &JunkX, &JunkY, + &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth); + XTranslateCoordinates(dpy,tmp_win->frame,Scr.Root,JunkX,JunkY, + &a,&b,&JunkChild); + tmp_win->diff_x -= a; + tmp_win->diff_y -= b; + } + + FetchWmProtocols (tmp_win); + + if( !(Scr.flags&FOLLOWTOMOUSE) ){ + XGrabButton(dpy, AnyButton, AnyModifier, tmp_win->frame,True, + ButtonPressMask, GrabModeSync,GrabModeAsync,None, + Scr.MlvwmCursors[SYS]); + } + + tmp_win->win_w = tmp_win->frame_w; + tmp_win->win_h = tmp_win->frame_h; + + GrabKeys( tmp_win ); + + return tmp_win; +} diff --git a/mlvwm/add_window.h b/mlvwm/add_window.h new file mode 100644 index 0000000..0736599 --- /dev/null +++ b/mlvwm/add_window.h @@ -0,0 +1,20 @@ +/**************************************************************************** + * This module is all original code + * by TakaC Hasegawa (tak@bioele.nuee.nagoya-u.ac.jp + * Copyright 1996, TakaC Hasegawa + * You may use this code for any purpose, as long as the original + * copyright remains in the source code and all documentation + ****************************************************************************/ +#ifndef _ADD_WINDOW_ +#define _ADD_WINDOW_ + +extern void FetchWmProtocols( MlvwmWindow * ); +extern styles *lookupstyles( char *, XClassHint * ); +extern void create_resizebox( MlvwmWindow * ); +extern void create_scrollbar( MlvwmWindow * ); +extern void create_titlebar( MlvwmWindow * ); +extern MlvwmWindow *AddWindow( Window ); +extern void GetWindowSizeHints( MlvwmWindow * ); + +extern char NoName[]; +#endif diff --git a/mlvwm/balloon.c b/mlvwm/balloon.c new file mode 100644 index 0000000..199afe1 --- /dev/null +++ b/mlvwm/balloon.c @@ -0,0 +1,365 @@ +/****************************************************************************/ +/* This module is mostly all new */ +/* by TakaC Hasegawa (tak@bioele.nuee.nagoya-u.ac.jp) */ +/* Copyright 1996 TakaC Hasegawa. No restrictions are placed on this code, */ +/* as long as the copyright notice is preserved */ +/****************************************************************************/ + +#include +#include + +#include "mlvwm.h" +#include "screen.h" +#include "misc.h" +#include "event.h" + +#include + +static char *WinLabel[] = { + "Name:", + "Class:", "Resource:", + "X:", "Y:", + "Width:", "Height:", + NULL }; + +void CreateBalloonWindow( void ) +{ + unsigned long valuemask; + XSetWindowAttributes attributes; + + valuemask = CWBackPixel | CWCursor | CWEventMask; + attributes.background_pixel = WhitePixel( dpy, Scr.screen ); + attributes.cursor = Scr.MlvwmCursors[DEFAULT]; + attributes.event_mask = ExposureMask| LeaveWindowMask; + Scr.Balloon = XCreateWindow( dpy, Scr.Root, 0, 0, 30, 30 , 0, + CopyFromParent, InputOutput, + CopyFromParent, + valuemask, &attributes ); +} + +void +DrawBackGround( int fx, int fy, int xoff, int yoff, int width, int height ) +{ + XPoint tri[3]; + + XDrawArc( dpy, Scr.Balloon, Scr.BlackGC, + xoff+0, yoff+0, 20, 20, 90*64, 90*64 ); + XDrawArc( dpy, Scr.Balloon, Scr.BlackGC, + xoff+width-21, yoff+0, 20, 20, 0, 90*64 ); + XDrawArc( dpy, Scr.Balloon, Scr.BlackGC, + xoff+width-21, yoff+height-21, 20, 20, 270*64, 90*64 ); + XDrawArc( dpy, Scr.Balloon, Scr.BlackGC, + xoff+0, yoff+height-21, 20, 20, 180*64, 90*64 ); + XDrawLine( dpy, Scr.Balloon, Scr.BlackGC, + xoff+10, yoff+0, xoff+width-11, yoff+0 ); + XDrawLine( dpy, Scr.Balloon, Scr.BlackGC, + xoff+10, yoff+height-1, xoff+width-11, yoff+height-1); + XDrawLine( dpy, Scr.Balloon, Scr.BlackGC, + xoff+0, yoff+10, xoff+0, yoff+height-11 ); + XDrawLine( dpy, Scr.Balloon, Scr.BlackGC, + xoff+width-1, yoff+10, xoff+width-1, yoff+height-11); + + tri[1].x = fx; tri[1].y = fy; + if( fx==0 && fy==height-1 ){ + tri[0].x = fx+20; tri[0].y = fy-20; + tri[2].x = fx+20; tri[2].y = fy-10; + } + if( fx==width-1 && fy==height+20-1 ){ + tri[0].x = fx-20; tri[0].y = fy-20; + tri[2].x = fx-10; tri[2].y = fy-20; + } + if( fx==width+20-1 && fy==0 ){ + tri[0].x = fx-20; tri[0].y = fy+20; + tri[2].x = fx-20; tri[2].y = fy+10; + } + if( fx==0 && fy==0 ){ + tri[0].x = fx+20; tri[0].y = fy+20; + tri[2].x = fx+10; tri[2].y = fy+20; + } + XDrawLines( dpy, Scr.Balloon, Scr.BlackGC, tri, 3, CoordModeOrigin ); + if( fx==0 && fy==height-1 ){ + tri[0].y++; tri[2].y--; + } + if( fx==width-1 && fy==height+20-1 ) tri[0].x++; + if( fx==width+20-1 && fy==0 ) tri[0].y--; + if( fx==0 && fy==0 ){ + tri[0].x--; tri[2].x++; + } + XDrawLine( dpy, Scr.Balloon, Scr.WhiteGC, + tri[0].x, tri[0].y, tri[2].x, tri[2].y ); +} + +void ShapeBalloon( int fx, int fy, int xoff, int yoff, int woff, int hoff, int width, int height ) +{ + XPoint tri[3]; + Pixmap mask; + GC ShapeGC; + + mask = XCreatePixmap( dpy, Scr.Root, width+woff, height+hoff, 1 ); + ShapeGC = XCreateGC( dpy, mask, 0, 0 ); + +#if defined(sun) && !defined(__NetBSD__) + XSetForeground( dpy, ShapeGC, WhitePixel( dpy, Scr.screen )); +#else + XSetForeground( dpy, ShapeGC, BlackPixel( dpy, Scr.screen )); +#endif + XFillRectangle( dpy, mask, ShapeGC, 0, 0, width+woff, height+hoff ); +#if defined(sun) && !defined(__NetBSD__) + XSetForeground( dpy, ShapeGC, BlackPixel( dpy, Scr.screen )); + XSetBackground( dpy, ShapeGC, WhitePixel( dpy, Scr.screen )); +#else + XSetForeground( dpy, ShapeGC, WhitePixel( dpy, Scr.screen )); + XSetBackground( dpy, ShapeGC, BlackPixel( dpy, Scr.screen )); +#endif + + XFillRectangle(dpy, mask, ShapeGC, xoff+10, yoff+0, width-20, 10); + XFillRectangle(dpy, mask, ShapeGC, xoff+10, yoff+height-10, width-20, 10); + XFillRectangle( dpy, mask, ShapeGC, xoff+0, yoff+10, width, height-20 ); + + XFillArc( dpy, mask, ShapeGC, xoff-1, yoff-1, 22, 22, 90*64, 90*64 ); + XFillArc( dpy, mask, ShapeGC, xoff+width-22, yoff-1, 22, 22, 0, 90*64 ); + XFillArc( dpy, mask, ShapeGC, + xoff+width-22, yoff+height-22, 22, 22, 270*64, 90*64 ); + XFillArc( dpy, mask, ShapeGC, + xoff-1, yoff+height-22, 22, 22, 180*64, 90*64 ); + + if( fx==0 && fy==height-1 ){ + tri[0].x = fx+20; tri[0].y = fy-21; + tri[1].x = fx-1; tri[1].y = fy+1; + tri[2].x = fx+20; tri[2].y = fy-9; + } + if( fx==width-1 && fy==height+20-1 ){ + tri[0].x = fx-21; tri[0].y = fy-20; + tri[1].x = fx+1; tri[1].y = fy+1; + tri[2].x = fx-9; tri[2].y = fy-20; + } + if( fx==width+20-1 && fy==0 ){ + tri[0].x = fx-20; tri[0].y = fy+21; + tri[1].x = fx+1; tri[1].y = fy-1; + tri[2].x = fx-20; tri[2].y = fy+9; + } + if( fx==0 && fy==0 ){ + tri[0].x = fx+21; tri[0].y = fy+20; + tri[1].x = fx-1; tri[1].y = fy-1; + tri[2].x = fx+9; tri[2].y = fy+20; + } + XFillPolygon( dpy, mask, ShapeGC, tri, 3, Nonconvex, CoordModeOrigin ); + + XShapeCombineMask( dpy, Scr.Balloon, ShapeBounding, + 0, 0, mask, ShapeSet); + + XFreePixmap( dpy, mask ); + XFreeGC( dpy, ShapeGC ); +} + +void BalloonSize( int *lh, int *lw, int *offset, int *w, int *h, MlvwmWindow *mw ) +{ + int lp; + char contents[256]; + int contents_width=0, strw, strh; + int xinc, yinc; + + *w = 0; /* Balloon Window Width */ + *h = 0; /* Balloon Window Height */ + *lw = 0; /* Label Width */ + *lh = 0; /* Line Height */ + + for( lp=0; WinLabel[lp]; lp++ ){ + StrWidthHeight( BALLOONFONT, &strw, &strh, + offset, WinLabel[lp], strlen(WinLabel[lp]) ); + *lw = max( *lw, strw ); + *lh = max( strh, *lh ); + } + + StrWidthHeight( BALLOONFONT, &strw, &strh, + offset, mw->name, strlen(mw->name) ); + *lh = max( strh, *lh ); + contents_width = max( contents_width, strw ); + + if( &(mw->class) ){ + StrWidthHeight( BALLOONFONT, &strw, &strh, + offset, mw->class.res_class, + strlen( mw->class.res_class) ); + contents_width = max( strw, contents_width ); + *lh = max( strh, *lh ); + StrWidthHeight( BALLOONFONT, &strw, &strh, + offset, mw->class.res_name, + strlen(mw->class.res_name) ); + contents_width = max( strw, contents_width ); + *lh = max( strh, *lh ); + } + + sprintf( contents, "%d", mw->frame_x ); + StrWidthHeight(BALLOONFONT,&strw,&strh,offset,contents,strlen(contents)); + contents_width = max( strw, contents_width ); + *lh = max( strh, *lh ); + + sprintf( contents, "%d", mw->frame_y ); + StrWidthHeight(BALLOONFONT,&strw,&strh,offset,contents,strlen(contents)); + contents_width = max( strw, contents_width ); + *lh = max( strh, *lh ); + + if( mw->hints.flags & PResizeInc){ + xinc = mw->hints.width_inc; + yinc = mw->hints.height_inc; + }else + xinc = yinc = 1; + + sprintf( contents, "%d", (mw->attr.width-mw->hints.base_width)/xinc ); + StrWidthHeight(BALLOONFONT,&strw,&strh,offset,contents,strlen(contents)); + contents_width = max( strw, contents_width ); + *lh = max( strh, *lh ); + + sprintf( contents, "%d", (mw->attr.height-mw->hints.base_height)/yinc ); + StrWidthHeight(BALLOONFONT,&strw,&strh,offset,contents,strlen(contents)); + contents_width = max( strw, contents_width ); + *lh = max( strh, *lh ); + + *w = contents_width + *lw + 20 + 20; /* 20 is a margin */ + *h = *lh * lp + 20; +} + +void DrawWindowBalloon( int xoff, int yoff, int lh, int offset, int lw, MlvwmWindow *mw ) +{ + int lp; + char contents[255]; + int xinc, yinc; + + for( lp=0; WinLabel[lp]!=NULL; lp++ ){ + XDRAWSTRING( dpy, Scr.Balloon, BALLOONFONT, + Scr.BlackGC, xoff+10, yoff+lh*lp+lh/2+10-offset, + WinLabel[lp], strlen(WinLabel[lp]) ); + } + XDRAWSTRING( dpy, Scr.Balloon, BALLOONFONT, + Scr.BlackGC, xoff+lw+30, yoff+lh/2+10-offset, + mw->name, strlen(mw->name) ); + XDRAWSTRING( dpy, Scr.Balloon, BALLOONFONT, + Scr.BlackGC, xoff+lw+30, yoff+lh+lh/2+10-offset, + mw->class.res_class, strlen(mw->class.res_class) ); + XDRAWSTRING( dpy, Scr.Balloon, BALLOONFONT, + Scr.BlackGC, xoff+lw+30, yoff+lh*2+lh/2+10-offset, + mw->class.res_name, strlen(mw->class.res_name) ); + sprintf( contents, "%d", mw->frame_x ); + XDRAWSTRING( dpy, Scr.Balloon, BALLOONFONT, + Scr.BlackGC, xoff+lw+30, yoff+lh*3+lh/2+10-offset, + contents, strlen(contents) ); + sprintf( contents, "%d", mw->frame_y ); + XDRAWSTRING( dpy, Scr.Balloon, BALLOONFONT, + Scr.BlackGC, xoff+lw+30, yoff+lh*4+lh/2+10-offset, + contents, strlen(contents) ); + + if( mw->hints.flags & PResizeInc){ + xinc = mw->hints.width_inc; + yinc = mw->hints.height_inc; + }else + xinc = yinc = 1; + + sprintf( contents, "%d", (mw->attr.width-mw->hints.base_width)/xinc ); + XDRAWSTRING( dpy, Scr.Balloon, BALLOONFONT, + Scr.BlackGC, xoff+lw+30, yoff+lh*5+lh/2+10-offset, + contents, strlen(contents) ); + sprintf( contents, "%d", (mw->attr.height-mw->hints.base_height)/yinc ); + XDRAWSTRING( dpy, Scr.Balloon, BALLOONFONT, + Scr.BlackGC, xoff+lw+30, yoff+lh*6+lh/2+10-offset, + contents, strlen(contents) ); +} + +void BalloonHelp( void ) +{ + int mx, my, JunkX, JunkY; + int winx, winy, fx, fy; + int height=0, label_width=0, one_line=0; + int width, offset, xoff=0, yoff=0, winwoff=0, winhoff=0; + unsigned int JunkMask; + Window JunkRoot, JunkChild; + XEvent ev; + Bool IsEnd=False; + MlvwmWindow *tmp_win; + + XQueryPointer( dpy, Scr.Root, &JunkRoot, &JunkChild, + &JunkX, &JunkY, &mx, &my, &JunkMask); + if( XFindContext ( dpy, JunkChild, MlvwmContext, (caddr_t *)&tmp_win ) + == XCNOENT ){ + return; + } + + if( Scr.Balloon==None ) CreateBalloonWindow(); + + BalloonSize( &one_line, &label_width, &offset, &width, &height, tmp_win ); + + winx = mx; + winy = my-height; + xoff = 20; + winwoff = 20; + fx = 0; + fy = height-1; + if( winx+width+20>Scr.MyDisplayWidth ){ + xoff = 0; + if( winy<0 ){ + winx = mx-width-20; + winy = my; + fx = width+20-1; + fy = 0; + } + else{ + winx = mx-width; + winy = my-height-20; + winhoff = 20; + fx = width-1; + fy = height+20-1; + } + } + else{ + if( winy<0 ){ + winy = my; + xoff = 0; + yoff = 20; + winwoff = 0; + winhoff = 20; + fx = 0; + fy = 0; + } + } + + GrabEvent( DEFAULT ); + + XMoveResizeWindow( dpy, Scr.Balloon, winx, winy, + width+winwoff, height+winhoff ); + ShapeBalloon( fx, fy, xoff, yoff, winwoff, winhoff, width, height ); + XMapRaised( dpy, Scr.Balloon ); + + UnGrabEvent(); + do{ + XNextEvent( dpy, &ev ); + switch( ev.type ){ + case Expose: + if( ev.xany.window==Scr.Balloon ){ + DrawBackGround( fx, fy, xoff, yoff, width, height ); + DrawWindowBalloon( xoff, yoff, + one_line, offset, label_width, tmp_win ); + XSync( dpy, 0 ); + } + else + HandleEvents( ev ); + break; + case EnterNotify: + case DestroyNotify: + case MapRequest: + case UnmapNotify: + case ButtonPress: + case ConfigureRequest: + case ClientMessage: + case PropertyNotify: + case KeyPress: + case ColormapNotify: + IsEnd = True; + default: + HandleEvents( ev ); + break; + } + } + while( !IsEnd ); + + XUnmapWindow( dpy, Scr.Balloon ); +} + diff --git a/mlvwm/balloon.h b/mlvwm/balloon.h new file mode 100644 index 0000000..77773ce --- /dev/null +++ b/mlvwm/balloon.h @@ -0,0 +1,12 @@ +/****************************************************************************/ +/* This module is all original code */ +/* by TakaC Hasegawa (tak@bioele.nuee.nagoya-u.ac.jp */ +/* Copyright 1996, TakaC Hasegawa */ +/* You may use this code for any purpose, as long as the original */ +/* copyright remains in the source code and all documentation */ +/****************************************************************************/ +#ifndef _BALLOON_ +#define _BALLOON_ + +extern void BalloonHelp( void ); +#endif /* _BALLOON_ */ diff --git a/mlvwm/borders.c b/mlvwm/borders.c new file mode 100644 index 0000000..c311d56 --- /dev/null +++ b/mlvwm/borders.c @@ -0,0 +1,1057 @@ +/****************************************************************************/ +/* This module is based on fvwm, but has been siginificantly modified */ +/* by TakaC Hasegawa (tak@bioele.nuee.nagoya-u.ac.jp) */ +/****************************************************************************/ +/**************************************************************************** + * This module is based on Twm, but has been siginificantly modified + * by Rob Nation (nation@rocket.sanders.lockheed.com) + ****************************************************************************/ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + +#include +#include +#include + +#include "mlvwm.h" +#include "screen.h" +#include "misc.h" +#include "borders.h" + +#include + +static unsigned char mesh_bits_v[] = { 0x04, 0x01 }; +static unsigned char mesh_bits_h[] = { 0x01, 0x00, 0x02, 0x00 }; + +void DrawShadowBox( int x, int y, int w, int h, Window win, int d, GC hilight, GC shadow, char mode ) +{ + int lp; + + w--; + h--; + for( lp=0; lpflags&(TITLE|SBARV|SBARH|RESIZER) ){ + shape_x = (Scr.flags&SYSTEM8?5:0); + shape_y = tmp_win->flags & TITLE ? TITLE_HEIGHT+1 : 0; + } + else{ + shape_x = 6; + shape_y = 6; + } + XShapeCombineShape (dpy, tmp_win->frame, ShapeBounding, + shape_x, shape_y, tmp_win->w, + ShapeBounding, ShapeSet); + if ( tmp_win->flags&TITLE ){ + rect[0].x = -1; rect[0].y = -1; + rect[0].width = w-1; rect[0].height = TITLE_HEIGHT+2; + point++; + for( lp=0; lp<3; lp++ ){ + rect[lp+1].x = tmp_win->frame_w-2+lp; rect[lp+1].y = lp; + rect[lp+1].width = 1; rect[lp+1].height = TITLE_HEIGHT+1-lp; + point++; + } + if( tmp_win->flags&SHADE ) + for( lp=0; lp<3; lp++ ){ + rect[lp+4].x = lp; rect[lp+4].y = tmp_win->frame_h-2+lp; + rect[lp+4].width = tmp_win->frame_w+1-lp; rect[lp+4].height = 1; + point++; + } + XShapeCombineRectangles(dpy,tmp_win->frame,ShapeBounding, + 0,0,rect,point,ShapeUnion,Unsorted); + } + if ( tmp_win->flags&RESIZER ){ + rect[0].x = tmp_win->frame_w-SBAR_WH-2-1-(Scr.flags&SYSTEM8?4:0); + rect[0].y = tmp_win->frame_h-SBAR_WH-2-1-(Scr.flags&SYSTEM8?4:0); + rect[0].width = SBAR_WH+2+(Scr.flags&SYSTEM8?4:0); + rect[0].height = SBAR_WH+2+(Scr.flags&SYSTEM8?4:0); + XShapeCombineRectangles(dpy,tmp_win->frame,ShapeBounding, + 0,0,rect,1,ShapeUnion,Unsorted); + } +} + +void SetUpFrame( MlvwmWindow *t, int x, int y, int w, int h, Bool sendEvent ) +{ + XWindowChanges xwcv; + unsigned long xwcm; + int title_height, sbar_v, sbar_h, resize_r; + int sbar_vh, sbar_hw; + + title_height = t->flags & TITLE ? TITLE_HEIGHT : 0; + sbar_v = t->flags & SBARV ? SBAR_WH : 0; + sbar_h = t->flags & SBARH ? SBAR_WH : 0; + resize_r = t->flags & RESIZER ? + SBAR_WH : ( sbar_v!=0 && sbar_h!=0 ? SBAR_WH : 0 ); + + if( t->flags&TITLE ) + XResizeWindow( dpy, t->title_w, + w-2-(t->flags&SBARV?0:1)-(Scr.flags&SYSTEM8?4:0), + TITLE_HEIGHT ); + if( t->flags&MINMAXR ){ + if( Scr.flags&SYSTEM8 ) + XMoveWindow(dpy, t->minmax_b, + w-BOXSIZE-9-(t->flags&SHADER?BOXSIZE+4:0), + (TITLE_HEIGHT-BOXSIZE)/2); + else + XMoveWindow(dpy, t->minmax_b, + w-BOXSIZE*2-1, + (TITLE_HEIGHT-BOXSIZE)/2); + } + if( t->flags&SHADER ) + XMoveWindow(dpy, t->shade_b, w-BOXSIZE-9, + (TITLE_HEIGHT-BOXSIZE)/2); + if( !(t->flags&SHADE) ){ + if( t->flags & ( TITLE | SBARV | SBARH | RESIZER ) ){ + t->attr.width = w-sbar_v-(t->flags&SBARV ? 2 : 1 )-1; + t->attr.height = h-sbar_h-title_height-2- + (t->flags&TITLE ? 1 : 0)- + (t->flags&SBARH ? 1 : 0); + if( Scr.flags&SYSTEM8 ){ + t->attr.width -= 12; + t->attr.height -= 6; + } + XMoveResizeWindow( dpy, t->Parent, + Scr.flags&SYSTEM8?5:-1, + t->flags & TITLE ? TITLE_HEIGHT : -1, + t->attr.width, t->attr.height ); + } + else{ + t->attr.width = w-12; + t->attr.height = h-12; + XMoveResizeWindow( dpy, t->Parent, 5, 5, + t->attr.width, t->attr.height ); + } + if( t->flags&RESIZER ) + XMoveWindow( dpy, t->resize_b, w-SBAR_WH-3-(Scr.flags&SYSTEM8?4:0), + h-SBAR_WH-3-(Scr.flags&SYSTEM8?4:0) ); + /* Vertical Scroll bar Height */ + sbar_vh = t->attr.height- + (t->flags&RESIZER && !(t->flags&SBARH)?SBAR_WH+1:0); + /* Horizontal Scroll width */ + sbar_hw = t->attr.width- + (t->flags&RESIZER && !(t->flags&SBARV)?SBAR_WH+1:0); + + if( t->flags&SBARV ){ + int anker_position; + + XMoveResizeWindow( dpy, t->scroll_v[0], + t->attr.width+(Scr.flags&SYSTEM8?6:0), + t->flags & TITLE ? TITLE_HEIGHT : -1, + SBAR_WH, sbar_vh ); + XMoveWindow( dpy, t->scroll_v[2], 0, sbar_vh-SBAR_WH ); + if( t->flags&SCROLL ){ + if( t->frame_hwin_h ) + anker_position = (double)((sbar_vh-3*SBAR_WH-2)*t->win_y)/ + (double)(t->frame_h-t->win_h) + + SBAR_WH+1; + else + anker_position = SBAR_WH+2; + if( anker_position>sbar_vh-3*SBAR_WH-2+SBAR_WH+1 ){ + anker_position = sbar_vh-3*SBAR_WH-2+SBAR_WH+1; + t->win_y = t->frame_h-t->win_h; + } + XMoveWindow( dpy, t->scroll_v[3], 0, anker_position ); + } + } + if( t->flags&SBARH ){ + int anker_position; + + XMoveResizeWindow( dpy,t->scroll_h[0], Scr.flags&SYSTEM8?5:-1, + h-1-SBAR_WH-2-(Scr.flags&SYSTEM8?6:0), + sbar_hw, SBAR_WH ); + XMoveWindow( dpy, t->scroll_h[2], sbar_hw-SBAR_WH, 0 ); + if( t->flags&SCROLL ){ + if( t->frame_wwin_w ) + anker_position = (double)( (sbar_hw-3*SBAR_WH-2)*t->win_x)/ + (double)(t->frame_w-t->win_w) + + SBAR_WH+1; + else + anker_position = SBAR_WH+2; + if( anker_position>sbar_hw-3*SBAR_WH-2+SBAR_WH+1 ){ + anker_position = sbar_hw-3*SBAR_WH-2+SBAR_WH+1; + t->win_x = t->frame_w-t->win_w; + } + XMoveWindow( dpy, t->scroll_h[3], anker_position, 0 ); + } + } + } + if( t->flags & SCROLL ){ + if( t->flags & SBARH ){ + t->attr.width = w>t->win_w ? t->attr.width : + t->win_w-sbar_v-(t->flags&SBARV ? 2 : 1 )-1 + -(Scr.flags&SYSTEM8?12:0); + t->win_x = w>t->win_w ? 0 : t->win_x; + } + if( t->flags & SBARV ){ + t->attr.height = h>t->win_h ? t->attr.height : + t->win_h-sbar_h-title_height-2- + (t->flags&TITLE ? 1 : 0)-(t->flags&SBARH ? 1 : 0) + -(Scr.flags&SYSTEM8?6:0); + t->win_y = h>t->win_h ? 0 : t->win_y; + } + } + else{ + t->win_x = 0; + t->win_y = 0; + } + XMoveResizeWindow( dpy, t->w, t->win_x, t->win_y, + t->attr.width, t->attr.height ); + + xwcm = (CWWidth | CWHeight | CWX | CWY ); + xwcv.x = x; + xwcv.y = y; + xwcv.width = w; + xwcv.height = h; + XConfigureWindow( dpy, t->frame, xwcm, &xwcv ); + + if( (!(t->wShaped) || t->flags&SHADE) && + t->flags & ( TITLE | SBARV | SBARH | RESIZER )){ + int lp; + XRectangle rect[7]; + + rect[0].x = -1; rect[0].y = -1; + rect[0].width = t->frame_w-1; rect[0].height = t->frame_h-1; + + for( lp=0; lp<3; lp++ ){ + rect[lp+1].x = t->frame_w-2+lp; rect[lp+1].y = lp; + rect[lp+1].width = 1; rect[lp+1].height = t->frame_h+1-lp; + } + for( lp=0; lp<3; lp++ ){ + rect[lp+4].x = lp; rect[lp+4].y = t->frame_h-2+lp; + rect[lp+4].width = t->frame_w+1-lp; rect[lp+4].height = 1; + } + XShapeCombineRectangles(dpy,t->frame,ShapeBounding, + 0,0,rect,7,ShapeSet,YSorted); + } + if( t->wShaped ) SetShape( t, w ); + if (sendEvent && !(t->flags&SHADE) ){ + XEvent client_event; + + client_event.type = ConfigureNotify; + client_event.xconfigure.display = dpy; + client_event.xconfigure.event = t->w; + client_event.xconfigure.window = t->w; + + if( t->flags&(TITLE|SBARV|SBARH|RESIZER)){ + client_event.xconfigure.x = x + 1 + t->win_x; + client_event.xconfigure.y = y + title_height + 1 + t->win_y; + if( Scr.flags&SYSTEM8 ) + client_event.xconfigure.x += 6; + } + else{ + client_event.xconfigure.x = x + 6; + client_event.xconfigure.y = y + 6; + } + client_event.xconfigure.width = t->attr.width; + client_event.xconfigure.height = t->attr.height; + client_event.xconfigure.border_width =0; /* Modifed */ + client_event.xconfigure.above = t->frame; + client_event.xconfigure.override_redirect = False; + XSendEvent(dpy, t->w, False, StructureNotifyMask, &client_event); + } +} + +void FillGradation( Window win ) +{ + XClearWindow( dpy, win ); + XDrawRectangle( dpy, win, Scr.BlackGC, + 1, 1, BOXSIZE-3, BOXSIZE-3 ); + DrawShadowBox( 0, 0, BOXSIZE, BOXSIZE, win, 1, + Scr.Gray3GC, Scr.WhiteGC, SHADOW_ALL ); + DrawShadowBox( 4, 4, BOXSIZE-6, BOXSIZE-6, win, BOXSIZE/2-2, + Scr.WhiteGC, Scr.WhiteGC, SHADOW_BOTTOM|SHADOW_RIGHT ); + DrawShadowBox( 2, 2, BOXSIZE-6, BOXSIZE-6, win, BOXSIZE/2-2, + Scr.Gray3GC, Scr.WhiteGC, SHADOW_TOP|SHADOW_LEFT ); + DrawShadowBox( 2, 2, 3, 3, win, 2, Scr.Gray2GC, Scr.WhiteGC, + SHADOW_TOP|SHADOW_LEFT ); + DrawShadowBox( 2, 2, BOXSIZE-4, BOXSIZE-4, win, 1, + Scr.WhiteGC, Scr.Gray3GC, SHADOW_ALL ); +} + +void DrawCloseBox( MlvwmWindow *t, Bool on ) +{ + unsigned long mask, valuemask; + XSetWindowAttributes attributes_box; + XGCValues xgcv; + + mask = GCForeground; + if( on || Scr.flags&SYSTEM8 ){ + if( !XGetGCValues( dpy, + (Scr.flags&SYSTEM8?Scr.Gray4GC:Scr.Gray3GC), + mask, &xgcv ) ){ + fprintf( stderr, "Sorry Can not get GC Values 3\n"); + xgcv.foreground = WhitePixel( dpy, Scr.screen ); + } + attributes_box.background_pixel = xgcv.foreground; + } + else + attributes_box.background_pixel = WhitePixel( dpy, Scr.screen ); + if( on ) attributes_box.cursor = Scr.MlvwmCursors[DESTROY]; + else attributes_box.cursor = Scr.MlvwmCursors[DEFAULT]; + valuemask = CWBackPixel | CWCursor; + XChangeWindowAttributes( dpy, t->close_b, valuemask, &attributes_box ); + XClearWindow( dpy, t->close_b ); + if( on ){ + if( Scr.flags&SYSTEM8 ){ + XFillRectangle( dpy, t->title_w, Scr.Gray4GC, + 4, (TITLE_HEIGHT-BOXSIZE)/2-2, + BOXSIZE+7, BOXSIZE+2 ); + FillGradation( t->close_b ); + } + else{ + XFillRectangle( dpy, t->title_w, Scr.Gray4GC, + BOXSIZE-1, (TITLE_HEIGHT-BOXSIZE)/2-1, + BOXSIZE+4, BOXSIZE+1 ); + DrawShadowBox( 0, 0, BOXSIZE, BOXSIZE, t->close_b, 1, + Scr.BlackGC, Scr.WhiteGC, SHADOW_ALL ); + DrawShadowBox( 1, 1, BOXSIZE-2, BOXSIZE-2, t->close_b, 1, + Scr.WhiteGC, Scr.BlackGC, SHADOW_ALL ); + } + } +} + +void DrawMinMax( MlvwmWindow *t, Bool on ) +{ + unsigned long mask, valuemask; + XSetWindowAttributes attributes_box; + XGCValues xgcv; + + mask = GCForeground; + if( on || Scr.flags&SYSTEM8 ){ + if( !XGetGCValues( dpy, + (Scr.flags&SYSTEM8?Scr.Gray4GC:Scr.Gray3GC), + mask, &xgcv ) ){ + fprintf( stderr, "Sorry Can not get GC Values 3\n"); + xgcv.foreground = WhitePixel( dpy, Scr.screen ); + } + attributes_box.background_pixel = xgcv.foreground; + } + else + attributes_box.background_pixel = WhitePixel( dpy, Scr.screen ); + + if( on ) attributes_box.cursor = Scr.MlvwmCursors[MINMAX_CURSOR]; + else attributes_box.cursor = Scr.MlvwmCursors[DEFAULT]; + valuemask = CWBackPixel | CWCursor; + XChangeWindowAttributes( dpy, t->minmax_b, valuemask, &attributes_box ); + XClearWindow( dpy, t->minmax_b ); + if( on ){ + if( Scr.flags&SYSTEM8 ){ + XFillRectangle( dpy, t->title_w, Scr.Gray4GC, + t->frame_w-BOXSIZE-15- + (t->flags&SHADER?BOXSIZE+6:0), + (TITLE_HEIGHT-BOXSIZE)/2-1, + BOXSIZE+8, BOXSIZE+2 ); + FillGradation( t->minmax_b ); + XDrawRectangle( dpy, t->minmax_b, Scr.BlackGC, + 1, 1, BOXSIZE-6, BOXSIZE-6 ); + } + else{ + XFillRectangle( dpy, t->title_w, Scr.Gray4GC, + t->frame_w-BOXSIZE*2-3,(TITLE_HEIGHT-BOXSIZE)/2-1, + BOXSIZE+4, BOXSIZE+1 ); + DrawShadowBox( 0, 0, BOXSIZE, BOXSIZE, t->minmax_b, 1, + Scr.BlackGC, Scr.WhiteGC, SHADOW_ALL ); + DrawShadowBox( 1, 1, BOXSIZE-2, BOXSIZE-2, t->minmax_b, 1, + Scr.WhiteGC, Scr.BlackGC, SHADOW_ALL ); + DrawShadowBox( 1, 1, BOXSIZE-6, BOXSIZE-6, t->minmax_b, 1, + Scr.WhiteGC, Scr.BlackGC, SHADOW_ALL ); + } + } +} + +void DrawShadeR( MlvwmWindow *t, Bool on ) +{ + unsigned long mask, valuemask; + XSetWindowAttributes attributes_box; + XGCValues xgcv; + + mask = GCForeground; + if( on || Scr.flags&SYSTEM8 ){ + if( !XGetGCValues( dpy, + (Scr.flags&SYSTEM8?Scr.Gray4GC:Scr.Gray3GC), + mask, &xgcv ) ){ + fprintf( stderr, "Sorry Can not get GC Values 3\n"); + xgcv.foreground = WhitePixel( dpy, Scr.screen ); + } + attributes_box.background_pixel = xgcv.foreground; + } + else + attributes_box.background_pixel = WhitePixel( dpy, Scr.screen ); + + if( on ){ + if( t->flags&SHADE ) + attributes_box.cursor = Scr.MlvwmCursors[SHADER_DOWN_CURSOR]; + else + attributes_box.cursor = Scr.MlvwmCursors[SHADER_UP_CURSOR]; + } + else attributes_box.cursor = Scr.MlvwmCursors[DEFAULT]; + valuemask = CWBackPixel | CWCursor; + XChangeWindowAttributes( dpy, t->shade_b, valuemask, &attributes_box ); + XClearWindow( dpy, t->shade_b ); + if( on ){ + XFillRectangle( dpy, t->title_w, Scr.Gray4GC, t->frame_w-BOXSIZE-15, + (TITLE_HEIGHT-BOXSIZE)/2-1, BOXSIZE+8, BOXSIZE+2 ); + FillGradation( t->shade_b ); + XDrawLine( dpy, t->shade_b, Scr.BlackGC, + 1, BOXSIZE/2-1, BOXSIZE-3, BOXSIZE/2-1 ); + XDrawLine( dpy, t->shade_b, Scr.BlackGC, + 1, BOXSIZE/2+1, BOXSIZE-3, BOXSIZE/2+1 ); + } +} + +void SetTitleBar( MlvwmWindow *t, Bool on_off ) +{ + int w, offset; + int titlelength, drawable; + int lp; + unsigned long mask, valuemask; + XSetWindowAttributes attributes_title, attributes_box; + XGCValues xgcv; + GC dispgc; + + mask = GCForeground; + if( on_off || Scr.flags&SYSTEM8 ){ + if( !XGetGCValues( dpy, Scr.Gray4GC, mask, &xgcv ) ){ + fprintf( stderr, "Sorry Can not get GC Values 4\n"); + xgcv.foreground = WhitePixel( dpy, Scr.screen ); + } + attributes_title.background_pixel = xgcv.foreground; + if( !XGetGCValues( dpy, Scr.Gray3GC, mask, &xgcv ) ){ + fprintf( stderr, "Sorry Can not get GC Values 3\n"); + xgcv.foreground = WhitePixel( dpy, Scr.screen ); + } + if( Scr.flags&SYSTEM8 ) + attributes_box.background_pixel = WhitePixel( dpy, Scr.screen ); + else + attributes_box.background_pixel = xgcv.foreground; + } + else{ + attributes_title.background_pixel = WhitePixel( dpy, Scr.screen ); + attributes_box.background_pixel = WhitePixel( dpy, Scr.screen ); + } + if( on_off ) attributes_title.cursor = Scr.MlvwmCursors[TITLE_CURSOR]; + else attributes_title.cursor = Scr.MlvwmCursors[DEFAULT]; + valuemask = CWBackPixel | CWCursor; + XChangeWindowAttributes( dpy, t->title_w, valuemask, &attributes_title ); + XClearWindow( dpy, t->title_w ); + + drawable = t->frame_w-14*4; + if( t->flags&CLOSER || t->flags&MINMAXR ) + drawable-=BOXSIZE*2; + if( t->flags&SHADER && t->flags&MINMAXR ) + drawable-=BOXSIZE*2; + + titlelength = strlen( t->name )+1; + do{ + titlelength--; + StrWidthHeight( WINDOWFONT, &w, NULL, &offset, t->name, titlelength ); + } + while( w+20>drawable && titlelength>0 ); + + if( on_off ){ + for( lp=4; lp<14; lp+=3 ){ + if( Scr.d_depth>1 ){ + if( Scr.flags&SYSTEM8 ) + DrawShadowBox( 4, lp-2, t->frame_w-15, 2, t->title_w, 1, + Scr.WhiteGC, Scr.Gray1GC, SHADOW_ALL ); + else + DrawShadowBox( 4, lp-1, t->frame_w-11, 2, t->title_w, 1, + Scr.Gray1GC, Scr.WhiteGC, SHADOW_ALL ); + } + else + XDrawLine( dpy, t->title_w, Scr.BlackGC, + 4, lp-1, t->frame_w-7, lp-1 ); + } + if( Scr.d_depth>1 ){ + if( Scr.flags&SYSTEM8 ) + DrawShadowBox( 4, 14, t->frame_w-15, 2, t->title_w, 1, + Scr.WhiteGC, Scr.Gray1GC, SHADOW_ALL ); + else + XDrawLine( dpy, t->title_w, Scr.Gray1GC, + 4, 15, t->frame_w-9, 15 ); + } + else + XDrawLine( dpy, t->title_w, Scr.BlackGC, + 4, 15, t->frame_w-7, 15 ); + if( Scr.flags&SYSTEM8 ){ + DrawShadowBox( 0, 0, t->frame_w-2, TITLE_HEIGHT, t->title_w, + 1, Scr.WhiteGC, Scr.Gray2GC, SHADOW_TOP ); + if( !(t->flags&SHADE) ) + XDrawLine( dpy, t->title_w, Scr.Gray2GC, + 2, TITLE_HEIGHT-1, t->frame_w-9, TITLE_HEIGHT-1 ); + } + else + DrawShadowBox( 0, 0, t->frame_w-2, TITLE_HEIGHT, t->title_w, + 1, Scr.WhiteGC, Scr.Gray2GC, SHADOW_ALL ); + XFillRectangle( dpy, t->title_w, Scr.Gray4GC, + (t->frame_w-w)/2-10, 1, w+20, TITLE_HEIGHT-2 ); + dispgc = Scr.BlackGC; + } + else{ + if( Scr.d_depth>1 ) dispgc = Scr.Gray3GC; + else dispgc = Scr.BlackGC; + } + if( t->flags&CLOSER ) DrawCloseBox( t, on_off ); + if( t->flags&MINMAXR ) DrawMinMax( t, on_off ); + if( t->flags&SHADER ) DrawShadeR( t, on_off ); + + XDRAWSTRING( dpy, t->title_w, WINDOWFONT, dispgc, (t->frame_w-w)/2, + TITLE_HEIGHT/2-offset, t->name, titlelength ); + if( Scr.d_depth<2 && !on_off ){ + xgcv.function = GXor; + mask = GCFunction; + XChangeGC( dpy, Scr.BlackGC, mask, &xgcv ); + XSetFillStyle( dpy, Scr.BlackGC, FillTiled ); + XFillRectangle( dpy, t->title_w, Scr.BlackGC, (t->frame_w-w)/2, 1, + w, TITLE_HEIGHT-2 ); + XSetFillStyle( dpy, Scr.BlackGC, FillSolid ); + xgcv.function = GXcopy; + XChangeGC( dpy, Scr.BlackGC, mask, &xgcv ); + } +} + +void DrawArrow( Window w, int direction, GC color ) +{ + XPoint arrow_p[] = { + {9,3},{2,10},{6,10},{6,15},{12,15},{12,10},{16,10},{9,3}, {0,0}}, + arrow_p8[] = {{15,11},{9,5},{3,11},{15,11}, {0,0}}; + XPoint *use_p; + int lp, JunkX, point; + + if( Scr.flags&SYSTEM8 ) use_p = arrow_p8; + else use_p = arrow_p; + + for( point=0; use_p[point].x!=0; point++ ){ + use_p[point].x = use_p[point].x*SBAR_WH/19.+0.5; + use_p[point].y = use_p[point].y*SBAR_WH/19.+0.5; + } + + if( direction==C_SBAR_LEFT || direction==C_SBAR_RIGHT ){ + for( lp=0; lpscroll_h[3]; + size = t->frame_w-t->win_w; + } + if( context==C_SBAR_V_AN ){ + win = t->scroll_v[3]; + size = t->frame_h-t->win_h; + } + + if( on_off ){ + if( t->flags&SCROLL && size<0 ){ + mask = GCForeground; + if( !XGetGCValues( dpy, Scr.flags&SYSTEM8? + Scr.ScrollBlueGC:Scr.Gray4GC, + mask, &xgcv ) ){ + fprintf( stderr, "Sorry Can not get GC Values 4\n"); + xgcv.foreground = WhitePixel( dpy, Scr.screen ); + } + attributes.background_pixel = xgcv.foreground; + attributes.cursor = Scr.MlvwmCursors[DEFAULT]; + valuemask = CWBackPixel | CWCursor; + + valuemask = CWBackPixel; + XChangeWindowAttributes( dpy, win, valuemask, &attributes ); + XClearWindow( dpy, win ); + + DrawShadowBox( 0, 0, SBAR_WH, SBAR_WH, win, 1, + Scr.WhiteGC, Scr.Gray2GC, SHADOW_ALL ); + scale = 11*SBAR_WH/19.+0.5; + if( context==C_SBAR_H_AN ){ + for( lp=0; lp<(SBAR_WH-6)/3; lp++ ) + DrawShadowBox( (lp+1)*3, (SBAR_WH-scale)/2+1, + 3, scale, win, 1, + Scr.WhiteGC, Scr.BlackGC, SHADOW_ALL ); + } + if( context==C_SBAR_V_AN ){ + scale = 11*SBAR_WH/19.+0.5; + for( lp=0; lp<(SBAR_WH-6)/3; lp++ ) + DrawShadowBox( (SBAR_WH-scale)/2, (lp+1)*3, + scale, 3, win, 1, + Scr.WhiteGC, Scr.BlackGC, SHADOW_ALL ); + } + } + else{ + mask = GCForeground; + if( !XGetGCValues( dpy, Scr.Gray4GC, mask, &xgcv ) ){ + fprintf( stderr, "Sorry Can not get GC Values 4\n"); + xgcv.foreground = WhitePixel( dpy, Scr.screen ); + } + attributes.background_pixel = xgcv.foreground; + attributes.cursor = Scr.MlvwmCursors[DEFAULT]; + valuemask = CWBackPixel | CWCursor; + + XChangeWindowAttributes(dpy, win, valuemask, &attributes); + XClearWindow( dpy, win ); + } + } + else{ + attributes.background_pixel = WhitePixel( dpy, Scr.screen ); + attributes.cursor = Scr.MlvwmCursors[DEFAULT]; + valuemask = CWBackPixel | CWCursor; + XChangeWindowAttributes(dpy, win, valuemask, &attributes); + XClearWindow( dpy, win ); + } +} + +void DrawSbarArrow( MlvwmWindow *t, int context, Bool on_off ) +{ + int size; + unsigned int mask, valuemask; + Window win; + XGCValues xgcv; + XSetWindowAttributes attributes; + Cursor cursor; + + switch( context ){ + case C_SBAR_UP: + win = t->scroll_v[1]; + size = t->frame_h-t->win_h; + cursor = Scr.MlvwmCursors[SBARV_CURSOR]; + break; + case C_SBAR_DOWN: + win = t->scroll_v[2]; + size = t->frame_h-t->win_h; + cursor = Scr.MlvwmCursors[SBARV_CURSOR]; + break; + case C_SBAR_LEFT: + win = t->scroll_h[1]; + size = t->frame_w-t->win_w; + cursor = Scr.MlvwmCursors[SBARH_CURSOR]; + break; + case C_SBAR_RIGHT: + win = t->scroll_h[2]; + size = t->frame_w-t->win_w; + cursor = Scr.MlvwmCursors[SBARH_CURSOR]; + break; + } + + if( on_off ){ + mask = GCForeground; + if( !XGetGCValues( dpy, Scr.Gray4GC, mask, &xgcv ) ){ + fprintf( stderr, "Sorry Can not get GC Values 4\n"); + xgcv.foreground = WhitePixel( dpy, Scr.screen ); + } + attributes.background_pixel = xgcv.foreground; + if( t->flags&SCROLL && size<0 ) + attributes.cursor = cursor; + else + attributes.cursor = Scr.MlvwmCursors[DEFAULT]; + valuemask = CWBackPixel | CWCursor; + + XChangeWindowAttributes( dpy, win, valuemask, &attributes ); + XClearWindow( dpy, win ); + + if( t->flags&SCROLL && size<0 ) + DrawShadowBox( 0, 0, SBAR_WH, SBAR_WH, win, 1, + Scr.WhiteGC, Scr.Gray2GC, SHADOW_ALL ); + + DrawArrow( win, context, Scr.Gray3GC ); + } + else{ + mask = GCForeground; + attributes.background_pixel = WhitePixel( dpy, Scr.screen ); + attributes.cursor = Scr.MlvwmCursors[DEFAULT]; + valuemask = CWBackPixel | CWCursor; + XChangeWindowAttributes( dpy, win, valuemask, &attributes ); + XClearWindow( dpy, win ); + } +} + +void DrawSbarBar( MlvwmWindow *t, int context, Bool on_off ) +{ + unsigned long mask, valuemask; + XSetWindowAttributes attributes; + XWindowAttributes winattrs; + XGCValues xgcv; + Window win; + int x, y, width_f, height_f, width, height, size, mesh_w, mesh_h; + char *mesh; + + if( context==C_SBAR_H ) win = t->scroll_h[0]; + if( context==C_SBAR_V ) win = t->scroll_v[0]; + + XSetWindowBackgroundPixmap( dpy, win, None ); + XGetWindowAttributes(dpy, win, &winattrs); + if( context==C_SBAR_H ){ + size = t->frame_w-t->win_w; + x = SBAR_WH+1; + y = 0; + width_f = winattrs.width; + height_f = SBAR_WH; + width = winattrs.width-SBAR_WH*2-2; + height = SBAR_WH; + mesh = mesh_bits_h; + mesh_w = 2; + mesh_h = 4; + } + if( context==C_SBAR_V ){ + size = t->frame_h-t->win_h; + x = 0; + y = SBAR_WH+1; + width_f = SBAR_WH; + height_f = winattrs.height; + width = SBAR_WH; + height = winattrs.height-SBAR_WH*2-2; + mesh = mesh_bits_v; + mesh_w = 4; + mesh_h = 2; + } + + if( on_off ){ + if( t->flags&SCROLL && size<0 ){ + if( Scr.flags&SYSTEM8 ){ + Pixmap bgpix; + bgpix = XCreatePixmap( dpy, Scr.Root, width_f, + height_f, Scr.d_depth ); + XFillRectangle(dpy,bgpix,Scr.Gray3GC,0,0,width_f,height_f); + + DrawShadowBox( x, y, width, height, bgpix, 1, + Scr.Gray2GC, Scr.WhiteGC, SHADOW_ALL ); + XSetWindowBackgroundPixmap( dpy, win, bgpix ); + XFreePixmap( dpy, bgpix ); + } + else{ + XSetWindowBackgroundPixmap( dpy, win, + XCreatePixmapFromBitmapData( dpy, Scr.Root, + mesh, mesh_w, mesh_h, + BlackPixel(dpy,Scr.screen), + WhitePixel(dpy,Scr.screen), + Scr.d_depth )); + } + XClearWindow( dpy, win ); + } + else{ + mask = GCForeground; + if( !XGetGCValues( dpy, Scr.Gray4GC, mask, &xgcv ) ){ + fprintf( stderr, "Sorry Can not get GC Values 4\n"); + xgcv.foreground = WhitePixel( dpy, Scr.screen ); + } + attributes.background_pixel = xgcv.foreground; + attributes.cursor = Scr.MlvwmCursors[DEFAULT]; + + valuemask = CWBackPixel | CWCursor; + XChangeWindowAttributes( dpy, win, valuemask, &attributes ); + XClearWindow( dpy, win ); + } + if( context==C_SBAR_V ){ + XDrawLine(dpy, win, Scr.BlackGC, x, y-1, width, y-1); + XDrawLine(dpy, win, Scr.BlackGC, x, y+height, width, y+height); + } + if( context==C_SBAR_H ){ + XDrawLine(dpy, win, Scr.BlackGC, x-1, y, x-1, height); + XDrawLine(dpy, win, Scr.BlackGC, x+width, y, x+width, height); + } + } + else{ + mask = GCForeground; + attributes.background_pixel = WhitePixel( dpy, Scr.screen ); + attributes.cursor = Scr.MlvwmCursors[DEFAULT]; + valuemask = CWBackPixel | CWCursor; + XChangeWindowAttributes( dpy, win, valuemask, &attributes ); + XClearWindow( dpy, win ); + } +} + +void DrawFrameShadow( MlvwmWindow *t, Bool on ) +{ + XSegment lines[4]; + int lp; + unsigned long valuemask; + XSetWindowAttributes attributes; + + if( on ) attributes.cursor = Scr.MlvwmCursors[TITLE_CURSOR]; + else attributes.cursor = Scr.MlvwmCursors[DEFAULT]; + valuemask = CWCursor; + XChangeWindowAttributes( dpy, t->frame, valuemask, &attributes ); + if( t->flags&( TITLE | SBARV | SBARH | RESIZER )){ + for( lp=0; lp<2; lp++ ) + SetSegment(0,t->frame_w,t->frame_h-lp-1, + t->frame_h-lp-1,lines+lp); + for( lp=0; lp<2; lp++ ) + SetSegment(t->frame_w-lp-1,t->frame_w-lp-1,0, + t->frame_h,lines+lp+2); + XDrawSegments( dpy, t->frame, Scr.BlackGC, lines, 4 ); + if( Scr.flags&SYSTEM8 ){ + if( on ){ + DrawShadowBox( 0, 0, t->frame_w-2, t->frame_h-2, t->frame, 5, + Scr.WhiteGC, Scr.WhiteGC, + SHADOW_LEFT|SHADOW_BOTTOM|SHADOW_RIGHT ); + DrawShadowBox( 0, 0, t->frame_w-2, t->frame_h-2, t->frame, 2, + Scr.WhiteGC, Scr.Gray3GC, + SHADOW_LEFT|SHADOW_BOTTOM|SHADOW_RIGHT ); + DrawShadowBox( 2, 0, t->frame_w-6, t->frame_h-4, t->frame, 2, + Scr.Gray4GC, Scr.Gray4GC, + SHADOW_LEFT|SHADOW_BOTTOM|SHADOW_RIGHT ); + XDrawLine( dpy, t->frame, Scr.Gray2GC, + 4, 0, 4, t->frame_h-7 ); + DrawShadowBox( t->frame_w-SBAR_WH-8, t->frame_h-SBAR_WH-8, + SBAR_WH+1, SBAR_WH+1, t->frame, 1, + Scr.WhiteGC, Scr.Gray4GC, + SHADOW_LEFT|SHADOW_TOP ); + } + else{ + DrawShadowBox( 0, 0, t->frame_w-2, t->frame_h-2, t->frame, 5, + Scr.Gray4GC, Scr.Gray4GC, + SHADOW_ALL ); + DrawShadowBox( t->frame_w-SBAR_WH-8, t->frame_h-SBAR_WH-8, + SBAR_WH+1, SBAR_WH+1, t->frame, 1, + Scr.Gray4GC, Scr.Gray4GC, + SHADOW_LEFT|SHADOW_TOP ); + } + } + } + else{ + DrawShadowBox( 0, 0, t->frame_w, t->frame_h, t->frame, 2, + Scr.WhiteGC, Scr.Gray3GC, SHADOW_ALL ); + DrawShadowBox( 3, 3, t->frame_w-6, t->frame_h-6, t->frame, 2, + Scr.Gray3GC, Scr.WhiteGC, SHADOW_ALL ); + if( Scr.flags&SYSTEM8 ) + DrawShadowBox( 2, 2, t->frame_w-4, t->frame_h-4, t->frame, 2, + Scr.Gray4GC, Scr.Gray4GC, SHADOW_ALL ); + } +} + +void DrawResizeBox( MlvwmWindow *t, Bool on_off ) +{ + unsigned long mask, valuemask; + XSetWindowAttributes attributes; + XGCValues xgcv; + int point, scale, lp; + + mask = GCForeground; + if( on_off || Scr.flags&SYSTEM8 ){ + if( !XGetGCValues( dpy, Scr.Gray4GC, mask, &xgcv ) ){ + fprintf( stderr, "Sorry Can not get GC Values 4\n"); + xgcv.foreground = WhitePixel( dpy, Scr.screen ); + } + attributes.background_pixel = xgcv.foreground; + } + else + attributes.background_pixel = WhitePixel( dpy, Scr.screen ); + if( on_off ) attributes.cursor = Scr.MlvwmCursors[RESIZE]; + else attributes.cursor = Scr.MlvwmCursors[DEFAULT]; + valuemask = CWBackPixel | CWCursor; + + XChangeWindowAttributes( dpy, t->resize_b, valuemask, &attributes ); + + XClearWindow( dpy, t->resize_b ); + if( on_off ){ + if( Scr.flags&SYSTEM8 ){ + for(lp=0; lp<3; lp++ ){ + XDrawLine( dpy, t->resize_b, Scr.WhiteGC, + 2+lp*3, 9+lp*3, 8+lp*3, 3+lp*3 ); + XDrawLine( dpy, t->resize_b, Scr.BlackGC, + 4+lp*3, 8+lp*3, 9+lp*3, 3+lp*3 ); + } + } + else{ + point = 6*SBAR_WH/19.+0.5; + scale = 9*SBAR_WH/19.+0.5; + DrawShadowBox( point, point, scale, scale, t->resize_b, + 1, Scr.WhiteGC, Scr.BlackGC, SHADOW_ALL ); + DrawShadowBox( point-1, point-1, scale+2, scale+2, t->resize_b, + 1, Scr.BlackGC, Scr.WhiteGC, SHADOW_ALL ); + + point = 3*SBAR_WH/19.+0.5; + scale = 8*SBAR_WH/19.+0.5; + XFillRectangle( dpy, t->resize_b, Scr.Gray4GC, + point, point, scale, scale ); + + point = 4*SBAR_WH/19.+0.5; + scale = 7*SBAR_WH/19.+0.5; + DrawShadowBox( point, point, scale, scale, t->resize_b, + 1, Scr.WhiteGC, Scr.BlackGC, SHADOW_ALL ); + DrawShadowBox( point-1, point-1, scale+2, scale+2, t->resize_b, + 1, Scr.BlackGC, Scr.WhiteGC, SHADOW_ALL ); + } + } + if( Scr.flags&SYSTEM8 && !(t->flags&(SBARV|SBARH)) ){ + DrawShadowBox( 0, 0, SBAR_WH, SBAR_WH, t->resize_b, + 1, Scr.BlackGC, Scr.BlackGC, + SHADOW_TOP|SHADOW_LEFT ); + if( on_off ) + DrawShadowBox( 1, 1, SBAR_WH-1, SBAR_WH-1, t->resize_b, + 1, Scr.WhiteGC, Scr.WhiteGC, + SHADOW_TOP|SHADOW_LEFT ); + } +} + +void DrawAllDecorations( MlvwmWindow *t, Bool on_off ) +{ + if( t->flags&SBARV ){ + DrawSbarBar( t, C_SBAR_V, on_off ); + DrawSbarAnk( t, C_SBAR_V_AN, on_off ); + DrawSbarArrow( t, C_SBAR_UP, on_off ); + DrawSbarArrow( t, C_SBAR_DOWN, on_off ); + } + if( t->flags&SBARH ){ + DrawSbarBar( t, C_SBAR_H, on_off ); + DrawSbarAnk( t, C_SBAR_H_AN, on_off ); + DrawSbarArrow( t, C_SBAR_LEFT, on_off ); + DrawSbarArrow( t, C_SBAR_RIGHT, on_off ); + } + if( t->flags&RESIZER ) + DrawResizeBox( t, on_off ); + if( t->flags&TITLE ) + SetTitleBar( t, on_off ); + if( Scr.flags&SYSTEM8 ) + DrawFrameShadow( t, on_off ); + + XSync( dpy, 0 ); +} + +void SetFocus( MlvwmWindow *t ) +{ + char *str, action[24], *winname; + unsigned long mask, valuemask; + XSetWindowAttributes attributes; + XGCValues xgcv; + + mask = GCForeground; + + if( Scr.ActiveWin==t ) return; + if( Scr.ActiveWin ){ + DrawAllDecorations( Scr.ActiveWin, False ); + + if( Scr.ActiveWin->flags&(SBARV|SBARH) && + !(Scr.ActiveWin->flags&RESIZER) && !(Scr.flags&SYSTEM8) ){ + attributes.background_pixel = WhitePixel( dpy, Scr.screen ); + valuemask = CWBackPixel; + XChangeWindowAttributes( dpy, Scr.ActiveWin->frame, + valuemask, &attributes ); + XClearArea( dpy, Scr.ActiveWin->frame, + Scr.ActiveWin->frame_w-2-SBAR_WH, + Scr.ActiveWin->frame_h-2-SBAR_WH, + SBAR_WH, SBAR_WH, False ); + } + + if( !(Scr.flags&FOLLOWTOMOUSE) ){ + XSync(dpy,0); + XGrabButton(dpy, AnyButton, AnyModifier, Scr.ActiveWin->frame, + True, ButtonPressMask, GrabModeSync,GrabModeAsync,None, + Scr.MlvwmCursors[DEFAULT]); + } + winname = WinListName( Scr.ActiveWin ); + sprintf( action, "Select %lX", (unsigned long)Scr.ActiveWin ); + ChangeMenuItemLabel( "ICON", winname, winname, + action, ~CHECKON, M_AND ); + free( winname ); + } + + Scr.ActiveWin=t; + MapMenuBar( Scr.ActiveWin ); + if( t==NULL || t->flags&TRANSIENT ){ + ChangeMenuLabel( &(Scr.IconMenu), NULL, Scr.SystemIcon ); + ChangeMenuItemLabel( "ICON", Scr.IconMenu.m_item->label, + Scr.IconMenu.m_item->label, NULL, STRGRAY, M_COPY); + ChangeMenuItemLabel( "ICON", "Hide Others", "Hide Others", + NULL, STRGRAY, M_COPY ); + XSetInputFocus( dpy, Scr.NoFocusWin, RevertToParent, CurrentTime ); + if( t==NULL ) + return; + } + ChangeMenuLabel( &(Scr.IconMenu), NULL, + t->miniicon==NULL?Scr.SystemIcon:t->miniicon ); + if( !(t->flags&TRANSIENT) ){ + str = calloc( strlen(t->name)+6, 1 ); + sprintf( str, "Hide %s", t->name ); + ChangeMenuItemLabel( "ICON", Scr.IconMenu.m_item->label, + str, NULL, SELECTON, M_COPY ); + ChangeMenuItemLabel( "ICON", "Hide Others", "Hide Others", + NULL, SELECTON, M_COPY ); + sprintf( action, "Select %lX", (unsigned long)t ); + winname = WinListName( t ); + ChangeMenuItemLabel( "ICON", winname, winname, + action, SELECTON|CHECKON, M_COPY ); + free( winname ); + free( str ); + } + + DrawAllDecorations( t, True ); + + if( t->flags&(SBARV|SBARH) && !(t->flags&RESIZER) ){ + if( !XGetGCValues( dpy, Scr.Gray4GC, mask, &xgcv ) ){ + fprintf( stderr, "Sorry Can not get GC Values 4\n"); + xgcv.foreground = WhitePixel( dpy, Scr.screen ); + } + attributes.background_pixel = xgcv.foreground; + valuemask = CWBackPixel; + XChangeWindowAttributes( dpy, t->frame, valuemask, &attributes ); + XClearArea( dpy, t->frame, + t->frame_w-2-SBAR_WH-1-(Scr.flags&SYSTEM8?6:0), + t->frame_h-2-SBAR_WH-1-(Scr.flags&SYSTEM8?6:0), + SBAR_WH+(Scr.flags&SYSTEM8?2:0), + SBAR_WH+(Scr.flags&SYSTEM8?2:0), False ); + } + + if( !(Scr.flags&FOLLOWTOMOUSE) ) + XUngrabButton( dpy, AnyButton, AnyModifier, t->frame ); + + if( !(t->flags&SHADE) ) + XSetInputFocus( dpy, t->w, RevertToParent, CurrentTime ); + else + XSetInputFocus( dpy, Scr.NoFocusWin, RevertToParent, CurrentTime ); +} diff --git a/mlvwm/borders.h b/mlvwm/borders.h new file mode 100644 index 0000000..3df431f --- /dev/null +++ b/mlvwm/borders.h @@ -0,0 +1,32 @@ +/****************************************************************************/ +/* This module is all original code */ +/* by TakaC Hasegawa (tak@bioele.nuee.nagoya-u.ac.jp */ +/* Copyright 1996, TakaC Hasegawa */ +/* You may use this code for any purpose, as long as the original */ +/* copyright remains in the source code and all documentation */ +/****************************************************************************/ +#ifndef _BORDERS_ +#define _BORDERS_ + +#define SHADOW_BOTTOM 1 +#define SHADOW_LEFT 2 +#define SHADOW_RIGHT 4 +#define SHADOW_TOP 8 +#define SHADOW_ALL (SHADOW_BOTTOM|SHADOW_LEFT|SHADOW_RIGHT|SHADOW_TOP) + +extern void SetShape( MlvwmWindow *, int ); +extern void SetUpFrame( MlvwmWindow *, int, int, int, int, Bool ); +extern void SetTitleBar( MlvwmWindow *, Bool ); +extern void DrawArrow( Window, int, GC ); +extern void DrawSbarAnk( MlvwmWindow *, int, Bool ); +extern void DrawSbarArrow( MlvwmWindow *, int, Bool ); +extern void DrawSbarBar( MlvwmWindow *, int, Bool ); +extern void DrawResizeBox( MlvwmWindow *, Bool ); +extern void DrawAllDecorations( MlvwmWindow *, Bool ); +extern void DrawFrameShadow( MlvwmWindow *, Bool ); +extern void SetFocus( MlvwmWindow * ); +extern void DrawShadowBox( int, int, int, int, Window, int, GC, GC, char ); +extern void DrawMinMax( MlvwmWindow *, Bool ); +extern void DrawCloseBox( MlvwmWindow *, Bool ); +extern void DrawShadeR( MlvwmWindow *, Bool ); +#endif diff --git a/mlvwm/config.c b/mlvwm/config.c new file mode 100644 index 0000000..939f830 --- /dev/null +++ b/mlvwm/config.c @@ -0,0 +1,795 @@ +/****************************************************************************/ +/* This module is mostly all new */ +/* by TakaC Hasegawa (tak@bioele.nuee.nagoya-u.ac.jp) */ +/* Copyright 1996 TakaC Hasegawa. No restrictions are placed on this code, */ +/* as long as the copyright notice is preserved */ +/****************************************************************************/ + +#include +#include +#include +#include + +#include "mlvwm.h" +#include "screen.h" +#include "menus.h" +#include "config.h" +#include "misc.h" + +struct configure key_modifiers[]= +{ + {'S',ShiftMask}, + {'C',ControlMask}, + {'M',Mod1Mask}, + {'1',Mod1Mask}, + {'2',Mod2Mask}, + {'3',Mod3Mask}, + {'4',Mod4Mask}, + {'5',Mod5Mask}, + {'A',AnyModifier}, + {'N',0}, + {0,0} +}; + +char *NoTitleStyle( styles *tmp_style, char *str ) +{ + tmp_style->flags &= ~TITLE; + tmp_style->flags &= ~CLOSER; + tmp_style->flags &= ~MINMAXR; + + return str+7; +} + +char *NoHScrollStyle( styles *tmp_style, char *str ) +{ + tmp_style->flags &= ~SBARH; + if( !(tmp_style->flags&SBARV) ) + tmp_style->flags &= ~SCROLL; + + return str+7; +} + +char *NoVScrollStyle( styles *tmp_style, char *str ) +{ + tmp_style->flags &= ~SBARV; + if( !(tmp_style->flags&SBARH) ) + tmp_style->flags &= ~SCROLL; + + return str+7; +} + +char *NoResizeRStyle( styles *tmp_style, char *str ) +{ + tmp_style->flags &= ~RESIZER; + + return str+9; +} + +char *NoMinMaxRStyle( styles *tmp_style, char *str ) +{ + tmp_style->flags &= ~MINMAXR; + + return str+9; +} + +char *NoCloseRStyle( styles *tmp_style, char *str ) +{ + tmp_style->flags &= ~CLOSER; + + return str+8; +} + +char *NoShadeRStyle( styles *tmp_style, char *str ) +{ + tmp_style->flags &= ~SHADER; + + return str+8; +} + +char *NoWinListStyle( styles *tmp_style, char *str ) +{ + tmp_style->flags |= NOWINLIST; + + return str+9; +} + +char *SetOnTopStyle( styles *tmp_style, char *str ) +{ + tmp_style->flags |= ONTOP; + + return str+9; +} + +char *SetStickyStyle( styles *tmp_style, char *str ) +{ + tmp_style->flags |= STICKY; + + return str+6; +} + +char *SetSkipSelectStyle( styles *tmp_style, char *str ) +{ + tmp_style->flags |= SKIPSELECT; + + return str+10; +} + +char *SetScrollStyle( styles *tmp_style, char *str ) +{ + if( tmp_style->flags & ( SBARV | SBARH ) ) + tmp_style->flags |= SCROLL; + + return str+12; +} + +char *SetFocusStyle( styles *tmp_style, char *str ) +{ + tmp_style->flags |= NOFOCUS; + + return str+7; +} + + +char *SetNormalStyle( styles *tmp_style, char *str ) +{ + tmp_style->flags |= NORMALWIN; + if( Scr.flags&SYSTEM8 ) tmp_style->flags |= SHADER; + + return str+16; +} + +char *SetNoTransientDecorate( styles *tmp_style, char *str ) +{ + tmp_style->flags |= NONTRANSIENTDECORATE; + + return str+20; +} + +char *SetMaxmizeScale( styles *tmp_style, char *str ) +{ + char *stop; + + if( (stop = strchr( str, ',' ))!=NULL ) *stop = '\0'; + if( strchr( SkipNonSpace(str), 'x' )){ + tmp_style->maxmizescale = 0; + sscanf( str, "MaxmizeScale%dx%d", + &(tmp_style->maxmizesize_w), &(tmp_style->maxmizesize_h) ); + } + else + sscanf( str, "MaxmizeScale%d", &(tmp_style->maxmizescale) ); + if( stop ) stop++; + else stop = str+strlen(str); + + return stop; +} + +char *SetMiniIcon( styles *tmp_style, char *str ) +{ + char *stop, *name, *path; + + if( (stop = strchr( str, ',' ))!=NULL ) + *stop = '\0'; + name = calloc( strlen(str)-7, 1 ); + sscanf( str, "MiniIcon%s", name ); + + tmp_style->iconname = name; + if((path = LookUpFiles( Scr.IconPath, name, R_OK ))==NULL ) + DrawErrMsgOnMenu( "Can't Find file ", name ); + else + free( path ); + + if( stop ) + stop++; + else + stop = str+strlen(str); + + return stop; +} + +char *SetMenuBarToWin( styles *tmp_style, char *str ) +{ + char *stop, *name; + Menu *tmp_m; + + if( (stop = strchr( str, ',' ))!=NULL ) + *stop = '\0'; + name = calloc( strlen(str)-7, 1 ); + sscanf( str, "MenuBar%s", name ); + + for( tmp_m = Scr.MenuRoot; tmp_m && strcmp( name, tmp_m->name ); + tmp_m=tmp_m->next ); + tmp_style->menubar = tmp_m; + if( !tmp_m ) + DrawErrMsgOnMenu( "Configuration Error(Style MenuBar) ", name ); + free( name ); + + if( stop ) stop++; + else stop = str+strlen(str); + + return stop; +} + +style_func style_config[]={ + { "NormalDecoration", SetNormalStyle }, + { "NoTitle", NoTitleStyle }, + { "NoSBarH", NoHScrollStyle }, + { "NoSBarV", NoVScrollStyle }, + { "NoResizeR", NoResizeRStyle }, + { "NoMinMaxR", NoMinMaxRStyle }, + { "NoCloseR", NoCloseRStyle }, + { "NoShadeR", NoShadeRStyle }, + { "NoWinList", NoWinListStyle }, + { "StayOnTop", SetOnTopStyle }, + { "Sticky", SetStickyStyle }, + { "SkipSelect", SetSkipSelectStyle }, + { "EnableScroll", SetScrollStyle }, + { "NoFocus", SetFocusStyle }, + { "MaxmizeScale", SetMaxmizeScale}, + { "MenuBar", SetMenuBarToWin }, + { "MiniIcon", SetMiniIcon}, + { "NoTransientDecorate", SetNoTransientDecorate }, + { NULL, 0} +}; + +void SetStyles( char *line, FILE *fp ) +{ + char str[256], *top, *name; + styles *tmp, *last, *check; + int lp; + + for( last = Scr.style_list; last && last->next; last=last->next ); + while( fgets( str, 256, fp )!=NULL && strncmp( str, "END", 3) ){ + if( str[0]=='#' ) continue; + top = stripquote( str, &name ); + if( name==NULL ){ + DrawErrMsgOnMenu( "Configuration Error ", "SetStyle" ); + continue; + } + + for( check=Scr.style_list; check && strcmp( check->name, name ); + check=check->next ); + + if( check==NULL ){ + tmp = calloc( 1, sizeof( styles ) ); + tmp->name = name; + tmp->flags = NORMALWIN; + if( Scr.flags&SYSTEM8 ) tmp->flags |= SHADER; + tmp->maxmizescale = 90; + if( last == NULL ) + Scr.style_list = tmp; + else + last->next = tmp; + last = tmp; + } + else{ + tmp = check; + free( name ); + } + + while( *top!='\n' && *top!='\0' ){ + for( ; !isalpha( *top ) && *top!='\n' && *top!='\0'; top++ ); + if( *top=='\n' || *top=='\0' ) break; + for( lp=0; style_config[lp].label!=NULL; lp++ ){ + if( !strncmp( top, style_config[lp].label, + strlen(style_config[lp].label) )){ + top=style_config[lp].action( tmp, top ); + break; + } + } + if( !style_config[lp].label ){ + DrawErrMsgOnMenu( "Configuration Error(Style)! ", str ); + for( ; *top!=',' && *top!='\n' && *top!='\0'; top++ ); + } + } + } +} + +void FreeStyles( void ) +{ + styles *now, *next; + + now = Scr.style_list; + for( ;now!=NULL; now = next ){ + next = now->next; + free( now->name ); + if( now->miniicon ){ + XFreePixmap( dpy, now->miniicon->icon ); + XFreePixmap( dpy, now->miniicon->lighticon ); + if( now->miniicon->mask!=None ) + XFreePixmap( dpy, now->miniicon->mask ); + free( now->miniicon ); + now->miniicon = NULL; + free( now->iconname ); + } + free( now ); + } +} + +void SetStartFunction( char *line, FILE *fp ) +{ + char str[256], *top; + ShortCut **new; + + if( (!strncmp( line, "InitFunction", 12 ) && Scr.Restarting) || + (!strncmp( line, "RestartFunction", 15 ) && !Scr.Restarting)){ + while( fgets( str, 256, fp )!=NULL && strncmp( str, "END", 3) ); + return; + } + + new = &Scr.StartFunc; + while( fgets( str, 256, fp )!=NULL && strncmp( str, "END", 3) ){ + if( str[0]=='#' ) continue; + *new = calloc( 1, sizeof( ShortCut ) ); + top = SkipSpace( str ); + (*new)->action = strdup( top ); + new = &(*new)->next; + } +} + +void SetShortCut( char *line, FILE *fp ) +{ + char str[256], *top, *end; + char keyname[256], modifiers[256], action[256]; + ShortCut *new; + KeySym keysym; + KeyCode keycode; + int len, tag; + + while( fgets( str, 256, fp )!=NULL && strncmp( str, "END", 3) ){ + if( str[0]=='#' ) continue; + top = SkipSpace( str ); + end = SkipNonSpace( top ); + strncpy( keyname, top, end-top ); + keyname[end-top] = '\0'; + top = SkipSpace( end+1 ); + end = SkipNonSpace( top ); + strncpy( modifiers, top, end-top ); + modifiers[end-top] = '\0'; + top = SkipSpace( end+1 ); + strcpy( action, top ); + action[strlen(action)-1] = '\0'; + + if ((keysym = XStringToKeysym(keyname)) == NoSymbol || + (keycode = XKeysymToKeycode(dpy, keysym)) == 0) + continue; + new = calloc( 1, sizeof( ShortCut ) ); + if( new==NULL ){ + fprintf( stderr, "Can not allocate memory for ShortCutKey\n" ); + continue; + } + new->next = Scr.ShortCutRoot; + Scr.ShortCutRoot = new; + len = 0; + new->mods = 0; + while( lenmods |= key_modifiers[tag].value; + } + len++; + } + new->keycode = keycode; + new->action = strdup( action ); + } +} + +void SetDeskTopNum( char *line, FILE *fp ) +{ + int lp; + char *label, *action; + + sscanf( line, "Desktopnum%d", &Scr.n_desktop ); + if( Scr.n_desktop<2 ){ + Scr.n_desktop = 1; + return; + } + if( Scr.n_desktop>999 ){ + Scr.n_desktop = 999; + DrawErrMsgOnMenu( "You must set Desktopnum", " less than 999." ); + } + for( lp=0; lp0 ) + Scr.bar_width = bar_width; +} + +void SetMenuFlush( char *line, FILE *fp ) +{ + sscanf( line, "FlushMenu%d%d", &(Scr.flush_time), &(Scr.flush_times) ); + Scr.flush_time *= 1000; +} + +void SetSystem8( char *line, FILE *fp ) +{ + XGCValues gcv; + XSetWindowAttributes attributes; + unsigned long gcm; + + if( Scr.d_depth<2 ) + DrawErrMsgOnMenu( "Can't use option ", "System8" ); + else{ + Scr.flags |= SYSTEM8; + gcm = GCForeground; + if( !XGetGCValues( dpy, Scr.MenuBlueGC, gcm, &gcv ) ){ + fprintf( stderr, "Sorry Can not get GC Values MenuBlue\n"); + gcv.foreground = WhitePixel( dpy, Scr.screen ); + } + attributes.background_pixel = gcv.foreground; + gcm = CWBackPixel; + XChangeWindowAttributes( dpy, Scr.MenuBar, gcm, &attributes ); + } +} + +void SetZoomWait( char *line, FILE *fp ) +{ + sscanf( line, "ZoomWait%d", &Scr.zoom_wait ); + Scr.zoom_wait *= 1000; +} + +void SetRotate( char *line, FILE *fp ) +{ + Scr.flags |= ROTATEDESK; +} + +void SetOpaqueMove( char *line, FILE *fp ) +{ + Scr.flags |= OPAQUEMOVE; +} + +void SetOpaqueResize( char *line, FILE *fp ) +{ + Scr.flags |= OPAQUERESIZE; +} + +void SetOneClickMenu( char *line, FILE *fp ) +{ + Scr.flags |= ONECLICKMENU; +} + +void SetIconPath( char *line, FILE *fp ) +{ + char *top; + + top = SkipSpace( line+8 ); + if( Scr.IconPath!=NULL ) free( Scr.IconPath ); + Scr.IconPath = calloc( strlen(top), 1 ); + strncpy( Scr.IconPath, top, strlen(top)-1 ); +} + +void SetDisplayDeskNum( char *line, FILE *fp ) +{ + Scr.flags |= DISPDESK; +} + +void SetIconMenuIcon( char *line, FILE *fp ) +{ + char *iconname; + + iconname = calloc( strlen(line)-11, 1 ); + if( sscanf( line, "IconMenuIcon%s", iconname )!=1 ){ + DrawErrMsgOnMenu( "Fail Set Icon. ", line ); + free( iconname ); + return; + } + Scr.SystemIcon = ReadIcon( iconname, NULL, True ); + + free( iconname ); +} + +void SetFont( +#ifdef USE_LOCALE +XFontSet *font, +#else +XFontStruct **font, +#endif + char *fontname) +{ +#ifdef USE_LOCALE + char **miss, *def; + int n_miss, lp; + XFontSet newfont; +#else + XFontStruct *newfont; +#endif + +#ifdef USE_LOCALE + newfont = XCreateFontSet( dpy, fontname, &miss, &n_miss, &def ); + if( n_miss>0 ){ + for( lp=0; lpnext ); + + *ml = calloc( 1, sizeof( MenuLabel ) ); + (*ml)->flags = ACTIVE | STICKLABEL; + (*ml)->xpm = BalloonIcon; + (*ml)->name = strdup( "Balloon" ); + (*ml)->LabelStr = NULL; + label = strdup( "About Balloon Help..." ); + AddMenuItem( *ml, label, NULL, NULL, NULL, NULL, STRGRAY ); + + label = strdup( "\0" ); + action = strdup( "Nop" ); + AddMenuItem( *ml, label, action, NULL, NULL, NULL, STRGRAY ); + + label = strdup( Scr.BalloonOffStr ); + action = strdup( "ToggleBalloon" ); + AddMenuItem( *ml, label, action, NULL, NULL, NULL, SELECTON ); +} + +void SetUseRootWin( char *line, FILE *fp ) +{ + Scr.flags |= USEROOT; + XSelectInput( dpy, Scr.Root, + PropertyChangeMask | + SubstructureRedirectMask | KeyPressMask | + SubstructureNotifyMask ); +} + +config_func main_config[]={ + { "Desktopnum", SetDeskTopNum }, + { "DoubleClickTime", SetDoubleClickTime }, + { "DisplayDeskNumber", SetDisplayDeskNum }, + { "FlushMenu", SetMenuFlush }, + { "FollowToMouse", SetFollowToMouse }, + { "Compatible", SetCompatible }, + { "IconMenuIcon", SetIconMenuIcon }, + { "IconPath", SetIconPath }, + { "IconifyHide", SetIconifyHide }, + { "IconifyShade", SetIconifyShade }, + { "InitFunction", SetStartFunction }, + { "RestartFunction", SetStartFunction }, + { "MenuBarFont", SetFontConfig }, + { "MenuBar", SetMenuBar }, + { "MenuFont", SetFontConfig }, + { "BalloonFont", SetFontConfig }, + { "Menu", SetMenu}, + { "Read", ReadNewConfigFile }, + { "RestartPreviousState", SetRstPrevState }, + { "ScrollBarWidth", SetBarWidth }, + { "ShadeMap", SetShadeMap }, + { "ShortCut", SetShortCut }, + { "SloppyFocus", SetSloppyFocus }, + { "StickyShade", SetStickyShade }, + { "StickyHide", SetStickyHide }, + { "Style", SetStyles }, + { "Swallow", SetSwallow }, + { "System8", SetSystem8 }, + { "OpaqueMove", SetOpaqueMove }, + { "OpaqueResize", SetOpaqueResize }, + { "OneClickMenu", SetOneClickMenu }, + { "RotateDesk", SetRotate }, + { "TitleBarFont", SetFontConfig }, + { "UseBalloon", SetBalloonHelp }, + { "UseRootWin", SetUseRootWin }, + { "ZoomWait", SetZoomWait }, + { NULL, 0 } +}; + +void ReadConfigFile( char *configfile ) +{ + int lp; + FILE *fp; + char str[256], *file, *cmp; +#ifdef MLVWMLIBDIR + char *sysrc; +#endif + + if( (file = LookUpFiles( NULL, configfile, R_OK ))==NULL ) + file = LookUpFiles( getenv("HOME"), configfile, R_OK ); +#ifdef MLVWMLIBDIR + if( !file ){ + if( strcmp( configfile, CONFIGNAME) ){ + sysrc = calloc( strlen(MLVWMLIBDIR)+strlen(configfile)+2, 1 ); + sprintf( sysrc, "%s/%s", MLVWMLIBDIR, configfile ); + } + else{ + sysrc = calloc( strlen(MLVWMLIBDIR)+strlen(configfile)+9, 1 ); + sprintf( sysrc, "%s/system%s", MLVWMLIBDIR, configfile ); + } + file = LookUpFiles( NULL, sysrc, R_OK ); + free( sysrc ); + } +#endif + if( file==NULL || (fp=fopen( file, "r" ))==NULL ){ + DrawErrMsgOnMenu( "Can't open your config file. ", configfile ); + if( file ) free( file ); + return; + } + while( fgets( str, 256, fp )!=NULL ){ + if( Scr.flags & DEBUGOUT ) + DrawStringMenuBar( str ); + cmp = str; + + if( *cmp == '#' ) continue; + cmp = SkipSpace( cmp ); + if( *cmp == '\n' ) continue; + for( lp=0; main_config[lp].label!=NULL; lp++ ){ + if( !strncmp( cmp, main_config[lp].label, + strlen(main_config[lp].label) )){ + main_config[lp].action( str, fp ); + break; + } + } + if( main_config[lp].label==NULL ){ + DrawErrMsgOnMenu( "Configuration Error! ", str ); + continue; + } + } + fclose( fp ); + free( file ); + + return; +} diff --git a/mlvwm/config.h b/mlvwm/config.h new file mode 100644 index 0000000..9957d76 --- /dev/null +++ b/mlvwm/config.h @@ -0,0 +1,50 @@ +/****************************************************************************/ +/* This module is all original code */ +/* by TakaC Hasegawa (tak@bioele.nuee.nagoya-u.ac.jp */ +/* Copyright 1996, TakaC Hasegawa */ +/* You may use this code for any purpose, as long as the original */ +/* copyright remains in the source code and all documentation */ +/****************************************************************************/ +#ifndef _CONFIG_ +#define _CONFIG_ + +#include +#include + +typedef struct styles +{ + char *name; + unsigned long flags; + int maxmizesize_w; + int maxmizesize_h; + int maxmizescale; + Icon *miniicon; + char *iconname; + Menu *menubar; + struct styles *next; +}styles; + +typedef struct config_func +{ + char *label; + void (*action)( char *, FILE * ); +}config_func; + +typedef struct style_func +{ + char *label; + char *(*action)( styles *, char * ); +}style_func; + +struct configure +{ + char key; + int value; +}; + +extern void SetDeskTopNum( char *, FILE * ); +extern void SetFollowToMouse( char *, FILE * ); +extern void ReadConfigFile( char * ); +extern void FreeStyles( void ); + +#endif diff --git a/mlvwm/event.c b/mlvwm/event.c new file mode 100644 index 0000000..072a009 --- /dev/null +++ b/mlvwm/event.c @@ -0,0 +1,1949 @@ +/****************************************************************************/ +/* This module is based on fvwm, but has been siginificantly modified */ +/* by TakaC Hasegawa (tak@bioele.nuee.nagoya-u.ac.jp) */ +/****************************************************************************/ +/**************************************************************************** + * This module is based on Twm, but has been siginificantly modified + * by Rob Nation (nation@rocket.sanders.lockheed.com) + ****************************************************************************/ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include "mlvwm.h" +#include "screen.h" +#include "menus.h" +#include "borders.h" +#include "add_window.h" +#include "functions.h" +#include "misc.h" +#include "balloon.h" + +#include + +#define MAX_NAME_LEN 200L /* truncate to this many */ + +extern int ShapeEventBase; + +extern void handle_expose( XEvent * ); + +MlvwmWindow *ColormapWindow = &Scr.MlvwmRoot; + +void send_clientmessage( Window w, Atom a, Time timestamp) +{ + MlvwmWindow *tmp_win; + XClientMessageEvent ev; + + if( XFindContext ( dpy, w, MlvwmContext, (caddr_t *)&tmp_win ) + == XCNOENT ) + tmp_win = NULL; + + ev.type = ClientMessage; + ev.window = w; + ev.message_type = _XA_WM_PROTOCOLS; + ev.format = 32; + ev.data.l[0] = a; + ev.data.l[1] = timestamp; + XSendEvent (dpy, w, False, 0L, (XEvent *) &ev); +} + +void InstallWindowColormaps (MlvwmWindow *tmp) +{ + XWindowAttributes attributes; + static Colormap last_cmap; + + ColormapWindow = tmp; + /* Save the colormap to be loaded for when force loading of + * root colormap(s) ends. + */ + Scr.pushed_window = tmp; + /* Don't load any new colormap if root colormap(s) has been + * force loaded. + */ + if (Scr.root_pushes) return; + + XGetWindowAttributes(dpy,tmp->w,&attributes); + + if(last_cmap != attributes.colormap){ + last_cmap = attributes.colormap; + XInstallColormap(dpy,attributes.colormap); + } +} + +void InstallRootColormap( void ) +{ + MlvwmWindow *tmp; + if (Scr.root_pushes == 0){ + tmp = Scr.pushed_window; + InstallWindowColormaps(&Scr.MlvwmRoot); + Scr.pushed_window = tmp; + } + Scr.root_pushes++; + return; +} + +void UninstallRootColormap( void ) +{ + if (Scr.root_pushes) + Scr.root_pushes--; + + if (!Scr.root_pushes) + InstallWindowColormaps(Scr.pushed_window); + + return; +} + +Bool GrabEvent( int cursor ) +{ + int i=0, val=0; + unsigned int mask; + + XSync( dpy, 0 ); + if(Scr.PreviousActive == NULL) + Scr.PreviousActive = Scr.ActiveWin; + XSetInputFocus( dpy, Scr.NoFocusWin, RevertToParent, CurrentTime ); + Scr.ActiveWin = NULL; + mask = ButtonPressMask | ButtonReleaseMask + | ButtonMotionMask | PointerMotionMask + | PointerMotionHintMask; + while((i<1000)&&(val=XGrabPointer(dpy, Scr.Root, True, mask, + GrabModeAsync, GrabModeAsync, Scr.Root, + Scr.MlvwmCursors[cursor], CurrentTime)!= + GrabSuccess)){ + i++; + sleep_a_little(1000); + } + XSync( dpy, 0 ); + if(val!=GrabSuccess) + return False; + else + return True; +} + +void UnGrabEvent( void ) +{ + XSync( dpy, 0 ); + XUngrabPointer( dpy, CurrentTime ); + + if(Scr.PreviousActive != NULL) { + SetFocus( Scr.PreviousActive ); + Scr.PreviousActive = NULL; + } + XSync( dpy, 0 ); +} + +void RestoreWithdrawnLocation( MlvwmWindow *tmp, Bool restart ) +{ + XWindowChanges xwc; + Window root, child; + int rx, ry; + unsigned int width, height, bw, depth; + unsigned int mask; + + if(!tmp) return; + + if (XGetGeometry (dpy, tmp->w, &root, &xwc.x, &xwc.y, + &width, &height, &bw, &depth)){ + XTranslateCoordinates(dpy,tmp->frame,Scr.Root,xwc.x,xwc.y, + &rx,&ry,&child); + + xwc.x = rx + tmp->diff_x; + xwc.y = ry + tmp->diff_y; + xwc.border_width = tmp->old_bw; + mask = (CWX | CWY | CWBorderWidth); + + if( !restart ){ + if( xwc.y>=Scr.MyDisplayHeight ) + xwc.y %= Scr.MyDisplayHeight; + if( xwc.y<0 ) + xwc.y = (tmp->frame_y+Scr.MyDisplayHeight*Scr.n_desktop) + %Scr.MyDisplayHeight; + } + XReparentWindow (dpy, tmp->w, Scr.Root, xwc.x, xwc.y ); + XConfigureWindow (dpy, tmp->w, mask, &xwc); + XSync(dpy,0); + } +} + +int GetContext( MlvwmWindow *t, XEvent *e, Window *w ) +{ + int Context; + + if(!t) return C_ROOT; + Context = C_NO_CONTEXT; + *w = e->xany.window; + + if( *w == Scr.NoFocusWin ) return C_ROOT; + + if((e->type==KeyPress)&&(e->xkey.subwindow!=None)) + *w = e->xkey.subwindow; + + if((e->type == ButtonPress)&&(e->xbutton.subwindow != None)&& + ((e->xbutton.subwindow == t->w)||(e->xbutton.subwindow == t->Parent))) + *w = e->xbutton.subwindow; + + if(*w == Scr.Root) Context = C_ROOT; + if(t){ + if(*w==t->frame) Context = C_FRAME; + if((*w == t->w)||(*w==t->Parent)) Context = C_WINDOW; + if(t->flags&TITLE && *w == t->title_w) Context = C_TITLE; + if(t->flags&CLOSER && *w == t->close_b) Context = C_CLOSE; + if(t->flags&MINMAXR && *w == t->minmax_b) Context = C_MINMAX; + if(t->flags&RESIZER && *w == t->resize_b) Context = C_RESIZE; + if(t->flags&SHADER && *w == t->shade_b ) Context = C_SHADE; + if( t->flags&SBARV ){ + if(*w == t->scroll_v[0] ) Context = C_SBAR_V; + if(*w == t->scroll_v[1] ) Context = C_SBAR_UP; + if(*w == t->scroll_v[2] ) Context = C_SBAR_DOWN; + if(*w == t->scroll_v[3] ) Context = C_SBAR_V_AN; + } + if( t->flags&SBARH ){ + if(*w == t->scroll_h[0] ) Context = C_SBAR_H; + if(*w == t->scroll_h[1] ) Context = C_SBAR_LEFT; + if(*w == t->scroll_h[2] ) Context = C_SBAR_RIGHT; + if(*w == t->scroll_h[3] ) Context = C_SBAR_H_AN; + } + } + return Context; +} + +MlvwmWindow *NextActiveWin( MlvwmWindow *t ) +{ + int lp; + Window parent, *children; + unsigned nchildren; + MlvwmWindow *NextActive; + + XQueryTree( dpy, Scr.Root, &Scr.Root, &parent, &children, &nchildren ); + for( lp=nchildren-1; lp>-1; lp-- ){ + if( XFindContext( dpy, children[lp], MlvwmContext, + (caddr_t *)&NextActive ) + !=XCNOENT && + NextActive->w!=t->w && + !(NextActive->flags&HIDED) && + !(NextActive->flags&NOWINLIST) && + !(NextActive->flags&SKIPSELECT) && + !(NextActive->flags&NOFOCUS) && + NextActive->Desk==Scr.currentdesk) + break; + } + if( lp==-1 ) + NextActive = NULL; + XFree( children ); + return NextActive; +} + +void SetMapStateProp( MlvwmWindow *tmp_win, int state) +{ + unsigned long data[2]; /* "suggested" by ICCCM version 1 */ + + data[0] = (unsigned long) state; + data[1] = (unsigned long) None; + + XChangeProperty (dpy, tmp_win->w, _XA_WM_STATE, _XA_WM_STATE, 32, + PropModeReplace, (unsigned char *) data, 2); +} + +int GetMapStateProp( MlvwmWindow *tmp_win ) +{ + Atom *protocols = NULL; + Atom atype; + int aformat; + unsigned long bytes_remain,nitems; + + if( XGetWindowProperty( dpy, tmp_win->w, _XA_WM_STATE, + 0L, 2L, False, + _XA_WM_STATE, &atype, &aformat, + &nitems, &bytes_remain, + (unsigned char **)&protocols ) == Success && + protocols ) + return + (int) protocols[0]; + else + return WithdrawnState; +} + +void Destroy( MlvwmWindow *t ) +{ + MlvwmWindow *NextActive; + int lp; + + NextActive = NextActiveWin( t ); + XDestroyWindow( dpy, t->Parent ); + XDestroyWindow( dpy, t->frame ); + + XDeleteContext( dpy, t->Parent, MlvwmContext ); + XDeleteContext( dpy, t->frame, MlvwmContext ); + XDeleteContext( dpy, t->w, MlvwmContext ); + if( t->flags&CLOSER ) + XDeleteContext( dpy, t->close_b, MlvwmContext ); + if( t->flags&MINMAXR ) + XDeleteContext( dpy, t->minmax_b, MlvwmContext ); + if( t->flags&SHADER ) + XDeleteContext( dpy, t->shade_b, MlvwmContext ); + if( t->flags&TITLE ) + XDeleteContext( dpy, t->title_w, MlvwmContext ); + if( t->flags&SBARV ) + for( lp=0; lp<4; lp++ ) + XDeleteContext( dpy, t->scroll_v[lp], MlvwmContext ); + if( t->flags&SBARH ) + for( lp=0; lp<4; lp++ ) + XDeleteContext( dpy, t->scroll_h[lp], MlvwmContext ); + if( t->flags&RESIZER ) + XDeleteContext( dpy, t->resize_b, MlvwmContext ); + if( Scr.n_desktop>1 ) + for( lp=0; lpprev->next = t->next; + if( t->next != NULL ) t->next->prev = t->prev; + + if( t==Scr.ActiveWin ){ + if( Scr.PreviousActive == Scr.ActiveWin ) + Scr.PreviousActive = NULL; + if( !(Scr.flags & FOLLOWTOMOUSE) || !(Scr.flags&SLOPPYFOCUS) ){ + if( Scr.PreviousActive ) + SetFocus( Scr.PreviousActive ); + else + SetFocus( NextActive ); + } + else + SetFocus( NULL ); + if( Scr.ActiveWin && + (!(Scr.flags & FOLLOWTOMOUSE) || !(Scr.flags&SLOPPYFOCUS)) ) + RaiseMlvwmWindow( Scr.ActiveWin ); + } + + if( t->wmhints ) XFree( t->wmhints ); + if ( t->name != NoName) XFree ( t->name ); + t->name = NULL; + if( t->class.res_name && t->class.res_name != NoName ) + XFree((char *)t->class.res_name); + if( t->class.res_class && t->class.res_class != NoName ) + XFree((char *)t->class.res_class); + free( t ); + XSync( dpy, 0 ); +} + +void HandleDestroy( XEvent *ev ) +{ + MlvwmWindow *tmp_win; + Window w; + char action[24]; + +/* w = ev->xany.window;*/ + XFlush(dpy); + w = ev->xdestroywindow.window; + if( XFindContext( dpy, w, MlvwmContext, (caddr_t *)&tmp_win )==XCNOENT ) + return; + if( !(tmp_win->flags & NOWINLIST) && !(tmp_win->flags&TRANSIENT) + && tmp_win->flags&MAPPED ){ + sprintf( action, "Select %lX", (unsigned long)tmp_win ); + DelMenuItem( &(Scr.IconMenu), action ); + } + Destroy( tmp_win ); +} + +void handle_configure_request( XEvent *ev ) +{ + XWindowChanges wc; + unsigned long xwcm; + MlvwmWindow *tmp_win; + XConfigureRequestEvent *xcr = &ev->xconfigurerequest; + int x, y, width, height, old_x, old_y; + int title_height, sbar_v, sbar_h; + Bool notify=False; + + ev->xany.window = xcr->window; /* mash parent field */ + if (XFindContext (dpy, xcr->window, MlvwmContext, (caddr_t *) &tmp_win) == + XCNOENT) + tmp_win = NULL; + if( !tmp_win ){ + wc.x = xcr->x; + wc.y = xcr->y; + wc.width = xcr->width; + wc.height = xcr->height; + wc.sibling = wc.stack_mode = TopIf; + xwcm = xcr->value_mask & (CWX | CWY | CWWidth | CWHeight); + XConfigureWindow( dpy, ev->xany.window, xwcm, &wc ); + return; + } + + { + int xws, yws, xbs, ybs; + unsigned wws, hws, wbs, hbs; + int boundingShaped, clipShaped; + + XShapeQueryExtents (dpy, tmp_win->w,&boundingShaped, &xws, &yws, &wws, + &hws,&clipShaped, &xbs, &ybs, &wbs, &hbs); + tmp_win->wShaped = boundingShaped; + } + + title_height = tmp_win->flags & TITLE ? TITLE_HEIGHT : -1; + sbar_v = tmp_win->flags & SBARV ? SBAR_WH+2: 1; + sbar_h = tmp_win->flags & SBARH ? SBAR_WH+2: 1; + + x = tmp_win->frame_x; + y = tmp_win->frame_y; + old_x = x; + old_y = y; + width = tmp_win->frame_w; + height = tmp_win->frame_h; + + if( tmp_win->flags&(TITLE|SBARV|SBARH|RESIZER) ){ + if (xcr->value_mask & CWX) x = xcr->x - 1; + if (xcr->value_mask & CWY) y = xcr->y - title_height - 2; + if (xcr->value_mask & CWWidth) width = xcr->width+1+sbar_v; + if (xcr->value_mask & CWHeight) + height = xcr->height+2+sbar_h+title_height; + if( Scr.flags&SYSTEM8 ){ + if (xcr->value_mask & CWX) x -= 6; + if (xcr->value_mask & CWWidth) width += 12; + if (xcr->value_mask & CWHeight) height += 6; + } + } + else{ + if (xcr->value_mask & CWX) x = xcr->x-6; + if (xcr->value_mask & CWY) y = xcr->y-6; + if (xcr->value_mask & CWWidth) width = xcr->width+12; + if (xcr->value_mask & CWHeight) height = xcr->height+12; + } +/* + tmp_win->frame_x = x<0 ? 0 : x; + tmp_win->frame_y = ywin_w = width; + tmp_win->win_h = height; + + if( old_x!=x || old_y!=y ) notify = True; + + if( !(tmp_win->flags&SCROLL) || + tmp_win->frame_w>tmp_win->win_w || !(tmp_win->flags&SBARH) ) + tmp_win->frame_w = tmp_win->win_w; + if( !(tmp_win->flags&SCROLL) || + tmp_win->frame_h>tmp_win->win_h || !(tmp_win->flags&SBARV) ) + tmp_win->frame_h = tmp_win->win_h; + + SetUpFrame(tmp_win, tmp_win->frame_x, tmp_win->frame_y, + tmp_win->frame_w, tmp_win->frame_h, notify ); + + if( tmp_win==Scr.ActiveWin ){ + Scr.ActiveWin = NULL; + SetFocus( tmp_win ); + } + KeepOnTop(); +} + +void MoveWindow( MlvwmWindow *mw, XEvent *evp ) +{ + Bool isEnd = False; + int pre_x, pre_y, drag_x, drag_y, last_x; + int x, y, JunkX, JunkY; + unsigned int JunkMask, emask; + Window JunkRoot, JunkChild; + XEvent ev; + + pre_x = evp->xbutton.x_root; + pre_y = evp->xbutton.y_root; + last_x = -1; + drag_x = 0; + drag_y = 0; + + XSync( dpy, 0 ); + while(XCheckMaskEvent(dpy, PointerMotionMask | ButtonMotionMask | + ButtonReleaseMask, &ev)) + if( ev.type == ButtonRelease) return; + + if( !(Scr.flags&OPAQUEMOVE) ){ + XGrabServer( dpy ); + XDrawRectangle( dpy, Scr.Root, Scr.RobberGC, mw->frame_x, mw->frame_y, + mw->frame_w, mw->frame_h ); + } + + XSync( dpy, 0 ); + if( !GrabEvent( MOVE ) ){ + XBell( dpy, 30 ); + return; + } + while( !isEnd ){ + emask = ButtonReleaseMask|ButtonMotionMask|PointerMotionMask; + if( Scr.flags&OPAQUEMOVE ) + emask |= ExposureMask; + XMaskEvent( dpy, emask, &ev ); + if ( ev.type == MotionNotify ) + while(XCheckMaskEvent(dpy, PointerMotionMask | ButtonMotionMask | + ButtonReleaseMask, &ev)) + if( ev.type == ButtonRelease) break; + switch( ev.type ){ + case Expose: handle_expose( &ev ); break; + case ButtonRelease: + if( !(Scr.flags&OPAQUEMOVE) ) + XDrawRectangle( dpy, Scr.Root, Scr.RobberGC, mw->frame_x-drag_x, + mw->frame_y-drag_y, mw->frame_w, mw->frame_h ); + XSync( dpy, 0 ); + mw->frame_x = mw->frame_x-drag_x; + mw->frame_y = mw->frame_y-drag_y; + SetUpFrame( mw, mw->frame_x, mw->frame_y, + mw->frame_w, mw->frame_h, True ); + isEnd = True; + break; + case MotionNotify: + XQueryPointer( dpy, ev.xany.window,&JunkRoot, &JunkChild, + &x, &y,&JunkX, &JunkY,&JunkMask); + if( drag_x==pre_x-x && drag_y==pre_y-y ) continue; + if( !(Scr.flags&OPAQUEMOVE) ) + XDrawRectangle( dpy, Scr.Root, Scr.RobberGC, + mw->frame_x-drag_x, mw->frame_y-drag_y, + mw->frame_w, mw->frame_h ); + if( mw->frame_y-pre_y+yframe_y+MENUB_H; + } + else last_x = -1; + drag_x = pre_x-x; + drag_y = pre_y-y; + if( Scr.flags&OPAQUEMOVE ) + XMoveWindow( dpy, mw->frame, + mw->frame_x-drag_x, mw->frame_y-drag_y ); + else + XDrawRectangle( dpy, Scr.Root, Scr.RobberGC, + mw->frame_x-drag_x, mw->frame_y-drag_y, + mw->frame_w, mw->frame_h ); + XSync( dpy, 0 ); + break; + } + } + if( !(Scr.flags&OPAQUEMOVE) ) XUngrabServer( dpy ); + UnGrabEvent(); + KeepOnTop(); +} + +void DisplayPush( Window win ) +{ + XSegment lines_a[4], lines_b[4]; + + XClearWindow( dpy, win ); + if( Scr.flags&SYSTEM8 ){ + XFillRectangle( dpy, win, Scr.Gray3GC, + 0, 0, BOXSIZE-1, BOXSIZE-1 ); + XDrawRectangle( dpy, win, Scr.BlackGC, + 1, 1, BOXSIZE-3, BOXSIZE-3 ); + DrawShadowBox( 0, 0, BOXSIZE, BOXSIZE, win, 1, + Scr.Gray3GC, Scr.WhiteGC, SHADOW_ALL ); + DrawShadowBox( 4, 4, BOXSIZE-6, BOXSIZE-6, win, BOXSIZE/2-2, + Scr.Gray4GC, Scr.Gray4GC, + SHADOW_BOTTOM|SHADOW_RIGHT ); + DrawShadowBox( 2, 2, BOXSIZE-6, BOXSIZE-6, win, BOXSIZE/2-2, + Scr.Gray2GC, Scr.WhiteGC, + SHADOW_TOP|SHADOW_LEFT ); + DrawShadowBox( 2, 2, 3, 3, win, 2, + Scr.Gray1GC, Scr.WhiteGC, + SHADOW_TOP|SHADOW_LEFT ); + } + else{ + SetSegment( 2, 4, 2, 4, lines_a ); + SetSegment( 2, 4, BOXSIZE-3, BOXSIZE-5, lines_a+1 ); + SetSegment( BOXSIZE-5, BOXSIZE-3, BOXSIZE-5, BOXSIZE-3, lines_a+2 ); + SetSegment( BOXSIZE-3, BOXSIZE-5, 2, 4, lines_a+3 ); + + SetSegment( 1, 4, 6, 6, lines_b ); + SetSegment( 6, 6, BOXSIZE-6, BOXSIZE-2, lines_b+1 ); + SetSegment( BOXSIZE-5, BOXSIZE-2, 6, 6, lines_b+2 ); + SetSegment( 6, 6, 1, 5, lines_b+3 ); + + XDrawSegments( dpy, win, Scr.Gray1GC, lines_a, 4 ); + XDrawSegments( dpy, win, Scr.BlackGC, lines_b, 4 ); + XDrawRectangle( dpy, win, Scr.BlackGC, 0, 0, BOXSIZE-1, BOXSIZE-1 ); + } + XSync( dpy, 0 ); +} + +void CloseWindow( MlvwmWindow *mw, XEvent *evp ) +{ + Bool isEnd = False, isIn = True; + XEvent ev; + int JunkX, JunkY; + Window JunkRoot; + unsigned int JunkWidth, JunkHeight, JunkBW, JunkDepth; + + DisplayPush( mw->close_b ); + while( !isEnd ){ + XMaskEvent( dpy,ButtonReleaseMask|EnterWindowMask|LeaveWindowMask, &ev ); + switch( ev.type ){ + case ButtonRelease: + isEnd = True; + break; + case EnterNotify: + if( ev.xcrossing.window==mw->close_b ){ + DisplayPush( mw->close_b ); + isIn = True; + } + break; + case LeaveNotify: + if( ev.xcrossing.window==mw->close_b ){ + DrawCloseBox( mw, True ); + isIn = False; + } + break; + } + } + + + if( isIn ){ + if ( mw->flags & DoesWmDeleteWindow) + send_clientmessage( mw->w, _XA_WM_DELETE_WINDOW, CurrentTime); + else if (XGetGeometry(dpy, mw->w, &JunkRoot, &JunkX, &JunkY, + &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth) + == 0) + Destroy( mw ); + else + XKillClient(dpy, mw->w); + } + XSync( dpy, 0 ); +} + +void DrawResizeFrame( int x, int y, int w, int h, MlvwmWindow *t ) +{ + XSegment lines[10]; + int nl=0; + + SetSegment( x, x+w, y, y, lines+nl ); nl++; + SetSegment( x+w, x+w, y, y+h, lines+nl ); nl++; + SetSegment( x, x+w, y+h, y+h, lines+nl ); nl++; + SetSegment( x, x, y, y+h, lines+nl ); nl++; + + if( Scr.flags&SYSTEM8 ){ + SetSegment( x+6, x+6, y+TITLE_HEIGHT+1, y+h-6, lines+nl ); nl++; + SetSegment( x+w-6, x+w-6, + y+TITLE_HEIGHT+1, y+h-6-(t->flags&RESIZER?SBAR_WH:0), + lines+nl ); + nl++; + SetSegment( x+6, x+w-6-(t->flags&RESIZER?SBAR_WH:0), + y+h-6, y+h-6, lines+nl ); + nl++; + if( t->flags&RESIZER ){ + SetSegment( x+w-SBAR_WH-6, x+w-SBAR_WH-6, + y+h-SBAR_WH-6, y+h-6, lines+nl ); + nl++; + SetSegment( x+w-SBAR_WH-6, x+w-6, + y+h-SBAR_WH-6, y+h-SBAR_WH-6, lines+nl ); + nl++; + } + if( t->flags&TITLE ){ + SetSegment( x+6, x+w-6, + y+TITLE_HEIGHT+1, y+TITLE_HEIGHT+1, lines+nl ); + nl++; + } + } + else{ + if( t->flags&SBARH ){ + SetSegment( x, x+w, y+h-2-SBAR_WH, y+h-2-SBAR_WH, lines+nl ); + nl++; + } + if( t->flags&SBARV ){ + SetSegment( x+w-2-SBAR_WH, x+w-2-SBAR_WH, + y+(t->flags&TITLE ? TITLE_HEIGHT : -1 )+1, y+h, + lines+nl ); + nl++; + } + if( t->flags&TITLE ){ + SetSegment( x, x+w, y+TITLE_HEIGHT+1, y+TITLE_HEIGHT+1, lines+nl ); + nl++; + } + } + + XDrawSegments( dpy, Scr.Root, Scr.RobberGC, lines, nl ); + XSync( dpy, 0 ); +} + +void ConstrainSize( MlvwmWindow *tmp_win, int *widthp, int *heightp ) +{ +#define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) ) +#define _min(a,b) (((a) < (b)) ? (a) : (b)) + + int minWidth, minHeight, maxWidth, maxHeight, xinc, yinc, delta; + int baseWidth, baseHeight; + int dwidth, dheight; + int title_height, sbar_v, sbar_h; + + title_height = tmp_win->flags & TITLE ? TITLE_HEIGHT : -1; + sbar_v = tmp_win->flags & SBARV ? SBAR_WH+2 : 1; + sbar_h = tmp_win->flags & SBARH ? SBAR_WH+2: 1; + + if( tmp_win->flags & ( TITLE | SBARV | SBARH | RESIZER ) ){ + dwidth = *widthp-1-sbar_v; + dheight = *heightp-2-sbar_h-title_height; + if( Scr.flags&SYSTEM8 ){ + dwidth -= 12; + dheight -= 6; + } + } + else{ + dwidth = *widthp-12; + dheight = *heightp-12; + } + if (tmp_win->hints.flags & PMinSize) { + minWidth = tmp_win->hints.min_width; + minHeight = tmp_win->hints.min_height; + } else if (tmp_win->hints.flags & PBaseSize) { + minWidth = tmp_win->hints.base_width; + minHeight = tmp_win->hints.base_height; + } else + minWidth = minHeight = 1; + + if (tmp_win->hints.flags & PBaseSize) { + baseWidth = tmp_win->hints.base_width; + baseHeight = tmp_win->hints.base_height; + } + else if (tmp_win->hints.flags & PMinSize) { + baseWidth = tmp_win->hints.min_width; + baseHeight = tmp_win->hints.min_height; + } + else + baseWidth = baseHeight = 0; + + if (tmp_win->hints.flags & PMinSize) { + baseWidth = tmp_win->hints.min_width; + baseHeight = tmp_win->hints.min_height; + } + else + baseWidth = baseHeight = 0; + + + if (tmp_win->hints.flags & PMaxSize) { + maxWidth = tmp_win->hints.max_width; + maxHeight = tmp_win->hints.max_height; + } + else { + maxWidth = MAX_WINDOW_WIDTH; + maxHeight = MAX_WINDOW_HEIGHT; + } + + if (tmp_win->hints.flags & PResizeInc) { + xinc = tmp_win->hints.width_inc; + yinc = tmp_win->hints.height_inc; + } else + xinc = yinc = 1; + /* + * First, clamp to min and max values + */ + if (dwidth < minWidth) dwidth = minWidth; + if (dheight < minHeight) dheight = minHeight; + + if (dwidth > maxWidth) dwidth = maxWidth; + if (dheight > maxHeight) dheight = maxHeight; + + /* + * Second, fit to base + N * inc + */ + dwidth = ((dwidth - baseWidth) / xinc * xinc) + baseWidth; + dheight = ((dheight - baseHeight) / yinc * yinc) + baseHeight; + + /* + * Third, adjust for aspect ratio + */ +#define maxAspectX tmp_win->hints.max_aspect.x +#define maxAspectY tmp_win->hints.max_aspect.y +#define minAspectX tmp_win->hints.min_aspect.x +#define minAspectY tmp_win->hints.min_aspect.y + /* + * The math looks like this: + * + * minAspectX dwidth maxAspectX + * ---------- <= ------- <= ---------- + * minAspectY dheight maxAspectY + * + * If that is multiplied out, then the width and height are + * invalid in the following situations: + * + * minAspectX * dheight > minAspectY * dwidth + * maxAspectX * dheight < maxAspectY * dwidth + * + */ + + if (tmp_win->hints.flags & PAspect){ + if (minAspectX * dheight > minAspectY * dwidth){ + delta = makemult(minAspectX * dheight / minAspectY - dwidth, + xinc); + if (dwidth + delta <= maxWidth) dwidth += delta; + else{ + delta = makemult(dheight - dwidth*minAspectY/minAspectX, + yinc); + if (dheight - delta >= minHeight) dheight -= delta; + } + } + + if (maxAspectX * dheight < maxAspectY * dwidth){ + delta = makemult(dwidth * maxAspectY / maxAspectX - dheight, + yinc); + if (dheight + delta <= maxHeight) dheight += delta; + else{ + delta = makemult(dwidth - maxAspectX*dheight/maxAspectY, + xinc); + if (dwidth - delta >= minWidth) dwidth -= delta; + } + } + } + + /* + * Fourth, account for border width and title height + */ + if( tmp_win->flags & ( TITLE | SBARV | SBARH | RESIZER ) ){ + if( Scr.flags&SYSTEM8 ){ + dwidth += 12; + dheight += 6; + } + *widthp = dwidth + sbar_v + 1; + *heightp = dheight + sbar_h + title_height + 2; + } + else{ + *widthp = dwidth + 12; + *heightp = dheight + 12; + } +} + +void ResizeWindow( MlvwmWindow *mw, XEvent *evp, Bool s_move ) +{ + Bool isEnd = False; + int pre_x, pre_y, new_w, new_h, org_w, org_h; + int x, y, JunkX, JunkY; + unsigned int JunkMask, evmask; + int xmotion, ymotion; + Window JunkRoot, JunkChild; + XEvent ev; + + pre_x = evp->xbutton.x_root; + pre_y = evp->xbutton.y_root; + org_w = new_w = mw->frame_w; + org_h = new_h = mw->frame_h; + if( s_move ){ + xmotion=1; + ymotion=1; + } + else{ + xmotion=0; + ymotion=0; + } + if( !GrabEvent( MOVE ) ){ + XBell( dpy, 30 ); + return; + } + if( !(Scr.flags&OPAQUERESIZE) ){ + XGrabServer( dpy ); + DrawResizeFrame( mw->frame_x, mw->frame_y, mw->frame_w, mw->frame_h, mw ); + } + while( !isEnd ){ + evmask = ButtonReleaseMask|ButtonMotionMask|PointerMotionMask; + if( Scr.flags&OPAQUERESIZE ) evmask |= ExposureMask; + XMaskEvent( dpy, evmask, &ev); + if ( ev.type == MotionNotify ) + while(XCheckMaskEvent(dpy, PointerMotionMask | ButtonMotionMask | + ButtonReleaseMask, &ev)) + if( ev.type == ButtonRelease) break; + switch( ev.type ){ + case Expose: handle_expose( &ev ); break; + case ButtonRelease: + if( !(Scr.flags&OPAQUERESIZE) ) + DrawResizeFrame( mw->frame_x, mw->frame_y, new_w, new_h, mw ); + XSync( dpy, 0 ); + mw->frame_w = new_w; + mw->frame_h = new_h; + SetUpFrame( mw, mw->frame_x, mw->frame_y, + mw->frame_w, mw->frame_h, False ); + isEnd = True; + break; + case MotionNotify: + XQueryPointer( dpy, ev.xany.window,&JunkRoot, &JunkChild, + &x, &y,&JunkX, &JunkY,&JunkMask); + if( xmotion==0 && x<=mw->frame_x ){ + xmotion=-1; + pre_x = mw->frame_x; + } + if( xmotion==0 && x>mw->frame_x + mw->frame_w ){ + xmotion=1; + pre_x = x; + } + if( ymotion==0 && y<=mw->frame_y ){ + ymotion=-1; + pre_y = mw->frame_y; + } + if( ymotion==0 && y>=mw->frame_y + mw->frame_h ){ + ymotion=1; + pre_y = y; + } + if( xmotion!=0 || ymotion!=0 ){ + if( !(Scr.flags&OPAQUERESIZE) ) + DrawResizeFrame( mw->frame_x, mw->frame_y, new_w, new_h, mw ); + if( xmotion!=0 ) + new_w = org_w + (x - pre_x)*xmotion; + if( ymotion!=0 ) + new_h = org_h + (y - pre_y)*ymotion; + + if( new_w<4*SBAR_WH ) new_w = 4*SBAR_WH+1; + if( new_h<4*SBAR_WH+(mw->flags & TITLE ? TITLE_HEIGHT : 0) ) + new_h = 4*SBAR_WH+(mw->flags & TITLE ? TITLE_HEIGHT : 0)+1; + + ConstrainSize( mw, &new_w, &new_h ); + + if( xmotion==-1 ) mw->frame_x = pre_x+mw->frame_w-new_w; + if( ymotion==-1 ) mw->frame_y = pre_y+mw->frame_h-new_h; + + if( Scr.flags&OPAQUERESIZE ){ + if( mw->frame_w!=new_w ) mw->frame_w = new_w; + if( mw->frame_h!=new_h ) mw->frame_h = new_h; + SetUpFrame( mw,mw->frame_x,mw->frame_y,new_w,new_h,False ); + } + else + DrawResizeFrame( mw->frame_x, mw->frame_y, new_w, new_h, mw ); + } + break; + } + } + if( !(Scr.flags&OPAQUERESIZE) ) + XUngrabServer( dpy ); + UnGrabEvent(); +} + +void MinMaxWindow( MlvwmWindow *mw, XEvent *evp ) +{ + Bool isEnd = False, isIn = True; + XEvent ev; + + DisplayPush( mw->minmax_b ); + XDrawRectangle( dpy, mw->minmax_b, Scr.BlackGC, + 1, 1, BOXSIZE-6, BOXSIZE-6 ); + while( !isEnd ){ + XMaskEvent( dpy, + ButtonReleaseMask|EnterWindowMask|LeaveWindowMask, &ev ); + switch( ev.type ){ + case ButtonRelease: + DrawMinMax( mw, True ); + XSync( dpy, 0 ); + isEnd = True; + break; + case EnterNotify: + if( ev.xcrossing.window==mw->minmax_b ){ + DisplayPush( mw->minmax_b ); + XDrawRectangle( dpy, mw->minmax_b, Scr.BlackGC, + 1, 1, BOXSIZE-6, BOXSIZE-6 ); + isIn = True; + } + break; + case LeaveNotify: + if( ev.xcrossing.window==mw->minmax_b ){ + DrawMinMax( mw, True ); + XSync( dpy, 0 ); + isIn = False; + } + break; + } + } + if( isIn ){ + if( mw->flags &SHADE ) + UnShadeWindow( mw ); + if( mw->flags & MAXIMAIZED ){ + if( mw->flags&SCROLL ){ + mw->win_x = mw->orig_win_x; + mw->win_y = mw->orig_win_y; + } + mw->frame_x = mw->orig_x; + mw->frame_y = mw->orig_y; + mw->frame_w = mw->orig_w; + mw->frame_h = mw->orig_h; + mw->flags &= ~MAXIMAIZED; + } + else{ + mw->orig_x = mw->frame_x; + mw->orig_y = mw->frame_y; + mw->orig_w = mw->frame_w; + mw->orig_h = mw->frame_h; + mw->frame_x = 0; + mw->frame_y = MENUB_H; + if( mw->flags&SCROLL ){ + mw->orig_win_x = mw->win_x; + mw->orig_win_y = mw->win_y; + mw->win_x = 0; + mw->win_y = 0; + } + if( mw->flags&SCROLL && + (mw->frame_wwin_w || + mw->frame_hwin_h) ){ + mw->frame_w = mw->win_w; + mw->frame_h = mw->win_h; + } + else{ + mw->frame_w = mw->size_w; + mw->frame_h = mw->size_h; + } + ConstrainSize( mw, &(mw->frame_w), &(mw->frame_h) ); + mw->flags |= MAXIMAIZED; + } + SetUpFrame( mw, mw->frame_x, mw->frame_y, + mw->frame_w, mw->frame_h, True ); + } +} + +void ShadeBox( MlvwmWindow *mw, XEvent *evp ) +{ + Bool isEnd = False, isIn = True; + XEvent ev; + + DisplayPush( mw->shade_b ); + XDrawLine( dpy, mw->shade_b, Scr.BlackGC, + 1, BOXSIZE/2-1, BOXSIZE-3, BOXSIZE/2-1 ); + XDrawLine( dpy, mw->shade_b, Scr.BlackGC, + 1, BOXSIZE/2+1, BOXSIZE-3, BOXSIZE/2+1 ); + while( !isEnd ){ + XMaskEvent( dpy, + ButtonReleaseMask|EnterWindowMask|LeaveWindowMask, &ev ); + switch( ev.type ){ + case ButtonRelease: + DrawShadeR( mw, True ); + XSync( dpy, 0 ); + isEnd = True; + break; + case EnterNotify: + if( ev.xcrossing.window==mw->shade_b ){ + DisplayPush( mw->shade_b ); + XDrawLine( dpy, mw->shade_b, Scr.BlackGC, + 1, BOXSIZE/2-1, BOXSIZE-3, BOXSIZE/2-1 ); + XDrawLine( dpy, mw->shade_b, Scr.BlackGC, + 1, BOXSIZE/2+1, BOXSIZE-3, BOXSIZE/2+1 ); + isIn = True; + } + break; + case LeaveNotify: + if( ev.xcrossing.window==mw->shade_b ){ + DrawShadeR( mw, True ); + XSync( dpy, 0 ); + isIn = False; + } + break; + } + } + if( isIn ){ + if( mw->flags&SHADE ) + UnShadeWindow( mw ); + else + ShadeWindow( mw ); + } +} + +void DoubleClickEvent( XEvent *ev ) +{ + MlvwmWindow *Tmp_win; + int context; + Window win; + + if( XFindContext( dpy, ev->xany.window, MlvwmContext, (caddr_t *)&Tmp_win ) + != XCNOENT ){ + context = GetContext( Tmp_win, ev, &win ); + if( context == C_TITLE ){ + if( Tmp_win->flags&SHADE ) + UnShadeWindow( Tmp_win ); + else + ShadeWindow( Tmp_win ); + } + } +} + +/*** + isHbar if scroll bar is Horizontal, then true +***/ +void PressSbarAnker( Bool isHbar, MlvwmWindow *tmp_win ) +{ + Window JunkRoot, JunkChild, bar, anker; + XEvent ev; + XWindowAttributes winattrs; + Bool isEnd = False; + int *mouse_p, *mouse_w, zero=0, *anker_x, *anker_y, *vector, anker_end; + int x, y, JunkX, JunkY; + unsigned int JunkMask; + int sub_edge=0, anker_calc, init_posi, hide_size; + + if( !(tmp_win->flags&SCROLL) || + (tmp_win->frame_w>=tmp_win->win_w && isHbar) || + (tmp_win->frame_h>=tmp_win->win_h && !isHbar) ) + return; + if( isHbar ){ + XGetWindowAttributes( dpy, tmp_win->scroll_h[3], &winattrs); + init_posi = winattrs.x; + mouse_p = &x; + mouse_w = &y; + anker = tmp_win->scroll_h[3]; + bar = tmp_win->scroll_h[0]; + anker_x = &anker_calc; + anker_y = &zero; + XGetWindowAttributes( dpy, tmp_win->scroll_h[0], &winattrs); + anker_end = winattrs.width-SBAR_WH-1-SBAR_WH; + vector = &(tmp_win->win_x); + hide_size = tmp_win->frame_w-tmp_win->win_w; + } + else{ + XGetWindowAttributes( dpy, tmp_win->scroll_v[3], &winattrs); + init_posi = winattrs.y; + mouse_w = &x; + mouse_p = &y; + anker = tmp_win->scroll_v[3]; + bar = tmp_win->scroll_v[0]; + anker_x = &zero; + anker_y = &anker_calc; + XGetWindowAttributes( dpy, tmp_win->scroll_v[0], &winattrs); + anker_end = winattrs.height-SBAR_WH-1-SBAR_WH; + vector = &(tmp_win->win_y); + hide_size = tmp_win->frame_h-tmp_win->win_h; + } + + if( XQueryPointer( dpy, bar, &JunkRoot, &JunkChild, + &JunkX, &JunkY, &x, &y, &JunkMask ) ) + sub_edge = *mouse_p-init_posi; + if( !GrabEvent( DEFAULT ) ){ + XBell( dpy, 30 ); + return; + } + XDrawRectangle( dpy, anker, Scr.BlackGC, 0, 0, SBAR_WH-1, SBAR_WH-1 ); + XSync( dpy, 0 ); + do{ + if( XCheckMaskEvent( dpy, ButtonReleaseMask | ExposureMask | + ButtonMotionMask | PointerMotionMask | + PointerMotionHintMask, &ev ) ){ + if( ev.type==MotionNotify ) + while( XCheckMaskEvent( dpy, PointerMotionMask | + ButtonMotionMask | ButtonReleaseMask, + &ev ) ) + if( ev.type == ButtonRelease ) break; + switch( ev.type ){ + case ButtonRelease: isEnd = True; + break; + case MotionNotify: + if( XQueryPointer( dpy, bar, &JunkRoot, &JunkChild, + &JunkX, &JunkY, &x, &y, &JunkMask ) && + *mouse_w>-2*SBAR_WH && *mouse_w<3*SBAR_WH){ + anker_calc = *mouse_p-sub_edge; + if( anker_calc<=SBAR_WH+1 ) anker_calc = SBAR_WH+1; + if( anker_calc>anker_end ) anker_calc = anker_end; + XMoveWindow( dpy, anker, *anker_x, *anker_y ); + } + } + } + } + while( !isEnd ); + *vector = (double)((anker_calc-SBAR_WH-1)*hide_size)/ + (double)(anker_end-SBAR_WH-1); + SetUpFrame( tmp_win, tmp_win->frame_x, tmp_win->frame_y, + tmp_win->frame_w, tmp_win->frame_h, True ); + UnGrabEvent(); +} + +/*** + isHbar if scroll bar is Horizontal, then true +***/ +void PressSbar( Bool isHbar, Window pressedwin, MlvwmWindow *tmp_win ) +{ + int *vector, pushd, pre_vector, direction=0; + Bool isEnd = False, isSelect = True; + int view, world, inc_view, inc=1; + int x, y, JunkX, JunkY; + unsigned int JunkMask; + int *check_axis, *anker_check, timeout=1; + struct timeval tp, current; + Window JunkRoot, JunkChild, bar, anker; + XWindowAttributes winattrs, winattrs_a; + int ignore=1; + XEvent ev; + + if( !(tmp_win->flags&SCROLL) || + (tmp_win->frame_w>=tmp_win->win_w && isHbar) || + (tmp_win->frame_h>=tmp_win->win_h && !isHbar) ) + return; + XGetWindowAttributes(dpy, tmp_win->Parent, &winattrs); + if( isHbar ){ + vector = &(tmp_win->win_x); + view = tmp_win->frame_w; + world = tmp_win->win_w; + for( pushd=0; pushd<4 && + tmp_win->scroll_h[pushd]!=pressedwin; pushd++ ); + if( pushd==1 ) direction = C_SBAR_LEFT; + if( pushd==2 ) direction = C_SBAR_RIGHT; + bar = tmp_win->scroll_h[0]; + if (tmp_win->hints.flags & PResizeInc) + inc = tmp_win->hints.width_inc; + inc_view = winattrs.width; + check_axis = &x; + anker_check = &(winattrs_a.x); + anker = tmp_win->scroll_h[3]; + } + else{ + vector = &(tmp_win->win_y); + view = tmp_win->frame_h; + world = tmp_win->win_h; + for( pushd=0; pushd<4 && + tmp_win->scroll_v[pushd]!=pressedwin; pushd++ ); + if( pushd==1 ) direction = C_SBAR_UP; + if( pushd==2 ) direction = C_SBAR_DOWN; + bar = tmp_win->scroll_v[0]; + if( tmp_win->hints.flags & PResizeInc ) + inc = tmp_win->hints.height_inc; + inc_view = winattrs.height; + check_axis = &y; + anker_check = &(winattrs_a.y); + anker = tmp_win->scroll_v[3]; + } + if( pushd!=0 ){ + DrawArrow( pressedwin, direction, Scr.BlackGC ); + XSync( dpy, 0 ); + } + + pre_vector = *vector; + + tp.tv_usec = 0; + tp.tv_sec = 0; + do{ + if( timeout && isSelect && !isEnd ){ + switch( pushd ){ + case 1: (*vector)+=inc; break; + case 2: (*vector)-=inc; break; + case 0: + XQueryPointer( dpy, pressedwin,&JunkRoot, &JunkChild, + &JunkX, &JunkY, &x, &y, &JunkMask); + XGetWindowAttributes(dpy, anker, &winattrs_a); + if( *check_axis>*anker_check+SBAR_WH ) (*vector)-=inc_view; + if( *check_axis<*anker_check ) (*vector)+=inc_view; + break; + } + *vector = view-world > *vector ? view-world : *vector; + *vector = *vector>0 ? 0 : *vector; + + if( pre_vector != *vector ){ + SetUpFrame( tmp_win, tmp_win->frame_x, tmp_win->frame_y, + tmp_win->frame_w, tmp_win->frame_h, True ); + XSync( dpy, 0 ); + pre_vector = *vector; + } + } + if( XPending(dpy)){ + if(XCheckMaskEvent( dpy, ButtonReleaseMask|EnterWindowMask| + LeaveWindowMask|ExposureMask, &ev ) ){ + switch( ev.type ){ + case ButtonRelease: + isEnd = True; + timeout = 1; + break; + case EnterNotify: + if( ev.xcrossing.window==pressedwin ){ + if( !isSelect ) + DrawArrow( pressedwin, direction, Scr.BlackGC ); + isSelect = True; + } + break; + case LeaveNotify: + if( ev.xcrossing.window==pressedwin ){ + if( isSelect ) + DrawArrow( pressedwin, direction, Scr.Gray3GC ); + isSelect = False; + } + break; + } + } + } + if( timeout ){ + gettimeofday( &tp, NULL ); + if( ignore ){ + tp.tv_usec += 1000000; + ignore = 0; + } + else + tp.tv_usec += 100000; + + tp.tv_sec += tp.tv_usec/1000000; + tp.tv_usec = tp.tv_usec%1000000; + timeout = 0; + } + + gettimeofday( ¤t, NULL ); + + if( (tp.tv_sec-current.tv_sec)*1000000-(tp.tv_usec-current.tv_usec)<0 ){ + timeout = 1; + } + else{ + if( !isEnd ) sleep_a_little( 20000 ); + } + } + while( !isEnd ); + + if( pushd!=0 ) + DrawArrow( pressedwin, direction, Scr.Gray3GC ); + XSync( dpy, 0 ); +} + +void handle_button_press( XEvent *ev ) +{ + MlvwmWindow *Tmp_win; + MenuLabel *tmp_menu; + Window win; + static Time PressTime=0; + static int Click_x, Click_y; + int context; + Bool newactive=False; + + if( ev->xbutton.time-PressTimexbutton.x>Click_x-4 && ev->xbutton.xxbutton.y>Click_y-4 && ev->xbutton.yxbutton.button == Button1 ){ + DoubleClickEvent( ev ); + PressTime=0; + + return; + } + else{ + PressTime = ev->xbutton.time; + Click_x = ev->xbutton.x; + Click_y = ev->xbutton.y; + } + if( XFindContext( dpy, ev->xany.window, MlvwmContext, (caddr_t *)&Tmp_win ) + != XCNOENT ){ + context = GetContext( Tmp_win, ev, &win ); + XGrabServer( dpy ); + if( (Tmp_win!=Scr.ActiveWin || Scr.flags&FOLLOWTOMOUSE) ) + RaiseMlvwmWindow( Tmp_win ); + XUngrabServer( dpy ); + + if( Tmp_win != Scr.ActiveWin ){ + SetFocus( Tmp_win ); + PressTime = 0; + newactive = True; + if( ev->xbutton.subwindow!=None ){ + ev->xany.window = ev->xbutton.subwindow; + context = GetContext( Tmp_win, ev, &win ); + } + XAllowEvents(dpy, AsyncPointer, CurrentTime ); + } + else + XAllowEvents(dpy, ReplayPointer, CurrentTime ); + XSync(dpy,0); + + if( newactive && context!=C_TITLE ) return; + if( ev->xbutton.button != Button1 ) return; + + switch( context ){ + case C_TITLE: MoveWindow( Tmp_win, ev ); break; + case C_CLOSE: CloseWindow( Tmp_win, ev ); break; + case C_MINMAX: MinMaxWindow( Tmp_win, ev ); break; + case C_SHADE: ShadeBox( Tmp_win, ev ); break; + case C_RESIZE: ResizeWindow( Tmp_win, ev, True ); break; + case C_SBAR_V: + case C_SBAR_UP: + case C_SBAR_DOWN: + PressSbar( False, ev->xany.window, Tmp_win ); + break; + case C_SBAR_H: + case C_SBAR_LEFT: + case C_SBAR_RIGHT: + PressSbar( True, ev->xany.window, Tmp_win ); + break; + case C_SBAR_V_AN: PressSbarAnker( False, Tmp_win ); break; + case C_SBAR_H_AN: PressSbarAnker( True, Tmp_win ); break; + case C_FRAME: + if( Scr.flags&SYSTEM8)MoveWindow( Tmp_win, ev ); break; + } + } + else{ + if( ev->xbutton.button != Button1 ) return; + if( XFindContext( dpy, ev->xany.window, + MenuContext, (caddr_t *)&tmp_menu )==XCNOENT ) + tmp_menu = NULL; + if( ev->xbutton.y<=MENUB_H ) + press_menu( tmp_menu ); + } + + if( !(Scr.flags&FOLLOWTOMOUSE) && Scr.ActiveWin != NULL && + GetContext( Scr.ActiveWin, ev, &win )==C_ROOT ) + SetFocus( NULL ); + if( Scr.flags&SLOPPYFOCUS && Scr.ActiveWin != NULL && + GetContext( Scr.ActiveWin, ev, &win )==C_ROOT ) + SetFocus( NULL ); + + KeepOnTop(); +} + +void handle_expose( XEvent *ev ) +{ + MlvwmWindow *Tmp_win, *ActiveWin; + MenuLabel *Tmp_menu; + int context; + Window win; + + if( Scr.ActiveWin==NULL && Scr.PreviousActive!=NULL ) + ActiveWin = Scr.PreviousActive; + else + ActiveWin = Scr.ActiveWin; + + if( ev->xexpose.count != 0 ) return; + if( XFindContext( dpy, ev->xany.window, MlvwmContext, (caddr_t *)&Tmp_win ) + != XCNOENT ){ + context = GetContext( Tmp_win, ev, &win ); + switch( context ){ + case C_TITLE: + SetTitleBar( Tmp_win, (ActiveWin==Tmp_win?True:False) ); + break; + case C_SBAR_V: + DrawSbarBar( Tmp_win, C_SBAR_V, (ActiveWin==Tmp_win?True:False) ); + break; + case C_SBAR_UP: case C_SBAR_DOWN: + case C_SBAR_LEFT: case C_SBAR_RIGHT: + DrawSbarArrow( Tmp_win, context, (ActiveWin==Tmp_win?True:False) ); + break; + case C_SBAR_V_AN: + DrawSbarAnk(Tmp_win, C_SBAR_V_AN ,(ActiveWin==Tmp_win?True:False)); + break; + case C_SBAR_H: + DrawSbarBar( Tmp_win, C_SBAR_H, (ActiveWin==Tmp_win?True:False) ); + break; + case C_SBAR_H_AN: + DrawSbarAnk(Tmp_win, C_SBAR_H_AN ,(ActiveWin==Tmp_win?True:False)); + break; + case C_RESIZE: + DrawResizeBox( Tmp_win, (ActiveWin==Tmp_win?True:False)); + break; + case C_FRAME: + DrawFrameShadow( Tmp_win, (ActiveWin==Tmp_win?True:False) ); + break; + } + } + if( ev->xany.window == Scr.MenuBar ) + RedrawMenuBar(); + if( XFindContext( dpy, ev->xany.window, MenuContext, (caddr_t *)&Tmp_menu ) + != XCNOENT ) + RedrawMenu( Tmp_menu, False ); +} + +void HandleEnterNotify( XEvent *ev ) +{ + MlvwmWindow *tmp_win; + XEnterWindowEvent *ewp = &(ev->xcrossing); + XEvent d; + + if(XCheckTypedWindowEvent (dpy, ewp->window, LeaveNotify, &d)) + if((d.xcrossing.mode==NotifyNormal)&&(d.xcrossing.detail!=NotifyInferior)) + return; + if( ev->xany.window == Scr.Root ){ + if ( Scr.flags&FOLLOWTOMOUSE && !(Scr.flags&SLOPPYFOCUS)) + SetFocus( NULL ); + InstallWindowColormaps( &Scr.MlvwmRoot ); + return; + } + if( XFindContext ( dpy, ev->xany.window, MlvwmContext, (caddr_t *)&tmp_win ) + != XCNOENT ){ + if( Scr.flags&FOLLOWTOMOUSE ) SetFocus( tmp_win ); + if( ev->xcrossing.window==tmp_win->w ) + InstallWindowColormaps( tmp_win ); + } +} + +void HandleLeaveNotify( XEvent *ev ) +{ + MlvwmWindow *tmp_win; + XEvent dummy; + + if( ev->xcrossing.window == Scr.Root) return; + if(XCheckTypedWindowEvent (dpy, ev->xcrossing.window, EnterNotify, &dummy)) + return; + if( XFindContext ( dpy, ev->xany.window, MlvwmContext, (caddr_t *)&tmp_win ) + == XCNOENT ) + return; + + if ( ev->xcrossing.detail != NotifyInferior ){ + if( ev->xcrossing.window==tmp_win->frame ){ + if( (Scr.flags & FOLLOWTOMOUSE) && !(Scr.flags&SLOPPYFOCUS) ){ + if( Scr.ActiveWin == tmp_win ) + SetFocus( NULL ); + } + InstallWindowColormaps (&Scr.MlvwmRoot); + } + else{ + if( ev->xcrossing.window==tmp_win->w ) + InstallWindowColormaps( &Scr.MlvwmRoot ); + } + } +} + +void HandleShapeNotify ( XEvent *ev ) +{ + MlvwmWindow *Tmp_win; + XShapeEvent *sev = (XShapeEvent *) ev; + + if( XFindContext ( dpy, ev->xany.window, MlvwmContext, (caddr_t *)&Tmp_win ) + == XCNOENT ) + return; + if (sev->kind != ShapeBounding) + return; + Tmp_win->wShaped = sev->shaped; + SetShape(Tmp_win,Tmp_win->frame_w); +} + +void handle_unmap_request( XEvent *ev ) +{ + int dstx, dsty; + Window dumwin; + XEvent dummy; + MlvwmWindow *tmp_win; + Bool reparented; + + if( ev->xunmap.event != ev->xunmap.window ) return; + if( XFindContext( dpy, ev->xany.window, MlvwmContext, (caddr_t *)&tmp_win ) + ==XCNOENT ){ + ev->xany.window = ev->xunmap.window; + if( XFindContext( dpy, ev->xany.window, MlvwmContext, (caddr_t *)&tmp_win ) + ==XCNOENT ) + return; + } + + if ( !(tmp_win->flags & MAPPED) ) return; + XGrabServer( dpy ); + + if(XCheckTypedWindowEvent (dpy, ev->xunmap.window, DestroyNotify, &dummy)){ +/* ev->xany.window = ev->xunmap.window;*/ + ev->xdestroywindow.window = ev->xunmap.window; + HandleDestroy( ev ); + XUngrabServer( dpy ); + return; + } + + if( XTranslateCoordinates ( dpy, ev->xunmap.window, Scr.Root, + 0, 0, &dstx, &dsty, &dumwin ) ){ + reparented = XCheckTypedWindowEvent (dpy, ev->xunmap.window, + ReparentNotify, &dummy); + SetMapStateProp (tmp_win, WithdrawnState); + if( !reparented ) + RestoreWithdrawnLocation (tmp_win,False); + XRemoveFromSaveSet (dpy, ev->xunmap.window); + XSelectInput (dpy, ev->xunmap.window, NoEventMask); +/* ev->xany.window = ev->xunmap.window;*/ + ev->xdestroywindow.window = ev->xunmap.window; + HandleDestroy( ev ); + } + XUngrabServer( dpy ); + XFlush (dpy); +} + +void handle_property_request( XEvent *ev ) +{ + MlvwmWindow *tmp_win; + unsigned char *prop = NULL; + Atom actual = None; + int actual_format; + unsigned long nitems, bytesafter; + int JunkX = 0, JunkY = 0; + Window JunkRoot; /* junk window */ + XTextProperty text_prop; + unsigned int JunkWidth, JunkHeight, JunkBW, JunkDepth; + char desk[8], *str, action[24]; +#ifdef USE_LOCALE + int num; + char **list; +#endif + char *oldWinName, *winname; + + if( ev->xproperty.atom==_XA_WM_DESKTOP && ev->xany.window==Scr.Root ){ + if ((XGetWindowProperty(dpy, Scr.Root, _XA_WM_DESKTOP, 0L, 1L, True, + _XA_WM_DESKTOP, &actual, &actual_format, &nitems, + &bytesafter, &prop))==Success){ + if(prop != NULL){ + sprintf( desk, "Desk %ld", *(unsigned long *)prop ); + ChangeDesk( desk ); + } + } + return; + } + if( XFindContext( dpy, ev->xany.window, MlvwmContext, (caddr_t *)&tmp_win ) + ==XCNOENT ) return; + if ( XGetGeometry( dpy, tmp_win->w, &JunkRoot, &JunkX, &JunkY, + & JunkWidth, &JunkHeight, &JunkBW, &JunkDepth) == 0 ) + return; + switch( ev->xproperty.atom ){ + case XA_WM_NAME: + oldWinName = WinListName( tmp_win ); + if( XGetWMName( dpy, tmp_win->w, &text_prop) != 0 ){ +#ifdef USE_LOCALE + if(text_prop.value) + text_prop.nitems = strlen(text_prop.value); + if(XmbTextPropertyToTextList(dpy, &text_prop, &list, &num) >= Success + && num > 0 && *list) + tmp_win->name = *list; +#else + tmp_win->name = (char *)text_prop.value; +#endif + } + else + tmp_win->name = NoName; + + winname = WinListName( tmp_win ); + sprintf( action, "Select %lX", (unsigned long)tmp_win ); + ChangeMenuItemLabel( "ICON", oldWinName, winname, + action, M_ALLSET, M_AND ); + if( tmp_win==Scr.ActiveWin ){ + str = calloc( strlen( tmp_win->name )+6, 1 ); + sprintf( str, "Hide %s", tmp_win->name ); + ChangeMenuItemLabel( "ICON", Scr.IconMenu.m_item->label, + str, NULL, SELECTON, M_COPY ); + free( str ); + } + free( oldWinName ); + free( winname ); + SetTitleBar( tmp_win, (Scr.ActiveWin==tmp_win?True:False) ); + break; + case XA_WM_ICON_NAME: + break; + case XA_WM_HINTS: + break; + case XA_WM_NORMAL_HINTS: + GetWindowSizeHints( tmp_win ); + break; + default: + if( ev->xproperty.atom == _XA_WM_PROTOCOLS) + FetchWmProtocols( tmp_win ); + break; + } +} + +void HandleMapNotify( XEvent *ev ) +{ + MlvwmWindow *tmp_win; + char action[24]; + + if( XFindContext( dpy, ev->xany.window, MlvwmContext, (caddr_t *)&tmp_win ) + ==XCNOENT ) + tmp_win = NULL; + if (!tmp_win){ + if( (ev->xmap.override_redirect == True) && + (ev->xmap.window != Scr.NoFocusWin)) + XSelectInput( dpy, ev->xmap.window,FocusChangeMask); + return; + } + + if( ev->xmap.event != ev->xmap.window) + return; + + XGrabServer (dpy); + + XMapSubwindows(dpy, tmp_win->frame); + + if( !(tmp_win->flags & MAPPED)){ + if( !(tmp_win->flags & NOWINLIST) && + !(tmp_win->flags & TRANSIENT) ){ + sprintf( action, "Select %lX", (unsigned long)tmp_win ); + AddMenuItem( &(Scr.IconMenu), WinListName( tmp_win ), action, + NULL, tmp_win->miniicon, NULL, + SELECTON ); + } + if( tmp_win->flags&STARTICONIC ){ + if( Scr.flags&ICONIFYSHADE && !(tmp_win->flags&SHADE )) + ShadeWindow( tmp_win ); + if( Scr.flags&ICONIFYHIDE && !(tmp_win->flags&HIDED )) + HideWindow( tmp_win ); + tmp_win->flags &= ~STARTICONIC; + } + } + if(tmp_win->Desk == Scr.currentdesk && !(tmp_win->flags&HIDED)){ + + if( Scr.flags&STARTING ) + XLowerWindow( dpy, tmp_win->frame ); + else + RaiseMlvwmWindow( tmp_win ); + XMapWindow(dpy, tmp_win->frame); + if( !(Scr.flags & FOLLOWTOMOUSE) && + !(Scr.flags&SLOPPYFOCUS) && + !(tmp_win->flags&NOFOCUS) ) + SetFocus( tmp_win ); + } + + tmp_win->flags |= MAPPED; + + XSync( dpy, 0 ); + XUngrabServer (dpy); + XFlush (dpy); +/* + KeepOnTop(); +*/ +} + + +void HandleMapRequest( Window win ) +{ + MlvwmWindow *tmp_win; + + if(XFindContext(dpy, win, MlvwmContext, + (caddr_t *)&tmp_win)==XCNOENT) + tmp_win = NULL; + + XFlush(dpy); + + /* If the window has never been mapped before ... */ + if(!tmp_win){ + /* Add decorations. */ + tmp_win = AddWindow( win ); + if( !tmp_win ) return; + } + + if (!(tmp_win->flags & ICON)){ + int state; + if( (!(Scr.flags&RSTPREVSTATE) || + (state = GetMapStateProp( tmp_win ))==WithdrawnState) && + tmp_win->wmhints && (tmp_win->wmhints->flags & StateHint) ) + state = tmp_win->wmhints->initial_state; + else + state = NormalState; + + XGrabServer( dpy ); + XMapWindow(dpy, tmp_win->w); + switch (state){ + case DontCareState: + case NormalState: + case InactiveState: + SetMapStateProp(tmp_win, NormalState); + break; + case IconicState: + tmp_win->flags |= STARTICONIC; + break; + } + XSync( dpy, 0 ); + XUngrabServer( dpy ); + } + KeepOnTop(); +} + +void HandleKeyPress( XEvent *ev ) +{ + MlvwmWindow *tmp_win; + ShortCut *key; + unsigned int mods_used = (ShiftMask | ControlMask | Mod1Mask | + Mod2Mask| Mod3Mask| Mod4Mask| Mod5Mask); + unsigned int modifier; + + if(XFindContext( dpy, ev->xany.window, MlvwmContext, (caddr_t *)&tmp_win ) + ==XCNOENT) + tmp_win=NULL; + + modifier = (ev->xkey.state & mods_used); + for (key = Scr.ShortCutRoot; key != NULL; key = key->next){ + ev->xkey.keycode = + XKeysymToKeycode(dpy, XKeycodeToKeysym(dpy,ev->xkey.keycode,0)); + if ((key->keycode == ev->xkey.keycode) && + ((key->mods == modifier)||(key->mods == AnyModifier))){ + ExecuteFunction( key->action ); + return; + } + } + if( tmp_win ){ + if( ev->xkey.window != tmp_win->w){ + ev->xkey.window = tmp_win->w; + XSendEvent(dpy, tmp_win->w, False, KeyPressMask, ev ); + } + } +} + +void HandleClientMessage( XEvent *ev ) +{ + MlvwmWindow *tmp_win; + XWindowAttributes winattrs; + unsigned long eventMask; + MlvwmWindow *NextActive; + char action[24]; + + if( XFindContext( dpy, ev->xany.window, MlvwmContext, (caddr_t *)&tmp_win ) + == XCNOENT ) return; + + if( ev->xclient.message_type==_XA_WM_CHANGE_STATE ){ + XGetWindowAttributes(dpy, tmp_win->w, &winattrs); + eventMask = winattrs.your_event_mask; + + switch( ev->xclient.data.l[0] ){ + case IconicState: + XSelectInput(dpy, tmp_win->w, eventMask & ~StructureNotifyMask); + + if( Scr.flags&ICONIFYSHADE && !(tmp_win->flags&SHADE )){ + ShadeWindow( tmp_win ); + XUnmapWindow( dpy, tmp_win->w ); + } + if( Scr.flags&ICONIFYHIDE && !(tmp_win->flags&HIDED )){ + NextActive = NextActiveWin( tmp_win ); + XUnmapWindow( dpy, tmp_win->w ); + HideWindow( tmp_win ); + if( !(Scr.flags & FOLLOWTOMOUSE) ){ + SetFocus( NextActive ); + if( NextActive ) + RaiseMlvwmWindow( NextActive ); + } + ChangeMenuItemLabel( "ICON", "Show All", "Show All", + NULL, SELECTON, M_COPY ); + } + XSelectInput(dpy, tmp_win->w, eventMask); + + break; + case NormalState: + if( Scr.flags&ICONIFYSHADE && !(tmp_win->flags&SHADE )) + UnShadeWindow( tmp_win ); + if( Scr.flags&ICONIFYHIDE && !(tmp_win->flags&HIDED )){ + sprintf( action, "Select %lX", (unsigned long)tmp_win ); + SelectWindow( action ); + } + break; + } + return; + } + if( ev->xclient.window != tmp_win->w){ + ev->xclient.window = tmp_win->w; + XSendEvent(dpy, tmp_win->w, False, NoEventMask, ev ); + } +} + +void HandleEvents( XEvent ev ) +{ + strcpy( Scr.ErrorFunc, "HandleEvents" ); + switch( ev.type ){ + case Expose: + strcpy( Scr.ErrorFunc, "Expose" ); + handle_expose( &ev ); + strcpy( Scr.ErrorFunc, "Expose End" ); + break; + case DestroyNotify: + strcpy( Scr.ErrorFunc, "DestroyNotify" ); + HandleDestroy( &ev ); + strcpy( Scr.ErrorFunc, "DestroyNotify End" ); + break; + case MapRequest: + strcpy( Scr.ErrorFunc, "MapRequest" ); + HandleMapRequest( ev.xmaprequest.window ); + strcpy( Scr.ErrorFunc, "MapRequest End" ); + break; + case MapNotify: + strcpy( Scr.ErrorFunc, "MapNotify" ); + HandleMapNotify( &ev ); + strcpy( Scr.ErrorFunc, "MapNotify End" ); + break; + case UnmapNotify: + strcpy( Scr.ErrorFunc, "UnmapNotify" ); + handle_unmap_request( &ev ); + strcpy( Scr.ErrorFunc, "UnmapNotify End" ); + break; + case ButtonPress: + strcpy( Scr.ErrorFunc, "ButtonPress" ); + handle_button_press( &ev ); + strcpy( Scr.ErrorFunc, "ButtonPress End" ); + break; + case EnterNotify: + strcpy( Scr.ErrorFunc, "EnterNotify" ); + HandleEnterNotify( &ev ); + strcpy( Scr.ErrorFunc, "EnterNotify End" ); + break; + case LeaveNotify: + strcpy( Scr.ErrorFunc, "LeaveNotify" ); + HandleLeaveNotify( &ev ); + strcpy( Scr.ErrorFunc, "LeaveNotify End" ); + break; + case FocusIn: + strcpy( Scr.ErrorFunc, "FocusIn" ); + break; + case ConfigureRequest: + strcpy( Scr.ErrorFunc, "ConfigureRequest" ); + handle_configure_request( &ev ); + strcpy( Scr.ErrorFunc, "ConfigureRequest End" ); + break; + case ClientMessage: + strcpy( Scr.ErrorFunc, "ClientMessage" ); + HandleClientMessage( &ev ); + break; + case PropertyNotify: + strcpy( Scr.ErrorFunc, "PropertyNotify" ); + handle_property_request( &ev ); + strcpy( Scr.ErrorFunc, "PropertyNotify End" ); + break; + case KeyPress: + strcpy( Scr.ErrorFunc, "KeyPress" ); + HandleKeyPress( &ev ); + strcpy( Scr.ErrorFunc, "KeyPress End" ); + break; + case ColormapNotify: + strcpy( Scr.ErrorFunc, "ColormapNotify" ); + break; + default: + strcpy( Scr.ErrorFunc, "default" ); + if( ev.type == (ShapeEventBase + ShapeNotify)){ + strcpy( Scr.ErrorFunc, "Shape" ); + HandleShapeNotify( &ev ); + strcpy( Scr.ErrorFunc, "Shape End" ); + } + strcpy( Scr.ErrorFunc, "default End" ); + break; + } + strcpy( Scr.ErrorFunc, "Leave Handle Events" ); +} + +void WaitEvents( void ) +{ + extern int xfd; + + XEvent ev; + struct timeval value; + fd_set in_fdset; + + value.tv_usec = 0; + value.tv_sec = 1; + + FD_ZERO( &in_fdset ); + FD_SET( xfd, &in_fdset ); + + strcpy( Scr.ErrorFunc, "WaitEvents" ); + XFlush( dpy ); + if( XPending( dpy ) ){ + XNextEvent( dpy, &ev ); + HandleEvents( ev ); + + return; + } + XFlush( dpy ); + ReapChildren(); + strcpy( Scr.ErrorFunc, "WaitEvents End" ); + if( Scr.flags & DEBUGOUT ) fprintf( stderr, "Return WaitEvents\n" ); + +#ifdef __hpux + if( select( xfd+1, (int *)&in_fdset, 0, 0, &value ) == 0){ +#else + if( select( xfd+1, &in_fdset, 0, 0, &value ) == 0){ +#endif + if( Scr.flags&BALLOONON ) BalloonHelp(); + } +} diff --git a/mlvwm/event.h b/mlvwm/event.h new file mode 100644 index 0000000..15b26db --- /dev/null +++ b/mlvwm/event.h @@ -0,0 +1,37 @@ +/****************************************************************************/ +/* This module is all original code */ +/* by TakaC Hasegawa (tak@bioele.nuee.nagoya-u.ac.jp */ +/* Copyright 1996, TakaC Hasegawa */ +/* You may use this code for any purpose, as long as the original */ +/* copyright remains in the source code and all documentation */ +/****************************************************************************/ +#ifndef _EVENT_ +#define _EVENT_ + +extern void InstallWindowColormaps (MlvwmWindow * ); +extern Bool GrabEvent( int ); +extern void UnGrabEvent( void ); +extern void RestoreWithdrawnLocation( MlvwmWindow *, Bool ); +extern int GetContext( MlvwmWindow *, XEvent *, Window * ); +extern void Destroy( MlvwmWindow * ); +extern void HandleDestroy( XEvent * ); +extern void handle_configure_request( XConfigureRequestEvent ); +extern void MoveWindow( MlvwmWindow *, XEvent *, Bool ); +extern void DisplayPush( Window ); +extern void CloseWindow( MlvwmWindow *, XEvent * ); +extern void DrawResizeFrame( int, int, int, int ); +extern void ResizeWindow( MlvwmWindow *, XEvent *, Bool ); +extern void MinMaxWindow( MlvwmWindow *, XEvent * ); +extern void HandleMapRequest( Window ); +extern void handle_button_press( XEvent * ); +extern void handle_expose( XEvent * ); +extern void HandleEnterNotify( XEvent * ); +extern void HandleLeaveNotify( XEvent * ); +extern void HandleShapeNotify ( XEvent * ); +extern void HandleEvents( XEvent ); +extern void send_clientmessage (Window, Atom, Time); +extern void WaitEvents( void ); +extern MlvwmWindow *NextActiveWin( MlvwmWindow * ); +extern void SetMapStateProp( MlvwmWindow *, int ); +extern void GetWindowSizeHints( MlvwmWindow * ); +#endif diff --git a/mlvwm/functions.c b/mlvwm/functions.c new file mode 100644 index 0000000..b1b7af0 --- /dev/null +++ b/mlvwm/functions.c @@ -0,0 +1,879 @@ +/****************************************************************************/ +/* This module is all original code */ +/* by TakaC Hasegawa (tak@bioele.nuee.nagoya-u.ac.jp */ +/* Copyright 1996, TakaC Hasegawa */ +/* You may use this code for any purpose, as long as the original */ +/* copyright remains in the source code and all documentation */ +/****************************************************************************/ +#include +#include +#include +#include + +#include "mlvwm.h" +#include "screen.h" +#include "functions.h" +#include "borders.h" +#include "event.h" +#include "misc.h" +#include "balloon.h" + +extern char NoName[]; + +void IconZoom ( MlvwmWindow *mw, Bool on ) +{ + int x,y,w,h, dx,dy,dw,dh; + float r,s; + dx = (Scr.IconMenu.LabelWidth - Scr.IconMenu.xpm->width)/2 - mw->frame_x + + Scr.IconMenu.LabelX; + dy = (MENUB_H - Scr.IconMenu.xpm->height)/2 - mw->frame_y; + dw = Scr.IconMenu.xpm->width - mw->frame_w; + dh = Scr.IconMenu.xpm->height - mw->frame_h; + + XGrabServer( dpy ); + for( r=0.; r<=1.; r=r+.05 ){ + s = on? 1. - r*r : 1. - (1.-r)*(1.-r); + x = mw->frame_x + s * dx; + y = mw->frame_y + s * dy; + w = mw->frame_w + s * dw; + h = mw->frame_h + s * dh; + XDrawRectangle( dpy, Scr.Root, Scr.RobberGC, x, y, w, h ); + sleep_a_little( Scr.zoom_wait ); + XSync( dpy, 0 ); + XDrawRectangle( dpy, Scr.Root, Scr.RobberGC, x, y, w, h ); + } + XSync( dpy, 0 ); + XUngrabServer( dpy ); +} + +void ShadeWindow( MlvwmWindow *mw ) +{ + unsigned long valuemask; + XSetWindowAttributes attr; + + mw->shade_h = mw->frame_h; + mw->frame_h = TITLE_HEIGHT+2; + mw->flags |= SHADE; + if( mw->flags&SBARV ) XUnmapWindow( dpy, mw->scroll_v[0] ); + if( mw->flags&SBARH ) XUnmapWindow( dpy, mw->scroll_h[0] ); + if( mw->flags&RESIZER ) XUnmapWindow( dpy, mw->resize_b ); + XUnmapWindow(dpy, mw->Parent); + + if( mw->flags&SHADER ){ + attr.cursor = Scr.MlvwmCursors[SHADER_DOWN_CURSOR]; + valuemask = CWCursor; + XChangeWindowAttributes( dpy, mw->shade_b, valuemask, &attr ); + } + if( Scr.flags&ICONIFYSHADE ) + SetMapStateProp( mw, IconicState ); + SetUpFrame( mw,mw->frame_x,mw->frame_y,mw->frame_w,mw->frame_h, False ); + if( Scr.flags&SYSTEM8 ) + SetTitleBar( mw, True ); +} + +void UnShadeWindow( MlvwmWindow *mw ) +{ + unsigned long valuemask; + XSetWindowAttributes attr; + + mw->frame_h = mw->shade_h; + mw->flags &= ~SHADE; + if( mw->flags&SBARV ) XMapWindow( dpy, mw->scroll_v[0] ); + if( mw->flags&SBARH ) XMapWindow( dpy, mw->scroll_h[0] ); + if( mw->flags&RESIZER ) XMapWindow( dpy, mw->resize_b ); + XMapWindow(dpy, mw->Parent); + + if( Scr.flags&ICONIFYSHADE ){ + XMapWindow( dpy, mw->w ); + SetMapStateProp( mw, NormalState ); + } + XSetInputFocus( dpy, mw->w, RevertToParent, CurrentTime ); + + if( mw->flags&SHADER ){ + attr.cursor = Scr.MlvwmCursors[SHADER_UP_CURSOR]; + valuemask = CWCursor; + XChangeWindowAttributes( dpy, mw->shade_b, valuemask, &attr ); + } + SetUpFrame( mw,mw->frame_x,mw->frame_y,mw->frame_w,mw->frame_h, True ); +} + +void UnmapIt( MlvwmWindow *t ) +{ + XWindowAttributes winattrs; + unsigned long eventMask; + /* + * Prevent the receipt of an UnmapNotify, since that would + * cause a transition to the Withdrawn state. + */ + XGetWindowAttributes(dpy, t->w, &winattrs); + eventMask = winattrs.your_event_mask; + XSelectInput(dpy, t->w, eventMask & ~StructureNotifyMask); + if(t->flags & MAPPED) + XUnmapWindow(dpy, t->frame); + XSelectInput(dpy, t->w, eventMask); +} + +void MapIt( MlvwmWindow *t ) +{ + if( t->flags&MAPPED && !(t->flags&HIDED) ){ + if( !(t->flags&SHADE) ){ + XMapWindow(dpy, t->Parent); + XMapWindow(dpy, t->frame); + } + else + XMapWindow(dpy, t->frame); + } +} + +MlvwmWindow *ChoiseWindow( XEvent *ev, int cursor ) +{ + Bool loop=True; + MlvwmWindow *tmp_win; + Window select_win; + + if( !GrabEvent( cursor ) ){ + XBell( dpy, 30 ); + return NULL; + } + while( loop ){ + XMaskEvent( dpy, ButtonPressMask | ButtonMotionMask | + PointerMotionMask | ExposureMask | + VisibilityChangeMask, ev ); + if( ev->type==ButtonPress ) + loop = False; + else + HandleEvents( *ev ); + } + UnGrabEvent(); + + select_win = ev->xany.window; + if((( select_win == Scr.Root ) || ( select_win == Scr.NoFocusWin ) ) + && ( ev->xbutton.subwindow != (Window)0 ) ) + select_win = ev->xbutton.subwindow; + if(XFindContext(dpy, select_win, MlvwmContext, (caddr_t *)&tmp_win)==XCNOENT) + tmp_win = NULL; + return tmp_win; +} + +void MoveWindowFunction( char *action ) +{ + MlvwmWindow *tmp_win; + XEvent ev; + + tmp_win = ChoiseWindow( &ev, MOVE ); + if( !tmp_win ){ + XBell( dpy, 30 ); + return; + } + MoveWindow( tmp_win, &ev, False ); +} + +void ResizeWindowFunction( char *action ) +{ + MlvwmWindow *tmp_win; + XEvent ev; + + tmp_win = ChoiseWindow( &ev, MOVE ); + if( !tmp_win ){ + XBell( dpy, 30 ); + return; + } + if( tmp_win->flags&SHADE ) return; + ResizeWindow( tmp_win, &ev, False ); +} + +void KillWindowFunction( char *action ) +{ + MlvwmWindow *tmp_win; + XEvent ev; + int JunkX, JunkY; + Window JunkRoot; + unsigned int JunkWidth, JunkHeight, JunkBW, JunkDepth; + + tmp_win = ChoiseWindow( &ev, DESTROY ); + if( !tmp_win ){ + XBell( dpy, 30 ); + return; + } + if ( tmp_win->flags & DoesWmDeleteWindow) + send_clientmessage( tmp_win->w, _XA_WM_DELETE_WINDOW, CurrentTime); + else if (XGetGeometry(dpy, tmp_win->w, &JunkRoot, &JunkX, &JunkY, + &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth) == 0) + Destroy( tmp_win ); + else + XKillClient(dpy, tmp_win->w); +} + +void ToggleScrollFunction( char *action ) +{ + MlvwmWindow *tmp_win; + XEvent ev; + + tmp_win = ChoiseWindow( &ev, SELECT ); + if( !tmp_win ){ + XBell( dpy, 30 ); + return; + } + if( tmp_win->flags & ( SBARV | SBARH ) ){ + if( tmp_win->flags&SCROLL ){ +/* Scroll Mode Off */ + tmp_win->flags &= ~SCROLL; + tmp_win->win_x = 0; + tmp_win->win_y = 0; + tmp_win->frame_w = tmp_win->win_w; + tmp_win->frame_h = tmp_win->win_h; + XUnmapWindow( dpy, tmp_win->scroll_v[3] ); + XUnmapWindow( dpy, tmp_win->scroll_h[3] ); + SetUpFrame( tmp_win, tmp_win->frame_x, tmp_win->frame_y, + tmp_win->frame_w, tmp_win->frame_h, True ); + } + else{ +/* Scroll Mode On */ + tmp_win->flags |= SCROLL; + tmp_win->win_x = 0; + tmp_win->win_y = 0; + if( tmp_win->flags&MAXIMAIZED ){ + tmp_win->win_w = tmp_win->orig_w; + tmp_win->win_h = tmp_win->orig_h; + } + else{ + tmp_win->win_w = tmp_win->frame_w; + tmp_win->win_h = tmp_win->frame_h; + } + XMoveWindow( dpy, tmp_win->scroll_v[3], 0, SBAR_WH+2 ); + XMoveWindow( dpy, tmp_win->scroll_h[3], SBAR_WH+2, 0 ); + XMapWindow( dpy, tmp_win->scroll_v[3] ); + XMapWindow( dpy, tmp_win->scroll_h[3] ); + } + } + else{ + XBell( dpy, 30 ); + tmp_win->flags &= ~SCROLL; + } +} + +void NopFunction( char *action ) +{ +} + +void AboutThisMachine( char *action ) +{ +} + +void RefreshScreen( char *action ) +{ + Window w; + XSetWindowAttributes attributes; + unsigned long valuemask; + + valuemask = CWBackingStore; + attributes.background_pixel = BlackPixel( dpy, Scr.screen ); + attributes.backing_store = NotUseful; + w = XCreateWindow (dpy, Scr.Root, 0, 0, + (unsigned int) Scr.MyDisplayWidth, + (unsigned int) Scr.MyDisplayHeight, + (unsigned int) 0, + CopyFromParent, (unsigned int) CopyFromParent, + (Visual *) CopyFromParent, valuemask, + &attributes); + XMapWindow (dpy, w); + XDestroyWindow (dpy, w); + XFlush (dpy); +} + +void ChangeDesk( char *action ) +{ + MlvwmWindow *tmp, *Active=NULL; + Bool LastActiveLive=False; + int newdesk; + char str[8], *oldwinname, *winname, builtaction[24]; + + if( strchr( action, '+' ) ){ + newdesk = Scr.currentdesk+1; + if( Scr.flags&ROTATEDESK && newdesk>Scr.n_desktop-1 ) + newdesk = 0; + newdesk = min( Scr.n_desktop-1, newdesk ); + } + else if( strchr( action, '-' ) ){ + newdesk = Scr.currentdesk-1; + if( Scr.flags&ROTATEDESK && newdesk<0 ) + newdesk = Scr.n_desktop-1; + newdesk = max( 0, newdesk ); + } + else + sscanf( action, "%s%d", str, &newdesk ); + + if( newdesk==Scr.currentdesk ) return; + + if( (Scr.ActiveWin && + ((Scr.flags&STICKSHADE && Scr.ActiveWin->flags&SHADE) || + Scr.ActiveWin->flags&STICKY)) && + !(Scr.ActiveWin->flags&SKIPSELECT) ) + Active = Scr.ActiveWin; + + Scr.LastActive[Scr.currentdesk] = Scr.ActiveWin; + + if( !Active ) + Active = Scr.LastActive[newdesk]; + + for (tmp = (MlvwmWindow *)Scr.MlvwmRoot.next; tmp != NULL; + tmp = (MlvwmWindow *)tmp->next){ + if( (Scr.flags&STICKSHADE && tmp->flags&SHADE) || tmp->flags&STICKY ){ + sprintf( builtaction, "Select %lX", (unsigned long)tmp ); + oldwinname = WinListName( tmp ); + tmp->Desk = newdesk; + winname = WinListName( tmp ); + if( Scr.flags&DISPDESK && !(tmp->flags&NOWINLIST) ) + ChangeMenuItemLabel( "ICON", oldwinname, winname, + builtaction, M_ALLSET, M_AND ); + free( winname ); + free( oldwinname ); + } + + if( newdesk==tmp->Desk ){ + MapIt( tmp ); + if( tmp==Active ) + LastActiveLive = True; + } + else + UnmapIt( tmp ); + } + + sprintf( str, "Desk %d", Scr.currentdesk ); + ChangeMenuItemLabel( "ICON", str, str, NULL, SELECTON, M_COPY ); + sprintf( str, "Desk %d", newdesk ); + ChangeMenuItemLabel( "ICON", str, str, NULL, SELECTON|CHECKON, M_COPY ); + + Scr.currentdesk=newdesk; + if( !LastActiveLive ) Active = NULL; + SetFocus( Active ); + + XUngrabServer (dpy); +/* + if( !(Scr.flags&STARTING) ){ + if( !(Scr.flags & FOLLOWTOMOUSE) && Active ) +*/ + if( !(Scr.flags&STARTING) && Active ){ + RaiseMlvwmWindow( Active ); +/* + else + KeepOnTop(); +*/ + } + return; +} + +void ShowBalloon( char *action ) +{ + BalloonHelp (); +} + +void ShadeUnShadeActiveWindow( char *action ) +{ + if( Scr.ActiveWin==NULL || !(Scr.ActiveWin->flags&TITLE) ) return; + + if( Scr.ActiveWin->flags&SHADE ) + UnShadeWindow( Scr.ActiveWin ); + else + ShadeWindow( Scr.ActiveWin ); +} + +void SelectWindow( char *action ) +{ + char str[7], desk[8], *oldwinname, *winname; + MlvwmWindow *tmp, *testwin; + int newdesk, hided=0; + + sscanf( action, "%s%lX", str, (unsigned long *)&tmp ); + if( Scr.flags&STICKHIDE && tmp->flags&HIDED ){ + oldwinname = WinListName( tmp ); + tmp->Desk = Scr.currentdesk; + winname = WinListName( tmp ); + if( Scr.flags&DISPDESK ) + ChangeMenuItemLabel( "ICON", oldwinname, winname, + action, M_ALLSET, M_AND ); + free( winname ); + free( oldwinname ); + } + if( Scr.currentdesk != tmp->Desk ){ + newdesk = tmp->Desk; + sprintf( desk, "Desk %d", newdesk ); + ChangeDesk( desk ); + } + if( tmp->flags&HIDED ){ + for( testwin = (MlvwmWindow *)Scr.MlvwmRoot.next; testwin != NULL; + testwin = (MlvwmWindow *)testwin->next) + if( (testwin->flags&TRANSIENT && + testwin->transientfor==tmp->w + && testwin!=tmp) || testwin==tmp ){ + testwin->flags &= ~HIDED; + MapIt( testwin ); + if( Scr.flags&ICONIFYHIDE ){ + XMapWindow( dpy, testwin->w ); + SetMapStateProp( testwin, NormalState ); + } + } + } + if( !(Scr.flags&SHADEMAP) && tmp->flags&SHADE ) + UnShadeWindow( tmp ); + if( Scr.flags&FOLLOWTOMOUSE ) + XWarpPointer( dpy,None,tmp->frame,0,0,0,0, + tmp->frame_w/2,TITLE_HEIGHT/2 ); + else + SetFocus( tmp ); + XSetInputFocus( dpy, tmp->w, RevertToParent, CurrentTime ); + RaiseMlvwmWindow( tmp ); + for (tmp = (MlvwmWindow *)Scr.MlvwmRoot.next; tmp != NULL; + tmp = (MlvwmWindow *)tmp->next) + if( tmp->flags&HIDED ) hided++; + if( hided==0 ) + ChangeMenuItemLabel( "ICON", "Show All", "Show All", + NULL, STRGRAY, M_COPY ); +} + +void SelectNextWindow( char *action ) +{ + MlvwmWindow *tmp, *last, *start, *lastactive=NULL; + char desk[8]; + int newdesk, lastdesk=0; + Bool samedesk=False; + + if( !Scr.MlvwmRoot.next ) return; + + if( !strcmp( action, "NextSameDeskWindow" )) samedesk = True; + + for( last = Scr.MlvwmRoot.next; last && last->next!=NULL; + last = last->next ); + + if( Scr.ActiveWin==NULL || Scr.ActiveWin->next==NULL ){ + tmp = Scr.MlvwmRoot.next; + start = last; + } + else{ + tmp = Scr.ActiveWin->next; + start = Scr.ActiveWin; + } + + while( (tmp->flags&HIDED || tmp->flags&SKIPSELECT || + (samedesk && Scr.currentdesk!=tmp->Desk)) && tmp!=start ){ + tmp = tmp->next; + if( tmp==NULL ) tmp = Scr.MlvwmRoot.next; + } + + if( tmp==Scr.ActiveWin || (samedesk && Scr.currentdesk!=tmp->Desk) ) + return; + + if( Scr.currentdesk != tmp->Desk ){ + newdesk = tmp->Desk; + sprintf( desk, "Desk %d", newdesk ); + Scr.LastActive[newdesk] = tmp; + if( Scr.ActiveWin && Scr.ActiveWin->flags&STICKY ){ + lastactive = Scr.ActiveWin; + lastdesk = Scr.currentdesk; + SetFocus( NULL ); + } + ChangeDesk( desk ); + if( lastactive ) + Scr.LastActive[lastdesk] = lastactive; + } + else + RaiseMlvwmWindow( tmp ); + + if( Scr.flags&FOLLOWTOMOUSE ) + XWarpPointer( dpy,None,tmp->frame,0,0,0,0, + tmp->frame_w/2,TITLE_HEIGHT/2 ); + else + SetFocus( tmp ); +} + +void SelectPreviousWindow( char *action ) +{ + MlvwmWindow *tmp, *last, *start, *lastactive=NULL; + char desk[8]; + int newdesk, lastdesk=0; + Bool samedesk=False; + + if( !Scr.MlvwmRoot.next ) return; + + if( !strcmp( action, "PreviousSameDeskWindow" )) + samedesk = True; + + for( last = Scr.MlvwmRoot.next; last && last->next!=NULL; + last = last->next ); + + if( Scr.ActiveWin==NULL || Scr.ActiveWin->prev==&Scr.MlvwmRoot ){ + tmp = last; + start = Scr.MlvwmRoot.next; + } + else{ + tmp = Scr.ActiveWin->prev; + start = Scr.ActiveWin; + } + while( (tmp->flags&HIDED || tmp->flags&SKIPSELECT || + (samedesk && Scr.currentdesk!=tmp->Desk)) && + tmp!=start ){ + tmp = tmp->prev; + if( tmp==&Scr.MlvwmRoot ) tmp = last; + } + if( tmp==Scr.ActiveWin || (samedesk && Scr.currentdesk!=tmp->Desk) ) + return; + if( Scr.currentdesk != tmp->Desk ){ + newdesk = tmp->Desk; + sprintf( desk, "Desk %d", newdesk ); + Scr.LastActive[newdesk] = tmp; + if( Scr.ActiveWin && Scr.ActiveWin->flags&STICKY ){ + lastactive = Scr.ActiveWin; + lastdesk = Scr.currentdesk; + SetFocus( NULL ); + } + ChangeDesk( desk ); + if( lastactive ) + Scr.LastActive[lastdesk] = lastactive; + } + else + RaiseMlvwmWindow( tmp ); + if( Scr.flags&FOLLOWTOMOUSE ) + XWarpPointer( dpy,None,tmp->frame,0,0,0,0, + tmp->frame_w/2,TITLE_HEIGHT/2 ); + else + SetFocus( tmp ); +} + +void HideWindow( MlvwmWindow *mw ) +{ + char builtaction[24]; + char *winname; + + winname = WinListName( mw ); + sprintf( builtaction, "Select %lX", (unsigned long)mw ); + ChangeMenuItemLabel( "ICON", winname, winname, + builtaction, ICONGRAY|SELECTON, M_COPY ); + if( mw->Desk==Scr.currentdesk ){ + UnmapIt( mw ); + if( mw->flags & MAPPED && !(mw->flags & HIDED) ) + IconZoom( mw, False ); + } + mw->flags |= HIDED; + if( Scr.flags&ICONIFYHIDE ){ + XMapWindow( dpy, mw->w ); + SetMapStateProp( mw, IconicState ); + } + free( winname ); +} + +void HideActiveWindow( char *action ) +{ + MlvwmWindow *NextActive, *testwin; + + if( Scr.ActiveWin ){ + NextActive = NextActiveWin( Scr.ActiveWin ); + for( testwin = (MlvwmWindow *)Scr.MlvwmRoot.next; testwin != NULL; + testwin = (MlvwmWindow *)testwin->next) + if( testwin->flags&TRANSIENT && + testwin->transientfor==Scr.ActiveWin->w + && testwin!=Scr.ActiveWin ) + HideWindow( testwin ); + + HideWindow( Scr.ActiveWin ); + if( !(Scr.flags & FOLLOWTOMOUSE) ){ + SetFocus( NextActive ); + if( NextActive ) + RaiseMlvwmWindow( NextActive ); + } + ChangeMenuItemLabel( "ICON", "Show All", "Show All", + NULL, SELECTON, M_COPY ); + } + else + XBell( dpy, 30 ); +} + +void HideOtherWindow( char *action ) +{ + MlvwmWindow *tmp; + int hidewin=0; + + if( !Scr.ActiveWin ) return; + for (tmp = (MlvwmWindow *)Scr.MlvwmRoot.next; tmp != NULL; + tmp = (MlvwmWindow *)tmp->next){ + if( tmp!=Scr.ActiveWin ){ + HideWindow( tmp ); + hidewin++; + } + } + if( hidewin ) + ChangeMenuItemLabel( "ICON", "Show All", "Show All", + NULL, SELECTON, M_COPY ); +} + +void ShowAllWindow( char *action ) +{ + MlvwmWindow *tmp, *ActiveWin=NULL; + char builtaction[24], *winname; + + for (tmp = (MlvwmWindow *)Scr.MlvwmRoot.next; tmp != NULL; + tmp = (MlvwmWindow *)tmp->next){ + sprintf( builtaction, "Select %lX", (unsigned long)tmp ); + winname = WinListName( tmp ); + ChangeMenuItemLabel( "ICON", winname, winname, + builtaction, SELECTON, M_COPY ); + free( winname ); + if( tmp->flags&HIDED ) { +/* + IconZoom( tmp, True ); +*/ + tmp->flags &= ~HIDED; + } + if( tmp->Desk==Scr.currentdesk ){ + MapIt( tmp ); + ActiveWin=tmp; + } + if( Scr.flags&ICONIFYHIDE ){ + XMapWindow( dpy, tmp->w ); + SetMapStateProp( tmp, NormalState ); + } + if( !(Scr.flags&SHADEMAP) && tmp->flags&SHADE ) + UnShadeWindow( tmp ); + } + ChangeMenuItemLabel( "ICON", "Show All", "Show All", + NULL, STRGRAY, M_COPY ); + if( ActiveWin ){ + if( Scr.flags&FOLLOWTOMOUSE ) + XWarpPointer( dpy,None,ActiveWin->frame,0,0,0,0, + ActiveWin->frame_w/2,TITLE_HEIGHT/2 ); + else + SetFocus( ActiveWin ); + XSetInputFocus( dpy, ActiveWin->w, RevertToParent, CurrentTime ); + RaiseMlvwmWindow( ActiveWin ); + } +} + +void ExecSystems( char *action ) +{ + char *comm; + + if( strchr( action, '"' ) ) + comm = strrchr( action, '"' )+1; + else + comm = action+5; + + if( Scr.flags & DEBUGOUT ) + fprintf( stderr, "Exec System <%s> !\n", comm ); + if (!(fork())){ /* child process */ + if( Scr.flags & DEBUGOUT ) + fprintf( stderr, "Fork Successful %s\n", comm ); + if (execl("/bin/sh", "/bin/sh", "-c", comm, (char *)0)==-1){ + fprintf( stderr, "Exec fail %s\n", comm ); + exit(100); + } + } +} + +void RestartSystem( char *action ) +{ + char *top; + + top = SkipSpace( SkipNonSpace( action+6 )); + if( strncmp( top, "mlvwm", 5 ) ) + Done( 1, top ); + else + Done( 1, NULL ); +} + +void ExitSystem( char *action ) +{ + Done( 0, NULL ); +} + +extern struct configure key_modifiers[]; + +void SendMessage( char *action ) +{ + XKeyEvent ev; + KeySym keysym; + KeyCode keycode=0; + Bool quota=False; + char *mem, *top, *mod, *key; + char oldchar, code[2]; + int lp, tag; + + if( !(Scr.ActiveWin) ) return; + mem = top = strdup( SkipSpace( SkipNonSpace( action ) ) ); + while( *top!='\n' && *top!='\0' ){ + key = top; + top = SkipNonSpace( top ); + oldchar = *top; + *top = '\0'; + mod = NULL; + if( strchr( key, '+' ) ){ + mod = key; + key = strchr( key, '+' ); + *key = '\0'; + key++; + } + ev.state = 0; + for( lp=0; mod && mod[lp]!='\0'; lp++ ){ + for( tag=0; key_modifiers[tag].key!=0; tag++ ){ + if( key_modifiers[tag].key==mod[lp] ) + ev.state |= key_modifiers[tag].value; + } + } + if( key[0]=='"' ) quota = True; + code[1] = '\0'; + do{ + if( quota ){ + key++; + keycode = 0; + if( *key=='"' ) + quota = False; + else{ + code[0] = *key; + if((keysym = XStringToKeysym(code)) != NoSymbol ) + keycode = XKeysymToKeycode(dpy, keysym); + } + } + else{ + if((keysym = XStringToKeysym(key)) != NoSymbol ) + keycode = XKeysymToKeycode(dpy, keysym); + } + ev.keycode = keycode; + ev.type = KeyPress; + ev.window = Scr.ActiveWin->w; + if( ev.keycode != 0 ) + XSendEvent(dpy,Scr.ActiveWin->w,False, + KeyPressMask,(XEvent *)&ev); + } + while( quota ); + *top = oldchar; + top = SkipSpace( top ); + } + free( mem ); +} + +void ToggleBalloon( char *action ) +{ + if( Scr.flags&BALLOONON ){ + Scr.flags &= ~BALLOONON; + if( Scr.BalloonOffStr && Scr.BalloonOnStr){ + ChangeMenuItemLabel( "Balloon", Scr.BalloonOnStr, + Scr.BalloonOffStr, NULL, SELECTON, M_COPY ); + } + } + else{ + Scr.flags |= BALLOONON; + if( Scr.BalloonOffStr && Scr.BalloonOnStr){ + ChangeMenuItemLabel( "Balloon", Scr.BalloonOffStr, + Scr.BalloonOnStr, NULL, SELECTON, M_COPY ); + } + } +} + +void WaitMap( char *action ) +{ + XEvent ev; + XClassHint class; + MlvwmWindow *tmp_win; + Bool done=True; + char *name, *waitname, *point; + Atom *protocols = NULL; + XTextProperty text_prop; +#ifdef USE_LOCALE + int num; + char **list; +#endif + + waitname = SkipSpace( action+5 ); + point=SkipNonSpace(waitname); + if( *point!='\0' ) + *point = '\0'; + else + *(--point)='\0'; + + do{ + XMaskEvent( dpy, SubstructureRedirectMask | + StructureNotifyMask | SubstructureNotifyMask, &ev ); + if( ev.type==MapRequest ){ + if( XGetWMName( dpy, ev.xmaprequest.window, &text_prop) != 0 ){ +#ifdef USE_LOCALE + if(text_prop.value) + text_prop.nitems = strlen(text_prop.value); + if(XmbTextPropertyToTextList(dpy, &text_prop, &list, &num) + >= Success + && num > 0 && *list) + name = *list; + else + name = NoName; +#else + name = (char *)text_prop.value; +#endif + } + else + name = NoName; + + XGetClassHint(dpy, ev.xmaprequest.window, &class); + if( !strcmp( name, waitname ) || + !strcmp( class.res_name, waitname ) || + !strcmp( class.res_class, waitname ) ){ + done = False; + if (protocols) XFree ((char *) protocols); + } + } + HandleEvents( ev ); + if( Scr.flags&STARTING && ev.type==MapNotify && + XFindContext( dpy, ev.xany.window, + MlvwmContext, (caddr_t *)&tmp_win )!=XCNOENT) + DrawStringMenuBar( tmp_win->name ); + } + while( done ); +} + +void DebugWinList( char *action ) +{ + MlvwmWindow *tmp; + + printf("Start\n"); + for( tmp = Scr.MlvwmRoot.next; tmp!=NULL; tmp = tmp->next ){ + printf("Name %s[%lX] Desk %d",tmp->name,(unsigned long)tmp,tmp->Desk); + if( tmp==Scr.ActiveWin ) printf("<=\n"); + else printf("\n"); + } + printf("End\n"); +} + +builtin_func funcs[] = { + { "DebugWinList", DebugWinList }, + { "About", AboutThisMachine }, + { "Desk", ChangeDesk }, + { "Exec", ExecSystems }, + { "Exit", ExitSystem }, + { "ShowBalloon", ShowBalloon }, + { "HideActive", HideActiveWindow }, + { "HideOthers", HideOtherWindow }, + { "KillWindow", KillWindowFunction }, + { "MoveWindow", MoveWindowFunction }, + { "NextWindow", SelectNextWindow }, + { "NextSameDeskWindow", SelectNextWindow }, + { "Nop", NopFunction }, + { "PreviousWindow", SelectPreviousWindow }, + { "PreviousSameDeskWindow", SelectPreviousWindow }, + { "Refresh", RefreshScreen }, + { "ResizeWindow", ResizeWindowFunction }, + { "Restart", RestartSystem }, + { "Select", SelectWindow }, + { "SendMessage", SendMessage }, + { "ShadeUnShadeActive", ShadeUnShadeActiveWindow }, + { "ShowAll", ShowAllWindow }, + { "ToggleScroll", ToggleScrollFunction }, + { "ToggleBalloon", ToggleBalloon }, + { "Wait", WaitMap }, + { NULL, 0 } +}; + +void ExecuteFunction( char *act ) +{ + int lp; + + if( act==NULL ) return; + for( lp=0; funcs[lp].label!=NULL; lp++ ) + if( !strncmp( act, funcs[lp].label, strlen( funcs[lp].label ) ) ) + funcs[lp].action( act ); +} diff --git a/mlvwm/functions.h b/mlvwm/functions.h new file mode 100644 index 0000000..203f83c --- /dev/null +++ b/mlvwm/functions.h @@ -0,0 +1,29 @@ +/****************************************************************************/ +/* This module is all original code */ +/* by TakaC Hasegawa (tak@bioele.nuee.nagoya-u.ac.jp */ +/* Copyright 1996, TakaC Hasegawa */ +/* You may use this code for any purpose, as long as the original */ +/* copyright remains in the source code and all documentation */ +/****************************************************************************/ +#ifndef _FUNCTION_ +#define _FUNCTION_ + +typedef struct builtin_func +{ + char *label; + void (*action)(); +} builtin_func; + +extern void ShadeWindow( MlvwmWindow * ); +extern void UnShadeWindow( MlvwmWindow * ); +extern void HideWindow( MlvwmWindow * ); +extern void NopFunction( char * ); +extern void AboutThisMachine( char * ); +extern void RefreshScreen( char * ); +extern void ChangeDesk( char * ); +extern void SelectWindow( char * ); +extern void ExecSystems( char * ); +extern void RestartSystem( char * ); +extern void ExitSystem( char * ); +extern void ExecuteFunction( char * ); +#endif diff --git a/mlvwm/menus.c b/mlvwm/menus.c new file mode 100644 index 0000000..543f042 --- /dev/null +++ b/mlvwm/menus.c @@ -0,0 +1,1593 @@ +/****************************************************************************/ +/* This module is all original code */ +/* by TakaC Hasegawa (tak@bioele.nuee.nagoya-u.ac.jp */ +/* Copyright 1996, TakaC Hasegawa */ +/* You may use this code for any purpose, as long as the original */ +/* copyright remains in the source code and all documentation */ +/****************************************************************************/ +#include +#include +#include +#include + +#include "mlvwm.h" +#include "screen.h" +#include "menus.h" +#include "event.h" +#include "functions.h" +#include "misc.h" +#include "add_window.h" +#include "borders.h" + +#include +#include + +#include + +void RedrawMenu( MenuLabel *m, Bool onoroff ) +{ + GC tmp_f_GC, tmp_b_GC; + int width, offset; + unsigned long gcm; + XGCValues gcv; + Pixel fore_pixel, back_pixel; + + if( Scr.flags&SYSTEM8 ){ + gcm = GCForeground; + if( !XGetGCValues( dpy, Scr.MenuBlueGC, gcm, &gcv ) ){ + fprintf( stderr, "Sorry Can not get GC Values Blue\n"); + gcv.foreground = WhitePixel( dpy, Scr.screen ); + } + fore_pixel = gcv.foreground; + if( !XGetGCValues( dpy, Scr.MenuSelectBlueGC, gcm, &gcv ) ){ + fprintf( stderr, "Sorry Can not get GC Values SelectBlue\n"); + gcv.foreground = WhitePixel( dpy, Scr.screen ); + } + back_pixel = gcv.foreground; + } + else{ + fore_pixel = WhitePixel( dpy, Scr.screen ); + back_pixel = BlackPixel( dpy, Scr.screen ); + } + + if( onoroff ) + XSetWindowBackground( dpy, m->LabelWin, back_pixel ); + else + XSetWindowBackground( dpy, m->LabelWin, fore_pixel ); + XClearWindow( dpy, m->LabelWin ); + + if( m->LabelStr ) + StrWidthHeight( MENUBARFONT, &width, NULL, &offset, + m->LabelStr, strlen(m->LabelStr)); + + if( onoroff ){ + tmp_f_GC = Scr.WhiteGC; + tmp_b_GC = Scr.BlackGC; + } + else{ + tmp_f_GC = Scr.BlackGC; + tmp_b_GC = Scr.WhiteGC; + } + if( !(m->flags&ACTIVE) && Scr.d_depth>1 ) + tmp_f_GC = Scr.Gray3GC; + if( !m->xpm ){ + if( m->LabelStr ){ + XDRAWSTRING( dpy, m->LabelWin, MENUBARFONT, tmp_f_GC, + (m->LabelWidth-width)/2, + (MENUB_H-2)/2-offset, + m->LabelStr, strlen(m->LabelStr) ); +/* Mask String for Mono Display */ + if( !(m->flags&ACTIVE) && Scr.d_depth<2 ){ + if( onoroff ) gcv.function = GXand; + else gcv.function = GXor; + gcm = GCFunction; + XChangeGC( dpy, Scr.BlackGC, gcm, &gcv ); + XSetFillStyle( dpy, Scr.BlackGC, FillTiled ); + XFillRectangle( dpy, m->LabelWin, Scr.BlackGC, 0, 0, + m->LabelWidth, MENUB_H); + XSetFillStyle( dpy, Scr.BlackGC, FillSolid ); + gcv.function = GXcopy; + XChangeGC( dpy, Scr.BlackGC, gcm, &gcv ); + } + } + } + else{ + if( m->xpm->kind==PIXMAP ){ + XSetClipMask( dpy, tmp_f_GC, m->xpm->mask ); + XSetClipOrigin( dpy, tmp_f_GC, + (m->LabelWidth-m->xpm->width)/2, + (MENUB_H-2-m->xpm->height)/2 ); + XCopyArea( dpy, m->xpm->icon, m->LabelWin, tmp_f_GC, 0, 0, + m->xpm->width, m->xpm->height, + (m->LabelWidth-m->xpm->width)/2, + (MENUB_H-2-m->xpm->height)/2 ); + XSetClipMask( dpy, tmp_f_GC, None ); + } + else{ + XCopyArea( dpy, onoroff?m->xpm->mask:m->xpm->icon, m->LabelWin, + tmp_f_GC, 0, 0, + m->xpm->width, m->xpm->height, + (m->LabelWidth-m->xpm->width)/2, + (MENUB_H-2-m->xpm->height)/2 ); + } + } +} + +void RedrawMenuBar( void ) +{ + int lp; + + if( Scr.flags&SYSTEM8 ) + DrawShadowBox( 0, 0, Scr.MyDisplayWidth, MENUB_H, Scr.MenuBar, 1, + Scr.WhiteGC, Scr.Gray1GC, SHADOW_ALL ); + XFillRectangle( dpy, Scr.MenuBar, Scr.BlackGC, 0, 0, 7, 7 ); + XFillRectangle( dpy, Scr.MenuBar, + Scr.BlackGC, Scr.MyDisplayWidth-7, 0, 7, 7 ); + if( Scr.flags&SYSTEM8 && !(Scr.flags&STARTING) ){ + for( lp=0; lp<2; lp++ ){ + XDrawArc( dpy, Scr.MenuBar, Scr.WhiteGC, 0, 0, + 14-lp, 14-lp, 180*64, -(90*64) ); + XDrawArc( dpy, Scr.MenuBar, Scr.Gray1GC, Scr.MyDisplayWidth-15, 0, + 14-lp, 14-lp, 0, 90*64 ); + } + XFillArc( dpy, Scr.MenuBar, Scr.MenuBlueGC, 0, 0, + 14, 14, 180*64, -(90*64) ); + XFillArc( dpy, Scr.MenuBar, Scr.MenuBlueGC, Scr.MyDisplayWidth-15, 0, + 14, 14, 0, 90*64 ); + } + else{ + XFillArc( dpy, Scr.MenuBar, Scr.WhiteGC, 0, 0, + 14, 14, 180*64, -(90*64) ); + XFillArc( dpy, Scr.MenuBar, Scr.WhiteGC, Scr.MyDisplayWidth-15, 0, + 14, 14, 0, 90*64 ); + } + if( !(Scr.flags&SYSTEM8) ) + XDrawLine( dpy, Scr.MenuBar, Scr.BlackGC, + 0, MENUB_H-1, Scr.MyDisplayWidth, MENUB_H-1 ); +} + +void DrawStringMenuBar( char *str ) +{ + static int width=0; + int offset; + + if( width!=0 ){ + XFillRectangle( dpy, Scr.MenuBar, Scr.WhiteGC, + (Scr.MyDisplayWidth-width)/2, 0, width, MENUB_H-1 ); + } + if( strlen( str )!=0 ){ + StrWidthHeight( MENUBARFONT, &width, NULL, &offset, + str, strlen(str)); + XDRAWSTRING( dpy, Scr.MenuBar, MENUBARFONT, Scr.BlackGC, + (Scr.MyDisplayWidth-width)/2, + MENUB_H/2-offset, str, strlen(str) ); + } + else + XClearWindow( dpy, Scr.MenuBar ); + RedrawMenuBar(); + XSync( dpy, 0 ); +} + +/* X 標準の関数で代用可能 */ +Bool isRect( int px, int py, int x, int y, int width, int height ) +{ + if( px>x && pxy && pyItemHeight/2-5); + XDrawLines( dpy, ml->PullWin, gc, check, 6, CoordModeOrigin ); +} + +void DrawSubMenuMark( MenuLabel *ml, GC gc, int topy ) +{ + XPoint mark[] = {{15, -7}, {15, 7}, {7,0}}; + int lp; + + for( lp=0; lp<3; lp++ ){ + mark[lp].x = ml->MenuWidth-mark[lp].x; + mark[lp].y += (topy+ml->ItemHeight/2); + } + XFillPolygon( dpy, ml->PullWin, gc, mark, 3, Convex, CoordModeOrigin ); +} + +MenuLabel *DrawMenuItem( MenuLabel *ml, int sel, Bool on ) +{ + GC r_tmpGC, s_tmpGC; + int label_p, top_y, lp, width, offset; + Pixmap icon; + MenuItem *mi; + unsigned long gcm; + XGCValues gcv; + char dots[] = { 2, 2 }; + + for( lp=0, mi = ml->m_item; lpnext ); + if( !(mi->mode&SELECTON) && on ) return NULL; + + top_y = ml->ItemHeight*(sel-1); + label_p = ml->ItemHeight==0?20:20+ml->ItemHeight+5; + + if( on ){ + r_tmpGC = Scr.flags&SYSTEM8?Scr.MenuSelectBlueGC:Scr.BlackGC; + s_tmpGC = Scr.WhiteGC; + } + else{ + r_tmpGC = Scr.flags&SYSTEM8?Scr.MenuBlueGC:Scr.WhiteGC; + s_tmpGC = Scr.BlackGC; + } + + if( mi->mode&STRGRAY && Scr.d_depth>2 ) + s_tmpGC = Scr.Gray3GC; + XFillRectangle( dpy, ml->PullWin, r_tmpGC, + 0+(Scr.flags&SYSTEM8?1:0), top_y, + ml->MenuWidth-(Scr.flags&SYSTEM8?2:0), ml->ItemHeight ); + +/** Draw Check Mark. **/ + if( mi->mode & CHECKON ) + DrawCheckMark( ml, s_tmpGC, top_y ); +/** Draw Submenu Mark **/ + if( mi->submenu ) + DrawSubMenuMark( ml, s_tmpGC, top_y ); +/** Draw Icon. **/ + if( mi->xpm ){ + if( mi->mode&STRGRAY || mi->mode&ICONGRAY) + icon = mi->xpm->lighticon; + else + icon = mi->xpm->icon; + if( mi->xpm->kind==PIXMAP ){ + XSetClipMask( dpy, s_tmpGC, mi->xpm->mask ); + XSetClipOrigin( dpy, s_tmpGC, + 20+(ml->IconWidth-mi->xpm->width)/2, + top_y+(ml->ItemHeight-mi->xpm->height)/2); + XCopyArea( dpy, icon, ml->PullWin, s_tmpGC, 0, 0, + mi->xpm->width, mi->xpm->height, + 20+(ml->IconWidth-mi->xpm->width)/2, + top_y+(ml->ItemHeight-mi->xpm->height)/2); + XSetClipMask( dpy, s_tmpGC, None ); + } + else{ + XCopyArea( dpy, on?mi->xpm->mask:mi->xpm->icon, + ml->PullWin, s_tmpGC, 0, 0, + mi->xpm->width, mi->xpm->height, + 20+(ml->IconWidth-mi->xpm->width)/2, + top_y+(ml->ItemHeight-mi->xpm->height)/2); + if( mi->mode&ICONGRAY ){ + if( on ) gcv.function = GXand; + else gcv.function = GXor; + gcm = GCFunction; + XChangeGC( dpy, Scr.BlackGC, gcm, &gcv ); + XSetFillStyle( dpy, Scr.BlackGC, FillTiled ); + XFillRectangle( dpy, ml->PullWin, Scr.BlackGC, 21, top_y, + mi->xpm->width, ml->ItemHeight ); + XSetFillStyle( dpy, Scr.BlackGC, FillSolid ); + gcv.function = GXcopy; + XChangeGC( dpy, Scr.BlackGC, gcm, &gcv ); + } + } + } +/** Draw Label String. **/ + if( mi->label ){ + StrWidthHeight( MENUFONT, &width, NULL, &offset, + mi->label, strlen(mi->label)); + XDRAWSTRING( dpy, ml->PullWin, MENUFONT, s_tmpGC, + (mi->xpm!=NULL?label_p:20), + top_y+ml->ItemHeight/2-offset, + mi->label, strlen(mi->label) ); +/* Mask String for Mono Display */ + if( mi->mode&STRGRAY && Scr.d_depth<2 ){ + if( on ) gcv.function = GXand; + else gcv.function = GXor; + gcm = GCFunction; + XChangeGC( dpy, Scr.BlackGC, gcm, &gcv ); + XSetFillStyle( dpy, Scr.BlackGC, FillTiled ); + XFillRectangle( dpy, ml->PullWin, Scr.BlackGC, 0, top_y, + ml->MenuWidth, ml->ItemHeight ); + XSetFillStyle( dpy, Scr.BlackGC, FillSolid ); + gcv.function = GXcopy; + XChangeGC( dpy, Scr.BlackGC, gcm, &gcv ); + } + } + if( mi->label && mi->label[0]=='\0' ){ + if( Scr.d_depth>1 ){ + if( Scr.flags&SYSTEM8 ){ + XDrawLine( dpy, ml->PullWin, Scr.Gray2GC, + 2, top_y+ml->ItemHeight/2, + ml->MenuWidth-3, top_y+ml->ItemHeight/2); + XDrawLine( dpy, ml->PullWin, Scr.WhiteGC, + 3, top_y+ml->ItemHeight/2+1, + ml->MenuWidth-2, top_y+ml->ItemHeight/2+1); + } + else + XDrawLine( dpy, ml->PullWin, Scr.Gray2GC, + 0, top_y+ml->ItemHeight/2, + ml->MenuWidth, top_y+ml->ItemHeight/2); + } + else{ + gcm = GCLineStyle; + gcv.line_style = LineOnOffDash; + XChangeGC( dpy, Scr.BlackGC, gcm, &gcv ); + XSetDashes( dpy, Scr.BlackGC, 0, dots, 2 ); + XDrawLine( dpy, ml->PullWin, Scr.BlackGC, + 0, top_y+ml->ItemHeight/2, + ml->MenuWidth, top_y+ml->ItemHeight/2); + gcm = GCLineStyle; + gcv.line_style = FillSolid; + XChangeGC( dpy, Scr.BlackGC, gcm, &gcv ); + } + } + + return mi->submenu; +} + +void SortMenuItem( MenuLabel *m, MenuItem *start ) +{ + MenuItem *fence, *lastSwap, *i, *j, *k; + + for(fence = NULL; fence != start; fence = lastSwap ) + for(j = (lastSwap = i = start)->next; + (k = j->next) != fence; + i = j, j = k ){ + if ( strcmp( j->label, k->label ) > 0 ){ + i->next = k; + j->next = k->next; + lastSwap = k->next = j; + } + } +} + +/***************************************************************** +MenuLabel *m Menu Label of Target +int left left side position of menu +int right right side position of menu +int y Height of menu +Bool side True left(Tear off right) + False right(Tear off left) +*****************************************************************/ +Bool MapMenu( MenuLabel *m, int left, int right, int y, Bool side ) +{ + int lp, items=0; + int label_w, local_mw=0, height; + MenuItem *mi; + unsigned long valuemask; + XSetWindowAttributes attributes; + + if( m->LabelWin!=None ) RedrawMenu( m, True ); + if( m->PullWin==None ){ + valuemask = CWCursor | CWEventMask | CWBackPixel; + attributes.background_pixel = WhitePixel( dpy, Scr.screen ); + attributes.cursor = Scr.MlvwmCursors[DEFAULT]; + attributes.event_mask = (SubstructureRedirectMask | ExposureMask | + SubstructureNotifyMask | PointerMotionMask | + EnterWindowMask | LeaveWindowMask ); + m->PullWin = XCreateWindow( dpy, Scr.Root, 0, 0, 10, 10 , 1, + CopyFromParent, InputOutput, + CopyFromParent, + valuemask, &attributes ); + XSaveContext( dpy, m->PullWin, MenuContext, (caddr_t)m ); + } + + if( m == &Scr.IconMenu && Scr.iconAnchor->next ) + SortMenuItem( &Scr.IconMenu, Scr.iconAnchor ); + + m->MenuWidth = 0; + m->MenuHeight = 0; + m->ItemHeight = 0; + m->IconWidth = 0; + m->SelectNum = -1; + + for( mi = m->m_item; mi; mi=mi->next ){ + StrWidthHeight( MENUFONT, &label_w, &height, NULL, + mi->label, strlen(mi->label)); + m->ItemHeight = max( height, m->ItemHeight ); + if( mi->iconname && !(mi->xpm) ) + mi->xpm = ReadIcon( mi->iconname, NULL, False ); + if( mi->xpm ){ + m->ItemHeight = max( mi->xpm->height, m->ItemHeight ); + m->IconWidth = max( mi->xpm->width, m->IconWidth ); + local_mw = 20+mi->xpm->width+5+label_w+10; + } + else + local_mw = 20+label_w+10; + if( mi->submenu ) local_mw += 15; + m->MenuWidth = max( local_mw, m->MenuWidth ); + if( (mi->label && mi->label[0]) || mi->next ) + items++; + } + + m->ItemHeight+=2; + m->MenuHeight = m->ItemHeight*items; + + if( side ) + m->MenuX = left; + else + m->MenuX = right-m->MenuWidth; + + if( m->MenuX+m->MenuWidth > Scr.MyDisplayWidth ){ + m->MenuX = right-m->MenuWidth; + side = False; + } + if( m->MenuX < 0 ){ + m->MenuX = 0; + side = True; + } + m->MenuY = y+m->MenuHeightMenuHeight; + m->MenuY = m->MenuYMenuY; + if( Scr.flags&SYSTEM8 ){ + m->MenuWidth+=2; + m->MenuHeight+=1; + } + XMoveResizeWindow( dpy, m->PullWin, m->MenuX, m->MenuY, + m->MenuWidth+2, m->MenuHeight+2 ); + { + XRectangle rect[7]; + int point=0; + + rect[point].x = -1; rect[point].y = -1; + rect[point].width = m->MenuWidth+1; + rect[point].height = m->MenuHeight+1; + point++; + for( lp=1; lp<4; lp++ ){ + rect[point].x = m->MenuWidth+lp-1; rect[point].y = lp-1; + rect[point].width = 1; rect[point].height = m->MenuHeight+2-lp+1; + point++; + } + for( lp=1; lp<4; lp++ ){ + rect[point].x = lp-1; rect[point].y = m->MenuHeight+lp-1; + rect[point].width = m->MenuWidth+2-lp+1; rect[point].height = 1; + point++; + } + XShapeCombineRectangles(dpy,m->PullWin,ShapeBounding, + 0,0,rect,point,ShapeSet,Unsorted); + } + + XMapRaised( dpy, m->PullWin ); + + return side; +} + +void UnmapMenu( MenuLabel *m, int mode ) +{ + if( mode&UNMAP_WINDOW ){ + XUnmapWindow( dpy, m->PullWin ); + m->SelectNum = -1; + } + if( mode&UNMAP_LABEL ) + RedrawMenu( m, False ); + XSync( dpy, 0 ); +} + +void ExecMenu( MenuLabel *m, int selected ) +{ + int lp; + MenuItem *tmp_item; + + for( lp=0, tmp_item = m->m_item; lpnext ); + if( !(tmp_item->mode&SELECTON) || !(tmp_item->action )) + return; + + for( lp=0; lpaction ); + UnmapMenu( m, UNMAP_LABEL ); +} + +void DrawMenuItemAll( MenuLabel *ml ) +{ + int lp; + MenuItem *tmp_item; + + for( lp=0, tmp_item=ml->m_item; tmp_item; lp++,tmp_item=tmp_item->next ) + DrawMenuItem( ml, lp+1, lp+1==ml->SelectNum?True:False ); + for( lp=0; lp<2; lp++ ){ + XDrawLine( dpy, ml->PullWin, Scr.BlackGC, + lp, ml->MenuHeight+lp, ml->MenuWidth+1, ml->MenuHeight+lp ); + XDrawLine( dpy, ml->PullWin, Scr.BlackGC, + ml->MenuWidth+lp, lp, ml->MenuWidth+lp, ml->MenuHeight); + } + if( Scr.flags&SYSTEM8 ){ + XDrawLine( dpy, ml->PullWin, Scr.WhiteGC, + 0, 0, 0, ml->MenuHeight ); + XDrawLine( dpy, ml->PullWin, Scr.Gray2GC, + 0, ml->MenuHeight-1, ml->MenuWidth-1, ml->MenuHeight-1 ); + XDrawLine( dpy, ml->PullWin, Scr.Gray2GC, + ml->MenuWidth-1, 0, ml->MenuWidth-1, ml->MenuHeight-1 ); + } +} + +Bool ChoiseMenu( MenuLabel *m, Window *entwin, int ignore, Bool side ) +{ + Bool isEnd = False, finishall=False, Release=False, ChildSide=True; + XEvent Event; + MenuLabel *mapped=NULL, *tmp_menu; + + while( !isEnd && !finishall){ + XNextEvent( dpy, &Event ); + switch( Event.type ){ + case Expose: + if( XFindContext( dpy, Event.xany.window, MenuContext, + (caddr_t *)&tmp_menu )!=XCNOENT ){ + if( Event.xexpose.count==0 ) DrawMenuItemAll( tmp_menu ); + } + else handle_expose( &Event ); + break; + case EnterNotify: + if( XFindContext( dpy, Event.xcrossing.window, MenuContext, + (caddr_t *)&tmp_menu )!=XCNOENT ){ + if( tmp_menu==mapped ){ + finishall = ChoiseMenu( mapped, entwin, ignore, ChildSide ); + if( *entwin!=m->PullWin ) isEnd = True; + } + else if( tmp_menu!=m || Event.xcrossing.window==m->LabelWin ){ + isEnd = True; + *entwin = Event.xcrossing.window; + if( m->SelectNum != -1 ){ + DrawMenuItem( m, m->SelectNum, False ); + m->SelectNum = -1; + if( mapped ){ + UnmapMenu( mapped, UNMAP_ALL ); + mapped = NULL; + } + } + } + } + if( Event.xcrossing.window == Scr.MenuBar && + Event.xcrossing.detail!=NotifyNonlinearVirtual ){ + isEnd = True; + *entwin = Scr.MenuBar; + } + break; + case ButtonRelease: + if( ignore ){ + isEnd = True; + finishall = True; + Release = True; + } + else ignore++; + break; + case MotionNotify: + if(isRect( Event.xbutton.x, Event.xbutton.y, 0, 0, + m->MenuWidth, m->MenuHeight ) && + Event.xany.window == m->PullWin ){ + if( m->SelectNum != (Event.xbutton.y-3)/m->ItemHeight+1 ){ + if( m->SelectNum != -1 ){ + DrawMenuItem( m, m->SelectNum, False); + if( mapped ){ + UnmapMenu( mapped, UNMAP_ALL ); + mapped = NULL; + } + } + m->SelectNum = (Event.xbutton.y-3)/m->ItemHeight+1; + mapped=DrawMenuItem( m, m->SelectNum, True ); + if( mapped ){ + ChildSide = MapMenu( mapped, + m->MenuX+m->MenuWidth-5, m->MenuX+5, + (m->MenuY==MENUB_H-1 && m->SelectNum==1) ? + m->MenuY+m->ItemHeight/2 : + m->MenuY+m->ItemHeight*(m->SelectNum-1), + side ); + } + } + } + else if( m->SelectNum != -1 ){ + DrawMenuItem( m, m->SelectNum, False ); + m->SelectNum = -1; + if( mapped ){ + UnmapMenu( mapped, UNMAP_ALL ); + mapped = NULL; + } + } + break; + default: + break; + } + } + + if( mapped ){ + UnmapMenu( mapped, UNMAP_ALL ); + DrawMenuItemAll( m ); + } + if( Release && m->SelectNum!=-1 ){ + UnGrabEvent(); + ExecMenu( m, m->SelectNum ); + if( !GrabEvent( DEFAULT ) ){ + XBell( dpy, 30 ); + return finishall; + } + } + + return finishall; +} + +void press_menu( MenuLabel *m ) +{ + Bool isEnd = False, Side=True; + XEvent Event; + MenuLabel *mapped, *tmp_menu; + int x, y, JunkX, JunkY; + unsigned int JunkMask; + Window JunkRoot, JunkChild, entwin; + int ignore; + + if( m!=NULL ) + Side=MapMenu( m, m->LabelX, m->LabelX+m->LabelWidth, MENUB_H-1, True ); + + if( !GrabEvent( DEFAULT ) ){ + XBell( dpy, 30 ); + return; + } + + if( Scr.flags&ONECLICKMENU ) ignore=0; + else ignore=1; + + mapped = m; + while( !isEnd ){ + XNextEvent( dpy, &Event ); + switch( Event.type ){ + case Expose: + if( mapped && Event.xany.window==mapped->PullWin && + Event.xexpose.count==0 ) + DrawMenuItemAll( mapped ); + else + handle_expose( &Event ); + break; + case ButtonRelease: + if( ignore ) isEnd = True; + else ignore++; + break; + case EnterNotify: + if( XFindContext( dpy, Event.xcrossing.window, + MenuContext, (caddr_t *)&tmp_menu ) + !=XCNOENT ){ + if( mapped != tmp_menu ){ + if( mapped ) UnmapMenu( mapped, UNMAP_ALL ); + mapped = tmp_menu; + Side = MapMenu( mapped, mapped->LabelX, + mapped->LabelX+mapped->LabelWidth, + MENUB_H-1, True ); + } + else if( Event.xcrossing.window==mapped->PullWin ){ + isEnd = ChoiseMenu( mapped, &entwin, ignore, Side ); + if( entwin == Scr.MenuBar ){ + UnmapMenu( mapped, UNMAP_ALL ); + mapped = NULL; + } + } + } + if( Event.xcrossing.window==Scr.MenuBar && + Event.xcrossing.detail!=NotifyVirtual ){ + if( mapped!=NULL ){ + XQueryPointer( dpy, mapped->PullWin, + &JunkRoot, &JunkChild, + &x, &y,&JunkX, &JunkY,&JunkMask); + if( !isRect( x, y, 0, 0, + mapped->MenuWidth, mapped->MenuHeight ) && + !isRect( x-mapped->LabelX, y, 0, 0, + mapped->LabelWidth, MENUB_H )){ + UnmapMenu( mapped, UNMAP_ALL ); + mapped = NULL; + } + } + } + break; + default: + break; + } + } + if( mapped ) UnmapMenu( mapped, UNMAP_ALL ); + UnGrabEvent(); +} + +Bool SwallowMenu( MenuLabel *ml ) +{ + XEvent ev; + XClassHint class; + XSizeHints hints; + MlvwmWindow *tmp_win; + Bool done=True; + char *name, *comm, *fullpath; + long supplied=0; + Atom *protocols = NULL, *ap; + int n, lp; + XWindowAttributes attr; + XTextProperty text_prop; +#ifdef USE_LOCALE + int num; + char **list; +#endif + + stripquote( ml->action, &comm ); + if( comm==NULL ){ + ml->flags &= ~SWALLOW; + + return False; + } + if( (fullpath=LookUpFiles( getenv("PATH"), comm, X_OK ))==NULL ){ + ml->flags &= ~SWALLOW; + DrawErrMsgOnMenu( "Swallow Falied(Can't Exec) ", comm ); + return False; + } + free( fullpath ); + free( comm ); + ExecuteFunction( ml->action ); + + do{ + XMaskEvent( dpy, SubstructureRedirectMask | + StructureNotifyMask | SubstructureNotifyMask, &ev ); + if( ev.type==MapRequest ){ + if( XGetWMName( dpy, ev.xmaprequest.window, &text_prop) != 0 ){ +#ifdef USE_LOCALE + if(text_prop.value) + text_prop.nitems = strlen(text_prop.value); + if(XmbTextPropertyToTextList(dpy, &text_prop, &list, &num) + >= Success + && num > 0 && *list) + name = *list; + else + name = NoName; +#else + name = (char *)text_prop.value; +#endif + } + else + name = NoName; + + XGetClassHint(dpy, ev.xmaprequest.window, &class); + if( !strcmp( name, ml->name ) || + !strcmp( class.res_name, ml->name ) || + !strcmp( class.res_class, ml->name ) ){ + done = False; + XGetWindowAttributes( dpy, ev.xmaprequest.window, &attr ); + + if(!XGetWMNormalHints( dpy, ev.xmaprequest.window, &hints, + &supplied )) + hints.flags = 0; + if((USSize | PSize ) & hints.flags ) + ml->LabelWidth = hints.width; + else + ml->LabelWidth = attr.width; + ml->LabelWin = ev.xmaprequest.window; + ml->flags &= ~CANDELETE; + if(XGetWMProtocols (dpy, ml->LabelWin, &protocols, &n)){ + for( lp=0, ap=protocols; lpflags |= CANDELETE; + } + if (protocols) XFree ((char *) protocols); + } + else + HandleEvents( ev ); + if( name!=NoName ) XFree( name ); + } + else + HandleEvents( ev ); + if( ev.type==MapNotify && + XFindContext( dpy, ev.xany.window, MlvwmContext, (caddr_t *)&tmp_win ) + !=XCNOENT) + DrawStringMenuBar( tmp_win->name ); + } + while( done ); + return True; +} + +void CreateMenuLabel( MenuLabel *ml ) +{ + unsigned long valuemask; + XSetWindowAttributes attributes; + int width; + + if( ml->flags&SWALLOW ){ + if( SwallowMenu( ml ) ){ + XSetWindowBorderWidth( dpy, ml->LabelWin, 0 ); + XResizeWindow( dpy, ml->LabelWin, ml->LabelWidth, MENUB_H-2 ); + XReparentWindow( dpy, ml->LabelWin, Scr.MenuBar, 0, 0 ); + ml->LabelWidth += 16; + } + } + else{ + if( ml->xpm ) + ml->LabelWidth = ml->xpm->width+16; + else{ + if( ml->LabelStr ){ + StrWidthHeight( MENUBARFONT, &width, NULL, NULL, + ml->LabelStr, strlen(ml->LabelStr)); + ml->LabelWidth = width+16; + } + else + ml->LabelWidth = 16; + } + valuemask = CWCursor | CWEventMask | CWBackPixel; + attributes.background_pixel = WhitePixel( dpy, Scr.screen ); + attributes.cursor = Scr.MlvwmCursors[DEFAULT]; + attributes.event_mask = (ButtonPressMask | ButtonReleaseMask | + EnterWindowMask | ExposureMask | + OwnerGrabButtonMask | PointerMotionMask); + ml->LabelWin = XCreateWindow( dpy, Scr.MenuBar, 0, 1, + ml->LabelWidth, MENUB_H-2, 0, + CopyFromParent, InputOutput, + CopyFromParent, + valuemask, &attributes ); + XSaveContext( dpy, ml->LabelWin, MenuContext, (caddr_t)ml ); + } +} + +void AddMenuItem( MenuLabel *ml, char *label, char *action, char *icon, Icon *miniicon, MenuLabel *submenu, int mode ) +{ + MenuItem *tmpitem, *newitem; + + newitem = calloc( 1, sizeof( MenuItem ) ); + + if( ml->m_item == NULL ) + ml->m_item = newitem; + else{ + for( tmpitem=ml->m_item; tmpitem->next; tmpitem=tmpitem->next ); + tmpitem->next = newitem; + } + newitem->label = strdup( label ); + newitem->action = action ? strdup( action ) : action ; + newitem->iconname = icon ? strdup( icon ) : icon ; + newitem->mode = mode; + newitem->submenu = submenu; + newitem->xpm = miniicon; +} + +void DelMenuItem( MenuLabel *ml, char *action ) +{ + MenuItem *mi, *prev; + + for( mi=ml->m_item, prev=NULL; + strcmp( mi->action, action )!=0 && mi; + prev=mi, mi=mi->next ); + if( !mi ) return; + + free( mi->label ); + if( mi->action ) free( mi->action ); + if( mi->iconname ) free( mi->iconname ); + if( prev ) prev->next = mi->next; + free( mi ); +} + +void CreateMenuItems( void ) +{ + MenuLabel *tmpmenu; + + Scr.IconMenu.flags = ACTIVE | STICKLABEL; + Scr.IconMenu.xpm = Scr.SystemIcon; + Scr.IconMenu.name = strdup( "ICON" ); + Scr.IconMenu.LabelStr = NULL; + CreateMenuLabel( &Scr.IconMenu ); + + for(tmpmenu=Scr.MenuLabelRoot;tmpmenu!=NULL;tmpmenu=tmpmenu->next) + CreateMenuLabel( tmpmenu ); +} + +char *SetItemGrayString( char *str, char **action, int *mode, char **icon, MenuLabel **submenu ) +{ + *mode |= STRGRAY; + + return str+4; +} + +char *SetItemBlackString( char *str, char **action, int *mode, char **icon, MenuLabel **submenu ) +{ + *mode &= ~STRGRAY; + + return str+5; +} + +char *SetItemCheckMark( char *str, char **action, int *mode, char **icon, MenuLabel **submenu ) +{ + *mode |= CHECKON; + + return str+5; +} + +char *SetItemNonCheckMark( char *str, char **action, int *mode, char **icon, MenuLabel **submenu ) +{ + *mode &= ~CHECKON; + + return str+8; +} + +char *SetItemSelect( char *str, char **action, int *mode, char **icon, MenuLabel **submenu ) +{ + *mode |= SELECTON; + + return str+6; +} + +char *SetItemNonSelect( char *str, char **action, int *mode, char **icon, MenuLabel **submenu ) +{ + *mode &= ~SELECTON; + + return str+9; +} + +char *SetItemIcon( char *str, char **action, int *mode, char **icon, MenuLabel **submenu ) +{ + char *name, *stop, tmp[5], *path; + + if( *icon ) + free( *icon ); + + if( (stop = strchr( str, ',' ))!=NULL ) + *stop = '\0'; + name = calloc( strlen(str)-4, 1 ); + sscanf( str, "%s%s", tmp, name ); + + *icon = name; + if((path = LookUpFiles( Scr.IconPath, name, R_OK ))==NULL ) + DrawErrMsgOnMenu( "Can't Find file ", name ); + else + free( path ); + + if( stop!=NULL ) + stop++; + else + stop = str+strlen(str); + + return stop; +} + +char *SetItemAction( char *str, char **action, int *mode, char **icon, MenuLabel **submenu ) +{ + char *stop, *top; + + if( *action ) free( *action ); + top = SkipSpace( str+6 ); + if( (stop = strchr( str, ',' ))!=NULL ) + *stop = '\0'; + else + str[strlen(str)-1]='\0'; + *action = strdup( top ); + + if( stop!=NULL ) + stop++; + else + stop = str+strlen(str); + + return stop; +} + +char *SetSubMenu( char *str, char **action, int *mode, char **icon, MenuLabel **submenu ) +{ + char *stop, *top; + MenuLabel *tmp_l; + + top = SkipSpace( str+7 ); + if( (stop = strchr( str, ',' ))!=NULL ) + *stop = '\0'; + else + str[strlen(str)-1]='\0'; + + for( tmp_l=Scr.MenuLabelRoot; + tmp_l && strcmp( top, tmp_l->name ); tmp_l=tmp_l->next ); + + if( tmp_l ) + *submenu = tmp_l; + else + DrawErrMsgOnMenu( "Configuration Error(SubMenu)! ", str ); + + if( stop!=NULL ) + stop++; + else + stop = str+strlen(str); + + return stop; +} + +menu_item_func MenuItemFunc[]={ + {"Gray", SetItemGrayString }, + {"Black", SetItemBlackString }, + {"Check", SetItemCheckMark }, + {"NonCheck", SetItemNonCheckMark }, + {"Select", SetItemSelect }, + {"NonSelect", SetItemNonSelect }, + {"SubMenu", SetSubMenu }, + {"Icon", SetItemIcon }, + {"Action", SetItemAction }, + {NULL, 0} +}; + + +char *SetLabelIconName( MenuLabel *ml, char *str ) +{ + char *name, *stop, tmp[5]; + + if( (stop = strchr( str, ',' ))!=NULL ) + *stop = '\0'; + name = calloc( strlen(str)-4, 1 ); + sscanf( str, "%s%s", tmp, name ); + ml->xpm = ReadIcon( name, NULL, True ); + free( name ); + + if( stop!=NULL ) + stop++; + else + stop = str+strlen(str); + + return stop; +} + +char *SetLabelStick( MenuLabel *ml, char *str ) +{ + ml->flags |= STICKLABEL; + + return str+5; +} + +char *SetLabelNonStick( MenuLabel *ml, char *str ) +{ + ml->flags &= ~STICKLABEL; + + return str+8; +} + +char *SetLabelRight( MenuLabel *ml, char *str ) +{ + ml->flags &= ~LEFTSIDE; + + return str+5; +} + +char *SetLabelLeft( MenuLabel *ml, char *str ) +{ + ml->flags |= LEFTSIDE; + + return str+5; +} + +char *SetMenuLabelLabel( MenuLabel *ml, char *str ) +{ + char *top; + + top = stripquote( str+6, &(ml->LabelStr) ); + + return top; +} + +char *SetSwallowAction( MenuLabel *ml, char *str ) +{ + char *stop, *top; + + top = SkipSpace( str+6 ); + if( (stop = strchr( str, ',' ))!=NULL ) + *stop = '\0'; + else + str[strlen(str)-1]='\0'; + ml->action = strdup( top ); + + if( stop!=NULL ) + stop++; + else + stop = str+strlen(str); + + return stop; +} + +menu_func MenuLabelFunc[]={ + {"Action", SetSwallowAction}, + {"Icon", SetLabelIconName}, + {"Label", SetMenuLabelLabel }, + {"Left", SetLabelLeft}, + {"Right", SetLabelRight}, + {"Stick", SetLabelStick}, + {"NonStick", SetLabelNonStick}, + {NULL, 0} +}; + +void SetSwallow( char *line, FILE *fp ) +{ + char str[256], *top; + MenuLabel *tmpmenu, *last_m; + int lp; + + tmpmenu = calloc( 1, sizeof( MenuLabel ) ); + + if( Scr.MenuLabelRoot==NULL ) Scr.MenuLabelRoot = tmpmenu; + else{ + for( last_m=Scr.MenuLabelRoot; + last_m->next!=NULL; + last_m=(MenuLabel *)last_m->next ); + last_m->next = tmpmenu; + } + top = stripquote( line, &(tmpmenu->name) ); + tmpmenu->flags = SWALLOW | ACTIVE | STICKLABEL; + + while( *top!='\n' && *top!='\0' ){ + for( ; !isalpha( *top ) && *top!='\n' && *top!='\0'; top++ ); + if( *top=='\n' || *top=='\0' ) break; + for( lp=0; MenuLabelFunc[lp].label!=NULL; lp++ ){ + if( !strncmp( top, MenuLabelFunc[lp].label, + strlen(MenuLabelFunc[lp].label) )){ + top=MenuLabelFunc[lp].action( tmpmenu, top ); + break; + } + } + if( !MenuLabelFunc[lp].label ){ + DrawErrMsgOnMenu( "Configuration Error(Swallow)! ", str ); + for( ; *top!=',' && *top!='\n' && *top!='\0'; top++ ); + } + } +} + +void SetMenu( char *line, FILE *fp ) +{ + char str[256], *top, tmp[5]; + MenuLabel *tmpmenu, *last_m, *submenu; + int mode; + char *action, *label; + char *icon; + int lp; + + tmpmenu = calloc( 1, sizeof( MenuLabel ) ); + + if( Scr.MenuLabelRoot==NULL ) Scr.MenuLabelRoot = tmpmenu; + else{ + for( last_m=Scr.MenuLabelRoot; + last_m->next!=NULL; + last_m=(MenuLabel *)last_m->next ); + last_m->next = tmpmenu; + } + + if( (top = strchr( line, ',' ))!=NULL ) + *top = '\0'; + tmpmenu->name = calloc( strlen(line)-4, 1 ); + sscanf( line, "%s%s", tmp, tmpmenu->name ); + if( top ) top++; + else top = line+strlen( line ); + + tmpmenu->flags = LEFTSIDE; + + while( *top!='\n' && *top!='\0' ){ + for( ; !isalpha( *top ) && *top!='\n' && *top!='\0'; top++ ); + if( *top=='\n' || *top=='\0' ) break; + for( lp=0; MenuLabelFunc[lp].label!=NULL; lp++ ){ + if( !strncmp( top, MenuLabelFunc[lp].label, + strlen(MenuLabelFunc[lp].label) )){ + top=MenuLabelFunc[lp].action( tmpmenu, top ); + break; + } + } + if( !MenuLabelFunc[lp].label ){ + DrawErrMsgOnMenu( "Configuration Error(Menu)! ", str ); + for( ; *top!=',' && *top!='\n' && *top!='\0'; top++ ); + } + } + + while( fgets( str, 256, fp )!=NULL && strncmp( str, "END", 3) ){ + if( str[0]=='#' ) continue; + mode = SELECTON; + label = NULL; + action = NULL; + icon = NULL; + submenu = NULL; + + top = stripquote( str, &label ); + if( !label ){ + DrawErrMsgOnMenu( "Configuration Error! ", str ); + continue; + } + while( *top!='\n' && *top!='\0' ){ + for( ; !isalpha( *top ) && *top!='\n' && *top!='\0'; top++ ); + if( *top=='\n' || *top=='\0' ) break; + for( lp=0; MenuItemFunc[lp].label!=NULL; lp++ ){ + if( !strncmp( top, MenuItemFunc[lp].label, + strlen(MenuItemFunc[lp].label) )){ + top = MenuItemFunc[lp].action( top, &action, + &mode, &icon, &submenu ); + break; + } + } + if( !MenuItemFunc[lp].label ){ + DrawErrMsgOnMenu( "Configuration Error(MenuItem)! ", str ); + for( ; *top!=',' && *top!='\n' && *top!='\0'; top++ ); + } + } + AddMenuItem( tmpmenu, label, action, icon, NULL, submenu, mode ); + if( label ) free( label ); + if( action ) free( action ); + if( icon ) free( icon ); + if( mode&SELECTON ) tmpmenu->flags |= ACTIVE; + } +} + +void SetMenuBar( char *line, FILE *fp ) +{ + char str[256], *top, tmp[8]; + Menu *tmp_m, *last_m; + MenuLink **tmp_link; + MenuLabel *tmp_l; + + tmp_m = calloc( 1, sizeof( Menu ) ); + + if( Scr.MenuRoot==NULL ) Scr.MenuRoot = tmp_m; + else{ + for( last_m=Scr.MenuRoot; + last_m->next!=NULL; + last_m=last_m->next ); + last_m->next = tmp_m; + } + if( (top = strchr( line, ',' ))!=NULL ) + *top = '\0'; + tmp_m->name = calloc( strlen(line)-7, 1 ); + sscanf( line, "%s%s", tmp, tmp_m->name ); + + if( top ) top++; + else top = line+strlen( line ); + tmp_link = &tmp_m->link; + + for( tmp_l=Scr.MenuLabelRoot; tmp_l; tmp_l=tmp_l->next ){ + if( tmp_l->flags&STICKLABEL ){ + *tmp_link = calloc( 1, sizeof( MenuLink ) ); + (*tmp_link)->link = tmp_l; + tmp_link = &(*tmp_link)->next; + } + } + while( fgets( str, 256, fp )!=NULL && strncmp( str, "END", 3) ){ + if( str[0]=='#' ) continue; + str[ strlen(str)-1] = '\0'; + for( tmp_l=Scr.MenuLabelRoot; + tmp_l && strcmp( str, tmp_l->name ); tmp_l=tmp_l->next ); + if( tmp_l ){ + *tmp_link = calloc( 1, sizeof( MenuLink ) ); + (*tmp_link)->link = tmp_l; + tmp_link = &(*tmp_link)->next; + } + else + DrawErrMsgOnMenu( "MenuBar Falied(Can't find) ", str ); + } +} + +Window PixmapWin (char **data_xpm, Window root, int x, int y) +{ + static XpmAttributes attributes; + + Pixmap pixmap; + Pixmap shapemask; + Window w; + XSetWindowAttributes attr; + + XpmCreatePixmapFromData( dpy, root, data_xpm, + &pixmap, &shapemask, &attributes ); + x = x<0? x + Scr.MyDisplayWidth - attributes.width : x-1; + y = y<0? y + Scr.MyDisplayHeight - attributes.height : y-1; + + attr.background_pixel = BlackPixel( dpy, DefaultScreen(dpy) ); + attr.override_redirect = True; + w = XCreateWindow( dpy, root, x, y, + attributes.width, attributes.height, 1, + CopyFromParent, InputOutput, CopyFromParent, + CWBackPixel | CWOverrideRedirect, &attr ); + XShapeCombineMask( dpy, w, ShapeBounding, 0, 0, shapemask, ShapeSet ); + + XFreePixmap( dpy, pixmap ); + XFreePixmap( dpy, shapemask ); + return w; +} + +void CreateMenuBar( void ) +{ + static char *lbot_xpm[] = { + "7 7 2 1", + " c none s none", + "# c black", + "# ", + "# ", + "# ", + "## ", + "### ", + "#### ", + "#######" + }; + static char *rbot_xpm[] = { + "7 7 2 1", + " c none s none", + "# c black", + " #", + " #", + " #", + " ##", + " ###", + " ####", + "#######" + }; + unsigned long valuemask; + XSetWindowAttributes attributes; + + valuemask = CWCursor | CWBackPixel | CWEventMask; + attributes.cursor = Scr.MlvwmCursors[DEFAULT]; + attributes.background_pixel = WhitePixel( dpy, Scr.screen ); + attributes.event_mask = (SubstructureRedirectMask | ButtonPressMask | + EnterWindowMask | ExposureMask | + OwnerGrabButtonMask | ButtonReleaseMask ); + Scr.MenuBar = XCreateWindow( dpy, Scr.Root, 0, 0, + Scr.MyDisplayWidth, MENUB_H ,0, + CopyFromParent, InputOutput, CopyFromParent, + valuemask, &attributes ); + XMapWindow( dpy, Scr.MenuBar ); + Scr.lbCorner = PixmapWin( lbot_xpm, Scr.Root, 0, -1 ); + XMapWindow( dpy, Scr.lbCorner ); + + Scr.rbCorner = PixmapWin( rbot_xpm, Scr.Root, -1, -1 ); + XMapWindow( dpy, Scr.rbCorner ); + RedrawMenuBar( ); +} + +void MapMenuBar( MlvwmWindow *win ) +{ + int left, right; + MenuLabel *tmpml; + MenuLink *mlink; + styles *style; + static Bool Mapped=False; + + if( Scr.flags&STARTING ) return; + left = 10; + right = Scr.MyDisplayWidth-Scr.IconMenu.LabelWidth-10; + + XMoveWindow( dpy, Scr.IconMenu.LabelWin, right, 1 ); + Scr.IconMenu.LabelX = right; + right--; + + if( Scr.MenuRoot==NULL ){ + if( Mapped ) return; + + for( tmpml=Scr.MenuLabelRoot; tmpml; tmpml=tmpml->next ){ + if( tmpml->flags&LEFTSIDE ){ + tmpml->LabelX = left; + left += tmpml->LabelWidth+1; + } + else{ + tmpml->LabelX = right-tmpml->LabelWidth-1; + right = tmpml->LabelX; + } + if( tmpml->flags&SWALLOW ) + XMoveWindow( dpy, tmpml->LabelWin, tmpml->LabelX+8, 1 ); + else + XMoveWindow( dpy, tmpml->LabelWin, tmpml->LabelX, 1 ); + } + XMapSubwindows( dpy, Scr.MenuBar ); + Mapped = True; + + return; + } + if((!win || (style = lookupstyles( win->name, &win->class ))==NULL) || + !(style->menubar) ) + if( (style = lookupstyles( "*", NULL ))==NULL ) + return; + if( !(style->menubar) ) return; + if( Scr.ActiveMenu==style->menubar ) return; + + XGrabServer (dpy); + for( mlink=style->menubar->link; mlink; mlink=mlink->next ){ + if( mlink->link->flags&LEFTSIDE ){ + mlink->link->LabelX = left; + left += mlink->link->LabelWidth+1; + } + else{ + mlink->link->LabelX = right-mlink->link->LabelWidth-1; + right = mlink->link->LabelX; + } + if( mlink->link->flags&SWALLOW ) + XMoveWindow( dpy, mlink->link->LabelWin, mlink->link->LabelX+8, 1); + else + XMoveWindow( dpy, mlink->link->LabelWin, mlink->link->LabelX, 1 ); + } + + if( Scr.ActiveMenu ) + for( mlink=Scr.ActiveMenu->link; mlink; mlink=mlink->next ) + if( !(mlink->link->flags&STICKLABEL) ) + XUnmapWindow( dpy, mlink->link->LabelWin ); + + XMapWindow( dpy, Scr.IconMenu.LabelWin ); + for( mlink=style->menubar->link; mlink; mlink=mlink->next ){ + XMapWindow( dpy, mlink->link->LabelWin ); + RedrawMenu( mlink->link, False ); + } + Scr.ActiveMenu = style->menubar; + XSync( dpy, 0 ); + XUngrabServer (dpy); +} + +void ChangeMenuLabel( MenuLabel *ml, char *newl, Icon *miniicon ) +{ + if( newl==NULL && ml->xpm==miniicon ) return; + if( ml->LabelStr && !strcmp(ml->LabelStr, newl )){ + if( ml->LabelStr ) + free( ml->LabelStr ); + ml->LabelStr = newl; + } + ml->xpm = miniicon; + RedrawMenu( ml, False ); +} + +void ChangeMenuItemLabel( char *name, char *oldl, char *newl, char *action, int mm, int sm ) +{ + MenuItem *tmpitem; + MenuLabel *tmplabel; + + if( oldl==NULL || *oldl=='\0' ) return; + if( !strcmp( name, "ICON" ) ) tmplabel = &(Scr.IconMenu); + else{ + for( tmplabel = Scr.MenuLabelRoot; + tmplabel && strcmp( name, tmplabel->name ); + tmplabel=tmplabel->next ); + if( tmplabel==NULL ) return; + } + for( tmpitem = tmplabel->m_item; + tmpitem && (strcmp( oldl, tmpitem->label ) || + (action==NULL?False:strcmp(tmpitem->action, action))); + tmpitem=tmpitem->next ); + if( tmpitem==NULL ) return; + switch( sm ){ + case M_COPY: tmpitem->mode = mm; break; + case M_AND: tmpitem->mode &= mm; break; + case M_OR: tmpitem->mode |= mm; break; + } + if( oldl==newl || !strcmp( oldl, newl ) ) return; + if( tmpitem->label!=NULL ) + free( tmpitem->label ); + tmpitem->label = strdup( newl ); +} + +void FreeMenuItems( MenuLabel *ml, Bool FreeIcon ) +{ + MenuItem *tmpitem, *next; + + tmpitem = ml->m_item; + while( tmpitem!=NULL ){ + next = tmpitem->next; + if( tmpitem->label ) free( tmpitem->label ); + if( tmpitem->action ) free( tmpitem->action ); + if( FreeIcon && tmpitem->xpm ){ + XFreePixmap( dpy, tmpitem->xpm->icon ); + XFreePixmap( dpy, tmpitem->xpm->lighticon ); + if( tmpitem->xpm->mask!=None ) + XFreePixmap( dpy, tmpitem->xpm->mask ); + free( tmpitem->xpm ); + free( tmpitem->iconname ); + } + free( tmpitem ); + tmpitem = next; + } +} + +void FreeMenuLabels( MenuLabel *ml, Bool all ) +{ + Bool cont=True; + XWindowAttributes winattrs; + unsigned long eventMask; + XEvent ev; + + FreeMenuItems( ml, all ); + free( ml->name ); + if( ml->LabelStr ) free( ml->LabelStr ); + if( ml->xpm ){ + XFreePixmap( dpy, ml->xpm->icon ); + XFreePixmap( dpy, ml->xpm->lighticon ); + if( ml->xpm->mask!=None ) XFreePixmap( dpy, ml->xpm->mask ); + free( ml->xpm ); + } + if( !(ml->flags&SWALLOW) ){ + if( ml->action ) + free( ml->action ); + if( ml->LabelWin!=None ) + XDestroyWindow( dpy, ml->LabelWin ); + if( ml->PullWin!=None ) + XDestroyWindow( dpy, ml->PullWin ); + } + else{ + if( XGetWindowAttributes(dpy, ml->LabelWin, &winattrs) ){ + eventMask = winattrs.your_event_mask; + XMoveWindow( dpy, ml->LabelWin, ml->LabelX, -MENUB_H ); + XMapWindow( dpy, ml->LabelWin ); + XSelectInput(dpy, ml->LabelWin, eventMask | StructureNotifyMask); + + if( ml->flags&CANDELETE ) + send_clientmessage( ml->LabelWin, _XA_WM_DELETE_WINDOW, + CurrentTime); + else + XKillClient( dpy, ml->LabelWin ); + do{ + XMaskEvent( dpy, StructureNotifyMask|SubstructureNotifyMask, + &ev ); + if( (ev.type==UnmapNotify || ev.type==DestroyNotify) && + (ev.xany.window==ml->LabelWin || + ev.xunmap.window==ml->LabelWin) ){ + cont = False; + XUnmapWindow( dpy, ev.xany.window ); + } + else + HandleEvents( ev ); + } + while( cont ); + } + free( ml->action ); + } + if( all ) free( ml ); +} + +void FreeMenu( void ) +{ + Menu *tmpm, *nextm; + MenuLink *tmplink, *nextlink; + MenuLabel *tmpml, *nextl; + + tmpm = Scr.MenuRoot; + while( tmpm ){ + nextm = tmpm->next; + tmplink = tmpm->link; + while( tmplink ){ + nextlink = tmplink->next; + free( tmplink ); + tmplink = nextlink; + } + free( tmpm->name ); + free( tmpm ); + tmpm = nextm; + } + + tmpml = Scr.MenuLabelRoot; + while( tmpml ){ + nextl = tmpml->next; + FreeMenuLabels( tmpml, True ); + tmpml = nextl; + } + ChangeMenuLabel( &(Scr.IconMenu), NULL, Scr.SystemIcon ); + FreeMenuLabels( &Scr.IconMenu, False ); + XUnmapWindow( dpy, Scr.MenuBar ); +} + +void FreeShortCut( void ) +{ + ShortCut *now, *next; + + now = Scr.ShortCutRoot; + for( ;now!=NULL; now = next ){ + next = now->next; + free( now->action ); + free( now ); + } +} + +void KeepOnTop( void ) +{ + MlvwmWindow *tmp; + + if( Scr.flags&STARTING ) return; + for (tmp = Scr.MlvwmRoot.next; tmp != NULL; tmp = tmp->next) + if( tmp->flags&ONTOP ) + RaiseMlvwmWindow( tmp ); + XRaiseWindow( dpy, Scr.MenuBar ); + XRaiseWindow( dpy, Scr.lbCorner ); + XRaiseWindow( dpy, Scr.rbCorner ); +} + +void CreateSimpleMenu( void ) +{ + Scr.MenuLabelRoot = calloc( 1, sizeof( MenuLabel ) ); + Scr.MenuLabelRoot->flags = LEFTSIDE | ACTIVE; + Scr.MenuLabelRoot->name = strdup( "Default" ); + Scr.MenuLabelRoot->LabelStr = strdup( "File" ); + + Scr.MenuLabelRoot->m_item = calloc( 1, sizeof( MenuItem ) ); + Scr.MenuLabelRoot->m_item->mode = SELECTON; + Scr.MenuLabelRoot->m_item->label = strdup( "Quit" ); + Scr.MenuLabelRoot->m_item->action = strdup( "Exit" ); +} diff --git a/mlvwm/menus.h b/mlvwm/menus.h new file mode 100644 index 0000000..86dbd72 --- /dev/null +++ b/mlvwm/menus.h @@ -0,0 +1,129 @@ +/****************************************************************************/ +/* This module is all original code */ +/* by TakaC Hasegawa (tak@bioele.nuee.nagoya-u.ac.jp */ +/* Copyright 1996, TakaC Hasegawa */ +/* You may use this code for any purpose, as long as the original */ +/* copyright remains in the source code and all documentation */ +/****************************************************************************/ +#ifndef _MENUS_ +#define _MENUS_ + +#include +#include +#include + +#define MENUB_H 25 + +/* Definitions of Menu Item */ +#define STRGRAY 1 /* Draw String Black or Gray? */ +#define ICONGRAY 2 /* Draw Icon Gray */ +#define CHECKON 4 /* Draw Check Mark or Not? */ +#define SELECTON 8 /* Can Select or Not? */ +#define M_ALLSET (STRGRAY|CHECKON|SELECTON) + +/* Definitions of ChangeMenuItemLabel mode */ +#define M_COPY 0 +#define M_AND 1 +#define M_OR 2 + +/* Definitions the way of unmap menu */ +#define UNMAP_LABEL 1 +#define UNMAP_WINDOW 2 +#define UNMAP_ALL UNMAP_LABEL|UNMAP_WINDOW + +typedef struct ShortCut +{ + struct ShortCut *next; + KeyCode keycode; + int mods; + char *action; +} +ShortCut; + +typedef struct MenuItem +{ + struct MenuItem *next; + struct MenuLabel *submenu; + Icon *xpm; + char *iconname; + char *label; + char *action; + int mode; +}MenuItem; + +/* Definitions of Menu Label */ +#define ACTIVE 1 +#define LEFTSIDE 2 +#define SWALLOW 4 +#define CANDELETE 8 +#define STICKLABEL 16 + +typedef struct MenuLabel +{ + struct MenuLabel *next; + Window LabelWin; + int LabelWidth; + char *LabelStr; + char *name; + char *action; /* use for swallow */ + int flags; + Icon *xpm; + int LabelX; /* Position of Label */ + MenuItem *m_item; + Window PullWin; + int SelectNum; + int MenuX; + int MenuY; + int MenuWidth; + int MenuHeight; + int ItemHeight; + int IconWidth; +} MenuLabel; + +typedef struct MenuLink +{ + struct MenuLink *next; + MenuLabel *link; +} MenuLink; + +typedef struct Menu +{ + struct Menu *next; + char *name; + MenuLink *link; +} Menu; + +typedef struct +{ + char *label; + char *(*action)( MenuLabel *, char * ); +}menu_func; + +typedef struct +{ + char *label; + char *(*action)( char *, char **, int *, char **, MenuLabel ** ); +}menu_item_func; + +extern void RedrawMenu( MenuLabel *, Bool ); +extern void RedrawMenuBar( void ); +extern Bool isRect( int, int, int, int, int, int ); +extern void press_menu( MenuLabel * ); +extern void CreateMenuLabel( MenuLabel * ); +extern void AddMenuItem(MenuLabel *, char *, char *, char *, Icon *, MenuLabel *, int); +extern void DelMenuItem( MenuLabel *, char * ); +extern void CreateIconMenu( void ); +extern void CreateMenuItems( void ); +extern void SetMenu( char *, FILE * ); +extern void SetMenuBar( char *, FILE * ); +extern void SetSwallow( char *, FILE * ); +extern void CreateMenuBar( void ); +extern void MapMenuBar( MlvwmWindow * ); +extern void FreeMenu( void ); +extern void KeepOnTop( void ); +extern void ChangeMenuLabel( MenuLabel *, char *, Icon * ); +extern void ChangeMenuItemLabel( char *, char *, char *, char *, int, int ); +extern void FreeShortCut( void ); +extern void DrawStringMenuBar( char * ); +extern void CreateSimpleMenu( void ); +#endif diff --git a/mlvwm/misc.c b/mlvwm/misc.c new file mode 100644 index 0000000..10b7488 --- /dev/null +++ b/mlvwm/misc.c @@ -0,0 +1,298 @@ +/****************************************************************************/ +/* This module is mostly all new */ +/* by TakaC Hasegawa (tak@bioele.nuee.nagoya-u.ac.jp) */ +/* Copyright 1996 TakaC Hasegawa. No restrictions are placed on this code, */ +/* as long as the copyright notice is preserved */ +/****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +#include "mlvwm.h" +#include "menus.h" +#include "screen.h" + +char *LookUpFiles( char *path, char *filename, int mode ) +{ + char *find; + + if( !access( filename, mode ) ){ + find = strdup( filename ); + return find; + } + if( path==NULL ) return NULL; + do{ + find = calloc( strlen(path)+strlen(filename)+2, 1 ); + if( strchr( path, ':' )==NULL ){ + sprintf( find, "%s/%s", path, filename ); + path += strlen( path ); + } + else{ + strcpy( find, path ); + sprintf( strchr( find, ':' ), "/%s", filename ); + path = strchr( path, ':') + 1; + } + if( !access(find, mode ) ){ + return find; + } + free( find ); + } + while( *path!='\0' && *path!='\n' ); + return NULL; +} + +char *SkipNonSpace( char *str ) +{ + for( ; *str!=' ' && *str!='\t' && *str; str++ ); + return str; +} + +char *stripquote( char *str, char **copy ) +{ + char *top, *last; + int len; + + top = strchr( str, '"' ); + last = top!=NULL ? strchr( top+1, '"' ) : NULL; + len = last-top; + if( top==NULL || last==NULL ){ + *copy = NULL; + return str+strlen(str)-1; + } + *copy = calloc( len, 1 ); + strncpy( *copy, top+1, len-1 ); + return last+1; +} + +char *stripspace_num( char *str ) +{ + char *action; + + for( ; (*str==' ' || *str=='\t' || isdigit(*str) ); str++ ); + action = calloc( strlen( str ), 1 ); + strncpy( action, str, strlen( str )-1 ); + return action; +} + +char *SkipSpace( char *str ) +{ + for( ; (*str==' ' || *str=='\t'); str++ ); + return str; +} + +void sleep_a_little(int n) +{ + struct timeval value; + + if (n <= 0) + return; + + value.tv_usec = n % 1000000; + value.tv_sec = n / 1000000; + + (void) select(1, 0, 0, 0, &value); +} + +void DrawErrMsgOnMenu( char *str1, char *str2 ) +{ + char *str; + static int call=0; + int wait_s; + + call++; + str = calloc( strlen(str1)+strlen(str2)+1, 1 ); + sprintf( str, "%s%s", str1, str2 ); + if( call<5 ) XBell( dpy, 30 ); + DrawStringMenuBar( str ); + wait_s = 3000000-call/5*500000; + wait_s = wait_s>0? wait_s : 300000; + sleep_a_little( wait_s ); + free( str ); +} + +Icon *ReadIcon( char *fn, Icon *icon, Bool err ) +{ + XWindowAttributes root_attr; + XpmAttributes attr; + int x, y, xhot, yhot; + Pixmap bitmap; + Icon *newicon; + char *path; + + if( icon==NULL ) newicon = (Icon *)calloc( 1, sizeof(Icon) ); + else newicon = icon; + if((path = LookUpFiles( Scr.IconPath, fn, R_OK ))==NULL ){ + if( err ) + DrawErrMsgOnMenu( "Can't Find file ", fn ); + return NULL; + } + XGetWindowAttributes(dpy,Scr.Root,&root_attr); + attr.colormap = root_attr.colormap; + attr.closeness = 40000; /* Allow for "similar" colors */ + attr.valuemask = XpmSize | XpmReturnPixels | XpmColormap | XpmCloseness; + if( XpmReadFileToPixmap( dpy, Scr.Root, path, + &newicon->icon, &newicon->mask, + &attr ) != XpmSuccess && + XReadBitmapFile( dpy, Scr.Root, path, &newicon->width, &newicon->height, + &bitmap, &xhot, &yhot) !=BitmapSuccess ){ + if( err ) + DrawErrMsgOnMenu( "Can't Read ICON ", fn ); + if( icon==NULL ) + free( newicon ); + newicon = NULL; + } + else{ + if( newicon->icon ){ + newicon->width = attr.width; + newicon->height = attr.height; + newicon->kind = PIXMAP; + } + else{ + newicon->icon = XCreatePixmap( dpy, Scr.Root, + newicon->width, newicon->height, + Scr.d_depth ); + newicon->mask = XCreatePixmap( dpy, Scr.Root, + newicon->width, newicon->height, + Scr.d_depth ); + XCopyPlane( dpy, bitmap, newicon->icon, Scr.BlackGC, 0, 0, + newicon->width, newicon->height, 0, 0, 1 ); + XCopyPlane( dpy, bitmap, newicon->mask, Scr.WhiteGC, 0, 0, + newicon->width, newicon->height, 0, 0, 1 ); + + newicon->kind = BITMAP; + XFreePixmap( dpy, bitmap ); + } + newicon->lighticon = XCreatePixmap( dpy, newicon->icon, + newicon->width, newicon->height, + Scr.d_depth ); + XCopyArea( dpy, newicon->icon, newicon->lighticon, + DefaultGC( dpy, Scr.screen ), + 0, 0, attr.width, attr.height, 0, 0 ); + for( y=0; yheight; y++ ) + for( x=y%2; xwidth; x+=2 ) + XDrawPoint( dpy, newicon->lighticon, Scr.WhiteGC, x, y ); + } + if( path!=NULL ) free( path ); + + XpmFreeAttributes( &attr ); + return newicon; +} + +Pixel GetColor( char *name ) +{ + XColor color; + XWindowAttributes attributes; + + XGetWindowAttributes( dpy, Scr.Root, &attributes ); + color.pixel = 0; + if( !XParseColor( dpy, attributes.colormap, name, &color )){ + fprintf( stderr, "Unknow color %s\n", name ); + exit( 1 ); + } + else if( !XAllocColor( dpy, attributes.colormap, &color )){ + fprintf( stderr, "Can't allocate color %s\n", name ); + exit( 1 ); + } + return color.pixel; +} + +void SetSegment( int x1, int x2, int y1, int y2, XSegment *seg ) +{ + seg->x1 = x1; + seg->x2 = x2; + seg->y1 = y1; + seg->y2 = y2; +} + +void RaiseMlvwmWindow( MlvwmWindow *win ) +{ + MlvwmWindow *tmp, *lastwin=NULL; + int count=4, set=3; + Window *wins; + + for( tmp = Scr.MlvwmRoot.next; tmp!=NULL; tmp=tmp->next ){ + if( tmp->flags&TRANSIENT && tmp->transientfor==win->w && tmp!=win + && !(tmp->flags&ONTOP) ) + count++; + if( tmp->flags&ONTOP && tmp!=win ) + count++; + if( tmp->next==NULL ) + lastwin = tmp; + } + wins = calloc( count, sizeof(Window) ); + wins[0] = Scr.MenuBar; + wins[1] = Scr.lbCorner; + wins[2] = Scr.rbCorner; + + for( tmp = Scr.MlvwmRoot.next; tmp!=NULL; tmp=tmp->next ){ + if( win->flags&TRANSIENT && win->transientfor==tmp->w + && tmp->flags&ONTOP ){ + wins[set++] = win->frame; + } + if( tmp!=win && tmp->flags&ONTOP ) + wins[set++] = tmp->frame; + } + for( tmp = lastwin; tmp!=&Scr.MlvwmRoot; tmp=tmp->prev ) + if( tmp->flags&TRANSIENT && tmp->transientfor==win->w && tmp!=win + && !(tmp->flags&ONTOP)) + wins[set++] = tmp->frame; + if( count!=set ) + wins[set++] = win->frame; + + XRaiseWindow( dpy, wins[0] ); + XRestackWindows( dpy, wins, set ); + + free( wins ); +} + +char *WinListName( MlvwmWindow *mw ) +{ + char *winname; + + winname = calloc( strlen( mw->name )+1+(Scr.flags&DISPDESK?3:0), 1 ); + if( Scr.flags&DISPDESK ){ + if( mw->flags&STICKY ) + sprintf( winname, "S:%s", mw->name ); + else + sprintf( winname, "%d:%s", mw->Desk, mw->name ); + } + else + strcpy( winname, mw->name ); + + return winname; +} + +void StrWidthHeight( +#ifdef USE_LOCALE +XFontSet font, +#else +XFontStruct *font, +#endif + int *width, int *height, int *offset, char *str, int length ) +{ +#ifdef USE_LOCALE + XRectangle ink, logical; +#else + int font_ascent, font_descent, direction; + XCharStruct overall; +#endif + +#ifdef USE_LOCALE + XmbTextExtents( font, str, length, &ink, &logical ); + if( width ) *width = logical.width; + if( height ) *height = logical.height; + if( offset ) + *offset = logical.height/2+logical.y; +#else + XTextExtents( font, str, length, + &direction, &font_ascent, &font_descent, &overall ); + if( width ) *width = overall.width; + if( height ) *height = font_ascent+font_descent; + if( offset ) + *offset = (font_ascent+font_descent)/2-font_ascent; +#endif +} diff --git a/mlvwm/misc.h b/mlvwm/misc.h new file mode 100644 index 0000000..c723659 --- /dev/null +++ b/mlvwm/misc.h @@ -0,0 +1,33 @@ +/****************************************************************************/ +/* This module is all original code */ +/* by TakaC Hasegawa (tak@bioele.nuee.nagoya-u.ac.jp */ +/* Copyright 1996, TakaC Hasegawa */ +/* You may use this code for any purpose, as long as the original */ +/* copyright remains in the source code and all documentation */ +/****************************************************************************/ +#ifndef _MISC_ +#define _MISC_ +#include + +extern char *SkipNonSpace( char * ); +extern char *LookUpFiles( char *, char *, int ); +extern void sleep_a_little( int ); +extern char *stripquote( char *, char ** ); +extern char *SkipSpace( char * ); +extern char *stripspace_num( char * ); +extern Icon *ReadIcon( char *, Icon *, Bool ); +extern void DrawErrMsgOnMenu( char *, char * ); +extern void SetSegment( int, int, int, int, XSegment * ); +extern void RaiseMlvwmWindow( MlvwmWindow * ); +extern Pixel GetColor( char * ); +extern char *WinListName( MlvwmWindow * ); + +extern void StrWidthHeight( +#ifdef USE_LOCALE +XFontSet , +#else +XFontStruct *, +#endif + int *, int *, int *, char *, int ); + +#endif /* _MISC_ */ diff --git a/mlvwm/mlvwm.c b/mlvwm/mlvwm.c new file mode 100644 index 0000000..dc52cdb --- /dev/null +++ b/mlvwm/mlvwm.c @@ -0,0 +1,699 @@ +/****************************************************************************/ +/* This module is based on fvwm, but has been siginificantly modified */ +/* by TakaC Hasegawa (tak@bioele.nuee.nagoya-u.ac.jp) */ +/****************************************************************************/ +/**************************************************************************** + * This module is based on Twm, but has been siginificantly modified + * by Rob Nation (nation@rocket.sanders.lockheed.com) + ****************************************************************************/ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "mlvwm.h" +#include "screen.h" +#include "event.h" +#include "add_window.h" +#include "config.h" +#include "functions.h" +#include "misc.h" + +#include +#include +#include +#include +#include +#ifdef USE_LOCALE +#include +#endif + +static unsigned char start_mesh[] = { 0x03, 0x03, 0x0c, 0x0c}; + +ScreenInfo Scr; +Display *dpy; +int xfd; +XContext MlvwmContext; +XContext MenuContext; +XClassHint NoClass; + +static char **g_argv; +int ShapeEventBase, ShapeErrorBase; + +void CreateCursors( void ) +{ + Scr.MlvwmCursors[DEFAULT] = XCreateFontCursor( dpy, XC_left_ptr ); + Scr.MlvwmCursors[SYS] = XCreateFontCursor( dpy, XC_X_cursor ); + Scr.MlvwmCursors[TITLE_CURSOR] = XCreateFontCursor( dpy, XC_hand2 ); + Scr.MlvwmCursors[RESIZE] = + XCreateFontCursor( dpy, XC_bottom_right_corner ); + Scr.MlvwmCursors[MOVE] = XCreateFontCursor( dpy, XC_fleur ); + Scr.MlvwmCursors[MENU] = XCreateFontCursor( dpy, XC_sb_left_arrow ); + Scr.MlvwmCursors[WAIT] = XCreateFontCursor( dpy, XC_watch ); + Scr.MlvwmCursors[SELECT] = XCreateFontCursor( dpy, XC_dot ); + Scr.MlvwmCursors[DESTROY] = XCreateFontCursor( dpy, XC_pirate ); + Scr.MlvwmCursors[SBARH_CURSOR] = + XCreateFontCursor( dpy, XC_sb_h_double_arrow ); + Scr.MlvwmCursors[SBARV_CURSOR] = + XCreateFontCursor( dpy, XC_sb_v_double_arrow ); + Scr.MlvwmCursors[MINMAX_CURSOR] = XCreateFontCursor( dpy, XC_sizing ); + Scr.MlvwmCursors[SHADER_UP_CURSOR] = + XCreateFontCursor( dpy, XC_based_arrow_up ); + Scr.MlvwmCursors[SHADER_DOWN_CURSOR] = + XCreateFontCursor( dpy, XC_based_arrow_down ); +} + +void LoadDefaultFonts( void ) +{ +#ifdef USE_LOCALE + char **miss, *def; + int n_miss, lp; + + Scr.MenuBarFs = XCreateFontSet( dpy, DEFAULTFS, &miss, &n_miss, &def ); + if( n_miss>0 ){ + for( lp=0; lp0 ){ + for( lp=0; lp0 ){ + for( lp=0; lp0 ){ + for( lp=0; lp1 ) + gcv.foreground = GetColor( "#777777" ); + else + gcv.foreground = WhitePixel( dpy, Scr.screen ); + gcv.line_style = FillSolid; + + Scr.RobberGC = XCreateGC( dpy, Scr.Root, gcm, &gcv ); + + gcm = GCFunction | GCPlaneMask | GCForeground | GCBackground | GCTile; + gcv.function = GXcopy; + gcv.plane_mask = AllPlanes; + gcv.line_width = 0; + gcv.fill_style = FillSolid; + gcv.tile = Scr.mask; + + gcv.foreground = BlackPixel( dpy, Scr.screen ); + gcv.background = WhitePixel( dpy, Scr.screen ); + Scr.BlackGC = XCreateGC( dpy, Scr.Root, gcm, &gcv ); + + gcv.foreground = WhitePixel( dpy, Scr.screen ); + gcv.background = BlackPixel( dpy, Scr.screen ); + Scr.WhiteGC = XCreateGC( dpy, Scr.Root, gcm, &gcv ); + + if( Scr.d_depth>1 ) gcv.foreground = GetColor( "#444444" ); + gcv.background = WhitePixel( dpy, Scr.screen ); + Scr.Gray1GC = XCreateGC( dpy, Scr.Root, gcm, &gcv ); + + if( Scr.d_depth>1 ) gcv.foreground = GetColor( "#777777" ); + gcv.background = WhitePixel( dpy, Scr.screen ); + Scr.Gray2GC = XCreateGC( dpy, Scr.Root, gcm, &gcv ); + + if( Scr.d_depth>1 ) gcv.foreground = GetColor( "#bbbbbb" ); + if( Scr.d_depth>1 ) gcv.foreground = GetColor( "#aaaaaa" ); + gcv.background = WhitePixel( dpy, Scr.screen ); + Scr.Gray3GC = XCreateGC( dpy, Scr.Root, gcm, &gcv ); + + if( Scr.d_depth>1 ) gcv.foreground = GetColor( "#e0e0e0" ); + gcv.background = WhitePixel( dpy, Scr.screen ); + Scr.Gray4GC = XCreateGC( dpy, Scr.Root, gcm, &gcv ); + + if( Scr.d_depth>1 ) gcv.foreground = GetColor( "#3333ff" ); + gcv.background = WhitePixel( dpy, Scr.screen ); + Scr.MenuSelectBlueGC = XCreateGC( dpy, Scr.Root, gcm, &gcv ); + + if( Scr.d_depth>1 ) gcv.foreground = GetColor( "#dddddd" ); + gcv.background = WhitePixel( dpy, Scr.screen ); + Scr.MenuBlueGC = XCreateGC( dpy, Scr.Root, gcm, &gcv ); + + if( Scr.d_depth>1 ) gcv.foreground = GetColor( "#ccccff" ); + gcv.background = WhitePixel( dpy, Scr.screen ); + Scr.ScrollBlueGC = XCreateGC( dpy, Scr.Root, gcm, &gcv ); +} + +void InitVariables( void ) +{ + MlvwmContext = XUniqueContext(); + + InitScrParams(); + InitGCs(); + + NoClass.res_name = NoName; + NoClass.res_class = NoName; + + AddMenuItem( &(Scr.IconMenu), "Hide Active", "HideActive", + NULL, NULL, NULL, STRGRAY ); + AddMenuItem( &(Scr.IconMenu), "Hide Others", "HideOthers", + NULL, NULL, NULL, STRGRAY ); + AddMenuItem( &(Scr.IconMenu), "Show All", "ShowAll", + NULL, NULL, NULL, STRGRAY ); + AddMenuItem( &(Scr.IconMenu), "", "Nop", NULL, NULL, NULL, STRGRAY ); +} + +Atom _XA_MIT_PRIORITY_COLORS; +Atom _XA_WM_CHANGE_STATE; +Atom _XA_WM_STATE; +Atom _XA_WM_COLORMAP_WINDOWS; +Atom _XA_WM_PROTOCOLS; +Atom _XA_WM_TAKE_FOCUS; +Atom _XA_WM_DELETE_WINDOW; +Atom _XA_WM_DESKTOP; + +void InternUsefulAtoms (void) +{ + /* + * Create priority colors if necessary. + */ + _XA_MIT_PRIORITY_COLORS = XInternAtom(dpy, "_MIT_PRIORITY_COLORS", False); + _XA_WM_CHANGE_STATE = XInternAtom (dpy, "WM_CHANGE_STATE", False); + _XA_WM_STATE = XInternAtom (dpy, "WM_STATE", False); + _XA_WM_COLORMAP_WINDOWS = XInternAtom (dpy, "WM_COLORMAP_WINDOWS", False); + _XA_WM_PROTOCOLS = XInternAtom (dpy, "WM_PROTOCOLS", False); + _XA_WM_TAKE_FOCUS = XInternAtom (dpy, "WM_TAKE_FOCUS", False); + _XA_WM_DELETE_WINDOW = XInternAtom (dpy, "WM_DELETE_WINDOW", False); + _XA_WM_DESKTOP = XInternAtom (dpy, "WM_DESKTOP", False); + + return; +} + +int MappedNotOverride( Window w ) +{ + XWindowAttributes wa; + + XGetWindowAttributes(dpy, w, &wa); + return ((wa.map_state != IsUnmapped) && (wa.override_redirect != True)); +} + +void RepaintAllWindows( Window w ) +{ + Window parent, *children; + XWindowAttributes attributes; + unsigned nchildren, lp; + MlvwmWindow *t; + + XQueryTree( dpy, Scr.Root, &Scr.Root, &parent, &children, &nchildren ); + for( lp=0; nchildren > lp; lp++ ){ + if( children[lp]==w || children[lp]==Scr.MenuBar ) continue; + XGetWindowAttributes( dpy, children[lp], &attributes ); + if( IsUnmapped ==attributes.map_state ) continue; + if( children[lp] && MappedNotOverride(children[lp]) ){ + HandleMapRequest( children[lp] ); + if( XFindContext( dpy, children[lp], + MlvwmContext, (caddr_t *)&t)!=XCNOENT) + DrawStringMenuBar( t->name ); + } + XLowerWindow( dpy, children[lp] ); + } + XFree( children ); +} + +void Reborder( Bool restart ) +{ + MlvwmWindow *tmp; + + XGrabServer (dpy); + InstallWindowColormaps( &Scr.MlvwmRoot ); /* force reinstall */ + for (tmp = (MlvwmWindow *)Scr.MlvwmRoot.next; tmp != NULL; + tmp = (MlvwmWindow *)tmp->next){ + XUnmapWindow(dpy,tmp->frame); + RestoreWithdrawnLocation( tmp, restart ); + } + XUngrabServer (dpy); + XSetInputFocus (dpy, PointerRoot, RevertToPointerRoot,CurrentTime); +} + +void SaveDesktopState( void ) +{ + MlvwmWindow *t; + unsigned long data[1]; + + for (t = Scr.MlvwmRoot.next; t != NULL; t = t->next){ + data[0] = (unsigned long) t->Desk; + XChangeProperty (dpy, t->w, _XA_WM_DESKTOP, _XA_WM_DESKTOP, 32, + PropModeReplace, (unsigned char *) data, 1); + } + + data[0] = (unsigned long) Scr.currentdesk; + XChangeProperty (dpy, Scr.Root, _XA_WM_DESKTOP, _XA_WM_DESKTOP, 32, + PropModeReplace, (unsigned char *) data, 1); + + XSync(dpy, 0); +} + +void Done( int restart, char *command ) +{ + char *my_argv[10]; + int i,done; + + strcpy( Scr.ErrorFunc, "Start Done" ); + + FreeMenu(); + strcpy( Scr.ErrorFunc, "FreeMenu Done" ); + + FreeShortCut(); + strcpy( Scr.ErrorFunc, "FreeShortCut Done" ); + + FreeStyles(); + strcpy( Scr.ErrorFunc, "FreeStyles Done" ); + + FreeFont(); + strcpy( Scr.ErrorFunc, "FreeFont Done" ); + + if( Scr.LastActive ) free( Scr.LastActive ); + if( Scr.Balloon!=None ) XDestroyWindow( dpy, Scr.Balloon ); + + Reborder( restart==0?False:True ); + strcpy( Scr.ErrorFunc, "Reborder Done" ); + + if(restart){ + i=0; + done = 0; + while((g_argv[i] != NULL)&&(i<8)){ + if(strcmp(g_argv[i],"-s")==0) + done = 1; + my_argv[i] = g_argv[i]; + i++; + } + if(!done) + my_argv[i++] = "-s"; + while(i<10) + my_argv[i++] = NULL; + SaveDesktopState(); + XSelectInput(dpy, Scr.Root, 0 ); + XSync(dpy, 0); + XCloseDisplay(dpy); + + sleep( 1 ); + ReapChildren(); + + if( command != NULL ) + execvp(command,g_argv); + else + execvp( *g_argv,g_argv); + + fprintf( stderr, "Call of '%s' failed!!!!", command); + execvp( *g_argv, g_argv); + fprintf( stderr, "Call of '%s' failed!!!!", g_argv[0]); + } + else{ + XCloseDisplay( dpy ); + exit(0); + } +} + +void SigDone(int nonsense) +{ + fprintf( stderr, "Catch Signal in [%s]\n", Scr.ErrorFunc ); + Done(0, NULL); + return; +} + +void setsighandle( int sig ) +{ + if( signal( sig, SIG_IGN ) != SIG_IGN ) + signal( sig, SigDone ); +} + +void usage( void ) +{ + fprintf( stderr, "Mlvwm Ver %s\n\n", VERSION ); + fprintf( stderr, "mlvwm [-d display] [-f config_file]"); + fprintf( stderr, " [-debug]\n" ); +} + +XErrorHandler CatchRedirectError(Display *err_dpy, XErrorEvent *event) +{ + fprintf( stderr, "MLVWM : another WM may be running.\n" ); + exit(1); +} + +XErrorHandler MlvwmErrorHandler(Display *err_dpy, XErrorEvent *event) +{ + char err_msg[80]; + + /* some errors are acceptable, mostly they're caused by + * trying to update a lost window */ + if((event->error_code == BadWindow) || + (event->request_code == X_GetGeometry) || + (event->error_code==BadDrawable) || + (event->request_code==X_SetInputFocus) || + (event->request_code == X_InstallColormap)) + return 0 ; + + XGetErrorText( err_dpy, event->error_code, err_msg, 80 ); + fprintf( stderr, "MLVWM : X Protocol error\n" ); + fprintf( stderr, " Error detected : %s\n", err_msg ); + fprintf( stderr, " Protocol Request : %d\n", event->request_code ); + fprintf( stderr, " Error : %d\n", event->error_code); + fprintf( stderr, " Resource ID : 0x%x\n", + (unsigned int)event->resourceid ); + fprintf( stderr,"\n"); + return 0; +} + +Window CreateStartWindow( void ) +{ + Pixmap p_map; + unsigned long valuemask; + Window StartWin; + XSetWindowAttributes attributes; + + if( Scr.flags & DEBUGOUT ) + fprintf( stderr, "Display Startup Screen !\n" ); + p_map = XCreatePixmapFromBitmapData( dpy, Scr.Root, start_mesh, 4, 4, + WhitePixel( dpy, Scr.screen ), + BlackPixel( dpy, Scr.screen ), Scr.d_depth ); + if( Scr.flags & DEBUGOUT ) + fprintf( stderr, "Pixmap Create !\n" ); + valuemask = CWBackPixmap | CWBackingStore | CWCursor; + attributes.background_pixmap = p_map; + attributes.cursor = Scr.MlvwmCursors[WAIT]; + attributes.backing_store = NotUseful; + StartWin = XCreateWindow (dpy, Scr.Root, 0, 0, + (unsigned int) Scr.MyDisplayWidth, + (unsigned int) Scr.MyDisplayHeight, + (unsigned int) 0, + CopyFromParent, (unsigned int) CopyFromParent, + (Visual *) CopyFromParent, valuemask, + &attributes); + XMapRaised (dpy, StartWin); + XFreePixmap( dpy, p_map ); + XFlush (dpy); + + return StartWin; +} + +void SegFault( int nosense ) +{ + fprintf( stderr,"Segmentation Fault\n" ); + fprintf( stderr,"\tin %s\n", Scr.ErrorFunc ); + exit( -1 ); +} + +void DoStartFunc( void ) +{ + ShortCut *now, *prev; + + now = Scr.StartFunc; + while( now ){ + ExecuteFunction( now->action ); + prev = now; + now = now->next; + free( prev->action ); + free( prev ); + } +} + +void main( int argc, char *argv[] ) +{ + char *display_name=NULL; + char *display_string; + char *config_file=NULL; + char message[255]; + char num[10]; + Window StartWin; + XSetWindowAttributes attributes; + int len, lp; + Bool single = False; + + Scr.flags = 0; + for( lp=1; lp=argc ) usage(); + else display_name = argv[lp]; + continue; + } + if( !strncmp( argv[lp], "-f", 2 ) ){ + if( ++lp>=argc ) usage(); + else config_file = argv[lp]; + continue; + } + if( !strncmp( argv[lp], "-s", 2 ) ){ + single = True; + continue; + } + if( !strncmp( argv[lp], "-debug", 6 )){ + Scr.flags |= DEBUGOUT; + continue; + } + usage(); + } + if( Scr.flags & DEBUGOUT ) + fprintf( stderr, "Welcome to MLVWM World !\n" ); +#ifdef USE_LOCALE + if( setlocale( LC_CTYPE, "" )==NULL ){ + fprintf( stderr, "Can't figure out your locale.\n" ); + fprintf( stderr, "Check $LANG.\n" ); + } + if( XSupportsLocale() == False ){ + fprintf( stderr, "Can't support your local.\n" ); + fprintf( stderr, "Use \"C\" locale.\n" ); + setlocale( LC_CTYPE, "C" ); + } +#endif + if( !(dpy = XOpenDisplay( display_name )) ){ + fprintf( stderr, "can't open display %s\n",XDisplayName(display_name)); + exit( 1 ); + } + xfd = XConnectionNumber(dpy); + + if( fcntl( xfd, F_SETFD, 1 ) == -1){ + fprintf( stderr, "Close-on-exec failed\n" ); + exit (1); + } + + Scr.screen = DefaultScreen( dpy ); + + g_argv = argv; + + setsighandle( SIGINT ); + setsighandle( SIGHUP ); + setsighandle( SIGQUIT ); + setsighandle( SIGTERM ); + signal( SIGSEGV, SegFault ); + Scr.NumberOfScreens = ScreenCount(dpy); + + if(!single){ + for(lp=0;lpnext->next != NULL; + Scr.iconAnchor = Scr.iconAnchor->next ); + RepaintAllWindows( StartWin ); + if( Scr.StartFunc ) DoStartFunc(); + + XDestroyWindow (dpy, StartWin); + + sprintf( message, "Desk %d", Scr.currentdesk ); + DrawStringMenuBar( "" ); + ChangeDesk( message ); + Scr.flags &= ~STARTING; + MapMenuBar( Scr.ActiveWin ); + + while( True ) WaitEvents(); +} diff --git a/mlvwm/mlvwm.h b/mlvwm/mlvwm.h new file mode 100644 index 0000000..63da7a1 --- /dev/null +++ b/mlvwm/mlvwm.h @@ -0,0 +1,186 @@ +/****************************************************************************/ +/* This module is based on fvwm, but has been siginificantly modified */ +/* by TakaC Hasegawa (tak@bioele.nuee.nagoya-u.ac.jp) */ +/****************************************************************************/ +/**************************************************************************** + * This module is based on Twm, but has been siginificantly modified + * by Rob Nation (nation@rocket.sanders.lockheed.com) + ****************************************************************************/ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + +#ifndef _MLVWM_ +#define _MLVFM_ + +#include +#include +#include +#include + +#include "sun_headers.h" + +#ifndef max +#define max( x, y ) ((x)>(y)? (x) : (y) ) +#endif +#ifndef min +#define min( x, y ) ((x)<(y)? (x) : (y) ) +#endif + +#include +#if defined(SYSV) || defined(SVR4) +#define ReapChildren() while ((waitpid(-1, NULL, WNOHANG)) > 0); +#else +#define ReapChildren() while ((wait3(NULL, WNOHANG, NULL)) > 0); +#endif + +#define TITLE_HEIGHT 20 +#define BOXSIZE 13 +#define SBAR_WH Scr.bar_width + +extern Display *dpy; +extern XContext MlvwmContext; +extern XContext MenuContext; +extern XClassHint NoClass; + +#define C_NO_CONTEXT 0x00000000 +#define C_WINDOW 0x00000001 +#define C_FRAME 0x00000002 +#define C_TITLE 0x00000004 +#define C_ICON 0x00000008 +#define C_ROOT 0x00000010 +#define C_CLOSE 0x00000020 +#define C_MINMAX 0x00000040 +#define C_RESIZE 0x00000080 +#define C_SHADE 0x00000100 +#define C_SBAR_UP 0x00000200 +#define C_SBAR_DOWN 0x00000400 +#define C_SBAR_H 0x00000800 +#define C_SBAR_H_AN 0x00001000 +#define C_SBAR_RIGHT 0x00002000 +#define C_SBAR_LEFT 0x00004000 +#define C_SBAR_V 0x00008000 +#define C_SBAR_V_AN 0x00010000 + +typedef struct Icon +{ + Pixmap icon; + Pixmap lighticon; + Pixmap mask; + int width, height; + enum {PIXMAP,BITMAP} kind; +} Icon; + +typedef struct MlvwmWindow +{ + struct MlvwmWindow *next; + struct MlvwmWindow *prev; + Window w; + Window frame; + Window Parent; + Window title_w; + Window scroll_h[4]; + Window scroll_v[4]; + Window close_b; + Window minmax_b; + Window resize_b; + Window shade_b; + Window transientfor; + int wShaped; + int frame_x, frame_y; + int frame_w, frame_h; + int size_w, size_h; + char *name; + XWindowAttributes attr; + XSizeHints hints; + XWMHints *wmhints; + XClassHint class; + Icon *miniicon; + unsigned int flags; + + int old_bw; + int diff_x, diff_y; +/* Use for Window Shade */ + int shade_h; +/* Use for Max(Min)imaize Operation */ + int orig_x, orig_y; + int orig_w, orig_h; +/* Use for scroll bar */ + int win_x, win_y; + int orig_win_x, orig_win_y; + int win_w, win_h; + int Desk; +} MlvwmWindow; + +/* + define flags +*/ +#define ONTOP 0x00000001 +#define TITLE 0x00000002 +#define SBARH 0x00000004 +#define SBARV 0x00000008 +#define RESIZER 0x00000010 +#define CLOSER 0x00000020 +#define MINMAXR 0x00000040 +#define SHADER 0x00000080 +#define NOWINLIST 0x00000100 +#define MAPPED 0x00000200 +#define ICON 0x00000400 +#define SHADE 0x00000800 +#define TRANSIENT 0x00001000 +#define VISIBLE 0x00002000 +#define MAXIMAIZED 0x00004000 +#define HIDED 0x00008000 +#define STICKY 0x00010000 +#define SKIPSELECT 0x00020000 +#define SCROLL 0x00040000 +#define NOFOCUS 0x00080000 +#define DISPDESK 0x00100000 +#define DoesWmTakeFocus 0x00200000 +#define DoesWmDeleteWindow 0x00400000 +#define STARTICONIC 0x00800000 +#define NONTRANSIENTDECORATE 0x01000000 + +#define NORMALWIN (TITLE | SBARH | SBARV | RESIZER | CLOSER | MINMAXR) + +extern Atom _XA_MIT_PRIORITY_COLORS; +extern Atom _XA_WM_CHANGE_STATE; +extern Atom _XA_WM_STATE; +extern Atom _XA_WM_COLORMAP_WINDOWS; +extern Atom _XA_WM_PROTOCOLS; +extern Atom _XA_WM_TAKE_FOCUS; +extern Atom _XA_WM_SAVE_YOURSELF; +extern Atom _XA_WM_DELETE_WINDOW; +extern Atom _XA_WM_DESKTOP; + +extern void Done( int, char * ); +#ifdef USE_LOCALE +#define DEFAULTFS "-adobe-*-*-r-*-*-14-*-*-*-p-*-*-*,\ +-*-*-*-r-*-*-14-*-*-*-*-*-*-*" +#else +#define DEFAULTFONT "-adobe-*-*-r-*-*-14-*-*-*-p-*-*-*" +#endif +#endif diff --git a/mlvwm/screen.h b/mlvwm/screen.h new file mode 100644 index 0000000..4dde62a --- /dev/null +++ b/mlvwm/screen.h @@ -0,0 +1,160 @@ +/**************************************************************************** + * This module is based on Twm, but has been siginificantly modified + * by Rob Nation (nation@rocket.sanders.lockheed.com) + ****************************************************************************/ +/* + * Copyright 1989 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. M.I.T. makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef _SCREEN_ +#define _SCREEN_ + +#include "menus.h" +#include "config.h" + +#include +#include +#include + +#define DEFAULT 0 +#define SYS 1 +#define TITLE_CURSOR 2 +#define MOVE 3 +#define RESIZE 4 +#define WAIT 5 +#define MENU 6 +#define SELECT 7 +#define DESTROY 8 +#define SBARH_CURSOR 9 +#define SBARV_CURSOR 10 +#define MINMAX_CURSOR 11 +#define SHADER_UP_CURSOR 12 +#define SHADER_DOWN_CURSOR 13 +#define MAX_CURSORS 14 + +#define MAX_WINDOW_WIDTH 32767 +#define MAX_WINDOW_HEIGHT 32767 + +typedef struct ScreenInfo +{ + int d_depth; + int screen; + int n_desktop; + int currentdesk; + int MyDisplayWidth; + int MyDisplayHeight; + int NumberOfScreens; + MlvwmWindow MlvwmRoot; + MenuLabel *MenuLabelRoot; + MenuLabel IconMenu; + Menu *MenuRoot; + Menu *ActiveMenu; + MenuItem *iconAnchor; + Window Root; + Window MenuBar; + Window NoFocusWin; + Window lbCorner; + Window rbCorner; + MlvwmWindow *ActiveWin; + MlvwmWindow **LastActive; + MlvwmWindow *PreviousActive; + ShortCut *ShortCutRoot; + int root_pushes; + MlvwmWindow *pushed_window; + Cursor MlvwmCursors[MAX_CURSORS]; + styles *style_list; + GC RobberGC; + GC BlackGC; + GC WhiteGC; + GC Gray1GC; + GC Gray2GC; + GC Gray3GC; + GC Gray4GC; + GC ScrollBlueGC; + GC MenuBlueGC; + GC MenuSelectBlueGC; +#ifdef USE_LOCALE + XFontSet MenuBarFs; + XFontSet MenuFs; + XFontSet WindowFs; + XFontSet BalloonFs; +#else + XFontStruct *MenuBarFont; + XFontStruct *MenuFont; + XFontStruct *WindowFont; + XFontStruct *BalloonFont; +#endif + unsigned int flags; + int double_click_time; + int bar_width; + int flush_time; + int flush_times; + int zoom_wait; + + char *IconPath; + + Icon *SystemIcon; + char ErrorFunc[30]; + + Window Balloon; + char *BalloonOffStr; + char *BalloonOnStr; + Pixmap mask; + + ShortCut *StartFunc; + + Bool Restarting; +} ScreenInfo; + +#define FOLLOWTOMOUSE 0x00000001 +#define SLOPPYFOCUS 0x00000002 +#define STICKSHADE 0x00000004 +#define STICKHIDE 0x00000008 +#define SHADEMAP 0x00000010 +#define ICONIFYHIDE 0x00000020 +#define ICONIFYSHADE 0x00000040 +#define COMPATIBLE 0x00000080 +#define BALLOONON 0x00000100 +#define STARTING 0x00000200 +#define SYSTEM8 0x00000400 +#define RSTPREVSTATE 0x00000800 +#define ROTATEDESK 0x00001000 +#define USEROOT 0x00002000 +#define OPAQUEMOVE 0x00004000 +#define OPAQUERESIZE 0x00008000 +#define ONECLICKMENU 0x00010000 +#define DEBUGOUT 0x00020000 + +#ifdef USE_LOCALE +#define MENUBARFONT Scr.MenuBarFs +#define MENUFONT Scr.MenuFs +#define WINDOWFONT Scr.WindowFs +#define BALLOONFONT Scr.BalloonFs +#define XDRAWSTRING XmbDrawString +#else +#define MENUBARFONT Scr.MenuBarFont +#define MENUFONT Scr.MenuFont +#define WINDOWFONT Scr.WindowFont +#define BALLOONFONT Scr.BalloonFont +#define XDRAWSTRING( d, w, f, g, x, y, s, l ) XSetFont( d, g, f->fid );\ + XDrawString( d, w, g, x, y, s, l ); +#endif + +extern ScreenInfo Scr; +#endif diff --git a/mlvwm/sun_headers.h b/mlvwm/sun_headers.h new file mode 100644 index 0000000..720519e --- /dev/null +++ b/mlvwm/sun_headers.h @@ -0,0 +1,42 @@ +/**************************************************************************/ +/* Prototypes that don't exist on suns */ +/* If I do ALL this, I can compile OK with -Wall -Wstrict-prototypes on the + * Sun's */ +#ifndef _SUNHEADERS_ +#define _SUNHEADERS_ +#if defined(sun) && !defined(SVR4) && !defined(__NetBSD__) +#include +#include +#include + + +extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); + +extern int system(char *); + +/* stdio things */ +extern int sscanf(char *, char *, ...); +extern int printf(char *, ...); +extern int fprintf(FILE *,char *, ...); +extern int fclose(FILE *); + +/* string manipulation */ +extern int putenv(char *); +extern int fork( void ); + +/* sunOS defines SIG_IGN, but they get it wrong, as far as GCC + * is concerned */ +#ifdef SIG_IGN +#undef SIG_IGN +#endif +#define SIG_IGN (void (*)(int))1 +int wait3(int *, int, struct rusage *); +int sigsetmask(int); +int sigblock(int); +int bzero(char *, int); + +int gethostname(char *name, int namelen); + +/**************************************************************************/ +#endif +#endif diff --git a/mlvwm/wild.c b/mlvwm/wild.c new file mode 100644 index 0000000..71805cd --- /dev/null +++ b/mlvwm/wild.c @@ -0,0 +1,75 @@ +#include + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +/***************************************************************************** + * Does `string' match `pattern'? '*' in pattern matches any sub-string + * (including the null string) '?' matches any single char. For use + * by filenameforall. Note that '*' matches across directory boundaries + * + * This code donated by Paul Hudson + * It is public domain, no strings attached. No guarantees either. + * + *****************************************************************************/ +int matchWildcards(char *pattern, char *string) +{ + if(string == NULL) + { + if(pattern == NULL) + return TRUE; + else if(strcmp(pattern,"*")==0) + return TRUE; + else + return FALSE; + } + if(pattern == NULL) + return TRUE; + + while (*string && *pattern) + { + if (*pattern == '?') + { + /* match any character */ + pattern += 1; + string += 1; + } + else if (*pattern == '*') + { + /* see if the rest of the pattern matches any trailing substring + of the string. */ + pattern += 1; + if (*pattern == 0) + { + return TRUE; /* trailing * must match rest */ + } + while (*string) + { + if (matchWildcards(pattern,string)) + { + return TRUE; + } + string++; + } + return FALSE; + } + else + { + if (*pattern == '\\') + pattern ++; /* has strange, but harmless effects if the last + character is a '\\' */ + if (*pattern++ != *string++) + { + return FALSE; + } + } + } + if((*pattern == 0)&&(*string == 0)) + return TRUE; + if((*string == 0)&&(strcmp(pattern,"*")==0)) + return TRUE; + return FALSE; +} + diff --git a/pixmap/MailEmpty.xpm b/pixmap/MailEmpty.xpm new file mode 100644 index 0000000..77e0412 --- /dev/null +++ b/pixmap/MailEmpty.xpm @@ -0,0 +1,33 @@ +/* XPM */ +static char * MailEmpty_xpm[] = { +"30 22 8 1", +" s None c None", +". c gray70", +"X c grey90", +"o c gray80", +"O c gray50", +"+ c red", +"@ c black", +"# c darkred", +" ", +" ", +" ", +" ...... ", +" ......XXXXX.. ", +" .....XXXXXX....... ", +" .XXXX.X.....ooooXXO ", +" .XXXXXX..ooooXXXXXXO ", +" .XXXXXX..XXXXXXXXo.O ", +" .XXXXXXoOXXXXXXo.+.@ ", +" .XXXXXXoOXXXXo.+++.@ ", +" .XXXXXXoOXo..+++++O@ ", +" .XXXXXooO.+++++##+O@ ", +" OoooooooO.+++##O##O@ ", +" OOOooooO.++#OOOOO@@ ", +" OOOOOOO##OO@@@@ ", +" OOOOO@@@@ ", +" O@@X.O@ ", +" X.O@ ", +" X.O@ ", +" X.O@ ", +" .O@@ "}; diff --git a/pixmap/MailFull.xpm b/pixmap/MailFull.xpm new file mode 100644 index 0000000..05b489b --- /dev/null +++ b/pixmap/MailFull.xpm @@ -0,0 +1,34 @@ +/* XPM */ +static char * MailFull_xpm[] = { +"30 22 9 1", +" s None c None", +". c gray70", +"X c gray90", +"o c gray80", +"O c gray50", +"+ c red", +"@ c black", +"# c darkred", +"$ c white", +" ", +" ", +" ", +" ...... ", +" ......XXXXXX. ", +" oooo.XXXXXX....... ", +" oOOOOoX..+++++oooX@ ", +" oOOOOOOo..++++#XXXX@ ", +" oOOO@@@O.o++##XXXXX@ ", +" oO@@XX.@OX++#XXXXoo@ ", +" @@@$$XX@.OX++#XXoo..@ ", +" @@$$$$$$@@.OX++#Xoo...@ ", +" @@@@@@@@@X.OX++#o....O@ ", +" @$$$$$$$X.Oo+++#..OOO@ ", +" @$$$$$$X.@.+++#OOOO@@ ", +" .O@$$$$$$X@.OOOO@@@@ ", +" .XXO@$$$$$@@O@@@@ ", +" .XXXXO@$$$@@@@X.O@ ", +" .XXXXXO@$@O@@ X.O@ ", +" .XXXXooO@@@@ X.O@ ", +" OooooOO@ X.O@ ", +" OOOO .O@@ "}; diff --git a/pixmap/disk.xpm b/pixmap/disk.xpm new file mode 100644 index 0000000..cfd6726 --- /dev/null +++ b/pixmap/disk.xpm @@ -0,0 +1,47 @@ +/* XPM */ +static char *disk_xpm[] = { +/* width height ncolors chars_per_pixel */ +"32 32 6 1", +/* colors */ +" s None c None", +"X c black", +"% c black", +"( c gray", +", c skyblue", +"0 c white", +/* pixels */ +" ", +" %%%XXXXXXXXXXXXXXXXXXXXXX%%% ", +" %%%%X,,,,,,,,,,,,,,,,,,,,X%%%%", +" %%%%X,,,,,,,,,,,,,,,,,,,,X%%%%", +" (%X0%X,,,,,,,,,,,,,,,,,,,,X%%%%", +" (%X(%X00000000000000000000X%%%%", +" (%XX%X00000000000000000000X%%%%", +" (%%%%X00000000000000000000X%%%%", +" (%%%%X00000000000000000000X%%%%", +" (%%%%X00000000000000000000X%%%%", +" (%%%%X00000000000000000000X%%%%", +" (%%%%X00000000000000000000X%%%%", +" (%%%%X00000000000000000000X%%%%", +" (%%%%X00000000000000000000X%%%%", +" (%%%%X00000000000000000000X%%%%", +" (%%%%X00000000000000000000X%%%%", +" (%%%%X00000000000000000000X%%%%", +" (%%%%X00000000000000000000X%%%%", +" (%%%%%XXXXXXXXXXXXXXXXXXXX%%%%%", +" (%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%", +" (%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%", +" (%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%", +" (%%%%%%(((((((((((((((((%%%%%%%", +" (%%%%%(%%%%%(0(((((((((((%%%%%%", +" (%%%%%(%%%%%(0(((((((((((%%%%%%", +" (%%%%%(%%%%%(0(((((((((((%%%%%%", +" (%%%%%(%%%%%(0(((((((((((%%%%%%", +" (%%%%%(%%%%%(0(((((((((((%%%%%%", +" (%%%%%(%%%%%(0(((((((((((%%%%%%", +" (((%%%(((((((((((((((((((%%%%%%", +" ((%%XXXXXXXXXXXXXXXXXXX%%%%%%", +" " +}; + + diff --git a/pixmap/label1.xpm b/pixmap/label1.xpm new file mode 100644 index 0000000..5a428b9 --- /dev/null +++ b/pixmap/label1.xpm @@ -0,0 +1,25 @@ +/* XPM */ +static char * label1_xpm[] = { +"13 18 4 1", +" s None c None", +". c red", +"X c white", +"o c IndianRed", +" ", +" ..... ", +" ....... ", +" ......X.. ", +" ......XXX.. ", +".......XXXX..", +"........XX...", +"o............", +"oo...........", +"oo...........", +"oo...........", +"ooo..........", +"ooooo........", +" ooooo...... ", +" ooooo.... ", +" ooooooo ", +" ooooo ", +" "}; diff --git a/pixmap/label2.xpm b/pixmap/label2.xpm new file mode 100644 index 0000000..219fae7 --- /dev/null +++ b/pixmap/label2.xpm @@ -0,0 +1,26 @@ +/* XPM */ +static char * label2_xpm[] = { +"14 18 5 1", +" s None c None", +". c #aaaaaaaaaaaa", +"X c #777777777777", +"o c black", +"O c white", +" ........Xo ", +" ........XXoo ", +"...OOO...XXooX", +"..OOOO..XXXooX", +"..OOOO..XXXooX", +"..OOOO..XXXooX", +"..OOO...XXXooX", +"........XXXooX", +".......XXXXooX", +"...XXXXXXXXooX", +".XXXXXXXXXoooX", +"XXXXXXXXXooooX", +"XXXXXXXXoooooX", +"XXXXXXXooooooX", +"oooXXXoooooooX", +"ooooooooooooXX", +" oooooooooXXX ", +" XXXXXXXXXX "}; diff --git a/pixmap/label3.xpm b/pixmap/label3.xpm new file mode 100644 index 0000000..43060da --- /dev/null +++ b/pixmap/label3.xpm @@ -0,0 +1,26 @@ +/* XPM */ +static char * balloon_xpm[] = { +"18 18 5 1", +" s None c None", +"X c #eecc33", +"L c #efef55", +"W c white", +"@ c #222222", +" @@@@@@@@@@@@ ", +" @XXXXXXXXXXXX@ ", +" @XXXXXXXXXXXXXX@ ", +"@XXXXXXXXXXXXXXXX@", +"@LLLLLLLLLLLLLLLL@", +"@LLLLLLLLLLLLLLLL@", +"@LLLLLLLLLLLLLLLL@", +"@WWWWWWWWWWWWWWWW@", +"@WWWWWWWWWWWWWWWW@", +"@WWWWWWWWWWWWWWWW@", +"@WWWWWWWWWWWWWWWW@", +"@LLLLLLLLLLLLLLLL@", +"@LLLLLLLLLLLLLLLL@", +"@LLLLLLLLLLLLLLLL@", +"@XXXXXXXXXXXXXXXX@", +" @XXXXXXXXXXXXXX@ ", +" @XXXXXXXXXXXX@ ", +" @@@@@@@@@@@@ "};? diff --git a/pixmap/pix_test.c b/pixmap/pix_test.c new file mode 100644 index 0000000..5a8eb4d --- /dev/null +++ b/pixmap/pix_test.c @@ -0,0 +1,63 @@ +/****************************************************************************/ +/* This module is all original code */ +/* by TakaC Hasegawa (tak@bioele.nuee.nagoya-u.ac.jp */ +/* Copyright 1996, TakaC Hasegawa */ +/* You may use this code for any purpose, as long as the original */ +/* copyright remains in the source code and all documentation */ +/****************************************************************************/ +#include +#include +#include +#include +#include "garbage.xpm" + +Display *dpy; +Window win; +Pixmap pixmap; +Pixmap mask; +XpmAttributes attributes; +GC gc; + +void HandleEvents() +{ + XEvent ev; + + XNextEvent( dpy, &ev ); + switch( ev.type ){ + case Expose: + printf("Copy\n"); + XCopyArea( dpy, pixmap, win, gc, 0, 0, + attributes.width, attributes.height, 0, 0 ); + break; + case ButtonPress: + exit( 1 ); + break; + } +} + +void main() +{ + Window root; + unsigned long valuemask; + XSetWindowAttributes attr; + + dpy = XOpenDisplay( NULL ); + root = RootWindow( dpy, 0 ); + if( XpmCreatePixmapFromData( dpy, root, garbage_xpm, + &pixmap, &mask, &attributes ) != XpmSuccess ){ + printf("Erroe\n"); + exit( -1 ); + } +/* valuemask = CWBackPixmap | CWEventMask;*/ + valuemask = CWBackPixel | CWEventMask; + attr.event_mask = ( ButtonPressMask | ExposureMask ); +/* attr.background_pixmap = pixmap;*/ + attr.background_pixel = WhitePixel( dpy, 0 ); + win = XCreateWindow( dpy, root, 0, 0, 30, 30, 1, + CopyFromParent, InputOutput, CopyFromParent, + valuemask, &attr ); + gc = DefaultGC( dpy, 0 ); + XMapWindow( dpy, win ); + XFlush( dpy ); + while( 1 ) HandleEvents(); +} diff --git a/sample_rc/Imakefile b/sample_rc/Imakefile new file mode 100644 index 0000000..5b63ee8 --- /dev/null +++ b/sample_rc/Imakefile @@ -0,0 +1,18 @@ +XCOMM Imakefile for MLVWM + +#include "../configure.h" + +XCOMM Do not change from here ! + +all:: +#if InstallSampleRC + SRC_CONFIG = Mlvwmrc + + SAMPLES = Mlvwmrc-Xterm \ + Mlvwmrc-Kterm-j \ + Mlvwmrc-Netscape \ + Mlvwmrc-j + +InstallNamedNonExec($(SRC_CONFIG),system$(MLVWMRC),$(MLVWMLIBDIR)) +InstallMultiple($(SAMPLES),$(MLVWMLIBDIR)) +#endif diff --git a/sample_rc/Mlvwmrc b/sample_rc/Mlvwmrc new file mode 100644 index 0000000..826fc55 --- /dev/null +++ b/sample_rc/Mlvwmrc @@ -0,0 +1,209 @@ +## Number of Desktop +Desktopnum 3 + +## Follow mouse activation of window +#FollowToMouse + +## Follow mouse activation of window but when mouse go into root window, +## active window is not changed +#SloppyFocus + +## Shaded window is all desktop +StickyShade + +## Displayed selected window at current desktop, +## when window is not mappted. +StickyHide + +## Interval and number of flush at flushing menu +#FlushMenu 100 2 + +## Map iconify window as shade +IconifyShade + +## Map window as hide when window is mapped as icon +#IconifyHide + +## Show the window as shade, when hide shaded window is shown +#ShadeMap + +## Enable MacOS 8 decoration feauture +System8 + +## Enable Opaque Move +OpaqueMove + +## Enable Opaque Resize +# OpaqueResize + +## Enable one click menu +#OneClickMenu + +# Double click time +DoubleClickTime 300 + +## Show window name with desktop number on window list +#DisplayDeskNumber + +## Draw move/resize line with dotted line +Compatible + +# Set icon search path. It needs before "Style". +IconPath /usr/local/include/X11/pixmaps:/home2/tak/bin/pixmap +IconMenuIcon label2.xpm + +# Balloon help Settings +UseBalloon "Show Balloon Help" "Hide Balloon Help", Icon label3.xpm + +# Font Settings(without LOCALE) +#MenuBarFont -*-*-medium-i-normal-*-16-*-*-*-*-*-iso8859-* +#MenuFont -*-*-medium-i-normal-*-16-*-*-*-*-*-iso8859-* +#TitleBarFont -*-*-medium-i-normal-*-16-*-*-*-*-*-iso8859-* +#BalloonFont -*-*-medium-i-normal-*-16-*-*-*-*-*-iso8859-* + +# Settings of keyborad short cut +ShortCut +Up C Desk - +Down C Desk + +Left C PreviousWindow +Right C NextWindow +Left M PreviousSameDeskWindow +Right M NextSameDeskWindow +Escape M Restart mlvwm +Escape SM Exit +END + +# Register the menu +Menu Apple, Icon label1.xpm, Stick +"About this Workstation..." NonSelect, Gray, Action About +"" NonSelect +"Terminal" Icon mini-display.xpm, Action Exec "kterm" exec kterm -ls +"Editor" Action Exec "mule" exec mule, Icon mini-edit.xpm +"calculator" Action Exec "xcal" exec xcalc, Icon mini-calc.xpm +END + +Menu def-File, Label "File", Left +"New Folder" NonSelect, Gray, Action Nop +"Open" NonSelect, Gray, Action Nop +"Print" NonSelect, Gray, Action Nop +"Close Window" NonSelect, Gray, Action Nop +"" NonSelect +"Get Info" NonSelect, Gray,Action Nop +"Duplicate" NonSelect, Gray, Action Nop +"" NonSelect +"Find..." NonSelect, Gray, Action Nop +"Find Again" NonSelect, Gray, Action Nop +"" NonSelect +"Page Setup..." NonSelect, Gray, Action Nop +"Print Desktop..." NonSelect, Gray, Action Nop +END + +Menu def-Edit, Label "Edit" +"Undo" NonSelect, Gray, Action Nop +"" NonSelect +"Cut" NonSelect, Gray +"Copy" NonSelect, Gray +"Paste" NonSelect, Gray +"Clear" NonSelect, Gray +"Select All" NonSelect, Gray +"" NonSelect +"Show Clipboard" NonSelect, Gray +END + +Menu def-View, Label "View" +"by Small Icon" NonSelect, Gray +"by Icon" NonSelect, Gray +"by Name" NonSelect, Gray +"by Size" NonSelect, Gray +"by Kind" NonSelect, Gray +"by Date" NonSelect, Gray +"by Version" NonSelect, Gray +END + +Menu def-Label, Label "Label" +"None" NonSelect, Gray +"" NonSelect +"Essential" NonSelect, Gray +"Hot" NonSelect, Gray +"In Progress" NonSelect, Gray +"Cool" NonSelect, Gray +"Personal" NonSelect, Gray +"Project 1" NonSelect, Gray +"Project 2" NonSelect, Gray +END + +Menu restart-sub +"Start twm" Action Restart twm +"Start fvwm" Action Restart fvwm +END + +Menu def-Special, Label "Special" +"Clean Up Desktop" Action Refresh +"Empty Trash" NonSelect, Gray +"" NonSelect +"Eject Disk" NonSelect, Gray +"Erase Disk..." NonSelect, Gray +"" NonSelect +"Start" SubMenu restart-sub +"Restart" Action Restart mlvwm +"Shut down" Action Exit +END + +Menu def-Window +"Move" Action MoveWindow +"Resize" Action ResizeWindow +"Toggle Scroll" Action ToggleScroll +"" NonSelect +"Quit" Action KillWindow +END + +# Swallow the application at menu +#Swallow "XEyes" Action Exec "xeyes" exec xeyes -geometry 25 +Swallow "XClock" Action Exec "xclock" exec xclock -geometry 180x25 -digital -padding 5 -update 1 + +# Definition MenuBar +MenuBar default +def-File +def-Edit +def-View +def-Label +def-Special +def-Window +END + +# Define the initial function +InitFunction +Desk 1 +Exec "xterm" xterm -ls -geometry 80x25 & +Wait xterm +Desk 0 +Exec "xterm" xterm -ls -geometry 80x25 & +Wait xterm +END + +# Define the restart function +RestartFunction +END + +# Define the default window decoration +Style +"*" MiniIcon mini-cross.xpm, MaxmizeScale 90, MenuBar default +END + +Style +"Emacs" MiniIcon mini-edit.xpm +"xv" MiniIcon mini-xv.xpm, EnableScroll +"XCalc" MiniIcon mini-calc.xpm +"Xarchie" MiniIcon mini.xarchie.xpm +"Xmag" MiniIcon mini.xmag.xpm +"XMeter" NoSBarH, NoSBarV, NoResizeR, NoMinMaxR, NoTitle, NoCloseR +"XMeter" NoWinList, Sticky, SkipSelect +"*biff" NoSBarH, NoSBarV, NoResizeR, NoMinMaxR, NoWinList, NoCloseR +"XEyes" NoSBarV, NoMinMaxR, NoSBarH, NoWinList +"XCal" NoSBarH, NoSBarV, NoResizeR, NoMinMaxR, NoWinList, NoCloseR +"XConsole" NoSBarH, NoSBarV, NoResizeR, NoTitle, NoWinList, SkipSelect +END + +# Read other configuration +Read Mlvwmrc-Xterm +Read Mlvwmrc-Netscape diff --git a/sample_rc/Mlvwmrc-Kterm-j b/sample_rc/Mlvwmrc-Kterm-j new file mode 100644 index 0000000..aa2d213 --- /dev/null +++ b/sample_rc/Mlvwmrc-Kterm-j @@ -0,0 +1,15 @@ +Menu kterm-file, Label "File", Left +"$B?75,(B" Action Exec "kterm" exec kterm -ls +"" NonSelect +"$B=*N;(B" Action SendMessage "exit" Return +END + +MenuBar kterm +kterm-file +def-Edit +END + +Style +"KTerm" MaxmizeScale 100, MiniIcon mini-term.xpm, MenuBar kterm, NoSBarH, NoSBarV +END + diff --git a/sample_rc/Mlvwmrc-Netscape b/sample_rc/Mlvwmrc-Netscape new file mode 100644 index 0000000..97a801c --- /dev/null +++ b/sample_rc/Mlvwmrc-Netscape @@ -0,0 +1,110 @@ +Menu netscape-file, Label "File", Left +"New Web Browser" Action SendMessage M+N +"New Mail Message" Action SendMessage M+M +"Mail Document..." NonSelect, Gray +"Open Location..." Action SendMessage M+L +"Open File..." Action SendMessage M+O +"" NonSelect +"Close" Action SendMessage M+W +"Save as" Action SendMessage M+S +"Upload File..." NonSelect, Gray +"" NonSelect +"Page Setup..." NonSelect, Gray +"Print..." Action SendMessage M+P +"" NonSelect +"Quit" Action SendMessage M+Q +END + +Menu netscape-edit, Label "Edit", Left +"Undo" Action SendMessage M+Z +"" NonSelect +"Cut" Action SendMessage M+X +"Copy" Action SendMessage M+C +"Paste" Action SendMessage M+Y +"Clear" NonSelect, Gray +"" NonSelect +"Select All" NonSelect, Gray +"" NonSelect +"Find" Action SendMessage M+F +"Find Again" Action SendMessage M+G +END + +Menu netscape-view, Label "View", Left +"Reload" Action SendMessage M+R +"Reload Frame" NonSelect, Gray +"Load Images" Action SendMessage M+I +"" NonSelect +"Document Source" NonSelect, Gray +"Document Info" NonSelect, Gray +"" NonSelect +"Frame Source" NonSelect, Gray +"Frame Info" NonSelect, Gray +END + +Menu netscape-go, Label "Go", Left +"Back" Action SendMessage M+Left +"Forward" Action SendMessage M+Right +"Home" NonSelect, Gray +"Stop Loading" Action SendMessage ESC +END + +Menu netscape-bookmarks, Label "Bookmarks", Left +"Add Bookmark" Action SendMessage M+A +"" NonSelect +"Mlvwm Home Page" Action Exec netscape -remote 'OpenURL(http://www.bioele.nuee.nagoya-u.ac.jp/member/tak/mlvwm.html)' +END + +Menu netscape-options, Label "Options", Left +"General Preferences..." NonSelect, Gray +"Mail and News Preferences..." NonSelect, Gray +"Network Preferences..." NonSelect, Gray +"Security Preferences..." NonSelect, Gray +"" NonSelect +"Show Menubar" NonSelect, Gray +"Show Toolbar" NonSelect, Gray +"Show Location" NonSelect, Gray +"Show Directory Buttons" NonSelect, Gray +"Show Java Console" NonSelect, Gray +"" NonSelect +"Auto Load Images" NonSelect, Gray +"" NonSelect +"Document Encoding" NonSelect, Gray +"Save Options" NonSelect, Gray +END + +Menu netscape-directory, Label "Directory", Left +"Netscape's Home" NonSelect, Gray +"What's New" NonSelect, Gray +"What's Cool" NonSelect, Gray +"" NonSelect +"Customer Showcase" NonSelect, Gray +"Netscape Destinations" NonSelect, Gray +"Internet Search" NonSelect, Gray +"People" NonSelect, Gray +"About the Internet" NonSelect, Gray +END + +Menu netscape-window, Label "Window", Left +"Netscape Mail" NonSelect, Gray +"Netscape News" NonSelect, Gray +"" NonSelect +"Address Book" NonSelect, Gray +"Bookmarks" Action SendMessage M+B +"History" Action SendMessage M+H +END + +MenuBar netscape +netscape-file +netscape-edit +netscape-view +netscape-go +netscape-bookmarks +netscape-options +netscape-directory +netscape-window +END + +Style +"Netscape" MiniIcon mini-nscape.xpm, MenuBar netscape +END + diff --git a/sample_rc/Mlvwmrc-Xterm b/sample_rc/Mlvwmrc-Xterm new file mode 100644 index 0000000..6d8ff75 --- /dev/null +++ b/sample_rc/Mlvwmrc-Xterm @@ -0,0 +1,16 @@ +Menu xterm-file, Label "File", Left +"New" Action Exec "xterm" exec xterm -ls +"" NonSelect +"Quit" Action SendMessage "exit" Return +END + +MenuBar xterm +xterm-file +def-Edit +END + +Style +"*Term" MaxmizeScale 80x80, NoSBarH, NoSBarV +"*Term" MiniIcon mini-term.xpm, MenuBar xterm +END + diff --git a/sample_rc/Mlvwmrc-j b/sample_rc/Mlvwmrc-j new file mode 100644 index 0000000..1cb08a9 --- /dev/null +++ b/sample_rc/Mlvwmrc-j @@ -0,0 +1,204 @@ +## デスクトップの数 +Desktopnum 3 + +## ウインドウのアクティブがマウスについていくか +#FollowToMouse + +## ウインドウのアクティブがマウスについていくが、root ウインドウにマウスが +## 入った場合アクティブウインドウは保存される +#SloppyFocus + +## シェイドしたウインドウが Stick するか +StickyShade + +## アンマップされているウインドウが Stick するか +StickyHide + +# メニューのフラッシュの時間と回数 +#FlushMenu 100 2 + +# ダブルクリックを認識する時間 +DoubleClickTime 300 + +## Icon化をShadeとする +IconifyShade + +## Icon化をHideとする +#IconifyHide + +## ShadeウインドウがHideからShowになるときShadeのまま +#ShadeMap + +## MacOS8のデコレーションを仕様可能に +#System8 + +## OpaqueMove を可能に +OpaqueMove + +## OpaqueResize を可能に +OpaqueResize + +## OneClickMenu を可能に +OneClickMenu + + +## ウインドウリストのウインドウ名にデスクトップ番号が一緒に表示 +#DisplayDeskNumber + +## リサイズ/移動の時に表示される線が点線になる +Compatible + +# IconPath の指定。Style の指定の前に必要 +IconPath /usr/local/include/X11/pixmaps:/home2/tak/bin/pixmap +IconMenuIcon label2.xpm + +# Balloon help Settings +UseBalloon "Show Balloon Help" "Hide Balloon Help", Icon label3.xpm + +# Font 設定(LOCALE設定ありのサンプル) +MenuBarFont -*-*-*-r-*-*-16-*-*-*-*-*-*-*,-misc-marumoji-*-*-*-*-16-*-*-*-*-*-jisx0208.1983 +MenuFont -*-*-*-r-*-*-16-*-*-*-*-*-*-*,-misc-marumoji-*-*-*-*-16-*-*-*-*-*-jisx0208.1983 +TitleBarFont -*-*-*-r-*-*-16-*-*-*-*-*-*-*,-misc-marumoji-*-*-*-*-16-*-*-*-*-*-jisx0208.1983 + +# Settings of keyborad short cut +ShortCut +Up C Desk - +Down C Desk + +Left C PreviousWindow +Right C NextWindow +Escape M Restart mlvwm +Escape SM Exit +END + +# Register the menu +Menu Apple, Icon label1.xpm, Stick +"このマシンについて..." NonSelect, Gray, Action About +"" NonSelect +"たーみなる" Icon mini-display.xpm, Action Exec "kterm" exec kterm -ls +"えでぃた" Action Exec "mule" exec mule, Icon mini-edit.xpm +"けいさんき" Action Exec "xcal" exec xcalc, Icon mini-calc.xpm +END + +Menu def-File, Label "ファイル", Left +"新規フォルダ" NonSelect, Gray, Action Nop +"開ける" NonSelect, Gray, Action Nop +"印刷" NonSelect, Gray, Action Nop +"ウインドウを閉じる" NonSelect, Gray, Action Nop +"" NonSelect +"情報..." NonSelect, Gray,Action Nop +"複製" NonSelect, Gray, Action Nop +"" NonSelect +"検索..." NonSelect, Gray, Action Nop +"再検索" NonSelect, Gray, Action Nop +"" NonSelect +"用紙設定..." NonSelect, Gray, Action Nop +"デスクトップを印刷..." NonSelect, Gray, Action Nop +END + +Menu def-Edit, Label "編集" +"取り消し" Action Nop +"" NonSelect +"切りとり" Action Nop +"複製" Action Nop +"張り付け" Action Nop +"消去" Action Nop +"すべてを選択" Action Nop +"" NonSelect +"クリップボード表示" Action Nop +END + +Menu def-View, Label "表示" +"アイコン" NonSelect, Gray +"小さいアイコン" NonSelect, Gray +"名前" NonSelect, Gray +"大きさ" NonSelect, Gray +"種類" NonSelect, Gray +"日付" NonSelect, Gray +"バージョン" NonSelect, Gray +END + +Menu def-Label, Label "ラベル" +"なし" NonSelect, Gray +"" NonSelect +"必須" NonSelect, Gray +"重要" NonSelect, Gray +"進行中" NonSelect, Gray +"未決" NonSelect, Gray +"個人用" NonSelect, Gray +"計画1" NonSelect, Gray +"計画2" NonSelect, Gray +END + +Menu def-Special, Label "特別" +"デスクトップを整頓" Action Refresh +"ゴミ箱を空に" NonSelect, Gray +"" NonSelect +"ディスクの取り出し" NonSelect, Gray +"ディスクの消去..." NonSelect, Gray +"" NonSelect +"twmを起動" Action Restart twm +"再起動" Action Restart mlvwm +"終了" Action Exit +END + +Menu def-Window +"移動" Action MoveWindow +"大きさ変更" Action ResizeWindow +"スクロール切替え" Action ToggleScroll +"" NonSelect +"ウインドウを閉じる" Action KillWindow +END + + +# Swallow the application at menu +#Swallow "XEyes" Action Exec "xeyes" exec xeyes -geometry 25 +Swallow "XClock" Action Exec "xclock" exec xclock -geometry 180x25 -digital -padding 5 -update 1 + +# Definition MenuBar +MenuBar default +def-File +def-Edit +def-View +def-Label +def-Special +def-Window +END + +# Definition MenuBar +MenuBar default +def-File +def-Edit +def-View +def-Label +def-Special +def-Window +END + +InitFunction +Desk 1 +Exec "kterm" kterm -ls -geometry 80x25 & +Wait kterm +Desk 0 +Exec "kterm" kterm -ls -geometry 80x25 & +Wait kterm +END + +# Window decoration +Style +"*" MiniIcon mini-cross.xpm, MaxmizeScale 90, MenuBar default +"Netscape" MiniIcon mini-nscape.xpm +"Emacs" MiniIcon mini-edit.xpm +"xv" MiniIcon mini-xv.xpm, EnableScroll +"XCalc" MiniIcon mini-calc.xpm +"Xarchie" MiniIcon mini.xarchie.xpm +"Xmag" MiniIcon mini.xmag.xpm +"XMeter" NoSBarH, NoSBarV, NoResizeR, NoMinMaxR, NoTitle, NoCloseR +"XMeter" NoWinList, Sticky, SkipSelect +"*biff" NoSBarH, NoSBarV, NoResizeR, NoMinMaxR, NoWinList, NoCloseR +"XEyes" NoSBarV, NoMinMaxR, NoSBarH, NoWinList +"XCal" NoSBarH, NoSBarV, NoResizeR, NoMinMaxR, NoWinList, NoCloseR +"XConsole" NoSBarH, NoSBarV, NoResizeR, NoTitle, NoWinList, SkipSelect +END + +# 他の設定を読む +Read Mlvwmrc-Kterm